Textbox example.
This commit is contained in:
@@ -8,6 +8,7 @@ target_sources(${DUSK_TARGET_NAME}
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
rpg.c
|
rpg.c
|
||||||
rpgcamera.c
|
rpgcamera.c
|
||||||
|
rpgtextbox.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Subdirs
|
# Subdirs
|
||||||
|
|||||||
@@ -12,8 +12,10 @@
|
|||||||
void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
||||||
switch(item->type) {
|
switch(item->type) {
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT: {
|
case CUTSCENE_ITEM_TYPE_TEXT: {
|
||||||
strncpy(data->text.buffer, item->text, CUTSCENE_TEXT_BUFFER);
|
rpgTextboxShow(
|
||||||
data->text.length = strlen(data->text.buffer);
|
item->text.position,
|
||||||
|
item->text.text
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +38,11 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
|||||||
|
|
||||||
void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
||||||
switch(item->type) {
|
switch(item->type) {
|
||||||
|
case CUTSCENE_ITEM_TYPE_TEXT:
|
||||||
|
if(rpgTextboxIsVisible()) return;
|
||||||
|
cutsceneSystemNext();
|
||||||
|
break;
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_WAIT:
|
case CUTSCENE_ITEM_TYPE_WAIT:
|
||||||
data->wait -= TIME.fixedDelta;
|
data->wait -= TIME.fixedDelta;
|
||||||
if(data->wait <= 0) cutsceneSystemNext();
|
if(data->wait <= 0) cutsceneSystemNext();
|
||||||
|
|||||||
@@ -27,12 +27,11 @@ typedef struct cutsceneitem_s {
|
|||||||
cutscenetext_t text;
|
cutscenetext_t text;
|
||||||
cutscenecallback_t callback;
|
cutscenecallback_t callback;
|
||||||
cutscenewait_t wait;
|
cutscenewait_t wait;
|
||||||
cutscenecutscene_t cutscene;
|
const cutscenecutscene_t cutscene;
|
||||||
};
|
};
|
||||||
} cutsceneitem_t;
|
} cutsceneitem_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
cutscenetextdata_t text;
|
|
||||||
cutscenewaitdata_t wait;
|
cutscenewaitdata_t wait;
|
||||||
} cutsceneitemdata_t;
|
} cutsceneitemdata_t;
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "rpg/rpgtextbox.h"
|
||||||
|
|
||||||
#define CUTSCENE_TEXT_BUFFER 256
|
typedef struct {
|
||||||
|
char_t text[RPG_TEXTBOX_MAX_CHARS];
|
||||||
typedef const char_t *cutscenetext_t;
|
rpgtextboxpos_t position;
|
||||||
|
} cutscenetext_t;
|
||||||
typedef struct cutscenetextdata_s {
|
|
||||||
char_t buffer[CUTSCENE_TEXT_BUFFER];
|
|
||||||
uint8_t length;
|
|
||||||
uint8_t scroll;
|
|
||||||
} cutscenetextdata_t;
|
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
#include "rpg/cutscene/cutscenesystem.h"
|
#include "rpg/cutscene/cutscenesystem.h"
|
||||||
|
|
||||||
static const cutsceneitem_t TEST_CUTSCENE_ONE_ITEMS[] = {
|
static const cutsceneitem_t TEST_CUTSCENE_ONE_ITEMS[] = {
|
||||||
{ .type = CUTSCENE_ITEM_TYPE_TEXT, .text = "This is a test cutscene." },
|
{ .type = CUTSCENE_ITEM_TYPE_TEXT, .text = { .text = "This is a test cutscene.", .position = RPG_TEXTBOX_POS_BOTTOM } },
|
||||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 2.0f },
|
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 2.0f },
|
||||||
{ .type = CUTSCENE_ITEM_TYPE_TEXT, .text = "It has multiple lines of text.\nAnd waits in between." },
|
{ .type = CUTSCENE_ITEM_TYPE_TEXT, .text = { .text = "It has multiple lines of text.\nAnd waits in between.", .position = RPG_TEXTBOX_POS_TOP } },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const cutscene_t TEST_CUTSCENE_ONE = {
|
static const cutscene_t TEST_CUTSCENE_ONE = {
|
||||||
@@ -21,7 +21,7 @@ static const cutscene_t TEST_CUTSCENE_ONE = {
|
|||||||
|
|
||||||
static const cutsceneitem_t TEST_CUTSCENE_TWO_ITEMS[] = {
|
static const cutsceneitem_t TEST_CUTSCENE_TWO_ITEMS[] = {
|
||||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 1.0f },
|
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 1.0f },
|
||||||
// { .type = CUTSCENE_ITEM_TYPE_CUTSCENE, .cutscene = &TEST_CUTSCENE_ONE },
|
{ .type = CUTSCENE_ITEM_TYPE_CUTSCENE, .cutscene = &TEST_CUTSCENE_ONE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const cutscene_t TEST_CUTSCENE = {
|
static const cutscene_t TEST_CUTSCENE = {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
|
||||||
#include "rpg/cutscene/scene/testcutscene.h"
|
#include "rpg/cutscene/scene/testcutscene.h"
|
||||||
|
#include "rpg/rpgtextbox.h"
|
||||||
|
|
||||||
void npcInit(entity_t *entity) {
|
void npcInit(entity_t *entity) {
|
||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
@@ -24,5 +25,7 @@ bool_t npcInteract(entity_t *player, entity_t *npc) {
|
|||||||
|
|
||||||
cutsceneSystemStartCutscene(&TEST_CUTSCENE);
|
cutsceneSystemStartCutscene(&TEST_CUTSCENE);
|
||||||
|
|
||||||
|
// rpgTextboxShow(RPG_TEXTBOX_POS_BOTTOM, "Hello World!");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "rpg/cutscene/cutscenesystem.h"
|
#include "rpg/cutscene/cutscenesystem.h"
|
||||||
#include "time/time.h"
|
#include "time/time.h"
|
||||||
#include "rpgcamera.h"
|
#include "rpgcamera.h"
|
||||||
|
#include "rpgtextbox.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
|
||||||
errorret_t rpgInit(void) {
|
errorret_t rpgInit(void) {
|
||||||
@@ -22,8 +23,8 @@ errorret_t rpgInit(void) {
|
|||||||
// Init the world.
|
// Init the world.
|
||||||
worldInit();
|
worldInit();
|
||||||
|
|
||||||
// Initialize the camera
|
|
||||||
rpgCameraInit();
|
rpgCameraInit();
|
||||||
|
rpgTextboxInit();
|
||||||
|
|
||||||
// TEST: Create some entities.
|
// TEST: Create some entities.
|
||||||
entity_t *ent;
|
entity_t *ent;
|
||||||
|
|||||||
39
src/rpg/rpgtextbox.c
Normal file
39
src/rpg/rpgtextbox.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rpgtextbox.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
rpgtextbox_t RPG_TEXTBOX;
|
||||||
|
|
||||||
|
void rpgTextboxInit() {
|
||||||
|
memoryZero(&RPG_TEXTBOX, sizeof(rpgtextbox_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpgTextboxShow(
|
||||||
|
const rpgtextboxpos_t position,
|
||||||
|
const char_t *text
|
||||||
|
) {
|
||||||
|
RPG_TEXTBOX.position = position;
|
||||||
|
RPG_TEXTBOX.visible = true;
|
||||||
|
|
||||||
|
stringCopy(
|
||||||
|
RPG_TEXTBOX.text,
|
||||||
|
text,
|
||||||
|
RPG_TEXTBOX_MAX_CHARS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpgTextboxHide() {
|
||||||
|
RPG_TEXTBOX.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t rpgTextboxIsVisible() {
|
||||||
|
return RPG_TEXTBOX.visible;
|
||||||
|
}
|
||||||
52
src/rpg/rpgtextbox.h
Normal file
52
src/rpg/rpgtextbox.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
#define RPG_TEXTBOX_MAX_CHARS 256
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RPG_TEXTBOX_POS_TOP,
|
||||||
|
RPG_TEXTBOX_POS_BOTTOM,
|
||||||
|
} rpgtextboxpos_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rpgtextboxpos_t position;
|
||||||
|
bool_t visible;
|
||||||
|
char_t text[RPG_TEXTBOX_MAX_CHARS];
|
||||||
|
} rpgtextbox_t;
|
||||||
|
|
||||||
|
extern rpgtextbox_t RPG_TEXTBOX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the RPG textbox.
|
||||||
|
*/
|
||||||
|
void rpgTextboxInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the RPG textbox at a specified position.
|
||||||
|
*
|
||||||
|
* @param position The position to show the textbox at.
|
||||||
|
* @param text The text to display in the textbox (copied).
|
||||||
|
*/
|
||||||
|
void rpgTextboxShow(
|
||||||
|
const rpgtextboxpos_t position,
|
||||||
|
const char_t *text
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the RPG textbox.
|
||||||
|
*/
|
||||||
|
void rpgTextboxHide();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the RPG textbox is currently visible.
|
||||||
|
*
|
||||||
|
* @return true if the textbox is visible, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t rpgTextboxIsVisible();
|
||||||
@@ -10,4 +10,5 @@ target_sources(${DUSK_TARGET_NAME}
|
|||||||
uitext.c
|
uitext.c
|
||||||
uifps.c
|
uifps.c
|
||||||
uiframe.c
|
uiframe.c
|
||||||
|
uitextbox.c
|
||||||
)
|
)
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "display/tileset/tileset_minogram.h"
|
#include "display/tileset/tileset_minogram.h"
|
||||||
#include "display/screen.h"
|
#include "display/screen.h"
|
||||||
|
#include "ui/uitextbox.h"
|
||||||
|
|
||||||
ui_t UI;
|
ui_t UI;
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ void uiUpdate(void) {
|
|||||||
UI.camera.orthographic.right = SCREEN.width;
|
UI.camera.orthographic.right = SCREEN.width;
|
||||||
UI.camera.orthographic.top = 0;
|
UI.camera.orthographic.top = 0;
|
||||||
UI.camera.orthographic.bottom = SCREEN.height;
|
UI.camera.orthographic.bottom = SCREEN.height;
|
||||||
|
|
||||||
|
uiTextboxUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiRender(void) {
|
void uiRender(void) {
|
||||||
@@ -39,6 +42,7 @@ void uiRender(void) {
|
|||||||
// Render UI elements here
|
// Render UI elements here
|
||||||
if(UI.fontTexture.width > 0) {
|
if(UI.fontTexture.width > 0) {
|
||||||
uiFPSRender(UI.fontTileset, &UI.fontTexture);
|
uiFPSRender(UI.fontTileset, &UI.fontTexture);
|
||||||
|
uiTextboxRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraPopMatrix();
|
cameraPopMatrix();
|
||||||
|
|||||||
45
src/ui/uitextbox.c
Normal file
45
src/ui/uitextbox.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uitextbox.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
#include "ui/uitext.h"
|
||||||
|
#include "rpg/rpgtextbox.h"
|
||||||
|
#include "display/screen.h"
|
||||||
|
#include "display/spritebatch.h"
|
||||||
|
#include "input/input.h"
|
||||||
|
|
||||||
|
void uiTextboxUpdate() {
|
||||||
|
if(!rpgTextboxIsVisible()) return;
|
||||||
|
|
||||||
|
if(inputPressed(INPUT_ACTION_ACCEPT)) {
|
||||||
|
rpgTextboxHide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTextboxRender() {
|
||||||
|
if(!rpgTextboxIsVisible()) return;
|
||||||
|
|
||||||
|
const char_t *text = RPG_TEXTBOX.text;
|
||||||
|
int32_t textWidth, textHeight;
|
||||||
|
|
||||||
|
uiTextMeasure(text, UI.fontTileset, &textWidth, &textHeight);
|
||||||
|
|
||||||
|
float_t y = 0;
|
||||||
|
if(RPG_TEXTBOX.position == RPG_TEXTBOX_POS_BOTTOM) {
|
||||||
|
y = SCREEN.height - (float_t)textHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteBatchPush(
|
||||||
|
NULL,
|
||||||
|
0.0f, y,
|
||||||
|
(float_t)SCREEN.width, (float_t)(y + textHeight),
|
||||||
|
COLOR_BLACK,
|
||||||
|
0.0f, 0.0f, 1.0f, 1.0f
|
||||||
|
);
|
||||||
|
uiTextDraw(0, y, text, COLOR_RED, UI.fontTileset, &UI.fontTexture);
|
||||||
|
}
|
||||||
19
src/ui/uitextbox.h
Normal file
19
src/ui/uitextbox.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the RPG textbox state.
|
||||||
|
*/
|
||||||
|
void uiTextboxUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the RPG textbox if it is visible.
|
||||||
|
*/
|
||||||
|
void uiTextboxRender();
|
||||||
Reference in New Issue
Block a user