#include "ADVect.h" #include "Graphics.h" #include #include #include #include #include namespace { SDL_Window* window; std::string m_name; bool running = false; u16 m_width = 1280; u16 m_height = 720; bool m_keys[65536]{}; std::vector scenes; u32 current_scene = 0; std::vector m_text{}; NVL::String speaker; u32 scene_pos = 0; struct ImageTrack { std::string name; ADVect::Graphics::ImageTexture* current = nullptr; i32 pos_x = 0, pos_y = 0; }; std::vector tracks_img{}; ImageTrack* find_image_track(const std::string& s) { for (auto& t : tracks_img) if (t.name == s) { return &t; } return nullptr; } bool add_image_track(const std::string& s) { if (find_image_track(s) == nullptr) { ImageTrack t; t.name = s; tracks_img.push_back(std::move(t)); return true; } std::cerr << "ADV: Redefinition of ImageTrack " << s << std::endl; return false; } } namespace ADVect { bool Init(std::string name, const std::vector& sc) { m_name = name; scenes = sc; // sure make a copy whatever if (SDL_Init(SDL_INIT_VIDEO)) { std::cerr << "ADV: Failed to init SDL: " << SDL_GetError() << std::endl; 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); if (window == NULL) { std::cerr << "ADV: Failed to create window: " << SDL_GetError() << std::endl; return false; } bgfx::Init bgfxInit; bgfxInit.type = bgfx::RendererType::Count; // Automatically choose a renderer. bgfxInit.resolution.width = m_width; bgfxInit.resolution.height = m_height; bgfxInit.resolution.reset = BGFX_RESET_VSYNC; #if !BX_PLATFORM_EMSCRIPTEN SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); if (!SDL_GetWindowWMInfo(window, &wmi)) { std::cerr << "ADV: SDL_SysWMinfo could not be retrieved: " << SDL_GetError() << std::endl; } #endif #if BX_PLATFORM_WINDOWS bgfxInit.platformData.nwh = wmi.info.win.window; #elif BX_PLATFORM_OSX bgfxInit.platformData.nwh = wmi.info.cocoa.window; #elif BX_PLATFORM_LINUX bgfxInit.platformData.ndt = wmi.info.x11.display; bgfxInit.platformData.nwh = (void*)(uintptr_t)wmi.info.x11.window; #elif BX_PLATFORM_EMSCRIPTEN bgfxInit.platformData.nwh = (void*)"#canvas"; #endif if (!bgfx::init(bgfxInit)) { std::cerr << "ADV: Failed bgfx initialization" << std::endl; return false; }; 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); 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); bgfx::setViewTransform(0, view, proj); if (!ADVect::Graphics::Init(m_width, m_height)) { std::cerr << "ADV: Graphics init failed" << std::endl; return false; } Advance(); return true; } void Shutdown() { Graphics::Shutdown(); bgfx::shutdown(); SDL_DestroyWindow(window); SDL_Quit(); } void Advance() { size_t curr_size = scenes[current_scene].get().size(); while (scene_pos < curr_size && std::get(scenes[current_scene].get()[scene_pos][0].value) != u"Say") { NVL::Environment::Apply(scenes[current_scene].get()[scene_pos]); scene_pos++; } if (curr_size == scene_pos) { running = false; return; } if (std::get(scenes[current_scene].get()[scene_pos][0].value) == u"Say") { NVL::Environment::Apply(scenes[current_scene].get()[scene_pos]); scene_pos++; } } void Update() { if (m_keys[SDL_SCANCODE_SPACE]) { Advance(); m_keys[SDL_SCANCODE_SPACE] = false; } } 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); 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::frame(); } void Run() { running = true; while (running) { for (SDL_Event event; SDL_PollEvent(&event);) { switch (event.type) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: m_keys[event.key.keysym.scancode] = true; break; case SDL_KEYUP: m_keys[event.key.keysym.scancode] = false; break; } } Update(); Render(); } } } int main(int argc, char* argv[]) { const std::string PJ_DIR = "..\\..\\..\\..\\NVL\\"; NVL::Environment::ENVIRONMENT.enter({ { u"Say", NVL::Environment::Variable([](std::vector args) { m_text = args; return NVL::Environment::Type::Nil; }, 2) }, { u"SwitchSpeaker", NVL::Environment::Variable([](std::vector args) { speaker = std::get(NVL::Environment::Variable(args[0]).value); return NVL::Environment::Type::Nil; }, 1) }, { u"ImageTrack", NVL::Environment::Variable([](std::vector args) { add_image_track(NVL::to_std_string(std::get(NVL::Environment::Variable(args[0]).value))); return NVL::Environment::Type::Nil; }, 1) }, { u"Show", NVL::Environment::Variable([](std::vector args) { std::string name = NVL::to_std_string(std::get(NVL::Environment::Variable(args[0]).value)); ImageTrack* t = find_image_track(name); if (t == nullptr) { std::cerr << "ADV: Cannot find ImageTrack " << name << std::endl; } else { auto s = std::get(NVL::Environment::Variable(args[1]).value); auto s2 = NVL::to_std_string(s); t->current = ADVect::Graphics::GetImageTextureFromFile(s2); } return NVL::Environment::Type::Nil; }, 2) } }); std::vector SCENES = NVL::Parse::ParseFile(PJ_DIR + "dialogue.nvl"); if (SCENES.empty()) return EXIT_FAILURE; if (!ADVect::Init("ADV", SCENES)) return EXIT_FAILURE; ADVect::Run(); ADVect::Shutdown(); return EXIT_SUCCESS; }