Lot of cutscene cleanup

This commit is contained in:
2026-07-02 15:53:02 -05:00
parent de67315178
commit bed3f20118
31 changed files with 320 additions and 36 deletions
+12
View File
@@ -64,6 +64,12 @@ typedef struct cutscene_s {
} \ } \
} }
#define CUTSCENE_ENTITY_REMOVE(ENTITY_INDEX) \
{ \
.type = CUTSCENE_ITEM_TYPE_ENTITY_REMOVE, \
.entityRemove = { .entityIndex = ENTITY_INDEX } \
}
#define CUTSCENE_ENTITY_TELEPORT(ENTITY_INDEX, X, Y, Z) \ #define CUTSCENE_ENTITY_TELEPORT(ENTITY_INDEX, X, Y, Z) \
{ \ { \
.type = CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, \ .type = CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, \
@@ -91,6 +97,12 @@ typedef struct cutscene_s {
#define CUTSCENE_SET_PAUSE(FLAGS) \ #define CUTSCENE_SET_PAUSE(FLAGS) \
{ .type = CUTSCENE_ITEM_TYPE_SET_PAUSE, .setPause = (FLAGS) } { .type = CUTSCENE_ITEM_TYPE_SET_PAUSE, .setPause = (FLAGS) }
#define CUTSCENE_ITEM_GIVE(ITEM_ID, QUANTITY) \
{ \
.type = CUTSCENE_ITEM_TYPE_ITEM_GIVE, \
.itemGive = { .item = ITEM_ID, .quantity = QUANTITY } \
}
// Runs all listed items simultaneously and waits until all are done. // Runs all listed items simultaneously and waits until all are done.
// Concurrent items cannot be nested inside another CUTSCENE_CONCURRENT. // Concurrent items cannot be nested inside another CUTSCENE_CONCURRENT.
#define CUTSCENE_CONCURRENT(...) \ #define CUTSCENE_CONCURRENT(...) \
+39 -1
View File
@@ -6,7 +6,9 @@
*/ */
#include "cutscenesystem.h" #include "cutscenesystem.h"
#include "rpg/entity/entity.h"
#include "util/memory.h" #include "util/memory.h"
#include "assert/assert.h"
cutscenesystem_t CUTSCENE_SYSTEM; cutscenesystem_t CUTSCENE_SYSTEM;
@@ -15,9 +17,19 @@ void cutsceneSystemInit() {
} }
void cutsceneSystemStartCutscene(const cutscene_t *cutscene) { void cutsceneSystemStartCutscene(const cutscene_t *cutscene) {
cutsceneSystemStartCutsceneWith(cutscene, NULL, NULL);
}
void cutsceneSystemStartCutsceneWith(
const cutscene_t *cutscene,
entity_t *interact,
entity_t *interacted
) {
CUTSCENE_SYSTEM.scene = cutscene; CUTSCENE_SYSTEM.scene = cutscene;
CUTSCENE_SYSTEM.pause = cutscene->pause; CUTSCENE_SYSTEM.pause = cutscene->pause;
CUTSCENE_SYSTEM.currentItem = 0xFF;// Set to 0xFF so start wraps. CUTSCENE_SYSTEM.entityInteract = interact;
CUTSCENE_SYSTEM.entityInteracted = interacted;
CUTSCENE_SYSTEM.currentItem = 0xFF;// Set to 0xFF so Next wraps to 0.
cutsceneSystemNext(); cutsceneSystemNext();
} }
@@ -40,6 +52,8 @@ void cutsceneSystemNext() {
CUTSCENE_SYSTEM.scene = NULL; CUTSCENE_SYSTEM.scene = NULL;
CUTSCENE_SYSTEM.currentItem = 0xFF; CUTSCENE_SYSTEM.currentItem = 0xFF;
CUTSCENE_SYSTEM.pause = CUTSCENE_PAUSE_NONE; CUTSCENE_SYSTEM.pause = CUTSCENE_PAUSE_NONE;
CUTSCENE_SYSTEM.entityInteract = NULL;
CUTSCENE_SYSTEM.entityInteracted = NULL;
return; return;
} }
@@ -55,8 +69,32 @@ const cutsceneitem_t * cutsceneSystemGetCurrentItem() {
return &CUTSCENE_SYSTEM.scene->items[CUTSCENE_SYSTEM.currentItem]; return &CUTSCENE_SYSTEM.scene->items[CUTSCENE_SYSTEM.currentItem];
} }
entity_t * cutsceneSystemGetEntity(const uint8_t entityIndex) {
if(entityIndex == CUTSCENE_ENTITY_INTERACT) {
assertNotNull(
CUTSCENE_SYSTEM.entityInteract,
"CUTSCENE_ENTITY_INTERACT used but no interact entity is set"
);
return CUTSCENE_SYSTEM.entityInteract;
}
if(entityIndex == CUTSCENE_ENTITY_INTERACTED) {
assertNotNull(
CUTSCENE_SYSTEM.entityInteracted,
"CUTSCENE_ENTITY_INTERACTED used but no interacted entity is set"
);
return CUTSCENE_SYSTEM.entityInteracted;
}
assertTrue(
entityIndex < ENTITY_COUNT,
"Entity index is out of range"
);
return &ENTITIES[entityIndex];
}
void cutsceneSystemDispose() { void cutsceneSystemDispose() {
CUTSCENE_SYSTEM.scene = NULL; CUTSCENE_SYSTEM.scene = NULL;
CUTSCENE_SYSTEM.currentItem = 0xFF; CUTSCENE_SYSTEM.currentItem = 0xFF;
CUTSCENE_SYSTEM.pause = CUTSCENE_PAUSE_NONE; CUTSCENE_SYSTEM.pause = CUTSCENE_PAUSE_NONE;
CUTSCENE_SYSTEM.entityInteract = NULL;
CUTSCENE_SYSTEM.entityInteracted = NULL;
} }
+31 -1
View File
@@ -8,10 +8,17 @@
#pragma once #pragma once
#include "cutscene.h" #include "cutscene.h"
typedef struct entity_s entity_t;
#define CUTSCENE_ENTITY_INTERACT ((uint8_t)0xFE)
#define CUTSCENE_ENTITY_INTERACTED ((uint8_t)0xFD)
typedef struct { typedef struct {
const cutscene_t *scene; const cutscene_t *scene;
uint8_t currentItem; uint8_t currentItem;
cutscenepause_t pause; cutscenepause_t pause;
entity_t *entityInteract;
entity_t *entityInteracted;
// Data (used by the current item). // Data (used by the current item).
cutsceneitemdata_t data; cutsceneitemdata_t data;
@@ -25,12 +32,35 @@ extern cutscenesystem_t CUTSCENE_SYSTEM;
void cutsceneSystemInit(); void cutsceneSystemInit();
/** /**
* Start a cutscene. * Start a cutscene with no bound entities.
* *
* @param cutscene Pointer to the cutscene to start. * @param cutscene Pointer to the cutscene to start.
*/ */
void cutsceneSystemStartCutscene(const cutscene_t *cutscene); void cutsceneSystemStartCutscene(const cutscene_t *cutscene);
/**
* Start a cutscene with the two entities that triggered it.
*
* @param cutscene Pointer to the cutscene to start.
* @param interact The entity that initiated the interaction (player).
* @param interacted The entity that was interacted with (NPC).
*/
void cutsceneSystemStartCutsceneWith(
const cutscene_t *cutscene,
entity_t *interact,
entity_t *interacted
);
/**
* Resolves a raw entity index (or sentinel) to an entity pointer.
* Handles CUTSCENE_ENTITY_INTERACT and CUTSCENE_ENTITY_INTERACTED.
* Asserts the resolved entity is within bounds.
*
* @param entityIndex Raw entity index or sentinel value.
* @returns Pointer to the resolved entity.
*/
entity_t * cutsceneSystemGetEntity(const uint8_t entityIndex);
/** /**
* Advance to the next item in the cutscene. * Advance to the next item in the cutscene.
*/ */
+5 -8
View File
@@ -3,16 +3,13 @@
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
cutsceneitem.c cutsceneitem.c
cutscenewait.c
cutscenetext.c
cutscenecallback.c cutscenecallback.c
cutscenefade.c
cutsceneentityteleport.c
cutsceneentitywalkto.c
cutscenesetpause.c
cutsceneconcurrent.c
) )
add_subdirectory(control)
add_subdirectory(entity)
add_subdirectory(item)
add_subdirectory(ui)
@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
cutscenewait.c
cutscenesetpause.c
cutsceneconcurrent.c
)
@@ -5,7 +5,7 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "assert/assert.h" #include "assert/assert.h"
void cutsceneConcurrentStart( void cutsceneConcurrentStart(
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include "cutscenewait.h" #include "cutscenewait.h"
#include "cutsceneentitywalkto.h" #include "rpg/cutscene/item/entity/cutsceneentitywalkto.h"
typedef struct cutsceneitem_s cutsceneitem_t; typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t; typedef union cutsceneitemdata_u cutsceneitemdata_t;
@@ -5,7 +5,7 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "rpg/cutscene/cutscenesystem.h" #include "rpg/cutscene/cutscenesystem.h"
void cutsceneSetPauseStart( void cutsceneSetPauseStart(
@@ -5,7 +5,7 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "time/time.h" #include "time/time.h"
void cutsceneWaitStart( void cutsceneWaitStart(
+14
View File
@@ -45,6 +45,14 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
cutsceneConcurrentStart(item, data); cutsceneConcurrentStart(item, data);
break; break;
case CUTSCENE_ITEM_TYPE_ITEM_GIVE:
cutsceneItemGiveStart(item, data);
break;
case CUTSCENE_ITEM_TYPE_ENTITY_REMOVE:
cutsceneEntityRemoveStart(item, data);
break;
default: default:
break; break;
} }
@@ -76,6 +84,12 @@ bool_t cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data)
case CUTSCENE_ITEM_TYPE_CONCURRENT: case CUTSCENE_ITEM_TYPE_CONCURRENT:
return cutsceneConcurrentUpdate(item, data); return cutsceneConcurrentUpdate(item, data);
case CUTSCENE_ITEM_TYPE_ITEM_GIVE:
return cutsceneItemGiveUpdate(item, data);
case CUTSCENE_ITEM_TYPE_ENTITY_REMOVE:
return cutsceneEntityRemoveUpdate(item, data);
default: default:
return false; return false;
} }
+14 -8
View File
@@ -6,14 +6,16 @@
*/ */
#pragma once #pragma once
#include "cutscenewait.h"
#include "cutscenecallback.h" #include "cutscenecallback.h"
#include "cutscenetext.h" #include "control/cutscenewait.h"
#include "cutscenefade.h" #include "control/cutscenesetpause.h"
#include "cutsceneentityteleport.h" #include "control/cutsceneconcurrent.h"
#include "cutsceneentitywalkto.h" #include "entity/cutsceneentityteleport.h"
#include "cutscenesetpause.h" #include "entity/cutsceneentitywalkto.h"
#include "cutsceneconcurrent.h" #include "entity/cutsceneentityremove.h"
#include "ui/cutscenetext.h"
#include "ui/cutscenefade.h"
#include "item/cutsceneitemgive.h"
typedef struct cutscene_s cutscene_t; typedef struct cutscene_s cutscene_t;
@@ -27,7 +29,9 @@ typedef enum {
CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO, CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO,
CUTSCENE_ITEM_TYPE_FADE, CUTSCENE_ITEM_TYPE_FADE,
CUTSCENE_ITEM_TYPE_SET_PAUSE, CUTSCENE_ITEM_TYPE_SET_PAUSE,
CUTSCENE_ITEM_TYPE_CONCURRENT CUTSCENE_ITEM_TYPE_CONCURRENT,
CUTSCENE_ITEM_TYPE_ITEM_GIVE,
CUTSCENE_ITEM_TYPE_ENTITY_REMOVE
} cutsceneitemtype_t; } cutsceneitemtype_t;
struct cutsceneitem_s { struct cutsceneitem_s {
@@ -43,6 +47,8 @@ struct cutsceneitem_s {
cutscenefade_t fade; cutscenefade_t fade;
cutscenepause_t setPause; cutscenepause_t setPause;
cutsceneconcurrent_t concurrent; cutsceneconcurrent_t concurrent;
cutsceneitemgive_t itemGive;
cutsceneentityremove_t entityRemove;
}; };
}; };
@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
cutsceneentityteleport.c
cutsceneentitywalkto.c
cutsceneentityremove.c
)
@@ -0,0 +1,25 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "rpg/cutscene/item/cutsceneitem.h"
#include "rpg/cutscene/cutscenesystem.h"
#include "rpg/entity/entity.h"
void cutsceneEntityRemoveStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
cutsceneSystemGetEntity(item->entityRemove.entityIndex)->type = \
ENTITY_TYPE_NULL;
}
bool_t cutsceneEntityRemoveUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
return true;
}
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t;
typedef struct {
uint8_t entityIndex;
} cutsceneentityremove_t;
/**
* Starts an entity remove step (removes the entity from the world immediately).
*
* @param item The cutscene item.
* @param data Runtime data storage.
*/
void cutsceneEntityRemoveStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
/**
* Updates an entity remove step (always completes immediately).
*
* @param item The cutscene item.
* @param data Runtime data storage.
* @returns true always.
*/
bool_t cutsceneEntityRemoveUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
@@ -5,7 +5,8 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "rpg/cutscene/cutscenesystem.h"
#include "rpg/entity/entity.h" #include "rpg/entity/entity.h"
void cutsceneEntityTeleportStart( void cutsceneEntityTeleportStart(
@@ -13,7 +14,7 @@ void cutsceneEntityTeleportStart(
cutsceneitemdata_t *data cutsceneitemdata_t *data
) { ) {
entityPositionSet( entityPositionSet(
&ENTITIES[item->entityTeleport.entityIndex], cutsceneSystemGetEntity(item->entityTeleport.entityIndex),
item->entityTeleport.target item->entityTeleport.target
); );
} }
@@ -5,8 +5,8 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "rpg/entity/entity.h" #include "rpg/cutscene/cutscenesystem.h"
#include "rpg/entity/entitypathstep.h" #include "rpg/entity/entitypathstep.h"
void cutsceneEntityWalkToStart( void cutsceneEntityWalkToStart(
@@ -21,7 +21,7 @@ bool_t cutsceneEntityWalkToUpdate(
cutsceneitemdata_t *data cutsceneitemdata_t *data
) { ) {
uint8_t i = data->entityWalkTo.currentIndex; uint8_t i = data->entityWalkTo.currentIndex;
entity_t *e = &ENTITIES[item->entityWalkTo.entityIndex]; entity_t *e = cutsceneSystemGetEntity(item->entityWalkTo.entityIndex);
if(!entityPathStep( if(!entityPathStep(
e, e,
item->entityWalkTo.positions[i], item->entityWalkTo.positions[i],
@@ -0,0 +1,9 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
cutsceneitemgive.c
)
@@ -0,0 +1,35 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "rpg/cutscene/item/cutsceneitem.h"
#include "rpg/item/backpack.h"
#include "ui/rpg/uitextboxmain.h"
#include "util/string.h"
void cutsceneItemGiveStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
backpackAdd(item->itemGive.item, item->itemGive.quantity);
char_t msg[CUTSCENE_TEXT_MAX_CHARS];
stringFormat(
msg,
CUTSCENE_TEXT_MAX_CHARS - 1,
"Received %s x%u",
ITEMS[item->itemGive.item].name,
(uint32_t)item->itemGive.quantity
);
uiTextboxMainSetText(msg);
}
bool_t cutsceneItemGiveUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
return !uiTextboxMainIsActive();
}
@@ -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/item/item.h"
typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t;
typedef struct {
itemid_t item;
uint8_t quantity;
} cutsceneitemgive_t;
/**
* Starts a give-item step (adds the item to the player's backpack immediately).
*
* @param item The cutscene item.
* @param data Runtime data storage.
*/
void cutsceneItemGiveStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
/**
* Updates a give-item step (always completes immediately).
*
* @param item The cutscene item.
* @param data Runtime data storage.
* @returns true always.
*/
bool_t cutsceneItemGiveUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
cutscenetext.c
cutscenefade.c
)
@@ -5,7 +5,7 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "ui/overlay/uifullbox.h" #include "ui/overlay/uifullbox.h"
void cutsceneFadeStart( void cutsceneFadeStart(
@@ -5,7 +5,7 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "cutsceneitem.h" #include "rpg/cutscene/item/cutsceneitem.h"
#include "ui/rpg/uitextboxmain.h" #include "ui/rpg/uitextboxmain.h"
void cutsceneTextStart( void cutsceneTextStart(
+3 -2
View File
@@ -16,8 +16,9 @@ CUTSCENE(TEST_ONE, DEFAULT,
CUTSCENE(TEST_TWO, DEFAULT, CUTSCENE(TEST_TWO, DEFAULT,
CUTSCENE_TEXT("Test Two."), CUTSCENE_TEXT("Test Two."),
CUTSCENE_CONCURRENT( CUTSCENE_CONCURRENT(
CUTSCENE_ENTITY_WALK_TO(0, 4, 4, 0), CUTSCENE_ENTITY_WALK_TO(CUTSCENE_ENTITY_INTERACT, 4, 4, 0),
CUTSCENE_ENTITY_WALK_TO(1, 8, 2, 0), CUTSCENE_ENTITY_WALK_TO(CUTSCENE_ENTITY_INTERACTED, 8, 2, 0),
), ),
CUTSCENE_ITEM_GIVE(ITEM_ID_POTATO, 3),
CUTSCENE_TEXT("Done."), CUTSCENE_TEXT("Done."),
); );
@@ -20,7 +20,11 @@ void entityInteractWith(entity_t *player, entity_t *target) {
target->interact.data.cutscene, target->interact.data.cutscene,
"Interact cutscene pointer cannot be NULL" "Interact cutscene pointer cannot be NULL"
); );
cutsceneSystemStartCutscene(target->interact.data.cutscene); cutsceneSystemStartCutsceneWith(
target->interact.data.cutscene,
player,
target
);
break; break;
case ENTITY_INTERACT_PRINT: case ENTITY_INTERACT_PRINT:
+2 -1
View File
@@ -11,6 +11,7 @@
#include "rpg/overworld/map.h" #include "rpg/overworld/map.h"
#include "rpg/cutscene/cutscenesystem.h" #include "rpg/cutscene/cutscenesystem.h"
#include "rpg/cutscene/scene/testcutscene.h" #include "rpg/cutscene/scene/testcutscene.h"
#include "rpg/item/backpack.h"
#include "time/time.h" #include "time/time.h"
#include "rpgcamera.h" #include "rpgcamera.h"
#include "util/memory.h" #include "util/memory.h"
@@ -20,7 +21,7 @@
errorret_t rpgInit(void) { errorret_t rpgInit(void) {
memoryZero(ENTITIES, sizeof(ENTITIES)); memoryZero(ENTITIES, sizeof(ENTITIES));
// Init cutscene subsystem backpackInit();
cutsceneSystemInit(); cutsceneSystemInit();
errorChain(mapInit()); errorChain(mapInit());