diff --git a/src/dusk/rpg/cutscene/cutscene.h b/src/dusk/rpg/cutscene/cutscene.h index 42ab40e9..ec7bc10a 100644 --- a/src/dusk/rpg/cutscene/cutscene.h +++ b/src/dusk/rpg/cutscene/cutscene.h @@ -41,8 +41,6 @@ typedef struct cutscene_s { #define CUTSCENE_CALLBACK(CALLBACK) \ { .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = CALLBACK } -// Single-destination walk: entity walks directly to (X, Y, Z). -// walkAround=true: tries perpendicular directions when blocked by an entity. #define CUTSCENE_ENTITY_WALK_TO(ENTITY_INDEX, X, Y, Z) \ { \ .type = CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO, \ @@ -54,7 +52,6 @@ typedef struct cutscene_s { } \ } -// Multi-waypoint walk: generates a named positions array then references it. #define CUTSCENE_ENTITY_WALK_PATH(NAME, ENTITY_INDEX, ...) \ static const worldpos_t CUTSCENE_##NAME##_POSITIONS[] = { __VA_ARGS__ }; \ static const cutsceneitem_t CUTSCENE_##NAME = { \ @@ -93,3 +90,17 @@ typedef struct cutscene_s { #define CUTSCENE_SET_PAUSE(FLAGS) \ { .type = CUTSCENE_ITEM_TYPE_SET_PAUSE, .setPause = (FLAGS) } + +// Runs all listed items simultaneously and waits until all are done. +// Concurrent items cannot be nested inside another CUTSCENE_CONCURRENT. +#define CUTSCENE_CONCURRENT(...) \ + { \ + .type = CUTSCENE_ITEM_TYPE_CONCURRENT, \ + .concurrent = { \ + .items = (const cutsceneitem_t[]){ __VA_ARGS__ }, \ + .count = (uint8_t)( \ + sizeof((cutsceneitem_t[]){ __VA_ARGS__ }) / \ + sizeof(cutsceneitem_t) \ + ) \ + } \ + } diff --git a/src/dusk/rpg/cutscene/cutscenesystem.c b/src/dusk/rpg/cutscene/cutscenesystem.c index a1cedca4..c94d5366 100644 --- a/src/dusk/rpg/cutscene/cutscenesystem.c +++ b/src/dusk/rpg/cutscene/cutscenesystem.c @@ -25,7 +25,7 @@ void cutsceneSystemUpdate() { if(CUTSCENE_SYSTEM.scene == NULL) return; const cutsceneitem_t *item = cutsceneSystemGetCurrentItem(); - cutsceneItemUpdate(item, &CUTSCENE_SYSTEM.data); + if(cutsceneItemUpdate(item, &CUTSCENE_SYSTEM.data)) cutsceneSystemNext(); } void cutsceneSystemNext() { diff --git a/src/dusk/rpg/cutscene/item/CMakeLists.txt b/src/dusk/rpg/cutscene/item/CMakeLists.txt index 6b3e271a..15f6bf42 100755 --- a/src/dusk/rpg/cutscene/item/CMakeLists.txt +++ b/src/dusk/rpg/cutscene/item/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2025 Dominic Masters -# +# # This software is released under the MIT License. # https://opensource.org/licenses/MIT @@ -7,4 +7,12 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC cutsceneitem.c -) \ No newline at end of file + cutscenewait.c + cutscenetext.c + cutscenecallback.c + cutscenefade.c + cutsceneentityteleport.c + cutsceneentitywalkto.c + cutscenesetpause.c + cutsceneconcurrent.c +) diff --git a/src/dusk/rpg/cutscene/item/cutscenecallback.c b/src/dusk/rpg/cutscene/item/cutscenecallback.c new file mode 100644 index 00000000..1cfe5526 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenecallback.c @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" + +void cutsceneCallbackStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + if(item->callback != NULL) item->callback(); +} + +bool_t cutsceneCallbackUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + return true; +} diff --git a/src/dusk/rpg/cutscene/item/cutscenecallback.h b/src/dusk/rpg/cutscene/item/cutscenecallback.h index 494f877d..b8dcf194 100644 --- a/src/dusk/rpg/cutscene/item/cutscenecallback.h +++ b/src/dusk/rpg/cutscene/item/cutscenecallback.h @@ -1,6 +1,6 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -8,4 +8,30 @@ #pragma once #include "dusk.h" -typedef void (*cutscenecallback_t)(void); \ No newline at end of file +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + +typedef void (*cutscenecallback_t)(void); + +/** + * Starts a callback item (invokes the callback immediately). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneCallbackStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates a callback item (always completes immediately). + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true always. + */ +bool_t cutsceneCallbackUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); \ No newline at end of file diff --git a/src/dusk/rpg/cutscene/item/cutsceneconcurrent.c b/src/dusk/rpg/cutscene/item/cutsceneconcurrent.c new file mode 100644 index 00000000..d505a101 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneconcurrent.c @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "assert/assert.h" + +void cutsceneConcurrentStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + assertTrue( + item->concurrent.count <= CUTSCENE_CONCURRENT_MAX, + "Too many items in CUTSCENE_CONCURRENT" + ); + for(uint8_t i = 0; i < item->concurrent.count; i++) { + assertTrue( + item->concurrent.items[i].type != CUTSCENE_ITEM_TYPE_CONCURRENT, + "Concurrent items cannot be nested" + ); + cutsceneItemStart( + &item->concurrent.items[i], + (cutsceneitemdata_t *)&data->concurrent.childData[i] + ); + } +} + +bool_t cutsceneConcurrentUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + for(uint8_t i = 0; i < item->concurrent.count; i++) { + if(data->concurrent.doneMask & (1u << i)) continue; + if(cutsceneItemUpdate( + &item->concurrent.items[i], + (cutsceneitemdata_t *)&data->concurrent.childData[i] + )) { + data->concurrent.doneMask |= (uint8_t)(1u << i); + } + } + uint8_t allDone = (uint8_t)((1u << item->concurrent.count) - 1u); + return data->concurrent.doneMask == allDone; +} diff --git a/src/dusk/rpg/cutscene/item/cutsceneconcurrent.h b/src/dusk/rpg/cutscene/item/cutsceneconcurrent.h new file mode 100644 index 00000000..48790dc6 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneconcurrent.h @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "cutscenewait.h" +#include "cutsceneentitywalkto.h" + +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + +/** Maximum number of items that may run inside a CUTSCENE_CONCURRENT. */ +#define CUTSCENE_CONCURRENT_MAX 8 + +/** + * Static (const) data for a concurrent cutscene item. + */ +typedef struct { + const cutsceneitem_t *items; + uint8_t count; +} cutsceneconcurrent_t; + +/** + * Runtime data for one non-concurrent child item. + * Concurrent items cannot be nested. + */ +typedef union { + cutscenewaitdata_t wait; + cutsceneentitywalktodata_t entityWalkTo; +} cutsceneconcurrentchilddata_t; + +/** Runtime data for a running concurrent item. */ +typedef struct { + cutsceneconcurrentchilddata_t childData[CUTSCENE_CONCURRENT_MAX]; + uint8_t doneMask; +} cutsceneconcurrentdata_t; + +/** + * Starts a concurrent item (starts all child items simultaneously). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneConcurrentStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates a concurrent item (ticks all unfinished children). + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true once every child has completed. + */ +bool_t cutsceneConcurrentUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); diff --git a/src/dusk/rpg/cutscene/item/cutsceneentityteleport.c b/src/dusk/rpg/cutscene/item/cutsceneentityteleport.c new file mode 100644 index 00000000..11d869c8 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneentityteleport.c @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "rpg/entity/entity.h" + +void cutsceneEntityTeleportStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + entityPositionSet( + &ENTITIES[item->entityTeleport.entityIndex], + item->entityTeleport.target + ); +} + +bool_t cutsceneEntityTeleportUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + return true; +} diff --git a/src/dusk/rpg/cutscene/item/cutsceneentityteleport.h b/src/dusk/rpg/cutscene/item/cutsceneentityteleport.h new file mode 100644 index 00000000..3237f89e --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneentityteleport.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "rpg/overworld/worldpos.h" + +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + +typedef struct { + uint8_t entityIndex; + worldpos_t target; +} cutsceneentityteleport_t; + +/** + * Starts an entity teleport item (teleports the entity immediately). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneEntityTeleportStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates an entity teleport item (always completes immediately). + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true always. + */ +bool_t cutsceneEntityTeleportUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); diff --git a/src/dusk/rpg/cutscene/item/cutsceneentitywalkto.c b/src/dusk/rpg/cutscene/item/cutsceneentitywalkto.c new file mode 100644 index 00000000..db55f974 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneentitywalkto.c @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "rpg/entity/entity.h" +#include "rpg/entity/entitypathstep.h" + +void cutsceneEntityWalkToStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + data->entityWalkTo.currentIndex = 0; +} + +bool_t cutsceneEntityWalkToUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + uint8_t i = data->entityWalkTo.currentIndex; + entity_t *e = &ENTITIES[item->entityWalkTo.entityIndex]; + if(!entityPathStep( + e, + item->entityWalkTo.positions[i], + item->entityWalkTo.walkAround + )) return false; + i++; + if(i < item->entityWalkTo.count) { + data->entityWalkTo.currentIndex = i; + return false; + } + return true; +} diff --git a/src/dusk/rpg/cutscene/item/cutsceneentitywalkto.h b/src/dusk/rpg/cutscene/item/cutsceneentitywalkto.h new file mode 100644 index 00000000..ecf4677c --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneentitywalkto.h @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "rpg/overworld/worldpos.h" + +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + +typedef struct { + uint8_t entityIndex; + const worldpos_t *positions; + uint8_t count; + bool_t walkAround; +} cutsceneentitywalkto_t; + +typedef struct { + uint8_t currentIndex; +} cutsceneentitywalktodata_t; + +/** + * Starts an entity walk-to item (resets the waypoint index). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneEntityWalkToStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates an entity walk-to item (steps the entity toward the next waypoint). + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true once all waypoints have been reached. + */ +bool_t cutsceneEntityWalkToUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); diff --git a/src/dusk/rpg/cutscene/item/cutscenefade.c b/src/dusk/rpg/cutscene/item/cutscenefade.c new file mode 100644 index 00000000..4bd89613 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenefade.c @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "ui/overlay/uifullbox.h" + +void cutsceneFadeStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + uiFullboxTransition( + &UI_FULLBOX_OVER, + item->fade.from, + item->fade.to, + item->fade.duration, + item->fade.easing + ); +} + +bool_t cutsceneFadeUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + return !( + UI_FULLBOX_OVER.duration > 0.0f && + UI_FULLBOX_OVER.time < UI_FULLBOX_OVER.duration + ); +} diff --git a/src/dusk/rpg/cutscene/item/cutscenefade.h b/src/dusk/rpg/cutscene/item/cutscenefade.h index 956abb01..c23b12f9 100644 --- a/src/dusk/rpg/cutscene/item/cutscenefade.h +++ b/src/dusk/rpg/cutscene/item/cutscenefade.h @@ -9,9 +9,35 @@ #include "display/color.h" #include "animation/easing.h" +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + typedef struct { color_t from; color_t to; float_t duration; easingtype_t easing; } cutscenefade_t; + +/** + * Starts a fade item (begins the overlay transition). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneFadeStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates a fade item. + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true once the overlay transition has completed. + */ +bool_t cutsceneFadeUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.c b/src/dusk/rpg/cutscene/item/cutsceneitem.c index c2e6b7a5..d767f96a 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.c +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.c @@ -1,30 +1,24 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "rpg/cutscene/cutscenesystem.h" -#include "input/input.h" -#include "ui/overlay/uifullbox.h" -#include "time/time.h" -#include "ui/rpg/uitextboxmain.h" -#include "rpg/entity/entity.h" -#include "rpg/entity/entitypathstep.h" void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) { switch(item->type) { case CUTSCENE_ITEM_TYPE_TEXT: - uiTextboxMainSetText(item->text.text); - break; - - case CUTSCENE_ITEM_TYPE_WAIT: - data->wait = item->wait; + cutsceneTextStart(item, data); break; case CUTSCENE_ITEM_TYPE_CALLBACK: - if(item->callback != NULL) item->callback(); + cutsceneCallbackStart(item, data); + break; + + case CUTSCENE_ITEM_TYPE_WAIT: + cutsceneWaitStart(item, data); break; case CUTSCENE_ITEM_TYPE_CUTSCENE: @@ -32,28 +26,23 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) { break; case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT: - entityPositionSet( - &ENTITIES[item->entityTeleport.entityIndex], - item->entityTeleport.target - ); + cutsceneEntityTeleportStart(item, data); break; case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO: - data->entityWalkTo.currentIndex = 0; + cutsceneEntityWalkToStart(item, data); break; case CUTSCENE_ITEM_TYPE_FADE: - uiFullboxTransition( - &UI_FULLBOX_OVER, - item->fade.from, - item->fade.to, - item->fade.duration, - item->fade.easing - ); + cutsceneFadeStart(item, data); break; case CUTSCENE_ITEM_TYPE_SET_PAUSE: - CUTSCENE_SYSTEM.pause = item->setPause; + cutsceneSetPauseStart(item, data); + break; + + case CUTSCENE_ITEM_TYPE_CONCURRENT: + cutsceneConcurrentStart(item, data); break; default: @@ -61,48 +50,33 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) { } } -void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) { +bool_t cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) { switch(item->type) { case CUTSCENE_ITEM_TYPE_TEXT: - if(uiTextboxMainIsActive()) return; - cutsceneSystemNext(); - break; + return cutsceneTextUpdate(item, data); + + case CUTSCENE_ITEM_TYPE_CALLBACK: + return cutsceneCallbackUpdate(item, data); case CUTSCENE_ITEM_TYPE_WAIT: - data->wait -= TIME.delta; - if(data->wait <= 0) cutsceneSystemNext(); - break; + return cutsceneWaitUpdate(item, data); case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT: - cutsceneSystemNext(); - break; + return cutsceneEntityTeleportUpdate(item, data); - case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO: { - uint8_t i = data->entityWalkTo.currentIndex; - entity_t *e = &ENTITIES[item->entityWalkTo.entityIndex]; - if(!entityPathStep(e, item->entityWalkTo.positions[i], item->entityWalkTo.walkAround)) return; - i++; - if(i < item->entityWalkTo.count) { - data->entityWalkTo.currentIndex = i; - return; - } - cutsceneSystemNext(); - break; - } + case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO: + return cutsceneEntityWalkToUpdate(item, data); case CUTSCENE_ITEM_TYPE_FADE: - if( - UI_FULLBOX_OVER.duration > 0.0f && - UI_FULLBOX_OVER.time < UI_FULLBOX_OVER.duration - ) return; - cutsceneSystemNext(); - break; + return cutsceneFadeUpdate(item, data); case CUTSCENE_ITEM_TYPE_SET_PAUSE: - cutsceneSystemNext(); - break; + return cutsceneSetPauseUpdate(item, data); + + case CUTSCENE_ITEM_TYPE_CONCURRENT: + return cutsceneConcurrentUpdate(item, data); default: - break; + return false; } -} \ No newline at end of file +} diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.h b/src/dusk/rpg/cutscene/item/cutsceneitem.h index 4964982a..7f5b3855 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.h +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.h @@ -1,6 +1,6 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -10,8 +10,10 @@ #include "cutscenecallback.h" #include "cutscenetext.h" #include "cutscenefade.h" -#include "rpg/cutscene/cutscenepause.h" -#include "rpg/overworld/worldpos.h" +#include "cutsceneentityteleport.h" +#include "cutsceneentitywalkto.h" +#include "cutscenesetpause.h" +#include "cutsceneconcurrent.h" typedef struct cutscene_s cutscene_t; @@ -24,54 +26,51 @@ typedef enum { CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO, CUTSCENE_ITEM_TYPE_FADE, - CUTSCENE_ITEM_TYPE_SET_PAUSE + CUTSCENE_ITEM_TYPE_SET_PAUSE, + CUTSCENE_ITEM_TYPE_CONCURRENT } cutsceneitemtype_t; -typedef struct cutsceneitem_s { +struct cutsceneitem_s { cutsceneitemtype_t type; - // Arguments/Data that will be used when this item is invoked. union { cutscenetext_t text; cutscenecallback_t callback; cutscenewait_t wait; const cutscene_t *cutscene; - struct { - uint8_t entityIndex; - worldpos_t target; - } entityTeleport; - struct { - uint8_t entityIndex; - const worldpos_t *positions; - uint8_t count; - bool_t walkAround; - } entityWalkTo; + cutsceneentityteleport_t entityTeleport; + cutsceneentitywalkto_t entityWalkTo; cutscenefade_t fade; cutscenepause_t setPause; + cutsceneconcurrent_t concurrent; }; -} cutsceneitem_t; +}; -typedef struct { - uint8_t currentIndex; -} cutsceneentitywalktodata_t; - -typedef union { +typedef union cutsceneitemdata_u { cutscenewaitdata_t wait; cutsceneentitywalktodata_t entityWalkTo; + cutsceneconcurrentdata_t concurrent; } cutsceneitemdata_t; /** * Start the given cutscene item. - * + * * @param item The cutscene item to start. - * @param data The cutscene item data storage. + * @param data Runtime data storage (pre-zeroed by caller). */ -void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data); +void cutsceneItemStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); /** * Tick the given cutscene item (one frame). - * + * * @param item The cutscene item to tick. - * @param data The cutscene item data storage. + * @param data Runtime data storage. + * @returns true if the item is complete and the cutscene should advance. */ -void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data); \ No newline at end of file +bool_t cutsceneItemUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); diff --git a/src/dusk/rpg/cutscene/item/cutscenesetpause.c b/src/dusk/rpg/cutscene/item/cutscenesetpause.c new file mode 100644 index 00000000..e1cfb725 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenesetpause.c @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "rpg/cutscene/cutscenesystem.h" + +void cutsceneSetPauseStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + CUTSCENE_SYSTEM.pause = item->setPause; +} + +bool_t cutsceneSetPauseUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + return true; +} diff --git a/src/dusk/rpg/cutscene/item/cutscenesetpause.h b/src/dusk/rpg/cutscene/item/cutscenesetpause.h new file mode 100644 index 00000000..bb04cf6a --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenesetpause.h @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "rpg/cutscene/cutscenepause.h" + +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + +/** + * Starts a set-pause item (applies the new pause flags immediately). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneSetPauseStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates a set-pause item (always completes immediately). + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true always. + */ +bool_t cutsceneSetPauseUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); diff --git a/src/dusk/rpg/cutscene/item/cutscenetext.c b/src/dusk/rpg/cutscene/item/cutscenetext.c new file mode 100644 index 00000000..9d0b68e4 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenetext.c @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "ui/rpg/uitextboxmain.h" + +void cutsceneTextStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + uiTextboxMainSetText(item->text.text); +} + +bool_t cutsceneTextUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + return !uiTextboxMainIsActive(); +} diff --git a/src/dusk/rpg/cutscene/item/cutscenetext.h b/src/dusk/rpg/cutscene/item/cutscenetext.h index 76fb6026..61017806 100644 --- a/src/dusk/rpg/cutscene/item/cutscenetext.h +++ b/src/dusk/rpg/cutscene/item/cutscenetext.h @@ -1,6 +1,6 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -8,8 +8,34 @@ #pragma once #include "dusk.h" +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + #define CUTSCENE_TEXT_MAX_CHARS 256 typedef struct { char_t text[CUTSCENE_TEXT_MAX_CHARS]; -} cutscenetext_t; \ No newline at end of file +} cutscenetext_t; + +/** + * Starts a text item (shows the textbox with the item's text). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneTextStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates a text item. + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true once the textbox has been dismissed. + */ +bool_t cutsceneTextUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); \ No newline at end of file diff --git a/src/dusk/rpg/cutscene/item/cutscenewait.c b/src/dusk/rpg/cutscene/item/cutscenewait.c new file mode 100644 index 00000000..505e73aa --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenewait.c @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "cutsceneitem.h" +#include "time/time.h" + +void cutsceneWaitStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + data->wait = item->wait; +} + +bool_t cutsceneWaitUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +) { + data->wait -= TIME.delta; + return data->wait <= 0; +} diff --git a/src/dusk/rpg/cutscene/item/cutscenewait.h b/src/dusk/rpg/cutscene/item/cutscenewait.h index 9d590df2..985dca67 100644 --- a/src/dusk/rpg/cutscene/item/cutscenewait.h +++ b/src/dusk/rpg/cutscene/item/cutscenewait.h @@ -1,6 +1,6 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -8,5 +8,31 @@ #pragma once #include "dusk.h" +typedef struct cutsceneitem_s cutsceneitem_t; +typedef union cutsceneitemdata_u cutsceneitemdata_t; + typedef float_t cutscenewait_t; -typedef float_t cutscenewaitdata_t; \ No newline at end of file +typedef float_t cutscenewaitdata_t; + +/** + * Starts a wait item (stores the duration in data). + * + * @param item The cutscene item. + * @param data Runtime data storage. + */ +void cutsceneWaitStart( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); + +/** + * Updates a wait item. + * + * @param item The cutscene item. + * @param data Runtime data storage. + * @returns true when the wait has elapsed. + */ +bool_t cutsceneWaitUpdate( + const cutsceneitem_t *item, + cutsceneitemdata_t *data +); \ No newline at end of file diff --git a/src/dusk/rpg/cutscene/scene/testcutscene.h b/src/dusk/rpg/cutscene/scene/testcutscene.h index b8690d7a..ee6cfee5 100755 --- a/src/dusk/rpg/cutscene/scene/testcutscene.h +++ b/src/dusk/rpg/cutscene/scene/testcutscene.h @@ -15,8 +15,9 @@ CUTSCENE(TEST_ONE, DEFAULT, CUTSCENE(TEST_TWO, DEFAULT, CUTSCENE_TEXT("Test Two."), - CUTSCENE_SET_PAUSE(CUTSCENE_PAUSE_NONE), - CUTSCENE_WAIT(5.0f), - CUTSCENE_TEXT("Hello world") - // CUTSCENE_ENTITY_WALK_TO(0, 0, 0, 0), + CUTSCENE_CONCURRENT( + CUTSCENE_ENTITY_WALK_TO(0, 4, 4, 0), + CUTSCENE_ENTITY_WALK_TO(1, 8, 2, 0), + ), + CUTSCENE_TEXT("Done."), ); \ No newline at end of file