-- more work on the menu - episode and skill menus are working in DN3D.

This commit is contained in:
Christoph Oelckers 2019-11-25 23:21:51 +01:00
parent d73f915c66
commit a74a670c99
20 changed files with 309 additions and 682 deletions

View file

@ -1780,7 +1780,7 @@ int32_t handleevents_sdlcommon(SDL_Event *ev)
break; break;
case SDL_QUIT: case SDL_QUIT:
quitevent = 1; throw ExitEvent(0); // completely bypass the hackery in the games to block Alt-F4.
return -1; return -1;
} }

View file

@ -178,7 +178,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller)
return true; return true;
case MKEY_Enter: case MKEY_Enter:
if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName))
{ {
gi->MenuChooseSound(); gi->MenuChooseSound();
} }
@ -320,7 +320,7 @@ void FListMenuItem::DrawSelector(int xofs, int yofs, FTexture *tex)
} }
} }
bool FListMenuItem::Activate() bool FListMenuItem::Activate(FName)
{ {
return false; // cannot be activated return false; // cannot be activated
} }
@ -476,10 +476,9 @@ bool FListMenuItemSelectable::Selectable()
return mEnabled && !mHidden; return mEnabled && !mHidden;
} }
bool FListMenuItemSelectable::Activate() bool FListMenuItemSelectable::Activate(FName caller)
{ {
M_SetMenu(mAction, mParam); return M_SetMenu(mAction, mParam, caller);
return true;
} }
FName FListMenuItemSelectable::GetAction(int *pparam) FName FListMenuItemSelectable::GetAction(int *pparam)

View file

@ -153,7 +153,7 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller)
{ {
case MKEY_Back: case MKEY_Back:
{ {
if (scriptID != 1) if (scriptID != 0)
{ {
Close(); Close();
//S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE);
@ -301,10 +301,17 @@ bool DMenu::TranslateKeyboardEvents()
void M_StartControlPanel (bool makeSound) void M_StartControlPanel (bool makeSound)
{ {
static bool created = false;
// intro might call this repeatedly // intro might call this repeatedly
if (DMenu::CurrentMenu != NULL) if (DMenu::CurrentMenu != NULL)
return; return;
if (!created) // Cannot do this earlier.
{
created = true;
M_CreateMenus();
}
buttonMap.ResetButtonStates (); buttonMap.ResetButtonStates ();
for (int i = 0; i < NUM_MKEYS; ++i) for (int i = 0; i < NUM_MKEYS; ++i)
{ {
@ -350,7 +357,7 @@ void M_ActivateMenu(DMenu *menu)
// //
//============================================================================= //=============================================================================
void M_SetMenu(FName menu, int param) bool M_SetMenu(FName menu, int param, FName caller)
{ {
if (DrawBackground == -1) if (DrawBackground == -1)
{ {
@ -358,32 +365,40 @@ void M_SetMenu(FName menu, int param)
else DrawBackground = 0; else DrawBackground = 0;
} }
// some menus need some special treatment (needs to be adjusted for the various frontends. // some menus need some special treatment (needs to be adjusted for the various frontends.
#if 0 switch (caller)
{
case NAME_EpisodeMenu:
// sent from the episode menu
GameStartupInfo.Episode = param;
GameStartupInfo.CustomLevel1 = GameStartupInfo.CustomLevel2 = -1;
GameStartupInfo.Skill = gDefaultSkill;
break;
case NAME_CustomGameMenu:
GameStartupInfo.CustomLevel1 = param;
GameStartupInfo.Episode = GameStartupInfo.CustomLevel2 = -1;
GameStartupInfo.Skill = gDefaultSkill;
// gi->CustomMenuSelection(-1, param);
break;
case NAME_CustomSubMenu1:
GameStartupInfo.CustomLevel2 = param;
// gi->CustomMenuSelection(GameStartupInfo.CustomLevel1, param);
menu = FName(ENamedName(menu + param));
break;
case NAME_SkillMenu:
GameStartupInfo.Skill = param;
break;
}
switch (menu) switch (menu)
{ {
case NAME_Episodemenu: case NAME_StartGame:
// sent from the player class menu // gi->StartGame(&GameStartupInfo);
GameStartupInfo.Skill = -1; return false;
GameStartupInfo.Episode = -1;
GameStartupInfo.PlayerClass =
param == -1000? NULL :
param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type);
break;
case NAME_Skillmenu:
// sent from the episode menu
if ((gameinfo.flags & GI_SHAREWARE) && param > 0)
{
// Only Doom and Heretic have multi-episode shareware versions.
M_StartMessage(GStrings("SWSTRING"), 1);
return;
}
GameStartupInfo.Episode = param;
M_StartupSkillMenu(&GameStartupInfo); // needs player class name from class menu (later)
break;
#if 0
case NAME_StartgameConfirm: case NAME_StartgameConfirm:
{ {
// sent from the skill menu for a skill that needs to be confirmed // sent from the skill menu for a skill that needs to be confirmed
@ -395,21 +410,6 @@ void M_SetMenu(FName menu, int param)
return; return;
} }
case NAME_Startgame:
// sent either from skill menu or confirmation screen. Skill gets only set if sent from skill menu
// Now we can finally start the game. Ugh...
GameStartupInfo.Skill = param;
case NAME_StartgameConfirmed:
G_DeferedInitNew (&GameStartupInfo);
if (gamestate == GS_FULLCONSOLE)
{
gamestate = GS_HIDECONSOLE;
gameaction = ga_newgame;
}
M_ClearMenus ();
return;
case NAME_Savegamemenu: case NAME_Savegamemenu:
if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL) if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL)
{ {
@ -417,8 +417,8 @@ void M_SetMenu(FName menu, int param)
M_StartMessage (GStrings("SAVEDEAD"), 1); M_StartMessage (GStrings("SAVEDEAD"), 1);
return; return;
} }
}
#endif #endif
}
// End of special checks // End of special checks
@ -439,7 +439,7 @@ void M_SetMenu(FName menu, int param)
if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size()) if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size())
{ {
// recursively activate the autoselected item without ever creating this menu. // recursively activate the autoselected item without ever creating this menu.
ld->mItems[ld->mAutoselect]->Activate(); ld->mItems[ld->mAutoselect]->Activate(ld->mMenuName);
} }
else else
{ {
@ -462,6 +462,7 @@ void M_SetMenu(FName menu, int param)
} }
newmenu->Init(DMenu::CurrentMenu, ld); newmenu->Init(DMenu::CurrentMenu, ld);
M_ActivateMenu(newmenu); M_ActivateMenu(newmenu);
return true;
} }
} }
else if ((*desc)->mType == MDESC_OptionsMenu) else if ((*desc)->mType == MDESC_OptionsMenu)
@ -473,7 +474,7 @@ void M_SetMenu(FName menu, int param)
newmenu->Init(DMenu::CurrentMenu, ld); newmenu->Init(DMenu::CurrentMenu, ld);
M_ActivateMenu(newmenu); M_ActivateMenu(newmenu);
} }
return; return true;
} }
else else
{ {
@ -486,12 +487,13 @@ void M_SetMenu(FName menu, int param)
DMenu *newmenu = (DMenu*)menuclass->CreateNew(); DMenu *newmenu = (DMenu*)menuclass->CreateNew();
newmenu->mParentMenu = DMenu::CurrentMenu; newmenu->mParentMenu = DMenu::CurrentMenu;
M_ActivateMenu(newmenu); M_ActivateMenu(newmenu);
return; return true;
} }
} }
*/ */
} }
Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars()); Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars());
return false;
} }
//============================================================================= //=============================================================================
@ -790,7 +792,6 @@ void M_Init (void)
RegisterDukeMenus(); RegisterDukeMenus();
timerSetCallback(M_Ticker); timerSetCallback(M_Ticker);
M_ParseMenuDefs(); M_ParseMenuDefs();
M_CreateMenus();
} }

View file

@ -17,6 +17,7 @@ enum EMax
{ {
MAXSKILLS = 7, MAXSKILLS = 7,
MAXVOLUMES = 7, MAXVOLUMES = 7,
MAXMENUGAMEPLAYENTRIES = 7,
}; };
// These get filled in by the map definition parsers of the front ends. // These get filled in by the map definition parsers of the front ends.
@ -24,11 +25,40 @@ extern FString gSkillNames[MAXSKILLS];
extern FString gVolumeNames[MAXVOLUMES]; extern FString gVolumeNames[MAXVOLUMES];
extern FString gVolumeSubtitles[MAXVOLUMES]; extern FString gVolumeSubtitles[MAXVOLUMES];
extern int32_t gVolumeFlags[MAXVOLUMES]; extern int32_t gVolumeFlags[MAXVOLUMES];
extern int gDefaultVolume, gDefaultSkill;
const int MENU_TICRATE = 30; const int MENU_TICRATE = 30;
extern bool help_disabled, credits_disabled; extern bool help_disabled, credits_disabled;
extern int g_currentMenu; extern int g_currentMenu;
enum
{
EF_HIDEFROMSP = 1 << 0,
};
enum MenuGameplayEntryFlags
{
MGE_Locked = 1u << 0u,
MGE_Hidden = 1u << 1u,
MGE_UserContent = 1u << 2u,
};
typedef struct MenuGameplayEntry
{
char name[64];
uint8_t flags;
bool isValid() const { return name[0] != '\0'; }
} MenuGameplayEntry;
typedef struct MenuGameplayStemEntry
{
MenuGameplayEntry entry;
MenuGameplayEntry subentries[MAXMENUGAMEPLAYENTRIES];
} MenuGameplayStemEntry;
extern MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];
enum EMenuState : int enum EMenuState : int
{ {
@ -86,9 +116,10 @@ enum ENativeFontValues
struct FGameStartup struct FGameStartup
{ {
const char *PlayerClass;
int Episode; int Episode;
int Skill; int Skill;
int CustomLevel1;
int CustomLevel2;
}; };
extern FGameStartup GameStartupInfo; extern FGameStartup GameStartupInfo;
@ -345,7 +376,7 @@ public:
virtual void Ticker(); virtual void Ticker();
virtual void Drawer(DListMenu *menu, const vec2_t& origin, bool selected); virtual void Drawer(DListMenu *menu, const vec2_t& origin, bool selected);
virtual bool Selectable(); virtual bool Selectable();
virtual bool Activate(); virtual bool Activate(FName caller);
virtual FName GetAction(int *pparam); virtual FName GetAction(int *pparam);
virtual bool SetString(int i, const char *s); virtual bool SetString(int i, const char *s);
virtual bool GetString(int i, char *s, int len); virtual bool GetString(int i, char *s, int len);
@ -363,6 +394,7 @@ public:
void SetX(int x) { mXpos = x; } void SetX(int x) { mXpos = x; }
void SetY(int x) { mYpos = x; } void SetY(int x) { mYpos = x; }
void SetHeight(int x) { mHeight = x; } void SetHeight(int x) { mHeight = x; }
void SetAction(FName action) { mAction = action; }
}; };
class FListMenuItemStaticPatch : public FListMenuItem class FListMenuItemStaticPatch : public FListMenuItem
@ -407,7 +439,7 @@ public:
bool CheckCoordinate(int x, int y) override; bool CheckCoordinate(int x, int y) override;
bool Selectable() override; bool Selectable() override;
bool CheckHotkey(int c) override; bool CheckHotkey(int c) override;
bool Activate() override; bool Activate(FName caller) override;
bool MouseEvent(int type, int x, int y) override; bool MouseEvent(int type, int x, int y) override;
FName GetAction(int *pparam) override; FName GetAction(int *pparam) override;
}; };
@ -636,9 +668,11 @@ void M_ParseMenuDefs();
void M_StartupSkillMenu(FGameStartup *gs); void M_StartupSkillMenu(FGameStartup *gs);
int M_GetDefaultSkill(); int M_GetDefaultSkill();
void M_StartControlPanel (bool makeSound); void M_StartControlPanel (bool makeSound);
void M_SetMenu(FName menu, int param = -1); bool M_SetMenu(FName menu, int param = -1, FName callingMenu = NAME_None);
void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave);
void M_StartMessage(const char *message, int messagemode, FName action = NAME_None); void M_StartMessage(const char *message, int messagemode, FName action = NAME_None);
void M_UnhideCustomMenu(int menu, int itemmask);
void I_SetMouseCapture(); void I_SetMouseCapture();
void I_ReleaseMouseCapture(); void I_ReleaseMouseCapture();

View file

@ -49,10 +49,13 @@
void ClearSaveGames(); void ClearSaveGames();
// Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded.
FString gSkillNames[MAXSKILLS]; FString gSkillNames[MAXSKILLS];
FString gVolumeNames[MAXVOLUMES]; FString gVolumeNames[MAXVOLUMES];
FString gVolumeSubtitles[MAXVOLUMES]; FString gVolumeSubtitles[MAXVOLUMES];
int32_t gVolumeFlags[MAXVOLUMES]; int32_t gVolumeFlags[MAXVOLUMES];
int gDefaultVolume = 0, gDefaultSkill = 1;
MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];
MenuDescriptorList MenuDescriptors; MenuDescriptorList MenuDescriptors;
static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus
@ -982,10 +985,34 @@ void M_ParseMenuDefs()
} }
//=============================================================================
//
// Unlocks a custom menu from a script
//
//=============================================================================
void M_UnhideCustomMenu(int menu, int iSet)
{
FName menuname = FName(ENamedName(NAME_CustomSubMenu1 + menu));
auto desc = MenuDescriptors.CheckKey(menuname);
if (desc != NULL && (*desc)->mType == MDESC_ListMenu)
{
FListMenuDescriptor* ld = static_cast<FListMenuDescriptor*>(*desc);
for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b)
{
if (b >= ld->mItems.Size()) return;
if (iSet & (1u << b))
{
ld->mItems[b]->mHidden = false;
ld->mItems[b]->mEnabled = true;
}
}
}
}
//============================================================================= //=============================================================================
// //
// Creates the episode menu // Creates the episode menu
// Falls back on an option menu if there's not enough screen space to show all episodes
// //
//============================================================================= //=============================================================================
@ -994,68 +1021,130 @@ static void BuildEpisodeMenu()
// Build episode menu // Build episode menu
int addedVolumes = 0; int addedVolumes = 0;
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_EpisodeMenu); FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_EpisodeMenu);
if (desc != NULL) if (desc != NULL && (*desc)->mType == MDESC_ListMenu)
{ {
if ((*desc)->mType == MDESC_ListMenu) FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc);
ld->mSelectedItem = gDefaultVolume;
for (int i = 0; i < MAXVOLUMES; i++)
{ {
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc); if (gVolumeNames[i].IsNotEmpty() && !(gVolumeFlags[i] & EF_HIDEFROMSP))
ld->mSelectedItem = 1;
for (int i = 0; i < MAXVOLUMES; i++)
{ {
if (gVolumeNames[i].IsNotEmpty()) auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1);
ld->mItems.Push(it);
addedVolumes++;
if (gVolumeSubtitles[i].IsNotEmpty())
{ {
auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); //auto it = new FListMenuItemNativeStaticText(ld->mXpos, gVolumeSubtitles[i], NIT_SmallFont);
ld->mItems.Push(it);
addedVolumes++;
if (gVolumeSubtitles[i].IsNotEmpty())
{
//auto it = new FListMenuItemNativeStaticText(ld->mXpos, gVolumeSubtitles[i], NIT_SmallFont);
//ld->mItems.Push(it);
}
}
if (1 /*CheckUserMaps()*/)
{
//auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer.
//ld->mItems.Push(it); //ld->mItems.Push(it);
}
}
}
if (1 /*CheckUserMaps()*/)
{
//auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer.
//ld->mItems.Push(it);
auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_UsermapMenu);
ld->mItems.Push(it); ld->mItems.Push(it);
addedVolumes++; addedVolumes++;
if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent. if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent.
{
//auto it = new FListMenuItemNativeStaticText(ld->mXpos, "$MNU_SELECTUSERMAP", NIT_SmallFont);
//ld->mItems.Push(it);
}
}
if (addedVolumes == 1)
{
ld->mAutoselect = 0;
}
}
// Build skill menu
int addedSkills = 0;
desc = MenuDescriptors.CheckKey(NAME_SkillMenu);
if (desc != NULL && (*desc)->mType == MDESC_ListMenu)
{
FListMenuDescriptor* ld = static_cast<FListMenuDescriptor*>(*desc);
ld->mSelectedItem = gDefaultSkill;
for (int i = 0; i < MAXSKILLS; i++)
{
if (gSkillNames[i].IsNotEmpty())
{
auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gSkillNames[i][0], gSkillNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_StartGame, i);
ld->mItems.Push(it);
addedSkills++;
}
}
if (addedSkills == 0)
{
// Need to add one item with the default skill so that the menu does not break.
auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "", NIT_BigFont, NIT_ActiveState, 1, NAME_StartGame, gDefaultSkill);
ld->mItems.Push(it);
}
if (addedSkills == 1)
{
ld->mAutoselect = 0;
}
}
if (g_MenuGameplayEntries[0].entry.isValid())
{
int e = 0;
FMenuDescriptor** desc = MenuDescriptors.CheckKey(NAME_CustomGameMenu);
if (desc != NULL && (*desc)->mType == MDESC_ListMenu)
{
FListMenuDescriptor* ld = static_cast<FListMenuDescriptor*>(*desc);
for (MenuGameplayStemEntry const& stem : g_MenuGameplayEntries)
{
MenuGameplayEntry const& entry = stem.entry;
if (!entry.isValid())
break;
int s = 0;
FMenuDescriptor** sdesc = MenuDescriptors.CheckKey(FName(ENamedName(NAME_CustomSubMenu1 + e)));
if (sdesc != NULL && (*sdesc)->mType == MDESC_ListMenu)
{
FListMenuDescriptor* ld = static_cast<FListMenuDescriptor*>(*desc);
for (MenuGameplayEntry const& subentry : stem.subentries)
{ {
//auto it = new FListMenuItemNativeStaticText(ld->mXpos, "$MNU_SELECTUSERMAP", NIT_SmallFont); if (!subentry.isValid())
//ld->mItems.Push(it); break;
auto li = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, subentry.name, NIT_BigFont, NIT_ActiveColor, 1.f, subentry.flags & MGE_UserContent ? NAME_UsermapMenu : NAME_SkillMenu);
if (subentry.flags & MGE_Locked) li->mEnabled = false;
if (subentry.flags & MGE_Hidden) li->mHidden = true;
++s;
} }
} }
if (addedVolumes == 1) FName link = entry.flags & MGE_UserContent ? NAME_UsermapMenu : s == 0 ? NAME_SkillMenu : NAME_CustomSubMenu1;
auto li = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, entry.name, NIT_BigFont, NIT_ActiveColor, 1.f, link, link == NAME_CustomSubMenu1 ? e : -1);
if (entry.flags & MGE_Locked) li->mEnabled = false;
if (entry.flags & MGE_Hidden) li->mHidden = true;
e++;
}
}
if (e > 0)
{
FMenuDescriptor** desc = MenuDescriptors.CheckKey(NAME_MainMenu);
if (desc != NULL && (*desc)->mType == MDESC_ListMenu)
{
FListMenuDescriptor* ld = static_cast<FListMenuDescriptor*>(*desc);
auto li = ld->mItems[0];
if (li->GetAction(nullptr) == NAME_EpisodeMenu)
{ {
ld->mAutoselect = 0; li->SetAction(NAME_CustomGameMenu);
} }
} }
} }
} }
#if 0
if (gVolumeNames[i].IsNotEmpty())
{
if (!(gVolumeFlags[i] & EF_HIDEFROMSP))
{
MEL_EPISODE[i] = &ME_EPISODE[i];
ME_EPISODE[i] = ME_EPISODE_TEMPLATE;
ME_EPISODE[i].name = gVolumeNames[i];
}
// if (!(EpisodeFlags[i] & EF_HIDEFROMMP))
{
MEOSN_NetEpisodes[k] = gVolumeNames[i];
MEOSV_NetEpisodes[k] = i;
k++;
}
}
M_EPISODE.numEntries = g_volumeCnt + 2;
#endif
} }
//============================================================================= //=============================================================================
@ -1141,181 +1230,6 @@ void M_CreateMenus()
#endif #endif
} }
//=============================================================================
//
// The skill menu must be refeshed each time it starts up
//
//=============================================================================
extern int restart;
void M_StartupSkillMenu(FGameStartup *gs)
{
#if 0
static int done = -1;
bool success = false;
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu);
if (desc != NULL)
{
if ((*desc)->mType == MDESC_ListMenu)
{
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc);
int x = ld->mXpos;
int y = ld->mYpos;
// Delete previous contents
for(unsigned i=0; i<ld->mItems.Size(); i++)
{
FName n = ld->mItems[i]->GetAction(NULL);
if (n == NAME_Startgame || n == NAME_StartgameConfirm)
{
for(unsigned j=i; j<ld->mItems.Size(); j++)
{
delete ld->mItems[j];
}
ld->mItems.Resize(i);
break;
}
}
if (done != restart)
{
done = restart;
int defskill = DefaultSkill;
if ((unsigned int)defskill >= AllSkills.Size())
{
defskill = (AllSkills.Size() - 1) / 2;
}
ld->mSelectedItem = ld->mItems.Size() + defskill;
int posy = y;
int topy = posy;
// Get lowest y coordinate of any static item in the menu
for(unsigned i = 0; i < ld->mItems.Size(); i++)
{
int y = ld->mItems[i]->GetY();
if (y < topy) topy = y;
}
// center the menu on the screen if the top space is larger than the bottom space
int totalheight = posy + AllSkills.Size() * ld->mLinespacing - topy;
if (totalheight < 190 || AllSkills.Size() == 1)
{
int newtop = (200 - totalheight + topy) / 2;
int topdelta = newtop - topy;
if (topdelta < 0)
{
for(unsigned i = 0; i < ld->mItems.Size(); i++)
{
ld->mItems[i]->OffsetPositionY(topdelta);
}
y = ld->mYpos = posy - topdelta;
}
}
else
{
// too large
delete ld;
desc = NULL;
done = false;
goto fail;
}
}
unsigned firstitem = ld->mItems.Size();
for(unsigned int i = 0; i < AllSkills.Size(); i++)
{
FSkillInfo &skill = AllSkills[i];
FListMenuItem *li;
// Using a different name for skills that must be confirmed makes handling this easier.
FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
NAME_StartgameConfirm : NAME_Startgame;
FString *pItemText = NULL;
if (gs->PlayerClass != NULL)
{
pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass);
}
if (skill.PicName.Len() != 0 && pItemText == NULL)
{
FTextureID tex = GetMenuTexture(skill.PicName);
li = new FListMenuItemPatch(ld->mXpos, y, ld->mLinespacing, skill.Shortcut, tex, action, i);
}
else
{
EColorRange color = (EColorRange)skill.GetTextColor();
if (color == CR_UNTRANSLATED) color = ld->mFontColor;
li = new FListMenuItemText(x, y, ld->mLinespacing, skill.Shortcut,
pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i);
}
ld->mItems.Push(li);
y += ld->mLinespacing;
}
if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1)
{
ld->mAutoselect = firstitem + M_GetDefaultSkill();
}
else
{
ld->mAutoselect = -1;
}
success = true;
}
}
if (success) return;
fail:
// Option menu fallback for overlong skill lists
FOptionMenuDescriptor *od;
if (desc == NULL)
{
od = new FOptionMenuDescriptor;
if (desc != NULL) delete *desc;
MenuDescriptors[NAME_Skillmenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Skillmenu;
od->mTitle = "$MNU_CHOOSESKILL";
od->mSelectedItem = 0;
od->mScrollPos = 0;
od->mClass = NULL;
od->mPosition = -15;
od->mScrollTop = 0;
od->mIndent = 160;
od->mDontDim = false;
}
else
{
od = static_cast<FOptionMenuDescriptor*>(*desc);
for(unsigned i=0;i<od->mItems.Size(); i++)
{
delete od->mItems[i];
}
od->mItems.Clear();
}
for(unsigned int i = 0; i < AllSkills.Size(); i++)
{
FSkillInfo &skill = AllSkills[i];
FOptionMenuItem *li;
// Using a different name for skills that must be confirmed makes handling this easier.
const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
"StartgameConfirm" : "Startgame";
FString *pItemText = NULL;
if (gs->PlayerClass != NULL)
{
pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass);
}
li = new FOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i);
od->mItems.Push(li);
if (!done)
{
done = true;
od->mSelectedItem = M_GetDefaultSkill();
}
}
#endif
}
//============================================================================= //=============================================================================
// //
// Returns the default skill level. // Returns the default skill level.
@ -1324,14 +1238,5 @@ fail:
int M_GetDefaultSkill() int M_GetDefaultSkill()
{ {
#if 0 return gDefaultSkill;
int defskill = DefaultSkill;
if ((unsigned int)defskill >= AllSkills.Size())
{
defskill = (AllSkills.Size() - 1) / 2;
}
return defskill;
#else
return 1;
#endif
} }

View file

@ -310,7 +310,7 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller)
break; break;
case MKEY_Enter: case MKEY_Enter:
if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName))
{ {
return true; return true;
} }

View file

@ -34,3 +34,5 @@ xx(CustomSubMenu4)
xx(CustomSubMenu5) xx(CustomSubMenu5)
xx(CustomSubMenu6) xx(CustomSubMenu6)
xx(CustomSubMenu7) xx(CustomSubMenu7)
xx(UsermapMenu)
xx(StartGame)

View file

@ -74,7 +74,6 @@ void CONFIG_SetDefaults(void)
ud.angleinterpolation = 0; ud.angleinterpolation = 0;
ud.camerasprite = -1; ud.camerasprite = -1;
ud.config.ShowWeapons = 0; ud.config.ShowWeapons = 0;
ud.default_skill = 1;
ud.display_bonus_screen = 1; ud.display_bonus_screen = 1;
hud_position = 0; hud_position = 0;

View file

@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gamecontrol.h" #include "gamecontrol.h"
#include "c_bind.h" #include "c_bind.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "gstrings.h"
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
BEGIN_DUKE_NS BEGIN_DUKE_NS
@ -44,10 +45,6 @@ BEGIN_DUKE_NS
#define MENU_MARGIN_CENTER 160 #define MENU_MARGIN_CENTER 160
#define MENU_HEIGHT_CENTER 100 #define MENU_HEIGHT_CENTER 100
// This is for intermediate levels in the episode selection chain. Ion Fury uses this.
MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];
int ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES];
int ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES];
enum MenuTextFlags_t enum MenuTextFlags_t
{ {
@ -96,212 +93,6 @@ void Menu_Init(void)
MF_Minifont.textflags |= TEXT_UPPERCASE; MF_Minifont.textflags |= TEXT_UPPERCASE;
#if 0 #if 0
//int32_t i, j, k;
if (FURY)
{
MMF_Top_Skill.pos.x = (320 << 15);
ME_SKILL_TEMPLATE.format = &MEF_LeftMenu;
}
// prepare gamefuncs and keys
MEOSN_Gamefuncs[0] = MenuGameFuncNone;
MEOSV_Gamefuncs[0] = -1;
k = 1;
for (i = 0; i < NUMGAMEFUNCTIONS; ++i)
{
MenuGameFuncs[i] = buttonMap.GetButtonAlias(i);
MenuGameFuncs[i].Substitute('_', ' ');
if (MenuGameFuncs[i][0] != '\0')
{
MEOSN_Gamefuncs[k] = MenuGameFuncs[i];
MEOSV_Gamefuncs[k] = i;
++k;
}
}
MEOS_Gamefuncs.numOptions = k;
for (i = 0; i < NUMKEYS; ++i)
MEOSN_Keys[i] = KB_ScanCodeToString(i);
MEOSN_Keys[NUMKEYS - 1] = MenuKeyNone;
// prepare episodes
k = 0;
if (gVolumeNames[i].IsNotEmpty())
{
if (!(gVolumeFlags[i] & EF_HIDEFROMSP))
{
MEL_EPISODE[i] = &ME_EPISODE[i];
ME_EPISODE[i] = ME_EPISODE_TEMPLATE;
ME_EPISODE[i].name = gVolumeNames[i];
}
// if (!(EpisodeFlags[i] & EF_HIDEFROMMP))
{
MEOSN_NetEpisodes[k] = gVolumeNames[i];
MEOSV_NetEpisodes[k] = i;
k++;
}
}
M_EPISODE.numEntries = g_volumeCnt + 2;
MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont;
MEL_EPISODE[g_volumeCnt + 1] = &ME_EPISODE_USERMAP;
MEOSN_NetEpisodes[k] = MenuUserMap;
MEOSV_NetEpisodes[k] = MAXVOLUMES;
MEOS_NETOPTIONS_EPISODE.numOptions = k + 1;
NetEpisode = MEOSV_NetEpisodes[0];
MMF_Top_Episode.pos.y = (58 + (3 - k) * 6) << 16;
if (g_skillCnt == 0)
MEO_EPISODE.linkID = MENU_NULL;
M_EPISODE.currentEntry = ud.default_volume;
// prepare new game custom :O
if (g_MenuGameplayEntries[0].entry.isValid())
{
MEO_MAIN_NEWGAME.linkID = M_NEWVERIFY.linkID = MENU_NEWGAMECUSTOM;
int e = 0;
for (MenuGameplayStemEntry const& stem : g_MenuGameplayEntries)
{
MenuGameplayEntry const& entry = stem.entry;
if (!entry.isValid())
break;
MenuEntry_t& e_me = ME_NEWGAMECUSTOMENTRIES[e];
e_me = ME_EPISODE_TEMPLATE;
MenuLink_t& e_meo = MEO_NEWGAMECUSTOM[e];
e_meo = MEO_NEWGAMECUSTOM_TEMPLATE;
e_me.entry = &e_meo;
e_me.name = entry.name;
if (entry.flags & MGE_Locked)
e_me.flags |= MEF_Disabled;
if (entry.flags & MGE_Hidden)
e_me.flags |= MEF_Hidden;
int s = 0;
for (MenuGameplayEntry const& subentry : stem.subentries)
{
if (!subentry.isValid())
break;
MenuEntry_t& s_me = ME_NEWGAMECUSTOMSUBENTRIES[e][s];
s_me = ME_EPISODE_TEMPLATE;
MenuLink_t& s_meo = MEO_NEWGAMECUSTOMSUB[e][s];
s_meo = MEO_NEWGAMECUSTOMSUB_TEMPLATE;
s_me.entry = &s_meo;
s_me.name = subentry.name;
if (subentry.flags & MGE_Locked)
s_me.flags |= MEF_Disabled;
if (subentry.flags & MGE_Hidden)
s_me.flags |= MEF_Hidden;
++s;
}
if (entry.flags & MGE_UserContent)
e_meo.linkID = MENU_USERMAP;
else if (s == 0)
e_meo.linkID = MENU_SKILL;
++e;
}
Menu_PopulateNewGameCustom();
}
// prepare skills
k = -1;
for (i = 0; i < g_skillCnt && g_skillNames[i][0]; ++i)
{
MEL_SKILL[i] = &ME_SKILL[i];
ME_SKILL[i] = ME_SKILL_TEMPLATE;
ME_SKILL[i].name = g_skillNames[i];
MEOSN_NetSkills[i] = g_skillNames[i];
k = i;
}
++k;
M_SKILL.numEntries = g_skillCnt; // k;
MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1;
MEOSN_NetSkills[g_skillCnt] = MenuSkillNone;
MMF_Top_Skill.pos.y = (58 + (4 - g_skillCnt) * 6) << 16;
M_SKILL.currentEntry = ud.default_skill;
Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL);
// prepare multiplayer gametypes
k = -1;
for (i = 0; i < MAXGAMETYPES; ++i)
if (g_gametypeNames[i][0])
{
MEOSN_NetGametypes[i] = g_gametypeNames[i];
k = i;
}
++k;
MEOS_NETOPTIONS_GAMETYPE.numOptions = k;
if (NAM_WW2GI)
ME_NETOPTIONS_MONSTERS.name = "Enemies";
// prepare cheats
for (i = 0; i < NUMCHEATFUNCS; ++i)
MEL_CHEATS[i + 1] = &ME_CheatCodes[i];
// prepare text chat macros
for (i = 0; i < MAXRIDECULE; ++i)
{
MEL_MACROS[i] = &ME_MACROS[i];
ME_MACROS[i] = ME_MACROS_TEMPLATE;
ME_MACROS[i].entry = &MEO_MACROS[i];
MEO_MACROS[i] = MEO_MACROS_TEMPLATE;
MEO_MACROS[i].variable = sink;// ud.ridecule[i]; temporarily disabled
}
// prepare input
for (i = 0; i < NUMGAMEFUNCTIONS; ++i)
{
if (MenuGameFuncs[i][0] == '\0')
{
MEL_KEYBOARDSETUPFUNCS[i] = NULL;
continue;
}
MEL_KEYBOARDSETUPFUNCS[i] = &ME_KEYBOARDSETUPFUNCS[i];
ME_KEYBOARDSETUPFUNCS[i] = ME_KEYBOARDSETUPFUNCS_TEMPLATE;
ME_KEYBOARDSETUPFUNCS[i].name = MenuGameFuncs[i];
ME_KEYBOARDSETUPFUNCS[i].entry = &MEO_KEYBOARDSETUPFUNCS[i];
MEO_KEYBOARDSETUPFUNCS[i] = MEO_KEYBOARDSETUPFUNCS_TEMPLATE;
}
M_KEYBOARDKEYS.numEntries = NUMGAMEFUNCTIONS;
for (i = 0; i < 2 * joystick.numButtons + 8 * joystick.numHats; ++i)
{
if (i < 2 * joystick.numButtons)
{
if (i & 1)
Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, "Double %s", joyGetName(1, i >> 1));
else
Bstrncpy(MenuJoystickNames[i], joyGetName(1, i >> 1), MAXJOYBUTTONSTRINGLENGTH);
}
else
{
Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, (i & 1) ? "Double Hat %d %s" : "Hat %d %s", ((i - 2 * joystick.numButtons) >> 3), MenuJoystickHatDirections[((i - 2 * joystick.numButtons) >> 1) % 4]);
}
}
for (i = 0; i < joystick.numAxes; ++i)
{
ME_JOYSTICKAXES[i] = ME_JOYSTICKAXES_TEMPLATE;
Bstrncpy(MenuJoystickAxes[i], joyGetName(0, i), MAXJOYBUTTONSTRINGLENGTH);
ME_JOYSTICKAXES[i].name = MenuJoystickAxes[i];
MEL_JOYSTICKAXES[i] = &ME_JOYSTICKAXES[i];
}
M_JOYSTICKAXES.numEntries = joystick.numAxes;
// prepare sound setup // prepare sound setup
#ifndef EDUKE32_STANDALONE #ifndef EDUKE32_STANDALONE
@ -311,28 +102,6 @@ void Menu_Init(void)
ME_SOUND_DUKETALK.name = "Grunt talk:"; ME_SOUND_DUKETALK.name = "Grunt talk:";
#endif #endif
if (FURY)
{
MF_Redfont.between.x = 2 << 16;
MF_Redfont.cursorScale = 32768;
MF_Redfont.zoom = 16384;
MF_Bluefont.zoom = 16384;
// hack; should swap out pointers
MF_Minifont = MF_Bluefont;
MMF_Top_Main.pos.x = 40 << 16;
MMF_Top_Main.pos.y = 130 << 16;
MMF_Top_Main.bottomcutoff = 190 << 16;
M_OPTIONS.format = &MMF_Top_Main;
MEF_MainMenu.width = MEF_OptionsMenu.width = -(160 << 16);
MEF_MainMenu.marginBottom = 7 << 16;
M_OPTIONS.title = NoTitle;
SELECTDIR_z = 16384;
}
// prepare shareware // prepare shareware
if (VOLUMEONE) if (VOLUMEONE)
@ -358,10 +127,7 @@ void Menu_Init(void)
M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits;
} }
MenuEntry_HideOnCondition(&ME_MAIN_HELP, G_GetLogoFlags() & LOGO_NOHELP);
#ifndef EDUKE32_SIMPLE_MENU
MenuEntry_HideOnCondition(&ME_MAIN_CREDITS, G_GetLogoFlags() & LOGO_NOCREDITS);
#endif
#endif #endif
} }
@ -374,6 +140,7 @@ static void Menu_DrawTopBar(const vec2_t origin)
static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin)
{ {
static char t[64]; static char t[64];
if (*caption == '$') caption = GStrings(caption + 1);
size_t const srclen = strlen(caption); size_t const srclen = strlen(caption);
size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1);
memcpy(t, caption, dstlen); memcpy(t, caption, dstlen);
@ -572,6 +339,11 @@ protected:
void PreDraw() override void PreDraw() override
{ {
CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true); CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true);
if (mDesc->mCaption.IsNotEmpty())
{
Menu_DrawTopBar(origin);
Menu_DrawTopBarCaption(mDesc->mCaption, origin);
}
} }
void PostDraw() override void PostDraw() override
@ -601,11 +373,6 @@ class MainMenu : public DukeListMenu
if (PLUTOPAK) // JBF 20030804 if (PLUTOPAK) // JBF 20030804
rotatesprite_fs((origin.y << 16) + ((MENU_MARGIN_CENTER+100)<<16), (origin.y << 16) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); rotatesprite_fs((origin.y << 16) + ((MENU_MARGIN_CENTER+100)<<16), (origin.y << 16) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8);
} }
else if (mDesc->mCaption.IsNotEmpty())
{
Menu_DrawTopBar(origin);
Menu_DrawTopBarCaption(mDesc->mCaption, origin);
}
} }
}; };

View file

@ -161,8 +161,6 @@ typedef struct {
int32_t playerbest; int32_t playerbest;
int32_t default_volume, default_skill;
int32_t returnvar[MAX_RETURN_VALUES-1]; int32_t returnvar[MAX_RETURN_VALUES-1];
uint32_t userbytever; uint32_t userbytever;

View file

@ -1508,8 +1508,8 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2)
case USERDEFS_GLOBAL_R: labelNum = globalr; break; case USERDEFS_GLOBAL_R: labelNum = globalr; break;
case USERDEFS_GLOBAL_G: labelNum = globalg; break; case USERDEFS_GLOBAL_G: labelNum = globalg; break;
case USERDEFS_GLOBAL_B: labelNum = globalb; break; case USERDEFS_GLOBAL_B: labelNum = globalb; break;
case USERDEFS_DEFAULT_VOLUME: labelNum = ud.default_volume; break; case USERDEFS_DEFAULT_VOLUME: labelNum = gDefaultVolume; break;
case USERDEFS_DEFAULT_SKILL: labelNum = ud.default_skill; break; case USERDEFS_DEFAULT_SKILL: labelNum = gDefaultSkill; break;
case USERDEFS_MENU_SHADEDESELECTED: labelNum = MF_Redfont.shade_deselected; break; case USERDEFS_MENU_SHADEDESELECTED: labelNum = MF_Redfont.shade_deselected; break;
case USERDEFS_MENU_SHADEDISABLED: labelNum = MF_Redfont.shade_disabled; break; case USERDEFS_MENU_SHADEDISABLED: labelNum = MF_Redfont.shade_disabled; break;
case USERDEFS_MENUTEXT_ZOOM: labelNum = MF_Redfont.zoom; break; case USERDEFS_MENUTEXT_ZOOM: labelNum = MF_Redfont.zoom; break;
@ -1701,8 +1701,8 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons
case USERDEFS_GLOBAL_R: globalr = iSet; break; case USERDEFS_GLOBAL_R: globalr = iSet; break;
case USERDEFS_GLOBAL_G: globalg = iSet; break; case USERDEFS_GLOBAL_G: globalg = iSet; break;
case USERDEFS_GLOBAL_B: globalb = iSet; break; case USERDEFS_GLOBAL_B: globalb = iSet; break;
case USERDEFS_DEFAULT_VOLUME: ud.default_volume = iSet; break; case USERDEFS_DEFAULT_VOLUME: gDefaultVolume = iSet; break;
case USERDEFS_DEFAULT_SKILL: ud.default_skill = iSet; break; case USERDEFS_DEFAULT_SKILL: gDefaultSkill = iSet; break;
case USERDEFS_MENU_SHADEDESELECTED: MF_Redfont.shade_deselected = MF_Bluefont.shade_deselected = MF_Minifont.shade_deselected = iSet; break; case USERDEFS_MENU_SHADEDESELECTED: MF_Redfont.shade_deselected = MF_Bluefont.shade_deselected = MF_Minifont.shade_deselected = iSet; break;
case USERDEFS_MENU_SHADEDISABLED: MF_Redfont.shade_disabled = MF_Bluefont.shade_disabled = MF_Minifont.shade_disabled = iSet; break; case USERDEFS_MENU_SHADEDISABLED: MF_Redfont.shade_disabled = MF_Bluefont.shade_disabled = MF_Minifont.shade_disabled = iSet; break;
case USERDEFS_MENUTEXT_ZOOM: MF_Redfont.zoom = iSet; break; case USERDEFS_MENUTEXT_ZOOM: MF_Redfont.zoom = iSet; break;
@ -1751,16 +1751,8 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons
case USERDEFS_DRAW_Y: rotatesprite_y_offset = iSet; break; case USERDEFS_DRAW_Y: rotatesprite_y_offset = iSet; break;
case USERDEFS_DRAW_YXASPECT: rotatesprite_yxaspect = iSet; break; case USERDEFS_DRAW_YXASPECT: rotatesprite_yxaspect = iSet; break;
case USERDEFS_FOV: r_fov.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_FOV: r_fov.SetGenericRepDefault(iSet, CVAR_Int); break;
case USERDEFS_NEWGAMECUSTOMOPEN: case USERDEFS_NEWGAMECUSTOMOPEN: M_UnhideCustomMenu(-1, iSet); break;
for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b) case USERDEFS_NEWGAMECUSTOMSUBOPEN: M_UnhideCustomMenu(lParm2, iSet); break;
if (iSet & (1u<<b))
ME_NEWGAMECUSTOMENTRIES[b] = 0;
break;
case USERDEFS_NEWGAMECUSTOMSUBOPEN:
for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b)
if (iSet & (1u<<b))
ME_NEWGAMECUSTOMSUBENTRIES[lParm2][b] = 0;
break;
} }
} }

View file

@ -189,11 +189,6 @@ extern int32_t g_gametypeFlags[MAXGAMETYPES];
extern const char *s_buildDate; extern const char *s_buildDate;
#endif #endif
enum
{
EF_HIDEFROMSP = 1<<0,
};
EXTERN_INLINE_HEADER void G_UpdateInterpolations(void); EXTERN_INLINE_HEADER void G_UpdateInterpolations(void);
EXTERN_INLINE_HEADER void G_RestoreInterpolations(void); EXTERN_INLINE_HEADER void G_RestoreInterpolations(void);

View file

@ -1564,8 +1564,6 @@ void Menu_Init(void)
} }
M_EPISODE.numEntries = g_volumeCnt+2; M_EPISODE.numEntries = g_volumeCnt+2;
MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont;
MEL_EPISODE[g_volumeCnt+1] = &ME_EPISODE_USERMAP;
MEOSN_NetEpisodes[k] = MenuUserMap; MEOSN_NetEpisodes[k] = MenuUserMap;
MEOSV_NetEpisodes[k] = MAXVOLUMES; MEOSV_NetEpisodes[k] = MAXVOLUMES;
@ -1576,74 +1574,6 @@ void Menu_Init(void)
MEO_EPISODE.linkID = MENU_NULL; MEO_EPISODE.linkID = MENU_NULL;
M_EPISODE.currentEntry = ud.default_volume; M_EPISODE.currentEntry = ud.default_volume;
// prepare new game custom :O
if (g_MenuGameplayEntries[0].entry.isValid())
{
MEO_MAIN_NEWGAME.linkID = M_NEWVERIFY.linkID = MENU_NEWGAMECUSTOM;
int e = 0;
for (MenuGameplayStemEntry const & stem : g_MenuGameplayEntries)
{
MenuGameplayEntry const & entry = stem.entry;
if (!entry.isValid())
break;
MenuEntry_t & e_me = ME_NEWGAMECUSTOMENTRIES[e];
e_me = ME_EPISODE_TEMPLATE;
MenuLink_t & e_meo = MEO_NEWGAMECUSTOM[e];
e_meo = MEO_NEWGAMECUSTOM_TEMPLATE;
e_me.entry = &e_meo;
e_me.name = entry.name;
if (entry.flags & MGE_Locked)
e_me.flags |= MEF_Disabled;
if (entry.flags & MGE_Hidden)
e_me.flags |= MEF_Hidden;
int s = 0;
for (MenuGameplayEntry const & subentry : stem.subentries)
{
if (!subentry.isValid())
break;
MenuEntry_t & s_me = ME_NEWGAMECUSTOMSUBENTRIES[e][s];
s_me = ME_EPISODE_TEMPLATE;
MenuLink_t & s_meo = MEO_NEWGAMECUSTOMSUB[e][s];
s_meo = MEO_NEWGAMECUSTOMSUB_TEMPLATE;
s_me.entry = &s_meo;
s_me.name = subentry.name;
if (subentry.flags & MGE_Locked)
s_me.flags |= MEF_Disabled;
if (subentry.flags & MGE_Hidden)
s_me.flags |= MEF_Hidden;
++s;
}
if (entry.flags & MGE_UserContent)
e_meo.linkID = MENU_USERMAP;
else if (s == 0)
e_meo.linkID = MENU_SKILL;
++e;
}
Menu_PopulateNewGameCustom();
}
// prepare skills
k = -1;
for (i = 0; i < g_skillCnt && g_skillNames[i][0]; ++i)
{
MEL_SKILL[i] = &ME_SKILL[i];
ME_SKILL[i] = ME_SKILL_TEMPLATE;
ME_SKILL[i].name = g_skillNames[i];
MEOSN_NetSkills[i] = g_skillNames[i];
k = i;
}
++k; ++k;
M_SKILL.numEntries = g_skillCnt; // k; M_SKILL.numEntries = g_skillCnt; // k;
MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1; MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1;

View file

@ -47,32 +47,6 @@ struct MenuFont_t
extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont;
#define MAXMENUGAMEPLAYENTRIES 7
enum MenuGameplayEntryFlags
{
MGE_Locked = 1u << 0u,
MGE_Hidden = 1u << 1u,
MGE_UserContent = 1u << 2u,
};
typedef struct MenuGameplayEntry
{
char name[64];
uint8_t flags;
bool isValid() const { return name[0] != '\0'; }
} MenuGameplayEntry;
typedef struct MenuGameplayStemEntry
{
MenuGameplayEntry entry;
MenuGameplayEntry subentries[MAXMENUGAMEPLAYENTRIES];
} MenuGameplayStemEntry;
extern MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];
extern int ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES];
extern int ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES];
void Menu_Init(void); void Menu_Init(void);

View file

@ -86,7 +86,6 @@ void CONFIG_SetDefaults(void)
ud.show_level_text = 1; ud.show_level_text = 1;
ud.screenfade = 1; ud.screenfade = 1;
ud.menubackground = 1; ud.menubackground = 1;
ud.default_skill = 1;
ud.slidebar_paldisabled = 1; ud.slidebar_paldisabled = 1;
ud.shadow_pal = 4; ud.shadow_pal = 4;
ud.menu_scrollbartilenum = -1; ud.menu_scrollbartilenum = -1;

View file

@ -163,8 +163,6 @@ typedef struct {
int32_t playerbest; int32_t playerbest;
int32_t default_volume, default_skill;
//int32_t returnvar[MAX_RETURN_VALUES-1]; //int32_t returnvar[MAX_RETURN_VALUES-1];
uint32_t userbytever; uint32_t userbytever;

View file

@ -1579,7 +1579,7 @@ void Menu_Init(void)
MMF_Top_Episode.pos.y = (58 + (3-k)*6)<<16; MMF_Top_Episode.pos.y = (58 + (3-k)*6)<<16;
if (g_skillCnt == 0) if (g_skillCnt == 0)
MEO_EPISODE.linkID = MENU_NULL; MEO_EPISODE.linkID = MENU_NULL;
M_EPISODE.currentEntry = ud.default_volume; M_EPISODE.currentEntry = gDefaultVolume;
// prepare skills // prepare skills
k = -1; k = -1;
@ -1598,7 +1598,7 @@ void Menu_Init(void)
MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1; MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1;
MEOSN_NetSkills[g_skillCnt] = MenuSkillNone; MEOSN_NetSkills[g_skillCnt] = MenuSkillNone;
MMF_Top_Skill.pos.y = (58 + (4-g_skillCnt)*6)<<16; MMF_Top_Skill.pos.y = (58 + (4-g_skillCnt)*6)<<16;
M_SKILL.currentEntry = ud.default_skill; M_SKILL.currentEntry = gDefaultSkill;
Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL); Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL);
// prepare multiplayer gametypes // prepare multiplayer gametypes

View file

@ -754,7 +754,6 @@ FString GameInterface::statFPS()
GameStats GameInterface::getStats() GameStats GameInterface::getStats()
{ {
GameStats stats;
DukePlayer_t* p = g_player[myconnectindex].ps; DukePlayer_t* p = g_player[myconnectindex].ps;
return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC }; return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC };
} }

View file

@ -10,4 +10,10 @@ Continue,MNU_CONTINUE,,,,,Fortfahren,,,,,,,,,,,,,,,,,
Credits,MNU_CREDITS,,,,,,,,,,,,,,,,,,,,,, Credits,MNU_CREDITS,,,,,,,,,,,,,,,,,,,,,,
Cool Stuff,MNU_COOLSTUFF,,,,,Cooles Zeug,,,,,,,,,,,,,,,,, Cool Stuff,MNU_COOLSTUFF,,,,,Cooles Zeug,,,,,,,,,,,,,,,,,
Multiplayer,MNU_MULTIPLAYER,,,,,Mehrspieler,,,,,,,,,,,,,,,,, Multiplayer,MNU_MULTIPLAYER,,,,,Mehrspieler,,,,,,,,,,,,,,,,,
End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,, End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,,
User Map,MNU_USERMAP,,,,,Benutzerlevel,,,,,,,,,,,,,,,,,
Select a user map to play,MNU_SELECTUSERMAP,,,,,"Wähle ein Level zum Spielen
",,,,,,,,,,,,,,,,,
Select an Episode,MNU_SELECTEPISODE,,,,,"Welche Episode?
",,,,,,,,,,,,,,,,,
Select Skill,MNU_SELECTSKILL,,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,,
1 default Identifier Remarks Filter eng enc ena enz eni ens enj enb enl ent enw cs de el eo es esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu fi fr hu it jp ko nl pl pt ptg ro ru sr
10 Credits MNU_CREDITS
11 Cool Stuff MNU_COOLSTUFF Cooles Zeug
12 Multiplayer MNU_MULTIPLAYER Mehrspieler
13 End Game MNU_ENDGAME Spiel beenden
14 User Map MNU_USERMAP Benutzerlevel
15 Select a user map to play MNU_SELECTUSERMAP Wähle ein Level zum Spielen
16 Select an Episode MNU_SELECTEPISODE Welche Episode?
17 Select Skill MNU_SELECTSKILL Schwierigkeitsgrad
18
19

View file

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------
// //
// Text only variant of the main menu for Doom, Strife and Chex Quest to be used with localized content. //
// //
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------
@ -20,7 +20,7 @@ LISTMENU "MainMenu"
centermenu centermenu
} }
class "Duke.MainMenu" class "Duke.MainMenu"
NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu"
//NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation)
ifgame(fury) ifgame(fury)
{ {
@ -37,8 +37,7 @@ LISTMENU "MainMenu"
} }
ifgame(Redneck, RedneckRides) ifgame(Redneck, RedneckRides)
{ {
linespacing 15 NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu"
NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
//NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation)
NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu"
@ -48,8 +47,7 @@ LISTMENU "MainMenu"
} }
ifgame(Blood) ifgame(Blood)
{ {
linespacing 15 NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu"
NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu"
NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu"
NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
@ -59,8 +57,7 @@ LISTMENU "MainMenu"
} }
ifgame(ShadowWarrior) ifgame(ShadowWarrior)
{ {
linespacing 15 NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu"
NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu"
NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu"
@ -87,7 +84,7 @@ LISTMENU "IngameMenu"
} }
linespacing 15 linespacing 15
class "Duke.MainMenu" class "Duke.MainMenu"
NativeTextItem "$MNU_NEWGAME", "n", "CustomGameMenu" NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu"
NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu"
NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu"
@ -131,68 +128,100 @@ LISTMENU "IngameMenu"
LISTMENU "EpisodeMenu" LISTMENU "EpisodeMenu"
{ {
ScriptId 100 ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu.
// Episode names filled in programmatically
//Spacer
/*
NativeTextItem "$MNU_USERMAP", "u", "UserMap"
ifgame(ShadowWarrior)
{ {
NativeStaticTextItem "$MNU_SELECTUSERMAP" caption "$MNU_SELECTEPISODE"
position 160, 48, 142
centermenu
fixedspacing 5
class "Duke.ListMenu"
} }
*/
ScriptId 100
} }
LISTMENU "SkillMenu" LISTMENU "SkillMenu"
{ {
NativeTextItem "1", "", "StartGame", 1 ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu.
{
caption "$MNU_SELECTSKILL"
position 160, 55, 135
centermenu
fixedspacing 5
class "Duke.ListMenu"
}
ScriptId 110
} }
LISTMENU "CustomGameMenu" LISTMENU "CustomGameMenu"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 102 ScriptId 102
// Filled in programmatically
//NativeTextItem "1", "", "CustomSubMenu1"
} }
LISTMENU "CustomSubMenu1" LISTMENU "CustomSubMenu1"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu"
} }
LISTMENU "CustomSubMenu2" LISTMENU "CustomSubMenu2"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu"
} }
LISTMENU "CustomSubMenu3" LISTMENU "CustomSubMenu3"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu"
} }
LISTMENU "CustomSubMenu4" LISTMENU "CustomSubMenu4"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu"
} }
LISTMENU "CustomSubMenu5" LISTMENU "CustomSubMenu5"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu"
} }
LISTMENU "CustomSubMenu6" LISTMENU "CustomSubMenu6"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu"
} }
LISTMENU "CustomSubMenu7" LISTMENU "CustomSubMenu7"
{ {
position 160, 48, 142
centermenu
fixedspacing 5
ScriptId 103 ScriptId 103
//NativeTextItem "1", "", "SkillMenu" }
LISTMENU "MultiMenu"
{
Caption "$MNU_NETWORKGAME"
NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu"
NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu"
NativeTextItem "$MNU_HOSTGAME", "h", "HostGameMenu"
} }