diff --git a/.github/actions/setup-devkitpro/action.yml b/.github/actions/setup-devkitpro/action.yml new file mode 100644 index 00000000..b65ad15d --- /dev/null +++ b/.github/actions/setup-devkitpro/action.yml @@ -0,0 +1,49 @@ +name: Setup devkitPro +description: Install devkitPro with GameCube/Wii packages on an Ubuntu runner + +runs: + using: composite + steps: + - name: Install apt dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y \ + cmake \ + python3 \ + python3-pip \ + python3-polib \ + python3-pil \ + python3-dotenv \ + python3-pyqt5 \ + python3-opengl \ + xorriso + - name: Install devkitPro pacman + shell: bash + run: | + sudo ln -sf /proc/self/mounts /etc/mtab + wget https://apt.devkitpro.org/install-devkitpro-pacman \ + -O /tmp/install-devkitpro-pacman + echo "=== installer script contents ===" + cat /tmp/install-devkitpro-pacman + echo "=================================" + chmod +x /tmp/install-devkitpro-pacman + sudo /tmp/install-devkitpro-pacman + echo "DEVKITPRO=/opt/devkitpro" >> $GITHUB_ENV + echo "DEVKITPPC=/opt/devkitpro/devkitPPC" >> $GITHUB_ENV + echo "/opt/devkitpro/tools/bin" >> $GITHUB_PATH + echo "/opt/devkitpro/devkitPPC/bin" >> $GITHUB_PATH + - name: Install devkitPro GameCube/Wii packages + shell: bash + run: | + sudo dkp-pacman -S --needed --noconfirm \ + gamecube-dev \ + gamecube-sdl2 \ + ppc-liblzma \ + ppc-libzip \ + libogc2 \ + gamecube-tools \ + ppc-libmad \ + ppc-zlib-ng \ + ppc-bzip2 \ + ppc-zstd diff --git a/.github/actions/setup-pspdev/action.yml b/.github/actions/setup-pspdev/action.yml new file mode 100644 index 00000000..8db48e7e --- /dev/null +++ b/.github/actions/setup-pspdev/action.yml @@ -0,0 +1,20 @@ +name: Setup pspdev +description: Install the pspdev PSP toolchain on an Ubuntu runner + +runs: + using: composite + steps: + - name: Install dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y cmake python3 python3-pip python3-dotenv + - name: Install pspdev toolchain + shell: bash + run: | + wget -q \ + https://github.com/pspdev/pspdev/releases/latest/download/pspdev-ubuntu-latest-x86_64.tar.gz \ + -O /tmp/pspdev.tar.gz + sudo tar -xzf /tmp/pspdev.tar.gz -C /usr/local + echo "PSPDEV=/usr/local/pspdev" >> $GITHUB_ENV + echo "/usr/local/pspdev/bin" >> $GITHUB_PATH diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7009a25b..fc96b793 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,23 +8,63 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 - - name: Run tests in Docker - run: ./scripts/test-linux-docker.sh + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + cmake \ + python3 \ + python3-pip \ + python3-polib \ + python3-pil \ + libsdl2-dev \ + libgl1-mesa-dev \ + libzip-dev \ + python3-dotenv \ + python3-pyqt5 \ + python3-opengl \ + xz-utils \ + liblzma-dev \ + libbz2-dev \ + zlib1g-dev \ + git \ + libssl-dev + - name: Run tests + run: ./scripts/test-linux.sh build-linux: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + cmake \ + python3 \ + python3-pip \ + python3-polib \ + python3-pil \ + libsdl2-dev \ + libgl1-mesa-dev \ + libzip-dev \ + python3-dotenv \ + python3-pyqt5 \ + python3-opengl \ + xz-utils \ + liblzma-dev \ + libbz2-dev \ + zlib1g-dev \ + git \ + libssl-dev - name: Build Linux - run: ./scripts/build-linux-docker.sh + run: ./scripts/build-linux.sh - name: Upload Linux binary - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v3 with: name: dusk-linux path: build-linux/Dusk @@ -34,53 +74,72 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 - - name: Build psp - run: ./scripts/build-psp-docker.sh + uses: actions/checkout@v4 + - name: Setup pspdev + uses: ./.github/actions/setup-pspdev + - name: Build PSP + run: ./scripts/build-psp.sh - name: Move EBOOT.PBP to Dusk subfolder run: | mkdir -p ./git-artifcats/Dusk/PSP/GAME/Dusk cp build-psp/EBOOT.PBP ./git-artifcats/Dusk/PSP/GAME/Dusk/EBOOT.PBP - - name: Upload psp binary - uses: actions/upload-artifact@v6 + - name: Upload PSP binary + uses: actions/upload-artifact@v3 with: name: dusk-psp path: ./git-artifcats/Dusk if-no-files-found: error - # build-vita: - # runs-on: ubuntu-latest - # steps: - # - name: Checkout repository - # uses: actions/checkout@v6 - # - name: Set up Docker - # uses: docker/setup-docker-action@v5 - # - name: Build Vita - # run: ./scripts/build-vita-docker.sh - # - name: Upload Vita binary - # uses: actions/upload-artifact@v6 - # with: - # name: dusk-vita - # path: build-vita/Dusk.vpk - # if-no-files-found: error - build-knulli: runs-on: ubuntu-latest + container: + image: debian:trixie steps: + - name: Install Node.js + run: apt-get update && apt-get install -y nodejs - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 - - name: Build knulli - run: ./scripts/build-knulli-docker.sh + uses: actions/checkout@v4 + - name: Install dependencies + run: | + dpkg --add-architecture arm64 + apt-get update + apt-get install -y --no-install-recommends \ + crossbuild-essential-arm64 \ + ca-certificates \ + pkg-config \ + cmake \ + make \ + ninja-build \ + git \ + file \ + python3 \ + python3-pip \ + python3-polib \ + python3-pil \ + python3-dotenv \ + python3-pyqt5 \ + python3-opengl \ + liblua5.4-dev:arm64 \ + xz-utils:arm64 \ + libbz2-dev:arm64 \ + zlib1g-dev:arm64 \ + libzip-dev:arm64 \ + libssl-dev:arm64 \ + libsdl2-dev:arm64 \ + liblzma-dev:arm64 \ + libopengl0:arm64 \ + libgl1:arm64 \ + libegl1:arm64 \ + libgles2:arm64 \ + libgl1-mesa-dev:arm64 + - name: Build Knulli + run: ./scripts/build-knulli.sh - name: Move output to Dusk subfolder run: | mkdir -p ./git-artifcats/Dusk cp -r build-knulli/dusk ./git-artifcats/Dusk - - name: Upload knulli binary - uses: actions/upload-artifact@v6 + - name: Upload Knulli binary + uses: actions/upload-artifact@v3 with: name: dusk-knulli path: ./git-artifcats/Dusk @@ -88,20 +147,31 @@ jobs: build-gamecube: runs-on: ubuntu-latest + container: + image: ghcr.io/extremscorner/libogc2:latest steps: + - name: Install Node.js + run: apt-get update && apt-get install -y nodejs - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 + uses: actions/checkout@v4 + - name: Install additional dependencies + run: | + apt-get install -y \ + python3-pip python3-polib python3-pil \ + python3-dotenv python3-pyqt5 python3-opengl + dkp-pacman -Syu --noconfirm + dkp-pacman -S --needed --noconfirm \ + gamecube-sdl2 ppc-liblzma ppc-libzip \ + gamecube-tools ppc-libmad ppc-zlib-ng ppc-bzip2 ppc-zstd - name: Build GameCube - run: ./scripts/build-gamecube-docker.sh - - name: Copy output files. + run: ./scripts/build-gamecube.sh + - name: Copy output files run: | mkdir -p ./git-artifcats/Dusk cp build-gamecube/Dusk.dol ./git-artifcats/Dusk/Dusk.dol cp build-gamecube/dusk.dsk ./git-artifcats/Dusk/dusk.dsk - name: Upload GameCube binary - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v3 with: name: dusk-gamecube path: ./git-artifcats/Dusk @@ -109,21 +179,32 @@ jobs: build-gamecube-iso: runs-on: ubuntu-latest + container: + image: ghcr.io/extremscorner/libogc2:latest steps: + - name: Install Node.js + run: apt-get update && apt-get install -y nodejs - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 + uses: actions/checkout@v4 + - name: Install additional dependencies + run: | + apt-get install -y \ + python3-pip python3-polib python3-pil \ + python3-dotenv python3-pyqt5 python3-opengl xorriso + dkp-pacman -Syu --noconfirm + dkp-pacman -S --needed --noconfirm \ + gamecube-sdl2 ppc-liblzma ppc-libzip \ + gamecube-tools ppc-libmad ppc-zlib-ng ppc-bzip2 ppc-zstd - name: Build GameCube ISO - run: ./scripts/build-gamecube-iso-docker.sh - - name: Copy output files. + run: ./scripts/build-gamecube-iso.sh + - name: Copy output files run: | mkdir -p ./git-artifcats/Dusk cp build-gamecube-iso/Dusk-NTSC-J.iso ./git-artifcats/Dusk/Dusk-NTSC-J.iso cp build-gamecube-iso/Dusk-NTSC-U.iso ./git-artifcats/Dusk/Dusk-NTSC-U.iso cp build-gamecube-iso/Dusk-PAL.iso ./git-artifcats/Dusk/Dusk-PAL.iso - name: Upload GameCube ISO - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v3 with: name: dusk-gamecube-iso path: ./git-artifcats/Dusk @@ -131,21 +212,32 @@ jobs: build-wii: runs-on: ubuntu-latest + container: + image: ghcr.io/extremscorner/libogc2:latest steps: + - name: Install Node.js + run: apt-get update && apt-get install -y nodejs - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 + uses: actions/checkout@v4 + - name: Install additional dependencies + run: | + apt-get install -y \ + python3-pip python3-polib python3-pil \ + python3-dotenv python3-pyqt5 python3-opengl + dkp-pacman -Syu --noconfirm + dkp-pacman -S --needed --noconfirm \ + gamecube-sdl2 ppc-liblzma ppc-libzip \ + gamecube-tools ppc-libmad ppc-zlib-ng ppc-bzip2 ppc-zstd - name: Build Wii - run: ./scripts/build-wii-docker.sh - - name: Copy output files. + run: ./scripts/build-wii.sh + - name: Copy output files run: | mkdir -p ./git-artifcats/Dusk/apps/Dusk cp build-wii/boot.dol ./git-artifcats/Dusk/apps/Dusk/boot.dol cp build-wii/dusk.dsk ./git-artifcats/Dusk/apps/Dusk/dusk.dsk cp build-wii/meta.xml ./git-artifcats/Dusk/apps/Dusk/meta.xml - name: Upload Wii binary - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v3 with: name: dusk-wii path: ./git-artifcats/Dusk @@ -153,22 +245,33 @@ jobs: build-wii-iso: runs-on: ubuntu-latest + container: + image: ghcr.io/extremscorner/libogc2:latest steps: + - name: Install Node.js + run: apt-get update && apt-get install -y nodejs - name: Checkout repository - uses: actions/checkout@v6 - - name: Set up Docker - uses: docker/setup-docker-action@v5 + uses: actions/checkout@v4 + - name: Install additional dependencies + run: | + apt-get install -y \ + python3-pip python3-polib python3-pil \ + python3-dotenv python3-pyqt5 python3-opengl xorriso + dkp-pacman -Syu --noconfirm + dkp-pacman -S --needed --noconfirm \ + gamecube-sdl2 ppc-liblzma ppc-libzip \ + gamecube-tools ppc-libmad ppc-zlib-ng ppc-bzip2 ppc-zstd - name: Build Wii ISO - run: ./scripts/build-wii-iso-docker.sh - - name: Copy output files. + run: ./scripts/build-wii-iso.sh + - name: Copy output files run: | mkdir -p ./git-artifcats/Dusk cp build-wii-iso/Dusk-NTSC-J.iso ./git-artifcats/Dusk/Dusk-NTSC-J.iso cp build-wii-iso/Dusk-NTSC-U.iso ./git-artifcats/Dusk/Dusk-NTSC-U.iso cp build-wii-iso/Dusk-PAL.iso ./git-artifcats/Dusk/Dusk-PAL.iso - name: Upload Wii ISO - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v3 with: name: dusk-wii-iso path: ./git-artifcats/Dusk - if-no-files-found: error \ No newline at end of file + if-no-files-found: error diff --git a/src/dusk/CMakeLists.txt b/src/dusk/CMakeLists.txt index a39c2f48..d99f093c 100644 --- a/src/dusk/CMakeLists.txt +++ b/src/dusk/CMakeLists.txt @@ -56,7 +56,6 @@ add_subdirectory(animation) add_subdirectory(event) add_subdirectory(assert) add_subdirectory(asset) -add_subdirectory(cutscene) add_subdirectory(console) add_subdirectory(display) add_subdirectory(log) diff --git a/src/dusk/cutscene/CMakeLists.txt b/src/dusk/cutscene/CMakeLists.txt deleted file mode 100644 index cf650948..00000000 --- a/src/dusk/cutscene/CMakeLists.txt +++ /dev/null @@ -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 -) diff --git a/src/dusk/cutscene/cutscene.c b/src/dusk/cutscene/cutscene.c deleted file mode 100644 index 33ff6af2..00000000 --- a/src/dusk/cutscene/cutscene.c +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/src/dusk/cutscene/cutscene.h b/src/dusk/cutscene/cutscene.h deleted file mode 100644 index 1a294eed..00000000 --- a/src/dusk/cutscene/cutscene.h +++ /dev/null @@ -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); diff --git a/src/dusk/engine/engine.c b/src/dusk/engine/engine.c index 54c59f3e..ce198c57 100644 --- a/src/dusk/engine/engine.c +++ b/src/dusk/engine/engine.c @@ -13,7 +13,6 @@ #include "rpg/rpg.h" #include "display/display.h" #include "scene/scene.h" -#include "cutscene/cutscene.h" #include "asset/asset.h" #include "ui/ui.h" #include "assert/assert.h" @@ -42,7 +41,6 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { errorChain(localeManagerInit()); errorChain(displayInit()); errorChain(uiInit()); - errorChain(cutsceneInit()); errorChain(rpgInit()); errorChain(networkInit()); errorChain(sceneInit()); @@ -61,7 +59,6 @@ errorret_t engineUpdate(void) { inputUpdate(); consoleUpdate(); errorChain(rpgUpdate()); - errorChain(cutsceneUpdate()); errorChain(sceneUpdate()); errorChain(assetUpdate()); errorChain(uiUpdate()); @@ -77,7 +74,6 @@ void engineExit(void) { } errorret_t engineDispose(void) { - cutsceneDispose(); errorChain(sceneDispose()); errorChain(networkDispose()); errorChain(rpgDispose()); diff --git a/src/dusk/rpg/cutscene/cutscenesystem.c b/src/dusk/rpg/cutscene/cutscenesystem.c index d803e05d..8017f80f 100644 --- a/src/dusk/rpg/cutscene/cutscenesystem.c +++ b/src/dusk/rpg/cutscene/cutscenesystem.c @@ -53,4 +53,10 @@ const cutsceneitem_t * cutsceneSystemGetCurrentItem() { if(CUTSCENE_SYSTEM.scene == NULL) return NULL; return &CUTSCENE_SYSTEM.scene->items[CUTSCENE_SYSTEM.currentItem]; +} + +void cutsceneSystemDispose() { + CUTSCENE_SYSTEM.scene = NULL; + CUTSCENE_SYSTEM.currentItem = 0xFF; + CUTSCENE_SYSTEM.mode = CUTSCENE_MODE_NONE; } \ No newline at end of file diff --git a/src/dusk/rpg/cutscene/cutscenesystem.h b/src/dusk/rpg/cutscene/cutscenesystem.h index 7c3242a9..63051aea 100644 --- a/src/dusk/rpg/cutscene/cutscenesystem.h +++ b/src/dusk/rpg/cutscene/cutscenesystem.h @@ -44,7 +44,12 @@ void cutsceneSystemUpdate(); /** * Get the current cutscene item. - * + * * @return Pointer to the current cutscene item. */ -const cutsceneitem_t * cutsceneSystemGetCurrentItem(); \ No newline at end of file +const cutsceneitem_t * cutsceneSystemGetCurrentItem(); + +/** + * Disposes of the cutscene system, stopping any active cutscene. + */ +void cutsceneSystemDispose(); \ No newline at end of file diff --git a/src/dusk/rpg/cutscene/item/CMakeLists.txt b/src/dusk/rpg/cutscene/item/CMakeLists.txt index 6b3e271a..f30d8b58 100755 --- a/src/dusk/rpg/cutscene/item/CMakeLists.txt +++ b/src/dusk/rpg/cutscene/item/CMakeLists.txt @@ -7,4 +7,5 @@ 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 new file mode 100644 index 00000000..39be9996 --- /dev/null +++ b/src/dusk/rpg/cutscene/item/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); + } +} diff --git a/src/dusk/rpg/cutscene/item/cutsceneentitymove.h b/src/dusk/rpg/cutscene/item/cutsceneentitymove.h new file mode 100644 index 00000000..cefa06ad --- /dev/null +++ b/src/dusk/rpg/cutscene/item/cutsceneentitymove.h @@ -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); diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.c b/src/dusk/rpg/cutscene/item/cutsceneitem.c index 18a8b582..8c41a4f3 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.c +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.c @@ -6,6 +6,7 @@ */ #include "rpg/cutscene/cutscenesystem.h" +#include "cutsceneentitymove.h" #include "input/input.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); break; + case CUTSCENE_ITEM_TYPE_ENTITY_MOVE: + cutsceneEntityMoveStart(item); + break; + default: break; } @@ -48,6 +53,10 @@ void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) { if(data->wait <= 0) cutsceneSystemNext(); break; + case CUTSCENE_ITEM_TYPE_ENTITY_MOVE: + cutsceneEntityMoveUpdate(item); + break; + default: break; } diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.h b/src/dusk/rpg/cutscene/item/cutsceneitem.h index f632518d..422c710d 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 "rpg/overworld/worldpos.h" typedef struct cutscene_s cutscene_t; @@ -17,7 +18,8 @@ typedef enum { CUTSCENE_ITEM_TYPE_TEXT, CUTSCENE_ITEM_TYPE_CALLBACK, CUTSCENE_ITEM_TYPE_WAIT, - CUTSCENE_ITEM_TYPE_CUTSCENE + CUTSCENE_ITEM_TYPE_CUTSCENE, + CUTSCENE_ITEM_TYPE_ENTITY_MOVE } cutsceneitemtype_t; typedef struct cutsceneitem_s { @@ -29,6 +31,11 @@ typedef struct cutsceneitem_s { cutscenecallback_t callback; cutscenewait_t wait; const cutscene_t *cutscene; + struct { + uint8_t entityIndex; + worldpos_t target; + bool_t run; + } entityMove; }; } cutsceneitem_t; diff --git a/src/dusk/rpg/item/backpack.c b/src/dusk/rpg/item/backpack.c index 4ed1be20..03bd91ae 100644 --- a/src/dusk/rpg/item/backpack.c +++ b/src/dusk/rpg/item/backpack.c @@ -6,6 +6,7 @@ */ #include "backpack.h" +#include "assert/assert.h" backpack_t BACKPACK; diff --git a/src/dusk/rpg/rpg.c b/src/dusk/rpg/rpg.c index 4fd6162b..c2e7446d 100644 --- a/src/dusk/rpg/rpg.c +++ b/src/dusk/rpg/rpg.c @@ -72,6 +72,7 @@ errorret_t rpgUpdate(void) { } errorret_t rpgDispose(void) { + cutsceneSystemDispose(); errorChain(mapDispose()); errorOk();