commit 49c1cacaa0086a0f39269dee934a3d12c0c62635 Author: Dreaded_X Date: Wed Jan 30 00:23:32 2019 +0100 Created basic ecs that has an optional lua module diff --git a/.flintlock b/.flintlock new file mode 100644 index 0000000..e560e56 --- /dev/null +++ b/.flintlock @@ -0,0 +1,6 @@ +[flint.py] +version = nightly +base_url = https://downloads.mtgames.nl/release/flint + +[flint.py-plugins] + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbaba0e --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +### Git ### +*.orig + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### Vim ### +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +# auto-generated tag files +tags + +# flint +.flint diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..902966f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "vendor/sol2"] + path = vendor/sol2 + url = https://github.com/ThePhD/sol2 +[submodule "vendor/lua"] + path = vendor/lua + url = https://github.com/lua/lua diff --git a/ecs-lua/include/ecs-lua.h b/ecs-lua/include/ecs-lua.h new file mode 100644 index 0000000..0916129 --- /dev/null +++ b/ecs-lua/include/ecs-lua.h @@ -0,0 +1,29 @@ +#pragma once + +#include "sol.hpp" +#include "ecs.h" + +#include + +namespace ecs::lua { + struct LuaWrapper : Component { + LuaWrapper(sol::object object) : _object(object) {} + + sol::object _object; + }; + + template + void register_component(sol::state& lua, Args... args) { + lua.new_usertype(get_typename(), + "new", sol::factories([](Constructor... constructor) { + return new T(constructor...); + }), args... + ); + lua.set_function("_internal_to_" + get_typename(), [] (Component* component) { + return (T*)component; + }); + } + + void init(sol::state& lua); +} + diff --git a/ecs-lua/src/ecs-lua.cpp b/ecs-lua/src/ecs-lua.cpp new file mode 100644 index 0000000..8b44310 --- /dev/null +++ b/ecs-lua/src/ecs-lua.cpp @@ -0,0 +1,50 @@ +#include "ecs-lua.h" + +namespace ecs::lua { + void init(sol::state& lua) { + sol::table ecs = lua.create_table("ecs"); + + ecs.new_usertype("Entity", + "add_component", [] (Entity* thiz, std::string name, Component* component) { + return thiz->add_component(name, component); + }, + "has_components", [] (Entity* thiz, sol::variadic_args args) { + std::vector names; + for (std::string name : args) { + names.push_back(name); + } + return thiz->has_components(names); + }, + "get_component", [&lua] (Entity* thiz, std::string name) -> sol::object { + // Convert to the correct component type + auto f1 = lua["_internal_to_" + name]; + if (f1.valid()) { + return f1(thiz->get_component(name)); + } + + // If the type of the component unknown we assume it a lua object and convert it to the wrapper + auto f2 = lua["_internal_to_LuaWrapper"]; + return f2(thiz->get_component(name)); + } + ); + + ecs.new_usertype>("View", + "for_each", &View<>::for_each + ); + + ecs.new_usertype("Manager", + "create_entity", &Manager::create_entity, + "view", [] (Manager* thiz, sol::variadic_args args) { + std::vector names; + for (std::string name : args) { + names.push_back(name); + } + return thiz->view(names); + } + ); + + register_component(lua, + "object", &LuaWrapper::_object + ); + } +} diff --git a/ecs/include/ecs.h b/ecs/include/ecs.h new file mode 100644 index 0000000..0c61a2e --- /dev/null +++ b/ecs/include/ecs.h @@ -0,0 +1,145 @@ +#pragma once +#include +#include +#include +#include +#include + +#include +#if __has_include() + #include +#endif + +namespace ecs { + template + std::string get_typename() { + #if __has_include() + std::string name = abi::__cxa_demangle(typeid(T).name(), 0, 0, 0); + #else + std::string name = typeid(T).name(); + // This is really janky + name = name.substr(name.find(' ')+1); + #endif + + auto index = name.find_last_of(':'); + if (index != std::string::npos) { + name = name.substr(index+1); + } + + return name; + } + + class ComponentID { + private: + static size_t _id; + // This needs to be a function because otherwise it might not be initialized on time + static std::unordered_map& _ids(); + + public: + static std::vector get_id(std::vector names); + + // This looks kind of ugly + template + inline static const size_t id = get_id({get_typename()})[0]; + }; + + struct Component { + virtual ~Component() {} + }; + + class Entity { + public: + ~Entity(); + + template + void add_component(Args... args) { + size_t id = ComponentID::id; + + if (_components.find(id) != _components.end()) { + throw std::runtime_error("Component already exists"); + } + + _components[id] = new T(args...); + } + + template + bool has_components() { + auto ids = {ComponentID::id...}; + for (const auto& id : ids) { + if (_components.find(id) == _components.end()) { + return false; + } + } + + return true; + } + + template + T* get_component() { + size_t id = ComponentID::id; + auto it = _components.find(id); + if (it == _components.end()) { + throw std::runtime_error("Component does not exist"); + } + + return (T*)it->second; + } + + void add_component(std::string name, Component* component); + bool has_components(std::vector names); + Component* get_component(std::string name); + + private: + std::unordered_map _components; + }; + + template + class View { + public: + View(std::vector entities) : _entities(entities) {} + + void for_each(std::function...)> function) { + for (auto entity : _entities) { + function(entity, entity->template get_component()...); + } + } + + private: + std::vector _entities; + }; + + class Manager { + public: + ~Manager(); + + template + View view() { + std::vector entities; + + for (auto entity : _entities) { + if (entity->has_components()) { + entities.push_back(entity); + } + } + + return View(entities); + } + + View<> view(std::vector names) { + std::vector entities; + + for (auto entity : _entities) { + if (entity->has_components(names)) { + entities.push_back(entity); + } + } + + return View<>(entities); + } + + Entity* create_entity(); + + private: + std::vector _entities; + }; +} diff --git a/ecs/src/ecs.cpp b/ecs/src/ecs.cpp new file mode 100644 index 0000000..5fb61cc --- /dev/null +++ b/ecs/src/ecs.cpp @@ -0,0 +1,82 @@ +#include "ecs.h" + +#include + +namespace ecs { + size_t ComponentID::_id; + // This needs to be a function because otherwise it might not be initialized on time + std::unordered_map& ComponentID::_ids() { + static std::unordered_map ids; + return ids; + }; + + std::vector ComponentID::get_id(std::vector names) { + std::vector ids; + + for (const auto& name : names) { + auto it = _ids().find(name); + if (it != _ids().end()) { + ids.push_back(it->second); + } else { + size_t id = _id++; + _ids()[name] = id; + ids.push_back(id); + } + } + + return ids; + } + + Entity::~Entity() { + // @todo This does not work... + for (auto component : _components) { + delete component.second; + component.second = nullptr; + } + _components.clear(); + } + + void Entity::add_component(std::string name, Component* component) { + size_t id = ComponentID::get_id({name})[0]; + if (_components.find(id) != _components.end()) { + throw std::runtime_error("Component already exists"); + } + + _components[id] = component; + } + + bool Entity::has_components(std::vector names) { + for (const auto& id : ComponentID::get_id(names)) { + if (_components.find(id) == _components.end()) { + return false; + } + } + + return true; + } + + Component* Entity::get_component(std::string name) { + auto it = _components.find(ComponentID::get_id({name})[0]); + if (it == _components.end()) { + throw std::runtime_error("Component does not exist"); + } + + return it->second; + } + + Manager::~Manager() { + for (auto entity : _entities) { + delete entity; + entity = nullptr; + } + _entities.clear(); + } + + Entity* Manager::create_entity() { + Entity* entity = new Entity; + + _entities.push_back(entity); + + return entity; + } +} diff --git a/flint.lua b/flint.lua new file mode 100644 index 0000000..89580c8 --- /dev/null +++ b/flint.lua @@ -0,0 +1,28 @@ +lib "lua" + src("*vendor/lua", "-vendor/lua/lua.c") + include "vendor/lua" + include "vendor/headers" + + warnings(false) + +lib "sol2" + include "vendor/sol2" + + dependency "lua" + +lib "ecs" + path "ecs" + + dependency "sol2" + +lib "ecs-lua" + path "ecs-lua" + + dependency "ecs" + +executable "test" + path "test" + + dependency "ecs-lua" + +run_target "test" diff --git a/flint.py b/flint.py new file mode 100755 index 0000000..879fa7c --- /dev/null +++ b/flint.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python3 +import os +import platform +import errno +import configparser +import urllib.request +import shutil +import subprocess +from subprocess import PIPE +import stat +import sys +import argparse + +flintlock = ".flintlock" + +def install_plugin(url, plugins_folder, config, local = False): + metainfo = configparser.ConfigParser() + + if not local: + req = urllib.request.Request(url + "/metainfo") + with urllib.request.urlopen(req) as response: + metainfo.read_string(response.read().decode("ascii")) + else: + with open(os.path.join(url, "metainfo.local"), "r") as f: + metainfo.read_file(f) + + plugin_name = metainfo["meta"]["name"] + "@" + metainfo["meta"]["author"] + + # Make sure we can't have local and remote version of the same plugin at the same time + # @todo This could be cleaner + if config.has_option("flint.py-plugins", plugin_name if local else plugin_name + ".local"): + config.remove_option("flint.py-plugins", plugin_name if local else plugin_name + ".local") + + print("Installing '" + plugin_name + "'") + + plugin_folder = os.path.join(plugins_folder, plugin_name) + + if os.path.exists(plugin_folder): + shutil.rmtree(plugin_folder) + os.makedirs(plugin_folder) + + # Register the plugin so that we can later update + config["flint.py-plugins"][plugin_name if not local else plugin_name + ".local"] = url + + with open(flintlock, "w") as f: + config.write(f) + + # @todo Use this same system for flint self + # @todo Add multiplatform support + if platform.system() == "Linux" and metainfo.has_section("linux"): + for filename in metainfo["linux"]: + if not local: + req = urllib.request.Request(url + "/" + filename) + with urllib.request.urlopen(req) as response, open(os.path.join(plugin_folder, filename), "wb") as f: + shutil.copyfileobj(response, f) + else: + os.symlink(os.path.abspath(os.path.join(url, metainfo["linux"][filename])), os.path.join(plugin_folder, filename)) + elif platform.system() == "Windows" and metainfo.has_section("windows"): + for filename in metainfo["windows"]: + if not local: + req = urllib.request.Request(url + "/" + filename) + with urllib.request.urlopen(req) as response, open(os.path.join(plugin_folder, filename), "wb") as f: + shutil.copyfileobj(response, f) + else: + # @todo This requires admin mode on windows + os.symlink(os.path.abspath(os.path.join(url, metainfo["windows"][filename])), os.path.join(plugin_folder, filename)) + + else: + print("Plugin not available for current platform") + +def remove_plugin(plugin_name, plugins_folder, config): + plugin_folder = os.path.join(plugins_folder, plugin_name) + + if config.has_option("flint.py-plugins", plugin_name): + config.remove_option("flint.py-plugins", plugin_name) + elif config.has_option("flint.py-plugins", plugin_name + ".local"): + config.remove_option("flint.py-plugins", plugin_name + ".local") + else: + print("Plugin '" + plugin_name + "' does not exist") + return + + if os.path.exists(plugin_folder): + shutil.rmtree(plugin_folder) + +def main(): + # @todo Add update, gets latest version and stores the specific version + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument("--config", action='store_const', const=True, default=False) + parser.add_argument("--local", action='store_const', const=True, default=False) + parser.add_argument("--generate") + parser.add_argument("--version") + parser.add_argument("--install", nargs='?', const="__update__") + parser.add_argument("--remove") + parser.add_argument("--debug-flint", action='store_const', const=True, default=False) + args, unknownargs = parser.parse_known_args() + + flintdir_base = ".flint" + flintdir = os.path.join(flintdir_base, "versions") + flintplug = os.path.join(flintdir_base, "plugins") + flintbin = "flint" + + if os.name == "nt": + flintbin += ".exe" + + # Make sure the flintlock file exists + if not os.path.isfile(flintlock): + # Create a new flintlock file with default values + config = configparser.ConfigParser() + with open(flintlock, "w") as f: + config.write(f) + + # Open the flintlock file + config = configparser.ConfigParser() + with open(flintlock, "r") as f: + config.read_file(f) + + # Make sure that all required keys exist + if not config.has_section("flint.py"): + config["flint.py"] = {} + if not config.has_option("flint.py", "version"): + config["flint.py"]["version"] = "nightly" + if not config.has_option("flint.py", "base_url"): + config["flint.py"]["base_url"] = "https://downloads.mtgames.nl/release/flint" + if not config.has_section("flint.py-plugins"): + config["flint.py-plugins"] = {} + + with open(flintlock, "w") as f: + config.write(f) + + # Check if the user has enable config mode + if args.config: + # @todo Improve config mode + if args.version: + config["flint.py"]["version"] = args.version + print("Flint will now use version: " + args.version) + else: + print("Did nothing...") + + with open(flintlock, "w") as f: + config.write(f) + elif args.generate: + if not os.path.exists(args.generate + "/src"): + os.makedirs(args.generate + "/src") + if not os.path.exists(args.generate + "/include"): + os.makedirs(args.generate + "/include") + + # @todo Also generate a simlpe example cpp file + with open("./flint.lua", "w") as f: + f.write("executable \"" + args.generate + "\"\n") + f.write("\tpath \"" + args.generate + "\"\n") + f.write("\n") + f.write("run_target \"" + args.generate + "\"\n") + elif args.install: + # @todo We need to auto update all plugins + # @todo We need to be able to remove plugins + metainfo = configparser.ConfigParser() + if args.install == "__update__": + for plugin in config["flint.py-plugins"]: + # @todo Make the download functions actual functions so we can call them here + install_plugin(config["flint.py-plugins"][plugin], flintplug, config, plugin.endswith(".local")) + else: + install_plugin(args.install, flintplug, config, args.local) + + elif args.remove: + remove_plugin(args.remove, flintplug, config) + + with open(flintlock, "w") as f: + config.write(f) + else: + # Check desired version + version = config["flint.py"]["version"] + base_url = config["flint.py"]["base_url"] + if args.version: + version = args.version + + print("Flint: " + version) + + flintdir = os.path.join(flintdir, version) + + if os.path.isfile(os.path.join(version, flintbin)): + # The version contains a path to a flint executable + flintdir = version + else: + # Make sure the flint directory exists + if not os.path.exists(flintdir): + try: + os.makedirs(flintdir) + except OSError as exc: + if exc != errno.EEXIST: + raise + + # Check if we need to update + needs_update = False + + # Download actual checksum + checksums = configparser.ConfigParser() + try: + req = urllib.request.Request(base_url + "/" + version + "/checksums") + with urllib.request.urlopen(req) as response: + checksums.read_string(response.read().decode("ascii")) + + checksums_current = configparser.ConfigParser() + if (not os.path.isfile(os.path.join(flintdir, flintbin))) or (not os.path.isfile(os.path.join(flintdir, "checksums"))): + # We need to download instead of update + needs_update = True + + checksums_current["flint"] = {} + + print("Downloading flint...") + else: + # Load the current checksum + with open(os.path.join(flintdir, "checksums"), "r") as f: + checksums_current.read_file(f) + + # Compare the checksum to determine if updates are needed + # @note This does not detect if the executable is corrupted + if not checksums_current["flint"][flintbin] == checksums["flint"][flintbin]: + needs_update = True + print("Updating flint...") + + # Store the new checksum + checksums_current["flint"][flintbin] = checksums["flint"][flintbin] + with open(os.path.join(flintdir, "checksums"), "w") as f: + checksums_current.write(f) + + except urllib.error.URLError as error: + print("Unable to update flint!") + needs_update = False + + # @todo Show progress bar + if needs_update: + try: + req = urllib.request.Request(base_url + "/" + version + "/" + flintbin) + with urllib.request.urlopen(req) as response, open(flintdir + "/" + flintbin, "wb") as f: + shutil.copyfileobj(response, f) + # Make sure we can execute flint + mode = os.stat(os.path.join(flintdir, flintbin)).st_mode + os.chmod(os.path.join(flintdir, flintbin), mode | stat.S_IEXEC) + + with open(flintlock, "w") as f: + config.write(f) + except urllib.error.URLError as error: + print("Flint update failed!") + needs_update = False + + command = [] + + env = os.environ + if os.name == "nt": + env["PATH"] = flintdir + ";.flint/plugins;" + env["PATH"] + else: + env["LD_LIBRARY_PATH"] = flintdir + ":.flint/plugins" + + if os.name == "nt": + command.extend([r"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat", "x64", "&&"]) + env["VSCMD_START_DIR"] = os.getcwd() + + if args.debug_flint: + if platform.system() == "Linux": + command.extend(["gdb", "--args"]) + elif platform.system() == "Windows": + command.extend(["devenv", "/debugexe"]) + else: + print("Debugging not available for current platform") + + command.append(os.path.join(flintdir, flintbin)) + command.extend(unknownargs) + + # Python pre 3.5 does not support run + return_code = 0 + if sys.version_info[1] < 5: + subprocess.call(command, env=env) + else: + return_code = subprocess.run(command, env=env).returncode + + exit(return_code) + +if __name__ == "__main__": + main() diff --git a/test/src/main.cpp b/test/src/main.cpp new file mode 100644 index 0000000..0178f7b --- /dev/null +++ b/test/src/main.cpp @@ -0,0 +1,138 @@ +#include "ecs-lua.h" + +#include + +struct Position : ecs::Component { + Position(float x, float y) : _x(x), _y(y) {} + + float _x; + float _y; +}; + +struct Velocity : ecs::Component{ + Velocity(float vx, float vy) : _vx(vx), _vy(vy) {} + + float _vx; + float _vy; +}; + +int main() { + sol::state lua; + lua.open_libraries(sol::lib::base); + + ecs::lua::init(lua); + + ecs::lua::register_component(lua, + "x", &Position::_x, + "y", &Position::_y + ); + + ecs::lua::register_component(lua, + "vx", &Velocity::_vx, + "vy", &Velocity::_vy + ); + + // This manages all our entities + ecs::Manager manager; + + lua.set_function("get_manager", [&manager] () -> ecs::Manager& { + return manager; + }); + + lua.script(R"lua( + manager = get_manager() + ent = manager:create_entity() + -- In the future we will be able to also write components in lua + -- @todo Figure out how get_component will work in this case + ent:add_component("Position", Position.new(1.9, 9.7)) + ent:add_component("Velocity", Velocity.new(0.2, 0.3)) + random = { + a = 10, + b = 11, + c = function(s) + print("Hello " .. s .. "!") + end + } + ent:add_component("Random", LuaWrapper.new(random)) + + print(ent:has_components("Position", "Velocity")) + pos = ent:get_component("Position") + print("x: " .. pos.x) + print("y: " .. pos.y) + vel = ent:get_component("Velocity") + print("v_x: " .. vel.vx) + print("v_y: " .. vel.vy) + + print("View test") + view = manager:view("Position", "Velocity") + view:for_each(function(ent) + pos = ent:get_component("Position") + vel = ent:get_component("Velocity") + + pos.x = pos.x + vel.vx + pos.y = pos.y + vel.vy + + print("x: " .. pos.x) + print("y: " .. pos.y) + + print("v_x: " .. vel.vx) + print("v_y: " .. vel.vy) + end) + + manager:view("Random"):for_each(function(ent) + wrapped = ent:get_component("Random").object + + print(wrapped.a) + wrapped.a = 11 + print(wrapped.a) + print(random.a) + random.a = 20 + print(wrapped.a) + print(random.a) + + random.c("you") + end) + )lua"); + + // for (int i = 0; i < 10; ++i) { + // // We can create entities + // Entity* entity = manager.create_entity(); + // // Then we can add components to them + // entity->add_component(0.0f, 0.0f); + // if (i % 2 == 0) { + // entity->add_component(0.1f, 0.2f); + // } + // + // // We can check for components by name + // if (entity->has_components()) { + // std::cout << "YES\n"; + // } else { + // std::cout << "NO\n"; + // } + // } + + std::cout << "Update position\n"; + manager.view().for_each([](ecs::Entity*, Position* pos, Velocity* vel) { + pos->_x += vel->_vx; + pos->_y += vel->_vy; + }); + + std::cout << "Show position!\n"; + manager.view().for_each([](ecs::Entity*, Position* pos) { + std::cout << "X: " << pos->_x << '\n'; + std::cout << "Y: " << pos->_y << '\n'; + }); + + manager.view({"Random"}).for_each([](ecs::Entity* entity) { + sol::table random = ((ecs::lua::LuaWrapper*)entity->get_component("Random"))->_object; + + random["a"] = 21; + std::cout << random["a"].get() << '\n'; + }); + + manager.view({"Random"}).for_each([](ecs::Entity* entity) { + sol::table random = ((ecs::lua::LuaWrapper*)entity->get_component("Random"))->_object; + + std::cout << random["a"].get() << '\n'; + }); +} diff --git a/vendor/headers/glfw/glfw_config.h b/vendor/headers/glfw/glfw_config.h new file mode 100644 index 0000000..fd0b7ce --- /dev/null +++ b/vendor/headers/glfw/glfw_config.h @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2010-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// As glfw_config.h.in, this file is used by CMake to produce the +// glfw_config.h configuration header file. If you are adding a feature +// requiring conditional compilation, this is where to add the macro. +//======================================================================== +// As glfw_config.h, this file defines compile-time option macros for a +// specific platform and development environment. If you are using the +// GLFW CMake files, modify glfw_config.h.in instead of this file. If you +// are using your own build system, make this file define the appropriate +// macros in whatever way is suitable. +//======================================================================== + +// Define this to 1 if building GLFW for X11 +// #cmakedefine _GLFW_X11 +// Define this to 1 if building GLFW for Win32 +// #cmakedefine _GLFW_WIN32 +// Define this to 1 if building GLFW for Cocoa +// #cmakedefine _GLFW_COCOA +// Define this to 1 if building GLFW for Wayland +// #cmakedefine _GLFW_WAYLAND +// Define this to 1 if building GLFW for OSMesa +// #cmakedefine _GLFW_OSMESA + +// Define this to 1 if building as a shared library / dynamic library / DLL +// #cmakedefine _GLFW_BUILD_DLL +// Define this to 1 to use Vulkan loader linked statically into application +// #cmakedefine _GLFW_VULKAN_STATIC + +// Define this to 1 to force use of high-performance GPU on hybrid systems +// #cmakedefine _GLFW_USE_HYBRID_HPG + +// Define this to 1 if xkbcommon supports the compose key +// #cmakedefine HAVE_XKBCOMMON_COMPOSE_H +// Define this to 1 if the libc supports memfd_create() +// #cmakedefine HAVE_MEMFD_CREATE + diff --git a/vendor/headers/glfw/mappings.h b/vendor/headers/glfw/mappings.h new file mode 100644 index 0000000..eb6c32f --- /dev/null +++ b/vendor/headers/glfw/mappings.h @@ -0,0 +1,73 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// As mappings.h.in, this file is used by CMake to produce the mappings.h +// header file. If you are adding a GLFW specific gamepad mapping, this is +// where to put it. +//======================================================================== +// As mappings.h, this provides all pre-defined gamepad mappings, including +// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad +// mappings not specific to GLFW should be submitted to SDL_GameControllerDB. +// This file can be re-generated from mappings.h.in and the upstream +// gamecontrollerdb.txt with the GenerateMappings.cmake script. +//======================================================================== + +// All gamepad mappings not labeled GLFW are copied from the +// SDL_GameControllerDB project under the following license: +// +// Simple DirectMedia Layer +// Copyright (C) 1997-2013 Sam Lantinga +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the +// use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. + +const char* _glfwDefaultMappings[] = +{ +@GLFW_GAMEPAD_MAPPINGS@ +"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", +NULL +}; + diff --git a/vendor/headers/lua.hpp b/vendor/headers/lua.hpp new file mode 100644 index 0000000..aa14d62 --- /dev/null +++ b/vendor/headers/lua.hpp @@ -0,0 +1,3 @@ +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" diff --git a/vendor/lua b/vendor/lua new file mode 160000 index 0000000..e354c63 --- /dev/null +++ b/vendor/lua @@ -0,0 +1 @@ +Subproject commit e354c6355e7f48e087678ec49e340ca0696725b1 diff --git a/vendor/sol2 b/vendor/sol2 new file mode 160000 index 0000000..6a60253 --- /dev/null +++ b/vendor/sol2 @@ -0,0 +1 @@ +Subproject commit 6a6025393f8c0756fb4225e71a2092ea1d51b3d4