fallout2-ce/src/options.cc

528 lines
15 KiB
C++
Raw Normal View History

2022-05-19 01:51:26 -07:00
#include "options.h"
2022-06-18 08:25:13 -07:00
#include "art.h"
2022-05-19 01:51:26 -07:00
#include "color.h"
#include "cycle.h"
#include "debug.h"
#include "draw.h"
#include "game.h"
#include "game_mouse.h"
#include "game_sound.h"
2022-12-27 07:59:24 -08:00
#include "graph_lib.h"
2022-10-04 23:23:27 -07:00
#include "input.h"
2022-10-03 06:42:34 -07:00
#include "kb.h"
2022-05-19 01:51:26 -07:00
#include "loadsave.h"
#include "memory.h"
2022-06-18 08:25:13 -07:00
#include "message.h"
2022-10-03 02:41:33 -07:00
#include "mouse.h"
2023-02-17 01:33:26 -08:00
#include "preferences.h"
2022-10-05 00:35:05 -07:00
#include "svga.h"
2022-05-19 01:51:26 -07:00
#include "text_font.h"
#include "tile.h"
#include "window_manager.h"
2022-09-23 05:43:44 -07:00
namespace fallout {
2022-06-18 08:25:13 -07:00
#define OPTIONS_WINDOW_BUTTONS_COUNT (10)
typedef enum PauseWindowFrm {
PAUSE_WINDOW_FRM_BACKGROUND,
PAUSE_WINDOW_FRM_DONE_BOX,
PAUSE_WINDOW_FRM_LITTLE_RED_BUTTON_UP,
PAUSE_WINDOW_FRM_LITTLE_RED_BUTTON_DOWN,
PAUSE_WINDOW_FRM_COUNT,
} PauseWindowFrm;
typedef enum OptionsWindowFrm {
OPTIONS_WINDOW_FRM_BACKGROUND,
OPTIONS_WINDOW_FRM_BUTTON_ON,
OPTIONS_WINDOW_FRM_BUTTON_OFF,
OPTIONS_WINDOW_FRM_COUNT,
} OptionsWindowFrm;
static int optionsWindowInit();
static int optionsWindowFree();
static void _ShadeScreen(bool a1);
2022-05-19 01:51:26 -07:00
// 0x48FC0C
2022-06-18 08:25:13 -07:00
static const int gPauseWindowFrmIds[PAUSE_WINDOW_FRM_COUNT] = {
2022-05-19 01:51:26 -07:00
208, // charwin.frm - character editor
209, // donebox.frm - character editor
8, // lilredup.frm - little red button up
9, // lilreddn.frm - little red button down
};
// 0x5197C0
2022-06-18 08:25:13 -07:00
static const int gOptionsWindowFrmIds[OPTIONS_WINDOW_FRM_COUNT] = {
2022-05-19 01:51:26 -07:00
220, // opbase.frm - character editor
222, // opbtnon.frm - character editor
221, // opbtnoff.frm - character editor
};
// 0x6637E8
2023-02-17 01:33:26 -08:00
static MessageList gPreferencesMessageList;
2022-05-19 01:51:26 -07:00
// 0x663840
2023-02-17 01:33:26 -08:00
static MessageListItem gPreferencesMessageListItem;
2022-05-19 01:51:26 -07:00
// 0x663878
2022-06-18 08:25:13 -07:00
static unsigned char* _opbtns[OPTIONS_WINDOW_BUTTONS_COUNT];
2022-05-19 01:51:26 -07:00
// 0x6638FC
2022-06-18 08:25:13 -07:00
static bool gOptionsWindowGameMouseObjectsWasVisible;
2022-05-19 01:51:26 -07:00
// 0x663900
2022-06-18 08:25:13 -07:00
static int gOptionsWindow;
2022-05-19 01:51:26 -07:00
// 0x663908
2022-06-18 08:25:13 -07:00
static unsigned char* gOptionsWindowBuffer;
2022-05-19 01:51:26 -07:00
// 0x66398C
2022-06-18 08:25:13 -07:00
static int gOptionsWindowOldFont;
2022-05-19 01:51:26 -07:00
// 0x663994
2022-06-18 08:25:13 -07:00
static bool gOptionsWindowIsoWasEnabled;
2022-05-19 01:51:26 -07:00
static FrmImage _optionsFrmImages[OPTIONS_WINDOW_FRM_COUNT];
2022-05-19 01:51:26 -07:00
// 0x48FC50
2023-02-17 01:33:26 -08:00
int showOptions()
2022-05-19 01:51:26 -07:00
{
2022-12-06 06:22:30 -08:00
ScopedGameMode gm(GameMode::kOptions);
2022-05-19 01:51:26 -07:00
if (optionsWindowInit() == -1) {
debugPrint("\nOPTION MENU: Error loading option dialog data!\n");
return -1;
}
int rc = -1;
while (rc == -1) {
2022-10-07 14:54:27 -07:00
sharedFpsLimiter.mark();
2022-10-05 00:11:47 -07:00
int keyCode = inputGetInput();
2022-05-19 01:51:26 -07:00
if (keyCode == KEY_ESCAPE || keyCode == 504 || _game_user_wants_to_quit != 0) {
rc = 0;
} else {
switch (keyCode) {
case KEY_RETURN:
case KEY_UPPERCASE_O:
case KEY_LOWERCASE_O:
case KEY_UPPERCASE_D:
case KEY_LOWERCASE_D:
soundPlayFile("ib1p1xx1");
rc = 0;
break;
case KEY_UPPERCASE_S:
case KEY_LOWERCASE_S:
case 500:
2022-11-03 08:16:50 -07:00
if (lsgSaveGame(LOAD_SAVE_MODE_NORMAL) == 1) {
2022-05-19 01:51:26 -07:00
rc = 1;
}
break;
case KEY_UPPERCASE_L:
case KEY_LOWERCASE_L:
case 501:
if (lsgLoadGame(LOAD_SAVE_MODE_NORMAL) == 1) {
rc = 1;
}
break;
case KEY_UPPERCASE_P:
case KEY_LOWERCASE_P:
soundPlayFile("ib1p1xx1");
// FALLTHROUGH
case 502:
// PREFERENCES
2023-02-17 01:33:26 -08:00
doPreferences(false);
2022-05-19 01:51:26 -07:00
break;
case KEY_PLUS:
case KEY_EQUAL:
brightnessIncrease();
break;
case KEY_UNDERSCORE:
case KEY_MINUS:
brightnessDecrease();
break;
case KEY_F12:
takeScreenshot();
break;
case KEY_UPPERCASE_E:
case KEY_LOWERCASE_E:
case KEY_CTRL_Q:
case KEY_CTRL_X:
case KEY_F10:
case 503:
showQuitConfirmationDialog();
break;
}
}
2022-10-07 14:54:27 -07:00
renderPresent();
sharedFpsLimiter.throttle();
2022-05-19 01:51:26 -07:00
}
optionsWindowFree();
return rc;
}
// 0x48FE14
2022-06-18 08:25:13 -07:00
static int optionsWindowInit()
2022-05-19 01:51:26 -07:00
{
gOptionsWindowOldFont = fontGetCurrent();
2023-02-17 01:33:26 -08:00
if (!messageListInit(&gPreferencesMessageList)) {
2022-05-19 01:51:26 -07:00
return -1;
}
2022-05-28 02:34:49 -07:00
char path[COMPAT_MAX_PATH];
2022-12-08 12:05:50 -08:00
snprintf(path, sizeof(path), "%s%s", asc_5186C8, "options.msg");
2023-02-17 01:33:26 -08:00
if (!messageListLoad(&gPreferencesMessageList, path)) {
2022-05-19 01:51:26 -07:00
return -1;
}
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, gOptionsWindowFrmIds[index], 0, 0, 0);
if (!_optionsFrmImages[index].lock(fid)) {
2022-05-19 01:51:26 -07:00
while (--index >= 0) {
_optionsFrmImages[index].unlock();
2022-05-19 01:51:26 -07:00
}
2023-02-17 01:33:26 -08:00
messageListFree(&gPreferencesMessageList);
2022-05-19 01:51:26 -07:00
return -1;
}
}
int cycle = 0;
for (int index = 0; index < OPTIONS_WINDOW_BUTTONS_COUNT; index++) {
_opbtns[index] = (unsigned char*)internal_malloc(_optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth() * _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getHeight() + 1024);
2022-05-19 01:51:26 -07:00
if (_opbtns[index] == NULL) {
while (--index >= 0) {
internal_free(_opbtns[index]);
}
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
_optionsFrmImages[index].unlock();
2022-05-19 01:51:26 -07:00
}
2023-02-17 01:33:26 -08:00
messageListFree(&gPreferencesMessageList);
2022-05-19 01:51:26 -07:00
return -1;
}
cycle = cycle ^ 1;
memcpy(_opbtns[index], _optionsFrmImages[cycle + 1].getData(), _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth() * _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getHeight());
2022-05-19 01:51:26 -07:00
}
int optionsWindowX = (screenGetWidth() - _optionsFrmImages[OPTIONS_WINDOW_FRM_BACKGROUND].getWidth()) / 2;
int optionsWindowY = (screenGetHeight() - _optionsFrmImages[OPTIONS_WINDOW_FRM_BACKGROUND].getHeight()) / 2 - 60;
2022-05-20 16:35:18 -07:00
gOptionsWindow = windowCreate(optionsWindowX,
optionsWindowY,
_optionsFrmImages[0].getWidth(),
_optionsFrmImages[0].getHeight(),
2022-05-19 01:51:26 -07:00
256,
2022-12-12 23:04:05 -08:00
WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
2022-05-19 01:51:26 -07:00
if (gOptionsWindow == -1) {
for (int index = 0; index < OPTIONS_WINDOW_BUTTONS_COUNT; index++) {
internal_free(_opbtns[index]);
}
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
_optionsFrmImages[index].unlock();
2022-05-19 01:51:26 -07:00
}
2023-02-17 01:33:26 -08:00
messageListFree(&gPreferencesMessageList);
2022-05-19 01:51:26 -07:00
return -1;
}
gOptionsWindowIsoWasEnabled = isoDisable();
gOptionsWindowGameMouseObjectsWasVisible = gameMouseObjectsIsVisible();
if (gOptionsWindowGameMouseObjectsWasVisible) {
gameMouseObjectsHide();
}
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
gOptionsWindowBuffer = windowGetBuffer(gOptionsWindow);
memcpy(gOptionsWindowBuffer, _optionsFrmImages[OPTIONS_WINDOW_FRM_BACKGROUND].getData(), _optionsFrmImages[OPTIONS_WINDOW_FRM_BACKGROUND].getWidth() * _optionsFrmImages[OPTIONS_WINDOW_FRM_BACKGROUND].getHeight());
2022-05-19 01:51:26 -07:00
fontSetCurrent(103);
int textY = (_optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getHeight() - fontGetLineHeight()) / 2 + 1;
2022-05-19 01:51:26 -07:00
int buttonY = 17;
for (int index = 0; index < OPTIONS_WINDOW_BUTTONS_COUNT; index += 2) {
char text[128];
2023-02-17 01:33:26 -08:00
const char* msg = getmsg(&gPreferencesMessageList, &gPreferencesMessageListItem, index / 2);
2022-05-19 01:51:26 -07:00
strcpy(text, msg);
int textX = (_optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth() - fontGetStringWidth(text)) / 2;
2022-05-19 01:51:26 -07:00
if (textX < 0) {
textX = 0;
}
fontDrawText(_opbtns[index] + _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth() * textY + textX, text, _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth(), _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth(), _colorTable[18979]);
fontDrawText(_opbtns[index + 1] + _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth() * textY + textX, text, _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth(), _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth(), _colorTable[14723]);
int btn = buttonCreate(gOptionsWindow,
13,
buttonY,
_optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getWidth(),
_optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getHeight(),
-1,
-1,
-1,
index / 2 + 500,
_opbtns[index],
_opbtns[index + 1],
NULL,
BUTTON_FLAG_TRANSPARENT);
2022-05-19 01:51:26 -07:00
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_lrg_butt_press, _gsound_lrg_butt_release);
}
buttonY += _optionsFrmImages[OPTIONS_WINDOW_FRM_BUTTON_ON].getHeight() + 3;
2022-05-19 01:51:26 -07:00
}
fontSetCurrent(101);
windowRefresh(gOptionsWindow);
return 0;
}
// 0x490244
2022-06-18 08:25:13 -07:00
static int optionsWindowFree()
2022-05-19 01:51:26 -07:00
{
windowDestroy(gOptionsWindow);
fontSetCurrent(gOptionsWindowOldFont);
2023-02-17 01:33:26 -08:00
messageListFree(&gPreferencesMessageList);
2022-05-19 01:51:26 -07:00
for (int index = 0; index < OPTIONS_WINDOW_BUTTONS_COUNT; index++) {
internal_free(_opbtns[index]);
}
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
_optionsFrmImages[index].unlock();
2022-05-19 01:51:26 -07:00
}
if (gOptionsWindowGameMouseObjectsWasVisible) {
gameMouseObjectsShow();
}
if (gOptionsWindowIsoWasEnabled) {
isoEnable();
}
return 0;
}
// 0x4902B0
int showPause(bool a1)
{
bool gameMouseWasVisible;
if (!a1) {
gOptionsWindowIsoWasEnabled = isoDisable();
colorCycleDisable();
gameMouseWasVisible = gameMouseObjectsIsVisible();
if (gameMouseWasVisible) {
gameMouseObjectsHide();
}
}
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
_ShadeScreen(a1);
FrmImage frmImages[PAUSE_WINDOW_FRM_COUNT];
2022-05-19 01:51:26 -07:00
for (int index = 0; index < PAUSE_WINDOW_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, gPauseWindowFrmIds[index], 0, 0, 0);
if (!frmImages[index].lock(fid)) {
2022-05-19 01:51:26 -07:00
debugPrint("\n** Error loading pause window graphics! **\n");
return -1;
}
}
2023-02-17 01:33:26 -08:00
if (!messageListInit(&gPreferencesMessageList)) {
2022-05-19 01:51:26 -07:00
// FIXME: Leaking graphics.
return -1;
}
2022-05-28 02:34:49 -07:00
char path[COMPAT_MAX_PATH];
2022-12-08 12:05:50 -08:00
snprintf(path, sizeof(path), "%s%s", asc_5186C8, "options.msg");
2023-02-17 01:33:26 -08:00
if (!messageListLoad(&gPreferencesMessageList, path)) {
2022-05-19 01:51:26 -07:00
// FIXME: Leaking graphics.
return -1;
}
int pauseWindowX = (screenGetWidth() - frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth()) / 2;
int pauseWindowY = (screenGetHeight() - frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getHeight()) / 2;
2022-05-19 01:51:26 -07:00
if (a1) {
2022-05-21 01:40:54 -07:00
pauseWindowX -= 65;
pauseWindowY -= 24;
2022-05-19 01:51:26 -07:00
} else {
2022-05-21 01:40:54 -07:00
pauseWindowY -= 54;
2022-05-19 01:51:26 -07:00
}
2022-05-21 01:40:54 -07:00
int window = windowCreate(pauseWindowX,
pauseWindowY,
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth(),
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getHeight(),
2022-05-21 01:40:54 -07:00
256,
2022-12-12 23:04:05 -08:00
WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
2022-05-19 01:51:26 -07:00
if (window == -1) {
2023-02-17 01:33:26 -08:00
messageListFree(&gPreferencesMessageList);
2022-05-19 01:51:26 -07:00
debugPrint("\n** Error opening pause window! **\n");
return -1;
}
unsigned char* windowBuffer = windowGetBuffer(window);
memcpy(windowBuffer,
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getData(),
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth() * frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getHeight());
2022-05-19 01:51:26 -07:00
blitBufferToBufferTrans(frmImages[PAUSE_WINDOW_FRM_DONE_BOX].getData(),
frmImages[PAUSE_WINDOW_FRM_DONE_BOX].getWidth(),
frmImages[PAUSE_WINDOW_FRM_DONE_BOX].getHeight(),
frmImages[PAUSE_WINDOW_FRM_DONE_BOX].getWidth(),
windowBuffer + frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth() * 42 + 13,
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth());
2022-05-19 01:51:26 -07:00
gOptionsWindowOldFont = fontGetCurrent();
fontSetCurrent(103);
char* messageItemText;
2023-02-17 01:33:26 -08:00
messageItemText = getmsg(&gPreferencesMessageList, &gPreferencesMessageListItem, 300);
fontDrawText(windowBuffer + frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth() * 45 + 52,
2022-05-19 01:51:26 -07:00
messageItemText,
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth(),
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth(),
2022-05-19 01:51:26 -07:00
_colorTable[18979]);
fontSetCurrent(104);
2023-02-17 01:33:26 -08:00
messageItemText = getmsg(&gPreferencesMessageList, &gPreferencesMessageListItem, 301);
2022-05-19 01:51:26 -07:00
strcpy(path, messageItemText);
int length = fontGetStringWidth(path);
fontDrawText(windowBuffer + frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth() * 10 + 2 + (frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth() - length) / 2,
2022-05-19 01:51:26 -07:00
path,
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth(),
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth(),
2022-05-19 01:51:26 -07:00
_colorTable[18979]);
int doneBtn = buttonCreate(window,
26,
46,
frmImages[PAUSE_WINDOW_FRM_LITTLE_RED_BUTTON_UP].getWidth(),
frmImages[PAUSE_WINDOW_FRM_LITTLE_RED_BUTTON_UP].getHeight(),
2022-05-19 01:51:26 -07:00
-1,
-1,
-1,
504,
frmImages[PAUSE_WINDOW_FRM_LITTLE_RED_BUTTON_UP].getData(),
frmImages[PAUSE_WINDOW_FRM_LITTLE_RED_BUTTON_DOWN].getData(),
2022-05-19 01:51:26 -07:00
NULL,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn != -1) {
buttonSetCallbacks(doneBtn, _gsound_red_butt_press, _gsound_red_butt_release);
}
windowRefresh(window);
bool done = false;
while (!done) {
2022-10-07 14:54:27 -07:00
sharedFpsLimiter.mark();
2022-10-05 00:11:47 -07:00
int keyCode = inputGetInput();
2022-05-19 01:51:26 -07:00
switch (keyCode) {
case KEY_PLUS:
case KEY_EQUAL:
brightnessIncrease();
break;
case KEY_MINUS:
case KEY_UNDERSCORE:
brightnessDecrease();
break;
default:
if (keyCode != -1 && keyCode != -2) {
done = true;
}
if (_game_user_wants_to_quit != 0) {
done = true;
}
}
2022-10-07 14:54:27 -07:00
renderPresent();
sharedFpsLimiter.throttle();
2022-05-19 01:51:26 -07:00
}
if (!a1) {
tileWindowRefresh();
}
windowDestroy(window);
2023-02-17 01:33:26 -08:00
messageListFree(&gPreferencesMessageList);
2022-05-19 01:51:26 -07:00
if (!a1) {
if (gameMouseWasVisible) {
gameMouseObjectsShow();
}
if (gOptionsWindowIsoWasEnabled) {
isoEnable();
}
colorCycleEnable();
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
}
fontSetCurrent(gOptionsWindowOldFont);
return 0;
}
// 0x490748
2022-06-18 08:25:13 -07:00
static void _ShadeScreen(bool a1)
2022-05-19 01:51:26 -07:00
{
if (a1) {
mouseHideCursor();
} else {
mouseHideCursor();
tileWindowRefresh();
2022-05-21 01:40:54 -07:00
int windowWidth = windowGetWidth(gIsoWindow);
2022-05-19 01:51:26 -07:00
int windowHeight = windowGetHeight(gIsoWindow);
unsigned char* windowBuffer = windowGetBuffer(gIsoWindow);
2022-05-21 01:40:54 -07:00
grayscalePaletteApply(windowBuffer, windowWidth, windowHeight, windowWidth);
2022-05-19 01:51:26 -07:00
windowRefresh(gIsoWindow);
}
mouseShowCursor();
}
// init_options_menu
// 0x4928B8
int _init_options_menu()
{
2023-02-17 01:33:26 -08:00
preferencesInit();
2022-05-19 01:51:26 -07:00
grayscalePaletteUpdate(0, 255);
return 0;
}
2022-09-23 05:43:44 -07:00
} // namespace fallout