Restored cutscene code
This commit is contained in:
@@ -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
|
||||
cutscenesystem.c
|
||||
)
|
||||
|
||||
add_subdirectory(item)
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "cutscene/cutscenepause.h"
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
|
||||
typedef struct cutscene_s {
|
||||
const cutsceneitem_t *items;
|
||||
uint8_t itemCount;
|
||||
cutscenepause_t pause;
|
||||
|
||||
/** Bytes of CUTSCENE_SYSTEM.userData this cutscene's callbacks use. */
|
||||
size_t dataSize;
|
||||
} cutscene_t;
|
||||
|
||||
/**
|
||||
* Declares a static cutscene_t named NAME with the given items.
|
||||
*
|
||||
* @param NAME Identifier for the resulting cutscene_t.
|
||||
* @param SIZE Bytes of scratch user data this cutscene's callbacks use.
|
||||
* @param PAUSE_TYPE A cutscenepause_t value applied while running.
|
||||
* @param ... cutsceneitem_t initializers, see the CUTSCENE_* item macros.
|
||||
*/
|
||||
#define CUTSCENE(NAME, SIZE, PAUSE_TYPE, ...) \
|
||||
static const cutsceneitem_t NAME##_ITEMS[] = { __VA_ARGS__ }; \
|
||||
static const cutscene_t NAME = { \
|
||||
NAME##_ITEMS, \
|
||||
sizeof(NAME##_ITEMS) / sizeof(cutsceneitem_t), \
|
||||
(PAUSE_TYPE), \
|
||||
(SIZE) \
|
||||
}
|
||||
|
||||
#define CUTSCENE_TEXT(TEXT) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_TEXT, .text = { TEXT } }
|
||||
|
||||
#define CUTSCENE_CALLBACK(CALLBACK) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = (CALLBACK) }
|
||||
|
||||
#define CUTSCENE_WAIT(SECONDS) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = (SECONDS) }
|
||||
|
||||
#define CUTSCENE_CUTSCENE(CUTSCENE_PTR) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CUTSCENE, .cutscene = (CUTSCENE_PTR) }
|
||||
|
||||
#define CUTSCENE_SET_PAUSE(PAUSE) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_SET_PAUSE, .setPause = (PAUSE) }
|
||||
|
||||
/**
|
||||
* @param ITEMS Identifier of a previously-declared cutsceneitem_t array;
|
||||
* its element count is taken via sizeof(ITEMS), so it must be a real
|
||||
* array, not a pointer.
|
||||
*/
|
||||
#define CUTSCENE_CONCURRENT(ITEMS) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_CONCURRENT, \
|
||||
.concurrent = { (ITEMS), sizeof(ITEMS) / sizeof(cutsceneitem_t) } \
|
||||
}
|
||||
|
||||
#define CUTSCENE_ENTITY_TELEPORT(ENTITY_INDEX, X, Y, Z) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, \
|
||||
.entityTeleport = { (ENTITY_INDEX), { (X), (Y), (Z) } } \
|
||||
}
|
||||
|
||||
#define CUTSCENE_ENTITY_WALK_TO(ENTITY_INDEX, X, Y, Z, SPEED) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO, \
|
||||
.entityWalkTo = { \
|
||||
(ENTITY_INDEX), (const vec3[]){ { (X), (Y), (Z) } }, 1, (SPEED) \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @param POSITIONS Identifier of a previously-declared vec3 array of
|
||||
* waypoints; its element count is taken via sizeof(POSITIONS), so it
|
||||
* must be a real array, not a pointer.
|
||||
*/
|
||||
#define CUTSCENE_ENTITY_WALK_PATH(ENTITY_INDEX, POSITIONS, SPEED) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO, \
|
||||
.entityWalkTo = { \
|
||||
(ENTITY_INDEX), (POSITIONS), sizeof(POSITIONS) / sizeof(vec3), (SPEED) \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CUTSCENE_ENTITY_WALK_TO_ENTITY( \
|
||||
ENTITY_INDEX, TARGET_ENTITY_INDEX, OFFSET_X, OFFSET_Z, SPEED \
|
||||
) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY, \
|
||||
.entityWalkToEntity = { \
|
||||
(ENTITY_INDEX), (TARGET_ENTITY_INDEX), (OFFSET_X), (OFFSET_Z), (SPEED) \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CUTSCENE_ENTITY_TURN(ENTITY_INDEX, YAW) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_TURN, \
|
||||
.entityTurn = { (ENTITY_INDEX), (YAW) } \
|
||||
}
|
||||
|
||||
#define CUTSCENE_ENTITY_ADD(PREFAB_NAME, X, Y, Z) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_ADD, \
|
||||
.entityAdd = { (PREFAB_NAME), { (X), (Y), (Z) } } \
|
||||
}
|
||||
|
||||
#define CUTSCENE_ENTITY_REMOVE(ENTITY_INDEX) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_REMOVE, \
|
||||
.entityRemove = { (ENTITY_INDEX) } \
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MESSAGE Shown in UI_TEXTBOX_MAIN; "" uses
|
||||
* ENTITY_INTERACTABLE_ITEM_PICKUP_MESSAGE_DEFAULT.
|
||||
*/
|
||||
#define CUTSCENE_ENTITY_ITEM_PICKUP(ENTITY_INDEX, MESSAGE) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_ITEM_PICKUP, \
|
||||
.entityItemPickup = { (ENTITY_INDEX), MESSAGE } \
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
typedef uint8_t cutscenepause_t;
|
||||
|
||||
#define CUTSCENE_PAUSE_NONE ((cutscenepause_t)0)
|
||||
#define CUTSCENE_PAUSE_NPC ((cutscenepause_t)(1 << 0))
|
||||
#define CUTSCENE_PAUSE_PLAYER ((cutscenepause_t)(1 << 1))
|
||||
#define CUTSCENE_PAUSE_WORLD ((cutscenepause_t)(1 << 2))
|
||||
|
||||
#define CUTSCENE_PAUSE_DEFAULT ((cutscenepause_t)( \
|
||||
CUTSCENE_PAUSE_NPC | CUTSCENE_PAUSE_PLAYER \
|
||||
))
|
||||
|
||||
#define CUTSCENE_PAUSE_ALL ((cutscenepause_t)( \
|
||||
CUTSCENE_PAUSE_NPC | CUTSCENE_PAUSE_PLAYER | CUTSCENE_PAUSE_WORLD \
|
||||
))
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "scene/scene.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
cutscenesystem_t CUTSCENE_SYSTEM;
|
||||
|
||||
errorret_t cutsceneSystemInit(void) {
|
||||
memoryZero(&CUTSCENE_SYSTEM, sizeof(cutscenesystem_t));
|
||||
CUTSCENE_SYSTEM.entityInteract = ENTITY_ID_INVALID;
|
||||
CUTSCENE_SYSTEM.entityInteracted = ENTITY_ID_INVALID;
|
||||
CUTSCENE_SYSTEM.entityLastCreated = ENTITY_ID_INVALID;
|
||||
CUTSCENE_SYSTEM.entityLastRef = ENTITY_ID_INVALID;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void cutsceneSystemStartCutscene(const cutscene_t *cutscene) {
|
||||
cutsceneSystemStartCutsceneWith(
|
||||
cutscene, ENTITY_ID_INVALID, ENTITY_ID_INVALID
|
||||
);
|
||||
}
|
||||
|
||||
void cutsceneSystemStartCutsceneWith(
|
||||
const cutscene_t *cutscene,
|
||||
const entityid_t interact,
|
||||
const entityid_t interacted
|
||||
) {
|
||||
assertNotNull(cutscene, "cutscene must not be NULL");
|
||||
assertTrue(
|
||||
cutscene->dataSize <= CUTSCENE_SYSTEM_SIZE_MAX,
|
||||
"Cutscene dataSize exceeds CUTSCENE_SYSTEM_SIZE_MAX"
|
||||
);
|
||||
|
||||
CUTSCENE_SYSTEM.mgr = sceneGetEntities(sceneGetActive());
|
||||
CUTSCENE_SYSTEM.scene = cutscene;
|
||||
CUTSCENE_SYSTEM.currentItem = 0;
|
||||
CUTSCENE_SYSTEM.pause = cutscene->pause;
|
||||
CUTSCENE_SYSTEM.entityInteract = interact;
|
||||
CUTSCENE_SYSTEM.entityInteracted = interacted;
|
||||
CUTSCENE_SYSTEM.entityLastCreated = ENTITY_ID_INVALID;
|
||||
CUTSCENE_SYSTEM.entityLastRef = ENTITY_ID_INVALID;
|
||||
memoryZero(&CUTSCENE_SYSTEM.data, sizeof(cutsceneitemdata_t));
|
||||
if(cutscene->dataSize > 0) {
|
||||
memoryZero(CUTSCENE_SYSTEM.userData, cutscene->dataSize);
|
||||
}
|
||||
|
||||
if(cutscene->itemCount > 0) {
|
||||
cutsceneItemStart(&cutscene->items[0], &CUTSCENE_SYSTEM.data);
|
||||
}
|
||||
}
|
||||
|
||||
entityid_t cutsceneSystemGetEntity(const uint8_t entityIndex) {
|
||||
switch(entityIndex) {
|
||||
case CUTSCENE_ENTITY_INTERACT: return CUTSCENE_SYSTEM.entityInteract;
|
||||
case CUTSCENE_ENTITY_INTERACTED: return CUTSCENE_SYSTEM.entityInteracted;
|
||||
case CUTSCENE_ENTITY_LAST_CREATED:
|
||||
return CUTSCENE_SYSTEM.entityLastCreated;
|
||||
case CUTSCENE_ENTITY_LAST_REF: return CUTSCENE_SYSTEM.entityLastRef;
|
||||
default: return (entityid_t)entityIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void cutsceneSystemNext(void) {
|
||||
CUTSCENE_SYSTEM.currentItem++;
|
||||
memoryZero(&CUTSCENE_SYSTEM.data, sizeof(cutsceneitemdata_t));
|
||||
|
||||
if(CUTSCENE_SYSTEM.currentItem >= CUTSCENE_SYSTEM.scene->itemCount) {
|
||||
CUTSCENE_SYSTEM.scene = NULL;
|
||||
CUTSCENE_SYSTEM.pause = CUTSCENE_PAUSE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
cutsceneItemStart(cutsceneSystemGetCurrentItem(), &CUTSCENE_SYSTEM.data);
|
||||
}
|
||||
|
||||
errorret_t cutsceneSystemUpdate(void) {
|
||||
if(CUTSCENE_SYSTEM.scene == NULL) errorOk();
|
||||
|
||||
if(cutsceneItemUpdate(
|
||||
cutsceneSystemGetCurrentItem(), &CUTSCENE_SYSTEM.data
|
||||
)) {
|
||||
cutsceneSystemNext();
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
const cutsceneitem_t *cutsceneSystemGetCurrentItem(void) {
|
||||
if(CUTSCENE_SYSTEM.scene == NULL) return NULL;
|
||||
return &CUTSCENE_SYSTEM.scene->items[CUTSCENE_SYSTEM.currentItem];
|
||||
}
|
||||
|
||||
errorret_t cutsceneSystemDispose(void) {
|
||||
errorOk();
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "entity/entitybase.h"
|
||||
#include "cutscene/cutscene.h"
|
||||
#include "error/error.h"
|
||||
|
||||
/** Resolves to CUTSCENE_SYSTEM.entityInteract; see
|
||||
* cutsceneSystemGetEntity(). */
|
||||
#define CUTSCENE_ENTITY_INTERACT ((entityid_t)0xFE)
|
||||
/** Resolves to CUTSCENE_SYSTEM.entityInteracted; see
|
||||
* cutsceneSystemGetEntity(). */
|
||||
#define CUTSCENE_ENTITY_INTERACTED ((entityid_t)0xFD)
|
||||
/** Resolves to CUTSCENE_SYSTEM.entityLastCreated; see
|
||||
* cutsceneSystemGetEntity(). */
|
||||
#define CUTSCENE_ENTITY_LAST_CREATED ((entityid_t)0xFC)
|
||||
/** Resolves to CUTSCENE_SYSTEM.entityLastRef; see
|
||||
* cutsceneSystemGetEntity(). */
|
||||
#define CUTSCENE_ENTITY_LAST_REF ((entityid_t)0xFB)
|
||||
|
||||
/** Size in bytes of CUTSCENE_SYSTEM.userData. */
|
||||
#define CUTSCENE_SYSTEM_SIZE_MAX 8192
|
||||
|
||||
typedef struct {
|
||||
/** The entity manager the running cutscene's entity items operate on;
|
||||
* resolved from the active scene when a cutscene starts. */
|
||||
entitymanager_t *mgr;
|
||||
|
||||
/** The currently running cutscene, or NULL if none is running. */
|
||||
const cutscene_t *scene;
|
||||
|
||||
/** Index of the currently running item within scene->items. */
|
||||
uint8_t currentItem;
|
||||
|
||||
/** Pause flags applied by the running cutscene; see cutscenepause_t. */
|
||||
cutscenepause_t pause;
|
||||
|
||||
/** Entity that initiated the current cutscene, if started via
|
||||
* cutsceneSystemStartCutsceneWith(); see CUTSCENE_ENTITY_INTERACT. */
|
||||
entityid_t entityInteract;
|
||||
|
||||
/** Entity that was interacted with to start the current cutscene, if
|
||||
* started via cutsceneSystemStartCutsceneWith(); see
|
||||
* CUTSCENE_ENTITY_INTERACTED. */
|
||||
entityid_t entityInteracted;
|
||||
|
||||
/** Entity most recently spawned by a CUTSCENE_ENTITY_ADD item; see
|
||||
* CUTSCENE_ENTITY_LAST_CREATED. */
|
||||
entityid_t entityLastCreated;
|
||||
|
||||
/** Entity most recently referenced by CUTSCENE_ENTITY_LAST_CREATED/
|
||||
* CUTSCENE_ENTITY_LAST_REF; see CUTSCENE_ENTITY_LAST_REF. */
|
||||
entityid_t entityLastRef;
|
||||
|
||||
/** Runtime data for the currently running item. */
|
||||
cutsceneitemdata_t data;
|
||||
|
||||
/** Scratch storage for a running cutscene's own state (see
|
||||
* cutscene_t.dataSize) and for CUTSCENE_CALLBACK's user pointer. */
|
||||
uint8_t userData[CUTSCENE_SYSTEM_SIZE_MAX];
|
||||
} cutscenesystem_t;
|
||||
|
||||
extern cutscenesystem_t CUTSCENE_SYSTEM;
|
||||
|
||||
/**
|
||||
* Initializes CUTSCENE_SYSTEM. No cutscene is running until
|
||||
* cutsceneSystemStartCutscene()/cutsceneSystemStartCutsceneWith() is
|
||||
* called.
|
||||
*
|
||||
* @return Error state.
|
||||
*/
|
||||
errorret_t cutsceneSystemInit(void);
|
||||
|
||||
/**
|
||||
* Starts a cutscene. Equivalent to cutsceneSystemStartCutsceneWith() with
|
||||
* both entity IDs set to ENTITY_ID_INVALID.
|
||||
*
|
||||
* @param cutscene The cutscene to start.
|
||||
*/
|
||||
void cutsceneSystemStartCutscene(const cutscene_t *cutscene);
|
||||
|
||||
/**
|
||||
* Starts a cutscene, recording which entities (if any) initiated it via
|
||||
* an interaction, so its items can reference them through
|
||||
* CUTSCENE_ENTITY_INTERACT/CUTSCENE_ENTITY_INTERACTED. Resolves
|
||||
* CUTSCENE_SYSTEM.mgr from the active scene (see sceneGetActive()).
|
||||
*
|
||||
* If a cutscene is already running, this replaces it outright -- there
|
||||
* is no call/return stack, so starting a cutscene from within another
|
||||
* (see CUTSCENE_CUTSCENE()) is a one-way jump; the outer cutscene's
|
||||
* remaining items are abandoned, not resumed afterwards.
|
||||
*
|
||||
* @param cutscene The cutscene to start.
|
||||
* @param interact The entity that initiated the interaction, or
|
||||
* ENTITY_ID_INVALID.
|
||||
* @param interacted The entity that was interacted with, or
|
||||
* ENTITY_ID_INVALID.
|
||||
*/
|
||||
void cutsceneSystemStartCutsceneWith(
|
||||
const cutscene_t *cutscene,
|
||||
const entityid_t interact,
|
||||
const entityid_t interacted
|
||||
);
|
||||
|
||||
/**
|
||||
* Resolves an item's entityIndex field into a real entity ID: the
|
||||
* CUTSCENE_ENTITY_* sentinels resolve to their corresponding
|
||||
* CUTSCENE_SYSTEM field, any other value passes through unchanged as a
|
||||
* literal entity ID within CUTSCENE_SYSTEM.mgr.
|
||||
*
|
||||
* @param entityIndex The entityIndex field from a cutscene item.
|
||||
* @return The resolved entity ID.
|
||||
*/
|
||||
entityid_t cutsceneSystemGetEntity(const uint8_t entityIndex);
|
||||
|
||||
/**
|
||||
* Advances to the next item in the running cutscene (starting it), or
|
||||
* ends the cutscene if none remain. Called by cutsceneSystemUpdate() once
|
||||
* the current item completes.
|
||||
*/
|
||||
void cutsceneSystemNext(void);
|
||||
|
||||
/**
|
||||
* Updates the running cutscene: ticks the current item, advancing to the
|
||||
* next one (see cutsceneSystemNext()) once it completes. No-op if no
|
||||
* cutscene is running.
|
||||
*
|
||||
* @return Error state.
|
||||
*/
|
||||
errorret_t cutsceneSystemUpdate(void);
|
||||
|
||||
/**
|
||||
* Gets the currently running item.
|
||||
*
|
||||
* @return The current item, or NULL if no cutscene is running.
|
||||
*/
|
||||
const cutsceneitem_t *cutsceneSystemGetCurrentItem(void);
|
||||
|
||||
/**
|
||||
* Disposes CUTSCENE_SYSTEM.
|
||||
*
|
||||
* @return Error state.
|
||||
*/
|
||||
errorret_t cutsceneSystemDispose(void);
|
||||
@@ -0,0 +1,14 @@
|
||||
# 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
|
||||
cutscenecallback.c
|
||||
cutsceneitem.c
|
||||
)
|
||||
|
||||
add_subdirectory(control)
|
||||
add_subdirectory(entity)
|
||||
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
|
||||
cutsceneconcurrent.c
|
||||
cutscenesetpause.c
|
||||
cutscenewait.c
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/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;
|
||||
}
|
||||
@@ -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 "cutscene/item/entity/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
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "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;
|
||||
}
|
||||
@@ -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 "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
|
||||
);
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/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;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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 float_t cutscenewait_t;
|
||||
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
|
||||
);
|
||||
@@ -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 "cutscene/cutscenesystem.h"
|
||||
|
||||
void cutsceneCallbackStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
if(item->callback != NULL) item->callback(CUTSCENE_SYSTEM.userData);
|
||||
}
|
||||
|
||||
bool_t cutsceneCallbackUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** @param user The cutscene's own userData scratch buffer; see cutscene_t. */
|
||||
typedef void (*cutscenecallback_t)(void *user);
|
||||
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
const cutsceneitemcallbacks_t
|
||||
CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT] = {
|
||||
[CUTSCENE_ITEM_TYPE_NULL] = { NULL, NULL },
|
||||
[CUTSCENE_ITEM_TYPE_TEXT] = {
|
||||
cutsceneTextStart, cutsceneTextUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_CALLBACK] = {
|
||||
cutsceneCallbackStart, cutsceneCallbackUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_WAIT] = {
|
||||
cutsceneWaitStart, cutsceneWaitUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_CUTSCENE] = {
|
||||
cutsceneCutsceneStart, cutsceneCutsceneUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_SET_PAUSE] = {
|
||||
cutsceneSetPauseStart, cutsceneSetPauseUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_CONCURRENT] = {
|
||||
cutsceneConcurrentStart, cutsceneConcurrentUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT] = {
|
||||
cutsceneEntityTeleportStart, cutsceneEntityTeleportUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO] = {
|
||||
cutsceneEntityWalkToStart, cutsceneEntityWalkToUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY] = {
|
||||
cutsceneEntityWalkToEntityStart, cutsceneEntityWalkToEntityUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_TURN] = {
|
||||
cutsceneEntityTurnStart, cutsceneEntityTurnUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_ADD] = {
|
||||
cutsceneEntityAddStart, cutsceneEntityAddUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_REMOVE] = {
|
||||
cutsceneEntityRemoveStart, cutsceneEntityRemoveUpdate
|
||||
},
|
||||
[CUTSCENE_ITEM_TYPE_ENTITY_ITEM_PICKUP] = {
|
||||
cutsceneEntityItemPickupStart, cutsceneEntityItemPickupUpdate
|
||||
}
|
||||
};
|
||||
|
||||
void cutsceneItemStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
assertTrue(item->type < CUTSCENE_ITEM_TYPE_COUNT, "Invalid cutscene item");
|
||||
cutsceneitemstartcallback_t start = CUTSCENE_ITEM_CALLBACKS[item->type].start;
|
||||
if(start != NULL) start(item, data);
|
||||
}
|
||||
|
||||
bool_t cutsceneItemUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
assertTrue(item->type < CUTSCENE_ITEM_TYPE_COUNT, "Invalid cutscene item");
|
||||
cutsceneitemupdatecallback_t update =
|
||||
CUTSCENE_ITEM_CALLBACKS[item->type].update;
|
||||
if(update == NULL) return true;
|
||||
return update(item, data);
|
||||
}
|
||||
|
||||
void cutsceneCutsceneStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
cutsceneSystemStartCutscene(item->cutscene);
|
||||
}
|
||||
|
||||
bool_t cutsceneCutsceneUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
#include "cutscene/item/cutscenecallback.h"
|
||||
#include "cutscene/item/control/cutscenewait.h"
|
||||
#include "cutscene/item/control/cutscenesetpause.h"
|
||||
#include "cutscene/item/control/cutsceneconcurrent.h"
|
||||
#include "cutscene/item/entity/cutsceneentityteleport.h"
|
||||
#include "cutscene/item/entity/cutsceneentitywalkto.h"
|
||||
#include "cutscene/item/entity/cutsceneentitywalktoentity.h"
|
||||
#include "cutscene/item/entity/cutsceneentityturn.h"
|
||||
#include "cutscene/item/entity/cutsceneentityadd.h"
|
||||
#include "cutscene/item/entity/cutsceneentityremove.h"
|
||||
#include "cutscene/item/entity/cutsceneentityitempickup.h"
|
||||
#include "cutscene/item/ui/cutscenetext.h"
|
||||
|
||||
typedef struct cutscene_s cutscene_t;
|
||||
|
||||
typedef enum {
|
||||
CUTSCENE_ITEM_TYPE_NULL,
|
||||
CUTSCENE_ITEM_TYPE_TEXT,
|
||||
CUTSCENE_ITEM_TYPE_CALLBACK,
|
||||
CUTSCENE_ITEM_TYPE_WAIT,
|
||||
CUTSCENE_ITEM_TYPE_CUTSCENE,
|
||||
CUTSCENE_ITEM_TYPE_SET_PAUSE,
|
||||
CUTSCENE_ITEM_TYPE_CONCURRENT,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_TURN,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_ADD,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_REMOVE,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_ITEM_PICKUP,
|
||||
CUTSCENE_ITEM_TYPE_COUNT
|
||||
} cutsceneitemtype_t;
|
||||
|
||||
typedef struct cutsceneitem_s {
|
||||
cutsceneitemtype_t type;
|
||||
union {
|
||||
cutscenetext_t text;
|
||||
cutscenecallback_t callback;
|
||||
cutscenewait_t wait;
|
||||
const cutscene_t *cutscene;
|
||||
cutscenepause_t setPause;
|
||||
cutsceneconcurrent_t concurrent;
|
||||
cutsceneentityteleport_t entityTeleport;
|
||||
cutsceneentitywalkto_t entityWalkTo;
|
||||
cutsceneentitywalktoentity_t entityWalkToEntity;
|
||||
cutsceneentityturn_t entityTurn;
|
||||
cutsceneentityadd_t entityAdd;
|
||||
cutsceneentityremove_t entityRemove;
|
||||
cutsceneentityitempickup_t entityItemPickup;
|
||||
};
|
||||
} cutsceneitem_t;
|
||||
|
||||
typedef union cutsceneitemdata_u {
|
||||
cutscenewaitdata_t wait;
|
||||
cutsceneentitywalktodata_t entityWalkTo;
|
||||
cutsceneconcurrentdata_t concurrent;
|
||||
} cutsceneitemdata_t;
|
||||
|
||||
typedef void (*cutsceneitemstartcallback_t)(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
typedef bool_t (*cutsceneitemupdatecallback_t)(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
cutsceneitemstartcallback_t start;
|
||||
cutsceneitemupdatecallback_t update;
|
||||
} cutsceneitemcallbacks_t;
|
||||
|
||||
extern const cutsceneitemcallbacks_t
|
||||
CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT];
|
||||
|
||||
/**
|
||||
* Starts a cutscene item by dispatching to its type's start callback.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage for the item.
|
||||
*/
|
||||
void cutsceneItemStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates a cutscene item by dispatching to its type's update callback.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage for the item.
|
||||
* @returns true once the item has completed.
|
||||
*/
|
||||
bool_t cutsceneItemUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Starts a nested-cutscene item -- hands control of CUTSCENE_SYSTEM over to
|
||||
* item->cutscene immediately (see cutsceneSystemStartCutscene()). This is a
|
||||
* one-way jump, not a call/return: the outer cutscene's remaining items are
|
||||
* abandoned, matching CUTSCENE_SYSTEM's single active-scene design.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage (unused).
|
||||
*/
|
||||
void cutsceneCutsceneStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates a nested-cutscene item (always completes immediately -- control
|
||||
* has already moved to the nested scene by the time this would run).
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage (unused).
|
||||
* @returns true always.
|
||||
*/
|
||||
bool_t cutsceneCutsceneUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
# 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
|
||||
cutsceneentityadd.c
|
||||
cutsceneentityitempickup.c
|
||||
cutsceneentityremove.c
|
||||
cutsceneentityteleport.c
|
||||
cutsceneentityturn.c
|
||||
cutsceneentitywalkto.c
|
||||
cutsceneentitywalktoentity.c
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/entityprefab.h"
|
||||
#include "entity/component/display/entityposition.h"
|
||||
|
||||
void cutsceneEntityAddStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
entityid_t entityId = entityManagerAdd(CUTSCENE_SYSTEM.mgr);
|
||||
|
||||
errorret_t ret = entityPrefabResolveAndApply(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, item->entityAdd.prefabName
|
||||
);
|
||||
if(errorIsNotOk(ret)) errorCatch(ret);
|
||||
|
||||
componentid_t posComp = entityGetComponent(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, COMPONENT_TYPE_POSITION
|
||||
);
|
||||
if(posComp != COMPONENT_ID_INVALID) {
|
||||
vec3 position = {
|
||||
item->entityAdd.position[0],
|
||||
item->entityAdd.position[1],
|
||||
item->entityAdd.position[2]
|
||||
};
|
||||
entityPositionSetLocalPosition(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, posComp, position
|
||||
);
|
||||
}
|
||||
|
||||
CUTSCENE_SYSTEM.entityLastCreated = entityId;
|
||||
CUTSCENE_SYSTEM.entityLastRef = entityId;
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityAddUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -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 "dusk.h"
|
||||
|
||||
typedef struct cutsceneitem_s cutsceneitem_t;
|
||||
typedef union cutsceneitemdata_u cutsceneitemdata_t;
|
||||
|
||||
typedef struct {
|
||||
/** Name of the entity prefab to apply; see entityPrefabResolveAndApply(). */
|
||||
const char_t *prefabName;
|
||||
vec3 position;
|
||||
} cutsceneentityadd_t;
|
||||
|
||||
/**
|
||||
* Starts an entity add item: spawns a new entity, applies prefabName to
|
||||
* it (see entityPrefabResolveAndApply()), and positions it if it ends up
|
||||
* with a POSITION component. Sets CUTSCENE_SYSTEM.entityLastCreated (and
|
||||
* entityLastRef) to the new entity. If prefabName fails to resolve, the
|
||||
* error is logged (see errorCatch()) and the entity is left as-is --
|
||||
* still created, just without whatever the prefab would have added.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
*/
|
||||
void cutsceneEntityAddStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates an entity add item (always completes immediately).
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
* @returns true always.
|
||||
*/
|
||||
bool_t cutsceneEntityAddUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/component/overworld/entityinteractable.h"
|
||||
#include "ui/textbox/uitextboxmain.h"
|
||||
|
||||
void cutsceneEntityItemPickupStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
entityid_t entityId = cutsceneSystemGetEntity(
|
||||
item->entityItemPickup.entityIndex
|
||||
);
|
||||
const char_t *message = item->entityItemPickup.message[0] != '\0'
|
||||
? item->entityItemPickup.message
|
||||
: ENTITY_INTERACTABLE_ITEM_PICKUP_MESSAGE_DEFAULT;
|
||||
uiTextboxMainSetText(message);
|
||||
entityDisposeDeep(CUTSCENE_SYSTEM.mgr, entityId);
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityItemPickupUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return !uiTextboxMainIsActive();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
#define CUTSCENE_ENTITY_ITEM_PICKUP_MESSAGE_MAX 128
|
||||
|
||||
typedef struct {
|
||||
uint8_t entityIndex;
|
||||
|
||||
/** Shown in UI_TEXTBOX_MAIN; empty means use
|
||||
* ENTITY_INTERACTABLE_ITEM_PICKUP_MESSAGE_DEFAULT. */
|
||||
char_t message[CUTSCENE_ENTITY_ITEM_PICKUP_MESSAGE_MAX];
|
||||
} cutsceneentityitempickup_t;
|
||||
|
||||
/**
|
||||
* Starts an entity item-pickup item: shows message (or the default
|
||||
* pickup message if empty) in UI_TEXTBOX_MAIN and removes the entity
|
||||
* immediately (see entityDisposeDeep()), mirroring
|
||||
* ENTITY_INTERACTABLE_TYPE_ITEM_PICKUP's own interaction behavior for
|
||||
* use within an authored cutscene.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
*/
|
||||
void cutsceneEntityItemPickupStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates an entity item-pickup item -- waits until UI_TEXTBOX_MAIN is
|
||||
* dismissed.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
* @returns true once the textbox is no longer active.
|
||||
*/
|
||||
bool_t cutsceneEntityItemPickupUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "entity/entitymanager.h"
|
||||
|
||||
void cutsceneEntityRemoveStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
entityid_t entityId = cutsceneSystemGetEntity(
|
||||
item->entityRemove.entityIndex
|
||||
);
|
||||
entityDisposeDeep(CUTSCENE_SYSTEM.mgr, entityId);
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityRemoveUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -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 "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 item (removes the entity from the world
|
||||
* immediately, via entityDisposeDeep()).
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
*/
|
||||
void cutsceneEntityRemoveStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates an entity remove item (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
|
||||
);
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/component/display/entityposition.h"
|
||||
|
||||
void cutsceneEntityTeleportStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
entityid_t entityId = cutsceneSystemGetEntity(
|
||||
item->entityTeleport.entityIndex
|
||||
);
|
||||
componentid_t posComp = entityGetComponent(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, COMPONENT_TYPE_POSITION
|
||||
);
|
||||
if(posComp == COMPONENT_ID_INVALID) return;
|
||||
|
||||
vec3 target = {
|
||||
item->entityTeleport.target[0],
|
||||
item->entityTeleport.target[1],
|
||||
item->entityTeleport.target[2]
|
||||
};
|
||||
entityPositionSetLocalPosition(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, posComp, target
|
||||
);
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityTeleportUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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;
|
||||
vec3 target;
|
||||
} cutsceneentityteleport_t;
|
||||
|
||||
/**
|
||||
* Starts an entity teleport item (teleports the entity immediately, via
|
||||
* entityPositionSetLocalPosition()). No-op if the entity has no POSITION
|
||||
* component.
|
||||
*
|
||||
* @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
|
||||
);
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/component/display/entityposition.h"
|
||||
|
||||
void cutsceneEntityTurnStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
entityid_t entityId = cutsceneSystemGetEntity(item->entityTurn.entityIndex);
|
||||
componentid_t posComp = entityGetComponent(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, COMPONENT_TYPE_POSITION
|
||||
);
|
||||
if(posComp == COMPONENT_ID_INVALID) return;
|
||||
|
||||
vec3 rotation;
|
||||
entityPositionGetLocalRotation(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, posComp, rotation
|
||||
);
|
||||
rotation[1] = item->entityTurn.yaw;
|
||||
entityPositionSetLocalRotation(
|
||||
CUTSCENE_SYSTEM.mgr, entityId, posComp, rotation
|
||||
);
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityTurnUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** Target yaw, in radians. See entityPositionSetLocalRotation(). */
|
||||
float_t yaw;
|
||||
} cutsceneentityturn_t;
|
||||
|
||||
/**
|
||||
* Starts an entity turn item: sets the entity's local yaw immediately.
|
||||
* No-op if the entity has no POSITION component. Unlike the original
|
||||
* tile-based version, there's no per-entity action/animation state to
|
||||
* wait on here, so this snaps instantly rather than deferring to Update.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
*/
|
||||
void cutsceneEntityTurnStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates an entity turn item (always completes immediately).
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
* @returns true always.
|
||||
*/
|
||||
bool_t cutsceneEntityTurnUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/component/display/entityposition.h"
|
||||
#include "time/time.h"
|
||||
#include "util/math.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;
|
||||
entityid_t entityId = cutsceneSystemGetEntity(
|
||||
item->entityWalkTo.entityIndex
|
||||
);
|
||||
float_t speed = item->entityWalkTo.speed > 0.0f
|
||||
? item->entityWalkTo.speed : CUTSCENE_ENTITY_WALK_SPEED_DEFAULT;
|
||||
|
||||
vec3 target = {
|
||||
item->entityWalkTo.positions[i][0],
|
||||
item->entityWalkTo.positions[i][1],
|
||||
item->entityWalkTo.positions[i][2]
|
||||
};
|
||||
if(!cutsceneEntityStepToward(CUTSCENE_SYSTEM.mgr, entityId, target, speed))
|
||||
return false;
|
||||
|
||||
i++;
|
||||
if(i < item->entityWalkTo.count) {
|
||||
data->entityWalkTo.currentIndex = i;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityStepToward(
|
||||
entitymanager_t *mgr,
|
||||
const entityid_t entityId,
|
||||
vec3 target,
|
||||
const float_t speed
|
||||
) {
|
||||
componentid_t posComp = entityGetComponent(
|
||||
mgr, entityId, COMPONENT_TYPE_POSITION
|
||||
);
|
||||
if(posComp == COMPONENT_ID_INVALID) return true;
|
||||
|
||||
vec3 pos;
|
||||
entityPositionGetLocalPosition(mgr, entityId, posComp, pos);
|
||||
|
||||
vec3 delta = {
|
||||
target[0] - pos[0], target[1] - pos[1], target[2] - pos[2]
|
||||
};
|
||||
float_t distSq = delta[0] * delta[0] + delta[1] * delta[1] +
|
||||
delta[2] * delta[2];
|
||||
if(distSq <= CUTSCENE_ENTITY_WALK_ARRIVE_THRESHOLD_SQ) {
|
||||
entityPositionSetLocalPosition(mgr, entityId, posComp, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
float_t dist = sqrtf(distSq);
|
||||
float_t step = speed * TIME.delta;
|
||||
float_t t = step >= dist ? 1.0f : step / dist;
|
||||
|
||||
vec3 newPos = {
|
||||
pos[0] + delta[0] * t,
|
||||
pos[1] + delta[1] * t,
|
||||
pos[2] + delta[2] * t
|
||||
};
|
||||
entityPositionSetLocalPosition(mgr, entityId, posComp, newPos);
|
||||
|
||||
// Face the direction of travel: entityPlayerUpdate's convention is
|
||||
// front = +local Z, so yaw = atan2(dx, dz) on the XZ ground plane.
|
||||
if(mathAbs(delta[0]) > 0.0001f || mathAbs(delta[2]) > 0.0001f) {
|
||||
vec3 rotation;
|
||||
entityPositionGetLocalRotation(mgr, entityId, posComp, rotation);
|
||||
rotation[1] = atan2f(delta[0], delta[2]);
|
||||
entityPositionSetLocalRotation(mgr, entityId, posComp, rotation);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "entity/entitybase.h"
|
||||
|
||||
typedef struct cutsceneitem_s cutsceneitem_t;
|
||||
typedef union cutsceneitemdata_u cutsceneitemdata_t;
|
||||
|
||||
/** Default speed for CUTSCENE_ENTITY_WALK_TO/_PATH, in units/second. */
|
||||
#define CUTSCENE_ENTITY_WALK_SPEED_DEFAULT 4.0f
|
||||
|
||||
/** Below this squared distance, an entity is considered to have arrived. */
|
||||
#define CUTSCENE_ENTITY_WALK_ARRIVE_THRESHOLD_SQ 0.0001f
|
||||
|
||||
typedef struct {
|
||||
uint8_t entityIndex;
|
||||
const vec3 *positions;
|
||||
uint8_t count;
|
||||
float_t speed;
|
||||
} 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
|
||||
);
|
||||
|
||||
/**
|
||||
* Steps an entity's local position directly toward target at speed
|
||||
* units/second (straight-line, no pathfinding/obstacle avoidance), and
|
||||
* faces it in the direction of travel. No-op (returns true immediately)
|
||||
* if the entity has no POSITION component.
|
||||
*
|
||||
* @param mgr The entity manager that owns the entity.
|
||||
* @param entityId The entity to move.
|
||||
* @param target The local-space destination.
|
||||
* @param speed Movement speed, in units/second.
|
||||
* @returns true once the entity is within
|
||||
* CUTSCENE_ENTITY_WALK_ARRIVE_THRESHOLD_SQ of target.
|
||||
*/
|
||||
bool_t cutsceneEntityStepToward(
|
||||
entitymanager_t *mgr,
|
||||
const entityid_t entityId,
|
||||
vec3 target,
|
||||
const float_t speed
|
||||
);
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "cutscene/cutscenesystem.h"
|
||||
#include "cutscene/item/entity/cutsceneentitywalkto.h"
|
||||
#include "entity/entitymanager.h"
|
||||
#include "entity/component/display/entityposition.h"
|
||||
|
||||
void cutsceneEntityWalkToEntityStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
}
|
||||
|
||||
bool_t cutsceneEntityWalkToEntityUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
) {
|
||||
entityid_t entityId = cutsceneSystemGetEntity(
|
||||
item->entityWalkToEntity.entityIndex
|
||||
);
|
||||
entityid_t targetId = cutsceneSystemGetEntity(
|
||||
item->entityWalkToEntity.targetEntityIndex
|
||||
);
|
||||
|
||||
componentid_t targetPosComp = entityGetComponent(
|
||||
CUTSCENE_SYSTEM.mgr, targetId, COMPONENT_TYPE_POSITION
|
||||
);
|
||||
if(targetPosComp == COMPONENT_ID_INVALID) return true;
|
||||
|
||||
vec3 targetPos;
|
||||
entityPositionGetWorldPosition(
|
||||
CUTSCENE_SYSTEM.mgr, targetId, targetPosComp, targetPos
|
||||
);
|
||||
|
||||
vec3 dest = {
|
||||
targetPos[0] + item->entityWalkToEntity.offsetX,
|
||||
targetPos[1],
|
||||
targetPos[2] + item->entityWalkToEntity.offsetZ
|
||||
};
|
||||
|
||||
float_t speed = item->entityWalkToEntity.speed > 0.0f
|
||||
? item->entityWalkToEntity.speed : CUTSCENE_ENTITY_WALK_SPEED_DEFAULT;
|
||||
|
||||
return cutsceneEntityStepToward(CUTSCENE_SYSTEM.mgr, entityId, dest, speed);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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;
|
||||
uint8_t targetEntityIndex;
|
||||
|
||||
/** Offset on the XZ ground plane from the target's current position. */
|
||||
float_t offsetX;
|
||||
float_t offsetZ;
|
||||
|
||||
float_t speed;
|
||||
} cutsceneentitywalktoentity_t;
|
||||
|
||||
/**
|
||||
* Starts an entity walk-to-entity item. No setup is needed -- the
|
||||
* destination is recomputed from the target's live position every
|
||||
* Update.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
*/
|
||||
void cutsceneEntityWalkToEntityStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates an entity walk-to-entity item: re-reads the target entity's
|
||||
* current world position each frame, applies the XZ offset, and steps
|
||||
* the entity toward it (see cutsceneEntityStepToward()). Unlike the
|
||||
* original tile-based version there's no terrain to resolve a Y from --
|
||||
* the destination Y is taken directly from the target's own position.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
* @returns true once the entity has reached the target's side.
|
||||
*/
|
||||
bool_t cutsceneEntityWalkToEntityUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
@@ -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
|
||||
cutscenetext.c
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutscene/item/cutsceneitem.h"
|
||||
#include "ui/textbox/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();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
#define CUTSCENE_TEXT_MAX_CHARS 256
|
||||
|
||||
typedef struct {
|
||||
char_t text[CUTSCENE_TEXT_MAX_CHARS];
|
||||
} cutscenetext_t;
|
||||
|
||||
/**
|
||||
* Starts a text item -- shows the given text in UI_TEXTBOX_MAIN.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
*/
|
||||
void cutsceneTextStart(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates a text item -- waits until UI_TEXTBOX_MAIN is dismissed.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
* @param data Runtime data storage.
|
||||
* @returns true once the textbox is no longer active.
|
||||
*/
|
||||
bool_t cutsceneTextUpdate(
|
||||
const cutsceneitem_t *item,
|
||||
cutsceneitemdata_t *data
|
||||
);
|
||||
Reference in New Issue
Block a user