Events base.
This commit is contained in:
@@ -25,6 +25,7 @@ target_sources(${DUSK_TARGET_NAME}
|
||||
add_subdirectory(assert)
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(entity)
|
||||
add_subdirectory(event)
|
||||
add_subdirectory(item)
|
||||
add_subdirectory(locale)
|
||||
add_subdirectory(physics)
|
||||
|
@@ -37,41 +37,10 @@ void npcInteract(entity_t *player, entity_t *self) {
|
||||
break;
|
||||
|
||||
case NPC_INTERACT_TYPE_EVENT:
|
||||
eventSetActive(self->npc.eventData);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown NPC interaction type");
|
||||
}
|
||||
|
||||
// uiTextboxSetText(
|
||||
// "Hello World how are you today? Hope things are going well for you! I am "
|
||||
// "having a great day, hope you are too. Did I ever tell you about the tragedy "
|
||||
// "of Darth Plagueis the Wise? He was a dark lord of the Sith, "
|
||||
// "so powerful and so wise he could use the Force to influence the midichlorians"
|
||||
// );
|
||||
// const char_t *name = "Dom";
|
||||
// const char_t *key = "name";
|
||||
// uint16_t len = languageFormat(
|
||||
// "test.npc.text",
|
||||
// NULL,
|
||||
// 0,
|
||||
// (const char_t *[]){ key },
|
||||
// (const char_t *[]){ name },
|
||||
// 1
|
||||
// );
|
||||
|
||||
// char_t *buffer = malloc(sizeof(char_t) + len + 1);
|
||||
// assertNotNull(buffer, "Failed to allocate buffer for NPC text");
|
||||
|
||||
// languageFormat(
|
||||
// "test.npc.text",
|
||||
// buffer,
|
||||
// len + 1,
|
||||
// (const char_t *[]){ key },
|
||||
// (const char_t *[]){ name },
|
||||
// 1
|
||||
// );
|
||||
|
||||
// uiTextboxSetText(buffer);
|
||||
// free(buffer);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
#include "event/eventlist.h"
|
||||
|
||||
typedef struct _entity_t entity_t;
|
||||
|
||||
@@ -15,7 +15,8 @@ typedef struct {
|
||||
npcinteracttype_t interactType;
|
||||
|
||||
union {
|
||||
char_t* text;
|
||||
const char_t* text;
|
||||
const eventdata_t *eventData;
|
||||
};
|
||||
} npc_t;
|
||||
|
||||
|
11
src/dusk/event/CMakeLists.txt
Normal file
11
src/dusk/event/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
event.c
|
||||
eventtext.c
|
||||
)
|
@@ -5,4 +5,69 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "event.h"
|
||||
#include "event.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
eventcallback_t EVENT_CALLBACKS[] = {
|
||||
[EVENT_TYPE_NULL] = { NULL, NULL },
|
||||
[EVENT_TYPE_TEXT] = { eventTextStart, eventTextUpdate },
|
||||
};
|
||||
|
||||
event_t EVENT;
|
||||
|
||||
void eventInit() {
|
||||
memoryZero(&EVENT, sizeof(event_t));
|
||||
}
|
||||
|
||||
void eventUpdate() {
|
||||
if(EVENT.active == NULL) {
|
||||
return; // No active event to update
|
||||
}
|
||||
|
||||
const eventitem_t *item = &EVENT.active->items[EVENT.item];
|
||||
assertNotNull(
|
||||
EVENT_CALLBACKS[item->type].update,
|
||||
"Event type does not have an update callback"
|
||||
);
|
||||
|
||||
EVENT_CALLBACKS[item->type].update(item);
|
||||
}
|
||||
|
||||
void eventSetActive(const eventdata_t *event) {
|
||||
assertNotNull(event, "Event data cannot be NULL");
|
||||
assertTrue(
|
||||
event->itemCount <= EVENT_ITEM_COUNT_MAX,
|
||||
"Event count too high"
|
||||
);
|
||||
assertTrue(event->itemCount > 0, "Event must have at least one item");
|
||||
|
||||
EVENT.active = event;
|
||||
EVENT.item = 0;
|
||||
|
||||
const eventitem_t *firstItem = &EVENT.active->items[EVENT.item];
|
||||
|
||||
assertNotNull(
|
||||
EVENT_CALLBACKS[firstItem->type].start,
|
||||
"Event type does not have a start callback"
|
||||
);
|
||||
EVENT_CALLBACKS[firstItem->type].start(firstItem);
|
||||
}
|
||||
|
||||
void eventNext() {
|
||||
assertNotNull(EVENT.active, "No active event to proceed with");
|
||||
assertTrue(EVENT.item < EVENT.active->itemCount, "No more items in the event");
|
||||
|
||||
EVENT.item++;
|
||||
if (EVENT.item >= EVENT.active->itemCount) {
|
||||
EVENT.active = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
const eventitem_t *nextItem = &EVENT.active->items[EVENT.item];
|
||||
assertNotNull(
|
||||
EVENT_CALLBACKS[nextItem->type].start,
|
||||
"Event type does not have a start callback"
|
||||
);
|
||||
EVENT_CALLBACKS[nextItem->type].start(nextItem);
|
||||
}
|
@@ -6,24 +6,41 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "eventtext.h"
|
||||
|
||||
typedef enum {
|
||||
EVENT_TYPE_NULL = 0,
|
||||
EVENT_TYPE_TEXT,
|
||||
} eventtype_t;
|
||||
|
||||
typedef struct _eventitem_t {
|
||||
eventtype_t type;
|
||||
|
||||
union {
|
||||
eventtext_t texts;
|
||||
};
|
||||
} eventitem_t;
|
||||
|
||||
#define EVENT_ITEM_COUNT_MAX 32
|
||||
#include "eventdata.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t itemCount;
|
||||
eventitem_t items[EVENT_ITEM_COUNT_MAX];
|
||||
} event_t;
|
||||
eventdata_t data;
|
||||
const eventdata_t *active;
|
||||
uint8_t item;
|
||||
} event_t;
|
||||
|
||||
typedef struct {
|
||||
void (*start)(const eventitem_t *item);
|
||||
void (*update)(const eventitem_t *item);
|
||||
} eventcallback_t;
|
||||
|
||||
extern eventcallback_t EVENT_CALLBACKS[EVENT_TYPE_COUNT];
|
||||
extern event_t EVENT;
|
||||
|
||||
/**
|
||||
* Initializes the event system.
|
||||
*/
|
||||
void eventInit();
|
||||
|
||||
/**
|
||||
* Updates the active event.
|
||||
*/
|
||||
void eventUpdate();
|
||||
|
||||
/**
|
||||
* Sets the active event.
|
||||
*
|
||||
* @param event The event to set as active.
|
||||
*/
|
||||
void eventSetActive(const eventdata_t *eventData);
|
||||
|
||||
/**
|
||||
* Goes to the next item in the active event. Only meant to be called by
|
||||
* event items.
|
||||
*/
|
||||
void eventNext();
|
14
src/dusk/event/eventdata.h
Normal file
14
src/dusk/event/eventdata.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "eventitem.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t itemCount;
|
||||
eventitem_t items[EVENT_ITEM_COUNT_MAX];
|
||||
} eventdata_t;
|
26
src/dusk/event/eventitem.h
Normal file
26
src/dusk/event/eventitem.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma ocne
|
||||
#include "eventtext.h"
|
||||
|
||||
typedef enum {
|
||||
EVENT_TYPE_NULL = 0,
|
||||
EVENT_TYPE_TEXT,
|
||||
} eventtype_t;
|
||||
|
||||
#define EVENT_TYPE_COUNT 2
|
||||
|
||||
typedef struct _eventitem_t {
|
||||
eventtype_t type;
|
||||
|
||||
union {
|
||||
eventtext_t text;
|
||||
};
|
||||
} eventitem_t;
|
||||
|
||||
#define EVENT_ITEM_COUNT_MAX 32
|
26
src/dusk/event/eventtext.c
Normal file
26
src/dusk/event/eventtext.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "event.h"
|
||||
#include "ui/uitextbox.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void eventTextStart(const eventitem_t *item) {
|
||||
assertNotNull(item, "Event item cannot be NULL");
|
||||
assertTrue(item->type == EVENT_TYPE_TEXT, "Event item must be of type TEXT");
|
||||
assertNotNull(item->text, "Event item must have at least one text");
|
||||
uiTextboxSetText(item->text);
|
||||
}
|
||||
|
||||
void eventTextUpdate(const eventitem_t *item) {
|
||||
assertNotNull(item, "Event item cannot be NULL");
|
||||
assertTrue(item->type == EVENT_TYPE_TEXT, "Event item must be of type TEXT");
|
||||
|
||||
if(!UI_TEXTBOX.visible) {
|
||||
eventNext();
|
||||
}
|
||||
}
|
@@ -12,4 +12,25 @@ typedef struct _eventitem_t eventitem_t;
|
||||
|
||||
#define EVENT_TEXT_STRING_COUNT_MAX 8
|
||||
|
||||
typedef const char_t* eventtext_t[EVENT_TEXT_STRING_COUNT_MAX];
|
||||
typedef const char_t* eventtext_t;
|
||||
|
||||
/**
|
||||
* Starts the text event for the given item.
|
||||
*
|
||||
* @param item The event item to start.
|
||||
*/
|
||||
void eventTextStart(const eventitem_t *item);
|
||||
|
||||
/**
|
||||
* Updates the text event for the given item.
|
||||
*
|
||||
* @param item The event item to update.
|
||||
*/
|
||||
void eventTextUpdate(const eventitem_t *item);
|
||||
|
||||
/**
|
||||
* Query whether the text event is done or not.
|
||||
*
|
||||
* @param item The event item to check.
|
||||
*/
|
||||
bool_t eventTextIsDone(const eventitem_t *item);
|
@@ -11,13 +11,14 @@
|
||||
#include "display/scene.h"
|
||||
#include "world/overworld.h"
|
||||
#include "input.h"
|
||||
|
||||
#include "event/event.h"
|
||||
#include "ui/uitextbox.h"
|
||||
|
||||
// Press F5 to compile and run the compiled game.gb in the Emulicous Emulator/Debugger
|
||||
void main(void) {
|
||||
renderInit();
|
||||
inputInit();
|
||||
eventInit();
|
||||
uiTextboxInit();
|
||||
|
||||
overworldInit();
|
||||
@@ -30,6 +31,7 @@ void main(void) {
|
||||
|
||||
overworldUpdate();
|
||||
uiTextboxUpdate();
|
||||
eventUpdate();
|
||||
|
||||
// Update input for next frame.
|
||||
inputUpdate();
|
||||
|
@@ -188,5 +188,4 @@ void uiTextboxSetText(const char_t *text) {
|
||||
|
||||
assertUnreachable("Code should not reach here, all cases handled.");
|
||||
}
|
||||
printf("test");
|
||||
}
|
Reference in New Issue
Block a user