mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-11 02:23:09 +00:00
364 lines
9 KiB
C
364 lines
9 KiB
C
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2025 by Vivian "toastergrl" Grannell.
|
|
// Copyright (C) 2025 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/extras-addons.c
|
|
/// \brief Addons menu!
|
|
|
|
#include "../k_menu.h"
|
|
#include "../filesrch.h" // Addfile
|
|
#include "../d_main.h"
|
|
#include "../z_zone.h"
|
|
#include "../s_sound.h"
|
|
#include "../v_video.h"
|
|
|
|
menuitem_t MISC_AddonsMenu[] =
|
|
{
|
|
{IT_STRING | IT_CVAR | IT_CV_STRING, "Search for add-ons", "Provide a full or partial name to filter available files by.",
|
|
NULL, {.cvar = &cv_dummyaddonsearch}, 0, 0},
|
|
{IT_KEYHANDLER | IT_NOTHING, NULL, NULL,
|
|
NULL, {.routine = M_HandleAddons}, 0, 0}, // dummy menuitem for the control func
|
|
};
|
|
|
|
menu_t MISC_AddonsDef = {
|
|
sizeof (MISC_AddonsMenu)/sizeof (menuitem_t),
|
|
NULL,
|
|
0,
|
|
MISC_AddonsMenu,
|
|
50, 28,
|
|
0, 0,
|
|
MBF_NOLOOPENTRIES,
|
|
"EXTRAS",
|
|
0, 0,
|
|
M_DrawAddons,
|
|
M_DrawExtrasBack,
|
|
M_AddonsRefresh,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
// Addons menu: (Merely copypasted, original code by toaster)
|
|
|
|
void M_Addons(INT32 choice)
|
|
{
|
|
const char *pathname = ".";
|
|
|
|
(void)choice;
|
|
|
|
pathname = addonsdir;
|
|
|
|
strlcpy(menupath, pathname, 1024);
|
|
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
|
|
|
|
if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0])
|
|
{
|
|
menupath[menupathindex[menudepthleft]-1] = PATHSEP[0];
|
|
menupath[menupathindex[menudepthleft]] = 0;
|
|
}
|
|
else
|
|
--menupathindex[menudepthleft];
|
|
|
|
if (!preparefilemenu(false, false))
|
|
{
|
|
M_StartMessage("Add-ons Menu", va("No files/folders found.\n\n%s\n", LOCATIONSTRING1),NULL,MM_NOTHING, NULL, NULL);
|
|
return;
|
|
}
|
|
else
|
|
dir_on[menudepthleft] = 0;
|
|
|
|
MISC_AddonsDef.lastOn = 0; // Always start on search
|
|
|
|
MISC_AddonsDef.prevMenu = currentMenu;
|
|
M_SetupNextMenu(&MISC_AddonsDef, false);
|
|
}
|
|
|
|
|
|
char *M_AddonsHeaderPath(void)
|
|
{
|
|
UINT32 len;
|
|
static char header[1024];
|
|
|
|
strlcpy(header, va("addons%s", menupath+menupathindex[menudepth-1]-1), 1024);
|
|
len = strlen(header);
|
|
if (len > 34)
|
|
{
|
|
len = len-34;
|
|
header[len] = header[len+1] = header[len+2] = '.';
|
|
}
|
|
else
|
|
len = 0;
|
|
|
|
return header+len;
|
|
}
|
|
|
|
#define UNEXIST S_StartSound(NULL, sfx_s26d);\
|
|
M_SetupNextMenu(MISC_AddonsDef.prevMenu, false);\
|
|
M_StartMessage("Add-ons Menu", va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n", M_AddonsHeaderPath()),NULL,MM_NOTHING, NULL, NULL)
|
|
|
|
#define CLEARNAME Z_Free(refreshdirname);\
|
|
refreshdirname = NULL
|
|
|
|
static boolean prevmajormods = false;
|
|
|
|
static void M_AddonsClearName(INT32 choice)
|
|
{
|
|
(void)choice;
|
|
|
|
if (!majormods || prevmajormods)
|
|
{
|
|
CLEARNAME;
|
|
}
|
|
}
|
|
|
|
// Handles messages for addon errors.
|
|
void M_AddonsRefresh(void)
|
|
{
|
|
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true, false))
|
|
{
|
|
UNEXIST;
|
|
if (refreshdirname)
|
|
{
|
|
CLEARNAME;
|
|
}
|
|
return;// true;
|
|
}
|
|
|
|
#ifdef DEVELOP
|
|
prevmajormods = majormods;
|
|
#else
|
|
if (!majormods && prevmajormods)
|
|
prevmajormods = false;
|
|
#endif
|
|
|
|
if ((refreshdirmenu & REFRESHDIR_ADDFILE) || (majormods && !prevmajormods))
|
|
{
|
|
char *message = NULL;
|
|
|
|
if (refreshdirmenu & REFRESHDIR_NOTLOADED)
|
|
{
|
|
S_StartSound(NULL, sfx_s26d);
|
|
if (refreshdirmenu & REFRESHDIR_MAX)
|
|
message = va("%c%s\x80\nMaximum number of addons reached.\nA file could not be loaded.\nIf you wish to play with this addon, restart the game to clear existing ones.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
|
else
|
|
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more info.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
|
}
|
|
else if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
|
|
{
|
|
S_StartSound(NULL, sfx_s224);
|
|
message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more info.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
|
|
}
|
|
else if (majormods && !prevmajormods)
|
|
{
|
|
S_StartSound(NULL, sfx_s221);
|
|
message = va("%c%s\x80\nYou've loaded a gameplay-modifying addon.\nCheck the console log for more info.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
|
prevmajormods = majormods;
|
|
}
|
|
|
|
if (message)
|
|
{
|
|
M_StartMessage("Add-ons Menu", message, &M_AddonsClearName,MM_NOTHING, NULL, NULL);
|
|
return;// true;
|
|
}
|
|
|
|
S_StartSound(NULL, sfx_s221);
|
|
CLEARNAME;
|
|
}
|
|
|
|
return;// false;
|
|
}
|
|
|
|
static void M_AddonExec(INT32 ch)
|
|
{
|
|
if (ch == MA_YES)
|
|
{
|
|
S_StartSound(NULL, sfx_zoom);
|
|
COM_BufAddText(va("exec \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
|
}
|
|
}
|
|
|
|
void M_UpdateAddonsSearch(void);
|
|
void M_UpdateAddonsSearch(void)
|
|
{
|
|
menusearch[0] = strlen(cv_dummyaddonsearch.string);
|
|
strlcpy(menusearch+1, cv_dummyaddonsearch.string, MAXSTRINGLENGTH);
|
|
if (!cv_addons_search_case.value)
|
|
strupr(menusearch+1);
|
|
|
|
#if 0 // much slower
|
|
if (!preparefilemenu(true, false))
|
|
{
|
|
UNEXIST;
|
|
return;
|
|
}
|
|
#else // streamlined
|
|
searchfilemenu(NULL);
|
|
#endif
|
|
}
|
|
|
|
void M_HandleAddons(INT32 choice)
|
|
{
|
|
const UINT8 pid = 0;
|
|
boolean exitmenu = false; // exit to previous menu
|
|
|
|
(void) choice;
|
|
|
|
if (menucmd[pid].dpad_ud > 0)
|
|
{
|
|
if (dir_on[menudepthleft] < sizedirmenu-1)
|
|
{
|
|
dir_on[menudepthleft]++;
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
}
|
|
else if (M_NextOpt())
|
|
{
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
}
|
|
M_SetMenuDelay(pid);
|
|
}
|
|
else if (menucmd[pid].dpad_ud < 0)
|
|
{
|
|
if (dir_on[menudepthleft])
|
|
{
|
|
dir_on[menudepthleft]--;
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
}
|
|
else if (M_PrevOpt())
|
|
{
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
}
|
|
M_SetMenuDelay(pid);
|
|
}
|
|
|
|
else if (M_MenuButtonPressed(pid, MBT_L))
|
|
{
|
|
UINT8 i;
|
|
for (i = numaddonsshown; i && (dir_on[menudepthleft] < sizedirmenu-1); i--)
|
|
dir_on[menudepthleft]++;
|
|
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
M_SetMenuDelay(pid);
|
|
}
|
|
|
|
else if (M_MenuButtonPressed(pid, MBT_R))
|
|
{
|
|
UINT8 i;
|
|
for (i = numaddonsshown; i && (dir_on[menudepthleft]); i--)
|
|
dir_on[menudepthleft]--;
|
|
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
M_SetMenuDelay(pid);
|
|
}
|
|
|
|
else if (M_MenuConfirmPressed(pid))
|
|
{
|
|
boolean refresh = true;
|
|
M_SetMenuDelay(pid);
|
|
|
|
if (!dirmenu[dir_on[menudepthleft]])
|
|
S_StartSound(NULL, sfx_s26d);
|
|
else
|
|
{
|
|
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
|
{
|
|
case EXT_FOLDER:
|
|
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
|
if (menudepthleft)
|
|
{
|
|
menupathindex[--menudepthleft] = strlen(menupath);
|
|
menupath[menupathindex[menudepthleft]] = 0;
|
|
|
|
if (!preparefilemenu(false, false))
|
|
{
|
|
S_StartSound(NULL, sfx_s224);
|
|
M_StartMessage("Add-ons Menu", va("%c%s\x80\nThis folder is empty.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING, NULL, NULL);
|
|
menupath[menupathindex[++menudepthleft]] = 0;
|
|
|
|
if (!preparefilemenu(true, false))
|
|
{
|
|
UNEXIST;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
dir_on[menudepthleft] = 1;
|
|
}
|
|
refresh = false;
|
|
}
|
|
else
|
|
{
|
|
S_StartSound(NULL, sfx_s26d);
|
|
M_StartMessage("Add-ons Menu", va("%c%s\x80\nThis folder is too deep to navigate to!\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING, NULL, NULL);
|
|
menupath[menupathindex[menudepthleft]] = 0;
|
|
}
|
|
break;
|
|
|
|
case EXT_UP:
|
|
S_StartSound(NULL, sfx_s3k5b);
|
|
menupath[menupathindex[++menudepthleft]] = 0;
|
|
if (!preparefilemenu(false, false))
|
|
{
|
|
UNEXIST;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case EXT_TXT:
|
|
M_StartMessage("Add-ons Menu", va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways?\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),&M_AddonExec,MM_YESNO, NULL, NULL);
|
|
break;
|
|
|
|
case EXT_CFG:
|
|
M_StartMessage("Add-ons Menu", va("%c%s\x80\nThis file may modify your settings.\nAttempt to run anyways?\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),&M_AddonExec,MM_YESNO, NULL, NULL);
|
|
break;
|
|
|
|
case EXT_LUA:
|
|
case EXT_SOC:
|
|
case EXT_WAD:
|
|
#ifdef USE_KART
|
|
case EXT_KART:
|
|
#endif
|
|
case EXT_PK3:
|
|
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
|
break;
|
|
|
|
default:
|
|
S_StartSound(NULL, sfx_s26d);
|
|
}
|
|
|
|
if (refresh)
|
|
refreshdirmenu |= REFRESHDIR_NORMAL;
|
|
}
|
|
}
|
|
else if (M_MenuBackPressed(pid))
|
|
{
|
|
exitmenu = true;
|
|
M_SetMenuDelay(pid);
|
|
}
|
|
|
|
|
|
if (exitmenu)
|
|
{
|
|
closefilemenu(true);
|
|
|
|
// Secret menu!
|
|
//MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
|
|
|
// I could guard it, but let's just always do this.
|
|
M_InitExtras(-1);
|
|
|
|
if (currentMenu->prevMenu)
|
|
M_SetupNextMenu(M_InterruptMenuWithChallenges(currentMenu->prevMenu), false);
|
|
else
|
|
M_ClearMenus(true);
|
|
|
|
M_SetMenuDelay(pid);
|
|
}
|
|
}
|