Files
Justin Marshall 7806bb8ef8 Added uisrc.
2026-04-27 10:37:37 -07:00

369 lines
9.4 KiB
C++

//****************************************************************************
// MainMenu.cpp
// Diablo UI main menu dialog
//
// By Frank Pearce
// created 9.17.96
//****************************************************************************
#define OEMRESOURCE
#include "pch.h"
#include "artfont.h"
#include "uisnd.h"
#define ALLOW_SINGLE 1 // 1 in final
#define MIN_MEMORY_REQ 0x00dac000L // 14MB
//****************************************************************************
//****************************************************************************
extern void TitleLogoDestroy(void);
extern void TitleLogoInit(HWND window);
extern void TitleFramesInit(HWND window, LPCTSTR filename);
extern void TitleLogoAnimate(HWND window);
extern int SpawnErrDialog(HWND parent, int errstrid, BOOL onmainmenu);
//****************************************************************************
//****************************************************************************
#define MILLISEC_PER_SEC 1000
#define FOCUS_TIMER_ID 1
#define FOCUS_FPS 16 // frames per second
#define FOCUS_TIMER_DELAY 55 //(MILLISEC_PER_SEC / FOCUS_FPS)
#define LOGO_TIMER_ID 2
#define LOGO_FPS 17 // frames per second
#define LOGO_TIMER_DELAY 55 //(MILLISEC_PER_SEC / LOGO_FPS)
#define ATTRACT_TIMER_ID 3
#define MAX_REG_LEN 64
static TCHAR sgRegistration[MAX_REG_LEN];
//****************************************************************************
//****************************************************************************
static int sgTextIDs[] = {
IDC_REGISTRATION,
0
};
#if ALLOW_SINGLE
static int sgBtnIDs[] = {
IDC_SINGLEPLAYER_BTN,
IDC_MULTIPLAYER_BTN,
IDC_REPLAYINTRO_BTN,
IDC_SUPPORT_BTN,
IDC_SHOWCREDITS_BTN,
IDCANCEL,
0
};
#else
static int sgGrayBtnIDs[] = {
IDC_SINGLEPLAYER_BTN,
0
};
static int sgBtnIDs[] = {
IDC_MULTIPLAYER_BTN,
IDC_REPLAYINTRO_BTN,
IDC_SUPPORT_BTN,
IDC_SHOWCREDITS_BTN,
IDCANCEL,
0
};
#endif
static UINT sgAttractTimeout;
//****************************************************************************
//****************************************************************************
LPCTSTR GetRegStr(void) {
return sgRegistration;
}
//****************************************************************************
//****************************************************************************
static void MainMenuDestroy(HWND window) {
TitleLogoDestroy();
FocusAnimateDestroy();
#if ALLOW_SINGLE
UiDoomCtrlsDestroy(window, sgBtnIDs);
#else
UiDoomCtrlsDestroy(window, sgGrayBtnIDs);
UiDoomCtrlsDestroy(window, sgBtnIDs);
#endif
UiDoomCtrlsDestroy(window, sgTextIDs);
UiFreeBmp((TPBMP) GetWindowLong(window, GWL_USERDATA));
SetWindowLong(window, GWL_USERDATA, (LONG) 0);
UiClearCursor();
}
//****************************************************************************
//****************************************************************************
static void MainMenuResetAttractTimer(HWND window) {
// Crashes so we pulled this.
//SDlgSetTimer(window, ATTRACT_TIMER_ID, sgAttractTimeout * MILLISEC_PER_SEC, NULL);
}
//****************************************************************************
//****************************************************************************
static void MainMenuInit(HWND window, UINT attracttimeout) {
TPBMP tpBmp;
HWND child;
// init a bmp for the window
tpBmp = UiAllocBmp();
if (tpBmp) {
SetWindowLong(window, GWL_USERDATA, (LONG) tpBmp);
LoadArtFile(
window,
NULL,
TEXT(""),
SDLG_STYLE_ANY,
SDLG_USAGE_BACKGROUND,
UiIsSpawned() ? TEXT("ui_art\\swmmenu.pcx") : TEXT("ui_art\\mainmenu.pcx"),
&tpBmp->data,
&tpBmp->datasize,
FALSE
);
UiFadeInit(window);
}
// set the reg string
child = GetDlgItem(window, IDC_REGISTRATION);
SetWindowText(child, sgRegistration);
// set up a doom-like interface
UiDoomStaticInit(window, sgTextIDs, AF_SMALLGRAY);
#if ALLOW_SINGLE
UiDoomButtonsInit(window, sgBtnIDs, AF_HUGE);
#else
UiDoomButtonsInit(window, sgBtnIDs, AF_HUGE);
UiDoomButtonsInit(window, sgGrayBtnIDs, AF_HUGEGRAY);
EnableWindow(GetDlgItem(window, IDC_SINGLEPLAYER_BTN), FALSE);
#endif
// set up the animating focus indicator
FocusAnimateInit("ui_art\\focus42.pcx");
SDlgSetTimer(window, FOCUS_TIMER_ID, FOCUS_TIMER_DELAY, NULL);
// set up the animating diablo logo
TitleLogoInit(window);
TitleFramesInit(window,TEXT("ui_art\\hf_logo2.pcx"));
TitleLogoAnimate(window);
SDlgSetTimer(window, LOGO_TIMER_ID, LOGO_TIMER_DELAY, NULL);
MainMenuResetAttractTimer(window);
UiActiveDownBtns(window, sgBtnIDs);
}
//****************************************************************************
//****************************************************************************
static BOOL HasMultiplayerMemory(void) {
MEMORYSTATUS memstat;
memstat.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&memstat);
return(memstat.dwTotalPhys > MIN_MEMORY_REQ);
}
//****************************************************************************
//****************************************************************************
static void MainMenuAbort(HWND window, int ReturnVal, BOOL playsnd) {
//Crashes so we pulled this.
//SDlgKillTimer(window, ATTRACT_TIMER_ID);
if (UiIsSpawned()) {
if (ReturnVal == MAINMENU_REPLAY_INTRO) {
SpawnErrDialog(window, IDS_SPAWNINTRO_ERR, TRUE);
MainMenuResetAttractTimer(window);
return;
}
}
// if user selected multiplayer confirm memory requirements
if (ReturnVal == MAINMENU_MULTIPLAYER) {
if (! HasMultiplayerMemory()) {
SpawnErrDialog(window, IDS_MEMORY_ERR, TRUE);
MainMenuResetAttractTimer(window);
return;
}
}
UiFadeAbort(window);
if (playsnd)
UiSndPlayEnter();
SDlgKillTimer(window, FOCUS_TIMER_ID);
SDlgKillTimer(window, LOGO_TIMER_ID);
UiVidFadeOut(DEFAULT_STEPS*2);
SDlgEndDialog(window, ReturnVal);
}
//****************************************************************************
//****************************************************************************
static void MainMenuBtnAction(HWND window, int id) {
switch (id) {
case IDC_SINGLEPLAYER_BTN:
MainMenuAbort(window,MAINMENU_SINGLE_PLAYER, TRUE);
break;
case IDC_MULTIPLAYER_BTN:
MainMenuAbort(window,MAINMENU_MULTIPLAYER, TRUE);
break;
case IDC_REPLAYINTRO_BTN:
MainMenuAbort(window,MAINMENU_REPLAY_INTRO, TRUE);
break;
case IDC_SUPPORT_BTN:
MainMenuAbort(window,MAINMENU_SUPPORT, TRUE);
break;
case IDC_SHOWCREDITS_BTN:
MainMenuAbort(window,MAINMENU_SHOW_CREDITS, TRUE);
break;
case IDCANCEL:
MainMenuAbort(window,MAINMENU_EXIT_DIABLO, TRUE);
break;
case IDOK: {
// enter key was pressed
HWND FocusBtn = GetFocus();
int BtnID = GetWindowLong(FocusBtn, GWL_ID);
SendMessage(window, WM_COMMAND, BtnID, NULL);
}
break;
}
}
//****************************************************************************
//****************************************************************************
static BOOL CALLBACK MainMenuDialogProc (HWND window,
UINT message,
WPARAM wparam,
LPARAM lparam) {
switch (message) {
case WM_COMMAND:
MainMenuResetAttractTimer(window);
if (HIWORD(wparam) == BN_KILLFOCUS) {
FocusLost(window, (HWND) lparam);
}
else if (HIWORD(wparam) == BN_SETFOCUS) {
FocusSnd((HWND) lparam);
FocusAnimate(window, (HWND) lparam);
}
else if (HIWORD(wparam) == BN_CLICKED) {
MainMenuBtnAction(window, LOWORD(wparam));
}
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MOUSEMOVE:
MainMenuResetAttractTimer(window);
break;
case WM_DESTROY:
MainMenuDestroy(window);
break;
case WM_INITDIALOG:
MainMenuInit(window, lparam);
PostMessage(window, WM_USER+1000, 0, 0);
return 1;
case WM_USER+1000:
if (! UiIsFading()) {
UiFadeStart(window);
}
return 0;
case WM_TIMER:
switch (wparam) {
case FOCUS_TIMER_ID:
FocusAnimate(window, GetFocus());
break;
case LOGO_TIMER_ID:
TitleLogoAnimate(window);
break;
case ATTRACT_TIMER_ID:
if (! UiIsSpawned()) {
MainMenuAbort(window,MAINMENU_ATTRACT_MODE, FALSE);
}
break;
}
return 0;
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
SendMessage(SDrawGetFrameWindow(), message, wparam, lparam);
break;
}
return SDlgDefDialogProc(window,message,wparam,lparam);
}
//****************************************************************************
//*
//* EXPORTED FUNCTIONS
//*
//****************************************************************************
//****************************************************************************
//****************************************************************************
BOOL APIENTRY UiMainMenuDialog(LPCTSTR registration,
DWORD * selection,
bool allowMultiplayer,
PLAYSND sndfcn,
UINT attracttimeoutseconds
) {
DWORD result;
sgAttractTimeout = attracttimeoutseconds;
// init the play sound routine for diabloui
UiSndSetFcn(sndfcn);
// init the custom non-windows font
ArtFontLoad();
sgRegistration[0] = 0;
if (registration)
strncpy(sgRegistration, registration, MAX_REG_LEN);
// DISPLAY THE DIALOG BOX
result = (DWORD)SDlgDialogBox(
global_hinstance,
(allowMultiplayer) ? TEXT("MAINMENU_DIALOG2") : TEXT("MAINMENU_DIALOG"),
SDrawGetFrameWindow(),
MainMenuDialogProc
);
if (result == MAINMENU_EXIT_DIABLO) {
ArtFontDestroy();
}
// set the results
if (selection)
*selection = result;
return 1;
}