diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index 50e80e6c..6936ddc7 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -29,6 +29,8 @@ # undef far /* Fuck Microsoft again */ #endif +#include "pegtl.hh" + #include "lolgl.h" namespace lol @@ -116,64 +118,97 @@ hash ShaderData::Hash; int ShaderData::nshaders = 0; /* - * Public Shader class + * LolFx parser */ -Shader *Shader::Create(String const &name, String const &code) +using namespace pegtl; + +struct lolfx_parser { - String src = String("\n") + code; +public: + lolfx_parser(String const &code) + : m_section("header") + { + basic_parse_string(std::string(code.C()), this); + } - /* Parse the crap */ - array sections; - char *key = nullptr; - for (char *parser = src.C(); *parser; ) +public: + String m_section; + map m_programs; + +private: + struct do_title : action_base { - if (key == nullptr && (parser[0] == '\n' || parser[0] == '\r') - && parser[1] == '[') + static void apply(std::string const &ctx, lolfx_parser *that) { - *parser = '\0'; - parser += 2; - key = parser; + that->m_section = ctx.c_str(); } - else if (key && parser[0] == ']') - { - *parser++ = '\0'; - } - else if (key && (parser[0] == '\n' || parser[0] == '\r')) - { - sections.Push(key, parser); - parser++; - key = nullptr; - } - else + }; + + struct do_code : action_base + { + static void apply(std::string const &ctx, lolfx_parser *that) { - parser++; + that->m_programs[that->m_section] = ctx.c_str(); } + }; + + // title <- '[' (!']')+ ']' .{eol} + struct title + : seq, + ifapply>, do_title>, + one<']'>, + until> {}; + + // FIXME: I’m using this rule because the ifapply<> above also + // gets triggered when using at<> which is non-consuming. + struct title_ignore + : seq, + plus>, + one<']'>, + until> {}; + + // code_line <- .{eol} + struct code_line + : until {}; + + // code_section < code_line{&(title / eof)} + struct code_section + : ifapply>, code_line>, do_code> {}; + + // shader < title code_section + struct shader + : seq {}; + + // header < code_section + struct header + : code_section {}; + + // lolfx < header code_section* + struct lolfx + : seq> {}; +}; + +/* + * Public Shader class + */ + +Shader *Shader::Create(String const &name, String const &code) +{ + lolfx_parser p(code); + + if (!p.m_programs.HasKey("vert.glsl")) + { + ASSERT(false, "no vertex shader found in %s", name.C()); } - char const *vert = nullptr, *frag = nullptr; - for (int i = 0; i < sections.Count(); i++) + if (!p.m_programs.HasKey("frag.glsl")) { -#if !defined __CELLOS_LV2__ && !defined _XBOX && !defined USE_D3D9 - if (!strcmp(sections[i].m1, "vert.glsl")) - vert = sections[i].m2; - if (!strcmp(sections[i].m1, "frag.glsl")) - frag = sections[i].m2; -#else - if (!strcmp(sections[i].m1, "vert.hlsl")) - vert = sections[i].m2; - if (!strcmp(sections[i].m1, "frag.hlsl")) - frag = sections[i].m2; -#endif + ASSERT(false, "no fragment shader found in %s", name.C()); } - /* FIXME: we don’t know how to handle these yet. */ - if (!vert) - Log::Error("no vertex shader found in %s… sorry, I’m gonna crash now.\n", - name.C()); - if (!frag) - Log::Error("no fragment shader found in %s… sorry, I’m gonna crash now.\n", - name.C()); + String vert = p.m_programs["vert.glsl"]; + String frag = p.m_programs["frag.glsl"]; uint32_t new_vert_crc = ShaderData::Hash(vert); uint32_t new_frag_crc = ShaderData::Hash(frag); @@ -201,7 +236,7 @@ void Shader::Destroy(Shader *shader) } Shader::Shader(String const &name, - char const *vert, char const *frag) + String const &vert, String const &frag) : data(new ShaderData()) { data->m_name = name; diff --git a/src/lol/gpu/shader.h b/src/lol/gpu/shader.h index c7598285..4b7b4446 100644 --- a/src/lol/gpu/shader.h +++ b/src/lol/gpu/shader.h @@ -171,7 +171,7 @@ public: void Unbind() const; protected: - Shader(String const &name, char const *vert, char const *frag); + Shader(String const &name, String const &vert, String const &frag); ~Shader(); private: diff --git a/src/platform/sdl/sdlinput.cpp b/src/platform/sdl/sdlinput.cpp index fea2d313..3a0ea5e5 100644 --- a/src/platform/sdl/sdlinput.cpp +++ b/src/platform/sdl/sdlinput.cpp @@ -65,7 +65,9 @@ private: static ivec2 GetMousePos(); static void SetMousePos(ivec2 position); - SdlInputData(int app_w, int app_h, int screen_w, int screen_h) : + SdlInputData(int app_w, int app_h, int screen_w, int screen_h) + : m_mouse(nullptr), + m_keyboard(nullptr), m_prevmouse(ivec2::zero), m_app(vec2((float)app_w, (float)app_h)), m_screen(vec2((float)screen_w, (float)screen_h)),