mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-10 00:34:32 +00:00
Merge branch 'master' into terrain-optimise-fresh
This commit is contained in:
commit
51aca52624
90 changed files with 17206 additions and 15606 deletions
|
|
@ -31,7 +31,6 @@ m_cheat.c
|
|||
m_cond.c
|
||||
m_easing.c
|
||||
m_fixed.c
|
||||
m_menu.c
|
||||
m_misc.c
|
||||
m_perfstats.c
|
||||
m_random.c
|
||||
|
|
@ -115,7 +114,12 @@ k_botsearch.c
|
|||
k_grandprix.c
|
||||
k_boss.c
|
||||
k_hud.c
|
||||
k_menudef.c
|
||||
k_menufunc.c
|
||||
k_menudraw.c
|
||||
k_terrain.c
|
||||
k_brightmap.c
|
||||
k_terrain.c
|
||||
k_director.c
|
||||
k_follower.c
|
||||
k_profiles.c
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ boolean AM_Responder(event_t *ev)
|
|||
{
|
||||
//faB: prevent alt-tab in win32 version to activate automap just before
|
||||
// minimizing the app; doesn't do any harm to the DOS version
|
||||
if (!gamekeydown[KEY_LALT] && !gamekeydown[KEY_RALT])
|
||||
if (!gamekeydown[0][KEY_LALT] && !gamekeydown[0][KEY_RALT])
|
||||
{
|
||||
bigstate = 0; //added : 24-01-98 : toggle off large view
|
||||
AM_Start();
|
||||
|
|
|
|||
105
src/command.c
105
src/command.c
|
|
@ -21,7 +21,7 @@
|
|||
#include "command.h"
|
||||
#include "console.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_fixed.h"
|
||||
#include "m_argv.h"
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "d_netfil.h" // findfile
|
||||
#include "r_data.h" // Color_cons_t
|
||||
#include "r_skins.h"
|
||||
|
||||
//========
|
||||
// protos.
|
||||
|
|
@ -81,10 +82,23 @@ CV_PossibleValue_t kartspeed_cons_t[] = {
|
|||
{KARTSPEED_HARD, "Hard"},
|
||||
{0, NULL}
|
||||
};
|
||||
CV_PossibleValue_t dummykartspeed_cons_t[] = {
|
||||
{KARTSPEED_EASY, "Easy"},
|
||||
{KARTSPEED_NORMAL, "Normal"},
|
||||
{KARTSPEED_HARD, "Hard"},
|
||||
{0, NULL}
|
||||
};
|
||||
CV_PossibleValue_t gpdifficulty_cons_t[] = {
|
||||
{KARTSPEED_EASY, "Easy"},
|
||||
{KARTSPEED_NORMAL, "Normal"},
|
||||
{KARTSPEED_HARD, "Hard"},
|
||||
{KARTGP_MASTER, "Master"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
// Filter consvars by EXECVERSION
|
||||
// First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0)
|
||||
// Also set CV_HIDEN during runtime, after config is loaded
|
||||
// Also set CV_HIDDEN during runtime, after config is loaded
|
||||
|
||||
static boolean execversion_enabled = false;
|
||||
consvar_t cv_execversion = CVAR_INIT ("execversion","1",CV_CALL,CV_Unsigned, CV_EnforceExecVersion);
|
||||
|
|
@ -1255,7 +1269,7 @@ void CV_RegisterVar(consvar_t *variable)
|
|||
}
|
||||
|
||||
// link the variable in
|
||||
if (!(variable->flags & CV_HIDEN))
|
||||
if (!(variable->flags & CV_HIDDEN))
|
||||
{
|
||||
variable->next = consvar_vars;
|
||||
consvar_vars = variable;
|
||||
|
|
@ -1537,8 +1551,7 @@ finish:
|
|||
// landing point for possiblevalue failures
|
||||
badinput:
|
||||
|
||||
if (var != &cv_nextmap) // Suppress errors for cv_nextmap
|
||||
CONS_Printf(M_GetText("\"%s\" is not a possible value for \"%s\"\n"), valstr, var->name);
|
||||
CONS_Printf(M_GetText("\"%s\" is not a possible value for \"%s\"\n"), valstr, var->name);
|
||||
|
||||
// default value not valid... ?!
|
||||
if (var->defaultvalue == valstr)
|
||||
|
|
@ -1804,6 +1817,15 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
|||
return;
|
||||
}
|
||||
|
||||
if (var == &cv_kartspeed && !M_SecretUnlocked(SECRET_HARDSPEED))
|
||||
{
|
||||
if (!stricmp(value, "Hard") || atoi(value) >= KARTSPEED_HARD)
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't unlocked this yet!\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (var == &cv_forceskin)
|
||||
{
|
||||
INT32 skin = R_SkinAvailable(value);
|
||||
|
|
@ -1939,6 +1961,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
|
||||
if (var->PossibleValue)
|
||||
{
|
||||
/*
|
||||
if (var == &cv_nextmap)
|
||||
{
|
||||
// Special case for the nextmap variable, used only directly from the menu
|
||||
|
|
@ -1972,9 +1995,11 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
else if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
|
|
@ -2079,9 +2104,16 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (var == &cv_kartspeed)
|
||||
else if (var->PossibleValue == kartspeed_cons_t
|
||||
|| var->PossibleValue == dummykartspeed_cons_t
|
||||
|| var->PossibleValue == gpdifficulty_cons_t)
|
||||
{
|
||||
max = (M_SecretUnlocked(SECRET_HARDSPEED) ? 3 : 2);
|
||||
if (!M_SecretUnlocked(SECRET_HARDSPEED))
|
||||
{
|
||||
max = KARTSPEED_NORMAL+1;
|
||||
if (var->PossibleValue == kartspeed_cons_t)
|
||||
max++; // Accommodate KARTSPEED_AUTO
|
||||
}
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
if (currentindice == -1)
|
||||
|
|
@ -2122,58 +2154,10 @@ static void CV_EnforceExecVersion(void)
|
|||
CV_StealthSetValue(&cv_execversion, EXECVERSION);
|
||||
}
|
||||
|
||||
static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
||||
{
|
||||
#if 1
|
||||
// We don't have changed axis defaults yet
|
||||
(void)v;
|
||||
(void)valstr;
|
||||
#else
|
||||
UINT8 i;
|
||||
|
||||
// If ALL axis settings are previous defaults, set them to the new defaults
|
||||
// EXECVERSION < 26 (2.1.21)
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (joyaxis_default[i])
|
||||
{
|
||||
if (!stricmp(v->name, "joyaxis_fire"))
|
||||
{
|
||||
if (joyaxis_count[i] > 7) return false;
|
||||
else if (joyaxis_count[i] == 7) return true;
|
||||
|
||||
if (!stricmp(valstr, "None")) joyaxis_count[i]++;
|
||||
else joyaxis_default[i] = false;
|
||||
}
|
||||
// reset all axis settings to defaults
|
||||
if (joyaxis_count[i] == 7)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
default:
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis[0].name, cv_turnaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis[0].name, cv_moveaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_brakeaxis[0].name, cv_brakeaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_aimaxis[0].name, cv_aimaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis[0].name, cv_lookaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis[0].name, cv_fireaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_driftaxis[0].name, cv_driftaxis[0].defaultvalue));
|
||||
break;
|
||||
}
|
||||
joyaxis_count[i]++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// we haven't reached our counts yet, or we're not default
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
||||
{
|
||||
(void)valstr;
|
||||
|
||||
// True means allow the CV change, False means block it
|
||||
|
||||
// We only care about CV_SAVE because this filters the user's config files
|
||||
|
|
@ -2191,11 +2175,6 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
|||
|| !stricmp(v->name, "mousemove2"))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// axis defaults were changed to be friendly to 360 controllers
|
||||
// if ALL axis settings are defaults, then change them to new values
|
||||
if (!CV_FilterJoyAxisVars(v, valstr))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ typedef enum
|
|||
CV_SHOWMODIF = 128, // say something when modified
|
||||
CV_SHOWMODIFONETIME = 256, // same but will be reset to 0 when modified, set in toggle
|
||||
CV_NOSHOWHELP = 512, // Don't show variable in the HELP list Tails 08-13-2002
|
||||
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
|
||||
CV_HIDDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
|
||||
// can only be set when we have the pointer to it
|
||||
// used on menus
|
||||
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on.
|
||||
|
|
@ -175,7 +175,7 @@ extern CV_PossibleValue_t CV_Natural[];
|
|||
#define KARTSPEED_NORMAL 1
|
||||
#define KARTSPEED_HARD 2
|
||||
#define KARTGP_MASTER 3 // Not a speed setting, gives the hardest speed with maxed out bots
|
||||
extern CV_PossibleValue_t kartspeed_cons_t[];
|
||||
extern CV_PossibleValue_t kartspeed_cons_t[], dummykartspeed_cons_t[], gpdifficulty_cons_t[];
|
||||
|
||||
extern consvar_t cv_execversion;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "i_system.h"
|
||||
#include "i_threads.h"
|
||||
#include "d_main.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "filesrch.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
|
|
@ -154,28 +154,6 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, {
|
|||
{0, NULL}};
|
||||
consvar_t cons_backcolor = CVAR_INIT ("con_backcolor", "Black", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change);
|
||||
|
||||
static CV_PossibleValue_t menuhighlight_cons_t[] =
|
||||
{
|
||||
{0, "Game type"},
|
||||
{V_YELLOWMAP, "Always yellow"},
|
||||
{V_PURPLEMAP, "Always purple"},
|
||||
{V_GREENMAP, "Always green"},
|
||||
{V_BLUEMAP, "Always blue"},
|
||||
{V_REDMAP, "Always red"},
|
||||
{V_GRAYMAP, "Always gray"},
|
||||
{V_ORANGEMAP, "Always orange"},
|
||||
{V_SKYMAP, "Always sky-blue"},
|
||||
{V_GOLDMAP, "Always gold"},
|
||||
{V_LAVENDERMAP, "Always lavender"},
|
||||
{V_AQUAMAP, "Always aqua-green"},
|
||||
{V_MAGENTAMAP, "Always magenta"},
|
||||
{V_PINKMAP, "Always pink"},
|
||||
{V_BROWNMAP, "Always brown"},
|
||||
{V_TANMAP, "Always tan"},
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cons_menuhighlight = CVAR_INIT ("menuhighlight", "Game type", CV_SAVE, menuhighlight_cons_t, NULL);
|
||||
|
||||
static void CON_Print(char *msg);
|
||||
|
||||
//
|
||||
|
|
@ -466,7 +444,6 @@ void CON_Init(void)
|
|||
CV_RegisterVar(&cons_height);
|
||||
CV_RegisterVar(&cons_backpic);
|
||||
CV_RegisterVar(&cons_backcolor);
|
||||
CV_RegisterVar(&cons_menuhighlight);
|
||||
COM_AddCommand("bind", CONS_Bind_f);
|
||||
}
|
||||
else
|
||||
|
|
@ -938,7 +915,7 @@ boolean CON_Responder(event_t *ev)
|
|||
if (modeattacking || metalrecording || marathonmode)
|
||||
return false;
|
||||
|
||||
if (ev->data1 >= KEY_MOUSE1) // See also: HUD_Responder
|
||||
if (ev->data1 >= NUMKEYS) // See also: HUD_Responder
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < num_gamecontrols; i++)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ extern INT32 con_clearlines; // lines of top of screen to refresh
|
|||
extern boolean con_hudupdate; // hud messages have changed, need refresh
|
||||
extern UINT32 con_scalefactor; // console text scale factor
|
||||
|
||||
extern consvar_t cons_backcolor, cons_menuhighlight;
|
||||
extern consvar_t cons_backcolor;
|
||||
|
||||
extern UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *orangemap,\
|
||||
*skymap, *goldmap, *lavendermap, *aquamap, *magentamap, *pinkmap, *brownmap, *tanmap;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "hu_stuff.h"
|
||||
#include "keys.h"
|
||||
#include "g_input.h" // JOY1
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "console.h"
|
||||
#include "d_netfil.h"
|
||||
#include "byteptr.h"
|
||||
|
|
@ -903,13 +903,13 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
|
||||
|
||||
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
|
||||
netbuffer->u.serverinfo.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
netbuffer->u.serverinfo.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value));
|
||||
|
||||
if (!node)
|
||||
netbuffer->u.serverinfo.refusereason = 0;
|
||||
else if (!cv_allownewplayer.value)
|
||||
netbuffer->u.serverinfo.refusereason = 1;
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||
else if (D_NumPlayers() >= cv_maxconnections.value)
|
||||
netbuffer->u.serverinfo.refusereason = 2;
|
||||
else
|
||||
netbuffer->u.serverinfo.refusereason = 0;
|
||||
|
|
@ -1073,7 +1073,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||
|
||||
netbuffer->u.servercfg.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
netbuffer->u.servercfg.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value));
|
||||
netbuffer->u.servercfg.allownewplayer = cv_allownewplayer.value;
|
||||
netbuffer->u.servercfg.discordinvites = (boolean)cv_discordinvites.value;
|
||||
|
||||
|
|
@ -1486,7 +1486,7 @@ static void M_ConfirmConnect(event_t *ev)
|
|||
#ifndef NONET
|
||||
if (ev->type == ev_keydown)
|
||||
{
|
||||
if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[0][gc_accelerate][0] || ev->data1 == gamecontrol[0][gc_accelerate][1])
|
||||
if (G_PlayerInputDown(0, gc_a, 1))
|
||||
{
|
||||
if (totalfilesrequestednum > 0)
|
||||
{
|
||||
|
|
@ -1509,7 +1509,7 @@ static void M_ConfirmConnect(event_t *ev)
|
|||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE|| ev->data1 == gamecontrol[0][gc_brake][0] || ev->data1 == gamecontrol[0][gc_brake][1])
|
||||
else if (G_PlayerInputDown(0, gc_x, 1))
|
||||
{
|
||||
cl_mode = CL_ABORTED;
|
||||
M_ClearMenus(true);
|
||||
|
|
@ -1910,6 +1910,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
{
|
||||
I_OsPolling();
|
||||
|
||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
||||
|
||||
if (cl_mode == CL_CONFIRMCONNECT)
|
||||
{
|
||||
D_ProcessEvents(); //needed for menu system to receive inputs
|
||||
|
|
@ -1920,7 +1922,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
G_MapEventsToControls(&events[eventtail]);
|
||||
}
|
||||
|
||||
if ((gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1]) || cl_mode == CL_ABORTED)
|
||||
if (G_PlayerInputDown(0, gc_x, 1) || cl_mode == CL_ABORTED)
|
||||
{
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
|
|
@ -1928,7 +1930,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
memset(gamekeydown, 0, NUMKEYS);
|
||||
memset(gamekeydown, 0, sizeof (gamekeydown));
|
||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1951,11 +1954,11 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
}
|
||||
CL_DrawConnectionStatus();
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
M_Drawer(); //Needed for drawing messageboxes on the connection screen
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
I_UpdateNoVsync(); // page flip or blit buffer
|
||||
if (moviemode)
|
||||
|
|
@ -2011,6 +2014,8 @@ static void CL_ConnectToServer(void)
|
|||
CONS_Printf(M_GetText("Contacting the server...\n"));
|
||||
}
|
||||
|
||||
if (cv_currprofile.value == -1)
|
||||
PR_ApplyProfilePretend(cv_ttlprofilen.value, 0);
|
||||
if (gamestate == GS_INTERMISSION)
|
||||
Y_EndIntermission(); // clean up intermission graphics etc
|
||||
if (gamestate == GS_VOTING)
|
||||
|
|
@ -2018,6 +2023,8 @@ static void CL_ConnectToServer(void)
|
|||
|
||||
DEBFILE(va("waiting %d nodes\n", doomcom->numnodes));
|
||||
G_SetGamestate(GS_WAITINGPLAYERS);
|
||||
if (wipegamestate == GS_MENU)
|
||||
M_ClearMenus(true);
|
||||
wipegamestate = GS_WAITINGPLAYERS;
|
||||
|
||||
ClearAdminPlayers();
|
||||
|
|
@ -2033,11 +2040,14 @@ static void CL_ConnectToServer(void)
|
|||
if (i != -1)
|
||||
{
|
||||
char *gametypestr = serverlist[i].info.gametypename;
|
||||
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
|
||||
|
||||
CON_LogMessage(va(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername));
|
||||
|
||||
gametypestr[sizeof serverlist[i].info.gametypename - 1] = '\0';
|
||||
CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr);
|
||||
CONS_Printf(M_GetText("Version: %d.%d\n"),
|
||||
serverlist[i].info.version, serverlist[i].info.subversion);
|
||||
CON_LogMessage(va(M_GetText("Gametype: %s\n"), gametypestr));
|
||||
|
||||
CON_LogMessage(va(M_GetText("Version: %d.%d\n"),
|
||||
serverlist[i].info.version, serverlist[i].info.subversion));
|
||||
}
|
||||
SL_ClearServerList(servernode);
|
||||
#endif
|
||||
|
|
@ -2069,6 +2079,16 @@ static void CL_ConnectToServer(void)
|
|||
DEBFILE(va("Synchronisation Finished\n"));
|
||||
|
||||
displayplayers[0] = consoleplayer;
|
||||
|
||||
// At this point we've succesfully joined the server, if we joined by IP (ie: a valid joinedIP string), save it!
|
||||
// @TODO: Save the proper server name, right now it doesn't seem like we can consistently retrieve it from the serverlist....?
|
||||
// It works... sometimes but not always which is weird.
|
||||
|
||||
if (*joinedIP && strlen(joinedIP)) // false if we have "" which is \0
|
||||
M_AddToJoinedIPs(joinedIP, netbuffer->u.serverinfo.servername);
|
||||
|
||||
strcpy(joinedIP, ""); // And empty this for good measure regardless of whether or not we actually used it.
|
||||
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
|
@ -2237,6 +2257,10 @@ static void Command_ReloadBan(void) //recheck ban.txt
|
|||
|
||||
static void Command_connect(void)
|
||||
{
|
||||
|
||||
// By default, clear the saved address that we'd save after succesfully joining just to be sure:
|
||||
strcpy(joinedIP, "");
|
||||
|
||||
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
|
||||
{
|
||||
CONS_Printf(M_GetText(
|
||||
|
|
@ -2252,6 +2276,33 @@ static void Command_connect(void)
|
|||
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||
return;
|
||||
}
|
||||
else if (cv_currprofile.value == 0)
|
||||
{
|
||||
CONS_Printf(M_GetText("You cannot connect while using the Guest Profile. Use a Custom Profile to play Online.\n"));
|
||||
return;
|
||||
}
|
||||
else if (cv_currprofile.value == -1)
|
||||
{
|
||||
// No profile set, we're attempting to connect from the title screen. (Discord RPC / connect command)
|
||||
// Automatically apply the last profiles for every potential split player.
|
||||
// Make sure Player 1's Profile ISN'T the guest profile even if we do that.
|
||||
|
||||
UINT8 i;
|
||||
|
||||
CONS_Printf(M_GetText("No Profile set, attempting to use last used Profiles...\n"));
|
||||
|
||||
for (i = 0; i < cv_splitplayers.value; i++)
|
||||
{
|
||||
if (cv_lastprofile[i].value || i > 0)
|
||||
PR_ApplyProfile(cv_lastprofile[i].value, i);
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Player 1's last used Profile is the Guest Profile, which cannot be used to play Online.\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
CONS_Printf(M_GetText("Profiles have been automatically set according to the last used Profiles.\n"));
|
||||
}
|
||||
|
||||
// modified game check: no longer handled
|
||||
// we don't request a restart unless the filelist differs
|
||||
|
|
@ -2292,6 +2343,10 @@ static void Command_connect(void)
|
|||
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
|
||||
else // address only, or address:port
|
||||
servernode = I_NetMakeNode(COM_Argv(1));
|
||||
|
||||
// Last IPs joined:
|
||||
// Keep the address we typed in memory so that we can save it if we *succesfully* join the server
|
||||
strcpy(joinedIP, COM_Argv(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2310,6 +2365,7 @@ static void Command_connect(void)
|
|||
SplitScreen_OnChange();
|
||||
}
|
||||
|
||||
M_ClearMenus(true);
|
||||
CL_ConnectToServer();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -3042,7 +3098,7 @@ consvar_t cv_joinnextround = CVAR_INIT ("joinnextround", "Off", CV_NETVAR, CV_On
|
|||
#endif
|
||||
|
||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_CALL, maxplayers_cons_t, Joinable_OnChange);
|
||||
consvar_t cv_maxconnections = CVAR_INIT ("maxconnections", "16", CV_SAVE|CV_CALL, maxplayers_cons_t, Joinable_OnChange);
|
||||
|
||||
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||
consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL);
|
||||
|
|
@ -3078,7 +3134,7 @@ static void Joinable_OnChange(void)
|
|||
if (!server)
|
||||
return;
|
||||
|
||||
maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value));
|
||||
|
||||
WRITEUINT8(p, maxplayer);
|
||||
WRITEUINT8(p, cv_allownewplayer.value);
|
||||
|
|
@ -3470,6 +3526,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
|||
players[newplayernum].splitscreenindex = 0;
|
||||
players[newplayernum].bot = true;
|
||||
players[newplayernum].botvars.difficulty = difficulty;
|
||||
players[newplayernum].lives = 9;
|
||||
|
||||
players[newplayernum].skincolor = skins[skinnum].prefcolor;
|
||||
sprintf(player_names[newplayernum], "%s", skins[skinnum].realname);
|
||||
|
|
@ -3614,7 +3671,7 @@ boolean SV_SpawnServer(void)
|
|||
|
||||
if (!serverrunning)
|
||||
{
|
||||
CONS_Printf(M_GetText("Starting Server....\n"));
|
||||
CON_LogMessage(M_GetText("Starting Server....\n"));
|
||||
serverrunning = true;
|
||||
SV_ResetServer();
|
||||
SV_GenContext();
|
||||
|
|
@ -3670,6 +3727,7 @@ void SV_StartSinglePlayerServer(void)
|
|||
server = true;
|
||||
netgame = false;
|
||||
multiplayer = false;
|
||||
strcpy(joinedIP, ""); // Make sure to empty this so that we don't save garbage when we start our own game. (because yes we use this for netgames too....)
|
||||
|
||||
if ((modeattacking == ATTACKING_CAPSULES) || (bossinfo.boss == true))
|
||||
{
|
||||
|
|
@ -3728,7 +3786,7 @@ static void HandleConnect(SINT8 node)
|
|||
// Sal: Dedicated mode is INCREDIBLY hacked together.
|
||||
// If a server filled out, then it'd overwrite the host and turn everyone into weird husks.....
|
||||
// It's too much effort to legimately fix right now. Just prevent it from reaching that state.
|
||||
UINT8 maxplayers = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value);
|
||||
UINT8 maxplayers = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value);
|
||||
|
||||
if (bannednode && bannednode[node])
|
||||
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server."));
|
||||
|
|
@ -5583,11 +5641,11 @@ void NetUpdate(void)
|
|||
{
|
||||
resptime = nowtime;
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
M_Ticker();
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
CON_Ticker();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ extern tic_t servermaxping;
|
|||
|
||||
extern boolean server_lagless;
|
||||
|
||||
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_joindelay;
|
||||
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_maxconnections, cv_joindelay;
|
||||
extern consvar_t cv_resynchattempts, cv_blamecfail;
|
||||
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@ typedef enum
|
|||
ev_console,
|
||||
ev_mouse,
|
||||
ev_joystick,
|
||||
ev_joystick2,
|
||||
ev_joystick3,
|
||||
ev_joystick4,
|
||||
} evtype_t;
|
||||
|
||||
// Event structure.
|
||||
|
|
@ -37,6 +34,7 @@ typedef struct
|
|||
INT32 data1; // keys / mouse/joystick buttons
|
||||
INT32 data2; // mouse/joystick x move
|
||||
INT32 data3; // mouse/joystick y move
|
||||
INT32 device; // which player's device it belongs to
|
||||
} event_t;
|
||||
|
||||
//
|
||||
|
|
|
|||
109
src/d_main.c
109
src/d_main.c
|
|
@ -44,7 +44,7 @@
|
|||
#include "i_threads.h"
|
||||
#include "i_video.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
|
|
@ -184,7 +184,9 @@ void D_ProcessEvents(void)
|
|||
event_t *ev;
|
||||
|
||||
boolean eaten;
|
||||
boolean menuresponse = false;
|
||||
|
||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||
{
|
||||
ev = &events[eventtail];
|
||||
|
|
@ -205,25 +207,6 @@ void D_ProcessEvents(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
// Menu input
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
#endif
|
||||
{
|
||||
eaten = M_Responder(ev);
|
||||
}
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
#endif
|
||||
|
||||
if (eaten)
|
||||
continue; // menu ate the event
|
||||
|
||||
// Demo input:
|
||||
if (demo.playback)
|
||||
if (M_DemoResponder(ev))
|
||||
continue; // demo ate the event
|
||||
|
||||
// console input
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&con_mutex);
|
||||
|
|
@ -241,8 +224,37 @@ void D_ProcessEvents(void)
|
|||
continue; // ate the event
|
||||
}
|
||||
|
||||
// Menu input
|
||||
menuresponse = true;
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
{
|
||||
eaten = M_Responder(ev);
|
||||
}
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
|
||||
if (eaten)
|
||||
continue; // menu ate the event
|
||||
|
||||
// Demo input:
|
||||
/*
|
||||
if (demo.playback)
|
||||
if (M_DemoResponder(ev))
|
||||
continue; // demo ate the event
|
||||
*/
|
||||
|
||||
|
||||
G_Responder(ev);
|
||||
}
|
||||
|
||||
// Reset menu controls when no event is processed
|
||||
if (!menuresponse)
|
||||
{
|
||||
M_MapMenuControls(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -321,7 +333,7 @@ static void D_Display(void)
|
|||
// set for all later
|
||||
wipedefindex = gamestate; // wipe_xxx_toblack
|
||||
if (gamestate == GS_TITLESCREEN && wipegamestate != GS_INTRO)
|
||||
wipedefindex = wipe_timeattack_toblack;
|
||||
wipedefindex = wipe_titlescreen_toblack;
|
||||
|
||||
if (wipetypepre < 0 || !F_WipeExists(wipetypepre))
|
||||
wipetypepre = wipedefs[wipedefindex];
|
||||
|
|
@ -335,7 +347,7 @@ static void D_Display(void)
|
|||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK, "FADEMAP0", false, false);
|
||||
F_RunWipe(wipetypepre, gamestate != GS_MENU, "FADEMAP0", false, false);
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL && rendermode != render_none)
|
||||
|
|
@ -348,7 +360,7 @@ static void D_Display(void)
|
|||
}
|
||||
else //dedicated servers
|
||||
{
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", false, false);
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_MENU, "FADEMAP0", false, false);
|
||||
wipegamestate = gamestate;
|
||||
}
|
||||
|
||||
|
|
@ -388,7 +400,7 @@ static void D_Display(void)
|
|||
HU_Drawer();
|
||||
break;
|
||||
|
||||
case GS_TIMEATTACK:
|
||||
case GS_MENU:
|
||||
break;
|
||||
|
||||
case GS_INTRO:
|
||||
|
|
@ -541,9 +553,8 @@ static void D_Display(void)
|
|||
if (rendermode == render_soft)
|
||||
{
|
||||
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
Y_ConsiderScreenBuffer();
|
||||
usebuffer = true;
|
||||
}
|
||||
|
||||
lastdraw = false;
|
||||
}
|
||||
|
||||
|
|
@ -595,11 +606,11 @@ static void D_Display(void)
|
|||
vid.recalc = 0;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
M_Drawer(); // menu is drawn even on top of everything
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
// focus lost moved to M_Drawer
|
||||
|
||||
|
|
@ -623,7 +634,7 @@ static void D_Display(void)
|
|||
{
|
||||
F_WipeEndScreen();
|
||||
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN, "FADEMAP0", true, false);
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_MENU && gamestate != GS_TITLESCREEN, "FADEMAP0", true, false);
|
||||
}
|
||||
|
||||
// reset counters so timedemo doesn't count the wipe duration
|
||||
|
|
@ -990,25 +1001,13 @@ void D_StartTitle(void)
|
|||
G_SetGametype(GT_RACE); // SRB2kart
|
||||
paused = false;
|
||||
advancedemo = false;
|
||||
F_InitMenuPresValues();
|
||||
F_StartTitleScreen();
|
||||
|
||||
currentMenu = &MainDef; // reset the current menu ID
|
||||
|
||||
// Reset the palette
|
||||
if (rendermode != render_none)
|
||||
V_SetPaletteLump("PLAYPAL");
|
||||
|
||||
// The title screen is obviously not a tutorial! (Unless I'm mistaken)
|
||||
/*
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
G_CopyControls(gamecontrol[0], gamecontroldefault[0][gcs_custom], gcl_full, num_gcl_full); // using gcs_custom as temp storage
|
||||
M_StartMessage("Do you want to \x82save the recommended \x82movement controls?\x80\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls",
|
||||
M_TutorialSaveControlResponse, MM_YESNO);
|
||||
}
|
||||
*/
|
||||
|
||||
tutorialmode = false;
|
||||
}
|
||||
|
||||
|
|
@ -1270,6 +1269,9 @@ void D_SRB2Main(void)
|
|||
strcpy(savegamename, SAVEGAMENAME"%u.ssg");
|
||||
strcpy(liveeventbackup, "live"SAVEGAMENAME".bkp"); // intentionally not ending with .ssg
|
||||
|
||||
// Init the joined IP table for quick rejoining of past games.
|
||||
M_InitJoinedIPArray();
|
||||
|
||||
{
|
||||
const char *userhome = D_Home(); //Alam: path to home
|
||||
|
||||
|
|
@ -1342,6 +1344,8 @@ void D_SRB2Main(void)
|
|||
}
|
||||
}
|
||||
|
||||
M_LoadJoinedIPs(); // load joined ips
|
||||
|
||||
// Create addons dir
|
||||
snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons");
|
||||
I_mkdir(addonsdir, 0755);
|
||||
|
|
@ -1398,13 +1402,6 @@ void D_SRB2Main(void)
|
|||
// adapt tables to SRB2's needs, including extra slots for dehacked file support
|
||||
P_PatchInfoTables();
|
||||
|
||||
// initiate menu metadata before SOCcing them
|
||||
M_InitMenuPresTables();
|
||||
|
||||
// init title screen display params
|
||||
if (M_GetUrlProtocolArg() || M_CheckParm("-connect"))
|
||||
F_InitMenuPresValues();
|
||||
|
||||
//---------------------------------------------------- READY TIME
|
||||
// we need to check for dedicated before initialization of some subsystems
|
||||
|
||||
|
|
@ -1415,10 +1412,6 @@ void D_SRB2Main(void)
|
|||
// Make backups of some SOCcable tables.
|
||||
P_BackupTables();
|
||||
|
||||
// Setup character tables
|
||||
// Have to be done here before files are loaded
|
||||
M_InitCharacterTables();
|
||||
|
||||
// load wad, including the main wad file
|
||||
CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
|
||||
W_InitMultipleFiles(startupiwads, false);
|
||||
|
|
@ -1565,6 +1558,9 @@ void D_SRB2Main(void)
|
|||
//--------------------------------------------------------- CONFIG.CFG
|
||||
M_FirstLoadConfig(); // WARNING : this do a "COM_BufExecute()"
|
||||
|
||||
// Load Profiles now that default controls have been defined
|
||||
PR_LoadProfiles(); // load control profiles
|
||||
|
||||
M_Init();
|
||||
|
||||
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
||||
|
|
@ -1717,9 +1713,9 @@ void D_SRB2Main(void)
|
|||
|
||||
// user settings come before "+" parameters.
|
||||
if (dedicated)
|
||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"kartserv.cfg\"\n", srb2home));
|
||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"ringserv.cfg\"\n", srb2home));
|
||||
else
|
||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"kartexec.cfg\" -noerror\n", srb2home));
|
||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"ringexec.cfg\" -noerror\n", srb2home));
|
||||
|
||||
if (!autostart)
|
||||
M_PushSpecialParameters(); // push all "+" parameters at the command buffer
|
||||
|
|
@ -1785,6 +1781,10 @@ void D_SRB2Main(void)
|
|||
|
||||
CV_ClearChangedFlags();
|
||||
|
||||
// Has to be done before anything else so skin, color, etc in command buffer has an affect.
|
||||
// ttlprofilen used because it's roughly equivalent in functionality - a QoL aid for quickly getting from startup to action
|
||||
PR_ApplyProfile(cv_ttlprofilen.value, 0);
|
||||
|
||||
// Do this here so if you run SRB2 with eg +timelimit 5, the time limit counts
|
||||
// as having been modified for the first game.
|
||||
M_PushSpecialParameters(); // push all "+" parameter at the command buffer
|
||||
|
|
@ -1886,7 +1886,6 @@ void D_SRB2Main(void)
|
|||
}
|
||||
else if (M_CheckParm("-skipintro"))
|
||||
{
|
||||
F_InitMenuPresValues();
|
||||
F_StartTitleScreen();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef __D_MAIN__
|
||||
#define __D_MAIN__
|
||||
|
||||
#include "k_profiles.h" // PR_LoadProfiles()
|
||||
#include "d_event.h"
|
||||
#include "w_wad.h" // for MAX_WADFILES
|
||||
|
||||
|
|
|
|||
127
src/d_netcmd.c
127
src/d_netcmd.c
|
|
@ -21,7 +21,7 @@
|
|||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "g_input.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "r_local.h"
|
||||
#include "r_skins.h"
|
||||
#include "p_local.h"
|
||||
|
|
@ -231,7 +231,7 @@ static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"},
|
|||
{4, "/dev/js3"}, {0, NULL}};
|
||||
#else
|
||||
// accept whatever value - it is in fact the joystick device number
|
||||
#define usejoystick_cons_t NULL
|
||||
static CV_PossibleValue_t usejoystick_cons_t[] = {{-1, "MIN"}, {MAXGAMEPADS, "MAX"}, {0, NULL}};
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
|
||||
|
|
@ -249,11 +249,11 @@ static consvar_t cv_fishcake = CVAR_INIT ("fishcake", "Off", CV_CALL|CV_NOSHOWHE
|
|||
#endif
|
||||
static consvar_t cv_dummyconsvar = CVAR_INIT ("dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, DummyConsvar_OnChange);
|
||||
|
||||
consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
|
||||
consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
|
||||
consvar_t cv_allowteamchange = CVAR_INIT ("allowteamchange", "Yes", CV_NETVAR, CV_YesNo, NULL);
|
||||
|
||||
static CV_PossibleValue_t ingamecap_cons_t[] = {{0, "MIN"}, {MAXPLAYERS-1, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_ingamecap = CVAR_INIT ("ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL);
|
||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{1, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_NETVAR, maxplayers_cons_t, NULL);
|
||||
|
||||
consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL);
|
||||
|
||||
|
|
@ -301,6 +301,28 @@ consvar_t cv_followercolor[MAXSPLITSCREENPLAYERS] = {
|
|||
CVAR_INIT ("followercolor4", "1", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor4_OnChange)
|
||||
};
|
||||
|
||||
// last selected profile, unaccessible cvar only set internally but is saved.
|
||||
// It's used to know what profile to autoload you to when you get into the character setup.
|
||||
|
||||
static CV_PossibleValue_t lastprofile_cons_t[] = {{-1, "MIN"}, {MAXPROFILES, "MAX"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_lastprofile[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("lastprofile", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL),
|
||||
CVAR_INIT ("lastprofile2", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL),
|
||||
CVAR_INIT ("lastprofile3", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL),
|
||||
CVAR_INIT ("lastprofile4", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL),
|
||||
};
|
||||
|
||||
// currently loaded profile for P1 menuing.
|
||||
// You choose this profile when starting the game, this will also set lastprofile[0]
|
||||
consvar_t cv_currprofile = CVAR_INIT ("currprofile", "-1", CV_HIDDEN, lastprofile_cons_t, NULL);
|
||||
|
||||
// This one is used exclusively for the titlescreen
|
||||
consvar_t cv_ttlprofilen = CVAR_INIT ("ttlprofilen", "0", CV_SAVE, lastprofile_cons_t, NULL);
|
||||
|
||||
// Cvar for using splitscreen with 1 device.
|
||||
consvar_t cv_splitdevice = CVAR_INIT ("splitdevice", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
INT32 cv_debug;
|
||||
|
|
@ -308,10 +330,10 @@ INT32 cv_debug;
|
|||
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
|
||||
|
||||
consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick1),
|
||||
CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2),
|
||||
CVAR_INIT ("use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3),
|
||||
CVAR_INIT ("use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4)
|
||||
CVAR_INIT ("use_device", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick1),
|
||||
CVAR_INIT ("use_device2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2),
|
||||
CVAR_INIT ("use_device3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3),
|
||||
CVAR_INIT ("use_device4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4)
|
||||
};
|
||||
|
||||
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
|
||||
|
|
@ -590,23 +612,17 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
|||
void D_RegisterServerCommands(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
Forceskin_cons_t[0].value = -1;
|
||||
Forceskin_cons_t[0].strvalue = "Off";
|
||||
|
||||
for (i = 0; i < NUMGAMETYPES; i++)
|
||||
{
|
||||
gametype_cons_t[i].value = i;
|
||||
gametype_cons_t[i].strvalue = Gametype_Names[i];
|
||||
}
|
||||
gametype_cons_t[NUMGAMETYPES].value = 0;
|
||||
gametype_cons_t[NUMGAMETYPES].strvalue = NULL;
|
||||
|
||||
// Set the values to 0/NULL, it will be overwritten later when a skin is assigned to the slot.
|
||||
for (i = 1; i < MAXSKINS; i++)
|
||||
{
|
||||
Forceskin_cons_t[i].value = 0;
|
||||
Forceskin_cons_t[i].strvalue = NULL;
|
||||
}
|
||||
|
||||
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
|
||||
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
|
||||
RegisterNetXCmd(XD_POWERLEVEL, Got_PowerLevel);
|
||||
|
|
@ -721,11 +737,11 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_allowexitlevel);
|
||||
CV_RegisterVar(&cv_restrictskinchange);
|
||||
CV_RegisterVar(&cv_allowteamchange);
|
||||
CV_RegisterVar(&cv_ingamecap);
|
||||
CV_RegisterVar(&cv_maxplayers);
|
||||
CV_RegisterVar(&cv_respawntime);
|
||||
|
||||
// d_clisrv
|
||||
CV_RegisterVar(&cv_maxplayers);
|
||||
CV_RegisterVar(&cv_maxconnections);
|
||||
CV_RegisterVar(&cv_joindelay);
|
||||
CV_RegisterVar(&cv_resynchattempts);
|
||||
CV_RegisterVar(&cv_maxsend);
|
||||
|
|
@ -876,8 +892,13 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_skin[i]);
|
||||
CV_RegisterVar(&cv_follower[i]);
|
||||
CV_RegisterVar(&cv_followercolor[i]);
|
||||
CV_RegisterVar(&cv_lastprofile[i]);
|
||||
}
|
||||
|
||||
CV_RegisterVar(&cv_currprofile);
|
||||
CV_RegisterVar(&cv_ttlprofilen);
|
||||
CV_RegisterVar(&cv_splitdevice);
|
||||
|
||||
// preferred number of players
|
||||
CV_RegisterVar(&cv_splitplayers);
|
||||
|
||||
|
|
@ -931,7 +952,7 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_bsaturation);
|
||||
CV_RegisterVar(&cv_msaturation);
|
||||
|
||||
// m_menu.c
|
||||
// k_menu.c
|
||||
//CV_RegisterVar(&cv_compactscoreboard);
|
||||
CV_RegisterVar(&cv_chatheight);
|
||||
CV_RegisterVar(&cv_chatwidth);
|
||||
|
|
@ -950,15 +971,7 @@ void D_RegisterClientCommands(void)
|
|||
{
|
||||
CV_RegisterVar(&cv_kickstartaccel[i]);
|
||||
CV_RegisterVar(&cv_shrinkme[i]);
|
||||
CV_RegisterVar(&cv_turnaxis[i]);
|
||||
CV_RegisterVar(&cv_moveaxis[i]);
|
||||
CV_RegisterVar(&cv_brakeaxis[i]);
|
||||
CV_RegisterVar(&cv_aimaxis[i]);
|
||||
CV_RegisterVar(&cv_lookaxis[i]);
|
||||
CV_RegisterVar(&cv_fireaxis[i]);
|
||||
CV_RegisterVar(&cv_driftaxis[i]);
|
||||
CV_RegisterVar(&cv_deadzone[i]);
|
||||
CV_RegisterVar(&cv_digitaldeadzone[i]);
|
||||
}
|
||||
|
||||
// filesrch.c
|
||||
|
|
@ -1310,6 +1323,8 @@ UINT8 CanChangeSkin(INT32 playernum)
|
|||
// Server has skin change restrictions.
|
||||
if (cv_restrictskinchange.value)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
// Can change skin during initial countdown.
|
||||
if (leveltime < starttime)
|
||||
return true;
|
||||
|
|
@ -1318,8 +1333,22 @@ UINT8 CanChangeSkin(INT32 playernum)
|
|||
if (players[playernum].spectator || players[playernum].playerstate == PST_DEAD || players[playernum].playerstate == PST_REBORN)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
// Check for freeeplay
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (i == consoleplayer)
|
||||
continue;
|
||||
if (playeringame[i] && !players[i].spectator && gamestate == GS_LEVEL)
|
||||
return false; // Not freeplay!
|
||||
}
|
||||
|
||||
// if we've gotten here, then it's freeplay, and switching anytime is fair game.
|
||||
return true;
|
||||
}
|
||||
// if restrictskinchange is off and we're trying to change skins, don't allow changing skins while moving after the race has started.
|
||||
else if (gamestate == GS_LEVEL && leveltime >= starttime)
|
||||
return (!P_PlayerMoving(playernum));
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1864,21 +1893,23 @@ static void Got_LeaveParty(UINT8 **cp,INT32 playernum)
|
|||
|
||||
void D_SendPlayerConfig(UINT8 n)
|
||||
{
|
||||
const profile_t *pr = PR_GetProfile(cv_lastprofile[n].value);
|
||||
|
||||
UINT8 buf[4];
|
||||
UINT8 *p = buf;
|
||||
|
||||
SendNameAndColor(n);
|
||||
SendWeaponPref(n);
|
||||
|
||||
if (n == 0)
|
||||
if (pr != NULL)
|
||||
{
|
||||
// Send it over
|
||||
WRITEUINT16(p, vspowerlevel[PWRLV_RACE]);
|
||||
WRITEUINT16(p, vspowerlevel[PWRLV_BATTLE]);
|
||||
WRITEUINT16(p, pr->powerlevels[PWRLV_RACE]);
|
||||
WRITEUINT16(p, pr->powerlevels[PWRLV_BATTLE]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Splitscreen players have invalid powerlevel
|
||||
// Guest players have no power level
|
||||
WRITEUINT16(p, 0);
|
||||
WRITEUINT16(p, 0);
|
||||
}
|
||||
|
|
@ -2372,10 +2403,12 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
|||
// The supplied data are assumed to be good.
|
||||
I_Assert(delay >= 0 && delay <= 2);
|
||||
|
||||
/*
|
||||
if (mapnum != -1)
|
||||
{
|
||||
CV_SetValue(&cv_nextmap, mapnum);
|
||||
}
|
||||
*/
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d pencoremode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
|
||||
mapnum, newgametype, pencoremode, resetplayers, delay, skipprecutscene);
|
||||
|
|
@ -2838,10 +2871,6 @@ static void Command_Map_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
G_CopyControls(gamecontrol[0], gamecontroldefault[0][gcs_custom], gcl_full, num_gcl_full); // using gcs_custom as temp storage
|
||||
}
|
||||
tutorialmode = false; // warping takes us out of tutorial mode
|
||||
|
||||
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, fromlevelselect);
|
||||
|
|
@ -2964,7 +2993,7 @@ static void Command_Pause(void)
|
|||
}
|
||||
else if (modeattacking) // in time attack, pausing restarts the map
|
||||
{
|
||||
M_ModeAttackRetry(0); // directly call from m_menu;
|
||||
//M_ModeAttackRetry(0); // directly call from m_menu;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4550,6 +4579,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
if (oldgt && newgt)
|
||||
CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt);
|
||||
}
|
||||
|
||||
// Only do the following as the server, not as remote admin.
|
||||
// There will always be a server, and this only needs to be done once.
|
||||
if (server && (multiplayer || netgame))
|
||||
|
|
@ -5022,7 +5052,7 @@ void Command_Retry_f(void)
|
|||
}
|
||||
else if (grandprixinfo.gp == false && bossinfo.boss == false)
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in Grand Prix or Mission Mode.\n"));
|
||||
CONS_Printf(M_GetText("This only works in singleplayer games.\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5482,7 +5512,7 @@ static void Followercolor4_OnChange(void)
|
|||
}
|
||||
}
|
||||
|
||||
/** Sends a skin change for the console player, unless that player is moving.
|
||||
/** Sends a skin change for the console player, unless that player is moving. Also forces them to spectate if the change is done during gameplay
|
||||
* \sa cv_skin, Skin2_OnChange, Color_OnChange
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
|
|
@ -5498,7 +5528,7 @@ static void Skin_OnChange(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
||||
if (CanChangeSkin(consoleplayer))
|
||||
SendNameAndColor(0);
|
||||
else
|
||||
{
|
||||
|
|
@ -5508,7 +5538,7 @@ static void Skin_OnChange(void)
|
|||
}
|
||||
|
||||
/** Sends a skin change for the secondary splitscreen player, unless that
|
||||
* player is moving.
|
||||
* player is moving. Forces spectate the player if the change is done during gameplay.
|
||||
* \sa cv_skin2, Skin_OnChange, Color2_OnChange
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
|
|
@ -5517,7 +5547,7 @@ static void Skin2_OnChange(void)
|
|||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
|
||||
if (CanChangeSkin(g_localplayers[1]) && !P_PlayerMoving(g_localplayers[1]))
|
||||
if (CanChangeSkin(g_localplayers[1]))
|
||||
SendNameAndColor(1);
|
||||
else
|
||||
{
|
||||
|
|
@ -5531,7 +5561,7 @@ static void Skin3_OnChange(void)
|
|||
if (!Playing() || splitscreen < 2)
|
||||
return; // do whatever you want
|
||||
|
||||
if (CanChangeSkin(g_localplayers[2]) && !P_PlayerMoving(g_localplayers[2]))
|
||||
if (CanChangeSkin(g_localplayers[2]))
|
||||
SendNameAndColor(2);
|
||||
else
|
||||
{
|
||||
|
|
@ -5545,7 +5575,7 @@ static void Skin4_OnChange(void)
|
|||
if (!Playing() || splitscreen < 3)
|
||||
return; // do whatever you want
|
||||
|
||||
if (CanChangeSkin(g_localplayers[3]) && !P_PlayerMoving(g_localplayers[3]))
|
||||
if (CanChangeSkin(g_localplayers[3]))
|
||||
SendNameAndColor(3);
|
||||
else
|
||||
{
|
||||
|
|
@ -5776,13 +5806,6 @@ static void KartFrantic_OnChange(void)
|
|||
|
||||
static void KartSpeed_OnChange(void)
|
||||
{
|
||||
if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == KARTSPEED_HARD)
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||
CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,19 @@ extern consvar_t cv_playercolor[MAXSPLITSCREENPLAYERS];
|
|||
extern consvar_t cv_skin[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_follower[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_followercolor[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_lastprofile[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
// current profile loaded.
|
||||
// Used to know how to make the options menu behave among other things.
|
||||
extern consvar_t cv_currprofile;
|
||||
|
||||
// This is used to save the last profile you used on the title screen.
|
||||
// that way you can mash n all...
|
||||
extern consvar_t cv_ttlprofilen;
|
||||
|
||||
// CVar that allows starting as many splitscreens as you want with one device
|
||||
// Intended for use with testing
|
||||
extern consvar_t cv_splitdevice;
|
||||
|
||||
// preferred number of players
|
||||
extern consvar_t cv_splitplayers;
|
||||
|
|
@ -56,7 +69,7 @@ extern consvar_t cv_runscripts;
|
|||
extern consvar_t cv_mute;
|
||||
extern consvar_t cv_pause;
|
||||
|
||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_ingamecap, cv_respawntime;
|
||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime;
|
||||
|
||||
// SRB2kart items
|
||||
extern consvar_t cv_superring, cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana;
|
||||
|
|
@ -85,7 +98,7 @@ extern consvar_t cv_kartusepwrlv;
|
|||
|
||||
extern consvar_t cv_votetime;
|
||||
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
#include "byteptr.h"
|
||||
#include "p_setup.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "md5.h"
|
||||
#include "filesrch.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -443,6 +443,8 @@ typedef struct player_s
|
|||
fixed_t spindashspeed; // Spindash release speed
|
||||
UINT8 spindashboost; // Spindash release boost timer
|
||||
|
||||
fixed_t fastfall; // Fast fall momentum
|
||||
|
||||
UINT8 numboosts; // Count of how many boosts are being stacked, for after image spawning
|
||||
fixed_t boostpower; // Base boost value, for offroad
|
||||
fixed_t speedboost; // Boost value smoothing for max speed
|
||||
|
|
@ -504,8 +506,8 @@ typedef struct player_s
|
|||
SINT8 lastjawztarget; // (-1 to 15) - Last person you target with jawz, for playing the target switch sfx
|
||||
UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy
|
||||
|
||||
UINT8 confirmInflictor; // Player ID that dealt damage to you
|
||||
UINT8 confirmInflictorDelay; // Delay before playing the sound
|
||||
UINT8 confirmVictim; // Player ID that you dealt damage to
|
||||
UINT8 confirmVictimDelay; // Delay before playing the sound
|
||||
|
||||
UINT8 trickpanel; // Trick panel state
|
||||
UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold
|
||||
|
|
|
|||
|
|
@ -33,13 +33,14 @@ typedef enum
|
|||
BT_LOOKBACK = 1<<5, // Look Backward
|
||||
|
||||
BT_EBRAKEMASK = (BT_ACCELERATE|BT_BRAKE),
|
||||
BT_SPINDASHMASK = (BT_ACCELERATE|BT_BRAKE|BT_DRIFT),
|
||||
|
||||
// free: 1<<6 to 1<<12
|
||||
|
||||
// Lua garbage
|
||||
BT_CUSTOM1 = 1<<13,
|
||||
BT_CUSTOM2 = 1<<14,
|
||||
BT_CUSTOM3 = 1<<15,
|
||||
BT_LUAA = 1<<13,
|
||||
BT_LUAB = 1<<14,
|
||||
BT_LUAC = 1<<15,
|
||||
} buttoncode_t;
|
||||
|
||||
// The data sampled per tick (single player)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "g_game.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h"
|
||||
#include "st_stuff.h"
|
||||
|
|
@ -486,16 +486,6 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MN_",word,3)) {
|
||||
p = word+3;
|
||||
for (i = 0; i < NUMMENUTYPES; i++)
|
||||
if (fastcmp(p, MENUTYPES_LIST[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("PRECIP_",word,7)) {
|
||||
p = word+7;
|
||||
for (i = 0; i < MAXPRECIP; i++)
|
||||
|
|
|
|||
411
src/deh_soc.c
411
src/deh_soc.c
|
|
@ -20,7 +20,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "y_inter.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "f_finale.h"
|
||||
#include "st_stuff.h"
|
||||
|
|
@ -164,200 +164,6 @@ void clear_levels(void)
|
|||
P_AllocMapHeader(gamemap-1);
|
||||
}
|
||||
|
||||
static boolean findFreeSlot(INT32 *num)
|
||||
{
|
||||
// Send the character select entry to a free slot.
|
||||
while (*num < MAXSKINS && (description[*num].used))
|
||||
*num = *num+1;
|
||||
|
||||
// No more free slots. :(
|
||||
if (*num >= MAXSKINS)
|
||||
return false;
|
||||
|
||||
// Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||
description[*num].picname[0] = '\0';
|
||||
description[*num].nametag[0] = '\0';
|
||||
description[*num].displayname[0] = '\0';
|
||||
description[*num].oppositecolor = SKINCOLOR_NONE;
|
||||
description[*num].tagtextcolor = SKINCOLOR_NONE;
|
||||
description[*num].tagoutlinecolor = SKINCOLOR_NONE;
|
||||
|
||||
// Found one! ^_^
|
||||
return (description[*num].used = true);
|
||||
}
|
||||
|
||||
// Reads a player.
|
||||
// For modifying the character select screen
|
||||
void readPlayer(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *displayname = ZZ_Alloc(MAXLINELEN+1);
|
||||
INT32 i;
|
||||
boolean slotfound = false;
|
||||
|
||||
#define SLOTFOUND \
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) \
|
||||
goto done;
|
||||
|
||||
displayname[MAXLINELEN] = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
char *tmp;
|
||||
if (s[i] == '=')
|
||||
{
|
||||
tmp = &s[i+2];
|
||||
strncpy(displayname, tmp, SKINNAMESIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
if (fastcmp(word, "PLAYERTEXT"))
|
||||
{
|
||||
char *playertext = NULL;
|
||||
|
||||
SLOTFOUND
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
if (s[i] == '=')
|
||||
{
|
||||
playertext = &s[i+2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (playertext)
|
||||
{
|
||||
strcpy(description[num].notes, playertext);
|
||||
strcat(description[num].notes, myhashfgets(playertext, sizeof (description[num].notes), f));
|
||||
}
|
||||
else
|
||||
strcpy(description[num].notes, "");
|
||||
|
||||
// For some reason, cutting the string did not work above. Most likely due to strcpy or strcat...
|
||||
// It works down here, though.
|
||||
{
|
||||
INT32 numline = 0;
|
||||
for (i = 0; (size_t)i < sizeof(description[num].notes)-1; i++)
|
||||
{
|
||||
if (numline < 20 && description[num].notes[i] == '\n')
|
||||
numline++;
|
||||
|
||||
if (numline >= 20 || description[num].notes[i] == '\0' || description[num].notes[i] == '#')
|
||||
break;
|
||||
}
|
||||
}
|
||||
description[num].notes[strlen(description[num].notes)-1] = '\0';
|
||||
description[num].notes[i] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
i = atoi(word2);
|
||||
|
||||
if (fastcmp(word, "PICNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
strncpy(description[num].picname, word2, 8);
|
||||
}
|
||||
// new character select
|
||||
else if (fastcmp(word, "DISPLAYNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
// replace '#' with line breaks
|
||||
// (also remove any '\n')
|
||||
{
|
||||
char *cur = NULL;
|
||||
|
||||
// remove '\n'
|
||||
cur = strchr(displayname, '\n');
|
||||
if (cur)
|
||||
*cur = '\0';
|
||||
|
||||
// turn '#' into '\n'
|
||||
cur = strchr(displayname, '#');
|
||||
while (cur)
|
||||
{
|
||||
*cur = '\n';
|
||||
cur = strchr(cur, '#');
|
||||
}
|
||||
}
|
||||
// copy final string
|
||||
strncpy(description[num].displayname, displayname, SKINNAMESIZE);
|
||||
}
|
||||
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].oppositecolor = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
strncpy(description[num].nametag, word2, 8);
|
||||
}
|
||||
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].tagtextcolor = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].tagoutlinecolor = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "STATUS"))
|
||||
{
|
||||
/*
|
||||
You MAY disable previous entries if you so desire...
|
||||
But try to enable something that's already enabled and you will be sent to a free slot.
|
||||
|
||||
Because of this, you are allowed to edit any previous entries you like, but only if you
|
||||
signal that you are purposely doing so by disabling and then reenabling the slot.
|
||||
*/
|
||||
if (i && !slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
|
||||
description[num].used = (!!i);
|
||||
}
|
||||
else if (fastcmp(word, "SKINNAME"))
|
||||
{
|
||||
// Send to free slot.
|
||||
SLOTFOUND
|
||||
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
|
||||
strlwr(description[num].skinname);
|
||||
}
|
||||
else
|
||||
deh_warning("readPlayer %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
#undef SLOTFOUND
|
||||
done:
|
||||
Z_Free(displayname);
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
// TODO: Figure out how to do undolines for this....
|
||||
// TODO: Warnings for running out of freeslots
|
||||
void readfreeslots(MYFILE *f)
|
||||
|
|
@ -1113,7 +919,6 @@ void readsprite2(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
// copypasted from readPlayer :]
|
||||
void readgametype(MYFILE *f, char *gtname)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
|
@ -2258,194 +2063,6 @@ void readtextprompt(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
void readmenu(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word = s;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 value;
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
// First remove trailing newline, if there is one
|
||||
tmp = strchr(s, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
word2 = (tmp += 2);
|
||||
strupr(word2);
|
||||
|
||||
value = atoi(word2); // used for numerical settings
|
||||
|
||||
if (fastcmp(word, "BACKGROUNDNAME"))
|
||||
{
|
||||
strncpy(menupres[num].bgname, word2, 8);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "HIDEBACKGROUND"))
|
||||
{
|
||||
menupres[num].bghide = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "BACKGROUNDCOLOR"))
|
||||
{
|
||||
menupres[num].bgcolor = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS") || fastcmp(word, "TITLEPICSHIDE"))
|
||||
{
|
||||
// true by default, except MM_MAIN
|
||||
menupres[num].hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSMODE"))
|
||||
{
|
||||
if (fastcmp(word2, "USER"))
|
||||
menupres[num].ttmode = TTMODE_USER;
|
||||
else if (fastcmp(word2, "HIDE") || fastcmp(word2, "HIDDEN") || fastcmp(word2, "NONE"))
|
||||
{
|
||||
menupres[num].ttmode = TTMODE_USER;
|
||||
menupres[num].ttname[0] = 0;
|
||||
menupres[num].hidetitlepics = true;
|
||||
}
|
||||
else if (fastcmp(word2, "RINGRACERS"))
|
||||
menupres[num].ttmode = TTMODE_RINGRACERS;
|
||||
else if (fastcmp(word2, "OLD"))
|
||||
menupres[num].ttmode = TTMODE_OLD;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSSCALE"))
|
||||
{
|
||||
// Don't handle Alacroix special case here; see Maincfg section.
|
||||
menupres[num].ttscale = max(1, min(8, (UINT8)get_number(word2)));
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSNAME"))
|
||||
{
|
||||
strncpy(menupres[num].ttname, word2, 9);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSX"))
|
||||
{
|
||||
menupres[num].ttx = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSY"))
|
||||
{
|
||||
menupres[num].tty = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSLOOP"))
|
||||
{
|
||||
menupres[num].ttloop = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSTICS"))
|
||||
{
|
||||
menupres[num].tttics = (UINT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLESCROLLSPEED") || fastcmp(word, "TITLESCROLLXSPEED")
|
||||
|| fastcmp(word, "SCROLLSPEED") || fastcmp(word, "SCROLLXSPEED"))
|
||||
{
|
||||
menupres[num].titlescrollxspeed = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLESCROLLYSPEED") || fastcmp(word, "SCROLLYSPEED"))
|
||||
{
|
||||
menupres[num].titlescrollyspeed = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "MUSIC"))
|
||||
{
|
||||
strncpy(menupres[num].musname, word2, 7);
|
||||
menupres[num].musname[6] = 0;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "MUSICTRACK"))
|
||||
{
|
||||
menupres[num].mustrack = ((UINT16)value - 1);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "MUSICLOOP"))
|
||||
{
|
||||
// true by default except MM_MAIN
|
||||
menupres[num].muslooping = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "NOMUSIC"))
|
||||
{
|
||||
menupres[num].musstop = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "IGNOREMUSIC"))
|
||||
{
|
||||
menupres[num].musignore = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "FADESTRENGTH"))
|
||||
{
|
||||
// one-based, <= 0 means use default value. 1-32
|
||||
menupres[num].fadestrength = get_number(word2)-1;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "NOENTERBUBBLE"))
|
||||
{
|
||||
menupres[num].enterbubble = !(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "NOEXITBUBBLE"))
|
||||
{
|
||||
menupres[num].exitbubble = !(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "ENTERTAG"))
|
||||
{
|
||||
menupres[num].entertag = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "EXITTAG"))
|
||||
{
|
||||
menupres[num].exittag = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "ENTERWIPE"))
|
||||
{
|
||||
menupres[num].enterwipe = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "EXITWIPE"))
|
||||
{
|
||||
menupres[num].exitwipe = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
void readframe(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
|
@ -3658,13 +3275,13 @@ void readwipes(MYFILE *f)
|
|||
else if (fastcmp(pword, "FINAL"))
|
||||
wipeoffset = wipe_titlescreen_final;
|
||||
}
|
||||
else if (fastncmp(word, "TIMEATTACK_", 11))
|
||||
else if (fastncmp(word, "MENU_", 11))
|
||||
{
|
||||
pword = word + 11;
|
||||
if (fastcmp(pword, "TOBLACK"))
|
||||
wipeoffset = wipe_timeattack_toblack;
|
||||
wipeoffset = wipe_menu_toblack;
|
||||
else if (fastcmp(pword, "FINAL"))
|
||||
wipeoffset = wipe_timeattack_final;
|
||||
wipeoffset = wipe_menu_final;
|
||||
}
|
||||
else if (fastncmp(word, "CREDITS_", 8))
|
||||
{
|
||||
|
|
@ -3869,6 +3486,7 @@ void readfollower(MYFILE *f)
|
|||
followers[numfollowers].bobamp = 4*FRACUNIT;
|
||||
followers[numfollowers].hitconfirmtime = TICRATE;
|
||||
followers[numfollowers].defaultcolor = SKINCOLOR_GREEN;
|
||||
strcpy(followers[numfollowers].icon, "M_NORANK");
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -3902,6 +3520,11 @@ void readfollower(MYFILE *f)
|
|||
strcpy(followers[numfollowers].name, word2);
|
||||
nameset = true;
|
||||
}
|
||||
else if (fastcmp(word, "ICON"))
|
||||
{
|
||||
strcpy(followers[numfollowers].icon, word2);
|
||||
nameset = true;
|
||||
}
|
||||
else if (fastcmp(word, "MODE"))
|
||||
{
|
||||
if (word2)
|
||||
|
|
@ -4268,20 +3891,6 @@ sfxenum_t get_sfx(const char *word)
|
|||
return sfx_None;
|
||||
}
|
||||
|
||||
menutype_t get_menutype(const char *word)
|
||||
{ // Returns the value of MN_ enumerations
|
||||
menutype_t i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
if (fastncmp("MN_",word,3))
|
||||
word += 3; // take off the MN_
|
||||
for (i = 0; i < NUMMENUTYPES; i++)
|
||||
if (fastcmp(word, MENUTYPES_LIST[i]))
|
||||
return i;
|
||||
deh_warning("Couldn't find menutype named 'MN_%s'",word);
|
||||
return MN_NONE;
|
||||
}
|
||||
|
||||
/*static INT16 get_gametype(const char *word)
|
||||
{ // Returns the value of GT_ enumerations
|
||||
INT16 i;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "m_argv.h"
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "f_finale.h"
|
||||
#include "st_stuff.h"
|
||||
|
|
@ -52,7 +52,6 @@ statenum_t get_state(const char *word);
|
|||
spritenum_t get_sprite(const char *word);
|
||||
playersprite_t get_sprite2(const char *word);
|
||||
sfxenum_t get_sfx(const char *word);
|
||||
menutype_t get_menutype(const char *word);
|
||||
//INT16 get_gametype(const char *word);
|
||||
//powertype_t get_power(const char *word);
|
||||
skincolornum_t get_skincolor(const char *word);
|
||||
|
|
@ -79,7 +78,6 @@ void readlight(MYFILE *f, INT32 num);
|
|||
void readskincolor(MYFILE *f, INT32 num);
|
||||
void readthing(MYFILE *f, INT32 num);
|
||||
void readfreeslots(MYFILE *f);
|
||||
void readPlayer(MYFILE *f, INT32 num);
|
||||
void clear_levels(void);
|
||||
void clear_conditionsets(void);
|
||||
|
||||
|
|
|
|||
108
src/deh_tables.c
108
src/deh_tables.c
|
|
@ -13,7 +13,7 @@
|
|||
#include "doomdef.h" // Constants
|
||||
#include "s_sound.h" // Sound constants
|
||||
#include "info.h" // Mobj, state, sprite, etc constants
|
||||
#include "m_menu.h" // Menu constants
|
||||
#include "k_menu.h" // Menu constants
|
||||
#include "y_inter.h" // Intermission constants
|
||||
#include "p_local.h" // some more constants
|
||||
#include "r_draw.h" // Colormap constants
|
||||
|
|
@ -6011,101 +6011,6 @@ const char *const HUDITEMS_LIST[] = {
|
|||
"POWERUPS"
|
||||
};
|
||||
|
||||
const char *const MENUTYPES_LIST[] = {
|
||||
"NONE",
|
||||
|
||||
"MAIN",
|
||||
|
||||
// Single Player
|
||||
"SP_MAIN",
|
||||
|
||||
"SP_LOAD",
|
||||
"SP_PLAYER",
|
||||
|
||||
"SP_LEVELSELECT",
|
||||
"SP_LEVELSTATS",
|
||||
|
||||
"SP_TIMEATTACK",
|
||||
"SP_TIMEATTACK_LEVELSELECT",
|
||||
"SP_GUESTREPLAY",
|
||||
"SP_REPLAY",
|
||||
"SP_GHOST",
|
||||
|
||||
"SP_NIGHTSATTACK",
|
||||
"SP_NIGHTS_LEVELSELECT",
|
||||
"SP_NIGHTS_GUESTREPLAY",
|
||||
"SP_NIGHTS_REPLAY",
|
||||
"SP_NIGHTS_GHOST",
|
||||
|
||||
// Multiplayer
|
||||
"MP_MAIN",
|
||||
"MP_SPLITSCREEN", // SplitServer
|
||||
"MP_SERVER",
|
||||
"MP_CONNECT",
|
||||
"MP_ROOM",
|
||||
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
||||
"MP_SERVER_OPTIONS",
|
||||
|
||||
// Options
|
||||
"OP_MAIN",
|
||||
|
||||
"OP_P1CONTROLS",
|
||||
"OP_CHANGECONTROLS", // OP_ChangeControlsDef shared with P2
|
||||
"OP_P1MOUSE",
|
||||
"OP_P1JOYSTICK",
|
||||
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
|
||||
"OP_P1CAMERA",
|
||||
|
||||
"OP_P2CONTROLS",
|
||||
"OP_P2MOUSE",
|
||||
"OP_P2JOYSTICK",
|
||||
"OP_P2CAMERA",
|
||||
|
||||
"OP_PLAYSTYLE",
|
||||
|
||||
"OP_VIDEO",
|
||||
"OP_VIDEOMODE",
|
||||
"OP_COLOR",
|
||||
"OP_OPENGL",
|
||||
"OP_OPENGL_LIGHTING",
|
||||
|
||||
"OP_SOUND",
|
||||
|
||||
"OP_SERVER",
|
||||
"OP_MONITORTOGGLE",
|
||||
|
||||
"OP_DATA",
|
||||
"OP_ADDONS",
|
||||
"OP_SCREENSHOTS",
|
||||
"OP_ERASEDATA",
|
||||
|
||||
// Extras
|
||||
"SR_MAIN",
|
||||
"SR_PANDORA",
|
||||
"SR_LEVELSELECT",
|
||||
"SR_UNLOCKCHECKLIST",
|
||||
"SR_EMBLEMHINT",
|
||||
"SR_PLAYER",
|
||||
"SR_SOUNDTEST",
|
||||
|
||||
// Addons (Part of MISC, but let's make it our own)
|
||||
"AD_MAIN",
|
||||
|
||||
// MISC
|
||||
// "MESSAGE",
|
||||
// "SPAUSE",
|
||||
|
||||
// "MPAUSE",
|
||||
// "SCRAMBLETEAM",
|
||||
// "CHANGETEAM",
|
||||
// "CHANGELEVEL",
|
||||
|
||||
// "MAPAUSE",
|
||||
// "HELP",
|
||||
|
||||
"SPECIAL"
|
||||
};
|
||||
|
||||
struct int_const_s const INT_CONST[] = {
|
||||
// If a mod removes some variables here,
|
||||
// please leave the names in-tact and just set
|
||||
|
|
@ -6574,9 +6479,9 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"BT_DRIFT",BT_DRIFT},
|
||||
{"BT_BRAKE",BT_BRAKE},
|
||||
{"BT_ATTACK",BT_ATTACK},
|
||||
{"BT_CUSTOM1",BT_CUSTOM1}, // Lua customizable
|
||||
{"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable
|
||||
{"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable
|
||||
{"BT_LUAA",BT_LUAA}, // Lua customizable
|
||||
{"BT_LUAB",BT_LUAB}, // Lua customizable
|
||||
{"BT_LUAC",BT_LUAC}, // Lua customizable
|
||||
|
||||
// Lua command registration flags
|
||||
{"COM_ADMIN",COM_ADMIN},
|
||||
|
|
@ -6598,8 +6503,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"CV_SHOWMODIF",CV_SHOWMODIF},
|
||||
{"CV_SHOWMODIFONETIME",CV_SHOWMODIFONETIME},
|
||||
{"CV_NOSHOWHELP",CV_NOSHOWHELP},
|
||||
{"CV_HIDEN",CV_HIDEN},
|
||||
{"CV_HIDDEN",CV_HIDEN},
|
||||
{"CV_HIDDEN",CV_HIDDEN},
|
||||
{"CV_CHEAT",CV_CHEAT},
|
||||
{"CV_NOLUA",CV_NOLUA},
|
||||
|
||||
|
|
@ -6707,7 +6611,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"GS_INTERMISSION",GS_INTERMISSION},
|
||||
{"GS_CONTINUING",GS_CONTINUING},
|
||||
{"GS_TITLESCREEN",GS_TITLESCREEN},
|
||||
{"GS_TIMEATTACK",GS_TIMEATTACK},
|
||||
{"GS_MENU",GS_MENU},
|
||||
{"GS_CREDITS",GS_CREDITS},
|
||||
{"GS_EVALUATION",GS_EVALUATION},
|
||||
{"GS_GAMEEND",GS_GAMEEND},
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ extern const char *COLOR_ENUMS[];
|
|||
extern const char *const POWERS_LIST[];
|
||||
extern const char *const KARTHUD_LIST[];
|
||||
extern const char *const HUDITEMS_LIST[];
|
||||
extern const char *const MENUTYPES_LIST[];
|
||||
|
||||
extern struct int_const_s const INT_CONST[];
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
/// \brief Load dehacked file and change tables and text
|
||||
|
||||
#include "doomdef.h"
|
||||
|
||||
#include "m_cond.h"
|
||||
#include "deh_soc.h"
|
||||
#include "deh_tables.h"
|
||||
|
|
@ -245,18 +246,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
else
|
||||
i = 0;
|
||||
|
||||
if (fastcmp(word, "CHARACTER"))
|
||||
{
|
||||
if (i >= 0 && i < 32)
|
||||
readPlayer(f, i);
|
||||
else
|
||||
{
|
||||
deh_warning("Character %d out of range (0 - 31)", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (fastcmp(word, "EMBLEM"))
|
||||
if (fastcmp(word, "EMBLEM"))
|
||||
{
|
||||
if (!mainfile && !gamedataadded)
|
||||
{
|
||||
|
|
@ -495,19 +485,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "MENU"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_menutype(word2); // find a huditem by name
|
||||
if (i >= 1 && i < NUMMENUTYPES)
|
||||
readmenu(f, i);
|
||||
else
|
||||
{
|
||||
// zero-based, but let's start at 1
|
||||
deh_warning("Menu number %d out of range (1 - %d)", i, NUMMENUTYPES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
if (!mainfile && !gamedataadded)
|
||||
|
|
@ -564,6 +541,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
{
|
||||
cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL);
|
||||
cup->id = numkartcupheaders;
|
||||
cup->unlockrequired = -1;
|
||||
deh_strlcpy(cup->name, word2,
|
||||
sizeof(cup->name), va("Cup header %s: name", word2));
|
||||
if (prev != NULL)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "i_net.h"
|
||||
#include "g_game.h"
|
||||
#include "p_tick.h"
|
||||
#include "m_menu.h" // gametype_cons_t
|
||||
#include "k_menu.h" // gametype_cons_t
|
||||
#include "r_things.h" // skins
|
||||
#include "mserv.h" // cv_advertise
|
||||
#include "z_zone.h"
|
||||
|
|
@ -267,7 +267,7 @@ static void DRPC_HandleJoinRequest(const DiscordUser *requestUser)
|
|||
else
|
||||
{
|
||||
discordRequestList = newRequest;
|
||||
M_RefreshPauseMenu();
|
||||
//M_RefreshPauseMenu();
|
||||
}
|
||||
|
||||
// Made it to the end, request was valid, so play the request sound :)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ extern char logfilename[1024];
|
|||
|
||||
// Comment out this line to completely disable update alerts (recommended for testing, but not for release)
|
||||
#ifndef BETAVERSION
|
||||
#define UPDATE_ALERT
|
||||
//#define UPDATE_ALERT
|
||||
#endif
|
||||
|
||||
// The string used in the alert that pops up in the event of an update being available.
|
||||
|
|
@ -205,8 +205,10 @@ extern char logfilename[1024];
|
|||
#define PLAYERSMASK (MAXPLAYERS-1)
|
||||
#define MAXPLAYERNAME 21
|
||||
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
|
||||
#define MAXGAMEPADS (MAXSPLITSCREENPLAYERS * 2) // Number of gamepads we'll be allowing
|
||||
|
||||
#define MAXSKINS UINT8_MAX
|
||||
#define SKINNAMESIZE 16 // Moved from r_skins.h as including that particular header causes issues later down the line.
|
||||
|
||||
#define COLORRAMPSIZE 16
|
||||
#define MAXCOLORNAME 32
|
||||
|
|
@ -225,6 +227,10 @@ typedef struct skincolor_s
|
|||
boolean accessible; // Accessible by the color command + setup menu
|
||||
} skincolor_t;
|
||||
|
||||
#define FOLLOWERCOLOR_MATCH UINT16_MAX
|
||||
#define FOLLOWERCOLOR_OPPOSITE (UINT16_MAX-1)
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SKINCOLOR_NONE = 0,
|
||||
|
|
|
|||
|
|
@ -195,7 +195,6 @@ extern INT16 bootmap; //bootmap for loading a map on startup
|
|||
|
||||
extern INT16 tutorialmap; // map to load for tutorial
|
||||
extern boolean tutorialmode; // are we in a tutorial right now?
|
||||
extern INT32 tutorialgcs; // which control scheme is loaded?
|
||||
|
||||
extern boolean looptitle;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "z_zone.h"
|
||||
#include "i_system.h"
|
||||
#include "i_threads.h"
|
||||
#include "m_menu.h"
|
||||
#include "dehacked.h"
|
||||
#include "g_input.h"
|
||||
#include "console.h"
|
||||
|
|
@ -42,6 +41,9 @@
|
|||
|
||||
#include "lua_hud.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_menu.h"
|
||||
|
||||
// Stage of animation:
|
||||
// 0 = text, 1 = art screen
|
||||
INT32 finalecount;
|
||||
|
|
@ -53,7 +55,6 @@ static INT32 timetonext; // Delay between screen changes
|
|||
|
||||
static tic_t animtimer; // Used for some animation timings
|
||||
static tic_t credbgtimer; // Credits background
|
||||
static INT16 skullAnimCounter; // Prompts: Chevron animation
|
||||
|
||||
static tic_t stoptimer;
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ mobj_t *titlemapcameraref = NULL;
|
|||
// menu presentation state
|
||||
char curbgname[9];
|
||||
SINT8 curfadevalue;
|
||||
INT32 curbgcolor;
|
||||
INT32 curbgcolor = -1; // Please stop assaulting my eyes.
|
||||
INT32 curbgxspeed;
|
||||
INT32 curbgyspeed;
|
||||
boolean curbghide;
|
||||
|
|
@ -427,11 +428,11 @@ void F_IntroTicker(void)
|
|||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
M_Drawer(); // menu is drawn even on top of wipes
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
|
||||
|
||||
|
|
@ -1682,11 +1683,9 @@ void F_GameEndTicker(void)
|
|||
// TITLE SCREEN
|
||||
// ==============
|
||||
|
||||
void F_InitMenuPresValues(void)
|
||||
static void F_InitMenuPresValues(void)
|
||||
{
|
||||
menuanimtimer = 0;
|
||||
prevMenuId = 0;
|
||||
activeMenuId = MainDef.menuid;
|
||||
|
||||
// Set defaults for presentation values
|
||||
strncpy(curbgname, "TITLESKY", 9);
|
||||
|
|
@ -1705,11 +1704,6 @@ void F_InitMenuPresValues(void)
|
|||
curttloop = ttloop;
|
||||
curtttics = tttics;
|
||||
|
||||
// Find current presentation values
|
||||
//M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY");
|
||||
//M_SetMenuCurFadeValue(16);
|
||||
//M_SetMenuCurTitlePics();
|
||||
|
||||
LUA_HUD_DestroyDrawList(luahuddrawlist_title);
|
||||
luahuddrawlist_title = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
|
@ -1842,11 +1836,13 @@ static void F_CacheTitleScreen(void)
|
|||
|
||||
void F_StartTitleScreen(void)
|
||||
{
|
||||
setup_numplayers = 0;
|
||||
|
||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
||||
{
|
||||
ttuser_count = 0;
|
||||
finalecount = 0;
|
||||
wipetypepost = menupres[MN_MAIN].enterwipe;
|
||||
wipetypepost = 0;
|
||||
}
|
||||
else
|
||||
wipegamestate = GS_TITLESCREEN;
|
||||
|
|
@ -1898,10 +1894,6 @@ void F_StartTitleScreen(void)
|
|||
camera[0].chase = true;
|
||||
camera[0].height = 0;
|
||||
|
||||
// Run enter linedef exec for MN_MAIN, since this is where we start
|
||||
if (menupres[MN_MAIN].entertag)
|
||||
P_LinedefExecute(menupres[MN_MAIN].entertag, players[displayplayers[0]].mo, NULL);
|
||||
|
||||
wipegamestate = prevwipegamestate;
|
||||
}
|
||||
else
|
||||
|
|
@ -1920,6 +1912,7 @@ void F_StartTitleScreen(void)
|
|||
demoDelayLeft = demoDelayTime;
|
||||
demoIdleLeft = demoIdleTime;
|
||||
|
||||
F_InitMenuPresValues();
|
||||
F_CacheTitleScreen();
|
||||
}
|
||||
|
||||
|
|
@ -1936,6 +1929,8 @@ void F_TitleScreenDrawer(void)
|
|||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor);
|
||||
else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS)
|
||||
F_SkyScroll(curbgxspeed, curbgyspeed, curbgname);
|
||||
else
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
// Don't draw outside of the title screen, or if the patch isn't there.
|
||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
||||
|
|
@ -2115,18 +2110,10 @@ luahook:
|
|||
LUA_HUD_DrawList(luahuddrawlist_title);
|
||||
}
|
||||
|
||||
// separate animation timer for backgrounds, since we also count
|
||||
// during GS_TIMEATTACK
|
||||
void F_MenuPresTicker(boolean run)
|
||||
{
|
||||
if (run)
|
||||
menuanimtimer++;
|
||||
}
|
||||
|
||||
// (no longer) De-Demo'd Title Screen
|
||||
void F_TitleScreenTicker(boolean run)
|
||||
{
|
||||
F_MenuPresTicker(true); // title sky
|
||||
menuanimtimer++; // title sky
|
||||
|
||||
if (run)
|
||||
{
|
||||
|
|
@ -2135,10 +2122,7 @@ void F_TitleScreenTicker(boolean run)
|
|||
if (finalecount == 1)
|
||||
{
|
||||
// Now start the music
|
||||
if (menupres[MN_MAIN].musname[0])
|
||||
S_ChangeMusic(menupres[MN_MAIN].musname, menupres[MN_MAIN].mustrack, menupres[MN_MAIN].muslooping);
|
||||
else
|
||||
S_ChangeMusicInternal("_title", looptitle);
|
||||
S_ChangeMusicInternal("_title", looptitle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2853,12 +2837,13 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex
|
|||
|
||||
static boolean F_GetTextPromptTutorialTag(char *tag, INT32 length)
|
||||
{
|
||||
INT32 gcs = gcs_custom;
|
||||
INT32 gcs = 0;
|
||||
boolean suffixed = true;
|
||||
|
||||
if (!tag || !tag[0] || !tutorialmode)
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (!strncmp(tag, "TAA", 3)) // Accelerate
|
||||
gcs = G_GetControlScheme(gamecontrol[0], gcl_accelerate, num_gcl_accelerate);
|
||||
else if (!strncmp(tag, "TAB", 3)) // Brake
|
||||
|
|
@ -2873,14 +2858,10 @@ static boolean F_GetTextPromptTutorialTag(char *tag, INT32 length)
|
|||
gcs = G_GetControlScheme(gamecontrol[0], gcl_item, num_gcl_item);
|
||||
else
|
||||
gcs = G_GetControlScheme(gamecontrol[0], gcl_full, num_gcl_full);
|
||||
*/
|
||||
|
||||
switch (gcs)
|
||||
{
|
||||
case gcs_kart:
|
||||
// strncat(tag, "KART", length);
|
||||
suffixed = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
strncat(tag, "CUSTOM", length);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -129,9 +129,6 @@ extern UINT16 curtttics;
|
|||
|
||||
#define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0])
|
||||
|
||||
void F_InitMenuPresValues(void);
|
||||
void F_MenuPresTicker(boolean run);
|
||||
|
||||
//
|
||||
// WIPE
|
||||
//
|
||||
|
|
@ -163,7 +160,7 @@ enum
|
|||
wipe_voting_toblack,
|
||||
wipe_continuing_toblack,
|
||||
wipe_titlescreen_toblack,
|
||||
wipe_timeattack_toblack,
|
||||
wipe_menu_toblack,
|
||||
wipe_credits_toblack,
|
||||
wipe_evaluation_toblack,
|
||||
wipe_gameend_toblack,
|
||||
|
|
@ -181,7 +178,7 @@ enum
|
|||
wipe_voting_final,
|
||||
wipe_continuing_final,
|
||||
wipe_titlescreen_final,
|
||||
wipe_timeattack_final,
|
||||
wipe_menu_final,
|
||||
wipe_credits_final,
|
||||
wipe_evaluation_final,
|
||||
wipe_gameend_final,
|
||||
|
|
|
|||
12
src/f_wipe.c
12
src/f_wipe.c
|
|
@ -26,7 +26,6 @@
|
|||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "i_threads.h"
|
||||
#include "m_menu.h"
|
||||
#include "console.h"
|
||||
#include "d_main.h"
|
||||
#include "m_misc.h" // movie mode
|
||||
|
|
@ -43,6 +42,9 @@
|
|||
#define NOWIPE // do not enable wipe image post processing for ARM, SH and MIPS CPUs
|
||||
#endif
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_menu.h"
|
||||
|
||||
typedef struct fademask_s {
|
||||
UINT8* mask;
|
||||
UINT16 width, height;
|
||||
|
|
@ -58,7 +60,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
0, // wipe_voting_toblack,
|
||||
0, // wipe_continuing_toblack
|
||||
0, // wipe_titlescreen_toblack
|
||||
0, // wipe_timeattack_toblack
|
||||
1, // wipe_menu_toblack
|
||||
99, // wipe_credits_toblack
|
||||
0, // wipe_evaluation_toblack
|
||||
0, // wipe_gameend_toblack
|
||||
|
|
@ -74,7 +76,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
0, // wipe_voting_final
|
||||
0, // wipe_continuing_final
|
||||
0, // wipe_titlescreen_final
|
||||
0, // wipe_timeattack_final
|
||||
1, // wipe_menu_final
|
||||
99, // wipe_credits_final
|
||||
0, // wipe_evaluation_final
|
||||
0, // wipe_gameend_final
|
||||
|
|
@ -509,11 +511,11 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r
|
|||
if (drawMenu)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
M_Drawer(); // menu is drawn even on top of wipes
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "d_netfil.h"
|
||||
#include "m_misc.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h" // Addons_option_Onchange
|
||||
#include "k_menu.h" // Addons_option_Onchange
|
||||
|
||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||
|
||||
|
|
@ -561,15 +561,15 @@ char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) pl
|
|||
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||
|
||||
|
||||
static boolean filemenucmp(char *haystack, char *needle)
|
||||
static boolean filemenucmp(char *haystack)
|
||||
{
|
||||
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]));
|
||||
return (strstr(localhaystack, menusearch+1) != 0);
|
||||
return (!strncmp(localhaystack, menusearch+1, menusearch[0]));
|
||||
}
|
||||
|
||||
void closefilemenu(boolean validsize)
|
||||
|
|
@ -616,7 +616,6 @@ void closefilemenu(boolean validsize)
|
|||
void searchfilemenu(char *tempname)
|
||||
{
|
||||
size_t i, first;
|
||||
char localmenusearch[MAXSTRINGLENGTH] = "";
|
||||
|
||||
if (dirmenu)
|
||||
{
|
||||
|
|
@ -662,14 +661,10 @@ void searchfilemenu(char *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))
|
||||
if (filemenucmp(coredirmenu[i]+DIR_STRING))
|
||||
sizedirmenu++;
|
||||
}
|
||||
|
||||
|
|
@ -691,7 +686,7 @@ void searchfilemenu(char *tempname)
|
|||
sizedirmenu = 0;
|
||||
for (i = first; i < sizecoredirmenu; i++)
|
||||
{
|
||||
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||
if (filemenucmp(coredirmenu[i]+DIR_STRING))
|
||||
{
|
||||
if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname))
|
||||
{
|
||||
|
|
@ -724,7 +719,10 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
|||
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
|
||||
CV_StealthSet(&cv_dummyaddonsearch, "");
|
||||
}
|
||||
|
||||
if (!(dirhandle = opendir(menupath))) // get directory
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "d_netfil.h"
|
||||
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||
#include "k_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;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "g_game.h"
|
||||
#include "g_demo.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_argv.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "z_zone.h"
|
||||
|
|
@ -3888,7 +3888,7 @@ boolean G_DemoTitleResponder(event_t *ev)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (ch == KEY_ENTER || ch >= KEY_MOUSE1)
|
||||
if (ch == KEY_ENTER || ch >= NUMKEYS)
|
||||
{
|
||||
demo.savemode = DSM_WILLSAVE;
|
||||
return true;
|
||||
|
|
|
|||
581
src/g_game.c
581
src/g_game.c
|
|
@ -33,7 +33,7 @@
|
|||
#include "g_demo.h"
|
||||
#include "m_cheat.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_argv.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "st_stuff.h"
|
||||
|
|
@ -75,8 +75,8 @@ JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
|
|||
#define SAVEGAMESIZE (1024)
|
||||
|
||||
// SRB2kart
|
||||
char gamedatafilename[64] = "kartdata.dat";
|
||||
char timeattackfolder[64] = "kart";
|
||||
char gamedatafilename[64] = "ringdata.dat";
|
||||
char timeattackfolder[64] = "ringracers";
|
||||
char customversionstring[32] = "\0";
|
||||
|
||||
static void G_DoCompleted(void);
|
||||
|
|
@ -160,7 +160,6 @@ INT16 bootmap; //bootmap for loading a map on startup
|
|||
|
||||
INT16 tutorialmap = 0; // map to load for tutorial
|
||||
boolean tutorialmode = false; // are we in a tutorial right now?
|
||||
INT32 tutorialgcs = gcs_custom; // which control scheme is loaded?
|
||||
|
||||
boolean looptitle = true;
|
||||
|
||||
|
|
@ -353,22 +352,6 @@ static void weaponPrefChange2(void);
|
|||
static void weaponPrefChange3(void);
|
||||
static void weaponPrefChange4(void);
|
||||
|
||||
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
||||
{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"},
|
||||
#if JOYAXISSET > 1
|
||||
{3, "Z-Axis"}, {4, "X-Rudder"}, {-3, "Z-Axis-"}, {-4, "X-Rudder-"},
|
||||
#endif
|
||||
#if JOYAXISSET > 2
|
||||
{5, "Y-Rudder"}, {6, "Z-Rudder"}, {-5, "Y-Rudder-"}, {-6, "Z-Rudder-"},
|
||||
#endif
|
||||
#if JOYAXISSET > 3
|
||||
{7, "U-Axis"}, {8, "V-Axis"}, {-7, "U-Axis-"}, {-8, "V-Axis-"},
|
||||
#endif
|
||||
{0, NULL}};
|
||||
#if JOYAXISSET > 4
|
||||
"More Axis Sets"
|
||||
#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.
|
||||
|
||||
// chat timer thingy
|
||||
|
|
@ -425,68 +408,12 @@ consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS] = {
|
|||
CVAR_INIT ("shrinkme4", "Off", CV_CALL, CV_OnOff, weaponPrefChange4)
|
||||
};
|
||||
|
||||
consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis3_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis4_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis_move2", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis_move3", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis_move4", "None", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_brake", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis2_brake", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis3_brake", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis4_brake", "None", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_aimaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis2_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis3_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis4_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_lookaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_look", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis3_look", "None", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis4_look", "None", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_fireaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_fire", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis_fire2", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis_fire3", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis_fire4", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_driftaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis2_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis3_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis4_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL)
|
||||
};
|
||||
|
||||
static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("joy2_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("joy3_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("joy4_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL)
|
||||
};
|
||||
|
||||
consvar_t cv_digitaldeadzone[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("joy2_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("joy3_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("joy4_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL)
|
||||
CVAR_INIT ("deadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("deadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("deadzone3", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
|
||||
CVAR_INIT ("deadzone4", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL)
|
||||
};
|
||||
|
||||
// now automatically allocated in D_RegisterClientCommands
|
||||
|
|
@ -672,9 +599,10 @@ const char *G_BuildMapName(INT32 map)
|
|||
{
|
||||
static char mapname[10] = "MAPXX"; // internal map name (wad resource name)
|
||||
|
||||
I_Assert(map >= 0);
|
||||
I_Assert(map > 0);
|
||||
I_Assert(map <= NUMMAPS);
|
||||
|
||||
#if 0
|
||||
if (map == 0) // hack???
|
||||
{
|
||||
if (gamestate == GS_TITLESCREEN)
|
||||
|
|
@ -685,6 +613,7 @@ const char *G_BuildMapName(INT32 map)
|
|||
map = prevmap;
|
||||
map = G_RandMap(G_TOLFlag(cv_newgametype.value), map, 0, 0, false, NULL)+1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (map < 100)
|
||||
sprintf(&mapname[3], "%.2d", map);
|
||||
|
|
@ -736,74 +665,161 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
|
|||
return (INT16)((*aiming)>>16);
|
||||
}
|
||||
|
||||
INT32 PlayerJoyAxis(UINT8 player, axis_input_e axissel)
|
||||
// Default controls for keyboard. These are hardcoded and cannot be changed.
|
||||
static INT32 keyboardMenuDefaults[][2] = {
|
||||
{gc_a, KEY_ENTER},
|
||||
{gc_c, KEY_BACKSPACE},
|
||||
{gc_x, KEY_ESCAPE},
|
||||
{gc_left, KEY_LEFTARROW},
|
||||
{gc_right, KEY_RIGHTARROW},
|
||||
{gc_up, KEY_UPARROW},
|
||||
{gc_down, KEY_DOWNARROW},
|
||||
|
||||
// special control
|
||||
{gc_start, KEY_ESCAPE},
|
||||
// 8 total controls*
|
||||
};
|
||||
|
||||
#define KEYBOARDDEFAULTSSPLIT 7
|
||||
|
||||
|
||||
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
||||
{
|
||||
INT32 retaxis;
|
||||
INT32 axisval;
|
||||
boolean flp = false;
|
||||
INT32 deviceID;
|
||||
INT32 i, j;
|
||||
INT32 deadzone = 0;
|
||||
boolean trydefaults = true;
|
||||
boolean tryingotherID = false;
|
||||
INT32 *controltable = &(gamecontrol[p][gc][0]);
|
||||
|
||||
//find what axis to get
|
||||
switch (axissel)
|
||||
if (p >= MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
case AXISTURN:
|
||||
axisval = cv_turnaxis[player-1].value;
|
||||
break;
|
||||
case AXISMOVE:
|
||||
axisval = cv_moveaxis[player-1].value;
|
||||
break;
|
||||
case AXISBRAKE:
|
||||
axisval = cv_brakeaxis[player-1].value;
|
||||
break;
|
||||
case AXISAIM:
|
||||
axisval = cv_aimaxis[player-1].value;
|
||||
break;
|
||||
case AXISLOOK:
|
||||
axisval = cv_lookaxis[player-1].value;
|
||||
break;
|
||||
case AXISFIRE:
|
||||
axisval = cv_fireaxis[player-1].value;
|
||||
break;
|
||||
case AXISDRIFT:
|
||||
axisval = cv_driftaxis[player-1].value;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (axisval < 0) //odd -axises
|
||||
{
|
||||
axisval = -axisval;
|
||||
flp = true;
|
||||
}
|
||||
if (axisval > JOYAXISSET*2 || axisval == 0) //not there in array or None
|
||||
#ifdef PARANOIA
|
||||
CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
if (axisval%2)
|
||||
{
|
||||
axisval /= 2;
|
||||
retaxis = joyxmove[player-1][axisval];
|
||||
}
|
||||
else
|
||||
{
|
||||
axisval--;
|
||||
axisval /= 2;
|
||||
retaxis = joyymove[player-1][axisval];
|
||||
}
|
||||
|
||||
if (retaxis < (-JOYAXISRANGE))
|
||||
retaxis = -JOYAXISRANGE;
|
||||
if (retaxis > (+JOYAXISRANGE))
|
||||
retaxis = +JOYAXISRANGE;
|
||||
deadzone = (JOYAXISRANGE * cv_deadzone[p].value) / FRACUNIT;
|
||||
|
||||
if (!Joystick[player-1].bGamepadStyle && axissel >= AXISDIGITAL)
|
||||
deviceID = cv_usejoystick[p].value;
|
||||
|
||||
retrygetcontrol:
|
||||
for (i = 0; i < MAXINPUTMAPPING; i++)
|
||||
{
|
||||
const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone[player-1].value) >> FRACBITS;
|
||||
if (-jdeadzone < retaxis && retaxis < jdeadzone)
|
||||
return 0;
|
||||
INT32 key = controltable[i];
|
||||
INT32 menukey = KEY_NULL;
|
||||
INT32 value = 0;
|
||||
boolean processinput = true;
|
||||
|
||||
|
||||
// for menus, keyboards have defaults!
|
||||
if (deviceID == 0)
|
||||
{
|
||||
|
||||
// In menus, check indexes 0 through 5 (everything besides gc_start)
|
||||
// Outside of menus, only consider the hardcoded input for gc_start at index 6
|
||||
|
||||
INT32 maxj = menuactive ? KEYBOARDDEFAULTSSPLIT : KEYBOARDDEFAULTSSPLIT+1;
|
||||
j = (!menuactive) ? KEYBOARDDEFAULTSSPLIT : 0;
|
||||
|
||||
for (; j < maxj; j++) // check keyboardMenuDefaults
|
||||
{
|
||||
// the gc we're looking for
|
||||
if (gc == keyboardMenuDefaults[j][0])
|
||||
{
|
||||
menukey = keyboardMenuDefaults[j][1];
|
||||
break;
|
||||
}
|
||||
|
||||
// The key is mapped to *something else*...?
|
||||
// Then don't process that as it would conflict with our hardcoded inputs.
|
||||
else if (key == keyboardMenuDefaults[j][1])
|
||||
{
|
||||
processinput = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid key number.
|
||||
if (!G_KeyIsAvailable(key, deviceID) && !G_KeyIsAvailable(menukey, deviceID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (processinput)
|
||||
{
|
||||
// It's possible to access this control right now, so let's disable the default control backup for later.
|
||||
trydefaults = false;
|
||||
|
||||
value = gamekeydown[deviceID][key];
|
||||
if (menukey && gamekeydown[deviceID][menukey])
|
||||
value = gamekeydown[deviceID][menukey];
|
||||
|
||||
if (value >= deadzone)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
// If you're on controller, try your keyboard-based binds as an immediate backup.
|
||||
// Do not do this if there are more than 1 local player.
|
||||
if (p == 0 && deviceID > 0 && !tryingotherID && menuPlayers < 2 && !splitscreen)
|
||||
{
|
||||
deviceID = 0;
|
||||
goto retrygetcontrol;
|
||||
}
|
||||
|
||||
if (menuPlayers == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We don't want menus to become unnavigable if people unbind
|
||||
// all of their controls, so we do several things in this scenario.
|
||||
// First: try other controllers.
|
||||
|
||||
if (!tryingotherID)
|
||||
{
|
||||
deviceID = MAXDEVICES;
|
||||
tryingotherID = true;
|
||||
}
|
||||
loweringid:
|
||||
deviceID--;
|
||||
if (deviceID > 0)
|
||||
{
|
||||
for (i = 0; i < menuPlayers; i++)
|
||||
{
|
||||
if (deviceID != cv_usejoystick[i].value)
|
||||
continue;
|
||||
// Controller taken? Try again...
|
||||
goto loweringid;
|
||||
}
|
||||
goto retrygetcontrol;
|
||||
}
|
||||
|
||||
if (trydefaults && G_KeyBindIsNecessary(gc))
|
||||
{
|
||||
// If we still haven't found anything and the keybind is necessary,
|
||||
// try it all again but with default binds.
|
||||
trydefaults = false;
|
||||
controltable = &(gamecontroldefault[gc][0]);
|
||||
tryingotherID = false;
|
||||
deviceID = cv_usejoystick[p].value;
|
||||
goto retrygetcontrol;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef KEYBOARDDEFAULTSSPLIT
|
||||
|
||||
boolean G_PlayerInputDown(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
||||
{
|
||||
return (G_PlayerInputAnalog(p, gc, menuPlayers) != 0);
|
||||
}
|
||||
|
||||
// Take a magnitude of two axes, and adjust it to take out the deadzone
|
||||
|
|
@ -950,27 +966,15 @@ static void G_DoAnglePrediction(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer, p
|
|||
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
{
|
||||
const UINT8 forplayer = ssplayer-1;
|
||||
|
||||
const INT32 lookaxis = cv_lookaxis[forplayer].value;
|
||||
const boolean invertmouse = cv_invertmouse.value;
|
||||
const boolean analogjoystickmove = cv_usejoystick[forplayer].value && !Joystick[forplayer].bGamepadStyle;
|
||||
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && Joystick[forplayer].bGamepadStyle;
|
||||
const boolean usejoystick = (analogjoystickmove || gamepadjoystickmove);
|
||||
|
||||
static boolean keyboard_look[MAXSPLITSCREENPLAYERS]; // true if lookup/down using keyboard
|
||||
static boolean resetdown[MAXSPLITSCREENPLAYERS]; // don't cam reset every frame
|
||||
|
||||
INT32 forward, axis;
|
||||
INT32 forward;
|
||||
|
||||
joystickvector2_t joystickvector;
|
||||
|
||||
boolean turnleft, turnright;
|
||||
|
||||
player_t *player = &players[g_localplayers[forplayer]];
|
||||
camera_t *thiscam = &camera[forplayer];
|
||||
boolean *kbl = &keyboard_look[forplayer];
|
||||
boolean *rd = &resetdown[forplayer];
|
||||
const boolean mouseaiming = player->spectator;
|
||||
//camera_t *thiscam = &camera[forplayer];
|
||||
//boolean *kbl = &keyboard_look[forplayer];
|
||||
//boolean *rd = &resetdown[forplayer];
|
||||
//const boolean mouseaiming = player->spectator;
|
||||
|
||||
if (demo.playback) return;
|
||||
|
||||
|
|
@ -999,16 +1003,27 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
return;
|
||||
}
|
||||
|
||||
cmd->flags = 0;
|
||||
|
||||
if (menuactive || chat_on || CON_Ready())
|
||||
{
|
||||
cmd->flags |= TICCMD_TYPING;
|
||||
|
||||
if (hu_keystrokes)
|
||||
{
|
||||
cmd->flags |= TICCMD_KEYSTROKE;
|
||||
}
|
||||
|
||||
goto aftercmdinput;
|
||||
}
|
||||
|
||||
if (K_PlayerUsesBotMovement(player))
|
||||
{
|
||||
// Bot ticcmd is generated by K_BuildBotTiccmd
|
||||
return;
|
||||
}
|
||||
|
||||
turnright = PlayerInputDown(ssplayer, gc_turnright);
|
||||
turnleft = PlayerInputDown(ssplayer, gc_turnleft);
|
||||
|
||||
joystickvector.xaxis = PlayerJoyAxis(ssplayer, AXISTURN);
|
||||
joystickvector.xaxis = G_PlayerInputAnalog(forplayer, gc_right, 0) - G_PlayerInputAnalog(forplayer, gc_left, 0);
|
||||
joystickvector.yaxis = 0;
|
||||
G_HandleAxisDeadZone(forplayer, &joystickvector);
|
||||
|
||||
|
|
@ -1016,143 +1031,99 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
// use it for aiming to throw items forward/backward and the vote screen
|
||||
// This mean that the turn axis will still be gradient but up/down will be 0
|
||||
// until the stick is pushed far enough
|
||||
joystickvector.yaxis = PlayerJoyAxis(ssplayer, AXISAIM);
|
||||
joystickvector.yaxis = G_PlayerInputAnalog(forplayer, gc_down, 0) - G_PlayerInputAnalog(forplayer, gc_up, 0);
|
||||
|
||||
if (encoremode)
|
||||
{
|
||||
turnright ^= turnleft; // swap these using three XORs
|
||||
turnleft ^= turnright;
|
||||
turnright ^= turnleft;
|
||||
joystickvector.xaxis = -joystickvector.xaxis;
|
||||
}
|
||||
|
||||
if (gamepadjoystickmove && joystickvector.xaxis != 0)
|
||||
{
|
||||
turnright = turnright || (joystickvector.xaxis > 0);
|
||||
turnleft = turnleft || (joystickvector.xaxis < 0);
|
||||
}
|
||||
forward = 0;
|
||||
|
||||
cmd->turning = 0;
|
||||
|
||||
// let movement keys cancel each other out
|
||||
if (turnright && !(turnleft))
|
||||
{
|
||||
cmd->turning -= KART_FULLTURN;
|
||||
}
|
||||
else if (turnleft && !(turnright))
|
||||
{
|
||||
cmd->turning += KART_FULLTURN;
|
||||
}
|
||||
|
||||
if (analogjoystickmove && joystickvector.xaxis != 0)
|
||||
if (joystickvector.xaxis != 0)
|
||||
{
|
||||
cmd->turning -= (joystickvector.xaxis * KART_FULLTURN) >> 10;
|
||||
}
|
||||
|
||||
// Specator mouse turning
|
||||
if (player->spectator)
|
||||
{
|
||||
cmd->turning -= (mousex * 8) * (encoremode ? -1 : 1);
|
||||
}
|
||||
|
||||
if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls
|
||||
{
|
||||
axis = PlayerJoyAxis(ssplayer, AXISMOVE);
|
||||
if (PlayerInputDown(ssplayer, gc_accelerate) || (usejoystick && axis > 0))
|
||||
if (G_PlayerInputDown(forplayer, gc_accel, 0))
|
||||
{
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
axis = PlayerJoyAxis(ssplayer, AXISBRAKE);
|
||||
if (PlayerInputDown(ssplayer, gc_brake) || (usejoystick && axis > 0))
|
||||
}
|
||||
|
||||
if (G_PlayerInputDown(forplayer, gc_brake, 0))
|
||||
{
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
axis = PlayerJoyAxis(ssplayer, AXISAIM);
|
||||
if (PlayerInputDown(ssplayer, gc_aimforward) || (usejoystick && axis < 0))
|
||||
}
|
||||
|
||||
if (joystickvector.yaxis < 0)
|
||||
{
|
||||
forward += MAXPLMOVE;
|
||||
if (PlayerInputDown(ssplayer, gc_aimbackward) || (usejoystick && axis > 0))
|
||||
}
|
||||
|
||||
if (joystickvector.yaxis > 0)
|
||||
{
|
||||
forward -= MAXPLMOVE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward with key or button // SRB2kart - we use an accel/brake instead of forward/backward.
|
||||
axis = PlayerJoyAxis(ssplayer, AXISMOVE);
|
||||
if (PlayerInputDown(ssplayer, gc_accelerate) || (gamepadjoystickmove && axis > 0))
|
||||
INT32 value = G_PlayerInputAnalog(forplayer, gc_accel, 0);
|
||||
if (value != 0)
|
||||
{
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
forward = MAXPLMOVE; // 50
|
||||
}
|
||||
else if (analogjoystickmove && axis > 0)
|
||||
{
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
forward += ((axis * MAXPLMOVE) >> 10);
|
||||
forward += ((value * MAXPLMOVE) >> 10);
|
||||
}
|
||||
|
||||
axis = PlayerJoyAxis(ssplayer, AXISBRAKE);
|
||||
if (PlayerInputDown(ssplayer, gc_brake) || (gamepadjoystickmove && axis > 0))
|
||||
value = G_PlayerInputAnalog(forplayer, gc_brake, 0);
|
||||
if (value != 0)
|
||||
{
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
if (cmd->buttons & BT_ACCELERATE || cmd->forwardmove <= 0)
|
||||
forward -= MAXPLMOVE;
|
||||
}
|
||||
else if (analogjoystickmove && axis > 0)
|
||||
{
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
if (cmd->buttons & BT_ACCELERATE || cmd->forwardmove <= 0)
|
||||
forward -= ((axis * MAXPLMOVE) >> 10);
|
||||
forward -= ((value * MAXPLMOVE) >> 10);
|
||||
}
|
||||
|
||||
// But forward/backward IS used for aiming.
|
||||
if (PlayerInputDown(ssplayer, gc_aimforward))
|
||||
cmd->throwdir += KART_FULLTURN;
|
||||
if (PlayerInputDown(ssplayer, gc_aimbackward))
|
||||
cmd->throwdir -= KART_FULLTURN;
|
||||
|
||||
if (analogjoystickmove && joystickvector.yaxis != 0)
|
||||
if (joystickvector.yaxis != 0)
|
||||
{
|
||||
cmd->throwdir -= (joystickvector.yaxis * KART_FULLTURN) >> 10;
|
||||
}
|
||||
}
|
||||
|
||||
// fire with any button/key
|
||||
axis = PlayerJoyAxis(ssplayer, AXISFIRE);
|
||||
if (PlayerInputDown(ssplayer, gc_fire) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
|
||||
// drift with any button/key
|
||||
axis = PlayerJoyAxis(ssplayer, AXISDRIFT);
|
||||
if (PlayerInputDown(ssplayer, gc_drift) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_DRIFT;
|
||||
|
||||
// Spindash with any button/key
|
||||
// Simply holds all of the inputs for you.
|
||||
axis = PlayerJoyAxis(ssplayer, AXISSPINDASH);
|
||||
if (PlayerInputDown(ssplayer, gc_spindash) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= (BT_ACCELERATE|BT_BRAKE|BT_DRIFT);
|
||||
|
||||
// rear view with any button/key
|
||||
axis = PlayerJoyAxis(ssplayer, AXISLOOKBACK);
|
||||
if (PlayerInputDown(ssplayer, gc_lookback) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
|
||||
// Lua scriptable buttons
|
||||
if (PlayerInputDown(ssplayer, gc_custom1))
|
||||
cmd->buttons |= BT_CUSTOM1;
|
||||
if (PlayerInputDown(ssplayer, gc_custom2))
|
||||
cmd->buttons |= BT_CUSTOM2;
|
||||
if (PlayerInputDown(ssplayer, gc_custom3))
|
||||
cmd->buttons |= BT_CUSTOM3;
|
||||
|
||||
// Reset camera
|
||||
if (PlayerInputDown(ssplayer, gc_camreset))
|
||||
// drift
|
||||
if (G_PlayerInputDown(forplayer, gc_drift, 0))
|
||||
{
|
||||
if (thiscam->chase && *rd == false)
|
||||
P_ResetCamera(player, thiscam);
|
||||
*rd = true;
|
||||
cmd->buttons |= BT_DRIFT;
|
||||
}
|
||||
else
|
||||
*rd = false;
|
||||
|
||||
// C
|
||||
if (G_PlayerInputDown(forplayer, gc_spindash, 0))
|
||||
{
|
||||
forward = 0;
|
||||
cmd->buttons |= BT_SPINDASHMASK;
|
||||
}
|
||||
|
||||
// fire
|
||||
if (G_PlayerInputDown(forplayer, gc_item, 0))
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
}
|
||||
|
||||
// rear view
|
||||
if (G_PlayerInputDown(forplayer, gc_lookback, 0))
|
||||
{
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
// lua buttons a thru c
|
||||
if (G_PlayerInputDown(forplayer, gc_luaa, 0)) { cmd->buttons |= BT_LUAA; }
|
||||
if (G_PlayerInputDown(forplayer, gc_luab, 0)) { cmd->buttons |= BT_LUAB; }
|
||||
if (G_PlayerInputDown(forplayer, gc_luac, 0)) { cmd->buttons |= BT_LUAC; }
|
||||
|
||||
// spectator aiming shit, ahhhh...
|
||||
/*
|
||||
{
|
||||
INT32 player_invert = invertmouse ? -1 : 1;
|
||||
INT32 screen_invert =
|
||||
|
|
@ -1160,15 +1131,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
&& (!thiscam->chase)) //because chasecam's not inverted
|
||||
? -1 : 1; // set to -1 or 1 to multiply
|
||||
|
||||
// mouse look stuff (mouse look is not the same as mouse aim)
|
||||
if (mouseaiming && player->spectator)
|
||||
{
|
||||
*kbl = false;
|
||||
|
||||
// looking up/down
|
||||
cmd->aiming += (mlooky<<19)*player_invert*screen_invert;
|
||||
}
|
||||
|
||||
axis = PlayerJoyAxis(ssplayer, AXISLOOK);
|
||||
if (analogjoystickmove && axis != 0 && lookaxis && player->spectator)
|
||||
cmd->aiming += (axis<<16) * screen_invert;
|
||||
|
|
@ -1194,22 +1156,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
if (PlayerInputDown(ssplayer, gc_centerview)) // No need to put a spectator limit on this one though :V
|
||||
cmd->aiming = 0;
|
||||
}
|
||||
|
||||
mousex = mousey = mlooky = 0;
|
||||
*/
|
||||
|
||||
cmd->forwardmove += (SINT8)forward;
|
||||
|
||||
cmd->flags = 0;
|
||||
|
||||
if (chat_on || CON_Ready())
|
||||
{
|
||||
cmd->flags |= TICCMD_TYPING;
|
||||
|
||||
if (hu_keystrokes)
|
||||
{
|
||||
cmd->flags |= TICCMD_KEYSTROKE;
|
||||
}
|
||||
}
|
||||
aftercmdinput:
|
||||
|
||||
/* Lua: Allow this hook to overwrite ticcmd.
|
||||
We check if we're actually in a level because for some reason this Hook would run in menus and on the titlescreen otherwise.
|
||||
|
|
@ -1304,7 +1255,7 @@ static void weaponPrefChange4(void)
|
|||
//
|
||||
void G_DoLoadLevel(boolean resetplayer)
|
||||
{
|
||||
INT32 i, j;
|
||||
INT32 i;
|
||||
|
||||
// Make sure objectplace is OFF when you first start the level!
|
||||
OP_ResetObjectplace();
|
||||
|
|
@ -1314,6 +1265,8 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
if (wipegamestate == GS_LEVEL)
|
||||
wipegamestate = -1; // force a wipe
|
||||
|
||||
if (cv_currprofile.value == -1)
|
||||
PR_ApplyProfilePretend(cv_ttlprofilen.value, 0);
|
||||
if (gamestate == GS_INTERMISSION)
|
||||
Y_EndIntermission();
|
||||
if (gamestate == GS_VOTING)
|
||||
|
|
@ -1335,6 +1288,8 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
titlemapinaction = TITLEMAP_OFF;
|
||||
|
||||
G_SetGamestate(GS_LEVEL);
|
||||
if (wipegamestate == GS_MENU)
|
||||
M_ClearMenus(true);
|
||||
I_UpdateMouseGrab();
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -1364,12 +1319,7 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
|
||||
// clear cmd building stuff
|
||||
memset(gamekeydown, 0, sizeof (gamekeydown));
|
||||
for (i = 0;i < JOYAXISSET; i++)
|
||||
{
|
||||
for (j = 0; j < MAXSPLITSCREENPLAYERS; j++)
|
||||
joyxmove[j][i] = joyymove[j][i] = 0;
|
||||
}
|
||||
mousex = mousey = 0;
|
||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
||||
|
||||
// clear hud messages remains (usually from game startup)
|
||||
CON_ClearHUD();
|
||||
|
|
@ -1468,7 +1418,7 @@ static INT32 camtoggledelay[MAXSPLITSCREENPLAYERS];
|
|||
//
|
||||
boolean G_Responder(event_t *ev)
|
||||
{
|
||||
UINT8 i;
|
||||
//INT32 i;
|
||||
|
||||
// any other key pops up menu if in demos
|
||||
if (gameaction == ga_nothing && !demo.quitafterplaying &&
|
||||
|
|
@ -1563,7 +1513,7 @@ boolean G_Responder(event_t *ev)
|
|||
|
||||
// allow spy mode changes even during the demo
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[0][gc_viewpoint][0] || ev->data1 == gamecontrol[0][gc_viewpoint][1]))
|
||||
&& (ev->data1 == KEY_F12 /*|| ev->data1 == gamecontrol[0][gc_viewpoint][0] || ev->data1 == gamecontrol[0][gc_viewpoint][1]*/))
|
||||
{
|
||||
if (!demo.playback && (r_splitscreen || !netgame))
|
||||
g_localplayers[0] = consoleplayer;
|
||||
|
|
@ -1581,6 +1531,7 @@ boolean G_Responder(event_t *ev)
|
|||
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam)
|
||||
{
|
||||
/*
|
||||
if (ev->data1 == gamecontrol[1][gc_viewpoint][0] || ev->data1 == gamecontrol[1][gc_viewpoint][1])
|
||||
{
|
||||
G_AdjustView(2, 1, true);
|
||||
|
|
@ -1596,12 +1547,13 @@ boolean G_Responder(event_t *ev)
|
|||
G_AdjustView(4, 1, true);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// Allow pausing
|
||||
if (
|
||||
ev->data1 == gamecontrol[0][gc_pause][0]
|
||||
|| ev->data1 == gamecontrol[0][gc_pause][1]
|
||||
|| ev->data1 == KEY_PAUSE
|
||||
//ev->data1 == gamecontrol[0][gc_pause][0]
|
||||
//|| ev->data1 == gamecontrol[0][gc_pause][1]
|
||||
ev->data1 == KEY_PAUSE
|
||||
)
|
||||
{
|
||||
paused = !paused;
|
||||
|
|
@ -1635,9 +1587,9 @@ boolean G_Responder(event_t *ev)
|
|||
switch (ev->type)
|
||||
{
|
||||
case ev_keydown:
|
||||
if (ev->data1 == gamecontrol[0][gc_pause][0]
|
||||
|| ev->data1 == gamecontrol[0][gc_pause][1]
|
||||
|| ev->data1 == KEY_PAUSE)
|
||||
if (//ev->data1 == gamecontrol[0][gc_pause][0]
|
||||
//|| ev->data1 == gamecontrol[0][gc_pause][1]
|
||||
ev->data1 == KEY_PAUSE)
|
||||
{
|
||||
if (modeattacking && !demo.playback && (gamestate == GS_LEVEL))
|
||||
{
|
||||
|
|
@ -1667,6 +1619,7 @@ boolean G_Responder(event_t *ev)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (ev->data1 == gamecontrol[i][gc_camtoggle][0]
|
||||
|
|
@ -1679,6 +1632,7 @@ boolean G_Responder(event_t *ev)
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
|
||||
|
|
@ -1691,15 +1645,6 @@ boolean G_Responder(event_t *ev)
|
|||
case ev_joystick:
|
||||
return true; // eat events
|
||||
|
||||
case ev_joystick2:
|
||||
return true; // eat events
|
||||
|
||||
case ev_joystick3:
|
||||
return true; // eat events
|
||||
|
||||
case ev_joystick4:
|
||||
return true; // eat events
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2044,8 +1989,7 @@ void G_Ticker(boolean run)
|
|||
HU_Ticker();
|
||||
break;
|
||||
|
||||
case GS_TIMEATTACK:
|
||||
F_MenuPresTicker(run);
|
||||
case GS_MENU:
|
||||
break;
|
||||
|
||||
case GS_INTRO:
|
||||
|
|
@ -3323,12 +3267,11 @@ INT16 G_SometimesGetDifferentGametype(void)
|
|||
// G_GetGametypeColor
|
||||
//
|
||||
// Pretty and consistent ^u^
|
||||
// See also M_GetGametypeColor.
|
||||
// See also M_GetGametypeColor (if that still exists).
|
||||
//
|
||||
UINT8 G_GetGametypeColor(INT16 gt)
|
||||
{
|
||||
if (modeattacking // == ATTACKING_TIME
|
||||
|| gamestate == GS_TIMEATTACK)
|
||||
if (modeattacking) // == ATTACKING_RECORD
|
||||
return orangemap[0];
|
||||
|
||||
if (gt == GT_BATTLE)
|
||||
|
|
@ -3802,8 +3745,6 @@ demointermission:
|
|||
// See also F_EndCutscene, the only other place which handles intra-map/ending transitions
|
||||
void G_AfterIntermission(void)
|
||||
{
|
||||
Y_CleanupScreenBuffer();
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
M_EndModeAttackRun();
|
||||
|
|
@ -3820,9 +3761,11 @@ void G_AfterIntermission(void)
|
|||
{
|
||||
G_StopDemo();
|
||||
|
||||
#if 0
|
||||
if (demo.inreplayhut)
|
||||
M_ReplayHut(0);
|
||||
else
|
||||
#endif
|
||||
D_StartTitle();
|
||||
|
||||
return;
|
||||
|
|
@ -4044,9 +3987,6 @@ void G_LoadGameData(void)
|
|||
totalplaytime = 0; // total play time (separate from all)
|
||||
matchesplayed = 0; // SRB2Kart: matches played & finished
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++) // SRB2Kart: online rank system
|
||||
vspowerlevel[i] = PWRLVRECORD_START;
|
||||
|
||||
if (M_CheckParm("-nodata"))
|
||||
return; // Don't load.
|
||||
|
||||
|
|
@ -4076,19 +4016,12 @@ void G_LoadGameData(void)
|
|||
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
|
||||
I_Error("Game data is from another version of SRB2.\nDelete %s (maybe in %s) and try again.", gamedatafilename, gdfolder);
|
||||
}
|
||||
|
||||
totalplaytime = READUINT32(save_p);
|
||||
matchesplayed = READUINT32(save_p);
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
{
|
||||
vspowerlevel[i] = READUINT16(save_p);
|
||||
if (vspowerlevel[i] < PWRLVRECORD_MIN || vspowerlevel[i] > PWRLVRECORD_MAX)
|
||||
goto datacorrupt;
|
||||
}
|
||||
|
||||
modded = READUINT8(save_p);
|
||||
|
||||
// Aha! Someone's been screwing with the save file!
|
||||
|
|
@ -4205,9 +4138,6 @@ void G_SaveGameData(void)
|
|||
WRITEUINT32(save_p, totalplaytime);
|
||||
WRITEUINT32(save_p, matchesplayed);
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
WRITEUINT16(save_p, vspowerlevel[i]);
|
||||
|
||||
WRITEUINT8(save_p, (UINT8)savemoddata);
|
||||
|
||||
// TODO put another cipher on these things? meh, I don't care...
|
||||
|
|
@ -4271,6 +4201,9 @@ void G_SaveGameData(void)
|
|||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
||||
// Also save profiles here.
|
||||
PR_SaveProfiles();
|
||||
}
|
||||
|
||||
#define VERSIONSIZE 16
|
||||
|
|
@ -4589,8 +4522,6 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
|||
|
||||
(void)FLS;
|
||||
|
||||
Y_CleanupScreenBuffer();
|
||||
|
||||
if (paused)
|
||||
{
|
||||
paused = false;
|
||||
|
|
|
|||
24
src/g_game.h
24
src/g_game.h
|
|
@ -65,7 +65,6 @@ extern consvar_t cv_lookaxis[MAXSPLITSCREENPLAYERS];
|
|||
extern consvar_t cv_fireaxis[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_driftaxis[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_digitaldeadzone[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
|
||||
|
||||
|
|
@ -96,26 +95,6 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
|
|||
INT32 G_ClipAimingPitch(INT32 *aiming);
|
||||
INT16 G_SoftwareClipAimingPitch(INT32 *aiming);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AXISNONE = 0,
|
||||
|
||||
AXISTURN,
|
||||
AXISMOVE,
|
||||
AXISBRAKE,
|
||||
AXISLOOK,
|
||||
|
||||
AXISDIGITAL, // axes below this use digital deadzone
|
||||
|
||||
AXISFIRE = AXISDIGITAL,
|
||||
AXISDRIFT,
|
||||
AXISSPINDASH,
|
||||
AXISLOOKBACK,
|
||||
AXISAIM,
|
||||
} axis_input_e;
|
||||
|
||||
INT32 PlayerJoyAxis(UINT8 player, axis_input_e axissel);
|
||||
|
||||
extern angle_t localangle[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
|
||||
extern INT32 localsteering[MAXSPLITSCREENPLAYERS];
|
||||
|
|
@ -123,6 +102,9 @@ extern INT32 localdelta[MAXSPLITSCREENPLAYERS];
|
|||
extern INT32 localstoredeltas[MAXSPLITSCREENPLAYERS][TICCMD_LATENCYMASK + 1];
|
||||
extern UINT8 localtic;
|
||||
|
||||
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers);
|
||||
boolean G_PlayerInputDown(UINT8 p, INT32 gc, UINT8 menuPlayers);
|
||||
|
||||
//
|
||||
// GAME
|
||||
//
|
||||
|
|
|
|||
1279
src/g_input.c
1279
src/g_input.c
File diff suppressed because it is too large
Load diff
155
src/g_input.h
155
src/g_input.h
|
|
@ -23,110 +23,93 @@
|
|||
#define NUMKEYS 256
|
||||
|
||||
#define MOUSEBUTTONS 8
|
||||
#define JOYBUTTONS 32 // 32 buttons
|
||||
#define JOYHATS 4 // 4 hats
|
||||
#define JOYAXISSET 4 // 4 Sets of 2 axises
|
||||
|
||||
#define JOYBUTTONS 21 // 21 buttons, to match SDL_GameControllerButton
|
||||
#define JOYANALOGS 2 // 2 sets of analog stick axes, with positive and negative each
|
||||
#define JOYTRIGGERS 1 // 1 set of trigger axes, positive only
|
||||
#define JOYAXISSETS (JOYANALOGS + JOYTRIGGERS)
|
||||
#define JOYAXES ((4 * JOYANALOGS) + (2 * JOYTRIGGERS))
|
||||
|
||||
#define MAXINPUTMAPPING 4
|
||||
|
||||
//
|
||||
// mouse and joystick buttons are handled as 'virtual' keys
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
KEY_MOUSE1 = NUMKEYS,
|
||||
KEY_JOY1 = KEY_MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_HAT1 = KEY_JOY1 + JOYBUTTONS,
|
||||
KEY_JOY1 = NUMKEYS,
|
||||
KEY_HAT1 = KEY_JOY1 + 11, // macro for SDL_CONTROLLER_BUTTON_DPAD_UP
|
||||
KEY_AXIS1 = KEY_JOY1 + JOYBUTTONS,
|
||||
JOYINPUTEND = KEY_AXIS1 + JOYAXES,
|
||||
|
||||
KEY_DBLMOUSE1 =KEY_HAT1 + JOYHATS*4, // double clicks
|
||||
KEY_DBLJOY1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
|
||||
KEY_DBLHAT1 = KEY_DBLJOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_2MOUSE1 = KEY_DBLHAT1 + JOYHATS*4,
|
||||
KEY_2JOY1 = KEY_2MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_2HAT1 = KEY_2JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_DBL2MOUSE1 = KEY_2HAT1 + JOYHATS*4,
|
||||
KEY_DBL2JOY1 = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_DBL2HAT1 = KEY_DBL2JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_3JOY1 = KEY_DBL2HAT1 + JOYHATS*4,
|
||||
KEY_3HAT1 = KEY_3JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_DBL3JOY1 = KEY_3HAT1 + JOYHATS*4,
|
||||
KEY_DBL3HAT1 = KEY_DBL3JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_4JOY1 = KEY_DBL3HAT1 + JOYHATS*4,
|
||||
KEY_4HAT1 = KEY_4JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_DBL4JOY1 = KEY_4HAT1 + JOYHATS*4,
|
||||
KEY_DBL4HAT1 = KEY_DBL4JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_MOUSEWHEELUP = KEY_DBL4HAT1 + JOYHATS*4,
|
||||
KEY_MOUSE1 = JOYINPUTEND,
|
||||
KEY_MOUSEMOVE = KEY_MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_MOUSEWHEELUP = KEY_MOUSEMOVE + 4,
|
||||
KEY_MOUSEWHEELDOWN = KEY_MOUSEWHEELUP + 1,
|
||||
KEY_2MOUSEWHEELUP = KEY_MOUSEWHEELDOWN + 1,
|
||||
KEY_2MOUSEWHEELDOWN = KEY_2MOUSEWHEELUP + 1,
|
||||
MOUSEINPUTEND = KEY_MOUSEWHEELDOWN + 1,
|
||||
|
||||
NUMINPUTS = KEY_2MOUSEWHEELDOWN + 1,
|
||||
NUMINPUTS = MOUSEINPUTEND,
|
||||
} key_input_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
gc_null = 0, // a key/button mapped to gc_null has no effect
|
||||
gc_aimforward,
|
||||
gc_aimbackward,
|
||||
gc_turnleft,
|
||||
gc_turnright,
|
||||
gc_accelerate,
|
||||
gc_drift,
|
||||
gc_brake,
|
||||
gc_spindash,
|
||||
gc_fire,
|
||||
gc_lookback,
|
||||
gc_camreset,
|
||||
gc_camtoggle,
|
||||
gc_spectate,
|
||||
gc_lookup,
|
||||
gc_lookdown,
|
||||
gc_centerview,
|
||||
gc_talkkey,
|
||||
gc_teamkey,
|
||||
gc_scores,
|
||||
|
||||
// The actual gamepad
|
||||
gc_up,
|
||||
gc_down,
|
||||
gc_left,
|
||||
gc_right,
|
||||
gc_a,
|
||||
gc_b,
|
||||
gc_c,
|
||||
gc_x,
|
||||
gc_y,
|
||||
gc_z,
|
||||
gc_l,
|
||||
gc_r,
|
||||
gc_start,
|
||||
|
||||
// special keys
|
||||
gc_abc,
|
||||
gc_luaa,
|
||||
gc_luab,
|
||||
gc_luac,
|
||||
gc_console,
|
||||
gc_pause,
|
||||
gc_systemmenu,
|
||||
gc_talk,
|
||||
gc_teamtalk,
|
||||
gc_screenshot,
|
||||
gc_recordgif,
|
||||
gc_viewpoint,
|
||||
gc_custom1, // Lua scriptable
|
||||
gc_custom2, // Lua scriptable
|
||||
gc_custom3, // Lua scriptable
|
||||
num_gamecontrols
|
||||
} gamecontrols_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
gcs_custom,
|
||||
gcs_kart, // Kart doesn't really need this code, like, at all? But I don't feel like removing it.
|
||||
num_gamecontrolschemes
|
||||
} gamecontrolschemes_e;
|
||||
num_gamecontrols,
|
||||
|
||||
// alias gameplay controls
|
||||
gc_accel = gc_a,
|
||||
gc_brake = gc_x,
|
||||
gc_drift = gc_r,
|
||||
|
||||
gc_item = gc_l,
|
||||
gc_spindash = gc_c,
|
||||
|
||||
gc_lookback = gc_b,
|
||||
} gamecontrols_e;
|
||||
|
||||
// mouse values are used once
|
||||
extern consvar_t cv_mousesens, cv_mouseysens;
|
||||
extern consvar_t cv_mousesens2, cv_mouseysens2;
|
||||
extern consvar_t cv_controlperkey;
|
||||
|
||||
extern INT32 mousex, mousey;
|
||||
extern INT32 mlooky; //mousey with mlookSensitivity
|
||||
// current state of the keys: JOYAXISRANGE or 0 when boolean.
|
||||
// Or anything inbetween for analog values
|
||||
#define MAXDEVICES (MAXGAMEPADS + 1) // Gamepads + keyboard & mouse
|
||||
extern INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
||||
extern boolean deviceResponding[MAXDEVICES];
|
||||
|
||||
extern INT32 joyxmove[MAXSPLITSCREENPLAYERS][JOYAXISSET], joyymove[MAXSPLITSCREENPLAYERS][JOYAXISSET];
|
||||
|
||||
// current state of the keys: true if pushed
|
||||
extern UINT8 gamekeydown[NUMINPUTS];
|
||||
|
||||
// two key codes (or virtual key) per game control
|
||||
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][2];
|
||||
extern INT32 gamecontroldefault[MAXSPLITSCREENPLAYERS][num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention
|
||||
#define PlayerInputDown(p, gc) (gamekeydown[gamecontrol[p-1][gc][0]] || gamekeydown[gamecontrol[p-1][gc][1]])
|
||||
// several key codes (or virtual key) per game control
|
||||
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
||||
extern INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING]; // default control storage
|
||||
|
||||
/*
|
||||
#define num_gcl_accelerate 1
|
||||
#define num_gcl_brake 1
|
||||
#define num_gcl_drift 1
|
||||
|
|
@ -142,10 +125,13 @@ extern const INT32 gcl_spindash[num_gcl_spindash];
|
|||
extern const INT32 gcl_movement[num_gcl_movement];
|
||||
extern const INT32 gcl_item[num_gcl_item];
|
||||
extern const INT32 gcl_full[num_gcl_full];
|
||||
*/
|
||||
|
||||
// peace to my little coder fingers!
|
||||
// check a gamecontrol being active or not
|
||||
|
||||
INT32 G_GetDevicePlayer(INT32 deviceID);
|
||||
|
||||
// remaps the input event to a game control.
|
||||
void G_MapEventsToControls(event_t *ev);
|
||||
|
||||
|
|
@ -153,17 +139,20 @@ void G_MapEventsToControls(event_t *ev);
|
|||
const char *G_KeynumToString(INT32 keynum);
|
||||
INT32 G_KeyStringtoNum(const char *keystr);
|
||||
|
||||
boolean G_KeyBindIsNecessary(INT32 gc);
|
||||
boolean G_KeyIsAvailable(INT32 key, INT32 deviceID);
|
||||
|
||||
// detach any keys associated to the given game control
|
||||
void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control);
|
||||
void G_ClearControlKeys(INT32 (*setupcontrols)[MAXINPUTMAPPING], INT32 control);
|
||||
void G_ClearAllControlKeys(void);
|
||||
void Command_Setcontrol_f(void);
|
||||
void Command_Setcontrol2_f(void);
|
||||
void Command_Setcontrol3_f(void);
|
||||
void Command_Setcontrol4_f(void);
|
||||
void G_DefineDefaultControls(void);
|
||||
INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
|
||||
void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
|
||||
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrolsa)[2], INT32 (*fromcontrolsb)[2], INT32 (*fromcontrolsc)[2], INT32 (*fromcontrolsd)[2]);
|
||||
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify);
|
||||
INT32 G_GetControlScheme(INT32 (*fromcontrols)[MAXINPUTMAPPING], const INT32 *gclist, INT32 gclen);
|
||||
void G_CopyControls(INT32 (*setupcontrols)[MAXINPUTMAPPING], INT32 (*fromcontrols)[MAXINPUTMAPPING], const INT32 *gclist, INT32 gclen);
|
||||
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrolsa)[MAXINPUTMAPPING], INT32 (*fromcontrolsb)[MAXINPUTMAPPING], INT32 (*fromcontrolsc)[MAXINPUTMAPPING], INT32 (*fromcontrolsd)[MAXINPUTMAPPING]);
|
||||
INT32 G_CheckDoubleUsage(INT32 keynum, INT32 playernum, boolean modify);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ typedef enum
|
|||
GS_CONTINUING, // continue screen
|
||||
|
||||
GS_TITLESCREEN, // title screen
|
||||
GS_TIMEATTACK, // time attack menu
|
||||
GS_MENU, // SRB2Kart: menu-only (previously was GS_TIMEATTACK)
|
||||
|
||||
GS_CREDITS, // credit sequence
|
||||
GS_EVALUATION, // Evaluation at the end of a game.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include "../z_zone.h"
|
||||
#include "../console.h"
|
||||
#include "../v_video.h"
|
||||
#include "../m_menu.h"
|
||||
#include "../k_menu.h"
|
||||
#include "../i_system.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../i_video.h"
|
||||
|
|
|
|||
|
|
@ -6603,6 +6603,7 @@ void HWR_AddCommands(void)
|
|||
CV_RegisterVar(&cv_glshearing);
|
||||
CV_RegisterVar(&cv_glshaders);
|
||||
CV_RegisterVar(&cv_glallowshaders);
|
||||
CV_RegisterVar(&cv_glanisotropicmode);
|
||||
|
||||
CV_RegisterVar(&cv_glfiltermode);
|
||||
CV_RegisterVar(&cv_glsolvetjoin);
|
||||
|
|
@ -6618,7 +6619,7 @@ void HWR_AddSessionCommands(void)
|
|||
{
|
||||
if (gl_sessioncommandsadded)
|
||||
return;
|
||||
CV_RegisterVar(&cv_glanisotropicmode);
|
||||
// Kept in case we ever need this again.
|
||||
gl_sessioncommandsadded = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Documentation available here.
|
|||
#include "command.h"
|
||||
#include "console.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "mserv.h"
|
||||
#include "i_tcp.h"/* for current_port */
|
||||
#include "i_threads.h"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "hu_stuff.h"
|
||||
#include "font.h"
|
||||
|
||||
#include "m_menu.h" // gametype_cons_t
|
||||
#include "k_menu.h" // gametype_cons_t
|
||||
#include "m_cond.h" // emblems
|
||||
#include "m_misc.h" // word jumping
|
||||
|
||||
|
|
@ -237,15 +237,13 @@ void HU_Init(void)
|
|||
DIG (3);
|
||||
|
||||
ADIM (HU);
|
||||
|
||||
PR ("STCFN");
|
||||
REG;
|
||||
|
||||
PR ("TNYFN");
|
||||
REG;
|
||||
|
||||
ADIM (KART);
|
||||
PR ("MKFNT");
|
||||
PR ("FILEF");
|
||||
REG;
|
||||
|
||||
ADIM (LT);
|
||||
|
|
@ -279,6 +277,26 @@ void HU_Init(void)
|
|||
PR ("PINGN");
|
||||
REG;
|
||||
|
||||
PR ("PRFN");
|
||||
REG;
|
||||
|
||||
DIG (3);
|
||||
|
||||
ADIM (KART);
|
||||
PR ("MKFNT");
|
||||
REG;
|
||||
|
||||
ADIM (LT);
|
||||
PR ("GAMEM");
|
||||
REG;
|
||||
|
||||
ADIM (LT);
|
||||
PR ("THIFN");
|
||||
REG;
|
||||
|
||||
PR ("TLWFN");
|
||||
REG;
|
||||
|
||||
#undef REG
|
||||
#undef DIG
|
||||
#undef PR
|
||||
|
|
@ -976,10 +994,12 @@ void HU_Ticker(void)
|
|||
hu_tick++;
|
||||
hu_tick &= 7; // currently only to blink chat input cursor
|
||||
|
||||
/*
|
||||
if (PlayerInputDown(1, gc_scores))
|
||||
hu_showscores = !chat_on;
|
||||
else
|
||||
hu_showscores = false;
|
||||
*/
|
||||
|
||||
hu_keystrokes = false;
|
||||
|
||||
|
|
@ -1195,16 +1215,24 @@ boolean HU_Responder(event_t *ev)
|
|||
// (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...)
|
||||
// (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...)
|
||||
|
||||
if (ev->data1 >= KEY_MOUSE1)
|
||||
if (ev->data1 >= NUMKEYS)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 i, j;
|
||||
for (i = 0; i < num_gamecontrols; i++)
|
||||
{
|
||||
if (gamecontrol[0][i][0] == ev->data1 || gamecontrol[0][i][1] == ev->data1)
|
||||
for (j = 0; j < MAXINPUTMAPPING; j++)
|
||||
{
|
||||
if (gamecontrol[0][i][j] == ev->data1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < MAXINPUTMAPPING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == num_gamecontrols)
|
||||
if (i == num_gamecontrols && j == MAXINPUTMAPPING)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1212,7 +1240,7 @@ boolean HU_Responder(event_t *ev)
|
|||
if (!chat_on)
|
||||
{
|
||||
// enter chat mode
|
||||
if ((ev->data1 == gamecontrol[0][gc_talkkey][0] || ev->data1 == gamecontrol[0][gc_talkkey][1])
|
||||
if ((ev->data1 == gamecontrol[0][gc_talk][0] || ev->data1 == gamecontrol[0][gc_talk][1])
|
||||
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
|
||||
{
|
||||
chat_on = true;
|
||||
|
|
@ -1222,7 +1250,7 @@ boolean HU_Responder(event_t *ev)
|
|||
typelines = 1;
|
||||
return true;
|
||||
}
|
||||
if ((ev->data1 == gamecontrol[0][gc_teamkey][0] || ev->data1 == gamecontrol[0][gc_teamkey][1])
|
||||
if ((ev->data1 == gamecontrol[0][gc_teamtalk][0] || ev->data1 == gamecontrol[0][gc_teamtalk][1])
|
||||
&& netgame && !OLD_MUTE)
|
||||
{
|
||||
chat_on = true;
|
||||
|
|
@ -1246,9 +1274,9 @@ boolean HU_Responder(event_t *ev)
|
|||
return true;
|
||||
|
||||
// Ignore non-keyboard keys, except when the talk key is bound
|
||||
if (ev->data1 >= KEY_MOUSE1
|
||||
&& (ev->data1 != gamecontrol[0][gc_talkkey][0]
|
||||
&& ev->data1 != gamecontrol[0][gc_talkkey][1]))
|
||||
if (ev->data1 >= NUMKEYS
|
||||
/*&& (ev->data1 != gamecontrol[0][gc_talkkey][0]
|
||||
&& ev->data1 != gamecontrol[0][gc_talkkey][1])*/)
|
||||
return false;
|
||||
|
||||
c = CON_ShiftChar(c);
|
||||
|
|
@ -1310,9 +1338,9 @@ boolean HU_Responder(event_t *ev)
|
|||
I_UpdateMouseGrab();
|
||||
}
|
||||
else if (c == KEY_ESCAPE
|
||||
|| ((c == gamecontrol[0][gc_talkkey][0] || c == gamecontrol[0][gc_talkkey][1]
|
||||
/*|| ((c == gamecontrol[0][gc_talkkey][0] || c == gamecontrol[0][gc_talkkey][1]
|
||||
|| c == gamecontrol[0][gc_teamkey][0] || c == gamecontrol[0][gc_teamkey][1])
|
||||
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
|
||||
&& c >= NUMKEYS)*/) // If it's not a keyboard key, then the chat button is used as a toggle.
|
||||
{
|
||||
chat_on = false;
|
||||
c_input = 0; // reset input cursor
|
||||
|
|
@ -1579,7 +1607,7 @@ static void HU_drawChatLog(INT32 offset)
|
|||
INT32 x = chatx+2, y, dx = 0, dy = 0;
|
||||
UINT32 i = 0;
|
||||
INT32 chat_topy, chat_bottomy;
|
||||
INT32 highlight = HU_GetHighlightColor();
|
||||
INT32 highlight = V_YELLOWMAP;
|
||||
boolean atbottom = false;
|
||||
|
||||
// make sure that our scroll position isn't "illegal";
|
||||
|
|
@ -2374,9 +2402,7 @@ static void HU_DrawRankings(void)
|
|||
|
||||
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
|
||||
|
||||
if (cons_menuhighlight.value)
|
||||
hilicol = cons_menuhighlight.value;
|
||||
else if (modeattacking)
|
||||
if (modeattacking)
|
||||
hilicol = V_ORANGEMAP;
|
||||
else
|
||||
hilicol = ((gametype == GT_RACE) ? V_SKYMAP : V_REDMAP);
|
||||
|
|
@ -2385,7 +2411,7 @@ static void HU_DrawRankings(void)
|
|||
if (modeattacking)
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "Record Attack");
|
||||
else
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, Gametype_Names[gametype]);
|
||||
|
||||
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@
|
|||
#define KART_FONTEND 'Z'
|
||||
|
||||
#define KART_FONTSIZE (KART_FONTEND - KART_FONTSTART + 1)
|
||||
|
||||
#define AZ_FONTSTART 'A' // the first font character
|
||||
#define AZ_FONTEND 'Z'
|
||||
|
||||
#define AZ_FONTSIZE (AZ_FONTEND - AZ_FONTSTART + 1)
|
||||
//
|
||||
|
||||
// Level title font
|
||||
|
|
@ -49,7 +54,7 @@ enum
|
|||
{
|
||||
X (HU),
|
||||
X (TINY),
|
||||
X (KART),
|
||||
X (FILE),
|
||||
|
||||
X (LT),
|
||||
X (CRED),
|
||||
|
|
@ -60,6 +65,12 @@ enum
|
|||
X (TALLNUM),
|
||||
X (NIGHTSNUM),
|
||||
X (PINGNUM),
|
||||
X (PROFNUM),
|
||||
|
||||
X (KART),
|
||||
X (GM),
|
||||
X (LSHI),
|
||||
X (LSLOW),
|
||||
};
|
||||
#undef X
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *p)
|
|||
void K_UpdateMatchRaceBots(void)
|
||||
{
|
||||
const UINT8 difficulty = cv_kartbot.value;
|
||||
UINT8 pmax = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value);
|
||||
UINT8 pmax = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value);
|
||||
UINT8 numplayers = 0;
|
||||
UINT8 numbots = 0;
|
||||
UINT8 numwaiting = 0;
|
||||
|
|
@ -136,9 +136,9 @@ void K_UpdateMatchRaceBots(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (cv_ingamecap.value > 0)
|
||||
if (cv_maxplayers.value > 0)
|
||||
{
|
||||
pmax = min(pmax, cv_ingamecap.value);
|
||||
pmax = min(pmax, cv_maxplayers.value);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && ((t1->threshold > 0 && t2->type == MT_PLAYER) || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
if (t1->health <= 0 || t2->health <= 0)
|
||||
|
|
|
|||
|
|
@ -175,6 +175,23 @@ static void K_SetFollowerState(mobj_t *f, statenum_t state)
|
|||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor)
|
||||
{
|
||||
if (followercolor < numskincolors) // bog standard
|
||||
return followercolor;
|
||||
|
||||
if (followercolor == FOLLOWERCOLOR_OPPOSITE) // "Opposite"
|
||||
return skincolors[playercolor].invcolor;
|
||||
|
||||
//if (followercolor == FOLLOWERCOLOR_MATCH) -- "Match"
|
||||
return playercolor;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_UpdateFollowerState(mobj_t *f, statenum_t state, followerstate_t type)
|
||||
|
||||
|
|
@ -302,24 +319,7 @@ void K_HandleFollower(player_t *player)
|
|||
}
|
||||
|
||||
// Set follower colour
|
||||
switch (player->followercolor)
|
||||
{
|
||||
case FOLLOWERCOLOR_MATCH: // "Match"
|
||||
color = player->skincolor;
|
||||
break;
|
||||
|
||||
case FOLLOWERCOLOR_OPPOSITE: // "Opposite"
|
||||
color = skincolors[player->skincolor].invcolor;
|
||||
break;
|
||||
|
||||
default:
|
||||
color = player->followercolor;
|
||||
if (color == 0 || color > MAXSKINCOLORS+2) // Make sure this isn't garbage
|
||||
{
|
||||
color = player->skincolor; // "Match" as fallback.
|
||||
}
|
||||
break;
|
||||
}
|
||||
color = K_GetEffectiveFollowerColor(player->followercolor, player->skincolor);
|
||||
|
||||
if (player->follower == NULL) // follower doesn't exist / isn't valid
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_skins.h"
|
||||
|
||||
#define FOLLOWERCOLOR_MATCH UINT16_MAX
|
||||
#define FOLLOWERCOLOR_OPPOSITE (UINT16_MAX-1)
|
||||
|
|
@ -48,6 +47,7 @@ typedef struct follower_s
|
|||
{
|
||||
char skinname[SKINNAMESIZE+1]; // Skin Name. This is what to refer to when asking the commands anything.
|
||||
char name[SKINNAMESIZE+1]; // Name. This is used for the menus. We'll just follow the same rules as skins for this.
|
||||
char icon[8+1]; // Lump names are only 8 characters. (+1 for \0)
|
||||
|
||||
skincolornum_t defaultcolor; // default color for menus.
|
||||
followermode_t mode; // Follower behavior modifier.
|
||||
|
|
@ -136,6 +136,23 @@ boolean K_SetFollowerByName(INT32 playernum, const char *skinname);
|
|||
void K_SetFollowerByNum(INT32 playernum, INT32 skinnum);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor)
|
||||
|
||||
Updates a player's follower pointer, and does
|
||||
its positioning and animations.
|
||||
|
||||
Input Arguments:-
|
||||
followercolor - The raw color setting for the follower
|
||||
playercolor - The player's associated colour, for reference
|
||||
|
||||
Return:-
|
||||
The resultant skincolor enum for the follower
|
||||
--------------------------------------------------*/
|
||||
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_HandleFollower(player_t *player)
|
||||
|
||||
|
|
|
|||
|
|
@ -662,6 +662,8 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
|||
return (tiny ? "K_ISMINE" : "K_ITMINE");
|
||||
case KITEM_LANDMINE:
|
||||
return (tiny ? "K_ISLNDM" : "K_ITLNDM");
|
||||
case KITEM_DROPTARGET:
|
||||
return (tiny ? "K_ISDTRG" : "K_ITDTRG");
|
||||
case KITEM_BALLHOG:
|
||||
return (tiny ? "K_ISBHOG" : "K_ITBHOG");
|
||||
case KITEM_SPB:
|
||||
|
|
@ -4469,7 +4471,7 @@ void K_drawKartFreePlay(void)
|
|||
if (((leveltime-lt_endtime) % TICRATE) < TICRATE/2)
|
||||
return;
|
||||
|
||||
V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy
|
||||
V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - 72, // mirror the laps thingy
|
||||
LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY");
|
||||
}
|
||||
|
||||
|
|
|
|||
224
src/k_kart.c
224
src/k_kart.c
|
|
@ -2824,91 +2824,107 @@ void K_PlayOvertakeSound(mobj_t *source)
|
|||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
void K_PlayPainSound(mobj_t *source)
|
||||
void K_PlayPainSound(mobj_t *source, mobj_t *other)
|
||||
{
|
||||
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
||||
|
||||
sfxenum_t sfx_id = ((skin_t *)source->skin)->soundsid[S_sfx[sfx_khurt1 + pick].skinsound];
|
||||
boolean alwaysHear = false;
|
||||
|
||||
if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL)
|
||||
{
|
||||
alwaysHear = P_IsDisplayPlayer(other->player);
|
||||
}
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(source, sfx_khurt1 + pick);
|
||||
{
|
||||
S_StartSound(alwaysHear ? NULL : source, sfx_id);
|
||||
}
|
||||
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *victim)
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *other)
|
||||
{
|
||||
const boolean victimIsLocal = (victim != NULL && P_IsDisplayPlayer(victim->player) == true);
|
||||
sfxenum_t sfx_id = ((skin_t *)source->skin)->soundsid[S_sfx[sfx_khitem].skinsound];
|
||||
boolean alwaysHear = false;
|
||||
|
||||
if (source->player->follower)
|
||||
if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL)
|
||||
{
|
||||
follower_t fl = followers[source->player->followerskin];
|
||||
source->player->follower->movecount = fl.hitconfirmtime; // movecount is used to play the hitconfirm animation for followers.
|
||||
alwaysHear = P_IsDisplayPlayer(other->player);
|
||||
}
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
{
|
||||
if (victimIsLocal == false)
|
||||
{
|
||||
S_StartSound(source, sfx_khitem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(source, sfx_s1c9); // The only lost gameplay functionality with voices disabled
|
||||
S_StartSound(alwaysHear ? NULL : source, sfx_id);
|
||||
}
|
||||
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
if (victim != NULL && victim->player != NULL)
|
||||
void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker)
|
||||
{
|
||||
if (victim == NULL || P_MobjWasRemoved(victim) == true || victim->player == NULL)
|
||||
{
|
||||
victim->player->confirmInflictor = source->player - players;
|
||||
victim->player->confirmInflictorDelay = TICRATE/2;
|
||||
return;
|
||||
}
|
||||
|
||||
// In a perfect world we could move this here, but there's
|
||||
// a few niche situations where we want a pain sound from
|
||||
// the victim, but no confirm sound from the attacker.
|
||||
// (ex: DMG_STING)
|
||||
|
||||
//K_PlayPainSound(victim, attacker);
|
||||
|
||||
if (attacker == NULL || P_MobjWasRemoved(attacker) == true || attacker->player == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
attacker->player->confirmVictim = (victim->player - players);
|
||||
attacker->player->confirmVictimDelay = TICRATE/2;
|
||||
|
||||
if (attacker->player->follower != NULL)
|
||||
{
|
||||
const follower_t *fl = &followers[attacker->player->followerskin];
|
||||
attacker->player->follower->movecount = fl->hitconfirmtime; // movecount is used to play the hitconfirm animation for followers.
|
||||
}
|
||||
}
|
||||
|
||||
void K_PlayPowerGloatSound(mobj_t *source)
|
||||
{
|
||||
if (cv_kartvoices.value)
|
||||
{
|
||||
S_StartSound(source, sfx_kgloat);
|
||||
}
|
||||
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
static void K_HandleDelayedHitByEm(player_t *player)
|
||||
{
|
||||
if (player->confirmInflictorDelay == 0)
|
||||
if (player->confirmVictimDelay == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->confirmInflictorDelay--;
|
||||
player->confirmVictimDelay--;
|
||||
|
||||
if (player->confirmInflictorDelay == 0
|
||||
&& P_IsDisplayPlayer(player) == true
|
||||
&& cv_kartvoices.value)
|
||||
if (player->confirmVictimDelay == 0)
|
||||
{
|
||||
player_t *inflictor = NULL;
|
||||
mobj_t *victim = NULL;
|
||||
|
||||
if (player->confirmInflictor >= MAXPLAYERS)
|
||||
if (player->confirmVictim < MAXPLAYERS && playeringame[player->confirmVictim])
|
||||
{
|
||||
return;
|
||||
player_t *victimPlayer = &players[player->confirmVictim];
|
||||
|
||||
if (victimPlayer != NULL && victimPlayer->spectator == false)
|
||||
{
|
||||
victim = victimPlayer->mo;
|
||||
}
|
||||
}
|
||||
|
||||
if (!playeringame[player->confirmInflictor])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inflictor = &players[player->confirmInflictor];
|
||||
if (inflictor == NULL || inflictor->spectator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inflictor->mo != NULL && P_MobjWasRemoved(inflictor->mo) == false)
|
||||
{
|
||||
sfxenum_t sfx_id = ((skin_t *)inflictor->mo->skin)->soundsid[S_sfx[sfx_khitem].skinsound];
|
||||
S_StartSound(NULL, sfx_id);
|
||||
}
|
||||
K_PlayHitEmSound(player->mo, victim);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4281,8 +4297,8 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
|
|||
|
||||
if (charge < 0)
|
||||
{
|
||||
// Stage 0: Yellow
|
||||
color = SKINCOLOR_GOLD;
|
||||
// Stage 0: Grey
|
||||
color = SKINCOLOR_SILVER;
|
||||
}
|
||||
else if (charge >= dsfour)
|
||||
{
|
||||
|
|
@ -4299,7 +4315,7 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
|
|||
}
|
||||
else if (charge >= dsthree)
|
||||
{
|
||||
// Stage 3: Purple
|
||||
// Stage 3: Blue
|
||||
if (charge <= dsthree+(16*3))
|
||||
{
|
||||
// transition 1
|
||||
|
|
@ -4308,19 +4324,6 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
|
|||
else if (charge <= dsthree+(32*3))
|
||||
{
|
||||
// transition 2
|
||||
color = SKINCOLOR_MOONSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = SKINCOLOR_PURPLE;
|
||||
}
|
||||
}
|
||||
else if (charge >= dstwo)
|
||||
{
|
||||
// Stage 2: Blue
|
||||
if (charge <= dstwo+(32*3))
|
||||
{
|
||||
// transition
|
||||
color = SKINCOLOR_NOVA;
|
||||
}
|
||||
else
|
||||
|
|
@ -4328,10 +4331,10 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
|
|||
color = SKINCOLOR_SAPPHIRE;
|
||||
}
|
||||
}
|
||||
else if (charge >= dsone)
|
||||
else if (charge >= dstwo)
|
||||
{
|
||||
// Stage 1: Red
|
||||
if (charge <= dsone+(32*3))
|
||||
// Stage 2: Red
|
||||
if (charge <= dstwo+(32*3))
|
||||
{
|
||||
// transition
|
||||
color = SKINCOLOR_TANGERINE;
|
||||
|
|
@ -4341,6 +4344,19 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
|
|||
color = SKINCOLOR_KETCHUP;
|
||||
}
|
||||
}
|
||||
else if (charge >= dsone)
|
||||
{
|
||||
// Stage 1: Yellow
|
||||
if (charge <= dsone+(32*3))
|
||||
{
|
||||
// transition
|
||||
color = SKINCOLOR_TAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = SKINCOLOR_GOLD;
|
||||
}
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
@ -8527,9 +8543,9 @@ INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage)
|
|||
}
|
||||
|
||||
/*
|
||||
Stage 1: red sparks
|
||||
Stage 2: blue sparks
|
||||
Stage 3: purple sparks
|
||||
Stage 1: yellow sparks
|
||||
Stage 2: red sparks
|
||||
Stage 3: blue sparks
|
||||
Stage 4: big large rainbow sparks
|
||||
Stage 0: air failsafe
|
||||
*/
|
||||
|
|
@ -8545,26 +8561,22 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage)
|
|||
switch (stage)
|
||||
{
|
||||
case 1:
|
||||
overlay->color = SKINCOLOR_KETCHUP;
|
||||
overlay->fuse = 16;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
overlay->color = SKINCOLOR_SAPPHIRE;
|
||||
|
||||
overlay->fuse = 32;
|
||||
|
||||
S_StartSound(player->mo, sfx_kc5b);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
overlay->color = SKINCOLOR_PURPLE;
|
||||
overlay->fuse = 48;
|
||||
|
||||
S_StartSound(player->mo, sfx_kc5b);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
overlay->color = SKINCOLOR_SILVER;
|
||||
overlay->fuse = 120;
|
||||
|
||||
S_StartSound(player->mo, sfx_kc5b);
|
||||
|
|
@ -8572,7 +8584,6 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage)
|
|||
break;
|
||||
|
||||
case 0:
|
||||
overlay->color = SKINCOLOR_SILVER;
|
||||
overlay->fuse = 16;
|
||||
break;
|
||||
}
|
||||
|
|
@ -8607,7 +8618,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
|
||||
if (player->driftcharge < 0)
|
||||
{
|
||||
// Stage 0: Yellow sparks
|
||||
// Stage 0: Grey sparks
|
||||
if (!onground)
|
||||
P_Thrust(player->mo, pushdir, player->speed / 8);
|
||||
|
||||
|
|
@ -8616,7 +8627,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
}
|
||||
else if (player->driftcharge >= dsone && player->driftcharge < dstwo)
|
||||
{
|
||||
// Stage 1: Red sparks
|
||||
// Stage 1: Yellow sparks
|
||||
if (!onground)
|
||||
P_Thrust(player->mo, pushdir, player->speed / 4);
|
||||
|
||||
|
|
@ -8627,7 +8638,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
}
|
||||
else if (player->driftcharge < dsthree)
|
||||
{
|
||||
// Stage 2: Blue sparks
|
||||
// Stage 2: Red sparks
|
||||
if (!onground)
|
||||
P_Thrust(player->mo, pushdir, player->speed / 3);
|
||||
|
||||
|
|
@ -8638,7 +8649,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
}
|
||||
else if (player->driftcharge < dsfour)
|
||||
{
|
||||
// Stage 3: Purple sparks
|
||||
// Stage 3: Blue sparks
|
||||
if (!onground)
|
||||
P_Thrust(player->mo, pushdir, ( 5 * player->speed ) / 12);
|
||||
|
||||
|
|
@ -9025,13 +9036,17 @@ static INT32 K_FlameShieldMax(player_t *player)
|
|||
|
||||
boolean K_PlayerEBrake(player_t *player)
|
||||
{
|
||||
if (player->fastfall != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return (K_GetKartButtons(player) & BT_EBRAKEMASK) == BT_EBRAKEMASK
|
||||
&& P_IsObjectOnGround(player->mo) == true
|
||||
&& player->drift == 0
|
||||
&& player->spinouttimer == 0
|
||||
&& player->justbumped == 0
|
||||
&& player->spindashboost == 0
|
||||
&& player->nocontrol == 0;
|
||||
&& player->drift == 0
|
||||
&& P_PlayerInPain(player) == false
|
||||
&& player->justbumped == 0
|
||||
&& player->spindashboost == 0
|
||||
&& player->nocontrol == 0;
|
||||
}
|
||||
|
||||
SINT8 K_Sliptiding(player_t *player)
|
||||
|
|
@ -9053,9 +9068,8 @@ void K_KartEbrakeVisuals(player_t *p)
|
|||
mobj_t *spdl;
|
||||
fixed_t sx, sy;
|
||||
|
||||
if (K_PlayerEBrake(p))
|
||||
if (K_PlayerEBrake(p) == true)
|
||||
{
|
||||
|
||||
if (p->ebrakefor % 20 == 0)
|
||||
{
|
||||
wave = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_SOFTLANDING);
|
||||
|
|
@ -9092,7 +9106,6 @@ void K_KartEbrakeVisuals(player_t *p)
|
|||
K_FlipFromObject(p->mo->hprev, p->mo);
|
||||
}
|
||||
|
||||
|
||||
if (!p->spindash)
|
||||
{
|
||||
// Spawn downwards fastline
|
||||
|
|
@ -9233,6 +9246,7 @@ static void K_KartSpindashWind(mobj_t *parent)
|
|||
|
||||
static void K_KartSpindash(player_t *player)
|
||||
{
|
||||
const boolean onGround = P_IsObjectOnGround(player->mo);
|
||||
const INT16 MAXCHARGETIME = K_GetSpindashChargeTime(player);
|
||||
UINT16 buttons = K_GetKartButtons(player);
|
||||
boolean spawnWind = (leveltime % 2 == 0);
|
||||
|
|
@ -9296,6 +9310,44 @@ static void K_KartSpindash(player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
// Handle fast falling behaviors first.
|
||||
if (onGround == false)
|
||||
{
|
||||
// Update fastfall.
|
||||
player->fastfall = player->mo->momz;
|
||||
player->spindash = 0;
|
||||
return;
|
||||
}
|
||||
else if (player->fastfall != 0)
|
||||
{
|
||||
// Handle fastfall bounce.
|
||||
const fixed_t maxBounce = player->mo->scale * 10;
|
||||
const fixed_t minBounce = player->mo->scale;
|
||||
fixed_t bounce = 2 * abs(player->fastfall) / 3;
|
||||
|
||||
if (bounce > maxBounce)
|
||||
{
|
||||
bounce = maxBounce;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lose speed on bad bounce.
|
||||
player->mo->momx /= 2;
|
||||
player->mo->momy /= 2;
|
||||
|
||||
if (bounce < minBounce)
|
||||
{
|
||||
bounce = minBounce;
|
||||
}
|
||||
}
|
||||
|
||||
S_StartSound(player->mo, sfx_ffbonc);
|
||||
player->mo->momz = bounce * P_MobjFlip(player->mo);
|
||||
|
||||
player->fastfall = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->speed == 0 && player->steering != 0 && leveltime % 8 == 0)
|
||||
{
|
||||
// Rubber burn turn sfx
|
||||
|
|
@ -10477,7 +10529,7 @@ void K_CheckSpectateStatus(void)
|
|||
if (!players[i].spectator)
|
||||
{
|
||||
numingame++;
|
||||
if (cv_ingamecap.value && numingame >= cv_ingamecap.value) // DON'T allow if you've hit the in-game player cap
|
||||
if (cv_maxplayers.value && numingame >= cv_maxplayers.value) // DON'T allow if you've hit the in-game player cap
|
||||
return;
|
||||
if (gamestate != GS_LEVEL) // Allow if you're not in a level
|
||||
continue;
|
||||
|
|
@ -10502,7 +10554,7 @@ void K_CheckSpectateStatus(void)
|
|||
return;
|
||||
|
||||
// Organize by spectate wait timer
|
||||
if (cv_ingamecap.value)
|
||||
if (cv_maxplayers.value)
|
||||
{
|
||||
UINT8 oldrespawnlist[MAXPLAYERS];
|
||||
memcpy(oldrespawnlist, respawnlist, numjoiners);
|
||||
|
|
@ -10529,7 +10581,7 @@ void K_CheckSpectateStatus(void)
|
|||
// Finally, we can de-spectate everyone!
|
||||
for (i = 0; i < numjoiners; i++)
|
||||
{
|
||||
if (cv_ingamecap.value && numingame+i >= cv_ingamecap.value) // Hit the in-game player cap while adding people?
|
||||
if (cv_maxplayers.value && numingame+i >= cv_maxplayers.value) // Hit the in-game player cap while adding people?
|
||||
break;
|
||||
//CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime);
|
||||
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
||||
|
|
|
|||
|
|
@ -154,8 +154,9 @@ void K_HandleDirectionalInfluence(player_t *player);
|
|||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
void K_PlayBoostTaunt(mobj_t *source);
|
||||
void K_PlayOvertakeSound(mobj_t *source);
|
||||
void K_PlayPainSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *victim);
|
||||
void K_PlayPainSound(mobj_t *source, mobj_t *other);
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *other);
|
||||
void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
fixed_t K_ItemScaleForPlayer(player_t *player);
|
||||
|
|
|
|||
1113
src/k_menu.h
Normal file
1113
src/k_menu.h
Normal file
File diff suppressed because it is too large
Load diff
1747
src/k_menudef.c
Normal file
1747
src/k_menudef.c
Normal file
File diff suppressed because it is too large
Load diff
4377
src/k_menudraw.c
Normal file
4377
src/k_menudraw.c
Normal file
File diff suppressed because it is too large
Load diff
6594
src/k_menufunc.c
Normal file
6594
src/k_menufunc.c
Normal file
File diff suppressed because it is too large
Load diff
539
src/k_profiles.c
Normal file
539
src/k_profiles.c
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_profiles.c
|
||||
/// \brief implements methods for profiles etc.
|
||||
|
||||
#include "d_main.h" // pandf
|
||||
#include "byteptr.h" // READ/WRITE macros
|
||||
#include "p_saveg.h" // save_p
|
||||
#include "m_misc.h" //FIL_WriteFile()
|
||||
#include "k_profiles.h"
|
||||
#include "z_zone.h"
|
||||
#include "r_skins.h"
|
||||
|
||||
// List of all the profiles.
|
||||
static profile_t *profilesList[MAXPROFILES+1]; // +1 because we're gonna add a default "GUEST' profile.
|
||||
static UINT8 numprofiles = 0; // # of loaded profiles
|
||||
|
||||
INT32 PR_GetNumProfiles(void)
|
||||
{
|
||||
return numprofiles;
|
||||
}
|
||||
|
||||
profile_t* PR_MakeProfile(
|
||||
const char *prname,
|
||||
const char *pname,
|
||||
const char *sname, const UINT16 col,
|
||||
const char *fname, const UINT16 fcol,
|
||||
INT32 controlarray[num_gamecontrols][MAXINPUTMAPPING],
|
||||
boolean guest)
|
||||
{
|
||||
profile_t *new = Z_Malloc(sizeof(profile_t), PU_STATIC, NULL);
|
||||
UINT8 i;
|
||||
|
||||
new->version = PROFILEVER;
|
||||
|
||||
strcpy(new->profilename, prname);
|
||||
new->profilename[sizeof new->profilename - 1] = '\0';
|
||||
|
||||
strcpy(new->skinname, sname);
|
||||
strcpy(new->playername, pname);
|
||||
new->color = col;
|
||||
|
||||
strcpy(new->follower, fname);
|
||||
new->followercolor = fcol;
|
||||
new->kickstartaccel = false;
|
||||
|
||||
// Copy from gamecontrol directly as we'll be setting controls up directly in the profile.
|
||||
memcpy(new->controls, controlarray, sizeof(new->controls));
|
||||
|
||||
// Init both power levels
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
{
|
||||
new->powerlevels[i] = (guest ? 0 : PWRLVRECORD_START);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
profile_t* PR_MakeProfileFromPlayer(const char *prname, const char *pname, const char *sname, const UINT16 col, const char *fname, UINT16 fcol, UINT8 pnum)
|
||||
{
|
||||
// Generate profile using the player's gamecontrol, as we set them directly when making profiles from menus.
|
||||
profile_t *new = PR_MakeProfile(prname, pname, sname, col, fname, fcol, gamecontrol[pnum], false);
|
||||
|
||||
// Player bound cvars:
|
||||
new->kickstartaccel = cv_kickstartaccel[pnum].value;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
boolean PR_AddProfile(profile_t *p)
|
||||
{
|
||||
if (numprofiles < MAXPROFILES+1)
|
||||
{
|
||||
profilesList[numprofiles] = p;
|
||||
numprofiles++;
|
||||
|
||||
CONS_Printf("Profile '%s' added\n", p->profilename);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
profile_t* PR_GetProfile(INT32 num)
|
||||
{
|
||||
if (num < numprofiles)
|
||||
return profilesList[num];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
boolean PR_DeleteProfile(INT32 num)
|
||||
{
|
||||
UINT8 i;
|
||||
profile_t* sacrifice;
|
||||
|
||||
if (num <= 0 || num > numprofiles)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sacrifice = profilesList[num];
|
||||
|
||||
// If we're deleting inbetween profiles, move everything.
|
||||
if (num < numprofiles)
|
||||
{
|
||||
for (i = num; i < numprofiles-1; i++)
|
||||
{
|
||||
profilesList[i] = profilesList[i+1];
|
||||
}
|
||||
|
||||
// Make sure to move cv_lastprofile (and title/current profile) values as well!
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS+2; i++)
|
||||
{
|
||||
consvar_t *cv;
|
||||
|
||||
if (i < MAXSPLITSCREENPLAYERS)
|
||||
cv = &cv_lastprofile[i];
|
||||
else if (i == MAXSPLITSCREENPLAYERS)
|
||||
cv = &cv_ttlprofilen;
|
||||
else
|
||||
cv = &cv_currprofile;
|
||||
|
||||
if (cv->value < num)
|
||||
{
|
||||
// Not affected.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cv->value > num)
|
||||
{
|
||||
// Shift our lastprofile number down to match the new order.
|
||||
CV_StealthSetValue(cv, cv->value-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cv != &cv_currprofile)
|
||||
{
|
||||
// There's no hope for it. If we were on the deleted profile, default back to guest.
|
||||
CV_StealthSetValue(cv, PROFILE_GUEST);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Oh boy, now we're really in for it.
|
||||
CV_StealthSetValue(cv, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// In any case, delete the last profile as well.
|
||||
profilesList[numprofiles] = NULL;
|
||||
numprofiles--;
|
||||
|
||||
PR_SaveProfiles();
|
||||
|
||||
// Finally, clear up our memory!
|
||||
Z_Free(sacrifice);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PR_InitNewProfile(void)
|
||||
{
|
||||
char pname[PROFILENAMELEN+1] = "PRF";
|
||||
profile_t *dprofile;
|
||||
UINT8 usenum = numprofiles-1;
|
||||
UINT8 i;
|
||||
boolean nameok = false;
|
||||
|
||||
pname[4] = '\0';
|
||||
|
||||
// When deleting profile, it's possible to do some pretty wacko stuff that would lead a new fresh profile to share the same name as another profile we have never changed the name of.
|
||||
// This could become an infinite loop if MAXPROFILES >= 26.
|
||||
while (!nameok)
|
||||
{
|
||||
pname[3] = 'A'+usenum;
|
||||
|
||||
for (i = 0; i < numprofiles; i++)
|
||||
{
|
||||
profile_t *pr = PR_GetProfile(i);
|
||||
if (!strcmp(pr->profilename, pname))
|
||||
{
|
||||
usenum++;
|
||||
if (pname[3] == 'Z')
|
||||
usenum = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// if we got here, then it means the name is okay!
|
||||
if (i == numprofiles-1)
|
||||
nameok = true;
|
||||
}
|
||||
}
|
||||
|
||||
dprofile = PR_MakeProfile(
|
||||
pname,
|
||||
PROFILEDEFAULTPNAME,
|
||||
PROFILEDEFAULTSKIN, PROFILEDEFAULTCOLOR,
|
||||
PROFILEDEFAULTFOLLOWER, PROFILEDEFAULTFOLLOWERCOLOR,
|
||||
gamecontroldefault,
|
||||
false
|
||||
);
|
||||
PR_AddProfile(dprofile);
|
||||
}
|
||||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
void PR_SaveProfiles(void)
|
||||
{
|
||||
size_t length = 0;
|
||||
const size_t headerlen = strlen(PROFILEHEADER);
|
||||
UINT8 i, j, k;
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(sizeof(UINT32) + (numprofiles * sizeof(profile_t)));
|
||||
if (!save_p)
|
||||
{
|
||||
I_Error("No more free memory for saving profiles\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add header.
|
||||
WRITESTRINGN(save_p, PROFILEHEADER, headerlen);
|
||||
WRITEUINT8(save_p, PROFILEVER);
|
||||
WRITEUINT8(save_p, numprofiles);
|
||||
|
||||
for (i = 1; i < numprofiles; i++)
|
||||
{
|
||||
// Names.
|
||||
WRITESTRINGN(save_p, profilesList[i]->profilename, PROFILENAMELEN);
|
||||
WRITESTRINGN(save_p, profilesList[i]->playername, MAXPLAYERNAME);
|
||||
|
||||
// Character and colour.
|
||||
WRITESTRINGN(save_p, profilesList[i]->skinname, SKINNAMESIZE);
|
||||
WRITEUINT16(save_p, profilesList[i]->color);
|
||||
|
||||
// Follower and colour.
|
||||
WRITESTRINGN(save_p, profilesList[i]->follower, SKINNAMESIZE);
|
||||
WRITEUINT16(save_p, profilesList[i]->followercolor);
|
||||
|
||||
// PWR.
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
{
|
||||
WRITEUINT16(save_p, profilesList[i]->powerlevels[j]);
|
||||
}
|
||||
|
||||
// Consvars.
|
||||
WRITEUINT8(save_p, profilesList[i]->kickstartaccel);
|
||||
|
||||
// Controls.
|
||||
for (j = 0; j < num_gamecontrols; j++)
|
||||
{
|
||||
for (k = 0; k < MAXINPUTMAPPING; k++)
|
||||
{
|
||||
WRITEINT32(save_p, profilesList[i]->controls[j][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
length = save_p - savebuffer;
|
||||
|
||||
if (!FIL_WriteFile(va(pandf, srb2home, PROFILESFILE), savebuffer, length))
|
||||
{
|
||||
free(savebuffer);
|
||||
I_Error("Couldn't save profiles. Are you out of Disk space / playing in a protected folder?");
|
||||
}
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
}
|
||||
|
||||
void PR_LoadProfiles(void)
|
||||
{
|
||||
size_t length = 0;
|
||||
const size_t headerlen = strlen(PROFILEHEADER);
|
||||
UINT8 i, j, k, version;
|
||||
profile_t *dprofile = PR_MakeProfile(
|
||||
PROFILEDEFAULTNAME,
|
||||
PROFILEDEFAULTPNAME,
|
||||
PROFILEDEFAULTSKIN, PROFILEDEFAULTCOLOR,
|
||||
PROFILEDEFAULTFOLLOWER, PROFILEDEFAULTFOLLOWERCOLOR,
|
||||
gamecontroldefault,
|
||||
true
|
||||
);
|
||||
|
||||
length = FIL_ReadFile(va(pandf, srb2home, PROFILESFILE), &savebuffer);
|
||||
if (!length)
|
||||
{
|
||||
// No profiles. Add the default one.
|
||||
PR_AddProfile(dprofile);
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
|
||||
if (strncmp(PROFILEHEADER, (const char *)savebuffer, headerlen))
|
||||
{
|
||||
const char *gdfolder = "the Ring Racers folder";
|
||||
if (strcmp(srb2home,"."))
|
||||
gdfolder = srb2home;
|
||||
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Not a valid Profile file.\nDelete %s (maybe in %s) and try again.", PROFILESFILE, gdfolder);
|
||||
}
|
||||
save_p += headerlen;
|
||||
|
||||
version = READUINT8(save_p);
|
||||
if (version > PROFILEVER)
|
||||
{
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Existing %s is from the future! (expected %d, got %d)", PROFILESFILE, PROFILEVER, version);
|
||||
}
|
||||
|
||||
numprofiles = READUINT8(save_p);
|
||||
if (numprofiles > MAXPROFILES)
|
||||
numprofiles = MAXPROFILES;
|
||||
|
||||
for (i = 1; i < numprofiles; i++)
|
||||
{
|
||||
profilesList[i] = Z_Malloc(sizeof(profile_t), PU_STATIC, NULL);
|
||||
|
||||
// Version.
|
||||
profilesList[i]->version = version;
|
||||
|
||||
// Names.
|
||||
READSTRINGN(save_p, profilesList[i]->profilename, PROFILENAMELEN);
|
||||
READSTRINGN(save_p, profilesList[i]->playername, MAXPLAYERNAME);
|
||||
|
||||
// Character and colour.
|
||||
READSTRINGN(save_p, profilesList[i]->skinname, SKINNAMESIZE);
|
||||
profilesList[i]->color = READUINT16(save_p);
|
||||
|
||||
if (profilesList[i]->color == SKINCOLOR_NONE)
|
||||
{
|
||||
; // Valid, even outside the bounds
|
||||
}
|
||||
else if (profilesList[i]->color >= numskincolors
|
||||
|| skincolors[profilesList[i]->color].accessible == false)
|
||||
{
|
||||
profilesList[i]->color = PROFILEDEFAULTCOLOR;
|
||||
}
|
||||
|
||||
// Follower and colour.
|
||||
READSTRINGN(save_p, profilesList[i]->follower, SKINNAMESIZE);
|
||||
profilesList[i]->followercolor = READUINT16(save_p);
|
||||
|
||||
if (profilesList[i]->followercolor == FOLLOWERCOLOR_MATCH
|
||||
|| profilesList[i]->followercolor == FOLLOWERCOLOR_OPPOSITE)
|
||||
{
|
||||
; // Valid, even outside the bounds
|
||||
}
|
||||
else if (profilesList[i]->followercolor >= numskincolors
|
||||
|| profilesList[i]->followercolor == SKINCOLOR_NONE
|
||||
|| skincolors[profilesList[i]->followercolor].accessible == false)
|
||||
{
|
||||
profilesList[i]->followercolor = PROFILEDEFAULTFOLLOWERCOLOR;
|
||||
}
|
||||
|
||||
// PWR.
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
{
|
||||
profilesList[i]->powerlevels[j] = READUINT16(save_p);
|
||||
if (profilesList[i]->powerlevels[j] < PWRLVRECORD_MIN
|
||||
|| profilesList[i]->powerlevels[j] > PWRLVRECORD_MAX)
|
||||
{
|
||||
// invalid, reset
|
||||
profilesList[i]->powerlevels[j] = PWRLVRECORD_START;
|
||||
}
|
||||
}
|
||||
|
||||
// Consvars.
|
||||
profilesList[i]->kickstartaccel = (boolean)READUINT8(save_p);
|
||||
|
||||
// Controls.
|
||||
for (j = 0; j < num_gamecontrols; j++)
|
||||
{
|
||||
for (k = 0; k < MAXINPUTMAPPING; k++)
|
||||
{
|
||||
profilesList[i]->controls[j][k] = READINT32(save_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the the default profile directly to avoid letting anyone tamper with it.
|
||||
profilesList[PROFILE_GUEST] = dprofile;
|
||||
}
|
||||
|
||||
skincolornum_t PR_GetProfileColor(profile_t *p)
|
||||
{
|
||||
if (p->color == SKINCOLOR_NONE)
|
||||
{
|
||||
// Get skin's prefcolor.
|
||||
INT32 foundskin = R_SkinAvailable(p->skinname);
|
||||
if (foundskin == -1)
|
||||
{
|
||||
// Return random default value
|
||||
return SKINCOLOR_RED;
|
||||
}
|
||||
|
||||
return skins[foundskin].prefcolor;
|
||||
}
|
||||
|
||||
// Get exact color.
|
||||
return p->color;
|
||||
}
|
||||
|
||||
static void PR_ApplyProfile_Appearance(profile_t *p, UINT8 playernum)
|
||||
{
|
||||
CV_StealthSet(&cv_skin[playernum], p->skinname);
|
||||
CV_StealthSetValue(&cv_playercolor[playernum], PR_GetProfileColor(p));
|
||||
CV_StealthSet(&cv_playername[playernum], p->playername);
|
||||
|
||||
// Followers
|
||||
CV_StealthSet(&cv_follower[playernum], p->follower);
|
||||
CV_StealthSetValue(&cv_followercolor[playernum], p->followercolor);
|
||||
}
|
||||
|
||||
static void PR_ApplyProfile_Settings(profile_t *p, UINT8 playernum)
|
||||
{
|
||||
// toggles
|
||||
CV_StealthSetValue(&cv_kickstartaccel[playernum], p->kickstartaccel);
|
||||
|
||||
// set controls...
|
||||
memcpy(&gamecontrol[playernum], p->controls, sizeof(gamecontroldefault));
|
||||
}
|
||||
|
||||
static void PR_ApplyProfile_Memory(UINT8 profilenum, UINT8 playernum)
|
||||
{
|
||||
// set memory cvar
|
||||
CV_StealthSetValue(&cv_lastprofile[playernum], profilenum);
|
||||
|
||||
// If we're doing this on P1, also change current profile.
|
||||
if (playernum == 0)
|
||||
{
|
||||
CV_StealthSetValue(&cv_currprofile, profilenum);
|
||||
}
|
||||
}
|
||||
|
||||
void PR_ApplyProfile(UINT8 profilenum, UINT8 playernum)
|
||||
{
|
||||
profile_t *p = PR_GetProfile(profilenum);
|
||||
|
||||
// this CAN happen!!
|
||||
if (p == NULL)
|
||||
{
|
||||
CONS_Printf("Profile '%d' could not be loaded as it does not exist. Guest Profile will be loaded instead.\n", profilenum);
|
||||
profilenum = 0; // make sure to set this so that the cvar is set properly.
|
||||
p = PR_GetProfile(profilenum);
|
||||
}
|
||||
|
||||
PR_ApplyProfile_Appearance(p, playernum);
|
||||
PR_ApplyProfile_Settings(p, playernum);
|
||||
PR_ApplyProfile_Memory(profilenum, playernum);
|
||||
}
|
||||
|
||||
void PR_ApplyProfileLight(UINT8 profilenum, UINT8 playernum)
|
||||
{
|
||||
profile_t *p = PR_GetProfile(profilenum);
|
||||
|
||||
// this CAN happen!!
|
||||
if (p == NULL)
|
||||
{
|
||||
// no need to be as loud...
|
||||
profilenum = 0; // make sure to set this so that the cvar is set properly.
|
||||
p = PR_GetProfile(profilenum);
|
||||
}
|
||||
|
||||
PR_ApplyProfile_Appearance(p, playernum);
|
||||
}
|
||||
|
||||
void PR_ApplyProfilePretend(UINT8 profilenum, UINT8 playernum)
|
||||
{
|
||||
profile_t *p = PR_GetProfile(profilenum);
|
||||
|
||||
// this CAN happen!!
|
||||
if (p == NULL)
|
||||
{
|
||||
CONS_Printf("Profile '%d' could not be loaded as it does not exist. Guest Profile will be loaded instead.\n", profilenum);
|
||||
profilenum = 0; // make sure to set this so that the cvar is set properly.
|
||||
p = PR_GetProfile(profilenum);
|
||||
}
|
||||
|
||||
PR_ApplyProfile_Memory(profilenum, playernum);
|
||||
}
|
||||
|
||||
UINT8 PR_GetProfileNum(profile_t *p)
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPROFILES+1; i++)
|
||||
{
|
||||
profile_t *comp = PR_GetProfile(i);
|
||||
if (comp == p)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SINT8 PR_ProfileUsedBy(profile_t *p)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 prn = PR_GetProfileNum(p);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (prn == cv_lastprofile[i].value)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
profile_t *PR_GetPlayerProfile(player_t *player)
|
||||
{
|
||||
const UINT8 playerNum = (player - players);
|
||||
UINT8 i;
|
||||
|
||||
if (demo.playback)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (playerNum == g_localplayers[i])
|
||||
{
|
||||
return PR_GetProfile(cv_lastprofile[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
155
src/k_profiles.h
Normal file
155
src/k_profiles.h
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh.
|
||||
// Copyright (C) 1999-2018 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_profiles.h
|
||||
/// \brief Control profiles definition
|
||||
|
||||
#ifndef __PROFILES_H__
|
||||
#define __PROFILES_H__
|
||||
|
||||
#include "doomdef.h" // MAXPLAYERNAME
|
||||
//#include "r_skins.h" // SKINNAMESIZE // This cuases stupid issues.
|
||||
#include "g_input.h" // Input related stuff
|
||||
#include "string.h" // strcpy etc
|
||||
#include "g_game.h" // game CVs
|
||||
#include "k_follower.h" // followers
|
||||
|
||||
// We have to redefine this because somehow including r_skins.h causes a redefinition of node_t since that's used for both net nodes and BSP nodes too......
|
||||
// And honestly I don't wanna refactor that.
|
||||
#define SKINNAMESIZE 16
|
||||
|
||||
#define PROFILENAMELEN 6
|
||||
#define PROFILEVER 1
|
||||
#define MAXPROFILES 16
|
||||
#define PROFILESFILE "ringprofiles.prf"
|
||||
#define PROFILE_GUEST 0
|
||||
|
||||
#define PROFILEDEFAULTNAME "GUEST"
|
||||
#define PROFILEDEFAULTPNAME "Guest"
|
||||
#define PROFILEDEFAULTSKIN "eggman"
|
||||
#define PROFILEDEFAULTCOLOR SKINCOLOR_NONE
|
||||
#define PROFILEDEFAULTFOLLOWER "none"
|
||||
#define PROFILEDEFAULTFOLLOWERCOLOR FOLLOWERCOLOR_MATCH
|
||||
|
||||
#define PROFILEHEADER "Doctor Robotnik's Ring Racers Profiles"
|
||||
|
||||
// Man I wish I had more than 16 friends!!
|
||||
|
||||
// profile_t definition (WIP)
|
||||
// If you edit, see PR_SaveProfiles and PR_LoadProfiles
|
||||
typedef struct profile_s
|
||||
{
|
||||
|
||||
// Versionning
|
||||
UINT8 version; // Version of the profile, this can be useful for backwards compatibility reading if we ever update the profile structure/format after release.
|
||||
// A version of 0 can easily be checked to identify an unitialized profile.
|
||||
|
||||
// Profile header
|
||||
char profilename[PROFILENAMELEN+1]; // Profile name (not to be confused with player name)
|
||||
|
||||
// Player data
|
||||
char playername[MAXPLAYERNAME+1]; // Player name
|
||||
char skinname[SKINNAMESIZE+1]; // Default Skin
|
||||
UINT16 color; // Default player coloUr. ...But for consistency we'll name it color.
|
||||
char follower[SKINNAMESIZE+1]; // Follower
|
||||
UINT16 followercolor; // Follower color
|
||||
|
||||
UINT16 powerlevels[PWRLV_NUMTYPES]; // PWRLV for each gametype.
|
||||
|
||||
// Player-specific consvars.
|
||||
// @TODO: List all of those
|
||||
boolean kickstartaccel; // cv_kickstartaccel
|
||||
|
||||
// Finally, control data itself
|
||||
INT32 controls[num_gamecontrols][MAXINPUTMAPPING]; // Lists of all the controls, defined the same way as default inputs in g_input.c
|
||||
} profile_t;
|
||||
|
||||
|
||||
// Functions
|
||||
|
||||
// returns how many profiles there are
|
||||
INT32 PR_GetNumProfiles(void);
|
||||
|
||||
// PR_MakeProfile
|
||||
// Makes a profile from the supplied profile name, player name, colour, follower, followercolour and controls.
|
||||
// The consvar values are left untouched.
|
||||
profile_t* PR_MakeProfile(
|
||||
const char *prname,
|
||||
const char *pname,
|
||||
const char *sname, const UINT16 col,
|
||||
const char *fname, const UINT16 fcol,
|
||||
INT32 controlarray[num_gamecontrols][MAXINPUTMAPPING],
|
||||
boolean guest
|
||||
);
|
||||
|
||||
// PR_MakeProfileFromPlayer
|
||||
// Makes a profile_t from the supplied profile name, player name, colour, follower and followercolour.
|
||||
// The last argument is a player number to read cvars from; as for convenience, cvars will be set directly when making a profile (since loading another one will overwrite them, this will be inconsequential)
|
||||
profile_t* PR_MakeProfileFromPlayer(const char *prname, const char *pname, const char *sname, const UINT16 col, const char *fname, UINT16 fcol, UINT8 pnum);
|
||||
|
||||
// PR_AddProfile(profile_t p)
|
||||
// Adds a profile to profilesList and increments numprofiles.
|
||||
// Returns true if succesful, false if not.
|
||||
boolean PR_AddProfile(profile_t *p);
|
||||
|
||||
// PR_GetProfile(INT32 num)
|
||||
// Returns a pointer to the profile you're asking for or NULL if the profile is uninitialized.
|
||||
profile_t* PR_GetProfile(INT32 num);
|
||||
|
||||
// PR_DeleteProfile(INT32 n)
|
||||
// Deletes the specified profile. n cannot be 0. Returns false if the profile couldn't be deleted, true otherwise.
|
||||
// This will also move every profile back accordingly to ensure the table has no empty profiles inbetween two valid profiles.
|
||||
boolean PR_DeleteProfile(INT32 n);
|
||||
|
||||
// PR_InitNewProfile(void)
|
||||
// Initializes the first new profile
|
||||
void PR_InitNewProfile(void);
|
||||
|
||||
// PR_SaveProfiles(void)
|
||||
// Saves all the profiles in profiles.cfg
|
||||
// This does not save profilesList[0] since that's always going to be the default profile.
|
||||
void PR_SaveProfiles(void);
|
||||
|
||||
// PR_LoadProfiles(void)
|
||||
// Loads all the profiles saved in profiles.cfg.
|
||||
// This also loads
|
||||
void PR_LoadProfiles(void);
|
||||
|
||||
// PR_GetProfileColor(profile_t *p)
|
||||
// Returns the profile's color, or the skin's prefcolor if set to none.
|
||||
skincolornum_t PR_GetProfileColor(profile_t *p);
|
||||
|
||||
// PR_ApplyProfile(UINT8 profilenum, UINT8 playernum)
|
||||
// Applies the given profile's settings to the given player.
|
||||
void PR_ApplyProfile(UINT8 profilenum, UINT8 playernum);
|
||||
|
||||
// PR_ApplyProfileLight(UINT8 profilenum, UINT8 playernum)
|
||||
// Similar to PR_ApplyProfile but only applies skin and follower values.
|
||||
// Controls, kickstartaccel and "current profile" data is *not* modified.
|
||||
void PR_ApplyProfileLight(UINT8 profilenum, UINT8 playernum);
|
||||
|
||||
// PR_ApplyProfilePretend(UINT8 profilenum, UINT8 playernum)
|
||||
// ONLY modifies "current profile" data.
|
||||
// Exists because any other option inteferes with rapid testing.
|
||||
void PR_ApplyProfilePretend(UINT8 profilenum, UINT8 playernum);
|
||||
|
||||
// PR_GetProfileNum(profile_t *p)
|
||||
// Gets the profile's index # in profilesList
|
||||
UINT8 PR_GetProfileNum(profile_t *p);
|
||||
|
||||
// PR_ProfileUsedBy(profile_t *p)
|
||||
// Returns the player # this profile is used by (if any)
|
||||
// If the profile belongs to no player, then this returns -1
|
||||
SINT8 PR_ProfileUsedBy(profile_t *p);
|
||||
|
||||
profile_t *PR_GetPlayerProfile(player_t *player);
|
||||
|
||||
#endif
|
||||
|
|
@ -17,10 +17,7 @@
|
|||
#include "p_tick.h" // leveltime
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
|
||||
// Online rankings for the main gametypes.
|
||||
// This array is saved to the gamedata.
|
||||
UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||
#include "k_profiles.h"
|
||||
|
||||
// Client-sided calculations done for Power Levels.
|
||||
// This is done so that clients will never be able to hack someone else's score over the server.
|
||||
|
|
@ -370,6 +367,7 @@ INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 baseInc)
|
|||
// Get at least one point.
|
||||
inc = 1;
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
// You trade points in 1v1s,
|
||||
|
|
@ -388,6 +386,7 @@ INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 baseInc)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (yourPower + inc > PWRLVRECORD_MAX)
|
||||
|
|
@ -416,14 +415,16 @@ void K_CashInPowerLevels(void)
|
|||
{
|
||||
if (playeringame[i] == true && powerType != PWRLV_DISABLED)
|
||||
{
|
||||
profile_t *pr = PR_GetPlayerProfile(&players[i]);
|
||||
INT16 inc = K_FinalPowerIncrement(&players[i], clientpowerlevels[i][powerType], clientPowerAdd[i]);
|
||||
|
||||
clientpowerlevels[i][powerType] += inc;
|
||||
|
||||
//CONS_Printf("%s: %d -> %d (%d)\n", player_names[i], clientpowerlevels[i][powerType] - inc, clientpowerlevels[i][powerType], inc);
|
||||
|
||||
if (!demo.playback && i == consoleplayer && inc != 0)
|
||||
if (pr != NULL && inc != 0)
|
||||
{
|
||||
vspowerlevel[powerType] = clientpowerlevels[i][powerType];
|
||||
pr->powerlevels[powerType] = clientpowerlevels[i][powerType];
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
{
|
||||
|
|
@ -567,6 +568,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
|||
|
||||
void K_PlayerForfeit(UINT8 playerNum, boolean pointLoss)
|
||||
{
|
||||
profile_t *pr;
|
||||
UINT8 p = 0;
|
||||
|
||||
SINT8 powerType = PWRLV_DISABLED;
|
||||
|
|
@ -631,17 +633,22 @@ void K_PlayerForfeit(UINT8 playerNum, boolean pointLoss)
|
|||
K_UpdatePowerLevelsOnFailure(&players[playerNum]);
|
||||
inc = K_FinalPowerIncrement(&players[playerNum], yourPower, clientPowerAdd[playerNum]);
|
||||
|
||||
if (inc >= 0)
|
||||
if (inc == 0)
|
||||
{
|
||||
// Don't record no change or increases.
|
||||
// No change
|
||||
return;
|
||||
}
|
||||
|
||||
// pointLoss isn't set for stuff like sync-outs,
|
||||
// which shouldn't be so harsh on the victim!
|
||||
if (!demo.playback && pointLoss == true && playerNum == consoleplayer)
|
||||
if (inc < 0 && pointLoss == false)
|
||||
{
|
||||
vspowerlevel[powerType] = yourPower + inc;
|
||||
// Don't record point losses for sync-out / crashes.
|
||||
return;
|
||||
}
|
||||
|
||||
pr = PR_GetPlayerProfile(&players[playerNum]);
|
||||
if (pr != NULL)
|
||||
{
|
||||
pr->powerlevels[powerType] = yourPower + inc;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ typedef enum
|
|||
extern SINT8 speedscramble;
|
||||
extern SINT8 encorescramble;
|
||||
|
||||
extern UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||
extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
||||
extern INT16 clientPowerAdd[MAXPLAYERS];
|
||||
extern UINT8 spectateGriefed;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "m_random.h"
|
||||
#include "s_sound.h"
|
||||
#include "g_game.h"
|
||||
#include "m_menu.h"
|
||||
#include "y_inter.h"
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "console.h"
|
||||
|
|
@ -33,7 +32,7 @@
|
|||
#include "k_color.h"
|
||||
#include "k_hud.h"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "m_menu.h" // Player Setup menu color stuff
|
||||
#include "k_menu.h" // Player Setup menu color stuff
|
||||
#include "m_misc.h" // M_MapNumber
|
||||
#include "p_spec.h" // P_StartQuake
|
||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||
|
|
@ -356,14 +355,26 @@ static int lib_pMoveColorAfter(lua_State *L)
|
|||
static int lib_pGetColorBefore(lua_State *L)
|
||||
{
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
|
||||
lua_pushinteger(L, M_GetColorBefore(color));
|
||||
UINT16 amount = (UINT16)luaL_checkinteger(L, 2);
|
||||
boolean follower = lua_optboolean(L, 3);
|
||||
lua_pushinteger(L, M_GetColorBefore(color, amount, follower));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pGetColorAfter(lua_State *L)
|
||||
{
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
|
||||
lua_pushinteger(L, M_GetColorAfter(color));
|
||||
UINT16 amount = (UINT16)luaL_checkinteger(L, 2);
|
||||
boolean follower = lua_optboolean(L, 3);
|
||||
lua_pushinteger(L, M_GetColorAfter(color, amount, follower));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pGetEffectiveFollowerColor(lua_State *L)
|
||||
{
|
||||
UINT16 followercolor = (UINT16)luaL_checkinteger(L, 1);
|
||||
UINT16 playercolor = (UINT16)luaL_checkinteger(L, 2);
|
||||
lua_pushinteger(L, K_GetEffectiveFollowerColor(followercolor, playercolor));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -3339,23 +3350,37 @@ static int lib_kOvertakeSound(lua_State *L)
|
|||
static int lib_kPainSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *other = NULL;
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayPainSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayPainSound(mobj);
|
||||
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
|
||||
other = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
K_PlayPainSound(mobj, other);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kHitEmSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *victim = NULL;
|
||||
mobj_t *other = NULL;
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
|
||||
victim = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
K_PlayHitEmSound(mobj, victim);
|
||||
other = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
K_PlayHitEmSound(mobj, other);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kTryHurtSoundExchange(lua_State *L)
|
||||
{
|
||||
mobj_t *victim = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *attacker = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
NOHUD
|
||||
if (!victim->player)
|
||||
return luaL_error(L, "K_TryHurtSoundExchange: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_TryHurtSoundExchange(victim, attacker);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3896,6 +3921,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_ReturnThrustX",lib_pReturnThrustX},
|
||||
{"P_ReturnThrustY",lib_pReturnThrustY},
|
||||
{"P_NukeEnemies",lib_pNukeEnemies},
|
||||
{"K_GetEffectiveFollowerColor",lib_pGetEffectiveFollowerColor},
|
||||
|
||||
// p_map
|
||||
{"P_CheckPosition",lib_pCheckPosition},
|
||||
|
|
@ -4037,6 +4063,7 @@ static luaL_Reg lib[] = {
|
|||
{"K_PlayLossSound", lib_kLossSound},
|
||||
{"K_PlayPainSound", lib_kPainSound},
|
||||
{"K_PlayHitEmSound", lib_kHitEmSound},
|
||||
{"K_TryHurtSoundExchange", lib_kTryHurtSoundExchange},
|
||||
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
||||
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
|
||||
{"K_KartBouncing",lib_kKartBouncing},
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->spindashspeed);
|
||||
else if (fastcmp(field,"spindashboost"))
|
||||
lua_pushinteger(L, plr->spindashboost);
|
||||
else if (fastcmp(field,"fastfall"))
|
||||
lua_pushfixed(L, plr->fastfall);
|
||||
else if (fastcmp(field,"numboosts"))
|
||||
lua_pushinteger(L, plr->numboosts);
|
||||
else if (fastcmp(field,"boostpower"))
|
||||
|
|
@ -360,10 +362,10 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->lastjawztarget);
|
||||
else if (fastcmp(field,"jawztargetdelay"))
|
||||
lua_pushinteger(L, plr->jawztargetdelay);
|
||||
else if (fastcmp(field,"confirmInflictor"))
|
||||
lua_pushinteger(L, plr->confirmInflictor);
|
||||
else if (fastcmp(field,"confirmInflictorDelay"))
|
||||
lua_pushinteger(L, plr->confirmInflictorDelay);
|
||||
else if (fastcmp(field,"confirmVictim"))
|
||||
lua_pushinteger(L, plr->confirmVictim);
|
||||
else if (fastcmp(field,"confirmVictimDelay"))
|
||||
lua_pushinteger(L, plr->confirmVictimDelay);
|
||||
else if (fastcmp(field,"glanceDir"))
|
||||
lua_pushinteger(L, plr->glanceDir);
|
||||
else if (fastcmp(field,"trickpanel"))
|
||||
|
|
@ -632,6 +634,8 @@ static int player_set(lua_State *L)
|
|||
plr->spindashspeed = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spindashboost"))
|
||||
plr->spindashboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"fastfall"))
|
||||
plr->fastfall = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"numboosts"))
|
||||
plr->numboosts = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"boostpower"))
|
||||
|
|
@ -718,10 +722,10 @@ static int player_set(lua_State *L)
|
|||
plr->lastjawztarget = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"jawztargetdelay"))
|
||||
plr->jawztargetdelay = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"confirmInflictor"))
|
||||
plr->confirmInflictor = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"confirmInflictorDelay"))
|
||||
plr->confirmInflictorDelay = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"confirmVictim"))
|
||||
plr->confirmVictim = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"confirmVictimDelay"))
|
||||
plr->confirmVictimDelay = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"glanceDir"))
|
||||
plr->glanceDir = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"trickpanel"))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "d_net.h"
|
||||
|
||||
#include "m_cheat.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_random.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
|
|
@ -58,20 +58,6 @@ typedef struct
|
|||
// ==========================================================================
|
||||
|
||||
// Cheat responders
|
||||
/*static UINT8 cheatf_ultimate(void)
|
||||
{
|
||||
if (menuactive && (currentMenu != &MainDef && currentMenu != &SP_LoadDef))
|
||||
return 0; // Only on the main menu, or the save select!
|
||||
|
||||
BwehHehHe();
|
||||
ultimate_selectable = (!ultimate_selectable);
|
||||
|
||||
// If on the save select, move to what is now Ultimate Mode!
|
||||
if (currentMenu == &SP_LoadDef)
|
||||
M_ForceSaveSlotSelected(NOSAVESLOT);
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
static UINT8 cheatf_warp(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
@ -83,7 +69,7 @@ static UINT8 cheatf_warp(void)
|
|||
if (menuactive && currentMenu != &MainDef)
|
||||
return 0; // Only on the main menu!
|
||||
|
||||
// Temporarily unlock EVERYTHING.
|
||||
// Unlock EVERYTHING.
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
if (!unlockables[i].conditionset)
|
||||
|
|
@ -134,18 +120,6 @@ static UINT8 cheatf_devmode(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*static cheatseq_t cheat_ultimate = {
|
||||
0, cheatf_ultimate,
|
||||
{ SCRAMBLE('u'), SCRAMBLE('l'), SCRAMBLE('t'), SCRAMBLE('i'), SCRAMBLE('m'), SCRAMBLE('a'), SCRAMBLE('t'), SCRAMBLE('e'), 0xff }
|
||||
};*/
|
||||
|
||||
/*static cheatseq_t cheat_ultimate_joy = {
|
||||
0, cheatf_ultimate,
|
||||
{ SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_DOWNARROW), SCRAMBLE(KEY_DOWNARROW),
|
||||
SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_RIGHTARROW), SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_RIGHTARROW),
|
||||
SCRAMBLE(KEY_ENTER), 0xff }
|
||||
};*/
|
||||
|
||||
static cheatseq_t cheat_warp = {
|
||||
0, cheatf_warp,
|
||||
//{ SCRAMBLE('r'), SCRAMBLE('e'), SCRAMBLE('d'), SCRAMBLE('x'), SCRAMBLE('v'), SCRAMBLE('i'), 0xff }
|
||||
|
|
@ -253,8 +227,6 @@ boolean cht_Responder(event_t *ev)
|
|||
else
|
||||
ch = (UINT8)ev->data1;
|
||||
|
||||
//ret += cht_CheckCheat(&cheat_ultimate, (char)ch);
|
||||
//ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch);
|
||||
ret += cht_CheckCheat(&cheat_warp, (char)ch);
|
||||
ret += cht_CheckCheat(&cheat_warp_joy, (char)ch);
|
||||
#ifdef DEVELOP
|
||||
|
|
|
|||
26
src/m_cond.c
26
src/m_cond.c
|
|
@ -20,7 +20,9 @@
|
|||
#include "g_game.h" // record info
|
||||
#include "r_skins.h" // numskins
|
||||
#include "r_draw.h" // R_GetColorByName
|
||||
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_profiles.h"
|
||||
|
||||
// Map triggers for linedef executors
|
||||
// 32 triggers, one bit each
|
||||
|
|
@ -108,7 +110,20 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
||||
return (matchesplayed >= (unsigned)cn->requirement);
|
||||
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
||||
return (vspowerlevel[cn->extrainfo1] >= (unsigned)cn->requirement);
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = PROFILE_GUEST; i < PR_GetNumProfiles(); i++)
|
||||
{
|
||||
profile_t *p = PR_GetProfile(i);
|
||||
|
||||
if (p->powerlevels[cn->extrainfo1] >= (unsigned)cn->requirement)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
case UC_GAMECLEAR: // Requires game beaten >= x times
|
||||
return (timesBeaten >= (unsigned)cn->requirement);
|
||||
case UC_OVERALLTIME: // Requires overall time <= x
|
||||
|
|
@ -359,10 +374,14 @@ UINT8 M_SecretUnlocked(INT32 type)
|
|||
{
|
||||
INT32 i;
|
||||
|
||||
#if 1
|
||||
if (dedicated)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
(void)type;
|
||||
(void)i;
|
||||
return false; // for quick testing
|
||||
#else
|
||||
|
||||
#ifdef DEVELOP
|
||||
#define CHADYES true
|
||||
|
|
@ -378,6 +397,7 @@ UINT8 M_SecretUnlocked(INT32 type)
|
|||
return CHADYES;
|
||||
|
||||
#undef CHADYES
|
||||
#endif //if 0
|
||||
}
|
||||
|
||||
UINT8 M_MapLocked(INT32 mapnum)
|
||||
|
|
|
|||
11586
src/m_menu.c
11586
src/m_menu.c
File diff suppressed because it is too large
Load diff
590
src/m_menu.h
590
src/m_menu.h
|
|
@ -1,590 +0,0 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh.
|
||||
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file m_menu.h
|
||||
/// \brief Menu widget stuff, selection and such
|
||||
|
||||
#ifndef __X_MENU__
|
||||
#define __X_MENU__
|
||||
|
||||
#include "doomstat.h" // for NUMGAMETYPES
|
||||
#include "d_event.h"
|
||||
#include "command.h"
|
||||
#include "f_finale.h" // for ttmode_enum
|
||||
#include "i_threads.h"
|
||||
#include "mserv.h"
|
||||
#include "r_skins.h" // for SKINNAMESIZE
|
||||
|
||||
// Compatibility with old-style named NiGHTS replay files.
|
||||
#define OLDNREPLAYNAME
|
||||
|
||||
//
|
||||
// MENUS
|
||||
//
|
||||
|
||||
// If menu hierarchies go deeper, change this up to 5.
|
||||
// Zero-based, inclusive.
|
||||
#define NUMMENULEVELS 3
|
||||
#define MENUBITS 6
|
||||
|
||||
// Menu IDs sectioned by numeric places to signify hierarchy
|
||||
/**
|
||||
* IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MN_NONE,
|
||||
|
||||
MN_MAIN,
|
||||
|
||||
// Single Player
|
||||
MN_SP_MAIN,
|
||||
|
||||
MN_SP_LOAD,
|
||||
MN_SP_PLAYER,
|
||||
|
||||
MN_SP_LEVELSELECT,
|
||||
MN_SP_LEVELSTATS,
|
||||
|
||||
MN_SP_TIMEATTACK,
|
||||
MN_SP_TIMEATTACK_LEVELSELECT,
|
||||
MN_SP_GUESTREPLAY,
|
||||
MN_SP_REPLAY,
|
||||
MN_SP_GHOST,
|
||||
|
||||
MN_SP_NIGHTSATTACK,
|
||||
MN_SP_NIGHTS_LEVELSELECT,
|
||||
MN_SP_NIGHTS_GUESTREPLAY,
|
||||
MN_SP_NIGHTS_REPLAY,
|
||||
MN_SP_NIGHTS_GHOST,
|
||||
|
||||
MN_SP_MARATHON,
|
||||
|
||||
// Multiplayer
|
||||
MN_MP_MAIN,
|
||||
MN_MP_SPLITSCREEN, // SplitServer
|
||||
MN_MP_SERVER,
|
||||
MN_MP_CONNECT,
|
||||
MN_MP_ROOM,
|
||||
MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
||||
MN_MP_SERVER_OPTIONS,
|
||||
|
||||
// Options
|
||||
MN_OP_MAIN,
|
||||
|
||||
MN_OP_P1CONTROLS,
|
||||
MN_OP_CHANGECONTROLS, // OP_ChangeControlsDef shared with P2
|
||||
MN_OP_P1MOUSE,
|
||||
MN_OP_P1JOYSTICK,
|
||||
MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2
|
||||
MN_OP_P1CAMERA,
|
||||
|
||||
MN_OP_P2CONTROLS,
|
||||
MN_OP_P2MOUSE,
|
||||
MN_OP_P2JOYSTICK,
|
||||
MN_OP_P2CAMERA,
|
||||
|
||||
MN_OP_PLAYSTYLE,
|
||||
|
||||
MN_OP_VIDEO,
|
||||
MN_OP_VIDEOMODE,
|
||||
MN_OP_COLOR,
|
||||
MN_OP_OPENGL,
|
||||
MN_OP_OPENGL_LIGHTING,
|
||||
|
||||
MN_OP_SOUND,
|
||||
|
||||
MN_OP_SERVER,
|
||||
MN_OP_MONITORTOGGLE,
|
||||
|
||||
MN_OP_DATA,
|
||||
MN_OP_ADDONS,
|
||||
MN_OP_SCREENSHOTS,
|
||||
MN_OP_ERASEDATA,
|
||||
|
||||
// Extras
|
||||
MN_SR_MAIN,
|
||||
MN_SR_PANDORA,
|
||||
MN_SR_LEVELSELECT,
|
||||
MN_SR_UNLOCKCHECKLIST,
|
||||
MN_SR_EMBLEMHINT,
|
||||
MN_SR_PLAYER,
|
||||
MN_SR_SOUNDTEST,
|
||||
|
||||
// Addons (Part of MISC, but let's make it our own)
|
||||
MN_AD_MAIN,
|
||||
|
||||
// MISC
|
||||
// MN_MESSAGE,
|
||||
// MN_SPAUSE,
|
||||
|
||||
// MN_MPAUSE,
|
||||
// MN_SCRAMBLETEAM,
|
||||
// MN_CHANGETEAM,
|
||||
// MN_CHANGELEVEL,
|
||||
|
||||
// MN_MAPAUSE,
|
||||
// MN_HELP,
|
||||
|
||||
MN_SPECIAL,
|
||||
NUMMENUTYPES,
|
||||
} menutype_t; // up to 63; MN_SPECIAL = 53
|
||||
#define MTREE2(a,b) (a | (b<<MENUBITS))
|
||||
#define MTREE3(a,b,c) MTREE2(a, MTREE2(b,c))
|
||||
#define MTREE4(a,b,c,d) MTREE2(a, MTREE3(b,c,d))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char bgname[8]; // name for background gfx lump; lays over titlemap if this is set
|
||||
SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined
|
||||
INT32 bgcolor; // fill color, overrides bg name. -1 means follow bg name rules.
|
||||
INT32 titlescrollxspeed; // background gfx scroll per menu; inherits global setting
|
||||
INT32 titlescrollyspeed; // y scroll
|
||||
boolean bghide; // for titlemaps, hide the background.
|
||||
|
||||
SINT8 hidetitlepics; // hide title gfx per menu; -1 means undefined, inherits global setting
|
||||
ttmode_enum ttmode; // title wing animation mode; default TTMODE_OLD
|
||||
UINT8 ttscale; // scale of title wing gfx (FRACUNIT / ttscale); -1 means undefined, inherits global setting
|
||||
char ttname[9]; // lump name of title wing gfx. If name length is <= 6, engine will attempt to load numbered frames (TTNAMExx)
|
||||
INT16 ttx; // X position of title wing
|
||||
INT16 tty; // Y position of title wing
|
||||
INT16 ttloop; // # frame to loop; -1 means dont loop
|
||||
UINT16 tttics; // # of tics per frame
|
||||
|
||||
char musname[7]; ///< Music track to play. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
boolean muslooping; ///< Loop the music
|
||||
boolean musstop; ///< Don't play any music
|
||||
boolean musignore; ///< Let the current music keep playing
|
||||
|
||||
boolean enterbubble; // run all entrance line execs after common ancestor and up to child. If false, only run the child's exec
|
||||
boolean exitbubble; // run all exit line execs from child and up to before common ancestor. If false, only run the child's exec
|
||||
INT32 entertag; // line exec to run on menu enter, if titlemap
|
||||
INT32 exittag; // line exec to run on menu exit, if titlemap
|
||||
INT16 enterwipe; // wipe type to run on menu enter, -1 means default
|
||||
INT16 exitwipe; // wipe type to run on menu exit, -1 means default
|
||||
} menupres_t;
|
||||
|
||||
extern menupres_t menupres[NUMMENUTYPES];
|
||||
extern UINT32 prevMenuId;
|
||||
extern UINT32 activeMenuId;
|
||||
|
||||
void M_InitMenuPresTables(void);
|
||||
//UINT8 M_GetYoungestChildMenu(void);
|
||||
//void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping);
|
||||
//void M_SetMenuCurBackground(const char *defaultname);
|
||||
//void M_SetMenuCurFadeValue(UINT8 defaultvalue);
|
||||
//void M_SetMenuCurTitlePics(void);
|
||||
|
||||
// Called by main loop,
|
||||
// saves config file and calls I_Quit when user exits.
|
||||
// Even when the menu is not displayed,
|
||||
// this can resize the view and change game parameters.
|
||||
// Does all the real work of the menu interaction.
|
||||
boolean M_Responder(event_t *ev);
|
||||
|
||||
// Called by main loop, runs for demo playback. If this returns true, nullify any further user input.
|
||||
boolean M_DemoResponder(event_t *ev);
|
||||
|
||||
// Called by main loop, only used for menu (skull cursor) animation.
|
||||
void M_Ticker(void);
|
||||
|
||||
// Called by main loop, draws the menus directly into the screen buffer.
|
||||
void M_Drawer(void);
|
||||
|
||||
// Called by D_SRB2Main, loads the config file.
|
||||
void M_Init(void);
|
||||
|
||||
// Called by D_SRB2Main also, sets up the playermenu and description tables.
|
||||
void M_InitCharacterTables(void);
|
||||
|
||||
// Called by intro code to force menu up upon a keypress,
|
||||
// does nothing if menu is already up.
|
||||
void M_StartControlPanel(void);
|
||||
|
||||
// Called upon end of a mode attack run
|
||||
void M_EndModeAttackRun(void);
|
||||
|
||||
// Called on new server add, or other reasons
|
||||
void M_SortServerList(void);
|
||||
|
||||
// Draws a box with a texture inside as background for messages
|
||||
void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines);
|
||||
|
||||
// Used in d_netcmd to restart time attack
|
||||
void M_ModeAttackRetry(INT32 choice);
|
||||
|
||||
// the function to show a message box typing with the string inside
|
||||
// string must be static (not in the stack)
|
||||
// routine is a function taking a INT32 in parameter
|
||||
typedef enum
|
||||
{
|
||||
MM_NOTHING = 0, // is just displayed until the user do someting
|
||||
MM_YESNO, // routine is called with only 'y' or 'n' in param
|
||||
MM_EVENTHANDLER // the same of above but without 'y' or 'n' restriction
|
||||
// and routine is void routine(event_t *) (ex: set control)
|
||||
} menumessagetype_t;
|
||||
void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
M_NOT_WAITING,
|
||||
|
||||
M_WAITING_VERSION,
|
||||
M_WAITING_SERVERS,
|
||||
}
|
||||
M_waiting_mode_t;
|
||||
|
||||
extern M_waiting_mode_t m_waiting_mode;
|
||||
|
||||
// Called by linux_x/i_video_xshm.c
|
||||
void M_QuitResponse(INT32 ch);
|
||||
|
||||
// Determines whether to show a level in the list (platter version does not need to be exposed)
|
||||
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||
|
||||
// flags for items in the menu
|
||||
// menu handle (what we do when key is pressed
|
||||
#define IT_TYPE 15 // (1+2+4+8)
|
||||
#define IT_CALL 0 // call the function
|
||||
#define IT_SPACE 1 // no handling
|
||||
#define IT_ARROWS 2 // call function with 0 for left arrow and 1 for right arrow in param
|
||||
#define IT_KEYHANDLER 4 // call with the key in param
|
||||
#define IT_SUBMENU 6 // go to sub menu
|
||||
#define IT_CVAR 8 // handle as a cvar
|
||||
#define IT_PAIR 11 // no handling, define both sides of text
|
||||
#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message)
|
||||
|
||||
#define IT_DISPLAY (48+64+128) // 16+32+64+128
|
||||
#define IT_NOTHING 0 // space
|
||||
#define IT_PATCH 16 // a patch or a string with big font
|
||||
#define IT_STRING 32 // little string (spaced with 10)
|
||||
#define IT_WHITESTRING 48 // little string in white
|
||||
#define IT_DYBIGSPACE 64 // same as noting
|
||||
#define IT_DYLITLSPACE (16+64) // little space
|
||||
#define IT_STRING2 (32+64) // a simple string
|
||||
#define IT_GRAYPATCH (16+32+64) // grayed patch or big font string
|
||||
#define IT_BIGSLIDER 128 // volume sound use this
|
||||
#define IT_TRANSTEXT (16+128) // Transparent text
|
||||
#define IT_TRANSTEXT2 (32+128) // used for control names
|
||||
#define IT_HEADERTEXT (48+128) // Non-selectable header option, displays in yellow offset to the left a little
|
||||
#define IT_QUESTIONMARKS (64+128) // Displays as question marks, used for secrets
|
||||
#define IT_CENTER 256 // if IT_PATCH, center it on screen
|
||||
|
||||
//consvar specific
|
||||
#define IT_CVARTYPE (512+1024+2048)
|
||||
#define IT_CV_NORMAL 0
|
||||
#define IT_CV_SLIDER 512
|
||||
#define IT_CV_STRING 1024
|
||||
#define IT_CV_NOPRINT 1536
|
||||
#define IT_CV_NOMOD 2048
|
||||
#define IT_CV_INVISSLIDER 2560
|
||||
#define IT_CV_INTEGERSTEP 4096 // if IT_CV_NORMAL and cvar is CV_FLOAT, modify it by 1 instead of 0.0625
|
||||
#define IT_CV_FLOATSLIDER 4608 // IT_CV_SLIDER, value modified by 0.0625 instead of 1 (for CV_FLOAT cvars)
|
||||
|
||||
//call/submenu specific
|
||||
// There used to be a lot more here but ...
|
||||
// A lot of them became redundant with the advent of the Pause menu, so they were removed
|
||||
#define IT_CALLTYPE (512+1024)
|
||||
#define IT_CALL_NORMAL 0
|
||||
#define IT_CALL_NOTMODIFIED 512
|
||||
|
||||
// in INT16 for some common use
|
||||
#define IT_BIGSPACE (IT_SPACE +IT_DYBIGSPACE)
|
||||
#define IT_LITLSPACE (IT_SPACE +IT_DYLITLSPACE)
|
||||
#define IT_CONTROL (IT_STRING2+IT_CALL)
|
||||
#define IT_CVARMAX (IT_CVAR +IT_CV_NOMOD)
|
||||
#define IT_DISABLED (IT_SPACE +IT_GRAYPATCH)
|
||||
#define IT_GRAYEDOUT (IT_SPACE +IT_TRANSTEXT)
|
||||
#define IT_GRAYEDOUT2 (IT_SPACE +IT_TRANSTEXT2)
|
||||
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
||||
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
||||
|
||||
#define MAXSTRINGLENGTH 32
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct menu_s *submenu; // IT_SUBMENU
|
||||
consvar_t *cvar; // IT_CVAR
|
||||
void (*routine)(INT32 choice); // IT_CALL, IT_KEYHANDLER, IT_ARROWS
|
||||
void (*eventhandler)(event_t *ev); // MM_EVENTHANDLER
|
||||
} itemaction_t;
|
||||
|
||||
//
|
||||
// MENU TYPEDEFS
|
||||
//
|
||||
typedef struct menuitem_s
|
||||
{
|
||||
// show IT_xxx
|
||||
UINT16 status;
|
||||
|
||||
const char *patch;
|
||||
const char *text; // used when FONTBxx lump is found
|
||||
|
||||
itemaction_t itemaction;
|
||||
|
||||
// hotkey in menu or y of the item
|
||||
UINT16 alphaKey;
|
||||
} menuitem_t;
|
||||
|
||||
typedef struct menu_s
|
||||
{
|
||||
UINT32 menuid; // ID to encode menu type and hierarchy
|
||||
const char *menutitlepic;
|
||||
INT16 numitems; // # of menu items
|
||||
struct menu_s *prevMenu; // previous menu
|
||||
menuitem_t *menuitems; // menu items
|
||||
void (*drawroutine)(void); // draw routine
|
||||
INT16 x, y; // x, y of menu
|
||||
INT16 lastOn; // last item user was on in menu
|
||||
boolean (*quitroutine)(void); // called before quit a menu return true if we can
|
||||
} menu_t;
|
||||
|
||||
void M_SetupNextMenu(menu_t *menudef);
|
||||
void M_ClearMenus(boolean callexitmenufunc);
|
||||
|
||||
// Maybe this goes here????? Who knows.
|
||||
boolean M_MouseNeeded(void);
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
extern I_mutex m_menu_mutex;
|
||||
#endif
|
||||
|
||||
extern menu_t *currentMenu;
|
||||
|
||||
extern menu_t MainDef;
|
||||
extern menu_t SP_LoadDef;
|
||||
|
||||
// Call upon joystick hotplug
|
||||
void M_SetupJoystickMenu(INT32 choice);
|
||||
extern menu_t OP_JoystickSetDef;
|
||||
|
||||
// Stuff for customizing the player select screen
|
||||
typedef struct
|
||||
{
|
||||
boolean used;
|
||||
char notes[441];
|
||||
char picname[8];
|
||||
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
|
||||
patch_t *charpic;
|
||||
UINT8 prev;
|
||||
UINT8 next;
|
||||
|
||||
// new character select
|
||||
char displayname[SKINNAMESIZE+1];
|
||||
SINT8 skinnum[2];
|
||||
UINT16 oppositecolor;
|
||||
char nametag[8];
|
||||
patch_t *namepic;
|
||||
UINT16 tagtextcolor;
|
||||
UINT16 tagoutlinecolor;
|
||||
} description_t;
|
||||
|
||||
// level select platter
|
||||
typedef struct
|
||||
{
|
||||
char header[22+5]; // mapheader_t lvltttl max length + " ZONE"
|
||||
INT32 maplist[3];
|
||||
char mapnames[3][17+1];
|
||||
boolean mapavailable[4]; // mapavailable[3] == wide or not
|
||||
} levelselectrow_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 numrows;
|
||||
levelselectrow_t *rows;
|
||||
} levelselect_t;
|
||||
// experimental level select end
|
||||
|
||||
// descriptions for gametype select screen
|
||||
/*typedef struct
|
||||
{
|
||||
UINT8 col[2];
|
||||
char notes[441];
|
||||
} gtdesc_t;
|
||||
extern gtdesc_t gametypedesc[NUMGAMETYPES];*/
|
||||
|
||||
// mode descriptions for video mode menu
|
||||
typedef struct
|
||||
{
|
||||
INT32 modenum; // video mode number in the vidmodes list
|
||||
const char *desc; // XXXxYYY
|
||||
UINT8 goodratio; // aspect correct if 1
|
||||
} modedesc_t;
|
||||
|
||||
// savegame struct for save game menu
|
||||
typedef struct
|
||||
{
|
||||
char levelname[32];
|
||||
UINT8 skinnum;
|
||||
UINT8 numemeralds;
|
||||
UINT8 numgameovers;
|
||||
INT32 lives;
|
||||
INT32 continuescore;
|
||||
INT32 gamemap;
|
||||
} saveinfo_t;
|
||||
|
||||
extern description_t description[MAXSKINS];
|
||||
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||
extern CV_PossibleValue_t gametype_cons_t[];
|
||||
|
||||
extern char dummystaffname[22];
|
||||
|
||||
extern INT16 startmap;
|
||||
extern INT32 ultimate_selectable;
|
||||
extern INT16 char_on, startchar;
|
||||
|
||||
#define MAXSAVEGAMES 31
|
||||
#define NOSAVESLOT 0 //slot where Play Without Saving appears
|
||||
#define MARATHONSLOT 420 // just has to be nonzero, but let's use one that'll show up as an obvious error if something goes wrong while not using our existing saves
|
||||
|
||||
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he
|
||||
|
||||
//void M_TutorialSaveControlResponse(INT32 ch);
|
||||
|
||||
void M_ForceSaveSlotSelected(INT32 sslot);
|
||||
|
||||
void M_CheatActivationResponder(INT32 ch);
|
||||
|
||||
void M_ModeAttackRetry(INT32 choice);
|
||||
|
||||
// Level select updating
|
||||
void Nextmap_OnChange(void);
|
||||
|
||||
// Screenshot menu updating
|
||||
void Moviemode_mode_Onchange(void);
|
||||
void Screenshot_option_Onchange(void);
|
||||
|
||||
// Addons menu updating
|
||||
void Addons_option_Onchange(void);
|
||||
|
||||
void M_ReplayHut(INT32 choice);
|
||||
void M_SetPlaybackMenuPointer(void);
|
||||
|
||||
void M_RefreshPauseMenu(void);
|
||||
|
||||
INT32 HU_GetHighlightColor(void);
|
||||
|
||||
// Moviemode menu updating
|
||||
void Moviemode_option_Onchange(void);
|
||||
|
||||
// Player Setup menu colors linked list
|
||||
typedef struct menucolor_s {
|
||||
struct menucolor_s *next;
|
||||
struct menucolor_s *prev;
|
||||
UINT16 color;
|
||||
} menucolor_t;
|
||||
|
||||
extern menucolor_t *menucolorhead, *menucolortail;
|
||||
|
||||
void M_AddMenuColor(UINT16 color);
|
||||
void M_MoveColorBefore(UINT16 color, UINT16 targ);
|
||||
void M_MoveColorAfter(UINT16 color, UINT16 targ);
|
||||
UINT16 M_GetColorBefore(UINT16 color);
|
||||
UINT16 M_GetColorAfter(UINT16 color);
|
||||
void M_InitPlayerSetupColors(void);
|
||||
void M_FreePlayerSetupColors(void);
|
||||
|
||||
// These defines make it a little easier to make menus
|
||||
#define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\
|
||||
{\
|
||||
id,\
|
||||
header,\
|
||||
sizeof(source)/sizeof(menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawGenericMenu,\
|
||||
x, y,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define DEFAULTSCROLLMENUSTYLE(id, header, source, prev, x, y)\
|
||||
{\
|
||||
id,\
|
||||
header,\
|
||||
sizeof(source)/sizeof(menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawGenericScrollMenu,\
|
||||
x, y,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define PAUSEMENUSTYLE(source, x, y)\
|
||||
{\
|
||||
MN_SPECIAL,\
|
||||
NULL,\
|
||||
sizeof(source)/sizeof(menuitem_t),\
|
||||
NULL,\
|
||||
source,\
|
||||
M_DrawPauseMenu,\
|
||||
x, y,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define CENTERMENUSTYLE(id, header, source, prev, y)\
|
||||
{\
|
||||
id,\
|
||||
header,\
|
||||
sizeof(source)/sizeof(menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawCenteredMenu,\
|
||||
BASEVIDWIDTH/2, y,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define MAPICONMENUSTYLE(header, source, prev)\
|
||||
{\
|
||||
MN_NONE,\
|
||||
header,\
|
||||
sizeof (source)/sizeof (menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawServerMenu,\
|
||||
24,40,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define CONTROLMENUSTYLE(id, source, prev)\
|
||||
{\
|
||||
id,\
|
||||
"M_CONTRO",\
|
||||
sizeof (source)/sizeof (menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawControl,\
|
||||
26, 40,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define IMAGEDEF(source)\
|
||||
{\
|
||||
MN_SPECIAL,\
|
||||
NULL,\
|
||||
sizeof (source)/sizeof (menuitem_t),\
|
||||
NULL,\
|
||||
source,\
|
||||
M_DrawImageDef,\
|
||||
0, 0,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#endif //__X_MENU__
|
||||
148
src/m_misc.c
148
src/m_misc.c
|
|
@ -46,7 +46,7 @@
|
|||
#include "m_anigif.h"
|
||||
|
||||
// So that the screenshot menu auto-updates...
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
|
@ -181,6 +181,51 @@ boolean takescreenshot = false; // Take a screenshot this tic
|
|||
|
||||
moviemode_t moviemode = MM_OFF;
|
||||
|
||||
char joinedIPlist[NUMLOGIP][2][255];
|
||||
char joinedIP[255];
|
||||
|
||||
// This initializes the above array to have NULL evrywhere it should.
|
||||
void M_InitJoinedIPArray(void)
|
||||
{
|
||||
UINT8 i;
|
||||
for (i=0; i < NUMLOGIP; i++)
|
||||
{
|
||||
strcpy(joinedIPlist[i][0], "");
|
||||
strcpy(joinedIPlist[i][1], "");
|
||||
}
|
||||
}
|
||||
|
||||
// This adds an entry to the above array
|
||||
void M_AddToJoinedIPs(char *address, char *servname)
|
||||
{
|
||||
|
||||
UINT8 i = 0;
|
||||
UINT8 dupeindex = 0;
|
||||
|
||||
// Check for dupes...
|
||||
for (; i < NUMLOGIP && !dupeindex; i++)
|
||||
{
|
||||
// I don't care about the server name (this is broken anyway...) but definitely check the addresses
|
||||
if (strcmp(joinedIPlist[i][0], address) == 0)
|
||||
dupeindex = i;
|
||||
}
|
||||
|
||||
CONS_Printf("Adding %s (%s) to list of manually joined IPs\n", servname, address);
|
||||
|
||||
// Start by moving every IP up 1 slot (dropping the last IP in the table)
|
||||
// If we found duplicates, start here instead and pull the rest up.
|
||||
i = dupeindex ? dupeindex : NUMLOGIP;
|
||||
for (; i; i--)
|
||||
{
|
||||
strcpy(joinedIPlist[i][0], joinedIPlist[i-1][0]);
|
||||
strcpy(joinedIPlist[i][1], joinedIPlist[i-1][1]);
|
||||
}
|
||||
|
||||
// and add the new IP at the start of the table!
|
||||
strcpy(joinedIPlist[0][0], address);
|
||||
strcpy(joinedIPlist[0][1], servname);
|
||||
}
|
||||
|
||||
/** Returns the map number for a map identified by the last two characters in
|
||||
* its name.
|
||||
*
|
||||
|
|
@ -449,6 +494,87 @@ boolean FIL_CheckExtension(const char *in)
|
|||
return false;
|
||||
}
|
||||
|
||||
// LAST IPs JOINED LOG FILE!
|
||||
// ...It won't be as overly engineered as the config file because let's be real there's 0 need to...
|
||||
|
||||
// Save the file:
|
||||
void M_SaveJoinedIPs(void)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
UINT8 i;
|
||||
char *filepath;
|
||||
|
||||
if (!strlen(joinedIPlist[0][0]))
|
||||
return; // Don't bother, there's nothing to save.
|
||||
|
||||
// append srb2home to beginning of filename
|
||||
// but check if srb2home isn't already there, first
|
||||
if (!strstr(IPLOGFILE, srb2home))
|
||||
filepath = va(pandf,srb2home, IPLOGFILE);
|
||||
else
|
||||
filepath = Z_StrDup(IPLOGFILE);
|
||||
|
||||
f = fopen(filepath, "w");
|
||||
|
||||
if (f == NULL)
|
||||
return; // Uh I guess you don't have disk space?????????
|
||||
|
||||
for (i=0; i < NUMLOGIP; i++)
|
||||
{
|
||||
if (strlen(joinedIPlist[i][0]))
|
||||
{
|
||||
char savestring[MAXSTRINGLENGTH];
|
||||
strcpy(savestring, joinedIPlist[i][0]);
|
||||
strcat(savestring, IPLOGFILESEP);
|
||||
strcat(savestring, joinedIPlist[i][1]);
|
||||
|
||||
fputs(savestring, f);
|
||||
fputs("\n", f); // Because this won't do it automatically now will it...
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
// Load the file:
|
||||
void M_LoadJoinedIPs(void)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
UINT8 i = 0;
|
||||
char *filepath;
|
||||
char *s;
|
||||
char content[255]; // 255 is more than long enough!
|
||||
|
||||
filepath = va("%s"PATHSEP"%s", srb2home, IPLOGFILE);
|
||||
f = fopen(filepath, "r");
|
||||
|
||||
if (f == NULL)
|
||||
return; // File doesn't exist? sure, just do nothing then.
|
||||
|
||||
while (fgets(content, 255, f) && i < NUMLOGIP && content[0] && content[0] != '\n') // Don't let us write more than we can chew!
|
||||
{
|
||||
|
||||
// Now we have garbage under the form of "address;string"
|
||||
// Now you might ask yourself, but what do we do if the player fucked with their file and now there's a bunch of garbage?
|
||||
// ...Well that's not my problem lol.
|
||||
|
||||
s = strtok(content, IPLOGFILESEP); // We got the address
|
||||
strcpy(joinedIPlist[i][0], s);
|
||||
|
||||
s = strtok(NULL, IPLOGFILESEP); // Let's get rid of this awful \n while we're here!
|
||||
|
||||
if (strlen(s))
|
||||
s[strlen(s)-1] = '\0'; // Remove the \n
|
||||
|
||||
strcpy(joinedIPlist[i][1], s);
|
||||
|
||||
i++;
|
||||
}
|
||||
fclose(f); // We're done here
|
||||
}
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
// CONFIGURATION FILE
|
||||
// ==========================================================================
|
||||
|
|
@ -507,7 +633,7 @@ void Command_LoadConfig_f(void)
|
|||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
G_CopyControls(gamecontrol[i], gamecontroldefault[i][gcs_kart], NULL, 0);
|
||||
G_CopyControls(gamecontrol[i], gamecontroldefault, NULL, 0);
|
||||
}
|
||||
|
||||
// temporarily reset execversion to default
|
||||
|
|
@ -561,7 +687,7 @@ void M_FirstLoadConfig(void)
|
|||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
G_CopyControls(gamecontrol[i], gamecontroldefault[i][gcs_kart], NULL, 0);
|
||||
G_CopyControls(gamecontrol[i], gamecontroldefault, NULL, 0);
|
||||
}
|
||||
|
||||
// register execversion here before we load any configs
|
||||
|
|
@ -663,15 +789,7 @@ void M_SaveConfig(const char *filename)
|
|||
|
||||
if (!dedicated)
|
||||
{
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
// using gcs_custom as temp storage
|
||||
G_SaveKeySetting(f, gamecontroldefault[0][gcs_custom], gamecontrol[1], gamecontrol[2], gamecontrol[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
G_SaveKeySetting(f, gamecontrol[0], gamecontrol[1], gamecontrol[2], gamecontrol[3]);
|
||||
}
|
||||
G_SaveKeySetting(f, gamecontrol[0], gamecontrol[1], gamecontrol[2], gamecontrol[3]);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
|
@ -1651,12 +1769,12 @@ boolean M_ScreenshotResponder(event_t *ev)
|
|||
|
||||
ch = ev->data1;
|
||||
|
||||
if (ch >= KEY_MOUSE1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus!
|
||||
if (ch >= NUMKEYS && menuactive) // If it's not a keyboard key, then don't allow it in the menus!
|
||||
return false;
|
||||
|
||||
if (ch == KEY_F8 || ch == gamecontrol[0][gc_screenshot][0] || ch == gamecontrol[0][gc_screenshot][1]) // remappable F8
|
||||
if (ch == KEY_F8 /*|| ch == gamecontrol[0][gc_screenshot][0] || ch == gamecontrol[0][gc_screenshot][1]*/) // remappable F8
|
||||
M_ScreenShot();
|
||||
else if (ch == KEY_F9 || ch == gamecontrol[0][gc_recordgif][0] || ch == gamecontrol[0][gc_recordgif][1]) // remappable F9
|
||||
else if (ch == KEY_F9 /*|| ch == gamecontrol[0][gc_recordgif][0] || ch == gamecontrol[0][gc_recordgif][1]*/) // remappable F9
|
||||
((moviemode) ? M_StopMovie : M_StartMovie)();
|
||||
else
|
||||
return false;
|
||||
|
|
|
|||
21
src/m_misc.h
21
src/m_misc.h
|
|
@ -40,7 +40,26 @@ void M_SaveFrame(void);
|
|||
void M_StopMovie(void);
|
||||
|
||||
// the file where game vars and settings are saved
|
||||
#define CONFIGFILENAME "kartconfig.cfg"
|
||||
#define CONFIGFILENAME "ringconfig.cfg"
|
||||
|
||||
// The file where we'll save the last IPs we joined
|
||||
#define IPLOGFILE "ringsavedips.txt"
|
||||
#define IPLOGFILESEP ";"
|
||||
#define NUMLOGIP 3
|
||||
|
||||
// Array where we'll store addresses to display for last servers joined
|
||||
// {address, servame}
|
||||
// 255 is long enough to store the text
|
||||
extern char joinedIPlist[NUMLOGIP][2][255];
|
||||
|
||||
// Keep the address we're joining in mind until we've finished joining.
|
||||
// Since we don't wanna add an IP address we aren't even sure worked out.
|
||||
extern char joinedIP[255];
|
||||
|
||||
void M_InitJoinedIPArray(void);
|
||||
void M_AddToJoinedIPs(char *address, char *servname);
|
||||
void M_SaveJoinedIPs(void);
|
||||
void M_LoadJoinedIPs(void);
|
||||
|
||||
INT32 M_MapNumber(char first, char second);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
#include "command.h"
|
||||
#include "i_threads.h"
|
||||
#include "mserv.h"
|
||||
#include "m_menu.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_menu.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
#endif
|
||||
|
|
@ -117,11 +119,11 @@ void AddMServCommands(void)
|
|||
static void WarnGUI (void)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
#endif
|
||||
M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n\nCheck the console for details.\n"), NULL, MM_NOTHING);
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
I_unlock_mutex(k_menu_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
104
src/p_inter.c
104
src/p_inter.c
|
|
@ -786,73 +786,76 @@ void P_CheckPointLimit(void)
|
|||
// Checks whether or not to end a race netgame.
|
||||
boolean P_CheckRacers(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 numplayersingame = 0;
|
||||
UINT8 numexiting = 0;
|
||||
boolean eliminatelast = cv_karteliminatelast.value;
|
||||
boolean everyonedone = true;
|
||||
boolean eliminatebots = false;
|
||||
const boolean griefed = (spectateGriefed > 0);
|
||||
|
||||
boolean eliminateLast = cv_karteliminatelast.value;
|
||||
boolean allHumansDone = true;
|
||||
//boolean allBotsDone = true;
|
||||
|
||||
UINT8 numPlaying = 0;
|
||||
UINT8 numExiting = 0;
|
||||
UINT8 numHumans = 0;
|
||||
UINT8 numBots = 0;
|
||||
|
||||
UINT8 i;
|
||||
|
||||
// Check if all the players in the race have finished. If so, end the level.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].lives <= 0) // Not playing
|
||||
if (!playeringame[i] || players[i].spectator || players[i].lives <= 0)
|
||||
{
|
||||
// Y'all aren't even playing
|
||||
continue;
|
||||
}
|
||||
|
||||
numplayersingame++;
|
||||
numPlaying++;
|
||||
|
||||
if (players[i].bot)
|
||||
{
|
||||
numBots++;
|
||||
}
|
||||
else
|
||||
{
|
||||
numHumans++;
|
||||
}
|
||||
|
||||
if (players[i].exiting || (players[i].pflags & PF_NOCONTEST))
|
||||
{
|
||||
numexiting++;
|
||||
numExiting++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].bot)
|
||||
{
|
||||
// Isn't a human, thus doesn't matter. (Sorry, robots.)
|
||||
// Set this so that we can check for bots that need to get eliminated, though!
|
||||
eliminatebots = true;
|
||||
continue;
|
||||
//allBotsDone = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
allHumansDone = false;
|
||||
}
|
||||
|
||||
everyonedone = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we returned here with bots left, then the last place bot may have a chance to finish the map and NOT get time over.
|
||||
// Not that it affects anything, they didn't make the map take longer or even get any points from it. But... it's a bit inconsistent!
|
||||
// So if there's any bots, we'll let the game skip this, continue onto calculating eliminatelast, THEN we return true anyway.
|
||||
if (everyonedone && !eliminatebots)
|
||||
{
|
||||
// Everyone's finished, we're done here!
|
||||
racecountdown = exitcountdown = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (numplayersingame <= 1)
|
||||
if (numPlaying <= 1)
|
||||
{
|
||||
// Never do this without enough players.
|
||||
eliminatelast = false;
|
||||
eliminateLast = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (grandprixinfo.gp == true)
|
||||
{
|
||||
// Always do this in GP
|
||||
eliminatelast = true;
|
||||
}
|
||||
else if (griefed)
|
||||
if (griefed == true)
|
||||
{
|
||||
// Don't do this if someone spectated
|
||||
eliminatelast = false;
|
||||
eliminateLast = false;
|
||||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
// Always do this in GP
|
||||
eliminateLast = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (eliminatelast == true && (numexiting >= numplayersingame-1))
|
||||
if (eliminateLast == true && (numExiting >= numPlaying-1))
|
||||
{
|
||||
// Everyone's done playing but one guy apparently.
|
||||
// Just kill everyone who is still playing.
|
||||
|
|
@ -879,9 +882,10 @@ boolean P_CheckRacers(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (everyonedone)
|
||||
if (numHumans > 0 && allHumansDone == true)
|
||||
{
|
||||
// See above: there might be bots that are still going, but all players are done, so we can exit now.
|
||||
// There might be bots that are still going,
|
||||
// but all of the humans are done, so we can exit now.
|
||||
racecountdown = exitcountdown = 0;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -889,22 +893,21 @@ boolean P_CheckRacers(void)
|
|||
// SO, we're not done playing.
|
||||
// Let's see if it's time to start the death counter!
|
||||
|
||||
if (!racecountdown)
|
||||
if (racecountdown == 0)
|
||||
{
|
||||
// If the winners are all done, then start the death timer.
|
||||
UINT8 winningpos = 1;
|
||||
UINT8 winningPos = max(1, numPlaying / 2);
|
||||
|
||||
winningpos = max(1, numplayersingame/2);
|
||||
if (numplayersingame % 2) // any remainder?
|
||||
if (numPlaying % 2) // Any remainder? Then round up.
|
||||
{
|
||||
winningpos++;
|
||||
winningPos++;
|
||||
}
|
||||
|
||||
if (numexiting >= winningpos)
|
||||
if (numExiting >= winningPos)
|
||||
{
|
||||
tic_t countdown = 30*TICRATE; // 30 seconds left to finish, get going!
|
||||
|
||||
if (netgame)
|
||||
if (K_CanChangeRules() == true)
|
||||
{
|
||||
// Custom timer
|
||||
countdown = cv_countdowntime.value * TICRATE;
|
||||
|
|
@ -914,13 +917,14 @@ boolean P_CheckRacers(void)
|
|||
}
|
||||
}
|
||||
|
||||
// We're still playing, but no one else is, so we need to reset spectator griefing.
|
||||
if (numplayersingame <= 1)
|
||||
// We're still playing, but no one else is,
|
||||
// so we need to reset spectator griefing.
|
||||
if (numPlaying <= 1)
|
||||
{
|
||||
spectateGriefed = 0;
|
||||
}
|
||||
|
||||
// Turns out we're still having a good time & playing the game, we didn't have to do anything :)
|
||||
// We are still having fun and playing the game :)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2012,7 +2016,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
source->player->invincibilitytimer += kinvextend;
|
||||
}
|
||||
|
||||
K_PlayHitEmSound(source, target);
|
||||
K_TryHurtSoundExchange(target, source);
|
||||
|
||||
K_BattleAwardHit(source->player, player, inflictor, takeBumpers);
|
||||
K_TakeBumpersFromPlayer(source->player, player, takeBumpers);
|
||||
|
|
@ -2085,14 +2089,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
player->flashing = K_GetKartFlashing(player);
|
||||
}
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
P_PlayRinglossSound(target);
|
||||
|
||||
if (ringburst > 0)
|
||||
{
|
||||
P_PlayerRingBurst(player, ringburst);
|
||||
}
|
||||
|
||||
K_PlayPainSound(player->mo);
|
||||
K_PlayPainSound(target, source);
|
||||
|
||||
if ((hardhit == true) || (cv_kartdebughuddrop.value && !modeattacking))
|
||||
{
|
||||
|
|
|
|||
17
src/p_map.c
17
src/p_map.c
|
|
@ -2463,12 +2463,6 @@ fixed_t P_GetThingStepUp(mobj_t *thing)
|
|||
const fixed_t maxstepmove = P_BaseStepUp();
|
||||
fixed_t maxstep = maxstepmove;
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
{
|
||||
// Skim special (not needed for kart?)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (P_WaterStepUp(thing) == true)
|
||||
{
|
||||
// Add some extra stepmove when waterskipping
|
||||
|
|
@ -2525,16 +2519,20 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
#endif
|
||||
|
||||
do {
|
||||
if (thing->flags & MF_NOCLIP) {
|
||||
if (thing->flags & MF_NOCLIP)
|
||||
{
|
||||
tryx = x;
|
||||
tryy = y;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x-tryx > radius)
|
||||
tryx += radius;
|
||||
else if (x-tryx < -radius)
|
||||
tryx -= radius;
|
||||
else
|
||||
tryx = x;
|
||||
|
||||
if (y-tryy > radius)
|
||||
tryy += radius;
|
||||
else if (y-tryy < -radius)
|
||||
|
|
@ -2603,7 +2601,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
return false; // mobj must lower itself to fit
|
||||
}
|
||||
}
|
||||
else if (!(P_MobjTouchingSectorSpecial(thing, 1, 14, false))) // Step down
|
||||
else if (thing->momz * P_MobjFlip(thing) <= 0 // Step down requires moving down.
|
||||
&& !(P_MobjTouchingSectorSpecial(thing, 1, 14, false)))
|
||||
{
|
||||
// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
|
||||
// step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more.
|
||||
|
|
|
|||
189
src/p_mobj.c
189
src/p_mobj.c
|
|
@ -1132,6 +1132,12 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
{
|
||||
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
|
||||
}
|
||||
|
||||
if (mo->player->fastfall != 0)
|
||||
{
|
||||
// Fast falling
|
||||
gravityadd *= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1761,7 +1767,9 @@ void P_XYMovement(mobj_t *mo)
|
|||
|
||||
if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) { // Check to see if we ran off
|
||||
|
||||
if (oldslope != mo->standingslope) { // First, compare different slopes
|
||||
if (oldslope != mo->standingslope)
|
||||
{
|
||||
// First, compare different slopes
|
||||
angle_t oldangle, newangle;
|
||||
angle_t moveangle = K_MomentumAngle(mo);
|
||||
|
||||
|
|
@ -1773,7 +1781,9 @@ void P_XYMovement(mobj_t *mo)
|
|||
newangle = 0;
|
||||
|
||||
// Now compare the Zs of the different quantizations
|
||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
|
||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180)
|
||||
{
|
||||
// Allow for a bit of sticking - this value can be adjusted later
|
||||
mo->standingslope = oldslope;
|
||||
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
||||
P_SlopeLaunch(mo);
|
||||
|
|
@ -1781,26 +1791,36 @@ void P_XYMovement(mobj_t *mo)
|
|||
//CONS_Printf("launched off of slope - ");
|
||||
}
|
||||
|
||||
/*CONS_Printf("old angle %f - new angle %f = %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(oldangle)),
|
||||
FIXED_TO_FLOAT(AngleFixed(newangle)),
|
||||
FIXED_TO_FLOAT(AngleFixed(oldangle-newangle))
|
||||
);*/
|
||||
// Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway
|
||||
} else if (predictedz-mo->z > abs(slopemom.z/2)
|
||||
&& !(mo->standingslope->flags & SL_NOPHYSICS)) { // Now check if we were supposed to stick to this slope
|
||||
/*
|
||||
CONS_Printf("old angle %f - new angle %f = %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(oldangle)),
|
||||
FIXED_TO_FLOAT(AngleFixed(newangle)),
|
||||
FIXED_TO_FLOAT(AngleFixed(oldangle-newangle))
|
||||
);
|
||||
*/
|
||||
|
||||
}
|
||||
else if (predictedz - mo->z > abs(slopemom.z / 2))
|
||||
{
|
||||
// Now check if we were supposed to stick to this slope
|
||||
//CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2));
|
||||
P_SlopeLaunch(mo);
|
||||
}
|
||||
} else if (moved && mo->standingslope && predictedz) {
|
||||
}
|
||||
else if (moved && mo->standingslope && predictedz)
|
||||
{
|
||||
angle_t moveangle = K_MomentumAngle(mo);
|
||||
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
|
||||
/*CONS_Printf("flat to angle %f - predicted z of %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)),
|
||||
FIXED_TO_FLOAT(predictedz)
|
||||
);*/
|
||||
if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) {
|
||||
/*
|
||||
CONS_Printf("flat to angle %f - predicted z of %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)),
|
||||
FIXED_TO_FLOAT(predictedz)
|
||||
);
|
||||
*/
|
||||
|
||||
if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180)
|
||||
{
|
||||
mo->momz = P_MobjFlip(mo)*FRACUNIT/2;
|
||||
mo->z = predictedz + P_MobjFlip(mo);
|
||||
mo->standingslope = NULL;
|
||||
|
|
@ -3120,12 +3140,6 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
if (mobj->watertop > top2)
|
||||
mobj->watertop = top2;
|
||||
|
||||
if (mobj->waterbottom < bot2)
|
||||
mobj->waterbottom = bot2;
|
||||
|
||||
// Spectators and dead players don't get to do any of the things after this.
|
||||
if (p && (p->spectator || p->playerstate != PST_LIVE))
|
||||
{
|
||||
|
|
@ -3133,8 +3147,10 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
}
|
||||
|
||||
// The rest of this code only executes on a water state change.
|
||||
if (!!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
|
||||
if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p && !p->waterskip &&
|
||||
p->curshield != KSHIELD_BUBBLE && wasinwater)
|
||||
|
|
@ -3171,62 +3187,6 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
diff = -diff;
|
||||
}
|
||||
|
||||
// Time to spawn the bubbles!
|
||||
{
|
||||
INT32 i;
|
||||
INT32 bubblecount;
|
||||
UINT8 prandom[4];
|
||||
mobj_t *bubble;
|
||||
mobjtype_t bubbletype;
|
||||
|
||||
if (mobj->eflags & MFE_GOOWATER || wasingoo)
|
||||
S_StartSound(mobj, sfx_ghit);
|
||||
else if (mobj->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(mobj, sfx_splash);
|
||||
else
|
||||
S_StartSound(mobj, sfx_splish); // And make a sound!
|
||||
|
||||
bubblecount = FixedDiv(abs(mobj->momz), mobj->scale)>>(FRACBITS-1);
|
||||
// Max bubble count
|
||||
if (bubblecount > 128)
|
||||
bubblecount = 128;
|
||||
|
||||
// Create tons of bubbles
|
||||
for (i = 0; i < bubblecount; i++)
|
||||
{
|
||||
// P_RandomByte()s are called individually to allow consistency
|
||||
// across various compilers, since the order of function calls
|
||||
// in C is not part of the ANSI specification.
|
||||
prandom[0] = P_RandomByte();
|
||||
prandom[1] = P_RandomByte();
|
||||
prandom[2] = P_RandomByte();
|
||||
prandom[3] = P_RandomByte();
|
||||
|
||||
bubbletype = MT_SMALLBUBBLE;
|
||||
if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32
|
||||
bubbletype = MT_MEDIUMBUBBLE;
|
||||
|
||||
bubble = P_SpawnMobj(
|
||||
mobj->x + FixedMul((prandom[1]<<(FRACBITS-3)) * (prandom[0]&0x80 ? 1 : -1), mobj->scale),
|
||||
mobj->y + FixedMul((prandom[2]<<(FRACBITS-3)) * (prandom[0]&0x40 ? 1 : -1), mobj->scale),
|
||||
mobj->z + FixedMul((prandom[3]<<(FRACBITS-2)), mobj->scale), bubbletype);
|
||||
|
||||
if (bubble)
|
||||
{
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
bubble->momz = mobj->momz >> 4;
|
||||
else
|
||||
bubble->momz = 0;
|
||||
|
||||
bubble->destscale = mobj->scale;
|
||||
P_SetScale(bubble, mobj->scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (waterwasnotset)
|
||||
return;
|
||||
|
||||
// Check to make sure you didn't just cross into a sector to jump out of
|
||||
// that has shallower water than the block you were originally in.
|
||||
if (diff <= (height >> 1))
|
||||
|
|
@ -3328,6 +3288,59 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
P_SetScale(splish, mobj->scale);
|
||||
}
|
||||
}
|
||||
|
||||
// Time to spawn the bubbles!
|
||||
{
|
||||
INT32 i;
|
||||
INT32 bubblecount;
|
||||
UINT8 prandom[4];
|
||||
mobj_t *bubble;
|
||||
mobjtype_t bubbletype;
|
||||
|
||||
if (mobj->eflags & MFE_GOOWATER || wasingoo)
|
||||
S_StartSound(mobj, sfx_ghit);
|
||||
else if (mobj->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(mobj, sfx_splash);
|
||||
else
|
||||
S_StartSound(mobj, sfx_splish); // And make a sound!
|
||||
|
||||
bubblecount = FixedDiv(abs(mobj->momz), mobj->scale) >> (FRACBITS-1);
|
||||
// Max bubble count
|
||||
if (bubblecount > 128)
|
||||
bubblecount = 128;
|
||||
|
||||
// Create tons of bubbles
|
||||
for (i = 0; i < bubblecount; i++)
|
||||
{
|
||||
// P_RandomByte()s are called individually to allow consistency
|
||||
// across various compilers, since the order of function calls
|
||||
// in C is not part of the ANSI specification.
|
||||
prandom[0] = P_RandomByte();
|
||||
prandom[1] = P_RandomByte();
|
||||
prandom[2] = P_RandomByte();
|
||||
prandom[3] = P_RandomByte();
|
||||
|
||||
bubbletype = MT_SMALLBUBBLE;
|
||||
if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32
|
||||
bubbletype = MT_MEDIUMBUBBLE;
|
||||
|
||||
bubble = P_SpawnMobj(
|
||||
mobj->x + FixedMul((prandom[1]<<(FRACBITS-3)) * (prandom[0]&0x80 ? 1 : -1), mobj->scale),
|
||||
mobj->y + FixedMul((prandom[2]<<(FRACBITS-3)) * (prandom[0]&0x40 ? 1 : -1), mobj->scale),
|
||||
mobj->z + FixedMul((prandom[3]<<(FRACBITS-2)), mobj->scale), bubbletype);
|
||||
|
||||
if (bubble)
|
||||
{
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
bubble->momz = mobj->momz >> 4;
|
||||
else
|
||||
bubble->momz = 0;
|
||||
|
||||
bubble->destscale = mobj->scale;
|
||||
P_SetScale(bubble, mobj->scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7104,17 +7117,17 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
if (mobj->fuse <= 16)
|
||||
{
|
||||
mobj->color = SKINCOLOR_KETCHUP;
|
||||
mobj->color = SKINCOLOR_GOLD;
|
||||
/* don't draw papersprite frames after blue boost */
|
||||
mobj->renderflags ^= RF_DONTDRAW;
|
||||
}
|
||||
else if (mobj->fuse <= 32)
|
||||
mobj->color = SKINCOLOR_SAPPHIRE;
|
||||
mobj->color = SKINCOLOR_KETCHUP;
|
||||
else if (mobj->fuse <= 48)
|
||||
mobj->color = SKINCOLOR_PURPLE;
|
||||
mobj->color = SKINCOLOR_SAPPHIRE;
|
||||
else if (mobj->fuse > 48)
|
||||
mobj->color = K_RainbowColor(
|
||||
(SKINCOLOR_PURPLE - SKINCOLOR_PINK) // Smoothly transition into the other state
|
||||
(SKINCOLOR_SAPPHIRE - SKINCOLOR_PINK) // Smoothly transition into the other state
|
||||
+ ((mobj->fuse - 32) * 2) // Make the color flashing slow down while it runs out
|
||||
);
|
||||
|
||||
|
|
@ -7129,14 +7142,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
|
||||
case 3:/* purple boost */
|
||||
if ((mobj->fuse == 32)/* to blue*/
|
||||
|| (mobj->fuse == 16))/* to red*/
|
||||
case 3:/* blue boost */
|
||||
if ((mobj->fuse == 32)/* to red*/
|
||||
|| (mobj->fuse == 16))/* to yellow*/
|
||||
K_SpawnDriftBoostClip(mobj->target->player);
|
||||
break;
|
||||
|
||||
case 2:/* blue boost */
|
||||
if (mobj->fuse == 16)/* to red*/
|
||||
case 2:/* red boost */
|
||||
if (mobj->fuse == 16)/* to yellow*/
|
||||
K_SpawnDriftBoostClip(mobj->target->player);
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -280,6 +280,8 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEFIXED(save_p, players[i].spindashspeed);
|
||||
WRITEUINT8(save_p, players[i].spindashboost);
|
||||
|
||||
WRITEFIXED(save_p, players[i].fastfall);
|
||||
|
||||
WRITEUINT8(save_p, players[i].numboosts);
|
||||
WRITEFIXED(save_p, players[i].boostpower);
|
||||
WRITEFIXED(save_p, players[i].speedboost);
|
||||
|
|
@ -337,8 +339,8 @@ static void P_NetArchivePlayers(void)
|
|||
WRITESINT8(save_p, players[i].lastjawztarget);
|
||||
WRITEUINT8(save_p, players[i].jawztargetdelay);
|
||||
|
||||
WRITEUINT8(save_p, players[i].confirmInflictor);
|
||||
WRITEUINT8(save_p, players[i].confirmInflictorDelay);
|
||||
WRITEUINT8(save_p, players[i].confirmVictim);
|
||||
WRITEUINT8(save_p, players[i].confirmVictimDelay);
|
||||
|
||||
WRITEUINT8(save_p, players[i].trickpanel);
|
||||
WRITEUINT8(save_p, players[i].tricktime);
|
||||
|
|
@ -565,6 +567,8 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].spindashspeed = READFIXED(save_p);
|
||||
players[i].spindashboost = READUINT8(save_p);
|
||||
|
||||
players[i].fastfall = READFIXED(save_p);
|
||||
|
||||
players[i].numboosts = READUINT8(save_p);
|
||||
players[i].boostpower = READFIXED(save_p);
|
||||
players[i].speedboost = READFIXED(save_p);
|
||||
|
|
@ -622,8 +626,8 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].lastjawztarget = READSINT8(save_p);
|
||||
players[i].jawztargetdelay = READUINT8(save_p);
|
||||
|
||||
players[i].confirmInflictor = READUINT8(save_p);
|
||||
players[i].confirmInflictorDelay = READUINT8(save_p);
|
||||
players[i].confirmVictim = READUINT8(save_p);
|
||||
players[i].confirmVictimDelay = READUINT8(save_p);
|
||||
|
||||
players[i].trickpanel = READUINT8(save_p);
|
||||
players[i].tricktime = READUINT8(save_p);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@
|
|||
#include "k_boss.h"
|
||||
#include "k_terrain.h" // TRF_TRIPWIRE
|
||||
#include "k_brightmap.h"
|
||||
#include "k_terrain.h" // TRF_TRIPWIRE
|
||||
#include "k_director.h" // K_InitDirector
|
||||
|
||||
// Replay names have time
|
||||
|
|
@ -3882,7 +3883,7 @@ static void P_ResetSpawnpoints(void)
|
|||
|
||||
static void P_LoadRecordGhosts(void)
|
||||
{
|
||||
// see also m_menu.c's Nextmap_OnChange
|
||||
// see also k_menu.c's Nextmap_OnChange
|
||||
const size_t glen = strlen(srb2home)+1+strlen("media")+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
|
||||
char *gpath = malloc(glen);
|
||||
INT32 i;
|
||||
|
|
|
|||
128
src/p_slopes.c
128
src/p_slopes.c
|
|
@ -894,6 +894,61 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y)
|
|||
return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height;
|
||||
}
|
||||
|
||||
// Returns true if we should run slope physics code on an object.
|
||||
boolean P_CanApplySlopePhysics(mobj_t *mo, pslope_t *slope)
|
||||
{
|
||||
if (slope == NULL || mo == NULL || P_MobjWasRemoved(mo) == true)
|
||||
{
|
||||
// Invalid input.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slope->flags & SL_NOPHYSICS)
|
||||
{
|
||||
// Physics are turned off.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0)
|
||||
{
|
||||
// Flat slope? No such thing, man. No such thing.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mo->player != NULL)
|
||||
{
|
||||
if (K_PlayerEBrake(mo->player) == true)
|
||||
{
|
||||
// Spindash negates slopes.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We can do slope physics.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if we should run slope launch code on an object.
|
||||
boolean P_CanApplySlopeLaunch(mobj_t *mo, pslope_t *slope)
|
||||
{
|
||||
if (slope == NULL || mo == NULL || P_MobjWasRemoved(mo) == true)
|
||||
{
|
||||
// Invalid input.
|
||||
return false;
|
||||
}
|
||||
|
||||
// No physics slopes are fine to launch off of.
|
||||
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0)
|
||||
{
|
||||
// Flat slope? No such thing, man. No such thing.
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can do slope launching.
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// P_QuantizeMomentumToSlope
|
||||
//
|
||||
|
|
@ -923,42 +978,23 @@ void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
|
|||
slope->zangle = InvAngle(slope->zangle);
|
||||
}
|
||||
|
||||
// SRB2Kart: This fixes all slope-based jumps for different scales in Kart automatically without map tweaking.
|
||||
// However, they will always feel off every single time... see for yourself: https://cdn.discordapp.com/attachments/270211093761097728/484924392128774165/kart0181.gif
|
||||
//#define GROWNEVERMISSES
|
||||
|
||||
//
|
||||
// P_SlopeLaunch
|
||||
//
|
||||
// Handles slope ejection for objects
|
||||
void P_SlopeLaunch(mobj_t *mo)
|
||||
{
|
||||
if (!(mo->standingslope->flags & SL_NOPHYSICS) // If there's physics, time for launching.
|
||||
&& (mo->standingslope->normal.x != 0
|
||||
|| mo->standingslope->normal.y != 0))
|
||||
if (P_CanApplySlopeLaunch(mo, mo->standingslope) == true) // If there's physics, time for launching.
|
||||
{
|
||||
// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
|
||||
// vertical launch given from slopes while increasing the horizontal launch
|
||||
// given. Good for SRB2's gravity and horizontal speeds.
|
||||
vector3_t slopemom;
|
||||
slopemom.x = mo->momx;
|
||||
slopemom.y = mo->momy;
|
||||
slopemom.z = mo->momz;
|
||||
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
|
||||
|
||||
#ifdef GROWNEVERMISSES
|
||||
{
|
||||
const fixed_t xyscale = mapobjectscale + (mapobjectscale - mo->scale);
|
||||
const fixed_t zscale = mapobjectscale + (mapobjectscale - mo->scale);
|
||||
mo->momx = FixedMul(slopemom.x, xyscale);
|
||||
mo->momy = FixedMul(slopemom.y, xyscale);
|
||||
mo->momz = FixedMul(slopemom.z, zscale);
|
||||
}
|
||||
#else
|
||||
mo->momx = slopemom.x;
|
||||
mo->momy = slopemom.y;
|
||||
mo->momz = slopemom.z;
|
||||
#endif
|
||||
|
||||
mo->eflags |= MFE_SLOPELAUNCHED;
|
||||
}
|
||||
|
|
@ -984,14 +1020,19 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
|||
vector3_t slopemom, axis;
|
||||
angle_t ang;
|
||||
|
||||
if (mo->standingslope->flags & SL_NOPHYSICS)
|
||||
return 0;
|
||||
if (P_CanApplySlopeLaunch(mo, mo->standingslope) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there's physics, time for launching.
|
||||
// Doesn't kill the vertical momentum as much as P_SlopeLaunch does.
|
||||
ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1);
|
||||
if (ang > ANGLE_90 && ang < ANGLE_180)
|
||||
ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
|
||||
{
|
||||
// hard cap of directly upwards
|
||||
ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90));
|
||||
}
|
||||
|
||||
slopemom.x = mo->momx;
|
||||
slopemom.y = mo->momy;
|
||||
|
|
@ -1010,13 +1051,16 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
|||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
||||
{
|
||||
vector3_t mom; // Ditto.
|
||||
if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated.
|
||||
|
||||
if (P_CanApplySlopePhysics(thing, slope) == false) // No physics, no need to make anything complicated.
|
||||
{
|
||||
if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope
|
||||
{
|
||||
thing->standingslope = slope;
|
||||
P_SetPitchRollFromSlope(thing, slope);
|
||||
thing->momz = -P_MobjFlip(thing);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1026,7 +1070,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
|
||||
P_ReverseQuantizeMomentumToSlope(&mom, slope);
|
||||
|
||||
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
|
||||
if (P_MobjFlip(thing)*mom.z < 0)
|
||||
{
|
||||
// falling, land on slope
|
||||
thing->momx = mom.x;
|
||||
thing->momy = mom.y;
|
||||
thing->standingslope = slope;
|
||||
|
|
@ -1041,27 +1087,29 @@ void P_ButteredSlope(mobj_t *mo)
|
|||
{
|
||||
fixed_t thrust;
|
||||
|
||||
if (!mo->standingslope)
|
||||
return;
|
||||
|
||||
if (mo->standingslope->flags & SL_NOPHYSICS)
|
||||
return; // No physics, no butter.
|
||||
|
||||
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
|
||||
return; // don't slide down slopes if you can't touch them or you're not affected by gravity
|
||||
|
||||
if (mo->player) {
|
||||
// SRB2Kart - spindash negates slopes
|
||||
if (K_PlayerEBrake(mo->player))
|
||||
return;
|
||||
if (P_CanApplySlopePhysics(mo, mo->standingslope) == false)
|
||||
return; // No physics, no butter.
|
||||
|
||||
// Changed in kart to only not apply physics on very slight slopes (I think about 4 degree angles)
|
||||
if (mo->player != NULL)
|
||||
{
|
||||
if (abs(mo->standingslope->zdelta) < FRACUNIT/21)
|
||||
return; // Don't slide on non-steep slopes
|
||||
{
|
||||
// Don't slide on non-steep slopes.
|
||||
// Changed in Ring Racers to only not apply physics on very slight slopes.
|
||||
// (I think about 4 degree angles.)
|
||||
return;
|
||||
}
|
||||
|
||||
// This only means you can be stopped on slopes that aren't steeper than 45 degrees
|
||||
if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy))
|
||||
return; // Allow the player to stand still on slopes below a certain steepness
|
||||
if (abs(mo->standingslope->zdelta) < FRACUNIT/2
|
||||
&& !(mo->player->rmomx || mo->player->rmomy))
|
||||
{
|
||||
// Allow the player to stand still on slopes below a certain steepness.
|
||||
// 45 degree angle steep, to be exact.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 5 / 4 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y);
|
|||
fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y);
|
||||
|
||||
// Lots of physics-based bullshit
|
||||
boolean P_CanApplySlopePhysics(mobj_t *mo, pslope_t *slope);
|
||||
boolean P_CanApplySlopeLaunch(mobj_t *mo, pslope_t *slope);
|
||||
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||
void P_SlopeLaunch(mobj_t *mo);
|
||||
|
|
|
|||
|
|
@ -721,7 +721,7 @@ void P_Ticker(boolean run)
|
|||
G_WriteAllGhostTics();
|
||||
|
||||
if (cv_recordmultiplayerdemos.value && (demo.savemode == DSM_NOTSAVING || demo.savemode == DSM_WILLAUTOSAVE))
|
||||
if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && PlayerInputDown(1, gc_lookback))
|
||||
if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && G_PlayerInputDown(0, gc_y, 0))
|
||||
demo.savemode = DSM_TITLEENTRY;
|
||||
}
|
||||
else if (demo.playback) // Use Ghost data for consistency checks.
|
||||
|
|
|
|||
35
src/p_user.c
35
src/p_user.c
|
|
@ -183,7 +183,7 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move)
|
|||
boolean P_AutoPause(void)
|
||||
{
|
||||
// Don't pause even on menu-up or focus-lost in netgames or record attack
|
||||
if (netgame || modeattacking || gamestate == GS_TITLESCREEN)
|
||||
if (netgame || modeattacking || gamestate == GS_TITLESCREEN || gamestate == GS_MENU || con_startup)
|
||||
return false;
|
||||
|
||||
return ((menuactive && !demo.playback) || ( window_notinfocus && cv_pauseifunfocused.value ));
|
||||
|
|
@ -473,6 +473,7 @@ void P_ResetPlayer(player_t *player)
|
|||
//player->drift = player->driftcharge = 0;
|
||||
player->trickpanel = 0;
|
||||
player->glanceDir = 0;
|
||||
player->fastfall = 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1099,7 +1100,7 @@ boolean P_IsMachineLocalPlayer(player_t *player)
|
|||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player == &players[g_localplayers[i]])
|
||||
return true;
|
||||
|
|
@ -1905,17 +1906,27 @@ static void P_3dMovement(player_t *player)
|
|||
}
|
||||
|
||||
if ((totalthrust.x || totalthrust.y)
|
||||
&& player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
|
||||
&& player->mo->standingslope != NULL
|
||||
&& (!(player->mo->standingslope->flags & SL_NOPHYSICS))
|
||||
&& abs(player->mo->standingslope->zdelta) > FRACUNIT/2)
|
||||
{
|
||||
// Factor thrust to slope, but only for the part pushing up it!
|
||||
// The rest is unaffected.
|
||||
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
|
||||
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y) - player->mo->standingslope->xydirection;
|
||||
|
||||
if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward
|
||||
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) {
|
||||
if (player->mo->standingslope->zdelta < 0)
|
||||
{
|
||||
// Direction goes down, so thrustangle needs to face toward
|
||||
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270)
|
||||
{
|
||||
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
|
||||
}
|
||||
} else { // Direction goes up, so thrustangle needs to face away
|
||||
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direction goes up, so thrustangle needs to face away
|
||||
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270)
|
||||
{
|
||||
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
|
||||
}
|
||||
}
|
||||
|
|
@ -2786,12 +2797,14 @@ void P_InitCameraCmd(void)
|
|||
|
||||
static ticcmd_t *P_CameraCmd(camera_t *cam)
|
||||
{
|
||||
/*
|
||||
INT32 forward, axis; //i
|
||||
// these ones used for multiple conditions
|
||||
boolean turnleft, turnright, mouseaiming;
|
||||
boolean invertmouse, lookaxis, usejoystick, kbl;
|
||||
INT32 player_invert;
|
||||
INT32 screen_invert;
|
||||
*/
|
||||
ticcmd_t *cmd = &cameracmd;
|
||||
|
||||
(void)cam;
|
||||
|
|
@ -2799,6 +2812,7 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
|
|||
if (!demo.playback)
|
||||
return cmd; // empty cmd, no.
|
||||
|
||||
/*
|
||||
kbl = democam.keyboardlook;
|
||||
|
||||
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
|
||||
|
|
@ -2843,7 +2857,7 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
|
|||
cmd->turning -= (mousex * 8) * (encoremode ? -1 : 1);
|
||||
|
||||
axis = PlayerJoyAxis(1, AXISMOVE);
|
||||
if (PlayerInputDown(1, gc_accelerate) || (usejoystick && axis > 0))
|
||||
if (PlayerInputDown(1, gc_a) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
axis = PlayerJoyAxis(1, AXISBRAKE);
|
||||
if (PlayerInputDown(1, gc_brake) || (usejoystick && axis > 0))
|
||||
|
|
@ -2889,8 +2903,6 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
|
|||
if (PlayerInputDown(1, gc_centerview)) // No need to put a spectator limit on this one though :V
|
||||
cmd->aiming = 0;
|
||||
|
||||
mousex = mousey = mlooky = 0;
|
||||
|
||||
cmd->forwardmove += (SINT8)forward;
|
||||
|
||||
if (cmd->forwardmove > MAXPLMOVE)
|
||||
|
|
@ -2904,6 +2916,7 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
|
|||
cmd->turning = -KART_FULLTURN;
|
||||
|
||||
democam.keyboardlook = kbl;
|
||||
*/
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -709,7 +709,7 @@ void R_RemoveMobjInterpolator(mobj_t *mobj)
|
|||
|
||||
if (interpolated_mobjs_len == 0) return;
|
||||
|
||||
for (i = 0; i < interpolated_mobjs_len - 1; i++)
|
||||
for (i = 0; i < interpolated_mobjs_len; i++)
|
||||
{
|
||||
if (interpolated_mobjs[i] == mobj)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "p_local.h"
|
||||
#include "keys.h"
|
||||
#include "i_video.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "am_map.h"
|
||||
#include "d_main.h"
|
||||
#include "v_video.h"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "r_defs.h" // spritedef_t
|
||||
|
||||
/// Defaults
|
||||
#define SKINNAMESIZE 16
|
||||
#define SKINRIVALS 3
|
||||
// should be all lowercase!! S_SKIN processing does a strlwr
|
||||
#define DEFAULTSKIN "eggman"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#include "st_stuff.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h" // character select
|
||||
#include "k_menu.h" // character select
|
||||
#include "m_misc.h"
|
||||
#include "info.h" // spr2names
|
||||
#include "i_video.h" // rendermode
|
||||
|
|
|
|||
|
|
@ -2505,9 +2505,9 @@ void GameDigiMusic_OnChange(void)
|
|||
{
|
||||
P_RestoreMusic(&players[consoleplayer]);
|
||||
}
|
||||
else if (S_MusicExists("_title"))
|
||||
else if (S_MusicExists("menu"))
|
||||
{
|
||||
S_ChangeMusicInternal("_title", looptitle);
|
||||
S_ChangeMusicInternal("menu", looptitle);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -405,12 +405,6 @@ void SCR_Recalc(void)
|
|||
// vid.recalc lasts only for the next refresh...
|
||||
con_recalc = true;
|
||||
am_recalc = true;
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Shoot! The screen texture was flushed!
|
||||
if ((rendermode == render_opengl) && (gamestate == GS_INTERMISSION))
|
||||
usebuffer = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check for screen cmd-line parms: to force a resolution.
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@ static char returnWadPath[256];
|
|||
#include "../r_main.h" // Frame interpolation/uncapped
|
||||
#include "../r_fps.h"
|
||||
|
||||
#include "../k_menu.h"
|
||||
|
||||
#ifdef MAC_ALERT
|
||||
#include "macosx/mac_alert.h"
|
||||
#endif
|
||||
|
|
@ -198,6 +200,48 @@ static char returnWadPath[256];
|
|||
#include "../byteptr.h"
|
||||
#endif
|
||||
|
||||
void I_StoreExJoystick(SDL_GameController *dev)
|
||||
{
|
||||
// ExJoystick is a massive hack to avoid needing to completely
|
||||
// rewrite pretty much all of the controller support from scratch...
|
||||
|
||||
// Used in favor of most instances of SDL_GameControllerClose.
|
||||
// If a joystick would've been discarded, then save it in an array,
|
||||
// because we want it have it for the joystick input screen.
|
||||
|
||||
int index = 0;
|
||||
|
||||
if (dev == NULL)
|
||||
{
|
||||
// No joystick?
|
||||
return;
|
||||
}
|
||||
|
||||
index = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(dev));
|
||||
|
||||
if (index >= MAXGAMEPADS || index < 0)
|
||||
{
|
||||
// Not enough space to save this joystick, completely discard.
|
||||
SDL_GameControllerClose(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExJoystick[index] == dev)
|
||||
{
|
||||
// No need to do anything else.
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExJoystick[index] != NULL)
|
||||
{
|
||||
// Discard joystick in the old slot.
|
||||
SDL_GameControllerClose(ExJoystick[index]);
|
||||
}
|
||||
|
||||
// Keep for safe-keeping.
|
||||
ExJoystick[index] = dev;
|
||||
}
|
||||
|
||||
/** \brief The JoyReset function
|
||||
|
||||
\param JoySet Joystick info to reset
|
||||
|
|
@ -208,7 +252,7 @@ static void JoyReset(SDLJoyInfo_t *JoySet)
|
|||
{
|
||||
if (JoySet->dev)
|
||||
{
|
||||
SDL_JoystickClose(JoySet->dev);
|
||||
I_StoreExJoystick(JoySet->dev);
|
||||
}
|
||||
JoySet->dev = NULL;
|
||||
JoySet->oldjoy = -1;
|
||||
|
|
@ -223,6 +267,7 @@ static INT32 joystick_started[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
|||
/** \brief SDL info about joystick 1
|
||||
*/
|
||||
SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||
SDL_GameController *ExJoystick[MAXGAMEPADS];
|
||||
|
||||
SDL_bool consolevent = SDL_FALSE;
|
||||
SDL_bool framebuffer = SDL_FALSE;
|
||||
|
|
@ -536,7 +581,7 @@ static void I_StartupConsole(void)
|
|||
void I_GetConsoleEvents(void)
|
||||
{
|
||||
// we use this when sending back commands
|
||||
event_t ev = {0,0,0,0};
|
||||
event_t ev = {0};
|
||||
char key = 0;
|
||||
ssize_t d;
|
||||
|
||||
|
|
@ -944,29 +989,16 @@ void I_JoyScale4(void)
|
|||
JoyInfo[3].scale = Joystick[3].bGamepadStyle?1:cv_joyscale[1].value;
|
||||
}
|
||||
|
||||
// Cheat to get the device index for a joystick handle
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev)
|
||||
// Cheat to get the device index for a game controller handle
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev)
|
||||
{
|
||||
INT32 i, count = SDL_NumJoysticks();
|
||||
SDL_Joystick *joystick = NULL;
|
||||
|
||||
for (i = 0; dev && i < count; i++)
|
||||
joystick = SDL_GameControllerGetJoystick(dev);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
SDL_Joystick *test = SDL_JoystickOpen(i);
|
||||
if (test && test == dev)
|
||||
return i;
|
||||
else
|
||||
{
|
||||
UINT8 j;
|
||||
|
||||
for (j = 0; j < MAXSPLITSCREENPLAYERS; j++)
|
||||
{
|
||||
if (JoyInfo[j].dev == test)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXSPLITSCREENPLAYERS)
|
||||
SDL_JoystickClose(test);
|
||||
}
|
||||
return SDL_JoystickInstanceID(joystick);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
@ -981,6 +1013,7 @@ void I_UpdateJoystickDeviceIndex(UINT8 player)
|
|||
if (JoyInfo[player].dev)
|
||||
{
|
||||
cv_usejoystick[player].value = I_GetJoystickDeviceIndex(JoyInfo[player].dev) + 1;
|
||||
CONS_Printf("I_UpdateJoystickDeviceIndex: Device for %d set to %d\n", player, cv_usejoystick[player].value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1004,6 +1037,7 @@ void I_UpdateJoystickDeviceIndex(UINT8 player)
|
|||
{
|
||||
// We DID make it through the whole loop, so we can use this one!
|
||||
cv_usejoystick[player].value = value;
|
||||
CONS_Printf("I_UpdateJoystickDeviceIndex: Device for %d set to %d\n", player, cv_usejoystick[player].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1013,6 +1047,7 @@ void I_UpdateJoystickDeviceIndex(UINT8 player)
|
|||
// We DID NOT make it through the whole loop, so we can't assign this joystick to anything.
|
||||
// When you try your best, but you don't succeed...
|
||||
cv_usejoystick[player].value = 0;
|
||||
CONS_Printf("I_UpdateJoystickDeviceIndex: Device for %d set to %d\n", player, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1032,14 +1067,6 @@ void I_UpdateJoystickDeviceIndices(UINT8 excludePlayer)
|
|||
}
|
||||
}
|
||||
|
||||
/** \brief Joystick buttons states
|
||||
*/
|
||||
static UINT64 lastjoybuttons[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
||||
|
||||
/** \brief Joystick hats state
|
||||
*/
|
||||
static UINT64 lastjoyhats[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
||||
|
||||
/** \brief Shuts down joystick
|
||||
\return void
|
||||
*/
|
||||
|
|
@ -1047,29 +1074,22 @@ void I_ShutdownJoystick(UINT8 index)
|
|||
{
|
||||
INT32 i;
|
||||
event_t event;
|
||||
event.type=ev_keyup;
|
||||
|
||||
event.device = I_GetJoystickDeviceIndex(JoyInfo[index].dev);
|
||||
event.type = ev_keyup;
|
||||
event.data2 = 0;
|
||||
event.data3 = 0;
|
||||
|
||||
lastjoybuttons[index] = lastjoyhats[index] = 0;
|
||||
|
||||
// emulate the up of all joystick buttons
|
||||
for (i=0;i<JOYBUTTONS;i++)
|
||||
for (i = 0; i < JOYBUTTONS; i++)
|
||||
{
|
||||
event.data1=KEY_JOY1+i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
// emulate the up of all joystick hats
|
||||
for (i=0;i<JOYHATS*4;i++)
|
||||
{
|
||||
event.data1=KEY_HAT1+i;
|
||||
event.data1 = KEY_JOY1+i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
// reset joystick position
|
||||
event.type = ev_joystick;
|
||||
for (i=0;i<JOYAXISSET; i++)
|
||||
for (i = 0; i < JOYAXES; i++)
|
||||
{
|
||||
event.data1 = i;
|
||||
D_PostEvent(&event);
|
||||
|
|
@ -1081,136 +1101,6 @@ void I_ShutdownJoystick(UINT8 index)
|
|||
// don't shut down the subsystem here, because hotplugging
|
||||
}
|
||||
|
||||
void I_GetJoystickEvents(UINT8 index)
|
||||
{
|
||||
static event_t event = {0,0,0,0};
|
||||
INT32 i = 0;
|
||||
UINT64 joyhats = 0;
|
||||
#if 0
|
||||
UINT64 joybuttons = 0;
|
||||
Sint16 axisx, axisy;
|
||||
#endif
|
||||
|
||||
if (!joystick_started[index]) return;
|
||||
|
||||
if (!JoyInfo[index].dev) //I_ShutdownJoystick(index);
|
||||
return;
|
||||
|
||||
#if 0
|
||||
//faB: look for as much buttons as g_input code supports,
|
||||
// we don't use the others
|
||||
for (i = JoyInfo[index].buttons - 1; i >= 0; i--)
|
||||
{
|
||||
joybuttons <<= 1;
|
||||
if (SDL_JoystickGetButton(JoyInfo[index].dev,i))
|
||||
joybuttons |= 1;
|
||||
}
|
||||
|
||||
if (joybuttons != lastjoybuttons[index])
|
||||
{
|
||||
INT64 j = 1; // keep only bits that changed since last time
|
||||
INT64 newbuttons = joybuttons ^ lastjoybuttons[index];
|
||||
lastjoybuttons[index] = joybuttons;
|
||||
|
||||
for (i = 0; i < JOYBUTTONS; i++, j <<= 1)
|
||||
{
|
||||
if (newbuttons & j) // button changed state?
|
||||
{
|
||||
if (joybuttons & j)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
event.type = ev_keyup;
|
||||
event.data1 = KEY_JOY1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = JoyInfo[index].hats - 1; i >= 0; i--)
|
||||
{
|
||||
Uint8 hat = SDL_JoystickGetHat(JoyInfo[index].dev, i);
|
||||
|
||||
if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i);
|
||||
if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i);
|
||||
if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i);
|
||||
if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i);
|
||||
}
|
||||
|
||||
if (joyhats != lastjoyhats[index])
|
||||
{
|
||||
INT64 j = 1; // keep only bits that changed since last time
|
||||
INT64 newhats = joyhats ^ lastjoyhats[index];
|
||||
lastjoyhats[index] = joyhats;
|
||||
|
||||
for (i = 0; i < JOYHATS*4; i++, j <<= 1)
|
||||
{
|
||||
if (newhats & j) // hat changed state?
|
||||
{
|
||||
if (joyhats & j)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
event.type = ev_keyup;
|
||||
event.data1 = KEY_HAT1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// send joystick axis positions
|
||||
event.type = ev_joystick;
|
||||
|
||||
for (i = JOYAXISSET - 1; i >= 0; i--)
|
||||
{
|
||||
event.data1 = i;
|
||||
if (i*2 + 1 <= JoyInfo[index].axises)
|
||||
axisx = SDL_JoystickGetAxis(JoyInfo[index].dev, i*2 + 0);
|
||||
else axisx = 0;
|
||||
if (i*2 + 2 <= JoyInfo[index].axises)
|
||||
axisy = SDL_JoystickGetAxis(JoyInfo[index].dev, i*2 + 1);
|
||||
else axisy = 0;
|
||||
|
||||
|
||||
// -32768 to 32767
|
||||
axisx = axisx/32;
|
||||
axisy = axisy/32;
|
||||
|
||||
|
||||
if (Joystick[index].bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (axisx < -(JOYAXISRANGE/2))
|
||||
event.data2 = -1;
|
||||
else if (axisx > (JOYAXISRANGE/2))
|
||||
event.data2 = 1;
|
||||
else event.data2 = 0;
|
||||
if (axisy < -(JOYAXISRANGE/2))
|
||||
event.data3 = -1;
|
||||
else if (axisy > (JOYAXISRANGE/2))
|
||||
event.data3 = 1;
|
||||
else event.data3 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
axisx = JoyInfo[index].scale?((axisx/JoyInfo[index].scale)*JoyInfo[index].scale):axisx;
|
||||
axisy = JoyInfo[index].scale?((axisy/JoyInfo[index].scale)*JoyInfo[index].scale):axisy;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0;
|
||||
if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0;
|
||||
#endif
|
||||
|
||||
// analog control style , just send the raw data
|
||||
event.data2 = axisx; // x axis
|
||||
event.data3 = axisy; // y axis
|
||||
}
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Open joystick handle
|
||||
|
||||
\param fname name of joystick
|
||||
|
|
@ -1221,7 +1111,7 @@ void I_GetJoystickEvents(UINT8 index)
|
|||
*/
|
||||
static int joy_open(int playerIndex, int joyIndex)
|
||||
{
|
||||
SDL_Joystick *newdev = NULL;
|
||||
SDL_GameController *newdev = NULL;
|
||||
int num_joy = 0;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
|
|
@ -1230,6 +1120,12 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0)
|
||||
{
|
||||
CONS_Printf(M_GetText("Game Controller subsystem not started\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (joyIndex <= 0)
|
||||
return -1;
|
||||
|
||||
|
|
@ -1241,7 +1137,7 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
return -1;
|
||||
}
|
||||
|
||||
newdev = SDL_JoystickOpen(joyIndex-1);
|
||||
newdev = SDL_GameControllerOpen(joyIndex-1);
|
||||
|
||||
// Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
|
||||
// This indexing is SDL's responsibility and there's not much we can do about it.
|
||||
|
|
@ -1256,9 +1152,9 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
if (JoyInfo[playerIndex].dev)
|
||||
{
|
||||
if (JoyInfo[playerIndex].dev == newdev // same device, nothing to do
|
||||
|| (newdev == NULL && SDL_JoystickGetAttached(JoyInfo[playerIndex].dev))) // we failed, but already have a working device
|
||||
|| (newdev == NULL && SDL_GameControllerGetAttached(JoyInfo[playerIndex].dev))) // we failed, but already have a working device
|
||||
{
|
||||
return JoyInfo[playerIndex].axises;
|
||||
return SDL_CONTROLLER_AXIS_MAX;
|
||||
}
|
||||
|
||||
// Else, we're changing devices, so send neutral joy events
|
||||
|
|
@ -1275,29 +1171,12 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
}
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: %s\n"), playerIndex+1, SDL_JoystickName(JoyInfo[playerIndex].dev));
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick%d: %s\n"), playerIndex+1, SDL_GameControllerName(JoyInfo[playerIndex].dev));
|
||||
|
||||
JoyInfo[playerIndex].axises = SDL_JoystickNumAxes(JoyInfo[playerIndex].dev);
|
||||
if (JoyInfo[playerIndex].axises > JOYAXISSET*2)
|
||||
JoyInfo[playerIndex].axises = JOYAXISSET*2;
|
||||
|
||||
/*
|
||||
if (joyaxes<2)
|
||||
{
|
||||
I_OutputMsg("Not enought axes?\n");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
JoyInfo[playerIndex].buttons = SDL_JoystickNumButtons(JoyInfo[playerIndex].dev);
|
||||
if (JoyInfo[playerIndex].buttons > JOYBUTTONS)
|
||||
JoyInfo[playerIndex].buttons = JOYBUTTONS;
|
||||
|
||||
JoyInfo[playerIndex].hats = SDL_JoystickNumHats(JoyInfo[playerIndex].dev);
|
||||
if (JoyInfo[playerIndex].hats > JOYHATS)
|
||||
JoyInfo[playerIndex].hats = JOYHATS;
|
||||
|
||||
JoyInfo[playerIndex].balls = SDL_JoystickNumBalls(JoyInfo[playerIndex].dev);
|
||||
JoyInfo[playerIndex].axises = SDL_CONTROLLER_AXIS_MAX;
|
||||
JoyInfo[playerIndex].buttons = SDL_CONTROLLER_BUTTON_MAX;
|
||||
JoyInfo[playerIndex].hats = 1;
|
||||
JoyInfo[playerIndex].balls = 0;
|
||||
|
||||
//JoyInfo[playerIndex].bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo[playerIndex].dev), "pad");
|
||||
|
||||
|
|
@ -1310,7 +1189,7 @@ static int joy_open(int playerIndex, int joyIndex)
|
|||
//
|
||||
void I_InitJoystick(UINT8 index)
|
||||
{
|
||||
SDL_Joystick *newjoy = NULL;
|
||||
SDL_GameController *newcontroller = NULL;
|
||||
UINT8 i;
|
||||
|
||||
//I_ShutdownJoystick();
|
||||
|
|
@ -1335,23 +1214,33 @@ void I_InitJoystick(UINT8 index)
|
|||
}
|
||||
}
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0)
|
||||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't initialize gamepads: %s\n"), SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_usejoystick[index].value)
|
||||
newjoy = SDL_JoystickOpen(cv_usejoystick[index].value-1);
|
||||
newcontroller = SDL_GameControllerOpen(cv_usejoystick[index].value-1);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (i == index)
|
||||
continue;
|
||||
|
||||
if (JoyInfo[i].dev == newjoy)
|
||||
if (JoyInfo[i].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (newjoy && i < MAXSPLITSCREENPLAYERS) // don't override an active device
|
||||
if (newcontroller && i < MAXSPLITSCREENPLAYERS) // don't override an active device
|
||||
{
|
||||
cv_usejoystick[index].value = I_GetJoystickDeviceIndex(JoyInfo[index].dev) + 1;
|
||||
CONS_Printf("I_InitJoystick: Device for %d set to %d\n", index, cv_usejoystick[index].value);
|
||||
}
|
||||
else if (newjoy && joy_open(index, cv_usejoystick[index].value) != -1)
|
||||
else if (newcontroller && joy_open(index, cv_usejoystick[index].value) != -1)
|
||||
{
|
||||
// SDL's device indexes are unstable, so cv_usejoystick may not match
|
||||
// the actual device index. So let's cheat a bit and find the device's current index.
|
||||
|
|
@ -1363,19 +1252,20 @@ void I_InitJoystick(UINT8 index)
|
|||
if (JoyInfo[index].oldjoy)
|
||||
I_ShutdownJoystick(index);
|
||||
cv_usejoystick[index].value = 0;
|
||||
CONS_Printf("I_InitJoystick: Device for %d set to %d\n", index, cv_usejoystick[index].value);
|
||||
joystick_started[index] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (JoyInfo[i].dev == newjoy)
|
||||
if (JoyInfo[i].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
// Joystick didn't end up being used
|
||||
SDL_JoystickClose(newjoy);
|
||||
I_StoreExJoystick(newcontroller);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1410,6 +1300,13 @@ static void I_ShutdownInput(void)
|
|||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
I_ShutdownJoystick(i);
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == SDL_INIT_GAMECONTROLLER)
|
||||
{
|
||||
CONS_Printf("Shutting down gamecontroller system\n");
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
I_OutputMsg("I_Joystick: SDL's Game Controller system has been shutdown\n");
|
||||
}
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
{
|
||||
CONS_Printf("Shutting down joy system\n");
|
||||
|
|
@ -1838,6 +1735,7 @@ void I_Quit(void)
|
|||
M_SaveConfig(NULL); //save game config, cvars..
|
||||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
M_SaveJoinedIPs();
|
||||
#endif
|
||||
|
||||
// Make sure you lose points for ALT-F4
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
#include "../i_system.h"
|
||||
#include "../v_video.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../m_menu.h"
|
||||
#include "../k_menu.h"
|
||||
#include "../d_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../i_sound.h" // midi pause/unpause
|
||||
|
|
@ -372,7 +372,7 @@ static boolean IgnoreMouse(void)
|
|||
if (cv_alwaysgrabmouse.value)
|
||||
return false;
|
||||
if (menuactive)
|
||||
return !M_MouseNeeded();
|
||||
return false; // return !M_MouseNeeded();
|
||||
if (paused || con_destlines || chat_on)
|
||||
return true;
|
||||
if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION &&
|
||||
|
|
@ -526,95 +526,31 @@ static inline void SDLJoyRemap(event_t *event)
|
|||
(void)event;
|
||||
}
|
||||
|
||||
static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which)
|
||||
static INT32 SDLJoyAxis(const Sint16 axis, UINT8 pid)
|
||||
{
|
||||
// -32768 to 32767
|
||||
INT32 raxis = axis/32;
|
||||
if (which == ev_joystick)
|
||||
INT32 raxis = axis / 32;
|
||||
|
||||
if (Joystick[pid].bGamepadStyle)
|
||||
{
|
||||
if (Joystick[0].bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else
|
||||
raxis = 0;
|
||||
}
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else
|
||||
{
|
||||
raxis = JoyInfo[0].scale!=1?((raxis/JoyInfo[0].scale)*JoyInfo[0].scale):raxis;
|
||||
raxis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
raxis = (abs(JoyInfo[pid].scale) > 1) ? ((raxis / JoyInfo[pid].scale) * JoyInfo[pid].scale) : raxis;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (which == ev_joystick2)
|
||||
{
|
||||
if (Joystick[1].bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else raxis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
raxis = JoyInfo[1].scale!=1?((raxis/JoyInfo[1].scale)*JoyInfo[1].scale):raxis;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (which == ev_joystick3)
|
||||
{
|
||||
if (Joystick[2].bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else raxis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
raxis = JoyInfo[2].scale!=1?((raxis/JoyInfo[2].scale)*JoyInfo[2].scale):raxis;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (which == ev_joystick4)
|
||||
{
|
||||
if (Joystick[3].bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else raxis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
raxis = JoyInfo[3].scale!=1?((raxis/JoyInfo[3].scale)*JoyInfo[3].scale):raxis;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return raxis;
|
||||
}
|
||||
|
||||
|
|
@ -679,7 +615,8 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
{
|
||||
SDLforceUngrabMouse();
|
||||
}
|
||||
memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset
|
||||
memset(gamekeydown, 0, sizeof(gamekeydown)); // TODO this is a scary memset
|
||||
memset(deviceResponding, false, sizeof (deviceResponding));
|
||||
|
||||
if (MOUSE_MENU)
|
||||
{
|
||||
|
|
@ -692,6 +629,9 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
|
||||
event.device = 0;
|
||||
|
||||
if (type == SDL_KEYUP)
|
||||
{
|
||||
event.type = ev_keyup;
|
||||
|
|
@ -773,6 +713,8 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
|
|||
/// \todo inputEvent.button.which
|
||||
if (USE_MOUSEINPUT)
|
||||
{
|
||||
event.device = 0;
|
||||
|
||||
if (type == SDL_MOUSEBUTTONUP)
|
||||
{
|
||||
event.type = ev_keyup;
|
||||
|
|
@ -805,6 +747,8 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt)
|
|||
|
||||
SDL_memset(&event, 0, sizeof(event_t));
|
||||
|
||||
event.device = 0;
|
||||
|
||||
if (evt.y > 0)
|
||||
{
|
||||
event.data1 = KEY_MOUSEWHEELUP;
|
||||
|
|
@ -826,138 +770,87 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt)
|
|||
}
|
||||
}
|
||||
|
||||
static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt)
|
||||
static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt)
|
||||
{
|
||||
event_t event;
|
||||
SDL_JoystickID joyid[MAXSPLITSCREENPLAYERS];
|
||||
UINT8 i;
|
||||
INT32 value;
|
||||
|
||||
// Determine the Joystick IDs for each current open joystick
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
joyid[i] = SDL_JoystickInstanceID(JoyInfo[i].dev);
|
||||
event.type = ev_joystick;
|
||||
|
||||
event.device = 1 + evt.which;
|
||||
if (event.device == INT32_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
evt.axis++;
|
||||
event.data1 = event.data2 = event.data3 = INT32_MAX;
|
||||
|
||||
if (evt.which == joyid[0])
|
||||
{
|
||||
event.type = ev_joystick;
|
||||
}
|
||||
else if (evt.which == joyid[1])
|
||||
{
|
||||
event.type = ev_joystick2;
|
||||
}
|
||||
else if (evt.which == joyid[2])
|
||||
{
|
||||
event.type = ev_joystick3;
|
||||
}
|
||||
else if (evt.which == joyid[3])
|
||||
{
|
||||
event.type = ev_joystick4;
|
||||
}
|
||||
else return;
|
||||
//axis
|
||||
if (evt.axis > JOYAXISSET*2)
|
||||
return;
|
||||
//vaule
|
||||
if (evt.axis%2)
|
||||
if (evt.axis > 2 * JOYAXISSETS)
|
||||
{
|
||||
event.data1 = evt.axis / 2;
|
||||
event.data2 = SDLJoyAxis(evt.value, event.type);
|
||||
return;
|
||||
}
|
||||
|
||||
//vaule[sic]
|
||||
value = SDLJoyAxis(evt.value, evt.which);
|
||||
|
||||
if (evt.axis & 1)
|
||||
{
|
||||
event.data3 = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.axis--;
|
||||
event.data1 = evt.axis / 2;
|
||||
event.data3 = SDLJoyAxis(evt.value, event.type);
|
||||
event.data2 = value;
|
||||
}
|
||||
|
||||
event.data1 = evt.axis / 2;
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt)
|
||||
static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
SDL_JoystickID joyid[MAXSPLITSCREENPLAYERS];
|
||||
UINT8 i;
|
||||
|
||||
// Determine the Joystick IDs for each current open joystick
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
joyid[i] = SDL_JoystickInstanceID(JoyInfo[i].dev);
|
||||
event.device = 1 + evt.which;
|
||||
|
||||
if (evt.hat >= JOYHATS)
|
||||
return; // ignore hats with too high an index
|
||||
if (event.device == INT32_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.which == joyid[0])
|
||||
{
|
||||
event.data1 = KEY_HAT1 + (evt.hat*4);
|
||||
}
|
||||
else if (evt.which == joyid[1])
|
||||
{
|
||||
event.data1 = KEY_2HAT1 + (evt.hat*4);
|
||||
}
|
||||
else if (evt.which == joyid[2])
|
||||
{
|
||||
event.data1 = KEY_3HAT1 + (evt.hat*4);
|
||||
}
|
||||
else if (evt.which == joyid[3])
|
||||
{
|
||||
event.data1 = KEY_4HAT1 + (evt.hat*4);
|
||||
}
|
||||
else return;
|
||||
event.data1 = KEY_JOY1;
|
||||
|
||||
// NOTE: UNFINISHED
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
SDL_JoystickID joyid[MAXSPLITSCREENPLAYERS];
|
||||
UINT8 i;
|
||||
|
||||
// Determine the Joystick IDs for each current open joystick
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
joyid[i] = SDL_JoystickInstanceID(JoyInfo[i].dev);
|
||||
|
||||
if (evt.which == joyid[0])
|
||||
{
|
||||
event.data1 = KEY_JOY1;
|
||||
}
|
||||
else if (evt.which == joyid[1])
|
||||
{
|
||||
event.data1 = KEY_2JOY1;
|
||||
}
|
||||
else if (evt.which == joyid[2])
|
||||
{
|
||||
event.data1 = KEY_3JOY1;
|
||||
}
|
||||
else if (evt.which == joyid[3])
|
||||
{
|
||||
event.data1 = KEY_4JOY1;
|
||||
}
|
||||
else return;
|
||||
if (type == SDL_JOYBUTTONUP)
|
||||
if (type == SDL_CONTROLLERBUTTONUP)
|
||||
{
|
||||
event.type = ev_keyup;
|
||||
}
|
||||
else if (type == SDL_JOYBUTTONDOWN)
|
||||
else if (type == SDL_CONTROLLERBUTTONDOWN)
|
||||
{
|
||||
event.type = ev_keydown;
|
||||
}
|
||||
else return;
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.button < JOYBUTTONS)
|
||||
{
|
||||
event.data1 += evt.button;
|
||||
}
|
||||
else return;
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDLJoyRemap(&event);
|
||||
if (event.type != ev_console) D_PostEvent(&event);
|
||||
|
||||
if (event.type != ev_console)
|
||||
{
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void I_GetEvent(void)
|
||||
{
|
||||
SDL_Event evt;
|
||||
|
|
@ -998,28 +891,23 @@ void I_GetEvent(void)
|
|||
case SDL_MOUSEWHEEL:
|
||||
Impl_HandleMouseWheelEvent(evt.wheel);
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
Impl_HandleJoystickAxisEvent(evt.jaxis);
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
Impl_HandleControllerAxisEvent(evt.caxis);
|
||||
break;
|
||||
#if 0
|
||||
case SDL_JOYHATMOTION:
|
||||
Impl_HandleJoystickHatEvent(evt.jhat)
|
||||
break;
|
||||
#endif
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
Impl_HandleControllerButtonEvent(evt.cbutton, evt.type);
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
case SDL_JOYDEVICEADDED:
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
{
|
||||
// OH BOY are you in for a good time! #abominationstation
|
||||
|
||||
SDL_Joystick *newjoy = SDL_JoystickOpen(evt.jdevice.which);
|
||||
SDL_GameController *newcontroller = SDL_GameControllerOpen(evt.cdevice.which);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick device index %d added\n", evt.jdevice.which + 1);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Controller device index %d added\n", evt.cdevice.which + 1);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Because SDL's device index is unstable, we're going to cheat here a bit:
|
||||
|
|
@ -1034,7 +922,7 @@ void I_GetEvent(void)
|
|||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (newjoy && (!JoyInfo[i].dev || !SDL_JoystickGetAttached(JoyInfo[i].dev)))
|
||||
if (newcontroller && (!JoyInfo[i].dev || !SDL_GameControllerGetAttached(JoyInfo[i].dev)))
|
||||
{
|
||||
UINT8 j;
|
||||
|
||||
|
|
@ -1043,14 +931,14 @@ void I_GetEvent(void)
|
|||
if (i == j)
|
||||
continue;
|
||||
|
||||
if (JoyInfo[j].dev == newjoy)
|
||||
if (JoyInfo[j].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
// ensures we aren't overriding a currently active device
|
||||
cv_usejoystick[i].value = evt.jdevice.which + 1;
|
||||
cv_usejoystick[i].value = evt.cdevice.which + 1;
|
||||
I_UpdateJoystickDeviceIndices(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1084,27 +972,29 @@ void I_GetEvent(void)
|
|||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
||||
|
||||
#if 0
|
||||
// update the menu
|
||||
if (currentMenu == &OP_JoystickSetDef)
|
||||
M_SetupJoystickMenu(0);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (JoyInfo[i].dev == newjoy)
|
||||
if (JoyInfo[i].dev == newcontroller)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXSPLITSCREENPLAYERS)
|
||||
SDL_JoystickClose(newjoy);
|
||||
I_StoreExJoystick(newcontroller);
|
||||
}
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
case SDL_JOYDEVICEREMOVED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (JoyInfo[i].dev && !SDL_JoystickGetAttached(JoyInfo[i].dev))
|
||||
if (JoyInfo[i].dev && !SDL_GameControllerGetAttached(JoyInfo[i].dev))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d removed, device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
||||
I_ShutdownJoystick(i);
|
||||
|
|
@ -1144,9 +1034,11 @@ void I_GetEvent(void)
|
|||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy);
|
||||
|
||||
#if 0
|
||||
// update the menu
|
||||
if (currentMenu == &OP_JoystickSetDef)
|
||||
M_SetupJoystickMenu(0);
|
||||
#endif
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
LUAh_GameQuit(true);
|
||||
|
|
@ -1171,7 +1063,10 @@ void I_GetEvent(void)
|
|||
|
||||
// In order to make wheels act like buttons, we have to set their state to Up.
|
||||
// This is because wheel messages don't have an up/down state.
|
||||
gamekeydown[KEY_MOUSEWHEELDOWN] = gamekeydown[KEY_MOUSEWHEELUP] = 0;
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
gamekeydown[i][KEY_MOUSEWHEELDOWN] = gamekeydown[i][KEY_MOUSEWHEELUP] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void I_StartupMouse(void)
|
||||
|
|
@ -1199,16 +1094,12 @@ void I_StartupMouse(void)
|
|||
void I_OsPolling(void)
|
||||
{
|
||||
SDL_Keymod mod;
|
||||
UINT8 i;
|
||||
|
||||
if (consolevent)
|
||||
I_GetConsoleEvents();
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
{
|
||||
SDL_JoystickUpdate();
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
I_GetJoystickEvents(i);
|
||||
}
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER))
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
I_GetEvent();
|
||||
|
||||
|
|
@ -1583,15 +1474,22 @@ static SDL_bool Impl_CreateContext(void)
|
|||
int flags = 0; // Use this to set SDL_RENDERER_* flags now
|
||||
if (usesdl2soft)
|
||||
flags |= SDL_RENDERER_SOFTWARE;
|
||||
#if 0
|
||||
// This shit is BROKEN.
|
||||
// - The version of SDL we're using cannot toggle VSync at runtime. We'll need a new SDL version implemented to have this work properly.
|
||||
// - cv_vidwait is initialized before config is loaded, so it's forced to default value at runtime, and forced off when switching. The config loading code would need restructured.
|
||||
// - With both this & frame interpolation on, I_FinishUpdate takes x10 longer. At this point, it is simpler to use a standard FPS cap.
|
||||
// So you can probably guess why I'm kinda over this, I'm just disabling it.
|
||||
else if (cv_vidwait.value)
|
||||
flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
#endif
|
||||
|
||||
// 3 August 2022
|
||||
// Possibly a Windows 11 issue; the default
|
||||
// "direct3d" driver (D3D9) causes Drmingw exchndl
|
||||
// to not write RPT files. Every other driver
|
||||
// seems fine.
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d11");
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
|
||||
|
||||
if (!renderer)
|
||||
renderer = SDL_CreateRenderer(window, -1, flags);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ extern SDL_bool framebuffer;
|
|||
*/
|
||||
typedef struct SDLJoyInfo_s
|
||||
{
|
||||
/// Joystick handle
|
||||
SDL_Joystick *dev;
|
||||
/// Controller handle
|
||||
SDL_GameController *dev;
|
||||
/// number of old joystick
|
||||
int oldjoy;
|
||||
/// number of axies
|
||||
|
|
@ -58,9 +58,12 @@ typedef struct SDLJoyInfo_s
|
|||
|
||||
} SDLJoyInfo_t;
|
||||
|
||||
/** \brief SDL info about joysticks
|
||||
/** \brief SDL info about controllers
|
||||
*/
|
||||
extern SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||
extern SDL_GameController *ExJoystick[MAXGAMEPADS];
|
||||
|
||||
void I_StoreExJoystick(SDL_GameController *dev);
|
||||
|
||||
/** \brief joystick axis deadzone
|
||||
*/
|
||||
|
|
@ -72,8 +75,8 @@ void I_GetConsoleEvents(void);
|
|||
// So we can call this from i_video event loop
|
||||
void I_ShutdownJoystick(UINT8 index);
|
||||
|
||||
// Cheat to get the device index for a joystick handle
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev);
|
||||
// Cheat to get the device index for a game controller handle
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev);
|
||||
|
||||
// Quick thing to make SDL_JOYDEVICEADDED events less of an abomination
|
||||
void I_UpdateJoystickDeviceIndex(UINT8 player);
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,9 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"kdtrg3", false, 64, 80, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // High energy, SF_X2AWAYSOUND|SF_X8AWAYSOUND
|
||||
|
||||
// SRB2kart - Grow/invinc clash
|
||||
{"parry", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND
|
||||
{"parry", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND
|
||||
|
||||
{"ffbonc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SRB2Kart - Engine sounds
|
||||
// Engine class A
|
||||
|
|
|
|||
|
|
@ -1176,6 +1176,9 @@ typedef enum
|
|||
// SRB2Kart - Powerup clash SFX
|
||||
sfx_parry,
|
||||
|
||||
// Fast fall bounce
|
||||
sfx_ffbonc,
|
||||
|
||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||
// Engine class A - Low Speed, Low Weight
|
||||
sfx_krta00,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "console.h"
|
||||
#include "s_sound.h"
|
||||
#include "i_system.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_cheat.h"
|
||||
#include "m_misc.h" // moviemode
|
||||
#include "m_anigif.h" // cv_gif_downscale
|
||||
|
|
@ -1057,7 +1057,7 @@ static void ST_overlayDrawer(void)
|
|||
else if (G_GametypeHasTeams())
|
||||
itemtxt = M_GetText("Item - Join Team");
|
||||
|
||||
if (cv_ingamecap.value)
|
||||
if (cv_maxplayers.value)
|
||||
{
|
||||
UINT8 numingame = 0;
|
||||
UINT8 i;
|
||||
|
|
@ -1066,7 +1066,7 @@ static void ST_overlayDrawer(void)
|
|||
if (playeringame[i] && !players[i].spectator)
|
||||
numingame++;
|
||||
|
||||
itemtxt = va("%s (%s: %d)", itemtxt, M_GetText("Slots left"), max(0, cv_ingamecap.value - numingame));
|
||||
itemtxt = va("%s (%s: %d)", itemtxt, M_GetText("Slots left"), max(0, cv_maxplayers.value - numingame));
|
||||
}
|
||||
|
||||
// SRB2kart: changed positions & text
|
||||
|
|
@ -1088,11 +1088,11 @@ static void ST_overlayDrawer(void)
|
|||
|
||||
void ST_DrawDemoTitleEntry(void)
|
||||
{
|
||||
static UINT8 skullAnimCounter = 0;
|
||||
static UINT8 anim = 0;
|
||||
char *nametodraw;
|
||||
|
||||
skullAnimCounter++;
|
||||
skullAnimCounter %= 8;
|
||||
anim++;
|
||||
anim %= 8;
|
||||
|
||||
nametodraw = demo.titlename;
|
||||
while (V_StringWidth(nametodraw, 0) > MAXSTRINGLENGTH*8 - 8)
|
||||
|
|
@ -1102,7 +1102,7 @@ void ST_DrawDemoTitleEntry(void)
|
|||
#define y (BASEVIDHEIGHT/2)
|
||||
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
|
||||
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, nametodraw);
|
||||
if (skullAnimCounter < 4)
|
||||
if (anim < 4)
|
||||
V_DrawCharacter(x + 8 + V_StringWidth(nametodraw, 0), y + 12,
|
||||
'_' | 0x80, false);
|
||||
|
||||
|
|
|
|||
638
src/v_video.c
638
src/v_video.c
|
|
@ -1966,6 +1966,48 @@ static inline fixed_t BunchedCharacterDim(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline fixed_t GamemodeCharacterDim(
|
||||
fixed_t scale,
|
||||
fixed_t chw,
|
||||
INT32 hchw,
|
||||
INT32 dupx,
|
||||
fixed_t * cwp)
|
||||
{
|
||||
(void)chw;
|
||||
(void)hchw;
|
||||
(void)dupx;
|
||||
(*cwp) = FixedMul (max (1, (*cwp) - 2) << FRACBITS, scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline fixed_t FileCharacterDim(
|
||||
fixed_t scale,
|
||||
fixed_t chw,
|
||||
INT32 hchw,
|
||||
INT32 dupx,
|
||||
fixed_t * cwp)
|
||||
{
|
||||
(void)chw;
|
||||
(void)hchw;
|
||||
(void)dupx;
|
||||
(*cwp) = FixedMul (max (1, (*cwp) - 3) << FRACBITS, scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline fixed_t LSTitleCharacterDim(
|
||||
fixed_t scale,
|
||||
fixed_t chw,
|
||||
INT32 hchw,
|
||||
INT32 dupx,
|
||||
fixed_t * cwp)
|
||||
{
|
||||
(void)chw;
|
||||
(void)hchw;
|
||||
(void)dupx;
|
||||
(*cwp) = FixedMul (max (1, (*cwp) - 4) << FRACBITS, scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void V_DrawStringScaled(
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
|
|
@ -1973,6 +2015,7 @@ void V_DrawStringScaled(
|
|||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
const UINT8 *colormap,
|
||||
int fontno,
|
||||
const char *s)
|
||||
{
|
||||
|
|
@ -1993,8 +2036,6 @@ void V_DrawStringScaled(
|
|||
boolean uppercase;
|
||||
boolean notcolored;
|
||||
|
||||
const UINT8 *colormap;
|
||||
|
||||
fixed_t cx, cy;
|
||||
|
||||
fixed_t cxoff;
|
||||
|
|
@ -2006,9 +2047,13 @@ void V_DrawStringScaled(
|
|||
int c;
|
||||
|
||||
uppercase = !( flags & V_ALLOWLOWERCASE );
|
||||
flags &= ~(V_FLIP);/* These two (V_ALLOWLOWERCASE) share a bit. */
|
||||
flags &= ~(V_FLIP);/* These two (V_ALLOWLOWERCASE) share a bit. */
|
||||
|
||||
if (colormap == NULL)
|
||||
{
|
||||
colormap = V_GetStringColormap(( flags & V_CHARCOLORMASK ));
|
||||
}
|
||||
|
||||
colormap = V_GetStringColormap(( flags & V_CHARCOLORMASK ));
|
||||
notcolored = !colormap;
|
||||
|
||||
font = &fontv[fontno];
|
||||
|
|
@ -2053,6 +2098,12 @@ void V_DrawStringScaled(
|
|||
spacewidth = 3;*/
|
||||
}
|
||||
break;
|
||||
case LT_FONT:
|
||||
spacew = 12;
|
||||
break;
|
||||
case CRED_FONT:
|
||||
spacew = 16;
|
||||
break;
|
||||
case KART_FONT:
|
||||
spacew = 12;
|
||||
switch (spacing)
|
||||
|
|
@ -2067,13 +2118,18 @@ void V_DrawStringScaled(
|
|||
spacew = 6;
|
||||
}
|
||||
break;
|
||||
case LT_FONT:
|
||||
spacew = 12;
|
||||
case GM_FONT:
|
||||
spacew = 6;
|
||||
break;
|
||||
case CRED_FONT:
|
||||
case FILE_FONT:
|
||||
spacew = 0;
|
||||
break;
|
||||
case LSHI_FONT:
|
||||
case LSLOW_FONT:
|
||||
spacew = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fontno)
|
||||
{
|
||||
default:
|
||||
|
|
@ -2084,8 +2140,18 @@ void V_DrawStringScaled(
|
|||
break;
|
||||
case LT_FONT:
|
||||
case CRED_FONT:
|
||||
case FILE_FONT:
|
||||
lfh = 12;
|
||||
break;
|
||||
case GM_FONT:
|
||||
lfh = 32;
|
||||
break;
|
||||
case LSHI_FONT:
|
||||
lfh = 56;
|
||||
break;
|
||||
case LSLOW_FONT:
|
||||
lfh = 38;
|
||||
break;
|
||||
}
|
||||
|
||||
hchw = chw >> 1;
|
||||
|
|
@ -2130,25 +2196,45 @@ void V_DrawStringScaled(
|
|||
right <<= FRACBITS;
|
||||
bot = vid.height << FRACBITS;
|
||||
|
||||
if (fontno == TINY_FONT)
|
||||
switch (fontno)
|
||||
{
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
{
|
||||
/* Reuse this flag for the alternate bunched-up spacing. */
|
||||
if (( flags & V_6WIDTHSPACE ))
|
||||
dim_fn = BunchedCharacterDim;
|
||||
default:
|
||||
if (chw)
|
||||
dim_fn = CenteredCharacterDim;
|
||||
else
|
||||
dim_fn = VariableCharacterDim;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chw)
|
||||
dim_fn = CenteredCharacterDim;
|
||||
else
|
||||
dim_fn = VariableCharacterDim;
|
||||
break;
|
||||
case TINY_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
{
|
||||
/* Reuse this flag for the alternate bunched-up spacing. */
|
||||
if (( flags & V_6WIDTHSPACE ))
|
||||
dim_fn = BunchedCharacterDim;
|
||||
else
|
||||
dim_fn = VariableCharacterDim;
|
||||
}
|
||||
break;
|
||||
case GM_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
dim_fn = GamemodeCharacterDim;
|
||||
break;
|
||||
case FILE_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
dim_fn = FileCharacterDim;
|
||||
break;
|
||||
case LSHI_FONT:
|
||||
case LSLOW_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
dim_fn = LSTitleCharacterDim;
|
||||
break;
|
||||
}
|
||||
|
||||
cx = x;
|
||||
|
|
@ -2194,7 +2280,237 @@ void V_DrawStringScaled(
|
|||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
fixed_t V_StringScaledWidth(
|
||||
fixed_t scale,
|
||||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
int fontno,
|
||||
const char *s)
|
||||
{
|
||||
fixed_t chw;
|
||||
INT32 hchw;/* half-width for centering */
|
||||
fixed_t spacew;
|
||||
fixed_t lfh;
|
||||
|
||||
INT32 dupx;
|
||||
|
||||
fixed_t (*dim_fn)(fixed_t,fixed_t,INT32,INT32,fixed_t *);
|
||||
|
||||
font_t *font;
|
||||
|
||||
boolean uppercase;
|
||||
|
||||
fixed_t cx, cy;
|
||||
|
||||
fixed_t cw;
|
||||
|
||||
INT32 spacing;
|
||||
|
||||
int c;
|
||||
|
||||
fixed_t fullwidth = 0;
|
||||
|
||||
uppercase = !( flags & V_ALLOWLOWERCASE );
|
||||
flags &= ~(V_FLIP);/* These two (V_ALLOWLOWERCASE) share a bit. */
|
||||
|
||||
font = &fontv[fontno];
|
||||
|
||||
chw = 0;
|
||||
|
||||
spacing = ( flags & V_SPACINGMASK );
|
||||
|
||||
/*
|
||||
Hardcoded until a better system can be implemented
|
||||
for determining how fonts space.
|
||||
*/
|
||||
switch (fontno)
|
||||
{
|
||||
default:
|
||||
case HU_FONT:
|
||||
spacew = 4;
|
||||
switch (spacing)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacew = 8;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
chw = 8;
|
||||
break;
|
||||
case V_6WIDTHSPACE:
|
||||
spacew = 6;
|
||||
}
|
||||
break;
|
||||
case TINY_FONT:
|
||||
spacew = 2;
|
||||
switch (spacing)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacew = 5;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
chw = 5;
|
||||
break;
|
||||
// Out of video flags, so we're reusing this for alternate charwidth instead
|
||||
/*case V_6WIDTHSPACE:
|
||||
spacewidth = 3;*/
|
||||
}
|
||||
break;
|
||||
case LT_FONT:
|
||||
spacew = 12;
|
||||
break;
|
||||
case CRED_FONT:
|
||||
spacew = 16;
|
||||
break;
|
||||
case KART_FONT:
|
||||
spacew = 12;
|
||||
switch (spacing)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacew = 12;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
chw = 12;
|
||||
break;
|
||||
case V_6WIDTHSPACE:
|
||||
spacew = 6;
|
||||
}
|
||||
break;
|
||||
case GM_FONT:
|
||||
case FILE_FONT:
|
||||
spacew = 0;
|
||||
break;
|
||||
case LSHI_FONT:
|
||||
case LSLOW_FONT:
|
||||
spacew = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fontno)
|
||||
{
|
||||
default:
|
||||
case HU_FONT:
|
||||
case TINY_FONT:
|
||||
case KART_FONT:
|
||||
lfh = 12;
|
||||
break;
|
||||
case LT_FONT:
|
||||
case CRED_FONT:
|
||||
case FILE_FONT:
|
||||
lfh = 12;
|
||||
break;
|
||||
case GM_FONT:
|
||||
lfh = 32;
|
||||
break;
|
||||
case LSHI_FONT:
|
||||
lfh = 56;
|
||||
break;
|
||||
case LSLOW_FONT:
|
||||
lfh = 38;
|
||||
break;
|
||||
}
|
||||
|
||||
hchw = chw >> 1;
|
||||
|
||||
chw <<= FRACBITS;
|
||||
spacew <<= FRACBITS;
|
||||
|
||||
#define Mul( id, scale ) ( id = FixedMul (scale, id) )
|
||||
Mul (chw, scale);
|
||||
Mul (spacew, scale);
|
||||
Mul (lfh, scale);
|
||||
|
||||
Mul (spacew, spacescale);
|
||||
Mul (lfh, lfscale);
|
||||
#undef Mul
|
||||
|
||||
if (( flags & V_NOSCALESTART ))
|
||||
{
|
||||
dupx = vid.dupx;
|
||||
|
||||
hchw *= dupx;
|
||||
|
||||
chw *= dupx;
|
||||
spacew *= dupx;
|
||||
lfh *= vid.dupy;
|
||||
}
|
||||
else
|
||||
{
|
||||
dupx = 1;
|
||||
}
|
||||
|
||||
switch (fontno)
|
||||
{
|
||||
default:
|
||||
if (chw)
|
||||
dim_fn = CenteredCharacterDim;
|
||||
else
|
||||
dim_fn = VariableCharacterDim;
|
||||
break;
|
||||
case TINY_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
{
|
||||
/* Reuse this flag for the alternate bunched-up spacing. */
|
||||
if (( flags & V_6WIDTHSPACE ))
|
||||
dim_fn = BunchedCharacterDim;
|
||||
else
|
||||
dim_fn = VariableCharacterDim;
|
||||
}
|
||||
break;
|
||||
case GM_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
dim_fn = GamemodeCharacterDim;
|
||||
break;
|
||||
case FILE_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
dim_fn = FileCharacterDim;
|
||||
break;
|
||||
case LSHI_FONT:
|
||||
case LSLOW_FONT:
|
||||
if (chw)
|
||||
dim_fn = FixedCharacterDim;
|
||||
else
|
||||
dim_fn = LSTitleCharacterDim;
|
||||
break;
|
||||
}
|
||||
|
||||
cx = cy = 0;
|
||||
|
||||
for (; ( c = *s ); ++s)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
cy += lfh;
|
||||
cx = 0;
|
||||
break;
|
||||
default:
|
||||
if (uppercase)
|
||||
c = toupper(c);
|
||||
|
||||
c -= font->start;
|
||||
if (c >= 0 && c < font->size && font->font[c])
|
||||
{
|
||||
cw = SHORT (font->font[c]->width) * dupx;
|
||||
(*dim_fn)(scale, chw, hchw, dupx, &cw);
|
||||
cx += cw;
|
||||
}
|
||||
else
|
||||
cx += spacew;
|
||||
}
|
||||
|
||||
fullwidth = max(cx, fullwidth);
|
||||
}
|
||||
|
||||
return fullwidth;
|
||||
}
|
||||
|
||||
void V_DrawCenteredString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
|
|
@ -2244,49 +2560,64 @@ void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, con
|
|||
V_DrawThinStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
// Draws a number using the PING font thingy.
|
||||
// TODO: Merge number drawing functions into one with "font name" selection.
|
||||
|
||||
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap)
|
||||
void V_DrawCenteredKartString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
INT32 w = SHORT(fontv[PINGNUM_FONT].font[0]->width); // this SHOULD always be 5 but I guess custom graphics exist.
|
||||
|
||||
if (flags & V_NOSCALESTART)
|
||||
w *= vid.dupx;
|
||||
|
||||
if (num < 0)
|
||||
num = -num;
|
||||
|
||||
// draw the number
|
||||
do
|
||||
{
|
||||
x -= (w-1); // Oni wanted their outline to intersect.
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, fontv[PINGNUM_FONT].font[num%10], colormap);
|
||||
num /= 10;
|
||||
} while (num);
|
||||
x -= V_KartStringWidth(string, option)/2;
|
||||
V_DrawKartString(x, y, option, string);
|
||||
}
|
||||
|
||||
// Find string width from cred_font chars
|
||||
//
|
||||
INT32 V_CreditStringWidth(const char *string)
|
||||
void V_DrawRightAlignedKartString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
INT32 c, w = 0;
|
||||
size_t i;
|
||||
x -= V_KartStringWidth(string, option);
|
||||
V_DrawKartString(x, y, option, string);
|
||||
}
|
||||
|
||||
// It's possible for string to be a null pointer
|
||||
if (!string)
|
||||
return 0;
|
||||
void V_DrawCenteredGamemodeString(INT32 x, INT32 y, INT32 option, const UINT8 *colormap, const char *string)
|
||||
{
|
||||
x -= V_GamemodeStringWidth(string, option)/2;
|
||||
V_DrawGamemodeString(x, y, option, colormap, string);
|
||||
}
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
c = toupper(string[i]) - CRED_FONTSTART;
|
||||
if (c < 0 || c >= CRED_FONTSIZE)
|
||||
w += 16;
|
||||
else
|
||||
w += fontv[CRED_FONT].font[c]->width;
|
||||
}
|
||||
void V_DrawRightAlignedGamemodeString(INT32 x, INT32 y, INT32 option, const UINT8 *colormap, const char *string)
|
||||
{
|
||||
x -= V_GamemodeStringWidth(string, option);
|
||||
V_DrawGamemodeString(x, y, option, colormap, string);
|
||||
}
|
||||
|
||||
return w;
|
||||
void V_DrawCenteredFileString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_FileStringWidth(string, option)/2;
|
||||
V_DrawFileString(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawRightAlignedFileString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_FileStringWidth(string, option);
|
||||
V_DrawFileString(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawCenteredLSTitleHighString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_LSTitleHighStringWidth(string, option)/2;
|
||||
V_DrawLSTitleHighString(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawRightAlignedLSTitleHighString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_LSTitleHighStringWidth(string, option);
|
||||
V_DrawLSTitleHighString(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawCenteredLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_LSTitleLowStringWidth(string, option)/2;
|
||||
V_DrawLSTitleLowString(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawRightAlignedLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_LSTitleLowStringWidth(string, option);
|
||||
V_DrawLSTitleLowString(x, y, option, string);
|
||||
}
|
||||
|
||||
// Draws a tallnum. Replaces two functions in y_inter and st_stuff
|
||||
|
|
@ -2335,25 +2666,43 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits)
|
|||
} while (--digits);
|
||||
}
|
||||
|
||||
// Find string width from lt_font chars
|
||||
//
|
||||
INT32 V_LevelNameWidth(const char *string)
|
||||
void V_DrawProfileNum(INT32 x, INT32 y, INT32 flags, UINT8 num)
|
||||
{
|
||||
INT32 c, w = 0;
|
||||
size_t i;
|
||||
UINT8 digits = 3;
|
||||
INT32 w = fontv[PROFNUM_FONT].font[0]->width;
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
if (flags & V_NOSCALESTART)
|
||||
w *= vid.dupx;
|
||||
|
||||
// draw the number
|
||||
do
|
||||
{
|
||||
if (string[i] & 0x80)
|
||||
continue;
|
||||
c = string[i] - LT_FONTSTART;
|
||||
if (c < 0 || c >= LT_FONTSIZE || !fontv[LT_FONT].font[c])
|
||||
w += 12;
|
||||
else
|
||||
w += fontv[LT_FONT].font[c]->width;
|
||||
}
|
||||
x -= (w-1);
|
||||
V_DrawScaledPatch(x, y, flags, fontv[PROFNUM_FONT].font[num % 10]);
|
||||
num /= 10;
|
||||
} while (--digits);
|
||||
}
|
||||
|
||||
return w;
|
||||
// Draws a number using the PING font thingy.
|
||||
// TODO: Merge number drawing functions into one with "font name" selection.
|
||||
|
||||
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap)
|
||||
{
|
||||
INT32 w = SHORT(fontv[PINGNUM_FONT].font[0]->width); // this SHOULD always be 5 but I guess custom graphics exist.
|
||||
|
||||
if (flags & V_NOSCALESTART)
|
||||
w *= vid.dupx;
|
||||
|
||||
if (num < 0)
|
||||
num = -num;
|
||||
|
||||
// draw the number
|
||||
do
|
||||
{
|
||||
x -= (w-1); // Oni wanted their outline to intersect.
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, fontv[PINGNUM_FONT].font[num%10], colormap);
|
||||
num /= 10;
|
||||
} while (num);
|
||||
}
|
||||
|
||||
// Find max height of the string
|
||||
|
|
@ -2376,145 +2725,6 @@ INT32 V_LevelNameHeight(const char *string)
|
|||
return w;
|
||||
}
|
||||
|
||||
//
|
||||
// Find string width from hu_font chars
|
||||
//
|
||||
INT32 V_StringWidth(const char *string, INT32 option)
|
||||
{
|
||||
INT32 c, w = 0;
|
||||
INT32 spacewidth = 4, charwidth = 0;
|
||||
size_t i;
|
||||
|
||||
switch (option & V_SPACINGMASK)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacewidth = 8;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
charwidth = 8;
|
||||
break;
|
||||
case V_6WIDTHSPACE:
|
||||
spacewidth = 6;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
c = string[i];
|
||||
if ((UINT8)c & 0x80) //color parsing! -Inuyasha 2.16.09
|
||||
continue;
|
||||
|
||||
c = toupper(c) - HU_FONTSTART;
|
||||
if (c < 0 || c >= HU_FONTSIZE || !fontv[HU_FONT].font[c])
|
||||
w += spacewidth;
|
||||
else
|
||||
w += (charwidth ? charwidth : fontv[HU_FONT].font[c]->width);
|
||||
}
|
||||
|
||||
if (option & (V_NOSCALESTART|V_NOSCALEPATCH))
|
||||
w *= vid.dupx;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
//
|
||||
// Find string width from hu_font chars, 0.5x scale
|
||||
//
|
||||
INT32 V_SmallStringWidth(const char *string, INT32 option)
|
||||
{
|
||||
INT32 c, w = 0;
|
||||
INT32 spacewidth = 2, charwidth = 0;
|
||||
size_t i;
|
||||
|
||||
switch (option & V_SPACINGMASK)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacewidth = 4;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
charwidth = 4;
|
||||
break;
|
||||
case V_6WIDTHSPACE:
|
||||
spacewidth = 3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
c = string[i];
|
||||
if ((UINT8)c & 0x80) //color parsing! -Inuyasha 2.16.09
|
||||
continue;
|
||||
|
||||
c = toupper(c) - HU_FONTSTART;
|
||||
if (c < 0 || c >= HU_FONTSIZE || !fontv[HU_FONT].font[c])
|
||||
w += spacewidth;
|
||||
else
|
||||
w += (charwidth ? charwidth : fontv[HU_FONT].font[c]->width / 2);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
//
|
||||
// Find string width from tny_font chars
|
||||
//
|
||||
INT32 V_ThinStringWidth(const char *string, INT32 option)
|
||||
{
|
||||
INT32 c, w = 0;
|
||||
INT32 spacewidth = 2, charwidth = 0;
|
||||
boolean lowercase = (option & V_ALLOWLOWERCASE);
|
||||
size_t i;
|
||||
|
||||
switch (option & V_SPACINGMASK)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacewidth = 5;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
charwidth = 5;
|
||||
break;
|
||||
// Out of video flags, so we're reusing this for alternate charwidth instead
|
||||
/*case V_6WIDTHSPACE:
|
||||
spacewidth = 3;*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
c = string[i];
|
||||
if ((UINT8)c & 0x80) //color parsing! -Inuyasha 2.16.09
|
||||
continue;
|
||||
|
||||
if (!lowercase || !fontv[TINY_FONT].font[c-HU_FONTSTART])
|
||||
c = toupper(c);
|
||||
c -= HU_FONTSTART;
|
||||
|
||||
if (c < 0 || c >= HU_FONTSIZE || !fontv[TINY_FONT].font[c])
|
||||
w += spacewidth;
|
||||
else
|
||||
{
|
||||
w += (charwidth ? charwidth
|
||||
: ((option & V_6WIDTHSPACE && i < strlen(string)-1) ? max(1, fontv[TINY_FONT].font[c]->width-1) // Reuse this flag for the alternate bunched-up spacing
|
||||
: fontv[TINY_FONT].font[c]->width));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
//
|
||||
// Find string width from tny_font chars, 0.5x scale
|
||||
//
|
||||
INT32 V_SmallThinStringWidth(const char *string, INT32 option)
|
||||
{
|
||||
INT32 w = V_ThinStringWidth(string, option)<<FRACBITS;
|
||||
return w/2 + FRACUNIT; // +FRACUNIT because otherwise it's offset wrong.
|
||||
}
|
||||
|
||||
boolean *heatshifter = NULL;
|
||||
INT32 lastheight = 0;
|
||||
INT32 heatindex[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
|
||||
|
|
|
|||
122
src/v_video.h
122
src/v_video.h
|
|
@ -207,10 +207,15 @@ void V_EncoreInvertScreen(void);
|
|||
void V_DrawPromptBack(INT32 boxheight, INT32 color);
|
||||
|
||||
/* Convenience macros for leagacy string function macros. */
|
||||
#define V__DrawOneScaleString( x,y,scale,option,font,string ) \
|
||||
V_DrawStringScaled(x,y,scale,FRACUNIT,FRACUNIT,option,font,string)
|
||||
#define V__DrawDupxString( x,y,scale,option,font,string )\
|
||||
V__DrawOneScaleString ((x)<<FRACBITS,(y)<<FRACBITS,scale,option,font,string)
|
||||
#define V__DrawOneScaleString( x,y,scale,option,cm,font,string ) \
|
||||
V_DrawStringScaled(x,y,scale,FRACUNIT,FRACUNIT,option,cm,font,string)
|
||||
#define V__DrawDupxString( x,y,scale,option,cm,font,string )\
|
||||
V__DrawOneScaleString ((x)<<FRACBITS,(y)<<FRACBITS,scale,option,cm,font,string)
|
||||
|
||||
#define V__OneScaleStringWidth( scale,option,font,string ) \
|
||||
V_StringScaledWidth(scale,FRACUNIT,FRACUNIT,option,font,string)
|
||||
#define V__IntegerStringWidth( scale,option,font,string ) \
|
||||
(V_StringScaledWidth(scale,FRACUNIT,FRACUNIT,option,font,string) / FRACUNIT)
|
||||
|
||||
// draw a single character
|
||||
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
||||
|
|
@ -220,7 +225,13 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UI
|
|||
UINT8 *V_GetStringColormap(INT32 colorflags);
|
||||
|
||||
#define V_DrawLevelTitle( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,LT_FONT,string)
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,LT_FONT,string)
|
||||
|
||||
// Find string width from lt_font chars
|
||||
#define V_LevelNameWidth( string ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,0,LT_FONT,string )
|
||||
|
||||
INT32 V_LevelNameHeight(const char *string);
|
||||
|
||||
// wordwrap a string using the hu_font
|
||||
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string);
|
||||
|
|
@ -233,34 +244,57 @@ void V_DrawStringScaled(
|
|||
fixed_t space_scale,
|
||||
fixed_t linefeed_scale,
|
||||
INT32 flags,
|
||||
const UINT8 *colormap,
|
||||
int font,
|
||||
const char *text);
|
||||
|
||||
fixed_t V_StringScaledWidth(
|
||||
fixed_t scale,
|
||||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
int fontno,
|
||||
const char *s);
|
||||
|
||||
// draw a string using the hu_font
|
||||
#define V_DrawString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,HU_FONT,string)
|
||||
#define V_DrawKartString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,KART_FONT,string)
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,HU_FONT,string)
|
||||
|
||||
#define V_StringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,HU_FONT,string )
|
||||
|
||||
void V_DrawCenteredString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
// draw a string using the hu_font, 0.5x scale
|
||||
#define V_DrawSmallString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT>>1,option,HU_FONT,string)
|
||||
V__DrawDupxString (x,y,FRACUNIT>>1,option,NULL,HU_FONT,string)
|
||||
|
||||
#define V_SmallStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT>>1,option,HU_FONT,string )
|
||||
|
||||
void V_DrawCenteredSmallString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
// draw a string using the tny_font
|
||||
#define V_DrawThinString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,TINY_FONT,string)
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,TINY_FONT,string)
|
||||
|
||||
#define V_ThinStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,TINY_FONT,string )
|
||||
|
||||
void V_DrawCenteredThinString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
#define V_DrawStringAtFixed( x,y,option,string ) \
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,HU_FONT,string)
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,NULL,HU_FONT,string)
|
||||
|
||||
#define V_DrawThinStringAtFixed( x,y,option,string ) \
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,TINY_FONT,string)
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,NULL,TINY_FONT,string)
|
||||
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
|
||||
|
||||
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
|
||||
|
|
@ -282,23 +316,59 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits)
|
|||
// This is a separate function because IMO lua should have access to it as well.
|
||||
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap);
|
||||
|
||||
// Find string width from lt_font chars
|
||||
INT32 V_LevelNameWidth(const char *string);
|
||||
INT32 V_LevelNameHeight(const char *string);
|
||||
INT16 V_LevelActNumWidth(UINT8 num); // act number width
|
||||
void V_DrawProfileNum(INT32 x, INT32 y, INT32 flags, UINT8 num);
|
||||
|
||||
#define V_DrawCreditString( x,y,option,string ) \
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,CRED_FONT,string)
|
||||
INT32 V_CreditStringWidth(const char *string);
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,NULL,CRED_FONT,string)
|
||||
|
||||
// Find string width from hu_font chars
|
||||
INT32 V_StringWidth(const char *string, INT32 option);
|
||||
// Find string width from hu_font chars, 0.5x scale
|
||||
INT32 V_SmallStringWidth(const char *string, INT32 option);
|
||||
// Find string width from tny_font chars
|
||||
INT32 V_ThinStringWidth(const char *string, INT32 option);
|
||||
// Find string width from tny_font chars, 0.5x scale
|
||||
INT32 V_SmallThinStringWidth(const char *string, INT32 option);
|
||||
#define V_CreditStringWidth( string ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,0,CRED_FONT,string )
|
||||
|
||||
// SRB2Kart
|
||||
#define V_DrawKartString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,KART_FONT,string)
|
||||
|
||||
#define V_KartStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,KART_FONT,string )
|
||||
|
||||
void V_DrawCenteredKartString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedKartString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
#define V_DrawGamemodeString( x,y,option,cm,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,cm,GM_FONT,string)
|
||||
|
||||
#define V_GamemodeStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,GM_FONT,string )
|
||||
|
||||
void V_DrawCenteredGamemodeString(INT32 x, INT32 y, INT32 option, const UINT8 *colormap, const char *string);
|
||||
void V_DrawRightAlignedGamemodeString(INT32 x, INT32 y, INT32 option, const UINT8 *colormap, const char *string);
|
||||
|
||||
#define V_DrawFileString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,FILE_FONT,string)
|
||||
|
||||
#define V_FileStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,FILE_FONT,string )
|
||||
|
||||
void V_DrawCenteredFileString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedFileString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
#define V_DrawLSTitleHighString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,LSHI_FONT,string)
|
||||
|
||||
#define V_LSTitleHighStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,LSHI_FONT,string )
|
||||
|
||||
void V_DrawCenteredLSTitleHighString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedLSTitleHighString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
#define V_DrawLSTitleLowString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,LSLOW_FONT,string)
|
||||
|
||||
#define V_LSTitleLowStringWidth( string,option ) \
|
||||
V__IntegerStringWidth ( FRACUNIT,option,LSLOW_FONT,string )
|
||||
|
||||
void V_DrawCenteredLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param);
|
||||
|
||||
|
|
|
|||
228
src/y_inter.c
228
src/y_inter.c
|
|
@ -26,7 +26,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "y_inter.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "i_system.h"
|
||||
#include "p_setup.h"
|
||||
|
|
@ -41,11 +41,10 @@
|
|||
#include "lua_hudlib_drawlist.h"
|
||||
|
||||
#include "m_random.h" // M_RandomKey
|
||||
#include "g_input.h" // PlayerInputDown
|
||||
#include "g_input.h" // G_PlayerInputDown
|
||||
#include "k_battle.h"
|
||||
#include "k_boss.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "console.h" // cons_menuhighlight
|
||||
#include "k_grandprix.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
|
@ -88,24 +87,10 @@ static patch_t *bgpatch = NULL; // INTERSCR
|
|||
static patch_t *widebgpatch = NULL;
|
||||
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
|
||||
static patch_t *interpic = NULL; // custom picture defined in map header
|
||||
static boolean usetile;
|
||||
static INT32 timer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 source_width, source_height;
|
||||
INT32 source_bpp, source_rowbytes;
|
||||
UINT8 *source_picture;
|
||||
INT32 target_width, target_height;
|
||||
INT32 target_bpp, target_rowbytes;
|
||||
UINT8 *target_picture;
|
||||
} y_buffer_t;
|
||||
|
||||
boolean usebuffer = false;
|
||||
static boolean useinterpic;
|
||||
|
||||
static INT32 timer;
|
||||
static INT32 powertype = PWRLV_DISABLED;
|
||||
static y_buffer_t *y_buffer;
|
||||
|
||||
static INT32 intertic;
|
||||
static INT32 endtic = -1;
|
||||
|
|
@ -117,8 +102,6 @@ intertype_t intermissiontypes[NUMGAMETYPES];
|
|||
static huddrawlist_h luahuddrawlist_intermission;
|
||||
|
||||
static void Y_FollowIntermission(void);
|
||||
|
||||
static void Y_RescaleScreenBuffer(void);
|
||||
static void Y_UnloadData(void);
|
||||
|
||||
// SRB2Kart: voting stuff
|
||||
|
|
@ -344,91 +327,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Y_ConsiderScreenBuffer
|
||||
//
|
||||
// Can we copy the current screen to a buffer?
|
||||
//
|
||||
void Y_ConsiderScreenBuffer(void)
|
||||
{
|
||||
if (gameaction != ga_completed)
|
||||
return;
|
||||
|
||||
if (y_buffer == NULL)
|
||||
y_buffer = Z_Calloc(sizeof(y_buffer_t), PU_STATIC, NULL);
|
||||
else
|
||||
return;
|
||||
|
||||
y_buffer->source_width = vid.width;
|
||||
y_buffer->source_height = vid.height;
|
||||
y_buffer->source_bpp = vid.bpp;
|
||||
y_buffer->source_rowbytes = vid.rowbytes;
|
||||
y_buffer->source_picture = ZZ_Alloc(y_buffer->source_width*vid.bpp * y_buffer->source_height);
|
||||
VID_BlitLinearScreen(screens[1], y_buffer->source_picture, vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
|
||||
// Make the rescaled screen buffer
|
||||
Y_RescaleScreenBuffer();
|
||||
}
|
||||
|
||||
//
|
||||
// Y_RescaleScreenBuffer
|
||||
//
|
||||
// Write the rescaled source picture, to the destination picture that has the current screen's resolutions.
|
||||
//
|
||||
static void Y_RescaleScreenBuffer(void)
|
||||
{
|
||||
INT32 sx, sy; // source
|
||||
INT32 dx, dy; // dest
|
||||
fixed_t scalefac, yscalefac;
|
||||
fixed_t rowfrac, colfrac;
|
||||
UINT8 *dest;
|
||||
|
||||
// Who knows?
|
||||
if (y_buffer == NULL)
|
||||
return;
|
||||
|
||||
if (y_buffer->target_picture)
|
||||
Z_Free(y_buffer->target_picture);
|
||||
|
||||
y_buffer->target_width = vid.width;
|
||||
y_buffer->target_height = vid.height;
|
||||
y_buffer->target_rowbytes = vid.rowbytes;
|
||||
y_buffer->target_bpp = vid.bpp;
|
||||
y_buffer->target_picture = ZZ_Alloc(y_buffer->target_width*vid.bpp * y_buffer->target_height);
|
||||
dest = y_buffer->target_picture;
|
||||
|
||||
scalefac = FixedDiv(y_buffer->target_width*FRACUNIT, y_buffer->source_width*FRACUNIT);
|
||||
yscalefac = FixedDiv(y_buffer->target_height*FRACUNIT, y_buffer->source_height*FRACUNIT);
|
||||
|
||||
rowfrac = FixedDiv(FRACUNIT, yscalefac);
|
||||
colfrac = FixedDiv(FRACUNIT, scalefac);
|
||||
|
||||
for (sy = 0, dy = 0; sy < (y_buffer->source_height << FRACBITS) && dy < y_buffer->target_height; sy += rowfrac, dy++)
|
||||
for (sx = 0, dx = 0; sx < (y_buffer->source_width << FRACBITS) && dx < y_buffer->target_width; sx += colfrac, dx += y_buffer->target_bpp)
|
||||
dest[(dy * y_buffer->target_rowbytes) + dx] = y_buffer->source_picture[((sy>>FRACBITS) * y_buffer->source_width) + (sx>>FRACBITS)];
|
||||
}
|
||||
|
||||
//
|
||||
// Y_CleanupScreenBuffer
|
||||
//
|
||||
// Free all related memory.
|
||||
//
|
||||
void Y_CleanupScreenBuffer(void)
|
||||
{
|
||||
// Who knows?
|
||||
if (y_buffer == NULL)
|
||||
return;
|
||||
|
||||
if (y_buffer->target_picture)
|
||||
Z_Free(y_buffer->target_picture);
|
||||
|
||||
if (y_buffer->source_picture)
|
||||
Z_Free(y_buffer->source_picture);
|
||||
|
||||
Z_Free(y_buffer);
|
||||
y_buffer = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Y_IntermissionDrawer
|
||||
//
|
||||
|
|
@ -442,38 +340,10 @@ void Y_IntermissionDrawer(void)
|
|||
if (intertype == int_none || rendermode == render_none)
|
||||
return;
|
||||
|
||||
if (useinterpic)
|
||||
V_DrawScaledPatch(0, 0, 0, interpic);
|
||||
else if (!usetile)
|
||||
// the merge was kind of a mess, how does this work -- toast 171021
|
||||
{
|
||||
if (rendermode == render_soft && usebuffer)
|
||||
{
|
||||
// no y_buffer
|
||||
if (y_buffer == NULL)
|
||||
VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
else
|
||||
{
|
||||
// Maybe the resolution changed?
|
||||
if ((y_buffer->target_width != vid.width) || (y_buffer->target_height != vid.height))
|
||||
Y_RescaleScreenBuffer();
|
||||
|
||||
// Blit the already-scaled screen buffer to the current screen
|
||||
VID_BlitLinearScreen(y_buffer->target_picture, screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
}
|
||||
}
|
||||
#ifdef HWRENDER
|
||||
else if (rendermode != render_soft && usebuffer)
|
||||
HWR_DrawIntermissionBG();
|
||||
#endif
|
||||
else if (bgpatch)
|
||||
{
|
||||
fixed_t hs = vid.width * FRACUNIT / BASEVIDWIDTH;
|
||||
fixed_t vs = vid.height * FRACUNIT / BASEVIDHEIGHT;
|
||||
V_DrawStretchyFixedPatch(0, 0, hs, vs, V_NOSCALEPATCH, bgpatch, NULL);
|
||||
}
|
||||
M_DrawMenuBackground();
|
||||
}
|
||||
else if (bgtile)
|
||||
V_DrawPatchFill(bgtile);
|
||||
|
||||
if (renderisnewtic)
|
||||
{
|
||||
|
|
@ -485,15 +355,10 @@ void Y_IntermissionDrawer(void)
|
|||
if (!LUA_HudEnabled(hud_intermissiontally))
|
||||
goto skiptallydrawer;
|
||||
|
||||
if (usebuffer) // Fade everything out
|
||||
V_DrawFadeScreen(0xFF00, 22);
|
||||
|
||||
if (!r_splitscreen)
|
||||
whiteplayer = demo.playback ? displayplayers[0] : consoleplayer;
|
||||
|
||||
if (cons_menuhighlight.value)
|
||||
hilicol = cons_menuhighlight.value;
|
||||
else if (modeattacking)
|
||||
if (modeattacking)
|
||||
hilicol = V_ORANGEMAP;
|
||||
else
|
||||
hilicol = ((intertype == int_race) ? V_SKYMAP : V_REDMAP);
|
||||
|
|
@ -639,7 +504,7 @@ void Y_IntermissionDrawer(void)
|
|||
{
|
||||
if (powertype != PWRLV_DISABLED && !clientpowerlevels[data.num[i]][powertype])
|
||||
{
|
||||
// No power level (splitscreen guests)
|
||||
// No power level (guests)
|
||||
STRBUFCPY(strtime, "----");
|
||||
}
|
||||
else
|
||||
|
|
@ -710,7 +575,7 @@ skiptallydrawer:
|
|||
if (!LUA_HudEnabled(hud_intermissionmessages))
|
||||
return;
|
||||
|
||||
if (timer && grandprixinfo.gp == false && bossinfo.boss == false)
|
||||
if (timer && grandprixinfo.gp == false && bossinfo.boss == false && !modeattacking)
|
||||
{
|
||||
char *string;
|
||||
INT32 tickdown = (timer+1)/TICRATE;
|
||||
|
|
@ -720,38 +585,40 @@ skiptallydrawer:
|
|||
else
|
||||
string = va("%s starts in %d", cv_advancemap.string, tickdown);
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol,
|
||||
string);
|
||||
}
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, string);
|
||||
|
||||
if ((demo.recording || demo.savemode == DSM_SAVED) && !demo.playback)
|
||||
switch (demo.savemode)
|
||||
if ((demo.recording || demo.savemode == DSM_SAVED) && !demo.playback)
|
||||
{
|
||||
case DSM_NOTSAVING:
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Look Backward: Save replay");
|
||||
break;
|
||||
switch (demo.savemode)
|
||||
{
|
||||
case DSM_NOTSAVING:
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "(B): Save replay");
|
||||
break;
|
||||
|
||||
case DSM_SAVED:
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Replay saved!");
|
||||
break;
|
||||
case DSM_SAVED:
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Replay saved!");
|
||||
break;
|
||||
|
||||
case DSM_TITLEENTRY:
|
||||
ST_DrawDemoTitleEntry();
|
||||
break;
|
||||
case DSM_TITLEENTRY:
|
||||
ST_DrawDemoTitleEntry();
|
||||
break;
|
||||
|
||||
default: // Don't render any text here
|
||||
break;
|
||||
default: // Don't render any text here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if ((intertic/TICRATE) & 1) // Make it obvious that scrambling is happening next round. (OR NOT, I GUESS)
|
||||
//{
|
||||
/*if (cv_scrambleonchange.value && cv_teamscramble.value)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/
|
||||
//if ((intertic/TICRATE) & 1) // Make it obvious that scrambling is happening next round. (OR NOT, I GUESS)
|
||||
//{
|
||||
if (speedscramble != -1 && speedscramble != gamespeed)
|
||||
{
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM,
|
||||
va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[1+speedscramble].strvalue));
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
if (speedscramble != -1 && speedscramble != gamespeed)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM,
|
||||
va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[1+speedscramble].strvalue));
|
||||
//}
|
||||
M_DrawMenuForeground();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -766,7 +633,7 @@ void Y_Ticker(void)
|
|||
|
||||
if (demo.recording)
|
||||
{
|
||||
if (demo.savemode == DSM_NOTSAVING && PlayerInputDown(1, gc_lookback))
|
||||
if (demo.savemode == DSM_NOTSAVING && G_PlayerInputDown(0, gc_y, 0))
|
||||
demo.savemode = DSM_TITLEENTRY;
|
||||
|
||||
if (demo.savemode == DSM_WILLSAVE || demo.savemode == DSM_WILLAUTOSAVE)
|
||||
|
|
@ -1017,12 +884,10 @@ void Y_StartIntermission(void)
|
|||
K_CashInPowerLevels();
|
||||
}
|
||||
|
||||
//if (intertype == int_race || intertype == int_battle)
|
||||
{
|
||||
//bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
|
||||
usetile = useinterpic = false;
|
||||
usebuffer = true;
|
||||
}
|
||||
bgpatch = W_CachePatchName("MENUBG", PU_STATIC);
|
||||
widebgpatch = W_CachePatchName("WEIRDRES", PU_STATIC);
|
||||
|
||||
M_UpdateMenuBGImage(true);
|
||||
}
|
||||
|
||||
// ======
|
||||
|
|
@ -1038,7 +903,6 @@ void Y_EndIntermission(void)
|
|||
endtic = -1;
|
||||
sorttic = -1;
|
||||
intertype = int_none;
|
||||
usebuffer = false;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1318,9 +1182,7 @@ void Y_VoteDrawer(void)
|
|||
if (timer)
|
||||
{
|
||||
INT32 hilicol, tickdown = (timer+1)/TICRATE;
|
||||
if (cons_menuhighlight.value)
|
||||
hilicol = cons_menuhighlight.value;
|
||||
else if (gametype == GT_RACE)
|
||||
if (gametype == GT_RACE)
|
||||
hilicol = V_SKYMAP;
|
||||
else //if (gametype == GT_BATTLE)
|
||||
hilicol = V_REDMAP;
|
||||
|
|
@ -1503,15 +1365,15 @@ void Y_VoteTicker(void)
|
|||
|
||||
if ((playeringame[p] && !players[p].spectator)
|
||||
&& !voteclient.playerinfo[i].delay
|
||||
&& pickedvote == -1 && votes[p] == -1)
|
||||
&& pickedvote == -1 && votes[p] == -1 && menuactive == false)
|
||||
{
|
||||
if (PlayerInputDown(i+1, gc_aimforward) || PlayerJoyAxis(i+1, AXISAIM) < 0)
|
||||
if (G_PlayerInputDown(i, gc_up, 0))
|
||||
{
|
||||
voteclient.playerinfo[i].selection--;
|
||||
pressed = true;
|
||||
}
|
||||
|
||||
if ((PlayerInputDown(i+1, gc_aimbackward) || PlayerJoyAxis(i+1, AXISAIM) > 0) && !pressed)
|
||||
if (G_PlayerInputDown(i, gc_down, 0) && pressed == false)
|
||||
{
|
||||
voteclient.playerinfo[i].selection++;
|
||||
pressed = true;
|
||||
|
|
@ -1522,7 +1384,7 @@ void Y_VoteTicker(void)
|
|||
if (voteclient.playerinfo[i].selection > 3)
|
||||
voteclient.playerinfo[i].selection = 0;
|
||||
|
||||
if ((PlayerInputDown(i+1, gc_accelerate) || PlayerJoyAxis(i+1, AXISMOVE) > 0) && !pressed)
|
||||
if (G_PlayerInputDown(i, gc_a, 0) && pressed == false)
|
||||
{
|
||||
D_ModifyClientVote(consoleplayer, voteclient.playerinfo[i].selection, i);
|
||||
pressed = true;
|
||||
|
|
@ -1667,7 +1529,7 @@ void Y_StartVote(void)
|
|||
// set up the gtc and gts
|
||||
levelinfo[i].gtc = G_GetGametypeColor(votelevels[i][1]);
|
||||
if (i == 2 && votelevels[i][1] != votelevels[0][1])
|
||||
levelinfo[i].gts = gametype_cons_t[votelevels[i][1]].strvalue;
|
||||
levelinfo[i].gts = Gametype_Names[votelevels[i][1]];
|
||||
else
|
||||
levelinfo[i].gts = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,17 +9,12 @@
|
|||
/// \file y_inter.h
|
||||
/// \brief Tally screens, or "Intermissions" as they were formally called in Doom
|
||||
|
||||
extern boolean usebuffer;
|
||||
|
||||
void Y_IntermissionDrawer(void);
|
||||
void Y_Ticker(void);
|
||||
|
||||
void Y_StartIntermission(void);
|
||||
void Y_EndIntermission(void);
|
||||
|
||||
void Y_ConsiderScreenBuffer(void);
|
||||
void Y_CleanupScreenBuffer(void);
|
||||
|
||||
void Y_DetermineIntermissionType(void);
|
||||
|
||||
void Y_VoteDrawer(void);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue