graphics overhaul; parser bugs, many things i forgot to commit
This commit is contained in:
parent
324ff7e7b5
commit
94515b0620
21 changed files with 403 additions and 187 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
.vs
|
||||
.vscode
|
||||
out
|
||||
build
|
||||
NVL/.vs
|
||||
|
|
|
@ -1,38 +1,176 @@
|
|||
#include "ADVect.h"
|
||||
#include "Common.h"
|
||||
#include "Environment.h"
|
||||
#include "Graphics.h"
|
||||
#include "SDL2/SDL_thread.h"
|
||||
#include "SDL2/SDL_timer.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <bx/math.h>
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <bgfx/platform.h>
|
||||
#include <bx/math.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
struct Track {
|
||||
T current;
|
||||
};
|
||||
|
||||
template <typename TR, typename T>
|
||||
concept IsTrack = requires (const TR& t) {
|
||||
std::is_same_v<T, decltype(t.current)>;
|
||||
};
|
||||
|
||||
template <typename TR, typename T>
|
||||
concept IsNamedTrack = IsTrack<TR, T> && requires (const TR& t) {
|
||||
std::is_same_v<std::string, decltype(t.name)>;
|
||||
};
|
||||
|
||||
template<typename T, typename TR> requires(!IsNamedTrack<TR, T>)
|
||||
struct NamedTrack : TR {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<typename T, IsTrack<T> TR>
|
||||
struct VisualTrack : TR {
|
||||
i32 pos_x = 0, pos_y = 0;
|
||||
u32 w = 500, h = 500;
|
||||
f32 opacity = 1.0f;
|
||||
// TODO other transforms
|
||||
};
|
||||
|
||||
template<typename T, IsTrack<T> TR>
|
||||
struct FillTrack : TR {
|
||||
i32 pos_x = 0, pos_y = 0;
|
||||
u32 w = 500, h = 500;
|
||||
f32 opacity = 1.0f;
|
||||
u32 fill = 0xFFFFFFFF;
|
||||
};
|
||||
|
||||
/* TODO impl
|
||||
struct AudioTrack {};
|
||||
*/
|
||||
|
||||
using TextTrack = FillTrack<NVL::String, Track<NVL::String>>;
|
||||
using MarkupTextTrack = FillTrack<NVL::Environment::MarkupString, Track<NVL::Environment::MarkupString>>;
|
||||
using NamedImageTrack = VisualTrack<ADVect::Graphics::ImageTexture*, NamedTrack<ADVect::Graphics::ImageTexture*, Track<ADVect::Graphics::ImageTexture*>>>;
|
||||
/* TODO VideoTrack */
|
||||
|
||||
SDL_Window* window;
|
||||
|
||||
std::string m_name;
|
||||
u16 window_width = 1280;
|
||||
u16 window_height = 720;
|
||||
|
||||
bool running = false;
|
||||
|
||||
u16 m_width = 1280;
|
||||
u16 m_height = 720;
|
||||
|
||||
bool m_keys[65536]{};
|
||||
|
||||
std::vector<NVL::Parse::Scene> scenes;
|
||||
u32 current_scene = 0;
|
||||
std::vector<NVL::Environment::Variable> m_text{};
|
||||
NVL::String speaker;
|
||||
u32 scene_pos = 0;
|
||||
u64 init_time, last_time, current_time, delta_t;
|
||||
|
||||
struct ImageTrack {
|
||||
std::string name;
|
||||
ADVect::Graphics::ImageTexture* current = nullptr;
|
||||
i32 pos_x = 0, pos_y = 0;
|
||||
template <typename T>
|
||||
struct Varying {
|
||||
u64 begin, duration;
|
||||
std::function<T(NVL::Number)> interp;
|
||||
bool done = true;
|
||||
|
||||
T get() const {
|
||||
if (done)
|
||||
return interp(1.f);
|
||||
else
|
||||
return interp((current_time - begin) / static_cast<f32>(duration));
|
||||
}
|
||||
void kickoff(u64 dur, const std::function<T(NVL::Number)>& f = [](NVL::Number x) { return static_cast<T>(x); }) {
|
||||
begin = current_time;
|
||||
done = false;
|
||||
duration = dur;
|
||||
interp = f;
|
||||
}
|
||||
bool check() {
|
||||
if (done) return true;
|
||||
else if (current_time >= begin + duration) {
|
||||
done = true;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<ImageTrack> tracks_img{};
|
||||
ImageTrack* find_image_track(const std::string& s) {
|
||||
struct NamedImageTransitionTrack : NamedImageTrack {
|
||||
ADVect::Graphics::ImageTexture* next = nullptr;
|
||||
Varying<f32> anim;
|
||||
std::function<void(const NamedImageTransitionTrack&)> draw;
|
||||
|
||||
void check() {
|
||||
if (next != nullptr && anim.check()) {
|
||||
current = next;
|
||||
next = nullptr;
|
||||
}
|
||||
}
|
||||
void change(ADVect::Graphics::ImageTexture* n, u64 dur, const std::function<f32(NVL::Number)>& f = [](NVL::Number x) { return x; }) {
|
||||
if (current == nullptr)
|
||||
current = n;
|
||||
else if (n == nullptr) current = n;
|
||||
else {
|
||||
next = n;
|
||||
anim.kickoff(dur, f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TypewriterMarkupTextTrack : MarkupTextTrack {
|
||||
Varying<u32> anim;
|
||||
void check() { anim.check(); }
|
||||
void change(const NVL::Environment::MarkupString& n, u16 speed) {
|
||||
current = n;
|
||||
anim.kickoff(speed * n.length(), [n](NVL::Number x) { return static_cast<size_t>(x * n.length()); });
|
||||
}
|
||||
void draw() {
|
||||
if (anim.done)
|
||||
ADVect::Graphics::RenderStringMarkup(current, pos_x, pos_y, fill);
|
||||
else
|
||||
ADVect::Graphics::RenderStringMarkup(current.substr(anim.get()), pos_x, pos_y, fill);
|
||||
}
|
||||
};
|
||||
|
||||
void draw_image_transition_fade(const NamedImageTransitionTrack& t) {
|
||||
if (t.current != nullptr) {
|
||||
if (t.next != nullptr) {
|
||||
ADVect::Graphics::DrawTextureImage(*t.current, t.pos_x, t.pos_y);
|
||||
ADVect::Graphics::DrawTextureImageAlpha(*t.next, t.pos_x, t.pos_y, t.anim.get());
|
||||
}
|
||||
else {
|
||||
ADVect::Graphics::DrawTextureImage(*t.current, t.pos_x, t.pos_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
void draw_image_transition_crossfade(const NamedImageTransitionTrack& t) {
|
||||
if (t.current != nullptr) {
|
||||
if (t.next != nullptr) {
|
||||
ADVect::Graphics::DrawTextureImageAlpha(*t.current, t.pos_x, t.pos_y, 1.0f - t.anim.get());
|
||||
ADVect::Graphics::DrawTextureImageAlpha(*t.next, t.pos_x, t.pos_y, t.anim.get());
|
||||
}
|
||||
else {
|
||||
ADVect::Graphics::DrawTextureImage(*t.current, t.pos_x, t.pos_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<NVL::Parse::Scene> scenes;
|
||||
u32 current_scene = 0;
|
||||
u32 scene_pos = 0;
|
||||
|
||||
TypewriterMarkupTextTrack m_text{ { {}, 280, 90 } };
|
||||
TextTrack speaker { u"", 250, 150 };
|
||||
NamedImageTransitionTrack bg, avatar;
|
||||
NamedImageTrack dialogue_bg;
|
||||
/*
|
||||
std::list<NamedImageTrack> tracks_img{}; // instead of vector because we need pointers to members; prevent use after free
|
||||
NamedImageTrack* find_image_track(const std::string& s) {
|
||||
for (auto& t : tracks_img)
|
||||
if (t.name == s) {
|
||||
return &t;
|
||||
|
@ -42,7 +180,7 @@ namespace {
|
|||
}
|
||||
bool add_image_track(const std::string& s) {
|
||||
if (find_image_track(s) == nullptr) {
|
||||
ImageTrack t;
|
||||
NamedImageTrack t;
|
||||
t.name = s;
|
||||
tracks_img.push_back(std::move(t));
|
||||
return true;
|
||||
|
@ -50,11 +188,12 @@ namespace {
|
|||
std::cerr << "ADV: Redefinition of ImageTrack " << s << std::endl;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
namespace ADVect {
|
||||
bool Init(std::string name, const std::vector<NVL::Parse::Scene>& sc) {
|
||||
m_name = name;
|
||||
scenes = sc; // sure make a copy whatever
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO)) {
|
||||
|
@ -62,7 +201,7 @@ namespace ADVect {
|
|||
return false;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow(m_name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_width, m_height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
window = SDL_CreateWindow(name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width, window_height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
if (window == NULL) {
|
||||
std::cerr << "ADV: Failed to create window: " << SDL_GetError() << std::endl;
|
||||
return false;
|
||||
|
@ -70,8 +209,8 @@ namespace ADVect {
|
|||
|
||||
bgfx::Init bgfxInit;
|
||||
bgfxInit.type = bgfx::RendererType::Count; // Automatically choose a renderer.
|
||||
bgfxInit.resolution.width = m_width;
|
||||
bgfxInit.resolution.height = m_height;
|
||||
bgfxInit.resolution.width = window_width;
|
||||
bgfxInit.resolution.height = window_height;
|
||||
bgfxInit.resolution.reset = BGFX_RESET_VSYNC;
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
|
@ -98,19 +237,22 @@ namespace ADVect {
|
|||
};
|
||||
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::setViewRect(0, 0, 0, window_width, window_height);
|
||||
bgfx::setViewMode(0, bgfx::ViewMode::Sequential);
|
||||
float view[16];
|
||||
bx::mtxTranslate(view, 0.f, 0.f, 1.0f);
|
||||
float proj[16];
|
||||
bx::mtxOrtho(proj, 0.0f, m_width, 0.0f, m_height, 0.1f, 100.0f, 0.f, bgfx::getCaps()->homogeneousDepth);
|
||||
bx::mtxOrtho(proj, 0.0f, window_width, 0.0f, window_height, 0.1f, 100.0f, 0.f, bgfx::getCaps()->homogeneousDepth);
|
||||
bgfx::setViewTransform(0, view, proj);
|
||||
|
||||
if (!ADVect::Graphics::Init(m_width, m_height)) {
|
||||
if (!ADVect::Graphics::Init(window_width, window_height)) {
|
||||
std::cerr << "ADV: Graphics init failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bg.draw = draw_image_transition_fade;
|
||||
avatar.draw = draw_image_transition_crossfade;
|
||||
|
||||
Advance();
|
||||
return true;
|
||||
}
|
||||
|
@ -143,31 +285,45 @@ namespace ADVect {
|
|||
Advance();
|
||||
m_keys[SDL_SCANCODE_SPACE] = false;
|
||||
}
|
||||
bg.check();
|
||||
avatar.check();
|
||||
m_text.check();
|
||||
}
|
||||
|
||||
void Render() {
|
||||
bgfx::touch(0);
|
||||
|
||||
/*
|
||||
for (auto& t : tracks_img) {
|
||||
if (t.current != nullptr)
|
||||
ADVect::Graphics::DrawTextureImage(*t.current, t.pos_x, t.pos_y);
|
||||
}
|
||||
ADVect::Graphics::RenderString(speaker, 250, 150, 0xFFFFFFFF, ADVect::Graphics::TEXT_BOLD);
|
||||
ADVect::Graphics::RenderStringMarkup(m_text, 300, 90, 0xFFFFFFFF);
|
||||
*/
|
||||
bg.draw(bg);
|
||||
if (dialogue_bg.current != nullptr)
|
||||
ADVect::Graphics::DrawTextureImage(*dialogue_bg.current, dialogue_bg.pos_x, dialogue_bg.pos_y);
|
||||
avatar.draw(avatar);
|
||||
|
||||
ADVect::Graphics::RenderString(speaker.current, speaker.pos_x, speaker.pos_y, speaker.fill, ADVect::Graphics::TEXT_BOLD);
|
||||
m_text.draw();
|
||||
|
||||
bgfx::dbgTextClear();
|
||||
bgfx::dbgTextPrintf(0, 44, 0xF8, "NouVeL x ADVect :: %s :: %s %s", BX_COMPILER_NAME, __DATE__, __TIME__);
|
||||
bgfx::dbgTextPrintf(0, 43, 0xF8, "SDL %i.%i.%2i :: bgfx 1.%i :: %s", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL, BGFX_API_VERSION, bgfx::getRendererName(bgfx::getRendererType()));
|
||||
bgfx::dbgTextPrintf(0, 42, 0xF8, "Current Position: %u", scene_pos);
|
||||
bgfx::dbgTextPrintf(0, 41, 0xF8, "Current Scene: %s", NVL::to_std_string(scenes[current_scene].name).c_str());
|
||||
bgfx::dbgTextPrintf(0, 0, 0xf8, "NouVeL x ADVect :: %s :: %s %s", BX_COMPILER_NAME, __DATE__, __TIME__);
|
||||
bgfx::dbgTextPrintf(0, 1, 0xf8, "SDL %i.%i.%2i :: bgfx 1.%i :: %s", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL, BGFX_API_VERSION, bgfx::getRendererName(bgfx::getRendererType()));
|
||||
bgfx::dbgTextPrintf(0, 2, 0xf8, "Current Position: %u", scene_pos);
|
||||
bgfx::dbgTextPrintf(0, 3, 0xf8, "Current Scene: %s", NVL::to_std_string(scenes[current_scene].name).c_str());
|
||||
|
||||
bgfx::frame();
|
||||
}
|
||||
|
||||
void Run() {
|
||||
last_time = init_time = SDL_GetTicks64();
|
||||
|
||||
running = true;
|
||||
while (running) {
|
||||
current_time = SDL_GetTicks64();
|
||||
delta_t = current_time - last_time;
|
||||
|
||||
for (SDL_Event event; SDL_PollEvent(&event);) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
|
@ -184,40 +340,42 @@ namespace ADVect {
|
|||
}
|
||||
Update();
|
||||
Render();
|
||||
|
||||
last_time = current_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const std::string PJ_DIR = "..\\..\\..\\..\\NVL\\";
|
||||
const std::string PJ_DIR = "E:\\Archive\\Projects\\NouVeL\\NVL\\";
|
||||
|
||||
NVL::Environment::ENVIRONMENT.enter({
|
||||
{
|
||||
u"Say",
|
||||
NVL::Environment::Variable([](std::vector<NVL::Environment::Variable> args) {
|
||||
m_text = args;
|
||||
m_text.change(NVL::Environment::UnpackMarkupVariable(std::get<std::vector<NVL::Environment::Variable>>(NVL::Environment::Variable(args[0]).value)), 10);
|
||||
return NVL::Environment::Type::Nil;
|
||||
}, 2)
|
||||
},
|
||||
{
|
||||
u"SwitchSpeaker",
|
||||
NVL::Environment::Variable([](std::vector<NVL::Environment::Variable> args) {
|
||||
speaker = std::get<NVL::String>(NVL::Environment::Variable(args[0]).value);
|
||||
speaker.current = std::get<NVL::String>(NVL::Environment::Variable(args[0]).value);
|
||||
return NVL::Environment::Type::Nil;
|
||||
}, 1)
|
||||
},
|
||||
{
|
||||
/* {
|
||||
u"ImageTrack",
|
||||
NVL::Environment::Variable([](std::vector<NVL::Environment::Variable> args) {
|
||||
add_image_track(NVL::to_std_string(std::get<NVL::String>(NVL::Environment::Variable(args[0]).value)));
|
||||
return NVL::Environment::Type::Nil;
|
||||
}, 1)
|
||||
},
|
||||
},*/
|
||||
{
|
||||
u"Show",
|
||||
NVL::Environment::Variable([](std::vector<NVL::Environment::Variable> args) {
|
||||
std::string name = NVL::to_std_string(std::get<NVL::String>(NVL::Environment::Variable(args[0]).value));
|
||||
ImageTrack* t = find_image_track(name);
|
||||
/* NamedImageTrack* t = find_image_track(name);
|
||||
if (t == nullptr) {
|
||||
std::cerr << "ADV: Cannot find ImageTrack " << name << std::endl;
|
||||
}
|
||||
|
@ -225,16 +383,27 @@ int main(int argc, char* argv[]) {
|
|||
auto s = std::get<NVL::String>(NVL::Environment::Variable(args[1]).value);
|
||||
auto s2 = NVL::to_std_string(s);
|
||||
t->current = ADVect::Graphics::GetImageTextureFromFile(s2);
|
||||
}
|
||||
}*/
|
||||
if (name == "BG")
|
||||
bg.change(ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get<NVL::String>(NVL::Environment::Variable(args[1]).value))), 200);
|
||||
else if (name == "Avatar")
|
||||
avatar.change(ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get<NVL::String>(NVL::Environment::Variable(args[1]).value))), 200);
|
||||
else if (name == "BGDialogue")
|
||||
dialogue_bg.current = ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get<NVL::String>(NVL::Environment::Variable(args[1]).value)));
|
||||
else
|
||||
std::cerr << "ADV: Cannot find ImageTrack " << name << std::endl;
|
||||
return NVL::Environment::Type::Nil;
|
||||
}, 2)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
std::vector<NVL::Parse::Scene> SCENES = NVL::Parse::ParseFile(PJ_DIR + "dialogue.nvl");
|
||||
if (SCENES.empty()) return EXIT_FAILURE;
|
||||
if (SCENES.empty()) {
|
||||
std::cerr << "ADV: Empty NVL parse, check file" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!ADVect::Init("ADV", SCENES)) return EXIT_FAILURE;
|
||||
if (!ADVect::Init("ADV Test", SCENES)) return EXIT_FAILURE;
|
||||
ADVect::Run();
|
||||
|
||||
ADVect::Shutdown();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <Parser.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <Environment.h>
|
||||
#include <Common.h>
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#include <Environment.h>
|
||||
|
||||
namespace ADVect {
|
||||
void bind_NVL() {
|
||||
auto f = [](NVL::Environment::Variable x) {
|
||||
return NVL::Environment::Variable(NVL::Environment::Type::Nil);
|
||||
};
|
||||
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 });
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
namespace ADVect {
|
||||
void bind_NVL();
|
||||
}
|
|
@ -5,7 +5,7 @@ cmake_minimum_required (VERSION 3.8)
|
|||
|
||||
project (ADVect)
|
||||
|
||||
add_executable (Game "ADVect.cpp" "Graphics.cpp" "Bindings.cpp")
|
||||
add_executable (Game "ADVect.cpp" "Graphics.cpp" )
|
||||
|
||||
# TODO: Add tests and install targets if needed.
|
||||
include_directories ("include" "../NVL/")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Graphics.h"
|
||||
#include "Environment.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "Graphics.h"
|
||||
|
||||
#include <bx/math.h>
|
||||
|
||||
|
@ -61,7 +62,7 @@ namespace {
|
|||
{ 1.f, 1.f, 0.0f, 1.0f, 1.0f }
|
||||
};
|
||||
|
||||
static const uint16_t quad_indices[] =
|
||||
static const u16 quad_indices[] =
|
||||
{
|
||||
0, 2, 1,
|
||||
1, 2, 3
|
||||
|
@ -98,7 +99,7 @@ namespace {
|
|||
}
|
||||
};
|
||||
|
||||
std::optional<Font> init_font(const char* path) {
|
||||
std::optional<Font> get_font(const char* path) {
|
||||
Font f;
|
||||
|
||||
error = FT_New_Face(library, path, 0, &f.face);
|
||||
|
@ -135,7 +136,7 @@ namespace {
|
|||
ImageTexture i;
|
||||
i.buffer = stbi_load(file.c_str(), &i.w, &i.h, &i.channels, 0);
|
||||
if (i.buffer == NULL) {
|
||||
std::cerr << "ADV: STB IMAGE loading failed" << std::endl;
|
||||
std::cerr << "ADV: STB IMAGE loading failed for " << file << std::endl;
|
||||
return std::nullopt;
|
||||
}
|
||||
const bgfx::Memory* buf = bgfx::makeRef(i.buffer, i.w * i.h * i.channels * sizeof(u8));
|
||||
|
@ -157,8 +158,10 @@ namespace {
|
|||
}
|
||||
|
||||
Font regular, bold;
|
||||
bgfx::ProgramHandle a_program, img_program;
|
||||
bgfx::ProgramHandle a_program, img_program, imga_program;
|
||||
|
||||
bgfx::UniformHandle s_texColor;
|
||||
bgfx::UniformHandle imga_opacity;
|
||||
|
||||
bgfx::IndexBufferHandle ibh;
|
||||
bgfx::VertexBufferHandle vbh;
|
||||
|
@ -175,8 +178,8 @@ namespace ADVect::Graphics {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (auto f = init_font("SourceHanSerif-Regular.ttc")) regular = *f; else return false;
|
||||
if (auto f = init_font("SourceHanSerif-Heavy.ttc")) bold = *f; else return false;
|
||||
if (auto f = get_font("SourceHanSerif-Regular.ttc")) regular = *f; else return false;
|
||||
if (auto f = get_font("SourceHanSerif-Heavy.ttc")) bold = *f; else return false;
|
||||
|
||||
pcvDecl.begin()
|
||||
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
|
||||
|
@ -185,9 +188,11 @@ namespace ADVect::Graphics {
|
|||
ibh = bgfx::createIndexBuffer(bgfx::makeRef(quad_indices, sizeof(quad_indices)));
|
||||
vbh = bgfx::createVertexBuffer(bgfx::makeRef(quad_vert, sizeof(quad_vert)), pcvDecl);
|
||||
|
||||
img_program = load_shader_program("test");
|
||||
a_program = load_shader_program("swizzle_aaaa");
|
||||
img_program = load_shader_program("test"); // RGBA
|
||||
imga_program = load_shader_program("ImageAlpha"); // RGBA + Opacity
|
||||
a_program = load_shader_program("AlphaStencil"); // A -> FFFA
|
||||
|
||||
imga_opacity = bgfx::createUniform("f_opacity", bgfx::UniformType::Vec4); // x -> alpha, yzw are dummies
|
||||
s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
|
||||
|
||||
return true;
|
||||
|
@ -204,16 +209,18 @@ namespace ADVect::Graphics {
|
|||
|
||||
bgfx::destroy(a_program);
|
||||
bgfx::destroy(img_program);
|
||||
bgfx::destroy(imga_program);
|
||||
|
||||
bgfx::destroy(ibh);
|
||||
bgfx::destroy(vbh);
|
||||
|
||||
bgfx::destroy(s_texColor);
|
||||
bgfx::destroy(imga_opacity);
|
||||
}
|
||||
|
||||
// Draws quad with texture on Z = 0
|
||||
void DrawTexture(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h, u64 state, const bgfx::ProgramHandle& pg) {
|
||||
float mtx1[16], mtx2[16], mtx3[16];
|
||||
f32 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);
|
||||
|
@ -237,6 +244,13 @@ namespace ADVect::Graphics {
|
|||
DrawTextureImage(img.tx, pos_x, pos_y, img.w, img.h);
|
||||
}
|
||||
|
||||
void DrawTextureImageAlpha(const ImageTexture& img, i32 pos_x, i32 pos_y, f32 alpha) {
|
||||
f32 pack[4]{};
|
||||
pack[0] = alpha;
|
||||
bgfx::setUniform(imga_opacity, pack);
|
||||
DrawTexture(img.tx, pos_x, pos_y, img.w, img.h, (BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) & ~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS), imga_program);
|
||||
}
|
||||
|
||||
ImageTexture* GetImageTextureFromFile(const std::string& file) {
|
||||
if (imgs.find(file) == imgs.end()) {
|
||||
ImageTexture img;
|
||||
|
@ -253,7 +267,7 @@ namespace ADVect::Graphics {
|
|||
DrawTexture(tex, pos_x, pos_y, w, h, (BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) & ~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS), a_program);
|
||||
}
|
||||
|
||||
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 = TEXT_NONE) {
|
||||
Font* f = ®ular;
|
||||
switch (style_flags) {
|
||||
case TEXT_NONE: break;
|
||||
|
@ -267,7 +281,7 @@ namespace ADVect::Graphics {
|
|||
f->cache_char(c);
|
||||
|
||||
pos_x += slot->bitmap_left;
|
||||
float ypos = pos_y - (slot->bitmap.rows - slot->bitmap_top);
|
||||
f32 ypos = pos_y - (slot->bitmap.rows - slot->bitmap_top);
|
||||
|
||||
if (slot->bitmap.width != 0) {
|
||||
DrawTextureStencilAlpha((f->cache)[c], pos_x, ypos, slot->bitmap.width, slot->bitmap.rows);
|
||||
|
@ -283,28 +297,13 @@ namespace ADVect::Graphics {
|
|||
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<NVL::Environment::Markup> ms{};
|
||||
for (const NVL::Environment::Variable& markup : std::get<std::vector<NVL::Environment::Variable>>(s[1].value)) {
|
||||
ms.push_back(NVL::Environment::UnpackMarkupVariable(markup));
|
||||
}
|
||||
|
||||
if (ms.empty()) {
|
||||
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, TEXT_NONE);
|
||||
|
||||
void RenderStringMarkup(const NVL::Environment::MarkupString& ms, u32 pos_x, u32 pos_y, u32 col) {
|
||||
// We assume markups are already sorted
|
||||
for (size_t i = 0; i < ms.size(); i++) {
|
||||
for (const NVL::Environment::MarkupSegment& s : ms.segments) {
|
||||
u32 style_flags = TEXT_NONE;
|
||||
const NVL::String* ruby = nullptr;
|
||||
|
||||
for (const auto& e : ms[i].efs) {
|
||||
for (const auto& e : s.efs) {
|
||||
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; }
|
||||
|
@ -318,17 +317,10 @@ namespace ADVect::Graphics {
|
|||
|
||||
if (ruby != nullptr) {
|
||||
u32 temp_x = pos_x, temp_y = pos_y + 20;
|
||||
RenderString(*ruby, temp_x, temp_y, col, TEXT_NONE);
|
||||
RenderString(*ruby, temp_x, temp_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);
|
||||
|
||||
RenderString(s.str, pos_x, pos_y, col, style_flags);
|
||||
}
|
||||
|
||||
if (ms.back().end != str.length())
|
||||
RenderString(str.substr(ms.back().end), pos_x, pos_y, col, TEXT_NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <bgfx/bgfx.h>
|
||||
|
@ -28,9 +30,10 @@ namespace ADVect::Graphics {
|
|||
void DrawTexture(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h, u64 state, const bgfx::ProgramHandle& pg);
|
||||
void DrawTextureImage(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h);
|
||||
void DrawTextureImage(const ImageTexture& img, i32 pos_x, i32 pos_y);
|
||||
void DrawTextureImageAlpha(const ImageTexture& img, i32 pos_x, i32 pos_y, f32 alpha);
|
||||
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 RenderStringMarkup(const NVL::Environment::MarkupString& s, u32 pos_x, u32 pos_y, u32 col);
|
||||
}
|
||||
|
|
|
@ -1,28 +1,33 @@
|
|||
import subprocess, os
|
||||
|
||||
SHADERC = "..\\out\\install\\x64-Debug\\bin\\shaderc"
|
||||
OUT = "..\\out\\build\\x64-Debug\\ADVect\\shaders\\"
|
||||
# OUT = "..\\build\\ADVect\\shaders\\"
|
||||
|
||||
P = lambda location, frag, vert: { 'location': location, 'frag': frag, 'vert': vert }
|
||||
plats = [
|
||||
{ 'location': 'glsl', 'frag': '140', 'vert': '140' },
|
||||
{ 'location': 'dx11', 'frag': 'ps_5_0', 'vert': 'vs_5_0' },
|
||||
{ 'location': 'spirv', 'frag': 'spirv', 'vert': 'spirv' }
|
||||
P('glsl', '140', '140'),
|
||||
P('dx11', 'ps_5_0', 'vs_5_0'),
|
||||
P('spirv', 'spirv', 'spirv')
|
||||
]
|
||||
|
||||
for root, dirs, _ in os.walk('shaders'):
|
||||
for name in dirs:
|
||||
for config in plats:
|
||||
subprocess.run(["..\\out\\install\\x64-Debug\\bin\\shaderc", "-f", os.path.join(root, name, name + '.frag'),
|
||||
subprocess.run([SHADERC, "-f", os.path.join(root, name, name + '.frag'),
|
||||
"--type", "fragment"
|
||||
"--platform", "windows",
|
||||
"--profile", config['frag'],
|
||||
"--varyingdef", os.path.join(root, name, "varying.def.sc"),
|
||||
"-i", "ext\\bgfx\\bgfx\\examples\\common",
|
||||
"-i", "ext\\bgfx\\bgfx\\src",
|
||||
"-o", "..\\out\\build\\x64-Debug\\ADVect\\shaders\\" + config['location'] + "\\" + name + ".frag.bin"])
|
||||
subprocess.run(["..\\out\\install\\x64-Debug\\bin\\shaderc", "-f", os.path.join(root, name, name + '.vert'),
|
||||
"-o", OUT + config['location'] + "\\" + name + ".frag.bin"])
|
||||
subprocess.run([SHADERC, "-f", os.path.join(root, name, name + '.vert'),
|
||||
"--type", "vertex"
|
||||
"--platform", "windows",
|
||||
"--profile", config['vert'],
|
||||
"--varyingdef", os.path.join(root, name, "varying.def.sc"),
|
||||
"-i", "ext\\bgfx\\bgfx\\examples\\common",
|
||||
"-i", "ext\\bgfx\\bgfx\\src",
|
||||
"-o", "..\\out\\build\\x64-Debug\\ADVect\\shaders\\" + config['location'] + "\\" + name + ".vert.bin"])
|
||||
"-o", OUT + config['location'] + "\\" + name + ".vert.bin"])
|
||||
|
|
@ -3,10 +3,13 @@ $input v_texcoord0
|
|||
#include <bgfx_shader.sh>
|
||||
#include <shaderlib.sh>
|
||||
|
||||
uniform vec4 f_opacity;
|
||||
SAMPLER2D(s_texColor, 0);
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y);
|
||||
gl_FragColor = texture2D(s_texColor, uv);
|
||||
vec4 tx = texture2D(s_texColor, uv);
|
||||
gl_FragColor = vec4(tx.rgb, f_opacity.x * tx.a);
|
||||
}
|
|
@ -15,14 +15,13 @@
|
|||
{
|
||||
"name": "x64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"variables": []
|
||||
"inheritEnvironments": [ "clang_cl_x64" ]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -86,26 +86,55 @@ namespace NVL::Environment {
|
|||
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);
|
||||
// Check MatchMarkup for more information
|
||||
MarkupString UnpackMarkupVariable(const std::vector<Variable>& v) {
|
||||
MarkupString ms{};
|
||||
for (const Variable& segment : v) {
|
||||
const auto& pair = std::get<std::vector<Variable>>(segment.value);
|
||||
const String s = std::get<String>(pair[0].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, {} });
|
||||
std::vector<std::pair<String, std::vector<String>>> efs;
|
||||
for (const Variable& combination : std::get<std::vector<Variable>>(pair[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 });
|
||||
}
|
||||
}
|
||||
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 });
|
||||
ms.segments.push_back({ s, efs });
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
|
||||
size_t MarkupString::length() const {
|
||||
size_t r = 0;
|
||||
for (const auto& s : segments)
|
||||
r += s.str.length();
|
||||
return r;
|
||||
}
|
||||
|
||||
MarkupString MarkupString::substr(size_t i) const {
|
||||
size_t r = 0;
|
||||
MarkupString res;
|
||||
for (const auto& s : segments) {
|
||||
size_t last_r = r;
|
||||
r += s.str.length();
|
||||
if (r <= i)
|
||||
res.segments.push_back(s);
|
||||
else {
|
||||
auto copy = s;
|
||||
copy.str = copy.str.substr(0, i - last_r);
|
||||
res.segments.push_back(copy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { begin, end, efs };
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,14 @@ namespace NVL::Environment {
|
|||
Variable Apply(const Parse::Command& c);
|
||||
void EvalScene(const Parse::Scene & s);
|
||||
|
||||
struct Markup {
|
||||
u32 begin, end;
|
||||
struct MarkupSegment {
|
||||
String str;
|
||||
std::vector<std::pair<String, std::vector<String>>> efs;
|
||||
};
|
||||
Markup UnpackMarkupVariable(const Variable& m);
|
||||
struct MarkupString {
|
||||
std::vector<MarkupSegment> segments{};
|
||||
size_t length() const;
|
||||
MarkupString substr(size_t idx) const;
|
||||
};
|
||||
MarkupString UnpackMarkupVariable(const std::vector<Variable>& v);
|
||||
}
|
||||
|
|
|
@ -328,63 +328,54 @@ namespace {
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* NVL Markup Parsetree
|
||||
*
|
||||
* * - Vec:2 - Num: Markup begin
|
||||
* | |
|
||||
* | - Num: Markup end
|
||||
* |
|
||||
* - Vec:N - Str: T of Markup
|
||||
* |
|
||||
* OR
|
||||
* |
|
||||
* - Vec:2 - Str: T of Markup
|
||||
* * - Vec:N - Vec:2 - Str: Str segment contents
|
||||
* |
|
||||
* - Vec: Params
|
||||
* - Vec:N - Str: T of Markup
|
||||
* |
|
||||
* OR
|
||||
* |
|
||||
* - Vec:2 - Str: T of Markup
|
||||
* |
|
||||
* - Vec: Params
|
||||
*/
|
||||
Parse::Object MatchMarkup(String& s) {
|
||||
Parse::Object MatchMarkup(const String& s) {
|
||||
static const srell::basic_regex<Char>
|
||||
typer(uR"((?<!\\)\[([^\]]+)\]\s*\{([^\}]+)\})"), // G1 -> Specifiers, G2 -> Contents
|
||||
effect(uR"(\s*(?:([^,\(\)]+?)\s*\(\s*([^\(\)]+?)\s*\)|([^,\(\)]+?))\s*(?:,\s*|$))"), // G1 & G2 -> Func, G3 -> Attr
|
||||
param(uR"(([^,]+?)\s*(?:,\s*|$))"); // Comma split of func args
|
||||
|
||||
std::vector<Parse::Object> tags;
|
||||
|
||||
srell::match_results<String::const_iterator> tags_match, effects_match, params_match;
|
||||
|
||||
String reconstruction{};
|
||||
|
||||
size_t running_offset = 0; // to account for characters removed
|
||||
|
||||
bool has_markup{};
|
||||
bool has_markup = false;
|
||||
|
||||
// Match tags
|
||||
std::vector<Parse::Object> segments;
|
||||
String::const_iterator tags_start(s.cbegin());
|
||||
while (srell::regex_search(tags_start, s.cend(), tags_match, typer)) {
|
||||
has_markup = true;
|
||||
Parse::Object m{ Parse::Type::Array, std::vector<Parse::Object>{} };
|
||||
reconstruction.append(tags_match.prefix().first, tags_match[0].first);
|
||||
reconstruction.append(tags_match[2].first, tags_match[2].second);
|
||||
running_offset += tags_match[2].first - tags_match[0].first;
|
||||
|
||||
size_t begin = tags_match[2].first - s.cbegin() - running_offset;
|
||||
String before {tags_match.prefix().first, tags_match[0].first};
|
||||
if (!before.empty())
|
||||
segments.push_back({ Parse::Type::Array, {
|
||||
{ Parse::Type::String, before },
|
||||
{ Parse::Type::Array, std::vector<Parse::Object>{} }
|
||||
}});
|
||||
|
||||
Parse::Object range{ Parse::Type::Array, { std::vector<Parse::Object>{
|
||||
{ static_cast<Number>(begin) },
|
||||
{ static_cast<Number>(begin + (tags_match[2].second - tags_match[2].first)) }
|
||||
}
|
||||
} };
|
||||
|
||||
std::vector<Parse::Object> effects{};
|
||||
String inner = tags_match[2].str(); // markupped
|
||||
|
||||
// Match markup options
|
||||
std::vector<Parse::Object> effects{};
|
||||
String::const_iterator effects_start(tags_match[1].first);
|
||||
while (srell::regex_search(effects_start, tags_match[1].second, effects_match, effect)) {
|
||||
if (effects_match[3].matched) {
|
||||
if (effects_match[3].matched) { // no params
|
||||
effects.push_back({ Parse::Type::String, effects_match[3].str() });
|
||||
}
|
||||
else {
|
||||
else { // no params
|
||||
|
||||
// Comma split
|
||||
std::vector<Parse::Object> args;
|
||||
String::const_iterator params_start(effects_match[2].first);
|
||||
while (srell::regex_search(params_start, effects_match[2].second, params_match, param)) {
|
||||
|
@ -396,20 +387,26 @@ namespace {
|
|||
}
|
||||
effects_start = effects_match.suffix().first;
|
||||
}
|
||||
running_offset += tags_match[0].second - tags_match[2].second;
|
||||
tags_start = tags_match.suffix().first;
|
||||
tags.push_back({ Parse::Type::Array, std::vector<Parse::Object>{ range, { Parse::Type::Array, effects } } });
|
||||
segments.push_back({ Parse::Type::Array, std::vector<Parse::Object>{ { Parse::Type::String, inner }, { Parse::Type::Array, effects } } });
|
||||
}
|
||||
|
||||
if (has_markup) {
|
||||
reconstruction.append(tags_match.suffix().first, tags_match.suffix().second);
|
||||
String end {tags_match.suffix().first, tags_match.suffix().second};
|
||||
if (!end.empty())
|
||||
segments.push_back({ Parse::Type::Array, {
|
||||
{ Parse::Type::String, end },
|
||||
{ Parse::Type::Array, std::vector<Parse::Object>{} }
|
||||
}});
|
||||
|
||||
s = reconstruction;
|
||||
|
||||
return { Parse::Type::Array, tags };
|
||||
return { Parse::Type::Array, segments };
|
||||
}
|
||||
else {
|
||||
return { Parse::Type::Array, std::vector<Parse::Object>{} };
|
||||
return { Parse::Type::Array, std::vector<Parse::Object>{
|
||||
{ Parse::Type::Array, {
|
||||
{ Parse::Type::String, s} , { Parse::Type::Array, std::vector<Parse::Object>{} }
|
||||
} } }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,10 +430,7 @@ namespace {
|
|||
throw std::runtime_error("Malformed speaker command");
|
||||
}
|
||||
|
||||
String copy{ s };
|
||||
Parse::Object tags = MatchMarkup(copy); // THIS WILL MODIFY COPY
|
||||
|
||||
return { { Parse::Type::Symbol, u"Say" }, { Parse::Type::String, copy }, tags };
|
||||
return { { Parse::Type::Symbol, u"Say" }, MatchMarkup(s) };
|
||||
}
|
||||
|
||||
Parse::Scene ParseScene(const String& f, size_t& pos) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
ImageTrack BG
|
||||
Show BG "image.png"
|
||||
<<-
|
||||
[但丁]
|
||||
[]
|
||||
由我这里,直通[b]{悲惨之城}。
|
||||
由我这里,直通[b]{无尽之苦}。
|
||||
由我这里,直通[b]{堕落众生}。
|
||||
|
|
|
@ -1,19 +1,57 @@
|
|||
BEGIN Scene1
|
||||
|
||||
ImageTrack BG
|
||||
ImageTrack Avatar
|
||||
Show BG "image.png"
|
||||
Show BGDialogue "grad.png"
|
||||
|
||||
<<-
|
||||
*!Show Avatar "mmaker.png"
|
||||
[MMaker]
|
||||
Hi I'm Electric [b, rb("Programmer")] {プログラマー} from Michigan.
|
||||
*!Show BG "googleplex/1.png"
|
||||
Park your car in a place that allows you to walk on the sidewalk.
|
||||
*!Show BG "googleplex/2.jpg"
|
||||
Wait until everyone is asleep.
|
||||
*!Show BG "googleplex/3.jpg"
|
||||
Sneak into the building and head towards the front door.
|
||||
*!Show BG "googleplex/4.png"
|
||||
Go through the security gate and walk around the perimeter of the grounds.
|
||||
*!Show BG "googleplex/5.jpg"
|
||||
Enter the building using the main entrance.
|
||||
*!Show BG "googleplex/6.jpg"
|
||||
Walk to the elevator and take it up to the sixth floor.
|
||||
*!Show BG "googleplex/7.png"
|
||||
Enter the stairwell leading to the roof and climb all the way to the top.
|
||||
*!Show BG "googleplex/8.jpg"
|
||||
Break open the skylight and enter the room containing the Google logo.
|
||||
*!Show BG "googleplex/9.jpg"
|
||||
Find the main server room.
|
||||
*!Show BG "googleplex/10.jpg"
|
||||
Kill the power to the server room.
|
||||
*!Show BG "googleplex/11.jpg"
|
||||
Search the room for a computer with a USB port.
|
||||
*!Show BG "googleplex/12.jpg"
|
||||
Plug the USB cable into the computer.
|
||||
*!Show BG "googleplex/13.jpg"
|
||||
Start typing in the password for the administrator account.
|
||||
*!Show BG "googleplex/14.png"
|
||||
After the login screen comes up, type in the password "G00gle."
|
||||
*!Show BG "googleplex/15.png"
|
||||
When the system reboots, you will see a prompt asking you to install a new program.
|
||||
Type "Y" and press ENTER.
|
||||
*!Show BG "googleplex/16.jpg"
|
||||
The Google search engine will come up. Type in "www.yahoo.com" and hit ENTER.
|
||||
*!Show BG "googleplex/17.png"
|
||||
A window will appear saying "You have successfully installed Google Chrome." Click OK.
|
||||
*!Show BG "googleplex/18.jpg"
|
||||
A new browser will open. Log in to your Yahoo mail account.
|
||||
*!Show BG "image3.png"
|
||||
Go to your inbox and click on the link to download the latest version of Google Chrome.
|
||||
*!Show BG "googleplex/20.jpg"
|
||||
Install the update.
|
||||
|
||||
*! Show BG "image2.jpg"
|
||||
|
||||
Commencing JS hypnosis...
|
||||
|
||||
*! Show BG "image3.png"
|
||||
*! Show BG "image.png"
|
||||
|
||||
*!Show Avatar "terrio.png"
|
||||
[Terrio]
|
||||
|
|
Loading…
Add table
Reference in a new issue