Add camera shake
This commit is contained in:
@@ -57,14 +57,14 @@ msgstr "Objetos"
|
|||||||
msgid "ui.game_menu.settings"
|
msgid "ui.game_menu.settings"
|
||||||
msgstr "Configuración"
|
msgstr "Configuración"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.csv
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.potion.name"
|
msgid "item.potion.name"
|
||||||
msgstr "Poción"
|
msgstr "Poción"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.csv
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.potato.name"
|
msgid "item.potato.name"
|
||||||
msgstr "Papa"
|
msgstr "Papa"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.csv
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.apple.name"
|
msgid "item.apple.name"
|
||||||
msgstr "Manzana"
|
msgstr "Manzana"
|
||||||
|
|||||||
@@ -57,14 +57,14 @@ msgstr "アイテム"
|
|||||||
msgid "ui.game_menu.settings"
|
msgid "ui.game_menu.settings"
|
||||||
msgstr "設定"
|
msgstr "設定"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.csv
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.potion.name"
|
msgid "item.potion.name"
|
||||||
msgstr "ポーション"
|
msgstr "ポーション"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.csv
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.potato.name"
|
msgid "item.potato.name"
|
||||||
msgstr "ジャガイモ"
|
msgstr "ジャガイモ"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.csv
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.apple.name"
|
msgid "item.apple.name"
|
||||||
msgstr "リンゴ"
|
msgstr "リンゴ"
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ target_compile_definitions(${DUSK_BINARY_TARGET_NAME} PUBLIC
|
|||||||
DUSK_DISPLAY_HEIGHT=272
|
DUSK_DISPLAY_HEIGHT=272
|
||||||
DUSK_THREAD_PTHREAD
|
DUSK_THREAD_PTHREAD
|
||||||
DUSK_TIME_DYNAMIC
|
DUSK_TIME_DYNAMIC
|
||||||
|
DUSK_DISPLAY_OVERSCAN=6
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|||||||
@@ -154,6 +154,14 @@ typedef struct cutscene_s {
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AMOUNT ranges 0 (no shake) to 4 (three tiles): 1 is half a tile, 2 is
|
||||||
|
// a full tile, 3 is two tiles, and 4 is three tiles.
|
||||||
|
#define CUTSCENE_SHAKE(AMOUNT, DURATION) \
|
||||||
|
{ \
|
||||||
|
.type = CUTSCENE_ITEM_TYPE_SHAKE, \
|
||||||
|
.shake = { .amount = AMOUNT, .duration = DURATION } \
|
||||||
|
}
|
||||||
|
|
||||||
#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) }
|
||||||
|
|
||||||
|
|||||||
@@ -7,160 +7,146 @@
|
|||||||
|
|
||||||
#include "rpg/cutscene/cutscenesystem.h"
|
#include "rpg/cutscene/cutscenesystem.h"
|
||||||
|
|
||||||
|
cutsceneitemcallbacks_t CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT] = {
|
||||||
|
[CUTSCENE_ITEM_TYPE_NULL] = { 0 },
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_TEXT] = {
|
||||||
|
.init = cutsceneTextStart,
|
||||||
|
.update = cutsceneTextUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_TEXT_MINI] = {
|
||||||
|
.init = cutsceneTextMiniStart,
|
||||||
|
.update = cutsceneTextMiniUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE] = {
|
||||||
|
.init = cutsceneTextMiniHideStart,
|
||||||
|
.update = cutsceneTextMiniHideUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_CALLBACK] = {
|
||||||
|
.init = cutsceneCallbackStart,
|
||||||
|
.update = cutsceneCallbackUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_WAIT] = {
|
||||||
|
.init = cutsceneWaitStart,
|
||||||
|
.update = cutsceneWaitUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_CUTSCENE] = {
|
||||||
|
.init = cutsceneCutsceneStart,
|
||||||
|
.update = cutsceneCutsceneUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT] = {
|
||||||
|
.init = cutsceneEntityTeleportStart,
|
||||||
|
.update = cutsceneEntityTeleportUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO] = {
|
||||||
|
.init = cutsceneEntityWalkToStart,
|
||||||
|
.update = cutsceneEntityWalkToUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_FADE] = {
|
||||||
|
.init = cutsceneFadeStart,
|
||||||
|
.update = cutsceneFadeUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_SET_PAUSE] = {
|
||||||
|
.init = cutsceneSetPauseStart,
|
||||||
|
.update = cutsceneSetPauseUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_CONCURRENT] = {
|
||||||
|
.init = cutsceneConcurrentStart,
|
||||||
|
.update = cutsceneConcurrentUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ITEM_GIVE] = {
|
||||||
|
.init = cutsceneItemGiveStart,
|
||||||
|
.update = cutsceneItemGiveUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ENTITY_REMOVE] = {
|
||||||
|
.init = cutsceneEntityRemoveStart,
|
||||||
|
.update = cutsceneEntityRemoveUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ENTITY_ADD] = {
|
||||||
|
.init = cutsceneEntityAddStart,
|
||||||
|
.update = cutsceneEntityAddUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ENTITY_TURN] = {
|
||||||
|
.init = cutsceneEntityTurnStart,
|
||||||
|
.update = cutsceneEntityTurnUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY] = {
|
||||||
|
.init = cutsceneEntityWalkToEntityStart,
|
||||||
|
.update = cutsceneEntityWalkToEntityUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_MAP_AREA_ADD] = {
|
||||||
|
.init = cutsceneMapAreaAddStart,
|
||||||
|
.update = cutsceneMapAreaAddUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_MAP_AREA_REMOVE] = {
|
||||||
|
.init = cutsceneMapAreaRemoveStart,
|
||||||
|
.update = cutsceneMapAreaRemoveUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT] = {
|
||||||
|
.init = cutsceneMapAreaWaitStart,
|
||||||
|
.update = cutsceneMapAreaWaitUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_START_BATTLE] = {
|
||||||
|
.init = cutsceneStartBattleStart,
|
||||||
|
.update = cutsceneStartBattleUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_EMOJI] = {
|
||||||
|
.init = cutsceneEmojiStart,
|
||||||
|
.update = cutsceneEmojiUpdate
|
||||||
|
},
|
||||||
|
|
||||||
|
[CUTSCENE_ITEM_TYPE_SHAKE] = {
|
||||||
|
.init = cutsceneShakeStart,
|
||||||
|
.update = cutsceneShakeUpdate
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
||||||
switch(item->type) {
|
cutsceneiteminitcallback_t *init = CUTSCENE_ITEM_CALLBACKS[item->type].init;
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT:
|
if(init != NULL) init(item, data);
|
||||||
cutsceneTextStart(item, data);
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT_MINI:
|
bool_t cutsceneItemUpdate(
|
||||||
cutsceneTextMiniStart(item, data);
|
const cutsceneitem_t *item,
|
||||||
break;
|
cutsceneitemdata_t *data
|
||||||
|
) {
|
||||||
|
cutsceneitemupdatecallback_t *update =
|
||||||
|
CUTSCENE_ITEM_CALLBACKS[item->type].update;
|
||||||
|
if(update == NULL) return false;
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE:
|
return update(item, data);
|
||||||
cutsceneTextMiniHideStart(item, data);
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_CALLBACK:
|
void cutsceneCutsceneStart(
|
||||||
cutsceneCallbackStart(item, data);
|
const cutsceneitem_t *item,
|
||||||
break;
|
cutsceneitemdata_t *data
|
||||||
|
) {
|
||||||
case CUTSCENE_ITEM_TYPE_WAIT:
|
|
||||||
cutsceneWaitStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_CUTSCENE:
|
|
||||||
if(item->cutscene != NULL) cutsceneSystemStartCutscene(item->cutscene);
|
if(item->cutscene != NULL) cutsceneSystemStartCutscene(item->cutscene);
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT:
|
|
||||||
cutsceneEntityTeleportStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO:
|
|
||||||
cutsceneEntityWalkToStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_FADE:
|
|
||||||
cutsceneFadeStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_SET_PAUSE:
|
|
||||||
cutsceneSetPauseStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_CONCURRENT:
|
|
||||||
cutsceneConcurrentStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ITEM_GIVE:
|
|
||||||
cutsceneItemGiveStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_REMOVE:
|
|
||||||
cutsceneEntityRemoveStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_ADD:
|
|
||||||
cutsceneEntityAddStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_TURN:
|
|
||||||
cutsceneEntityTurnStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY:
|
|
||||||
cutsceneEntityWalkToEntityStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_ADD:
|
|
||||||
cutsceneMapAreaAddStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_REMOVE:
|
|
||||||
cutsceneMapAreaRemoveStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT:
|
|
||||||
cutsceneMapAreaWaitStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_START_BATTLE:
|
|
||||||
cutsceneStartBattleStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_EMOJI:
|
|
||||||
cutsceneEmojiStart(item, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
bool_t cutsceneCutsceneUpdate(
|
||||||
switch(item->type) {
|
const cutsceneitem_t *item,
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT:
|
cutsceneitemdata_t *data
|
||||||
return cutsceneTextUpdate(item, data);
|
) {
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT_MINI:
|
|
||||||
return cutsceneTextMiniUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE:
|
|
||||||
return cutsceneTextMiniHideUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_CALLBACK:
|
|
||||||
return cutsceneCallbackUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_WAIT:
|
|
||||||
return cutsceneWaitUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT:
|
|
||||||
return cutsceneEntityTeleportUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO:
|
|
||||||
return cutsceneEntityWalkToUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_FADE:
|
|
||||||
return cutsceneFadeUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_SET_PAUSE:
|
|
||||||
return cutsceneSetPauseUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_CONCURRENT:
|
|
||||||
return cutsceneConcurrentUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ITEM_GIVE:
|
|
||||||
return cutsceneItemGiveUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_REMOVE:
|
|
||||||
return cutsceneEntityRemoveUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_ADD:
|
|
||||||
return cutsceneEntityAddUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_TURN:
|
|
||||||
return cutsceneEntityTurnUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY:
|
|
||||||
return cutsceneEntityWalkToEntityUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_ADD:
|
|
||||||
return cutsceneMapAreaAddUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_REMOVE:
|
|
||||||
return cutsceneMapAreaRemoveUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT:
|
|
||||||
return cutsceneMapAreaWaitUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_START_BATTLE:
|
|
||||||
return cutsceneStartBattleUpdate(item, data);
|
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_EMOJI:
|
|
||||||
return cutsceneEmojiUpdate(item, data);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "ui/cutscenetextminihide.h"
|
#include "ui/cutscenetextminihide.h"
|
||||||
#include "ui/cutscenefade.h"
|
#include "ui/cutscenefade.h"
|
||||||
#include "ui/cutsceneemoji.h"
|
#include "ui/cutsceneemoji.h"
|
||||||
|
#include "ui/cutsceneshake.h"
|
||||||
#include "item/cutsceneitemgive.h"
|
#include "item/cutsceneitemgive.h"
|
||||||
#include "maparea/cutscenemapareaadd.h"
|
#include "maparea/cutscenemapareaadd.h"
|
||||||
#include "maparea/cutscenemaparearemove.h"
|
#include "maparea/cutscenemaparearemove.h"
|
||||||
@@ -31,6 +32,7 @@ typedef struct cutscene_s cutscene_t;
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CUTSCENE_ITEM_TYPE_NULL,
|
CUTSCENE_ITEM_TYPE_NULL,
|
||||||
|
|
||||||
CUTSCENE_ITEM_TYPE_TEXT,
|
CUTSCENE_ITEM_TYPE_TEXT,
|
||||||
CUTSCENE_ITEM_TYPE_TEXT_MINI,
|
CUTSCENE_ITEM_TYPE_TEXT_MINI,
|
||||||
CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE,
|
CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE,
|
||||||
@@ -51,7 +53,10 @@ typedef enum {
|
|||||||
CUTSCENE_ITEM_TYPE_MAP_AREA_REMOVE,
|
CUTSCENE_ITEM_TYPE_MAP_AREA_REMOVE,
|
||||||
CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT,
|
CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT,
|
||||||
CUTSCENE_ITEM_TYPE_START_BATTLE,
|
CUTSCENE_ITEM_TYPE_START_BATTLE,
|
||||||
CUTSCENE_ITEM_TYPE_EMOJI
|
CUTSCENE_ITEM_TYPE_EMOJI,
|
||||||
|
CUTSCENE_ITEM_TYPE_SHAKE,
|
||||||
|
|
||||||
|
CUTSCENE_ITEM_TYPE_COUNT
|
||||||
} cutsceneitemtype_t;
|
} cutsceneitemtype_t;
|
||||||
|
|
||||||
struct cutsceneitem_s {
|
struct cutsceneitem_s {
|
||||||
@@ -79,6 +84,7 @@ struct cutsceneitem_s {
|
|||||||
cutscenemapareawait_t mapAreaWait;
|
cutscenemapareawait_t mapAreaWait;
|
||||||
cutscenestartbattle_t startBattle;
|
cutscenestartbattle_t startBattle;
|
||||||
cutsceneemoji_t emoji;
|
cutsceneemoji_t emoji;
|
||||||
|
cutsceneshake_t shake;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,6 +95,24 @@ typedef union cutsceneitemdata_u {
|
|||||||
cutscenemapareawaitdata_t mapAreaWait;
|
cutscenemapareawaitdata_t mapAreaWait;
|
||||||
} cutsceneitemdata_t;
|
} cutsceneitemdata_t;
|
||||||
|
|
||||||
|
typedef void (cutsceneiteminitcallback_t)(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef bool_t (cutsceneitemupdatecallback_t)(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
cutsceneiteminitcallback_t *init;
|
||||||
|
cutsceneitemupdatecallback_t *update;
|
||||||
|
} cutsceneitemcallbacks_t;
|
||||||
|
|
||||||
|
extern cutsceneitemcallbacks_t
|
||||||
|
CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the given cutscene item.
|
* Start the given cutscene item.
|
||||||
*
|
*
|
||||||
@@ -111,3 +135,29 @@ bool_t cutsceneItemUpdate(
|
|||||||
const cutsceneitem_t *item,
|
const cutsceneitem_t *item,
|
||||||
cutsceneitemdata_t *data
|
cutsceneitemdata_t *data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a nested-cutscene item, handing control over to the
|
||||||
|
* referenced cutscene.
|
||||||
|
*
|
||||||
|
* @param item The cutscene item.
|
||||||
|
* @param data Runtime data storage.
|
||||||
|
*/
|
||||||
|
void cutsceneCutsceneStart(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a nested-cutscene item. By the time this would run, control
|
||||||
|
* has already moved on to the referenced cutscene, so this always
|
||||||
|
* reports incomplete.
|
||||||
|
*
|
||||||
|
* @param item The cutscene item.
|
||||||
|
* @param data Runtime data storage.
|
||||||
|
* @returns false always.
|
||||||
|
*/
|
||||||
|
bool_t cutsceneCutsceneUpdate(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
);
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
cutscenetextminihide.c
|
cutscenetextminihide.c
|
||||||
cutscenefade.c
|
cutscenefade.c
|
||||||
cutsceneemoji.c
|
cutsceneemoji.c
|
||||||
|
cutsceneshake.c
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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/rpgcamera.h"
|
||||||
|
|
||||||
|
void cutsceneShakeStart(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
) {
|
||||||
|
rpgCameraShake(item->shake.amount, item->shake.duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t cutsceneShakeUpdate(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t amount;
|
||||||
|
float_t duration;
|
||||||
|
} cutsceneshake_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a camera shake item (kicks off the shake on the RPG camera).
|
||||||
|
*
|
||||||
|
* @param item The cutscene item.
|
||||||
|
* @param data Runtime data storage.
|
||||||
|
*/
|
||||||
|
void cutsceneShakeStart(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a camera shake item. The shake itself runs asynchronously on
|
||||||
|
* the RPG camera, so this always completes immediately.
|
||||||
|
*
|
||||||
|
* @param item The cutscene item.
|
||||||
|
* @param data Runtime data storage.
|
||||||
|
* @returns true always.
|
||||||
|
*/
|
||||||
|
bool_t cutsceneShakeUpdate(
|
||||||
|
const cutsceneitem_t *item,
|
||||||
|
cutsceneitemdata_t *data
|
||||||
|
);
|
||||||
@@ -14,9 +14,9 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
|
|
||||||
# Item Definitions
|
# Item Definitions
|
||||||
dusk_run_python(
|
dusk_run_python(
|
||||||
dusk_item_csv_defs
|
dusk_item_json_defs
|
||||||
tools.item
|
tools.item
|
||||||
--csv ${CMAKE_CURRENT_SOURCE_DIR}/item.csv
|
--json ${CMAKE_CURRENT_SOURCE_DIR}/item.json
|
||||||
--output ${DUSK_GENERATED_HEADERS_DIR}/rpg/item/itemdef.h
|
--output ${DUSK_GENERATED_HEADERS_DIR}/rpg/item/itemdef.h
|
||||||
)
|
)
|
||||||
add_dependencies(${DUSK_LIBRARY_TARGET_NAME} dusk_item_csv_defs)
|
add_dependencies(${DUSK_LIBRARY_TARGET_NAME} dusk_item_json_defs)
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
id,type,weight,name
|
|
||||||
POTION,MEDICINE,1.0,potion
|
|
||||||
POTATO,FOOD,0.5,potato
|
|
||||||
APPLE,FOOD,0.3,apple
|
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
{ "id": "POTION", "type": "MEDICINE", "weight": 1.0, "name": "potion" },
|
||||||
|
{ "id": "POTATO", "type": "FOOD", "weight": 0.5, "name": "potato" },
|
||||||
|
{ "id": "APPLE", "type": "FOOD", "weight": 0.3, "name": "apple" }
|
||||||
|
]
|
||||||
@@ -7,12 +7,18 @@
|
|||||||
|
|
||||||
#include "rpgcamera.h"
|
#include "rpgcamera.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
#include "util/random.h"
|
||||||
#include "rpg/entity/entity.h"
|
#include "rpg/entity/entity.h"
|
||||||
#include "rpg/overworld/map.h"
|
#include "rpg/overworld/map.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
#include "time/time.h"
|
||||||
|
|
||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
|
|
||||||
|
static const float_t RPG_CAMERA_SHAKE_AMOUNTS[] = {
|
||||||
|
0.0f, 0.5f, 1.0f, 2.0f, 3.0f
|
||||||
|
};
|
||||||
|
|
||||||
rpgcamera_t RPG_CAMERA;
|
rpgcamera_t RPG_CAMERA;
|
||||||
|
|
||||||
void rpgCameraInit(void) {
|
void rpgCameraInit(void) {
|
||||||
@@ -20,6 +26,13 @@ void rpgCameraInit(void) {
|
|||||||
RPG_CAMERA.projectionDirty = true;
|
RPG_CAMERA.projectionDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rpgCameraShake(uint8_t amount, float_t duration) {
|
||||||
|
assertTrue(amount <= 4, "Camera shake amount must be between 0 and 4");
|
||||||
|
RPG_CAMERA.shakeAmount = RPG_CAMERA_SHAKE_AMOUNTS[amount];
|
||||||
|
RPG_CAMERA.shakeDuration = duration;
|
||||||
|
RPG_CAMERA.shakeTime = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void rpgCameraGetPosition(vec3 out) {
|
void rpgCameraGetPosition(vec3 out) {
|
||||||
switch(RPG_CAMERA.mode) {
|
switch(RPG_CAMERA.mode) {
|
||||||
case RPG_CAMERA_MODE_FREE:
|
case RPG_CAMERA_MODE_FREE:
|
||||||
@@ -67,6 +80,13 @@ void rpgCameraUpdateEye(void) {
|
|||||||
rpgCameraGetPosition(target);
|
rpgCameraGetPosition(target);
|
||||||
glm_vec3_add(target, (vec3){ 0.5f, 0.5f, 0.5f }, target);
|
glm_vec3_add(target, (vec3){ 0.5f, 0.5f, 0.5f }, target);
|
||||||
|
|
||||||
|
if(RPG_CAMERA.shakeTime < RPG_CAMERA.shakeDuration) {
|
||||||
|
float_t t = 1.0f - (RPG_CAMERA.shakeTime / RPG_CAMERA.shakeDuration);
|
||||||
|
float_t magnitude = RPG_CAMERA.shakeAmount * t;
|
||||||
|
target[0] += randomFloat(-magnitude, magnitude);
|
||||||
|
target[2] += randomFloat(-magnitude, magnitude);
|
||||||
|
}
|
||||||
|
|
||||||
glm_lookat(
|
glm_lookat(
|
||||||
(vec3){ target[0], target[1] + offset, target[2] + z },
|
(vec3){ target[0], target[1] + offset, target[2] + z },
|
||||||
target,
|
target,
|
||||||
@@ -90,6 +110,10 @@ void rpgCameraToScreen(vec3 worldPos, vec2 out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t rpgCameraUpdate(void) {
|
errorret_t rpgCameraUpdate(void) {
|
||||||
|
if(RPG_CAMERA.shakeTime < RPG_CAMERA.shakeDuration) {
|
||||||
|
RPG_CAMERA.shakeTime += TIME.delta;
|
||||||
|
}
|
||||||
|
|
||||||
if(!mapIsLoaded()) errorOk();
|
if(!mapIsLoaded()) errorOk();
|
||||||
|
|
||||||
vec3 pos;
|
vec3 pos;
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ typedef struct {
|
|||||||
mat4 eye;
|
mat4 eye;
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
bool_t projectionDirty;
|
bool_t projectionDirty;
|
||||||
|
|
||||||
|
float_t shakeAmount;
|
||||||
|
float_t shakeDuration;
|
||||||
|
float_t shakeTime;
|
||||||
} rpgcamera_t;
|
} rpgcamera_t;
|
||||||
|
|
||||||
extern rpgcamera_t RPG_CAMERA;
|
extern rpgcamera_t RPG_CAMERA;
|
||||||
@@ -69,6 +73,17 @@ void rpgCameraUpdateProjection(void);
|
|||||||
*/
|
*/
|
||||||
void rpgCameraUpdateEye(void);
|
void rpgCameraUpdateEye(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shakes the RPG camera, randomly offsetting its position by a
|
||||||
|
* decreasing amount over the given duration.
|
||||||
|
*
|
||||||
|
* @param amount Shake strength from 0 (no shake) to 4 (three tiles).
|
||||||
|
* 1 is half a tile, 2 is a full tile, 3 is two tiles, and 4 is three
|
||||||
|
* tiles.
|
||||||
|
* @param duration How long the shake lasts, in seconds.
|
||||||
|
*/
|
||||||
|
void rpgCameraShake(uint8_t amount, float_t duration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a world-space position to screen-space pixel coordinates,
|
* Converts a world-space position to screen-space pixel coordinates,
|
||||||
* using the camera's current eye and projection matrices.
|
* using the camera's current eye and projection matrices.
|
||||||
|
|||||||
+12
-12
@@ -1,9 +1,9 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import csv
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Item CSV to .h defines")
|
parser = argparse.ArgumentParser(description="Item JSON to .h defines")
|
||||||
parser.add_argument("--csv", required=True, help="Path to item CSV file")
|
parser.add_argument("--json", required=True, help="Path to item JSON file")
|
||||||
parser.add_argument("--output", required=True, help="Path to output .h file")
|
parser.add_argument("--output", required=True, help="Path to output .h file")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -13,20 +13,20 @@ def type_enum(name):
|
|||||||
def id_enum(name):
|
def id_enum(name):
|
||||||
return "ITEM_ID_" + name.upper()
|
return "ITEM_ID_" + name.upper()
|
||||||
|
|
||||||
# Load CSV
|
# Load JSON
|
||||||
item_ids = []
|
item_ids = []
|
||||||
item_types = []
|
item_types = []
|
||||||
rows = {}
|
rows = {}
|
||||||
|
|
||||||
with open(args.csv, newline="", encoding="utf-8") as f:
|
with open(args.json, encoding="utf-8") as f:
|
||||||
reader = csv.DictReader(f)
|
entries = json.load(f)
|
||||||
if (
|
|
||||||
"id" not in reader.fieldnames or
|
if not all(
|
||||||
"type" not in reader.fieldnames or
|
"id" in row and "type" in row and "name" in row for row in entries
|
||||||
"name" not in reader.fieldnames
|
|
||||||
):
|
):
|
||||||
raise ValueError("CSV must have 'id', 'type', and 'name' columns")
|
raise ValueError("Each item must have 'id', 'type', and 'name' fields")
|
||||||
for row in reader:
|
|
||||||
|
for row in entries:
|
||||||
item_id, item_type = row["id"], row["type"]
|
item_id, item_type = row["id"], row["type"]
|
||||||
if item_id not in item_ids:
|
if item_id not in item_ids:
|
||||||
item_ids.append(item_id)
|
item_ids.append(item_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user