- got the basics working for Exhumed's main menu.

This commit is contained in:
Christoph Oelckers 2020-10-08 00:21:07 +02:00
parent a953404331
commit 56eae0b42d
11 changed files with 156 additions and 158 deletions

View file

@ -1097,3 +1097,6 @@ xy(menu_clear, "menu/clear")
xy(menu_dismiss, "menu/dismiss") xy(menu_dismiss, "menu/dismiss")
xy(menu_change, "menu/change") xy(menu_change, "menu/change")
xy(menu_advance, "menu/advance") xy(menu_advance, "menu/advance")
xx(zoomsize)

View file

@ -1796,27 +1796,6 @@ void playerProcessHelpers(fixed_t* q16ang, double* angAdjust, fixed_t* angTarget
} }
} }
void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg)
{
double scale = SmallFontScale();
int formatwidth = int(320 / scale);
auto lines = V_BreakLines(SmallFont, formatwidth, text, true);
auto fheight = bg ? 10 : SmallFont->GetHeight() * scale; // Fixme: Get spacing for text pages from elsewhere.
if (!bg)
{
auto totaltextheight = lines.Size() * fheight;
position -= totaltextheight / 2;
}
double y = origin.Y + position;
for (auto& line : lines)
{
double x = origin.X + 160 - line.Width * scale * 0.5;
DrawText(twod, SmallFont, CR_UNTRANSLATED, x, y, line.Text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE);
y += fheight;
}
}
bool M_Active() bool M_Active()
{ {
return CurrentMenu != nullptr || ConsoleState == c_down || ConsoleState == c_falling; return CurrentMenu != nullptr || ConsoleState == c_down || ConsoleState == c_falling;

View file

@ -56,7 +56,6 @@ struct GameInterface
virtual void FreeGameData() {} virtual void FreeGameData() {}
virtual void PlayHudSound() {} virtual void PlayHudSound() {}
virtual GameStats getStats() { return {}; } virtual GameStats getStats() { return {}; }
virtual void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) {}
virtual void MainMenuOpened() {} virtual void MainMenuOpened() {}
virtual void MenuOpened() {} virtual void MenuOpened() {}
virtual void MenuClosed() {} virtual void MenuClosed() {}
@ -66,7 +65,6 @@ struct GameInterface
virtual bool StartGame(FNewGameStartup& gs) { return false; } virtual bool StartGame(FNewGameStartup& gs) { return false; }
virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; }
virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; }
virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool withbg = true);
virtual double SmallFontScale() { return 1; } virtual double SmallFontScale() { return 1; }
virtual bool SaveGame() { return true; } virtual bool SaveGame() { return true; }
virtual bool LoadGame() { return true; } virtual bool LoadGame() { return true; }

View file

@ -31,109 +31,34 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mapinfo.h" #include "mapinfo.h"
#include "gamecontrol.h" #include "gamecontrol.h"
#include "v_draw.h" #include "v_draw.h"
#include "vm.h"
#include "razemenu.h"
#include "razemenu.h" // to override the local menu.h
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
BEGIN_PS_NS BEGIN_PS_NS
//----------------------------------------------------------------------------
//
// Implements the native looking menu used for the main menu
// and the episode/skill selection screens, i.e. the parts
// that need to look authentic
//
//----------------------------------------------------------------------------
void menu_DoPlasma();
double zoomsize = 0;
#if 0 DEFINE_ACTION_FUNCTION(_ListMenuItemExhumedPlasma, Draw)
class PSMainMenu : public DListMenu
{ {
void Init(DMenu* parent, FListMenuDescriptor* desc) override
{
DListMenu::Init(parent, desc);
PlayLocalSound(StaticSound[kSound31], 0, false, CHANF_UI);
}
void Ticker() override
{
// handle the menu zoom-in
if (zoomsize < 1.)
{
zoomsize += 0.0625;
if (zoomsize >= 1.) {
zoomsize = 1.;
}
}
}
void PreDraw() override
{
if (mDesc->mMenuName == NAME_Mainmenu)
menu_DoPlasma(); menu_DoPlasma();
else return 0;
{ }
DEFINE_ACTION_FUNCTION(_ListMenuItemExhumedLogo, Draw)
{
auto nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo; auto nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo;
DrawRel(nLogoTile, 160, 40); DrawRel(nLogoTile, 160, 40);
} return 0;
}
};
#endif
//----------------------------------------------------------------------------
//
// Menu related game interface functions
//
//----------------------------------------------------------------------------
void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags)
{
#if 0
int tilenum = (int)strtoll(text, nullptr, 0);
double y = ypos - tilesiz[tilenum].y / 2;
int8_t shade;
if (state == NIT_SelectedState)
{ // currently selected menu item
shade = Sin(I_GetBuildTime() << 4) >> 9;
}
else if (state == NIT_ActiveState) {
shade = 0;
}
else {
shade = 25;
}
// Todo: Replace the boxes with an empty one and draw the text with a font.
auto tex = tileGetTexture(tilenum);
DrawTexture(twod, tex, 160, y + tex->GetDisplayHeight(), DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffset, true, DTA_ScaleX, zoomsize, DTA_ScaleY, zoomsize,
DTA_Color, shadeToLight(shade), TAG_DONE);
// tilesizx is 51
// tilesizy is 33
if (state == NIT_SelectedState)
{
tex = tileGetTexture(kMenuCursorTile);
DrawTexture(twod, tex, 62, ypos - 12, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, TAG_DONE);
DrawTexture(twod, tex, 207, ypos - 12, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, DTA_FlipX, true, TAG_DONE);
}
#endif
} }
void GameInterface::MenuOpened() void GameInterface::MenuOpened()
{ {
GrabPalette(); GrabPalette();
zoomsize = 0; menuDelegate->FloatVar(NAME_zoomsize) = 0;
StopAllSounds(); StopAllSounds();
StopLocalSound(); StopLocalSound();
} }
@ -142,6 +67,10 @@ void GameInterface::MenuSound(EMenuSounds snd)
{ {
switch (snd) switch (snd)
{ {
case ActivateSound:
PlayLocalSound(StaticSound[kSound31], 0, false, CHANF_UI);
break;
case CursorSound: case CursorSound:
PlayLocalSound(StaticSound[kSound35], 0, false, CHANF_UI); PlayLocalSound(StaticSound[kSound35], 0, false, CHANF_UI);
break; break;

View file

@ -237,7 +237,6 @@ struct GameInterface : ::GameInterface
void app_init() override; void app_init() override;
void clearlocalinputstate() override; void clearlocalinputstate() override;
bool GenerateSavePic() override; bool GenerateSavePic() override;
void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override;
void MenuOpened() override; void MenuOpened() override;
void MenuSound(EMenuSounds snd) override; void MenuSound(EMenuSounds snd) override;
void MenuClosed() override; void MenuClosed() override;

View file

@ -157,16 +157,6 @@ FSavegameInfo GameInterface::GetSaveSig()
return { SAVESIG_DN3D, MINSAVEVER_DN3D, SAVEVER_DN3D }; return { SAVESIG_DN3D, MINSAVEVER_DN3D, SAVEVER_DN3D };
} }
void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg)
{
if (bg) Menu_DrawBackground(origin);
else if (!isRR())
{
//Menu_DrawCursor(160, 130, 1, false);
}
::GameInterface::DrawCenteredTextScreen(origin, text, position, bg);
}
void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam)
{ {
int mclock = I_GetBuildTime(); int mclock = I_GetBuildTime();

View file

@ -42,7 +42,6 @@ struct GameInterface : public ::GameInterface
bool CanSave() override; bool CanSave() override;
bool StartGame(FNewGameStartup& gs) override; bool StartGame(FNewGameStartup& gs) override;
FSavegameInfo GetSaveSig() override; FSavegameInfo GetSaveSig() override;
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override;
double SmallFontScale() override { return isRR() ? 0.5 : 1.; } double SmallFontScale() override { return isRR() ? 0.5 : 1.; }
void SerializeGameState(FSerializer& arc) override; void SerializeGameState(FSerializer& arc) override;
void QuitToTitle() override; void QuitToTitle() override;

View file

@ -56,16 +56,15 @@ LISTMENU "MainMenu"
} }
ifgame(Exhumed) ifgame(Exhumed)
{ {
/* class ExhumedMainMenu
Position 160, 65 Position 160, 65
centermenu
linespacing 22 linespacing 22
NativeTextItem "3460", "n", "StartGameNoSkill", 1 ExhumedPlasma
NativeTextItem "3461", "l", "LoadGameMenu" ExhumedTextItem "$MNU_NEWGAME", "n", "StartGameNoSkill", 1
NativeTextItem "3462", "m", "StartGameNoSkill", 0 ExhumedTextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
NativeTextItem "3463", "v", "OptionsMenu" ExhumedTextItem "$TXT_EX_MAP00", "m", "StartGameSkill", 0
NativeTextItem "3464", "q", "QuitMenu" ExhumedTextItem "$MNU_OPTIONS", "v", "OptionsMenu"
*/ ExhumedTextItem "$MNU_QUITGAME", "q", "QuitMenu"
} }
} }
@ -126,19 +125,18 @@ LISTMENU "IngameMenu"
} }
SWTextItem "$MNU_QUITGAME", "q", "QuitMenu" SWTextItem "$MNU_QUITGAME", "q", "QuitMenu"
} }
/*
ifgame(Exhumed) ifgame(Exhumed)
{ {
class ExhumedMainMenu
Position 160, 65 Position 160, 65
centermenu
linespacing 22 linespacing 22
NativeTextItem "3460", "n", "StartGame", 1 ExhumedLogo
NativeTextItem "3461", "l", "LoadGameMenu" ExhumedTextItem "$MNU_NEWGAME", "n", "StartGameNoSkill", 1
NativeTextItem "3462", "m", "StartGame", 0 ExhumedTextItem "$MNU_LOADGAME", "l", "LoadGameMenu"
NativeTextItem "3463", "v", "OptionsMenu" ExhumedTextItem "$TXT_EX_MAP00", "m", "StartGameSkill", 0
NativeTextItem "3464", "q", "QuitMenu" ExhumedTextItem "$MNU_OPTIONS", "v", "OptionsMenu"
ExhumedTextItem "$MNU_QUITGAME", "q", "QuitMenu"
} }
*/
} }
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------

View file

@ -25,11 +25,6 @@ class DukeMenuDelegate : RazeMenuDelegate
return int((y+h) * fh / 200); // This must be the covered height of the header in true pixels. return int((y+h) * fh / 200); // This must be the covered height of the header in true pixels.
} }
static int calcSinTableValue(int ang)
{
return int(16384 * sin((360./2048) * ang));
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
// //
@ -43,7 +38,7 @@ class DukeMenuDelegate : RazeMenuDelegate
String picname; String picname;
if (!right) picname= String.Format("SPINNINGNUKEICON%d", ((mclock >> 3) % frames)); if (!right) picname= String.Format("SPINNINGNUKEICON%d", ((mclock >> 3) % frames));
else picname = String.Format("SPINNINGNUKEICON%d", frames - 1 - ((frames - 1 + (mclock >> 3)) % frames)); else picname = String.Format("SPINNINGNUKEICON%d", frames - 1 - ((frames - 1 + (mclock >> 3)) % frames));
int light = 231 + (calcSinTableValue(mclock<<5) / 768.); int light = 231 + (Build.calcSinTableValue(mclock<<5) / 768.);
let pe = color(255, light, light, light); let pe = color(255, light, light, light);
Screen.DrawTexture(TexMan.CheckForTexture(picname), false, x, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_Color, pe, DTA_CenterOffsetRel, true); Screen.DrawTexture(TexMan.CheckForTexture(picname), false, x, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_Color, pe, DTA_CenterOffsetRel, true);
} }
@ -90,7 +85,7 @@ class ListMenuItemDukeLogo : ListMenuItem
if (gameinfo.gametype & GAMEFLAG_PLUTOPAK) if (gameinfo.gametype & GAMEFLAG_PLUTOPAK)
{ {
int mclock = MSTime() * 120 / 1000; int mclock = MSTime() * 120 / 1000;
int light = 223 + (DukeMenuDelegate.calcSinTableValue(mclock<<4) / 512.); int light = 223 + (Build.calcSinTableValue(mclock<<4) / 512.);
let pe = Color(255, light, light, light); let pe = Color(255, light, light, light);
Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), false, x + 100, 36, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_Color, pe, DTA_CenterOffsetRel, true); Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), false, x + 100, 36, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_Color, pe, DTA_CenterOffsetRel, true);
} }
@ -128,7 +123,7 @@ class ListMenuItemDukeTextItem : ListMenuItemTextItem
if (selected) if (selected)
{ {
int mclock = MSTime() * 120 / 1000; int mclock = MSTime() * 120 / 1000;
int light = 231 + (DukeMenuDelegate.calcSinTableValue(mclock<<5) / 512.); int light = 231 + (Build.calcSinTableValue(mclock<<5) / 512.);
pe = Color(255, light, light, light); pe = Color(255, light, light, light);
} }
else else

View file

@ -1,9 +1,12 @@
class ExhumedMenuDelegate : RazeMenuDelegate class ExhumedMenuDelegate : RazeMenuDelegate
{ {
double zoomsize; // this is the only persistent place where it can be conveniently stored.
override int DrawCaption(String title, Font fnt, int y, bool drawit) override int DrawCaption(String title, Font fnt, int y, bool drawit)
{ {
let font = generic_ui? NewConsoleFont : BigFont; // this ignores the passed font intentionally. let font = generic_ui? NewConsoleFont : BigFont; // this ignores the passed font intentionally.
let cr = generic_ui ? Font.CR_FIRE : Font.CR_UNTRANSLATED; // this ignores the passed font intentionally.
let texid = TexMan.CheckForTexture("MENUBLANK"); let texid = TexMan.CheckForTexture("MENUBLANK");
let texsize = TexMan.GetScaledSize(texid); let texsize = TexMan.GetScaledSize(texid);
let fonth = font.GetGlyphHeight("A"); let fonth = font.GetGlyphHeight("A");
@ -16,7 +19,7 @@ class ExhumedMenuDelegate : RazeMenuDelegate
if (texsize.X - 18 < width) scalex = width / (texsize.X - 18); if (texsize.X - 18 < width) scalex = width / (texsize.X - 18);
screen.DrawTexture(texid, false, 160, 20, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_CenterOffset, true, DTA_ScaleX, scalex); screen.DrawTexture(texid, false, 160, 20, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_CenterOffset, true, DTA_ScaleX, scalex);
} }
screen.DrawText(font, Font.CR_UNTRANSLATED, 160 - width / 2, 20 - fonth / 2, title, DTA_FullscreenScale, FSMode_Fit320x200Top); screen.DrawText(font, cr, 160 - width / 2, 20 - fonth / 2, title, DTA_FullscreenScale, FSMode_Fit320x200Top);
} }
double fx, fy, fw, fh; double fx, fy, fw, fh;
[fx, fy, fw, fh] = Screen.GetFullscreenRect(320, 200, FSMode_ScaleToFit43Top); [fx, fy, fw, fh] = Screen.GetFullscreenRect(320, 200, FSMode_ScaleToFit43Top);
@ -25,3 +28,103 @@ class ExhumedMenuDelegate : RazeMenuDelegate
} }
} }
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
class ListMenuItemExhumedPlasma : ListMenuItem
{
void Init(ListMenuDescriptor desc)
{
Super.Init(0, 0);
}
native override void Draw(bool selected, ListMenuDescriptor desc);
}
class ListMenuItemExhumedLogo : ListMenuItem
{
void Init(ListMenuDescriptor desc)
{
Super.Init(0, 0);
}
native override void Draw(bool selected, ListMenuDescriptor desc);
}
//----------------------------------------------------------------------------
//
// Menu related game interface functions
//
//----------------------------------------------------------------------------
class ListMenuItemExhumedTextItem : ListMenuItemTextItem
{
void Init(ListMenuDescriptor desc, String text, String hotkey, Name child, int param = 0)
{
Super.Init(desc, text, hotkey, child, param);
if (child == 'none') mEnabled = -1;
}
void InitDirect(double x, double y, int height, String hotkey, String text, Font font, int color, int color2, Name child, int param = 0)
{
Super.InitDirect(x, y, height, hotkey, text, font, color, color2, child, param);
}
override void Draw(bool selected, ListMenuDescriptor desc)
{
let font = generic_ui ? NewConsoleFont : BigFont; // this ignores the passed font intentionally.
let cr = generic_ui ? Font.CR_FIRE : Font.CR_UNTRANSLATED; // this ignores the passed font intentionally.
let tex = TexMan.CheckForTexture("MENUBLANK");
let texsize = TexMan.GetScaledSize(tex);
let fonth = font.GetGlyphHeight("A");
int width = font.StringWidth(mText);
let v = TexMan.GetScaledSize(tex);
double y = mYpos + v.y / 2;
int shade;
if (selected) shade = Build.CalcSinTableValue(MSTime() * 16 * 120 / 1000) >> 9;
else if (Selectable()) shade = 0;
else shade = 25;
let color = Build.shadeToLight(shade);
double scalex = 1.; // Squash the text if it is too wide. Due to design limitations we cannot expand the box here. :(
if (texsize.X - 18 < width) scalex = (texsize.X - 18) / width;
screen.DrawTexture(tex, false, 160, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffset, true, DTA_ScaleX, scalex, DTA_Color, color);
screen.DrawText(font, cr, 160 - width / 2, y - fonth / 2, mText, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Color, color);
if (selected)
{
tex = TexMan.CheckForTexture("MENUCURSORTILE");
screen.DrawTexture(tex, false, 62, y - 12, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true);
screen.DrawTexture( tex, false, 207, y - 12, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, DTA_FlipX, true);
}
}
}
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
class ExhumedMainMenu : ListMenu
{
override void Ticker()
{
Super.Ticker();
let delegate = ExhumedMenuDelegate(menuDelegate);
if (!delegate) return;
// handle the menu zoom-in
if (delegate.zoomsize < 1.)
{
delegate.zoomsize += 0.0625;
if (delegate.zoomsize >= 1.)
delegate.zoomsize = 1.;
}
}
}

View file

@ -30,6 +30,11 @@ enum EGameType
struct Build struct Build
{ {
static int calcSinTableValue(int ang)
{
return int(16384 * sin((360./2048) * ang));
}
native static Color shadeToLight(int shade); native static Color shadeToLight(int shade);
} }