- main menu works in the common framework.

The rest is messed up, though. This menu is really on an entirely different level of crappiness, even for a 1995 game.
This commit is contained in:
Christoph Oelckers 2019-12-14 12:39:18 +01:00
parent 5ac0eaad0b
commit cc81b95570
9 changed files with 244 additions and 430 deletions

View file

@ -58,6 +58,7 @@ void RegisterDukeMenus();
void RegisterRedneckMenus(); void RegisterRedneckMenus();
void RegisterBloodMenus(); void RegisterBloodMenus();
void RegisterSWMenus(); void RegisterSWMenus();
void RegisterPSMenus();
void RegisterLoadsaveMenus(); void RegisterLoadsaveMenus();
void RegisterOptionMenus(); void RegisterOptionMenus();
extern bool rotatesprite_2doverride; extern bool rotatesprite_2doverride;
@ -952,6 +953,7 @@ void M_Init (void)
RegisterRedneckMenus(); RegisterRedneckMenus();
RegisterBloodMenus(); RegisterBloodMenus();
RegisterSWMenus(); RegisterSWMenus();
RegisterPSMenus();
RegisterLoadsaveMenus(); RegisterLoadsaveMenus();
RegisterOptionMenus(); RegisterOptionMenus();
timerSetCallback(M_Ticker); timerSetCallback(M_Ticker);

View file

@ -63,16 +63,19 @@ const char *GetVersionString();
#define SAVESIG_BLD "Demolition.Blood" #define SAVESIG_BLD "Demolition.Blood"
#define SAVESIG_RR "Demolition.Redneck" #define SAVESIG_RR "Demolition.Redneck"
#define SAVESIG_SW "Demolition.SW" #define SAVESIG_SW "Demolition.SW"
#define SAVESIG_PS "Demolition.Powerslave"
#define MINSAVEVER_DN3D 1 #define MINSAVEVER_DN3D 1
#define MINSAVEVER_BLD 1 #define MINSAVEVER_BLD 1
#define MINSAVEVER_RR 1 #define MINSAVEVER_RR 1
#define MINSAVEVER_SW 1 #define MINSAVEVER_SW 1
#define MINSAVEVER_PS 1
#define SAVEVER_DN3D 1 #define SAVEVER_DN3D 1
#define SAVEVER_BLD 1 #define SAVEVER_BLD 1
#define SAVEVER_RR 1 #define SAVEVER_RR 1
#define SAVEVER_SW 1 #define SAVEVER_SW 1
#define SAVEVER_PS 1
#if defined(__APPLE__) || defined(_WIN32) #if defined(__APPLE__) || defined(_WIN32)
#define GAME_DIR GAMENAME #define GAME_DIR GAMENAME

View file

@ -93,9 +93,9 @@ set( PCH_SOURCES
src/text2.cpp src/text2.cpp
src/timer.cpp src/timer.cpp
src/trigdat.cpp src/trigdat.cpp
src/version.cpp
src/view.cpp src/view.cpp
src/wasp.cpp src/wasp.cpp
src/d_menu.cpp
) )
if( MSVC ) if( MSVC )

View file

@ -0,0 +1,220 @@
//-------------------------------------------------------------------------
/*
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 "build.h"
#include "osd.h"
#include "osd.h"
#include "exhumed.h"
#include "engine.h"
#include "sound.h"
#include "names.h"
#include "version.h"
#include "config.h"
#include "menu/menu.h"
#include "../../glbackend/glbackend.h"
BEGIN_PS_NS
int handle1;
int MenuExitCondition;
int MenuStartCondition;
int menu_Menu(int nVal)
{
MenuStartCondition = nVal;
MenuExitCondition = -2;
M_StartControlPanel(false);
M_SetMenu(NAME_MainMenu);
while (M_Active())
{
HandleAsync();
videoNextPage();
}
return MenuExitCondition;
}
//----------------------------------------------------------------------------
//
// 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();
int zoomsize = 0;
class PSMainMenu : public DListMenu
{
void Init(DMenu* parent, FListMenuDescriptor* desc) override
{
DListMenu::Init(parent, desc);
PlayLocalSound(StaticSound[kSound31], 0);
}
void Ticker()
{
// handle the menu zoom-in
if (zoomsize < 0x10000)
{
zoomsize += 4096;
if (zoomsize >= 0x10000) {
zoomsize = 0x10000;
}
}
}
void PreDraw() override
{
menu_DoPlasma();
}
};
//----------------------------------------------------------------------------
//
// Menu related game interface functions
//
//----------------------------------------------------------------------------
void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags)
{
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((int)totalclock << 4) >> 9;
}
else if (state == NIT_ActiveState) {
shade = 0;
}
else {
shade = 25;
}
picanm[tilenum].xofs = 0;
picanm[tilenum].yofs = 0;
rotatesprite(160 << 16, int((y + tilesiz[tilenum].y) *65536), zoomsize, 0, tilenum, shade, 0, 2, 0, 0, xdim, ydim);
// tilesizx is 51
// tilesizy is 33
if (state == NIT_SelectedState)
{
overwritesprite(62, short(ypos - 12), kMenuCursorTile, 0, 2, kPalNormal);
overwritesprite(62 + 146, short(ypos - 12), kMenuCursorTile, 0, 10, kPalNormal);
}
}
void GameInterface::MenuOpened()
{
GrabPalette();
zoomsize = 0;
StopAllSounds();
StopLocalSound();
}
void GameInterface::MenuSound(EMenuSounds snd)
{
switch (snd)
{
case CursorSound:
PlayLocalSound(StaticSound[kSound35], 0);
break;
case AdvanceSound:
case BackSound:
PlayLocalSound(StaticSound[kSound33], 0);
break;
default:
return;
}
}
void GameInterface::MenuClosed()
{
}
bool GameInterface::CanSave()
{
return MenuStartCondition == 1;
}
void GameInterface::StartGame(FGameStartup& gs)
{
MenuExitCondition = gs.Episode; // Gross hack. The main loop needs to be redone for better handling.
}
FSavegameInfo GameInterface::GetSaveSig()
{
return { SAVESIG_PS, MINSAVEVER_PS, SAVEVER_PS };
}
void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg)
{
if (text)
{
int height = 11;
auto lines = FString(text).Split("\n");
int y = 100 - (height * lines.Size() / 2);
for (auto& l : lines)
{
int width = MyGetStringWidth(l);
myprintext(int(origin.X) + 160 - width / 2, int(origin.Y) + y, l, 0);
y += height;
}
}
}
END_PS_NS
//----------------------------------------------------------------------------
//
// Class registration
//
//----------------------------------------------------------------------------
static TMenuClassDescriptor<Powerslave::PSMainMenu> _mm("Exhumed.MainMenu");
void RegisterPSMenus()
{
menuClasses.Push(&_mm);
}

View file

@ -278,6 +278,15 @@ struct GameInterface : ::GameInterface
bool validate_hud(int) override { return true; } bool validate_hud(int) override { return true; }
void set_hud_layout(int size) override {} void set_hud_layout(int size) override {}
void set_hud_scale(int size) override {} void set_hud_scale(int size) override {}
void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override;
void MenuOpened() override;
void MenuSound(EMenuSounds snd) override;
void MenuClosed() override;
void StartGame(FGameStartup& gs) override;
bool CanSave() override;
FSavegameInfo GetSaveSig() override;
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg);
//FString statFPS() override; //FString statFPS() override;
//GameStats getStats() override; //GameStats getStats() override;
}; };

View file

@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "cd.h" #include "cd.h"
#include "cdaudio.h" #include "cdaudio.h"
#include "input.h" #include "input.h"
#include "menu/menu.h"
#include <string> #include <string>
#include <assert.h> #include <assert.h>
@ -89,7 +90,6 @@ int plasma_C[5] = {0};
short nMenuKeys[] = { sc_N, sc_L, sc_M, sc_V, sc_Q, sc_None }; // select a menu item using the keys. 'N' for New Gane, 'V' for voume etc. 'M' picks Training for some reason... short nMenuKeys[] = { sc_N, sc_L, sc_M, sc_V, sc_Q, sc_None }; // select a menu item using the keys. 'N' for New Gane, 'V' for voume etc. 'M' picks Training for some reason...
int zoomsize = 0;
void menu_ResetKeyTimer(); void menu_ResetKeyTimer();
@ -1243,90 +1243,11 @@ int menu_LoadGameMenu()
fclose(fp); fclose(fp);
} }
while (1)
{
menu_DoPlasma();
HandleAsync();
overwritesprite(80, 65, kMenuLoadGameTile, 0, 2, kPalNormal);
int spriteY = 90;
int textY = 98;
for (int i = 0; i < kMaxSaveSlots; i++)
{
int8_t shade = ((Sin((int)totalclock << 4) >> 9)* (i == nSlot)) + ((i != nSlot) * 31);
overwritesprite(55, spriteY, kMenuBlankTitleTile, shade, 2, kPalNormal);
myprintext(63, textY, nameList[i], 0);
textY += 22;
spriteY += 22;
}
int y = (nSlot * 22) + 78;
overwritesprite(35, y, kMenuCursorTile, 0, 2, kPalNormal);
overwritesprite(233, y, kMenuCursorTile, 0, 10, kPalNormal);
videoNextPage();
if (I_EscapeTrigger())
{
I_EscapeTriggerClear();
PlayLocalSound(StaticSound[kSound33], 0);
return -1;
}
if (I_MenuUp())
{
I_MenuUpClear();
PlayLocalSound(StaticSound[kSound35], 0);
if (nSlot > 0) {
nSlot--;
}
else {
nSlot = kMaxSaveSlots - 1;
}
}
if (I_MenuDown())
{
I_MenuDownClear();
PlayLocalSound(StaticSound[kSound35], 0);
if (nSlot < kMaxSaveSlots - 1) {
nSlot++;
}
else {
nSlot = 0;
}
}
if (!I_AdvanceTrigger()) {
continue;
}
PlayLocalSound(StaticSound[kSound33], 0);
I_AdvanceTriggerClear();
inputState.ClearAllKeyStatus();
inputState.keyFlushChars();
if (nameList[nSlot][0] != '\0')
{
PlayLocalSound(StaticSound[33], 0);
return nSlot;
}
PlayLocalSound(4, 0);
}
#endif #endif
return 0; return 0;
} }
void menu_ResetKeyTimer()
{
keytimer = (int)totalclock + 2400;
}
void menu_GameLoad2(FILE *fp, bool bIsDemo) void menu_GameLoad2(FILE *fp, bool bIsDemo)
{ {
if (bIsDemo) if (bIsDemo)
@ -1437,296 +1358,6 @@ void menu_GameSave(int nSaveSlot)
} }
} }
void menu_ResetZoom()
{
zoomsize = 0;
PlayLocalSound(StaticSound[kSound31], 0);
}
int menu_Menu(int nVal)
{
#if 0
GrabPalette();
int var_1C = 0;
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
StopAllSounds();
StopLocalSound();
menu_ResetKeyTimer();
inputState.keyFlushChars();
inputState.ClearAllKeyStatus();
menu_ResetZoom();
short ptr[5];
memset(ptr, 1, sizeof(ptr));
// disable new game and load game if in multiplayer?
if (nNetPlayerCount)
{
ptr[1] = 0;
ptr[0] = 0;
}
// denote which menu item we've currently got selected
int nMenu = 0;
while (1)
{
HandleAsync();
// skip any disabled menu items so we're selecting the first active one
while (!ptr[nMenu])
{
nMenu++;
if (nMenu == 5) {
nMenu = 0;
}
}
// handle the menu zoom-in
if (zoomsize < 0x10000)
{
zoomsize += 4096;
if (zoomsize >= 0x10000) {
zoomsize = 0x10000;
}
}
// TODO: Uncomment after fixing demo playback
// menu idle timer
// if (!nVal && (int)totalclock > keytimer) {
// return 9;
// }
// loc_39F54:
menu_DoPlasma();
int y = 65 - tilesiz[kMenuNewGameTile].y / 2;
// YELLOW loop - Draw the 5 menu options (NEW GAME, TRAINING etc)
for (int j = 0; j < 5; j++)
{
int8_t shade;
if (nMenu == j) { // currently selected menu item
shade = Sin((int)totalclock << 4) >> 9;
}
else if (ptr[j]) {
shade = 0;
}
else {
shade = 25;
}
picanm[j + kMenuNewGameTile].xofs = 0;
picanm[j + kMenuNewGameTile].yofs = 0;
rotatesprite(160 << 16, (y + tilesiz[j + kMenuNewGameTile].y) << 16, zoomsize, 0, kMenuNewGameTile + j, shade, 0, 2, 0, 0, xdim, ydim);
y += 22;
}
// tilesizx is 51
// tilesizy is 33
int markerY = (22 * nMenu) + 53;
overwritesprite(62, markerY, kMenuCursorTile, 0, 2, kPalNormal);
overwritesprite(62 + 146, markerY, kMenuCursorTile, 0, 10, kPalNormal);
videoNextPage();
int l = 0; // edi
// ORANGE loop
for (l = 0; ; l++)
{
int nKey = nMenuKeys[l];
if (!nKey) {
break;
}
if (inputState.GetKeyStatus(nKey))
{
goto LABEL_21; // TEMP
}
}
// loc_3A0A7
while (I_EscapeTrigger())
{
HandleAsync();
PlayLocalSound(StaticSound[kSound33], 0);
I_EscapeTriggerClear();
if (nVal)
{
StopAllSounds();
PlayLocalSound(StaticSound[kSound33], 0);
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
return -1;
}
l = 4;
LABEL_21:
menu_ResetKeyTimer();
if (l != nMenu)
{
PlayLocalSound(StaticSound[kSound35], 0);
inputState.ClearKeyStatus(nMenuKeys[l]);
nMenu = l;
}
}
if (I_AdvanceTrigger())
{
I_AdvanceTriggerClear();
var_1C = 1;
}
else if (var_1C)
{
var_1C = 0;
PlayLocalSound(StaticSound[kSound33], 0);
switch (nMenu) // TODO - change var name?
{
case kMenuNewGame:
{
if (nTotalPlayers > 1) {
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
SavePosition = menu_NewGameMenu();
if (SavePosition == -1) {
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
FadeOut(1);
StopAllSounds();
StopAllSounds();
PlayLocalSound(StaticSound[kSound33], 0);
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
return 1;
}
case kMenuLoadGame:
{
if (nTotalPlayers > 1) {
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
SavePosition = menu_LoadGameMenu();
if (SavePosition == -1) {
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
StopAllSounds();
StopAllSounds();
PlayLocalSound(StaticSound[kSound33], 0);
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
return 2;
}
case kMenuTraining:
{
if (nTotalPlayers > 1) {
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
StopAllSounds();
PlayLocalSound(StaticSound[kSound33], 0);
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
return 3;
}
case kMenuVolume:
{
menu_AdjustVolume();
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
case kMenuQuitGame:
{
StopAllSounds();
StopAllSounds();
PlayLocalSound(StaticSound[kSound33], 0);
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
return 0;
}
default:
menu_ResetZoom();
menu_ResetKeyTimer();
break;
}
}
if (I_MenuUp())
{
I_MenuUpClear();
PlayLocalSound(StaticSound[kSound35], 0);
if (nMenu <= 0) {
nMenu = 4;
}
else {
nMenu--;
}
menu_ResetKeyTimer();
}
if (I_MenuDown())
{
I_MenuDownClear();
PlayLocalSound(StaticSound[kSound35], 0);
if (nMenu >= 4) {
nMenu = 0;
}
else {
nMenu++;
}
menu_ResetKeyTimer();
}
// TODO - change to #defines
/* why are these cleares although they are never used anywhere?
if (KB_KeyDown[0x5c]) {
KB_KeyDown[0x5c] = 0;
}
if (KB_KeyDown[0x5d]) {
KB_KeyDown[0x5d] = 0;
}
*/
}
#endif
return 0;// todo
}
#define kMaxCinemaPals 16 #define kMaxCinemaPals 16
const char *cinpalfname[kMaxCinemaPals] = { const char *cinpalfname[kMaxCinemaPals] = {
"3454.pal", "3454.pal",
@ -2016,11 +1647,13 @@ void GoToTheCinema(int nVal)
} }
} }
#if 0
if (ISDEMOVER) { if (ISDEMOVER) {
if (!waloff[cinematile]) { //???
tileCreate(cinematile, 320, 200); if (tilesiz[cinematile].x * tilesiz[cinematile].y == 0)
} TileFiles.tileCreate(cinematile, 320, 200);
} }
#endif
FadeOut(kFalse); FadeOut(kFalse);
StopAllSounds(); StopAllSounds();

View file

@ -1,25 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 sirlemonhead, Nuke.YKT
This file is part of PCExhumed.
PCExhumed 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"
#include "version.h"
BEGIN_PS_NS
const char *versionstr = "Mar 19 1997 17:31:18";
END_PS_NS

View file

@ -1,28 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 sirlemonhead, Nuke.YKT
This file is part of PCExhumed.
PCExhumed 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.
*/
//-------------------------------------------------------------------------
#ifndef __version_h__
#define __version_h__
BEGIN_PS_NS
extern const char *versionstr;
END_PS_NS
#endif

View file

@ -86,7 +86,7 @@ LISTMENU "MainMenu"
linespacing 22 linespacing 22
NativeTextItem "3460", "n", "StartGame 1" NativeTextItem "3460", "n", "StartGame 1"
NativeTextItem "3461", "l", "LoadGameMenu" NativeTextItem "3461", "l", "LoadGameMenu"
NativeTextItem "3462", "m", "StartGame 2" NativeTextItem "3462", "m", "StartGame 3"
NativeTextItem "3463", "v", "OptionsMenu" NativeTextItem "3463", "v", "OptionsMenu"
NativeTextItem "3464", "q", "QuitMenu" NativeTextItem "3464", "q", "QuitMenu"
} }
@ -173,7 +173,7 @@ LISTMENU "IngameMenu"
linespacing 22 linespacing 22
NativeTextItem "3460", "n", "StartGame 1" NativeTextItem "3460", "n", "StartGame 1"
NativeTextItem "3461", "l", "LoadGameMenu" NativeTextItem "3461", "l", "LoadGameMenu"
NativeTextItem "3462", "m", "StartGame 2" NativeTextItem "3462", "m", "StartGame 3"
NativeTextItem "3463", "v", "OptionsMenu" NativeTextItem "3463", "v", "OptionsMenu"
NativeTextItem "3464", "q", "QuitMenu" NativeTextItem "3464", "q", "QuitMenu"
} }