looking like a real one

This commit is contained in:
lachrymaL 2022-08-22 02:15:25 -04:00
parent 646d24b47c
commit b0b73bb47e
No known key found for this signature in database
GPG key ID: F3640ACFA174B1C1
16 changed files with 8233 additions and 209 deletions

View file

@ -1,5 +0,0 @@
{
"files.associations": {
"xstring": "cpp"
}
}

View file

@ -5,6 +5,7 @@
#include <bgfx/bgfx.h>
#include <bgfx/platform.h>
#include <chrono>
#include <iostream>
namespace {
@ -23,10 +24,17 @@ namespace {
std::vector<NVL::Environment::Variable> m_text{};
NVL::String speaker;
u32 scene_pos = 0;
char* date;
}
namespace ADVect {
void Init(std::string name, const std::vector<NVL::Parse::Scene>& sc) {
std::time_t now_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
date = std::ctime(&now_time);
date[10] = '\0';
date = &date[4];
m_name = name;
scenes = sc; // sure make a copy whatever
@ -37,7 +45,7 @@ namespace ADVect {
window = SDL_CreateWindow(m_name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_width, m_height, SDL_WINDOW_SHOWN);
if (window == NULL) {
std::cerr << "Failed to create window: " << SDL_GetError() << std::endl;
std::cerr << "ADV: Failed to create window: " << SDL_GetError() << std::endl;
return;
}
bgfx::Init bgfxInit;
@ -50,7 +58,7 @@ namespace ADVect {
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
if (!SDL_GetWindowWMInfo(window, &wmi)) {
std::cerr << "SDL_SysWMinfo could not be retrieved: " << SDL_GetError() << std::endl;
std::cerr << "ADV: SDL_SysWMinfo could not be retrieved: " << SDL_GetError() << std::endl;
}
#endif
#if BX_PLATFORM_WINDOWS
@ -65,22 +73,22 @@ namespace ADVect {
#endif
if (!bgfx::init(bgfxInit)) {
std::cerr << "Failed bgfx initialization" << std::endl;
std::cerr << "ADV: Failed bgfx initialization" << std::endl;
return;
};
bgfx::setDebug(BGFX_DEBUG_TEXT | BGFX_DEBUG_STATS);
bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x443355ff, 1.0f, 0);
bgfx::setDebug(BGFX_DEBUG_TEXT);
bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x443322ff, 1.0f, 0);
bgfx::setViewRect(0, 0, 0, m_width, m_height);
bgfx::setViewMode(0, bgfx::ViewMode::Sequential);
ADVect::Graphics::Init(m_width, m_height);
NVL::Environment::ENVIRONMENT.enter(L"Say", NVL::Environment::Variable([&](std::vector<NVL::Environment::Variable> args) {
NVL::Environment::ENVIRONMENT.enter(u"Say", NVL::Environment::Variable([&](std::vector<NVL::Environment::Variable> args) {
m_text = args;
return NVL::Environment::Type::Nil;
}, 2));
NVL::Environment::ENVIRONMENT.enter(L"SwitchSpeaker", NVL::Environment::Variable([&](std::vector<NVL::Environment::Variable> args) {
NVL::Environment::ENVIRONMENT.enter(u"SwitchSpeaker", NVL::Environment::Variable([&](std::vector<NVL::Environment::Variable> args) {
speaker = std::get<NVL::String>(NVL::Environment::Variable(args[0]).value);
return NVL::Environment::Type::Nil;
}, 1));
@ -97,7 +105,7 @@ namespace ADVect {
void Advance() {
size_t curr_size = scenes[current_scene].get().size();
while (scene_pos < curr_size) {
if (std::get<NVL::String>(scenes[current_scene].get()[scene_pos][0].value) == L"Say") {
if (std::get<NVL::String>(scenes[current_scene].get()[scene_pos][0].value) == u"Say") {
NVL::Environment::Apply(scenes[current_scene].get()[scene_pos]);
scene_pos++;
return;
@ -113,7 +121,7 @@ namespace ADVect {
case 1:
return;
default:
if (std::get<NVL::String>(scenes[current_scene].get()[scene_pos + 1][0].value) == L"Say") {
if (std::get<NVL::String>(scenes[current_scene].get()[scene_pos + 1][0].value) == u"Say") {
NVL::Environment::Apply(scenes[current_scene].get()[scene_pos]);
scene_pos++;
return;
@ -137,10 +145,15 @@ namespace ADVect {
void Render() {
bgfx::touch(0);
ADVect::Graphics::RenderString(speaker, 50, 630, 0xFFFFFFFF);
ADVect::Graphics::RenderStringMarkup(m_text, 50, 580, 0xFFFFFFFF);
ADVect::Graphics::DrawRandomShit();
ADVect::Graphics::RenderString(speaker, 100, 150, 0xFFFFFFFF, ADVect::Graphics::TEXT_BOLD);
ADVect::Graphics::RenderStringMarkup(m_text, 300, 90, 0xFFFFFFFF);
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 44, 0xF0, "NouVeL x ADVect :: %s 2022", date);
bgfx::dbgTextPrintf(0, 43, 0xF0, "Current Position: %u", scene_pos);
bgfx::dbgTextPrintf(0, 42, 0xF0, "Current Scene: %s", NVL::to_std_string(scenes[current_scene].name).c_str());
bgfx::frame();
@ -173,7 +186,7 @@ int main(int argc, char* argv[]) {
const std::string PJ_DIR = "..\\..\\..\\..\\NVL\\";
std::vector<NVL::Parse::Scene> SCENES = NVL::Parse::ParseFile(PJ_DIR + "dialogue.nvl");
ADVect::Init("Test", SCENES);
ADVect::Init("ADV", SCENES);
ADVect::Run();
ADVect::Shutdown();

View file

@ -5,17 +5,15 @@ namespace ADVect {
auto f = [](NVL::Environment::Variable x) {
return NVL::Environment::Variable(NVL::Environment::Type::Nil);
};
NVL::Environment::ENVIRONMENT.enter(L"Hello", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(L"Command", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(L"Do", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(L"Set", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(L"This", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(L"ClearDialog", { f, 0 });
NVL::Environment::ENVIRONMENT.enter(L"Choice", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(L"=?", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(L"+", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(L"switch", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(L"SwitchSpeaker", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(L"Say", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(u"Hello", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(u"Command", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(u"Do", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(u"Set", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(u"This", { f, 1 });
NVL::Environment::ENVIRONMENT.enter(u"ClearDialog", { f, 0 });
NVL::Environment::ENVIRONMENT.enter(u"Choice", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(u"=?", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(u"+", { f, 2 });
NVL::Environment::ENVIRONMENT.enter(u"switch", { f, 2 });
}
}

View file

@ -2,26 +2,26 @@
#include FT_FREETYPE_H
#include "Graphics.h"
#include <bgfx/bgfx.h>
#include <bx/math.h>
#include <iostream>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
namespace {
FT_Library library;
FT_Error error;
FT_Face face;
FT_Face face_regular, face_bold;
struct PosUVVertex
static struct PosUVVertex
{
f32 x;
f32 y;
f32 z;
f32 u;
f32 v;
};
static PosUVVertex quad_vert[] =
} quad_vert[] =
{
{ 0.f, 0.f, 0.0f, 0.0f, 0.0f },
{ 0.f, 1.f, 0.0f, 0.0f, 1.0f },
@ -67,38 +67,45 @@ namespace {
return bgfx::createShader(mem);
}
bgfx::ShaderHandle vsh;
bgfx::ShaderHandle fsh;
bgfx::ProgramHandle program;
bgfx::ShaderHandle a_vsh, img_vsh;
bgfx::ShaderHandle a_fsh, img_fsh;
bgfx::ProgramHandle a_program, img_program;
bgfx::IndexBufferHandle ibh;
bgfx::VertexBufferHandle vbh;
bgfx::UniformHandle s_texColor;
bgfx::VertexLayout pcvDecl;
std::unordered_map<wchar_t, bgfx::TextureHandle> cache{};
std::unordered_map<NVL::Char, bgfx::TextureHandle> cache_regular {};
std::unordered_map<NVL::Char, bgfx::TextureHandle> cache_bold {};
int w, h, channels;
u8* img;
bgfx::TextureHandle tx;
}
namespace ADVect::Graphics {
i16 Init(u16 width, u16 height) {
error = FT_Init_FreeType(&library);
if (error) {
std::cerr << "FreeType init error: " << error << std::endl;
std::cerr << "ADV: FreeType init error: " << error << std::endl;
return -1;
}
error = FT_New_Face(library, "SourceHanSerif-Heavy.ttc", 0, &face);
error = FT_New_Face(library, "SourceHanSans-Regular.ttc", 0, &face_regular);
error = FT_New_Face(library, "SourceHanSans-Bold.ttc", 0, &face_bold);
if (error == FT_Err_Unknown_File_Format) {
std::cerr << "FreeType Unknown_File_Format: " << error << std::endl;
std::cerr << "ADV: FreeType Unknown_File_Format: " << error << std::endl;
return -1;
}
else if (error) {
std::cerr << "FreeType font loading error: " << error << std::endl;
std::cerr << "ADV: FreeType font loading error: " << error << std::endl;
return -1;
}
error = FT_Set_Char_Size(face, 0, 20 * 64, 72, 72);
error = FT_Set_Char_Size(face_regular, 0, 20 * 64, 72, 72);
error = FT_Set_Char_Size(face_bold, 0, 20 * 64, 72, 72);
if (error == FT_Err_Unknown_File_Format) {
std::cerr << "FreeType Set_Char_Size error: " << error << std::endl;
std::cerr << "ADV: FreeType Set_Char_Size error: " << error << std::endl;
return -1;
}
@ -115,47 +122,122 @@ namespace ADVect::Graphics {
ibh = bgfx::createIndexBuffer(bgfx::makeRef(quad_indices, sizeof(quad_indices)));
vbh = bgfx::createVertexBuffer(bgfx::makeRef(quad_vert, sizeof(quad_vert)), pcvDecl);
vsh = loadShader("test.vert.bin");
fsh = loadShader("test.frag.bin");
program = bgfx::createProgram(vsh, fsh, true);
img_vsh = loadShader("test.vert.bin");
img_fsh = loadShader("test.frag.bin");
img_program = bgfx::createProgram(img_vsh, img_fsh, true);
a_vsh = loadShader("swizzle_aaaa.vert.bin");
a_fsh = loadShader("swizzle_aaaa.frag.bin");
a_program = bgfx::createProgram(a_vsh, a_fsh, true);
s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
img = stbi_load("image.png", &w, &h, &channels, 0);
if (img == NULL) {
std::cerr << "ADV: STB IMAGE loading failed" << std::endl;
return -1;
}
const bgfx::Memory* buf = bgfx::makeRef(img, w * h * channels * sizeof(u8));
tx = bgfx::createTexture2D(
w,
h,
false,
1,
bgfx::TextureFormat::RGBA8,
BGFX_TEXTURE_NONE | BGFX_SAMPLER_UVW_CLAMP,
buf
);
return 0;
}
void Shutdown() {
FT_Done_Face(face);
FT_Done_Face(face_regular);
FT_Done_Face(face_bold);
FT_Done_FreeType(library);
bgfx::destroy(vsh);
bgfx::destroy(fsh);
bgfx::destroy(program);
bgfx::destroy(a_vsh);
bgfx::destroy(a_fsh);
bgfx::destroy(img_vsh);
bgfx::destroy(img_fsh);
bgfx::destroy(a_program);
bgfx::destroy(img_program);
bgfx::destroy(ibh);
bgfx::destroy(vbh);
bgfx::destroy(s_texColor);
for (auto it = cache.begin(); it != cache.end(); it++) {
for (auto it = cache_regular .begin(); it != cache_regular.end(); it++) {
bgfx::destroy(it->second);
}
for (auto it = cache_bold.begin(); it != cache_bold.end(); it++) {
bgfx::destroy(it->second);
}
bgfx::destroy(tx);
}
void RenderString(const NVL::String& s, u32& pos_x, u32& pos_y, u32 col) {
FT_GlyphSlot slot = face->glyph;
// Draws quad with texture on Z = 0
void DrawTexture(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h) {
float mtx1[16], mtx2[16], mtx3[16];
bx::mtxTranslate(mtx1, pos_x, pos_y, 0.0f);
bx::mtxScale(mtx2, w, h, 1.0f);
bx::mtxMul(mtx3, mtx2, mtx1);
bgfx::setTransform(mtx3);
bgfx::setVertexBuffer(0, vbh);
bgfx::setIndexBuffer(ibh);
bgfx::setTexture(0, s_texColor, tex);
bgfx::setState(BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_NORMAL);
bgfx::submit(0, img_program);
}
void DrawTextureStencilAlpha(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h) {
float mtx1[16], mtx2[16], mtx3[16];
bx::mtxTranslate(mtx1, pos_x, pos_y, 0.0f);
bx::mtxScale(mtx2, w, h, 1.0f);
bx::mtxMul(mtx3, mtx2, mtx1);
bgfx::setTransform(mtx3);
bgfx::setVertexBuffer(0, vbh);
bgfx::setIndexBuffer(ibh);
bgfx::setTexture(0, s_texColor, tex);
bgfx::setState((BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) & ~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS));
bgfx::submit(0, a_program);
}
void RenderString(const NVL::String& s, u32& pos_x, u32& pos_y, u32 col, u32 style_flags) {
FT_Face active = face_regular;
std::unordered_map<NVL::Char, bgfx::TextureHandle>* cache = &cache_regular;
switch (style_flags) {
case TEXT_NONE: break;
case TEXT_BOLD: active = face_bold; cache = &cache_bold; break;
case TEXT_ITALIC: break;
case TEXT_ITALIC | TEXT_BOLD: break;
}
FT_GlyphSlot slot = active->glyph;
for (const auto& c : s) {
error = FT_Load_Char(face, c, FT_LOAD_RENDER);
error = FT_Load_Char(active, c, FT_LOAD_RENDER);
if (error) continue;
if (cache.find(c) == cache.end() && slot->bitmap.width != 0) {
if (cache->find(c) == cache->end() && slot->bitmap.width != 0) {
const bgfx::Memory* buf = bgfx::copy(slot->bitmap.buffer, slot->bitmap.pitch * slot->bitmap.rows);
cache.emplace(c, bgfx::createTexture2D(
cache->emplace(c, bgfx::createTexture2D(
slot->bitmap.width,
slot->bitmap.rows,
false,
1,
bgfx::TextureFormat::A8,
BGFX_TEXTURE_NONE | BGFX_SAMPLER_POINT | BGFX_SAMPLER_UVW_CLAMP,
BGFX_TEXTURE_NONE | BGFX_SAMPLER_UVW_CLAMP,
buf
));
}
@ -164,111 +246,70 @@ namespace ADVect::Graphics {
float ypos = pos_y - (slot->bitmap.rows - slot->bitmap_top);
if (slot->bitmap.width != 0) {
float mtx1[16], mtx2[16], mtx3[16];
bx::mtxTranslate(mtx1, (f32)pos_x, (f32)ypos, 0.0f);
bx::mtxScale(mtx2, slot->bitmap.width, slot->bitmap.rows, 1.0f);
bx::mtxMul(mtx3, mtx2, mtx1);
bgfx::setTransform(mtx3);
bgfx::setVertexBuffer(0, vbh);
bgfx::setIndexBuffer(ibh);
bgfx::setTexture(0, s_texColor, cache[c]);
bgfx::setState(BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ADD);
bgfx::submit(0, program);
DrawTextureStencilAlpha((*cache)[c], pos_x, ypos, slot->bitmap.width, slot->bitmap.rows);
}
pos_x += slot->advance.x >> 6;
pos_y += slot->advance.y >> 6;
}
}
void RenderString(const NVL::String& s, u32&& pos_x, u32&& pos_y, u32 col) {
void RenderString(const NVL::String& s, u32&& pos_x, u32&& pos_y, u32 col, u32 style_flags) {
u32 x = pos_x, y = pos_y;
RenderString(s, x, y, col);
}
// Check ParseMarkup for more information
struct Markup {
u32 begin, end;
std::vector<std::pair<NVL::String, std::vector<NVL::String>>> efs;
} UnpackMarkupVariable(const NVL::Environment::Variable& m) {
const auto& range = std::get<std::vector<NVL::Environment::Variable>>(std::get<std::vector<NVL::Environment::Variable>>(m.value)[0].value);
const u32 begin = std::get<NVL::Number>(range[0].value), end = std::get<NVL::Number>(range[1].value);
std::vector<std::pair<NVL::String, std::vector<NVL::String>>> efs;
for (const NVL::Environment::Variable& combination : std::get<std::vector<NVL::Environment::Variable>>(std::get<std::vector<NVL::Environment::Variable>>(m.value)[1].value)) {
if (combination.type == NVL::Environment::Type::String) {
const NVL::String ef = std::get<NVL::String>(combination.value);
efs.push_back({ ef, {} });
}
else if (combination.type == NVL::Environment::Type::Array) {
const std::vector<NVL::Environment::Variable>& ef_t = std::get<std::vector<NVL::Environment::Variable>>(combination.value);
const NVL::String& ef = std::get<NVL::String>(ef_t[0].value);
const std::vector<NVL::Environment::Variable>& args = std::get<std::vector<NVL::Environment::Variable>>(ef_t[1].value);
std::vector<NVL::String> ss{};
for (const auto& s : args) { ss.push_back(std::get<NVL::String>(s.value)); }
efs.push_back({ ef, ss });
}
}
return { begin, end, efs };
RenderString(s, x, y, col, style_flags);
}
void RenderStringMarkup(const std::vector<NVL::Environment::Variable>& s, u32 pos_x, u32 pos_y, u32 col) {
const NVL::String& str = std::get<NVL::String>(s[0].value);
std::vector<Markup> ms{};
std::vector<NVL::Environment::Markup> ms{};
for (const NVL::Environment::Variable& markup : std::get<std::vector<NVL::Environment::Variable>>(s[1].value)) {
ms.push_back(UnpackMarkupVariable(markup));
ms.push_back(NVL::Environment::UnpackMarkupVariable(markup));
}
if (ms.empty()) {
RenderString(str, pos_x, pos_y, col);
RenderString(str, pos_x, pos_y, col, TEXT_NONE);
return;
}
if (ms[0].begin != 0)
RenderString(str.substr(0, ms[0].begin), pos_x, pos_y, col);
RenderString(str.substr(0, ms[0].begin), pos_x, pos_y, col, TEXT_NONE);
// We assume markups are already sorted
for (size_t i = 0; i < ms.size(); i++) {
bool bold = false,
italic = false;
u32 style_flags = TEXT_NONE;
const NVL::String* ruby = nullptr;
for (const auto& e : ms[i].efs) {
if (e.first == L"b") { bold = true; }
else if (e.first == L"i") { italic = true; }
else if (e.first == L"rb") { ruby = &e.second[0]; }
if (e.first == u"b") { style_flags |= TEXT_BOLD; }
else if (e.first == u"i") { style_flags |= TEXT_ITALIC; }
else if (e.first == u"u") { style_flags |= TEXT_UNDERLINE; }
else if (e.first == u"s") { style_flags |= TEXT_STRIKETHROUGH; }
else if (e.first == u"o") { style_flags |= TEXT_OVERLINE; }
else if (e.first == u"rb") { ruby = &e.second[0]; }
else {
std::cerr << "ADV: Unrecognized text markup: " << NVL::to_std_string(e.first) << std::endl;
}
}
if (ruby != nullptr) {
u32 temp_x = pos_x, temp_y = pos_y + 20;
RenderString(*ruby, temp_x, temp_y, col);
}
if (bold && italic) {
}
else if (bold) {
u32 temp_x = pos_x, temp_y = pos_y;
RenderString(str.substr(ms[i].begin, ms[i].end - ms[i].begin), pos_x, pos_y, col);
RenderString(str.substr(ms[i].begin, ms[i].end - ms[i].begin), temp_x + 2, temp_y - 1, col);
}
else if (italic) {
}
else {
RenderString(str.substr(ms[i].begin, ms[i].end - ms[i].begin), pos_x, pos_y, col);
RenderString(*ruby, temp_x, temp_y, col, TEXT_NONE);
}
if (i != ms.size() - 1 && ms[i + 1].begin - 1 != ms[i].end) {
RenderString(str.substr(ms[i].end, ms[i + 1].begin - ms[i].end), pos_x, pos_y, col);
}
RenderString(str.substr(ms[i].begin, ms[i].end - ms[i].begin), pos_x, pos_y, col, style_flags);
if (i != ms.size() - 1 && ms[i + 1].begin - 1 != ms[i].end)
RenderString(str.substr(ms[i].end, ms[i + 1].begin - ms[i].end), pos_x, pos_y, col, TEXT_NONE);
}
if (ms.back().end != str.length())
RenderString(str.substr(ms.back().end), pos_x, pos_y, col);
RenderString(str.substr(ms.back().end), pos_x, pos_y, col, TEXT_NONE);
}
}
void DrawRandomShit() {
DrawTexture(tx, 0, -40, w, h);
}
}

View file

@ -1,12 +1,29 @@
#include <SDL2/SDL.h>
#include <bgfx/bgfx.h>
#include <Common.h>
#include <Environment.h>
namespace ADVect::Graphics {
i16 Init(u16 width, u16 height);
void Shutdown();
void RenderString(const NVL::String& s, u32& pos_x, u32& pos_y, u32 col);
void RenderString(const NVL::String& s, u32&& pos_x, u32&& pos_y, u32 col);
enum MarkupStyle {
TEXT_NONE = 0,
TEXT_BOLD = 1 << 0,
TEXT_ITALIC = 1 << 1,
TEXT_UNDERLINE = 1 << 2,
TEXT_STRIKETHROUGH = 1 << 3,
TEXT_OVERLINE = 1 << 4
};
void DrawTexture(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h);
void DrawTextureStencilAlpha(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h);
void RenderString(const NVL::String& s, u32& pos_x, u32& pos_y, u32 col, u32 style_flags);
void RenderString(const NVL::String& s, u32&& pos_x, u32&& pos_y, u32 col, u32 style_flags);
void RenderStringMarkup(const std::vector<NVL::Environment::Variable>& s, u32 pos_x, u32 pos_y, u32 col);
void DrawRandomShit();
}

7897
ADVect/include/stb_image.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
$input v_texcoord0
#include <bgfx_shader.sh>
#include <shaderlib.sh>
SAMPLER2D(s_texColor, 0);
void main()
{
vec2 uv = { v_texcoord0.x, 1.0f - v_texcoord0.y };
gl_FragColor = vec4(1.0, 1.0, 1.0, texture2D(s_texColor, uv).a);
}

View file

@ -0,0 +1,11 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include <bgfx_shader.sh>
#include <shaderlib.sh>
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
v_texcoord0 = a_texcoord0;
}

View file

@ -0,0 +1,4 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 a_position : POSITION;
vec2 a_texcoord0 : TEXCOORD0;

View file

@ -8,6 +8,5 @@ SAMPLER2D(s_texColor, 0);
void main()
{
vec2 uv = { v_texcoord0.x, 1.0f - v_texcoord0.y };
gl_FragColor = texture2D(s_texColor, uv).aaaa;
//gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
gl_FragColor = texture2D(s_texColor, uv);
}

View file

@ -14,7 +14,17 @@ typedef uint64_t u64;
#include <string>
#include <locale>
#include <codecvt>
namespace NVL {
using String = std::wstring;
using Number = f32;
using Char = char16_t;
using String = std::u16string;
static std::wstring_convert<std::codecvt_utf8_utf16<Char>, Char> str_converter;
inline static std::string to_std_string(const String& s) noexcept { return str_converter.to_bytes(s); }
inline static String to_NVL_string(const std::string& s) noexcept { return str_converter.from_bytes(s); }
}

View file

@ -22,7 +22,7 @@ namespace NVL::Environment {
case Type::Number:
return std::get<Number>(other.value) == std::get<Number>(value);
case Type::String:
return std::get<String>(other.value) == std::get<NVL::String>(value);
return std::get<String>(other.value) == std::get<String>(value);
default:
return false;
}
@ -81,4 +81,27 @@ namespace NVL::Environment {
for (const auto& c : s.get())
Apply(c);
}
// Check ParseMarkup for more information
Markup UnpackMarkupVariable(const Variable& m) {
const auto& range = std::get<std::vector<Variable>>(std::get<std::vector<Variable>>(m.value)[0].value);
const u32 begin = std::get<Number>(range[0].value), end = std::get<Number>(range[1].value);
std::vector<std::pair<String, std::vector<String>>> efs;
for (const Variable& combination : std::get<std::vector<Variable>>(std::get<std::vector<Variable>>(m.value)[1].value)) {
if (combination.type == Type::String) {
const String ef = std::get<String>(combination.value);
efs.push_back({ ef, {} });
}
else if (combination.type == Type::Array) {
const std::vector<Variable>& ef_t = std::get<std::vector<Variable>>(combination.value);
const String& ef = std::get<String>(ef_t[0].value);
const std::vector<Variable>& args = std::get<std::vector<Variable>>(ef_t[1].value);
std::vector<String> ss{};
for (const auto& s : args) { ss.push_back(std::get<String>(s.value)); }
efs.push_back({ ef, ss });
}
}
return { begin, end, efs };
}
}

View file

@ -37,4 +37,9 @@ namespace NVL::Environment {
Variable Eval(const Parse::Object& obj);
Variable Apply(const Parse::Command& c);
void EvalScene(const Parse::Scene & s);
struct Markup {
u32 begin, end;
std::vector<std::pair<String, std::vector<String>>> efs;
} UnpackMarkupVariable(const Variable& m);
}

View file

@ -11,8 +11,6 @@
#include <stdexcept>
#include "Environment.h"
#include <locale>
#include <codecvt>
namespace {
using namespace NVL;
@ -31,11 +29,11 @@ namespace {
struct Match {
String accept;
operator wchar_t() const {
operator Char() const {
if (accept.length() == 1)
return accept[0];
else {
std::wcerr << "Cannot demote Match " << accept << " to char" << std::endl;
std::cerr << "NVL: Cannot demote Match " << to_std_string(accept) << " to char" << std::endl;
return '\0';
}
}
@ -44,74 +42,74 @@ namespace {
}
};
const ParseGroup NUMERIC = { L"1234567890" };
const Match DECIMAL_DOT = { L"." };
const Match NEGATIVE = { L"-" };
const ParseGroup ALPHA = { L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" };
const Match ARRAY_OPEN = { L"[" };
const Match ARRAY_CLOSE = { L"]" };
const Match ARRAY_DELIM = { L"," };
const Match GROUP_OPEN = { L"(" };
const Match GROUP_CLOSE = { L")" };
const Match QUOTE = { L"\"" };
const Match COMMENT_BEGIN = { L"//" };
const Match DIALOGUE_OPEN = { L"<<-" };
const Match DIALOGUE_CLOSE = { L"->>" };
const Match BEGIN = { L"BEGIN" };
const Match END = { L"END" };
const ParseGroup SYMBOL = { ALPHA.accept + NUMERIC.accept + L"_"};
const ParseGroup NUMERIC = { u"1234567890" };
const Match DECIMAL_DOT = { u"." };
const Match NEGATIVE = { u"-" };
const ParseGroup ALPHA = { u"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" };
const Match ARRAY_OPEN = { u"[" };
const Match ARRAY_CLOSE = { u"]" };
const Match ARRAY_DELIM = { u"," };
const Match GROUP_OPEN = { u"(" };
const Match GROUP_CLOSE = { u")" };
const Match QUOTE = { u"\"" };
const Match COMMENT_BEGIN = { u"//" };
const Match DIALOGUE_OPEN = { u"<<-" };
const Match DIALOGUE_CLOSE = { u"->>" };
const Match BEGIN = { u"BEGIN" };
const Match END = { u"END" };
const ParseGroup SYMBOL = { ALPHA.accept + NUMERIC.accept + u"_"};
const Match SPECIAL_SYMBOLS[] = {
{ L"+" },
{ L"-" },
{ L"*" },
{ L"/" },
{ L"=?" },
{ L">?" },
{ L"<?" },
{ L"<=?" },
{ L">=?" }
{ u"+" },
{ u"-" },
{ u"*" },
{ u"/" },
{ u"=?" },
{ u">?" },
{ u"<?" },
{ u"<=?" },
{ u">=?" }
};
const ParseGroup WS = { L" \t\v\f\r\n" };
const ParseGroup WS = { u" \t\v\f\r\n" };
const ParseGroup SEPARATOR = {
WS.accept +
wchar_t(ARRAY_OPEN) +
wchar_t(ARRAY_CLOSE) +
wchar_t(GROUP_OPEN) +
wchar_t(GROUP_CLOSE) +
wchar_t(ARRAY_DELIM) +
Char(ARRAY_OPEN) +
Char(ARRAY_CLOSE) +
Char(GROUP_OPEN) +
Char(GROUP_CLOSE) +
Char(ARRAY_DELIM) +
COMMENT_BEGIN.accept[0]
};
const Match NEWLINE = { L"\n" };
const ParseGroup ESCAPED = { L"\\\"" };
const Match NEWLINE = { u"\n" };
const ParseGroup ESCAPED = { u"\\\"" };
const Match ESCAPE = { L"\\" };
const Match ESCAPE = { u"\\" };
// Dialogue mode matches
const Match MARKUP_OPEN = { L"[" };
const Match MARKUP_CLOSE = { L"]" };
const Match SPEAKER_OPEN = { L"[" };
const Match SPEAKER_CLOSE = { L"]" };
const Match MARKUP_TEXT_OPEN = { L"{" };
const Match MARKUP_TEXT_CLOSE = { L"}" };
const Match TEMPLATE_IND = { L"$" };
const Match TEMPLATE_OPEN = { L"{" };
const Match TEMPLATE_CLOSE = { L"}" };
const Match MARKUP_OPEN = { u"[" };
const Match MARKUP_CLOSE = { u"]" };
const Match SPEAKER_OPEN = { u"[" };
const Match SPEAKER_CLOSE = { u"]" };
const Match MARKUP_TEXT_OPEN = { u"{" };
const Match MARKUP_TEXT_CLOSE = { u"}" };
const Match TEMPLATE_IND = { u"$" };
const Match TEMPLATE_OPEN = { u"{" };
const Match TEMPLATE_CLOSE = { u"}" };
const Match COMMAND_ESCAPE = { L"*!" };
const Match COMMAND_ESCAPE = { u"*!" };
const ParseGroup DIALOGUE_ESCAPED_SINGLE = {
ESCAPE.accept +
wchar_t(MARKUP_OPEN) +
wchar_t(MARKUP_CLOSE) +
wchar_t(MARKUP_TEXT_OPEN) +
wchar_t(MARKUP_TEXT_CLOSE) +
// char(SPEAKER_OPEN) +
// char(SPEAKER_CLOSE) +
wchar_t(TEMPLATE_IND)
// char(TEMPLATE_OPEN) +
// char(TEMPLATE_CLOSE)
Char(MARKUP_OPEN) +
Char(MARKUP_CLOSE) +
Char(MARKUP_TEXT_OPEN) +
Char(MARKUP_TEXT_CLOSE) +
// Char(SPEAKER_OPEN) +
// Char(SPEAKER_CLOSE) +
Char(TEMPLATE_IND)
// Char(TEMPLATE_OPEN) +
// Char(TEMPLATE_CLOSE)
};
std::wstring read_file_to_string(const std::string& path) {
String read_file_to_string(const std::string& path) {
std::ifstream f(path);
{ // Some apps on Windows adds this signature in front of UTF-8 files when saving
char a, b, c;
@ -119,12 +117,12 @@ namespace {
if (a != (char)0xEF || b != (char)0xBB || c != (char)0xBF)
f.seekg(0);
else
std::cerr << "Warning: Windows UTF-8 BOM skipped" << std::endl;
std::cerr << "NVL Warning: Windows UTF-8 BOM skipped" << std::endl;
}
std::stringstream buffer;
buffer << f.rdbuf();
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(buffer.str());
return to_NVL_string(buffer.str());
}
std::vector<String> split_string_by_lines(const String& str) {
@ -321,7 +319,7 @@ namespace {
else {
auto token = GetToken(f, pos);
if (IsNumeric(token))
return { std::stof(token) };
return { std::stof(to_std_string(token)) };
else if (IsLegalSymbolName(token))
return { Parse::Type::Symbol, token };
else
@ -352,9 +350,9 @@ namespace {
std::vector<Parse::Object> tags;
std::wsmatch tags_match;
std::wsmatch effects_match;
std::wsmatch params_match;
std::match_results<String::const_iterator> tags_match;
std::match_results<String::const_iterator> effects_match;
std::match_results<String::const_iterator> params_match;
String reconstruction{};
@ -421,7 +419,7 @@ namespace {
if (s.substr(0, 2) == COMMAND_ESCAPE.accept) {
size_t dummy = 0;
// Pad a space towards the end, the helpers do not expect strings to immediately terminate
return ParseCommand(s.substr(2) + L" ", dummy);
return ParseCommand(s.substr(2) + u" ", dummy);
}
// assume arity for SwitchSpeaker and Say
@ -430,7 +428,7 @@ namespace {
if (s.front() == SPEAKER_OPEN) {
auto name = s.substr(1, s.length() - 2);
// if (IsLegalSymbolName(name))
return { { Parse::Type::Symbol, L"SwitchSpeaker" }, { Parse::Type::String, name } };
return { { Parse::Type::Symbol, u"SwitchSpeaker" }, { Parse::Type::String, name } };
}
else
throw std::runtime_error("Malformed speaker command");
@ -439,7 +437,7 @@ namespace {
String copy{ s };
Parse::Object tags = MatchMarkup(copy); // THIS WILL MODIFY COPY
return { { Parse::Type::Symbol, L"Say" }, { Parse::Type::String, copy }, tags };
return { { Parse::Type::Symbol, u"Say" }, { Parse::Type::String, copy }, tags };
}
Parse::Scene ParseScene(const String& f, size_t& pos) {
@ -513,7 +511,7 @@ namespace NVL::Parse {
}
std::vector<Scene> ParseFile(const std::string& path) {
std::wstring f = read_file_to_string(path);
String f = read_file_to_string(path);
std::vector<Scene> list {}; // Vector of scenes which each contain a vector of Parses
for (size_t i = 0; i < f.length(); i++) {

View file

@ -5,7 +5,6 @@
#include <utility>
#include "Common.h"
namespace NVL::Parse {
enum class Type { Symbol, Number, String, Array, Subexpression };
@ -29,9 +28,9 @@ namespace NVL::Parse {
using Command = std::vector<Object>;
class Scene {
String name;
std::vector<Command> commands{};
public:
String name;
Scene(const String& name) : name(name) {}
void append(const Command& c) {
commands.push_back(c);

View file

@ -5,6 +5,8 @@ Hi I'm Electric [b, rb("Programmer")] {プログラマー} from Michigan.
Commencing JS hypnosis...
Enchanté !
Advance
[Terrio]
mesugaki
Thanks
[死大师]
他们肯定做炫酷的漫画[b] {静止系mad}。并拉扯运动曲线和使用[rb("思源宋体")] {Source Han Serif}作为主要的字体。