From 900b3f85580bedcf5812cc925327d1133f4e51f0 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 2 Jul 2026 12:54:12 -0500 Subject: [PATCH] More cutscene stuff --- src/dusk/rpg/cutscene/cutscene.h | 20 +++++++++- src/dusk/rpg/cutscene/item/CMakeLists.txt | 1 - .../rpg/cutscene/item/cutsceneentitymove.c | 39 ------------------- .../rpg/cutscene/item/cutsceneentitymove.h | 24 ------------ src/dusk/rpg/cutscene/item/cutscenefade.h | 17 ++++++++ src/dusk/rpg/cutscene/item/cutsceneitem.c | 32 ++++++++++++--- src/dusk/rpg/cutscene/item/cutsceneitem.h | 8 ++-- src/dusk/rpg/cutscene/scene/testcutscene.h | 12 +++--- src/dusk/rpg/entity/entity.c | 9 +++++ src/dusk/rpg/entity/entity.h | 10 ++++- src/dusk/rpg/rpg.c | 4 +- 11 files changed, 95 insertions(+), 81 deletions(-) delete mode 100644 src/dusk/rpg/cutscene/item/cutsceneentitymove.c delete mode 100644 src/dusk/rpg/cutscene/item/cutsceneentitymove.h create mode 100644 src/dusk/rpg/cutscene/item/cutscenefade.h diff --git a/src/dusk/rpg/cutscene/cutscene.h b/src/dusk/rpg/cutscene/cutscene.h index 03f8bb53..bc89329b 100644 --- a/src/dusk/rpg/cutscene/cutscene.h +++ b/src/dusk/rpg/cutscene/cutscene.h @@ -33,4 +33,22 @@ typedef struct cutscene_s { { .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = WAIT } #define CUTSCENE_CUTSCENE(CUTSCENE) \ - { .type = CUTSCENE_ITEM_TYPE_CUTSCENE, .cutscene = CUTSCENE_REFERENCE(CUTSCENE) } + { \ + .type = CUTSCENE_ITEM_TYPE_CUTSCENE, \ + .cutscene = CUTSCENE_REFERENCE(CUTSCENE) \ + } + +#define CUTSCENE_CALLBACK(CALLBACK) \ + { .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = CALLBACK } + +#define CUTSCENE_ENTITY_TELEPORT(ENTITY_INDEX, X, Y, Z) \ + { \ + .type = CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, \ + .entityTeleport = { .entityIndex = ENTITY_INDEX, .target = { X, Y, Z } } \ + } + +#define CUTSCENE_FADE(FROM, TO, DURATION, EASING) \ + { \ + .type = CUTSCENE_ITEM_TYPE_FADE, \ + .fade = { .from = FROM, .to = TO, .duration = DURATION, .easing = EASING } \ + } diff --git a/src/dusk/rpg/cutscene/item/CMakeLists.txt b/src/dusk/rpg/cutscene/item/CMakeLists.txt index f30d8b58..6b3e271a 100755 --- a/src/dusk/rpg/cutscene/item/CMakeLists.txt +++ b/src/dusk/rpg/cutscene/item/CMakeLists.txt @@ -7,5 +7,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC cutsceneitem.c - cutsceneentitymove.c ) \ No newline at end of file diff --git a/src/dusk/rpg/cutscene/item/cutsceneentitymove.c b/src/dusk/rpg/cutscene/item/cutsceneentitymove.c deleted file mode 100644 index 39be9996..00000000 --- a/src/dusk/rpg/cutscene/item/cutsceneentitymove.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "cutsceneentitymove.h" -#include "rpg/cutscene/cutscenesystem.h" -#include "rpg/entity/entity.h" - -void cutsceneEntityMoveStart(const cutsceneitem_t *item) { -} - -void cutsceneEntityMoveUpdate(const cutsceneitem_t *item) { - entity_t *entity = &ENTITIES[item->entityMove.entityIndex]; - - if(worldPosIsEqual(entity->position, item->entityMove.target)) { - cutsceneSystemNext(); - return; - } - - entitydir_t dir; - if(entity->position.x != item->entityMove.target.x) { - dir = entity->position.x < item->entityMove.target.x - ? ENTITY_DIR_EAST : ENTITY_DIR_WEST; - } else { - dir = entity->position.y < item->entityMove.target.y - ? ENTITY_DIR_SOUTH : ENTITY_DIR_NORTH; - } - - if(entityCanTurn(entity)) entityTurn(entity, dir); - - if(item->entityMove.run) { - if(entityCanRun(entity)) entityRun(entity, dir); - } else { - if(entityCanWalk(entity)) entityWalk(entity, dir); - } -} diff --git a/src/dusk/rpg/cutscene/item/cutsceneentitymove.h b/src/dusk/rpg/cutscene/item/cutsceneentitymove.h deleted file mode 100644 index cefa06ad..00000000 --- a/src/dusk/rpg/cutscene/item/cutsceneentitymove.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "cutsceneitem.h" - -/** - * Handles the start of an entity move cutscene item. - * - * @param item The cutscene item. - */ -void cutsceneEntityMoveStart(const cutsceneitem_t *item); - -/** - * Updates an entity move cutscene item, steering the entity one step - * per frame toward the target and advancing the cutscene on arrival. - * - * @param item The cutscene item. - */ -void cutsceneEntityMoveUpdate(const cutsceneitem_t *item); diff --git a/src/dusk/rpg/cutscene/item/cutscenefade.h b/src/dusk/rpg/cutscene/item/cutscenefade.h new file mode 100644 index 00000000..956abb01 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutscenefade.h @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "display/color.h" +#include "animation/easing.h" + +typedef struct { + color_t from; + color_t to; + float_t duration; + easingtype_t easing; +} cutscenefade_t; diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.c b/src/dusk/rpg/cutscene/item/cutsceneitem.c index 263ebf7d..1c0f0007 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.c +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.c @@ -6,10 +6,11 @@ */ #include "rpg/cutscene/cutscenesystem.h" -#include "cutsceneentitymove.h" #include "input/input.h" +#include "ui/overlay/uifullbox.h" #include "time/time.h" #include "ui/rpg/uitextboxmain.h" +#include "rpg/entity/entity.h" void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) { switch(item->type) { @@ -29,8 +30,21 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) { if(item->cutscene != NULL) cutsceneSystemStartCutscene(item->cutscene); break; - case CUTSCENE_ITEM_TYPE_ENTITY_MOVE: - cutsceneEntityMoveStart(item); + case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT: + entityPositionSet( + &ENTITIES[item->entityTeleport.entityIndex], + item->entityTeleport.target + ); + break; + + case CUTSCENE_ITEM_TYPE_FADE: + uiFullboxTransition( + &UI_FULLBOX_OVER, + item->fade.from, + item->fade.to, + item->fade.duration, + item->fade.easing + ); break; default: @@ -50,8 +64,16 @@ void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) { if(data->wait <= 0) cutsceneSystemNext(); break; - case CUTSCENE_ITEM_TYPE_ENTITY_MOVE: - cutsceneEntityMoveUpdate(item); + case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT: + cutsceneSystemNext(); + break; + + case CUTSCENE_ITEM_TYPE_FADE: + if( + UI_FULLBOX_OVER.duration > 0.0f && + UI_FULLBOX_OVER.time < UI_FULLBOX_OVER.duration + ) return; + cutsceneSystemNext(); break; default: diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.h b/src/dusk/rpg/cutscene/item/cutsceneitem.h index 422c710d..7fb1b548 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.h +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.h @@ -9,6 +9,7 @@ #include "cutscenewait.h" #include "cutscenecallback.h" #include "cutscenetext.h" +#include "cutscenefade.h" #include "rpg/overworld/worldpos.h" typedef struct cutscene_s cutscene_t; @@ -19,7 +20,8 @@ typedef enum { CUTSCENE_ITEM_TYPE_CALLBACK, CUTSCENE_ITEM_TYPE_WAIT, CUTSCENE_ITEM_TYPE_CUTSCENE, - CUTSCENE_ITEM_TYPE_ENTITY_MOVE + CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, + CUTSCENE_ITEM_TYPE_FADE } cutsceneitemtype_t; typedef struct cutsceneitem_s { @@ -34,8 +36,8 @@ typedef struct cutsceneitem_s { struct { uint8_t entityIndex; worldpos_t target; - bool_t run; - } entityMove; + } entityTeleport; + cutscenefade_t fade; }; } cutsceneitem_t; diff --git a/src/dusk/rpg/cutscene/scene/testcutscene.h b/src/dusk/rpg/cutscene/scene/testcutscene.h index fd08a922..db37debd 100755 --- a/src/dusk/rpg/cutscene/scene/testcutscene.h +++ b/src/dusk/rpg/cutscene/scene/testcutscene.h @@ -7,14 +7,16 @@ #pragma once #include "rpg/cutscene/cutscene.h" +#include "rpg/cutscene/cutscenesystem.h" CUTSCENE(TEST_ONE, DEFAULT, - CUTSCENE_TEXT("This is a test cutscene."), - CUTSCENE_WAIT(0.5f), - CUTSCENE_TEXT("It has multiple lines of text.\nAnd waits in between.") + CUTSCENE_TEXT("Test One."), ); CUTSCENE(TEST_TWO, DEFAULT, - CUTSCENE_WAIT(0.1f), - CUTSCENE_CUTSCENE(TEST_ONE), + CUTSCENE_TEXT("Test Two."), + CUTSCENE_FADE(COLOR_TRANSPARENT_BLACK, COLOR_BLACK, 1.0f, EASING_LINEAR), + CUTSCENE_ENTITY_TELEPORT(0, 20, 0, 0), + CUTSCENE_WAIT(1.0f), + CUTSCENE_FADE(COLOR_BLACK, COLOR_TRANSPARENT_BLACK, 1.0f, EASING_LINEAR), ); \ No newline at end of file diff --git a/src/dusk/rpg/entity/entity.c b/src/dusk/rpg/entity/entity.c index a3df79e0..844fdfde 100644 --- a/src/dusk/rpg/entity/entity.c +++ b/src/dusk/rpg/entity/entity.c @@ -244,6 +244,15 @@ uint8_t entityGetAvailable() { return 0xFF; } +void entityPositionSet(entity_t *entity, const worldpos_t pos) { + assertNotNull(entity, "Entity pointer cannot be NULL"); + entity->lastPosition = pos; + entity->position = pos; + entity->animation = ENTITY_ANIM_IDLE; + entity->animTime = 0; + entity->walkEndCooldown = 0; +} + void entitySetChunk(entity_t *entity, const uint8_t chunkIndex) { assertNotNull(entity, "Entity pointer cannot be NULL"); diff --git a/src/dusk/rpg/entity/entity.h b/src/dusk/rpg/entity/entity.h index 787d8aa5..d924addf 100644 --- a/src/dusk/rpg/entity/entity.h +++ b/src/dusk/rpg/entity/entity.h @@ -122,4 +122,12 @@ uint8_t entityGetAvailable(); * @param entity Pointer to the entity. * @param chunkIndex Index of the chunk to assign to, or 0xFF for none. */ -void entitySetChunk(entity_t *entity, const uint8_t chunkIndex); \ No newline at end of file +void entitySetChunk(entity_t *entity, const uint8_t chunkIndex); + +/** + * Instantly moves an entity to a world position, resetting movement state. + * + * @param entity Pointer to the entity to move. + * @param pos The world position to place the entity at. + */ +void entityPositionSet(entity_t *entity, const worldpos_t pos); \ No newline at end of file diff --git a/src/dusk/rpg/rpg.c b/src/dusk/rpg/rpg.c index c825c250..5dba6e44 100644 --- a/src/dusk/rpg/rpg.c +++ b/src/dusk/rpg/rpg.c @@ -33,7 +33,7 @@ errorret_t rpgInit(void) { assertTrue(entIndex != 0xFF, "No available entity slots!."); entity_t *ent = &ENTITIES[entIndex]; entityInit(ent, ENTITY_TYPE_PLAYER); - ent->position = (worldpos_t){ 10, 2, 0 }; + entityPositionSet(ent, (worldpos_t){ 10, 2, 0 }); RPG_CAMERA.mode = RPG_CAMERA_MODE_FOLLOW_ENTITY; RPG_CAMERA.followEntity.followEntityId = ent->id; { @@ -47,7 +47,7 @@ errorret_t rpgInit(void) { entity_t *npc = &ENTITIES[npcIndex]; entityInit(npc, ENTITY_TYPE_NPC); npcSetMoveType(npc, NPC_MOVE_TYPE_PATH); - npc->position = (worldpos_t){ 8, 8, 1 }; + entityPositionSet(npc, (worldpos_t){ 8, 8, 1 }); npc->interact.type = ENTITY_INTERACT_CUTSCENE; npc->interact.data.cutscene = CUTSCENE_REFERENCE(TEST_TWO); {