Scene change support

This commit is contained in:
2023-06-30 07:33:22 -07:00
parent 282d999603
commit 29048234a7
32 changed files with 236 additions and 135 deletions

View File

@ -4,4 +4,5 @@
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
tool_prefab(${CMAKE_CURRENT_LIST_DIR}/EthPrefab.xml) tool_prefab(${CMAKE_CURRENT_LIST_DIR}/EthPrefab.xml)
tool_prefab(${CMAKE_CURRENT_LIST_DIR}/VNTextbox.xml) tool_prefab(${CMAKE_CURRENT_LIST_DIR}/VNTextbox.xml)
tool_prefab(${CMAKE_CURRENT_LIST_DIR}/VNTextboxMonologue.xml)

View File

@ -3,7 +3,6 @@
<asset type="texture" name="texture_border" /> <asset type="texture" name="texture_border" />
<UIBorder <UIBorder
ref="border"
borderSize="16, 16" borderSize="16, 16"
alignment="50, 0, 0, 0" alignment="50, 0, 0, 0"
alignUnitLeft="UI_COMPONENT_ALIGN_UNIT_PERCENT" alignUnitLeft="UI_COMPONENT_ALIGN_UNIT_PERCENT"

View File

@ -0,0 +1,28 @@
<prefab name="VNTextboxMonologue" type="">
<asset type="truetype" name="font_main" />
<UIEmpty
ref="container"
alignment="20, 20, 20, 20"
alignUnitTop="UI_COMPONENT_ALIGN_UNIT_PERCENT"
alignUnitBottom="UI_COMPONENT_ALIGN_UNIT_PERCENT"
alignUnitLeft="UI_COMPONENT_ALIGN_UNIT_PERCENT"
alignUnitRight="UI_COMPONENT_ALIGN_UNIT_PERCENT"
alignX="UI_COMPONENT_ALIGN_STRETCH"
alignY="UI_COMPONENT_ALIGN_STRETCH"
/>
<child>
<UIRichTextLabel
alignment="0, 0, 65, 192"
alignUnitLeft="UI_COMPONENT_ALIGN_UNIT_PERCENT"
alignUnitRight="UI_COMPONENT_ALIGN_UNIT_PERCENT"
alignX="UI_COMPONENT_ALIGN_MIDDLE"
alignY="UI_COMPONENT_ALIGN_MIDDLE"
ref="uiLabel"
>
</UIRichTextLabel>
</child>
<VNTextboxScroller ref="textboxScroller" label="uiLabel" visibleLines="6" />
</prefab>

View File

@ -3,5 +3,7 @@
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
tool_scene(${CMAKE_CURRENT_LIST_DIR}/SceneBase.xml) tool_scene(${CMAKE_CURRENT_LIST_DIR}/SceneStandard.xml)
tool_vnscene(${CMAKE_CURRENT_LIST_DIR}/Scene1Prologue0.xml) tool_scene(${CMAKE_CURRENT_LIST_DIR}/SceneMonologue.xml)
tool_vnscene(${CMAKE_CURRENT_LIST_DIR}/Scene1Prologue0.xml)
tool_vnscene(${CMAKE_CURRENT_LIST_DIR}/Scene1Prologue1.xml)

View File

@ -1,48 +1,37 @@
<vnscene name="Scene1Prologue" extend="scenes/SceneBase"> <vnscene name="Scene1Prologue0" extend="scenes/SceneMonologue">
<asset type="texture" name="texture_eth_face_day_anger" ref="faceDayAnger" />
<asset type="texture" name="texture_eth_face_day_confused" ref="faceDayConfused" />
<asset type="texture" name="texture_eth_pose_day_back" ref="poseDayBack" />
<asset type="texture" name="texture_eth_pose_day_cross" ref="poseDayCross" />
<events> <events>
<set property="eth->faceMaterial->texture" to="&faceDayConfused->texture" type="Texture*" />
<set property="eth->bodyMaterial->texture" to="&poseDayBack->texture" type="Texture*" />
<text> <text>
<string lang="en"><font style="italics">Confused to Angry</font></string> <string lang="en"><font style="italics">There is a bucket.</font></string>
</text> </text>
<set property="eth->faceMaterial->texture" to="&faceDayAnger->texture" type="Texture*" /> <!-- <text>
<string lang="en"><font style="italics">It sways above your head like the mouth of a god. You are on Angelwood's best stage, and they are cheering for you, calling you their Queen, their Prom Queen.</font></string>
<text>
<string lang="en">Angry to Cross</string>
</text>
<set property="eth->bodyMaterial->texture" to="&poseDayCross->texture" type="Texture*" />
<text>
<string lang="en">And you are dead soon.</string>
</text> </text>
<text> <text>
<string lang="en">It's Prom Day. The metal bucket is swaying. Over you. Drenching your white pristine dress in guts and gore red. They aren't cheering anymore. They're gasping. But not screaming: oh, no, not in respectable Angelwood.</string> <string lang="en"><font style="italics">And you are dead soon.</font></string>
</text> </text>
<text> <text>
<string lang="en">God. You didn't think a pig's intestines could feel so cold.</string> <string lang="en"><font style="italics">It's Prom Day. The metal bucket is swaying. Over you. Drenching your white pristine dress in guts and gore red. They aren't cheering anymore. They're gasping. But not screaming: oh, no, not in respectable Angelwood.</font></string>
</text> </text>
<text> <text>
<string lang="en">You are dead when the bucket falls - crushes your skull - caves you open - drenches you and drenches you, drowns you, fells you and kills, kills, kills you.</string> <string lang="en"><font style="italics">God. You didn't think a pig's intestines could feel so cold.</font></string>
</text> </text>
<text> <text>
<string lang="en">And the last thing you see ---</string> <string lang="en"><font style="italics">You are dead when the bucket falls - crushes your skull - caves you open - drenches you and drenches you, drowns you, fells you and kills, kills, kills you.</font></string>
</text> </text>
<text> <text>
<string lang="en">Is their eyes.</string> <string lang="en"><font style="italics">And the last thing you see -</font></string>
</text> </text>
<text>
<string lang="en"><font style="italics">Is their eyes.</font></string>
</text> -->
<scene-change scene="vnscenes/Scene1Prologue1" />
</events> </events>
</vnscene> </vnscene>

View File

@ -1,90 +1,9 @@
<vnscene name="Scene1Prologue" extend="scenes/SceneBase"> <vnscene name="Scene1Prologue1" extend="scenes/SceneStandard">
<events> <events>
<text> <text>
<string lang="en">I wake.</string> <string lang="en"><font style="italics">whoa</font></string>
</text>
<text>
<string lang="en">I gasp. I close my eyes - Im fine, Im fine. I'm still here. Breathing.</string>
</text>
<text>
<string lang="en">That bucket was a dream. My death was a dream. Im not dead.</string>
</text>
<text>
<string lang="en">(Am I?)</string>
</text>
<text>
<string lang="en">(...)</string>
</text> </text>
<text> <scene-change scene="vnscenes/Scene1Prologue1" />
<string lang="en">(Aren't I?)</string>
</text>
<text>
<string lang="en">Of course Im not.</string>
</text>
<text>
<string lang="en">I exhale. My feet fall to the edges of my bed. Slowly, I raise myself to stand.</string>
</text>
<text>
<string lang="en">My fingers tremble by the edges of my leg: I curl my hand in. My nails catch on my skin. Theyre sharp, pastel pink. Done for Prom Day today.</string>
</text>
<text>
<string lang="en">The dream didnt happen. How could it have? Prom Day hasnt happened yet. </string>
</text>
<text>
<string lang="en">I'm fine.</string>
</text>
<text>
<string lang="en">(Didnt it happen?)</string>
</text>
<text>
<string lang="en">(It felt so…)</string>
</text>
<text>
<string lang="en">(Real.)</string>
</text>
<text>
<string lang="en">I tidy the bedsheets. Pull the corners over the beds edges, fluff up the pillows, pat away the sweat and the residue of a scream: my parents want it pretty.</string>
</text>
<text>
<string lang="en">It wasnt real. I only had a visceral dream, sunken into my brain as an anchor to a sea, as a stone angels crumbling visage, as a birds descent off Devil Cradles cliffs. That wasnt real.</string>
</text>
<text>
<string lang="en">No, of course not. </string>
</text>
<text>
<string lang="en">My calendar says May 29th. Ive got to prepare for Prom.</string>
</text>
<text>
<string lang="en">After all, if there is anything I will be, it is Prom Queen.</string>
</text>
<text>
<string lang="en">Ive been chasing this moment since the beginning of time. Today is the finale. </string>
</text>
<text>
<string lang="en">And I am nothing if not ready. </string>
</text>
</events> </events>
</vnscene> </vnscene>

View File

@ -0,0 +1,20 @@
<scene name="SceneMonologue">
<item position="0, 0, -10">
<MeshRenderer />
<QuadMeshHost xy0="-500000, -500000" xy1="500000, 500000" />
<SimpleTexturedMaterial color="COLOR_BLACK" />
</item>
<item lookAt="0, 0.65, 1.8, 0, .65, 0">
<Camera ref="camera" fov="0.610865" />
</item>
<item>
<UICanvas ref="canvas" camera="camera" />
<item ref="textbox" prefab="prefabs/VNTextboxMonologue" />
</item>
<item ref="vnItem">
<VNManager ref="vnManager" />
</item>
</scene>

View File

@ -1,4 +1,4 @@
<scene name="SceneBase"> <scene name="SceneStandard">
<item lookAt="9999, 9999, 9999, 9999, 9999, 0"> <item lookAt="9999, 9999, 9999, 9999, 9999, 0">
<Camera ref="backCamera" /> <Camera ref="backCamera" />
</item> </item>

Submodule lib/SDL updated: 87a83787a3...c065a9b128

Submodule lib/glm updated: efec5db081...5c46b9c070

View File

@ -14,7 +14,7 @@ namespace Dawn {
AssetManager *assetManager; AssetManager *assetManager;
std::string name; std::string name;
uint8_t state = 0x00; uint8_t state = 0x00;
bool loaded = false; bool_t loaded = false;
Event<> eventLoaded; Event<> eventLoaded;
StateEvent<> event2Loaded; StateEvent<> event2Loaded;

View File

@ -95,11 +95,11 @@ namespace Dawn {
* @return The count of bytes read. * @return The count of bytes read.
*/ */
template<class T> template<class T>
size_t loadBufferedCallback(T *instance, bool (T::*callback)(uint8_t n)) { size_t loadBufferedCallback(T *instance, bool_t (T::*callback)(uint8_t n)) {
uint8_t buffer[1024]; uint8_t buffer[1024];
size_t read, length; size_t read, length;
int32_t i; int32_t i;
bool result; bool_t result;
assertNotNull(instance); assertNotNull(instance);
assertNotNull(callback); assertNotNull(callback);

View File

@ -147,7 +147,7 @@ void Transform::setWorldTransform(glm::mat4 transform) {
void Transform::setParent(Transform *parent) { void Transform::setParent(Transform *parent) {
assertTrue(parent != this); assertTrue(parent == nullptr || parent != this);
auto currentParent = this->getParent(); auto currentParent = this->getParent();
if(currentParent == parent) return; if(currentParent == parent) return;
@ -190,6 +190,6 @@ Transform::~Transform() {
auto it = this->children.begin(); auto it = this->children.begin();
while(it != this->children.end()) { while(it != this->children.end()) {
(*it)->setParent(nullptr); (*it)->setParent(nullptr);
++it; it = this->children.begin();
} }
} }

View File

@ -32,6 +32,8 @@ TrueTypeFaceTexture::TrueTypeFaceTexture(
assertUnreachable(); assertUnreachable();
} }
if(face->glyph->bitmap.width == 0 || face->glyph->bitmap.rows == 0) continue;
// Update the width and height // Update the width and height
w = mathMax<size_t>(w, face->glyph->bitmap.width); w = mathMax<size_t>(w, face->glyph->bitmap.width);
h += face->glyph->bitmap.rows; h += face->glyph->bitmap.rows;

View File

@ -33,6 +33,13 @@ int32_t DawnGame::update(float_t delta) {
this->renderManager.update(); this->renderManager.update();
if(this->sceneToCutTo != nullptr) {
delete this->scene;
this->scene = nullptr;
this->scene = this->sceneToCutTo;
this->sceneToCutTo = nullptr;
}
return DAWN_GAME_UPDATE_RESULT_SUCCESS; return DAWN_GAME_UPDATE_RESULT_SUCCESS;
} }

View File

@ -0,0 +1,25 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "VNEvent.hpp"
#include "scene/Scene.hpp"
namespace Dawn {
template<class T>
class VNSceneChangeEvent : public VNEvent {
protected:
void onStart() override {
auto game = this->manager->getGame();
T *nextScene = new T(this->manager->getGame());
auto assets = nextScene->getRequiredAssets();
game->assetManager.queueLoad(assets);
game->assetManager.syncLoad();
nextScene->stage();
game->sceneCutover(nextScene);
}
};
}

View File

@ -10,6 +10,7 @@ target_sources(${DAWN_TARGET_NAME}
UIComponent.cpp UIComponent.cpp
UIComponentRenderable.cpp UIComponentRenderable.cpp
UIImage.cpp UIImage.cpp
UIEmpty.cpp
UIBorder.cpp UIBorder.cpp
) )

View File

@ -0,0 +1,15 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIEmpty.hpp"
using namespace Dawn;
UIEmpty::UIEmpty(SceneItem *item) : UIComponent(item) { }
float_t UIEmpty::getContentWidth() { return 0.0f; }
float_t UIEmpty::getContentHeight() { return 0.0f; }
float_t UIEmpty::getChildOffsetX() { return 0.0f; }
float_t UIEmpty::getChildOffsetY() { return 0.0f; }

View File

@ -0,0 +1,18 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
namespace Dawn {
class UIEmpty : public UIComponent {
public:
UIEmpty(SceneItem *item);
float_t getContentWidth() override;
float_t getContentHeight() override;
float_t getChildOffsetX() override;
float_t getChildOffsetY() override;
};
}

View File

@ -211,7 +211,9 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
// Now, iterate each character // Now, iterate each character
for(int32_t i = 0; i < len; i++) { for(int32_t i = 0; i < len; i++) {
char ch = text.text[i]; std::u32string::value_type ch = text.text[i];
// FT_ULong ch = text.text[i];
char c = text.text[i];
// Handle special characters // Handle special characters
if(ch == '\n') { if(ch == '\n') {
@ -228,8 +230,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
assertTrue(ch != '\n'); assertTrue(ch != '\n');
// Get font data. // Get font data.
FT_ULong c = ch; auto charInfo = realText.texture->getCharacterData(ch);
auto charInfo = realText.texture->getCharacterData(c);
// Word wrapping // Word wrapping
if( if(

View File

@ -4,12 +4,12 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
#include "vnscenes/Scene1Prologue.hpp" #include "vnscenes/Scene1Prologue0.hpp"
#include "scenes/HelloWorldScene.hpp" #include "scenes/HelloWorldScene.hpp"
using namespace Dawn; using namespace Dawn;
Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) { Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) {
// return new HelloWorldScene(game); // return new HelloWorldScene(game);
return new Scene1Prologue(game); return new Scene1Prologue0(game);
} }

View File

@ -6,8 +6,8 @@
#pragma once #pragma once
#include "util/flag.hpp" #include "util/flag.hpp"
#define TRUE_TYPE_CHAR_BEGIN 32 #define TRUE_TYPE_CHAR_BEGIN 0x00
#define TRUE_TYPE_CHAR_END 192 #define TRUE_TYPE_CHAR_END 0xFF
#define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0) #define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0)
#define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1) #define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1)

View File

@ -21,8 +21,8 @@ void File::mkdirp(std::string path) {
std::string buffer; std::string buffer;
char c; char c;
size_t i = 0; size_t i = 0;
bool inFile; bool_t inFile;
bool hasMore; bool_t hasMore;
inFile = false; inFile = false;
hasMore = false; hasMore = false;

View File

@ -135,6 +135,12 @@ void VNSceneGen::test(
break; break;
} }
case VN_SCENE_EVENT_TYPE_SCENE_CHANGE:
initType = "VNSceneChangeEvent<" + event->sceneChange.scene + ">";
toInclude = "games/vn/events/VNSceneChangeEvent.hpp";
includes->push_back(event->sceneChange.include);
break;
default: default:
std::cout << "Unknown event type: " << event->type << std::endl; std::cout << "Unknown event type: " << event->type << std::endl;
assertUnreachable(); assertUnreachable();

View File

@ -17,4 +17,5 @@ target_sources(vnscenetool
VNChoiceEventParser.cpp VNChoiceEventParser.cpp
VNChoiceSetEventParser.cpp VNChoiceSetEventParser.cpp
VNIfEventParser.cpp VNIfEventParser.cpp
VNSceneChangeEventParser.cpp
) )

View File

@ -0,0 +1,33 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "VNSceneChangeEventParser.hpp"
using namespace Dawn;
std::vector<std::string> VNSceneChangeEventParser::getRequiredAttributes() {
return { "scene" };
}
std::map<std::string, std::string> VNSceneChangeEventParser::getOptionalAttributes() {
return {};
}
int32_t VNSceneChangeEventParser::onParse(
Xml *node,
std::map<std::string, std::string> values,
struct VNSceneChangeEvent *out,
std::string *error
) {
out->include = values["scene"] + ".hpp";
// Find last slash and take all string after that
size_t lastSlash = values["scene"].find_last_of('/');
if(lastSlash != std::string::npos) {
out->scene = values["scene"].substr(lastSlash+1);
}
return 0;
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "util/XmlParser.hpp"
namespace Dawn {
struct VNSceneChangeEvent {
std::string scene;
std::string include;
};
class VNSceneChangeEventParser : public XmlParser<struct VNSceneChangeEvent> {
protected:
std::vector<std::string> getRequiredAttributes() override;
std::map<std::string, std::string> getOptionalAttributes() override;
int32_t onParse(
Xml *node,
std::map<std::string, std::string> values,
struct VNSceneChangeEvent *out,
std::string *error
) override;
};
}

View File

@ -80,6 +80,11 @@ int32_t VNSceneEventsParser::onParse(
ret = (VNIfEventParser()).parse(child, &event.ifEvent, error); ret = (VNIfEventParser()).parse(child, &event.ifEvent, error);
if(ret != 0) return ret; if(ret != 0) return ret;
} else if(child->node == "scene-change") {
event.type = VN_SCENE_EVENT_TYPE_SCENE_CHANGE;
ret = (VNSceneChangeEventParser()).parse(child, &event.sceneChange, error);
if(ret != 0) return ret;
} else { } else {
*error = "Unknown child node '" + child->node + "'"; *error = "Unknown child node '" + child->node + "'";
return -1; return -1;

View File

@ -14,6 +14,7 @@
#include "VNChoiceEventParser.hpp" #include "VNChoiceEventParser.hpp"
#include "VNChoiceSetEventParser.hpp" #include "VNChoiceSetEventParser.hpp"
#include "VNIfEventParser.hpp" #include "VNIfEventParser.hpp"
#include "VNSceneChangeEventParser.hpp"
namespace Dawn { namespace Dawn {
struct VNSceneEvent; struct VNSceneEvent;
@ -32,7 +33,8 @@ namespace Dawn {
VN_SCENE_EVENT_TYPE_GOTO_MARKER, VN_SCENE_EVENT_TYPE_GOTO_MARKER,
VN_SCENE_EVENT_TYPE_CHOICES, VN_SCENE_EVENT_TYPE_CHOICES,
VN_SCENE_EVENT_TYPE_CHOICE_SET, VN_SCENE_EVENT_TYPE_CHOICE_SET,
VN_SCENE_EVENT_TYPE_IF VN_SCENE_EVENT_TYPE_IF,
VN_SCENE_EVENT_TYPE_SCENE_CHANGE
}; };
struct VNParallelEvent { struct VNParallelEvent {
@ -58,6 +60,7 @@ namespace Dawn {
struct VNChoiceEvent choices; struct VNChoiceEvent choices;
struct VNChoiceSetEvent choiceSet; struct VNChoiceSetEvent choiceSet;
struct VNIfEvent ifEvent; struct VNIfEvent ifEvent;
struct VNSceneChangeEvent sceneChange;
}; };
class VNSceneEventsParser : public XmlParser<struct VNSceneEventList> { class VNSceneEventsParser : public XmlParser<struct VNSceneEventList> {