- more work on the menu.

Duke Nukem's menu title is getting rendered.
This commit is contained in:
Christoph Oelckers 2019-11-22 22:52:11 +01:00
parent 5f9b57519a
commit ceb07280cf
20 changed files with 302 additions and 108 deletions

View file

@ -37,6 +37,8 @@
#include "dobject.h"
#if 0
PClass DObject::_StaticType;
ClassReg DObject::RegistrationInfo =
{
@ -71,3 +73,4 @@ DObject::~DObject ()
void DObject::Destroy ()
{
}
#endif

View file

@ -34,6 +34,8 @@
#ifndef __DOBJECT_H__
#define __DOBJECT_H__
#if 0
#include <stdlib.h>
struct PClass;
@ -176,4 +178,5 @@ inline bool DObject::IsA (const PClass *type)
return (type == GetClass());
}
#endif
#endif //__DOBJECT_H__

View file

@ -38,6 +38,7 @@
#include "templates.h"
#include "autosegs.h"
#include "tarray.h"
#if 0
static TArray<PClass *> Types;
static TMap<FName, PClass *> Map;
@ -102,3 +103,4 @@ DObject *PClass::CreateNew () const
((DObject *)mem)->SetClass (const_cast<PClass *>(this));
return (DObject *)mem;
}
#endif

View file

@ -226,10 +226,8 @@ public:
class DJoystickConfigMenu : public DOptionMenu
{
DECLARE_CLASS(DJoystickConfigMenu, DOptionMenu)
};
IMPLEMENT_CLASS(DJoystickConfigMenu)
//=============================================================================
//

View file

@ -40,8 +40,6 @@
#include "menu.h"
#include "v_draw.h"
IMPLEMENT_CLASS(DListMenu)
//=============================================================================
//
//
@ -253,12 +251,14 @@ void DListMenu::Ticker ()
void DListMenu::Drawer ()
{
PreDraw();
for(unsigned i=0;i<mDesc->mItems.Size(); i++)
{
if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(mDesc->mSelectedItem == (int)i);
}
if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size())
mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector);
PostDraw();
Super::Drawer();
}

View file

@ -48,7 +48,7 @@
class DLoadSaveMenu : public DListMenu
{
DECLARE_CLASS(DLoadSaveMenu, DListMenu)
using Super = DListMenu;
friend void ClearSaveGames();
protected:
@ -109,8 +109,6 @@ public:
};
IMPLEMENT_CLASS(DLoadSaveMenu)
TArray<FSaveGameNode*> DLoadSaveMenu::SaveGames;
int DLoadSaveMenu::LastSaved = -1;
int DLoadSaveMenu::LastAccessed = -1;
@ -723,8 +721,7 @@ bool DLoadSaveMenu::Responder (event_t *ev)
class DSaveMenu : public DLoadSaveMenu
{
DECLARE_CLASS(DSaveMenu, DLoadSaveMenu)
using Super = DLoadSaveMenu;
FSaveGameNode NewSaveNode;
public:
@ -737,9 +734,6 @@ public:
};
IMPLEMENT_CLASS(DSaveMenu)
//=============================================================================
//
//
@ -895,7 +889,7 @@ bool DSaveMenu::Responder (event_t *ev)
class DLoadMenu : public DLoadSaveMenu
{
DECLARE_CLASS(DLoadMenu, DLoadSaveMenu)
using Super = DLoadSaveMenu;
public:
@ -904,9 +898,6 @@ public:
bool MenuEvent (int mkey, bool fromcontroller);
};
IMPLEMENT_CLASS(DLoadMenu)
//=============================================================================
//
//

View file

@ -49,6 +49,9 @@
#include "v_draw.h"
#include "gamecontrol.h"
void RegisterDukeMenus();
extern bool rotatesprite_2doverride;
//
// Todo: Move these elsewhere
//
@ -60,6 +63,8 @@ CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE)
CVAR(Int, m_use_mouse, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
TArray<MenuClassDescriptor*> menuClasses(TArray<MenuClassDescriptor*>::ENoInit(0));
DMenu *DMenu::CurrentMenu;
int DMenu::MenuTime;
@ -83,7 +88,6 @@ static bool MenuEnabled = true;
//
//============================================================================
IMPLEMENT_CLASS (DMenu)
DMenu::DMenu(DMenu *parent)
{
@ -164,6 +168,7 @@ void DMenu::Close ()
assert(DMenu::CurrentMenu == this);
DMenu::CurrentMenu = mParentMenu;
Destroy();
delete this;
if (DMenu::CurrentMenu == NULL)
{
M_ClearMenus ();
@ -417,9 +422,23 @@ void M_SetMenu(FName menu, int param)
}
else
{
//const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass;
DListMenu* newmenu = new DListMenu;
DListMenu* newmenu;
if (ld->mClass != NAME_None)
{
auto ndx = menuClasses.FindEx([=](const auto p) { return p->mName == ld->mClass; });
if (ndx == menuClasses.Size())
{
I_Error("Bad menu class %s\n", ld->mClass.GetChars());
}
else
{
newmenu = (DListMenu*)menuClasses[ndx]->CreateNew();
}
}
else
{
newmenu = new DListMenu;
}
newmenu->Init(DMenu::CurrentMenu, ld);
M_ActivateMenu(newmenu);
}
@ -437,6 +456,7 @@ void M_SetMenu(FName menu, int param)
}
else
{
/*
const PClass *menuclass = PClass::FindClass(menu);
if (menuclass != NULL)
{
@ -448,6 +468,7 @@ void M_SetMenu(FName menu, int param)
return;
}
}
*/
}
Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars());
}
@ -687,6 +708,7 @@ void M_Ticker (void)
void M_Drawer (void)
{
rotatesprite_2doverride = true;
PalEntry fade = 0x70000000;
#if 0
player_t *player = &players[consoleplayer];
@ -705,9 +727,11 @@ void M_Drawer (void)
if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off)
{
DMenu::CurrentMenu->origin = { 0,0 };
if (DMenu::CurrentMenu->DimAllowed() && fade) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade);
DMenu::CurrentMenu->Drawer();
}
rotatesprite_2doverride = false;
}
//=============================================================================
@ -722,6 +746,7 @@ void M_ClearMenus ()
if (DMenu::CurrentMenu != NULL)
{
DMenu::CurrentMenu->Destroy();
delete DMenu::CurrentMenu;
DMenu::CurrentMenu = NULL;
}
menuactive = MENU_Off;
@ -736,6 +761,7 @@ void M_ClearMenus ()
void M_Init (void)
{
RegisterDukeMenus();
timerSetCallback(M_Ticker);
M_ParseMenuDefs();
M_CreateMenus();

View file

@ -4,7 +4,6 @@
#include "dobject.h"
#include "c_cvars.h"
#include "v_font.h"
#include "version.h"
@ -107,6 +106,7 @@ class FOptionMenuItem;
struct FListMenuDescriptor : public FMenuDescriptor
{
TDeletingArray<FListMenuItem *> mItems;
FString mCaption;
int mSelectedItem;
int mSelectOfsX;
int mSelectOfsY;
@ -116,6 +116,8 @@ struct FListMenuDescriptor : public FMenuDescriptor
int mWLeft, mWRight;
int mLinespacing; // needs to be stored for dynamically created menus
int mAutoselect; // this can only be set by internal menu creation functions
int mScriptId;
int mSecondaryId;
FFont *mFont;
EColorRange mFontColor;
EColorRange mFontColor2;
@ -136,6 +138,8 @@ struct FListMenuDescriptor : public FMenuDescriptor
mFont = NULL;
mFontColor = CR_UNTRANSLATED;
mFontColor2 = CR_UNTRANSLATED;
mScriptId = 0;
mSecondaryId = 0;
}
};
@ -211,10 +215,8 @@ struct FMenuRect
};
class DMenu : public DObject
class DMenu
{
DECLARE_CLASS (DMenu, DObject)
protected:
bool mMouseCapture;
bool mBackbuttonSelected;
@ -236,19 +238,24 @@ public:
static int MenuTime;
DMenu *mParentMenu;
vec2_t origin;
DMenu(DMenu *parent = NULL);
virtual bool Responder (event_t *ev);
virtual bool MenuEvent (int mkey, bool fromcontroller);
virtual void Ticker ();
virtual void PreDraw() {}
virtual void PostDraw() {}
virtual void Drawer ();
virtual bool DimAllowed ();
virtual bool TranslateKeyboardEvents();
virtual void Close();
virtual bool MouseEvent(int type, int x, int y);
virtual void Destroy() {}
bool MouseEventBack(int type, int x, int y);
void SetCapture();
void ReleaseCapture();
void SetOrigin();
bool HasCapture()
{
return mMouseCapture;
@ -427,8 +434,7 @@ public:
class DListMenu : public DMenu
{
DECLARE_CLASS(DListMenu, DMenu)
typedef DMenu Super;
protected:
FListMenuDescriptor *mDesc = nullptr;
FListMenuItem *mFocusControl = nullptr;
@ -516,8 +522,7 @@ extern FOptionMap OptionValues;
class DOptionMenu : public DMenu
{
DECLARE_CLASS(DOptionMenu, DMenu)
using Super = DMenu;
bool CanScrollUp;
bool CanScrollDown;
int VisBottom;
@ -560,8 +565,7 @@ public:
class DTextEnterMenu : public DMenu
{
DECLARE_ABSTRACT_CLASS(DTextEnterMenu, DMenu)
using Super = DMenu;
TArray<char> mEnterString;
FString* mOutString;
unsigned int mEnterSize;
@ -611,5 +615,28 @@ void M_StartMessage(const char *message, int messagemode, FName action = NAME_No
void I_SetMouseCapture();
void I_ReleaseMouseCapture();
struct MenuClassDescriptor;
extern TArray<MenuClassDescriptor*> menuClasses;
struct MenuClassDescriptor
{
FName mName;
MenuClassDescriptor(const char* name) : mName(name)
{
//menuClasses.Push(this);
}
virtual DMenu* CreateNew() = 0;
};
template<class Menu> struct TMenuClassDescriptor : public MenuClassDescriptor
{
TMenuClassDescriptor(const char* name) : MenuClassDescriptor(name)
{}
DMenu* CreateNew()
{
return new Menu;
}
};
#endif

View file

@ -133,7 +133,7 @@ struct gamefilter
static const gamefilter games[] = {
{ "Duke", GAMEFLAG_DUKE},
{ "Nam", GAMEFLAG_NAM},
{ "Nam", GAMEFLAG_NAM|GAMEFLAG_NAPALM},
{ "WW2GI", GAMEFLAG_WW2GI},
{ "Fury", GAMEFLAG_FURY},
{ "Redneck", GAMEFLAG_RR},
@ -294,6 +294,16 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered);
desc->mItems.Push(it);
}
else if (sc.Compare("ScriptId"))
{
sc.MustGetNumber();
desc->mScriptId = sc.Number;
}
else if (sc.Compare("Caption"))
{
sc.MustGetString();
desc->mCaption = sc.String;
}
else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered"))
{
bool centered = sc.Compare("StaticTextCentered");

View file

@ -41,8 +41,6 @@
#include "v_text.h"
#include "v_draw.h"
IMPLEMENT_ABSTRACT_CLASS(DTextEnterMenu)
#define INPUTGRID_WIDTH 13
#define INPUTGRID_HEIGHT 5

View file

@ -46,8 +46,7 @@ extern FSaveGameNode *quickSaveSlot;
class DMessageBoxMenu : public DMenu
{
DECLARE_CLASS(DMessageBoxMenu, DMenu)
using Super = DMenu;
TArray<FBrokenLines> mMessage;
int mMessageMode;
int messageSelection;
@ -67,7 +66,6 @@ public:
virtual void HandleResult(bool res);
};
IMPLEMENT_CLASS(DMessageBoxMenu)
//=============================================================================
//

View file

@ -62,7 +62,6 @@ void M_DrawConText (int color, int x, int y, const char *str)
}
IMPLEMENT_CLASS(DOptionMenu)
//=============================================================================
//

View file

@ -322,8 +322,6 @@ public:
class DEnterKey : public DMenu
{
DECLARE_CLASS(DEnterKey, DMenu)
int *pKey;
public:
@ -342,6 +340,7 @@ public:
void SetMenuMessage(int which)
{
/*
if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu)))
{
DOptionMenu *m = static_cast<DOptionMenu*>(mParentMenu);
@ -351,6 +350,7 @@ public:
it->SetValue(0, which);
}
}
*/
}
bool Responder(event_t *ev)
@ -373,10 +373,6 @@ public:
}
};
#ifndef NO_IMP
IMPLEMENT_ABSTRACT_CLASS(DEnterKey)
#endif
//=============================================================================
//
// // Edit a key binding, Action is the CCMD to bind

View file

@ -41,7 +41,6 @@
class DReadThisMenu : public DMenu
{
DECLARE_CLASS(DReadThisMenu, DMenu)
int mScreen;
int mInfoTic;
@ -54,7 +53,6 @@ public:
bool MouseEvent(int type, int x, int y);
};
IMPLEMENT_CLASS(DReadThisMenu)
//=============================================================================
//

View file

@ -62,6 +62,7 @@ set( PCH_SOURCES
src/sector.cpp
src/sounds.cpp
src/soundsdyn.cpp
src/d_menu.cpp
)
if( MSVC )

View file

@ -0,0 +1,146 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
Copyright (C) 2019 Christoph Oelckers
This is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "cheats.h"
#include "compat.h"
#include "demo.h"
#include "duke3d.h"
#include "input.h"
#include "menus.h"
#include "osdcmds.h"
#include "savegame.h"
#include "game.h"
#include "superfasthash.h"
#include "gamecvars.h"
#include "gamecontrol.h"
#include "c_bind.h"
#include "menu/menu.h"
#include "../../glbackend/glbackend.h"
BEGIN_DUKE_NS
#define MENU_MARGIN_REGULAR 40
#define MENU_MARGIN_WIDE 32
#define MENU_MARGIN_CENTER 160
#define MENU_HEIGHT_CENTER 100
static void Menu_DrawTopBar(const vec2_t origin)
{
if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0)
rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10);
}
static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin)
{
static char t[64];
size_t const srclen = strlen(caption);
size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1);
memcpy(t, caption, dstlen);
t[dstlen] = '\0';
char *p = &t[dstlen-1];
if (*p == ':')
*p = '\0';
captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t);
}
class DukeListMenu : public DListMenu
{
using Super = DListMenu;
protected:
virtual void CallScript(int event, bool getorigin = false)
{
ud.returnvar[0] = origin.x;
ud.returnvar[1] = origin.y;
ud.returnvar[2] = mDesc->mSelectedItem;
VM_OnEventWithReturn(event, g_player[screenpeek].ps->i, screenpeek, mDesc->mScriptId);
if (getorigin)
{
origin.x = ud.returnvar[0];
origin.y = ud.returnvar[1];
}
}
void PreDraw() override
{
CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true);
}
void PostDraw() override
{
CallScript(CurrentMenu == this ? EVENT_DISPLAYMENUREST : EVENT_DISPLAYINACTIVEMENUREST, false);
}
void Drawer() override
{
auto v = origin;
Super::Drawer();
origin = v;
}
};
class DukeNewGameCustomSubMenu : public DukeListMenu
{
virtual void CallScript(int event, bool getorigin) override
{
// This needs to get the secondary ID to the script.
ud.returnvar[3] = mDesc->mSecondaryId;
DukeListMenu::CallScript(event, getorigin);
}
};
class MainMenu : public DukeListMenu
{
void PreDraw() override
{
DukeListMenu::PreDraw();
if ((G_GetLogoFlags() & LOGO_NOGAMETITLE) == 0)
{
rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10);
if (PLUTOPAK) // JBF 20030804
rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER+100)<<16), origin.y + (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);
}
}
};
END_DUKE_NS
static TMenuClassDescriptor<Duke::MainMenu> _mm("Duke.MainMenu");
static TMenuClassDescriptor<Duke::DukeListMenu> _lm("Duke.ListMenu");
static TMenuClassDescriptor<Duke::DukeNewGameCustomSubMenu> _ngcsm("Duke.NewGameCustomSubMenu");
void RegisterDukeMenus()
{
menuClasses.Push(&_mm);
menuClasses.Push(&_lm);
menuClasses.Push(&_ngcsm);
}

View file

@ -118,32 +118,12 @@ void A_DeleteSprite(int spriteNum);
static inline int32_t G_GetLogoFlags(void)
{
#if !defined LUNATIC
return Gv_GetVarByLabel("LOGO_FLAGS",255, -1, -1);
#else
extern int32_t g_logoFlags;
return g_logoFlags;
#endif
}
#ifdef LUNATIC
typedef struct {
vec3_t pos;
int32_t dist, clock;
fix16_t q16horiz, q16ang;
int16_t sect;
} camera_t;
extern camera_t g_camera;
# define CAMERA(Membname) (g_camera.Membname)
# define CAMERADIST (g_camera.dist)
# define CAMERACLOCK (g_camera.clock)
#else
# define CAMERA(Membname) (ud.camera ## Membname)
# define CAMERADIST g_cameraDistance
# define CAMERACLOCK g_cameraClock
#endif
#endif
@ -155,9 +135,7 @@ extern camera_t g_camera;
#define MAX_RETURN_VALUES 6
typedef struct {
#if !defined LUNATIC
vec3_t camerapos;
#endif
int32_t const_visibility,uw_framerate;
int32_t camera_time,folfvel,folavel,folx,foly,fola;
int32_t reccnt;
@ -188,10 +166,8 @@ typedef struct {
uint32_t userbytever;
#if !defined LUNATIC
fix16_t cameraq16ang, cameraq16horiz;
int16_t camerasect;
#endif
int16_t pause_on,from_bonus;
int16_t camerasprite,last_camsprite;
int16_t last_level,secretlevel;

View file

@ -1603,15 +1603,12 @@ void Menu_Init(void)
MEOS_NETOPTIONS_LEVEL[i].optionNames = MEOSN_NetLevels[i];
}
M_EPISODE.numEntries = g_volumeCnt+2;
#ifndef EDUKE32_SIMPLE_MENU
MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont;
MEL_EPISODE[g_volumeCnt+1] = &ME_EPISODE_USERMAP;
MEOSN_NetEpisodes[k] = MenuUserMap;
MEOSV_NetEpisodes[k] = MAXVOLUMES;
#else
M_EPISODE.numEntries = g_volumeCnt;
k--;
#endif
MEOS_NETOPTIONS_EPISODE.numOptions = k + 1;
NetEpisode = MEOSV_NetEpisodes[0];
MMF_Top_Episode.pos.y = (58 + (3-k)*6)<<16;

View file

@ -129,6 +129,8 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
// This just gets forwarded to the original drawer. Long term this should not survive and all calls be refactored.
UseColorOnly(false);
SetFadeDisable(false);
SetVertexBuffer(nullptr, 0, 0);
SetIndexBuffer(nullptr);
polymost_dorotatesprite(cmd.mVertIndex, cmd.mVertCount, cmd.mIndexIndex, cmd.mIndexCount, cmd.mSpecialColormap[0].d, cmd.mRemapIndex, cmd.mFlags, cmd.mSpecialColormap[1].d,
cmd.mDesaturate, cmd.mColor1.d, cmd.mScissor[0], cmd.mScissor[1], cmd.mScissor[2], cmd.mScissor[3], 0);
// Reset everything to the default.
@ -138,6 +140,8 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
EnableBlend(true);
EnableAlphaTest(true);
SetBlendFunc(STYLEALPHA_Src, STYLEALPHA_InvSrc);
SetVertexBuffer(vb.GetBufferObjects().first, 0, 0);
SetIndexBuffer(vb.GetBufferObjects().second);
continue;
}

View file

@ -6,17 +6,38 @@
LISTMENU "MainMenu"
{
ifgame(Duke, Nam, WW2GI, Fury)
{
linespacing 15
class "Duke.MainMenu"
TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
//TextItem "$MNU_MULTIPLAYER", "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)
{
TextItem "$MNU_CONTINUE", "l", "LoadGameMenu"
}
else
{
TextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
}
TextItem "$MNU_OPTIONS", "o", "OptionsMenu"
TextItem "$MNU_HELP", "h", "HelpMenu"
TextItem "$MNU_CREDITS", "c", "CreditsMenu"
TextItem "$MNU_QUITGAME", "q", "QuitMenu"
}
ifgame(Redneck, RedneckRides)
{
linespacing 15
TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
//TextItem "$MNU_MULTIPLAYER", "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)
TextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
TextItem "$MNU_OPTIONS", "o", "OptionsMenu"
TextItem "$MNU_HELP", "h", "HelpMenu"
TextItem "$MNU_CREDITS", "c", "CreditsMenu"
TextItem "$MNU_QUITGAME", "q", "QuitMenu"
}
LISTMENU "MainMenu_Blood"
{
}
ifgame(Blood)
{
linespacing 15
TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu"
@ -25,10 +46,9 @@ LISTMENU "MainMenu_Blood"
TextItem "$MNU_HELP", "h", "HelpMenu"
TextItem "$MNU_CREDITS", "c", "CreditsMenu"
TextItem "$MNU_QUITGAME", "q", "QuitMenu"
}
LISTMENU "MainMenu_SW"
{
}
ifgame(ShadowWarrior)
{
linespacing 15
TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu"
TextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
@ -36,5 +56,6 @@ LISTMENU "MainMenu_SW"
TextItem "$MNU_OPTIONS", "o", "OptionsMenu"
TextItem "$MNU_COOLSTUFF", "h", "HelpMenu"
TextItem "$MNU_QUITGAME", "q", "QuitMenu"
}
}