1bd73d69fe
- keyframeGetValue now returns the last keyframe's value for times at or beyond it, fixes a missing util/math.h include, and asserts keyframes are sorted by time; adds test/animation/test_keyframe.c - Adds mainmenu scene/UI and a battle HUD UI frame - Adds save autosave-related fields and battle scene tweaks - Adds headless test coverage for cutscenes, entities, and map areas
144 lines
4.3 KiB
C
144 lines
4.3 KiB
C
/**
|
|
* Copyright (c) 2026 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "dusktest.h"
|
|
#include "rpg/cutscene/cutscenesystem.h"
|
|
#include "rpg/overworld/maparea.h"
|
|
#include "util/memory.h"
|
|
|
|
static void resetMapAreas(void) {
|
|
memoryZero(MAP_AREAS, sizeof(MAP_AREAS));
|
|
}
|
|
|
|
static void test_cutsceneMapAreaAddCreatesAreaAndStoresLastCreated(
|
|
void **state
|
|
) {
|
|
|
|
resetMapAreas();
|
|
cutsceneitem_t item = CUTSCENE_MAP_AREA_ADD(
|
|
0, 0, 0, 5, 5, 0, mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
cutsceneitemdata_t data;
|
|
|
|
cutsceneMapAreaAddStart(&item, &data);
|
|
assert_true(cutsceneMapAreaAddUpdate(&item, &data));
|
|
|
|
uint8_t id = CUTSCENE_SYSTEM.areaLastCreated;
|
|
assert_ptr_equal(MAP_AREAS[id].callback, mapAreaNoopCallback);
|
|
assert_int_equal(MAP_AREAS[id].max.x, 5);
|
|
}
|
|
|
|
static void test_cutsceneMapAreaRemoveClearsSlot(void **state) {
|
|
|
|
resetMapAreas();
|
|
uint8_t id = mapAreaAdd(
|
|
(worldpos_t){ 0, 0, 0 }, (worldpos_t){ 5, 5, 0 },
|
|
mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
|
|
cutsceneitem_t item = CUTSCENE_MAP_AREA_REMOVE(id);
|
|
cutsceneitemdata_t data;
|
|
|
|
cutsceneMapAreaRemoveStart(&item, &data);
|
|
assert_true(cutsceneMapAreaRemoveUpdate(&item, &data));
|
|
assert_null(MAP_AREAS[id].callback);
|
|
}
|
|
|
|
static void test_cutsceneMapAreaRemoveResolvesLastCreatedSentinel(
|
|
void **state
|
|
) {
|
|
|
|
resetMapAreas();
|
|
cutsceneitem_t addItem = CUTSCENE_MAP_AREA_ADD(
|
|
0, 0, 0, 5, 5, 0, mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
cutsceneitemdata_t data;
|
|
cutsceneMapAreaAddStart(&addItem, &data);
|
|
uint8_t id = CUTSCENE_SYSTEM.areaLastCreated;
|
|
|
|
cutsceneitem_t removeItem = CUTSCENE_MAP_AREA_REMOVE(CUTSCENE_AREA_LAST_CREATED);
|
|
cutsceneMapAreaRemoveStart(&removeItem, &data);
|
|
assert_null(MAP_AREAS[id].callback);
|
|
}
|
|
|
|
static void test_cutsceneMapAreaWaitCompletesWhenTriggerCountChanges(
|
|
void **state
|
|
) {
|
|
|
|
resetMapAreas();
|
|
uint8_t id = mapAreaAdd(
|
|
(worldpos_t){ 0, 0, 0 }, (worldpos_t){ 5, 5, 0 },
|
|
mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
|
|
cutsceneitem_t item = CUTSCENE_MAP_AREA_WAIT(id);
|
|
cutsceneitemdata_t data;
|
|
|
|
cutsceneMapAreaWaitStart(&item, &data);
|
|
assert_false(cutsceneMapAreaWaitUpdate(&item, &data));
|
|
|
|
MAP_AREAS[id].triggerCount++;// simulates the area's callback firing
|
|
assert_true(cutsceneMapAreaWaitUpdate(&item, &data));
|
|
}
|
|
|
|
static void test_cutsceneMapAreaWaitCompletesWhenAnyWatchedAreaChanges(
|
|
void **state
|
|
) {
|
|
|
|
resetMapAreas();
|
|
uint8_t idA = mapAreaAdd(
|
|
(worldpos_t){ 0, 0, 0 }, (worldpos_t){ 5, 5, 0 },
|
|
mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
uint8_t idB = mapAreaAdd(
|
|
(worldpos_t){ 10, 10, 0 }, (worldpos_t){ 15, 15, 0 },
|
|
mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
|
|
cutsceneitem_t item = CUTSCENE_MAP_AREA_WAIT(idA, idB);
|
|
cutsceneitemdata_t data;
|
|
|
|
cutsceneMapAreaWaitStart(&item, &data);
|
|
assert_false(cutsceneMapAreaWaitUpdate(&item, &data));
|
|
|
|
MAP_AREAS[idB].triggerCount++;// only the second watched area fires
|
|
assert_true(cutsceneMapAreaWaitUpdate(&item, &data));
|
|
}
|
|
|
|
static void test_cutsceneMapAreaWaitResolvesLastCreatedSentinel(
|
|
void **state
|
|
) {
|
|
|
|
resetMapAreas();
|
|
cutsceneitem_t addItem = CUTSCENE_MAP_AREA_ADD(
|
|
0, 0, 0, 5, 5, 0, mapAreaNoopCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
|
);
|
|
cutsceneitemdata_t data;
|
|
cutsceneMapAreaAddStart(&addItem, &data);
|
|
uint8_t id = CUTSCENE_SYSTEM.areaLastCreated;
|
|
|
|
cutsceneitem_t waitItem = CUTSCENE_MAP_AREA_WAIT(CUTSCENE_AREA_LAST_CREATED);
|
|
cutsceneMapAreaWaitStart(&waitItem, &data);
|
|
assert_false(cutsceneMapAreaWaitUpdate(&waitItem, &data));
|
|
|
|
MAP_AREAS[id].triggerCount++;
|
|
assert_true(cutsceneMapAreaWaitUpdate(&waitItem, &data));
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
const struct CMUnitTest tests[] = {
|
|
cmocka_unit_test(test_cutsceneMapAreaAddCreatesAreaAndStoresLastCreated),
|
|
cmocka_unit_test(test_cutsceneMapAreaRemoveClearsSlot),
|
|
cmocka_unit_test(test_cutsceneMapAreaRemoveResolvesLastCreatedSentinel),
|
|
cmocka_unit_test(test_cutsceneMapAreaWaitCompletesWhenTriggerCountChanges),
|
|
cmocka_unit_test(test_cutsceneMapAreaWaitCompletesWhenAnyWatchedAreaChanges),
|
|
cmocka_unit_test(test_cutsceneMapAreaWaitResolvesLastCreatedSentinel),
|
|
};
|
|
|
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
|
}
|