Some label fixes
This commit is contained in:
+3
-4
@@ -14,10 +14,9 @@ cmake_policy(SET CMP0079 NEW)
|
|||||||
|
|
||||||
option(DUSK_BUILD_TESTS "Enable tests" OFF)
|
option(DUSK_BUILD_TESTS "Enable tests" OFF)
|
||||||
|
|
||||||
# Game identity — override these per-project
|
set(DUSK_GAME_NAME "Dusk" CACHE STRING "Game display name")
|
||||||
set(DUSK_GAME_NAME "Dusk" CACHE STRING "Game display name")
|
set(DUSK_GAME_AUTHOR "YourWishes" CACHE STRING "Game author / coder")
|
||||||
set(DUSK_GAME_AUTHOR "YouWish" CACHE STRING "Game author / coder")
|
set(DUSK_GAME_SHORT_DESCRIPTION "Dusk game" CACHE STRING "One-line description")
|
||||||
set(DUSK_GAME_SHORT_DESCRIPTION "Dusk game" CACHE STRING "One-line description")
|
|
||||||
set(DUSK_GAME_LONG_DESCRIPTION "No description yet." CACHE STRING "Full description")
|
set(DUSK_GAME_LONG_DESCRIPTION "No description yet." CACHE STRING "Full description")
|
||||||
|
|
||||||
# Prep cache
|
# Prep cache
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ endif()
|
|||||||
|
|
||||||
# Link libraries.
|
# Link libraries.
|
||||||
# zip/z/lzma use target_link_options (raw flags) to bypass cmake target
|
# zip/z/lzma use target_link_options (raw flags) to bypass cmake target
|
||||||
# resolution — pkg-config-generated targets for these carry ZLIB::ZLIB in
|
# resolution - pkg-config-generated targets for these carry ZLIB::ZLIB in
|
||||||
# INTERFACE_LINK_LIBRARIES which breaks the PPC link step.
|
# INTERFACE_LINK_LIBRARIES which breaks the PPC link step.
|
||||||
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE
|
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE
|
||||||
cglm
|
cglm
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ void uiSettingsSelected(
|
|||||||
const uint8_t index,
|
const uint8_t index,
|
||||||
const uimenuitem_t *item
|
const uimenuitem_t *item
|
||||||
) {
|
) {
|
||||||
if(item->type == UIMENU_WIDGET_TYPE_CHECKBOX) {
|
if(item->type == UI_MENU_WIDGET_TYPE_CHECKBOX) {
|
||||||
uiCheckboxToggle(&UI_SETTINGS.items[index].checkbox);
|
uiCheckboxToggle(&UI_SETTINGS.items[index].checkbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,27 +30,42 @@ void uiSettingsClosed(const uimenu_t *menu) {
|
|||||||
errorret_t uiSettingsInit(void) {
|
errorret_t uiSettingsInit(void) {
|
||||||
memoryZero(&UI_SETTINGS, sizeof(uisettings_t));
|
memoryZero(&UI_SETTINGS, sizeof(uisettings_t));
|
||||||
|
|
||||||
UI_SETTINGS.items[0] = (uimenuitem_t){
|
uint8_t i = 0;
|
||||||
.type = UIMENU_WIDGET_TYPE_LABEL,
|
|
||||||
|
UI_SETTINGS.items[i] = (uimenuitem_t){
|
||||||
|
.type = UI_MENU_WIDGET_TYPE_LABEL,
|
||||||
.label = "Settings"
|
.label = "Settings"
|
||||||
};
|
};
|
||||||
UI_SETTINGS.items[1] = (uimenuitem_t){
|
++i;
|
||||||
.type = UIMENU_WIDGET_TYPE_LABEL,
|
|
||||||
.label = "Settings two"
|
UI_SETTINGS.items[i].type = UI_MENU_WIDGET_TYPE_BUTTON;
|
||||||
|
uiButtonInit(&UI_SETTINGS.items[i].button, "Do thing");
|
||||||
|
++i;
|
||||||
|
|
||||||
|
UI_SETTINGS.items[i].type = UI_MENU_WIDGET_TYPE_BUTTON;
|
||||||
|
uiButtonInit(&UI_SETTINGS.items[i].button, "Do other thing");
|
||||||
|
++i;
|
||||||
|
|
||||||
|
UI_SETTINGS.items[i].type = UI_MENU_WIDGET_TYPE_SPACER;
|
||||||
|
++i;
|
||||||
|
|
||||||
|
UI_SETTINGS.items[i] = (uimenuitem_t){
|
||||||
|
.type = UI_MENU_WIDGET_TYPE_LABEL,
|
||||||
|
.label = "Options"
|
||||||
};
|
};
|
||||||
UI_SETTINGS.items[2] = (uimenuitem_t){
|
++i;
|
||||||
.type = UIMENU_WIDGET_TYPE_LABEL,
|
|
||||||
.label = "Settings three"
|
UI_SETTINGS.items[i].type = UI_MENU_WIDGET_TYPE_CHECKBOX;
|
||||||
};
|
uiCheckboxInit(&UI_SETTINGS.items[i].checkbox, "Enable thing?");
|
||||||
UI_SETTINGS.items[3].type = UIMENU_WIDGET_TYPE_CHECKBOX;
|
++i;
|
||||||
uiCheckboxInit(&UI_SETTINGS.items[3].checkbox, "Enable thing?");
|
|
||||||
|
assertTrue(i <= UI_SETTINGS_ITEM_COUNT, "Settings item count mismatch");
|
||||||
|
|
||||||
uiMenuInit(&UI_SETTINGS.menu, uiSettingsSelected, uiSettingsClosed, NULL);
|
uiMenuInit(&UI_SETTINGS.menu, uiSettingsSelected, uiSettingsClosed, NULL);
|
||||||
uiMenuSetItems(
|
uiMenuSetItems(
|
||||||
&UI_SETTINGS.menu,
|
&UI_SETTINGS.menu,
|
||||||
UI_SETTINGS.items,
|
UI_SETTINGS.items,
|
||||||
UI_SETTINGS_ITEM_COUNT,
|
i, 1
|
||||||
2
|
|
||||||
);
|
);
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "ui/widget/uimenu.h"
|
#include "ui/widget/uimenu.h"
|
||||||
|
|
||||||
#define UI_SETTINGS_ITEM_COUNT 4
|
#define UI_SETTINGS_ITEM_COUNT 6
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uimenu_t menu;
|
uimenu_t menu;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
uibutton.c
|
||||||
uicheckbox.c
|
uicheckbox.c
|
||||||
uimenu.c
|
uimenu.c
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uibutton.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "display/text/text.h"
|
||||||
|
#include "display/color.h"
|
||||||
|
|
||||||
|
void uiButtonInit(uibutton_t *button, const char_t *label) {
|
||||||
|
assertNotNull(button, "Button cannot be NULL");
|
||||||
|
assertNotNull(label, "Label cannot be NULL");
|
||||||
|
memoryZero(button, sizeof(uibutton_t));
|
||||||
|
button->label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t uiButtonIsHighlighted(const uibutton_t *button) {
|
||||||
|
assertNotNull(button, "Button cannot be NULL");
|
||||||
|
return button->highlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiButtonSetHighlighted(uibutton_t *button, const bool_t highlighted) {
|
||||||
|
assertNotNull(button, "Button cannot be NULL");
|
||||||
|
button->highlighted = highlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t uiButtonDraw(
|
||||||
|
const uibutton_t *button,
|
||||||
|
const float_t x,
|
||||||
|
const float_t y
|
||||||
|
) {
|
||||||
|
assertNotNull(button, "Button cannot be NULL");
|
||||||
|
errorChain(textDraw(
|
||||||
|
x, y, button->label,
|
||||||
|
button->highlighted ? COLOR_RED : COLOR_WHITE,
|
||||||
|
&FONT_DEFAULT
|
||||||
|
));
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
|
||||||
|
#define UI_BUTTON_LABEL_MAX 32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char_t *label;
|
||||||
|
bool_t highlighted;
|
||||||
|
} uibutton_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a button.
|
||||||
|
*
|
||||||
|
* @param button The button to initialize.
|
||||||
|
* @param label Display label.
|
||||||
|
*/
|
||||||
|
void uiButtonInit(uibutton_t *button, const char_t *label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the button is highlighted.
|
||||||
|
*
|
||||||
|
* @param button The button to query.
|
||||||
|
* @returns True if highlighted.
|
||||||
|
*/
|
||||||
|
bool_t uiButtonIsHighlighted(const uibutton_t *button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the highlighted state of the button.
|
||||||
|
*
|
||||||
|
* @param button The button to update.
|
||||||
|
* @param highlighted The new highlighted state.
|
||||||
|
*/
|
||||||
|
void uiButtonSetHighlighted(uibutton_t *button, const bool_t highlighted);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the button at the given screen position.
|
||||||
|
*
|
||||||
|
* @param button The button to draw.
|
||||||
|
* @param x Screen x position.
|
||||||
|
* @param y Screen y position.
|
||||||
|
* @return Any error that occurs.
|
||||||
|
*/
|
||||||
|
errorret_t uiButtonDraw(
|
||||||
|
const uibutton_t *button,
|
||||||
|
const float_t x,
|
||||||
|
const float_t y
|
||||||
|
);
|
||||||
@@ -16,7 +16,7 @@ void uiCheckboxInit(
|
|||||||
const char_t *label
|
const char_t *label
|
||||||
) {
|
) {
|
||||||
memoryZero(checkbox, sizeof(uicheckbox_t));
|
memoryZero(checkbox, sizeof(uicheckbox_t));
|
||||||
stringCopy(checkbox->label, label, UI_CHECKBOX_LABEL_MAX);
|
checkbox->label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t uiCheckboxIsChecked(const uicheckbox_t *checkbox) {
|
bool_t uiCheckboxIsChecked(const uicheckbox_t *checkbox) {
|
||||||
|
|||||||
@@ -8,10 +8,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
#define UI_CHECKBOX_LABEL_MAX 32
|
|
||||||
|
|
||||||
typedef struct uicheckbox_s {
|
typedef struct uicheckbox_s {
|
||||||
char_t label[UI_CHECKBOX_LABEL_MAX];
|
const char_t *label;
|
||||||
bool_t checked;
|
bool_t checked;
|
||||||
bool_t highlighted;
|
bool_t highlighted;
|
||||||
} uicheckbox_t;
|
} uicheckbox_t;
|
||||||
@@ -20,7 +18,7 @@ typedef struct uicheckbox_s {
|
|||||||
* Initializes a checkbox.
|
* Initializes a checkbox.
|
||||||
*
|
*
|
||||||
* @param checkbox The checkbox to initialize.
|
* @param checkbox The checkbox to initialize.
|
||||||
* @param label Display label, truncated to UI_CHECKBOX_LABEL_MAX - 1 chars.
|
* @param label Display label.
|
||||||
*/
|
*/
|
||||||
void uiCheckboxInit(
|
void uiCheckboxInit(
|
||||||
uicheckbox_t *checkbox,
|
uicheckbox_t *checkbox,
|
||||||
|
|||||||
+73
-21
@@ -10,6 +10,7 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "display/text/text.h"
|
#include "display/text/text.h"
|
||||||
#include "display/color.h"
|
#include "display/color.h"
|
||||||
|
#include "ui/widget/uibutton.h"
|
||||||
|
|
||||||
void uiMenuInit(
|
void uiMenuInit(
|
||||||
uimenu_t *menu,
|
uimenu_t *menu,
|
||||||
@@ -52,7 +53,9 @@ void uiMenuOpen(uimenu_t *menu) {
|
|||||||
assertTrue(menu->columns > 0, "Menu columns must be > 0");
|
assertTrue(menu->columns > 0, "Menu columns must be > 0");
|
||||||
if(menu->focusItem != NULL) return;
|
if(menu->focusItem != NULL) return;
|
||||||
|
|
||||||
uint8_t rows = (menu->itemCount + menu->columns - 1) / menu->columns;
|
uint8_t focusable = uiMenuFocusableCount(menu);
|
||||||
|
uint8_t rows = focusable > 0 ?
|
||||||
|
(focusable + menu->columns - 1) / menu->columns : 1;
|
||||||
menu->focusItem = uiFocusPush(
|
menu->focusItem = uiFocusPush(
|
||||||
menu->columns, rows,
|
menu->columns, rows,
|
||||||
uiMenuFocusSelected,
|
uiMenuFocusSelected,
|
||||||
@@ -87,34 +90,49 @@ errorret_t uiMenuDraw(
|
|||||||
float_t colStep = width / (float_t)menu->columns;
|
float_t colStep = width / (float_t)menu->columns;
|
||||||
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
||||||
|
|
||||||
uint8_t focusIndex = menu->focusItem != NULL ?
|
uint8_t col = 0;
|
||||||
menu->focusItem->y * menu->columns + menu->focusItem->x :
|
uint8_t row = 0;
|
||||||
0xFF;
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
const uimenuitem_t *item = &menu->items[i];
|
const uimenuitem_t *item = &menu->items[i];
|
||||||
uint8_t col = i % menu->columns;
|
|
||||||
uint8_t row = i / menu->columns;
|
if(item->type == UI_MENU_WIDGET_TYPE_LABEL) {
|
||||||
|
if(col > 0) { row++; col = 0; }
|
||||||
|
errorChain(textDraw(
|
||||||
|
x,
|
||||||
|
y + (float_t)row * rowHeight,
|
||||||
|
item->label,
|
||||||
|
COLOR_WHITE,
|
||||||
|
&FONT_DEFAULT
|
||||||
|
));
|
||||||
|
row++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item->type == UI_MENU_WIDGET_TYPE_SPACER) {
|
||||||
|
if(col > 0) { row++; col = 0; }
|
||||||
|
row++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float_t ix = x + (float_t)col * colStep;
|
float_t ix = x + (float_t)col * colStep;
|
||||||
float_t iy = y + (float_t)row * rowHeight;
|
float_t iy = y + (float_t)row * rowHeight;
|
||||||
bool_t highlighted = i == focusIndex;
|
|
||||||
|
|
||||||
switch(item->type) {
|
switch(item->type) {
|
||||||
case UIMENU_WIDGET_TYPE_LABEL:
|
case UI_MENU_WIDGET_TYPE_CHECKBOX:
|
||||||
errorChain(textDraw(
|
errorChain(uiCheckboxDraw(&item->checkbox, ix, iy));
|
||||||
ix, iy, item->label,
|
|
||||||
highlighted ? COLOR_RED : COLOR_WHITE,
|
|
||||||
&FONT_DEFAULT
|
|
||||||
));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UIMENU_WIDGET_TYPE_CHECKBOX:
|
case UI_MENU_WIDGET_TYPE_BUTTON:
|
||||||
errorChain(uiCheckboxDraw(&item->checkbox, ix, iy));
|
errorChain(uiButtonDraw(&item->button, ix, iy));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
col++;
|
||||||
|
if(col >= menu->columns) { col = 0; row++; }
|
||||||
}
|
}
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
@@ -126,8 +144,9 @@ bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem) {
|
|||||||
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
||||||
if(menu->selected == NULL) return true;
|
if(menu->selected == NULL) return true;
|
||||||
|
|
||||||
uint8_t index = focusItem->y * menu->columns + focusItem->x;
|
uint8_t slot = focusItem->y * menu->columns + focusItem->x;
|
||||||
if(index >= menu->itemCount) return true;
|
uint8_t index = uiMenuFocusSlotToIndex(menu, slot);
|
||||||
|
if(index == 0xFF) return true;
|
||||||
|
|
||||||
menu->selected(menu, index, &menu->items[index]);
|
menu->selected(menu, index, &menu->items[index]);
|
||||||
return true;
|
return true;
|
||||||
@@ -138,16 +157,27 @@ bool_t uiMenuFocusChanged(const uifocusitem_t *focusItem) {
|
|||||||
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
||||||
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
||||||
|
|
||||||
uint8_t index = focusItem->y * menu->columns + focusItem->x;
|
uint8_t focusSlot = focusItem->y * menu->columns + focusItem->x;
|
||||||
|
uint8_t slot = 0;
|
||||||
|
|
||||||
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
uimenuitem_t *item = &menu->items[i];
|
uimenuitem_t *item = &menu->items[i];
|
||||||
if(item->type != UIMENU_WIDGET_TYPE_CHECKBOX) continue;
|
if(
|
||||||
uiCheckboxSetHighlighted(&item->checkbox, i == index);
|
item->type == UI_MENU_WIDGET_TYPE_LABEL ||
|
||||||
|
item->type == UI_MENU_WIDGET_TYPE_SPACER
|
||||||
|
) continue;
|
||||||
|
bool_t isActive = (slot == focusSlot);
|
||||||
|
if(item->type == UI_MENU_WIDGET_TYPE_CHECKBOX) {
|
||||||
|
uiCheckboxSetHighlighted(&item->checkbox, isActive);
|
||||||
|
} else if(item->type == UI_MENU_WIDGET_TYPE_BUTTON) {
|
||||||
|
uiButtonSetHighlighted(&item->button, isActive);
|
||||||
|
}
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(menu->changed == NULL) return true;
|
if(menu->changed == NULL) return true;
|
||||||
if(index >= menu->itemCount) return true;
|
uint8_t index = uiMenuFocusSlotToIndex(menu, focusSlot);
|
||||||
|
if(index == 0xFF) return true;
|
||||||
|
|
||||||
menu->changed(menu, index, &menu->items[index]);
|
menu->changed(menu, index, &menu->items[index]);
|
||||||
return true;
|
return true;
|
||||||
@@ -161,3 +191,25 @@ bool_t uiMenuFocusClosed(const uifocusitem_t *focusItem) {
|
|||||||
if(menu->closed != NULL) menu->closed(menu);
|
if(menu->closed != NULL) menu->closed(menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t uiMenuFocusableCount(const uimenu_t *menu) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
uint8_t count = 0;
|
||||||
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
|
uimenuwidgettype_t t = menu->items[i].type;
|
||||||
|
if(t != UI_MENU_WIDGET_TYPE_LABEL && t != UI_MENU_WIDGET_TYPE_SPACER) count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t uiMenuFocusSlotToIndex(const uimenu_t *menu, const uint8_t slot) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
uint8_t focusable = 0;
|
||||||
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
|
uimenuwidgettype_t t = menu->items[i].type;
|
||||||
|
if(t == UI_MENU_WIDGET_TYPE_LABEL || t == UI_MENU_WIDGET_TYPE_SPACER) continue;
|
||||||
|
if(focusable == slot) return i;
|
||||||
|
focusable++;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "ui/focus/uifocus.h"
|
#include "ui/focus/uifocus.h"
|
||||||
|
#include "ui/widget/uibutton.h"
|
||||||
#include "ui/widget/uicheckbox.h"
|
#include "ui/widget/uicheckbox.h"
|
||||||
|
|
||||||
#define UI_MENU_LABEL_MAX UI_CHECKBOX_LABEL_MAX
|
#define UI_MENU_LABEL_MAX UI_CHECKBOX_LABEL_MAX
|
||||||
@@ -15,16 +16,19 @@
|
|||||||
typedef struct uimenu_s uimenu_t;
|
typedef struct uimenu_s uimenu_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UIMENU_WIDGET_TYPE_NONE,
|
UI_MENU_WIDGET_TYPE_NONE,
|
||||||
UIMENU_WIDGET_TYPE_LABEL,
|
UI_MENU_WIDGET_TYPE_LABEL,
|
||||||
UIMENU_WIDGET_TYPE_CHECKBOX,
|
UI_MENU_WIDGET_TYPE_SPACER,
|
||||||
|
UI_MENU_WIDGET_TYPE_CHECKBOX,
|
||||||
|
UI_MENU_WIDGET_TYPE_BUTTON,
|
||||||
} uimenuwidgettype_t;
|
} uimenuwidgettype_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uimenuwidgettype_t type;
|
uimenuwidgettype_t type;
|
||||||
union {
|
union {
|
||||||
char_t label[UI_MENU_LABEL_MAX];
|
char_t *label;
|
||||||
uicheckbox_t checkbox;
|
uicheckbox_t checkbox;
|
||||||
|
uibutton_t button;
|
||||||
};
|
};
|
||||||
} uimenuitem_t;
|
} uimenuitem_t;
|
||||||
|
|
||||||
@@ -136,7 +140,25 @@ errorret_t uiMenuDraw(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal focus callback — forwards selection to the menu's selected handler.
|
* Returns the number of focusable (non-label) items in the menu.
|
||||||
|
*
|
||||||
|
* @param menu The menu to query.
|
||||||
|
* @returns Count of non-label items.
|
||||||
|
*/
|
||||||
|
uint8_t uiMenuFocusableCount(const uimenu_t *menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps a flat focus slot index to the corresponding item array index,
|
||||||
|
* skipping over label items which are not focusable.
|
||||||
|
*
|
||||||
|
* @param menu The menu to query.
|
||||||
|
* @param slot The focus slot index (y * columns + x).
|
||||||
|
* @returns The item array index, or 0xFF if out of range.
|
||||||
|
*/
|
||||||
|
uint8_t uiMenuFocusSlotToIndex(const uimenu_t *menu, const uint8_t slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal focus callback - forwards selection to the menu's selected handler.
|
||||||
*
|
*
|
||||||
* @param focusItem The active focus item; user field must point to uimenu_t.
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
* @returns True.
|
* @returns True.
|
||||||
@@ -144,7 +166,7 @@ errorret_t uiMenuDraw(
|
|||||||
bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem);
|
bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal focus callback — updates checkbox highlights and fires changed.
|
* Internal focus callback - updates widget highlights and fires changed.
|
||||||
*
|
*
|
||||||
* @param focusItem The active focus item; user field must point to uimenu_t.
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
* @returns True.
|
* @returns True.
|
||||||
@@ -152,7 +174,7 @@ bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem);
|
|||||||
bool_t uiMenuFocusChanged(const uifocusitem_t *focusItem);
|
bool_t uiMenuFocusChanged(const uifocusitem_t *focusItem);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal focus callback — clears focusItem and fires the closed handler.
|
* Internal focus callback - clears focusItem and fires the closed handler.
|
||||||
*
|
*
|
||||||
* @param focusItem The active focus item; user field must point to uimenu_t.
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
* @returns True.
|
* @returns True.
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ static void test_assertStrLenMin(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_assertIsMainThread(void **state) {
|
static void test_assertIsMainThread(void **state) {
|
||||||
// The group setup recorded this thread as main — assertIsMainThread must pass.
|
// The group setup recorded this thread as main - assertIsMainThread must pass.
|
||||||
assertIsMainThread("test thread is main, should not assert");
|
assertIsMainThread("test thread is main, should not assert");
|
||||||
|
|
||||||
// assertNotMainThread must fail when called from the main thread.
|
// assertNotMainThread must fail when called from the main thread.
|
||||||
|
|||||||
+10
-10
@@ -40,7 +40,7 @@ static int asset_setup(void **state) {
|
|||||||
// Save real callbacks so we can restore them in teardown.
|
// Save real callbacks so we can restore them in teardown.
|
||||||
memoryCopy(saved_callbacks, ASSET_LOADER_CALLBACKS, sizeof(saved_callbacks));
|
memoryCopy(saved_callbacks, ASSET_LOADER_CALLBACKS, sizeof(saved_callbacks));
|
||||||
|
|
||||||
// Manually init ASSET — no thread, no ZIP.
|
// Manually init ASSET - no thread, no ZIP.
|
||||||
memoryZero(&ASSET, sizeof(ASSET));
|
memoryZero(&ASSET, sizeof(ASSET));
|
||||||
for(size_t i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
|
for(size_t i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
|
||||||
threadMutexInit(&ASSET.loading[i].mutex);
|
threadMutexInit(&ASSET.loading[i].mutex);
|
||||||
@@ -117,7 +117,7 @@ static void test_getEntry_distinct_names(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetUpdate — state machine tests
|
// assetUpdate - state machine tests
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_update_entry_reaches_loaded(void **state) {
|
static void test_update_entry_reaches_loaded(void **state) {
|
||||||
@@ -252,7 +252,7 @@ static void test_update_overflow_queues_entries(void **state) {
|
|||||||
}
|
}
|
||||||
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
||||||
|
|
||||||
// Unlock first batch — the reaper can collect them in update 2.
|
// Unlock first batch - the reaper can collect them in update 2.
|
||||||
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
|
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
|
||||||
assetEntryUnlock(entries[i]);
|
assetEntryUnlock(entries[i]);
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ static void test_update_error_slot_stays_occupied(void **state) {
|
|||||||
assetUpdate();
|
assetUpdate();
|
||||||
assert_int_equal(entry->state, ASSET_ENTRY_STATE_ERROR);
|
assert_int_equal(entry->state, ASSET_ENTRY_STATE_ERROR);
|
||||||
|
|
||||||
// Unlike LOADED, the ERROR case does NOT clear the slot — it throws instead.
|
// Unlike LOADED, the ERROR case does NOT clear the slot - it throws instead.
|
||||||
assert_true(loading_slot_has_entry(entry));
|
assert_true(loading_slot_has_entry(entry));
|
||||||
|
|
||||||
errorret_t ret = assetUpdate();
|
errorret_t ret = assetUpdate();
|
||||||
@@ -295,7 +295,7 @@ static void test_update_error_slot_stays_occupied(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetEntryInit — input copy
|
// assetEntryInit - input copy
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getEntry_null_input_stays_null(void **state) {
|
static void test_getEntry_null_input_stays_null(void **state) {
|
||||||
@@ -312,7 +312,7 @@ static void test_getEntry_input_copied_into_entry(void **state) {
|
|||||||
|
|
||||||
assetentry_t *entry = assetGetEntry("test.texture", ASSET_LOADER_TYPE_TEXTURE, &input);
|
assetentry_t *entry = assetGetEntry("test.texture", ASSET_LOADER_TYPE_TEXTURE, &input);
|
||||||
|
|
||||||
// input must have been copied — entry->input must point inside the entry.
|
// input must have been copied - entry->input must point inside the entry.
|
||||||
assert_non_null(entry->input);
|
assert_non_null(entry->input);
|
||||||
assert_ptr_equal(entry->input, &entry->inputData);
|
assert_ptr_equal(entry->input, &entry->inputData);
|
||||||
assert_int_equal((int)entry->input->texture, 42);
|
assert_int_equal((int)entry->input->texture, 42);
|
||||||
@@ -321,7 +321,7 @@ static void test_getEntry_input_copied_into_entry(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetUpdate — re-entrant sync loader
|
// assetUpdate - re-entrant sync loader
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static assetentry_t *reentrant_inner_entry = NULL;
|
static assetentry_t *reentrant_inner_entry = NULL;
|
||||||
@@ -362,7 +362,7 @@ static void test_update_reentrant_sync_loader(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetGetEntry — dedup against non-NOT_STARTED entries
|
// assetGetEntry - dedup against non-NOT_STARTED entries
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getEntry_returns_loaded_entry(void **state) {
|
static void test_getEntry_returns_loaded_entry(void **state) {
|
||||||
@@ -464,7 +464,7 @@ static void test_requireLoaded_propagates_error(void **state) {
|
|||||||
|
|
||||||
assetentry_t *entry = assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry = assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
// requireLoaded spins assetUpdate until LOADED — but the loader always fails,
|
// requireLoaded spins assetUpdate until LOADED - but the loader always fails,
|
||||||
// so the second assetUpdate sees ERROR and throws, which errorChain propagates.
|
// so the second assetUpdate sees ERROR and throws, which errorChain propagates.
|
||||||
errorret_t ret = assetRequireLoaded(entry);
|
errorret_t ret = assetRequireLoaded(entry);
|
||||||
assert_true(errorIsNotOk(ret));
|
assert_true(errorIsNotOk(ret));
|
||||||
@@ -489,7 +489,7 @@ int main(void) {
|
|||||||
cmocka_unit_test_setup_teardown(test_getEntry_null_input_stays_null, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(test_getEntry_null_input_stays_null, asset_setup, asset_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_input_copied_into_entry, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(test_getEntry_input_copied_into_entry, asset_setup, asset_teardown),
|
||||||
|
|
||||||
// assetUpdate — state machine
|
// assetUpdate - state machine
|
||||||
cmocka_unit_test_setup_teardown(test_update_noop_on_empty_table, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(test_update_noop_on_empty_table, asset_setup, asset_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_update_entry_reaches_loaded, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(test_update_entry_reaches_loaded, asset_setup, asset_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_update_slot_occupied_after_first_update, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(test_update_slot_occupied_after_first_update, asset_setup, asset_teardown),
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ static int locale_teardown(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetLocaleParseHeader — pure tests (no ZIP required)
|
// assetLocaleParseHeader - pure tests (no ZIP required)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_parseHeader_english(void **state) {
|
static void test_parseHeader_english(void **state) {
|
||||||
@@ -251,7 +251,7 @@ static void test_parseHeader_error_missing_nplurals(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetLocaleEvaluatePlural — pure tests
|
// assetLocaleEvaluatePlural - pure tests
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_evaluatePlural_english_singular(void **state) {
|
static void test_evaluatePlural_english_singular(void **state) {
|
||||||
@@ -302,7 +302,7 @@ static void test_evaluatePlural_less_than_boundary(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetLocaleGetString — ZIP-based tests
|
// assetLocaleGetString - ZIP-based tests
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getString_simple(void **state) {
|
static void test_getString_simple(void **state) {
|
||||||
@@ -355,7 +355,7 @@ static void test_getString_missing_id(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// assetLocaleGetStringWithArgs — ZIP-based tests
|
// assetLocaleGetStringWithArgs - ZIP-based tests
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getStringWithArgs_int(void **state) {
|
static void test_getStringWithArgs_int(void **state) {
|
||||||
@@ -392,7 +392,7 @@ static void test_getStringWithArgs_string(void **state) {
|
|||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
// parseHeader — pure
|
// parseHeader - pure
|
||||||
cmocka_unit_test(test_parseHeader_english),
|
cmocka_unit_test(test_parseHeader_english),
|
||||||
cmocka_unit_test(test_parseHeader_singular),
|
cmocka_unit_test(test_parseHeader_singular),
|
||||||
cmocka_unit_test(test_parseHeader_less_than),
|
cmocka_unit_test(test_parseHeader_less_than),
|
||||||
@@ -402,20 +402,20 @@ int main(void) {
|
|||||||
cmocka_unit_test(test_parseHeader_error_nplurals_too_large),
|
cmocka_unit_test(test_parseHeader_error_nplurals_too_large),
|
||||||
cmocka_unit_test(test_parseHeader_error_missing_nplurals),
|
cmocka_unit_test(test_parseHeader_error_missing_nplurals),
|
||||||
|
|
||||||
// evaluatePlural — pure
|
// evaluatePlural - pure
|
||||||
cmocka_unit_test(test_evaluatePlural_english_singular),
|
cmocka_unit_test(test_evaluatePlural_english_singular),
|
||||||
cmocka_unit_test(test_evaluatePlural_english_plural),
|
cmocka_unit_test(test_evaluatePlural_english_plural),
|
||||||
cmocka_unit_test(test_evaluatePlural_singular_only),
|
cmocka_unit_test(test_evaluatePlural_singular_only),
|
||||||
cmocka_unit_test(test_evaluatePlural_less_than_boundary),
|
cmocka_unit_test(test_evaluatePlural_less_than_boundary),
|
||||||
|
|
||||||
// getString — in-memory ZIP
|
// getString - in-memory ZIP
|
||||||
cmocka_unit_test_setup_teardown(test_getString_simple, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getString_simple, locale_setup, locale_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_getString_plural_singular, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getString_plural_singular, locale_setup, locale_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_getString_plural_many, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getString_plural_many, locale_setup, locale_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_getString_multiple_calls, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getString_multiple_calls, locale_setup, locale_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_getString_missing_id, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getString_missing_id, locale_setup, locale_teardown),
|
||||||
|
|
||||||
// getStringWithArgs — in-memory ZIP
|
// getStringWithArgs - in-memory ZIP
|
||||||
cmocka_unit_test_setup_teardown(test_getStringWithArgs_int, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getStringWithArgs_int, locale_setup, locale_teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_getStringWithArgs_string, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(test_getStringWithArgs_string, locale_setup, locale_teardown),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static void test_thread_start_stop(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_thread_should_stop(void **state) {
|
static void test_thread_should_stop(void **state) {
|
||||||
// threadStop blocks until STOPPED — if threadShouldStop is broken the
|
// threadStop blocks until STOPPED - if threadShouldStop is broken the
|
||||||
// looping callback never exits and this test hangs / times out.
|
// looping callback never exits and this test hangs / times out.
|
||||||
thread_t thread;
|
thread_t thread;
|
||||||
threadInit(&thread, helper_loop);
|
threadInit(&thread, helper_loop);
|
||||||
@@ -108,12 +108,12 @@ typedef struct {
|
|||||||
static void helper_trylock(thread_t *thread) {
|
static void helper_trylock(thread_t *thread) {
|
||||||
trylock_data_t *data = (trylock_data_t *)thread->data;
|
trylock_data_t *data = (trylock_data_t *)thread->data;
|
||||||
|
|
||||||
// Phase 1: main holds the lock — trylock must fail.
|
// Phase 1: main holds the lock - trylock must fail.
|
||||||
while(data->phase != 1) {}
|
while(data->phase != 1) {}
|
||||||
data->resultWhileLocked = threadMutexTryLock(data->target);
|
data->resultWhileLocked = threadMutexTryLock(data->target);
|
||||||
data->phase = 2;
|
data->phase = 2;
|
||||||
|
|
||||||
// Phase 3: main released the lock — trylock must succeed.
|
// Phase 3: main released the lock - trylock must succeed.
|
||||||
while(data->phase != 3) {}
|
while(data->phase != 3) {}
|
||||||
data->resultAfterUnlock = threadMutexTryLock(data->target);
|
data->resultAfterUnlock = threadMutexTryLock(data->target);
|
||||||
if(data->resultAfterUnlock) {
|
if(data->resultAfterUnlock) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Builds GameCube / Wii disc images (NTSC-J, NTSC-U, PAL) using xorrisofs /
|
|||||||
mkisofs + Swiss-GC system-area headers.
|
mkisofs + Swiss-GC system-area headers.
|
||||||
|
|
||||||
The Swiss-GC headers contain a working GCN apploader that boots any DOL via
|
The Swiss-GC headers contain a working GCN apploader that boots any DOL via
|
||||||
the El Torito catalog — no custom PPC assembly needed.
|
the El Torito catalog - no custom PPC assembly needed.
|
||||||
|
|
||||||
Headers are cached in <script_dir>/../buildtools/iso/ and downloaded from the
|
Headers are cached in <script_dir>/../buildtools/iso/ and downloaded from the
|
||||||
Swiss-GC repository on first use.
|
Swiss-GC repository on first use.
|
||||||
@@ -14,8 +14,8 @@ Disc layout (produced by xorrisofs):
|
|||||||
sector 16 ISO 9660 PVD
|
sector 16 ISO 9660 PVD
|
||||||
sector 17 El Torito Boot Record
|
sector 17 El Torito Boot Record
|
||||||
... directory records, file data
|
... directory records, file data
|
||||||
Dusk.dol (El Torito boot image — loaded by apploader)
|
Dusk.dol (El Torito boot image - loaded by apploader)
|
||||||
dusk.dsk (asset archive — found at runtime via ISO 9660)
|
dusk.dsk (asset archive - found at runtime via ISO 9660)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
Vendored
+4
-4
@@ -8,11 +8,11 @@
|
|||||||
/**
|
/**
|
||||||
* Descriptor for one entry in an `AssetBatch`.
|
* Descriptor for one entry in an `AssetBatch`.
|
||||||
*
|
*
|
||||||
* `format` — texture format constant (`Texture.FORMAT_*`). Alias for `input`
|
* `format` - texture format constant (`Texture.FORMAT_*`). Alias for `input`
|
||||||
* when the type is `Asset.TYPE_TEXTURE`.
|
* when the type is `Asset.TYPE_TEXTURE`.
|
||||||
* `axis` — mesh axis constant (`Asset.MESH_AXIS_*`). Alias for `input`
|
* `axis` - mesh axis constant (`Asset.MESH_AXIS_*`). Alias for `input`
|
||||||
* when the type is `Asset.TYPE_MESH`.
|
* when the type is `Asset.TYPE_MESH`.
|
||||||
* `input` — generic numeric input for all other loader types.
|
* `input` - generic numeric input for all other loader types.
|
||||||
*/
|
*/
|
||||||
interface AssetBatchDescriptor {
|
interface AssetBatchDescriptor {
|
||||||
path: string;
|
path: string;
|
||||||
@@ -48,7 +48,7 @@ interface AssetBatch {
|
|||||||
lock(): this;
|
lock(): this;
|
||||||
/**
|
/**
|
||||||
* Releases all locks and clears the batch.
|
* Releases all locks and clears the batch.
|
||||||
* After this call the object is invalid — do not use it again.
|
* After this call the object is invalid - do not use it again.
|
||||||
*/
|
*/
|
||||||
unlock(): void;
|
unlock(): void;
|
||||||
/**
|
/**
|
||||||
|
|||||||
Vendored
+7
-7
@@ -13,24 +13,24 @@
|
|||||||
interface AssetEntry {
|
interface AssetEntry {
|
||||||
/** Archive-relative path used as the cache key. */
|
/** Archive-relative path used as the cache key. */
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
/** Current loading state — compare against `AssetEntry.*` state constants. */
|
/** Current loading state - compare against `AssetEntry.*` state constants. */
|
||||||
readonly state: number;
|
readonly state: number;
|
||||||
/** Loader type — one of the `AssetEntry.TYPE_*` constants. */
|
/** Loader type - one of the `AssetEntry.TYPE_*` constants. */
|
||||||
readonly type: number;
|
readonly type: number;
|
||||||
/** `true` when the entry has fully loaded (`state === AssetEntry.LOADED`). */
|
/** `true` when the entry has fully loaded (`state === AssetEntry.LOADED`). */
|
||||||
readonly isLoaded: boolean;
|
readonly isLoaded: boolean;
|
||||||
/**
|
/**
|
||||||
* Returns a `Texture` for this entry when it is a loaded texture asset.
|
* Returns a `Texture` for this entry when it is a loaded texture asset.
|
||||||
* The `Texture` holds its own asset lock — independent of this `AssetEntry`.
|
* The `Texture` holds its own asset lock - independent of this `AssetEntry`.
|
||||||
* Returns `undefined` if the entry is not of type `Asset.TYPE_TEXTURE` or
|
* Returns `undefined` if the entry is not of type `Asset.TYPE_TEXTURE` or
|
||||||
* is not yet loaded.
|
* is not yet loaded.
|
||||||
*/
|
*/
|
||||||
readonly texture: Texture | undefined;
|
readonly texture: Texture | undefined;
|
||||||
/** Event proxy — subscribe up to 4 callbacks for when loading completes. */
|
/** Event proxy - subscribe up to 4 callbacks for when loading completes. */
|
||||||
readonly onLoaded: AssetEventProxy;
|
readonly onLoaded: AssetEventProxy;
|
||||||
/** Event proxy — subscribe up to 4 callbacks for when the entry is disposed. */
|
/** Event proxy - subscribe up to 4 callbacks for when the entry is disposed. */
|
||||||
readonly onUnloaded: AssetEventProxy;
|
readonly onUnloaded: AssetEventProxy;
|
||||||
/** Event proxy — subscribe up to 4 callbacks for when loading fails. */
|
/** Event proxy - subscribe up to 4 callbacks for when loading fails. */
|
||||||
readonly onError: AssetEventProxy;
|
readonly onError: AssetEventProxy;
|
||||||
/**
|
/**
|
||||||
* Returns a Promise that resolves when the entry is loaded, or rejects on
|
* Returns a Promise that resolves when the entry is loaded, or rejects on
|
||||||
@@ -45,7 +45,7 @@ interface AssetEntry {
|
|||||||
requireLoaded(): this;
|
requireLoaded(): this;
|
||||||
/**
|
/**
|
||||||
* Releases the lock immediately.
|
* Releases the lock immediately.
|
||||||
* After this call the object is invalid — do not use it again.
|
* After this call the object is invalid - do not use it again.
|
||||||
*/
|
*/
|
||||||
unlock(): void;
|
unlock(): void;
|
||||||
toString(): string;
|
toString(): string;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A loaded texture asset. Holds a lock on the underlying asset entry —
|
* A loaded texture asset. Holds a lock on the underlying asset entry -
|
||||||
* the lock is released automatically when the object is garbage collected.
|
* the lock is released automatically when the object is garbage collected.
|
||||||
*/
|
*/
|
||||||
interface Texture {
|
interface Texture {
|
||||||
|
|||||||
+2
-2
@@ -8,11 +8,11 @@
|
|||||||
/** Overworld character component (player or NPC). */
|
/** Overworld character component (player or NPC). */
|
||||||
interface Overworld extends Component {
|
interface Overworld extends Component {
|
||||||
/**
|
/**
|
||||||
* Entity type — `Overworld.PLAYER` or `Overworld.NPC`.
|
* Entity type - `Overworld.PLAYER` or `Overworld.NPC`.
|
||||||
*/
|
*/
|
||||||
type: number;
|
type: number;
|
||||||
/**
|
/**
|
||||||
* Facing direction — one of the `Overworld.FACING_*` constants.
|
* Facing direction - one of the `Overworld.FACING_*` constants.
|
||||||
*/
|
*/
|
||||||
facing: number;
|
facing: number;
|
||||||
/** Component ID of the linked Renderable, or INVALID if none. */
|
/** Component ID of the linked Renderable, or INVALID if none. */
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ interface OverworldCamera extends Component {
|
|||||||
/** Orthographic scale factor (larger = wider view). */
|
/** Orthographic scale factor (larger = wider view). */
|
||||||
scale: number;
|
scale: number;
|
||||||
/**
|
/**
|
||||||
* Convenience setter — equivalent to assigning `targetEntity` and
|
* Convenience setter - equivalent to assigning `targetEntity` and
|
||||||
* `targetPositionComponent` individually.
|
* `targetPositionComponent` individually.
|
||||||
*/
|
*/
|
||||||
setTarget(targetEntityId: number, targetPositionComponentId: number): void;
|
setTarget(targetEntityId: number, targetPositionComponentId: number): void;
|
||||||
|
|||||||
Vendored
+2
-2
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
/** Physics body component. */
|
/** Physics body component. */
|
||||||
interface Physics extends Component {
|
interface Physics extends Component {
|
||||||
/** Body simulation type — `Physics.STATIC`, `DYNAMIC`, or `KINEMATIC`. */
|
/** Body simulation type - `Physics.STATIC`, `DYNAMIC`, or `KINEMATIC`. */
|
||||||
bodyType: number;
|
bodyType: number;
|
||||||
/**
|
/**
|
||||||
* Collision shape type — one of the `Physics.SHAPE_*` constants.
|
* Collision shape type - one of the `Physics.SHAPE_*` constants.
|
||||||
* Changing the type preserves existing velocity and ground state.
|
* Changing the type preserves existing velocity and ground state.
|
||||||
*/
|
*/
|
||||||
shape: number;
|
shape: number;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Transform component — local/world PRS with an optional parent hierarchy. */
|
/** Transform component - local/world PRS with an optional parent hierarchy. */
|
||||||
interface Position extends Component {
|
interface Position extends Component {
|
||||||
/**
|
/**
|
||||||
* Local-space position. Reading returns a Vec3 copy; assigning a Vec3
|
* Local-space position. Reading returns a Vec3 copy; assigning a Vec3
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
/** A Renderable component. Returned by `entity.add(Component.RENDERABLE)`. */
|
/** A Renderable component. Returned by `entity.add(Component.RENDERABLE)`. */
|
||||||
interface Renderable extends Component {
|
interface Renderable extends Component {
|
||||||
/** Current render type — one of the `Renderable.*` type constants. */
|
/** Current render type - one of the `Renderable.*` type constants. */
|
||||||
type: number;
|
type: number;
|
||||||
/** Render priority. 0 = auto. Higher = drawn later. */
|
/** Render priority. 0 = auto. Higher = drawn later. */
|
||||||
priority: number;
|
priority: number;
|
||||||
@@ -28,7 +28,7 @@ interface Renderable extends Component {
|
|||||||
texture: Texture | undefined;
|
texture: Texture | undefined;
|
||||||
/**
|
/**
|
||||||
* Sprite list. Reading returns a JS array of 10-element sub-arrays
|
* Sprite list. Reading returns a JS array of 10-element sub-arrays
|
||||||
* `[x1,y1,z1, x2,y2,z2, u1,v1, u2,v2]` — one per sprite.
|
* `[x1,y1,z1, x2,y2,z2, u1,v1, u2,v2]` - one per sprite.
|
||||||
*
|
*
|
||||||
* Assigning an array replaces all sprites. Each element may be:
|
* Assigning an array replaces all sprites. Each element may be:
|
||||||
* - 10 numbers (3D): `[x1,y1,z1, x2,y2,z2, u1,v1, u2,v2]`
|
* - 10 numbers (3D): `[x1,y1,z1, x2,y2,z2, u1,v1, u2,v2]`
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*
|
*
|
||||||
* Root type declarations for the Dusk engine built-in JavaScript modules.
|
* Root type declarations for the Dusk engine built-in JavaScript modules.
|
||||||
* These globals are injected by the native JerryScript runtime — they are not
|
* These globals are injected by the native JerryScript runtime - they are not
|
||||||
* ES modules and cannot be imported.
|
* ES modules and cannot be imported.
|
||||||
*
|
*
|
||||||
* Reference this file from a jsconfig.json or tsconfig.json to get
|
* Reference this file from a jsconfig.json or tsconfig.json to get
|
||||||
|
|||||||
Vendored
+1
-1
@@ -37,7 +37,7 @@ interface InputNamespace {
|
|||||||
/** Polling-based input system. */
|
/** Polling-based input system. */
|
||||||
declare var Input: InputNamespace;
|
declare var Input: InputNamespace;
|
||||||
|
|
||||||
// Input action constants — injected as globals by the engine at startup.
|
// Input action constants - injected as globals by the engine at startup.
|
||||||
declare var INPUT_ACTION_UP: InputAction;
|
declare var INPUT_ACTION_UP: InputAction;
|
||||||
declare var INPUT_ACTION_DOWN: InputAction;
|
declare var INPUT_ACTION_DOWN: InputAction;
|
||||||
declare var INPUT_ACTION_LEFT: InputAction;
|
declare var INPUT_ACTION_LEFT: InputAction;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -58,6 +58,6 @@ interface BackpackNamespace {
|
|||||||
|
|
||||||
declare var Backpack: BackpackNamespace;
|
declare var Backpack: BackpackNamespace;
|
||||||
|
|
||||||
// Inventory sort constants — injected as globals by the engine at startup.
|
// Inventory sort constants - injected as globals by the engine at startup.
|
||||||
declare var INVENTORY_SORT_BY_ID: number;
|
declare var INVENTORY_SORT_BY_ID: number;
|
||||||
declare var INVENTORY_SORT_BY_TYPE: number;
|
declare var INVENTORY_SORT_BY_TYPE: number;
|
||||||
|
|||||||
Vendored
+2
-2
@@ -29,11 +29,11 @@ interface ItemNamespace {
|
|||||||
|
|
||||||
declare var Item: ItemNamespace;
|
declare var Item: ItemNamespace;
|
||||||
|
|
||||||
// Item ID constants — injected as globals by the engine at startup.
|
// Item ID constants - injected as globals by the engine at startup.
|
||||||
declare var ITEM_ID_POTION: ItemId;
|
declare var ITEM_ID_POTION: ItemId;
|
||||||
declare var ITEM_ID_POTATO: ItemId;
|
declare var ITEM_ID_POTATO: ItemId;
|
||||||
declare var ITEM_ID_APPLE: ItemId;
|
declare var ITEM_ID_APPLE: ItemId;
|
||||||
|
|
||||||
// Item type constants — injected as globals by the engine at startup.
|
// Item type constants - injected as globals by the engine at startup.
|
||||||
declare var ITEM_TYPE_MEDICINE: ItemType;
|
declare var ITEM_TYPE_MEDICINE: ItemType;
|
||||||
declare var ITEM_TYPE_FOOD: ItemType;
|
declare var ITEM_TYPE_FOOD: ItemType;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -43,7 +43,7 @@ interface SceneNamespace {
|
|||||||
*/
|
*/
|
||||||
set(newScene: SceneObject | null): void;
|
set(newScene: SceneObject | null): void;
|
||||||
|
|
||||||
/** Called each frame by the engine — drives `current.update()`. */
|
/** Called each frame by the engine - drives `current.update()`. */
|
||||||
update(): void;
|
update(): void;
|
||||||
|
|
||||||
/** Called each frame by the engine for dynamic/physics updates. */
|
/** Called each frame by the engine for dynamic/physics updates. */
|
||||||
|
|||||||
Vendored
+1
-1
@@ -26,5 +26,5 @@ interface StoryNamespace {
|
|||||||
|
|
||||||
declare var Story: StoryNamespace;
|
declare var Story: StoryNamespace;
|
||||||
|
|
||||||
// Story flag constants — injected as globals by the engine at startup.
|
// Story flag constants - injected as globals by the engine at startup.
|
||||||
declare var STORY_FLAG_TEST: StoryFlag;
|
declare var STORY_FLAG_TEST: StoryFlag;
|
||||||
|
|||||||
Reference in New Issue
Block a user