Compare commits

...
Author SHA1 Message Date
Mike Klaas 492536f0c7 Refine main menu subscreen flow 2026-07-19 14:57:52 -07:00
Mike Klaas 75b7b06764 WIP mainmenu behind submenus 2026-07-19 14:57:52 -07:00
11 changed files with 322 additions and 79 deletions
+3
View File
@@ -161,6 +161,9 @@ inventory_columns=2
; Set to 1 to scale only the main menu background image to fit the screen while maintaining aspect ratio.
; Set to 2 to also scale the main menu button panel, red buttons, and button labels with the menu art.
main_menu_scale_mode=1
;Set to 1 to keep the main menu visible behind the 640x480 New Game, Load Game, and Options screens,
;but only when the effective main menu background is larger than 640x480.
main_menu_overlay_subscreens=1
; Set to 1 to show a Help option in the in-game options menu which opens the F1 help screen.
in_game_menu_help=1
+13 -6
View File
@@ -28,6 +28,7 @@
#include "interface.h"
#include "item.h"
#include "kb.h"
#include "mainmenu.h"
#include "map.h"
#include "memory.h"
#include "message.h"
@@ -232,6 +233,7 @@ typedef struct KillInfo {
static int characterEditorWindowInit();
static void characterEditorWindowFree();
static int characterEditorGetModalWindowFlags();
static int _get_input_str(int win, int cancelKeyCode, char* text, int maxLength, int x, int y, int textColor, int backgroundColor, int flags);
static void characterEditorDrawFolders();
static void characterEditorDrawPerksFolder();
@@ -1204,6 +1206,11 @@ int characterEditorShow(bool isCreationMode)
return rc;
}
static int characterEditorGetModalWindowFlags()
{
return mainMenuSubscreenWindowFlags(WINDOW_MODAL | WINDOW_DONT_MOVE_TOP, WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
}
// 0x4329EC CharEditStart
static int characterEditorWindowInit()
{
@@ -1378,7 +1385,7 @@ static int characterEditorWindowInit()
EDITOR_WINDOW_WIDTH,
EDITOR_WINDOW_HEIGHT,
256,
WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
characterEditorGetModalWindowFlags());
if (gCharacterEditorWindow == -1) {
for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) {
if (gCharacterEditorFrmShouldCopy[i]) {
@@ -3211,7 +3218,7 @@ static int characterEditorEditName()
int nameWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2 + 17;
int nameWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2;
int win = windowCreate(nameWindowX, nameWindowY, windowWidth, windowHeight, 256, WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
int win = windowCreate(nameWindowX, nameWindowY, windowWidth, windowHeight, 256, characterEditorGetModalWindowFlags());
if (win == -1) {
return -1;
}
@@ -3343,7 +3350,7 @@ static int characterEditorEditAge()
int ageWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2 + _editorFrmImages[EDITOR_GRAPHIC_NAME_ON].getWidth() + 9;
int ageWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2;
win = windowCreate(ageWindowX, ageWindowY, windowWidth, windowHeight, 256, WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
win = windowCreate(ageWindowX, ageWindowY, windowWidth, windowHeight, 256, characterEditorGetModalWindowFlags());
if (win == -1) {
return -1;
}
@@ -3582,7 +3589,7 @@ static void characterEditorEditGender()
+ _editorFrmImages[EDITOR_GRAPHIC_NAME_ON].getWidth()
+ _editorFrmImages[EDITOR_GRAPHIC_AGE_ON].getWidth();
int genderWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2;
int win = windowCreate(genderWindowX, genderWindowY, windowWidth, windowHeight, 256, WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
int win = windowCreate(genderWindowX, genderWindowY, windowWidth, windowHeight, 256, characterEditorGetModalWindowFlags());
if (win == -1) {
return;
@@ -3825,7 +3832,7 @@ static int characterEditorShowOptions()
int optionsWindowY = (screenGetHeight() != 480)
? (screenGetHeight() - _editorFrmImages[41].getHeight()) / 2
: 90;
int win = windowCreate(optionsWindowX, optionsWindowY, _editorFrmImages[41].getWidth(), _editorFrmImages[41].getHeight(), 256, WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
int win = windowCreate(optionsWindowX, optionsWindowY, _editorFrmImages[41].getWidth(), _editorFrmImages[41].getHeight(), 256, characterEditorGetModalWindowFlags());
if (win == -1) {
return -1;
}
@@ -5830,7 +5837,7 @@ static int perkDialogShow()
int perkWindowY = screenGetHeight() != 480
? (screenGetHeight() - PERK_WINDOW_HEIGHT) / 2
: PERK_WINDOW_Y;
gPerkDialogWindow = windowCreate(perkWindowX, perkWindowY, PERK_WINDOW_WIDTH, PERK_WINDOW_HEIGHT, 256, WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
gPerkDialogWindow = windowCreate(perkWindowX, perkWindowY, PERK_WINDOW_WIDTH, PERK_WINDOW_HEIGHT, 256, characterEditorGetModalWindowFlags());
if (gPerkDialogWindow == -1) {
_perkDialogBackgroundFrmImage.unlock();
debugPrint("\n *** Error running perks dialog window ***\n");
+9 -4
View File
@@ -18,6 +18,7 @@
#include "game_sound.h"
#include "input.h"
#include "kb.h"
#include "mainmenu.h"
#include "memory.h"
#include "message.h"
#include "mouse.h"
@@ -160,8 +161,7 @@ int characterSelectorOpen()
mouseShowCursor();
}
colorPaletteLoad("color.pal");
paletteFadeTo(_cmap);
mainMenuShowSubscreen(true);
int rc = 0;
bool done = false;
@@ -247,7 +247,11 @@ int characterSelectorOpen()
sharedFpsLimiter.throttle();
}
paletteFadeTo(gPaletteBlack);
if (rc == 2) {
mainMenuFadeOutAfterSubscreen(true);
} else {
mainMenuRestoreAfterSubscreen(true);
}
characterSelectorWindowFree();
if (cursorWasHidden) {
@@ -269,7 +273,8 @@ static bool characterSelectorWindowInit()
int characterSelectorWindowX = (screenGetWidth() - CS_WINDOW_WIDTH) / 2;
int characterSelectorWindowY = (screenGetHeight() - CS_WINDOW_HEIGHT) / 2;
gCharacterSelectorWindow = windowCreate(characterSelectorWindowX, characterSelectorWindowY, CS_WINDOW_WIDTH, CS_WINDOW_HEIGHT, COLOR_BLACK, 0);
int characterSelectorWindowFlags = mainMenuSubscreenWindowFlags(0, WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
gCharacterSelectorWindow = windowCreate(characterSelectorWindowX, characterSelectorWindowY, CS_WINDOW_WIDTH, CS_WINDOW_HEIGHT, _colorTable[0], characterSelectorWindowFlags);
if (gCharacterSelectorWindow == -1) {
return characterSelectorWindowFatalError(false);
}
+1
View File
@@ -24,6 +24,7 @@ namespace fallout {
#define GAME_CONFIG_WINDOWED_KEY "windowed"
#define GAME_CONFIG_SCALE_KEY "scale"
#define GAME_CONFIG_MAIN_MENU_SCALE_MODE_KEY "main_menu_scale_mode"
#define GAME_CONFIG_MAIN_MENU_OVERLAY_SUBSCREENS_KEY "main_menu_overlay_subscreens"
#define GAME_CONFIG_IFACE_BAR_MODE_KEY "iface_bar_mode"
#define GAME_CONFIG_IFACE_BAR_WIDTH_KEY "iface_bar_width"
#define GAME_CONFIG_IFACE_BAR_SIDE_ART_KEY "iface_bar_side_art"
+3 -3
View File
@@ -32,6 +32,7 @@
#include "interface.h"
#include "item.h"
#include "kb.h"
#include "mainmenu.h"
#include "map.h"
#include "memory.h"
#include "message.h"
@@ -1202,8 +1203,7 @@ int lsgLoadGame(int mode)
windowRefresh(gLoadSaveWindow);
renderPresent();
if (mode == LOAD_SAVE_MODE_FROM_MAIN_MENU) {
colorPaletteLoad("color.pal");
paletteFadeTo(_cmap);
mainMenuShowSubscreen(true);
}
_dbleclkcntr = 24;
@@ -1554,7 +1554,7 @@ int lsgLoadGame(int mode)
}
if (mode == LOAD_SAVE_MODE_FROM_MAIN_MENU && rc == 0) {
paletteFadeTo(gPaletteBlack);
mainMenuRestoreAfterSubscreen(true);
}
lsgWindowFree(mode == LOAD_SAVE_MODE_FROM_MAIN_MENU
+55 -58
View File
@@ -57,6 +57,7 @@ static void main_unload_new();
static void mainParseCommandLineArguments(int argc, char** argv);
static bool mainTryParseDevLoadGameSlot(const char* value, int* slotPtr);
static void mainLoop();
static void mainRunGameLoopAndCleanup();
static void showDeath();
static void _main_death_voiceover_callback();
static int _mainDeathGrabTextFile(const char* fileName, char* dest);
@@ -125,10 +126,11 @@ int falloutMain(int argc, char** argv)
gameMoviePlay(MOVIE_INTRO, GAME_MOVIE_STOP_MUSIC);
gameMoviePlay(MOVIE_CREDITS, 0);
break;
case MAIN_MENU_NEW_GAME:
mainMenuWindowHide(true);
mainMenuWindowFree();
case MAIN_MENU_NEW_GAME: {
mainMenuBeginSubscreen();
if (characterSelectorOpen() == 2) {
mainMenuFinishSubscreen();
gameMoviePlay(MOVIE_ELDER, GAME_MOVIE_STOP_MUSIC);
randomSeedPrerandom(-1);
@@ -150,62 +152,38 @@ int falloutMain(int argc, char** argv)
sfallOnAfterGameStarted();
gGameLoaded = true;
mainLoop();
paletteFadeTo(gPaletteWhite);
// NOTE: Uninline.
main_unload_new();
// NOTE: Uninline.
main_reset_system();
if (_main_show_death_scene != 0) {
showDeath();
_main_show_death_scene = 0;
}
}
mainMenuWindowInit();
break;
case MAIN_MENU_LOAD_GAME:
if (1) {
int win = windowCreate(0, 0, screenGetWidth(), screenGetHeight(), COLOR_BLACK, WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
mainMenuWindowHide(true);
mainMenuWindowFree();
// NOTE: Uninline.
main_loadgame_new();
if (devLoadGameSlot != -1) {
lsgDevSetLoadGameSlot(devLoadGameSlot);
}
int loadGameRc = lsgLoadGame(LOAD_SAVE_MODE_FROM_MAIN_MENU);
if (loadGameRc == -1) {
debugPrint("\n ** Error running LoadGame()! **\n");
} else if (loadGameRc != 0) {
windowDestroy(win);
win = -1;
mainLoop();
paletteFadeTo(gPaletteWhite);
}
if (win != -1) {
windowDestroy(win);
}
// NOTE: Uninline.
main_unload_new();
// NOTE: Uninline.
main_reset_system();
if (_main_show_death_scene != 0) {
showDeath();
_main_show_death_scene = 0;
}
mainRunGameLoopAndCleanup();
mainMenuWindowInit();
} else {
mainMenuCancelSubscreen();
}
break;
}
case MAIN_MENU_LOAD_GAME: {
mainMenuBeginSubscreen();
// NOTE: Uninline.
main_loadgame_new();
if (devLoadGameSlot != -1) {
lsgDevSetLoadGameSlot(devLoadGameSlot);
}
int loadGameRc = lsgLoadGame(LOAD_SAVE_MODE_FROM_MAIN_MENU);
if (loadGameRc == -1) {
debugPrint("\n ** Error running LoadGame()! **\n");
}
if (loadGameRc > 0) {
mainMenuFinishSubscreen();
mainRunGameLoopAndCleanup();
mainMenuWindowInit();
} else {
main_unload_new();
main_reset_system();
mainMenuCancelSubscreen();
}
break;
}
case MAIN_MENU_TIMEOUT:
debugPrint("Main menu timed-out\n");
// FALLTHROUGH
@@ -213,10 +191,12 @@ int falloutMain(int argc, char** argv)
mainMenuWindowHide(true);
gameMoviePlay(MOVIE_INTRO, GAME_MOVIE_PAUSE_MUSIC);
break;
case MAIN_MENU_OPTIONS:
mainMenuWindowHide(true);
case MAIN_MENU_OPTIONS: {
mainMenuBeginSubscreen();
doPreferences(true);
mainMenuCancelSubscreen();
break;
}
case MAIN_MENU_CREDITS:
mainMenuWindowHide(true);
creditsOpen("credits.txt", -1, false);
@@ -414,6 +394,23 @@ static void mainLoop()
}
}
static void mainRunGameLoopAndCleanup()
{
mainLoop();
paletteFadeTo(gPaletteWhite);
// NOTE: Uninline.
main_unload_new();
// NOTE: Uninline.
main_reset_system();
if (_main_show_death_scene != 0) {
showDeath();
_main_show_death_scene = 0;
}
}
// 0x48118C
static void showDeath()
{
+221
View File
@@ -1,11 +1,14 @@
#include "mainmenu.h"
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include "art.h"
#include "color.h"
#include "content_config.h"
#include "debug.h"
#include "delay.h"
#include "draw.h"
#include "font_manager.h"
#include "game.h"
@@ -48,6 +51,12 @@ namespace fallout {
#define MAIN_MENU_VERSION_Y 440
#define MAIN_MENU_BUILD_HASH_Y 450
#define MAIN_MENU_BUILD_DATE_Y 460
#define MAIN_MENU_OVERLAY_WINDOW_WIDTH 640
#define MAIN_MENU_OVERLAY_WINDOW_HEIGHT 480
#define MAIN_MENU_OVERLAY_DIM_TARGET_INTENSITY 0x8000
#define MAIN_MENU_OVERLAY_DIM_CLEAR_INTENSITY 0x10000
#define MAIN_MENU_OVERLAY_DIM_ANIMATION_STEPS 8
#define MAIN_MENU_OVERLAY_DIM_FRAME_DELAY 20
typedef enum MainMenuButton {
MAIN_MENU_BUTTON_INTRO,
@@ -105,12 +114,20 @@ static int gMainMenuButtons[MAIN_MENU_BUTTON_COUNT];
// 0x614858 main_menu_is_hidden
static bool gMainMenuWindowHidden;
static int gMainMenuOverlayCount = 0;
static bool gMainMenuOverlayBackgroundEnabled = false;
static FrmImage mainMenuBackgroundFrmImage;
static FrmImage mainMenuButtonPanelFrmImage;
static FrmImage mainMenuButtonNormalFrmImage;
static FrmImage mainMenuButtonPressedFrmImage;
static std::vector<unsigned char> mainMenuScaledButtonData;
static std::vector<unsigned char> mainMenuOverlayDimmedBackup;
static void mainMenuSetButtonsEnabled(bool enabled);
static void mainMenuApplyOverlayDim();
static void mainMenuRemoveOverlayDim();
static void mainMenuSetOverlayDimIntensity(int intensity);
static void mainMenuAnimateOverlayDim(int startIntensity, int endIntensity);
struct MainMenuLayout {
int screenWidth;
@@ -147,9 +164,14 @@ static int mainMenuScaleX(const MainMenuLayout& layout, int value);
static int mainMenuScaleY(const MainMenuLayout& layout, int value);
static int mainMenuGetAnchoredY(const MainMenuLayout& layout, int value);
static int mainMenuGetAnchoredRightX(const MainMenuLayout& layout, int rightMargin, int width);
static bool mainMenuShouldEnableOverlayBackground(const MainMenuLayout& layout);
static void mainMenuDrawBuildInfo(const MainMenuLayout& layout, const MainMenuOffsets& offsets);
static bool mainMenuCreateButtons(const MainMenuLayout& layout, const MainMenuOffsets& offsets);
static void mainMenuDrawButtonLabels(const MainMenuLayout& layout, const MainMenuOffsets& offsets);
static bool mainMenuWindowIsOverlayActive();
static void mainMenuWindowEnterOverlay();
static void mainMenuWindowLeaveOverlay();
static void mainMenuWindowShowOverlayDim();
static void mainMenuComputeAspectFit(int srcWidth, int srcHeight, int& outX, int& outY, int& outWidth, int& outHeight)
{
@@ -352,6 +374,13 @@ static int mainMenuGetAnchoredRightX(const MainMenuLayout& layout, int rightMarg
return layout.backgroundX + layout.backgroundWidth - rightMargin - width;
}
static bool mainMenuShouldEnableOverlayBackground(const MainMenuLayout& layout)
{
return settings.ui.main_menu_overlay_subscreens
&& (layout.backgroundWidth > MAIN_MENU_OVERLAY_WINDOW_WIDTH
|| layout.backgroundHeight > MAIN_MENU_OVERLAY_WINDOW_HEIGHT);
}
static void mainMenuDrawBuildInfo(const MainMenuLayout& layout, const MainMenuOffsets& offsets)
{
MessageListItem msg;
@@ -509,6 +538,7 @@ int mainMenuWindowInit()
}
MainMenuLayout layout = mainMenuBuildLayout();
gMainMenuOverlayBackgroundEnabled = mainMenuShouldEnableOverlayBackground(layout);
MainMenuOffsets offsets = mainMenuReadOffsets(layout);
mainMenuDrawBackground(layout);
@@ -531,6 +561,8 @@ int mainMenuWindowInit()
gMainMenuWindowInitialized = true;
gMainMenuWindowHidden = true;
gMainMenuOverlayCount = 0;
mainMenuOverlayDimmedBackup.clear();
return 0;
}
@@ -546,6 +578,7 @@ void mainMenuWindowFree()
}
mainMenuScaledButtonData.clear();
mainMenuOverlayDimmedBackup.clear();
mainMenuButtonPanelFrmImage.unlock();
mainMenuButtonPressedFrmImage.unlock();
mainMenuButtonNormalFrmImage.unlock();
@@ -559,6 +592,8 @@ void mainMenuWindowFree()
gMainMenuWindow = -1;
gMainMenuWindowBuffer = nullptr;
gMainMenuWindowHidden = true;
gMainMenuOverlayCount = 0;
gMainMenuOverlayBackgroundEnabled = false;
}
// 0x481A00 main_menu_hide
@@ -581,6 +616,8 @@ void mainMenuWindowHide(bool animate)
windowHide(gMainMenuWindow);
touch_set_touchscreen_mode(false);
mainMenuOverlayDimmedBackup.clear();
gMainMenuOverlayCount = 0;
gMainMenuWindowHidden = true;
}
@@ -607,6 +644,119 @@ void mainMenuWindowUnhide(bool animate)
gMainMenuWindowHidden = false;
}
static void mainMenuWindowEnterOverlay()
{
if (!gMainMenuWindowInitialized || gMainMenuWindowHidden) {
return;
}
if (gMainMenuOverlayCount == 0) {
mainMenuSetButtonsEnabled(false);
}
gMainMenuOverlayCount += 1;
}
static void mainMenuWindowLeaveOverlay()
{
if (!gMainMenuWindowInitialized || gMainMenuWindowHidden) {
gMainMenuOverlayCount = 0;
return;
}
assert(gMainMenuOverlayCount > 0);
if (gMainMenuOverlayCount <= 0) {
gMainMenuOverlayCount = 0;
return;
}
gMainMenuOverlayCount -= 1;
if (gMainMenuOverlayCount == 0) {
mainMenuRemoveOverlayDim();
mainMenuSetButtonsEnabled(true);
touch_set_touchscreen_mode(true);
}
}
static bool mainMenuWindowIsOverlayActive()
{
return gMainMenuWindowInitialized && !gMainMenuWindowHidden && gMainMenuOverlayCount > 0;
}
static bool mainMenuWindowShouldUseOverlayBackground()
{
return gMainMenuOverlayBackgroundEnabled;
}
static void mainMenuWindowShowOverlayDim()
{
if (!mainMenuWindowIsOverlayActive() || !mainMenuOverlayDimmedBackup.empty()) {
return;
}
mainMenuApplyOverlayDim();
}
void mainMenuBeginSubscreen()
{
if (mainMenuWindowShouldUseOverlayBackground()) {
mainMenuWindowEnterOverlay();
return;
}
mainMenuWindowHide(true);
}
void mainMenuCancelSubscreen()
{
if (mainMenuWindowIsOverlayActive()) {
mainMenuWindowLeaveOverlay();
}
}
void mainMenuFinishSubscreen()
{
if (mainMenuWindowIsOverlayActive()) {
mainMenuWindowHide(false);
}
mainMenuWindowFree();
}
int mainMenuSubscreenWindowFlags(int defaultFlags, int overlayFlags)
{
return mainMenuWindowIsOverlayActive() ? overlayFlags : defaultFlags;
}
void mainMenuShowSubscreen(bool animate)
{
if (mainMenuWindowIsOverlayActive()) {
renderPresent();
mainMenuWindowShowOverlayDim();
} else if (animate) {
colorPaletteLoad("color.pal");
paletteFadeTo(_cmap);
}
}
void mainMenuRestoreAfterSubscreen(bool animate)
{
if (!animate || mainMenuWindowIsOverlayActive()) {
return;
}
paletteFadeTo(gPaletteBlack);
}
void mainMenuFadeOutAfterSubscreen(bool animate)
{
if (!animate) {
return;
}
paletteFadeTo(gPaletteBlack);
}
// 0x481AA8 main_menu_is_enabled
int _main_menu_is_enabled()
{
@@ -722,4 +872,75 @@ static void main_menu_play_sound(const char* fileName)
soundPlayFile(fileName);
}
static void mainMenuSetButtonsEnabled(bool enabled)
{
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
if (gMainMenuButtons[index] == -1) {
continue;
}
if (enabled) {
buttonEnable(gMainMenuButtons[index]);
} else {
buttonDisable(gMainMenuButtons[index]);
}
}
}
static void mainMenuApplyOverlayDim()
{
if (gMainMenuWindow == -1 || gMainMenuWindowBuffer == nullptr) {
return;
}
int width = windowGetWidth(gMainMenuWindow);
int height = windowGetHeight(gMainMenuWindow);
int size = width * height;
mainMenuOverlayDimmedBackup.assign(gMainMenuWindowBuffer, gMainMenuWindowBuffer + size);
mainMenuAnimateOverlayDim(MAIN_MENU_OVERLAY_DIM_CLEAR_INTENSITY, MAIN_MENU_OVERLAY_DIM_TARGET_INTENSITY);
}
static void mainMenuRemoveOverlayDim()
{
if (gMainMenuWindow == -1 || gMainMenuWindowBuffer == nullptr || mainMenuOverlayDimmedBackup.empty()) {
return;
}
int width = windowGetWidth(gMainMenuWindow);
int height = windowGetHeight(gMainMenuWindow);
int size = width * height;
if (static_cast<int>(mainMenuOverlayDimmedBackup.size()) != size) {
mainMenuOverlayDimmedBackup.clear();
return;
}
mainMenuAnimateOverlayDim(MAIN_MENU_OVERLAY_DIM_TARGET_INTENSITY, MAIN_MENU_OVERLAY_DIM_CLEAR_INTENSITY);
memcpy(gMainMenuWindowBuffer, mainMenuOverlayDimmedBackup.data(), size);
mainMenuOverlayDimmedBackup.clear();
windowRefresh(gMainMenuWindow);
}
static void mainMenuSetOverlayDimIntensity(int intensity)
{
if (gMainMenuWindow == -1 || gMainMenuWindowBuffer == nullptr || mainMenuOverlayDimmedBackup.empty()) {
return;
}
int width = windowGetWidth(gMainMenuWindow);
int height = windowGetHeight(gMainMenuWindow);
_dark_trans_buf_to_buf(mainMenuOverlayDimmedBackup.data(), width, height, width, gMainMenuWindowBuffer, 0, 0, width, intensity);
windowRefresh(gMainMenuWindow);
renderPresent();
}
static void mainMenuAnimateOverlayDim(int startIntensity, int endIntensity)
{
for (int step = 0; step < MAIN_MENU_OVERLAY_DIM_ANIMATION_STEPS; step++) {
int intensity = startIntensity + (endIntensity - startIntensity) * (step + 1) / MAIN_MENU_OVERLAY_DIM_ANIMATION_STEPS;
mainMenuSetOverlayDimIntensity(intensity);
delay_ms(MAIN_MENU_OVERLAY_DIM_FRAME_DELAY);
}
}
} // namespace fallout
+7
View File
@@ -20,6 +20,13 @@ int mainMenuWindowInit();
void mainMenuWindowFree();
void mainMenuWindowHide(bool animate);
void mainMenuWindowUnhide(bool animate);
void mainMenuBeginSubscreen();
void mainMenuCancelSubscreen();
void mainMenuFinishSubscreen();
int mainMenuSubscreenWindowFlags(int defaultFlags, int overlayFlags);
void mainMenuShowSubscreen(bool animate);
void mainMenuRestoreAfterSubscreen(bool animate);
void mainMenuFadeOutAfterSubscreen(bool animate);
int _main_menu_is_enabled();
int mainMenuWindowHandleEvents();
void mainMenuRequestExit();
+6 -8
View File
@@ -15,6 +15,7 @@
#include "graph_lib.h"
#include "input.h"
#include "kb.h"
#include "mainmenu.h"
#include "message.h"
#include "mouse.h"
#include "palette.h"
@@ -1009,12 +1010,14 @@ static int preferencesWindowInit()
int preferencesWindowX = (screenGetWidth() - PREFERENCES_WINDOW_WIDTH) / 2;
int preferencesWindowY = (screenGetHeight() - PREFERENCES_WINDOW_HEIGHT) / 2;
int preferencesWindowFlags = mainMenuSubscreenWindowFlags(WINDOW_MODAL | WINDOW_DONT_MOVE_TOP, WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
gPreferencesWindow = windowCreate(preferencesWindowX,
preferencesWindowY,
PREFERENCES_WINDOW_WIDTH,
PREFERENCES_WINDOW_HEIGHT,
256,
WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
preferencesWindowFlags);
if (gPreferencesWindow == -1) {
for (i = 0; i < PREFERENCES_WINDOW_FRM_COUNT; i++) {
_preferencesFrmImages[i].unlock();
@@ -1233,10 +1236,7 @@ int doPreferences(bool animated)
touch_set_touchscreen_mode(true);
if (animated) {
colorPaletteLoad("color.pal");
paletteFadeTo(_cmap);
}
mainMenuShowSubscreen(animated);
int rc = -1;
while (rc == -1) {
@@ -1286,9 +1286,7 @@ int doPreferences(bool animated)
sharedFpsLimiter.throttle();
}
if (animated) {
paletteFadeTo(gPaletteBlack);
}
mainMenuRestoreAfterSubscreen(animated);
if (cursorWasHidden) {
mouseHideCursor();
+1
View File
@@ -152,6 +152,7 @@ void initSettingsRegistry(bool isMapper)
#define SECT ui
SETTING_P(main_menu_scale_mode, clamp(0, 2));
SETTING(in_game_menu_help);
SETTING(main_menu_overlay_subscreens);
SETTING(iface_bar_mode);
SETTING_P(iface_bar_width, clamp(640, 4320));
SETTING_P(iface_bar_side_art, clamp(0, 999));
+3
View File
@@ -45,6 +45,9 @@ struct UISettings {
// Show the Help option in the in-game options menu.
bool in_game_menu_help = true;
// Whether to keep the main menu visible behind 640x480 main-menu subwindows
// like load, options, and new game when the effective menu background is larger.
bool main_menu_overlay_subscreens = true;
// Should the game window stretch all the way to the bottom or sit at the top of the interface bar (default).
bool iface_bar_mode = false;