From 722fe2ccfb16deedff184a69463bd495c5ea2bb6 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 25 Jun 2026 19:56:14 -0500 Subject: [PATCH] Some label fixes --- CMakeLists.txt | 7 +- cmake/targets/dolphin.cmake | 2 +- src/dusk/ui/frame/uisettings.c | 43 +++++++--- src/dusk/ui/frame/uisettings.h | 2 +- src/dusk/ui/widget/CMakeLists.txt | 1 + src/dusk/ui/widget/uibutton.c | 44 ++++++++++ src/dusk/ui/widget/uibutton.h | 54 ++++++++++++ src/dusk/ui/widget/uicheckbox.c | 2 +- src/dusk/ui/widget/uicheckbox.h | 6 +- src/dusk/ui/widget/uimenu.c | 94 ++++++++++++++++----- src/dusk/ui/widget/uimenu.h | 36 ++++++-- test/assert/test_assert.c | 2 +- test/asset/test_asset.c | 20 ++--- test/asset/test_assetlocale.c | 16 ++-- test/thread/test_thread.c | 6 +- tools/makedolphiniso.py | 6 +- types/asset/assetbatch.d.ts | 8 +- types/asset/assetentry.d.ts | 14 +-- types/display/texture.d.ts | 2 +- types/entity/component/overworld.d.ts | 4 +- types/entity/component/overworldcamera.d.ts | 2 +- types/entity/component/physics.d.ts | 4 +- types/entity/component/position.d.ts | 2 +- types/entity/component/renderable.d.ts | 4 +- types/index.d.ts | 2 +- types/input/input.d.ts | 2 +- types/item/backpack.d.ts | 2 +- types/item/item.d.ts | 4 +- types/scene/scene.d.ts | 2 +- types/story/story.d.ts | 2 +- 30 files changed, 290 insertions(+), 105 deletions(-) create mode 100644 src/dusk/ui/widget/uibutton.c create mode 100644 src/dusk/ui/widget/uibutton.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ed0a5731..f3a57347 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,10 +14,9 @@ cmake_policy(SET CMP0079 NEW) 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_AUTHOR "YouWish" CACHE STRING "Game author / coder") -set(DUSK_GAME_SHORT_DESCRIPTION "Dusk game" CACHE STRING "One-line description") +set(DUSK_GAME_NAME "Dusk" CACHE STRING "Game display name") +set(DUSK_GAME_AUTHOR "YourWishes" CACHE STRING "Game author / coder") +set(DUSK_GAME_SHORT_DESCRIPTION "Dusk game" CACHE STRING "One-line description") set(DUSK_GAME_LONG_DESCRIPTION "No description yet." CACHE STRING "Full description") # Prep cache diff --git a/cmake/targets/dolphin.cmake b/cmake/targets/dolphin.cmake index dac969e1..ff6164ba 100644 --- a/cmake/targets/dolphin.cmake +++ b/cmake/targets/dolphin.cmake @@ -45,7 +45,7 @@ endif() # Link libraries. # 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. target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE cglm diff --git a/src/dusk/ui/frame/uisettings.c b/src/dusk/ui/frame/uisettings.c index 551ada08..768ed5bf 100644 --- a/src/dusk/ui/frame/uisettings.c +++ b/src/dusk/ui/frame/uisettings.c @@ -18,7 +18,7 @@ void uiSettingsSelected( const uint8_t index, 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); } } @@ -30,27 +30,42 @@ void uiSettingsClosed(const uimenu_t *menu) { errorret_t uiSettingsInit(void) { memoryZero(&UI_SETTINGS, sizeof(uisettings_t)); - UI_SETTINGS.items[0] = (uimenuitem_t){ - .type = UIMENU_WIDGET_TYPE_LABEL, + uint8_t i = 0; + + UI_SETTINGS.items[i] = (uimenuitem_t){ + .type = UI_MENU_WIDGET_TYPE_LABEL, .label = "Settings" }; - UI_SETTINGS.items[1] = (uimenuitem_t){ - .type = UIMENU_WIDGET_TYPE_LABEL, - .label = "Settings two" + ++i; + + 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){ - .type = UIMENU_WIDGET_TYPE_LABEL, - .label = "Settings three" - }; - UI_SETTINGS.items[3].type = UIMENU_WIDGET_TYPE_CHECKBOX; - uiCheckboxInit(&UI_SETTINGS.items[3].checkbox, "Enable thing?"); + ++i; + + UI_SETTINGS.items[i].type = UI_MENU_WIDGET_TYPE_CHECKBOX; + uiCheckboxInit(&UI_SETTINGS.items[i].checkbox, "Enable thing?"); + ++i; + + assertTrue(i <= UI_SETTINGS_ITEM_COUNT, "Settings item count mismatch"); uiMenuInit(&UI_SETTINGS.menu, uiSettingsSelected, uiSettingsClosed, NULL); uiMenuSetItems( &UI_SETTINGS.menu, UI_SETTINGS.items, - UI_SETTINGS_ITEM_COUNT, - 2 + i, 1 ); errorOk(); diff --git a/src/dusk/ui/frame/uisettings.h b/src/dusk/ui/frame/uisettings.h index 386dcbfd..928bb4ed 100644 --- a/src/dusk/ui/frame/uisettings.h +++ b/src/dusk/ui/frame/uisettings.h @@ -9,7 +9,7 @@ #include "error/error.h" #include "ui/widget/uimenu.h" -#define UI_SETTINGS_ITEM_COUNT 4 +#define UI_SETTINGS_ITEM_COUNT 6 typedef struct { uimenu_t menu; diff --git a/src/dusk/ui/widget/CMakeLists.txt b/src/dusk/ui/widget/CMakeLists.txt index 5c3c5f88..028e726e 100644 --- a/src/dusk/ui/widget/CMakeLists.txt +++ b/src/dusk/ui/widget/CMakeLists.txt @@ -5,6 +5,7 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC + uibutton.c uicheckbox.c uimenu.c ) diff --git a/src/dusk/ui/widget/uibutton.c b/src/dusk/ui/widget/uibutton.c new file mode 100644 index 00000000..912f2946 --- /dev/null +++ b/src/dusk/ui/widget/uibutton.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(); +} diff --git a/src/dusk/ui/widget/uibutton.h b/src/dusk/ui/widget/uibutton.h new file mode 100644 index 00000000..b8a28268 --- /dev/null +++ b/src/dusk/ui/widget/uibutton.h @@ -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 +); diff --git a/src/dusk/ui/widget/uicheckbox.c b/src/dusk/ui/widget/uicheckbox.c index 813cce1a..afbf34dc 100644 --- a/src/dusk/ui/widget/uicheckbox.c +++ b/src/dusk/ui/widget/uicheckbox.c @@ -16,7 +16,7 @@ void uiCheckboxInit( const char_t *label ) { memoryZero(checkbox, sizeof(uicheckbox_t)); - stringCopy(checkbox->label, label, UI_CHECKBOX_LABEL_MAX); + checkbox->label = label; } bool_t uiCheckboxIsChecked(const uicheckbox_t *checkbox) { diff --git a/src/dusk/ui/widget/uicheckbox.h b/src/dusk/ui/widget/uicheckbox.h index 2d06b619..b32d52cc 100644 --- a/src/dusk/ui/widget/uicheckbox.h +++ b/src/dusk/ui/widget/uicheckbox.h @@ -8,10 +8,8 @@ #pragma once #include "error/error.h" -#define UI_CHECKBOX_LABEL_MAX 32 - typedef struct uicheckbox_s { - char_t label[UI_CHECKBOX_LABEL_MAX]; + const char_t *label; bool_t checked; bool_t highlighted; } uicheckbox_t; @@ -20,7 +18,7 @@ typedef struct uicheckbox_s { * Initializes a checkbox. * * @param checkbox The checkbox to initialize. - * @param label Display label, truncated to UI_CHECKBOX_LABEL_MAX - 1 chars. + * @param label Display label. */ void uiCheckboxInit( uicheckbox_t *checkbox, diff --git a/src/dusk/ui/widget/uimenu.c b/src/dusk/ui/widget/uimenu.c index 5e7b8a5a..5ff2e4b7 100644 --- a/src/dusk/ui/widget/uimenu.c +++ b/src/dusk/ui/widget/uimenu.c @@ -10,6 +10,7 @@ #include "util/memory.h" #include "display/text/text.h" #include "display/color.h" +#include "ui/widget/uibutton.h" void uiMenuInit( uimenu_t *menu, @@ -52,7 +53,9 @@ void uiMenuOpen(uimenu_t *menu) { assertTrue(menu->columns > 0, "Menu columns must be > 0"); 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->columns, rows, uiMenuFocusSelected, @@ -87,34 +90,49 @@ errorret_t uiMenuDraw( float_t colStep = width / (float_t)menu->columns; float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight; - uint8_t focusIndex = menu->focusItem != NULL ? - menu->focusItem->y * menu->columns + menu->focusItem->x : - 0xFF; + uint8_t col = 0; + uint8_t row = 0; for(uint8_t i = 0; i < menu->itemCount; 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 iy = y + (float_t)row * rowHeight; - bool_t highlighted = i == focusIndex; switch(item->type) { - case UIMENU_WIDGET_TYPE_LABEL: - errorChain(textDraw( - ix, iy, item->label, - highlighted ? COLOR_RED : COLOR_WHITE, - &FONT_DEFAULT - )); + case UI_MENU_WIDGET_TYPE_CHECKBOX: + errorChain(uiCheckboxDraw(&item->checkbox, ix, iy)); break; - case UIMENU_WIDGET_TYPE_CHECKBOX: - errorChain(uiCheckboxDraw(&item->checkbox, ix, iy)); + case UI_MENU_WIDGET_TYPE_BUTTON: + errorChain(uiButtonDraw(&item->button, ix, iy)); break; default: break; } + + col++; + if(col >= menu->columns) { col = 0; row++; } } errorOk(); @@ -126,8 +144,9 @@ bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem) { uimenu_t *menu = (uimenu_t *)focusItem->user; if(menu->selected == NULL) return true; - uint8_t index = focusItem->y * menu->columns + focusItem->x; - if(index >= menu->itemCount) return true; + uint8_t slot = focusItem->y * menu->columns + focusItem->x; + uint8_t index = uiMenuFocusSlotToIndex(menu, slot); + if(index == 0xFF) return true; menu->selected(menu, index, &menu->items[index]); return true; @@ -138,16 +157,27 @@ bool_t uiMenuFocusChanged(const uifocusitem_t *focusItem) { assertNotNull(focusItem->user, "Focus item user cannot be NULL"); 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++) { uimenuitem_t *item = &menu->items[i]; - if(item->type != UIMENU_WIDGET_TYPE_CHECKBOX) continue; - uiCheckboxSetHighlighted(&item->checkbox, i == index); + if( + 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(index >= menu->itemCount) return true; + uint8_t index = uiMenuFocusSlotToIndex(menu, focusSlot); + if(index == 0xFF) return true; menu->changed(menu, index, &menu->items[index]); return true; @@ -161,3 +191,25 @@ bool_t uiMenuFocusClosed(const uifocusitem_t *focusItem) { if(menu->closed != NULL) menu->closed(menu); 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; +} diff --git a/src/dusk/ui/widget/uimenu.h b/src/dusk/ui/widget/uimenu.h index 1acdf57d..0f8e0301 100644 --- a/src/dusk/ui/widget/uimenu.h +++ b/src/dusk/ui/widget/uimenu.h @@ -8,6 +8,7 @@ #pragma once #include "error/error.h" #include "ui/focus/uifocus.h" +#include "ui/widget/uibutton.h" #include "ui/widget/uicheckbox.h" #define UI_MENU_LABEL_MAX UI_CHECKBOX_LABEL_MAX @@ -15,16 +16,19 @@ typedef struct uimenu_s uimenu_t; typedef enum { - UIMENU_WIDGET_TYPE_NONE, - UIMENU_WIDGET_TYPE_LABEL, - UIMENU_WIDGET_TYPE_CHECKBOX, + UI_MENU_WIDGET_TYPE_NONE, + UI_MENU_WIDGET_TYPE_LABEL, + UI_MENU_WIDGET_TYPE_SPACER, + UI_MENU_WIDGET_TYPE_CHECKBOX, + UI_MENU_WIDGET_TYPE_BUTTON, } uimenuwidgettype_t; typedef struct { uimenuwidgettype_t type; union { - char_t label[UI_MENU_LABEL_MAX]; + char_t *label; uicheckbox_t checkbox; + uibutton_t button; }; } 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. * @returns True. @@ -144,7 +166,7 @@ errorret_t uiMenuDraw( 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. * @returns True. @@ -152,7 +174,7 @@ bool_t uiMenuFocusSelected(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. * @returns True. diff --git a/test/assert/test_assert.c b/test/assert/test_assert.c index e65a1f5e..d79dd120 100644 --- a/test/assert/test_assert.c +++ b/test/assert/test_assert.c @@ -108,7 +108,7 @@ static void test_assertStrLenMin(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"); // assertNotMainThread must fail when called from the main thread. diff --git a/test/asset/test_asset.c b/test/asset/test_asset.c index a64c3197..0ff4d9ef 100644 --- a/test/asset/test_asset.c +++ b/test/asset/test_asset.c @@ -40,7 +40,7 @@ static int asset_setup(void **state) { // Save real callbacks so we can restore them in teardown. 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)); for(size_t i = 0; i < ASSET_LOADING_COUNT_MAX; i++) { 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) { @@ -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); - // 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++) { assetEntryUnlock(entries[i]); } @@ -284,7 +284,7 @@ static void test_update_error_slot_stays_occupied(void **state) { assetUpdate(); 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)); 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) { @@ -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); - // 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_ptr_equal(entry->input, &entry->inputData); 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; @@ -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) { @@ -464,7 +464,7 @@ static void test_requireLoaded_propagates_error(void **state) { 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. errorret_t ret = assetRequireLoaded(entry); 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_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_entry_reaches_loaded, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_slot_occupied_after_first_update, asset_setup, asset_teardown), diff --git a/test/asset/test_assetlocale.c b/test/asset/test_assetlocale.c index fd17d9fc..8a7d44d2 100644 --- a/test/asset/test_assetlocale.c +++ b/test/asset/test_assetlocale.c @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -392,7 +392,7 @@ static void test_getStringWithArgs_string(void **state) { int main(void) { const struct CMUnitTest tests[] = { - // parseHeader — pure + // parseHeader - pure cmocka_unit_test(test_parseHeader_english), cmocka_unit_test(test_parseHeader_singular), 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_missing_nplurals), - // evaluatePlural — pure + // evaluatePlural - pure cmocka_unit_test(test_evaluatePlural_english_singular), cmocka_unit_test(test_evaluatePlural_english_plural), cmocka_unit_test(test_evaluatePlural_singular_only), 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_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_multiple_calls, 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_string, locale_setup, locale_teardown), }; diff --git a/test/thread/test_thread.c b/test/thread/test_thread.c index 039d128e..585ab348 100644 --- a/test/thread/test_thread.c +++ b/test/thread/test_thread.c @@ -45,7 +45,7 @@ static void test_thread_start_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. thread_t thread; threadInit(&thread, helper_loop); @@ -108,12 +108,12 @@ typedef struct { static void helper_trylock(thread_t *thread) { 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) {} data->resultWhileLocked = threadMutexTryLock(data->target); 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) {} data->resultAfterUnlock = threadMutexTryLock(data->target); if(data->resultAfterUnlock) { diff --git a/tools/makedolphiniso.py b/tools/makedolphiniso.py index f1cd13ba..5456320e 100644 --- a/tools/makedolphiniso.py +++ b/tools/makedolphiniso.py @@ -4,7 +4,7 @@ Builds GameCube / Wii disc images (NTSC-J, NTSC-U, PAL) using xorrisofs / mkisofs + Swiss-GC system-area headers. 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 /../buildtools/iso/ and downloaded from the Swiss-GC repository on first use. @@ -14,8 +14,8 @@ Disc layout (produced by xorrisofs): sector 16 ISO 9660 PVD sector 17 El Torito Boot Record ... directory records, file data - Dusk.dol (El Torito boot image — loaded by apploader) - dusk.dsk (asset archive — found at runtime via ISO 9660) + Dusk.dol (El Torito boot image - loaded by apploader) + dusk.dsk (asset archive - found at runtime via ISO 9660) """ import argparse diff --git a/types/asset/assetbatch.d.ts b/types/asset/assetbatch.d.ts index 09b23a7b..64f5d474 100644 --- a/types/asset/assetbatch.d.ts +++ b/types/asset/assetbatch.d.ts @@ -8,11 +8,11 @@ /** * 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`. - * `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`. - * `input` — generic numeric input for all other loader types. + * `input` - generic numeric input for all other loader types. */ interface AssetBatchDescriptor { path: string; @@ -48,7 +48,7 @@ interface AssetBatch { lock(): this; /** * 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; /** diff --git a/types/asset/assetentry.d.ts b/types/asset/assetentry.d.ts index f20b8d64..9feb9ee4 100644 --- a/types/asset/assetentry.d.ts +++ b/types/asset/assetentry.d.ts @@ -13,24 +13,24 @@ interface AssetEntry { /** Archive-relative path used as the cache key. */ readonly name: string; - /** Current loading state — compare against `AssetEntry.*` state constants. */ + /** Current loading state - compare against `AssetEntry.*` state constants. */ readonly state: number; - /** Loader type — one of the `AssetEntry.TYPE_*` constants. */ + /** Loader type - one of the `AssetEntry.TYPE_*` constants. */ readonly type: number; /** `true` when the entry has fully loaded (`state === AssetEntry.LOADED`). */ readonly isLoaded: boolean; /** * 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 * is not yet loaded. */ 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; - /** 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; - /** 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; /** * Returns a Promise that resolves when the entry is loaded, or rejects on @@ -45,7 +45,7 @@ interface AssetEntry { requireLoaded(): this; /** * 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; toString(): string; diff --git a/types/display/texture.d.ts b/types/display/texture.d.ts index 665ec7ad..904e7d11 100644 --- a/types/display/texture.d.ts +++ b/types/display/texture.d.ts @@ -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. */ interface Texture { diff --git a/types/entity/component/overworld.d.ts b/types/entity/component/overworld.d.ts index 91696332..461c5bd6 100644 --- a/types/entity/component/overworld.d.ts +++ b/types/entity/component/overworld.d.ts @@ -8,11 +8,11 @@ /** Overworld character component (player or NPC). */ interface Overworld extends Component { /** - * Entity type — `Overworld.PLAYER` or `Overworld.NPC`. + * Entity type - `Overworld.PLAYER` or `Overworld.NPC`. */ type: number; /** - * Facing direction — one of the `Overworld.FACING_*` constants. + * Facing direction - one of the `Overworld.FACING_*` constants. */ facing: number; /** Component ID of the linked Renderable, or INVALID if none. */ diff --git a/types/entity/component/overworldcamera.d.ts b/types/entity/component/overworldcamera.d.ts index ecfa243f..5fcd1b5a 100644 --- a/types/entity/component/overworldcamera.d.ts +++ b/types/entity/component/overworldcamera.d.ts @@ -21,7 +21,7 @@ interface OverworldCamera extends Component { /** Orthographic scale factor (larger = wider view). */ scale: number; /** - * Convenience setter — equivalent to assigning `targetEntity` and + * Convenience setter - equivalent to assigning `targetEntity` and * `targetPositionComponent` individually. */ setTarget(targetEntityId: number, targetPositionComponentId: number): void; diff --git a/types/entity/component/physics.d.ts b/types/entity/component/physics.d.ts index c4616a24..abc31bcf 100644 --- a/types/entity/component/physics.d.ts +++ b/types/entity/component/physics.d.ts @@ -7,10 +7,10 @@ /** Physics body component. */ interface Physics extends Component { - /** Body simulation type — `Physics.STATIC`, `DYNAMIC`, or `KINEMATIC`. */ + /** Body simulation type - `Physics.STATIC`, `DYNAMIC`, or `KINEMATIC`. */ 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. */ shape: number; diff --git a/types/entity/component/position.d.ts b/types/entity/component/position.d.ts index 5f7addfe..5cceb852 100644 --- a/types/entity/component/position.d.ts +++ b/types/entity/component/position.d.ts @@ -5,7 +5,7 @@ * 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 { /** * Local-space position. Reading returns a Vec3 copy; assigning a Vec3 diff --git a/types/entity/component/renderable.d.ts b/types/entity/component/renderable.d.ts index 11a0d77a..c8a4ef5f 100644 --- a/types/entity/component/renderable.d.ts +++ b/types/entity/component/renderable.d.ts @@ -7,7 +7,7 @@ /** A Renderable component. Returned by `entity.add(Component.RENDERABLE)`. */ interface Renderable extends Component { - /** Current render type — one of the `Renderable.*` type constants. */ + /** Current render type - one of the `Renderable.*` type constants. */ type: number; /** Render priority. 0 = auto. Higher = drawn later. */ priority: number; @@ -28,7 +28,7 @@ interface Renderable extends Component { texture: Texture | undefined; /** * 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: * - 10 numbers (3D): `[x1,y1,z1, x2,y2,z2, u1,v1, u2,v2]` diff --git a/types/index.d.ts b/types/index.d.ts index e2d0edf4..6a9d3298 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -5,7 +5,7 @@ * https://opensource.org/licenses/MIT * * 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. * * Reference this file from a jsconfig.json or tsconfig.json to get diff --git a/types/input/input.d.ts b/types/input/input.d.ts index e39a2f24..da26313b 100644 --- a/types/input/input.d.ts +++ b/types/input/input.d.ts @@ -37,7 +37,7 @@ interface InputNamespace { /** Polling-based input system. */ 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_DOWN: InputAction; declare var INPUT_ACTION_LEFT: InputAction; diff --git a/types/item/backpack.d.ts b/types/item/backpack.d.ts index d4eb9fd1..692f243d 100644 --- a/types/item/backpack.d.ts +++ b/types/item/backpack.d.ts @@ -58,6 +58,6 @@ interface 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_TYPE: number; diff --git a/types/item/item.d.ts b/types/item/item.d.ts index 00566669..021fb3b9 100644 --- a/types/item/item.d.ts +++ b/types/item/item.d.ts @@ -29,11 +29,11 @@ interface 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_POTATO: 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_FOOD: ItemType; diff --git a/types/scene/scene.d.ts b/types/scene/scene.d.ts index b64e77ed..db3ee6db 100644 --- a/types/scene/scene.d.ts +++ b/types/scene/scene.d.ts @@ -43,7 +43,7 @@ interface SceneNamespace { */ 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; /** Called each frame by the engine for dynamic/physics updates. */ diff --git a/types/story/story.d.ts b/types/story/story.d.ts index 9b555afe..15745386 100644 --- a/types/story/story.d.ts +++ b/types/story/story.d.ts @@ -26,5 +26,5 @@ interface 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;