[script-command, dynmultichoice] add shouldSort, initialSelected arguments. read pushed arguments front to back

This commit is contained in:
sbird 2023-01-16 22:40:36 +01:00
parent 569fa0a60a
commit 276ce62d95
6 changed files with 61 additions and 28 deletions

View File

@ -1729,29 +1729,35 @@
.2byte \quantity
.endm
@ Displays a multichoice box from which the user can choose a selection, and blocks script execution until a selection is made.
@ Lists of options are provided in argv.
@ If ignoreBPress is set to a non-zero value, then the user will not be allowed to back out of the multichoice with the B button.
.macro dynmultichoice left:req, top:req, ignoreBPress:req, maxBeforeScroll:req argv:vararg
.macro _dynmultichoice left:req, top:req, ignoreBPress:req, maxBeforeScroll:req, shouldSort:req, initialSelected:req argv:vararg
.byte 0xe3
.byte \left
.byte \top
.byte \ignoreBPress
.byte \maxBeforeScroll
.byte \shouldSort
.2byte \initialSelected
.byte (.Ldynmultichoice_\@_2 - .Ldynmultichoice_\@_1) / 4
.Ldynmultichoice_\@_1:
.4byte \argv
.Ldynmultichoice_\@_2:
.endm
@ Displays a multichoice box from which the user can choose a selection, and blocks script execution until a selection is made.
@ Lists of options are provided in argv.
@ If ignoreBPress is set to a non-zero value, then the user will not be allowed to back out of the multichoice with the B button.
.macro dynmultichoice left:req, top:req, ignoreBPress:req, maxBeforeScroll:req, shouldSort:req, initialSelected:req argv:vararg
_dynamicmultichoice \left, \top, \ignoreBPress, \maxBeforeScroll, FALSE, \initialSelected, \argv
.endm
.macro dynmultipush name:req, id:req
.byte 0xe4
.4byte \name
.byte \id
.endm
.macro dynmultistack left:req, top:req, ignoreBPress:req, maxBeforeScroll:req
dynmultichoice \left, \top, \ignoreBPress, \maxBeforeScroll, NULL
.macro dynmultistack left:req, top:req, ignoreBPress:req, maxBeforeScroll:req, shouldSort:req, initialSelected:req
_dynmultichoice \left, \top, \ignoreBPress, \maxBeforeScroll, \shouldSort, \initialSelected, NULL
.endm

View File

@ -126,5 +126,7 @@ u8 AddScrollIndicatorArrowPair(const struct ScrollArrowsTemplate *arrowInfo, u16
u8 AddScrollIndicatorArrowPairParameterized(u32 arrowType, s32 commonPos, s32 firstPos, s32 secondPos, s32 fullyDownThreshold, s32 tileTag, s32 palTag, u16 *currItemPtr);
void RemoveScrollIndicatorArrowPair(u8 taskId);
void Task_ScrollIndicatorArrowPairOnMainMenu(u8 taskId);
bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAndCallCallback, u8 count, bool8 movingDown);
bool8 ListMenuChangeSelectionFull(struct ListMenu *list, bool32 updateCursor, bool32 callCallback, u8 count, bool8 movingDown);
#endif //GUARD_LIST_MENU_H

View File

@ -27,8 +27,9 @@ u32 MultichoiceDynamic_StackSize(void);
void MultichoiceDynamic_PushElement(struct ListMenuItem item);
struct ListMenuItem *MultichoiceDynamic_PopElement(void);
struct ListMenuItem *MultichoiceDynamic_PeekElement(void);
struct ListMenuItem *MultichoiceDynamic_PeekElementAt(u32 index);
void MultichoiceDynamic_DestroyStack(void);
bool8 ScriptMenu_MultichoiceDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u8 maxBeforeScroll);
bool8 ScriptMenu_MultichoiceDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u8 maxBeforeScroll, u32 initialRow);
bool8 ScriptMenu_Multichoice(u8 left, u8 top, u8 multichoiceId, bool8 ignoreBPress);
bool8 ScriptMenu_MultichoiceWithDefault(u8 left, u8 top, u8 multichoiceId, bool8 ignoreBPress, u8 defaultChoice);
bool8 ScriptMenu_YesNo(u8 left, u8 top);

View File

@ -70,7 +70,6 @@ struct RedArrowCursor
// this file's functions
static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow);
static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAndCallCallback, u8 count, bool8 movingDown);
static void ListMenuPrintEntries(struct ListMenu *list, u16 startIndex, u16 yOffset, u16 count);
static void ListMenuDrawCursor(struct ListMenu *list);
static void ListMenuCallSelectionChangedCallback(struct ListMenu *list, u8 onInit);
@ -837,7 +836,7 @@ static void ListMenuScroll(struct ListMenu *list, u8 count, bool8 movingDown)
}
}
static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAndCallCallback, u8 count, bool8 movingDown)
bool8 ListMenuChangeSelectionFull(struct ListMenu *list, bool32 updateCursor, bool32 callCallback, u8 count, bool8 movingDown)
{
u16 oldSelectedRow;
u8 selectionChange, i, cursorCount;
@ -857,7 +856,7 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
} while (list->template.items[list->scrollOffset + list->selectedRow].id == LIST_HEADER);
}
if (updateCursorAndCallCallback)
if (updateCursor)
{
switch (selectionChange)
{
@ -867,7 +866,8 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
case 1:
ListMenuErasePrintedCursor(list, oldSelectedRow);
ListMenuDrawCursor(list);
ListMenuCallSelectionChangedCallback(list, FALSE);
if (callCallback)
ListMenuCallSelectionChangedCallback(list, FALSE);
CopyWindowToVram(list->template.windowId, COPYWIN_GFX);
break;
case 2:
@ -875,7 +875,8 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
ListMenuErasePrintedCursor(list, oldSelectedRow);
ListMenuScroll(list, cursorCount, movingDown);
ListMenuDrawCursor(list);
ListMenuCallSelectionChangedCallback(list, FALSE);
if (callCallback)
ListMenuCallSelectionChangedCallback(list, FALSE);
CopyWindowToVram(list->template.windowId, COPYWIN_GFX);
break;
}
@ -884,6 +885,11 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
return FALSE;
}
bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAndCallCallback, u8 count, bool8 movingDown)
{
ListMenuChangeSelectionFull(list, updateCursorAndCallCallback, updateCursorAndCallCallback, count, movingDown);
}
static void ListMenuCallSelectionChangedCallback(struct ListMenu *list, u8 onInit)
{
if (list->template.moveCursorFunc != NULL)

View File

@ -1376,12 +1376,15 @@ static void DynamicMultichoiceSortList(struct ListMenuItem *items, u32 count)
bool8 ScrCmd_dynmultichoice(struct ScriptContext *ctx)
{
u32 i;
u8 left = ScriptReadByte(ctx);
u8 top = ScriptReadByte(ctx);
bool8 ignoreBPress = ScriptReadByte(ctx);
u8 maxBeforeScroll = ScriptReadByte(ctx);
u32 left = ScriptReadByte(ctx);
u32 top = ScriptReadByte(ctx);
bool32 ignoreBPress = ScriptReadByte(ctx);
u32 maxBeforeScroll = ScriptReadByte(ctx);
bool32 shouldSort = ScriptReadByte(ctx);
u32 initialSelected = VarGet(ScriptReadHalfword(ctx));
u32 initialRow = 0;
// Read vararg
u8 argc = ScriptReadByte(ctx);
u32 argc = ScriptReadByte(ctx);
struct ListMenuItem *items;
if (argc == 0)
@ -1400,6 +1403,8 @@ bool8 ScrCmd_dynmultichoice(struct ScriptContext *ctx)
StringExpandPlaceholders(nameBuffer, arg);
items[i].name = nameBuffer;
items[i].id = i;
if (i == initialSelected)
initialRow = i;
}
}
else
@ -1409,16 +1414,19 @@ bool8 ScrCmd_dynmultichoice(struct ScriptContext *ctx)
for (i = 0; i < argc; ++i)
{
u8 *nameBuffer = Alloc(100);
struct ListMenuItem *currentItem = MultichoiceDynamic_PopElement();
struct ListMenuItem *currentItem = MultichoiceDynamic_PeekElementAt(i);
StringExpandPlaceholders(nameBuffer, currentItem->name);
items[i].name = nameBuffer;
items[i].id = currentItem->id;
if (currentItem->id == initialSelected)
initialRow = i;
}
DynamicMultichoiceSortList(items, argc);
if (shouldSort)
DynamicMultichoiceSortList(items, argc);
MultichoiceDynamic_DestroyStack();
}
if (ScriptMenu_MultichoiceDynamic(left, top, argc, items, ignoreBPress, maxBeforeScroll))
if (ScriptMenu_MultichoiceDynamic(left, top, argc, items, ignoreBPress, maxBeforeScroll, initialRow))
{
ScriptContext_Stop();
return TRUE;

View File

@ -33,7 +33,7 @@ static void Task_HandleScrollingMultichoiceInput(u8 taskId);
static void Task_HandleMultichoiceInput(u8 taskId);
static void Task_HandleYesNoInput(u8 taskId);
static void Task_HandleMultichoiceGridInput(u8 taskId);
static void DrawMultichoiceMenuDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u8 cursorPos, u8 maxBeforeScroll);
static void DrawMultichoiceMenuDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u32 initialRow, u8 maxBeforeScroll);
static void DrawMultichoiceMenu(u8 left, u8 top, u8 multichoiceId, bool8 ignoreBPress, u8 cursorPos);
static void InitMultichoiceCheckWrap(bool8 ignoreBPress, u8 count, u8 windowId, u8 multichoiceId);
static void DrawLinkServicesMultichoiceMenu(u8 multichoiceId);
@ -55,7 +55,7 @@ static const struct ListMenuTemplate sScriptableListMenuTemplate =
.fontId = FONT_NORMAL,
};
bool8 ScriptMenu_MultichoiceDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u8 maxBeforeScroll)
bool8 ScriptMenu_MultichoiceDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u8 maxBeforeScroll, u32 initialRow)
{
if (FuncIsActiveTask(Task_HandleMultichoiceInput) == TRUE)
{
@ -65,7 +65,7 @@ bool8 ScriptMenu_MultichoiceDynamic(u8 left, u8 top, u8 argc, struct ListMenuIte
else
{
gSpecialVar_Result = 0xFF;
DrawMultichoiceMenuDynamic(left, top, argc, items, ignoreBPress, 0, maxBeforeScroll);
DrawMultichoiceMenuDynamic(left, top, argc, items, ignoreBPress, initialRow, maxBeforeScroll);
return TRUE;
}
}
@ -203,6 +203,15 @@ struct ListMenuItem *MultichoiceDynamic_PeekElement(void)
return &sDynamicMultiChoiceStack->elements[sDynamicMultiChoiceStack->top];
}
struct ListMenuItem *MultichoiceDynamic_PeekElementAt(u32 index)
{
if (sDynamicMultiChoiceStack == NULL)
return NULL;
if (sDynamicMultiChoiceStack->top < index)
return NULL;
return &sDynamicMultiChoiceStack->elements[index];
}
void MultichoiceDynamic_DestroyStack(void)
{
TRY_FREE_AND_SET_NULL(sDynamicMultiChoiceStack->elements);
@ -216,13 +225,11 @@ static void MultichoiceDynamic_MoveCursor(s32 itemIndex, bool8 onInit, struct Li
taskId = FindTaskIdByFunc(Task_HandleScrollingMultichoiceInput);
if (taskId != TASK_NONE)
{
u16 scrollOffset;
ListMenuGetScrollAndRow(gTasks[taskId].data[0], &scrollOffset, NULL);
gScrollableMultichoice_ScrollOffset = scrollOffset;
ListMenuGetScrollAndRow(gTasks[taskId].data[0], &gScrollableMultichoice_ScrollOffset, NULL);
}
}
static void DrawMultichoiceMenuDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u8 cursorPos, u8 maxBeforeScroll)
static void DrawMultichoiceMenuDynamic(u8 left, u8 top, u8 argc, struct ListMenuItem *items, bool8 ignoreBPress, u32 initialRow, u8 maxBeforeScroll)
{
u32 i;
u8 windowId;
@ -230,6 +237,7 @@ static void DrawMultichoiceMenuDynamic(u8 left, u8 top, u8 argc, struct ListMenu
u8 newWidth;
u8 taskId;
u32 windowHeight;
struct ListMenu *list;
for (i = 0; i < argc; ++i)
{
@ -256,7 +264,9 @@ static void DrawMultichoiceMenuDynamic(u8 left, u8 top, u8 argc, struct ListMenu
gTasks[taskId].data[5] = argc;
gTasks[taskId].data[7] = maxBeforeScroll;
StoreWordInTwoHalfwords(&gTasks[taskId].data[3], (u32) items);
list = (void *) gTasks[gTasks[taskId].data[0]].data;
ListMenuChangeSelectionFull(list, TRUE, FALSE, initialRow, TRUE);
ListMenuGetScrollAndRow(gTasks[taskId].data[0], &gScrollableMultichoice_ScrollOffset, NULL);
if (argc > maxBeforeScroll)
{
// Create Scrolling Arrows