Cutscene combined

This commit is contained in:
2026-06-26 10:24:39 -05:00
parent 1e890f6d86
commit bbf5b706f0
13 changed files with 95 additions and 198 deletions
-1
View File
@@ -56,7 +56,6 @@ add_subdirectory(animation)
add_subdirectory(event) add_subdirectory(event)
add_subdirectory(assert) add_subdirectory(assert)
add_subdirectory(asset) add_subdirectory(asset)
add_subdirectory(cutscene)
add_subdirectory(console) add_subdirectory(console)
add_subdirectory(display) add_subdirectory(display)
add_subdirectory(log) add_subdirectory(log)
-9
View File
@@ -1,9 +0,0 @@
# 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
cutscene.c
)
-96
View File
@@ -1,96 +0,0 @@
// Copyright (c) 2026 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "cutscene.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "console/console.h"
#include "time/time.h"
cutscene_t CUTSCENE;
errorret_t cutsceneInit(void) {
memoryZero(&CUTSCENE, sizeof(cutscene_t));
errorOk();
}
errorret_t cutsceneUpdate(void) {
#ifdef DUSK_TIME_DYNAMIC
if(TIME.dynamicUpdate) {
errorOk();
}
#endif
if(!CUTSCENE.active) errorOk();
cutsceneevent_t *event = &CUTSCENE.events[CUTSCENE.eventCurrent];
if(event->onUpdate) errorChain(event->onUpdate());
errorOk();
}
errorret_t cutscenePlay(
const cutsceneevent_t *events,
const uint8_t eventCount
) {
assertNotNull(events, "Events cannot be null");
assertTrue(eventCount > 0, "Event count must be greater than zero");
assertTrue(
eventCount <= CUTSCENE_EVENT_COUNT_MAX,
"Event count exceeds CUTSCENE_EVENT_COUNT_MAX"
);
if(CUTSCENE.active) {
errorChain(cutsceneStop());
}
memoryCopy(CUTSCENE.events, events, sizeof(cutsceneevent_t) * eventCount);
CUTSCENE.eventCount = eventCount;
CUTSCENE.eventCurrent = 0;
CUTSCENE.active = true;
cutsceneevent_t *firstEvent = &CUTSCENE.events[0];
if(firstEvent->onStart) errorChain(firstEvent->onStart());
errorOk();
}
errorret_t cutsceneAdvance(void) {
if(!CUTSCENE.active) errorOk();
cutsceneevent_t *currentEvent = &CUTSCENE.events[CUTSCENE.eventCurrent];
if(currentEvent->onEnd) errorChain(currentEvent->onEnd());
CUTSCENE.eventCurrent++;
if(CUTSCENE.eventCurrent >= CUTSCENE.eventCount) {
if(CUTSCENE.onStop) errorChain(CUTSCENE.onStop());
CUTSCENE.active = false;
errorOk();
}
cutsceneevent_t *nextEvent = &CUTSCENE.events[CUTSCENE.eventCurrent];
if(nextEvent->onStart) errorChain(nextEvent->onStart());
consolePrint("Cutscene advance");
errorOk();
}
errorret_t cutsceneStop(void) {
if(!CUTSCENE.active) errorOk();
cutsceneevent_t *currentEvent = &CUTSCENE.events[CUTSCENE.eventCurrent];
if(currentEvent->onEnd) errorChain(currentEvent->onEnd());
if(CUTSCENE.onStop) errorChain(CUTSCENE.onStop());
CUTSCENE.active = false;
errorOk();
}
errorret_t cutsceneDispose(void) {
errorChain(cutsceneStop());
errorOk();
}
bool_t cutsceneIsActive(void) {
return CUTSCENE.active;
}
-85
View File
@@ -1,85 +0,0 @@
// Copyright (c) 2026 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "error/error.h"
#define CUTSCENE_EVENT_COUNT_MAX 16
typedef struct {
errorret_t (*onStart)(void);
errorret_t (*onEnd)(void);
errorret_t (*onUpdate)(void);
} cutsceneevent_t;
typedef struct {
cutsceneevent_t events[CUTSCENE_EVENT_COUNT_MAX];
uint8_t eventCount;
uint8_t eventCurrent;
errorret_t (*onStop)(void);
bool_t active;
} cutscene_t;
extern cutscene_t CUTSCENE;
/**
* Initializes the cutscene manager.
*
* @return Any error state that happened.
*/
errorret_t cutsceneInit(void);
/**
* Ticks the active cutscene event, calling its onUpdate callback.
* Does nothing when no cutscene is playing.
*
* @return Any error state that happened.
*/
errorret_t cutsceneUpdate(void);
/**
* Copies the given event array and begins playing from the first
* event. If a cutscene is already playing it is stopped first.
*
* @param events Array of events to copy.
* @param eventCount Number of events. Must be > 0 and
* <= CUTSCENE_EVENT_COUNT_MAX.
* @return Any error state that happened.
*/
errorret_t cutscenePlay(
const cutsceneevent_t *events,
const uint8_t eventCount
);
/**
* Ends the current event and starts the next one.
* Marks the cutscene as inactive after the last event ends.
* Does nothing when no cutscene is playing.
*
* @return Any error state that happened.
*/
errorret_t cutsceneAdvance(void);
/**
* Ends the current event and stops the cutscene immediately.
* Does nothing when no cutscene is playing.
*
* @return Any error state that happened.
*/
errorret_t cutsceneStop(void);
/**
* Disposes of the cutscene manager, stopping any active cutscene.
*
* @return Any error state that happened.
*/
errorret_t cutsceneDispose(void);
/**
* Returns whether a cutscene is currently playing.
*
* @return true if a cutscene is active.
*/
bool_t cutsceneIsActive(void);
-4
View File
@@ -13,7 +13,6 @@
#include "rpg/rpg.h" #include "rpg/rpg.h"
#include "display/display.h" #include "display/display.h"
#include "scene/scene.h" #include "scene/scene.h"
#include "cutscene/cutscene.h"
#include "asset/asset.h" #include "asset/asset.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "assert/assert.h" #include "assert/assert.h"
@@ -42,7 +41,6 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
errorChain(localeManagerInit()); errorChain(localeManagerInit());
errorChain(displayInit()); errorChain(displayInit());
errorChain(uiInit()); errorChain(uiInit());
errorChain(cutsceneInit());
errorChain(rpgInit()); errorChain(rpgInit());
errorChain(networkInit()); errorChain(networkInit());
errorChain(sceneInit()); errorChain(sceneInit());
@@ -61,7 +59,6 @@ errorret_t engineUpdate(void) {
inputUpdate(); inputUpdate();
consoleUpdate(); consoleUpdate();
errorChain(rpgUpdate()); errorChain(rpgUpdate());
errorChain(cutsceneUpdate());
errorChain(sceneUpdate()); errorChain(sceneUpdate());
errorChain(assetUpdate()); errorChain(assetUpdate());
errorChain(uiUpdate()); errorChain(uiUpdate());
@@ -77,7 +74,6 @@ void engineExit(void) {
} }
errorret_t engineDispose(void) { errorret_t engineDispose(void) {
cutsceneDispose();
errorChain(sceneDispose()); errorChain(sceneDispose());
errorChain(networkDispose()); errorChain(networkDispose());
errorChain(rpgDispose()); errorChain(rpgDispose());
+6
View File
@@ -53,4 +53,10 @@ const cutsceneitem_t * cutsceneSystemGetCurrentItem() {
if(CUTSCENE_SYSTEM.scene == NULL) return NULL; if(CUTSCENE_SYSTEM.scene == NULL) return NULL;
return &CUTSCENE_SYSTEM.scene->items[CUTSCENE_SYSTEM.currentItem]; return &CUTSCENE_SYSTEM.scene->items[CUTSCENE_SYSTEM.currentItem];
}
void cutsceneSystemDispose() {
CUTSCENE_SYSTEM.scene = NULL;
CUTSCENE_SYSTEM.currentItem = 0xFF;
CUTSCENE_SYSTEM.mode = CUTSCENE_MODE_NONE;
} }
+7 -2
View File
@@ -44,7 +44,12 @@ void cutsceneSystemUpdate();
/** /**
* Get the current cutscene item. * Get the current cutscene item.
* *
* @return Pointer to the current cutscene item. * @return Pointer to the current cutscene item.
*/ */
const cutsceneitem_t * cutsceneSystemGetCurrentItem(); const cutsceneitem_t * cutsceneSystemGetCurrentItem();
/**
* Disposes of the cutscene system, stopping any active cutscene.
*/
void cutsceneSystemDispose();
@@ -7,4 +7,5 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
cutsceneitem.c cutsceneitem.c
cutsceneentitymove.c
) )
@@ -0,0 +1,39 @@
/**
* 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);
}
}
@@ -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 "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);
@@ -6,6 +6,7 @@
*/ */
#include "rpg/cutscene/cutscenesystem.h" #include "rpg/cutscene/cutscenesystem.h"
#include "cutsceneentitymove.h"
#include "input/input.h" #include "input/input.h"
#include "time/time.h" #include "time/time.h"
@@ -31,6 +32,10 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
if(item->cutscene != NULL) cutsceneSystemStartCutscene(item->cutscene); if(item->cutscene != NULL) cutsceneSystemStartCutscene(item->cutscene);
break; break;
case CUTSCENE_ITEM_TYPE_ENTITY_MOVE:
cutsceneEntityMoveStart(item);
break;
default: default:
break; break;
} }
@@ -48,6 +53,10 @@ void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
if(data->wait <= 0) cutsceneSystemNext(); if(data->wait <= 0) cutsceneSystemNext();
break; break;
case CUTSCENE_ITEM_TYPE_ENTITY_MOVE:
cutsceneEntityMoveUpdate(item);
break;
default: default:
break; break;
} }
+8 -1
View File
@@ -9,6 +9,7 @@
#include "cutscenewait.h" #include "cutscenewait.h"
#include "cutscenecallback.h" #include "cutscenecallback.h"
#include "cutscenetext.h" #include "cutscenetext.h"
#include "rpg/overworld/worldpos.h"
typedef struct cutscene_s cutscene_t; typedef struct cutscene_s cutscene_t;
@@ -17,7 +18,8 @@ typedef enum {
CUTSCENE_ITEM_TYPE_TEXT, CUTSCENE_ITEM_TYPE_TEXT,
CUTSCENE_ITEM_TYPE_CALLBACK, CUTSCENE_ITEM_TYPE_CALLBACK,
CUTSCENE_ITEM_TYPE_WAIT, CUTSCENE_ITEM_TYPE_WAIT,
CUTSCENE_ITEM_TYPE_CUTSCENE CUTSCENE_ITEM_TYPE_CUTSCENE,
CUTSCENE_ITEM_TYPE_ENTITY_MOVE
} cutsceneitemtype_t; } cutsceneitemtype_t;
typedef struct cutsceneitem_s { typedef struct cutsceneitem_s {
@@ -29,6 +31,11 @@ typedef struct cutsceneitem_s {
cutscenecallback_t callback; cutscenecallback_t callback;
cutscenewait_t wait; cutscenewait_t wait;
const cutscene_t *cutscene; const cutscene_t *cutscene;
struct {
uint8_t entityIndex;
worldpos_t target;
bool_t run;
} entityMove;
}; };
} cutsceneitem_t; } cutsceneitem_t;
+1
View File
@@ -72,6 +72,7 @@ errorret_t rpgUpdate(void) {
} }
errorret_t rpgDispose(void) { errorret_t rpgDispose(void) {
cutsceneSystemDispose();
errorChain(mapDispose()); errorChain(mapDispose());
errorOk(); errorOk();