2022-05-19 01:51:26 -07:00
|
|
|
#include "dbox.h"
|
|
|
|
|
2022-09-15 02:38:23 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "art.h"
|
2022-06-07 13:18:59 -07:00
|
|
|
#include "character_editor.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "color.h"
|
|
|
|
#include "core.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "game.h"
|
|
|
|
#include "game_sound.h"
|
|
|
|
#include "message.h"
|
2022-10-03 02:41:33 -07:00
|
|
|
#include "mouse.h"
|
2022-05-28 02:34:49 -07:00
|
|
|
#include "platform_compat.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "text_font.h"
|
|
|
|
#include "window_manager.h"
|
|
|
|
#include "word_wrap.h"
|
|
|
|
|
2022-09-23 05:43:44 -07:00
|
|
|
namespace fallout {
|
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
#define FILE_DIALOG_LINE_COUNT 12
|
|
|
|
|
|
|
|
#define FILE_DIALOG_DOUBLE_CLICK_DELAY 32
|
|
|
|
|
|
|
|
#define LOAD_FILE_DIALOG_DONE_BUTTON_X 58
|
|
|
|
#define LOAD_FILE_DIALOG_DONE_BUTTON_Y 187
|
|
|
|
|
|
|
|
#define LOAD_FILE_DIALOG_DONE_LABEL_X 79
|
|
|
|
#define LOAD_FILE_DIALOG_DONE_LABEL_Y 187
|
|
|
|
|
|
|
|
#define LOAD_FILE_DIALOG_CANCEL_BUTTON_X 163
|
|
|
|
#define LOAD_FILE_DIALOG_CANCEL_BUTTON_Y 187
|
|
|
|
|
|
|
|
#define LOAD_FILE_DIALOG_CANCEL_LABEL_X 182
|
|
|
|
#define LOAD_FILE_DIALOG_CANCEL_LABEL_Y 187
|
|
|
|
|
|
|
|
#define SAVE_FILE_DIALOG_DONE_BUTTON_X 58
|
|
|
|
#define SAVE_FILE_DIALOG_DONE_BUTTON_Y 214
|
|
|
|
|
|
|
|
#define SAVE_FILE_DIALOG_DONE_LABEL_X 79
|
|
|
|
#define SAVE_FILE_DIALOG_DONE_LABEL_Y 213
|
|
|
|
|
|
|
|
#define SAVE_FILE_DIALOG_CANCEL_BUTTON_X 163
|
|
|
|
#define SAVE_FILE_DIALOG_CANCEL_BUTTON_Y 214
|
|
|
|
|
|
|
|
#define SAVE_FILE_DIALOG_CANCEL_LABEL_X 182
|
|
|
|
#define SAVE_FILE_DIALOG_CANCEL_LABEL_Y 213
|
|
|
|
|
|
|
|
#define FILE_DIALOG_TITLE_X 49
|
|
|
|
#define FILE_DIALOG_TITLE_Y 16
|
|
|
|
|
|
|
|
#define FILE_DIALOG_SCROLL_BUTTON_X 36
|
|
|
|
#define FILE_DIALOG_SCROLL_BUTTON_Y 44
|
|
|
|
|
|
|
|
#define FILE_DIALOG_FILE_LIST_X 55
|
|
|
|
#define FILE_DIALOG_FILE_LIST_Y 49
|
|
|
|
#define FILE_DIALOG_FILE_LIST_WIDTH 190
|
|
|
|
#define FILE_DIALOG_FILE_LIST_HEIGHT 124
|
|
|
|
|
2022-06-18 06:12:07 -07:00
|
|
|
typedef enum DialogType {
|
|
|
|
DIALOG_TYPE_MEDIUM,
|
|
|
|
DIALOG_TYPE_LARGE,
|
|
|
|
DIALOG_TYPE_COUNT,
|
|
|
|
} DialogType;
|
|
|
|
|
|
|
|
typedef enum FileDialogFrm {
|
|
|
|
FILE_DIALOG_FRM_BACKGROUND,
|
|
|
|
FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL,
|
|
|
|
FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED,
|
|
|
|
FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL,
|
|
|
|
FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED,
|
|
|
|
FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL,
|
|
|
|
FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED,
|
|
|
|
FILE_DIALOG_FRM_COUNT,
|
|
|
|
} FileDialogFrm;
|
|
|
|
|
|
|
|
typedef enum FileDialogScrollDirection {
|
|
|
|
FILE_DIALOG_SCROLL_DIRECTION_NONE,
|
|
|
|
FILE_DIALOG_SCROLL_DIRECTION_UP,
|
|
|
|
FILE_DIALOG_SCROLL_DIRECTION_DOWN,
|
|
|
|
} FileDialogScrollDirection;
|
|
|
|
|
|
|
|
static void fileDialogRenderFileList(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch);
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x5108C8
|
2022-06-18 06:12:07 -07:00
|
|
|
static const int gDialogBoxBackgroundFrmIds[DIALOG_TYPE_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
218, // MEDIALOG.FRM - Medium generic dialog box
|
|
|
|
217, // LGDIALOG.FRM - Large generic dialog box
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x5108D0
|
2022-06-18 06:12:07 -07:00
|
|
|
static const int _ytable[DIALOG_TYPE_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
23,
|
|
|
|
27,
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x5108D8
|
2022-06-18 06:12:07 -07:00
|
|
|
static const int _xtable[DIALOG_TYPE_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
29,
|
|
|
|
29,
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x5108E0
|
2022-06-18 06:12:07 -07:00
|
|
|
static const int _doneY[DIALOG_TYPE_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
81,
|
|
|
|
98,
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x5108E8
|
2022-06-18 06:12:07 -07:00
|
|
|
static const int _doneX[DIALOG_TYPE_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
51,
|
|
|
|
37,
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x5108F0
|
2022-06-18 06:12:07 -07:00
|
|
|
static const int _dblines[DIALOG_TYPE_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
5,
|
|
|
|
6,
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x510900
|
2022-06-18 06:12:07 -07:00
|
|
|
static int gLoadFileDialogFrmIds[FILE_DIALOG_FRM_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
224, // loadbox.frm - character editor
|
|
|
|
8, // lilredup.frm - little red button up
|
|
|
|
9, // lilreddn.frm - little red button down
|
|
|
|
181, // dnarwoff.frm - character editor
|
|
|
|
182, // dnarwon.frm - character editor
|
|
|
|
199, // uparwoff.frm - character editor
|
|
|
|
200, // uparwon.frm - character editor
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x51091C
|
2022-06-18 06:12:07 -07:00
|
|
|
static int gSaveFileDialogFrmIds[FILE_DIALOG_FRM_COUNT] = {
|
2022-05-19 01:51:26 -07:00
|
|
|
225, // savebox.frm - character editor
|
|
|
|
8, // lilredup.frm - little red button up
|
|
|
|
9, // lilreddn.frm - little red button down
|
|
|
|
181, // dnarwoff.frm - character editor
|
|
|
|
182, // dnarwon.frm - character editor
|
|
|
|
199, // uparwoff.frm - character editor
|
|
|
|
200, // uparwon.frm - character editor
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0x41CF20
|
|
|
|
int showDialogBox(const char* title, const char** body, int bodyLength, int x, int y, int titleColor, const char* a8, int bodyColor, int flags)
|
|
|
|
{
|
|
|
|
MessageList messageList;
|
|
|
|
MessageListItem messageListItem;
|
|
|
|
int savedFont = fontGetCurrent();
|
|
|
|
|
|
|
|
bool v86 = false;
|
|
|
|
|
|
|
|
bool hasTwoButtons = false;
|
|
|
|
if (a8 != NULL) {
|
|
|
|
hasTwoButtons = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasTitle = false;
|
|
|
|
if (title != NULL) {
|
|
|
|
hasTitle = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & DIALOG_BOX_YES_NO) != 0) {
|
|
|
|
hasTwoButtons = true;
|
|
|
|
flags |= DIALOG_BOX_LARGE;
|
|
|
|
flags &= ~DIALOG_BOX_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
int maximumLineWidth = 0;
|
|
|
|
if (hasTitle) {
|
|
|
|
maximumLineWidth = fontGetStringWidth(title);
|
|
|
|
}
|
|
|
|
|
|
|
|
int linesCount = 0;
|
|
|
|
for (int index = 0; index < bodyLength; index++) {
|
|
|
|
// NOTE: Calls [fontGetStringWidth] twice because of [max] macro.
|
2022-05-28 04:45:48 -07:00
|
|
|
maximumLineWidth = std::max(fontGetStringWidth(body[index]), maximumLineWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
linesCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
int dialogType;
|
|
|
|
if ((flags & DIALOG_BOX_LARGE) != 0 || hasTwoButtons) {
|
|
|
|
dialogType = DIALOG_TYPE_LARGE;
|
|
|
|
} else if ((flags & DIALOG_BOX_MEDIUM) != 0) {
|
|
|
|
dialogType = DIALOG_TYPE_MEDIUM;
|
|
|
|
} else {
|
|
|
|
if (hasTitle) {
|
|
|
|
linesCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
dialogType = maximumLineWidth > 168 || linesCount > 5
|
|
|
|
? DIALOG_TYPE_LARGE
|
|
|
|
: DIALOG_TYPE_MEDIUM;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
FrmImage backgroundFrmImage;
|
|
|
|
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
|
|
|
|
if (!backgroundFrmImage.lock(backgroundFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-05-21 01:23:43 -07:00
|
|
|
// Maintain original position in original resolution, otherwise center it.
|
2022-09-24 09:41:25 -07:00
|
|
|
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundFrmImage.getWidth()) / 2;
|
|
|
|
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundFrmImage.getHeight()) / 2;
|
|
|
|
int win = windowCreate(x,
|
|
|
|
y,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getHeight(),
|
|
|
|
256,
|
|
|
|
WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (win == -1) {
|
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char* windowBuf = windowGetBuffer(win);
|
2022-09-24 09:41:25 -07:00
|
|
|
memcpy(windowBuf, backgroundFrmImage.getData(), backgroundFrmImage.getWidth() * backgroundFrmImage.getHeight());
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
FrmImage doneBoxFrmImage;
|
|
|
|
FrmImage buttonNormalFrmImage;
|
|
|
|
FrmImage buttonPressedFrmImage;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if ((flags & DIALOG_BOX_0x20) == 0) {
|
2022-07-29 06:04:05 -07:00
|
|
|
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
|
2022-09-24 09:41:25 -07:00
|
|
|
if (!doneBoxFrmImage.lock(doneBoxFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int pressedFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
|
|
|
if (!buttonPressedFrmImage.lock(pressedFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int normalFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
|
|
|
if (!buttonNormalFrmImage.lock(normalFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int v27 = hasTwoButtons
|
|
|
|
? _doneX[dialogType]
|
|
|
|
: (backgroundFrmImage.getWidth() - doneBoxFrmImage.getWidth()) / 2;
|
|
|
|
blitBufferToBuffer(doneBoxFrmImage.getData(),
|
|
|
|
doneBoxFrmImage.getWidth(),
|
|
|
|
doneBoxFrmImage.getHeight(),
|
|
|
|
doneBoxFrmImage.getWidth(),
|
|
|
|
windowBuf + backgroundFrmImage.getWidth() * _doneY[dialogType] + v27,
|
|
|
|
backgroundFrmImage.getWidth());
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (!messageListInit(&messageList)) {
|
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-05-28 02:34:49 -07:00
|
|
|
char path[COMPAT_MAX_PATH];
|
2022-05-19 01:51:26 -07:00
|
|
|
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
|
|
|
|
|
|
|
|
if (!messageListLoad(&messageList, path)) {
|
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
// FIXME: Window is not removed.
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(103);
|
|
|
|
|
|
|
|
// 100 - DONE
|
|
|
|
// 101 - YES
|
|
|
|
messageListItem.num = (flags & DIALOG_BOX_YES_NO) == 0 ? 100 : 101;
|
|
|
|
if (messageListGetItem(&messageList, &messageListItem)) {
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * (_doneY[dialogType] + 3) + v27 + 35,
|
|
|
|
messageListItem.text,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
_colorTable[18979]);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int btn = buttonCreate(win,
|
|
|
|
v27 + 13,
|
|
|
|
_doneY[dialogType] + 4,
|
|
|
|
buttonPressedFrmImage.getWidth(),
|
|
|
|
buttonPressedFrmImage.getHeight(),
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
500,
|
|
|
|
buttonNormalFrmImage.getData(),
|
|
|
|
buttonPressedFrmImage.getData(),
|
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (btn != -1) {
|
|
|
|
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
v86 = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasTwoButtons && dialogType == DIALOG_TYPE_LARGE) {
|
|
|
|
if (v86) {
|
|
|
|
if ((flags & DIALOG_BOX_YES_NO) != 0) {
|
|
|
|
a8 = getmsg(&messageList, &messageListItem, 102);
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(103);
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
blitBufferToBufferTrans(doneBoxFrmImage.getData(),
|
|
|
|
doneBoxFrmImage.getWidth(),
|
|
|
|
doneBoxFrmImage.getHeight(),
|
|
|
|
doneBoxFrmImage.getWidth(),
|
|
|
|
windowBuf + backgroundFrmImage.getWidth() * _doneY[dialogType] + _doneX[dialogType] + doneBoxFrmImage.getWidth() + 24,
|
|
|
|
backgroundFrmImage.getWidth());
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * (_doneY[dialogType] + 3) + _doneX[dialogType] + doneBoxFrmImage.getWidth() + 59,
|
|
|
|
a8,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
_colorTable[18979]);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
int btn = buttonCreate(win,
|
2022-09-24 09:41:25 -07:00
|
|
|
doneBoxFrmImage.getWidth() + _doneX[dialogType] + 37,
|
2022-05-19 01:51:26 -07:00
|
|
|
_doneY[dialogType] + 4,
|
2022-09-24 09:41:25 -07:00
|
|
|
buttonPressedFrmImage.getWidth(),
|
|
|
|
buttonPressedFrmImage.getHeight(),
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
501,
|
|
|
|
buttonNormalFrmImage.getData(),
|
|
|
|
buttonPressedFrmImage.getData(),
|
|
|
|
0,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (btn != -1) {
|
|
|
|
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
} else {
|
2022-07-29 06:04:05 -07:00
|
|
|
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
|
2022-09-24 09:41:25 -07:00
|
|
|
if (!doneBoxFrmImage.lock(doneBoxFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int pressedFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
|
|
|
if (!buttonPressedFrmImage.lock(pressedFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int normalFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
|
|
|
if (!buttonNormalFrmImage.lock(normalFid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!messageListInit(&messageList)) {
|
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-05-28 02:34:49 -07:00
|
|
|
char path[COMPAT_MAX_PATH];
|
2022-05-19 01:51:26 -07:00
|
|
|
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
|
|
|
|
|
|
|
|
if (!messageListLoad(&messageList, path)) {
|
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
blitBufferToBufferTrans(doneBoxFrmImage.getData(),
|
|
|
|
doneBoxFrmImage.getWidth(),
|
|
|
|
doneBoxFrmImage.getHeight(),
|
|
|
|
doneBoxFrmImage.getWidth(),
|
|
|
|
windowBuf + backgroundFrmImage.getWidth() * _doneY[dialogType] + _doneX[dialogType],
|
|
|
|
backgroundFrmImage.getWidth());
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
fontSetCurrent(103);
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * (_doneY[dialogType] + 3) + _doneX[dialogType] + 35,
|
|
|
|
a8, backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(), _colorTable[18979]);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
int btn = buttonCreate(win,
|
|
|
|
_doneX[dialogType] + 13,
|
|
|
|
_doneY[dialogType] + 4,
|
2022-09-24 09:41:25 -07:00
|
|
|
buttonPressedFrmImage.getWidth(),
|
|
|
|
buttonPressedFrmImage.getHeight(),
|
2022-05-19 01:51:26 -07:00
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
501,
|
2022-09-24 09:41:25 -07:00
|
|
|
buttonNormalFrmImage.getData(),
|
|
|
|
buttonPressedFrmImage.getData(),
|
2022-05-19 01:51:26 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (btn != -1) {
|
|
|
|
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
v86 = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(101);
|
|
|
|
|
|
|
|
int v23 = _ytable[dialogType];
|
|
|
|
|
|
|
|
if ((flags & DIALOG_BOX_NO_VERTICAL_CENTERING) == 0) {
|
|
|
|
int v41 = _dblines[dialogType] * fontGetLineHeight() / 2 + v23;
|
|
|
|
v23 = v41 - ((bodyLength + 1) * fontGetLineHeight() / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasTitle) {
|
|
|
|
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType],
|
|
|
|
title,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
titleColor);
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
|
|
|
int length = fontGetStringWidth(title);
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2,
|
|
|
|
title,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
titleColor);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
v23 += fontGetLineHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int v94 = 0; v94 < bodyLength; v94++) {
|
|
|
|
int len = fontGetStringWidth(body[v94]);
|
2022-09-24 09:41:25 -07:00
|
|
|
if (len <= backgroundFrmImage.getWidth() - 26) {
|
2022-05-19 01:51:26 -07:00
|
|
|
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType],
|
|
|
|
body[v94],
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
bodyColor);
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
|
|
|
int length = fontGetStringWidth(body[v94]);
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2,
|
|
|
|
body[v94],
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
bodyColor);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
v23 += fontGetLineHeight();
|
|
|
|
} else {
|
|
|
|
short beginnings[WORD_WRAP_MAX_COUNT];
|
|
|
|
short count;
|
2022-09-24 09:41:25 -07:00
|
|
|
if (wordWrap(body[v94], backgroundFrmImage.getWidth() - 26, beginnings, &count) != 0) {
|
2022-05-19 01:51:26 -07:00
|
|
|
debugPrint("\nError: dialog_out");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int v48 = 1; v48 < count; v48++) {
|
|
|
|
int v51 = beginnings[v48] - beginnings[v48 - 1];
|
|
|
|
if (v51 >= 260) {
|
|
|
|
v51 = 259;
|
|
|
|
}
|
|
|
|
|
|
|
|
char string[260];
|
|
|
|
strncpy(string, body[v94] + beginnings[v48 - 1], v51);
|
|
|
|
string[v51] = '\0';
|
|
|
|
|
|
|
|
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType],
|
|
|
|
string,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
bodyColor);
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
|
|
|
int length = fontGetStringWidth(string);
|
2022-09-24 09:41:25 -07:00
|
|
|
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2,
|
|
|
|
string,
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
bodyColor);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
v23 += fontGetLineHeight();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
windowRefresh(win);
|
|
|
|
|
|
|
|
int rc = -1;
|
|
|
|
while (rc == -1) {
|
|
|
|
int keyCode = _get_input();
|
|
|
|
|
|
|
|
if (keyCode == 500) {
|
|
|
|
rc = 1;
|
|
|
|
} else if (keyCode == KEY_RETURN) {
|
|
|
|
soundPlayFile("ib1p1xx1");
|
|
|
|
rc = 1;
|
|
|
|
} else if (keyCode == KEY_ESCAPE || keyCode == 501) {
|
|
|
|
rc = 0;
|
|
|
|
} else {
|
|
|
|
if ((flags & 0x10) != 0) {
|
|
|
|
if (keyCode == KEY_UPPERCASE_Y || keyCode == KEY_LOWERCASE_Y) {
|
|
|
|
rc = 1;
|
|
|
|
} else if (keyCode == KEY_UPPERCASE_N || keyCode == KEY_LOWERCASE_N) {
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_game_user_wants_to_quit != 0) {
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
windowDestroy(win);
|
|
|
|
fontSetCurrent(savedFont);
|
|
|
|
|
|
|
|
if (v86) {
|
|
|
|
messageListFree(&messageList);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
// 0x41DE90
|
2022-07-29 06:04:05 -07:00
|
|
|
int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
2022-06-07 13:18:59 -07:00
|
|
|
{
|
|
|
|
int oldFont = fontGetCurrent();
|
|
|
|
|
|
|
|
bool isScrollable = false;
|
|
|
|
if (fileListLength > FILE_DIALOG_LINE_COUNT) {
|
|
|
|
isScrollable = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int selectedFileIndex = 0;
|
|
|
|
int pageOffset = 0;
|
|
|
|
int maxPageOffset = fileListLength - (FILE_DIALOG_LINE_COUNT + 1);
|
|
|
|
if (maxPageOffset < 0) {
|
|
|
|
maxPageOffset = fileListLength - 1;
|
|
|
|
if (maxPageOffset < 0) {
|
|
|
|
maxPageOffset = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
FrmImage frmImages[FILE_DIALOG_FRM_COUNT];
|
2022-06-07 13:18:59 -07:00
|
|
|
|
|
|
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
2022-07-29 06:04:05 -07:00
|
|
|
int fid = buildFid(OBJ_TYPE_INTERFACE, gLoadFileDialogFrmIds[index], 0, 0, 0);
|
2022-09-24 09:41:25 -07:00
|
|
|
if (!frmImages[index].lock(fid)) {
|
2022-06-07 13:18:59 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int backgroundWidth = frmImages[FILE_DIALOG_FRM_BACKGROUND].getWidth();
|
|
|
|
int backgroundHeight = frmImages[FILE_DIALOG_FRM_BACKGROUND].getHeight();
|
2022-06-07 13:18:59 -07:00
|
|
|
|
|
|
|
// Maintain original position in original resolution, otherwise center it.
|
|
|
|
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
|
|
|
|
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
|
|
|
|
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
|
|
|
if (win == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
2022-09-24 09:41:25 -07:00
|
|
|
memcpy(windowBuffer, frmImages[FILE_DIALOG_FRM_BACKGROUND].getData(), backgroundWidth * backgroundHeight);
|
2022-06-07 13:18:59 -07:00
|
|
|
|
|
|
|
MessageList messageList;
|
|
|
|
MessageListItem messageListItem;
|
|
|
|
|
|
|
|
if (!messageListInit(&messageList)) {
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char path[COMPAT_MAX_PATH];
|
|
|
|
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
|
|
|
|
|
|
|
|
if (!messageListLoad(&messageList, path)) {
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(103);
|
|
|
|
|
|
|
|
// DONE
|
|
|
|
const char* done = getmsg(&messageList, &messageListItem, 100);
|
|
|
|
fontDrawText(windowBuffer + LOAD_FILE_DIALOG_DONE_LABEL_Y * backgroundWidth + LOAD_FILE_DIALOG_DONE_LABEL_X, done, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
|
|
|
|
|
|
|
// CANCEL
|
|
|
|
const char* cancel = getmsg(&messageList, &messageListItem, 103);
|
|
|
|
fontDrawText(windowBuffer + LOAD_FILE_DIALOG_CANCEL_LABEL_Y * backgroundWidth + LOAD_FILE_DIALOG_CANCEL_LABEL_X, cancel, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
|
|
|
|
|
|
|
int doneBtn = buttonCreate(win,
|
|
|
|
LOAD_FILE_DIALOG_DONE_BUTTON_X,
|
|
|
|
LOAD_FILE_DIALOG_DONE_BUTTON_Y,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
|
2022-06-07 13:18:59 -07:00
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
500,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
|
2022-06-07 13:18:59 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (doneBtn != -1) {
|
|
|
|
buttonSetCallbacks(doneBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
int cancelBtn = buttonCreate(win,
|
|
|
|
LOAD_FILE_DIALOG_CANCEL_BUTTON_X,
|
|
|
|
LOAD_FILE_DIALOG_CANCEL_BUTTON_Y,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
|
2022-06-07 13:18:59 -07:00
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
501,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
|
2022-06-07 13:18:59 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (cancelBtn != -1) {
|
|
|
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
int scrollUpBtn = buttonCreate(win,
|
|
|
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
|
|
|
FILE_DIALOG_SCROLL_BUTTON_Y,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
|
2022-06-07 13:18:59 -07:00
|
|
|
-1,
|
|
|
|
505,
|
|
|
|
506,
|
|
|
|
505,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getData(),
|
2022-06-07 13:18:59 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (scrollUpBtn != -1) {
|
|
|
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
int scrollDownButton = buttonCreate(win,
|
|
|
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
2022-09-24 09:41:25 -07:00
|
|
|
FILE_DIALOG_SCROLL_BUTTON_Y + frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getHeight(),
|
2022-06-07 13:18:59 -07:00
|
|
|
-1,
|
|
|
|
503,
|
|
|
|
504,
|
|
|
|
503,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getData(),
|
2022-06-07 13:18:59 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (scrollUpBtn != -1) {
|
|
|
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
buttonCreate(
|
|
|
|
win,
|
|
|
|
FILE_DIALOG_FILE_LIST_X,
|
|
|
|
FILE_DIALOG_FILE_LIST_Y,
|
|
|
|
FILE_DIALOG_FILE_LIST_WIDTH,
|
|
|
|
FILE_DIALOG_FILE_LIST_HEIGHT,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
502,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (title != NULL) {
|
|
|
|
fontDrawText(windowBuffer + backgroundWidth * FILE_DIALOG_TITLE_Y + FILE_DIALOG_TITLE_X, title, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(101);
|
|
|
|
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
windowRefresh(win);
|
|
|
|
|
|
|
|
int doubleClickSelectedFileIndex = -2;
|
|
|
|
int doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
|
|
|
|
|
|
|
int rc = -1;
|
|
|
|
while (rc == -1) {
|
|
|
|
unsigned int tick = _get_time();
|
|
|
|
int keyCode = _get_input();
|
|
|
|
int scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_NONE;
|
|
|
|
int scrollCounter = 0;
|
|
|
|
bool isScrolling = false;
|
|
|
|
|
2022-08-07 04:52:44 -07:00
|
|
|
convertMouseWheelToArrowKey(&keyCode);
|
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
if (keyCode == 500) {
|
|
|
|
if (fileListLength != 0) {
|
|
|
|
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
|
|
|
|
rc = 0;
|
|
|
|
} else {
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
} else if (keyCode == 501 || keyCode == KEY_ESCAPE) {
|
|
|
|
rc = 1;
|
|
|
|
} else if (keyCode == 502 && fileListLength != 0) {
|
|
|
|
int mouseX;
|
|
|
|
int mouseY;
|
|
|
|
mouseGetPosition(&mouseX, &mouseY);
|
|
|
|
|
|
|
|
int selectedLine = (mouseY - y - FILE_DIALOG_FILE_LIST_Y) / fontGetLineHeight();
|
|
|
|
if (selectedLine - 1 < 0) {
|
|
|
|
selectedLine = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isScrollable || selectedLine < fileListLength) {
|
|
|
|
if (selectedLine >= FILE_DIALOG_LINE_COUNT) {
|
|
|
|
selectedLine = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selectedLine = fileListLength - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
selectedFileIndex = selectedLine;
|
|
|
|
if (selectedFileIndex == doubleClickSelectedFileIndex) {
|
|
|
|
soundPlayFile("ib1p1xx1");
|
|
|
|
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
doubleClickSelectedFileIndex = selectedFileIndex;
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
} else if (keyCode == 506) {
|
|
|
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_UP;
|
|
|
|
} else if (keyCode == 504) {
|
|
|
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_DOWN;
|
|
|
|
} else {
|
|
|
|
switch (keyCode) {
|
|
|
|
case KEY_ARROW_UP:
|
|
|
|
pageOffset--;
|
|
|
|
if (pageOffset < 0) {
|
|
|
|
selectedFileIndex--;
|
|
|
|
if (selectedFileIndex < 0) {
|
|
|
|
selectedFileIndex = 0;
|
|
|
|
}
|
|
|
|
pageOffset = 0;
|
|
|
|
}
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
case KEY_ARROW_DOWN:
|
|
|
|
if (isScrollable) {
|
|
|
|
pageOffset++;
|
|
|
|
// FIXME: Should be >= maxPageOffset (as in save dialog).
|
|
|
|
// Otherwise out of bounds index is considered selected.
|
|
|
|
if (pageOffset > maxPageOffset) {
|
|
|
|
selectedFileIndex++;
|
|
|
|
// FIXME: Should be >= FILE_DIALOG_LINE_COUNT (as in
|
|
|
|
// save dialog). Otherwise out of bounds index is
|
|
|
|
// considered selected.
|
|
|
|
if (selectedFileIndex > FILE_DIALOG_LINE_COUNT) {
|
|
|
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
}
|
|
|
|
pageOffset = maxPageOffset;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex > maxPageOffset) {
|
|
|
|
selectedFileIndex = maxPageOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
case KEY_HOME:
|
|
|
|
selectedFileIndex = 0;
|
|
|
|
pageOffset = 0;
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
case KEY_END:
|
|
|
|
if (isScrollable) {
|
|
|
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
pageOffset = maxPageOffset;
|
|
|
|
} else {
|
|
|
|
selectedFileIndex = maxPageOffset;
|
|
|
|
pageOffset = 0;
|
|
|
|
}
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrollDirection != FILE_DIALOG_SCROLL_DIRECTION_NONE) {
|
|
|
|
unsigned int scrollDelay = 4;
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
while (1) {
|
|
|
|
unsigned int scrollTick = _get_time();
|
|
|
|
scrollCounter += 1;
|
|
|
|
if ((!isScrolling && scrollCounter == 1) || (isScrolling && scrollCounter > 14.4)) {
|
|
|
|
isScrolling = true;
|
|
|
|
|
|
|
|
if (scrollCounter > 14.4) {
|
|
|
|
scrollDelay += 1;
|
|
|
|
if (scrollDelay > 24) {
|
|
|
|
scrollDelay = 24;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrollDirection == FILE_DIALOG_SCROLL_DIRECTION_UP) {
|
|
|
|
pageOffset--;
|
|
|
|
if (pageOffset < 0) {
|
|
|
|
selectedFileIndex--;
|
|
|
|
if (selectedFileIndex < 0) {
|
|
|
|
selectedFileIndex = 0;
|
|
|
|
}
|
|
|
|
pageOffset = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (isScrollable) {
|
|
|
|
pageOffset++;
|
|
|
|
if (pageOffset > maxPageOffset) {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex >= FILE_DIALOG_LINE_COUNT) {
|
|
|
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
}
|
|
|
|
pageOffset = maxPageOffset;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex > maxPageOffset) {
|
|
|
|
selectedFileIndex = maxPageOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
windowRefresh(win);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int delay = (scrollCounter > 14.4) ? 1000 / scrollDelay : 1000 / 24;
|
|
|
|
while (getTicksSince(scrollTick) < delay) {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_game_user_wants_to_quit != 0) {
|
|
|
|
rc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
int keyCode = _get_input();
|
|
|
|
if (keyCode == 505 || keyCode == 503) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
windowRefresh(win);
|
|
|
|
|
|
|
|
doubleClickTimer--;
|
|
|
|
if (doubleClickTimer == 0) {
|
|
|
|
doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (getTicksSince(tick) < (1000 / 24)) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_game_user_wants_to_quit) {
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
windowDestroy(win);
|
|
|
|
|
|
|
|
messageListFree(&messageList);
|
|
|
|
fontSetCurrent(oldFont);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x41EA78
|
2022-06-07 13:18:59 -07:00
|
|
|
int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int oldFont = fontGetCurrent();
|
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
bool isScrollable = false;
|
|
|
|
if (fileListLength > FILE_DIALOG_LINE_COUNT) {
|
|
|
|
isScrollable = true;
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
int selectedFileIndex = 0;
|
|
|
|
int pageOffset = 0;
|
|
|
|
int maxPageOffset = fileListLength - (FILE_DIALOG_LINE_COUNT + 1);
|
|
|
|
if (maxPageOffset < 0) {
|
|
|
|
maxPageOffset = fileListLength - 1;
|
|
|
|
if (maxPageOffset < 0) {
|
|
|
|
maxPageOffset = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
FrmImage frmImages[FILE_DIALOG_FRM_COUNT];
|
2022-06-07 13:18:59 -07:00
|
|
|
|
|
|
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
2022-07-29 06:04:05 -07:00
|
|
|
int fid = buildFid(OBJ_TYPE_INTERFACE, gSaveFileDialogFrmIds[index], 0, 0, 0);
|
2022-09-24 09:41:25 -07:00
|
|
|
if (!frmImages[index].lock(fid)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-24 09:41:25 -07:00
|
|
|
int backgroundWidth = frmImages[FILE_DIALOG_FRM_BACKGROUND].getWidth();
|
|
|
|
int backgroundHeight = frmImages[FILE_DIALOG_FRM_BACKGROUND].getHeight();
|
2022-06-07 13:18:59 -07:00
|
|
|
|
|
|
|
// Maintain original position in original resolution, otherwise center it.
|
|
|
|
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
|
|
|
|
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
|
|
|
|
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (win == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
2022-09-24 09:41:25 -07:00
|
|
|
memcpy(windowBuffer, frmImages[FILE_DIALOG_FRM_BACKGROUND].getData(), backgroundWidth * backgroundHeight);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
MessageList messageList;
|
|
|
|
MessageListItem messageListItem;
|
|
|
|
|
|
|
|
if (!messageListInit(&messageList)) {
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-05-28 02:34:49 -07:00
|
|
|
char path[COMPAT_MAX_PATH];
|
2022-05-19 01:51:26 -07:00
|
|
|
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
|
|
|
|
|
|
|
|
if (!messageListLoad(&messageList, path)) {
|
|
|
|
windowDestroy(win);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(103);
|
|
|
|
|
|
|
|
// DONE
|
|
|
|
const char* done = getmsg(&messageList, &messageListItem, 100);
|
2022-06-07 13:18:59 -07:00
|
|
|
fontDrawText(windowBuffer + backgroundWidth * SAVE_FILE_DIALOG_DONE_LABEL_Y + SAVE_FILE_DIALOG_DONE_LABEL_X, done, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// CANCEL
|
|
|
|
const char* cancel = getmsg(&messageList, &messageListItem, 103);
|
2022-06-07 13:18:59 -07:00
|
|
|
fontDrawText(windowBuffer + backgroundWidth * SAVE_FILE_DIALOG_CANCEL_LABEL_Y + SAVE_FILE_DIALOG_CANCEL_LABEL_X, cancel, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
int doneBtn = buttonCreate(win,
|
2022-06-07 13:18:59 -07:00
|
|
|
SAVE_FILE_DIALOG_DONE_BUTTON_X,
|
|
|
|
SAVE_FILE_DIALOG_DONE_BUTTON_Y,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
|
2022-05-19 01:51:26 -07:00
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
500,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].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);
|
|
|
|
}
|
|
|
|
|
|
|
|
int cancelBtn = buttonCreate(win,
|
2022-06-07 13:18:59 -07:00
|
|
|
SAVE_FILE_DIALOG_CANCEL_BUTTON_X,
|
|
|
|
SAVE_FILE_DIALOG_CANCEL_BUTTON_Y,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
|
2022-05-19 01:51:26 -07:00
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
501,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
|
2022-05-19 01:51:26 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (cancelBtn != -1) {
|
|
|
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
int scrollUpBtn = buttonCreate(win,
|
2022-06-07 13:18:59 -07:00
|
|
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
|
|
|
FILE_DIALOG_SCROLL_BUTTON_Y,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
|
2022-05-19 01:51:26 -07:00
|
|
|
-1,
|
|
|
|
505,
|
|
|
|
506,
|
|
|
|
505,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getData(),
|
2022-05-19 01:51:26 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (scrollUpBtn != -1) {
|
|
|
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
int scrollDownButton = buttonCreate(win,
|
2022-06-07 13:18:59 -07:00
|
|
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
2022-09-24 09:41:25 -07:00
|
|
|
FILE_DIALOG_SCROLL_BUTTON_Y + frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getWidth(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getHeight(),
|
2022-05-19 01:51:26 -07:00
|
|
|
-1,
|
|
|
|
503,
|
|
|
|
504,
|
|
|
|
503,
|
2022-09-24 09:41:25 -07:00
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL].getData(),
|
|
|
|
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getData(),
|
2022-05-19 01:51:26 -07:00
|
|
|
NULL,
|
|
|
|
BUTTON_FLAG_TRANSPARENT);
|
|
|
|
if (scrollUpBtn != -1) {
|
|
|
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
buttonCreate(
|
|
|
|
win,
|
2022-06-07 13:18:59 -07:00
|
|
|
FILE_DIALOG_FILE_LIST_X,
|
|
|
|
FILE_DIALOG_FILE_LIST_Y,
|
|
|
|
FILE_DIALOG_FILE_LIST_WIDTH,
|
|
|
|
FILE_DIALOG_FILE_LIST_HEIGHT,
|
2022-05-19 01:51:26 -07:00
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
502,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
if (title != NULL) {
|
|
|
|
fontDrawText(windowBuffer + backgroundWidth * FILE_DIALOG_TITLE_Y + FILE_DIALOG_TITLE_X, title, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(101);
|
|
|
|
|
|
|
|
int cursorHeight = fontGetLineHeight();
|
|
|
|
int cursorWidth = fontGetStringWidth("_") - 4;
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
|
|
|
|
int fileNameLength = 0;
|
|
|
|
char* pch = dest;
|
|
|
|
while (*pch != '\0' && *pch != '.') {
|
|
|
|
fileNameLength++;
|
|
|
|
if (fileNameLength >= 12) {
|
|
|
|
break;
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-06-07 13:18:59 -07:00
|
|
|
dest[fileNameLength] = '\0';
|
|
|
|
|
|
|
|
char fileNameCopy[32];
|
|
|
|
strncpy(fileNameCopy, dest, 32);
|
2022-07-29 06:04:05 -07:00
|
|
|
|
2022-09-24 09:43:27 -07:00
|
|
|
size_t fileNameCopyLength = strlen(fileNameCopy);
|
2022-06-07 13:18:59 -07:00
|
|
|
fileNameCopy[fileNameCopyLength + 1] = '\0';
|
|
|
|
fileNameCopy[fileNameCopyLength] = ' ';
|
|
|
|
|
|
|
|
unsigned char* fileNameBufferPtr = windowBuffer + backgroundWidth * 190 + 57;
|
|
|
|
|
|
|
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
|
|
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
|
|
|
|
|
|
|
windowRefresh(win);
|
|
|
|
|
|
|
|
int blinkingCounter = 3;
|
|
|
|
bool blink = false;
|
|
|
|
|
|
|
|
int doubleClickSelectedFileIndex = -2;
|
|
|
|
int doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
|
|
|
|
|
|
|
int rc = -1;
|
|
|
|
while (rc == -1) {
|
|
|
|
unsigned int tick = _get_time();
|
|
|
|
int keyCode = _get_input();
|
|
|
|
int scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_NONE;
|
|
|
|
int scrollCounter = 0;
|
|
|
|
bool isScrolling = false;
|
|
|
|
|
2022-08-07 04:52:44 -07:00
|
|
|
convertMouseWheelToArrowKey(&keyCode);
|
|
|
|
|
2022-06-07 13:18:59 -07:00
|
|
|
if (keyCode == 500) {
|
|
|
|
rc = 0;
|
|
|
|
} else if (keyCode == KEY_RETURN) {
|
|
|
|
soundPlayFile("ib1p1xx1");
|
|
|
|
rc = 0;
|
|
|
|
} else if (keyCode == 501 || keyCode == KEY_ESCAPE) {
|
|
|
|
rc = 1;
|
|
|
|
} else if ((keyCode == KEY_DELETE || keyCode == KEY_BACKSPACE) && fileNameCopyLength > 0) {
|
|
|
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
|
|
|
fileNameCopy[fileNameCopyLength - 1] = ' ';
|
|
|
|
fileNameCopy[fileNameCopyLength] = '\0';
|
|
|
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
|
|
|
fileNameCopyLength--;
|
|
|
|
windowRefresh(win);
|
|
|
|
} else if (keyCode < KEY_FIRST_INPUT_CHARACTER || keyCode > KEY_LAST_INPUT_CHARACTER || fileNameCopyLength >= 8) {
|
|
|
|
if (keyCode == 502 && fileListLength != 0) {
|
|
|
|
int mouseX;
|
|
|
|
int mouseY;
|
|
|
|
mouseGetPosition(&mouseX, &mouseY);
|
|
|
|
|
|
|
|
int selectedLine = (mouseY - y - FILE_DIALOG_FILE_LIST_Y) / fontGetLineHeight();
|
|
|
|
if (selectedLine - 1 < 0) {
|
|
|
|
selectedLine = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isScrollable || selectedLine < fileListLength) {
|
|
|
|
if (selectedLine >= FILE_DIALOG_LINE_COUNT) {
|
|
|
|
selectedLine = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selectedLine = fileListLength - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
selectedFileIndex = selectedLine;
|
|
|
|
if (selectedFileIndex == doubleClickSelectedFileIndex) {
|
|
|
|
soundPlayFile("ib1p1xx1");
|
|
|
|
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
|
|
|
|
|
|
|
|
int index;
|
|
|
|
for (index = 0; index < 12; index++) {
|
|
|
|
if (dest[index] == '.' || dest[index] == '\0') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dest[index] = '\0';
|
|
|
|
rc = 2;
|
|
|
|
} else {
|
|
|
|
doubleClickSelectedFileIndex = selectedFileIndex;
|
|
|
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
|
|
|
strncpy(fileNameCopy, fileList[selectedFileIndex + pageOffset], 16);
|
|
|
|
|
|
|
|
int index;
|
|
|
|
for (index = 0; index < 12; index++) {
|
|
|
|
if (fileNameCopy[index] == '.' || fileNameCopy[index] == '\0') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileNameCopy[index] = '\0';
|
|
|
|
fileNameCopyLength = strlen(fileNameCopy);
|
|
|
|
fileNameCopy[fileNameCopyLength] = ' ';
|
|
|
|
fileNameCopy[fileNameCopyLength + 1] = '\0';
|
|
|
|
|
|
|
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
}
|
|
|
|
} else if (keyCode == 506) {
|
|
|
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_UP;
|
|
|
|
} else if (keyCode == 504) {
|
|
|
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_DOWN;
|
|
|
|
} else {
|
|
|
|
switch (keyCode) {
|
|
|
|
case KEY_ARROW_UP:
|
|
|
|
pageOffset--;
|
|
|
|
if (pageOffset < 0) {
|
|
|
|
selectedFileIndex--;
|
|
|
|
if (selectedFileIndex < 0) {
|
|
|
|
selectedFileIndex = 0;
|
|
|
|
}
|
|
|
|
pageOffset = 0;
|
|
|
|
}
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
case KEY_ARROW_DOWN:
|
|
|
|
if (isScrollable) {
|
|
|
|
pageOffset++;
|
|
|
|
if (pageOffset >= maxPageOffset) {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex >= FILE_DIALOG_LINE_COUNT) {
|
|
|
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
}
|
|
|
|
pageOffset = maxPageOffset;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex > maxPageOffset) {
|
|
|
|
selectedFileIndex = maxPageOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
case KEY_HOME:
|
|
|
|
selectedFileIndex = 0;
|
|
|
|
pageOffset = 0;
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
case KEY_END:
|
|
|
|
if (isScrollable) {
|
|
|
|
selectedFileIndex = 11;
|
|
|
|
pageOffset = maxPageOffset;
|
|
|
|
} else {
|
|
|
|
selectedFileIndex = maxPageOffset;
|
|
|
|
pageOffset = 0;
|
|
|
|
}
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (_isdoschar(keyCode)) {
|
|
|
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
|
|
|
|
|
|
|
fileNameCopy[fileNameCopyLength] = keyCode & 0xFF;
|
|
|
|
fileNameCopy[fileNameCopyLength + 1] = ' ';
|
|
|
|
fileNameCopy[fileNameCopyLength + 2] = '\0';
|
|
|
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
|
|
|
fileNameCopyLength++;
|
|
|
|
|
|
|
|
windowRefresh(win);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrollDirection != FILE_DIALOG_SCROLL_DIRECTION_NONE) {
|
|
|
|
unsigned int scrollDelay = 4;
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
while (1) {
|
|
|
|
unsigned int scrollTick = _get_time();
|
|
|
|
scrollCounter += 1;
|
|
|
|
if ((!isScrolling && scrollCounter == 1) || (isScrolling && scrollCounter > 14.4)) {
|
|
|
|
isScrolling = true;
|
|
|
|
|
|
|
|
if (scrollCounter > 14.4) {
|
|
|
|
scrollDelay += 1;
|
|
|
|
if (scrollDelay > 24) {
|
|
|
|
scrollDelay = 24;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrollDirection == FILE_DIALOG_SCROLL_DIRECTION_UP) {
|
|
|
|
pageOffset--;
|
|
|
|
if (pageOffset < 0) {
|
|
|
|
selectedFileIndex--;
|
|
|
|
if (selectedFileIndex < 0) {
|
|
|
|
selectedFileIndex = 0;
|
|
|
|
}
|
|
|
|
pageOffset = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (isScrollable) {
|
|
|
|
pageOffset++;
|
|
|
|
if (pageOffset > maxPageOffset) {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex >= FILE_DIALOG_LINE_COUNT) {
|
|
|
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
|
|
|
}
|
|
|
|
pageOffset = maxPageOffset;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selectedFileIndex++;
|
|
|
|
if (selectedFileIndex > maxPageOffset) {
|
|
|
|
selectedFileIndex = maxPageOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
|
|
|
windowRefresh(win);
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Original code is slightly different. For unknown reason
|
|
|
|
// entire blinking stuff is placed into two different branches,
|
|
|
|
// which only differs by amount of delay. Probably result of
|
|
|
|
// using large blinking macro as there are no traces of inlined
|
|
|
|
// function.
|
|
|
|
blinkingCounter -= 1;
|
|
|
|
if (blinkingCounter == 0) {
|
|
|
|
blinkingCounter = 3;
|
|
|
|
|
|
|
|
int color = blink ? 100 : _colorTable[992];
|
|
|
|
blink = !blink;
|
|
|
|
|
|
|
|
bufferFill(fileNameBufferPtr + fontGetStringWidth(fileNameCopy) - cursorWidth, cursorWidth, cursorHeight - 2, backgroundWidth, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Missing windowRefresh makes blinking useless.
|
|
|
|
|
|
|
|
unsigned int delay = (scrollCounter > 14.4) ? 1000 / scrollDelay : 1000 / 24;
|
|
|
|
while (getTicksSince(scrollTick) < delay) {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_game_user_wants_to_quit != 0) {
|
|
|
|
rc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
int key = _get_input();
|
|
|
|
if (key == 505 || key == 503) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
blinkingCounter -= 1;
|
|
|
|
if (blinkingCounter == 0) {
|
|
|
|
blinkingCounter = 3;
|
|
|
|
|
|
|
|
int color = blink ? 100 : _colorTable[992];
|
|
|
|
blink = !blink;
|
|
|
|
|
|
|
|
bufferFill(fileNameBufferPtr + fontGetStringWidth(fileNameCopy) - cursorWidth, cursorWidth, cursorHeight - 2, backgroundWidth, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
windowRefresh(win);
|
|
|
|
|
|
|
|
doubleClickTimer--;
|
|
|
|
if (doubleClickTimer == 0) {
|
|
|
|
doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
|
|
|
doubleClickSelectedFileIndex = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (getTicksSince(tick) < (1000 / 24)) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_game_user_wants_to_quit != 0) {
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rc == 0) {
|
|
|
|
if (fileNameCopyLength != 0) {
|
|
|
|
fileNameCopy[fileNameCopyLength] = '\0';
|
|
|
|
strcpy(dest, fileNameCopy);
|
|
|
|
} else {
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (rc == 2) {
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
windowDestroy(win);
|
|
|
|
messageListFree(&messageList);
|
|
|
|
fontSetCurrent(oldFont);
|
|
|
|
|
|
|
|
return rc;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x41FBDC
|
2022-06-18 06:12:07 -07:00
|
|
|
static void fileDialogRenderFileList(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int lineHeight = fontGetLineHeight();
|
2022-06-07 13:18:59 -07:00
|
|
|
int y = FILE_DIALOG_FILE_LIST_Y;
|
|
|
|
bufferFill(buffer + y * pitch + FILE_DIALOG_FILE_LIST_X, FILE_DIALOG_FILE_LIST_WIDTH, FILE_DIALOG_FILE_LIST_HEIGHT, pitch, 100);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (fileListLength != 0) {
|
2022-06-07 13:18:59 -07:00
|
|
|
if (fileListLength - pageOffset > FILE_DIALOG_LINE_COUNT) {
|
|
|
|
fileListLength = FILE_DIALOG_LINE_COUNT;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int index = 0; index < fileListLength; index++) {
|
|
|
|
int color = index == selectedIndex ? _colorTable[32747] : _colorTable[992];
|
2022-06-07 13:18:59 -07:00
|
|
|
fontDrawText(buffer + pitch * y + FILE_DIALOG_FILE_LIST_X, fileList[pageOffset + index], pitch, pitch, color);
|
2022-05-19 01:51:26 -07:00
|
|
|
y += lineHeight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-23 05:43:44 -07:00
|
|
|
|
|
|
|
} // namespace fallout
|