RingRacers/src/menus/options-1.c
2024-04-05 10:18:34 -04:00

310 lines
7.7 KiB
C

// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by "Lat'".
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 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 menus/options-1.c
/// \brief Options Menu
#include "../i_time.h"
#include "../k_menu.h"
#include "../k_grandprix.h" // K_CanChangeRules
#include "../m_cond.h" // Condition Sets
#include "../k_follower.h"
#include "../s_sound.h"
// options menu -- see mopt_e
menuitem_t OPTIONS_Main[] =
{
{IT_STRING | IT_CALL, "Profile Setup", "Remap keys & buttons.",
NULL, {.routine = M_ProfileSelectInit}, 0, 0},
{IT_STRING | IT_CALL, "Video Options", "Change the resolution.",
NULL, {.routine = M_VideoOptions}, 0, 0},
{IT_STRING | IT_CALL, "Sound Options", "Adjust the volume.",
NULL, {.routine = M_SoundOptions}, 0, 0},
{IT_STRING | IT_SUBMENU, "HUD Options", "Tweak the Heads-Up Display.",
NULL, {.submenu = &OPTIONS_HUDDef}, 0, 0},
{IT_STRING | IT_CALL, "Gameplay Options", "Modify game mechanics.",
NULL, {.routine = M_GameplayOptions}, 0, 0},
{IT_STRING | IT_CALL, "Server Options", "Update server settings.",
NULL, {.routine = M_ServerOptions}, 0, 0},
{IT_STRING | IT_SUBMENU, "Data Options", "Video recording, file saving, Discord status.",
NULL, {.submenu = &OPTIONS_DataDef}, 0, 0},
#ifdef TODONEWMANUAL
{IT_STRING | IT_CALL, "Tricks & Secrets", "Those who bother reading a game manual always get the edge over those who don't!",
NULL, {.routine = M_Manual}, 0, 0},
#endif
};
// For options menu, the 'extra1' field will determine the background colour to use for... the background! (What a concept!)
menu_t OPTIONS_MainDef = {
sizeof (OPTIONS_Main) / sizeof (menuitem_t),
&MainDef,
0,
OPTIONS_Main,
0, 0,
SKINCOLOR_SLATE, 0,
MBF_DRAWBGWHILEPLAYING,
NULL,
2, 5,
M_DrawOptions,
M_DrawOptionsCogs,
M_OptionsTick,
NULL,
NULL,
M_OptionsInputs
};
struct optionsmenu_s optionsmenu;
void M_ResetOptions(void)
{
optionsmenu.ticker = 0;
optionsmenu.offset.start = 0;
optionsmenu.optx = 0;
optionsmenu.opty = 0;
optionsmenu.toptx = 0;
optionsmenu.topty = 0;
// BG setup:
optionsmenu.currcolour = OPTIONS_MainDef.extra1;
optionsmenu.lastcolour = 0;
optionsmenu.fade = 0;
// For profiles:
memset(setup_player, 0, sizeof(setup_player));
optionsmenu.profile = NULL;
}
void M_InitOptions(INT32 choice)
{
(void)choice;
OPTIONS_MainDef.menuitems[mopt_gameplay].status = IT_STRING | IT_TRANSTEXT;
OPTIONS_MainDef.menuitems[mopt_server].status = IT_STRING | IT_TRANSTEXT;
// enable gameplay & server options under the right circumstances.
if (gamestate == GS_MENU
|| ((server || IsPlayerAdmin(consoleplayer)) && K_CanChangeRules(false)))
{
OPTIONS_MainDef.menuitems[mopt_gameplay].status = IT_STRING | IT_CALL;
OPTIONS_MainDef.menuitems[mopt_server].status = IT_STRING | IT_CALL;
OPTIONS_GameplayDef.menuitems[gopt_encore].status =
(M_SecretUnlocked(SECRET_ENCORE, false) ? (IT_STRING | IT_CVAR) : IT_DISABLED);
}
// Data Options
OPTIONS_DataAdvancedDef.menuitems[daopt_addon].status = (M_SecretUnlocked(SECRET_ADDONS, true)
? (IT_STRING | IT_SUBMENU)
: (IT_NOTHING | IT_SPACE));
OPTIONS_DataDef.menuitems[dopt_erase].status = (gamestate == GS_MENU
? (IT_STRING | IT_SUBMENU)
: (IT_TRANSTEXT2 | IT_SPACE));
M_ResetOptions();
// So that pause doesn't go to the main menu...
OPTIONS_MainDef.prevMenu = currentMenu;
M_SetupNextMenu(&OPTIONS_MainDef, false);
}
// Prepares changing the colour of the background
void M_OptionsChangeBGColour(INT16 newcolour)
{
optionsmenu.fade = 10;
optionsmenu.lastcolour = optionsmenu.currcolour;
optionsmenu.currcolour = newcolour;
}
boolean M_OptionsQuit(void)
{
optionsmenu.toptx = 140;
optionsmenu.topty = 70;
// Reset button behaviour because profile menu is different, since of course it is.
if (optionsmenu.resetprofilemenu)
{
optionsmenu.profilemenu = false;
optionsmenu.profile = NULL;
optionsmenu.resetprofilemenu = false;
}
return true; // Always allow quitting, duh.
}
void M_OptionsTick(void)
{
boolean instanttransmission = optionsmenu.ticker == 0 && menuwipe;
optionsmenu.ticker++;
// Move the button for cool animations
if (currentMenu == &OPTIONS_MainDef)
{
M_OptionsQuit(); // ...So now this is used here.
}
else if (optionsmenu.profile == NULL) // Not currently editing a profile (otherwise we're using these variables for other purposes....)
{
// I don't like this, it looks like shit but it needs to be done..........
if (optionsmenu.profilemenu)
{
optionsmenu.toptx = 440;
optionsmenu.topty = 70+1;
}
else if (currentMenu == &OPTIONS_GameplayItemsDef)
{
optionsmenu.toptx = -160; // off the side of the screen
optionsmenu.topty = 50;
}
else
{
optionsmenu.toptx = 160;
optionsmenu.topty = 50;
}
}
// Handle the background stuff:
if (optionsmenu.fade)
optionsmenu.fade--;
// change the colour if we aren't matching the current menu colour
if (instanttransmission)
{
optionsmenu.currcolour = currentMenu->extra1;
optionsmenu.offset.start = optionsmenu.fade = 0;
optionsmenu.optx = optionsmenu.toptx;
optionsmenu.opty = optionsmenu.topty;
}
else
{
if (optionsmenu.fade)
optionsmenu.fade--;
if (optionsmenu.currcolour != currentMenu->extra1)
M_OptionsChangeBGColour(currentMenu->extra1);
if (optionsmenu.optx != optionsmenu.toptx || optionsmenu.opty != optionsmenu.topty)
{
tic_t t = I_GetTime();
tic_t n = t - optionsmenu.topt_start;
if (n == M_OPTIONS_OFSTIME)
{
optionsmenu.optx = optionsmenu.toptx;
optionsmenu.opty = optionsmenu.topty;
}
else if (n > M_OPTIONS_OFSTIME)
{
optionsmenu.topt_start = I_GetTime();
}
}
M_GonerCheckLooking();
}
// And one last giggle...
if (shitsfree)
shitsfree--;
}
static void M_OptionsMenuGoto(menu_t *assignment)
{
assignment->prevMenu = currentMenu;
assignment->music = currentMenu->music;
M_SetupNextMenu(assignment, false);
if (currentMenu != &OPTIONS_MainDef)
{
optionsmenu.ticker = 0;
M_OptionsTick();
}
}
void M_VideoOptions(INT32 choice)
{
(void)choice;
M_OptionsMenuGoto(&OPTIONS_VideoDef);
M_GonerResetLooking(GDGONER_VIDEO);
}
void M_SoundOptions(INT32 choice)
{
(void)choice;
M_OptionsMenuGoto(&OPTIONS_SoundDef);
M_GonerResetLooking(GDGONER_SOUND);
}
void M_GameplayOptions(INT32 choice)
{
(void)choice;
OPTIONS_GameplayItemsDef.music = currentMenu->music;
M_OptionsMenuGoto(&OPTIONS_GameplayDef);
OPTIONS_MainDef.lastOn = mopt_gameplay;
}
void M_ServerOptions(INT32 choice)
{
(void)choice;
OPTIONS_ServerAdvancedDef.music = currentMenu->music;
M_OptionsMenuGoto(&OPTIONS_ServerDef);
OPTIONS_MainDef.lastOn = mopt_server;
}
boolean M_OptionsInputs(INT32 ch)
{
const UINT8 pid = 0;
(void)ch;
if (menucmd[pid].dpad_ud > 0)
{
M_SetMenuDelay(pid);
optionsmenu.offset.dist = 48;
M_NextOpt();
S_StartSound(NULL, sfx_s3k5b);
if (itemOn == 0)
optionsmenu.offset.dist -= currentMenu->numitems*48;
optionsmenu.offset.start = I_GetTime();
return true;
}
else if (menucmd[pid].dpad_ud < 0)
{
M_SetMenuDelay(pid);
optionsmenu.offset.dist = -48;
M_PrevOpt();
S_StartSound(NULL, sfx_s3k5b);
if (itemOn == currentMenu->numitems-1)
optionsmenu.offset.dist += currentMenu->numitems*48;
optionsmenu.offset.start = I_GetTime();
return true;
}
else if (M_MenuConfirmPressed(pid))
{
if (currentMenu->menuitems[itemOn].status & IT_TRANSTEXT)
return true; // No.
optionsmenu.optx = 140;
optionsmenu.opty = 70; // Default position for the currently selected option.
return false; // Don't eat.
}
return false;
}