diff --git a/.gitignore b/.gitignore index f203f51..e0e6fff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,15 @@ -dub.userprefs -dub.selections.json -.dub -/.vscode -LOC -perf.data -perf.data.old -*.o -*.a -*.obj -*.exe -*.lib -*.so -*.def -*.lib -*.dll -*.exp \ No newline at end of file +* +!source/** +!tests/** +!README.md +!dub.json +!.gitignore +!codecov.yml +!skeleton.html +!**/meson.build +!**/*.wrap +!meson_options.txt +!compile_wasm.py +!compile_android.py +!.gitlab-ci.yml +!LICENSE \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..f1d8ecc --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,107 @@ +default: + artifacts: + expire_in: 1 day + +stages: + - build + - test + - testcov + - build_wasm + - build_emscripten + - deploy + +build_code: + stage: build + image: "registry.gitlab.com/mergul/bubel-ecs:latest" + script: + - /bin/bash /compile_ecs.sh + artifacts: + expire_in: 1h + paths: + - binaries + allow_failure: true + +test_dmd_debug: + stage: test + image: debian:buster-slim + script: + - binaries/dmd_debug_unittest + artifacts: + reports: + junit: test_report.xml +test_dmd: + stage: test + image: debian:buster-slim + script: + - binaries/dmd_release_unittest + artifacts: + reports: + junit: test_report.xml +test_dmd_betterC: + stage: test + image: debian:buster-slim + script: + - binaries/dmd_debug_unittest_bc + artifacts: + reports: + junit: test_report.xml + +coverage_test_dmd: + stage: testcov + image: "registry.gitlab.com/mergul/bubel-ecs/curl:latest" + needs: ["test_dmd_debug", "build_code"] + dependencies: + - build_code + script: + - mkdir reports + - binaries/dmd_unittest_cov + after_script: + - bash <(curl -s https://codecov.io/bash) -s reports -t df87b1d8-85f4-4584-96e3-1315d27ec2c5 + +wasm: + stage: build_wasm + image: "registry.gitlab.com/mergul/bubel-ecs:latest" + script: + - /bin/bash /compile_wasm.sh + - /bin/bash /gen_doc.sh + artifacts: + expire_in: 1h + paths: + - build + rules: + - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_BRANCH == "master"' + when: always + allow_failure: true + +emscripten: + stage: build_emscripten + image: "registry.gitlab.com/mergul/bubel-ecs/emscripten:latest" + dependencies: + - wasm + script: + - /bin/bash /build.sh + rules: + - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_BRANCH == "master"' + when: always + artifacts: + expire_in: 1h + paths: + - wasm + +pages: + stage: deploy + image: frolvlad/alpine-glibc + dependencies: + - wasm + - emscripten + script: + - mkdir public + - cp -r wasm/* public/ + - cp -r build/public/* public/ + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + when: always + artifacts: + expire_in: 1h + paths: + - public diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ede0cb3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Dawid Masiukiewicz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 08cab68..14e6d75 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,211 @@ -# Dynamic Entity Component System +# Bubel Entity Component System +[![pipeline status](https://gitlab.com/Mergul/bubel-ecs/badges/master/pipeline.svg)](https://gitlab.com/Mergul/bubel-ecs/-/commits/master) +[![codecov](https://codecov.io/gl/Mergul/bubel-ecs/branch/master/graph/badge.svg?token=Unm0TJhFoW)](https://codecov.io/gl/Mergul/bubel-ecs) -Entity-Component-System implementation in D language. \ No newline at end of file +**Bubel ECS** is Entity-Component-System architectural pattern implementation in D language. +Library aims to delivery fast and flexible architecture for developing games. Library is **@nogc** and **betterC** compatible. WASM is supported thorugh Emscripten. +Project haven't any external dependencies. + +Bubel ECS was tested on Linux, Windows, Android and WASM. + +**Currently library is in beta stage so some significant API changes can appear.** + +Package is available on [DUB package repository](https://code.dlang.org/packages/bubel-ecs). Usage: +``` + "dependencies": { + "bubel-ecs": "~>0.1.1" + } +``` + +## Design + +For core information about Entity-Component-System architectural pattern please read definition described at [Wikipedia](https://en.wikipedia.org/wiki/Entity_component_system). + +Main design principles are: + + * **Data oriented design** - components memory is packed into tight blocks so iterating over entity components is cache friendly + * **Fast and safe EntityID** - every entity is referenced by its unique ID. Accessing by ID is safe even if entity doesn't exists. Accessing by ID is constant time operation. + * **Multithreading support** - whole library was developed with multithreading in mind. Adding components is thread-friendly so you get usable EntityID as early as possible. Operations like adding or removing components are deferred to end of frame. Dependencies between systems parallel execution are generated automatically. + * **Good logic separation** - system needs information only about components which it uses, there is no relation between systems. Systems can be compiled as multiple separate libraries and used together. + * **Flexible execution model** - system iterate over entities which meet specified conditions. Components can be marked as required, optional or excluded. Systems are exectued in specific order determined by system priority. + * **Builtin events handling** - library has builtin support for event handlig to makes easier communication between different entities. + * **Hot-reload** - hot-reloading for systems should be as easy as possible. In other words library should give functionality to support hot-reload of systems and components with minimal work. **(WIP!)**. + +There are some assumptions that should be considered when developing application: + + * Iterating over components throught system ```onUpdate()``` callback is fastest way of access data so it's should be main way of making calculations. + * Using direct access and events should be used very wisely and minimized. + * Direct component access is faster than events, because events must buffer memory and call multiple system handler callbacks. + * Components can be used to marking entities, assingment to systems and changing logic of entity in runtime. Using too much component based marking can lead to memory fragmentation and performence drop. + * Systems give great opporunity to separate game logic. Systems can be enabled and disabled easly in runtime. It's can be used to enabling some debug systems if needed. Additionaly this concept makes game logic changes easier to deal with. If you develop your application wisely it should be trivial to change some core logic by changing only several systems or adding some new. Every entity can easily takes some behaviour from different entity type by adding several components. + +### Features + + * ECS architectural pattern + * Data oriented design + * Safe identifiers (EntityID) + * EntityTemplates + * Basic events handling + * Easy systems ordering + * Runtime and fast components adding and removing + * Listeners for adding and removing entity components inside systems + * Update passes + * Calling custom callbacks for system entity groups + * betterC compatibility + * Emscripten compatibility + * Automatic multithreaded jobs generation + * External dependencies - ability to provide dependencies between systems which aren't related to components + * Compatibility with all big compilers: DMD, LDC, GDC. + +### Planned + + * Worlds - every world works as separate environment. Entities don't interact with entities from different world. Systems and components should be registered for every world separately. + * Hot-reload support - currently only reloading systems (their functions) works. There is possibility to serialize every entity and system, but it's should be provided by library itself with special callbacks and helpers. Additionaly planned is system which helps with taking new EntityID from serialized identifiers. + * Static components - this components will have different memory model and can be accessed only directly. It will be slower to access but won't trigger memory copy when component is added. It should fix problem with big components which isn't needed by systems iteration callbacks or is required rarely. + * Better EventManager - there are several optimization and improvements that can be added in the future (e.g. multithreading). + * More demos and examples - demo appliaction is very basic now, but in future more minigames and sanbox mode (opportunity to mix many components and systems) are planned. + * C API - it's highly depends on amount of work required. Makes it possible to use library from different languages. + * More smaller improvements... + +For more information about design and usage feel free to read [documentation](https://mergul.gitlab.io/bubel-ecs/ecs.html) and [WIKI](https://gitlab.com/Mergul/bubel-ecs/-/wikis/home)**(WIP)**. + +## Build Instructions + +To build library you needs recent D compiler and optionally Emscripten (with python) to build web version. Currenlty tested are: LDC, DMD and GDC. \ +Supported build systems are DUB and Meson. + +##### DUB +```shell +#available configurations: library, dynlib, library-betterC, dynlib-betterC, unittest-runner, unittest-runner-betterC +dub build -c library -b release +``` + +##### Meson +```shell +#use '-DbetterC=true ' to build betterC code +meson build . #add '--buildtype=release' to build release code +cd build +ninja +``` + +##### Emscripten +```shell +python compile_wasm.py -opt +``` + +##### Documentation +```shell +adrdox -i source/bubel/ecs/ -o docs/ -s skeleton.html +``` + +## Demos + +Repository contain demo application. You can check demo [online](https://mergul.gitlab.io/bubel-ecs/ecs_demo.html) or build it form source code using Meson. \ +Online demo support multithreading and page tries to check if client support WASM multithreading or not and loads proper JS and WASM code. It was tested on Chrome, Firefox, Opera, Brave on Linux, Windows and Android. On firefox there is problem with multithreaded version so if demo doesn't work please try to disable shared_memory in browser flags. + +Demos uses these libraries: SDL2, SDL2_Image, bindbc-loader, bindbc-sdl, cimgui, glad, mmutils. \ +C++ compiler is required for building dependencies. + +Meson is preferred way of building demos. It will download and compile dependencies automatically. DUB version is used only for library development. Build instructions: + +```shell +#use '-DbetterC=true ' to build betterC code +meson build . -DBuildDemos=true #add '--buildtype=release' to build release code +cd build +ninja +``` + +## Code example + +```d + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.attributes; +import std.array : staticArray; + +struct Position +{ + float x; + float y; +} + +struct Velocity +{ + //default values works + float x = 0.1; + float y = 1; +} + +struct StaticFlag +{ +} + +struct UpdateSystem +{ + mixin ECS.System; //makes struct system + + mixin ECS.ExcludedComponents!(StaticFlag); //prevents static entities from update + + struct EntitiesData + { + int length; //entities count + @readonly Entity[] entities; //entities arrays, entity contain ID only + Position[] positions; //positions array, by default components are considered to has write access (used for multithreading dependencies) + @readonly Velocity[] velocities; //veocities array, readonly (Multithreading tag) + } + + void onUpdate(EntitiesData data) //update callback, called multiple times per frame for every entities types + { + foreach(i; 0..data.length) //iterate over entities + { + data.positions[i].x += data.velocities[i].x; + data.positions[i].y += data.velocities[i].y; + } + } +} + +void main() +{ + //initialize ECS + EntityManager.initialize(); + + //begin registering process + gEntityManager.beginRegister(); + //register components + gEntityManager.registerComponent!Position; + gEntityManager.registerComponent!Velocity; + gEntityManager.registerComponent!StaticFlag; + //register system with priority 0 + gEntityManager.registerSystem!UpdateSystem(0); + //end registering process + gEntityManager.endRegister(); + + //allocate template + EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!Velocity, becsID!Position].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl); + + //gets pointer to template component data + Position* position = tmpl.getComponent!Position; + foreach(i; 0 .. 100) + { + position.x = i % 10; + position.y = i / 10; + gEntityManager.addEntity(tmpl); + } + + gEntityManager.begin(); //start frame, inside system onBegin callbacks are called + gEntityManager.update(); //update all systems, there onUpdate callbacks are called + gEntityManager.end(); //end frame, inside system onEnd callbacks are called*/ + + //free ECS data + EntityManager.destroy(); +} + +``` + +## Links + +Documentation: https://mergul.gitlab.io/bubel-ecs/ecs.html \ +Wiki: https://gitlab.com/Mergul/bubel-ecs/-/wikis/home \ +Online demo: https://mergul.gitlab.io/bubel-ecs/ecs_demo.html diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..5672706 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,10 @@ +ignore: + - "tests/*" + - "**/traits*" + +coverage: + status: + project: + default: + threshold: 5 + patch: off \ No newline at end of file diff --git a/compile_android.py b/compile_android.py new file mode 100644 index 0000000..15f04ea --- /dev/null +++ b/compile_android.py @@ -0,0 +1,78 @@ +import os +import ntpath +import sys + +def compile(sources, output): + files = [] + # r=root, d=directories, f = files + for path in sources: + for r, d, f in os.walk(path): + for file in f: + if ntpath.basename(file) != 'win_dll.d': + filename, file_extension = os.path.splitext(file) + if file_extension == '.d' and filename != 'package': + files.append(os.path.join(r, file)) + + ldc_path = 'ldc' + if 'LDC' in os.environ: + ldc_path = os.environ['LDC'] + + ldc_cmd = ldc_path + ' ' + ldc_flags + '-lib -mtriple=armv7-none-linux-androideabi -fvisibility=hidden -betterC -oq -od=obj/ --singleobj --of=' + output + ' ' + + for path in sources: + ldc_cmd += '-I' + path + ' ' + + for path in import_paths: + ldc_cmd += '-I' + path + ' ' + + for f in files: + ldc_cmd += f + ' ' + + print(ldc_cmd) + + if os.system(ldc_cmd): + exit(0) + print() + +clean = 0 +ldc_flags = '' +import_paths = ['source','tests'] +build_tests = 0 + +for arg in sys.argv[1:]: + if(arg == '-release'): + ldc_flags += '-release ' + elif(arg == '-enable-inlining'): + ldc_flags += '-enable-inlining ' + elif(arg == '-O3'): + ldc_flags += '-O3 ' + elif(arg == '-O2'): + ldc_flags += '-O2 ' + elif(arg == '-O1'): + ldc_flags += '-O1 ' + elif(arg == '-O0'): + ldc_flags += '-O0 ' + elif(arg == '-Os'): + ldc_flags += '-Os ' + elif(arg == '-Oz'): + ldc_flags += '-Oz ' + elif(arg == '-g'): + ldc_flags += '-g ' + elif(arg == '-opt'): + ldc_flags += '-release -enable-inlining -O3 ' + else: + print('unknown argument: ' + arg) + exit() + +compile(['source'], 'ecs.a') + +#export LDC_LIBS=/path/to/your/ldc-build-runtime.tmp/lib/ +CC = os.environ['NDK'] + '/toolchains/llvm/prebuilt/linux-x86_64/bin/clang' +TOOLCHAIN = os.environ['NDK'] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64' +SYSROOT = os.environ['NDK'] + '/platforms/android-21/arch-arm' +LDC_LIBS = ''#os.environ['LDC_LIBS'] + '/libphobos2-ldc.a ' + os.environ['LDC_LIBS'] + '/libdruntime-ldc.a' + +os.system(CC + ' -Wl,-soname,libecs.so -shared --sysroot=' + SYSROOT + ' obj/*.o ' + LDC_LIBS + ' -lgcc -gcc-toolchain ' + TOOLCHAIN + +' -no-canonical-prefixes -fuse-ld=bfd -target armv7-none-linux-androideabi -fvisibility=hidden \ +-Wl,--gc-sections -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro \ +-Wl,-z,now -mthumb -o libecs.so') diff --git a/compile_wasm.py b/compile_wasm.py new file mode 100644 index 0000000..7214801 --- /dev/null +++ b/compile_wasm.py @@ -0,0 +1,93 @@ +import os +import ntpath +import sys + +def compile(sources, output): + files = [] + # r=root, d=directories, f = files + for path in sources: + for r, d, f in os.walk(path): + for file in f: + if ntpath.basename(file) != 'win_dll.d': + filename, file_extension = os.path.splitext(file) + if file_extension == '.d' and filename != 'package': + files.append(os.path.join(r, file)) + + ldc_cmd = 'ldc2 ' + shared_flags + ldc_flags + '-oq -mtriple=wasm32-unknown-emscripten -betterC --output-bc --od=.bc --singleobj --checkaction=C --of=' + output + ' ' + + for path in sources: + ldc_cmd += '-I' + path + ' ' + + for path in import_paths: + ldc_cmd += '-I' + path + ' ' + + for f in files: + ldc_cmd += f + ' ' + + print(ldc_cmd) + + if os.system(ldc_cmd): + exit(0) + print() + +shared_flags = '' +clean = 0 +emc_flags = '' +ldc_flags = '' +import_paths = ['source','tests'] +build_tests = 0 + +for arg in sys.argv[1:]: + if(arg == '-release'): + ldc_flags += '-release ' + elif(arg == '-enable-inlining'): + ldc_flags += '-enable-inlining ' + elif(arg == '-O3'): + shared_flags += '-O3 ' + elif(arg == '-O2'): + shared_flags += '-O2 ' + elif(arg == '-O1'): + shared_flags += '-O1 ' + elif(arg == '-O0'): + shared_flags += '-O0 ' + elif(arg == '-Os'): + shared_flags += '-Os ' + elif(arg == '-Oz'): + shared_flags += '-Oz ' + elif(arg == '-g'): + shared_flags += '-g ' + elif(arg == '-g4'): + ldc_flags += '-g ' + emc_flags += '-g4 ' + elif(arg == '--build-tests'): + build_tests = 1 + elif(arg == '--llvm-lto'): + emc_flags += '--llvm-lto 3 ' + elif(arg == '--simd'): + emc_flags += '-s SIMD=1 ' + elif(arg == '-opt'): + shared_flags += '-O3 ' + ldc_flags += '-release -enable-inlining ' + emc_flags += '--llvm-lto 3 -s SIMD=1 ' + elif(arg == '-pthread'): + emc_flags += '-s PTHREAD_POOL_SIZE=16 -s USE_PTHREADS=1 ' + else: + print('unknown argument: ' + arg) + exit() + +compile(['source'], 'ecs.bc') + +if build_tests == 0: + exit(0) + +compile(['tests'], 'tests.bc') + +emcc_cmd = 'emcc -v ' + shared_flags + emc_flags + '-s ALLOW_MEMORY_GROWTH=1 -s WASM_MEM_MAX=1024MB -s MALLOC=dlmalloc -s WASM=1 -o index.html ' +#-s ALLOW_MEMORY_GROWTH=1 + +emcc_cmd += 'ecs.bc tests.bc' +#emcc_cmd += 'tests.bc' + +print(emcc_cmd) + +os.system(emcc_cmd) diff --git a/demos/.gitignore b/demos/.gitignore new file mode 100644 index 0000000..d137ce7 --- /dev/null +++ b/demos/.gitignore @@ -0,0 +1,20 @@ +* +!*/ +!**/dub.json +!libs/ +!*.dll +!libs/** +!utils/**/*.d +!source/**/*.d +!launcher/**/*.d +!assets/** +!external/**/*.d +!.gitignore +!compile_wasm.py +!cimgui.bc +!emscripten_shell.html +!emscripten_multi_shell.html +!compile_android.py +!**/meson.build +.dub +Android \ No newline at end of file diff --git a/demos/SDL2.dll b/demos/SDL2.dll new file mode 100644 index 0000000..0edb386 Binary files /dev/null and b/demos/SDL2.dll differ diff --git a/demos/SDL2_image.dll b/demos/SDL2_image.dll new file mode 100644 index 0000000..d701655 Binary files /dev/null and b/demos/SDL2_image.dll differ diff --git a/demos/assets/fonts/Ruda-Bold.ttf b/demos/assets/fonts/Ruda-Bold.ttf new file mode 100644 index 0000000..53ae69c Binary files /dev/null and b/demos/assets/fonts/Ruda-Bold.ttf differ diff --git a/demos/assets/shaders/additive_particles.fp b/demos/assets/shaders/additive_particles.fp new file mode 100644 index 0000000..df711a2 --- /dev/null +++ b/demos/assets/shaders/additive_particles.fp @@ -0,0 +1,54 @@ + +#ifdef GLES + precision mediump int; + precision mediump float; + precision lowp sampler2D; + precision lowp samplerCube; + #define TEX(x,y) texture2D(x,y) + #if __VERSION__ >290 + #define M_IN in mediump + #define L_IN in lowp + #else + #define M_IN varying mediump + #define L_IN varying lowp + #endif +#else + #define TEX(x,y) texture(x,y) + #if __VERSION__ > 320 + #define M_IN in + #define L_IN in + #else + #define M_IN varying + #define L_IN varying + #endif +#endif + + +M_IN vec2 uv; +M_IN vec4 color; +/* +#ifdef GLES + #if __VERSION__ >290 + in mediump vec2 uv; + #else + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + in vec2 uv; + #else + varying vec2 uv; + #endif +#endif*/ + +//layout(binding = 0)uniform sampler2D tex; + +uniform sampler2D tex; + +//layout(location = 0) out vec4 outColor; + +void main() +{ + gl_FragColor = /*TEX(tex,uv) **/ color; + if(gl_FragColor.a < 0.01)discard; +} diff --git a/demos/assets/shaders/additive_particles.vp b/demos/assets/shaders/additive_particles.vp new file mode 100644 index 0000000..cf90081 --- /dev/null +++ b/demos/assets/shaders/additive_particles.vp @@ -0,0 +1,107 @@ + +#ifdef GLES + precision highp float; + precision highp int; + precision lowp sampler2D; + precision lowp samplerCube; + #if __VERSION__ >290 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out mediump + #define L_OUT out lowp + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying mediump + #define L_OUT varying lowp + #endif +#else + #if __VERSION__ > 320 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out + #define L_OUT out + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying + #define L_OUT varying + #endif +#endif +/* +#ifdef GLES + #if __VERSION__ >290 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out mediump vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying vec2 uv; + #endif +#endif*/ + +#define VBO_BATCH 1 + +M_OUT vec2 uv; +L_OUT vec4 color; + +LOC(0) ATT vec2 positions; +LOC(1) ATT vec2 tex_coords; + +#ifdef VBO_BATCH + LOC(2) ATT float depth; + LOC(3) ATT vec4 vcolor; +#else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + uniform vec4 vcolor; + + float depth = matrix_2.z; +#endif + +void main() { + #ifdef VBO_BATCH + vec3 position = vec3(positions*4.0,1.0); + uv = tex_coords; + #else + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0); + uv = tex_coords * uv_transform.zw + uv_transform.xy; + #endif + + color = vcolor; + + gl_Position = vec4(position.xy,depth,1.0); + +} diff --git a/demos/assets/shaders/base.fp b/demos/assets/shaders/base.fp new file mode 100644 index 0000000..d667b24 --- /dev/null +++ b/demos/assets/shaders/base.fp @@ -0,0 +1,55 @@ + +#ifdef GLES + precision mediump int; + precision mediump float; + precision lowp sampler2D; + precision lowp samplerCube; + #define TEX(x,y) texture2D(x,y) + #if __VERSION__ >290 + #define M_IN in mediump + #define L_IN in lowp + #else + #define M_IN varying mediump + #define L_IN varying lowp + #endif +#else + #if __VERSION__ > 320 + #define TEX(x,y) texture(x,y) + #define M_IN in + #define L_IN in + #else + #define TEX(x,y) texture2D(x,y) + #define M_IN varying + #define L_IN varying + #endif +#endif + + +M_IN vec2 uv; +M_IN vec4 color; +/* +#ifdef GLES + #if __VERSION__ >290 + in mediump vec2 uv; + #else + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + in vec2 uv; + #else + varying vec2 uv; + #endif +#endif*/ + +//layout(binding = 0)uniform sampler2D tex; + +uniform sampler2D tex; + +//layout(location = 0) out vec4 outColor; + +void main() +{ + gl_FragColor = TEX(tex,uv) * color; + if(gl_FragColor.a < 0.01)discard; +} diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp new file mode 100644 index 0000000..333ae59 --- /dev/null +++ b/demos/assets/shaders/base.vp @@ -0,0 +1,107 @@ + +#ifdef GLES + precision highp float; + precision highp int; + precision lowp sampler2D; + precision lowp samplerCube; + #if __VERSION__ >290 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out mediump + #define L_OUT out lowp + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying mediump + #define L_OUT varying lowp + #endif +#else + #if __VERSION__ > 320 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out + #define L_OUT out + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying + #define L_OUT varying + #endif +#endif +/* +#ifdef GLES + #if __VERSION__ >290 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out mediump vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying vec2 uv; + #endif +#endif*/ + +#define VBO_BATCH 1 + +M_OUT vec2 uv; +L_OUT vec4 color; + +LOC(0) ATT vec2 positions; +LOC(1) ATT vec2 tex_coords; + +#ifdef VBO_BATCH + LOC(2) ATT float depth; + LOC(3) ATT vec4 vcolor; +#else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + uniform vec4 vcolor; + + float depth = matrix_2.z; +#endif + +void main() { + #ifdef VBO_BATCH + vec3 position = vec3(positions*4.0,1.0); + uv = tex_coords; + #else + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0); + uv = tex_coords * uv_transform.zw + uv_transform.xy; + #endif + + color = vcolor * 2.0; + + gl_Position = vec4(position.xy,depth,1.0); + +} diff --git a/demos/assets/shaders/circle.fp b/demos/assets/shaders/circle.fp new file mode 100644 index 0000000..dd0449c --- /dev/null +++ b/demos/assets/shaders/circle.fp @@ -0,0 +1,63 @@ + +#ifdef GLES + precision mediump int; + precision mediump float; + precision lowp sampler2D; + precision lowp samplerCube; + #define TEX(x,y) texture2D(x,y) + #if __VERSION__ >290 + #define M_IN in mediump + #define L_IN in lowp + #else + #define M_IN varying mediump + #define L_IN varying lowp + #endif +#else + #define TEX(x,y) texture(x,y) + #if __VERSION__ > 320 + #define M_IN in + #define L_IN in + #else + #define M_IN varying + #define L_IN varying + #endif +#endif + +M_IN vec2 pos; +M_IN float edge; +//flat M_IN vec2 fpos; + +//M_IN vec2 uv; +//M_IN vec4 color; +/* +#ifdef GLES + #if __VERSION__ >290 + in mediump vec2 uv; + #else + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + in vec2 uv; + #else + varying vec2 uv; + #endif +#endif*/ + +//layout(binding = 0)uniform sampler2D tex; + +//uniform sampler2D tex; + +//layout(location = 0) out vec4 outColor; + +void main() +{ + float len2 = dot(pos,pos); + + if(len2 > 1.0)discard; + + if(len2 > edge)gl_FragColor = vec4(0.4,0.8,1.0,0.8);//TEX(tex,uv) * color; + else gl_FragColor = vec4(0,0.6,1.0,0.35);//TEX(tex,uv) * color; + //gl_FragColor = vec4(pos,0,1); + //if(gl_FragColor.a < 0.01)discard; +} diff --git a/demos/assets/shaders/circle.vp b/demos/assets/shaders/circle.vp new file mode 100644 index 0000000..9c1b85c --- /dev/null +++ b/demos/assets/shaders/circle.vp @@ -0,0 +1,115 @@ + +#ifdef GLES + precision highp float; + precision highp int; + precision lowp sampler2D; + precision lowp samplerCube; + #if __VERSION__ >290 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out mediump + #define L_OUT out lowp + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying mediump + #define L_OUT varying lowp + #endif +#else + #if __VERSION__ > 320 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out + #define L_OUT out + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying + #define L_OUT varying + #endif +#endif +/* +#ifdef GLES + #if __VERSION__ >290 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out mediump vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying vec2 uv; + #endif +#endif*/ + +//#define VBO_BATCH 1 + +//M_OUT vec2 uv; +//L_OUT vec4 color; +M_OUT vec2 pos; +M_OUT float edge; +//flat M_OUT vec2 fpos; + +LOC(0) ATT vec2 positions; +//LOC(1) ATT vec2 tex_coords; + +#ifdef VBO_BATCH + LOC(2) ATT float depth; + LOC(3) ATT vec4 vcolor; +#else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + //uniform vec4 uv_transform; + //uniform vec4 vcolor; + + //float depth = matrix_2.z; +#endif + +void main() { + //#ifdef VBO_BATCH + // vec3 position = vec3(positions*4.0,1.0); + // uv = tex_coords; + //#else + //edge = mix(0.1, 0.96, (matrix_2.z / 256)); + edge = (matrix_1.w - matrix_2.z) / matrix_1.w;//matrix_2.z;//clamp((matrix_2,0.0,1.0); + edge *= edge; + pos = positions * 2.0;// / matrix_2.zw * 2; + //fpos = positions * matrix_2.xy; + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0); + // uv = tex_coords * uv_transform.zw + uv_transform.xy; + //#endif + + //color = vcolor * 2.0; + + gl_Position = vec4(position.xy,0,1.0); + +} diff --git a/demos/assets/textures/apple.png b/demos/assets/textures/apple.png new file mode 100644 index 0000000..63d8fb4 Binary files /dev/null and b/demos/assets/textures/apple.png differ diff --git a/demos/assets/textures/atlas.png b/demos/assets/textures/atlas.png new file mode 100644 index 0000000..b84c3fa Binary files /dev/null and b/demos/assets/textures/atlas.png differ diff --git a/demos/assets/textures/buckler.png b/demos/assets/textures/buckler.png new file mode 100644 index 0000000..243f747 Binary files /dev/null and b/demos/assets/textures/buckler.png differ diff --git a/demos/assets/textures/snake.png b/demos/assets/textures/snake.png new file mode 100644 index 0000000..7bc34f0 Binary files /dev/null and b/demos/assets/textures/snake.png differ diff --git a/demos/assets/textures/snake_head.png b/demos/assets/textures/snake_head.png new file mode 100644 index 0000000..9c8dbae Binary files /dev/null and b/demos/assets/textures/snake_head.png differ diff --git a/demos/assets/textures/snake_horizontal.png b/demos/assets/textures/snake_horizontal.png new file mode 100644 index 0000000..1859449 Binary files /dev/null and b/demos/assets/textures/snake_horizontal.png differ diff --git a/demos/cimgui.bc b/demos/cimgui.bc new file mode 100644 index 0000000..e248fd9 Binary files /dev/null and b/demos/cimgui.bc differ diff --git a/demos/cimgui.dll b/demos/cimgui.dll new file mode 100644 index 0000000..ef645de Binary files /dev/null and b/demos/cimgui.dll differ diff --git a/demos/compile_android.py b/demos/compile_android.py new file mode 100644 index 0000000..75d6106 --- /dev/null +++ b/demos/compile_android.py @@ -0,0 +1,91 @@ +import os +import ntpath +import sys + +def compile(sources, output): + files = [] + # r=root, d=directories, f = files + for path in sources: + for r, d, f in os.walk(path): + for file in f: + if ntpath.basename(file) != 'win_dll.d': + filename, file_extension = os.path.splitext(file) + if file_extension == '.d': + files.append(os.path.join(r, file)) + + ldc_path = 'ldc' + if 'LDC' in os.environ: + ldc_path = os.environ['LDC'] + + ldc_cmd = ldc_path + ' ' + ldc_flags + '-lib -mtriple=armv7-none-linux-androideabi -fvisibility=hidden -betterC -oq -od=obj/ --singleobj --of=' + output + ' ' + + for path in sources: + ldc_cmd += '-I' + path + ' ' + + for path in import_paths: + ldc_cmd += '-I' + path + ' ' + + for f in files: + ldc_cmd += f + ' ' + + print(ldc_cmd) + + if os.system(ldc_cmd): + print('some kind of error') + exit(0) + print() + +clean = 0 +ldc_flags = '--d-version=SDL_209 --d-version=BindSDL_Image --d-version=MM_USE_POSIX_THREADS ' +#import_paths = ['source','tests'] +import_paths = ['external/android','external/sources', 'external/imports', 'external/wasm_imports', '../source', 'utils/source', 'simple/source'] +build_tests = 0 + +for arg in sys.argv[1:]: + if(arg == '-release'): + ldc_flags += '-release ' + elif(arg == '-enable-inlining'): + ldc_flags += '-enable-inlining ' + elif(arg == '-O3'): + ldc_flags += '-O3 ' + elif(arg == '-O2'): + ldc_flags += '-O2 ' + elif(arg == '-O1'): + ldc_flags += '-O1 ' + elif(arg == '-O0'): + ldc_flags += '-O0 ' + elif(arg == '-Os'): + ldc_flags += '-Os ' + elif(arg == '-Oz'): + ldc_flags += '-Oz ' + elif(arg == '-g'): + ldc_flags += '-g ' + elif(arg == '-opt'): + ldc_flags += '-release -enable-inlining -O3 ' + else: + print('unknown argument: ' + arg) + exit() + +#compile(['source'], 'ecs.a') +compile(['external/wasm_imports/bindbc/sdl'], 'build/bindbc-sdl.a') +compile(['utils/source'], 'build/utils.a') +compile(['external/sources/mmutils'], 'build/mmutils.a') +compile(['external/sources/glad'], 'build/glad.a') +compile(['external/android/bindbc'], 'build/bindbc.a') +compile(['source'], 'build/demo.a') + +#compile(['external/wasm_imports/bindbc/sdl','utils/source','external/sources/mmutils','external/sources/glad'], 'build/asd.a') + +#export LDC_LIBS=/path/to/your/ldc-build-runtime.tmp/lib/ +CC = os.environ['NDK'] + '/toolchains/llvm/prebuilt/linux-x86_64/bin/clang' +TOOLCHAIN = os.environ['NDK'] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64' +SYSROOT = os.environ['NDK'] + '/platforms/android-21/arch-arm' +#LDC_LIBS = os.environ['LDC_LIBS'] + '/libphobos2-ldc.a ' + os.environ['LDC_LIBS'] + '/libdruntime-ldc.a' +LDC_LIBS = '' +LIBS = '-L/platforms/android-21/arch-arm/usr/lib' + +os.system(CC + ' -Wl,-soname,libdemos.so -shared --sysroot=' + SYSROOT + ' ../obj/*.o obj/*.o ' + LDC_LIBS + ' -lgcc -gcc-toolchain ' + TOOLCHAIN + +' -no-canonical-prefixes -fuse-ld=bfd -target armv7-none-linux-androideabi -fvisibility=hidden \ +-Wl,--gc-sections -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro \ +-Wl,-z,now -mthumb -lm -lc -Llibs/armeabi-v7a -lcimgui -o libdemos.so') + diff --git a/demos/compile_wasm.py b/demos/compile_wasm.py new file mode 100644 index 0000000..b178260 --- /dev/null +++ b/demos/compile_wasm.py @@ -0,0 +1,142 @@ +import os +import ntpath +import sys + +def compile(sources, output): + files = [] + # r=root, d=directories, f = files + for path in sources: + for r, d, f in os.walk(path): + for file in f: + if ntpath.basename(file) != 'win_dll.d': + filename, file_extension = os.path.splitext(file) + if file_extension == '.d' and filename != 'package': + files.append(os.path.join(r, file)) + + ldc_cmd = compiler + shared_flags + ldc_flags + '-oq -mtriple=wasm32-unknown-emscripten -betterC --output-bc --od=.bc --singleobj --checkaction=C --of=' + output + ' ' + + for path in sources: + ldc_cmd += '-I' + path + ' ' + + for path in import_paths: + ldc_cmd += '-I' + path + ' ' + + for f in files: + ldc_cmd += f + ' ' + + print(ldc_cmd) + + if os.system(ldc_cmd): + exit(0) + print() + + +compiler = 'ldc2 ' +#compiler = 'ldmd2 -vtls ' +shared_flags = '' +clean = 0 +demo = 0 +only_bc = 0 +multi = 0 +sources = ['tests', 'source'] +emc_flags = '-s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS="[\'png\']" ' +ldc_flags = '--d-version=SDL_209 --d-version=BindSDL_Static --d-version=BindSDL_Image --d-version=MM_USE_POSIX_THREADS ' +import_paths = ['external/sources', 'external/imports', 'external/wasm_imports', '../source', 'utils/source', 'simple/source'] + +for arg in sys.argv[1:]: + if(arg == '-release'): + ldc_flags += '-release ' + elif(arg == '-enable-inlining'): + ldc_flags += '-enable-inlining ' + elif(arg == '-O3'): + shared_flags += '-O3 ' + elif(arg == '-O2'): + shared_flags += '-O2 ' + elif(arg == '-O1'): + shared_flags += '-O1 ' + elif(arg == '-O0'): + shared_flags += '-O0 ' + elif(arg == '-Os'): + shared_flags += '-Os ' + elif(arg == '-Oz'): + shared_flags += '-Oz ' + elif(arg == '-g'): + shared_flags += '-g ' + elif(arg == '--multi'): + multi = 1 + elif(arg == '-g4'): + ldc_flags += '-g ' + emc_flags += '-g4 --source-map-base ./ ' + elif(arg == '--llvm-lto'): + emc_flags += '--llvm-lto 3 ' + elif(arg == '--simd'): + emc_flags += '-s SIMD=1 ' + elif(arg == '-opt'): + shared_flags += '-O3 ' + ldc_flags += '-release -enable-inlining ' + emc_flags += '--llvm-lto 3 -s SIMD=1 ' + elif(arg == '-quiet'): + emc_flags += "-Wl,--no-check-features " + elif(arg == '--clean'): + clean = 1 + elif(arg == '-pthread'): + emc_flags += '-s USE_PTHREADS=1 ' + elif(arg == '--demo=simple'): + demo = 0 + elif(arg == '--only-bc'): + only_bc = 1 + else: + print('unknown argument: ' + arg) + exit() + +compile(['external/wasm_imports/bindbc/sdl'], 'bindbc-sdl.bc') +compile(['utils/source'], 'utils.bc') +compile(['external/sources/mmutils'], 'mmutils.bc') +compile(['external/sources/glad'], 'glad.bc') +compile(['source'], 'demo.bc') + +if clean or os.path.exists('../ecs.bc') == 0 or os.path.isfile('../ecs.bc') == 0: + compile(['../source'], '../ecs.bc') + +if only_bc: + exit() + +if multi: + emcc_cmd = 'emcc ' + shared_flags + emc_flags + '--pre-js build/assets.js -s FORCE_FILESYSTEM=1 -s MAX_WEBGL_VERSION=2 --emrun -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ALLOW_MEMORY_GROWTH=1 -s WASM_MEM_MAX=2048MB -s MALLOC=dlmalloc -s WASM=1 {0} -o {1} --shell-file emscripten_multi_shell.html ' +else: + emcc_cmd = 'emcc ' + shared_flags + emc_flags + '--pre-js build/assets.js -s FORCE_FILESYSTEM=1 -s MAX_WEBGL_VERSION=2 --emrun -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ALLOW_MEMORY_GROWTH=1 -s WASM_MEM_MAX=2048MB -s MALLOC=dlmalloc -s WASM=1 -o build/ecs_demo.html --shell-file emscripten_shell.html ' + +#emcc_cmd = 'emcc -v ' + shared_flags + emc_flags + '-s MAX_WEBGL_VERSION=2 --emrun -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ALLOW_MEMORY_GROWTH=1 -s WASM_MEM_MAX=2048MB -s MALLOC=dlmalloc -s WASM=1 -o build/ecs_demo.html --shell-file emscripten_shell.html ' +#-s ALLOW_MEMORY_GROWTH=1 -s PROXY_TO_PTHREAD=1 -Wl,--no-check-features -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s TOTAL_MEMORY=512MB +#-s MAX_WEBGL_VERSION=2 + +emcc_cmd += '../ecs.bc ' +emcc_cmd += 'utils.bc ' +emcc_cmd += 'bindbc-sdl.bc ' +emcc_cmd += 'glad.bc ' +emcc_cmd += 'cimgui.bc ' +emcc_cmd += 'mmutils.bc ' +emcc_cmd += 'demo.bc ' + +os.system("mkdir build") + +# emscripten = imp.load_source('', os.path.expanduser("~") + '/.emscripten') +# pack_cmd = emscripten.EMSCRIPTEN_ROOT + '/tools/file_packager.py build/assets.data --preload assets --js-output=build/assets.js' +pack_cmd = os.path.expandvars('$EMSDK/upstream/emscripten') + '/tools/file_packager.py build/assets.data --preload assets --js-output=build/assets.js' +print('Packafing files: ' + pack_cmd) + +os.system(pack_cmd) + +if multi: + final_cmd = emcc_cmd.format('','build/ecs_demo.html') + print(final_cmd) + os.system(final_cmd) + final_cmd = emcc_cmd.format('-s USE_PTHREADS=1','build/ecs_demo_mt.js') + print(final_cmd) + os.system(final_cmd) +else: + print(emcc_cmd) + os.system(emcc_cmd) + +os.system('rm build/assets.js') + diff --git a/demos/dub.json b/demos/dub.json new file mode 100644 index 0000000..1c1fe65 --- /dev/null +++ b/demos/dub.json @@ -0,0 +1,45 @@ +{ + "name": "demo", + "authors": [ + "Michał Masiukiewicz", "Dawid Masiukiewicz" + ], + "description": "Dynamic Entity Component System simple example", + "copyright": "Copyright © 2018-2019, Michał Masiukiewicz, Dawid Masiukiewicz", + "license": "BSD 3-clause", + "dependencies": { + "ecs_utils":{"path":"utils/"} + }, + "sourcePaths": [ + "source" + ], + "importPaths": [ + "source" + ], + "libs-windows-x86_64": ["libs/windows/x64/SDL2","libs/windows/x64/SDL2_Image","libs/windows/x64/cimgui"], + "libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"], + "lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"], + "dflags-ldc" : [ + "--ffast-math" + ], + "configurations" : [ + { + "name" : "default", + "targetType" : "executable", + "subConfigurations": + { + "ecs_utils":"default" + } + }, + { + "name" : "betterC", + "targetType" : "executable", + "dflags": [ + "-betterC" + ], + "subConfigurations": + { + "ecs_utils":"betterC" + } + } + ] +} \ No newline at end of file diff --git a/demos/emscripten_multi_shell.html b/demos/emscripten_multi_shell.html new file mode 100644 index 0000000..c0b5598 --- /dev/null +++ b/demos/emscripten_multi_shell.html @@ -0,0 +1,170 @@ + + + + + + ECS Demo + + + + +
emscripten
+
Downloading...
+
+ +
+
+ +
+ + +
+ +
+ + + + diff --git a/demos/emscripten_shell.html b/demos/emscripten_shell.html new file mode 100644 index 0000000..a657766 --- /dev/null +++ b/demos/emscripten_shell.html @@ -0,0 +1,154 @@ + + + + + + ECS Demo + + + + +
emscripten
+
Downloading...
+
+ +
+
+ +
+ + +
+ +
+ + {{{ SCRIPT }}} + + diff --git a/demos/external/android/bindbc/loader/package.d b/demos/external/android/bindbc/loader/package.d new file mode 100644 index 0000000..3ed4e31 --- /dev/null +++ b/demos/external/android/bindbc/loader/package.d @@ -0,0 +1,11 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.loader; + +public +import bindbc.loader.sharedlib, + bindbc.loader.system; \ No newline at end of file diff --git a/demos/external/android/bindbc/loader/sharedlib.d b/demos/external/android/bindbc/loader/sharedlib.d new file mode 100644 index 0000000..ca3c654 --- /dev/null +++ b/demos/external/android/bindbc/loader/sharedlib.d @@ -0,0 +1,282 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.loader.sharedlib; + +import core.stdc.stdlib; +import core.stdc.string; + +/// Handle to a shared library +struct SharedLib { + private void* _handle; +} + +/// Indicates an uninitialized or unassigned handle. +enum invalidHandle = SharedLib.init; + +// Contains information about shared library and symbol load failures. +struct ErrorInfo { +private: + char[32] _error; + char[96] _message; + +public @nogc nothrow @property: + /** + Returns the string "Missing Symbol" to indicate a symbol load failure, and + the name of a library to indicate a library load failure. + */ + const(char)* error() const { return _error.ptr; } + + /** + Returns a symbol name for symbol load failures, and a system-specific error + message for library load failures. + */ + const(char)* message() const { return _message.ptr; } +} + +private { + __gshared ErrorInfo[] _errors; + __gshared size_t _errorCount; +} + +@nogc nothrow: + +/** + Returns an slice containing all errors that have been accumulated by the + `load` and `bindSymbol` functions since the last call to `resetErrors`. +*/ +const(ErrorInfo)[] errors() +{ + return _errors[0 .. _errorCount]; +} + +/** + Returns the total number of errors that have been accumulated by the + `load` and `bindSymbol` functions since the last call to `resetErrors`. +*/ +size_t errorCount() +{ + return _errorCount; +} + +/** + Sets the error count to 0 and erases all accumulated errors. This function + does not release any memory allocated for the error list. +*/ +void resetErrors() +{ + _errorCount = 0; + memset(_errors.ptr, 0, _errors.length * ErrorInfo.sizeof); +} + +/* +void freeErrors() +{ + free(_errors.ptr); + _errors.length = _errorCount = 0; +} +*/ + +/** + Loads a symbol from a shared library and assigns it to a caller-supplied pointer. + + Params: + lib = a valid handle to a shared library loaded via the `load` function. + ptr = a pointer to a function or variable pointer whose declaration is + appropriate for the symbol being bound (it is up to the caller to + verify the types match). + symbolName = the name of the symbol to bind. +*/ +void bindSymbol(SharedLib lib, void** ptr, const(char)* symbolName) +{ + // Without this, DMD can hang in release builds + pragma(inline, false); + + assert(lib._handle); + auto sym = loadSymbol(lib._handle, symbolName); + if(sym) { + *ptr = sym; + } + else { + addErr("Missing Symbol", symbolName); + } +} + +/** + Formats a symbol using the Windows stdcall mangling if necessary before passing it on to + bindSymbol. + + Params: + lib = a valid handle to a shared library loaded via the `load` function. + ptr = a pointer to a function or variable pointer whose declaration is + appropriate for the symbol being bound (it is up to the caller to + verify the types match). + symbolName = the name of the symbol to bind. +*/ +void bindSymbol_stdcall(Func)(SharedLib lib, ref Func f, const(char)* symbolName) +{ + import bindbc.loader.system : bindWindows, bind32; + + static if(bindWindows && bind32) { + import core.stdc.stdio : snprintf; + import std.traits : ParameterTypeTuple; + + uint paramSize(A...)(A args) + { + size_t sum = 0; + foreach(arg; args) { + sum += arg.sizeof; + + // Align on 32-bit stack + if((sum & 3) != 0) { + sum += 4 - (sum & 3); + } + } + return sum; + } + + ParameterTypeTuple!f params; + char[128] mangled; + snprintf(mangled.ptr, mangled.length, "_%s@%d", symbolName, paramSize(params)); + symbolName = mangled.ptr; + } + bindSymbol(lib, cast(void**)&f, symbolName); +} + +/** + Loads a shared library from disk, using the system-specific API and search rules. + + libName = the name of the library to load. May include the full or relative + path for the file. +*/ +SharedLib load(const(char)* libName) +{ + auto handle = loadLib(libName); + if(handle) return SharedLib(handle); + else { + addErr(libName, null); + return invalidHandle; + } +} + +/** + Unloads a shared library from process memory. + + Generally, it is not necessary to call this function at program exit, as the system will ensure + any shared libraries loaded by the process will be unloaded then. However, any loaded shared + libraries that are no longer needed by the program during runtime, such as those that are part + of a "hot swap" mechanism, should be unloaded to free up resources. +*/ +void unload(ref SharedLib lib) { + if(lib._handle) { + unloadLib(lib._handle); + lib = invalidHandle; + } +} + +private: +void allocErrs() { + size_t newSize = _errorCount == 0 ? 16 : _errors.length * 2; + auto errs = cast(ErrorInfo*)malloc(ErrorInfo.sizeof * newSize); + if(!errs) exit(EXIT_FAILURE); + + if(_errorCount > 0) { + memcpy(errs, _errors.ptr, ErrorInfo.sizeof * _errors.length); + free(_errors.ptr); + } + + _errors = errs[0 .. newSize]; +} + +void addErr(const(char)* errstr, const(char)* message) +{ + if(_errors.length == 0 || _errorCount >= _errors.length) { + allocErrs(); + } + + auto pinfo = &_errors[_errorCount]; + strcpy(pinfo._error.ptr, errstr); + + if(message) { + strncpy(pinfo._message.ptr, message, pinfo._message.length); + pinfo._message[pinfo._message.length - 1] = 0; + } + else { + sysError(pinfo._message.ptr, pinfo._message.length); + } + ++_errorCount; +} + +version(Windows) +{ + import core.sys.windows.windows; + + void* loadLib(const(char)* name) + { + return LoadLibraryA(name); + } + + void unloadLib(void* lib) + { + FreeLibrary(lib); + } + + void* loadSymbol(void* lib, const(char)* symbolName) + { + return GetProcAddress(lib, symbolName); + } + + void sysError(char* buf, size_t len) + { + char* msgBuf; + enum uint langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); + + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + null, + GetLastError(), + langID, + cast(char*)&msgBuf, + 0, + null + ); + + if(msgBuf) { + strncpy(buf, msgBuf, len); + buf[len - 1] = 0; + LocalFree(msgBuf); + } + else strncpy(buf, "Unknown Error\0", len); + } +} +else version(Posix) { + import core.sys.posix.dlfcn; + + void* loadLib(const(char)* name) + { + return dlopen(name, RTLD_NOW); + } + + void unloadLib(void* lib) + { + dlclose(lib); + } + + void* loadSymbol(void* lib, const(char)* symbolName) + { + return dlsym(lib, symbolName); + } + + void sysError(char* buf, size_t len) + { + const (char)* msg = dlerror(); + strncpy(buf, msg != null ? msg : "Unknown Error", len); + buf[len - 1] = 0; + } +} +else static assert(0, "bindbc-loader is not implemented on this platform."); \ No newline at end of file diff --git a/demos/external/android/bindbc/loader/system.d b/demos/external/android/bindbc/loader/system.d new file mode 100644 index 0000000..c721100 --- /dev/null +++ b/demos/external/android/bindbc/loader/system.d @@ -0,0 +1,55 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.loader.system; + +static if((void*).sizeof == 8) { + enum bind64 = true; + enum bind32 = false; +} +else { + enum bind64 = false; + enum bind32 = true; +} + +version(Windows) enum bindWindows = true; +else enum bindWindows = false; + +version(OSX) enum bindMac = true; +else enum bindMac = false; + +version(linux) enum bindLinux = true; +else enum bindLinux = false; + +version(Posix) enum bindPosix = true; +else enum bindPosix = false; + +version(Android) enum bindAndroid = true; +else enum bindAndroid = false; + +enum bindIOS = false; +enum bindWinRT = false; + +version(FreeBSD) { + enum bindBSD = true; + enum bindFreeBSD = true; + enum bindOpenBSD = false; +} +else version(OpenBSD) { + enum bindBSD = true; + enum bindFreeBSD = false; + enum bindOpenBSD = true; +} +else version(BSD) { + enum bindBSD = true; + enum bindFreeBSD = false; + enum bindOpenBSD = false; +} +else { + enum bindBSD = false; + enum bindFreeBSD = false; + enum bindOpenBSD = false; +} \ No newline at end of file diff --git a/demos/external/meson.build b/demos/external/meson.build new file mode 100644 index 0000000..0bfd84c --- /dev/null +++ b/demos/external/meson.build @@ -0,0 +1,12 @@ +demos_src += files( + 'sources/cimgui/cimgui.d', + 'sources/glad/gl/all.d', + 'sources/glad/gl/enums.d', + 'sources/glad/gl/ext.d', + 'sources/glad/gl/funcs.d', + 'sources/glad/gl/gl.d', + 'sources/glad/gl/gles2.d', + 'sources/glad/gl/loader.d', + 'sources/glad/gl/types.d', + 'sources/mmutils/thread_pool.d', +) \ No newline at end of file diff --git a/demos/external/sources/cimgui/cimgui.d b/demos/external/sources/cimgui/cimgui.d new file mode 100644 index 0000000..1fc119f --- /dev/null +++ b/demos/external/sources/cimgui/cimgui.d @@ -0,0 +1,1998 @@ +//This file is automatically generated by generator.lua from https://github.com/cimgui/cimgui +//based on imgui.h file version "1.73" from Dear ImGui https://github.com/ocornut/imgui +module cimgui.cimgui; + +// import core.stdc.stdarg; +//import core.stdc.stdio; + +version(WebAssembly) +{ + alias va_list = char*; + pragma(LDC_va_start) + void va_start(T)(out va_list ap, ref T parmn) @nogc; +} +else import core.stdc.stdarg; + +extern (C): + +//alias ImU64 = ulong; + +//typedef unsigned long long ImU64; + +//UDT stuff +struct ImVec2_Simple +{ + float x; + float y; +} + +struct ImVec4_Simple +{ + float x; + float y; + float z; + float w; +} + +struct ImColor_Simple +{ + ImVec4_Simple Value; +} + +struct ImGuiContext; +struct ImDrawListSharedData; + +alias ImTextureID = void*; +alias ImGuiID = uint; +alias ImWchar = ushort; +alias ImGuiCol = int; +alias ImGuiCond = int; +alias ImGuiDataType = int; +alias ImGuiDir = int; +alias ImGuiKey = int; +alias ImGuiNavInput = int; +alias ImGuiMouseCursor = int; +alias ImGuiStyleVar = int; +alias ImDrawCornerFlags = int; +alias ImDrawListFlags = int; +alias ImFontAtlasFlags = int; +alias ImGuiBackendFlags = int; +alias ImGuiColorEditFlags = int; +alias ImGuiConfigFlags = int; +alias ImGuiComboFlags = int; +alias ImGuiDragDropFlags = int; +alias ImGuiFocusedFlags = int; +alias ImGuiHoveredFlags = int; +alias ImGuiInputTextFlags = int; +alias ImGuiSelectableFlags = int; +alias ImGuiTabBarFlags = int; +alias ImGuiTabItemFlags = int; +alias ImGuiTreeNodeFlags = int; +alias ImGuiWindowFlags = int; +alias ImGuiInputTextCallback = int function (ImGuiInputTextCallbackData* data); +alias ImGuiSizeCallback = void function (ImGuiSizeCallbackData* data); +alias ImS8 = byte; +alias ImU8 = ubyte; +alias ImS16 = short; +alias ImU16 = ushort; +alias ImS32 = int; +alias ImU32 = uint; +alias ImS64 = long; +alias ImU64 = ulong; +alias ImDrawCallback = void function (const(ImDrawList)* parent_list, const(ImDrawCmd)* cmd); +alias ImDrawIdx = ushort; + +struct ImVector +{ + int Size; + int Capacity; + void* Data; +} + +struct ImVector_float +{ + int Size; + int Capacity; + float* Data; +} + +struct ImVector_ImWchar +{ + int Size; + int Capacity; + ImWchar* Data; +} + +struct ImVector_ImDrawVert +{ + int Size; + int Capacity; + ImDrawVert* Data; +} + +struct ImVector_ImFontGlyph +{ + int Size; + int Capacity; + ImFontGlyph* Data; +} + +struct ImVector_ImGuiTextRange +{ + int Size; + int Capacity; + ImGuiTextRange* Data; +} + +struct ImVector_ImGuiStoragePair +{ + int Size; + int Capacity; + ImGuiStoragePair* Data; +} + +struct ImVector_ImDrawChannel +{ + int Size; + int Capacity; + ImDrawChannel* Data; +} + +struct ImVector_char +{ + int Size; + int Capacity; + char* Data; +} + +struct ImVector_ImU32 +{ + int Size; + int Capacity; + ImU32* Data; +} + +struct ImVector_ImFontAtlasCustomRect +{ + int Size; + int Capacity; + ImFontAtlasCustomRect* Data; +} + +struct ImVector_ImTextureID +{ + int Size; + int Capacity; + ImTextureID* Data; +} + +struct ImVector_ImFontConfig +{ + int Size; + int Capacity; + ImFontConfig* Data; +} + +struct ImVector_ImFontPtr +{ + int Size; + int Capacity; + ImFont** Data; +} + +struct ImVector_ImDrawCmd +{ + int Size; + int Capacity; + ImDrawCmd* Data; +} + +struct ImVector_ImVec4 +{ + int Size; + int Capacity; + ImVec4* Data; +} + +struct ImVector_ImDrawIdx +{ + int Size; + int Capacity; + ImDrawIdx* Data; +} + +struct ImVector_ImVec2 +{ + int Size; + int Capacity; + ImVec2* Data; +} + +struct ImVec2 +{ + float x; + float y; +} + +struct ImVec4 +{ + float x; + float y; + float z; + float w; +} + +enum ImGuiWindowFlags_ +{ + ImGuiWindowFlags_None = 0, + ImGuiWindowFlags_NoTitleBar = 1 << 0, + ImGuiWindowFlags_NoResize = 1 << 1, + ImGuiWindowFlags_NoMove = 1 << 2, + ImGuiWindowFlags_NoScrollbar = 1 << 3, + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, + ImGuiWindowFlags_NoCollapse = 1 << 5, + ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, + ImGuiWindowFlags_NoBackground = 1 << 7, + ImGuiWindowFlags_NoSavedSettings = 1 << 8, + ImGuiWindowFlags_NoMouseInputs = 1 << 9, + ImGuiWindowFlags_MenuBar = 1 << 10, + ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, + ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, + ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, + ImGuiWindowFlags_AlwaysVerticalScrollbar = 1 << 14, + ImGuiWindowFlags_AlwaysHorizontalScrollbar = 1 << 15, + ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, + ImGuiWindowFlags_NoNavInputs = 1 << 18, + ImGuiWindowFlags_NoNavFocus = 1 << 19, + ImGuiWindowFlags_UnsavedDocument = 1 << 20, + ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + ImGuiWindowFlags_NoDecoration = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse, + ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + ImGuiWindowFlags_NavFlattened = 1 << 23, + ImGuiWindowFlags_ChildWindow = 1 << 24, + ImGuiWindowFlags_Tooltip = 1 << 25, + ImGuiWindowFlags_Popup = 1 << 26, + ImGuiWindowFlags_Modal = 1 << 27, + ImGuiWindowFlags_ChildMenu = 1 << 28 +} + +alias ImGuiWindowFlags_None = ImGuiWindowFlags_.ImGuiWindowFlags_None; +alias ImGuiWindowFlags_NoTitleBar = ImGuiWindowFlags_.ImGuiWindowFlags_NoTitleBar; +alias ImGuiWindowFlags_NoResize = ImGuiWindowFlags_.ImGuiWindowFlags_NoResize; +alias ImGuiWindowFlags_NoMove = ImGuiWindowFlags_.ImGuiWindowFlags_NoMove; +alias ImGuiWindowFlags_NoScrollbar = ImGuiWindowFlags_.ImGuiWindowFlags_NoScrollbar; +alias ImGuiWindowFlags_NoScrollWithMouse = ImGuiWindowFlags_.ImGuiWindowFlags_NoScrollWithMouse; +alias ImGuiWindowFlags_NoCollapse = ImGuiWindowFlags_.ImGuiWindowFlags_NoCollapse; +alias ImGuiWindowFlags_AlwaysAutoResize = ImGuiWindowFlags_.ImGuiWindowFlags_AlwaysAutoResize; +alias ImGuiWindowFlags_NoBackground = ImGuiWindowFlags_.ImGuiWindowFlags_NoBackground; +alias ImGuiWindowFlags_NoSavedSettings = ImGuiWindowFlags_.ImGuiWindowFlags_NoSavedSettings; +alias ImGuiWindowFlags_NoMouseInputs = ImGuiWindowFlags_.ImGuiWindowFlags_NoMouseInputs; +alias ImGuiWindowFlags_MenuBar = ImGuiWindowFlags_.ImGuiWindowFlags_MenuBar; +alias ImGuiWindowFlags_HorizontalScrollbar = ImGuiWindowFlags_.ImGuiWindowFlags_HorizontalScrollbar; +alias ImGuiWindowFlags_NoFocusOnAppearing = ImGuiWindowFlags_.ImGuiWindowFlags_NoFocusOnAppearing; +alias ImGuiWindowFlags_NoBringToFrontOnFocus = ImGuiWindowFlags_.ImGuiWindowFlags_NoBringToFrontOnFocus; +alias ImGuiWindowFlags_AlwaysVerticalScrollbar = ImGuiWindowFlags_.ImGuiWindowFlags_AlwaysVerticalScrollbar; +alias ImGuiWindowFlags_AlwaysHorizontalScrollbar = ImGuiWindowFlags_.ImGuiWindowFlags_AlwaysHorizontalScrollbar; +alias ImGuiWindowFlags_AlwaysUseWindowPadding = ImGuiWindowFlags_.ImGuiWindowFlags_AlwaysUseWindowPadding; +alias ImGuiWindowFlags_NoNavInputs = ImGuiWindowFlags_.ImGuiWindowFlags_NoNavInputs; +alias ImGuiWindowFlags_NoNavFocus = ImGuiWindowFlags_.ImGuiWindowFlags_NoNavFocus; +alias ImGuiWindowFlags_UnsavedDocument = ImGuiWindowFlags_.ImGuiWindowFlags_UnsavedDocument; +alias ImGuiWindowFlags_NoNav = ImGuiWindowFlags_.ImGuiWindowFlags_NoNav; +alias ImGuiWindowFlags_NoDecoration = ImGuiWindowFlags_.ImGuiWindowFlags_NoDecoration; +alias ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_.ImGuiWindowFlags_NoInputs; +alias ImGuiWindowFlags_NavFlattened = ImGuiWindowFlags_.ImGuiWindowFlags_NavFlattened; +alias ImGuiWindowFlags_ChildWindow = ImGuiWindowFlags_.ImGuiWindowFlags_ChildWindow; +alias ImGuiWindowFlags_Tooltip = ImGuiWindowFlags_.ImGuiWindowFlags_Tooltip; +alias ImGuiWindowFlags_Popup = ImGuiWindowFlags_.ImGuiWindowFlags_Popup; +alias ImGuiWindowFlags_Modal = ImGuiWindowFlags_.ImGuiWindowFlags_Modal; +alias ImGuiWindowFlags_ChildMenu = ImGuiWindowFlags_.ImGuiWindowFlags_ChildMenu; + +enum ImGuiInputTextFlags_ +{ + ImGuiInputTextFlags_None = 0, + ImGuiInputTextFlags_CharsDecimal = 1 << 0, + ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, + ImGuiInputTextFlags_CharsUppercase = 1 << 2, + ImGuiInputTextFlags_CharsNoBlank = 1 << 3, + ImGuiInputTextFlags_AutoSelectAll = 1 << 4, + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, + ImGuiInputTextFlags_CallbackCompletion = 1 << 6, + ImGuiInputTextFlags_CallbackHistory = 1 << 7, + ImGuiInputTextFlags_CallbackAlways = 1 << 8, + ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, + ImGuiInputTextFlags_AllowTabInput = 1 << 10, + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, + ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, + ImGuiInputTextFlags_ReadOnly = 1 << 14, + ImGuiInputTextFlags_Password = 1 << 15, + ImGuiInputTextFlags_NoUndoRedo = 1 << 16, + ImGuiInputTextFlags_CharsScientific = 1 << 17, + ImGuiInputTextFlags_CallbackResize = 1 << 18, + ImGuiInputTextFlags_Multiline = 1 << 20, + ImGuiInputTextFlags_NoMarkEdited = 1 << 21 +} + +alias ImGuiInputTextFlags_None = ImGuiInputTextFlags_.ImGuiInputTextFlags_None; +alias ImGuiInputTextFlags_CharsDecimal = ImGuiInputTextFlags_.ImGuiInputTextFlags_CharsDecimal; +alias ImGuiInputTextFlags_CharsHexadecimal = ImGuiInputTextFlags_.ImGuiInputTextFlags_CharsHexadecimal; +alias ImGuiInputTextFlags_CharsUppercase = ImGuiInputTextFlags_.ImGuiInputTextFlags_CharsUppercase; +alias ImGuiInputTextFlags_CharsNoBlank = ImGuiInputTextFlags_.ImGuiInputTextFlags_CharsNoBlank; +alias ImGuiInputTextFlags_AutoSelectAll = ImGuiInputTextFlags_.ImGuiInputTextFlags_AutoSelectAll; +alias ImGuiInputTextFlags_EnterReturnsTrue = ImGuiInputTextFlags_.ImGuiInputTextFlags_EnterReturnsTrue; +alias ImGuiInputTextFlags_CallbackCompletion = ImGuiInputTextFlags_.ImGuiInputTextFlags_CallbackCompletion; +alias ImGuiInputTextFlags_CallbackHistory = ImGuiInputTextFlags_.ImGuiInputTextFlags_CallbackHistory; +alias ImGuiInputTextFlags_CallbackAlways = ImGuiInputTextFlags_.ImGuiInputTextFlags_CallbackAlways; +alias ImGuiInputTextFlags_CallbackCharFilter = ImGuiInputTextFlags_.ImGuiInputTextFlags_CallbackCharFilter; +alias ImGuiInputTextFlags_AllowTabInput = ImGuiInputTextFlags_.ImGuiInputTextFlags_AllowTabInput; +alias ImGuiInputTextFlags_CtrlEnterForNewLine = ImGuiInputTextFlags_.ImGuiInputTextFlags_CtrlEnterForNewLine; +alias ImGuiInputTextFlags_NoHorizontalScroll = ImGuiInputTextFlags_.ImGuiInputTextFlags_NoHorizontalScroll; +alias ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_.ImGuiInputTextFlags_AlwaysInsertMode; +alias ImGuiInputTextFlags_ReadOnly = ImGuiInputTextFlags_.ImGuiInputTextFlags_ReadOnly; +alias ImGuiInputTextFlags_Password = ImGuiInputTextFlags_.ImGuiInputTextFlags_Password; +alias ImGuiInputTextFlags_NoUndoRedo = ImGuiInputTextFlags_.ImGuiInputTextFlags_NoUndoRedo; +alias ImGuiInputTextFlags_CharsScientific = ImGuiInputTextFlags_.ImGuiInputTextFlags_CharsScientific; +alias ImGuiInputTextFlags_CallbackResize = ImGuiInputTextFlags_.ImGuiInputTextFlags_CallbackResize; +alias ImGuiInputTextFlags_Multiline = ImGuiInputTextFlags_.ImGuiInputTextFlags_Multiline; +alias ImGuiInputTextFlags_NoMarkEdited = ImGuiInputTextFlags_.ImGuiInputTextFlags_NoMarkEdited; + +enum ImGuiTreeNodeFlags_ +{ + ImGuiTreeNodeFlags_None = 0, + ImGuiTreeNodeFlags_Selected = 1 << 0, + ImGuiTreeNodeFlags_Framed = 1 << 1, + ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, + ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, + ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, + ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, + ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, + ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, + ImGuiTreeNodeFlags_Leaf = 1 << 8, + ImGuiTreeNodeFlags_Bullet = 1 << 9, + ImGuiTreeNodeFlags_FramePadding = 1 << 10, + ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, + ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, + ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 13, + ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog +} + +alias ImGuiTreeNodeFlags_None = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_None; +alias ImGuiTreeNodeFlags_Selected = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_Selected; +alias ImGuiTreeNodeFlags_Framed = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_Framed; +alias ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_AllowItemOverlap; +alias ImGuiTreeNodeFlags_NoTreePushOnOpen = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_NoTreePushOnOpen; +alias ImGuiTreeNodeFlags_NoAutoOpenOnLog = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_NoAutoOpenOnLog; +alias ImGuiTreeNodeFlags_DefaultOpen = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_DefaultOpen; +alias ImGuiTreeNodeFlags_OpenOnDoubleClick = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_OpenOnDoubleClick; +alias ImGuiTreeNodeFlags_OpenOnArrow = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_OpenOnArrow; +alias ImGuiTreeNodeFlags_Leaf = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_Leaf; +alias ImGuiTreeNodeFlags_Bullet = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_Bullet; +alias ImGuiTreeNodeFlags_FramePadding = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_FramePadding; +alias ImGuiTreeNodeFlags_SpanAvailWidth = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_SpanAvailWidth; +alias ImGuiTreeNodeFlags_SpanFullWidth = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_SpanFullWidth; +alias ImGuiTreeNodeFlags_NavLeftJumpsBackHere = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_NavLeftJumpsBackHere; +alias ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_.ImGuiTreeNodeFlags_CollapsingHeader; + +enum ImGuiSelectableFlags_ +{ + ImGuiSelectableFlags_None = 0, + ImGuiSelectableFlags_DontClosePopups = 1 << 0, + ImGuiSelectableFlags_SpanAllColumns = 1 << 1, + ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, + ImGuiSelectableFlags_Disabled = 1 << 3, + ImGuiSelectableFlags_AllowItemOverlap = 1 << 4 +} + +alias ImGuiSelectableFlags_None = ImGuiSelectableFlags_.ImGuiSelectableFlags_None; +alias ImGuiSelectableFlags_DontClosePopups = ImGuiSelectableFlags_.ImGuiSelectableFlags_DontClosePopups; +alias ImGuiSelectableFlags_SpanAllColumns = ImGuiSelectableFlags_.ImGuiSelectableFlags_SpanAllColumns; +alias ImGuiSelectableFlags_AllowDoubleClick = ImGuiSelectableFlags_.ImGuiSelectableFlags_AllowDoubleClick; +alias ImGuiSelectableFlags_Disabled = ImGuiSelectableFlags_.ImGuiSelectableFlags_Disabled; +alias ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_.ImGuiSelectableFlags_AllowItemOverlap; + +enum ImGuiComboFlags_ +{ + ImGuiComboFlags_None = 0, + ImGuiComboFlags_PopupAlignLeft = 1 << 0, + ImGuiComboFlags_HeightSmall = 1 << 1, + ImGuiComboFlags_HeightRegular = 1 << 2, + ImGuiComboFlags_HeightLarge = 1 << 3, + ImGuiComboFlags_HeightLargest = 1 << 4, + ImGuiComboFlags_NoArrowButton = 1 << 5, + ImGuiComboFlags_NoPreview = 1 << 6, + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest +} + +alias ImGuiComboFlags_None = ImGuiComboFlags_.ImGuiComboFlags_None; +alias ImGuiComboFlags_PopupAlignLeft = ImGuiComboFlags_.ImGuiComboFlags_PopupAlignLeft; +alias ImGuiComboFlags_HeightSmall = ImGuiComboFlags_.ImGuiComboFlags_HeightSmall; +alias ImGuiComboFlags_HeightRegular = ImGuiComboFlags_.ImGuiComboFlags_HeightRegular; +alias ImGuiComboFlags_HeightLarge = ImGuiComboFlags_.ImGuiComboFlags_HeightLarge; +alias ImGuiComboFlags_HeightLargest = ImGuiComboFlags_.ImGuiComboFlags_HeightLargest; +alias ImGuiComboFlags_NoArrowButton = ImGuiComboFlags_.ImGuiComboFlags_NoArrowButton; +alias ImGuiComboFlags_NoPreview = ImGuiComboFlags_.ImGuiComboFlags_NoPreview; +alias ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_.ImGuiComboFlags_HeightMask_; + +enum ImGuiTabBarFlags_ +{ + ImGuiTabBarFlags_None = 0, + ImGuiTabBarFlags_Reorderable = 1 << 0, + ImGuiTabBarFlags_AutoSelectNewTabs = 1 << 1, + ImGuiTabBarFlags_TabListPopupButton = 1 << 2, + ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 1 << 3, + ImGuiTabBarFlags_NoTabListScrollingButtons = 1 << 4, + ImGuiTabBarFlags_NoTooltip = 1 << 5, + ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 6, + ImGuiTabBarFlags_FittingPolicyScroll = 1 << 7, + ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyResizeDown | ImGuiTabBarFlags_FittingPolicyScroll, + ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyResizeDown +} + +alias ImGuiTabBarFlags_None = ImGuiTabBarFlags_.ImGuiTabBarFlags_None; +alias ImGuiTabBarFlags_Reorderable = ImGuiTabBarFlags_.ImGuiTabBarFlags_Reorderable; +alias ImGuiTabBarFlags_AutoSelectNewTabs = ImGuiTabBarFlags_.ImGuiTabBarFlags_AutoSelectNewTabs; +alias ImGuiTabBarFlags_TabListPopupButton = ImGuiTabBarFlags_.ImGuiTabBarFlags_TabListPopupButton; +alias ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = ImGuiTabBarFlags_.ImGuiTabBarFlags_NoCloseWithMiddleMouseButton; +alias ImGuiTabBarFlags_NoTabListScrollingButtons = ImGuiTabBarFlags_.ImGuiTabBarFlags_NoTabListScrollingButtons; +alias ImGuiTabBarFlags_NoTooltip = ImGuiTabBarFlags_.ImGuiTabBarFlags_NoTooltip; +alias ImGuiTabBarFlags_FittingPolicyResizeDown = ImGuiTabBarFlags_.ImGuiTabBarFlags_FittingPolicyResizeDown; +alias ImGuiTabBarFlags_FittingPolicyScroll = ImGuiTabBarFlags_.ImGuiTabBarFlags_FittingPolicyScroll; +alias ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_.ImGuiTabBarFlags_FittingPolicyMask_; +alias ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_.ImGuiTabBarFlags_FittingPolicyDefault_; + +enum ImGuiTabItemFlags_ +{ + ImGuiTabItemFlags_None = 0, + ImGuiTabItemFlags_UnsavedDocument = 1 << 0, + ImGuiTabItemFlags_SetSelected = 1 << 1, + ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, + ImGuiTabItemFlags_NoPushId = 1 << 3 +} + +alias ImGuiTabItemFlags_None = ImGuiTabItemFlags_.ImGuiTabItemFlags_None; +alias ImGuiTabItemFlags_UnsavedDocument = ImGuiTabItemFlags_.ImGuiTabItemFlags_UnsavedDocument; +alias ImGuiTabItemFlags_SetSelected = ImGuiTabItemFlags_.ImGuiTabItemFlags_SetSelected; +alias ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = ImGuiTabItemFlags_.ImGuiTabItemFlags_NoCloseWithMiddleMouseButton; +alias ImGuiTabItemFlags_NoPushId = ImGuiTabItemFlags_.ImGuiTabItemFlags_NoPushId; + +enum ImGuiFocusedFlags_ +{ + ImGuiFocusedFlags_None = 0, + ImGuiFocusedFlags_ChildWindows = 1 << 0, + ImGuiFocusedFlags_RootWindow = 1 << 1, + ImGuiFocusedFlags_AnyWindow = 1 << 2, + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows +} + +alias ImGuiFocusedFlags_None = ImGuiFocusedFlags_.ImGuiFocusedFlags_None; +alias ImGuiFocusedFlags_ChildWindows = ImGuiFocusedFlags_.ImGuiFocusedFlags_ChildWindows; +alias ImGuiFocusedFlags_RootWindow = ImGuiFocusedFlags_.ImGuiFocusedFlags_RootWindow; +alias ImGuiFocusedFlags_AnyWindow = ImGuiFocusedFlags_.ImGuiFocusedFlags_AnyWindow; +alias ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_.ImGuiFocusedFlags_RootAndChildWindows; + +enum ImGuiHoveredFlags_ +{ + ImGuiHoveredFlags_None = 0, + ImGuiHoveredFlags_ChildWindows = 1 << 0, + ImGuiHoveredFlags_RootWindow = 1 << 1, + ImGuiHoveredFlags_AnyWindow = 1 << 2, + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, + ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, + ImGuiHoveredFlags_AllowWhenDisabled = 1 << 7, + ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, + ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows +} + +alias ImGuiHoveredFlags_None = ImGuiHoveredFlags_.ImGuiHoveredFlags_None; +alias ImGuiHoveredFlags_ChildWindows = ImGuiHoveredFlags_.ImGuiHoveredFlags_ChildWindows; +alias ImGuiHoveredFlags_RootWindow = ImGuiHoveredFlags_.ImGuiHoveredFlags_RootWindow; +alias ImGuiHoveredFlags_AnyWindow = ImGuiHoveredFlags_.ImGuiHoveredFlags_AnyWindow; +alias ImGuiHoveredFlags_AllowWhenBlockedByPopup = ImGuiHoveredFlags_.ImGuiHoveredFlags_AllowWhenBlockedByPopup; +alias ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = ImGuiHoveredFlags_.ImGuiHoveredFlags_AllowWhenBlockedByActiveItem; +alias ImGuiHoveredFlags_AllowWhenOverlapped = ImGuiHoveredFlags_.ImGuiHoveredFlags_AllowWhenOverlapped; +alias ImGuiHoveredFlags_AllowWhenDisabled = ImGuiHoveredFlags_.ImGuiHoveredFlags_AllowWhenDisabled; +alias ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_.ImGuiHoveredFlags_RectOnly; +alias ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_.ImGuiHoveredFlags_RootAndChildWindows; + +enum ImGuiDragDropFlags_ +{ + ImGuiDragDropFlags_None = 0, + ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, + ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, + ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, + ImGuiDragDropFlags_SourceExtern = 1 << 4, + ImGuiDragDropFlags_SourceAutoExpirePayload = 1 << 5, + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, + ImGuiDragDropFlags_AcceptNoPreviewTooltip = 1 << 12, + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect +} + +alias ImGuiDragDropFlags_None = ImGuiDragDropFlags_.ImGuiDragDropFlags_None; +alias ImGuiDragDropFlags_SourceNoPreviewTooltip = ImGuiDragDropFlags_.ImGuiDragDropFlags_SourceNoPreviewTooltip; +alias ImGuiDragDropFlags_SourceNoDisableHover = ImGuiDragDropFlags_.ImGuiDragDropFlags_SourceNoDisableHover; +alias ImGuiDragDropFlags_SourceNoHoldToOpenOthers = ImGuiDragDropFlags_.ImGuiDragDropFlags_SourceNoHoldToOpenOthers; +alias ImGuiDragDropFlags_SourceAllowNullID = ImGuiDragDropFlags_.ImGuiDragDropFlags_SourceAllowNullID; +alias ImGuiDragDropFlags_SourceExtern = ImGuiDragDropFlags_.ImGuiDragDropFlags_SourceExtern; +alias ImGuiDragDropFlags_SourceAutoExpirePayload = ImGuiDragDropFlags_.ImGuiDragDropFlags_SourceAutoExpirePayload; +alias ImGuiDragDropFlags_AcceptBeforeDelivery = ImGuiDragDropFlags_.ImGuiDragDropFlags_AcceptBeforeDelivery; +alias ImGuiDragDropFlags_AcceptNoDrawDefaultRect = ImGuiDragDropFlags_.ImGuiDragDropFlags_AcceptNoDrawDefaultRect; +alias ImGuiDragDropFlags_AcceptNoPreviewTooltip = ImGuiDragDropFlags_.ImGuiDragDropFlags_AcceptNoPreviewTooltip; +alias ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_.ImGuiDragDropFlags_AcceptPeekOnly; + +enum ImGuiDataType_ +{ + ImGuiDataType_S8 = 0, + ImGuiDataType_U8 = 1, + ImGuiDataType_S16 = 2, + ImGuiDataType_U16 = 3, + ImGuiDataType_S32 = 4, + ImGuiDataType_U32 = 5, + ImGuiDataType_S64 = 6, + ImGuiDataType_U64 = 7, + ImGuiDataType_Float = 8, + ImGuiDataType_Double = 9, + ImGuiDataType_COUNT = 10 +} + +alias ImGuiDataType_S8 = ImGuiDataType_.ImGuiDataType_S8; +alias ImGuiDataType_U8 = ImGuiDataType_.ImGuiDataType_U8; +alias ImGuiDataType_S16 = ImGuiDataType_.ImGuiDataType_S16; +alias ImGuiDataType_U16 = ImGuiDataType_.ImGuiDataType_U16; +alias ImGuiDataType_S32 = ImGuiDataType_.ImGuiDataType_S32; +alias ImGuiDataType_U32 = ImGuiDataType_.ImGuiDataType_U32; +alias ImGuiDataType_S64 = ImGuiDataType_.ImGuiDataType_S64; +alias ImGuiDataType_U64 = ImGuiDataType_.ImGuiDataType_U64; +alias ImGuiDataType_Float = ImGuiDataType_.ImGuiDataType_Float; +alias ImGuiDataType_Double = ImGuiDataType_.ImGuiDataType_Double; +alias ImGuiDataType_COUNT = ImGuiDataType_.ImGuiDataType_COUNT; + +enum ImGuiDir_ +{ + ImGuiDir_None = -1, + ImGuiDir_Left = 0, + ImGuiDir_Right = 1, + ImGuiDir_Up = 2, + ImGuiDir_Down = 3, + ImGuiDir_COUNT = 4 +} + +alias ImGuiDir_None = ImGuiDir_.ImGuiDir_None; +alias ImGuiDir_Left = ImGuiDir_.ImGuiDir_Left; +alias ImGuiDir_Right = ImGuiDir_.ImGuiDir_Right; +alias ImGuiDir_Up = ImGuiDir_.ImGuiDir_Up; +alias ImGuiDir_Down = ImGuiDir_.ImGuiDir_Down; +alias ImGuiDir_COUNT = ImGuiDir_.ImGuiDir_COUNT; + +enum ImGuiKey_ +{ + ImGuiKey_Tab = 0, + ImGuiKey_LeftArrow = 1, + ImGuiKey_RightArrow = 2, + ImGuiKey_UpArrow = 3, + ImGuiKey_DownArrow = 4, + ImGuiKey_PageUp = 5, + ImGuiKey_PageDown = 6, + ImGuiKey_Home = 7, + ImGuiKey_End = 8, + ImGuiKey_Insert = 9, + ImGuiKey_Delete = 10, + ImGuiKey_Backspace = 11, + ImGuiKey_Space = 12, + ImGuiKey_Enter = 13, + ImGuiKey_Escape = 14, + ImGuiKey_KeyPadEnter = 15, + ImGuiKey_A = 16, + ImGuiKey_C = 17, + ImGuiKey_V = 18, + ImGuiKey_X = 19, + ImGuiKey_Y = 20, + ImGuiKey_Z = 21, + ImGuiKey_COUNT = 22 +} + +alias ImGuiKey_Tab = ImGuiKey_.ImGuiKey_Tab; +alias ImGuiKey_LeftArrow = ImGuiKey_.ImGuiKey_LeftArrow; +alias ImGuiKey_RightArrow = ImGuiKey_.ImGuiKey_RightArrow; +alias ImGuiKey_UpArrow = ImGuiKey_.ImGuiKey_UpArrow; +alias ImGuiKey_DownArrow = ImGuiKey_.ImGuiKey_DownArrow; +alias ImGuiKey_PageUp = ImGuiKey_.ImGuiKey_PageUp; +alias ImGuiKey_PageDown = ImGuiKey_.ImGuiKey_PageDown; +alias ImGuiKey_Home = ImGuiKey_.ImGuiKey_Home; +alias ImGuiKey_End = ImGuiKey_.ImGuiKey_End; +alias ImGuiKey_Insert = ImGuiKey_.ImGuiKey_Insert; +alias ImGuiKey_Delete = ImGuiKey_.ImGuiKey_Delete; +alias ImGuiKey_Backspace = ImGuiKey_.ImGuiKey_Backspace; +alias ImGuiKey_Space = ImGuiKey_.ImGuiKey_Space; +alias ImGuiKey_Enter = ImGuiKey_.ImGuiKey_Enter; +alias ImGuiKey_Escape = ImGuiKey_.ImGuiKey_Escape; +alias ImGuiKey_KeyPadEnter = ImGuiKey_.ImGuiKey_KeyPadEnter; +alias ImGuiKey_A = ImGuiKey_.ImGuiKey_A; +alias ImGuiKey_C = ImGuiKey_.ImGuiKey_C; +alias ImGuiKey_V = ImGuiKey_.ImGuiKey_V; +alias ImGuiKey_X = ImGuiKey_.ImGuiKey_X; +alias ImGuiKey_Y = ImGuiKey_.ImGuiKey_Y; +alias ImGuiKey_Z = ImGuiKey_.ImGuiKey_Z; +alias ImGuiKey_COUNT = ImGuiKey_.ImGuiKey_COUNT; + +enum ImGuiNavInput_ +{ + ImGuiNavInput_Activate = 0, + ImGuiNavInput_Cancel = 1, + ImGuiNavInput_Input = 2, + ImGuiNavInput_Menu = 3, + ImGuiNavInput_DpadLeft = 4, + ImGuiNavInput_DpadRight = 5, + ImGuiNavInput_DpadUp = 6, + ImGuiNavInput_DpadDown = 7, + ImGuiNavInput_LStickLeft = 8, + ImGuiNavInput_LStickRight = 9, + ImGuiNavInput_LStickUp = 10, + ImGuiNavInput_LStickDown = 11, + ImGuiNavInput_FocusPrev = 12, + ImGuiNavInput_FocusNext = 13, + ImGuiNavInput_TweakSlow = 14, + ImGuiNavInput_TweakFast = 15, + ImGuiNavInput_KeyMenu_ = 16, + ImGuiNavInput_KeyTab_ = 17, + ImGuiNavInput_KeyLeft_ = 18, + ImGuiNavInput_KeyRight_ = 19, + ImGuiNavInput_KeyUp_ = 20, + ImGuiNavInput_KeyDown_ = 21, + ImGuiNavInput_COUNT = 22, + ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_ +} + +alias ImGuiNavInput_Activate = ImGuiNavInput_.ImGuiNavInput_Activate; +alias ImGuiNavInput_Cancel = ImGuiNavInput_.ImGuiNavInput_Cancel; +alias ImGuiNavInput_Input = ImGuiNavInput_.ImGuiNavInput_Input; +alias ImGuiNavInput_Menu = ImGuiNavInput_.ImGuiNavInput_Menu; +alias ImGuiNavInput_DpadLeft = ImGuiNavInput_.ImGuiNavInput_DpadLeft; +alias ImGuiNavInput_DpadRight = ImGuiNavInput_.ImGuiNavInput_DpadRight; +alias ImGuiNavInput_DpadUp = ImGuiNavInput_.ImGuiNavInput_DpadUp; +alias ImGuiNavInput_DpadDown = ImGuiNavInput_.ImGuiNavInput_DpadDown; +alias ImGuiNavInput_LStickLeft = ImGuiNavInput_.ImGuiNavInput_LStickLeft; +alias ImGuiNavInput_LStickRight = ImGuiNavInput_.ImGuiNavInput_LStickRight; +alias ImGuiNavInput_LStickUp = ImGuiNavInput_.ImGuiNavInput_LStickUp; +alias ImGuiNavInput_LStickDown = ImGuiNavInput_.ImGuiNavInput_LStickDown; +alias ImGuiNavInput_FocusPrev = ImGuiNavInput_.ImGuiNavInput_FocusPrev; +alias ImGuiNavInput_FocusNext = ImGuiNavInput_.ImGuiNavInput_FocusNext; +alias ImGuiNavInput_TweakSlow = ImGuiNavInput_.ImGuiNavInput_TweakSlow; +alias ImGuiNavInput_TweakFast = ImGuiNavInput_.ImGuiNavInput_TweakFast; +alias ImGuiNavInput_KeyMenu_ = ImGuiNavInput_.ImGuiNavInput_KeyMenu_; +alias ImGuiNavInput_KeyTab_ = ImGuiNavInput_.ImGuiNavInput_KeyTab_; +alias ImGuiNavInput_KeyLeft_ = ImGuiNavInput_.ImGuiNavInput_KeyLeft_; +alias ImGuiNavInput_KeyRight_ = ImGuiNavInput_.ImGuiNavInput_KeyRight_; +alias ImGuiNavInput_KeyUp_ = ImGuiNavInput_.ImGuiNavInput_KeyUp_; +alias ImGuiNavInput_KeyDown_ = ImGuiNavInput_.ImGuiNavInput_KeyDown_; +alias ImGuiNavInput_COUNT = ImGuiNavInput_.ImGuiNavInput_COUNT; +alias ImGuiNavInput_InternalStart_ = ImGuiNavInput_.ImGuiNavInput_InternalStart_; + +enum ImGuiConfigFlags_ +{ + ImGuiConfigFlags_None = 0, + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, + ImGuiConfigFlags_NavEnableGamepad = 1 << 1, + ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, + ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, + ImGuiConfigFlags_NoMouse = 1 << 4, + ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, + ImGuiConfigFlags_IsSRGB = 1 << 20, + ImGuiConfigFlags_IsTouchScreen = 1 << 21 +} + +alias ImGuiConfigFlags_None = ImGuiConfigFlags_.ImGuiConfigFlags_None; +alias ImGuiConfigFlags_NavEnableKeyboard = ImGuiConfigFlags_.ImGuiConfigFlags_NavEnableKeyboard; +alias ImGuiConfigFlags_NavEnableGamepad = ImGuiConfigFlags_.ImGuiConfigFlags_NavEnableGamepad; +alias ImGuiConfigFlags_NavEnableSetMousePos = ImGuiConfigFlags_.ImGuiConfigFlags_NavEnableSetMousePos; +alias ImGuiConfigFlags_NavNoCaptureKeyboard = ImGuiConfigFlags_.ImGuiConfigFlags_NavNoCaptureKeyboard; +alias ImGuiConfigFlags_NoMouse = ImGuiConfigFlags_.ImGuiConfigFlags_NoMouse; +alias ImGuiConfigFlags_NoMouseCursorChange = ImGuiConfigFlags_.ImGuiConfigFlags_NoMouseCursorChange; +alias ImGuiConfigFlags_IsSRGB = ImGuiConfigFlags_.ImGuiConfigFlags_IsSRGB; +alias ImGuiConfigFlags_IsTouchScreen = ImGuiConfigFlags_.ImGuiConfigFlags_IsTouchScreen; + +enum ImGuiBackendFlags_ +{ + ImGuiBackendFlags_None = 0, + ImGuiBackendFlags_HasGamepad = 1 << 0, + ImGuiBackendFlags_HasMouseCursors = 1 << 1, + ImGuiBackendFlags_HasSetMousePos = 1 << 2, + ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3 +} + +alias ImGuiBackendFlags_None = ImGuiBackendFlags_.ImGuiBackendFlags_None; +alias ImGuiBackendFlags_HasGamepad = ImGuiBackendFlags_.ImGuiBackendFlags_HasGamepad; +alias ImGuiBackendFlags_HasMouseCursors = ImGuiBackendFlags_.ImGuiBackendFlags_HasMouseCursors; +alias ImGuiBackendFlags_HasSetMousePos = ImGuiBackendFlags_.ImGuiBackendFlags_HasSetMousePos; +alias ImGuiBackendFlags_RendererHasVtxOffset = ImGuiBackendFlags_.ImGuiBackendFlags_RendererHasVtxOffset; + +enum ImGuiCol_ +{ + ImGuiCol_Text = 0, + ImGuiCol_TextDisabled = 1, + ImGuiCol_WindowBg = 2, + ImGuiCol_ChildBg = 3, + ImGuiCol_PopupBg = 4, + ImGuiCol_Border = 5, + ImGuiCol_BorderShadow = 6, + ImGuiCol_FrameBg = 7, + ImGuiCol_FrameBgHovered = 8, + ImGuiCol_FrameBgActive = 9, + ImGuiCol_TitleBg = 10, + ImGuiCol_TitleBgActive = 11, + ImGuiCol_TitleBgCollapsed = 12, + ImGuiCol_MenuBarBg = 13, + ImGuiCol_ScrollbarBg = 14, + ImGuiCol_ScrollbarGrab = 15, + ImGuiCol_ScrollbarGrabHovered = 16, + ImGuiCol_ScrollbarGrabActive = 17, + ImGuiCol_CheckMark = 18, + ImGuiCol_SliderGrab = 19, + ImGuiCol_SliderGrabActive = 20, + ImGuiCol_Button = 21, + ImGuiCol_ButtonHovered = 22, + ImGuiCol_ButtonActive = 23, + ImGuiCol_Header = 24, + ImGuiCol_HeaderHovered = 25, + ImGuiCol_HeaderActive = 26, + ImGuiCol_Separator = 27, + ImGuiCol_SeparatorHovered = 28, + ImGuiCol_SeparatorActive = 29, + ImGuiCol_ResizeGrip = 30, + ImGuiCol_ResizeGripHovered = 31, + ImGuiCol_ResizeGripActive = 32, + ImGuiCol_Tab = 33, + ImGuiCol_TabHovered = 34, + ImGuiCol_TabActive = 35, + ImGuiCol_TabUnfocused = 36, + ImGuiCol_TabUnfocusedActive = 37, + ImGuiCol_PlotLines = 38, + ImGuiCol_PlotLinesHovered = 39, + ImGuiCol_PlotHistogram = 40, + ImGuiCol_PlotHistogramHovered = 41, + ImGuiCol_TextSelectedBg = 42, + ImGuiCol_DragDropTarget = 43, + ImGuiCol_NavHighlight = 44, + ImGuiCol_NavWindowingHighlight = 45, + ImGuiCol_NavWindowingDimBg = 46, + ImGuiCol_ModalWindowDimBg = 47, + ImGuiCol_COUNT = 48 +} + +alias ImGuiCol_Text = ImGuiCol_.ImGuiCol_Text; +alias ImGuiCol_TextDisabled = ImGuiCol_.ImGuiCol_TextDisabled; +alias ImGuiCol_WindowBg = ImGuiCol_.ImGuiCol_WindowBg; +alias ImGuiCol_ChildBg = ImGuiCol_.ImGuiCol_ChildBg; +alias ImGuiCol_PopupBg = ImGuiCol_.ImGuiCol_PopupBg; +alias ImGuiCol_Border = ImGuiCol_.ImGuiCol_Border; +alias ImGuiCol_BorderShadow = ImGuiCol_.ImGuiCol_BorderShadow; +alias ImGuiCol_FrameBg = ImGuiCol_.ImGuiCol_FrameBg; +alias ImGuiCol_FrameBgHovered = ImGuiCol_.ImGuiCol_FrameBgHovered; +alias ImGuiCol_FrameBgActive = ImGuiCol_.ImGuiCol_FrameBgActive; +alias ImGuiCol_TitleBg = ImGuiCol_.ImGuiCol_TitleBg; +alias ImGuiCol_TitleBgActive = ImGuiCol_.ImGuiCol_TitleBgActive; +alias ImGuiCol_TitleBgCollapsed = ImGuiCol_.ImGuiCol_TitleBgCollapsed; +alias ImGuiCol_MenuBarBg = ImGuiCol_.ImGuiCol_MenuBarBg; +alias ImGuiCol_ScrollbarBg = ImGuiCol_.ImGuiCol_ScrollbarBg; +alias ImGuiCol_ScrollbarGrab = ImGuiCol_.ImGuiCol_ScrollbarGrab; +alias ImGuiCol_ScrollbarGrabHovered = ImGuiCol_.ImGuiCol_ScrollbarGrabHovered; +alias ImGuiCol_ScrollbarGrabActive = ImGuiCol_.ImGuiCol_ScrollbarGrabActive; +alias ImGuiCol_CheckMark = ImGuiCol_.ImGuiCol_CheckMark; +alias ImGuiCol_SliderGrab = ImGuiCol_.ImGuiCol_SliderGrab; +alias ImGuiCol_SliderGrabActive = ImGuiCol_.ImGuiCol_SliderGrabActive; +alias ImGuiCol_Button = ImGuiCol_.ImGuiCol_Button; +alias ImGuiCol_ButtonHovered = ImGuiCol_.ImGuiCol_ButtonHovered; +alias ImGuiCol_ButtonActive = ImGuiCol_.ImGuiCol_ButtonActive; +alias ImGuiCol_Header = ImGuiCol_.ImGuiCol_Header; +alias ImGuiCol_HeaderHovered = ImGuiCol_.ImGuiCol_HeaderHovered; +alias ImGuiCol_HeaderActive = ImGuiCol_.ImGuiCol_HeaderActive; +alias ImGuiCol_Separator = ImGuiCol_.ImGuiCol_Separator; +alias ImGuiCol_SeparatorHovered = ImGuiCol_.ImGuiCol_SeparatorHovered; +alias ImGuiCol_SeparatorActive = ImGuiCol_.ImGuiCol_SeparatorActive; +alias ImGuiCol_ResizeGrip = ImGuiCol_.ImGuiCol_ResizeGrip; +alias ImGuiCol_ResizeGripHovered = ImGuiCol_.ImGuiCol_ResizeGripHovered; +alias ImGuiCol_ResizeGripActive = ImGuiCol_.ImGuiCol_ResizeGripActive; +alias ImGuiCol_Tab = ImGuiCol_.ImGuiCol_Tab; +alias ImGuiCol_TabHovered = ImGuiCol_.ImGuiCol_TabHovered; +alias ImGuiCol_TabActive = ImGuiCol_.ImGuiCol_TabActive; +alias ImGuiCol_TabUnfocused = ImGuiCol_.ImGuiCol_TabUnfocused; +alias ImGuiCol_TabUnfocusedActive = ImGuiCol_.ImGuiCol_TabUnfocusedActive; +alias ImGuiCol_PlotLines = ImGuiCol_.ImGuiCol_PlotLines; +alias ImGuiCol_PlotLinesHovered = ImGuiCol_.ImGuiCol_PlotLinesHovered; +alias ImGuiCol_PlotHistogram = ImGuiCol_.ImGuiCol_PlotHistogram; +alias ImGuiCol_PlotHistogramHovered = ImGuiCol_.ImGuiCol_PlotHistogramHovered; +alias ImGuiCol_TextSelectedBg = ImGuiCol_.ImGuiCol_TextSelectedBg; +alias ImGuiCol_DragDropTarget = ImGuiCol_.ImGuiCol_DragDropTarget; +alias ImGuiCol_NavHighlight = ImGuiCol_.ImGuiCol_NavHighlight; +alias ImGuiCol_NavWindowingHighlight = ImGuiCol_.ImGuiCol_NavWindowingHighlight; +alias ImGuiCol_NavWindowingDimBg = ImGuiCol_.ImGuiCol_NavWindowingDimBg; +alias ImGuiCol_ModalWindowDimBg = ImGuiCol_.ImGuiCol_ModalWindowDimBg; +alias ImGuiCol_COUNT = ImGuiCol_.ImGuiCol_COUNT; + +enum ImGuiStyleVar_ +{ + ImGuiStyleVar_Alpha = 0, + ImGuiStyleVar_WindowPadding = 1, + ImGuiStyleVar_WindowRounding = 2, + ImGuiStyleVar_WindowBorderSize = 3, + ImGuiStyleVar_WindowMinSize = 4, + ImGuiStyleVar_WindowTitleAlign = 5, + ImGuiStyleVar_ChildRounding = 6, + ImGuiStyleVar_ChildBorderSize = 7, + ImGuiStyleVar_PopupRounding = 8, + ImGuiStyleVar_PopupBorderSize = 9, + ImGuiStyleVar_FramePadding = 10, + ImGuiStyleVar_FrameRounding = 11, + ImGuiStyleVar_FrameBorderSize = 12, + ImGuiStyleVar_ItemSpacing = 13, + ImGuiStyleVar_ItemInnerSpacing = 14, + ImGuiStyleVar_IndentSpacing = 15, + ImGuiStyleVar_ScrollbarSize = 16, + ImGuiStyleVar_ScrollbarRounding = 17, + ImGuiStyleVar_GrabMinSize = 18, + ImGuiStyleVar_GrabRounding = 19, + ImGuiStyleVar_TabRounding = 20, + ImGuiStyleVar_ButtonTextAlign = 21, + ImGuiStyleVar_SelectableTextAlign = 22, + ImGuiStyleVar_COUNT = 23 +} + +alias ImGuiStyleVar_Alpha = ImGuiStyleVar_.ImGuiStyleVar_Alpha; +alias ImGuiStyleVar_WindowPadding = ImGuiStyleVar_.ImGuiStyleVar_WindowPadding; +alias ImGuiStyleVar_WindowRounding = ImGuiStyleVar_.ImGuiStyleVar_WindowRounding; +alias ImGuiStyleVar_WindowBorderSize = ImGuiStyleVar_.ImGuiStyleVar_WindowBorderSize; +alias ImGuiStyleVar_WindowMinSize = ImGuiStyleVar_.ImGuiStyleVar_WindowMinSize; +alias ImGuiStyleVar_WindowTitleAlign = ImGuiStyleVar_.ImGuiStyleVar_WindowTitleAlign; +alias ImGuiStyleVar_ChildRounding = ImGuiStyleVar_.ImGuiStyleVar_ChildRounding; +alias ImGuiStyleVar_ChildBorderSize = ImGuiStyleVar_.ImGuiStyleVar_ChildBorderSize; +alias ImGuiStyleVar_PopupRounding = ImGuiStyleVar_.ImGuiStyleVar_PopupRounding; +alias ImGuiStyleVar_PopupBorderSize = ImGuiStyleVar_.ImGuiStyleVar_PopupBorderSize; +alias ImGuiStyleVar_FramePadding = ImGuiStyleVar_.ImGuiStyleVar_FramePadding; +alias ImGuiStyleVar_FrameRounding = ImGuiStyleVar_.ImGuiStyleVar_FrameRounding; +alias ImGuiStyleVar_FrameBorderSize = ImGuiStyleVar_.ImGuiStyleVar_FrameBorderSize; +alias ImGuiStyleVar_ItemSpacing = ImGuiStyleVar_.ImGuiStyleVar_ItemSpacing; +alias ImGuiStyleVar_ItemInnerSpacing = ImGuiStyleVar_.ImGuiStyleVar_ItemInnerSpacing; +alias ImGuiStyleVar_IndentSpacing = ImGuiStyleVar_.ImGuiStyleVar_IndentSpacing; +alias ImGuiStyleVar_ScrollbarSize = ImGuiStyleVar_.ImGuiStyleVar_ScrollbarSize; +alias ImGuiStyleVar_ScrollbarRounding = ImGuiStyleVar_.ImGuiStyleVar_ScrollbarRounding; +alias ImGuiStyleVar_GrabMinSize = ImGuiStyleVar_.ImGuiStyleVar_GrabMinSize; +alias ImGuiStyleVar_GrabRounding = ImGuiStyleVar_.ImGuiStyleVar_GrabRounding; +alias ImGuiStyleVar_TabRounding = ImGuiStyleVar_.ImGuiStyleVar_TabRounding; +alias ImGuiStyleVar_ButtonTextAlign = ImGuiStyleVar_.ImGuiStyleVar_ButtonTextAlign; +alias ImGuiStyleVar_SelectableTextAlign = ImGuiStyleVar_.ImGuiStyleVar_SelectableTextAlign; +alias ImGuiStyleVar_COUNT = ImGuiStyleVar_.ImGuiStyleVar_COUNT; + +enum ImGuiColorEditFlags_ +{ + ImGuiColorEditFlags_None = 0, + ImGuiColorEditFlags_NoAlpha = 1 << 1, + ImGuiColorEditFlags_NoPicker = 1 << 2, + ImGuiColorEditFlags_NoOptions = 1 << 3, + ImGuiColorEditFlags_NoSmallPreview = 1 << 4, + ImGuiColorEditFlags_NoInputs = 1 << 5, + ImGuiColorEditFlags_NoTooltip = 1 << 6, + ImGuiColorEditFlags_NoLabel = 1 << 7, + ImGuiColorEditFlags_NoSidePreview = 1 << 8, + ImGuiColorEditFlags_NoDragDrop = 1 << 9, + ImGuiColorEditFlags_AlphaBar = 1 << 16, + ImGuiColorEditFlags_AlphaPreview = 1 << 17, + ImGuiColorEditFlags_AlphaPreviewHalf = 1 << 18, + ImGuiColorEditFlags_HDR = 1 << 19, + ImGuiColorEditFlags_DisplayRGB = 1 << 20, + ImGuiColorEditFlags_DisplayHSV = 1 << 21, + ImGuiColorEditFlags_DisplayHex = 1 << 22, + ImGuiColorEditFlags_Uint8 = 1 << 23, + ImGuiColorEditFlags_Float = 1 << 24, + ImGuiColorEditFlags_PickerHueBar = 1 << 25, + ImGuiColorEditFlags_PickerHueWheel = 1 << 26, + ImGuiColorEditFlags_InputRGB = 1 << 27, + ImGuiColorEditFlags_InputHSV = 1 << 28, + ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags__DisplayMask = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex, + ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float, + ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags__InputMask = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV +} + +alias ImGuiColorEditFlags_None = ImGuiColorEditFlags_.ImGuiColorEditFlags_None; +alias ImGuiColorEditFlags_NoAlpha = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoAlpha; +alias ImGuiColorEditFlags_NoPicker = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoPicker; +alias ImGuiColorEditFlags_NoOptions = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoOptions; +alias ImGuiColorEditFlags_NoSmallPreview = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoSmallPreview; +alias ImGuiColorEditFlags_NoInputs = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoInputs; +alias ImGuiColorEditFlags_NoTooltip = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoTooltip; +alias ImGuiColorEditFlags_NoLabel = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoLabel; +alias ImGuiColorEditFlags_NoSidePreview = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoSidePreview; +alias ImGuiColorEditFlags_NoDragDrop = ImGuiColorEditFlags_.ImGuiColorEditFlags_NoDragDrop; +alias ImGuiColorEditFlags_AlphaBar = ImGuiColorEditFlags_.ImGuiColorEditFlags_AlphaBar; +alias ImGuiColorEditFlags_AlphaPreview = ImGuiColorEditFlags_.ImGuiColorEditFlags_AlphaPreview; +alias ImGuiColorEditFlags_AlphaPreviewHalf = ImGuiColorEditFlags_.ImGuiColorEditFlags_AlphaPreviewHalf; +alias ImGuiColorEditFlags_HDR = ImGuiColorEditFlags_.ImGuiColorEditFlags_HDR; +alias ImGuiColorEditFlags_DisplayRGB = ImGuiColorEditFlags_.ImGuiColorEditFlags_DisplayRGB; +alias ImGuiColorEditFlags_DisplayHSV = ImGuiColorEditFlags_.ImGuiColorEditFlags_DisplayHSV; +alias ImGuiColorEditFlags_DisplayHex = ImGuiColorEditFlags_.ImGuiColorEditFlags_DisplayHex; +alias ImGuiColorEditFlags_Uint8 = ImGuiColorEditFlags_.ImGuiColorEditFlags_Uint8; +alias ImGuiColorEditFlags_Float = ImGuiColorEditFlags_.ImGuiColorEditFlags_Float; +alias ImGuiColorEditFlags_PickerHueBar = ImGuiColorEditFlags_.ImGuiColorEditFlags_PickerHueBar; +alias ImGuiColorEditFlags_PickerHueWheel = ImGuiColorEditFlags_.ImGuiColorEditFlags_PickerHueWheel; +alias ImGuiColorEditFlags_InputRGB = ImGuiColorEditFlags_.ImGuiColorEditFlags_InputRGB; +alias ImGuiColorEditFlags_InputHSV = ImGuiColorEditFlags_.ImGuiColorEditFlags_InputHSV; +alias ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_.ImGuiColorEditFlags__OptionsDefault; +alias ImGuiColorEditFlags__DisplayMask = ImGuiColorEditFlags_.ImGuiColorEditFlags__DisplayMask; +alias ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_.ImGuiColorEditFlags__DataTypeMask; +alias ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_.ImGuiColorEditFlags__PickerMask; +alias ImGuiColorEditFlags__InputMask = ImGuiColorEditFlags_.ImGuiColorEditFlags__InputMask; + +enum ImGuiMouseCursor_ +{ + ImGuiMouseCursor_None = -1, + ImGuiMouseCursor_Arrow = 0, + ImGuiMouseCursor_TextInput = 1, + ImGuiMouseCursor_ResizeAll = 2, + ImGuiMouseCursor_ResizeNS = 3, + ImGuiMouseCursor_ResizeEW = 4, + ImGuiMouseCursor_ResizeNESW = 5, + ImGuiMouseCursor_ResizeNWSE = 6, + ImGuiMouseCursor_Hand = 7, + ImGuiMouseCursor_COUNT = 8 +} + +alias ImGuiMouseCursor_None = ImGuiMouseCursor_.ImGuiMouseCursor_None; +alias ImGuiMouseCursor_Arrow = ImGuiMouseCursor_.ImGuiMouseCursor_Arrow; +alias ImGuiMouseCursor_TextInput = ImGuiMouseCursor_.ImGuiMouseCursor_TextInput; +alias ImGuiMouseCursor_ResizeAll = ImGuiMouseCursor_.ImGuiMouseCursor_ResizeAll; +alias ImGuiMouseCursor_ResizeNS = ImGuiMouseCursor_.ImGuiMouseCursor_ResizeNS; +alias ImGuiMouseCursor_ResizeEW = ImGuiMouseCursor_.ImGuiMouseCursor_ResizeEW; +alias ImGuiMouseCursor_ResizeNESW = ImGuiMouseCursor_.ImGuiMouseCursor_ResizeNESW; +alias ImGuiMouseCursor_ResizeNWSE = ImGuiMouseCursor_.ImGuiMouseCursor_ResizeNWSE; +alias ImGuiMouseCursor_Hand = ImGuiMouseCursor_.ImGuiMouseCursor_Hand; +alias ImGuiMouseCursor_COUNT = ImGuiMouseCursor_.ImGuiMouseCursor_COUNT; + +enum ImGuiCond_ +{ + ImGuiCond_Always = 1 << 0, + ImGuiCond_Once = 1 << 1, + ImGuiCond_FirstUseEver = 1 << 2, + ImGuiCond_Appearing = 1 << 3 +} + +alias ImGuiCond_Always = ImGuiCond_.ImGuiCond_Always; +alias ImGuiCond_Once = ImGuiCond_.ImGuiCond_Once; +alias ImGuiCond_FirstUseEver = ImGuiCond_.ImGuiCond_FirstUseEver; +alias ImGuiCond_Appearing = ImGuiCond_.ImGuiCond_Appearing; + +struct ImGuiStyle +{ + float Alpha; + ImVec2 WindowPadding; + float WindowRounding; + float WindowBorderSize; + ImVec2 WindowMinSize; + ImVec2 WindowTitleAlign; + ImGuiDir WindowMenuButtonPosition; + float ChildRounding; + float ChildBorderSize; + float PopupRounding; + float PopupBorderSize; + ImVec2 FramePadding; + float FrameRounding; + float FrameBorderSize; + ImVec2 ItemSpacing; + ImVec2 ItemInnerSpacing; + ImVec2 TouchExtraPadding; + float IndentSpacing; + float ColumnsMinSpacing; + float ScrollbarSize; + float ScrollbarRounding; + float GrabMinSize; + float GrabRounding; + float TabRounding; + float TabBorderSize; + ImGuiDir ColorButtonPosition; + ImVec2 ButtonTextAlign; + ImVec2 SelectableTextAlign; + ImVec2 DisplayWindowPadding; + ImVec2 DisplaySafeAreaPadding; + float MouseCursorScale; + bool AntiAliasedLines; + bool AntiAliasedFill; + float CurveTessellationTol; + ImVec4[ImGuiCol_COUNT] Colors; +} + +struct ImGuiIO +{ + ImGuiConfigFlags ConfigFlags; + ImGuiBackendFlags BackendFlags; + ImVec2 DisplaySize; + float DeltaTime; + float IniSavingRate; + const(char)* IniFilename; + const(char)* LogFilename; + float MouseDoubleClickTime; + float MouseDoubleClickMaxDist; + float MouseDragThreshold; + int[ImGuiKey_COUNT] KeyMap; + float KeyRepeatDelay; + float KeyRepeatRate; + void* UserData; + ImFontAtlas* Fonts; + float FontGlobalScale; + bool FontAllowUserScaling; + ImFont* FontDefault; + ImVec2 DisplayFramebufferScale; + bool MouseDrawCursor; + bool ConfigMacOSXBehaviors; + bool ConfigInputTextCursorBlink; + bool ConfigWindowsResizeFromEdges; + bool ConfigWindowsMoveFromTitleBarOnly; + float ConfigWindowsMemoryCompactTimer; + const(char)* BackendPlatformName; + const(char)* BackendRendererName; + void* BackendPlatformUserData; + void* BackendRendererUserData; + void* BackendLanguageUserData; + const(char)* function (void* user_data) GetClipboardTextFn; + void function (void* user_data, const(char)* text) SetClipboardTextFn; + void* ClipboardUserData; + void function (int x, int y) ImeSetInputScreenPosFn; + void* ImeWindowHandle; + void* RenderDrawListsFnUnused; + ImVec2 MousePos; + bool[5] MouseDown; + float MouseWheel; + float MouseWheelH; + bool KeyCtrl; + bool KeyShift; + bool KeyAlt; + bool KeySuper; + bool[512] KeysDown; + float[ImGuiNavInput_COUNT] NavInputs; + bool WantCaptureMouse; + bool WantCaptureKeyboard; + bool WantTextInput; + bool WantSetMousePos; + bool WantSaveIniSettings; + bool NavActive; + bool NavVisible; + float Framerate; + int MetricsRenderVertices; + int MetricsRenderIndices; + int MetricsRenderWindows; + int MetricsActiveWindows; + int MetricsActiveAllocations; + ImVec2 MouseDelta; + ImVec2 MousePosPrev; + ImVec2[5] MouseClickedPos; + double[5] MouseClickedTime; + bool[5] MouseClicked; + bool[5] MouseDoubleClicked; + bool[5] MouseReleased; + bool[5] MouseDownOwned; + bool[5] MouseDownWasDoubleClick; + float[5] MouseDownDuration; + float[5] MouseDownDurationPrev; + ImVec2[5] MouseDragMaxDistanceAbs; + float[5] MouseDragMaxDistanceSqr; + float[512] KeysDownDuration; + float[512] KeysDownDurationPrev; + float[ImGuiNavInput_COUNT] NavInputsDownDuration; + float[ImGuiNavInput_COUNT] NavInputsDownDurationPrev; + ImVector_ImWchar InputQueueCharacters; +} + +struct ImGuiInputTextCallbackData +{ + ImGuiInputTextFlags EventFlag; + ImGuiInputTextFlags Flags; + void* UserData; + ImWchar EventChar; + ImGuiKey EventKey; + char* Buf; + int BufTextLen; + int BufSize; + bool BufDirty; + int CursorPos; + int SelectionStart; + int SelectionEnd; +} + +struct ImGuiSizeCallbackData +{ + void* UserData; + ImVec2 Pos; + ImVec2 CurrentSize; + ImVec2 DesiredSize; +} + +struct ImGuiPayload +{ + void* Data; + int DataSize; + ImGuiID SourceId; + ImGuiID SourceParentId; + int DataFrameCount; + char[33] DataType; + bool Preview; + bool Delivery; +} + +struct ImGuiOnceUponAFrame +{ + int RefFrame; +} + +struct ImGuiTextFilter +{ + char[256] InputBuf; + ImVector_ImGuiTextRange Filters; + int CountGrep; +} + +struct ImGuiTextBuffer +{ + ImVector_char Buf; +} + +struct ImGuiStorage +{ + ImVector_ImGuiStoragePair Data; +} + +struct ImGuiListClipper +{ + float StartPosY; + float ItemsHeight; + int ItemsCount; + int StepNo; + int DisplayStart; + int DisplayEnd; +} + +struct ImColor +{ + ImVec4 Value; +} + +struct ImDrawCmd +{ + uint ElemCount; + ImVec4 ClipRect; + ImTextureID TextureId; + uint VtxOffset; + uint IdxOffset; + ImDrawCallback UserCallback; + void* UserCallbackData; +} + +struct ImDrawVert +{ + ImVec2 pos; + ImVec2 uv; + ImU32 col; +} + +struct ImDrawChannel +{ + ImVector_ImDrawCmd _CmdBuffer; + ImVector_ImDrawIdx _IdxBuffer; +} + +struct ImDrawListSplitter +{ + int _Current; + int _Count; + ImVector_ImDrawChannel _Channels; +} + +enum ImDrawCornerFlags_ +{ + ImDrawCornerFlags_None = 0, + ImDrawCornerFlags_TopLeft = 1 << 0, + ImDrawCornerFlags_TopRight = 1 << 1, + ImDrawCornerFlags_BotLeft = 1 << 2, + ImDrawCornerFlags_BotRight = 1 << 3, + ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, + ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, + ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, + ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight, + ImDrawCornerFlags_All = 0xF +} + +alias ImDrawCornerFlags_None = ImDrawCornerFlags_.ImDrawCornerFlags_None; +alias ImDrawCornerFlags_TopLeft = ImDrawCornerFlags_.ImDrawCornerFlags_TopLeft; +alias ImDrawCornerFlags_TopRight = ImDrawCornerFlags_.ImDrawCornerFlags_TopRight; +alias ImDrawCornerFlags_BotLeft = ImDrawCornerFlags_.ImDrawCornerFlags_BotLeft; +alias ImDrawCornerFlags_BotRight = ImDrawCornerFlags_.ImDrawCornerFlags_BotRight; +alias ImDrawCornerFlags_Top = ImDrawCornerFlags_.ImDrawCornerFlags_Top; +alias ImDrawCornerFlags_Bot = ImDrawCornerFlags_.ImDrawCornerFlags_Bot; +alias ImDrawCornerFlags_Left = ImDrawCornerFlags_.ImDrawCornerFlags_Left; +alias ImDrawCornerFlags_Right = ImDrawCornerFlags_.ImDrawCornerFlags_Right; +alias ImDrawCornerFlags_All = ImDrawCornerFlags_.ImDrawCornerFlags_All; + +enum ImDrawListFlags_ +{ + ImDrawListFlags_None = 0, + ImDrawListFlags_AntiAliasedLines = 1 << 0, + ImDrawListFlags_AntiAliasedFill = 1 << 1, + ImDrawListFlags_AllowVtxOffset = 1 << 2 +} + +alias ImDrawListFlags_None = ImDrawListFlags_.ImDrawListFlags_None; +alias ImDrawListFlags_AntiAliasedLines = ImDrawListFlags_.ImDrawListFlags_AntiAliasedLines; +alias ImDrawListFlags_AntiAliasedFill = ImDrawListFlags_.ImDrawListFlags_AntiAliasedFill; +alias ImDrawListFlags_AllowVtxOffset = ImDrawListFlags_.ImDrawListFlags_AllowVtxOffset; + +struct ImDrawList +{ + ImVector_ImDrawCmd CmdBuffer; + ImVector_ImDrawIdx IdxBuffer; + ImVector_ImDrawVert VtxBuffer; + ImDrawListFlags Flags; + const(ImDrawListSharedData)* _Data; + const(char)* _OwnerName; + uint _VtxCurrentOffset; + uint _VtxCurrentIdx; + ImDrawVert* _VtxWritePtr; + ImDrawIdx* _IdxWritePtr; + ImVector_ImVec4 _ClipRectStack; + ImVector_ImTextureID _TextureIdStack; + ImVector_ImVec2 _Path; + ImDrawListSplitter _Splitter; +} + +struct ImDrawData +{ + bool Valid; + ImDrawList** CmdLists; + int CmdListsCount; + int TotalIdxCount; + int TotalVtxCount; + ImVec2 DisplayPos; + ImVec2 DisplaySize; + ImVec2 FramebufferScale; +} + +struct ImFontConfig +{ + void* FontData; + int FontDataSize; + bool FontDataOwnedByAtlas; + int FontNo; + float SizePixels; + int OversampleH; + int OversampleV; + bool PixelSnapH; + ImVec2 GlyphExtraSpacing; + ImVec2 GlyphOffset; + const(ImWchar)* GlyphRanges; + float GlyphMinAdvanceX; + float GlyphMaxAdvanceX; + bool MergeMode; + uint RasterizerFlags; + float RasterizerMultiply; + ImWchar EllipsisChar; + char[40] Name; + ImFont* DstFont; +} + +struct ImFontGlyph +{ + ImWchar Codepoint; + float AdvanceX; + float X0; + float Y0; + float X1; + float Y1; + float U0; + float V0; + float U1; + float V1; +} + +struct ImFontGlyphRangesBuilder +{ + ImVector_ImU32 UsedChars; +} + +struct ImFontAtlasCustomRect +{ + uint ID; + ushort Width; + ushort Height; + ushort X; + ushort Y; + float GlyphAdvanceX; + ImVec2 GlyphOffset; + ImFont* Font; +} + +enum ImFontAtlasFlags_ +{ + ImFontAtlasFlags_None = 0, + ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, + ImFontAtlasFlags_NoMouseCursors = 1 << 1 +} + +alias ImFontAtlasFlags_None = ImFontAtlasFlags_.ImFontAtlasFlags_None; +alias ImFontAtlasFlags_NoPowerOfTwoHeight = ImFontAtlasFlags_.ImFontAtlasFlags_NoPowerOfTwoHeight; +alias ImFontAtlasFlags_NoMouseCursors = ImFontAtlasFlags_.ImFontAtlasFlags_NoMouseCursors; + +struct ImFontAtlas +{ + bool Locked; + ImFontAtlasFlags Flags; + ImTextureID TexID; + int TexDesiredWidth; + int TexGlyphPadding; + ubyte* TexPixelsAlpha8; + uint* TexPixelsRGBA32; + int TexWidth; + int TexHeight; + ImVec2 TexUvScale; + ImVec2 TexUvWhitePixel; + ImVector_ImFontPtr Fonts; + ImVector_ImFontAtlasCustomRect CustomRects; + ImVector_ImFontConfig ConfigData; + int[1] CustomRectIds; +} + +struct ImFont +{ + ImVector_float IndexAdvanceX; + float FallbackAdvanceX; + float FontSize; + ImVector_ImWchar IndexLookup; + ImVector_ImFontGlyph Glyphs; + const(ImFontGlyph)* FallbackGlyph; + ImVec2 DisplayOffset; + ImFontAtlas* ContainerAtlas; + const(ImFontConfig)* ConfigData; + short ConfigDataCount; + ImWchar FallbackChar; + ImWchar EllipsisChar; + float Scale; + float Ascent; + float Descent; + int MetricsTotalSurface; + bool DirtyLookupTables; +} + +struct ImGuiTextRange +{ + const(char)* b; + const(char)* e; +} + +struct ImGuiStoragePair +{ + ImGuiID key; + + union + { + int val_i; + float val_f; + void* val_p; + } +} + +// CIMGUI_DEFINE_ENUMS_AND_STRUCTS + +//CIMGUI_DEFINE_ENUMS_AND_STRUCTS +ImVec2* ImVec2_ImVec2 (); +void ImVec2_destroy (ImVec2* self); +ImVec2* ImVec2_ImVec2Float (float _x, float _y); +ImVec4* ImVec4_ImVec4 (); +void ImVec4_destroy (ImVec4* self); +ImVec4* ImVec4_ImVec4Float (float _x, float _y, float _z, float _w); +ImGuiContext* igCreateContext (ImFontAtlas* shared_font_atlas); +void igDestroyContext (ImGuiContext* ctx); +ImGuiContext* igGetCurrentContext (); +void igSetCurrentContext (ImGuiContext* ctx); +bool igDebugCheckVersionAndDataLayout (const(char)* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); +ImGuiIO* igGetIO (); +ImGuiStyle* igGetStyle (); +void igNewFrame (); +void igEndFrame (); +void igRender (); +ImDrawData* igGetDrawData (); +void igShowDemoWindow (bool* p_open); +void igShowAboutWindow (bool* p_open); +void igShowMetricsWindow (bool* p_open); +void igShowStyleEditor (ImGuiStyle* ref_); +bool igShowStyleSelector (const(char)* label); +void igShowFontSelector (const(char)* label); +void igShowUserGuide (); +const(char)* igGetVersion (); +void igStyleColorsDark (ImGuiStyle* dst); +void igStyleColorsClassic (ImGuiStyle* dst); +void igStyleColorsLight (ImGuiStyle* dst); +bool igBegin (const(char)* name, bool* p_open, ImGuiWindowFlags flags); +void igEnd (); +bool igBeginChild (const(char)* str_id, const ImVec2 size, bool border, ImGuiWindowFlags flags); +bool igBeginChildID (ImGuiID id, const ImVec2 size, bool border, ImGuiWindowFlags flags); +void igEndChild (); +bool igIsWindowAppearing (); +bool igIsWindowCollapsed (); +bool igIsWindowFocused (ImGuiFocusedFlags flags); +bool igIsWindowHovered (ImGuiHoveredFlags flags); +ImDrawList* igGetWindowDrawList (); +ImVec2 igGetWindowPos (); +ImVec2 igGetWindowSize (); +float igGetWindowWidth (); +float igGetWindowHeight (); +void igSetNextWindowPos (const ImVec2 pos, ImGuiCond cond, const ImVec2 pivot); +void igSetNextWindowSize (const ImVec2 size, ImGuiCond cond); +void igSetNextWindowSizeConstraints (const ImVec2 size_min, const ImVec2 size_max, ImGuiSizeCallback custom_callback, void* custom_callback_data); +void igSetNextWindowContentSize (const ImVec2 size); +void igSetNextWindowCollapsed (bool collapsed, ImGuiCond cond); +void igSetNextWindowFocus (); +void igSetNextWindowBgAlpha (float alpha); +void igSetWindowPosVec2 (const ImVec2 pos, ImGuiCond cond); +void igSetWindowSizeVec2 (const ImVec2 size, ImGuiCond cond); +void igSetWindowCollapsedBool (bool collapsed, ImGuiCond cond); +void igSetWindowFocus (); +void igSetWindowFontScale (float scale); +void igSetWindowPosStr (const(char)* name, const ImVec2 pos, ImGuiCond cond); +void igSetWindowSizeStr (const(char)* name, const ImVec2 size, ImGuiCond cond); +void igSetWindowCollapsedStr (const(char)* name, bool collapsed, ImGuiCond cond); +void igSetWindowFocusStr (const(char)* name); +ImVec2 igGetContentRegionMax (); +ImVec2 igGetContentRegionAvail (); +ImVec2 igGetWindowContentRegionMin (); +ImVec2 igGetWindowContentRegionMax (); +float igGetWindowContentRegionWidth (); +float igGetScrollX (); +float igGetScrollY (); +float igGetScrollMaxX (); +float igGetScrollMaxY (); +void igSetScrollX (float scroll_x); +void igSetScrollY (float scroll_y); +void igSetScrollHereX (float center_x_ratio); +void igSetScrollHereY (float center_y_ratio); +void igSetScrollFromPosX (float local_x, float center_x_ratio); +void igSetScrollFromPosY (float local_y, float center_y_ratio); +void igPushFont (ImFont* font); +void igPopFont (); +void igPushStyleColorU32 (ImGuiCol idx, ImU32 col); +void igPushStyleColor (ImGuiCol idx, const ImVec4 col); +void igPopStyleColor (int count); +void igPushStyleVarFloat (ImGuiStyleVar idx, float val); +void igPushStyleVarVec2 (ImGuiStyleVar idx, const ImVec2 val); +void igPopStyleVar (int count); +const(ImVec4)* igGetStyleColorVec4 (ImGuiCol idx); +ImFont* igGetFont (); +float igGetFontSize (); +ImVec2 igGetFontTexUvWhitePixel (); +ImU32 igGetColorU32 (ImGuiCol idx, float alpha_mul); +ImU32 igGetColorU32Vec4 (const ImVec4 col); +ImU32 igGetColorU32U32 (ImU32 col); +void igPushItemWidth (float item_width); +void igPopItemWidth (); +void igSetNextItemWidth (float item_width); +float igCalcItemWidth (); +void igPushTextWrapPos (float wrap_local_pos_x); +void igPopTextWrapPos (); +void igPushAllowKeyboardFocus (bool allow_keyboard_focus); +void igPopAllowKeyboardFocus (); +void igPushButtonRepeat (bool repeat); +void igPopButtonRepeat (); +void igSeparator (); +void igSameLine (float offset_from_start_x, float spacing); +void igNewLine (); +void igSpacing (); +void igDummy (const ImVec2 size); +void igIndent (float indent_w); +void igUnindent (float indent_w); +void igBeginGroup (); +void igEndGroup (); +ImVec2 igGetCursorPos (); +float igGetCursorPosX (); +float igGetCursorPosY (); +void igSetCursorPos (const ImVec2 local_pos); +void igSetCursorPosX (float local_x); +void igSetCursorPosY (float local_y); +ImVec2 igGetCursorStartPos (); +ImVec2 igGetCursorScreenPos (); +void igSetCursorScreenPos (const ImVec2 pos); +void igAlignTextToFramePadding (); +float igGetTextLineHeight (); +float igGetTextLineHeightWithSpacing (); +float igGetFrameHeight (); +float igGetFrameHeightWithSpacing (); +void igPushIDStr (const(char)* str_id); +void igPushIDRange (const(char)* str_id_begin, const(char)* str_id_end); +void igPushIDPtr (const(void)* ptr_id); +void igPushIDInt (int int_id); +void igPopID (); +ImGuiID igGetIDStr (const(char)* str_id); +ImGuiID igGetIDRange (const(char)* str_id_begin, const(char)* str_id_end); +ImGuiID igGetIDPtr (const(void)* ptr_id); +void igTextUnformatted (const(char)* text, const(char)* text_end); +void igText (const(char)* fmt, ...); +void igTextV (const(char)* fmt, va_list args); +void igTextColored (const ImVec4 col, const(char)* fmt, ...); +void igTextColoredV (const ImVec4 col, const(char)* fmt, va_list args); +void igTextDisabled (const(char)* fmt, ...); +void igTextDisabledV (const(char)* fmt, va_list args); +void igTextWrapped (const(char)* fmt, ...); +void igTextWrappedV (const(char)* fmt, va_list args); +void igLabelText (const(char)* label, const(char)* fmt, ...); +void igLabelTextV (const(char)* label, const(char)* fmt, va_list args); +void igBulletText (const(char)* fmt, ...); +void igBulletTextV (const(char)* fmt, va_list args); +bool igButton (const(char)* label, const ImVec2 size); +bool igSmallButton (const(char)* label); +bool igInvisibleButton (const(char)* str_id, const ImVec2 size); +bool igArrowButton (const(char)* str_id, ImGuiDir dir); +void igImage (ImTextureID user_texture_id, const ImVec2 size, const ImVec2 uv0, const ImVec2 uv1, const ImVec4 tint_col, const ImVec4 border_col); +bool igImageButton (ImTextureID user_texture_id, const ImVec2 size, const ImVec2 uv0, const ImVec2 uv1, int frame_padding, const ImVec4 bg_col, const ImVec4 tint_col); +bool igCheckbox (const(char)* label, bool* v); +bool igCheckboxFlags (const(char)* label, uint* flags, uint flags_value); +bool igRadioButtonBool (const(char)* label, bool active); +bool igRadioButtonIntPtr (const(char)* label, int* v, int v_button); +void igProgressBar (float fraction, const ImVec2 size_arg, const(char)* overlay); +void igBullet (); +bool igBeginCombo (const(char)* label, const(char)* preview_value, ImGuiComboFlags flags); +void igEndCombo (); +bool igCombo (const(char)* label, int* current_item, const(char*)* items, int items_count, int popup_max_height_in_items); +bool igComboStr (const(char)* label, int* current_item, const(char)* items_separated_by_zeros, int popup_max_height_in_items); +bool igComboFnPtr (const(char)* label, int* current_item, bool function (void* data, int idx, const(char*)* out_text) items_getter, void* data, int items_count, int popup_max_height_in_items); +bool igDragFloat (const(char)* label, float* v, float v_speed, float v_min, float v_max, const(char)* format, float power); +bool igDragFloat2 (const(char)* label, ref float[2] v, float v_speed, float v_min, float v_max, const(char)* format, float power); +bool igDragFloat3 (const(char)* label, ref float[3] v, float v_speed, float v_min, float v_max, const(char)* format, float power); +bool igDragFloat4 (const(char)* label, ref float[4] v, float v_speed, float v_min, float v_max, const(char)* format, float power); +bool igDragFloatRange2 (const(char)* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const(char)* format, const(char)* format_max, float power); +bool igDragInt (const(char)* label, int* v, float v_speed, int v_min, int v_max, const(char)* format); +bool igDragInt2 (const(char)* label, ref int[2] v, float v_speed, int v_min, int v_max, const(char)* format); +bool igDragInt3 (const(char)* label, ref int[3] v, float v_speed, int v_min, int v_max, const(char)* format); +bool igDragInt4 (const(char)* label, ref int[4] v, float v_speed, int v_min, int v_max, const(char)* format); +bool igDragIntRange2 (const(char)* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const(char)* format, const(char)* format_max); +bool igDragScalar (const(char)* label, ImGuiDataType data_type, void* v, float v_speed, const(void)* v_min, const(void)* v_max, const(char)* format, float power); +bool igDragScalarN (const(char)* label, ImGuiDataType data_type, void* v, int components, float v_speed, const(void)* v_min, const(void)* v_max, const(char)* format, float power); +bool igSliderFloat (const(char)* label, float* v, float v_min, float v_max, const(char)* format, float power); +bool igSliderFloat2 (const(char)* label, ref float[2] v, float v_min, float v_max, const(char)* format, float power); +bool igSliderFloat3 (const(char)* label, ref float[3] v, float v_min, float v_max, const(char)* format, float power); +bool igSliderFloat4 (const(char)* label, ref float[4] v, float v_min, float v_max, const(char)* format, float power); +bool igSliderAngle (const(char)* label, float* v_rad, float v_degrees_min, float v_degrees_max, const(char)* format); +bool igSliderInt (const(char)* label, int* v, int v_min, int v_max, const(char)* format); +bool igSliderInt2 (const(char)* label, ref int[2] v, int v_min, int v_max, const(char)* format); +bool igSliderInt3 (const(char)* label, ref int[3] v, int v_min, int v_max, const(char)* format); +bool igSliderInt4 (const(char)* label, ref int[4] v, int v_min, int v_max, const(char)* format); +bool igSliderScalar (const(char)* label, ImGuiDataType data_type, void* v, const(void)* v_min, const(void)* v_max, const(char)* format, float power); +bool igSliderScalarN (const(char)* label, ImGuiDataType data_type, void* v, int components, const(void)* v_min, const(void)* v_max, const(char)* format, float power); +bool igVSliderFloat (const(char)* label, const ImVec2 size, float* v, float v_min, float v_max, const(char)* format, float power); +bool igVSliderInt (const(char)* label, const ImVec2 size, int* v, int v_min, int v_max, const(char)* format); +bool igVSliderScalar (const(char)* label, const ImVec2 size, ImGuiDataType data_type, void* v, const(void)* v_min, const(void)* v_max, const(char)* format, float power); +bool igInputText (const(char)* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); +bool igInputTextMultiline (const(char)* label, char* buf, size_t buf_size, const ImVec2 size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); +bool igInputTextWithHint (const(char)* label, const(char)* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); +bool igInputFloat (const(char)* label, float* v, float step, float step_fast, const(char)* format, ImGuiInputTextFlags flags); +bool igInputFloat2 (const(char)* label, ref float[2] v, const(char)* format, ImGuiInputTextFlags flags); +bool igInputFloat3 (const(char)* label, ref float[3] v, const(char)* format, ImGuiInputTextFlags flags); +bool igInputFloat4 (const(char)* label, ref float[4] v, const(char)* format, ImGuiInputTextFlags flags); +bool igInputInt (const(char)* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags); +bool igInputInt2 (const(char)* label, ref int[2] v, ImGuiInputTextFlags flags); +bool igInputInt3 (const(char)* label, ref int[3] v, ImGuiInputTextFlags flags); +bool igInputInt4 (const(char)* label, ref int[4] v, ImGuiInputTextFlags flags); +bool igInputDouble (const(char)* label, double* v, double step, double step_fast, const(char)* format, ImGuiInputTextFlags flags); +bool igInputScalar (const(char)* label, ImGuiDataType data_type, void* v, const(void)* step, const(void)* step_fast, const(char)* format, ImGuiInputTextFlags flags); +bool igInputScalarN (const(char)* label, ImGuiDataType data_type, void* v, int components, const(void)* step, const(void)* step_fast, const(char)* format, ImGuiInputTextFlags flags); +bool igColorEdit3 (const(char)* label, ref float[3] col, ImGuiColorEditFlags flags); +bool igColorEdit4 (const(char)* label, ref float[4] col, ImGuiColorEditFlags flags); +bool igColorPicker3 (const(char)* label, ref float[3] col, ImGuiColorEditFlags flags); +bool igColorPicker4 (const(char)* label, ref float[4] col, ImGuiColorEditFlags flags, const(float)* ref_col); +bool igColorButton (const(char)* desc_id, const ImVec4 col, ImGuiColorEditFlags flags, ImVec2 size); +void igSetColorEditOptions (ImGuiColorEditFlags flags); +bool igTreeNodeStr (const(char)* label); +bool igTreeNodeStrStr (const(char)* str_id, const(char)* fmt, ...); +bool igTreeNodePtr (const(void)* ptr_id, const(char)* fmt, ...); +bool igTreeNodeVStr (const(char)* str_id, const(char)* fmt, va_list args); +bool igTreeNodeVPtr (const(void)* ptr_id, const(char)* fmt, va_list args); +bool igTreeNodeExStr (const(char)* label, ImGuiTreeNodeFlags flags); +bool igTreeNodeExStrStr (const(char)* str_id, ImGuiTreeNodeFlags flags, const(char)* fmt, ...); +bool igTreeNodeExPtr (const(void)* ptr_id, ImGuiTreeNodeFlags flags, const(char)* fmt, ...); +bool igTreeNodeExVStr (const(char)* str_id, ImGuiTreeNodeFlags flags, const(char)* fmt, va_list args); +bool igTreeNodeExVPtr (const(void)* ptr_id, ImGuiTreeNodeFlags flags, const(char)* fmt, va_list args); +void igTreePushStr (const(char)* str_id); +void igTreePushPtr (const(void)* ptr_id); +void igTreePop (); +float igGetTreeNodeToLabelSpacing (); +bool igCollapsingHeader (const(char)* label, ImGuiTreeNodeFlags flags); +bool igCollapsingHeaderBoolPtr (const(char)* label, bool* p_open, ImGuiTreeNodeFlags flags); +void igSetNextItemOpen (bool is_open, ImGuiCond cond); +bool igSelectable (const(char)* label, bool selected, ImGuiSelectableFlags flags, const ImVec2 size); +bool igSelectableBoolPtr (const(char)* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2 size); +bool igListBoxStr_arr (const(char)* label, int* current_item, const(char*)* items, int items_count, int height_in_items); +bool igListBoxFnPtr (const(char)* label, int* current_item, bool function (void* data, int idx, const(char*)* out_text) items_getter, void* data, int items_count, int height_in_items); +bool igListBoxHeaderVec2 (const(char)* label, const ImVec2 size); +bool igListBoxHeaderInt (const(char)* label, int items_count, int height_in_items); +void igListBoxFooter (); +void igPlotLines (const(char)* label, const(float)* values, int values_count, int values_offset, const(char)* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride); +void igPlotLinesFnPtr (const(char)* label, float function (void* data, int idx) values_getter, void* data, int values_count, int values_offset, const(char)* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); +void igPlotHistogramFloatPtr (const(char)* label, const(float)* values, int values_count, int values_offset, const(char)* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride); +void igPlotHistogramFnPtr (const(char)* label, float function (void* data, int idx) values_getter, void* data, int values_count, int values_offset, const(char)* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); +void igValueBool (const(char)* prefix, bool b); +void igValueInt (const(char)* prefix, int v); +void igValueUint (const(char)* prefix, uint v); +void igValueFloat (const(char)* prefix, float v, const(char)* float_format); +bool igBeginMainMenuBar (); +void igEndMainMenuBar (); +bool igBeginMenuBar (); +void igEndMenuBar (); +bool igBeginMenu (const(char)* label, bool enabled); +void igEndMenu (); +bool igMenuItemBool (const(char)* label, const(char)* shortcut, bool selected, bool enabled); +bool igMenuItemBoolPtr (const(char)* label, const(char)* shortcut, bool* p_selected, bool enabled); +void igBeginTooltip (); +void igEndTooltip (); +void igSetTooltip (const(char)* fmt, ...); +void igSetTooltipV (const(char)* fmt, va_list args); +void igOpenPopup (const(char)* str_id); +bool igBeginPopup (const(char)* str_id, ImGuiWindowFlags flags); +bool igBeginPopupContextItem (const(char)* str_id, int mouse_button); +bool igBeginPopupContextWindow (const(char)* str_id, int mouse_button, bool also_over_items); +bool igBeginPopupContextVoid (const(char)* str_id, int mouse_button); +bool igBeginPopupModal (const(char)* name, bool* p_open, ImGuiWindowFlags flags); +void igEndPopup (); +bool igOpenPopupOnItemClick (const(char)* str_id, int mouse_button); +bool igIsPopupOpen (const(char)* str_id); +void igCloseCurrentPopup (); +void igColumns (int count, const(char)* id, bool border); +void igNextColumn (); +int igGetColumnIndex (); +float igGetColumnWidth (int column_index); +void igSetColumnWidth (int column_index, float width); +float igGetColumnOffset (int column_index); +void igSetColumnOffset (int column_index, float offset_x); +int igGetColumnsCount (); +bool igBeginTabBar (const(char)* str_id, ImGuiTabBarFlags flags); +void igEndTabBar (); +bool igBeginTabItem (const(char)* label, bool* p_open, ImGuiTabItemFlags flags); +void igEndTabItem (); +void igSetTabItemClosed (const(char)* tab_or_docked_window_label); +void igLogToTTY (int auto_open_depth); +void igLogToFile (int auto_open_depth, const(char)* filename); +void igLogToClipboard (int auto_open_depth); +void igLogFinish (); +void igLogButtons (); +bool igBeginDragDropSource (ImGuiDragDropFlags flags); +bool igSetDragDropPayload (const(char)* type, const(void)* data, size_t sz, ImGuiCond cond); +void igEndDragDropSource (); +bool igBeginDragDropTarget (); +const(ImGuiPayload)* igAcceptDragDropPayload (const(char)* type, ImGuiDragDropFlags flags); +void igEndDragDropTarget (); +const(ImGuiPayload)* igGetDragDropPayload (); +void igPushClipRect (const ImVec2 clip_rect_min, const ImVec2 clip_rect_max, bool intersect_with_current_clip_rect); +void igPopClipRect (); +void igSetItemDefaultFocus (); +void igSetKeyboardFocusHere (int offset); +bool igIsItemHovered (ImGuiHoveredFlags flags); +bool igIsItemActive (); +bool igIsItemFocused (); +bool igIsItemClicked (int mouse_button); +bool igIsItemVisible (); +bool igIsItemEdited (); +bool igIsItemActivated (); +bool igIsItemDeactivated (); +bool igIsItemDeactivatedAfterEdit (); +bool igIsAnyItemHovered (); +bool igIsAnyItemActive (); +bool igIsAnyItemFocused (); +ImVec2 igGetItemRectMin (); +ImVec2 igGetItemRectMax (); +ImVec2 igGetItemRectSize (); +void igSetItemAllowOverlap (); +bool igIsRectVisible (const ImVec2 size); +bool igIsRectVisibleVec2 (const ImVec2 rect_min, const ImVec2 rect_max); +double igGetTime (); +int igGetFrameCount (); +ImDrawList* igGetBackgroundDrawList (); +ImDrawList* igGetForegroundDrawList (); +ImDrawListSharedData* igGetDrawListSharedData (); +const(char)* igGetStyleColorName (ImGuiCol idx); +void igSetStateStorage (ImGuiStorage* storage); +ImGuiStorage* igGetStateStorage (); +ImVec2 igCalcTextSize (const(char)* text, const(char)* text_end, bool hide_text_after_double_hash, float wrap_width); +void igCalcListClipping (int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); +bool igBeginChildFrame (ImGuiID id, const ImVec2 size, ImGuiWindowFlags flags); +void igEndChildFrame (); +ImVec4 igColorConvertU32ToFloat4 (ImU32 in_); +ImU32 igColorConvertFloat4ToU32 (const ImVec4 in_); +int igGetKeyIndex (ImGuiKey imgui_key); +bool igIsKeyDown (int user_key_index); +bool igIsKeyPressed (int user_key_index, bool repeat); +bool igIsKeyReleased (int user_key_index); +int igGetKeyPressedAmount (int key_index, float repeat_delay, float rate); +bool igIsMouseDown (int button); +bool igIsAnyMouseDown (); +bool igIsMouseClicked (int button, bool repeat); +bool igIsMouseDoubleClicked (int button); +bool igIsMouseReleased (int button); +bool igIsMouseDragging (int button, float lock_threshold); +bool igIsMouseHoveringRect (const ImVec2 r_min, const ImVec2 r_max, bool clip); +bool igIsMousePosValid (const(ImVec2)* mouse_pos); +ImVec2 igGetMousePos (); +ImVec2 igGetMousePosOnOpeningCurrentPopup (); +ImVec2 igGetMouseDragDelta (int button, float lock_threshold); +void igResetMouseDragDelta (int button); +ImGuiMouseCursor igGetMouseCursor (); +void igSetMouseCursor (ImGuiMouseCursor type); +void igCaptureKeyboardFromApp (bool want_capture_keyboard_value); +void igCaptureMouseFromApp (bool want_capture_mouse_value); +const(char)* igGetClipboardText (); +void igSetClipboardText (const(char)* text); +void igLoadIniSettingsFromDisk (const(char)* ini_filename); +void igLoadIniSettingsFromMemory (const(char)* ini_data, size_t ini_size); +void igSaveIniSettingsToDisk (const(char)* ini_filename); +const(char)* igSaveIniSettingsToMemory (size_t* out_ini_size); +void igSetAllocatorFunctions (void* function (size_t sz, void* user_data) alloc_func, void function (void* ptr, void* user_data) free_func, void* user_data); +void* igMemAlloc (size_t size); +void igMemFree (void* ptr); +ImGuiStyle* ImGuiStyle_ImGuiStyle (); +void ImGuiStyle_destroy (ImGuiStyle* self); +void ImGuiStyle_ScaleAllSizes (ImGuiStyle* self, float scale_factor); +void ImGuiIO_AddInputCharacter (ImGuiIO* self, uint c); +void ImGuiIO_AddInputCharactersUTF8 (ImGuiIO* self, const(char)* str); +void ImGuiIO_ClearInputCharacters (ImGuiIO* self); +ImGuiIO* ImGuiIO_ImGuiIO (); +void ImGuiIO_destroy (ImGuiIO* self); +ImGuiInputTextCallbackData* ImGuiInputTextCallbackData_ImGuiInputTextCallbackData (); +void ImGuiInputTextCallbackData_destroy (ImGuiInputTextCallbackData* self); +void ImGuiInputTextCallbackData_DeleteChars (ImGuiInputTextCallbackData* self, int pos, int bytes_count); +void ImGuiInputTextCallbackData_InsertChars (ImGuiInputTextCallbackData* self, int pos, const(char)* text, const(char)* text_end); +bool ImGuiInputTextCallbackData_HasSelection (ImGuiInputTextCallbackData* self); +ImGuiPayload* ImGuiPayload_ImGuiPayload (); +void ImGuiPayload_destroy (ImGuiPayload* self); +void ImGuiPayload_Clear (ImGuiPayload* self); +bool ImGuiPayload_IsDataType (ImGuiPayload* self, const(char)* type); +bool ImGuiPayload_IsPreview (ImGuiPayload* self); +bool ImGuiPayload_IsDelivery (ImGuiPayload* self); +ImGuiOnceUponAFrame* ImGuiOnceUponAFrame_ImGuiOnceUponAFrame (); +void ImGuiOnceUponAFrame_destroy (ImGuiOnceUponAFrame* self); +ImGuiTextFilter* ImGuiTextFilter_ImGuiTextFilter (const(char)* default_filter); +void ImGuiTextFilter_destroy (ImGuiTextFilter* self); +bool ImGuiTextFilter_Draw (ImGuiTextFilter* self, const(char)* label, float width); +bool ImGuiTextFilter_PassFilter (ImGuiTextFilter* self, const(char)* text, const(char)* text_end); +void ImGuiTextFilter_Build (ImGuiTextFilter* self); +void ImGuiTextFilter_Clear (ImGuiTextFilter* self); +bool ImGuiTextFilter_IsActive (ImGuiTextFilter* self); +ImGuiTextRange* ImGuiTextRange_ImGuiTextRange (); +void ImGuiTextRange_destroy (ImGuiTextRange* self); +ImGuiTextRange* ImGuiTextRange_ImGuiTextRangeStr (const(char)* _b, const(char)* _e); +bool ImGuiTextRange_empty (ImGuiTextRange* self); +void ImGuiTextRange_split (ImGuiTextRange* self, char separator, ImVector_ImGuiTextRange* out_); +ImGuiTextBuffer* ImGuiTextBuffer_ImGuiTextBuffer (); +void ImGuiTextBuffer_destroy (ImGuiTextBuffer* self); +const(char)* ImGuiTextBuffer_begin (ImGuiTextBuffer* self); +const(char)* ImGuiTextBuffer_end (ImGuiTextBuffer* self); +int ImGuiTextBuffer_size (ImGuiTextBuffer* self); +bool ImGuiTextBuffer_empty (ImGuiTextBuffer* self); +void ImGuiTextBuffer_clear (ImGuiTextBuffer* self); +void ImGuiTextBuffer_reserve (ImGuiTextBuffer* self, int capacity); +const(char)* ImGuiTextBuffer_c_str (ImGuiTextBuffer* self); +void ImGuiTextBuffer_append (ImGuiTextBuffer* self, const(char)* str, const(char)* str_end); +void ImGuiTextBuffer_appendfv (ImGuiTextBuffer* self, const(char)* fmt, va_list args); +ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePairInt (ImGuiID _key, int _val_i); +void ImGuiStoragePair_destroy (ImGuiStoragePair* self); +ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePairFloat (ImGuiID _key, float _val_f); +ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePairPtr (ImGuiID _key, void* _val_p); +void ImGuiStorage_Clear (ImGuiStorage* self); +int ImGuiStorage_GetInt (ImGuiStorage* self, ImGuiID key, int default_val); +void ImGuiStorage_SetInt (ImGuiStorage* self, ImGuiID key, int val); +bool ImGuiStorage_GetBool (ImGuiStorage* self, ImGuiID key, bool default_val); +void ImGuiStorage_SetBool (ImGuiStorage* self, ImGuiID key, bool val); +float ImGuiStorage_GetFloat (ImGuiStorage* self, ImGuiID key, float default_val); +void ImGuiStorage_SetFloat (ImGuiStorage* self, ImGuiID key, float val); +void* ImGuiStorage_GetVoidPtr (ImGuiStorage* self, ImGuiID key); +void ImGuiStorage_SetVoidPtr (ImGuiStorage* self, ImGuiID key, void* val); +int* ImGuiStorage_GetIntRef (ImGuiStorage* self, ImGuiID key, int default_val); +bool* ImGuiStorage_GetBoolRef (ImGuiStorage* self, ImGuiID key, bool default_val); +float* ImGuiStorage_GetFloatRef (ImGuiStorage* self, ImGuiID key, float default_val); +void** ImGuiStorage_GetVoidPtrRef (ImGuiStorage* self, ImGuiID key, void* default_val); +void ImGuiStorage_SetAllInt (ImGuiStorage* self, int val); +void ImGuiStorage_BuildSortByKey (ImGuiStorage* self); +ImGuiListClipper* ImGuiListClipper_ImGuiListClipper (int items_count, float items_height); +void ImGuiListClipper_destroy (ImGuiListClipper* self); +bool ImGuiListClipper_Step (ImGuiListClipper* self); +void ImGuiListClipper_Begin (ImGuiListClipper* self, int items_count, float items_height); +void ImGuiListClipper_End (ImGuiListClipper* self); +ImColor* ImColor_ImColor (); +void ImColor_destroy (ImColor* self); +ImColor* ImColor_ImColorInt (int r, int g, int b, int a); +ImColor* ImColor_ImColorU32 (ImU32 rgba); +ImColor* ImColor_ImColorFloat (float r, float g, float b, float a); +ImColor* ImColor_ImColorVec4 (const ImVec4 col); +void ImColor_SetHSV (ImColor* self, float h, float s, float v, float a); +ImColor ImColor_HSV (ImColor* self, float h, float s, float v, float a); +ImDrawCmd* ImDrawCmd_ImDrawCmd (); +void ImDrawCmd_destroy (ImDrawCmd* self); +ImDrawListSplitter* ImDrawListSplitter_ImDrawListSplitter (); +void ImDrawListSplitter_destroy (ImDrawListSplitter* self); +void ImDrawListSplitter_Clear (ImDrawListSplitter* self); +void ImDrawListSplitter_ClearFreeMemory (ImDrawListSplitter* self); +void ImDrawListSplitter_Split (ImDrawListSplitter* self, ImDrawList* draw_list, int count); +void ImDrawListSplitter_Merge (ImDrawListSplitter* self, ImDrawList* draw_list); +void ImDrawListSplitter_SetCurrentChannel (ImDrawListSplitter* self, ImDrawList* draw_list, int channel_idx); +ImDrawList* ImDrawList_ImDrawList (const(ImDrawListSharedData)* shared_data); +void ImDrawList_destroy (ImDrawList* self); +void ImDrawList_PushClipRect (ImDrawList* self, ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect); +void ImDrawList_PushClipRectFullScreen (ImDrawList* self); +void ImDrawList_PopClipRect (ImDrawList* self); +void ImDrawList_PushTextureID (ImDrawList* self, ImTextureID texture_id); +void ImDrawList_PopTextureID (ImDrawList* self); +ImVec2 ImDrawList_GetClipRectMin (ImDrawList* self); +ImVec2 ImDrawList_GetClipRectMax (ImDrawList* self); +void ImDrawList_AddLine (ImDrawList* self, const ImVec2 p1, const ImVec2 p2, ImU32 col, float thickness); +void ImDrawList_AddRect (ImDrawList* self, const ImVec2 p_min, const ImVec2 p_max, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners, float thickness); +void ImDrawList_AddRectFilled (ImDrawList* self, const ImVec2 p_min, const ImVec2 p_max, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners); +void ImDrawList_AddRectFilledMultiColor (ImDrawList* self, const ImVec2 p_min, const ImVec2 p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); +void ImDrawList_AddQuad (ImDrawList* self, const ImVec2 p1, const ImVec2 p2, const ImVec2 p3, const ImVec2 p4, ImU32 col, float thickness); +void ImDrawList_AddQuadFilled (ImDrawList* self, const ImVec2 p1, const ImVec2 p2, const ImVec2 p3, const ImVec2 p4, ImU32 col); +void ImDrawList_AddTriangle (ImDrawList* self, const ImVec2 p1, const ImVec2 p2, const ImVec2 p3, ImU32 col, float thickness); +void ImDrawList_AddTriangleFilled (ImDrawList* self, const ImVec2 p1, const ImVec2 p2, const ImVec2 p3, ImU32 col); +void ImDrawList_AddCircle (ImDrawList* self, const ImVec2 center, float radius, ImU32 col, int num_segments, float thickness); +void ImDrawList_AddCircleFilled (ImDrawList* self, const ImVec2 center, float radius, ImU32 col, int num_segments); +void ImDrawList_AddText (ImDrawList* self, const ImVec2 pos, ImU32 col, const(char)* text_begin, const(char)* text_end); +void ImDrawList_AddTextFontPtr (ImDrawList* self, const(ImFont)* font, float font_size, const ImVec2 pos, ImU32 col, const(char)* text_begin, const(char)* text_end, float wrap_width, const(ImVec4)* cpu_fine_clip_rect); +void ImDrawList_AddPolyline (ImDrawList* self, const(ImVec2)* points, int num_points, ImU32 col, bool closed, float thickness); +void ImDrawList_AddConvexPolyFilled (ImDrawList* self, const(ImVec2)* points, int num_points, ImU32 col); +void ImDrawList_AddBezierCurve (ImDrawList* self, const ImVec2 pos0, const ImVec2 cp0, const ImVec2 cp1, const ImVec2 pos1, ImU32 col, float thickness, int num_segments); +void ImDrawList_AddImage (ImDrawList* self, ImTextureID user_texture_id, const ImVec2 p_min, const ImVec2 p_max, const ImVec2 uv_min, const ImVec2 uv_max, ImU32 col); +void ImDrawList_AddImageQuad (ImDrawList* self, ImTextureID user_texture_id, const ImVec2 p1, const ImVec2 p2, const ImVec2 p3, const ImVec2 p4, const ImVec2 uv1, const ImVec2 uv2, const ImVec2 uv3, const ImVec2 uv4, ImU32 col); +void ImDrawList_AddImageRounded (ImDrawList* self, ImTextureID user_texture_id, const ImVec2 p_min, const ImVec2 p_max, const ImVec2 uv_min, const ImVec2 uv_max, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners); +void ImDrawList_PathClear (ImDrawList* self); +void ImDrawList_PathLineTo (ImDrawList* self, const ImVec2 pos); +void ImDrawList_PathLineToMergeDuplicate (ImDrawList* self, const ImVec2 pos); +void ImDrawList_PathFillConvex (ImDrawList* self, ImU32 col); +void ImDrawList_PathStroke (ImDrawList* self, ImU32 col, bool closed, float thickness); +void ImDrawList_PathArcTo (ImDrawList* self, const ImVec2 center, float radius, float a_min, float a_max, int num_segments); +void ImDrawList_PathArcToFast (ImDrawList* self, const ImVec2 center, float radius, int a_min_of_12, int a_max_of_12); +void ImDrawList_PathBezierCurveTo (ImDrawList* self, const ImVec2 p1, const ImVec2 p2, const ImVec2 p3, int num_segments); +void ImDrawList_PathRect (ImDrawList* self, const ImVec2 rect_min, const ImVec2 rect_max, float rounding, ImDrawCornerFlags rounding_corners); +void ImDrawList_AddCallback (ImDrawList* self, ImDrawCallback callback, void* callback_data); +void ImDrawList_AddDrawCmd (ImDrawList* self); +ImDrawList* ImDrawList_CloneOutput (ImDrawList* self); +void ImDrawList_ChannelsSplit (ImDrawList* self, int count); +void ImDrawList_ChannelsMerge (ImDrawList* self); +void ImDrawList_ChannelsSetCurrent (ImDrawList* self, int n); +void ImDrawList_Clear (ImDrawList* self); +void ImDrawList_ClearFreeMemory (ImDrawList* self); +void ImDrawList_PrimReserve (ImDrawList* self, int idx_count, int vtx_count); +void ImDrawList_PrimRect (ImDrawList* self, const ImVec2 a, const ImVec2 b, ImU32 col); +void ImDrawList_PrimRectUV (ImDrawList* self, const ImVec2 a, const ImVec2 b, const ImVec2 uv_a, const ImVec2 uv_b, ImU32 col); +void ImDrawList_PrimQuadUV (ImDrawList* self, const ImVec2 a, const ImVec2 b, const ImVec2 c, const ImVec2 d, const ImVec2 uv_a, const ImVec2 uv_b, const ImVec2 uv_c, const ImVec2 uv_d, ImU32 col); +void ImDrawList_PrimWriteVtx (ImDrawList* self, const ImVec2 pos, const ImVec2 uv, ImU32 col); +void ImDrawList_PrimWriteIdx (ImDrawList* self, ImDrawIdx idx); +void ImDrawList_PrimVtx (ImDrawList* self, const ImVec2 pos, const ImVec2 uv, ImU32 col); +void ImDrawList_UpdateClipRect (ImDrawList* self); +void ImDrawList_UpdateTextureID (ImDrawList* self); +ImDrawData* ImDrawData_ImDrawData (); +void ImDrawData_destroy (ImDrawData* self); +void ImDrawData_Clear (ImDrawData* self); +void ImDrawData_DeIndexAllBuffers (ImDrawData* self); +void ImDrawData_ScaleClipRects (ImDrawData* self, const ImVec2 fb_scale); +ImFontConfig* ImFontConfig_ImFontConfig (); +void ImFontConfig_destroy (ImFontConfig* self); +ImFontGlyphRangesBuilder* ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder (); +void ImFontGlyphRangesBuilder_destroy (ImFontGlyphRangesBuilder* self); +void ImFontGlyphRangesBuilder_Clear (ImFontGlyphRangesBuilder* self); +bool ImFontGlyphRangesBuilder_GetBit (ImFontGlyphRangesBuilder* self, int n); +void ImFontGlyphRangesBuilder_SetBit (ImFontGlyphRangesBuilder* self, int n); +void ImFontGlyphRangesBuilder_AddChar (ImFontGlyphRangesBuilder* self, ImWchar c); +void ImFontGlyphRangesBuilder_AddText (ImFontGlyphRangesBuilder* self, const(char)* text, const(char)* text_end); +void ImFontGlyphRangesBuilder_AddRanges (ImFontGlyphRangesBuilder* self, const(ImWchar)* ranges); +void ImFontGlyphRangesBuilder_BuildRanges (ImFontGlyphRangesBuilder* self, ImVector_ImWchar* out_ranges); +ImFontAtlasCustomRect* ImFontAtlasCustomRect_ImFontAtlasCustomRect (); +void ImFontAtlasCustomRect_destroy (ImFontAtlasCustomRect* self); +bool ImFontAtlasCustomRect_IsPacked (ImFontAtlasCustomRect* self); +ImFontAtlas* ImFontAtlas_ImFontAtlas (); +void ImFontAtlas_destroy (ImFontAtlas* self); +ImFont* ImFontAtlas_AddFont (ImFontAtlas* self, const(ImFontConfig)* font_cfg); +ImFont* ImFontAtlas_AddFontDefault (ImFontAtlas* self, const(ImFontConfig)* font_cfg); +ImFont* ImFontAtlas_AddFontFromFileTTF (ImFontAtlas* self, const(char)* filename, float size_pixels, const(ImFontConfig)* font_cfg, const(ImWchar)* glyph_ranges); +ImFont* ImFontAtlas_AddFontFromMemoryTTF (ImFontAtlas* self, void* font_data, int font_size, float size_pixels, const(ImFontConfig)* font_cfg, const(ImWchar)* glyph_ranges); +ImFont* ImFontAtlas_AddFontFromMemoryCompressedTTF (ImFontAtlas* self, const(void)* compressed_font_data, int compressed_font_size, float size_pixels, const(ImFontConfig)* font_cfg, const(ImWchar)* glyph_ranges); +ImFont* ImFontAtlas_AddFontFromMemoryCompressedBase85TTF (ImFontAtlas* self, const(char)* compressed_font_data_base85, float size_pixels, const(ImFontConfig)* font_cfg, const(ImWchar)* glyph_ranges); +void ImFontAtlas_ClearInputData (ImFontAtlas* self); +void ImFontAtlas_ClearTexData (ImFontAtlas* self); +void ImFontAtlas_ClearFonts (ImFontAtlas* self); +void ImFontAtlas_Clear (ImFontAtlas* self); +bool ImFontAtlas_Build (ImFontAtlas* self); +void ImFontAtlas_GetTexDataAsAlpha8 (ImFontAtlas* self, ubyte** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel); +void ImFontAtlas_GetTexDataAsRGBA32 (ImFontAtlas* self, ubyte** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel); +bool ImFontAtlas_IsBuilt (ImFontAtlas* self); +void ImFontAtlas_SetTexID (ImFontAtlas* self, ImTextureID id); +const(ImWchar)* ImFontAtlas_GetGlyphRangesDefault (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesKorean (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesJapanese (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesChineseFull (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesChineseSimplifiedCommon (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesCyrillic (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesThai (ImFontAtlas* self); +const(ImWchar)* ImFontAtlas_GetGlyphRangesVietnamese (ImFontAtlas* self); +int ImFontAtlas_AddCustomRectRegular (ImFontAtlas* self, uint id, int width, int height); +int ImFontAtlas_AddCustomRectFontGlyph (ImFontAtlas* self, ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2 offset); +const(ImFontAtlasCustomRect)* ImFontAtlas_GetCustomRectByIndex (ImFontAtlas* self, int index); +void ImFontAtlas_CalcCustomRectUV (ImFontAtlas* self, const(ImFontAtlasCustomRect)* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); +bool ImFontAtlas_GetMouseCursorTexData (ImFontAtlas* self, ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ref ImVec2[2] out_uv_border, ref ImVec2[2] out_uv_fill); +ImFont* ImFont_ImFont (); +void ImFont_destroy (ImFont* self); +const(ImFontGlyph)* ImFont_FindGlyph (ImFont* self, ImWchar c); +const(ImFontGlyph)* ImFont_FindGlyphNoFallback (ImFont* self, ImWchar c); +float ImFont_GetCharAdvance (ImFont* self, ImWchar c); +bool ImFont_IsLoaded (ImFont* self); +const(char)* ImFont_GetDebugName (ImFont* self); +ImVec2 ImFont_CalcTextSizeA (ImFont* self, float size, float max_width, float wrap_width, const(char)* text_begin, const(char)* text_end, const(char*)* remaining); +const(char)* ImFont_CalcWordWrapPositionA (ImFont* self, float scale, const(char)* text, const(char)* text_end, float wrap_width); +void ImFont_RenderChar (ImFont* self, ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c); +void ImFont_RenderText (ImFont* self, ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4 clip_rect, const(char)* text_begin, const(char)* text_end, float wrap_width, bool cpu_fine_clip); +void ImFont_BuildLookupTable (ImFont* self); +void ImFont_ClearOutputData (ImFont* self); +void ImFont_GrowIndex (ImFont* self, int new_size); +void ImFont_AddGlyph (ImFont* self, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); +void ImFont_AddRemapChar (ImFont* self, ImWchar dst, ImWchar src, bool overwrite_dst); +void ImFont_SetFallbackChar (ImFont* self, ImWchar c); +void igGetWindowPos_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetWindowPos_nonUDT2 (); +void igGetWindowSize_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetWindowSize_nonUDT2 (); +void igGetContentRegionMax_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetContentRegionMax_nonUDT2 (); +void igGetContentRegionAvail_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetContentRegionAvail_nonUDT2 (); +void igGetWindowContentRegionMin_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetWindowContentRegionMin_nonUDT2 (); +void igGetWindowContentRegionMax_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetWindowContentRegionMax_nonUDT2 (); +void igGetFontTexUvWhitePixel_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetFontTexUvWhitePixel_nonUDT2 (); +void igGetCursorPos_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetCursorPos_nonUDT2 (); +void igGetCursorStartPos_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetCursorStartPos_nonUDT2 (); +void igGetCursorScreenPos_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetCursorScreenPos_nonUDT2 (); +void igGetItemRectMin_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetItemRectMin_nonUDT2 (); +void igGetItemRectMax_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetItemRectMax_nonUDT2 (); +void igGetItemRectSize_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetItemRectSize_nonUDT2 (); +void igCalcTextSize_nonUDT (ImVec2* pOut, const(char)* text, const(char)* text_end, bool hide_text_after_double_hash, float wrap_width); +ImVec2_Simple igCalcTextSize_nonUDT2 (const(char)* text, const(char)* text_end, bool hide_text_after_double_hash, float wrap_width); +void igColorConvertU32ToFloat4_nonUDT (ImVec4* pOut, ImU32 in_); +ImVec4_Simple igColorConvertU32ToFloat4_nonUDT2 (ImU32 in_); +void igGetMousePos_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetMousePos_nonUDT2 (); +void igGetMousePosOnOpeningCurrentPopup_nonUDT (ImVec2* pOut); +ImVec2_Simple igGetMousePosOnOpeningCurrentPopup_nonUDT2 (); +void igGetMouseDragDelta_nonUDT (ImVec2* pOut, int button, float lock_threshold); +ImVec2_Simple igGetMouseDragDelta_nonUDT2 (int button, float lock_threshold); +void ImColor_HSV_nonUDT (ImColor* pOut, ImColor* self, float h, float s, float v, float a); +ImColor_Simple ImColor_HSV_nonUDT2 (ImColor* self, float h, float s, float v, float a); +void ImDrawList_GetClipRectMin_nonUDT (ImVec2* pOut, ImDrawList* self); +ImVec2_Simple ImDrawList_GetClipRectMin_nonUDT2 (ImDrawList* self); +void ImDrawList_GetClipRectMax_nonUDT (ImVec2* pOut, ImDrawList* self); +ImVec2_Simple ImDrawList_GetClipRectMax_nonUDT2 (ImDrawList* self); +void ImFont_CalcTextSizeA_nonUDT (ImVec2* pOut, ImFont* self, float size, float max_width, float wrap_width, const(char)* text_begin, const(char)* text_end, const(char*)* remaining); +ImVec2_Simple ImFont_CalcTextSizeA_nonUDT2 (ImFont* self, float size, float max_width, float wrap_width, const(char)* text_begin, const(char)* text_end, const(char*)* remaining); + +/////////////////////////hand written functions +//no LogTextV +void igLogText (const(char)* fmt, ...); +//no appendfV +void ImGuiTextBuffer_appendf (ImGuiTextBuffer* buffer, const(char)* fmt, ...); +//for getting FLT_MAX in bindings +float igGET_FLT_MAX (); +//not const args from & to * +void igColorConvertRGBtoHSV (float r, float g, float b, float* out_h, float* out_s, float* out_v); +void igColorConvertHSVtoRGB (float h, float s, float v, float* out_r, float* out_g, float* out_b); + +ImVector_ImWchar* ImVector_ImWchar_create (); +void ImVector_ImWchar_destroy (ImVector_ImWchar* self); +void ImVector_ImWchar_Init (ImVector_ImWchar* p); +void ImVector_ImWchar_UnInit (ImVector_ImWchar* p); +//CIMGUI_INCLUDED diff --git a/demos/external/sources/glad/gl/all.d b/demos/external/sources/glad/gl/all.d new file mode 100644 index 0000000..99c9ee4 --- /dev/null +++ b/demos/external/sources/glad/gl/all.d @@ -0,0 +1,28 @@ +/* + + OpenGL, OpenGL ES loader generated by glad 0.1.33 on Fri Nov 8 17:14:30 2019. + + Language/Generator: D + Specification: gl + APIs: gl=3.3, gles2=3.0 + Profile: compatibility + Extensions: + + Loader: True + Local files: False + Omit khrplatform: False + Reproducible: False + + Commandline: + --profile="compatibility" --api="gl=3.3,gles2=3.0" --generator="d" --spec="gl" --extensions="" + Online: + https://glad.dav1d.de/#profile=compatibility&language=d&specification=gl&loader=on&api=gl%3D3.3&api=gles2%3D3.0 +*/ + +module glad.gl.all; + + +public import glad.gl.funcs; +public import glad.gl.ext; +public import glad.gl.enums; +public import glad.gl.types; diff --git a/demos/external/sources/glad/gl/enums.d b/demos/external/sources/glad/gl/enums.d new file mode 100644 index 0000000..c840fbc --- /dev/null +++ b/demos/external/sources/glad/gl/enums.d @@ -0,0 +1,1302 @@ +module glad.gl.enums; + + +private import glad.gl.types; +enum ubyte GL_FALSE = 0; +enum ubyte GL_TRUE = 1; +enum uint GL_NO_ERROR = 0; +enum uint GL_NONE = 0; +enum uint GL_ZERO = 0; +enum uint GL_ONE = 1; +enum uint GL_NONE_OES = 0; +enum uint GL_INVALID_INDEX = 0xFFFFFFFF; +enum ulong GL_TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFF; +enum ulong GL_TIMEOUT_IGNORED_APPLE = 0xFFFFFFFFFFFFFFFF; +enum uint GL_VERSION_ES_CL_1_0 = 1; +enum uint GL_VERSION_ES_CM_1_1 = 1; +enum uint GL_VERSION_ES_CL_1_1 = 1; +enum uint GL_DEPTH_BUFFER_BIT = 0x00000100; +enum uint GL_STENCIL_BUFFER_BIT = 0x00000400; +enum uint GL_COLOR_BUFFER_BIT = 0x00004000; +enum uint GL_POINTS = 0x0000; +enum uint GL_LINES = 0x0001; +enum uint GL_LINE_LOOP = 0x0002; +enum uint GL_LINE_STRIP = 0x0003; +enum uint GL_TRIANGLES = 0x0004; +enum uint GL_TRIANGLE_STRIP = 0x0005; +enum uint GL_TRIANGLE_FAN = 0x0006; +enum uint GL_QUADS = 0x0007; +enum uint GL_NEVER = 0x0200; +enum uint GL_LESS = 0x0201; +enum uint GL_EQUAL = 0x0202; +enum uint GL_LEQUAL = 0x0203; +enum uint GL_GREATER = 0x0204; +enum uint GL_NOTEQUAL = 0x0205; +enum uint GL_GEQUAL = 0x0206; +enum uint GL_ALWAYS = 0x0207; +enum uint GL_SRC_COLOR = 0x0300; +enum uint GL_ONE_MINUS_SRC_COLOR = 0x0301; +enum uint GL_SRC_ALPHA = 0x0302; +enum uint GL_ONE_MINUS_SRC_ALPHA = 0x0303; +enum uint GL_DST_ALPHA = 0x0304; +enum uint GL_ONE_MINUS_DST_ALPHA = 0x0305; +enum uint GL_DST_COLOR = 0x0306; +enum uint GL_ONE_MINUS_DST_COLOR = 0x0307; +enum uint GL_SRC_ALPHA_SATURATE = 0x0308; +enum uint GL_FRONT_LEFT = 0x0400; +enum uint GL_FRONT_RIGHT = 0x0401; +enum uint GL_BACK_LEFT = 0x0402; +enum uint GL_BACK_RIGHT = 0x0403; +enum uint GL_FRONT = 0x0404; +enum uint GL_BACK = 0x0405; +enum uint GL_LEFT = 0x0406; +enum uint GL_RIGHT = 0x0407; +enum uint GL_FRONT_AND_BACK = 0x0408; +enum uint GL_INVALID_ENUM = 0x0500; +enum uint GL_INVALID_VALUE = 0x0501; +enum uint GL_INVALID_OPERATION = 0x0502; +enum uint GL_OUT_OF_MEMORY = 0x0505; +enum uint GL_CW = 0x0900; +enum uint GL_CCW = 0x0901; +enum uint GL_POINT_SIZE = 0x0B11; +enum uint GL_POINT_SIZE_RANGE = 0x0B12; +enum uint GL_POINT_SIZE_GRANULARITY = 0x0B13; +enum uint GL_LINE_SMOOTH = 0x0B20; +enum uint GL_LINE_WIDTH = 0x0B21; +enum uint GL_LINE_WIDTH_RANGE = 0x0B22; +enum uint GL_LINE_WIDTH_GRANULARITY = 0x0B23; +enum uint GL_POLYGON_MODE = 0x0B40; +enum uint GL_POLYGON_SMOOTH = 0x0B41; +enum uint GL_CULL_FACE = 0x0B44; +enum uint GL_CULL_FACE_MODE = 0x0B45; +enum uint GL_FRONT_FACE = 0x0B46; +enum uint GL_DEPTH_RANGE = 0x0B70; +enum uint GL_DEPTH_TEST = 0x0B71; +enum uint GL_DEPTH_WRITEMASK = 0x0B72; +enum uint GL_DEPTH_CLEAR_VALUE = 0x0B73; +enum uint GL_DEPTH_FUNC = 0x0B74; +enum uint GL_STENCIL_TEST = 0x0B90; +enum uint GL_STENCIL_CLEAR_VALUE = 0x0B91; +enum uint GL_STENCIL_FUNC = 0x0B92; +enum uint GL_STENCIL_VALUE_MASK = 0x0B93; +enum uint GL_STENCIL_FAIL = 0x0B94; +enum uint GL_STENCIL_PASS_DEPTH_FAIL = 0x0B95; +enum uint GL_STENCIL_PASS_DEPTH_PASS = 0x0B96; +enum uint GL_STENCIL_REF = 0x0B97; +enum uint GL_STENCIL_WRITEMASK = 0x0B98; +enum uint GL_VIEWPORT = 0x0BA2; +enum uint GL_DITHER = 0x0BD0; +enum uint GL_BLEND_DST = 0x0BE0; +enum uint GL_BLEND_SRC = 0x0BE1; +enum uint GL_BLEND = 0x0BE2; +enum uint GL_LOGIC_OP_MODE = 0x0BF0; +enum uint GL_DRAW_BUFFER = 0x0C01; +enum uint GL_READ_BUFFER = 0x0C02; +enum uint GL_SCISSOR_BOX = 0x0C10; +enum uint GL_SCISSOR_TEST = 0x0C11; +enum uint GL_COLOR_CLEAR_VALUE = 0x0C22; +enum uint GL_COLOR_WRITEMASK = 0x0C23; +enum uint GL_DOUBLEBUFFER = 0x0C32; +enum uint GL_STEREO = 0x0C33; +enum uint GL_LINE_SMOOTH_HINT = 0x0C52; +enum uint GL_POLYGON_SMOOTH_HINT = 0x0C53; +enum uint GL_UNPACK_SWAP_BYTES = 0x0CF0; +enum uint GL_UNPACK_LSB_FIRST = 0x0CF1; +enum uint GL_UNPACK_ROW_LENGTH = 0x0CF2; +enum uint GL_UNPACK_SKIP_ROWS = 0x0CF3; +enum uint GL_UNPACK_SKIP_PIXELS = 0x0CF4; +enum uint GL_UNPACK_ALIGNMENT = 0x0CF5; +enum uint GL_PACK_SWAP_BYTES = 0x0D00; +enum uint GL_PACK_LSB_FIRST = 0x0D01; +enum uint GL_PACK_ROW_LENGTH = 0x0D02; +enum uint GL_PACK_SKIP_ROWS = 0x0D03; +enum uint GL_PACK_SKIP_PIXELS = 0x0D04; +enum uint GL_PACK_ALIGNMENT = 0x0D05; +enum uint GL_MAX_TEXTURE_SIZE = 0x0D33; +enum uint GL_MAX_VIEWPORT_DIMS = 0x0D3A; +enum uint GL_SUBPIXEL_BITS = 0x0D50; +enum uint GL_TEXTURE_1D = 0x0DE0; +enum uint GL_TEXTURE_2D = 0x0DE1; +enum uint GL_TEXTURE_WIDTH = 0x1000; +enum uint GL_TEXTURE_HEIGHT = 0x1001; +enum uint GL_TEXTURE_BORDER_COLOR = 0x1004; +enum uint GL_DONT_CARE = 0x1100; +enum uint GL_FASTEST = 0x1101; +enum uint GL_NICEST = 0x1102; +enum uint GL_BYTE = 0x1400; +enum uint GL_UNSIGNED_BYTE = 0x1401; +enum uint GL_SHORT = 0x1402; +enum uint GL_UNSIGNED_SHORT = 0x1403; +enum uint GL_INT = 0x1404; +enum uint GL_UNSIGNED_INT = 0x1405; +enum uint GL_FLOAT = 0x1406; +enum uint GL_STACK_OVERFLOW = 0x0503; +enum uint GL_STACK_UNDERFLOW = 0x0504; +enum uint GL_CLEAR = 0x1500; +enum uint GL_AND = 0x1501; +enum uint GL_AND_REVERSE = 0x1502; +enum uint GL_COPY = 0x1503; +enum uint GL_AND_INVERTED = 0x1504; +enum uint GL_NOOP = 0x1505; +enum uint GL_XOR = 0x1506; +enum uint GL_OR = 0x1507; +enum uint GL_NOR = 0x1508; +enum uint GL_EQUIV = 0x1509; +enum uint GL_INVERT = 0x150A; +enum uint GL_OR_REVERSE = 0x150B; +enum uint GL_COPY_INVERTED = 0x150C; +enum uint GL_OR_INVERTED = 0x150D; +enum uint GL_NAND = 0x150E; +enum uint GL_SET = 0x150F; +enum uint GL_TEXTURE = 0x1702; +enum uint GL_COLOR = 0x1800; +enum uint GL_DEPTH = 0x1801; +enum uint GL_STENCIL = 0x1802; +enum uint GL_STENCIL_INDEX = 0x1901; +enum uint GL_DEPTH_COMPONENT = 0x1902; +enum uint GL_RED = 0x1903; +enum uint GL_GREEN = 0x1904; +enum uint GL_BLUE = 0x1905; +enum uint GL_ALPHA = 0x1906; +enum uint GL_RGB = 0x1907; +enum uint GL_RGBA = 0x1908; +enum uint GL_POINT = 0x1B00; +enum uint GL_LINE = 0x1B01; +enum uint GL_FILL = 0x1B02; +enum uint GL_KEEP = 0x1E00; +enum uint GL_REPLACE = 0x1E01; +enum uint GL_INCR = 0x1E02; +enum uint GL_DECR = 0x1E03; +enum uint GL_VENDOR = 0x1F00; +enum uint GL_RENDERER = 0x1F01; +enum uint GL_VERSION = 0x1F02; +enum uint GL_EXTENSIONS = 0x1F03; +enum uint GL_NEAREST = 0x2600; +enum uint GL_LINEAR = 0x2601; +enum uint GL_NEAREST_MIPMAP_NEAREST = 0x2700; +enum uint GL_LINEAR_MIPMAP_NEAREST = 0x2701; +enum uint GL_NEAREST_MIPMAP_LINEAR = 0x2702; +enum uint GL_LINEAR_MIPMAP_LINEAR = 0x2703; +enum uint GL_TEXTURE_MAG_FILTER = 0x2800; +enum uint GL_TEXTURE_MIN_FILTER = 0x2801; +enum uint GL_TEXTURE_WRAP_S = 0x2802; +enum uint GL_TEXTURE_WRAP_T = 0x2803; +enum uint GL_REPEAT = 0x2901; +enum uint GL_CURRENT_BIT = 0x00000001; +enum uint GL_POINT_BIT = 0x00000002; +enum uint GL_LINE_BIT = 0x00000004; +enum uint GL_POLYGON_BIT = 0x00000008; +enum uint GL_POLYGON_STIPPLE_BIT = 0x00000010; +enum uint GL_PIXEL_MODE_BIT = 0x00000020; +enum uint GL_LIGHTING_BIT = 0x00000040; +enum uint GL_FOG_BIT = 0x00000080; +enum uint GL_ACCUM_BUFFER_BIT = 0x00000200; +enum uint GL_VIEWPORT_BIT = 0x00000800; +enum uint GL_TRANSFORM_BIT = 0x00001000; +enum uint GL_ENABLE_BIT = 0x00002000; +enum uint GL_HINT_BIT = 0x00008000; +enum uint GL_EVAL_BIT = 0x00010000; +enum uint GL_LIST_BIT = 0x00020000; +enum uint GL_TEXTURE_BIT = 0x00040000; +enum uint GL_SCISSOR_BIT = 0x00080000; +enum uint GL_ALL_ATTRIB_BITS = 0xFFFFFFFF; +enum uint GL_QUAD_STRIP = 0x0008; +enum uint GL_POLYGON = 0x0009; +enum uint GL_ACCUM = 0x0100; +enum uint GL_LOAD = 0x0101; +enum uint GL_RETURN = 0x0102; +enum uint GL_MULT = 0x0103; +enum uint GL_ADD = 0x0104; +enum uint GL_AUX0 = 0x0409; +enum uint GL_AUX1 = 0x040A; +enum uint GL_AUX2 = 0x040B; +enum uint GL_AUX3 = 0x040C; +enum uint GL_2D = 0x0600; +enum uint GL_3D = 0x0601; +enum uint GL_3D_COLOR = 0x0602; +enum uint GL_3D_COLOR_TEXTURE = 0x0603; +enum uint GL_4D_COLOR_TEXTURE = 0x0604; +enum uint GL_PASS_THROUGH_TOKEN = 0x0700; +enum uint GL_POINT_TOKEN = 0x0701; +enum uint GL_LINE_TOKEN = 0x0702; +enum uint GL_POLYGON_TOKEN = 0x0703; +enum uint GL_BITMAP_TOKEN = 0x0704; +enum uint GL_DRAW_PIXEL_TOKEN = 0x0705; +enum uint GL_COPY_PIXEL_TOKEN = 0x0706; +enum uint GL_LINE_RESET_TOKEN = 0x0707; +enum uint GL_EXP = 0x0800; +enum uint GL_EXP2 = 0x0801; +enum uint GL_COEFF = 0x0A00; +enum uint GL_ORDER = 0x0A01; +enum uint GL_DOMAIN = 0x0A02; +enum uint GL_PIXEL_MAP_I_TO_I = 0x0C70; +enum uint GL_PIXEL_MAP_S_TO_S = 0x0C71; +enum uint GL_PIXEL_MAP_I_TO_R = 0x0C72; +enum uint GL_PIXEL_MAP_I_TO_G = 0x0C73; +enum uint GL_PIXEL_MAP_I_TO_B = 0x0C74; +enum uint GL_PIXEL_MAP_I_TO_A = 0x0C75; +enum uint GL_PIXEL_MAP_R_TO_R = 0x0C76; +enum uint GL_PIXEL_MAP_G_TO_G = 0x0C77; +enum uint GL_PIXEL_MAP_B_TO_B = 0x0C78; +enum uint GL_PIXEL_MAP_A_TO_A = 0x0C79; +enum uint GL_CURRENT_COLOR = 0x0B00; +enum uint GL_CURRENT_INDEX = 0x0B01; +enum uint GL_CURRENT_NORMAL = 0x0B02; +enum uint GL_CURRENT_TEXTURE_COORDS = 0x0B03; +enum uint GL_CURRENT_RASTER_COLOR = 0x0B04; +enum uint GL_CURRENT_RASTER_INDEX = 0x0B05; +enum uint GL_CURRENT_RASTER_TEXTURE_COORDS = 0x0B06; +enum uint GL_CURRENT_RASTER_POSITION = 0x0B07; +enum uint GL_CURRENT_RASTER_POSITION_VALID = 0x0B08; +enum uint GL_CURRENT_RASTER_DISTANCE = 0x0B09; +enum uint GL_POINT_SMOOTH = 0x0B10; +enum uint GL_LINE_STIPPLE = 0x0B24; +enum uint GL_LINE_STIPPLE_PATTERN = 0x0B25; +enum uint GL_LINE_STIPPLE_REPEAT = 0x0B26; +enum uint GL_LIST_MODE = 0x0B30; +enum uint GL_MAX_LIST_NESTING = 0x0B31; +enum uint GL_LIST_BASE = 0x0B32; +enum uint GL_LIST_INDEX = 0x0B33; +enum uint GL_POLYGON_STIPPLE = 0x0B42; +enum uint GL_EDGE_FLAG = 0x0B43; +enum uint GL_LIGHTING = 0x0B50; +enum uint GL_LIGHT_MODEL_LOCAL_VIEWER = 0x0B51; +enum uint GL_LIGHT_MODEL_TWO_SIDE = 0x0B52; +enum uint GL_LIGHT_MODEL_AMBIENT = 0x0B53; +enum uint GL_SHADE_MODEL = 0x0B54; +enum uint GL_COLOR_MATERIAL_FACE = 0x0B55; +enum uint GL_COLOR_MATERIAL_PARAMETER = 0x0B56; +enum uint GL_COLOR_MATERIAL = 0x0B57; +enum uint GL_FOG = 0x0B60; +enum uint GL_FOG_INDEX = 0x0B61; +enum uint GL_FOG_DENSITY = 0x0B62; +enum uint GL_FOG_START = 0x0B63; +enum uint GL_FOG_END = 0x0B64; +enum uint GL_FOG_MODE = 0x0B65; +enum uint GL_FOG_COLOR = 0x0B66; +enum uint GL_ACCUM_CLEAR_VALUE = 0x0B80; +enum uint GL_MATRIX_MODE = 0x0BA0; +enum uint GL_NORMALIZE = 0x0BA1; +enum uint GL_MODELVIEW_STACK_DEPTH = 0x0BA3; +enum uint GL_PROJECTION_STACK_DEPTH = 0x0BA4; +enum uint GL_TEXTURE_STACK_DEPTH = 0x0BA5; +enum uint GL_MODELVIEW_MATRIX = 0x0BA6; +enum uint GL_PROJECTION_MATRIX = 0x0BA7; +enum uint GL_TEXTURE_MATRIX = 0x0BA8; +enum uint GL_ATTRIB_STACK_DEPTH = 0x0BB0; +enum uint GL_ALPHA_TEST = 0x0BC0; +enum uint GL_ALPHA_TEST_FUNC = 0x0BC1; +enum uint GL_ALPHA_TEST_REF = 0x0BC2; +enum uint GL_LOGIC_OP = 0x0BF1; +enum uint GL_AUX_BUFFERS = 0x0C00; +enum uint GL_INDEX_CLEAR_VALUE = 0x0C20; +enum uint GL_INDEX_WRITEMASK = 0x0C21; +enum uint GL_INDEX_MODE = 0x0C30; +enum uint GL_RGBA_MODE = 0x0C31; +enum uint GL_RENDER_MODE = 0x0C40; +enum uint GL_PERSPECTIVE_CORRECTION_HINT = 0x0C50; +enum uint GL_POINT_SMOOTH_HINT = 0x0C51; +enum uint GL_FOG_HINT = 0x0C54; +enum uint GL_TEXTURE_GEN_S = 0x0C60; +enum uint GL_TEXTURE_GEN_T = 0x0C61; +enum uint GL_TEXTURE_GEN_R = 0x0C62; +enum uint GL_TEXTURE_GEN_Q = 0x0C63; +enum uint GL_PIXEL_MAP_I_TO_I_SIZE = 0x0CB0; +enum uint GL_PIXEL_MAP_S_TO_S_SIZE = 0x0CB1; +enum uint GL_PIXEL_MAP_I_TO_R_SIZE = 0x0CB2; +enum uint GL_PIXEL_MAP_I_TO_G_SIZE = 0x0CB3; +enum uint GL_PIXEL_MAP_I_TO_B_SIZE = 0x0CB4; +enum uint GL_PIXEL_MAP_I_TO_A_SIZE = 0x0CB5; +enum uint GL_PIXEL_MAP_R_TO_R_SIZE = 0x0CB6; +enum uint GL_PIXEL_MAP_G_TO_G_SIZE = 0x0CB7; +enum uint GL_PIXEL_MAP_B_TO_B_SIZE = 0x0CB8; +enum uint GL_PIXEL_MAP_A_TO_A_SIZE = 0x0CB9; +enum uint GL_MAP_COLOR = 0x0D10; +enum uint GL_MAP_STENCIL = 0x0D11; +enum uint GL_INDEX_SHIFT = 0x0D12; +enum uint GL_INDEX_OFFSET = 0x0D13; +enum uint GL_RED_SCALE = 0x0D14; +enum uint GL_RED_BIAS = 0x0D15; +enum uint GL_ZOOM_X = 0x0D16; +enum uint GL_ZOOM_Y = 0x0D17; +enum uint GL_GREEN_SCALE = 0x0D18; +enum uint GL_GREEN_BIAS = 0x0D19; +enum uint GL_BLUE_SCALE = 0x0D1A; +enum uint GL_BLUE_BIAS = 0x0D1B; +enum uint GL_ALPHA_SCALE = 0x0D1C; +enum uint GL_ALPHA_BIAS = 0x0D1D; +enum uint GL_DEPTH_SCALE = 0x0D1E; +enum uint GL_DEPTH_BIAS = 0x0D1F; +enum uint GL_MAX_EVAL_ORDER = 0x0D30; +enum uint GL_MAX_LIGHTS = 0x0D31; +enum uint GL_MAX_CLIP_PLANES = 0x0D32; +enum uint GL_MAX_PIXEL_MAP_TABLE = 0x0D34; +enum uint GL_MAX_ATTRIB_STACK_DEPTH = 0x0D35; +enum uint GL_MAX_MODELVIEW_STACK_DEPTH = 0x0D36; +enum uint GL_MAX_NAME_STACK_DEPTH = 0x0D37; +enum uint GL_MAX_PROJECTION_STACK_DEPTH = 0x0D38; +enum uint GL_MAX_TEXTURE_STACK_DEPTH = 0x0D39; +enum uint GL_INDEX_BITS = 0x0D51; +enum uint GL_RED_BITS = 0x0D52; +enum uint GL_GREEN_BITS = 0x0D53; +enum uint GL_BLUE_BITS = 0x0D54; +enum uint GL_ALPHA_BITS = 0x0D55; +enum uint GL_DEPTH_BITS = 0x0D56; +enum uint GL_STENCIL_BITS = 0x0D57; +enum uint GL_ACCUM_RED_BITS = 0x0D58; +enum uint GL_ACCUM_GREEN_BITS = 0x0D59; +enum uint GL_ACCUM_BLUE_BITS = 0x0D5A; +enum uint GL_ACCUM_ALPHA_BITS = 0x0D5B; +enum uint GL_NAME_STACK_DEPTH = 0x0D70; +enum uint GL_AUTO_NORMAL = 0x0D80; +enum uint GL_MAP1_COLOR_4 = 0x0D90; +enum uint GL_MAP1_INDEX = 0x0D91; +enum uint GL_MAP1_NORMAL = 0x0D92; +enum uint GL_MAP1_TEXTURE_COORD_1 = 0x0D93; +enum uint GL_MAP1_TEXTURE_COORD_2 = 0x0D94; +enum uint GL_MAP1_TEXTURE_COORD_3 = 0x0D95; +enum uint GL_MAP1_TEXTURE_COORD_4 = 0x0D96; +enum uint GL_MAP1_VERTEX_3 = 0x0D97; +enum uint GL_MAP1_VERTEX_4 = 0x0D98; +enum uint GL_MAP2_COLOR_4 = 0x0DB0; +enum uint GL_MAP2_INDEX = 0x0DB1; +enum uint GL_MAP2_NORMAL = 0x0DB2; +enum uint GL_MAP2_TEXTURE_COORD_1 = 0x0DB3; +enum uint GL_MAP2_TEXTURE_COORD_2 = 0x0DB4; +enum uint GL_MAP2_TEXTURE_COORD_3 = 0x0DB5; +enum uint GL_MAP2_TEXTURE_COORD_4 = 0x0DB6; +enum uint GL_MAP2_VERTEX_3 = 0x0DB7; +enum uint GL_MAP2_VERTEX_4 = 0x0DB8; +enum uint GL_MAP1_GRID_DOMAIN = 0x0DD0; +enum uint GL_MAP1_GRID_SEGMENTS = 0x0DD1; +enum uint GL_MAP2_GRID_DOMAIN = 0x0DD2; +enum uint GL_MAP2_GRID_SEGMENTS = 0x0DD3; +enum uint GL_TEXTURE_COMPONENTS = 0x1003; +enum uint GL_TEXTURE_BORDER = 0x1005; +enum uint GL_AMBIENT = 0x1200; +enum uint GL_DIFFUSE = 0x1201; +enum uint GL_SPECULAR = 0x1202; +enum uint GL_POSITION = 0x1203; +enum uint GL_SPOT_DIRECTION = 0x1204; +enum uint GL_SPOT_EXPONENT = 0x1205; +enum uint GL_SPOT_CUTOFF = 0x1206; +enum uint GL_CONSTANT_ATTENUATION = 0x1207; +enum uint GL_LINEAR_ATTENUATION = 0x1208; +enum uint GL_QUADRATIC_ATTENUATION = 0x1209; +enum uint GL_COMPILE = 0x1300; +enum uint GL_COMPILE_AND_EXECUTE = 0x1301; +enum uint GL_2_BYTES = 0x1407; +enum uint GL_3_BYTES = 0x1408; +enum uint GL_4_BYTES = 0x1409; +enum uint GL_EMISSION = 0x1600; +enum uint GL_SHININESS = 0x1601; +enum uint GL_AMBIENT_AND_DIFFUSE = 0x1602; +enum uint GL_COLOR_INDEXES = 0x1603; +enum uint GL_MODELVIEW = 0x1700; +enum uint GL_PROJECTION = 0x1701; +enum uint GL_COLOR_INDEX = 0x1900; +enum uint GL_LUMINANCE = 0x1909; +enum uint GL_LUMINANCE_ALPHA = 0x190A; +enum uint GL_BITMAP = 0x1A00; +enum uint GL_RENDER = 0x1C00; +enum uint GL_FEEDBACK = 0x1C01; +enum uint GL_SELECT = 0x1C02; +enum uint GL_FLAT = 0x1D00; +enum uint GL_SMOOTH = 0x1D01; +enum uint GL_S = 0x2000; +enum uint GL_T = 0x2001; +enum uint GL_R = 0x2002; +enum uint GL_Q = 0x2003; +enum uint GL_MODULATE = 0x2100; +enum uint GL_DECAL = 0x2101; +enum uint GL_TEXTURE_ENV_MODE = 0x2200; +enum uint GL_TEXTURE_ENV_COLOR = 0x2201; +enum uint GL_TEXTURE_ENV = 0x2300; +enum uint GL_EYE_LINEAR = 0x2400; +enum uint GL_OBJECT_LINEAR = 0x2401; +enum uint GL_SPHERE_MAP = 0x2402; +enum uint GL_TEXTURE_GEN_MODE = 0x2500; +enum uint GL_OBJECT_PLANE = 0x2501; +enum uint GL_EYE_PLANE = 0x2502; +enum uint GL_CLAMP = 0x2900; +enum uint GL_CLIP_PLANE0 = 0x3000; +enum uint GL_CLIP_PLANE1 = 0x3001; +enum uint GL_CLIP_PLANE2 = 0x3002; +enum uint GL_CLIP_PLANE3 = 0x3003; +enum uint GL_CLIP_PLANE4 = 0x3004; +enum uint GL_CLIP_PLANE5 = 0x3005; +enum uint GL_LIGHT0 = 0x4000; +enum uint GL_LIGHT1 = 0x4001; +enum uint GL_LIGHT2 = 0x4002; +enum uint GL_LIGHT3 = 0x4003; +enum uint GL_LIGHT4 = 0x4004; +enum uint GL_LIGHT5 = 0x4005; +enum uint GL_LIGHT6 = 0x4006; +enum uint GL_LIGHT7 = 0x4007; +enum uint GL_COLOR_LOGIC_OP = 0x0BF2; +enum uint GL_POLYGON_OFFSET_UNITS = 0x2A00; +enum uint GL_POLYGON_OFFSET_POINT = 0x2A01; +enum uint GL_POLYGON_OFFSET_LINE = 0x2A02; +enum uint GL_POLYGON_OFFSET_FILL = 0x8037; +enum uint GL_POLYGON_OFFSET_FACTOR = 0x8038; +enum uint GL_TEXTURE_BINDING_1D = 0x8068; +enum uint GL_TEXTURE_BINDING_2D = 0x8069; +enum uint GL_TEXTURE_INTERNAL_FORMAT = 0x1003; +enum uint GL_TEXTURE_RED_SIZE = 0x805C; +enum uint GL_TEXTURE_GREEN_SIZE = 0x805D; +enum uint GL_TEXTURE_BLUE_SIZE = 0x805E; +enum uint GL_TEXTURE_ALPHA_SIZE = 0x805F; +enum uint GL_DOUBLE = 0x140A; +enum uint GL_PROXY_TEXTURE_1D = 0x8063; +enum uint GL_PROXY_TEXTURE_2D = 0x8064; +enum uint GL_R3_G3_B2 = 0x2A10; +enum uint GL_RGB4 = 0x804F; +enum uint GL_RGB5 = 0x8050; +enum uint GL_RGB8 = 0x8051; +enum uint GL_RGB10 = 0x8052; +enum uint GL_RGB12 = 0x8053; +enum uint GL_RGB16 = 0x8054; +enum uint GL_RGBA2 = 0x8055; +enum uint GL_RGBA4 = 0x8056; +enum uint GL_RGB5_A1 = 0x8057; +enum uint GL_RGBA8 = 0x8058; +enum uint GL_RGB10_A2 = 0x8059; +enum uint GL_RGBA12 = 0x805A; +enum uint GL_RGBA16 = 0x805B; +enum uint GL_CLIENT_PIXEL_STORE_BIT = 0x00000001; +enum uint GL_CLIENT_VERTEX_ARRAY_BIT = 0x00000002; +enum uint GL_CLIENT_ALL_ATTRIB_BITS = 0xFFFFFFFF; +enum uint GL_VERTEX_ARRAY_POINTER = 0x808E; +enum uint GL_NORMAL_ARRAY_POINTER = 0x808F; +enum uint GL_COLOR_ARRAY_POINTER = 0x8090; +enum uint GL_INDEX_ARRAY_POINTER = 0x8091; +enum uint GL_TEXTURE_COORD_ARRAY_POINTER = 0x8092; +enum uint GL_EDGE_FLAG_ARRAY_POINTER = 0x8093; +enum uint GL_FEEDBACK_BUFFER_POINTER = 0x0DF0; +enum uint GL_SELECTION_BUFFER_POINTER = 0x0DF3; +enum uint GL_CLIENT_ATTRIB_STACK_DEPTH = 0x0BB1; +enum uint GL_INDEX_LOGIC_OP = 0x0BF1; +enum uint GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = 0x0D3B; +enum uint GL_FEEDBACK_BUFFER_SIZE = 0x0DF1; +enum uint GL_FEEDBACK_BUFFER_TYPE = 0x0DF2; +enum uint GL_SELECTION_BUFFER_SIZE = 0x0DF4; +enum uint GL_VERTEX_ARRAY = 0x8074; +enum uint GL_NORMAL_ARRAY = 0x8075; +enum uint GL_COLOR_ARRAY = 0x8076; +enum uint GL_INDEX_ARRAY = 0x8077; +enum uint GL_TEXTURE_COORD_ARRAY = 0x8078; +enum uint GL_EDGE_FLAG_ARRAY = 0x8079; +enum uint GL_VERTEX_ARRAY_SIZE = 0x807A; +enum uint GL_VERTEX_ARRAY_TYPE = 0x807B; +enum uint GL_VERTEX_ARRAY_STRIDE = 0x807C; +enum uint GL_NORMAL_ARRAY_TYPE = 0x807E; +enum uint GL_NORMAL_ARRAY_STRIDE = 0x807F; +enum uint GL_COLOR_ARRAY_SIZE = 0x8081; +enum uint GL_COLOR_ARRAY_TYPE = 0x8082; +enum uint GL_COLOR_ARRAY_STRIDE = 0x8083; +enum uint GL_INDEX_ARRAY_TYPE = 0x8085; +enum uint GL_INDEX_ARRAY_STRIDE = 0x8086; +enum uint GL_TEXTURE_COORD_ARRAY_SIZE = 0x8088; +enum uint GL_TEXTURE_COORD_ARRAY_TYPE = 0x8089; +enum uint GL_TEXTURE_COORD_ARRAY_STRIDE = 0x808A; +enum uint GL_EDGE_FLAG_ARRAY_STRIDE = 0x808C; +enum uint GL_TEXTURE_LUMINANCE_SIZE = 0x8060; +enum uint GL_TEXTURE_INTENSITY_SIZE = 0x8061; +enum uint GL_TEXTURE_PRIORITY = 0x8066; +enum uint GL_TEXTURE_RESIDENT = 0x8067; +enum uint GL_ALPHA4 = 0x803B; +enum uint GL_ALPHA8 = 0x803C; +enum uint GL_ALPHA12 = 0x803D; +enum uint GL_ALPHA16 = 0x803E; +enum uint GL_LUMINANCE4 = 0x803F; +enum uint GL_LUMINANCE8 = 0x8040; +enum uint GL_LUMINANCE12 = 0x8041; +enum uint GL_LUMINANCE16 = 0x8042; +enum uint GL_LUMINANCE4_ALPHA4 = 0x8043; +enum uint GL_LUMINANCE6_ALPHA2 = 0x8044; +enum uint GL_LUMINANCE8_ALPHA8 = 0x8045; +enum uint GL_LUMINANCE12_ALPHA4 = 0x8046; +enum uint GL_LUMINANCE12_ALPHA12 = 0x8047; +enum uint GL_LUMINANCE16_ALPHA16 = 0x8048; +enum uint GL_INTENSITY = 0x8049; +enum uint GL_INTENSITY4 = 0x804A; +enum uint GL_INTENSITY8 = 0x804B; +enum uint GL_INTENSITY12 = 0x804C; +enum uint GL_INTENSITY16 = 0x804D; +enum uint GL_V2F = 0x2A20; +enum uint GL_V3F = 0x2A21; +enum uint GL_C4UB_V2F = 0x2A22; +enum uint GL_C4UB_V3F = 0x2A23; +enum uint GL_C3F_V3F = 0x2A24; +enum uint GL_N3F_V3F = 0x2A25; +enum uint GL_C4F_N3F_V3F = 0x2A26; +enum uint GL_T2F_V3F = 0x2A27; +enum uint GL_T4F_V4F = 0x2A28; +enum uint GL_T2F_C4UB_V3F = 0x2A29; +enum uint GL_T2F_C3F_V3F = 0x2A2A; +enum uint GL_T2F_N3F_V3F = 0x2A2B; +enum uint GL_T2F_C4F_N3F_V3F = 0x2A2C; +enum uint GL_T4F_C4F_N3F_V4F = 0x2A2D; +enum uint GL_UNSIGNED_BYTE_3_3_2 = 0x8032; +enum uint GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033; +enum uint GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034; +enum uint GL_UNSIGNED_INT_8_8_8_8 = 0x8035; +enum uint GL_UNSIGNED_INT_10_10_10_2 = 0x8036; +enum uint GL_TEXTURE_BINDING_3D = 0x806A; +enum uint GL_PACK_SKIP_IMAGES = 0x806B; +enum uint GL_PACK_IMAGE_HEIGHT = 0x806C; +enum uint GL_UNPACK_SKIP_IMAGES = 0x806D; +enum uint GL_UNPACK_IMAGE_HEIGHT = 0x806E; +enum uint GL_TEXTURE_3D = 0x806F; +enum uint GL_PROXY_TEXTURE_3D = 0x8070; +enum uint GL_TEXTURE_DEPTH = 0x8071; +enum uint GL_TEXTURE_WRAP_R = 0x8072; +enum uint GL_MAX_3D_TEXTURE_SIZE = 0x8073; +enum uint GL_UNSIGNED_BYTE_2_3_3_REV = 0x8362; +enum uint GL_UNSIGNED_SHORT_5_6_5 = 0x8363; +enum uint GL_UNSIGNED_SHORT_5_6_5_REV = 0x8364; +enum uint GL_UNSIGNED_SHORT_4_4_4_4_REV = 0x8365; +enum uint GL_UNSIGNED_SHORT_1_5_5_5_REV = 0x8366; +enum uint GL_UNSIGNED_INT_8_8_8_8_REV = 0x8367; +enum uint GL_UNSIGNED_INT_2_10_10_10_REV = 0x8368; +enum uint GL_BGR = 0x80E0; +enum uint GL_BGRA = 0x80E1; +enum uint GL_MAX_ELEMENTS_VERTICES = 0x80E8; +enum uint GL_MAX_ELEMENTS_INDICES = 0x80E9; +enum uint GL_CLAMP_TO_EDGE = 0x812F; +enum uint GL_TEXTURE_MIN_LOD = 0x813A; +enum uint GL_TEXTURE_MAX_LOD = 0x813B; +enum uint GL_TEXTURE_BASE_LEVEL = 0x813C; +enum uint GL_TEXTURE_MAX_LEVEL = 0x813D; +enum uint GL_SMOOTH_POINT_SIZE_RANGE = 0x0B12; +enum uint GL_SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13; +enum uint GL_SMOOTH_LINE_WIDTH_RANGE = 0x0B22; +enum uint GL_SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23; +enum uint GL_ALIASED_LINE_WIDTH_RANGE = 0x846E; +enum uint GL_RESCALE_NORMAL = 0x803A; +enum uint GL_LIGHT_MODEL_COLOR_CONTROL = 0x81F8; +enum uint GL_SINGLE_COLOR = 0x81F9; +enum uint GL_SEPARATE_SPECULAR_COLOR = 0x81FA; +enum uint GL_ALIASED_POINT_SIZE_RANGE = 0x846D; +enum uint GL_TEXTURE0 = 0x84C0; +enum uint GL_TEXTURE1 = 0x84C1; +enum uint GL_TEXTURE2 = 0x84C2; +enum uint GL_TEXTURE3 = 0x84C3; +enum uint GL_TEXTURE4 = 0x84C4; +enum uint GL_TEXTURE5 = 0x84C5; +enum uint GL_TEXTURE6 = 0x84C6; +enum uint GL_TEXTURE7 = 0x84C7; +enum uint GL_TEXTURE8 = 0x84C8; +enum uint GL_TEXTURE9 = 0x84C9; +enum uint GL_TEXTURE10 = 0x84CA; +enum uint GL_TEXTURE11 = 0x84CB; +enum uint GL_TEXTURE12 = 0x84CC; +enum uint GL_TEXTURE13 = 0x84CD; +enum uint GL_TEXTURE14 = 0x84CE; +enum uint GL_TEXTURE15 = 0x84CF; +enum uint GL_TEXTURE16 = 0x84D0; +enum uint GL_TEXTURE17 = 0x84D1; +enum uint GL_TEXTURE18 = 0x84D2; +enum uint GL_TEXTURE19 = 0x84D3; +enum uint GL_TEXTURE20 = 0x84D4; +enum uint GL_TEXTURE21 = 0x84D5; +enum uint GL_TEXTURE22 = 0x84D6; +enum uint GL_TEXTURE23 = 0x84D7; +enum uint GL_TEXTURE24 = 0x84D8; +enum uint GL_TEXTURE25 = 0x84D9; +enum uint GL_TEXTURE26 = 0x84DA; +enum uint GL_TEXTURE27 = 0x84DB; +enum uint GL_TEXTURE28 = 0x84DC; +enum uint GL_TEXTURE29 = 0x84DD; +enum uint GL_TEXTURE30 = 0x84DE; +enum uint GL_TEXTURE31 = 0x84DF; +enum uint GL_ACTIVE_TEXTURE = 0x84E0; +enum uint GL_MULTISAMPLE = 0x809D; +enum uint GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E; +enum uint GL_SAMPLE_ALPHA_TO_ONE = 0x809F; +enum uint GL_SAMPLE_COVERAGE = 0x80A0; +enum uint GL_SAMPLE_BUFFERS = 0x80A8; +enum uint GL_SAMPLES = 0x80A9; +enum uint GL_SAMPLE_COVERAGE_VALUE = 0x80AA; +enum uint GL_SAMPLE_COVERAGE_INVERT = 0x80AB; +enum uint GL_TEXTURE_CUBE_MAP = 0x8513; +enum uint GL_TEXTURE_BINDING_CUBE_MAP = 0x8514; +enum uint GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +enum uint GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +enum uint GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +enum uint GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +enum uint GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +enum uint GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A; +enum uint GL_PROXY_TEXTURE_CUBE_MAP = 0x851B; +enum uint GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; +enum uint GL_COMPRESSED_RGB = 0x84ED; +enum uint GL_COMPRESSED_RGBA = 0x84EE; +enum uint GL_TEXTURE_COMPRESSION_HINT = 0x84EF; +enum uint GL_TEXTURE_COMPRESSED_IMAGE_SIZE = 0x86A0; +enum uint GL_TEXTURE_COMPRESSED = 0x86A1; +enum uint GL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2; +enum uint GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3; +enum uint GL_CLAMP_TO_BORDER = 0x812D; +enum uint GL_CLIENT_ACTIVE_TEXTURE = 0x84E1; +enum uint GL_MAX_TEXTURE_UNITS = 0x84E2; +enum uint GL_TRANSPOSE_MODELVIEW_MATRIX = 0x84E3; +enum uint GL_TRANSPOSE_PROJECTION_MATRIX = 0x84E4; +enum uint GL_TRANSPOSE_TEXTURE_MATRIX = 0x84E5; +enum uint GL_TRANSPOSE_COLOR_MATRIX = 0x84E6; +enum uint GL_MULTISAMPLE_BIT = 0x20000000; +enum uint GL_NORMAL_MAP = 0x8511; +enum uint GL_REFLECTION_MAP = 0x8512; +enum uint GL_COMPRESSED_ALPHA = 0x84E9; +enum uint GL_COMPRESSED_LUMINANCE = 0x84EA; +enum uint GL_COMPRESSED_LUMINANCE_ALPHA = 0x84EB; +enum uint GL_COMPRESSED_INTENSITY = 0x84EC; +enum uint GL_COMBINE = 0x8570; +enum uint GL_COMBINE_RGB = 0x8571; +enum uint GL_COMBINE_ALPHA = 0x8572; +enum uint GL_SOURCE0_RGB = 0x8580; +enum uint GL_SOURCE1_RGB = 0x8581; +enum uint GL_SOURCE2_RGB = 0x8582; +enum uint GL_SOURCE0_ALPHA = 0x8588; +enum uint GL_SOURCE1_ALPHA = 0x8589; +enum uint GL_SOURCE2_ALPHA = 0x858A; +enum uint GL_OPERAND0_RGB = 0x8590; +enum uint GL_OPERAND1_RGB = 0x8591; +enum uint GL_OPERAND2_RGB = 0x8592; +enum uint GL_OPERAND0_ALPHA = 0x8598; +enum uint GL_OPERAND1_ALPHA = 0x8599; +enum uint GL_OPERAND2_ALPHA = 0x859A; +enum uint GL_RGB_SCALE = 0x8573; +enum uint GL_ADD_SIGNED = 0x8574; +enum uint GL_INTERPOLATE = 0x8575; +enum uint GL_SUBTRACT = 0x84E7; +enum uint GL_CONSTANT = 0x8576; +enum uint GL_PRIMARY_COLOR = 0x8577; +enum uint GL_PREVIOUS = 0x8578; +enum uint GL_DOT3_RGB = 0x86AE; +enum uint GL_DOT3_RGBA = 0x86AF; +enum uint GL_BLEND_DST_RGB = 0x80C8; +enum uint GL_BLEND_SRC_RGB = 0x80C9; +enum uint GL_BLEND_DST_ALPHA = 0x80CA; +enum uint GL_BLEND_SRC_ALPHA = 0x80CB; +enum uint GL_POINT_FADE_THRESHOLD_SIZE = 0x8128; +enum uint GL_DEPTH_COMPONENT16 = 0x81A5; +enum uint GL_DEPTH_COMPONENT24 = 0x81A6; +enum uint GL_DEPTH_COMPONENT32 = 0x81A7; +enum uint GL_MIRRORED_REPEAT = 0x8370; +enum uint GL_MAX_TEXTURE_LOD_BIAS = 0x84FD; +enum uint GL_TEXTURE_LOD_BIAS = 0x8501; +enum uint GL_INCR_WRAP = 0x8507; +enum uint GL_DECR_WRAP = 0x8508; +enum uint GL_TEXTURE_DEPTH_SIZE = 0x884A; +enum uint GL_TEXTURE_COMPARE_MODE = 0x884C; +enum uint GL_TEXTURE_COMPARE_FUNC = 0x884D; +enum uint GL_POINT_SIZE_MIN = 0x8126; +enum uint GL_POINT_SIZE_MAX = 0x8127; +enum uint GL_POINT_DISTANCE_ATTENUATION = 0x8129; +enum uint GL_GENERATE_MIPMAP = 0x8191; +enum uint GL_GENERATE_MIPMAP_HINT = 0x8192; +enum uint GL_FOG_COORDINATE_SOURCE = 0x8450; +enum uint GL_FOG_COORDINATE = 0x8451; +enum uint GL_FRAGMENT_DEPTH = 0x8452; +enum uint GL_CURRENT_FOG_COORDINATE = 0x8453; +enum uint GL_FOG_COORDINATE_ARRAY_TYPE = 0x8454; +enum uint GL_FOG_COORDINATE_ARRAY_STRIDE = 0x8455; +enum uint GL_FOG_COORDINATE_ARRAY_POINTER = 0x8456; +enum uint GL_FOG_COORDINATE_ARRAY = 0x8457; +enum uint GL_COLOR_SUM = 0x8458; +enum uint GL_CURRENT_SECONDARY_COLOR = 0x8459; +enum uint GL_SECONDARY_COLOR_ARRAY_SIZE = 0x845A; +enum uint GL_SECONDARY_COLOR_ARRAY_TYPE = 0x845B; +enum uint GL_SECONDARY_COLOR_ARRAY_STRIDE = 0x845C; +enum uint GL_SECONDARY_COLOR_ARRAY_POINTER = 0x845D; +enum uint GL_SECONDARY_COLOR_ARRAY = 0x845E; +enum uint GL_TEXTURE_FILTER_CONTROL = 0x8500; +enum uint GL_DEPTH_TEXTURE_MODE = 0x884B; +enum uint GL_COMPARE_R_TO_TEXTURE = 0x884E; +enum uint GL_BLEND_COLOR = 0x8005; +enum uint GL_BLEND_EQUATION = 0x8009; +enum uint GL_CONSTANT_COLOR = 0x8001; +enum uint GL_ONE_MINUS_CONSTANT_COLOR = 0x8002; +enum uint GL_CONSTANT_ALPHA = 0x8003; +enum uint GL_ONE_MINUS_CONSTANT_ALPHA = 0x8004; +enum uint GL_FUNC_ADD = 0x8006; +enum uint GL_FUNC_REVERSE_SUBTRACT = 0x800B; +enum uint GL_FUNC_SUBTRACT = 0x800A; +enum uint GL_MIN = 0x8007; +enum uint GL_MAX = 0x8008; +enum uint GL_BUFFER_SIZE = 0x8764; +enum uint GL_BUFFER_USAGE = 0x8765; +enum uint GL_QUERY_COUNTER_BITS = 0x8864; +enum uint GL_CURRENT_QUERY = 0x8865; +enum uint GL_QUERY_RESULT = 0x8866; +enum uint GL_QUERY_RESULT_AVAILABLE = 0x8867; +enum uint GL_ARRAY_BUFFER = 0x8892; +enum uint GL_ELEMENT_ARRAY_BUFFER = 0x8893; +enum uint GL_ARRAY_BUFFER_BINDING = 0x8894; +enum uint GL_ELEMENT_ARRAY_BUFFER_BINDING = 0x8895; +enum uint GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F; +enum uint GL_READ_ONLY = 0x88B8; +enum uint GL_WRITE_ONLY = 0x88B9; +enum uint GL_READ_WRITE = 0x88BA; +enum uint GL_BUFFER_ACCESS = 0x88BB; +enum uint GL_BUFFER_MAPPED = 0x88BC; +enum uint GL_BUFFER_MAP_POINTER = 0x88BD; +enum uint GL_STREAM_DRAW = 0x88E0; +enum uint GL_STREAM_READ = 0x88E1; +enum uint GL_STREAM_COPY = 0x88E2; +enum uint GL_STATIC_DRAW = 0x88E4; +enum uint GL_STATIC_READ = 0x88E5; +enum uint GL_STATIC_COPY = 0x88E6; +enum uint GL_DYNAMIC_DRAW = 0x88E8; +enum uint GL_DYNAMIC_READ = 0x88E9; +enum uint GL_DYNAMIC_COPY = 0x88EA; +enum uint GL_SAMPLES_PASSED = 0x8914; +enum uint GL_SRC1_ALPHA = 0x8589; +enum uint GL_VERTEX_ARRAY_BUFFER_BINDING = 0x8896; +enum uint GL_NORMAL_ARRAY_BUFFER_BINDING = 0x8897; +enum uint GL_COLOR_ARRAY_BUFFER_BINDING = 0x8898; +enum uint GL_INDEX_ARRAY_BUFFER_BINDING = 0x8899; +enum uint GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = 0x889A; +enum uint GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = 0x889B; +enum uint GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = 0x889C; +enum uint GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = 0x889D; +enum uint GL_WEIGHT_ARRAY_BUFFER_BINDING = 0x889E; +enum uint GL_FOG_COORD_SRC = 0x8450; +enum uint GL_FOG_COORD = 0x8451; +enum uint GL_CURRENT_FOG_COORD = 0x8453; +enum uint GL_FOG_COORD_ARRAY_TYPE = 0x8454; +enum uint GL_FOG_COORD_ARRAY_STRIDE = 0x8455; +enum uint GL_FOG_COORD_ARRAY_POINTER = 0x8456; +enum uint GL_FOG_COORD_ARRAY = 0x8457; +enum uint GL_FOG_COORD_ARRAY_BUFFER_BINDING = 0x889D; +enum uint GL_SRC0_RGB = 0x8580; +enum uint GL_SRC1_RGB = 0x8581; +enum uint GL_SRC2_RGB = 0x8582; +enum uint GL_SRC0_ALPHA = 0x8588; +enum uint GL_SRC2_ALPHA = 0x858A; +enum uint GL_BLEND_EQUATION_RGB = 0x8009; +enum uint GL_VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622; +enum uint GL_VERTEX_ATTRIB_ARRAY_SIZE = 0x8623; +enum uint GL_VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624; +enum uint GL_VERTEX_ATTRIB_ARRAY_TYPE = 0x8625; +enum uint GL_CURRENT_VERTEX_ATTRIB = 0x8626; +enum uint GL_VERTEX_PROGRAM_POINT_SIZE = 0x8642; +enum uint GL_VERTEX_ATTRIB_ARRAY_POINTER = 0x8645; +enum uint GL_STENCIL_BACK_FUNC = 0x8800; +enum uint GL_STENCIL_BACK_FAIL = 0x8801; +enum uint GL_STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802; +enum uint GL_STENCIL_BACK_PASS_DEPTH_PASS = 0x8803; +enum uint GL_MAX_DRAW_BUFFERS = 0x8824; +enum uint GL_DRAW_BUFFER0 = 0x8825; +enum uint GL_DRAW_BUFFER1 = 0x8826; +enum uint GL_DRAW_BUFFER2 = 0x8827; +enum uint GL_DRAW_BUFFER3 = 0x8828; +enum uint GL_DRAW_BUFFER4 = 0x8829; +enum uint GL_DRAW_BUFFER5 = 0x882A; +enum uint GL_DRAW_BUFFER6 = 0x882B; +enum uint GL_DRAW_BUFFER7 = 0x882C; +enum uint GL_DRAW_BUFFER8 = 0x882D; +enum uint GL_DRAW_BUFFER9 = 0x882E; +enum uint GL_DRAW_BUFFER10 = 0x882F; +enum uint GL_DRAW_BUFFER11 = 0x8830; +enum uint GL_DRAW_BUFFER12 = 0x8831; +enum uint GL_DRAW_BUFFER13 = 0x8832; +enum uint GL_DRAW_BUFFER14 = 0x8833; +enum uint GL_DRAW_BUFFER15 = 0x8834; +enum uint GL_BLEND_EQUATION_ALPHA = 0x883D; +enum uint GL_MAX_VERTEX_ATTRIBS = 0x8869; +enum uint GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A; +enum uint GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872; +enum uint GL_FRAGMENT_SHADER = 0x8B30; +enum uint GL_VERTEX_SHADER = 0x8B31; +enum uint GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49; +enum uint GL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A; +enum uint GL_MAX_VARYING_FLOATS = 0x8B4B; +enum uint GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; +enum uint GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D; +enum uint GL_SHADER_TYPE = 0x8B4F; +enum uint GL_FLOAT_VEC2 = 0x8B50; +enum uint GL_FLOAT_VEC3 = 0x8B51; +enum uint GL_FLOAT_VEC4 = 0x8B52; +enum uint GL_INT_VEC2 = 0x8B53; +enum uint GL_INT_VEC3 = 0x8B54; +enum uint GL_INT_VEC4 = 0x8B55; +enum uint GL_BOOL = 0x8B56; +enum uint GL_BOOL_VEC2 = 0x8B57; +enum uint GL_BOOL_VEC3 = 0x8B58; +enum uint GL_BOOL_VEC4 = 0x8B59; +enum uint GL_FLOAT_MAT2 = 0x8B5A; +enum uint GL_FLOAT_MAT3 = 0x8B5B; +enum uint GL_FLOAT_MAT4 = 0x8B5C; +enum uint GL_SAMPLER_1D = 0x8B5D; +enum uint GL_SAMPLER_2D = 0x8B5E; +enum uint GL_SAMPLER_3D = 0x8B5F; +enum uint GL_SAMPLER_CUBE = 0x8B60; +enum uint GL_SAMPLER_1D_SHADOW = 0x8B61; +enum uint GL_SAMPLER_2D_SHADOW = 0x8B62; +enum uint GL_DELETE_STATUS = 0x8B80; +enum uint GL_COMPILE_STATUS = 0x8B81; +enum uint GL_LINK_STATUS = 0x8B82; +enum uint GL_VALIDATE_STATUS = 0x8B83; +enum uint GL_INFO_LOG_LENGTH = 0x8B84; +enum uint GL_ATTACHED_SHADERS = 0x8B85; +enum uint GL_ACTIVE_UNIFORMS = 0x8B86; +enum uint GL_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87; +enum uint GL_SHADER_SOURCE_LENGTH = 0x8B88; +enum uint GL_ACTIVE_ATTRIBUTES = 0x8B89; +enum uint GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A; +enum uint GL_FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B; +enum uint GL_SHADING_LANGUAGE_VERSION = 0x8B8C; +enum uint GL_CURRENT_PROGRAM = 0x8B8D; +enum uint GL_POINT_SPRITE_COORD_ORIGIN = 0x8CA0; +enum uint GL_LOWER_LEFT = 0x8CA1; +enum uint GL_UPPER_LEFT = 0x8CA2; +enum uint GL_STENCIL_BACK_REF = 0x8CA3; +enum uint GL_STENCIL_BACK_VALUE_MASK = 0x8CA4; +enum uint GL_STENCIL_BACK_WRITEMASK = 0x8CA5; +enum uint GL_VERTEX_PROGRAM_TWO_SIDE = 0x8643; +enum uint GL_POINT_SPRITE = 0x8861; +enum uint GL_COORD_REPLACE = 0x8862; +enum uint GL_MAX_TEXTURE_COORDS = 0x8871; +enum uint GL_PIXEL_PACK_BUFFER = 0x88EB; +enum uint GL_PIXEL_UNPACK_BUFFER = 0x88EC; +enum uint GL_PIXEL_PACK_BUFFER_BINDING = 0x88ED; +enum uint GL_PIXEL_UNPACK_BUFFER_BINDING = 0x88EF; +enum uint GL_FLOAT_MAT2x3 = 0x8B65; +enum uint GL_FLOAT_MAT2x4 = 0x8B66; +enum uint GL_FLOAT_MAT3x2 = 0x8B67; +enum uint GL_FLOAT_MAT3x4 = 0x8B68; +enum uint GL_FLOAT_MAT4x2 = 0x8B69; +enum uint GL_FLOAT_MAT4x3 = 0x8B6A; +enum uint GL_SRGB = 0x8C40; +enum uint GL_SRGB8 = 0x8C41; +enum uint GL_SRGB_ALPHA = 0x8C42; +enum uint GL_SRGB8_ALPHA8 = 0x8C43; +enum uint GL_COMPRESSED_SRGB = 0x8C48; +enum uint GL_COMPRESSED_SRGB_ALPHA = 0x8C49; +enum uint GL_CURRENT_RASTER_SECONDARY_COLOR = 0x845F; +enum uint GL_SLUMINANCE_ALPHA = 0x8C44; +enum uint GL_SLUMINANCE8_ALPHA8 = 0x8C45; +enum uint GL_SLUMINANCE = 0x8C46; +enum uint GL_SLUMINANCE8 = 0x8C47; +enum uint GL_COMPRESSED_SLUMINANCE = 0x8C4A; +enum uint GL_COMPRESSED_SLUMINANCE_ALPHA = 0x8C4B; +enum uint GL_COMPARE_REF_TO_TEXTURE = 0x884E; +enum uint GL_CLIP_DISTANCE0 = 0x3000; +enum uint GL_CLIP_DISTANCE1 = 0x3001; +enum uint GL_CLIP_DISTANCE2 = 0x3002; +enum uint GL_CLIP_DISTANCE3 = 0x3003; +enum uint GL_CLIP_DISTANCE4 = 0x3004; +enum uint GL_CLIP_DISTANCE5 = 0x3005; +enum uint GL_CLIP_DISTANCE6 = 0x3006; +enum uint GL_CLIP_DISTANCE7 = 0x3007; +enum uint GL_MAX_CLIP_DISTANCES = 0x0D32; +enum uint GL_MAJOR_VERSION = 0x821B; +enum uint GL_MINOR_VERSION = 0x821C; +enum uint GL_NUM_EXTENSIONS = 0x821D; +enum uint GL_CONTEXT_FLAGS = 0x821E; +enum uint GL_COMPRESSED_RED = 0x8225; +enum uint GL_COMPRESSED_RG = 0x8226; +enum uint GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = 0x00000001; +enum uint GL_RGBA32F = 0x8814; +enum uint GL_RGB32F = 0x8815; +enum uint GL_RGBA16F = 0x881A; +enum uint GL_RGB16F = 0x881B; +enum uint GL_VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD; +enum uint GL_MAX_ARRAY_TEXTURE_LAYERS = 0x88FF; +enum uint GL_MIN_PROGRAM_TEXEL_OFFSET = 0x8904; +enum uint GL_MAX_PROGRAM_TEXEL_OFFSET = 0x8905; +enum uint GL_CLAMP_READ_COLOR = 0x891C; +enum uint GL_FIXED_ONLY = 0x891D; +enum uint GL_MAX_VARYING_COMPONENTS = 0x8B4B; +enum uint GL_TEXTURE_1D_ARRAY = 0x8C18; +enum uint GL_PROXY_TEXTURE_1D_ARRAY = 0x8C19; +enum uint GL_TEXTURE_2D_ARRAY = 0x8C1A; +enum uint GL_PROXY_TEXTURE_2D_ARRAY = 0x8C1B; +enum uint GL_TEXTURE_BINDING_1D_ARRAY = 0x8C1C; +enum uint GL_TEXTURE_BINDING_2D_ARRAY = 0x8C1D; +enum uint GL_R11F_G11F_B10F = 0x8C3A; +enum uint GL_UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +enum uint GL_RGB9_E5 = 0x8C3D; +enum uint GL_UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +enum uint GL_TEXTURE_SHARED_SIZE = 0x8C3F; +enum uint GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = 0x8C76; +enum uint GL_TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F; +enum uint GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80; +enum uint GL_TRANSFORM_FEEDBACK_VARYINGS = 0x8C83; +enum uint GL_TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84; +enum uint GL_TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85; +enum uint GL_PRIMITIVES_GENERATED = 0x8C87; +enum uint GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88; +enum uint GL_RASTERIZER_DISCARD = 0x8C89; +enum uint GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A; +enum uint GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B; +enum uint GL_INTERLEAVED_ATTRIBS = 0x8C8C; +enum uint GL_SEPARATE_ATTRIBS = 0x8C8D; +enum uint GL_TRANSFORM_FEEDBACK_BUFFER = 0x8C8E; +enum uint GL_TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F; +enum uint GL_RGBA32UI = 0x8D70; +enum uint GL_RGB32UI = 0x8D71; +enum uint GL_RGBA16UI = 0x8D76; +enum uint GL_RGB16UI = 0x8D77; +enum uint GL_RGBA8UI = 0x8D7C; +enum uint GL_RGB8UI = 0x8D7D; +enum uint GL_RGBA32I = 0x8D82; +enum uint GL_RGB32I = 0x8D83; +enum uint GL_RGBA16I = 0x8D88; +enum uint GL_RGB16I = 0x8D89; +enum uint GL_RGBA8I = 0x8D8E; +enum uint GL_RGB8I = 0x8D8F; +enum uint GL_RED_INTEGER = 0x8D94; +enum uint GL_GREEN_INTEGER = 0x8D95; +enum uint GL_BLUE_INTEGER = 0x8D96; +enum uint GL_RGB_INTEGER = 0x8D98; +enum uint GL_RGBA_INTEGER = 0x8D99; +enum uint GL_BGR_INTEGER = 0x8D9A; +enum uint GL_BGRA_INTEGER = 0x8D9B; +enum uint GL_SAMPLER_1D_ARRAY = 0x8DC0; +enum uint GL_SAMPLER_2D_ARRAY = 0x8DC1; +enum uint GL_SAMPLER_1D_ARRAY_SHADOW = 0x8DC3; +enum uint GL_SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +enum uint GL_SAMPLER_CUBE_SHADOW = 0x8DC5; +enum uint GL_UNSIGNED_INT_VEC2 = 0x8DC6; +enum uint GL_UNSIGNED_INT_VEC3 = 0x8DC7; +enum uint GL_UNSIGNED_INT_VEC4 = 0x8DC8; +enum uint GL_INT_SAMPLER_1D = 0x8DC9; +enum uint GL_INT_SAMPLER_2D = 0x8DCA; +enum uint GL_INT_SAMPLER_3D = 0x8DCB; +enum uint GL_INT_SAMPLER_CUBE = 0x8DCC; +enum uint GL_INT_SAMPLER_1D_ARRAY = 0x8DCE; +enum uint GL_INT_SAMPLER_2D_ARRAY = 0x8DCF; +enum uint GL_UNSIGNED_INT_SAMPLER_1D = 0x8DD1; +enum uint GL_UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +enum uint GL_UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +enum uint GL_UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +enum uint GL_UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6; +enum uint GL_UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; +enum uint GL_QUERY_WAIT = 0x8E13; +enum uint GL_QUERY_NO_WAIT = 0x8E14; +enum uint GL_QUERY_BY_REGION_WAIT = 0x8E15; +enum uint GL_QUERY_BY_REGION_NO_WAIT = 0x8E16; +enum uint GL_BUFFER_ACCESS_FLAGS = 0x911F; +enum uint GL_BUFFER_MAP_LENGTH = 0x9120; +enum uint GL_BUFFER_MAP_OFFSET = 0x9121; +enum uint GL_DEPTH_COMPONENT32F = 0x8CAC; +enum uint GL_DEPTH32F_STENCIL8 = 0x8CAD; +enum uint GL_FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +enum uint GL_INVALID_FRAMEBUFFER_OPERATION = 0x0506; +enum uint GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210; +enum uint GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211; +enum uint GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212; +enum uint GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213; +enum uint GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214; +enum uint GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215; +enum uint GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216; +enum uint GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217; +enum uint GL_FRAMEBUFFER_DEFAULT = 0x8218; +enum uint GL_FRAMEBUFFER_UNDEFINED = 0x8219; +enum uint GL_DEPTH_STENCIL_ATTACHMENT = 0x821A; +enum uint GL_MAX_RENDERBUFFER_SIZE = 0x84E8; +enum uint GL_DEPTH_STENCIL = 0x84F9; +enum uint GL_UNSIGNED_INT_24_8 = 0x84FA; +enum uint GL_DEPTH24_STENCIL8 = 0x88F0; +enum uint GL_TEXTURE_STENCIL_SIZE = 0x88F1; +enum uint GL_TEXTURE_RED_TYPE = 0x8C10; +enum uint GL_TEXTURE_GREEN_TYPE = 0x8C11; +enum uint GL_TEXTURE_BLUE_TYPE = 0x8C12; +enum uint GL_TEXTURE_ALPHA_TYPE = 0x8C13; +enum uint GL_TEXTURE_DEPTH_TYPE = 0x8C16; +enum uint GL_UNSIGNED_NORMALIZED = 0x8C17; +enum uint GL_FRAMEBUFFER_BINDING = 0x8CA6; +enum uint GL_DRAW_FRAMEBUFFER_BINDING = 0x8CA6; +enum uint GL_RENDERBUFFER_BINDING = 0x8CA7; +enum uint GL_READ_FRAMEBUFFER = 0x8CA8; +enum uint GL_DRAW_FRAMEBUFFER = 0x8CA9; +enum uint GL_READ_FRAMEBUFFER_BINDING = 0x8CAA; +enum uint GL_RENDERBUFFER_SAMPLES = 0x8CAB; +enum uint GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0; +enum uint GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1; +enum uint GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2; +enum uint GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3; +enum uint GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4; +enum uint GL_FRAMEBUFFER_COMPLETE = 0x8CD5; +enum uint GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6; +enum uint GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7; +enum uint GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 0x8CDB; +enum uint GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 0x8CDC; +enum uint GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD; +enum uint GL_MAX_COLOR_ATTACHMENTS = 0x8CDF; +enum uint GL_COLOR_ATTACHMENT0 = 0x8CE0; +enum uint GL_COLOR_ATTACHMENT1 = 0x8CE1; +enum uint GL_COLOR_ATTACHMENT2 = 0x8CE2; +enum uint GL_COLOR_ATTACHMENT3 = 0x8CE3; +enum uint GL_COLOR_ATTACHMENT4 = 0x8CE4; +enum uint GL_COLOR_ATTACHMENT5 = 0x8CE5; +enum uint GL_COLOR_ATTACHMENT6 = 0x8CE6; +enum uint GL_COLOR_ATTACHMENT7 = 0x8CE7; +enum uint GL_COLOR_ATTACHMENT8 = 0x8CE8; +enum uint GL_COLOR_ATTACHMENT9 = 0x8CE9; +enum uint GL_COLOR_ATTACHMENT10 = 0x8CEA; +enum uint GL_COLOR_ATTACHMENT11 = 0x8CEB; +enum uint GL_COLOR_ATTACHMENT12 = 0x8CEC; +enum uint GL_COLOR_ATTACHMENT13 = 0x8CED; +enum uint GL_COLOR_ATTACHMENT14 = 0x8CEE; +enum uint GL_COLOR_ATTACHMENT15 = 0x8CEF; +enum uint GL_COLOR_ATTACHMENT16 = 0x8CF0; +enum uint GL_COLOR_ATTACHMENT17 = 0x8CF1; +enum uint GL_COLOR_ATTACHMENT18 = 0x8CF2; +enum uint GL_COLOR_ATTACHMENT19 = 0x8CF3; +enum uint GL_COLOR_ATTACHMENT20 = 0x8CF4; +enum uint GL_COLOR_ATTACHMENT21 = 0x8CF5; +enum uint GL_COLOR_ATTACHMENT22 = 0x8CF6; +enum uint GL_COLOR_ATTACHMENT23 = 0x8CF7; +enum uint GL_COLOR_ATTACHMENT24 = 0x8CF8; +enum uint GL_COLOR_ATTACHMENT25 = 0x8CF9; +enum uint GL_COLOR_ATTACHMENT26 = 0x8CFA; +enum uint GL_COLOR_ATTACHMENT27 = 0x8CFB; +enum uint GL_COLOR_ATTACHMENT28 = 0x8CFC; +enum uint GL_COLOR_ATTACHMENT29 = 0x8CFD; +enum uint GL_COLOR_ATTACHMENT30 = 0x8CFE; +enum uint GL_COLOR_ATTACHMENT31 = 0x8CFF; +enum uint GL_DEPTH_ATTACHMENT = 0x8D00; +enum uint GL_STENCIL_ATTACHMENT = 0x8D20; +enum uint GL_FRAMEBUFFER = 0x8D40; +enum uint GL_RENDERBUFFER = 0x8D41; +enum uint GL_RENDERBUFFER_WIDTH = 0x8D42; +enum uint GL_RENDERBUFFER_HEIGHT = 0x8D43; +enum uint GL_RENDERBUFFER_INTERNAL_FORMAT = 0x8D44; +enum uint GL_STENCIL_INDEX1 = 0x8D46; +enum uint GL_STENCIL_INDEX4 = 0x8D47; +enum uint GL_STENCIL_INDEX8 = 0x8D48; +enum uint GL_STENCIL_INDEX16 = 0x8D49; +enum uint GL_RENDERBUFFER_RED_SIZE = 0x8D50; +enum uint GL_RENDERBUFFER_GREEN_SIZE = 0x8D51; +enum uint GL_RENDERBUFFER_BLUE_SIZE = 0x8D52; +enum uint GL_RENDERBUFFER_ALPHA_SIZE = 0x8D53; +enum uint GL_RENDERBUFFER_DEPTH_SIZE = 0x8D54; +enum uint GL_RENDERBUFFER_STENCIL_SIZE = 0x8D55; +enum uint GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56; +enum uint GL_MAX_SAMPLES = 0x8D57; +enum uint GL_INDEX = 0x8222; +enum uint GL_TEXTURE_LUMINANCE_TYPE = 0x8C14; +enum uint GL_TEXTURE_INTENSITY_TYPE = 0x8C15; +enum uint GL_FRAMEBUFFER_SRGB = 0x8DB9; +enum uint GL_HALF_FLOAT = 0x140B; +enum uint GL_MAP_READ_BIT = 0x0001; +enum uint GL_MAP_WRITE_BIT = 0x0002; +enum uint GL_MAP_INVALIDATE_RANGE_BIT = 0x0004; +enum uint GL_MAP_INVALIDATE_BUFFER_BIT = 0x0008; +enum uint GL_MAP_FLUSH_EXPLICIT_BIT = 0x0010; +enum uint GL_MAP_UNSYNCHRONIZED_BIT = 0x0020; +enum uint GL_COMPRESSED_RED_RGTC1 = 0x8DBB; +enum uint GL_COMPRESSED_SIGNED_RED_RGTC1 = 0x8DBC; +enum uint GL_COMPRESSED_RG_RGTC2 = 0x8DBD; +enum uint GL_COMPRESSED_SIGNED_RG_RGTC2 = 0x8DBE; +enum uint GL_RG = 0x8227; +enum uint GL_RG_INTEGER = 0x8228; +enum uint GL_R8 = 0x8229; +enum uint GL_R16 = 0x822A; +enum uint GL_RG8 = 0x822B; +enum uint GL_RG16 = 0x822C; +enum uint GL_R16F = 0x822D; +enum uint GL_R32F = 0x822E; +enum uint GL_RG16F = 0x822F; +enum uint GL_RG32F = 0x8230; +enum uint GL_R8I = 0x8231; +enum uint GL_R8UI = 0x8232; +enum uint GL_R16I = 0x8233; +enum uint GL_R16UI = 0x8234; +enum uint GL_R32I = 0x8235; +enum uint GL_R32UI = 0x8236; +enum uint GL_RG8I = 0x8237; +enum uint GL_RG8UI = 0x8238; +enum uint GL_RG16I = 0x8239; +enum uint GL_RG16UI = 0x823A; +enum uint GL_RG32I = 0x823B; +enum uint GL_RG32UI = 0x823C; +enum uint GL_VERTEX_ARRAY_BINDING = 0x85B5; +enum uint GL_CLAMP_VERTEX_COLOR = 0x891A; +enum uint GL_CLAMP_FRAGMENT_COLOR = 0x891B; +enum uint GL_ALPHA_INTEGER = 0x8D97; +enum uint GL_SAMPLER_2D_RECT = 0x8B63; +enum uint GL_SAMPLER_2D_RECT_SHADOW = 0x8B64; +enum uint GL_SAMPLER_BUFFER = 0x8DC2; +enum uint GL_INT_SAMPLER_2D_RECT = 0x8DCD; +enum uint GL_INT_SAMPLER_BUFFER = 0x8DD0; +enum uint GL_UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5; +enum uint GL_UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8; +enum uint GL_TEXTURE_BUFFER = 0x8C2A; +enum uint GL_MAX_TEXTURE_BUFFER_SIZE = 0x8C2B; +enum uint GL_TEXTURE_BINDING_BUFFER = 0x8C2C; +enum uint GL_TEXTURE_BUFFER_DATA_STORE_BINDING = 0x8C2D; +enum uint GL_TEXTURE_RECTANGLE = 0x84F5; +enum uint GL_TEXTURE_BINDING_RECTANGLE = 0x84F6; +enum uint GL_PROXY_TEXTURE_RECTANGLE = 0x84F7; +enum uint GL_MAX_RECTANGLE_TEXTURE_SIZE = 0x84F8; +enum uint GL_R8_SNORM = 0x8F94; +enum uint GL_RG8_SNORM = 0x8F95; +enum uint GL_RGB8_SNORM = 0x8F96; +enum uint GL_RGBA8_SNORM = 0x8F97; +enum uint GL_R16_SNORM = 0x8F98; +enum uint GL_RG16_SNORM = 0x8F99; +enum uint GL_RGB16_SNORM = 0x8F9A; +enum uint GL_RGBA16_SNORM = 0x8F9B; +enum uint GL_SIGNED_NORMALIZED = 0x8F9C; +enum uint GL_PRIMITIVE_RESTART = 0x8F9D; +enum uint GL_PRIMITIVE_RESTART_INDEX = 0x8F9E; +enum uint GL_COPY_READ_BUFFER = 0x8F36; +enum uint GL_COPY_WRITE_BUFFER = 0x8F37; +enum uint GL_UNIFORM_BUFFER = 0x8A11; +enum uint GL_UNIFORM_BUFFER_BINDING = 0x8A28; +enum uint GL_UNIFORM_BUFFER_START = 0x8A29; +enum uint GL_UNIFORM_BUFFER_SIZE = 0x8A2A; +enum uint GL_MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B; +enum uint GL_MAX_GEOMETRY_UNIFORM_BLOCKS = 0x8A2C; +enum uint GL_MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D; +enum uint GL_MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E; +enum uint GL_MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F; +enum uint GL_MAX_UNIFORM_BLOCK_SIZE = 0x8A30; +enum uint GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31; +enum uint GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = 0x8A32; +enum uint GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33; +enum uint GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34; +enum uint GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = 0x8A35; +enum uint GL_ACTIVE_UNIFORM_BLOCKS = 0x8A36; +enum uint GL_UNIFORM_TYPE = 0x8A37; +enum uint GL_UNIFORM_SIZE = 0x8A38; +enum uint GL_UNIFORM_NAME_LENGTH = 0x8A39; +enum uint GL_UNIFORM_BLOCK_INDEX = 0x8A3A; +enum uint GL_UNIFORM_OFFSET = 0x8A3B; +enum uint GL_UNIFORM_ARRAY_STRIDE = 0x8A3C; +enum uint GL_UNIFORM_MATRIX_STRIDE = 0x8A3D; +enum uint GL_UNIFORM_IS_ROW_MAJOR = 0x8A3E; +enum uint GL_UNIFORM_BLOCK_BINDING = 0x8A3F; +enum uint GL_UNIFORM_BLOCK_DATA_SIZE = 0x8A40; +enum uint GL_UNIFORM_BLOCK_NAME_LENGTH = 0x8A41; +enum uint GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42; +enum uint GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43; +enum uint GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44; +enum uint GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45; +enum uint GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46; +enum uint GL_CONTEXT_CORE_PROFILE_BIT = 0x00000001; +enum uint GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = 0x00000002; +enum uint GL_LINES_ADJACENCY = 0x000A; +enum uint GL_LINE_STRIP_ADJACENCY = 0x000B; +enum uint GL_TRIANGLES_ADJACENCY = 0x000C; +enum uint GL_TRIANGLE_STRIP_ADJACENCY = 0x000D; +enum uint GL_PROGRAM_POINT_SIZE = 0x8642; +enum uint GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = 0x8C29; +enum uint GL_FRAMEBUFFER_ATTACHMENT_LAYERED = 0x8DA7; +enum uint GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = 0x8DA8; +enum uint GL_GEOMETRY_SHADER = 0x8DD9; +enum uint GL_GEOMETRY_VERTICES_OUT = 0x8916; +enum uint GL_GEOMETRY_INPUT_TYPE = 0x8917; +enum uint GL_GEOMETRY_OUTPUT_TYPE = 0x8918; +enum uint GL_MAX_GEOMETRY_UNIFORM_COMPONENTS = 0x8DDF; +enum uint GL_MAX_GEOMETRY_OUTPUT_VERTICES = 0x8DE0; +enum uint GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 0x8DE1; +enum uint GL_MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122; +enum uint GL_MAX_GEOMETRY_INPUT_COMPONENTS = 0x9123; +enum uint GL_MAX_GEOMETRY_OUTPUT_COMPONENTS = 0x9124; +enum uint GL_MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125; +enum uint GL_CONTEXT_PROFILE_MASK = 0x9126; +enum uint GL_DEPTH_CLAMP = 0x864F; +enum uint GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 0x8E4C; +enum uint GL_FIRST_VERTEX_CONVENTION = 0x8E4D; +enum uint GL_LAST_VERTEX_CONVENTION = 0x8E4E; +enum uint GL_PROVOKING_VERTEX = 0x8E4F; +enum uint GL_TEXTURE_CUBE_MAP_SEAMLESS = 0x884F; +enum uint GL_MAX_SERVER_WAIT_TIMEOUT = 0x9111; +enum uint GL_OBJECT_TYPE = 0x9112; +enum uint GL_SYNC_CONDITION = 0x9113; +enum uint GL_SYNC_STATUS = 0x9114; +enum uint GL_SYNC_FLAGS = 0x9115; +enum uint GL_SYNC_FENCE = 0x9116; +enum uint GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117; +enum uint GL_UNSIGNALED = 0x9118; +enum uint GL_SIGNALED = 0x9119; +enum uint GL_ALREADY_SIGNALED = 0x911A; +enum uint GL_TIMEOUT_EXPIRED = 0x911B; +enum uint GL_CONDITION_SATISFIED = 0x911C; +enum uint GL_WAIT_FAILED = 0x911D; +enum uint GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001; +enum uint GL_SAMPLE_POSITION = 0x8E50; +enum uint GL_SAMPLE_MASK = 0x8E51; +enum uint GL_SAMPLE_MASK_VALUE = 0x8E52; +enum uint GL_MAX_SAMPLE_MASK_WORDS = 0x8E59; +enum uint GL_TEXTURE_2D_MULTISAMPLE = 0x9100; +enum uint GL_PROXY_TEXTURE_2D_MULTISAMPLE = 0x9101; +enum uint GL_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9102; +enum uint GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9103; +enum uint GL_TEXTURE_BINDING_2D_MULTISAMPLE = 0x9104; +enum uint GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = 0x9105; +enum uint GL_TEXTURE_SAMPLES = 0x9106; +enum uint GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = 0x9107; +enum uint GL_SAMPLER_2D_MULTISAMPLE = 0x9108; +enum uint GL_INT_SAMPLER_2D_MULTISAMPLE = 0x9109; +enum uint GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A; +enum uint GL_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B; +enum uint GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C; +enum uint GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D; +enum uint GL_MAX_COLOR_TEXTURE_SAMPLES = 0x910E; +enum uint GL_MAX_DEPTH_TEXTURE_SAMPLES = 0x910F; +enum uint GL_MAX_INTEGER_SAMPLES = 0x9110; +enum uint GL_VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE; +enum uint GL_SRC1_COLOR = 0x88F9; +enum uint GL_ONE_MINUS_SRC1_COLOR = 0x88FA; +enum uint GL_ONE_MINUS_SRC1_ALPHA = 0x88FB; +enum uint GL_MAX_DUAL_SOURCE_DRAW_BUFFERS = 0x88FC; +enum uint GL_ANY_SAMPLES_PASSED = 0x8C2F; +enum uint GL_SAMPLER_BINDING = 0x8919; +enum uint GL_RGB10_A2UI = 0x906F; +enum uint GL_TEXTURE_SWIZZLE_R = 0x8E42; +enum uint GL_TEXTURE_SWIZZLE_G = 0x8E43; +enum uint GL_TEXTURE_SWIZZLE_B = 0x8E44; +enum uint GL_TEXTURE_SWIZZLE_A = 0x8E45; +enum uint GL_TEXTURE_SWIZZLE_RGBA = 0x8E46; +enum uint GL_TIME_ELAPSED = 0x88BF; +enum uint GL_TIMESTAMP = 0x8E28; +enum uint GL_INT_2_10_10_10_REV = 0x8D9F; +enum uint GL_FIXED = 0x140C; +enum uint GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; +enum uint GL_MAX_VARYING_VECTORS = 0x8DFC; +enum uint GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; +enum uint GL_IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A; +enum uint GL_IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B; +enum uint GL_SHADER_COMPILER = 0x8DFA; +enum uint GL_SHADER_BINARY_FORMATS = 0x8DF8; +enum uint GL_NUM_SHADER_BINARY_FORMATS = 0x8DF9; +enum uint GL_LOW_FLOAT = 0x8DF0; +enum uint GL_MEDIUM_FLOAT = 0x8DF1; +enum uint GL_HIGH_FLOAT = 0x8DF2; +enum uint GL_LOW_INT = 0x8DF3; +enum uint GL_MEDIUM_INT = 0x8DF4; +enum uint GL_HIGH_INT = 0x8DF5; +enum uint GL_RGB565 = 0x8D62; +enum uint GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9; +enum uint GL_PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69; +enum uint GL_COPY_READ_BUFFER_BINDING = 0x8F36; +enum uint GL_COPY_WRITE_BUFFER_BINDING = 0x8F37; +enum uint GL_ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A; +enum uint GL_TRANSFORM_FEEDBACK = 0x8E22; +enum uint GL_TRANSFORM_FEEDBACK_PAUSED = 0x8E23; +enum uint GL_TRANSFORM_FEEDBACK_ACTIVE = 0x8E24; +enum uint GL_TRANSFORM_FEEDBACK_BINDING = 0x8E25; +enum uint GL_PROGRAM_BINARY_RETRIEVABLE_HINT = 0x8257; +enum uint GL_PROGRAM_BINARY_LENGTH = 0x8741; +enum uint GL_NUM_PROGRAM_BINARY_FORMATS = 0x87FE; +enum uint GL_PROGRAM_BINARY_FORMATS = 0x87FF; +enum uint GL_COMPRESSED_R11_EAC = 0x9270; +enum uint GL_COMPRESSED_SIGNED_R11_EAC = 0x9271; +enum uint GL_COMPRESSED_RG11_EAC = 0x9272; +enum uint GL_COMPRESSED_SIGNED_RG11_EAC = 0x9273; +enum uint GL_COMPRESSED_RGB8_ETC2 = 0x9274; +enum uint GL_COMPRESSED_SRGB8_ETC2 = 0x9275; +enum uint GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276; +enum uint GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277; +enum uint GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278; +enum uint GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279; +enum uint GL_TEXTURE_IMMUTABLE_FORMAT = 0x912F; +enum uint GL_MAX_ELEMENT_INDEX = 0x8D6B; +enum uint GL_NUM_SAMPLE_COUNTS = 0x9380; +enum uint GL_TEXTURE_IMMUTABLE_LEVELS = 0x82DF; diff --git a/demos/external/sources/glad/gl/ext.d b/demos/external/sources/glad/gl/ext.d new file mode 100644 index 0000000..ad03be6 --- /dev/null +++ b/demos/external/sources/glad/gl/ext.d @@ -0,0 +1,10 @@ +module glad.gl.ext; + + +private import glad.gl.types; +private import glad.gl.enums; +private import glad.gl.funcs; +nothrow @nogc extern(System) { +} +__gshared { +} diff --git a/demos/external/sources/glad/gl/funcs.d b/demos/external/sources/glad/gl/funcs.d new file mode 100644 index 0000000..bfad207 --- /dev/null +++ b/demos/external/sources/glad/gl/funcs.d @@ -0,0 +1,1508 @@ +module glad.gl.funcs; + + +private import glad.gl.types; +__gshared bool GL_VERSION_1_0; +__gshared bool GL_VERSION_1_1; +__gshared bool GL_VERSION_1_2; +__gshared bool GL_VERSION_1_3; +__gshared bool GL_VERSION_1_4; +__gshared bool GL_VERSION_1_5; +__gshared bool GL_VERSION_2_0; +__gshared bool GL_VERSION_2_1; +__gshared bool GL_VERSION_3_0; +__gshared bool GL_VERSION_3_1; +__gshared bool GL_VERSION_3_2; +__gshared bool GL_VERSION_3_3; +__gshared bool GL_ES_VERSION_2_0; +__gshared bool GL_ES_VERSION_3_0; +nothrow @nogc extern(System) { +alias fp_glCullFace = void function(GLenum); +alias fp_glFrontFace = void function(GLenum); +alias fp_glHint = void function(GLenum, GLenum); +alias fp_glLineWidth = void function(GLfloat); +alias fp_glPointSize = void function(GLfloat); +alias fp_glPolygonMode = void function(GLenum, GLenum); +alias fp_glScissor = void function(GLint, GLint, GLsizei, GLsizei); +alias fp_glTexParameterf = void function(GLenum, GLenum, GLfloat); +alias fp_glTexParameterfv = void function(GLenum, GLenum, const(GLfloat)*); +alias fp_glTexParameteri = void function(GLenum, GLenum, GLint); +alias fp_glTexParameteriv = void function(GLenum, GLenum, const(GLint)*); +alias fp_glTexImage1D = void function(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const(void)*); +alias fp_glTexImage2D = void function(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const(void)*); +alias fp_glDrawBuffer = void function(GLenum); +alias fp_glClear = void function(GLbitfield); +alias fp_glClearColor = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glClearStencil = void function(GLint); +alias fp_glClearDepth = void function(GLdouble); +alias fp_glStencilMask = void function(GLuint); +alias fp_glColorMask = void function(GLboolean, GLboolean, GLboolean, GLboolean); +alias fp_glDepthMask = void function(GLboolean); +alias fp_glDisable = void function(GLenum); +alias fp_glEnable = void function(GLenum); +alias fp_glFinish = void function(); +alias fp_glFlush = void function(); +alias fp_glBlendFunc = void function(GLenum, GLenum); +alias fp_glLogicOp = void function(GLenum); +alias fp_glStencilFunc = void function(GLenum, GLint, GLuint); +alias fp_glStencilOp = void function(GLenum, GLenum, GLenum); +alias fp_glDepthFunc = void function(GLenum); +alias fp_glPixelStoref = void function(GLenum, GLfloat); +alias fp_glPixelStorei = void function(GLenum, GLint); +alias fp_glReadBuffer = void function(GLenum); +alias fp_glReadPixels = void function(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void*); +alias fp_glGetBooleanv = void function(GLenum, GLboolean*); +alias fp_glGetDoublev = void function(GLenum, GLdouble*); +alias fp_glGetError = GLenum function(); +alias fp_glGetFloatv = void function(GLenum, GLfloat*); +alias fp_glGetIntegerv = void function(GLenum, GLint*); +alias fp_glGetString = const(GLubyte)* function(GLenum); +alias fp_glGetTexImage = void function(GLenum, GLint, GLenum, GLenum, void*); +alias fp_glGetTexParameterfv = void function(GLenum, GLenum, GLfloat*); +alias fp_glGetTexParameteriv = void function(GLenum, GLenum, GLint*); +alias fp_glGetTexLevelParameterfv = void function(GLenum, GLint, GLenum, GLfloat*); +alias fp_glGetTexLevelParameteriv = void function(GLenum, GLint, GLenum, GLint*); +alias fp_glIsEnabled = GLboolean function(GLenum); +alias fp_glDepthRange = void function(GLdouble, GLdouble); +alias fp_glViewport = void function(GLint, GLint, GLsizei, GLsizei); +alias fp_glNewList = void function(GLuint, GLenum); +alias fp_glEndList = void function(); +alias fp_glCallList = void function(GLuint); +alias fp_glCallLists = void function(GLsizei, GLenum, const(void)*); +alias fp_glDeleteLists = void function(GLuint, GLsizei); +alias fp_glGenLists = GLuint function(GLsizei); +alias fp_glListBase = void function(GLuint); +alias fp_glBegin = void function(GLenum); +alias fp_glBitmap = void function(GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat, const(GLubyte)*); +alias fp_glColor3b = void function(GLbyte, GLbyte, GLbyte); +alias fp_glColor3bv = void function(const(GLbyte)*); +alias fp_glColor3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glColor3dv = void function(const(GLdouble)*); +alias fp_glColor3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glColor3fv = void function(const(GLfloat)*); +alias fp_glColor3i = void function(GLint, GLint, GLint); +alias fp_glColor3iv = void function(const(GLint)*); +alias fp_glColor3s = void function(GLshort, GLshort, GLshort); +alias fp_glColor3sv = void function(const(GLshort)*); +alias fp_glColor3ub = void function(GLubyte, GLubyte, GLubyte); +alias fp_glColor3ubv = void function(const(GLubyte)*); +alias fp_glColor3ui = void function(GLuint, GLuint, GLuint); +alias fp_glColor3uiv = void function(const(GLuint)*); +alias fp_glColor3us = void function(GLushort, GLushort, GLushort); +alias fp_glColor3usv = void function(const(GLushort)*); +alias fp_glColor4b = void function(GLbyte, GLbyte, GLbyte, GLbyte); +alias fp_glColor4bv = void function(const(GLbyte)*); +alias fp_glColor4d = void function(GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glColor4dv = void function(const(GLdouble)*); +alias fp_glColor4f = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glColor4fv = void function(const(GLfloat)*); +alias fp_glColor4i = void function(GLint, GLint, GLint, GLint); +alias fp_glColor4iv = void function(const(GLint)*); +alias fp_glColor4s = void function(GLshort, GLshort, GLshort, GLshort); +alias fp_glColor4sv = void function(const(GLshort)*); +alias fp_glColor4ub = void function(GLubyte, GLubyte, GLubyte, GLubyte); +alias fp_glColor4ubv = void function(const(GLubyte)*); +alias fp_glColor4ui = void function(GLuint, GLuint, GLuint, GLuint); +alias fp_glColor4uiv = void function(const(GLuint)*); +alias fp_glColor4us = void function(GLushort, GLushort, GLushort, GLushort); +alias fp_glColor4usv = void function(const(GLushort)*); +alias fp_glEdgeFlag = void function(GLboolean); +alias fp_glEdgeFlagv = void function(const(GLboolean)*); +alias fp_glEnd = void function(); +alias fp_glIndexd = void function(GLdouble); +alias fp_glIndexdv = void function(const(GLdouble)*); +alias fp_glIndexf = void function(GLfloat); +alias fp_glIndexfv = void function(const(GLfloat)*); +alias fp_glIndexi = void function(GLint); +alias fp_glIndexiv = void function(const(GLint)*); +alias fp_glIndexs = void function(GLshort); +alias fp_glIndexsv = void function(const(GLshort)*); +alias fp_glNormal3b = void function(GLbyte, GLbyte, GLbyte); +alias fp_glNormal3bv = void function(const(GLbyte)*); +alias fp_glNormal3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glNormal3dv = void function(const(GLdouble)*); +alias fp_glNormal3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glNormal3fv = void function(const(GLfloat)*); +alias fp_glNormal3i = void function(GLint, GLint, GLint); +alias fp_glNormal3iv = void function(const(GLint)*); +alias fp_glNormal3s = void function(GLshort, GLshort, GLshort); +alias fp_glNormal3sv = void function(const(GLshort)*); +alias fp_glRasterPos2d = void function(GLdouble, GLdouble); +alias fp_glRasterPos2dv = void function(const(GLdouble)*); +alias fp_glRasterPos2f = void function(GLfloat, GLfloat); +alias fp_glRasterPos2fv = void function(const(GLfloat)*); +alias fp_glRasterPos2i = void function(GLint, GLint); +alias fp_glRasterPos2iv = void function(const(GLint)*); +alias fp_glRasterPos2s = void function(GLshort, GLshort); +alias fp_glRasterPos2sv = void function(const(GLshort)*); +alias fp_glRasterPos3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glRasterPos3dv = void function(const(GLdouble)*); +alias fp_glRasterPos3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glRasterPos3fv = void function(const(GLfloat)*); +alias fp_glRasterPos3i = void function(GLint, GLint, GLint); +alias fp_glRasterPos3iv = void function(const(GLint)*); +alias fp_glRasterPos3s = void function(GLshort, GLshort, GLshort); +alias fp_glRasterPos3sv = void function(const(GLshort)*); +alias fp_glRasterPos4d = void function(GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glRasterPos4dv = void function(const(GLdouble)*); +alias fp_glRasterPos4f = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glRasterPos4fv = void function(const(GLfloat)*); +alias fp_glRasterPos4i = void function(GLint, GLint, GLint, GLint); +alias fp_glRasterPos4iv = void function(const(GLint)*); +alias fp_glRasterPos4s = void function(GLshort, GLshort, GLshort, GLshort); +alias fp_glRasterPos4sv = void function(const(GLshort)*); +alias fp_glRectd = void function(GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glRectdv = void function(const(GLdouble)*, const(GLdouble)*); +alias fp_glRectf = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glRectfv = void function(const(GLfloat)*, const(GLfloat)*); +alias fp_glRecti = void function(GLint, GLint, GLint, GLint); +alias fp_glRectiv = void function(const(GLint)*, const(GLint)*); +alias fp_glRects = void function(GLshort, GLshort, GLshort, GLshort); +alias fp_glRectsv = void function(const(GLshort)*, const(GLshort)*); +alias fp_glTexCoord1d = void function(GLdouble); +alias fp_glTexCoord1dv = void function(const(GLdouble)*); +alias fp_glTexCoord1f = void function(GLfloat); +alias fp_glTexCoord1fv = void function(const(GLfloat)*); +alias fp_glTexCoord1i = void function(GLint); +alias fp_glTexCoord1iv = void function(const(GLint)*); +alias fp_glTexCoord1s = void function(GLshort); +alias fp_glTexCoord1sv = void function(const(GLshort)*); +alias fp_glTexCoord2d = void function(GLdouble, GLdouble); +alias fp_glTexCoord2dv = void function(const(GLdouble)*); +alias fp_glTexCoord2f = void function(GLfloat, GLfloat); +alias fp_glTexCoord2fv = void function(const(GLfloat)*); +alias fp_glTexCoord2i = void function(GLint, GLint); +alias fp_glTexCoord2iv = void function(const(GLint)*); +alias fp_glTexCoord2s = void function(GLshort, GLshort); +alias fp_glTexCoord2sv = void function(const(GLshort)*); +alias fp_glTexCoord3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glTexCoord3dv = void function(const(GLdouble)*); +alias fp_glTexCoord3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glTexCoord3fv = void function(const(GLfloat)*); +alias fp_glTexCoord3i = void function(GLint, GLint, GLint); +alias fp_glTexCoord3iv = void function(const(GLint)*); +alias fp_glTexCoord3s = void function(GLshort, GLshort, GLshort); +alias fp_glTexCoord3sv = void function(const(GLshort)*); +alias fp_glTexCoord4d = void function(GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glTexCoord4dv = void function(const(GLdouble)*); +alias fp_glTexCoord4f = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glTexCoord4fv = void function(const(GLfloat)*); +alias fp_glTexCoord4i = void function(GLint, GLint, GLint, GLint); +alias fp_glTexCoord4iv = void function(const(GLint)*); +alias fp_glTexCoord4s = void function(GLshort, GLshort, GLshort, GLshort); +alias fp_glTexCoord4sv = void function(const(GLshort)*); +alias fp_glVertex2d = void function(GLdouble, GLdouble); +alias fp_glVertex2dv = void function(const(GLdouble)*); +alias fp_glVertex2f = void function(GLfloat, GLfloat); +alias fp_glVertex2fv = void function(const(GLfloat)*); +alias fp_glVertex2i = void function(GLint, GLint); +alias fp_glVertex2iv = void function(const(GLint)*); +alias fp_glVertex2s = void function(GLshort, GLshort); +alias fp_glVertex2sv = void function(const(GLshort)*); +alias fp_glVertex3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glVertex3dv = void function(const(GLdouble)*); +alias fp_glVertex3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glVertex3fv = void function(const(GLfloat)*); +alias fp_glVertex3i = void function(GLint, GLint, GLint); +alias fp_glVertex3iv = void function(const(GLint)*); +alias fp_glVertex3s = void function(GLshort, GLshort, GLshort); +alias fp_glVertex3sv = void function(const(GLshort)*); +alias fp_glVertex4d = void function(GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glVertex4dv = void function(const(GLdouble)*); +alias fp_glVertex4f = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glVertex4fv = void function(const(GLfloat)*); +alias fp_glVertex4i = void function(GLint, GLint, GLint, GLint); +alias fp_glVertex4iv = void function(const(GLint)*); +alias fp_glVertex4s = void function(GLshort, GLshort, GLshort, GLshort); +alias fp_glVertex4sv = void function(const(GLshort)*); +alias fp_glClipPlane = void function(GLenum, const(GLdouble)*); +alias fp_glColorMaterial = void function(GLenum, GLenum); +alias fp_glFogf = void function(GLenum, GLfloat); +alias fp_glFogfv = void function(GLenum, const(GLfloat)*); +alias fp_glFogi = void function(GLenum, GLint); +alias fp_glFogiv = void function(GLenum, const(GLint)*); +alias fp_glLightf = void function(GLenum, GLenum, GLfloat); +alias fp_glLightfv = void function(GLenum, GLenum, const(GLfloat)*); +alias fp_glLighti = void function(GLenum, GLenum, GLint); +alias fp_glLightiv = void function(GLenum, GLenum, const(GLint)*); +alias fp_glLightModelf = void function(GLenum, GLfloat); +alias fp_glLightModelfv = void function(GLenum, const(GLfloat)*); +alias fp_glLightModeli = void function(GLenum, GLint); +alias fp_glLightModeliv = void function(GLenum, const(GLint)*); +alias fp_glLineStipple = void function(GLint, GLushort); +alias fp_glMaterialf = void function(GLenum, GLenum, GLfloat); +alias fp_glMaterialfv = void function(GLenum, GLenum, const(GLfloat)*); +alias fp_glMateriali = void function(GLenum, GLenum, GLint); +alias fp_glMaterialiv = void function(GLenum, GLenum, const(GLint)*); +alias fp_glPolygonStipple = void function(const(GLubyte)*); +alias fp_glShadeModel = void function(GLenum); +alias fp_glTexEnvf = void function(GLenum, GLenum, GLfloat); +alias fp_glTexEnvfv = void function(GLenum, GLenum, const(GLfloat)*); +alias fp_glTexEnvi = void function(GLenum, GLenum, GLint); +alias fp_glTexEnviv = void function(GLenum, GLenum, const(GLint)*); +alias fp_glTexGend = void function(GLenum, GLenum, GLdouble); +alias fp_glTexGendv = void function(GLenum, GLenum, const(GLdouble)*); +alias fp_glTexGenf = void function(GLenum, GLenum, GLfloat); +alias fp_glTexGenfv = void function(GLenum, GLenum, const(GLfloat)*); +alias fp_glTexGeni = void function(GLenum, GLenum, GLint); +alias fp_glTexGeniv = void function(GLenum, GLenum, const(GLint)*); +alias fp_glFeedbackBuffer = void function(GLsizei, GLenum, GLfloat*); +alias fp_glSelectBuffer = void function(GLsizei, GLuint*); +alias fp_glRenderMode = GLint function(GLenum); +alias fp_glInitNames = void function(); +alias fp_glLoadName = void function(GLuint); +alias fp_glPassThrough = void function(GLfloat); +alias fp_glPopName = void function(); +alias fp_glPushName = void function(GLuint); +alias fp_glClearAccum = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glClearIndex = void function(GLfloat); +alias fp_glIndexMask = void function(GLuint); +alias fp_glAccum = void function(GLenum, GLfloat); +alias fp_glPopAttrib = void function(); +alias fp_glPushAttrib = void function(GLbitfield); +alias fp_glMap1d = void function(GLenum, GLdouble, GLdouble, GLint, GLint, const(GLdouble)*); +alias fp_glMap1f = void function(GLenum, GLfloat, GLfloat, GLint, GLint, const(GLfloat)*); +alias fp_glMap2d = void function(GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const(GLdouble)*); +alias fp_glMap2f = void function(GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const(GLfloat)*); +alias fp_glMapGrid1d = void function(GLint, GLdouble, GLdouble); +alias fp_glMapGrid1f = void function(GLint, GLfloat, GLfloat); +alias fp_glMapGrid2d = void function(GLint, GLdouble, GLdouble, GLint, GLdouble, GLdouble); +alias fp_glMapGrid2f = void function(GLint, GLfloat, GLfloat, GLint, GLfloat, GLfloat); +alias fp_glEvalCoord1d = void function(GLdouble); +alias fp_glEvalCoord1dv = void function(const(GLdouble)*); +alias fp_glEvalCoord1f = void function(GLfloat); +alias fp_glEvalCoord1fv = void function(const(GLfloat)*); +alias fp_glEvalCoord2d = void function(GLdouble, GLdouble); +alias fp_glEvalCoord2dv = void function(const(GLdouble)*); +alias fp_glEvalCoord2f = void function(GLfloat, GLfloat); +alias fp_glEvalCoord2fv = void function(const(GLfloat)*); +alias fp_glEvalMesh1 = void function(GLenum, GLint, GLint); +alias fp_glEvalPoint1 = void function(GLint); +alias fp_glEvalMesh2 = void function(GLenum, GLint, GLint, GLint, GLint); +alias fp_glEvalPoint2 = void function(GLint, GLint); +alias fp_glAlphaFunc = void function(GLenum, GLfloat); +alias fp_glPixelZoom = void function(GLfloat, GLfloat); +alias fp_glPixelTransferf = void function(GLenum, GLfloat); +alias fp_glPixelTransferi = void function(GLenum, GLint); +alias fp_glPixelMapfv = void function(GLenum, GLsizei, const(GLfloat)*); +alias fp_glPixelMapuiv = void function(GLenum, GLsizei, const(GLuint)*); +alias fp_glPixelMapusv = void function(GLenum, GLsizei, const(GLushort)*); +alias fp_glCopyPixels = void function(GLint, GLint, GLsizei, GLsizei, GLenum); +alias fp_glDrawPixels = void function(GLsizei, GLsizei, GLenum, GLenum, const(void)*); +alias fp_glGetClipPlane = void function(GLenum, GLdouble*); +alias fp_glGetLightfv = void function(GLenum, GLenum, GLfloat*); +alias fp_glGetLightiv = void function(GLenum, GLenum, GLint*); +alias fp_glGetMapdv = void function(GLenum, GLenum, GLdouble*); +alias fp_glGetMapfv = void function(GLenum, GLenum, GLfloat*); +alias fp_glGetMapiv = void function(GLenum, GLenum, GLint*); +alias fp_glGetMaterialfv = void function(GLenum, GLenum, GLfloat*); +alias fp_glGetMaterialiv = void function(GLenum, GLenum, GLint*); +alias fp_glGetPixelMapfv = void function(GLenum, GLfloat*); +alias fp_glGetPixelMapuiv = void function(GLenum, GLuint*); +alias fp_glGetPixelMapusv = void function(GLenum, GLushort*); +alias fp_glGetPolygonStipple = void function(GLubyte*); +alias fp_glGetTexEnvfv = void function(GLenum, GLenum, GLfloat*); +alias fp_glGetTexEnviv = void function(GLenum, GLenum, GLint*); +alias fp_glGetTexGendv = void function(GLenum, GLenum, GLdouble*); +alias fp_glGetTexGenfv = void function(GLenum, GLenum, GLfloat*); +alias fp_glGetTexGeniv = void function(GLenum, GLenum, GLint*); +alias fp_glIsList = GLboolean function(GLuint); +alias fp_glFrustum = void function(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glLoadIdentity = void function(); +alias fp_glLoadMatrixf = void function(const(GLfloat)*); +alias fp_glLoadMatrixd = void function(const(GLdouble)*); +alias fp_glMatrixMode = void function(GLenum); +alias fp_glMultMatrixf = void function(const(GLfloat)*); +alias fp_glMultMatrixd = void function(const(GLdouble)*); +alias fp_glOrtho = void function(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glPopMatrix = void function(); +alias fp_glPushMatrix = void function(); +alias fp_glRotated = void function(GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glRotatef = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glScaled = void function(GLdouble, GLdouble, GLdouble); +alias fp_glScalef = void function(GLfloat, GLfloat, GLfloat); +alias fp_glTranslated = void function(GLdouble, GLdouble, GLdouble); +alias fp_glTranslatef = void function(GLfloat, GLfloat, GLfloat); +alias fp_glDrawArrays = void function(GLenum, GLint, GLsizei); +alias fp_glDrawElements = void function(GLenum, GLsizei, GLenum, const(void)*); +alias fp_glGetPointerv = void function(GLenum, void**); +alias fp_glPolygonOffset = void function(GLfloat, GLfloat); +alias fp_glCopyTexImage1D = void function(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +alias fp_glCopyTexImage2D = void function(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +alias fp_glCopyTexSubImage1D = void function(GLenum, GLint, GLint, GLint, GLint, GLsizei); +alias fp_glCopyTexSubImage2D = void function(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +alias fp_glTexSubImage1D = void function(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const(void)*); +alias fp_glTexSubImage2D = void function(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const(void)*); +alias fp_glBindTexture = void function(GLenum, GLuint); +alias fp_glDeleteTextures = void function(GLsizei, const(GLuint)*); +alias fp_glGenTextures = void function(GLsizei, GLuint*); +alias fp_glIsTexture = GLboolean function(GLuint); +alias fp_glArrayElement = void function(GLint); +alias fp_glColorPointer = void function(GLint, GLenum, GLsizei, const(void)*); +alias fp_glDisableClientState = void function(GLenum); +alias fp_glEdgeFlagPointer = void function(GLsizei, const(void)*); +alias fp_glEnableClientState = void function(GLenum); +alias fp_glIndexPointer = void function(GLenum, GLsizei, const(void)*); +alias fp_glInterleavedArrays = void function(GLenum, GLsizei, const(void)*); +alias fp_glNormalPointer = void function(GLenum, GLsizei, const(void)*); +alias fp_glTexCoordPointer = void function(GLint, GLenum, GLsizei, const(void)*); +alias fp_glVertexPointer = void function(GLint, GLenum, GLsizei, const(void)*); +alias fp_glAreTexturesResident = GLboolean function(GLsizei, const(GLuint)*, GLboolean*); +alias fp_glPrioritizeTextures = void function(GLsizei, const(GLuint)*, const(GLfloat)*); +alias fp_glIndexub = void function(GLubyte); +alias fp_glIndexubv = void function(const(GLubyte)*); +alias fp_glPopClientAttrib = void function(); +alias fp_glPushClientAttrib = void function(GLbitfield); +alias fp_glDrawRangeElements = void function(GLenum, GLuint, GLuint, GLsizei, GLenum, const(void)*); +alias fp_glTexImage3D = void function(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const(void)*); +alias fp_glTexSubImage3D = void function(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const(void)*); +alias fp_glCopyTexSubImage3D = void function(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +alias fp_glActiveTexture = void function(GLenum); +alias fp_glSampleCoverage = void function(GLfloat, GLboolean); +alias fp_glCompressedTexImage3D = void function(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const(void)*); +alias fp_glCompressedTexImage2D = void function(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const(void)*); +alias fp_glCompressedTexImage1D = void function(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const(void)*); +alias fp_glCompressedTexSubImage3D = void function(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const(void)*); +alias fp_glCompressedTexSubImage2D = void function(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const(void)*); +alias fp_glCompressedTexSubImage1D = void function(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const(void)*); +alias fp_glGetCompressedTexImage = void function(GLenum, GLint, void*); +alias fp_glClientActiveTexture = void function(GLenum); +alias fp_glMultiTexCoord1d = void function(GLenum, GLdouble); +alias fp_glMultiTexCoord1dv = void function(GLenum, const(GLdouble)*); +alias fp_glMultiTexCoord1f = void function(GLenum, GLfloat); +alias fp_glMultiTexCoord1fv = void function(GLenum, const(GLfloat)*); +alias fp_glMultiTexCoord1i = void function(GLenum, GLint); +alias fp_glMultiTexCoord1iv = void function(GLenum, const(GLint)*); +alias fp_glMultiTexCoord1s = void function(GLenum, GLshort); +alias fp_glMultiTexCoord1sv = void function(GLenum, const(GLshort)*); +alias fp_glMultiTexCoord2d = void function(GLenum, GLdouble, GLdouble); +alias fp_glMultiTexCoord2dv = void function(GLenum, const(GLdouble)*); +alias fp_glMultiTexCoord2f = void function(GLenum, GLfloat, GLfloat); +alias fp_glMultiTexCoord2fv = void function(GLenum, const(GLfloat)*); +alias fp_glMultiTexCoord2i = void function(GLenum, GLint, GLint); +alias fp_glMultiTexCoord2iv = void function(GLenum, const(GLint)*); +alias fp_glMultiTexCoord2s = void function(GLenum, GLshort, GLshort); +alias fp_glMultiTexCoord2sv = void function(GLenum, const(GLshort)*); +alias fp_glMultiTexCoord3d = void function(GLenum, GLdouble, GLdouble, GLdouble); +alias fp_glMultiTexCoord3dv = void function(GLenum, const(GLdouble)*); +alias fp_glMultiTexCoord3f = void function(GLenum, GLfloat, GLfloat, GLfloat); +alias fp_glMultiTexCoord3fv = void function(GLenum, const(GLfloat)*); +alias fp_glMultiTexCoord3i = void function(GLenum, GLint, GLint, GLint); +alias fp_glMultiTexCoord3iv = void function(GLenum, const(GLint)*); +alias fp_glMultiTexCoord3s = void function(GLenum, GLshort, GLshort, GLshort); +alias fp_glMultiTexCoord3sv = void function(GLenum, const(GLshort)*); +alias fp_glMultiTexCoord4d = void function(GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glMultiTexCoord4dv = void function(GLenum, const(GLdouble)*); +alias fp_glMultiTexCoord4f = void function(GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glMultiTexCoord4fv = void function(GLenum, const(GLfloat)*); +alias fp_glMultiTexCoord4i = void function(GLenum, GLint, GLint, GLint, GLint); +alias fp_glMultiTexCoord4iv = void function(GLenum, const(GLint)*); +alias fp_glMultiTexCoord4s = void function(GLenum, GLshort, GLshort, GLshort, GLshort); +alias fp_glMultiTexCoord4sv = void function(GLenum, const(GLshort)*); +alias fp_glLoadTransposeMatrixf = void function(const(GLfloat)*); +alias fp_glLoadTransposeMatrixd = void function(const(GLdouble)*); +alias fp_glMultTransposeMatrixf = void function(const(GLfloat)*); +alias fp_glMultTransposeMatrixd = void function(const(GLdouble)*); +alias fp_glBlendFuncSeparate = void function(GLenum, GLenum, GLenum, GLenum); +alias fp_glMultiDrawArrays = void function(GLenum, const(GLint)*, const(GLsizei)*, GLsizei); +alias fp_glMultiDrawElements = void function(GLenum, const(GLsizei)*, GLenum, const(void*)*, GLsizei); +alias fp_glPointParameterf = void function(GLenum, GLfloat); +alias fp_glPointParameterfv = void function(GLenum, const(GLfloat)*); +alias fp_glPointParameteri = void function(GLenum, GLint); +alias fp_glPointParameteriv = void function(GLenum, const(GLint)*); +alias fp_glFogCoordf = void function(GLfloat); +alias fp_glFogCoordfv = void function(const(GLfloat)*); +alias fp_glFogCoordd = void function(GLdouble); +alias fp_glFogCoorddv = void function(const(GLdouble)*); +alias fp_glFogCoordPointer = void function(GLenum, GLsizei, const(void)*); +alias fp_glSecondaryColor3b = void function(GLbyte, GLbyte, GLbyte); +alias fp_glSecondaryColor3bv = void function(const(GLbyte)*); +alias fp_glSecondaryColor3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glSecondaryColor3dv = void function(const(GLdouble)*); +alias fp_glSecondaryColor3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glSecondaryColor3fv = void function(const(GLfloat)*); +alias fp_glSecondaryColor3i = void function(GLint, GLint, GLint); +alias fp_glSecondaryColor3iv = void function(const(GLint)*); +alias fp_glSecondaryColor3s = void function(GLshort, GLshort, GLshort); +alias fp_glSecondaryColor3sv = void function(const(GLshort)*); +alias fp_glSecondaryColor3ub = void function(GLubyte, GLubyte, GLubyte); +alias fp_glSecondaryColor3ubv = void function(const(GLubyte)*); +alias fp_glSecondaryColor3ui = void function(GLuint, GLuint, GLuint); +alias fp_glSecondaryColor3uiv = void function(const(GLuint)*); +alias fp_glSecondaryColor3us = void function(GLushort, GLushort, GLushort); +alias fp_glSecondaryColor3usv = void function(const(GLushort)*); +alias fp_glSecondaryColorPointer = void function(GLint, GLenum, GLsizei, const(void)*); +alias fp_glWindowPos2d = void function(GLdouble, GLdouble); +alias fp_glWindowPos2dv = void function(const(GLdouble)*); +alias fp_glWindowPos2f = void function(GLfloat, GLfloat); +alias fp_glWindowPos2fv = void function(const(GLfloat)*); +alias fp_glWindowPos2i = void function(GLint, GLint); +alias fp_glWindowPos2iv = void function(const(GLint)*); +alias fp_glWindowPos2s = void function(GLshort, GLshort); +alias fp_glWindowPos2sv = void function(const(GLshort)*); +alias fp_glWindowPos3d = void function(GLdouble, GLdouble, GLdouble); +alias fp_glWindowPos3dv = void function(const(GLdouble)*); +alias fp_glWindowPos3f = void function(GLfloat, GLfloat, GLfloat); +alias fp_glWindowPos3fv = void function(const(GLfloat)*); +alias fp_glWindowPos3i = void function(GLint, GLint, GLint); +alias fp_glWindowPos3iv = void function(const(GLint)*); +alias fp_glWindowPos3s = void function(GLshort, GLshort, GLshort); +alias fp_glWindowPos3sv = void function(const(GLshort)*); +alias fp_glBlendColor = void function(GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glBlendEquation = void function(GLenum); +alias fp_glGenQueries = void function(GLsizei, GLuint*); +alias fp_glDeleteQueries = void function(GLsizei, const(GLuint)*); +alias fp_glIsQuery = GLboolean function(GLuint); +alias fp_glBeginQuery = void function(GLenum, GLuint); +alias fp_glEndQuery = void function(GLenum); +alias fp_glGetQueryiv = void function(GLenum, GLenum, GLint*); +alias fp_glGetQueryObjectiv = void function(GLuint, GLenum, GLint*); +alias fp_glGetQueryObjectuiv = void function(GLuint, GLenum, GLuint*); +alias fp_glBindBuffer = void function(GLenum, GLuint); +alias fp_glDeleteBuffers = void function(GLsizei, const(GLuint)*); +alias fp_glGenBuffers = void function(GLsizei, GLuint*); +alias fp_glIsBuffer = GLboolean function(GLuint); +alias fp_glBufferData = void function(GLenum, GLsizeiptr, const(void)*, GLenum); +alias fp_glBufferSubData = void function(GLenum, GLintptr, GLsizeiptr, const(void)*); +alias fp_glGetBufferSubData = void function(GLenum, GLintptr, GLsizeiptr, void*); +alias fp_glMapBuffer = void* function(GLenum, GLenum); +alias fp_glUnmapBuffer = GLboolean function(GLenum); +alias fp_glGetBufferParameteriv = void function(GLenum, GLenum, GLint*); +alias fp_glGetBufferPointerv = void function(GLenum, GLenum, void**); +alias fp_glBlendEquationSeparate = void function(GLenum, GLenum); +alias fp_glDrawBuffers = void function(GLsizei, const(GLenum)*); +alias fp_glStencilOpSeparate = void function(GLenum, GLenum, GLenum, GLenum); +alias fp_glStencilFuncSeparate = void function(GLenum, GLenum, GLint, GLuint); +alias fp_glStencilMaskSeparate = void function(GLenum, GLuint); +alias fp_glAttachShader = void function(GLuint, GLuint); +alias fp_glBindAttribLocation = void function(GLuint, GLuint, const(GLchar)*); +alias fp_glCompileShader = void function(GLuint); +alias fp_glCreateProgram = GLuint function(); +alias fp_glCreateShader = GLuint function(GLenum); +alias fp_glDeleteProgram = void function(GLuint); +alias fp_glDeleteShader = void function(GLuint); +alias fp_glDetachShader = void function(GLuint, GLuint); +alias fp_glDisableVertexAttribArray = void function(GLuint); +alias fp_glEnableVertexAttribArray = void function(GLuint); +alias fp_glGetActiveAttrib = void function(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); +alias fp_glGetActiveUniform = void function(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); +alias fp_glGetAttachedShaders = void function(GLuint, GLsizei, GLsizei*, GLuint*); +alias fp_glGetAttribLocation = GLint function(GLuint, const(GLchar)*); +alias fp_glGetProgramiv = void function(GLuint, GLenum, GLint*); +alias fp_glGetProgramInfoLog = void function(GLuint, GLsizei, GLsizei*, GLchar*); +alias fp_glGetShaderiv = void function(GLuint, GLenum, GLint*); +alias fp_glGetShaderInfoLog = void function(GLuint, GLsizei, GLsizei*, GLchar*); +alias fp_glGetShaderSource = void function(GLuint, GLsizei, GLsizei*, GLchar*); +alias fp_glGetUniformLocation = GLint function(GLuint, const(GLchar)*); +alias fp_glGetUniformfv = void function(GLuint, GLint, GLfloat*); +alias fp_glGetUniformiv = void function(GLuint, GLint, GLint*); +alias fp_glGetVertexAttribdv = void function(GLuint, GLenum, GLdouble*); +alias fp_glGetVertexAttribfv = void function(GLuint, GLenum, GLfloat*); +alias fp_glGetVertexAttribiv = void function(GLuint, GLenum, GLint*); +alias fp_glGetVertexAttribPointerv = void function(GLuint, GLenum, void**); +alias fp_glIsProgram = GLboolean function(GLuint); +alias fp_glIsShader = GLboolean function(GLuint); +alias fp_glLinkProgram = void function(GLuint); +alias fp_glShaderSource = void function(GLuint, GLsizei, const(GLchar*)*, const(GLint)*); +alias fp_glUseProgram = void function(GLuint); +alias fp_glUniform1f = void function(GLint, GLfloat); +alias fp_glUniform2f = void function(GLint, GLfloat, GLfloat); +alias fp_glUniform3f = void function(GLint, GLfloat, GLfloat, GLfloat); +alias fp_glUniform4f = void function(GLint, GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glUniform1i = void function(GLint, GLint); +alias fp_glUniform2i = void function(GLint, GLint, GLint); +alias fp_glUniform3i = void function(GLint, GLint, GLint, GLint); +alias fp_glUniform4i = void function(GLint, GLint, GLint, GLint, GLint); +alias fp_glUniform1fv = void function(GLint, GLsizei, const(GLfloat)*); +alias fp_glUniform2fv = void function(GLint, GLsizei, const(GLfloat)*); +alias fp_glUniform3fv = void function(GLint, GLsizei, const(GLfloat)*); +alias fp_glUniform4fv = void function(GLint, GLsizei, const(GLfloat)*); +alias fp_glUniform1iv = void function(GLint, GLsizei, const(GLint)*); +alias fp_glUniform2iv = void function(GLint, GLsizei, const(GLint)*); +alias fp_glUniform3iv = void function(GLint, GLsizei, const(GLint)*); +alias fp_glUniform4iv = void function(GLint, GLsizei, const(GLint)*); +alias fp_glUniformMatrix2fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix3fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix4fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glValidateProgram = void function(GLuint); +alias fp_glVertexAttrib1d = void function(GLuint, GLdouble); +alias fp_glVertexAttrib1dv = void function(GLuint, const(GLdouble)*); +alias fp_glVertexAttrib1f = void function(GLuint, GLfloat); +alias fp_glVertexAttrib1fv = void function(GLuint, const(GLfloat)*); +alias fp_glVertexAttrib1s = void function(GLuint, GLshort); +alias fp_glVertexAttrib1sv = void function(GLuint, const(GLshort)*); +alias fp_glVertexAttrib2d = void function(GLuint, GLdouble, GLdouble); +alias fp_glVertexAttrib2dv = void function(GLuint, const(GLdouble)*); +alias fp_glVertexAttrib2f = void function(GLuint, GLfloat, GLfloat); +alias fp_glVertexAttrib2fv = void function(GLuint, const(GLfloat)*); +alias fp_glVertexAttrib2s = void function(GLuint, GLshort, GLshort); +alias fp_glVertexAttrib2sv = void function(GLuint, const(GLshort)*); +alias fp_glVertexAttrib3d = void function(GLuint, GLdouble, GLdouble, GLdouble); +alias fp_glVertexAttrib3dv = void function(GLuint, const(GLdouble)*); +alias fp_glVertexAttrib3f = void function(GLuint, GLfloat, GLfloat, GLfloat); +alias fp_glVertexAttrib3fv = void function(GLuint, const(GLfloat)*); +alias fp_glVertexAttrib3s = void function(GLuint, GLshort, GLshort, GLshort); +alias fp_glVertexAttrib3sv = void function(GLuint, const(GLshort)*); +alias fp_glVertexAttrib4Nbv = void function(GLuint, const(GLbyte)*); +alias fp_glVertexAttrib4Niv = void function(GLuint, const(GLint)*); +alias fp_glVertexAttrib4Nsv = void function(GLuint, const(GLshort)*); +alias fp_glVertexAttrib4Nub = void function(GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +alias fp_glVertexAttrib4Nubv = void function(GLuint, const(GLubyte)*); +alias fp_glVertexAttrib4Nuiv = void function(GLuint, const(GLuint)*); +alias fp_glVertexAttrib4Nusv = void function(GLuint, const(GLushort)*); +alias fp_glVertexAttrib4bv = void function(GLuint, const(GLbyte)*); +alias fp_glVertexAttrib4d = void function(GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +alias fp_glVertexAttrib4dv = void function(GLuint, const(GLdouble)*); +alias fp_glVertexAttrib4f = void function(GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +alias fp_glVertexAttrib4fv = void function(GLuint, const(GLfloat)*); +alias fp_glVertexAttrib4iv = void function(GLuint, const(GLint)*); +alias fp_glVertexAttrib4s = void function(GLuint, GLshort, GLshort, GLshort, GLshort); +alias fp_glVertexAttrib4sv = void function(GLuint, const(GLshort)*); +alias fp_glVertexAttrib4ubv = void function(GLuint, const(GLubyte)*); +alias fp_glVertexAttrib4uiv = void function(GLuint, const(GLuint)*); +alias fp_glVertexAttrib4usv = void function(GLuint, const(GLushort)*); +alias fp_glVertexAttribPointer = void function(GLuint, GLint, GLenum, GLboolean, GLsizei, const(void)*); +alias fp_glUniformMatrix2x3fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix3x2fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix2x4fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix4x2fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix3x4fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glUniformMatrix4x3fv = void function(GLint, GLsizei, GLboolean, const(GLfloat)*); +alias fp_glColorMaski = void function(GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +alias fp_glGetBooleani_v = void function(GLenum, GLuint, GLboolean*); +alias fp_glGetIntegeri_v = void function(GLenum, GLuint, GLint*); +alias fp_glEnablei = void function(GLenum, GLuint); +alias fp_glDisablei = void function(GLenum, GLuint); +alias fp_glIsEnabledi = GLboolean function(GLenum, GLuint); +alias fp_glBeginTransformFeedback = void function(GLenum); +alias fp_glEndTransformFeedback = void function(); +alias fp_glBindBufferRange = void function(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +alias fp_glBindBufferBase = void function(GLenum, GLuint, GLuint); +alias fp_glTransformFeedbackVaryings = void function(GLuint, GLsizei, const(GLchar*)*, GLenum); +alias fp_glGetTransformFeedbackVarying = void function(GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*); +alias fp_glClampColor = void function(GLenum, GLenum); +alias fp_glBeginConditionalRender = void function(GLuint, GLenum); +alias fp_glEndConditionalRender = void function(); +alias fp_glVertexAttribIPointer = void function(GLuint, GLint, GLenum, GLsizei, const(void)*); +alias fp_glGetVertexAttribIiv = void function(GLuint, GLenum, GLint*); +alias fp_glGetVertexAttribIuiv = void function(GLuint, GLenum, GLuint*); +alias fp_glVertexAttribI1i = void function(GLuint, GLint); +alias fp_glVertexAttribI2i = void function(GLuint, GLint, GLint); +alias fp_glVertexAttribI3i = void function(GLuint, GLint, GLint, GLint); +alias fp_glVertexAttribI4i = void function(GLuint, GLint, GLint, GLint, GLint); +alias fp_glVertexAttribI1ui = void function(GLuint, GLuint); +alias fp_glVertexAttribI2ui = void function(GLuint, GLuint, GLuint); +alias fp_glVertexAttribI3ui = void function(GLuint, GLuint, GLuint, GLuint); +alias fp_glVertexAttribI4ui = void function(GLuint, GLuint, GLuint, GLuint, GLuint); +alias fp_glVertexAttribI1iv = void function(GLuint, const(GLint)*); +alias fp_glVertexAttribI2iv = void function(GLuint, const(GLint)*); +alias fp_glVertexAttribI3iv = void function(GLuint, const(GLint)*); +alias fp_glVertexAttribI4iv = void function(GLuint, const(GLint)*); +alias fp_glVertexAttribI1uiv = void function(GLuint, const(GLuint)*); +alias fp_glVertexAttribI2uiv = void function(GLuint, const(GLuint)*); +alias fp_glVertexAttribI3uiv = void function(GLuint, const(GLuint)*); +alias fp_glVertexAttribI4uiv = void function(GLuint, const(GLuint)*); +alias fp_glVertexAttribI4bv = void function(GLuint, const(GLbyte)*); +alias fp_glVertexAttribI4sv = void function(GLuint, const(GLshort)*); +alias fp_glVertexAttribI4ubv = void function(GLuint, const(GLubyte)*); +alias fp_glVertexAttribI4usv = void function(GLuint, const(GLushort)*); +alias fp_glGetUniformuiv = void function(GLuint, GLint, GLuint*); +alias fp_glBindFragDataLocation = void function(GLuint, GLuint, const(GLchar)*); +alias fp_glGetFragDataLocation = GLint function(GLuint, const(GLchar)*); +alias fp_glUniform1ui = void function(GLint, GLuint); +alias fp_glUniform2ui = void function(GLint, GLuint, GLuint); +alias fp_glUniform3ui = void function(GLint, GLuint, GLuint, GLuint); +alias fp_glUniform4ui = void function(GLint, GLuint, GLuint, GLuint, GLuint); +alias fp_glUniform1uiv = void function(GLint, GLsizei, const(GLuint)*); +alias fp_glUniform2uiv = void function(GLint, GLsizei, const(GLuint)*); +alias fp_glUniform3uiv = void function(GLint, GLsizei, const(GLuint)*); +alias fp_glUniform4uiv = void function(GLint, GLsizei, const(GLuint)*); +alias fp_glTexParameterIiv = void function(GLenum, GLenum, const(GLint)*); +alias fp_glTexParameterIuiv = void function(GLenum, GLenum, const(GLuint)*); +alias fp_glGetTexParameterIiv = void function(GLenum, GLenum, GLint*); +alias fp_glGetTexParameterIuiv = void function(GLenum, GLenum, GLuint*); +alias fp_glClearBufferiv = void function(GLenum, GLint, const(GLint)*); +alias fp_glClearBufferuiv = void function(GLenum, GLint, const(GLuint)*); +alias fp_glClearBufferfv = void function(GLenum, GLint, const(GLfloat)*); +alias fp_glClearBufferfi = void function(GLenum, GLint, GLfloat, GLint); +alias fp_glGetStringi = const(GLubyte)* function(GLenum, GLuint); +alias fp_glIsRenderbuffer = GLboolean function(GLuint); +alias fp_glBindRenderbuffer = void function(GLenum, GLuint); +alias fp_glDeleteRenderbuffers = void function(GLsizei, const(GLuint)*); +alias fp_glGenRenderbuffers = void function(GLsizei, GLuint*); +alias fp_glRenderbufferStorage = void function(GLenum, GLenum, GLsizei, GLsizei); +alias fp_glGetRenderbufferParameteriv = void function(GLenum, GLenum, GLint*); +alias fp_glIsFramebuffer = GLboolean function(GLuint); +alias fp_glBindFramebuffer = void function(GLenum, GLuint); +alias fp_glDeleteFramebuffers = void function(GLsizei, const(GLuint)*); +alias fp_glGenFramebuffers = void function(GLsizei, GLuint*); +alias fp_glCheckFramebufferStatus = GLenum function(GLenum); +alias fp_glFramebufferTexture1D = void function(GLenum, GLenum, GLenum, GLuint, GLint); +alias fp_glFramebufferTexture2D = void function(GLenum, GLenum, GLenum, GLuint, GLint); +alias fp_glFramebufferTexture3D = void function(GLenum, GLenum, GLenum, GLuint, GLint, GLint); +alias fp_glFramebufferRenderbuffer = void function(GLenum, GLenum, GLenum, GLuint); +alias fp_glGetFramebufferAttachmentParameteriv = void function(GLenum, GLenum, GLenum, GLint*); +alias fp_glGenerateMipmap = void function(GLenum); +alias fp_glBlitFramebuffer = void function(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); +alias fp_glRenderbufferStorageMultisample = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei); +alias fp_glFramebufferTextureLayer = void function(GLenum, GLenum, GLuint, GLint, GLint); +alias fp_glMapBufferRange = void* function(GLenum, GLintptr, GLsizeiptr, GLbitfield); +alias fp_glFlushMappedBufferRange = void function(GLenum, GLintptr, GLsizeiptr); +alias fp_glBindVertexArray = void function(GLuint); +alias fp_glDeleteVertexArrays = void function(GLsizei, const(GLuint)*); +alias fp_glGenVertexArrays = void function(GLsizei, GLuint*); +alias fp_glIsVertexArray = GLboolean function(GLuint); +alias fp_glDrawArraysInstanced = void function(GLenum, GLint, GLsizei, GLsizei); +alias fp_glDrawElementsInstanced = void function(GLenum, GLsizei, GLenum, const(void)*, GLsizei); +alias fp_glTexBuffer = void function(GLenum, GLenum, GLuint); +alias fp_glPrimitiveRestartIndex = void function(GLuint); +alias fp_glCopyBufferSubData = void function(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); +alias fp_glGetUniformIndices = void function(GLuint, GLsizei, const(GLchar*)*, GLuint*); +alias fp_glGetActiveUniformsiv = void function(GLuint, GLsizei, const(GLuint)*, GLenum, GLint*); +alias fp_glGetActiveUniformName = void function(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); +alias fp_glGetUniformBlockIndex = GLuint function(GLuint, const(GLchar)*); +alias fp_glGetActiveUniformBlockiv = void function(GLuint, GLuint, GLenum, GLint*); +alias fp_glGetActiveUniformBlockName = void function(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); +alias fp_glUniformBlockBinding = void function(GLuint, GLuint, GLuint); +alias fp_glDrawElementsBaseVertex = void function(GLenum, GLsizei, GLenum, const(void)*, GLint); +alias fp_glDrawRangeElementsBaseVertex = void function(GLenum, GLuint, GLuint, GLsizei, GLenum, const(void)*, GLint); +alias fp_glDrawElementsInstancedBaseVertex = void function(GLenum, GLsizei, GLenum, const(void)*, GLsizei, GLint); +alias fp_glMultiDrawElementsBaseVertex = void function(GLenum, const(GLsizei)*, GLenum, const(void*)*, GLsizei, const(GLint)*); +alias fp_glProvokingVertex = void function(GLenum); +alias fp_glFenceSync = GLsync function(GLenum, GLbitfield); +alias fp_glIsSync = GLboolean function(GLsync); +alias fp_glDeleteSync = void function(GLsync); +alias fp_glClientWaitSync = GLenum function(GLsync, GLbitfield, GLuint64); +alias fp_glWaitSync = void function(GLsync, GLbitfield, GLuint64); +alias fp_glGetInteger64v = void function(GLenum, GLint64*); +alias fp_glGetSynciv = void function(GLsync, GLenum, GLsizei, GLsizei*, GLint*); +alias fp_glGetInteger64i_v = void function(GLenum, GLuint, GLint64*); +alias fp_glGetBufferParameteri64v = void function(GLenum, GLenum, GLint64*); +alias fp_glFramebufferTexture = void function(GLenum, GLenum, GLuint, GLint); +alias fp_glTexImage2DMultisample = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); +alias fp_glTexImage3DMultisample = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean); +alias fp_glGetMultisamplefv = void function(GLenum, GLuint, GLfloat*); +alias fp_glSampleMaski = void function(GLuint, GLbitfield); +alias fp_glBindFragDataLocationIndexed = void function(GLuint, GLuint, GLuint, const(GLchar)*); +alias fp_glGetFragDataIndex = GLint function(GLuint, const(GLchar)*); +alias fp_glGenSamplers = void function(GLsizei, GLuint*); +alias fp_glDeleteSamplers = void function(GLsizei, const(GLuint)*); +alias fp_glIsSampler = GLboolean function(GLuint); +alias fp_glBindSampler = void function(GLuint, GLuint); +alias fp_glSamplerParameteri = void function(GLuint, GLenum, GLint); +alias fp_glSamplerParameteriv = void function(GLuint, GLenum, const(GLint)*); +alias fp_glSamplerParameterf = void function(GLuint, GLenum, GLfloat); +alias fp_glSamplerParameterfv = void function(GLuint, GLenum, const(GLfloat)*); +alias fp_glSamplerParameterIiv = void function(GLuint, GLenum, const(GLint)*); +alias fp_glSamplerParameterIuiv = void function(GLuint, GLenum, const(GLuint)*); +alias fp_glGetSamplerParameteriv = void function(GLuint, GLenum, GLint*); +alias fp_glGetSamplerParameterIiv = void function(GLuint, GLenum, GLint*); +alias fp_glGetSamplerParameterfv = void function(GLuint, GLenum, GLfloat*); +alias fp_glGetSamplerParameterIuiv = void function(GLuint, GLenum, GLuint*); +alias fp_glQueryCounter = void function(GLuint, GLenum); +alias fp_glGetQueryObjecti64v = void function(GLuint, GLenum, GLint64*); +alias fp_glGetQueryObjectui64v = void function(GLuint, GLenum, GLuint64*); +alias fp_glVertexAttribDivisor = void function(GLuint, GLuint); +alias fp_glVertexAttribP1ui = void function(GLuint, GLenum, GLboolean, GLuint); +alias fp_glVertexAttribP1uiv = void function(GLuint, GLenum, GLboolean, const(GLuint)*); +alias fp_glVertexAttribP2ui = void function(GLuint, GLenum, GLboolean, GLuint); +alias fp_glVertexAttribP2uiv = void function(GLuint, GLenum, GLboolean, const(GLuint)*); +alias fp_glVertexAttribP3ui = void function(GLuint, GLenum, GLboolean, GLuint); +alias fp_glVertexAttribP3uiv = void function(GLuint, GLenum, GLboolean, const(GLuint)*); +alias fp_glVertexAttribP4ui = void function(GLuint, GLenum, GLboolean, GLuint); +alias fp_glVertexAttribP4uiv = void function(GLuint, GLenum, GLboolean, const(GLuint)*); +alias fp_glVertexP2ui = void function(GLenum, GLuint); +alias fp_glVertexP2uiv = void function(GLenum, const(GLuint)*); +alias fp_glVertexP3ui = void function(GLenum, GLuint); +alias fp_glVertexP3uiv = void function(GLenum, const(GLuint)*); +alias fp_glVertexP4ui = void function(GLenum, GLuint); +alias fp_glVertexP4uiv = void function(GLenum, const(GLuint)*); +alias fp_glTexCoordP1ui = void function(GLenum, GLuint); +alias fp_glTexCoordP1uiv = void function(GLenum, const(GLuint)*); +alias fp_glTexCoordP2ui = void function(GLenum, GLuint); +alias fp_glTexCoordP2uiv = void function(GLenum, const(GLuint)*); +alias fp_glTexCoordP3ui = void function(GLenum, GLuint); +alias fp_glTexCoordP3uiv = void function(GLenum, const(GLuint)*); +alias fp_glTexCoordP4ui = void function(GLenum, GLuint); +alias fp_glTexCoordP4uiv = void function(GLenum, const(GLuint)*); +alias fp_glMultiTexCoordP1ui = void function(GLenum, GLenum, GLuint); +alias fp_glMultiTexCoordP1uiv = void function(GLenum, GLenum, const(GLuint)*); +alias fp_glMultiTexCoordP2ui = void function(GLenum, GLenum, GLuint); +alias fp_glMultiTexCoordP2uiv = void function(GLenum, GLenum, const(GLuint)*); +alias fp_glMultiTexCoordP3ui = void function(GLenum, GLenum, GLuint); +alias fp_glMultiTexCoordP3uiv = void function(GLenum, GLenum, const(GLuint)*); +alias fp_glMultiTexCoordP4ui = void function(GLenum, GLenum, GLuint); +alias fp_glMultiTexCoordP4uiv = void function(GLenum, GLenum, const(GLuint)*); +alias fp_glNormalP3ui = void function(GLenum, GLuint); +alias fp_glNormalP3uiv = void function(GLenum, const(GLuint)*); +alias fp_glColorP3ui = void function(GLenum, GLuint); +alias fp_glColorP3uiv = void function(GLenum, const(GLuint)*); +alias fp_glColorP4ui = void function(GLenum, GLuint); +alias fp_glColorP4uiv = void function(GLenum, const(GLuint)*); +alias fp_glSecondaryColorP3ui = void function(GLenum, GLuint); +alias fp_glSecondaryColorP3uiv = void function(GLenum, const(GLuint)*); +alias fp_glClearDepthf = void function(GLfloat); +alias fp_glDepthRangef = void function(GLfloat, GLfloat); +alias fp_glGetShaderPrecisionFormat = void function(GLenum, GLenum, GLint*, GLint*); +alias fp_glReleaseShaderCompiler = void function(); +alias fp_glShaderBinary = void function(GLsizei, const(GLuint)*, GLenum, const(void)*, GLsizei); +alias fp_glBindTransformFeedback = void function(GLenum, GLuint); +alias fp_glDeleteTransformFeedbacks = void function(GLsizei, const(GLuint)*); +alias fp_glGenTransformFeedbacks = void function(GLsizei, GLuint*); +alias fp_glIsTransformFeedback = GLboolean function(GLuint); +alias fp_glPauseTransformFeedback = void function(); +alias fp_glResumeTransformFeedback = void function(); +alias fp_glGetProgramBinary = void function(GLuint, GLsizei, GLsizei*, GLenum*, void*); +alias fp_glProgramBinary = void function(GLuint, GLenum, const(void)*, GLsizei); +alias fp_glProgramParameteri = void function(GLuint, GLenum, GLint); +alias fp_glInvalidateFramebuffer = void function(GLenum, GLsizei, const(GLenum)*); +alias fp_glInvalidateSubFramebuffer = void function(GLenum, GLsizei, const(GLenum)*, GLint, GLint, GLsizei, GLsizei); +alias fp_glTexStorage2D = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei); +alias fp_glTexStorage3D = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei); +alias fp_glGetInternalformativ = void function(GLenum, GLenum, GLenum, GLsizei, GLint*); +} +__gshared { +fp_glCopyTexImage1D glCopyTexImage1D; +fp_glVertexAttribI3ui glVertexAttribI3ui; +fp_glWindowPos2s glWindowPos2s; +fp_glWindowPos2i glWindowPos2i; +fp_glWindowPos2f glWindowPos2f; +fp_glWindowPos2d glWindowPos2d; +fp_glVertex2fv glVertex2fv; +fp_glIndexi glIndexi; +fp_glFramebufferRenderbuffer glFramebufferRenderbuffer; +fp_glRectdv glRectdv; +fp_glCompressedTexSubImage3D glCompressedTexSubImage3D; +fp_glEvalCoord2d glEvalCoord2d; +fp_glEvalCoord2f glEvalCoord2f; +fp_glIndexd glIndexd; +fp_glVertexAttrib1sv glVertexAttrib1sv; +fp_glIndexf glIndexf; +fp_glBindSampler glBindSampler; +fp_glLineWidth glLineWidth; +fp_glColorP3uiv glColorP3uiv; +fp_glGetIntegeri_v glGetIntegeri_v; +fp_glGetMapfv glGetMapfv; +fp_glIndexs glIndexs; +fp_glCompileShader glCompileShader; +fp_glGetTransformFeedbackVarying glGetTransformFeedbackVarying; +fp_glWindowPos2iv glWindowPos2iv; +fp_glIndexfv glIndexfv; +fp_glFogiv glFogiv; +fp_glStencilMaskSeparate glStencilMaskSeparate; +fp_glRasterPos2fv glRasterPos2fv; +fp_glLightModeliv glLightModeliv; +fp_glDepthRangef glDepthRangef; +fp_glColor4ui glColor4ui; +fp_glSecondaryColor3fv glSecondaryColor3fv; +fp_glMultiTexCoordP3ui glMultiTexCoordP3ui; +fp_glFogfv glFogfv; +fp_glVertexP4ui glVertexP4ui; +fp_glEnablei glEnablei; +fp_glVertex4iv glVertex4iv; +fp_glEvalCoord1fv glEvalCoord1fv; +fp_glWindowPos2sv glWindowPos2sv; +fp_glVertexAttribP4ui glVertexAttribP4ui; +fp_glCreateShader glCreateShader; +fp_glIsBuffer glIsBuffer; +fp_glGetMultisamplefv glGetMultisamplefv; +fp_glGenRenderbuffers glGenRenderbuffers; +fp_glCopyTexSubImage2D glCopyTexSubImage2D; +fp_glCompressedTexImage2D glCompressedTexImage2D; +fp_glVertexAttrib1f glVertexAttrib1f; +fp_glBlendFuncSeparate glBlendFuncSeparate; +fp_glVertex4fv glVertex4fv; +fp_glBindTexture glBindTexture; +fp_glVertexAttrib1s glVertexAttrib1s; +fp_glTexCoord2fv glTexCoord2fv; +fp_glSampleMaski glSampleMaski; +fp_glVertexP2ui glVertexP2ui; +fp_glDrawRangeElementsBaseVertex glDrawRangeElementsBaseVertex; +fp_glTexCoord4fv glTexCoord4fv; +fp_glUniformMatrix3x2fv glUniformMatrix3x2fv; +fp_glPointSize glPointSize; +fp_glVertexAttrib2dv glVertexAttrib2dv; +fp_glDeleteProgram glDeleteProgram; +fp_glColor4bv glColor4bv; +fp_glRasterPos2f glRasterPos2f; +fp_glRasterPos2d glRasterPos2d; +fp_glLoadIdentity glLoadIdentity; +fp_glRasterPos2i glRasterPos2i; +fp_glRenderbufferStorage glRenderbufferStorage; +fp_glUniformMatrix4x3fv glUniformMatrix4x3fv; +fp_glColor3b glColor3b; +fp_glClearBufferfv glClearBufferfv; +fp_glEdgeFlag glEdgeFlag; +fp_glDeleteSamplers glDeleteSamplers; +fp_glVertex3d glVertex3d; +fp_glVertex3f glVertex3f; +fp_glVertex3i glVertex3i; +fp_glColor3i glColor3i; +fp_glUniform3f glUniform3f; +fp_glVertexAttrib4ubv glVertexAttrib4ubv; +fp_glColor3s glColor3s; +fp_glVertex3s glVertex3s; +fp_glTexCoordP2ui glTexCoordP2ui; +fp_glColorMaski glColorMaski; +fp_glClearBufferfi glClearBufferfi; +fp_glTexCoord1iv glTexCoord1iv; +fp_glBlitFramebuffer glBlitFramebuffer; +fp_glPauseTransformFeedback glPauseTransformFeedback; +fp_glMultiTexCoordP2ui glMultiTexCoordP2ui; +fp_glGetSamplerParameterIiv glGetSamplerParameterIiv; +fp_glGetFragDataIndex glGetFragDataIndex; +fp_glTexStorage3D glTexStorage3D; +fp_glVertexAttrib3f glVertexAttrib3f; +fp_glVertex2iv glVertex2iv; +fp_glColor3sv glColor3sv; +fp_glGetVertexAttribdv glGetVertexAttribdv; +fp_glUniformMatrix3x4fv glUniformMatrix3x4fv; +fp_glNormalPointer glNormalPointer; +fp_glTexCoordP3uiv glTexCoordP3uiv; +fp_glVertex4sv glVertex4sv; +fp_glPassThrough glPassThrough; +fp_glMultiTexCoordP4ui glMultiTexCoordP4ui; +fp_glFogi glFogi; +fp_glBegin glBegin; +fp_glEvalCoord2dv glEvalCoord2dv; +fp_glColor3ubv glColor3ubv; +fp_glVertexPointer glVertexPointer; +fp_glSecondaryColor3uiv glSecondaryColor3uiv; +fp_glDeleteFramebuffers glDeleteFramebuffers; +fp_glDrawArrays glDrawArrays; +fp_glUniform1ui glUniform1ui; +fp_glMultiTexCoord1d glMultiTexCoord1d; +fp_glMultiTexCoord1f glMultiTexCoord1f; +fp_glProgramParameteri glProgramParameteri; +fp_glLightfv glLightfv; +fp_glTexCoordP3ui glTexCoordP3ui; +fp_glVertexAttrib3d glVertexAttrib3d; +fp_glClear glClear; +fp_glMultiTexCoord1i glMultiTexCoord1i; +fp_glGetActiveUniformName glGetActiveUniformName; +fp_glMultiTexCoord1s glMultiTexCoord1s; +fp_glIsEnabled glIsEnabled; +fp_glStencilOp glStencilOp; +fp_glGetQueryObjectuiv glGetQueryObjectuiv; +fp_glFramebufferTexture2D glFramebufferTexture2D; +fp_glGetFramebufferAttachmentParameteriv glGetFramebufferAttachmentParameteriv; +fp_glTranslatef glTranslatef; +fp_glVertexAttrib4Nub glVertexAttrib4Nub; +fp_glTranslated glTranslated; +fp_glTexCoord3sv glTexCoord3sv; +fp_glGetFragDataLocation glGetFragDataLocation; +fp_glTexImage1D glTexImage1D; +fp_glVertexP3uiv glVertexP3uiv; +fp_glTexParameteriv glTexParameteriv; +fp_glSecondaryColor3bv glSecondaryColor3bv; +fp_glGetMaterialfv glGetMaterialfv; +fp_glGetTexImage glGetTexImage; +fp_glFogCoordfv glFogCoordfv; +fp_glPixelMapuiv glPixelMapuiv; +fp_glGetShaderInfoLog glGetShaderInfoLog; +fp_glGetQueryObjecti64v glGetQueryObjecti64v; +fp_glGenFramebuffers glGenFramebuffers; +fp_glIndexsv glIndexsv; +fp_glGetAttachedShaders glGetAttachedShaders; +fp_glIsRenderbuffer glIsRenderbuffer; +fp_glVertex3iv glVertex3iv; +fp_glBitmap glBitmap; +fp_glMateriali glMateriali; +fp_glIsVertexArray glIsVertexArray; +fp_glDisableVertexAttribArray glDisableVertexAttribArray; +fp_glGetQueryiv glGetQueryiv; +fp_glTexCoord4f glTexCoord4f; +fp_glTexCoord4d glTexCoord4d; +fp_glGetSamplerParameterfv glGetSamplerParameterfv; +fp_glTexCoord4i glTexCoord4i; +fp_glMaterialf glMaterialf; +fp_glTexCoord4s glTexCoord4s; +fp_glGetUniformIndices glGetUniformIndices; +fp_glIsShader glIsShader; +fp_glMultiTexCoord2s glMultiTexCoord2s; +fp_glVertexAttribI4ubv glVertexAttribI4ubv; +fp_glVertex3dv glVertex3dv; +fp_glGetInteger64v glGetInteger64v; +fp_glPointParameteriv glPointParameteriv; +fp_glEnable glEnable; +fp_glGetActiveUniformsiv glGetActiveUniformsiv; +fp_glColor4fv glColor4fv; +fp_glTexCoord1fv glTexCoord1fv; +fp_glTexCoord2sv glTexCoord2sv; +fp_glVertexAttrib4dv glVertexAttrib4dv; +fp_glMultiTexCoord1dv glMultiTexCoord1dv; +fp_glMultiTexCoord2i glMultiTexCoord2i; +fp_glTexCoord3fv glTexCoord3fv; +fp_glSecondaryColor3usv glSecondaryColor3usv; +fp_glTexGenf glTexGenf; +fp_glMultiTexCoordP3uiv glMultiTexCoordP3uiv; +fp_glVertexAttribP3ui glVertexAttribP3ui; +fp_glMultiTexCoordP1ui glMultiTexCoordP1ui; +fp_glGetPointerv glGetPointerv; +fp_glPolygonOffset glPolygonOffset; +fp_glGetUniformuiv glGetUniformuiv; +fp_glNormal3fv glNormal3fv; +fp_glSecondaryColor3s glSecondaryColor3s; +fp_glDepthRange glDepthRange; +fp_glFrustum glFrustum; +fp_glMultiTexCoord4sv glMultiTexCoord4sv; +fp_glDrawBuffer glDrawBuffer; +fp_glPushMatrix glPushMatrix; +fp_glRasterPos3fv glRasterPos3fv; +fp_glOrtho glOrtho; +fp_glDrawElementsInstanced glDrawElementsInstanced; +fp_glWindowPos3sv glWindowPos3sv; +fp_glClearIndex glClearIndex; +fp_glMap1d glMap1d; +fp_glMap1f glMap1f; +fp_glFlush glFlush; +fp_glGetRenderbufferParameteriv glGetRenderbufferParameteriv; +fp_glIndexiv glIndexiv; +fp_glRasterPos3sv glRasterPos3sv; +fp_glGetVertexAttribPointerv glGetVertexAttribPointerv; +fp_glPixelZoom glPixelZoom; +fp_glFenceSync glFenceSync; +fp_glDeleteVertexArrays glDeleteVertexArrays; +fp_glColorP3ui glColorP3ui; +fp_glVertexAttrib3sv glVertexAttrib3sv; +fp_glBeginConditionalRender glBeginConditionalRender; +fp_glGetShaderPrecisionFormat glGetShaderPrecisionFormat; +fp_glDrawElementsBaseVertex glDrawElementsBaseVertex; +fp_glGetTexLevelParameteriv glGetTexLevelParameteriv; +fp_glLighti glLighti; +fp_glMultiTexCoordP4uiv glMultiTexCoordP4uiv; +fp_glLightf glLightf; +fp_glGetAttribLocation glGetAttribLocation; +fp_glStencilFuncSeparate glStencilFuncSeparate; +fp_glGenSamplers glGenSamplers; +fp_glClampColor glClampColor; +fp_glUniform4iv glUniform4iv; +fp_glClearStencil glClearStencil; +fp_glTexCoordP1uiv glTexCoordP1uiv; +fp_glMultiTexCoord3fv glMultiTexCoord3fv; +fp_glGetPixelMapuiv glGetPixelMapuiv; +fp_glGenTextures glGenTextures; +fp_glTexCoord4iv glTexCoord4iv; +fp_glGetTexParameterIuiv glGetTexParameterIuiv; +fp_glIndexPointer glIndexPointer; +fp_glVertexAttrib4Nbv glVertexAttrib4Nbv; +fp_glIsSync glIsSync; +fp_glVertex2f glVertex2f; +fp_glVertex2d glVertex2d; +fp_glDeleteRenderbuffers glDeleteRenderbuffers; +fp_glUniform2i glUniform2i; +fp_glMapGrid2d glMapGrid2d; +fp_glMapGrid2f glMapGrid2f; +fp_glTexCoordP4ui glTexCoordP4ui; +fp_glVertex2i glVertex2i; +fp_glVertexAttribPointer glVertexAttribPointer; +fp_glFramebufferTextureLayer glFramebufferTextureLayer; +fp_glVertex2s glVertex2s; +fp_glNormal3bv glNormal3bv; +fp_glVertexAttrib4Nuiv glVertexAttrib4Nuiv; +fp_glFlushMappedBufferRange glFlushMappedBufferRange; +fp_glTexStorage2D glTexStorage2D; +fp_glSecondaryColor3sv glSecondaryColor3sv; +fp_glVertex3sv glVertex3sv; +fp_glGenQueries glGenQueries; +fp_glGetPixelMapfv glGetPixelMapfv; +fp_glTexEnvf glTexEnvf; +fp_glVertexAttribP1ui glVertexAttribP1ui; +fp_glTexSubImage3D glTexSubImage3D; +fp_glGetInteger64i_v glGetInteger64i_v; +fp_glFogCoordd glFogCoordd; +fp_glFogCoordf glFogCoordf; +fp_glCopyTexImage2D glCopyTexImage2D; +fp_glTexEnvi glTexEnvi; +fp_glMultiTexCoord1iv glMultiTexCoord1iv; +fp_glIsEnabledi glIsEnabledi; +fp_glSecondaryColorP3ui glSecondaryColorP3ui; +fp_glVertexAttribI2i glVertexAttribI2i; +fp_glBindFragDataLocationIndexed glBindFragDataLocationIndexed; +fp_glMultiTexCoord2dv glMultiTexCoord2dv; +fp_glUniform2iv glUniform2iv; +fp_glVertexAttrib1fv glVertexAttrib1fv; +fp_glGetInternalformativ glGetInternalformativ; +fp_glUniform4uiv glUniform4uiv; +fp_glMatrixMode glMatrixMode; +fp_glFeedbackBuffer glFeedbackBuffer; +fp_glGetMapiv glGetMapiv; +fp_glFramebufferTexture1D glFramebufferTexture1D; +fp_glGetShaderiv glGetShaderiv; +fp_glMultiTexCoord2d glMultiTexCoord2d; +fp_glMultiTexCoord2f glMultiTexCoord2f; +fp_glInvalidateFramebuffer glInvalidateFramebuffer; +fp_glBindFragDataLocation glBindFragDataLocation; +fp_glPrioritizeTextures glPrioritizeTextures; +fp_glCallList glCallList; +fp_glSecondaryColor3ubv glSecondaryColor3ubv; +fp_glGetDoublev glGetDoublev; +fp_glMultiTexCoord3iv glMultiTexCoord3iv; +fp_glVertexAttrib1d glVertexAttrib1d; +fp_glLightModelf glLightModelf; +fp_glGetUniformiv glGetUniformiv; +fp_glVertex2sv glVertex2sv; +fp_glLightModeli glLightModeli; +fp_glWindowPos3iv glWindowPos3iv; +fp_glMultiTexCoordP1uiv glMultiTexCoordP1uiv; +fp_glUniform3fv glUniform3fv; +fp_glPixelStorei glPixelStorei; +fp_glCallLists glCallLists; +fp_glInvalidateSubFramebuffer glInvalidateSubFramebuffer; +fp_glMapBuffer glMapBuffer; +fp_glSecondaryColor3d glSecondaryColor3d; +fp_glTexCoord3i glTexCoord3i; +fp_glMultiTexCoord4fv glMultiTexCoord4fv; +fp_glRasterPos3i glRasterPos3i; +fp_glSecondaryColor3b glSecondaryColor3b; +fp_glRasterPos3d glRasterPos3d; +fp_glRasterPos3f glRasterPos3f; +fp_glCompressedTexImage3D glCompressedTexImage3D; +fp_glTexCoord3f glTexCoord3f; +fp_glDeleteSync glDeleteSync; +fp_glTexCoord3d glTexCoord3d; +fp_glTexImage2DMultisample glTexImage2DMultisample; +fp_glGetVertexAttribiv glGetVertexAttribiv; +fp_glMultiDrawElements glMultiDrawElements; +fp_glVertexAttrib3fv glVertexAttrib3fv; +fp_glTexCoord3s glTexCoord3s; +fp_glUniform3iv glUniform3iv; +fp_glRasterPos3s glRasterPos3s; +fp_glPolygonMode glPolygonMode; +fp_glDrawBuffers glDrawBuffers; +fp_glGetActiveUniformBlockiv glGetActiveUniformBlockiv; +fp_glAreTexturesResident glAreTexturesResident; +fp_glIsList glIsList; +fp_glRasterPos2sv glRasterPos2sv; +fp_glRasterPos4sv glRasterPos4sv; +fp_glColor4s glColor4s; +fp_glGetProgramBinary glGetProgramBinary; +fp_glUseProgram glUseProgram; +fp_glLineStipple glLineStipple; +fp_glMultiTexCoord1sv glMultiTexCoord1sv; +fp_glGetProgramInfoLog glGetProgramInfoLog; +fp_glGetBufferParameteriv glGetBufferParameteriv; +fp_glMultiTexCoord2iv glMultiTexCoord2iv; +fp_glUniformMatrix2x4fv glUniformMatrix2x4fv; +fp_glBindVertexArray glBindVertexArray; +fp_glColor4b glColor4b; +fp_glSecondaryColor3f glSecondaryColor3f; +fp_glColor4f glColor4f; +fp_glColor4d glColor4d; +fp_glColor4i glColor4i; +fp_glSamplerParameterIiv glSamplerParameterIiv; +fp_glMultiDrawElementsBaseVertex glMultiDrawElementsBaseVertex; +fp_glRasterPos3iv glRasterPos3iv; +fp_glVertex2dv glVertex2dv; +fp_glTexCoord4sv glTexCoord4sv; +fp_glUniform2uiv glUniform2uiv; +fp_glCompressedTexSubImage1D glCompressedTexSubImage1D; +fp_glFinish glFinish; +fp_glGetBooleanv glGetBooleanv; +fp_glDeleteShader glDeleteShader; +fp_glDrawElements glDrawElements; +fp_glRasterPos2s glRasterPos2s; +fp_glGetMapdv glGetMapdv; +fp_glVertexAttrib4Nsv glVertexAttrib4Nsv; +fp_glMaterialfv glMaterialfv; +fp_glViewport glViewport; +fp_glUniform1uiv glUniform1uiv; +fp_glTransformFeedbackVaryings glTransformFeedbackVaryings; +fp_glIndexdv glIndexdv; +fp_glCopyTexSubImage3D glCopyTexSubImage3D; +fp_glTexCoord3iv glTexCoord3iv; +fp_glVertexAttribI3i glVertexAttribI3i; +fp_glClearDepth glClearDepth; +fp_glVertexAttribI4usv glVertexAttribI4usv; +fp_glTexParameterf glTexParameterf; +fp_glTexParameteri glTexParameteri; +fp_glGetShaderSource glGetShaderSource; +fp_glTexBuffer glTexBuffer; +fp_glPopName glPopName; +fp_glValidateProgram glValidateProgram; +fp_glPixelStoref glPixelStoref; +fp_glUniform3uiv glUniform3uiv; +fp_glRasterPos4fv glRasterPos4fv; +fp_glEvalCoord1dv glEvalCoord1dv; +fp_glMultiTexCoordP2uiv glMultiTexCoordP2uiv; +fp_glRecti glRecti; +fp_glColor4ub glColor4ub; +fp_glMultTransposeMatrixf glMultTransposeMatrixf; +fp_glRectf glRectf; +fp_glRectd glRectd; +fp_glNormal3sv glNormal3sv; +fp_glNewList glNewList; +fp_glColor4us glColor4us; +fp_glVertexAttribP1uiv glVertexAttribP1uiv; +fp_glLinkProgram glLinkProgram; +fp_glHint glHint; +fp_glRects glRects; +fp_glTexCoord2dv glTexCoord2dv; +fp_glRasterPos4iv glRasterPos4iv; +fp_glGetString glGetString; +fp_glVertexAttribP2uiv glVertexAttribP2uiv; +fp_glEdgeFlagv glEdgeFlagv; +fp_glDetachShader glDetachShader; +fp_glScalef glScalef; +fp_glEndQuery glEndQuery; +fp_glScaled glScaled; +fp_glEdgeFlagPointer glEdgeFlagPointer; +fp_glCopyPixels glCopyPixels; +fp_glVertexAttribI2ui glVertexAttribI2ui; +fp_glPopAttrib glPopAttrib; +fp_glDeleteTextures glDeleteTextures; +fp_glStencilOpSeparate glStencilOpSeparate; +fp_glDeleteQueries glDeleteQueries; +fp_glNormalP3uiv glNormalP3uiv; +fp_glVertexAttrib4f glVertexAttrib4f; +fp_glVertexAttrib4d glVertexAttrib4d; +fp_glInitNames glInitNames; +fp_glGetBufferParameteri64v glGetBufferParameteri64v; +fp_glColor3dv glColor3dv; +fp_glVertexAttribI1i glVertexAttribI1i; +fp_glGetTexParameteriv glGetTexParameteriv; +fp_glWaitSync glWaitSync; +fp_glVertexAttrib4s glVertexAttrib4s; +fp_glColorMaterial glColorMaterial; +fp_glSampleCoverage glSampleCoverage; +fp_glSamplerParameteri glSamplerParameteri; +fp_glSamplerParameterf glSamplerParameterf; +fp_glUniform1f glUniform1f; +fp_glGetVertexAttribfv glGetVertexAttribfv; +fp_glRenderMode glRenderMode; +fp_glGetCompressedTexImage glGetCompressedTexImage; +fp_glWindowPos2dv glWindowPos2dv; +fp_glUniform1i glUniform1i; +fp_glGetActiveAttrib glGetActiveAttrib; +fp_glUniform3i glUniform3i; +fp_glPixelTransferi glPixelTransferi; +fp_glTexSubImage2D glTexSubImage2D; +fp_glDisable glDisable; +fp_glLogicOp glLogicOp; +fp_glEvalPoint2 glEvalPoint2; +fp_glPixelTransferf glPixelTransferf; +fp_glSecondaryColor3i glSecondaryColor3i; +fp_glUniform4ui glUniform4ui; +fp_glColor3f glColor3f; +fp_glBindFramebuffer glBindFramebuffer; +fp_glGetTexEnvfv glGetTexEnvfv; +fp_glRectfv glRectfv; +fp_glCullFace glCullFace; +fp_glGetLightfv glGetLightfv; +fp_glColor3d glColor3d; +fp_glTexGend glTexGend; +fp_glTexGeni glTexGeni; +fp_glMultiTexCoord3s glMultiTexCoord3s; +fp_glGetStringi glGetStringi; +fp_glMultiTexCoord3i glMultiTexCoord3i; +fp_glMultiTexCoord3f glMultiTexCoord3f; +fp_glMultiTexCoord3d glMultiTexCoord3d; +fp_glAttachShader glAttachShader; +fp_glFogCoorddv glFogCoorddv; +fp_glUniformMatrix2x3fv glUniformMatrix2x3fv; +fp_glGetTexGenfv glGetTexGenfv; +fp_glQueryCounter glQueryCounter; +fp_glFogCoordPointer glFogCoordPointer; +fp_glProvokingVertex glProvokingVertex; +fp_glShaderBinary glShaderBinary; +fp_glFramebufferTexture3D glFramebufferTexture3D; +fp_glTexGeniv glTexGeniv; +fp_glRasterPos2dv glRasterPos2dv; +fp_glSecondaryColor3dv glSecondaryColor3dv; +fp_glClientActiveTexture glClientActiveTexture; +fp_glVertexAttribI4sv glVertexAttribI4sv; +fp_glSecondaryColor3us glSecondaryColor3us; +fp_glNormalP3ui glNormalP3ui; +fp_glTexEnvfv glTexEnvfv; +fp_glReadBuffer glReadBuffer; +fp_glTexParameterIuiv glTexParameterIuiv; +fp_glDrawArraysInstanced glDrawArraysInstanced; +fp_glGenerateMipmap glGenerateMipmap; +fp_glWindowPos3fv glWindowPos3fv; +fp_glLightModelfv glLightModelfv; +fp_glSamplerParameteriv glSamplerParameteriv; +fp_glDeleteLists glDeleteLists; +fp_glGetClipPlane glGetClipPlane; +fp_glVertex4dv glVertex4dv; +fp_glTexCoord2d glTexCoord2d; +fp_glPopMatrix glPopMatrix; +fp_glTexCoord2f glTexCoord2f; +fp_glColor4iv glColor4iv; +fp_glIndexubv glIndexubv; +fp_glUnmapBuffer glUnmapBuffer; +fp_glTexCoord2i glTexCoord2i; +fp_glRasterPos4d glRasterPos4d; +fp_glRasterPos4f glRasterPos4f; +fp_glVertexAttrib3s glVertexAttrib3s; +fp_glTexCoord2s glTexCoord2s; +fp_glBindRenderbuffer glBindRenderbuffer; +fp_glVertex3fv glVertex3fv; +fp_glTexCoord4dv glTexCoord4dv; +fp_glMaterialiv glMaterialiv; +fp_glVertexAttribP4uiv glVertexAttribP4uiv; +fp_glIsProgram glIsProgram; +fp_glVertexAttrib4bv glVertexAttrib4bv; +fp_glVertex4s glVertex4s; +fp_glVertexAttrib4fv glVertexAttrib4fv; +fp_glNormal3dv glNormal3dv; +fp_glReleaseShaderCompiler glReleaseShaderCompiler; +fp_glUniform4i glUniform4i; +fp_glActiveTexture glActiveTexture; +fp_glEnableVertexAttribArray glEnableVertexAttribArray; +fp_glRotated glRotated; +fp_glRotatef glRotatef; +fp_glVertex4i glVertex4i; +fp_glReadPixels glReadPixels; +fp_glVertexAttribI3iv glVertexAttribI3iv; +fp_glLoadName glLoadName; +fp_glUniform4f glUniform4f; +fp_glRenderbufferStorageMultisample glRenderbufferStorageMultisample; +fp_glGenVertexArrays glGenVertexArrays; +fp_glShadeModel glShadeModel; +fp_glMapGrid1d glMapGrid1d; +fp_glGetUniformfv glGetUniformfv; +fp_glMapGrid1f glMapGrid1f; +fp_glSamplerParameterfv glSamplerParameterfv; +fp_glDisableClientState glDisableClientState; +fp_glMultiTexCoord3sv glMultiTexCoord3sv; +fp_glDrawElementsInstancedBaseVertex glDrawElementsInstancedBaseVertex; +fp_glSecondaryColorPointer glSecondaryColorPointer; +fp_glAlphaFunc glAlphaFunc; +fp_glUniform1iv glUniform1iv; +fp_glMultiTexCoord4iv glMultiTexCoord4iv; +fp_glGetQueryObjectiv glGetQueryObjectiv; +fp_glStencilFunc glStencilFunc; +fp_glMultiTexCoord1fv glMultiTexCoord1fv; +fp_glUniformBlockBinding glUniformBlockBinding; +fp_glColor4uiv glColor4uiv; +fp_glRectiv glRectiv; +fp_glColorP4ui glColorP4ui; +fp_glRasterPos3dv glRasterPos3dv; +fp_glEvalMesh2 glEvalMesh2; +fp_glEvalMesh1 glEvalMesh1; +fp_glTexCoordPointer glTexCoordPointer; +fp_glVertexAttrib4Nubv glVertexAttrib4Nubv; +fp_glVertexAttribI4iv glVertexAttribI4iv; +fp_glEvalCoord2fv glEvalCoord2fv; +fp_glColor4ubv glColor4ubv; +fp_glLoadTransposeMatrixd glLoadTransposeMatrixd; +fp_glLoadTransposeMatrixf glLoadTransposeMatrixf; +fp_glVertexAttribI4i glVertexAttribI4i; +fp_glRasterPos2iv glRasterPos2iv; +fp_glGetBufferSubData glGetBufferSubData; +fp_glTexEnviv glTexEnviv; +fp_glBlendEquationSeparate glBlendEquationSeparate; +fp_glVertexAttribI1ui glVertexAttribI1ui; +fp_glGenBuffers glGenBuffers; +fp_glSelectBuffer glSelectBuffer; +fp_glVertexAttrib2sv glVertexAttrib2sv; +fp_glPushAttrib glPushAttrib; +fp_glVertexAttribIPointer glVertexAttribIPointer; +fp_glBlendFunc glBlendFunc; +fp_glCreateProgram glCreateProgram; +fp_glTexImage3D glTexImage3D; +fp_glIsFramebuffer glIsFramebuffer; +fp_glLightiv glLightiv; +fp_glPrimitiveRestartIndex glPrimitiveRestartIndex; +fp_glTexGenfv glTexGenfv; +fp_glEnd glEnd; +fp_glDeleteBuffers glDeleteBuffers; +fp_glScissor glScissor; +fp_glTexCoordP4uiv glTexCoordP4uiv; +fp_glClipPlane glClipPlane; +fp_glPushName glPushName; +fp_glTexGendv glTexGendv; +fp_glIndexub glIndexub; +fp_glVertexP2uiv glVertexP2uiv; +fp_glSecondaryColor3iv glSecondaryColor3iv; +fp_glRasterPos4i glRasterPos4i; +fp_glMultTransposeMatrixd glMultTransposeMatrixd; +fp_glClearColor glClearColor; +fp_glVertexAttrib4uiv glVertexAttrib4uiv; +fp_glNormal3s glNormal3s; +fp_glVertexAttrib4Niv glVertexAttrib4Niv; +fp_glClearBufferiv glClearBufferiv; +fp_glPointParameteri glPointParameteri; +fp_glColorP4uiv glColorP4uiv; +fp_glBlendColor glBlendColor; +fp_glWindowPos3d glWindowPos3d; +fp_glVertexAttribI2uiv glVertexAttribI2uiv; +fp_glSamplerParameterIuiv glSamplerParameterIuiv; +fp_glUniform3ui glUniform3ui; +fp_glColor4dv glColor4dv; +fp_glVertexAttribI4uiv glVertexAttribI4uiv; +fp_glPointParameterfv glPointParameterfv; +fp_glResumeTransformFeedback glResumeTransformFeedback; +fp_glUniform2fv glUniform2fv; +fp_glSecondaryColor3ub glSecondaryColor3ub; +fp_glSecondaryColor3ui glSecondaryColor3ui; +fp_glTexCoord3dv glTexCoord3dv; +fp_glGetSamplerParameterIuiv glGetSamplerParameterIuiv; +fp_glBindBufferRange glBindBufferRange; +fp_glNormal3iv glNormal3iv; +fp_glWindowPos3s glWindowPos3s; +fp_glPointParameterf glPointParameterf; +fp_glClearDepthf glClearDepthf; +fp_glGetVertexAttribIuiv glGetVertexAttribIuiv; +fp_glWindowPos3i glWindowPos3i; +fp_glMultiTexCoord4s glMultiTexCoord4s; +fp_glWindowPos3f glWindowPos3f; +fp_glGenTransformFeedbacks glGenTransformFeedbacks; +fp_glColor3us glColor3us; +fp_glColor3uiv glColor3uiv; +fp_glVertexAttrib4Nusv glVertexAttrib4Nusv; +fp_glGetLightiv glGetLightiv; +fp_glDepthFunc glDepthFunc; +fp_glCompressedTexSubImage2D glCompressedTexSubImage2D; +fp_glListBase glListBase; +fp_glMultiTexCoord4f glMultiTexCoord4f; +fp_glColor3ub glColor3ub; +fp_glMultiTexCoord4d glMultiTexCoord4d; +fp_glVertexAttribI4bv glVertexAttribI4bv; +fp_glGetTexParameterfv glGetTexParameterfv; +fp_glColor3ui glColor3ui; +fp_glMultiTexCoord4i glMultiTexCoord4i; +fp_glGetPolygonStipple glGetPolygonStipple; +fp_glClientWaitSync glClientWaitSync; +fp_glVertexAttribI4ui glVertexAttribI4ui; +fp_glMultiTexCoord4dv glMultiTexCoord4dv; +fp_glColorMask glColorMask; +fp_glTexParameterIiv glTexParameterIiv; +fp_glBlendEquation glBlendEquation; +fp_glGetUniformLocation glGetUniformLocation; +fp_glGetSamplerParameteriv glGetSamplerParameteriv; +fp_glRasterPos4s glRasterPos4s; +fp_glEndTransformFeedback glEndTransformFeedback; +fp_glVertexAttrib4usv glVertexAttrib4usv; +fp_glMultiTexCoord3dv glMultiTexCoord3dv; +fp_glColor4sv glColor4sv; +fp_glPopClientAttrib glPopClientAttrib; +fp_glBeginTransformFeedback glBeginTransformFeedback; +fp_glFogf glFogf; +fp_glVertexAttribI1iv glVertexAttribI1iv; +fp_glProgramBinary glProgramBinary; +fp_glIsSampler glIsSampler; +fp_glVertexP3ui glVertexP3ui; +fp_glVertexAttribDivisor glVertexAttribDivisor; +fp_glColor3iv glColor3iv; +fp_glCompressedTexImage1D glCompressedTexImage1D; +fp_glDeleteTransformFeedbacks glDeleteTransformFeedbacks; +fp_glCopyTexSubImage1D glCopyTexSubImage1D; +fp_glTexCoord1i glTexCoord1i; +fp_glCheckFramebufferStatus glCheckFramebufferStatus; +fp_glTexCoord1d glTexCoord1d; +fp_glTexCoord1f glTexCoord1f; +fp_glEndConditionalRender glEndConditionalRender; +fp_glEnableClientState glEnableClientState; +fp_glBindAttribLocation glBindAttribLocation; +fp_glUniformMatrix4x2fv glUniformMatrix4x2fv; +fp_glMultiTexCoord2sv glMultiTexCoord2sv; +fp_glVertexAttrib1dv glVertexAttrib1dv; +fp_glDrawRangeElements glDrawRangeElements; +fp_glTexCoord1s glTexCoord1s; +fp_glBindBufferBase glBindBufferBase; +fp_glBufferSubData glBufferSubData; +fp_glVertexAttrib4iv glVertexAttrib4iv; +fp_glGenLists glGenLists; +fp_glColor3bv glColor3bv; +fp_glMapBufferRange glMapBufferRange; +fp_glFramebufferTexture glFramebufferTexture; +fp_glGetTexGendv glGetTexGendv; +fp_glMultiDrawArrays glMultiDrawArrays; +fp_glEndList glEndList; +fp_glVertexP4uiv glVertexP4uiv; +fp_glUniform2ui glUniform2ui; +fp_glVertexAttribI2iv glVertexAttribI2iv; +fp_glColor3usv glColor3usv; +fp_glWindowPos2fv glWindowPos2fv; +fp_glDisablei glDisablei; +fp_glIndexMask glIndexMask; +fp_glPushClientAttrib glPushClientAttrib; +fp_glShaderSource glShaderSource; +fp_glGetActiveUniformBlockName glGetActiveUniformBlockName; +fp_glVertexAttribI3uiv glVertexAttribI3uiv; +fp_glIsTransformFeedback glIsTransformFeedback; +fp_glClearAccum glClearAccum; +fp_glGetSynciv glGetSynciv; +fp_glTexCoordP2uiv glTexCoordP2uiv; +fp_glUniform2f glUniform2f; +fp_glBeginQuery glBeginQuery; +fp_glGetUniformBlockIndex glGetUniformBlockIndex; +fp_glBindBuffer glBindBuffer; +fp_glMap2d glMap2d; +fp_glMap2f glMap2f; +fp_glVertex4d glVertex4d; +fp_glUniformMatrix2fv glUniformMatrix2fv; +fp_glTexCoord1sv glTexCoord1sv; +fp_glBufferData glBufferData; +fp_glEvalPoint1 glEvalPoint1; +fp_glGetTexParameterIiv glGetTexParameterIiv; +fp_glTexCoord1dv glTexCoord1dv; +fp_glTexCoordP1ui glTexCoordP1ui; +fp_glGetError glGetError; +fp_glGetTexEnviv glGetTexEnviv; +fp_glGetProgramiv glGetProgramiv; +fp_glVertexAttribP2ui glVertexAttribP2ui; +fp_glGetFloatv glGetFloatv; +fp_glTexSubImage1D glTexSubImage1D; +fp_glMultiTexCoord2fv glMultiTexCoord2fv; +fp_glVertexAttrib2fv glVertexAttrib2fv; +fp_glEvalCoord1d glEvalCoord1d; +fp_glGetTexLevelParameterfv glGetTexLevelParameterfv; +fp_glEvalCoord1f glEvalCoord1f; +fp_glPixelMapfv glPixelMapfv; +fp_glVertexAttribP3uiv glVertexAttribP3uiv; +fp_glGetPixelMapusv glGetPixelMapusv; +fp_glSecondaryColorP3uiv glSecondaryColorP3uiv; +fp_glGetIntegerv glGetIntegerv; +fp_glAccum glAccum; +fp_glGetBufferPointerv glGetBufferPointerv; +fp_glGetVertexAttribIiv glGetVertexAttribIiv; +fp_glRasterPos4dv glRasterPos4dv; +fp_glTexCoord2iv glTexCoord2iv; +fp_glIsQuery glIsQuery; +fp_glVertexAttrib4sv glVertexAttrib4sv; +fp_glWindowPos3dv glWindowPos3dv; +fp_glTexImage2D glTexImage2D; +fp_glStencilMask glStencilMask; +fp_glDrawPixels glDrawPixels; +fp_glMultMatrixd glMultMatrixd; +fp_glMultMatrixf glMultMatrixf; +fp_glIsTexture glIsTexture; +fp_glGetMaterialiv glGetMaterialiv; +fp_glUniform1fv glUniform1fv; +fp_glLoadMatrixf glLoadMatrixf; +fp_glLoadMatrixd glLoadMatrixd; +fp_glTexParameterfv glTexParameterfv; +fp_glUniformMatrix3fv glUniformMatrix3fv; +fp_glVertex4f glVertex4f; +fp_glRectsv glRectsv; +fp_glColor4usv glColor4usv; +fp_glPolygonStipple glPolygonStipple; +fp_glInterleavedArrays glInterleavedArrays; +fp_glNormal3i glNormal3i; +fp_glNormal3f glNormal3f; +fp_glNormal3d glNormal3d; +fp_glNormal3b glNormal3b; +fp_glPixelMapusv glPixelMapusv; +fp_glGetTexGeniv glGetTexGeniv; +fp_glArrayElement glArrayElement; +fp_glCopyBufferSubData glCopyBufferSubData; +fp_glVertexAttribI1uiv glVertexAttribI1uiv; +fp_glVertexAttrib2d glVertexAttrib2d; +fp_glBindTransformFeedback glBindTransformFeedback; +fp_glVertexAttrib2f glVertexAttrib2f; +fp_glVertexAttrib3dv glVertexAttrib3dv; +fp_glGetQueryObjectui64v glGetQueryObjectui64v; +fp_glDepthMask glDepthMask; +fp_glVertexAttrib2s glVertexAttrib2s; +fp_glColor3fv glColor3fv; +fp_glTexImage3DMultisample glTexImage3DMultisample; +fp_glUniformMatrix4fv glUniformMatrix4fv; +fp_glUniform4fv glUniform4fv; +fp_glGetActiveUniform glGetActiveUniform; +fp_glColorPointer glColorPointer; +fp_glFrontFace glFrontFace; +fp_glGetBooleani_v glGetBooleani_v; +fp_glClearBufferuiv glClearBufferuiv; +} diff --git a/demos/external/sources/glad/gl/gl.d b/demos/external/sources/glad/gl/gl.d new file mode 100644 index 0000000..2659e44 --- /dev/null +++ b/demos/external/sources/glad/gl/gl.d @@ -0,0 +1,404 @@ +module glad.gl.gl; + + +public import glad.gl.types; +public import glad.gl.funcs : +glCopyTexImage1D, glVertexAttribI3ui, glWindowPos2s, glWindowPos2i, glWindowPos2f, +glWindowPos2d, glVertex2fv, glColor4ub, glIndexi, glFramebufferRenderbuffer, +glRectdv, glCompressedTexSubImage3D, glEvalCoord2d, glEvalCoord2f, glIndexd, +glVertexAttrib1sv, glIndexf, glBindSampler, glLineWidth, glColorP3uiv, +glGetIntegeri_v, glGetMapfv, glIndexs, glCompileShader, glGetTransformFeedbackVarying, +glVertex3sv, glIndexfv, glFogiv, glStencilMaskSeparate, glRasterPos2fv, +glLightModeliv, glRectd, glSecondaryColor3fv, glMultiTexCoordP3ui, glFogfv, +glVertexP4ui, glEnablei, glVertex4iv, glEvalCoord1fv, glWindowPos2sv, +glVertexAttribP4ui, glCreateShader, glIsBuffer, glGetMultisamplefv, glGenRenderbuffers, +glCopyTexSubImage2D, glCompressedTexImage2D, glVertexAttrib1f, glBlendFuncSeparate, glVertex4fv, +glDrawBuffers, glVertexAttrib1s, glTexCoord2fv, glSampleMaski, glVertexP2ui, +glTexCoord1i, glTexCoord4fv, glUniformMatrix3x2fv, glPointSize, glVertexAttrib2dv, +glDeleteProgram, glColor4bv, glRasterPos2f, glRasterPos2d, glLoadIdentity, +glRasterPos2i, glUniformMatrix4x3fv, glColor3b, glClearBufferfv, glEdgeFlag, +glFogCoordf, glVertex3d, glVertex3f, glVertex3i, glColor3i, +glUniform3f, glVertexAttrib4ubv, glColor3s, glVertex3s, glTexCoordP2ui, +glColorMaski, glEnableClientState, glClearBufferfi, glTexCoord1iv, glMultiTexCoord1iv, +glMultiTexCoordP2ui, glGetSamplerParameterIiv, glGetFragDataIndex, glRasterPos4i, glVertex2iv, +glColor3sv, glGetVertexAttribdv, glUniformMatrix3x4fv, glNormalPointer, glTexCoordP3uiv, +glVertex4sv, glPassThrough, glMultiTexCoordP4ui, glFogi, glBegin, +glEvalCoord2dv, glColor3ubv, glVertexPointer, glScaled, glDeleteFramebuffers, +glDrawArrays, glUniform1ui, glMultiTexCoord1d, glMultiTexCoord1f, glLightfv, +glClear, glMultiTexCoord1i, glGetActiveUniformName, glMultiTexCoord1s, glStencilOp, +glTexCoord1s, glFramebufferTexture2D, glGetFramebufferAttachmentParameteriv, glTranslatef, glVertexAttrib4Nub, +glTranslated, glTexCoord3sv, glGetFragDataLocation, glTexImage1D, glTexParameteriv, +glCopyPixels, glSecondaryColor3bv, glGetMaterialfv, glGetTexImage, glFogCoordfv, +glVertexAttrib4iv, glPixelMapuiv, glColor4ubv, glGetQueryObjecti64v, glGenFramebuffers, +glIndexsv, glGetAttachedShaders, glIsRenderbuffer, glVertex3iv, glBitmap, +glMateriali, glIsVertexArray, glDisableVertexAttribArray, glGetQueryiv, glTexCoord4f, +glTexCoord4d, glGetSamplerParameterfv, glTexCoord4i, glMaterialf, glTexCoord4s, +glGetUniformIndices, glIsShader, glFeedbackBuffer, glVertexAttribI4ubv, glVertex3dv, +glPointParameteriv, glDisable, glEnable, glGetActiveUniformsiv, glColor4fv, +glTexCoord1fv, glTexCoord2sv, glVertexAttrib4dv, glMultiTexCoord1dv, glGetMapiv, +glTexCoord3fv, glSecondaryColor3usv, glMultiTexCoordP3uiv, glVertexAttribP3ui, glGetPointerv, +glPolygonOffset, glGetUniformuiv, glNormal3fv, glDepthRange, glFrustum, +glMultiTexCoord2f, glDrawBuffer, glPushMatrix, glRasterPos3fv, glOrtho, +glDrawElementsInstanced, glWindowPos3sv, glVertexAttrib4d, glClearIndex, glMap1d, +glMap1f, glFlush, glGetRenderbufferParameteriv, glIndexiv, glRasterPos3sv, +glGetVertexAttribPointerv, glPixelZoom, glDeleteBuffers, glFenceSync, glDeleteVertexArrays, +glColorP3ui, glVertexAttrib3sv, glVertexAttrib4s, glGetTexLevelParameteriv, glLighti, +glMultiTexCoordP4uiv, glLightf, glGetAttribLocation, glStencilFuncSeparate, glGenSamplers, +glClampColor, glUniform4iv, glClearStencil, glVertexAttrib2sv, glMultiTexCoord3fv, +glGetPixelMapuiv, glGenTextures, glTexCoord4iv, glGetTexParameterIuiv, glIndexPointer, +glVertexAttrib4Nbv, glGetQueryObjectiv, glIsSync, glVertex2f, glVertex2d, +glDeleteRenderbuffers, glUniform2i, glMapGrid2d, glMapGrid2f, glShaderSource, +glVertex2i, glVertexAttribPointer, glFramebufferTextureLayer, glVertex2s, glNormal3bv, +glFlushMappedBufferRange, glSecondaryColor3sv, glPointParameteri, glWindowPos2iv, glGenQueries, +glGetPixelMapfv, glTexEnvf, glVertexAttribP1ui, glTexSubImage3D, glGetInteger64i_v, +glFogCoordd, glDeleteSamplers, glCopyTexImage2D, glTexEnvi, glBlitFramebuffer, +glIsEnabledi, glSecondaryColorP3ui, glBindFragDataLocationIndexed, glMultiTexCoord2dv, glUniform2iv, +glUniform4uiv, glMatrixMode, glMultiTexCoord2s, glColor3uiv, glMultiTexCoord2i, +glFramebufferTexture1D, glGetShaderiv, glMultiTexCoord2d, glMultiTexCoord4sv, glBindFragDataLocation, +glPrioritizeTextures, glCallList, glSecondaryColor3ubv, glGetDoublev, glMultiTexCoord3iv, +glVertexAttrib1d, glLightModelf, glVertexAttrib1fv, glVertex2sv, glLightModeli, +glBindBufferRange, glWindowPos3iv, glMultiTexCoordP1uiv, glUniform3fv, glCallLists, +glMapBuffer, glSecondaryColor3d, glTexCoord3i, glMultiTexCoord4fv, glRasterPos3i, +glSecondaryColor3b, glRasterPos3d, glRasterPos3f, glCompressedTexImage3D, glTexCoord3f, +glDeleteSync, glMultiTexCoordP1ui, glGetVertexAttribiv, glSecondaryColor3s, glVertexAttrib3fv, +glTexCoord3s, glUniform3iv, glRasterPos3s, glPolygonMode, glGetActiveUniformBlockiv, +glAreTexturesResident, glIsList, glRasterPos4sv, glCopyTexSubImage3D, glColor4s, +glUseProgram, glLineStipple, glSamplerParameterIuiv, glMultiTexCoord1sv, glGetProgramInfoLog, +glMultiTexCoord2iv, glTexCoord1sv, glBindVertexArray, glColor4b, glSecondaryColor3f, +glColor4f, glColor4d, glColor4i, glMultiDrawElementsBaseVertex, glUniform4fv, +glRasterPos3iv, glVertex2dv, glTexCoord4sv, glUniform2uiv, glCompressedTexSubImage1D, +glFinish, glClipPlane, glDeleteShader, glRasterPos2s, glGetMapdv, +glVertexAttrib4Nsv, glTexGendv, glViewport, glBindBufferBase, glVertexP3uiv, +glTransformFeedbackVaryings, glIndexdv, glTexCoord3d, glTexCoord3iv, glVertexAttribI3i, +glClearDepth, glVertexAttribI4usv, glTexParameterf, glTexParameteri, glGetShaderSource, +glTexBuffer, glPixelStorei, glValidateProgram, glPixelStoref, glSecondaryColor3iv, +glRasterPos4fv, glEvalCoord1dv, glMultiTexCoordP2uiv, glRecti, glMultiDrawElements, +glRectf, glColor4ui, glNormal3sv, glGetFloatv, glColor4us, +glVertexAttribP1uiv, glLinkProgram, glTexSubImage1D, glBindTexture, glRects, +glTexCoord2dv, glRasterPos4iv, glGetString, glVertexAttribP2uiv, glEdgeFlagv, +glDetachShader, glScalef, glEndQuery, glSecondaryColor3uiv, glEdgeFlagPointer, +glVertexAttrib4Nuiv, glVertexAttribI2ui, glPopAttrib, glDeleteTextures, glStencilOpSeparate, +glDeleteQueries, glNormalP3uiv, glVertexAttrib4f, glRenderbufferStorage, glInitNames, +glColor3dv, glPixelMapfv, glGetTexParameteriv, glWaitSync, glBeginConditionalRender, +glDrawElementsBaseVertex, glSampleCoverage, glSamplerParameteri, glSamplerParameterf, glUniform1f, +glGetVertexAttribfv, glRenderMode, glGetCompressedTexImage, glWindowPos2dv, glUniform1i, +glGetActiveAttrib, glUniform3i, glPixelTransferi, glTexSubImage2D, glGetUniformiv, +glLogicOp, glEvalPoint2, glPixelTransferf, glUniform4ui, glColor3f, +glBindFramebuffer, glGetTexEnvfv, glRectfv, glCullFace, glGetLightfv, +glTexGenf, glTexGend, glTexGeni, glMultiTexCoord3s, glVertexAttribI2uiv, +glMultiTexCoord3i, glMultiTexCoord3f, glMultiTexCoord3d, glAttachShader, glFogCoorddv, +glGetTexGenfv, glQueryCounter, glFogCoordPointer, glProvokingVertex, glRasterPos4dv, +glTexGeniv, glDrawElements, glColorMaterial, glSecondaryColor3dv, glClientActiveTexture, +glVertexAttribI4sv, glTexCoord2iv, glUniform1iv, glGetBufferParameteriv, glReadBuffer, +glTexParameterIuiv, glDrawArraysInstanced, glGenerateMipmap, glWindowPos3fv, glLightModelfv, +glSamplerParameteriv, glDeleteLists, glGetClipPlane, glVertexAttrib3f, glTexCoord2d, +glVertexAttrib3d, glTexCoord2f, glRasterPos2dv, glIndexubv, glUnmapBuffer, +glTexCoord2i, glRasterPos4d, glRasterPos4f, glVertexAttrib3s, glTexCoord2s, +glBindRenderbuffer, glVertex3fv, glTexCoord4dv, glMaterialiv, glVertexAttribP4uiv, +glIsProgram, glPointParameterfv, glVertex4s, glPopMatrix, glVertexAttrib4fv, +glNormal3dv, glUniform4i, glActiveTexture, glEnableVertexAttribArray, glRotated, +glRotatef, glVertex4i, glArrayElement, glReadPixels, glVertexAttribI3iv, +glStencilMask, glUniform4f, glRenderbufferStorageMultisample, glColor3d, glGenVertexArrays, +glShadeModel, glMapGrid1d, glGetUniformfv, glMapGrid1f, glDrawPixels, +glDisableClientState, glMultiTexCoord3sv, glDrawElementsInstancedBaseVertex, glSecondaryColorPointer, glAlphaFunc, +glMultiTexCoord4iv, glTexEnvfv, glStencilFunc, glTexCoord3dv, glUniformBlockBinding, +glColor4uiv, glRectiv, glColorP4ui, glRasterPos3dv, glEvalMesh2, +glEvalMesh1, glTexCoordPointer, glLoadMatrixf, glVertexAttribI4iv, glEvalCoord2fv, +glGetShaderInfoLog, glLoadTransposeMatrixd, glLoadTransposeMatrixf, glVertexAttribI4i, glRasterPos2iv, +glGetBufferSubData, glTexEnviv, glBlendEquationSeparate, glVertexAttribI1ui, glGenBuffers, +glSelectBuffer, glTexCoordP1uiv, glPushAttrib, glVertexAttribIPointer, glBlendFunc, +glCreateProgram, glTexImage3D, glIsFramebuffer, glLightiv, glPrimitiveRestartIndex, +glTexGenfv, glTexCoord1dv, glEnd, glGetInteger64v, glScissor, +glTexCoordP4uiv, glGetBooleanv, glPushName, glMaterialfv, glIndexub, +glVertexP2uiv, glUniform3uiv, glMultTransposeMatrixf, glMultTransposeMatrixd, glClearColor, +glVertexAttrib4uiv, glPolygonStipple, glVertexAttrib4Niv, glClearBufferiv, glGetBufferParameteri64v, +glColorP4uiv, glBlendColor, glWindowPos3d, glGetStringi, glColor4iv, +glUniform3ui, glSecondaryColor3us, glVertexAttribI4uiv, glVertexAttrib4bv, glUniform2fv, +glSecondaryColor3ub, glSecondaryColor3ui, glMultiTexCoord1fv, glGetSamplerParameterIuiv, glNormal3i, +glTexCoordP3ui, glNormal3iv, glWindowPos3s, glPointParameterf, glColor3us, +glWindowPos3i, glUniformMatrix2x3fv, glWindowPos3f, glGetVertexAttribIuiv, glMultiTexCoord4s, +glVertexAttrib4Nusv, glGetLightiv, glDepthFunc, glCompressedTexSubImage2D, glListBase, +glMultiTexCoord4f, glColor3ub, glMultiTexCoord4d, glVertexAttribI4bv, glGetTexParameterfv, +glColor3ui, glMultiTexCoord4i, glGetPolygonStipple, glClientWaitSync, glVertexAttribI4ui, +glPixelMapusv, glColorMask, glTexParameterIiv, glBlendEquation, glGetUniformLocation, +glGetTexGeniv, glRasterPos4s, glEndTransformFeedback, glVertexAttrib4usv, glTexImage2DMultisample, +glColor4sv, glPopClientAttrib, glColor4dv, glBeginTransformFeedback, glFogf, +glVertexAttribI1iv, glIsSampler, glVertexP3ui, glVertexAttribDivisor, glColor3iv, +glCompressedTexImage1D, glCopyTexSubImage1D, glDrawRangeElementsBaseVertex, glCheckFramebufferStatus, glTexCoord1d, +glTexCoord1f, glEndConditionalRender, glUniform1uiv, glBindAttribLocation, glUniformMatrix4x2fv, +glMultiTexCoord2sv, glVertexAttrib1dv, glDrawRangeElements, glGetQueryObjectuiv, glSamplerParameterIiv, +glBufferSubData, glVertexAttribI2i, glGenLists, glColor3bv, glMapBufferRange, +glFramebufferTexture, glGetTexGendv, glMultiDrawArrays, glEndList, glVertexP4uiv, +glUniform2ui, glVertexAttribI2iv, glColor3usv, glWindowPos2fv, glDisablei, +glIndexMask, glPushClientAttrib, glVertex4dv, glTexCoordP4ui, glGetActiveUniformBlockName, +glVertexAttribI3uiv, glClearAccum, glGetSynciv, glTexCoordP2uiv, glUniform2f, +glBeginQuery, glUniformMatrix4fv, glBindBuffer, glMap2d, glMap2f, +glRasterPos2sv, glUniformMatrix2fv, glUniformMatrix2x4fv, glBufferData, glEvalPoint1, +glGetTexParameterIiv, glIsEnabled, glTexCoordP1ui, glGetError, glGetTexEnviv, +glGetProgramiv, glVertexAttribP2ui, glNewList, glSecondaryColor3i, glMultiTexCoord2fv, +glNormalP3ui, glEvalCoord1d, glGetTexLevelParameterfv, glEvalCoord1f, glVertexAttribI1i, +glVertex4d, glVertexAttribP3uiv, glGetPixelMapusv, glSecondaryColorP3uiv, glGetIntegerv, +glAccum, glGetBufferPointerv, glGetVertexAttribIiv, glFramebufferTexture3D, glVertexAttrib2fv, +glIsQuery, glVertexAttrib4sv, glWindowPos3dv, glTexImage2D, glLoadName, +glSamplerParameterfv, glMultMatrixd, glMultMatrixf, glIsTexture, glGetMaterialiv, +glUniform1fv, glVertexAttrib4Nubv, glLoadMatrixd, glTexParameterfv, glUniformMatrix3fv, +glVertex4f, glRectsv, glColor4usv, glNormal3s, glInterleavedArrays, +glHint, glNormal3f, glNormal3d, glNormal3b, glMultiTexCoord4dv, +glGetSamplerParameteriv, glPopName, glCopyBufferSubData, glVertexAttribI1uiv, glVertexAttrib2d, +glVertexAttrib2f, glVertexAttrib3dv, glGetQueryObjectui64v, glDepthMask, glVertexAttrib2s, +glColor3fv, glTexImage3DMultisample, glGetUniformBlockIndex, glMultiTexCoord3dv, glGetActiveUniform, +glColorPointer, glFrontFace, glGetBooleani_v, glClearBufferuiv; + +public import glad.gl.enums : +GL_INDEX_CLEAR_VALUE, GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, GL_FOG_INDEX, GL_ALPHA_TEST_FUNC, +GL_SOURCE1_ALPHA, GL_NORMAL_MAP, GL_DITHER, GL_QUERY_RESULT, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, +GL_R16_SNORM, GL_FOG_COORD_ARRAY, GL_FLOAT, GL_PROXY_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LOD, +GL_RGB16_SNORM, GL_SAMPLER_2D_RECT, GL_RGB9_E5, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_TEXTURE_COMPRESSED, +GL_T2F_C4UB_V3F, GL_EDGE_FLAG_ARRAY_POINTER, GL_PROXY_TEXTURE_3D, GL_MAX_LIST_NESTING, GL_COLOR_ATTACHMENT22, +GL_SOURCE0_ALPHA, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_BYTE, GL_TIMEOUT_IGNORED, +GL_COLOR_ARRAY, GL_ZOOM_Y, GL_ZOOM_X, GL_RENDERBUFFER_SAMPLES, GL_HINT_BIT, +GL_COLOR_CLEAR_VALUE, GL_LINEAR_MIPMAP_LINEAR, GL_DEPTH_WRITEMASK, GL_TEXTURE_GEN_MODE, GL_3D_COLOR_TEXTURE, +GL_COLOR_ARRAY_POINTER, GL_TEXTURE_DEPTH_SIZE, GL_FLOAT_MAT3x2, GL_PIXEL_MAP_G_TO_G, GL_RENDER, +GL_MAX_TEXTURE_COORDS, GL_FLOAT_MAT3x4, GL_COLOR_ATTACHMENT28, GL_TEXTURE_BINDING_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT24, +GL_COLOR_ATTACHMENT25, GL_COLOR_ATTACHMENT26, GL_COLOR_ATTACHMENT27, GL_COLOR_ATTACHMENT20, GL_COLOR_ATTACHMENT21, +GL_COMPRESSED_RGBA, GL_COLOR_ATTACHMENT23, GL_CLIENT_ATTRIB_STACK_DEPTH, GL_UNSIGNED_SHORT_5_5_5_1, GL_TEXTURE_COMPONENTS, +GL_QUERY_NO_WAIT, GL_PROVOKING_VERTEX, GL_SIGNED_NORMALIZED, GL_CURRENT_RASTER_TEXTURE_COORDS, GL_EXP, +GL_LINE_STRIP_ADJACENCY, GL_POINT_SIZE, GL_TEXTURE_COMPARE_FUNC, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, GL_BITMAP_TOKEN, +GL_RGB10, GL_RGB16, GL_POLYGON_OFFSET_FILL, GL_LINE_TOKEN, GL_DOUBLEBUFFER, +GL_MAX_CLIP_PLANES, GL_FOG_COORDINATE_ARRAY_STRIDE, GL_RGB_INTEGER, GL_COMPILE_AND_EXECUTE, GL_MULT, +GL_STENCIL_CLEAR_VALUE, GL_GREEN_BITS, GL_SHADING_LANGUAGE_VERSION, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_SRC2_RGB, +GL_FRAGMENT_SHADER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_INDEX_ARRAY_TYPE, GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_TEXTURE_DEPTH, +GL_VIEWPORT, GL_DRAW_BUFFER6, GL_DRAW_BUFFER7, GL_DRAW_BUFFER4, GL_DRAW_BUFFER5, +GL_DRAW_BUFFER2, GL_DRAW_BUFFER3, GL_DRAW_BUFFER0, GL_DRAW_BUFFER1, GL_LIGHT1, +GL_LIGHT0, GL_LIGHT3, GL_LIGHT2, GL_COPY, GL_LIGHT4, +GL_BLEND_SRC, GL_LIGHT6, GL_MAP_STENCIL, GL_QUADRATIC_ATTENUATION, GL_TEXTURE_CUBE_MAP_SEAMLESS, +GL_TEXTURE_RECTANGLE, GL_FILL, GL_SRC_COLOR, GL_SAMPLER_BINDING, GL_DEPTH24_STENCIL8, +GL_SAMPLE_BUFFERS, GL_RGBA_INTEGER, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, GL_COLOR_INDEX, GL_EXTENSIONS, +GL_MAP2_NORMAL, GL_BUFFER_SIZE, GL_PASS_THROUGH_TOKEN, GL_MAX_EVAL_ORDER, GL_UPPER_LEFT, +GL_TEXTURE_COMPARE_MODE, GL_ANY_SAMPLES_PASSED, GL_LAST_VERTEX_CONVENTION, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, GL_DEPTH_BUFFER_BIT, +GL_STENCIL_BACK_PASS_DEPTH_FAIL, GL_UNSIGNALED, GL_UNIFORM_BUFFER, GL_MAP_WRITE_BIT, GL_SHADE_MODEL, +GL_COMPRESSED_SLUMINANCE, GL_CCW, GL_RGB32I, GL_DEPTH_COMPONENT24, GL_INDEX_SHIFT, +GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_LIST_BIT, GL_ONE_MINUS_SRC1_COLOR, GL_STREAM_READ, GL_LINEAR, +GL_R32F, GL_VERTEX_ARRAY, GL_OR_REVERSE, GL_LUMINANCE12_ALPHA4, GL_LOGIC_OP, +GL_VERTEX_ARRAY_BUFFER_BINDING, GL_PIXEL_MAP_R_TO_R, GL_FOG_COORDINATE_SOURCE, GL_UNSIGNED_SHORT_5_6_5_REV, GL_TEXTURE_BORDER, +GL_GREATER, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_MAX_TEXTURE_IMAGE_UNITS, GL_RGB32F, +GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FRONT_FACE, GL_DEPTH, GL_REPLACE, +GL_VERTEX_ATTRIB_ARRAY_STRIDE, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, GL_OPERAND1_RGB, GL_RGBA32UI, GL_RG8I, +GL_RGBA8I, GL_TEXTURE_FILTER_CONTROL, GL_ACCUM_CLEAR_VALUE, GL_SRC1_ALPHA, GL_RG32F, +GL_R3_G3_B2, GL_ALPHA_BIAS, GL_RENDERBUFFER_BINDING, GL_TEXTURE_STACK_DEPTH, GL_TEXTURE_LUMINANCE_SIZE, +GL_TEXTURE_MIN_LOD, GL_FOG_COORDINATE_ARRAY, GL_BLEND, GL_FEEDBACK_BUFFER_TYPE, GL_MAP1_TEXTURE_COORD_3, +GL_R16UI, GL_MAP1_TEXTURE_COORD_1, GL_UNSIGNED_SHORT, GL_MIN, GL_MAP1_TEXTURE_COORD_4, +GL_COMPRESSED_SRGB_ALPHA, GL_ONE_MINUS_SRC_COLOR, GL_TEXTURE, GL_INTENSITY12, GL_MAX_PROJECTION_STACK_DEPTH, +GL_RGB_SCALE, GL_MAX_CLIP_DISTANCES, GL_PERSPECTIVE_CORRECTION_HINT, GL_LIST_MODE, GL_TIMESTAMP, +GL_ACTIVE_UNIFORMS, GL_VERTEX_PROGRAM_POINT_SIZE, GL_MAX_COLOR_ATTACHMENTS, GL_TEXTURE_BINDING_CUBE_MAP, GL_OPERAND2_RGB, +GL_R, GL_SRGB_ALPHA, GL_S, GL_NUM_COMPRESSED_TEXTURE_FORMATS, GL_PACK_SKIP_ROWS, +GL_T, GL_MAX_TEXTURE_UNITS, GL_SLUMINANCE8, GL_MAX_TEXTURE_BUFFER_SIZE, GL_MAP1_COLOR_4, +GL_GEOMETRY_SHADER, GL_R8I, GL_TEXTURE_MAX_LEVEL, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_BLEND_COLOR, +GL_ALPHA_BITS, GL_LINE_STIPPLE, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, GL_ONE_MINUS_CONSTANT_ALPHA, GL_NEAREST_MIPMAP_LINEAR, +GL_ALPHA8, GL_BLEND_EQUATION, GL_SRC2_ALPHA, GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, GL_ALPHA4, +GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, GL_FOG_END, GL_SAMPLER_1D, GL_LINE, GL_STENCIL_BITS, +GL_FOG_COORDINATE_ARRAY_TYPE, GL_SAMPLES_PASSED, GL_RENDERBUFFER_RED_SIZE, GL_COMPRESSED_SLUMINANCE_ALPHA, GL_BLUE_INTEGER, +GL_DYNAMIC_COPY, GL_CURRENT_FOG_COORD, GL_SYNC_FLAGS, GL_RG32I, GL_UNSIGNED_BYTE_2_3_3_REV, +GL_RENDERBUFFER_INTERNAL_FORMAT, GL_CLIENT_ACTIVE_TEXTURE, GL_TEXTURE_HEIGHT, GL_RGBA16I, GL_RGBA16F, +GL_OPERAND2_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE, GL_FOG_DENSITY, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, GL_CONSTANT_ATTENUATION, +GL_RED, GL_DEPTH_BIAS, GL_EQUIV, GL_POLYGON_OFFSET_LINE, GL_FUNC_REVERSE_SUBTRACT, +GL_GREEN, GL_INVALID_OPERATION, GL_CLAMP_READ_COLOR, GL_RED_INTEGER, GL_TEXTURE_BINDING_BUFFER, +GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT4, GL_MAP2_TEXTURE_COORD_2, GL_COLOR_ATTACHMENT6, GL_MAP2_TEXTURE_COORD_4, +GL_COLOR_ATTACHMENT0, GL_4_BYTES, GL_COLOR_ATTACHMENT2, GL_MAX_MODELVIEW_STACK_DEPTH, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, +GL_COLOR_ATTACHMENT9, GL_COLOR_ATTACHMENT8, GL_PACK_IMAGE_HEIGHT, GL_PIXEL_MAP_B_TO_B_SIZE, GL_BUFFER_USAGE, +GL_CULL_FACE_MODE, GL_UNSIGNED_INT_8_8_8_8_REV, GL_BOOL, GL_MAX_COMBINED_UNIFORM_BLOCKS, GL_3D_COLOR, +GL_GREEN_INTEGER, GL_DST_COLOR, GL_T2F_V3F, GL_UNSIGNED_INT, GL_OPERAND0_ALPHA, +GL_ALWAYS, GL_NOOP, GL_V3F, GL_POINT_SPRITE_COORD_ORIGIN, GL_POINT_SIZE_RANGE, +GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_LUMINANCE16, GL_GREEN_BIAS, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, GL_LUMINANCE12, +GL_SAMPLER_2D_MULTISAMPLE_ARRAY, GL_SHADER_TYPE, GL_RG16_SNORM, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, GL_COLOR_ARRAY_TYPE, +GL_QUERY_COUNTER_BITS, GL_MODULATE, GL_RG_INTEGER, GL_DRAW_BUFFER10, GL_FOG_COORD_ARRAY_BUFFER_BINDING, +GL_TEXTURE_LUMINANCE_TYPE, GL_RENDERBUFFER_HEIGHT, GL_RG16UI, GL_INTERLEAVED_ATTRIBS, GL_TEXTURE_ALPHA_TYPE, +GL_COLOR_ATTACHMENT29, GL_MAP2_TEXTURE_COORD_1, GL_DRAW_BUFFER14, GL_FOG_COORD_ARRAY_STRIDE, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, +GL_MAP2_TEXTURE_COORD_3, GL_TEXTURE_BLUE_TYPE, GL_COLOR_ATTACHMENT1, GL_C4F_N3F_V3F, GL_COMBINE_RGB, +GL_STEREO, GL_ALREADY_SIGNALED, GL_T4F_V4F, GL_STREAM_COPY, GL_LIGHT_MODEL_LOCAL_VIEWER, +GL_SOURCE0_RGB, GL_EYE_PLANE, GL_TEXTURE_CUBE_MAP, GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, +GL_CLIP_PLANE1, GL_CLIP_PLANE0, GL_CLIP_PLANE3, GL_CLIP_PLANE2, GL_CLIP_PLANE5, +GL_CLIP_PLANE4, GL_ORDER, GL_NORMAL_ARRAY_TYPE, GL_TEXTURE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, +GL_LINE_STIPPLE_REPEAT, GL_POINTS, GL_LIGHTING_BIT, GL_SYNC_STATUS, GL_RENDERBUFFER_BLUE_SIZE, +GL_UNIFORM_NAME_LENGTH, GL_FASTEST, GL_LUMINANCE8, GL_LUMINANCE4, GL_POLYGON, +GL_NAND, GL_MAP1_INDEX, GL_LINE_WIDTH_GRANULARITY, GL_ADD_SIGNED, GL_MAX_3D_TEXTURE_SIZE, +GL_CLIENT_PIXEL_STORE_BIT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_DONT_CARE, +GL_POLYGON_BIT, GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING, GL_QUERY_WAIT, GL_MAP_FLUSH_EXPLICIT_BIT, GL_TEXTURE_COORD_ARRAY_SIZE, +GL_RED_SCALE, GL_SRGB8, GL_CURRENT_NORMAL, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_FRAGMENT_DEPTH, +GL_UNIFORM_BLOCK_BINDING, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, GL_SRC0_ALPHA, GL_LEQUAL, GL_PIXEL_MAP_A_TO_A_SIZE, +GL_TEXTURE_WIDTH, GL_ONE_MINUS_SRC1_ALPHA, GL_MAP_COLOR, GL_UNIFORM_SIZE, GL_POINT_SPRITE, +GL_FLOAT_MAT4x2, GL_SHADER_SOURCE_LENGTH, GL_DOT3_RGBA, GL_COMPRESSED_RG, GL_UNPACK_SWAP_BYTES, +GL_CURRENT_VERTEX_ATTRIB, GL_POLYGON_OFFSET_UNITS, GL_LUMINANCE6_ALPHA2, GL_MAX_COLOR_TEXTURE_SAMPLES, GL_COLOR_ATTACHMENT7, +GL_PRIMARY_COLOR, GL_C3F_V3F, GL_OUT_OF_MEMORY, GL_AUX_BUFFERS, GL_NORMAL_ARRAY_STRIDE, +GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_SMOOTH, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, GL_GEOMETRY_OUTPUT_TYPE, GL_RASTERIZER_DISCARD, +GL_MAX_TEXTURE_LOD_BIAS, GL_CURRENT_TEXTURE_COORDS, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GL_FRONT_RIGHT, +GL_EDGE_FLAG_ARRAY, GL_INT_SAMPLER_2D_MULTISAMPLE, GL_RETURN, GL_STENCIL_TEST, GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION, +GL_R11F_G11F_B10F, GL_LUMINANCE_ALPHA, GL_PIXEL_UNPACK_BUFFER_BINDING, GL_INVERT, GL_PROXY_TEXTURE_1D, +GL_COMPRESSED_INTENSITY, GL_TRANSFORM_FEEDBACK_VARYINGS, GL_DEPTH_COMPONENT32F, GL_TRIANGLE_FAN, GL_LIST_BASE, +GL_MAX_ELEMENTS_VERTICES, GL_CURRENT_COLOR, GL_INVALID_FRAMEBUFFER_OPERATION, GL_RGB12, GL_UNIFORM_BUFFER_SIZE, +GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING, GL_DEPTH32F_STENCIL8, GL_MAX_ARRAY_TEXTURE_LAYERS, GL_RED_BITS, GL_MAX_SERVER_WAIT_TIMEOUT, +GL_NOR, GL_FLAT, GL_PACK_ALIGNMENT, GL_PIXEL_MAP_S_TO_S, GL_UNPACK_LSB_FIRST, +GL_BGRA, GL_ACTIVE_UNIFORM_BLOCKS, GL_SOURCE1_RGB, GL_UNPACK_SKIP_IMAGES, GL_RGB16I, +GL_ACTIVE_TEXTURE, GL_TEXTURE_BASE_LEVEL, GL_RGB16F, GL_SMOOTH_LINE_WIDTH_RANGE, GL_ALPHA_INTEGER, +GL_GREEN_SCALE, GL_CLIP_DISTANCE7, GL_FOG_BIT, GL_TRANSPOSE_TEXTURE_MATRIX, GL_UNSIGNED_INT_SAMPLER_3D, +GL_SAMPLE_MASK, GL_INT_VEC4, GL_INT_VEC3, GL_INT_VEC2, GL_STENCIL_FAIL, +GL_CURRENT_FOG_COORDINATE, GL_CONDITION_SATISFIED, GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT, GL_FRAMEBUFFER_UNSUPPORTED, GL_RED_BIAS, +GL_DST_ALPHA, GL_SECONDARY_COLOR_ARRAY_POINTER, GL_R8, GL_RENDER_MODE, GL_EDGE_FLAG_ARRAY_BUFFER_BINDING, +GL_MAX_CUBE_MAP_TEXTURE_SIZE, GL_TEXTURE_1D_ARRAY, GL_RENDERBUFFER_WIDTH, GL_READ_FRAMEBUFFER_BINDING, GL_FRAMEBUFFER_ATTACHMENT_LAYERED, +GL_TEXTURE_BLUE_SIZE, GL_COORD_REPLACE, GL_RGBA2, GL_RGBA4, GL_MULTISAMPLE_BIT, +GL_FOG_COLOR, GL_DRAW_BUFFER11, GL_DRAW_BUFFER12, GL_DRAW_BUFFER13, GL_UNSIGNED_INT_10_10_10_2, +GL_DRAW_BUFFER15, GL_INFO_LOG_LENGTH, GL_R16F, GL_RENDERBUFFER_STENCIL_SIZE, GL_CONSTANT_ALPHA, +GL_RESCALE_NORMAL, GL_R16I, GL_POINT_SIZE_GRANULARITY, GL_STATIC_READ, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, +GL_COMPARE_R_TO_TEXTURE, GL_PREVIOUS, GL_MAP_READ_BIT, GL_SPOT_DIRECTION, GL_DEPTH_SCALE, +GL_STENCIL, GL_SAMPLE_MASK_VALUE, GL_LINE_BIT, GL_DIFFUSE, GL_MAX_RENDERBUFFER_SIZE, +GL_T2F_N3F_V3F, GL_TRANSFORM_BIT, GL_COLOR_ATTACHMENT30, GL_STENCIL_PASS_DEPTH_PASS, GL_INCR_WRAP, +GL_SOURCE2_RGB, GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_R, GL_TEXTURE_GEN_Q, +GL_RENDERBUFFER_ALPHA_SIZE, GL_ALPHA12, GL_LIGHT_MODEL_TWO_SIDE, GL_ALPHA16, GL_DECR_WRAP, +GL_POLYGON_SMOOTH, GL_COMPILE, GL_SAMPLE_POSITION, GL_TRANSPOSE_MODELVIEW_MATRIX, GL_INCR, +GL_POINT_SIZE_MIN, GL_MAX_RECTANGLE_TEXTURE_SIZE, GL_RGBA12, GL_GENERATE_MIPMAP_HINT, GL_ALPHA_TEST_REF, +GL_RGBA16, GL_UNPACK_SKIP_ROWS, GL_MAP1_NORMAL, GL_SOURCE2_ALPHA, GL_DEPTH_CLAMP, +GL_POLYGON_STIPPLE_BIT, GL_BLEND_DST_ALPHA, GL_INT_SAMPLER_CUBE, GL_CURRENT_QUERY, GL_RGB5_A1, +GL_EXP2, GL_UNPACK_SKIP_PIXELS, GL_RGB16UI, GL_COPY_INVERTED, GL_TEXTURE_PRIORITY, +GL_MAX_GEOMETRY_INPUT_COMPONENTS, GL_LOWER_LEFT, GL_FOG_HINT, GL_TEXTURE_BINDING_1D, GL_PROJECTION_MATRIX, +GL_AUX0, GL_PIXEL_UNPACK_BUFFER, GL_LINEAR_MIPMAP_NEAREST, GL_POINT_DISTANCE_ATTENUATION, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, +GL_RGB10_A2, GL_AMBIENT_AND_DIFFUSE, GL_ZERO, GL_ELEMENT_ARRAY_BUFFER, GL_CONTEXT_CORE_PROFILE_BIT, +GL_SCISSOR_BIT, GL_READ_ONLY, GL_MAX_FRAGMENT_INPUT_COMPONENTS, GL_MAP1_GRID_DOMAIN, GL_PIXEL_MAP_I_TO_A_SIZE, +GL_UNSIGNED_NORMALIZED, GL_SMOOTH_POINT_SIZE_GRANULARITY, GL_CLAMP_VERTEX_COLOR, GL_MAP2_INDEX, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, +GL_PIXEL_MAP_I_TO_R_SIZE, GL_NOTEQUAL, GL_TEXTURE_COORD_ARRAY, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_MAP2_GRID_DOMAIN, +GL_COMPRESSED_RED, GL_INT_SAMPLER_1D_ARRAY, GL_DRAW_PIXEL_TOKEN, GL_MAX_LIGHTS, GL_RGBA16_SNORM, +GL_OBJECT_LINEAR, GL_LIST_INDEX, GL_TEXTURE_BORDER_COLOR, GL_LUMINANCE16_ALPHA16, GL_TEXTURE_SHARED_SIZE, +GL_COMPILE_STATUS, GL_LOGIC_OP_MODE, GL_LUMINANCE8_ALPHA8, GL_RENDERBUFFER_DEPTH_SIZE, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, +GL_SLUMINANCE_ALPHA, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_FEEDBACK_BUFFER_POINTER, GL_SPOT_EXPONENT, GL_SHORT, +GL_BLUE, GL_CW, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_BYTE, GL_MAX_VERTEX_UNIFORM_COMPONENTS, +GL_QUADS, GL_DEPTH_TEXTURE_MODE, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R16, GL_PIXEL_PACK_BUFFER, +GL_PACK_LSB_FIRST, GL_RENDERBUFFER, GL_UNSIGNED_BYTE_3_3_2, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, GL_RGB8I, +GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, GL_DRAW_BUFFER, GL_STENCIL_INDEX1, GL_STENCIL_INDEX4, GL_SAMPLER_3D, +GL_TEXTURE_GREEN_TYPE, GL_STENCIL_INDEX8, GL_DEPTH_BITS, GL_OR_INVERTED, GL_RGB8UI, +GL_STENCIL_INDEX16, GL_STENCIL_BACK_REF, GL_SELECT, GL_INTENSITY4, GL_BLEND_DST_RGB, +GL_INTENSITY8, GL_LIGHT5, GL_LINE_RESET_TOKEN, GL_MAP1_VERTEX_3, GL_TEXTURE_BINDING_2D_ARRAY, +GL_VERTEX_ATTRIB_ARRAY_DIVISOR, GL_CLEAR, GL_DRAW_BUFFER8, GL_CURRENT_RASTER_POSITION_VALID, GL_FOG_COORD_SRC, +GL_DRAW_BUFFER9, GL_SRC0_RGB, GL_PIXEL_PACK_BUFFER_BINDING, GL_DECAL, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, +GL_2D, GL_SELECTION_BUFFER_POINTER, GL_SELECTION_BUFFER_SIZE, GL_SAMPLES, GL_UNSIGNED_INT_VEC2, +GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4, GL_UNSIGNED_SHORT_5_6_5, GL_CURRENT_RASTER_POSITION, GL_VERTEX_ATTRIB_ARRAY_SIZE, +GL_VERTEX_SHADER, GL_RGBA_MODE, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, +GL_COEFF, GL_RGB32UI, GL_BUFFER_MAP_OFFSET, GL_MIN_PROGRAM_TEXEL_OFFSET, GL_PROXY_TEXTURE_RECTANGLE, +GL_UNSIGNED_INT_SAMPLER_BUFFER, GL_UNIFORM_BUFFER_START, GL_MAX_TEXTURE_STACK_DEPTH, GL_UNSIGNED_INT_SAMPLER_2D, GL_TEXTURE8, +GL_INT_SAMPLER_2D_RECT, GL_TEXTURE_COORD_ARRAY_STRIDE, GL_TEXTURE4, GL_TEXTURE5, GL_TEXTURE6, +GL_TEXTURE7, GL_TEXTURE0, GL_CONTEXT_PROFILE_MASK, GL_TEXTURE2, GL_TEXTURE3, +GL_BOOL_VEC4, GL_DOUBLE, GL_RG8_SNORM, GL_BOOL_VEC3, GL_BOOL_VEC2, +GL_COLOR_MATERIAL_PARAMETER, GL_DOT3_RGB, GL_ONE, GL_SRC_ALPHA_SATURATE, GL_MAX_SAMPLES, +GL_UNPACK_IMAGE_HEIGHT, GL_TRIANGLE_STRIP, GL_N3F_V3F, GL_CONTEXT_FLAGS, GL_FRONT_LEFT, +GL_CLAMP, GL_POINT_SMOOTH_HINT, GL_INDEX_OFFSET, GL_INTENSITY, GL_POINT_SIZE_MAX, +GL_MODELVIEW_MATRIX, GL_VERTEX_ARRAY_BINDING, GL_INDEX_BITS, GL_TIMEOUT_EXPIRED, GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, +GL_STENCIL_FUNC, GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, GL_TEXTURE_ENV, GL_ALIASED_LINE_WIDTH_RANGE, GL_DECR, +GL_BACK, GL_VIEWPORT_BIT, GL_INT, GL_CLIP_DISTANCE1, GL_CLIP_DISTANCE0, +GL_CLIP_DISTANCE3, GL_CLIP_DISTANCE2, GL_CLIP_DISTANCE5, GL_CLIP_DISTANCE4, GL_MINOR_VERSION, +GL_PIXEL_MAP_G_TO_G_SIZE, GL_FRONT_AND_BACK, GL_POINT, GL_COMPRESSED_RG_RGTC2, GL_POLYGON_TOKEN, +GL_SMOOTH_LINE_WIDTH_GRANULARITY, GL_SRGB, GL_NORMAL_ARRAY_POINTER, GL_SYNC_FENCE, GL_ONE_MINUS_CONSTANT_COLOR, +GL_UNSIGNED_INT_8_8_8_8, GL_RGB8_SNORM, GL_TEXTURE_ALPHA_SIZE, GL_UNSIGNED_INT_SAMPLER_2D_RECT, GL_CONSTANT_COLOR, +GL_UNSIGNED_SHORT_4_4_4_4, GL_NO_ERROR, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, GL_BLEND_SRC_ALPHA, GL_CURRENT_SECONDARY_COLOR, +GL_RGBA16UI, GL_AND_REVERSE, GL_MAX_INTEGER_SAMPLES, GL_CLAMP_FRAGMENT_COLOR, GL_QUERY_RESULT_AVAILABLE, +GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, GL_MAX_DRAW_BUFFERS, GL_ONE_MINUS_DST_ALPHA, GL_FOG_MODE, GL_R32UI, +GL_RGBA8_SNORM, GL_C4UB_V2F, GL_INT_SAMPLER_3D, GL_CURRENT_INDEX, GL_AND, +GL_INDEX_MODE, GL_ACCUM_GREEN_BITS, GL_MAJOR_VERSION, GL_STATIC_COPY, GL_REFLECTION_MAP, +GL_BGR_INTEGER, GL_3_BYTES, GL_UNIFORM_BUFFER_BINDING, GL_UNIFORM_TYPE, GL_DELETE_STATUS, +GL_POINT_BIT, GL_SYNC_GPU_COMMANDS_COMPLETE, GL_SMOOTH_POINT_SIZE_RANGE, GL_ALIASED_POINT_SIZE_RANGE, GL_3D, +GL_MAP_INVALIDATE_BUFFER_BIT, GL_UNSIGNED_INT_5_9_9_9_REV, GL_DEPTH_TEST, GL_BUFFER_MAP_LENGTH, GL_VERTEX_ATTRIB_ARRAY_POINTER, +GL_MULTISAMPLE, GL_MAX_GEOMETRY_OUTPUT_VERTICES, GL_TEXTURE_RED_TYPE, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_FUNC_SUBTRACT, +GL_VERTEX_PROGRAM_TWO_SIDE, GL_SAMPLER_BUFFER, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_TEXTURE_COORD_ARRAY_TYPE, GL_CLAMP_TO_BORDER, +GL_COLOR_ATTACHMENT15, GL_COLOR_ATTACHMENT14, GL_COLOR_ATTACHMENT17, GL_DEPTH_RANGE, GL_COLOR_ATTACHMENT11, +GL_COLOR_ATTACHMENT10, GL_COLOR_ATTACHMENT13, GL_COLOR_ATTACHMENT12, GL_NEAREST, GL_COMPRESSED_TEXTURE_FORMATS, +GL_COLOR_ATTACHMENT19, GL_COLOR_ATTACHMENT18, GL_RENDERBUFFER_GREEN_SIZE, GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, GL_PIXEL_MAP_S_TO_S_SIZE, +GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, GL_RGBA8, GL_T2F_C3F_V3F, GL_SAMPLER_2D_RECT_SHADOW, GL_ALL_ATTRIB_BITS, +GL_POINT_TOKEN, GL_T4F_C4F_N3F_V4F, GL_TEXTURE30, GL_TEXTURE31, GL_UNSIGNED_INT_SAMPLER_1D, +GL_POINT_SMOOTH, GL_DEPTH_CLEAR_VALUE, GL_GEOMETRY_INPUT_TYPE, GL_BACK_LEFT, GL_TEXTURE_ENV_COLOR, +GL_BUFFER_MAP_POINTER, GL_LINE_SMOOTH, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_STENCIL_REF, GL_CURRENT_BIT, +GL_FOG_COORDINATE, GL_COPY_WRITE_BUFFER, GL_MAX_VARYING_FLOATS, GL_PRIMITIVE_RESTART_INDEX, GL_OPERAND0_RGB, +GL_LIGHT_MODEL_COLOR_CONTROL, GL_FEEDBACK, GL_ONE_MINUS_DST_COLOR, GL_MAX_ATTRIB_STACK_DEPTH, GL_FOG_COORD_ARRAY_TYPE, +GL_PROXY_TEXTURE_1D_ARRAY, GL_ACCUM_ALPHA_BITS, GL_PIXEL_MAP_I_TO_G, GL_PIXEL_MAP_I_TO_B, GL_PIXEL_MAP_I_TO_A, +GL_COLOR_BUFFER_BIT, GL_PIXEL_MAP_I_TO_I, GL_SPOT_CUTOFF, GL_PIXEL_MAP_I_TO_R, GL_LINEAR_ATTENUATION, +GL_SAMPLER_2D, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, GL_NEAREST_MIPMAP_NEAREST, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, GL_EDGE_FLAG_ARRAY_STRIDE, +GL_TEXTURE_MAG_FILTER, GL_COLOR_MATERIAL_FACE, GL_CONTEXT_COMPATIBILITY_PROFILE_BIT, GL_SINGLE_COLOR, GL_R32I, +GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, GL_SAMPLER_CUBE, GL_INT_2_10_10_10_REV, GL_SAMPLER_CUBE_SHADOW, GL_LEFT, +GL_AND_INVERTED, GL_ACCUM_BLUE_BITS, GL_FRAMEBUFFER_SRGB, GL_SECONDARY_COLOR_ARRAY_TYPE, GL_POLYGON_OFFSET_POINT, +GL_BGR, GL_MAX_TEXTURE_SIZE, GL_COMBINE_ALPHA, GL_RIGHT, GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, +GL_ARRAY_BUFFER, GL_COMPRESSED_ALPHA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT16, GL_MAX_SAMPLE_MASK_WORDS, +GL_TEXTURE_COMPRESSED_IMAGE_SIZE, GL_TEXTURE_RED_SIZE, GL_TEXTURE_1D, GL_MAX_VARYING_COMPONENTS, GL_NAME_STACK_DEPTH, +GL_BLEND_SRC_RGB, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, GL_BGRA_INTEGER, GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, GL_FALSE, +GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, GL_ONE_MINUS_SRC_ALPHA, GL_SAMPLE_ALPHA_TO_ONE, GL_WEIGHT_ARRAY_BUFFER_BINDING, GL_COLOR_ATTACHMENT3, +GL_PIXEL_MAP_I_TO_G_SIZE, GL_MAP2_GRID_SEGMENTS, GL_PROGRAM_POINT_SIZE, GL_COLOR_ATTACHMENT16, GL_MAX_VIEWPORT_DIMS, +GL_DEPTH_ATTACHMENT, GL_INT_SAMPLER_2D, GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, GL_STENCIL_PASS_DEPTH_FAIL, GL_PIXEL_MAP_A_TO_A, +GL_TEXTURE_COORD_ARRAY_POINTER, GL_MAP1_GRID_SEGMENTS, GL_MAX_GEOMETRY_UNIFORM_BLOCKS, GL_ATTRIB_STACK_DEPTH, GL_LINE_WIDTH, +GL_FEEDBACK_BUFFER_SIZE, GL_BLUE_BIAS, GL_FIXED_ONLY, GL_NONE, GL_FRAMEBUFFER_DEFAULT, +GL_POLYGON_MODE, GL_HALF_FLOAT, GL_UNIFORM_BLOCK_NAME_LENGTH, GL_V2F, GL_TEXTURE_BINDING_RECTANGLE, +GL_LINE_SMOOTH_HINT, GL_CLAMP_TO_EDGE, GL_FRONT, GL_SCISSOR_BOX, GL_UNIFORM_BLOCK_DATA_SIZE, +GL_AMBIENT, GL_NUM_EXTENSIONS, GL_UNIFORM_IS_ROW_MAJOR, GL_MAX_UNIFORM_BLOCK_SIZE, GL_INDEX_ARRAY, +GL_FRAMEBUFFER_BINDING, GL_NORMAL_ARRAY_BUFFER_BINDING, GL_ALPHA, GL_SET, GL_COLOR_WRITEMASK, +GL_DEPTH_FUNC, GL_TEXTURE_WRAP_R, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TEXTURE9, +GL_INVALID_ENUM, GL_EVAL_BIT, GL_INT_SAMPLER_2D_ARRAY, GL_COMPRESSED_RGB, GL_LIGHT_MODEL_AMBIENT, +GL_DEPTH_COMPONENT, GL_SRC1_COLOR, GL_FOG_START, GL_WAIT_FAILED, GL_COMPARE_REF_TO_TEXTURE, +GL_PROJECTION_STACK_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_TRUE, GL_TEXTURE_MIN_FILTER, GL_FLOAT_MAT4, +GL_BLUE_BITS, GL_STACK_UNDERFLOW, GL_AUX1, GL_TEXTURE_SWIZZLE_R, GL_AUX3, +GL_AUX2, GL_PACK_SWAP_BYTES, GL_FIRST_VERTEX_CONVENTION, GL_EQUAL, GL_TEXTURE_SWIZZLE_G, +GL_DEPTH_STENCIL_ATTACHMENT, GL_TRIANGLE_STRIP_ADJACENCY, GL_ADD, GL_TEXTURE_BINDING_1D_ARRAY, GL_TEXTURE_SWIZZLE_B, +GL_TEXTURE_SWIZZLE_A, GL_FUNC_ADD, GL_MODELVIEW_STACK_DEPTH, GL_FLOAT_MAT4x3, GL_POINT_FADE_THRESHOLD_SIZE, +GL_INT_SAMPLER_BUFFER, GL_UNPACK_ALIGNMENT, GL_LINE_STRIP, GL_PACK_ROW_LENGTH, GL_COLOR_MATERIAL, +GL_MAX_PIXEL_MAP_TABLE, GL_COLOR, GL_POLYGON_STIPPLE, GL_BITMAP, GL_DYNAMIC_READ, +GL_COMPRESSED_LUMINANCE, GL_LUMINANCE12_ALPHA12, GL_DEPTH_STENCIL, GL_RG8UI, GL_MAX_VERTEX_OUTPUT_COMPONENTS, +GL_KEEP, GL_TEXTURE_INTENSITY_SIZE, GL_PROXY_TEXTURE_2D, GL_SYNC_CONDITION, GL_ACTIVE_UNIFORM_MAX_LENGTH, +GL_OR, GL_MAP_INVALIDATE_RANGE_BIT, GL_TEXTURE23, GL_TEXTURE22, GL_TEXTURE21, +GL_TEXTURE20, GL_TEXTURE27, GL_TEXTURE26, GL_TEXTURE25, GL_TEXTURE24, +GL_R8_SNORM, GL_TEXTURE29, GL_TEXTURE28, GL_SAMPLER_1D_ARRAY, GL_ELEMENT_ARRAY_BUFFER_BINDING, +GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER, GL_TRIANGLES_ADJACENCY, GL_PIXEL_MODE_BIT, GL_LINE_LOOP, GL_ALPHA_SCALE, +GL_READ_BUFFER, GL_PACK_SKIP_PIXELS, GL_BACK_RIGHT, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, GL_SUBPIXEL_BITS, +GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS, GL_GEQUAL, GL_ALPHA_TEST, GL_SLUMINANCE8_ALPHA8, GL_SAMPLER_2D_MULTISAMPLE, +GL_LUMINANCE4_ALPHA4, GL_RGBA8UI, GL_UNIFORM_OFFSET, GL_TEXTURE1, GL_OBJECT_PLANE, +GL_UNSIGNED_INT_SAMPLER_CUBE, GL_SUBTRACT, GL_TIME_ELAPSED, GL_SECONDARY_COLOR_ARRAY_SIZE, GL_COMPRESSED_RED_RGTC1, +GL_READ_WRITE, GL_BUFFER_ACCESS, GL_LINES_ADJACENCY, GL_ARRAY_BUFFER_BINDING, GL_INDEX_WRITEMASK, +GL_TEXTURE_2D, GL_VERTEX_ARRAY_STRIDE, GL_DYNAMIC_DRAW, GL_4D_COLOR_TEXTURE, GL_NICEST, +GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, GL_UNPACK_ROW_LENGTH, GL_CURRENT_PROGRAM, GL_BUFFER_MAPPED, GL_EYE_LINEAR, +GL_STREAM_DRAW, GL_POLYGON_SMOOTH_HINT, GL_INDEX, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_SIGNALED, +GL_FRAMEBUFFER, GL_SPECULAR, GL_TEXTURE_BINDING_2D, GL_GENERATE_MIPMAP, GL_DOMAIN, +GL_COLOR_ARRAY_SIZE, GL_STENCIL_BACK_FAIL, GL_POLYGON_OFFSET_FACTOR, GL_R8UI, GL_SYNC_FLUSH_COMMANDS_BIT, +GL_DRAW_FRAMEBUFFER_BINDING, GL_STATIC_DRAW, GL_MODELVIEW, GL_PIXEL_MAP_I_TO_B_SIZE, GL_TRIANGLES, +GL_SAMPLER_2D_ARRAY_SHADOW, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, GL_UNIFORM_MATRIX_STRIDE, GL_MAX_DEPTH_TEXTURE_SAMPLES, GL_QUERY_BY_REGION_WAIT, +GL_TEXTURE_RESIDENT, GL_SLUMINANCE, GL_SRGB8_ALPHA8, GL_FOG, GL_FOG_COORD, +GL_SAMPLER_2D_ARRAY, GL_POSITION, GL_RENDERER, GL_MIRRORED_REPEAT, GL_RG, +GL_PIXEL_MAP_B_TO_B, GL_LINE_STIPPLE_PATTERN, GL_STENCIL_BACK_FUNC, GL_PIXEL_MAP_R_TO_R_SIZE, GL_MAP1_TEXTURE_COORD_2, +GL_TEXTURE_BINDING_3D, GL_COLOR_LOGIC_OP, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, GL_UNIFORM_BLOCK_INDEX, GL_ENABLE_BIT, +GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, GL_MAX_VERTEX_ATTRIBS, GL_SPHERE_MAP, GL_CONSTANT, GL_LINE_WIDTH_RANGE, +GL_XOR, GL_PROJECTION, GL_LESS, GL_COPY_PIXEL_TOKEN, GL_FRAMEBUFFER_UNDEFINED, +GL_2_BYTES, GL_TEXTURE_STENCIL_SIZE, GL_CURRENT_RASTER_INDEX, GL_EMISSION, GL_COMPRESSED_SRGB, +GL_TEXTURE_DEPTH_TYPE, GL_TEXTURE_ENV_MODE, GL_COMPRESSED_LUMINANCE_ALPHA, GL_INT_SAMPLER_1D, GL_CURRENT_RASTER_COLOR, +GL_PROXY_TEXTURE_2D_ARRAY, GL_QUAD_STRIP, GL_REPEAT, GL_ACCUM, GL_T2F_C4F_N3F_V3F, +GL_TEXTURE_INTENSITY_TYPE, GL_INTENSITY16, GL_VERTEX_ARRAY_TYPE, GL_VERTEX_ARRAY_SIZE, GL_TEXTURE_GREEN_SIZE, +GL_CLIENT_ALL_ATTRIB_BITS, GL_VALIDATE_STATUS, GL_RG16, GL_LIGHT7, GL_STENCIL_BACK_VALUE_MASK, +GL_SCISSOR_TEST, GL_STENCIL_BUFFER_BIT, GL_TEXTURE_2D_MULTISAMPLE, GL_SAMPLER_1D_ARRAY_SHADOW, GL_SRC1_RGB, +GL_BLEND_EQUATION_ALPHA, GL_ACTIVE_ATTRIBUTES, GL_COLOR_ATTACHMENT31, GL_LIGHTING, GL_CURRENT_RASTER_DISTANCE, +GL_VERTEX_ARRAY_POINTER, GL_ATTACHED_SHADERS, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GL_QUERY_BY_REGION_NO_WAIT, GL_SAMPLE_COVERAGE_INVERT, +GL_LINES, GL_TEXTURE18, GL_TEXTURE19, GL_TEXTURE16, GL_TEXTURE17, +GL_TEXTURE14, GL_TEXTURE15, GL_TEXTURE12, GL_TEXTURE13, GL_TEXTURE10, +GL_TEXTURE11, GL_RGB, GL_SEPARATE_SPECULAR_COLOR, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_TRANSFORM_FEEDBACK_BUFFER_START, +GL_MAX_PROGRAM_TEXEL_OFFSET, GL_STACK_OVERFLOW, GL_MAP1_VERTEX_4, GL_TEXTURE_COMPRESSION_HINT, GL_RGBA32F, +GL_RGBA32I, GL_COLOR_ARRAY_BUFFER_BINDING, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_TRANSPOSE_COLOR_MATRIX, GL_STENCIL_WRITEMASK, +GL_RG8, GL_FOG_COORDINATE_ARRAY_POINTER, GL_STENCIL_BACK_PASS_DEPTH_PASS, GL_INVALID_VALUE, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, +GL_VERSION, GL_MAP_UNSYNCHRONIZED_BIT, GL_PRIMITIVE_RESTART, GL_COLOR_ARRAY_STRIDE, GL_MAX_ELEMENTS_INDICES, +GL_SRC_ALPHA, GL_TEXTURE_3D, GL_GEOMETRY_VERTICES_OUT, GL_RGB8, GL_INDEX_ARRAY_POINTER, +GL_MATRIX_MODE, GL_UNIFORM_ARRAY_STRIDE, GL_TEXTURE_SAMPLES, GL_RGB4, GL_RGB5, +GL_CULL_FACE, GL_PIXEL_MAP_I_TO_I_SIZE, GL_SAMPLE_COVERAGE_VALUE, GL_PROXY_TEXTURE_CUBE_MAP, GL_SECONDARY_COLOR_ARRAY_STRIDE, +GL_COMPRESSED_SIGNED_RG_RGTC2, GL_COLOR_INDEXES, GL_RG32UI, GL_OPERAND1_ALPHA, GL_NORMALIZE, +GL_NEVER, GL_STENCIL_VALUE_MASK, GL_BLEND_DST, GL_STENCIL_BACK_WRITEMASK, GL_BLUE_SCALE, +GL_TEXTURE_INTERNAL_FORMAT, GL_LOAD, GL_FRAMEBUFFER_COMPLETE, GL_COPY_READ_BUFFER, GL_INDEX_ARRAY_STRIDE, +GL_FOG_COORD_ARRAY_POINTER, GL_MAP2_VERTEX_3, GL_TEXTURE_SWIZZLE_RGBA, GL_DEPTH_COMPONENT32, GL_RGBA, +GL_READ_FRAMEBUFFER, GL_NORMAL_ARRAY, GL_COLOR_SUM, GL_BLEND_EQUATION_RGB, GL_MAP2_COLOR_4, +GL_VENDOR, GL_TEXTURE_2D_ARRAY, GL_ACCUM_BUFFER_BIT, GL_EDGE_FLAG, GL_OBJECT_TYPE, +GL_C4UB_V3F, GL_INTERPOLATE, GL_BUFFER_ACCESS_FLAGS, GL_LINK_STATUS, GL_PACK_SKIP_IMAGES, +GL_FLOAT_MAT2x3, GL_COMBINE, GL_FLOAT_MAT2x4, GL_Q, GL_SECONDARY_COLOR_ARRAY, +GL_INDEX_LOGIC_OP, GL_SEPARATE_ATTRIBS, GL_PRIMITIVES_GENERATED, GL_MAX, GL_LUMINANCE, +GL_INVALID_INDEX, GL_MAP2_VERTEX_4, GL_AUTO_NORMAL, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, GL_CURRENT_RASTER_SECONDARY_COLOR, +GL_SAMPLER_1D_SHADOW, GL_ACCUM_RED_BITS, GL_SAMPLER_2D_SHADOW, GL_TEXTURE_MATRIX, GL_TRANSPOSE_PROJECTION_MATRIX, +GL_CLIP_DISTANCE6, GL_RG16F, GL_MAX_NAME_STACK_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, GL_TEXTURE_BIT, +GL_RG16I, GL_WRITE_ONLY, GL_STENCIL_ATTACHMENT, GL_CLIENT_VERTEX_ARRAY_BIT, GL_SAMPLE_COVERAGE, +GL_INDEX_ARRAY_BUFFER_BINDING, GL_SHININESS, GL_DRAW_FRAMEBUFFER, GL_TEXTURE_LOD_BIAS, GL_RGB10_A2UI +; + diff --git a/demos/external/sources/glad/gl/gles2.d b/demos/external/sources/glad/gl/gles2.d new file mode 100644 index 0000000..18fea32 --- /dev/null +++ b/demos/external/sources/glad/gl/gles2.d @@ -0,0 +1,183 @@ +module glad.gl.gles2; + + +public import glad.gl.types; +public import glad.gl.funcs : +glUniformMatrix2fv, glBeginTransformFeedback, glFlush, glGetRenderbufferParameteriv, glClearColor, +glClearBufferiv, glStencilMaskSeparate, glGetVertexAttribPointerv, glLinkProgram, glBindTexture, +glGetStringi, glFenceSync, glUniform3ui, glFramebufferRenderbuffer, glGetString, +glCompressedTexSubImage3D, glDetachShader, glVertexAttribI4uiv, glEndQuery, glBindSampler, +glLineWidth, glUniform2fv, glGetIntegeri_v, glCompileShader, glGetTransformFeedbackVarying, +glDeleteTextures, glStencilOpSeparate, glStencilFuncSeparate, glBindBufferRange, glVertexAttrib4f, +glUniform2f, glRenderbufferStorage, glDeleteShader, glGetBufferParameteri64v, glDepthRangef, +glUniform4iv, glGetTexParameteriv, glClearStencil, glUniformMatrix2x3fv, glGetUniformiv, +glGenTransformFeedbacks, glGetVertexAttribIuiv, glSampleCoverage, glSamplerParameteri, glGenTextures, +glSamplerParameterf, glDepthFunc, glCompressedTexSubImage2D, glUniform1f, glGetVertexAttribfv, +glProgramBinary, glGetTexParameterfv, glCreateShader, glIsBuffer, glUniform1i, +glGenRenderbuffers, glCopyTexSubImage2D, glCompressedTexImage2D, glDisable, glUniform2i, +glBlendFuncSeparate, glGetProgramiv, glColorMask, glHint, glFramebufferTextureLayer, +glBlendEquation, glGetUniformLocation, glBindFramebuffer, glEndTransformFeedback, glCullFace, +glUniformMatrix3x2fv, glTexStorage2D, glUniform4fv, glGetInternalformativ, glDeleteProgram, +glIsSampler, glVertexAttribDivisor, glGenQueries, glWaitSync, glAttachShader, +glUniformMatrix4x3fv, glUniform3i, glClearBufferfv, glDeleteTransformFeedbacks, glShaderBinary, +glCheckFramebufferStatus, glTexSubImage3D, glGetInteger64i_v, glDeleteSamplers, glCopyTexImage2D, +glUniform3f, glBlitFramebuffer, glBindAttribLocation, glUniformMatrix4x2fv, glBlendEquationSeparate, +glDrawElements, glGetShaderSource, glUniform2iv, glGetQueryObjectuiv, glGenVertexArrays, +glBindBufferBase, glBufferSubData, glUniform1iv, glGetBufferParameteriv, glMapBufferRange, +glReadBuffer, glTexStorage3D, glClientWaitSync, glDrawArraysInstanced, glViewport, +glGenerateMipmap, glGetShaderiv, glUniformMatrix3x4fv, glUniform2ui, glVertexAttrib3f, +glGetActiveAttrib, glBlendColor, glGetShaderPrecisionFormat, glResumeTransformFeedback, glUnmapBuffer, +glGetUniformfv, glDisableVertexAttribArray, glShaderSource, glBindRenderbuffer, glDeleteRenderbuffers, +glIsSync, glReleaseShaderCompiler, glDeleteFramebuffers, glDrawArrays, glUniform1ui, +glIsProgram, glTexSubImage2D, glGetSynciv, glVertexAttrib1fv, glClear, +glVertexAttrib4fv, glProgramParameteri, glIsTransformFeedback, glUniform4i, glActiveTexture, +glEnableVertexAttribArray, glDrawRangeElements, glBindBuffer, glIsEnabled, glStencilOp, +glReadPixels, glStencilMask, glUniform4f, glFramebufferTexture2D, glGetFramebufferAttachmentParameteriv, +glUniformMatrix2x4fv, glUniform3fv, glBufferData, glCompressedTexImage3D, glDeleteSync, +glPauseTransformFeedback, glGetError, glGetActiveUniformBlockName, glGetVertexAttribiv, glTexParameteriv, +glGetProgramBinary, glVertexAttrib3fv, glGetFloatv, glUniform3iv, glVertexAttrib2fv, +glGetShaderInfoLog, glGenFramebuffers, glDrawBuffers, glGetActiveUniformBlockiv, glStencilFunc, +glGetIntegerv, glGetAttachedShaders, glUniformBlockBinding, glIsRenderbuffer, glGetBufferPointerv, +glDeleteVertexArrays, glIsShader, glRenderbufferStorageMultisample, glUniform4uiv, glIsQuery, +glIsVertexArray, glUseProgram, glVertexAttribI4iv, glGetQueryiv, glTexImage2D, +glGetProgramInfoLog, glGetSamplerParameterfv, glBindTransformFeedback, glUniform4ui, glSamplerParameterfv, +glClearBufferuiv, glBindVertexArray, glIsTexture, glGetUniformIndices, glUniform1fv, +glGetInteger64v, glVertexAttribPointer, glTexParameterfv, glInvalidateSubFramebuffer, glUniformMatrix3fv, +glScissor, glEnable, glGetActiveUniformsiv, glVertexAttribI4i, glVertexAttribI4ui, +glGetFragDataLocation, glUniform2uiv, glGenBuffers, glFinish, glGetAttribLocation, +glBeginQuery, glVertexAttribIPointer, glBlendFunc, glCreateProgram, glTexImage3D, +glGenSamplers, glGetSamplerParameteriv, glIsFramebuffer, glFlushMappedBufferRange, glUniformMatrix4fv, +glCopyBufferSubData, glInvalidateFramebuffer, glUniform1uiv, glTransformFeedbackVaryings, glVertexAttrib2f, +glVertexAttrib1f, glCopyTexSubImage3D, glDepthMask, glGetUniformuiv, glGetUniformBlockIndex, +glGetVertexAttribIiv, glGetActiveUniform, glTexParameterf, glClearBufferfi, glTexParameteri, +glFrontFace, glClearDepthf, glDeleteBuffers, glSamplerParameteriv, glDrawElementsInstanced, +glGetBooleanv, glPixelStorei, glValidateProgram, glPolygonOffset, glDeleteQueries, +glUniform3uiv; + +public import glad.gl.enums : +GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4, GL_UNSIGNED_SHORT_5_6_5, +GL_VERTEX_ATTRIB_ARRAY_SIZE, GL_DEPTH_ATTACHMENT, GL_DITHER, GL_TRANSFORM_FEEDBACK_PAUSED, GL_RGB16UI, +GL_QUERY_RESULT, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, +GL_FLOAT, GL_RGB32UI, GL_TEXTURE_MAX_LOD, GL_BUFFER_MAP_OFFSET, GL_BUFFER_SIZE, +GL_RGB9_E5, GL_UNIFORM_BUFFER_START, GL_COMPRESSED_R11_EAC, GL_RGBA32UI, GL_UNSIGNED_INT_SAMPLER_2D, +GL_TEXTURE_MIN_LOD, GL_TEXTURE8, GL_TEXTURE9, GL_TEXTURE4, GL_TEXTURE5, +GL_TEXTURE6, GL_TEXTURE7, GL_TEXTURE0, GL_LINEAR_MIPMAP_LINEAR, GL_TEXTURE2, +GL_TEXTURE3, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_BLEND_EQUATION, GL_BYTE, +GL_BOOL_VEC3, GL_BOOL_VEC2, GL_TIMEOUT_IGNORED, GL_MAX_VARYING_VECTORS, GL_RENDERBUFFER_SAMPLES, +GL_ONE, GL_RG, GL_COLOR_CLEAR_VALUE, GL_MAX_SAMPLES, GL_BUFFER_USAGE, +GL_UNPACK_IMAGE_HEIGHT, GL_FLOAT_MAT3x2, GL_TRIANGLE_STRIP, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, +GL_FLOAT_MAT3x4, GL_COLOR_ATTACHMENT28, GL_COLOR_ATTACHMENT29, GL_COLOR_ATTACHMENT24, GL_COLOR_ATTACHMENT25, +GL_COLOR_ATTACHMENT26, GL_COLOR_ATTACHMENT27, GL_COLOR_ATTACHMENT20, GL_COLOR_ATTACHMENT21, GL_COLOR_ATTACHMENT22, +GL_COLOR_ATTACHMENT23, GL_TRANSFORM_FEEDBACK_BUFFER, GL_VERTEX_ARRAY_BINDING, GL_UNSIGNED_SHORT_5_5_5_1, GL_TIMEOUT_EXPIRED, +GL_COMPRESSED_RGB8_ETC2, GL_SIGNED_NORMALIZED, GL_STENCIL_FUNC, GL_MAX_TEXTURE_LOD_BIAS, GL_ALIASED_LINE_WIDTH_RANGE, +GL_DECR, GL_BACK, GL_TEXTURE_COMPARE_FUNC, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, GL_INT, +GL_COMPRESSED_SIGNED_RG11_EAC, GL_POLYGON_OFFSET_FILL, GL_MINOR_VERSION, GL_FRONT_AND_BACK, GL_R8, +GL_RGB_INTEGER, GL_STENCIL_CLEAR_VALUE, GL_SRGB, GL_GREEN_BITS, GL_SYNC_FENCE, +GL_ONE_MINUS_CONSTANT_COLOR, GL_SHADING_LANGUAGE_VERSION, GL_RGB8_SNORM, GL_UNPACK_SKIP_PIXELS, GL_TEXTURE_IMMUTABLE_LEVELS, +GL_FRAGMENT_SHADER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, GL_FRAGMENT_SHADER_DERIVATIVE_HINT, +GL_NO_ERROR, GL_VIEWPORT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, GL_BLEND_SRC_ALPHA, GL_DRAW_BUFFER6, +GL_DRAW_BUFFER7, GL_DRAW_BUFFER4, GL_DRAW_BUFFER5, GL_DRAW_BUFFER2, GL_DRAW_BUFFER3, +GL_DRAW_BUFFER0, GL_DRAW_BUFFER1, GL_COMPRESSED_SRGB8_ETC2, GL_QUERY_RESULT_AVAILABLE, GL_DRAW_BUFFER8, +GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, GL_MAX_DRAW_BUFFERS, GL_KEEP, GL_DELETE_STATUS, GL_R32UI, +GL_RGBA8_SNORM, GL_INT_SAMPLER_3D, GL_SRC_COLOR, GL_SAMPLER_BINDING, GL_DEPTH24_STENCIL8, +GL_SAMPLE_BUFFERS, GL_MAJOR_VERSION, GL_STATIC_COPY, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, GL_EXTENSIONS, +GL_UNIFORM_BUFFER_BINDING, GL_UNIFORM_TYPE, GL_COPY_READ_BUFFER_BINDING, GL_TEXTURE_COMPARE_MODE, GL_ANY_SAMPLES_PASSED, +GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BACK_PASS_DEPTH_FAIL, GL_UNIFORM_BUFFER, GL_MAP_WRITE_BIT, +GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_ALIASED_POINT_SIZE_RANGE, GL_CCW, GL_MAP_INVALIDATE_BUFFER_BIT, GL_DEPTH_COMPONENT24, +GL_UNSIGNED_INT_5_9_9_9_REV, GL_DEPTH_TEST, GL_SYNC_GPU_COMMANDS_COMPLETE, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, +GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_STREAM_READ, GL_LINEAR, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_FUNC_SUBTRACT, +GL_R32F, GL_MAX_VARYING_COMPONENTS, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, GL_IMPLEMENTATION_COLOR_READ_FORMAT, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, +GL_MAX_ELEMENT_INDEX, GL_COLOR_ATTACHMENT15, GL_COLOR_ATTACHMENT14, GL_HIGH_FLOAT, GL_DEPTH_RANGE, +GL_GREATER, GL_CLAMP_TO_EDGE, GL_COLOR_ATTACHMENT13, GL_COLOR_ATTACHMENT12, GL_NEAREST, +GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_COLOR_ATTACHMENT19, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, GL_MAX_TEXTURE_IMAGE_UNITS, GL_RGB32F, +GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FRONT_FACE, GL_DEPTH, GL_FLOAT_MAT4, +GL_RENDERBUFFER_GREEN_SIZE, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, GL_TEXTURE30, GL_TEXTURE31, +GL_RG8I, GL_RGBA8I, GL_RG8UI, GL_DEPTH_CLEAR_VALUE, GL_BUFFER_MAP_POINTER, +GL_RENDERBUFFER_BINDING, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_STENCIL_REF, GL_MAX_3D_TEXTURE_SIZE, GL_COPY_WRITE_BUFFER_BINDING, +GL_COPY_WRITE_BUFFER, GL_BLEND, GL_MIRRORED_REPEAT, GL_R16UI, GL_TEXTURE_BINDING_3D, +GL_UNSIGNED_SHORT, GL_MIN, GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_TEXTURE, +GL_COLOR_BUFFER_BIT, GL_DONT_CARE, GL_ACTIVE_UNIFORMS, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_MAX_VERTEX_UNIFORM_VECTORS, +GL_TEXTURE_BINDING_CUBE_MAP, GL_SAMPLER_2D, GL_INVALID_VALUE, GL_DRAW_BUFFER12, GL_NEAREST_MIPMAP_NEAREST, +GL_NUM_COMPRESSED_TEXTURE_FORMATS, GL_PACK_SKIP_ROWS, GL_TEXTURE_MAG_FILTER, GL_TEXTURE1, GL_BLEND_EQUATION_RGB, +GL_LINK_STATUS, GL_TEXTURE_MAX_LEVEL, GL_R32I, GL_BLEND_COLOR, GL_ALPHA_BITS, +GL_BOOL_VEC4, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, GL_ONE_MINUS_CONSTANT_ALPHA, GL_NEAREST_MIPMAP_LINEAR, GL_INT_2_10_10_10_REV, +GL_SAMPLER_CUBE_SHADOW, GL_WAIT_FAILED, GL_MAX_TEXTURE_SIZE, GL_RG32F, GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, +GL_ARRAY_BUFFER, GL_DEPTH_COMPONENT16, GL_UNSIGNALED, GL_RGB32I, GL_BLEND_SRC_RGB, +GL_FRAMEBUFFER_UNDEFINED, GL_SYNC_FLAGS, GL_FALSE, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, GL_ONE_MINUS_SRC_ALPHA, +GL_RG32I, GL_RENDERBUFFER_INTERNAL_FORMAT, GL_NUM_SHADER_BINARY_FORMATS, GL_RGBA16I, GL_R8I, +GL_SAMPLE_ALPHA_TO_COVERAGE, GL_INT_SAMPLER_2D, GL_STENCIL_BITS, GL_STENCIL_PASS_DEPTH_FAIL, GL_RED, +GL_FUNC_REVERSE_SUBTRACT, GL_RGBA8UI, GL_GREEN, GL_INVALID_OPERATION, GL_RED_INTEGER, +GL_NONE, GL_STENCIL_BACK_PASS_DEPTH_PASS, GL_COLOR_ATTACHMENT5, GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, GL_COLOR_ATTACHMENT7, +GL_UNIFORM_BLOCK_NAME_LENGTH, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT2, +GL_UNIFORM_BLOCK_INDEX, GL_FRAMEBUFFER_DEFAULT, GL_RGBA16UI, GL_COLOR_ATTACHMENT9, GL_COLOR_ATTACHMENT8, +GL_COLOR_ATTACHMENT10, GL_FRONT, GL_SCISSOR_BOX, GL_UNIFORM_BLOCK_DATA_SIZE, GL_DEPTH_WRITEMASK, +GL_CULL_FACE_MODE, GL_MAX_FRAGMENT_UNIFORM_VECTORS, GL_NUM_EXTENSIONS, GL_UNIFORM_IS_ROW_MAJOR, GL_MAX_UNIFORM_BLOCK_SIZE, +GL_BOOL, GL_MAX_COMBINED_UNIFORM_BLOCKS, GL_FRAMEBUFFER_BINDING, GL_UNSIGNED_INT_24_8, GL_COMPRESSED_TEXTURE_FORMATS, +GL_ALPHA, GL_COLOR_WRITEMASK, GL_DST_COLOR, GL_UNSIGNED_INT, GL_DEPTH_FUNC, +GL_ALWAYS, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_INVALID_ENUM, GL_PROGRAM_BINARY_LENGTH, +GL_STENCIL_BACK_VALUE_MASK, GL_INT_SAMPLER_2D_ARRAY, GL_DEPTH_COMPONENT, GL_SCISSOR_TEST, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, +GL_SHADER_TYPE, GL_COMPARE_REF_TO_TEXTURE, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_TRUE, +GL_TEXTURE_MIN_FILTER, GL_REPLACE, GL_BLUE_BITS, GL_RG_INTEGER, GL_TEXTURE_SWIZZLE_R, +GL_VERTEX_ATTRIB_ARRAY_STRIDE, GL_EQUAL, GL_TEXTURE_SWIZZLE_G, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_HEIGHT, +GL_RG16UI, GL_INTERLEAVED_ATTRIBS, GL_TEXTURE_SWIZZLE_A, GL_POLYGON_OFFSET_UNITS, GL_LOW_FLOAT, +GL_HALF_FLOAT, GL_FLOAT_MAT4x3, GL_DYNAMIC_COPY, GL_COLOR_ATTACHMENT6, GL_UNPACK_ALIGNMENT, +GL_ALREADY_SIGNALED, GL_LINE_STRIP, GL_STREAM_COPY, GL_PACK_ROW_LENGTH, GL_NUM_SAMPLE_COUNTS, +GL_MEDIUM_INT, GL_TEXTURE_CUBE_MAP, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, GL_COLOR, GL_RENDERBUFFER_DEPTH_SIZE, +GL_DYNAMIC_READ, GL_PROGRAM_BINARY_FORMATS, GL_LOW_INT, GL_DEPTH_STENCIL, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, +GL_MAX_VERTEX_OUTPUT_COMPONENTS, GL_POINTS, GL_COMPRESSED_RG11_EAC, GL_RENDERBUFFER_BLUE_SIZE, GL_UNIFORM_NAME_LENGTH, +GL_FASTEST, GL_SYNC_CONDITION, GL_ACTIVE_UNIFORM_MAX_LENGTH, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, GL_MAP_INVALIDATE_RANGE_BIT, +GL_TEXTURE23, GL_TEXTURE22, GL_TEXTURE21, GL_TEXTURE20, GL_TEXTURE27, +GL_TEXTURE26, GL_TEXTURE25, GL_TEXTURE24, GL_R8_SNORM, GL_TEXTURE29, +GL_TEXTURE28, GL_ELEMENT_ARRAY_BUFFER_BINDING, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, +GL_LINE_LOOP, GL_READ_BUFFER, GL_MAP_FLUSH_EXPLICIT_BIT, GL_PACK_SKIP_PIXELS, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, +GL_SUBPIXEL_BITS, GL_R16F, GL_GEQUAL, GL_READ_FRAMEBUFFER, GL_UNIFORM_BLOCK_BINDING, +GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, GL_LINE_WIDTH, GL_UNIFORM_OFFSET, GL_LEQUAL, GL_TRANSFORM_FEEDBACK, +GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_INT_SAMPLER_CUBE, GL_COLOR_ATTACHMENT4, GL_UNIFORM_SIZE, GL_FUNC_ADD, +GL_FLOAT_MAT4x2, GL_SHADER_SOURCE_LENGTH, GL_CURRENT_VERTEX_ATTRIB, GL_ARRAY_BUFFER_BINDING, GL_TEXTURE_2D, +GL_DYNAMIC_DRAW, GL_OUT_OF_MEMORY, GL_NICEST, GL_IMPLEMENTATION_COLOR_READ_TYPE, GL_UNPACK_ROW_LENGTH, +GL_CURRENT_PROGRAM, GL_BUFFER_MAPPED, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, GL_RASTERIZER_DISCARD, GL_NUM_PROGRAM_BINARY_FORMATS, +GL_STREAM_DRAW, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_SIGNALED, GL_FRAMEBUFFER, +GL_UNPACK_SKIP_ROWS, GL_MEDIUM_FLOAT, GL_STENCIL_TEST, GL_R11F_G11F_B10F, GL_SRGB8, +GL_LUMINANCE_ALPHA, GL_PIXEL_UNPACK_BUFFER_BINDING, GL_INVERT, GL_STENCIL_BACK_FAIL, GL_POLYGON_OFFSET_FACTOR, +GL_TRANSFORM_FEEDBACK_VARYINGS, GL_DEPTH_COMPONENT32F, GL_TRIANGLE_FAN, GL_SYNC_FLUSH_COMMANDS_BIT, GL_ONE_MINUS_DST_ALPHA, +GL_DRAW_FRAMEBUFFER_BINDING, GL_MAX_ELEMENTS_VERTICES, GL_STENCIL_BACK_WRITEMASK, GL_INVALID_FRAMEBUFFER_OPERATION, GL_BUFFER_ACCESS_FLAGS, +GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNIFORM_BUFFER_SIZE, GL_TRIANGLES, GL_SAMPLER_2D_ARRAY_SHADOW, GL_DEPTH32F_STENCIL8, +GL_MAX_ARRAY_TEXTURE_LAYERS, GL_RED_BITS, GL_UNIFORM_MATRIX_STRIDE, GL_MAX_SERVER_WAIT_TIMEOUT, GL_SRGB8_ALPHA8, +GL_RGBA16F, GL_PACK_ALIGNMENT, GL_SAMPLER_2D_ARRAY, GL_RENDERER, GL_MAX_COLOR_ATTACHMENTS, +GL_ACTIVE_UNIFORM_BLOCKS, GL_UNPACK_SKIP_IMAGES, GL_STENCIL_BACK_FUNC, GL_RGB16I, GL_ACTIVE_TEXTURE, +GL_TEXTURE_BASE_LEVEL, GL_RGB16F, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_INT_SAMPLER_3D, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, +GL_TEXTURE_WRAP_R, GL_INT_VEC4, GL_INT_VEC3, GL_INT_VEC2, GL_STENCIL_FAIL, +GL_MAX_VERTEX_ATTRIBS, GL_CONDITION_SATISFIED, GL_TEXTURE_IMMUTABLE_FORMAT, GL_FRAMEBUFFER_UNSUPPORTED, GL_DST_ALPHA, +GL_LESS, GL_MAX_CUBE_MAP_TEXTURE_SIZE, GL_RGB565, GL_TRANSFORM_FEEDBACK_BINDING, GL_RENDERBUFFER_WIDTH, +GL_READ_FRAMEBUFFER_BINDING, GL_RGBA4, GL_DRAW_BUFFER10, GL_DRAW_BUFFER11, GL_RGBA8, +GL_DRAW_BUFFER13, GL_DRAW_BUFFER14, GL_DRAW_BUFFER15, GL_INFO_LOG_LENGTH, GL_PRIMITIVE_RESTART_FIXED_INDEX, +GL_SRC_ALPHA_SATURATE, GL_RENDERBUFFER_STENCIL_SIZE, GL_REPEAT, GL_R16I, GL_RG8_SNORM, +GL_PIXEL_PACK_BUFFER, GL_STATIC_READ, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, GL_VALIDATE_STATUS, +GL_MAP_READ_BIT, GL_STENCIL, GL_STENCIL_BUFFER_BIT, GL_TEXTURE_SWIZZLE_B, GL_COLOR_ATTACHMENT17, +GL_BLEND_EQUATION_ALPHA, GL_RGBA_INTEGER, GL_ACTIVE_ATTRIBUTES, GL_MAX_RENDERBUFFER_SIZE, GL_COLOR_ATTACHMENT31, +GL_COLOR_ATTACHMENT30, GL_STENCIL_PASS_DEPTH_PASS, GL_INCR_WRAP, GL_RENDERBUFFER_ALPHA_SIZE, GL_HIGH_INT, +GL_COLOR_ATTACHMENT16, GL_DECR_WRAP, GL_ATTACHED_SHADERS, GL_MAX_FRAGMENT_INPUT_COMPONENTS, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, +GL_LINES, GL_TEXTURE18, GL_TEXTURE19, GL_TEXTURE16, GL_TEXTURE17, +GL_TEXTURE14, GL_GENERATE_MIPMAP_HINT, GL_TEXTURE12, GL_COLOR_ATTACHMENT11, GL_TEXTURE10, +GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_BLEND_DST_ALPHA, GL_RGB, GL_INT_SAMPLER_CUBE, GL_CURRENT_QUERY, +GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_RGB5_A1, GL_VERTEX_SHADER, GL_TRANSFORM_FEEDBACK_BUFFER_START, GL_MAX_PROGRAM_TEXEL_OFFSET, +GL_SHADER_BINARY_FORMATS, GL_CONSTANT_COLOR, GL_RGBA32F, GL_RGBA32I, GL_VERTEX_ATTRIB_ARRAY_TYPE, +GL_PIXEL_UNPACK_BUFFER, GL_LINEAR_MIPMAP_NEAREST, GL_STENCIL_WRITEMASK, GL_RG8, GL_RGB10_A2, +GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, GL_VERSION, GL_MAP_UNSYNCHRONIZED_BIT, GL_ZERO, GL_ELEMENT_ARRAY_BUFFER, +GL_SYNC_STATUS, GL_BUFFER_MAP_LENGTH, GL_MAX_ELEMENTS_INDICES, GL_UNSIGNED_NORMALIZED, GL_CONSTANT_ALPHA, +GL_SRC_ALPHA, GL_TEXTURE_3D, GL_FIXED, GL_RGB8, GL_SAMPLE_COVERAGE_INVERT, +GL_NOTEQUAL, GL_UNIFORM_ARRAY_STRIDE, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_INCR, GL_CULL_FACE, +GL_SAMPLE_COVERAGE_VALUE, GL_RENDERBUFFER_RED_SIZE, GL_MAX_VIEWPORT_DIMS, GL_RG32UI, GL_NEVER, +GL_TEXTURE15, GL_STENCIL_VALUE_MASK, GL_TEXTURE13, GL_DRAW_BUFFER9, GL_COMPILE_STATUS, +GL_FRAMEBUFFER_COMPLETE, GL_TEXTURE11, GL_COPY_READ_BUFFER, GL_SHADER_COMPILER, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, +GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_LUMINANCE, GL_RGBA, GL_SHORT, GL_BLUE, +GL_CW, GL_MIN_PROGRAM_TEXEL_OFFSET, GL_UNSIGNED_BYTE, GL_MAX_VERTEX_UNIFORM_COMPONENTS, GL_VENDOR, +GL_TEXTURE_2D_ARRAY, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_TEXTURE_BINDING_2D, GL_OBJECT_TYPE, GL_R8UI, +GL_STATIC_DRAW, GL_RENDERBUFFER, GL_FLOAT_MAT2x3, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, GL_FLOAT_MAT2x4, +GL_RGB8I, GL_COLOR_ATTACHMENT18, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, GL_TRANSFORM_FEEDBACK_ACTIVE, GL_SEPARATE_ATTRIBS, +GL_SAMPLER_3D, GL_MAX, GL_STENCIL_INDEX8, GL_DEPTH_BITS, GL_RGB8UI, +GL_STENCIL_BACK_REF, GL_INVALID_INDEX, GL_BLEND_DST_RGB, GL_SAMPLER_2D_SHADOW, GL_TEXTURE_BINDING_2D_ARRAY, +GL_RG16F, GL_SAMPLER_CUBE, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, GL_RG16I, +GL_PIXEL_PACK_BUFFER_BINDING, GL_STENCIL_ATTACHMENT, GL_SAMPLE_COVERAGE, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_DRAW_FRAMEBUFFER, +GL_RGB10_A2UI, GL_SAMPLES; + diff --git a/demos/external/sources/glad/gl/loader.d b/demos/external/sources/glad/gl/loader.d new file mode 100644 index 0000000..8bc904f --- /dev/null +++ b/demos/external/sources/glad/gl/loader.d @@ -0,0 +1,1323 @@ +module glad.gl.loader; + + +private import glad.gl.funcs; +private import glad.gl.ext; +private import glad.gl.enums; +private import glad.gl.types; +alias Loader = void* delegate(const(char)*); + +version(Windows) { + private import core.sys.windows.windows; +} else { + private import core.sys.posix.dlfcn; +} + +version(Windows) { + private __gshared HMODULE libGL; +} else { + private __gshared void* libGL; +} +extern(System) private @nogc alias gladGetProcAddressPtrType = void* function(const(char)*); +private __gshared gladGetProcAddressPtrType gladGetProcAddressPtr; + +private +bool open_gl() @nogc { + version(WebAssembly)return false; + else version(Windows) { + libGL = LoadLibraryA("opengl32.dll"); + if(libGL !is null) { + gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))GetProcAddress( + libGL, "wglGetProcAddress"); + return gladGetProcAddressPtr !is null; + } + + return false; + } else { + version(OSX) { + enum const(char)*[4] NAMES = [ + "../Frameworks/OpenGL.framework/OpenGL", + "/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" + ]; + } else { + enum const(char)*[2] NAMES = ["libGL.so.1", "libGL.so"]; + } + + foreach(name; NAMES) { + libGL = dlopen(name, RTLD_NOW | RTLD_GLOBAL); + if(libGL !is null) { + version(OSX) { + return true; + } else { + gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))dlsym(libGL, + "glXGetProcAddressARB"); + return gladGetProcAddressPtr !is null; + } + } + } + + return false; + } +} + +private +void* get_proc(const(char)* namez) @nogc { + if(libGL is null) return null; + void* result; + + if(gladGetProcAddressPtr !is null) { + result = gladGetProcAddressPtr(namez); + } + if(result is null) { + version(WebAssembly)return result; + else version(Windows) { + result = GetProcAddress(libGL, namez); + } else { + result = dlsym(libGL, namez); + } + } + + return result; +} + +private +void close_gl() @nogc { + version(WebAssembly){} + else version(Windows) { + if(libGL !is null) { + FreeLibrary(libGL); + libGL = null; + } + } else { + if(libGL !is null) { + dlclose(libGL); + libGL = null; + } + } +} + +bool gladLoadGL() { + bool status = false; + + if(open_gl()) { + status = gladLoadGL(x => get_proc(x)); + close_gl(); + } + + return status; +} + +__gshared struct GLVersion { __gshared int major = 0; __gshared int minor = 0; } +private extern(C) char* strstr(const(char)*, const(char)*) @nogc; +private extern(C) int strcmp(const(char)*, const(char)*) @nogc; +private extern(C) int strncmp(const(char)*, const(char)*, size_t) @nogc; +private extern(C) size_t strlen(const(char)*) @nogc; +private bool has_ext(const(char)* ext) @nogc { + if(GLVersion.major < 3) { + const(char)* extensions = cast(const(char)*)glGetString(GL_EXTENSIONS); + const(char)* loc; + const(char)* terminator; + + if(extensions is null || ext is null) { + return false; + } + + while(1) { + loc = strstr(extensions, ext); + if(loc is null) { + return false; + } + + terminator = loc + strlen(ext); + if((loc is extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return true; + } + extensions = terminator; + } + } else { + int num; + glGetIntegerv(GL_NUM_EXTENSIONS, &num); + + for(uint i=0; i < cast(uint)num; i++) { + if(strcmp(cast(const(char)*)glGetStringi(GL_EXTENSIONS, i), ext) == 0) { + return true; + } + } + } + + return false; +} +bool gladLoadGL(Loader load) { + glGetString = cast(typeof(glGetString))load("glGetString"); + if(glGetString is null) { return false; } + if(glGetString(GL_VERSION) is null) { return false; } + + find_coreGL(); + load_GL_VERSION_1_0(load); + load_GL_VERSION_1_1(load); + load_GL_VERSION_1_2(load); + load_GL_VERSION_1_3(load); + load_GL_VERSION_1_4(load); + load_GL_VERSION_1_5(load); + load_GL_VERSION_2_0(load); + load_GL_VERSION_2_1(load); + load_GL_VERSION_3_0(load); + load_GL_VERSION_3_1(load); + load_GL_VERSION_3_2(load); + load_GL_VERSION_3_3(load); + + find_extensionsGL(); + return GLVersion.major != 0 || GLVersion.minor != 0; +} + +private { + +void find_coreGL() { + + // Thank you @elmindreda + // https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 + // https://github.com/glfw/glfw/blob/master/src/context.c#L36 + int i; + const(char)* glversion; + const(char)*[3] prefixes = [ + "OpenGL ES-CM ".ptr, + "OpenGL ES-CL ".ptr, + "OpenGL ES ".ptr, + ]; + + glversion = cast(const(char)*)glGetString(GL_VERSION); + if (glversion is null) return; + + foreach(prefix; prefixes) { + size_t length = strlen(prefix); + if (strncmp(glversion, prefix, length) == 0) { + glversion += length; + break; + } + } + + int major = glversion[0] - '0'; + int minor = glversion[2] - '0'; + GLVersion.major = major; GLVersion.minor = minor; + GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + return; +} + +void find_extensionsGL() { + return; +} + +void load_GL_VERSION_1_0(Loader load) { + if(!GL_VERSION_1_0) return; + glCullFace = cast(typeof(glCullFace))load("glCullFace"); + glFrontFace = cast(typeof(glFrontFace))load("glFrontFace"); + glHint = cast(typeof(glHint))load("glHint"); + glLineWidth = cast(typeof(glLineWidth))load("glLineWidth"); + glPointSize = cast(typeof(glPointSize))load("glPointSize"); + glPolygonMode = cast(typeof(glPolygonMode))load("glPolygonMode"); + glScissor = cast(typeof(glScissor))load("glScissor"); + glTexParameterf = cast(typeof(glTexParameterf))load("glTexParameterf"); + glTexParameterfv = cast(typeof(glTexParameterfv))load("glTexParameterfv"); + glTexParameteri = cast(typeof(glTexParameteri))load("glTexParameteri"); + glTexParameteriv = cast(typeof(glTexParameteriv))load("glTexParameteriv"); + glTexImage1D = cast(typeof(glTexImage1D))load("glTexImage1D"); + glTexImage2D = cast(typeof(glTexImage2D))load("glTexImage2D"); + glDrawBuffer = cast(typeof(glDrawBuffer))load("glDrawBuffer"); + glClear = cast(typeof(glClear))load("glClear"); + glClearColor = cast(typeof(glClearColor))load("glClearColor"); + glClearStencil = cast(typeof(glClearStencil))load("glClearStencil"); + glClearDepth = cast(typeof(glClearDepth))load("glClearDepth"); + glStencilMask = cast(typeof(glStencilMask))load("glStencilMask"); + glColorMask = cast(typeof(glColorMask))load("glColorMask"); + glDepthMask = cast(typeof(glDepthMask))load("glDepthMask"); + glDisable = cast(typeof(glDisable))load("glDisable"); + glEnable = cast(typeof(glEnable))load("glEnable"); + glFinish = cast(typeof(glFinish))load("glFinish"); + glFlush = cast(typeof(glFlush))load("glFlush"); + glBlendFunc = cast(typeof(glBlendFunc))load("glBlendFunc"); + glLogicOp = cast(typeof(glLogicOp))load("glLogicOp"); + glStencilFunc = cast(typeof(glStencilFunc))load("glStencilFunc"); + glStencilOp = cast(typeof(glStencilOp))load("glStencilOp"); + glDepthFunc = cast(typeof(glDepthFunc))load("glDepthFunc"); + glPixelStoref = cast(typeof(glPixelStoref))load("glPixelStoref"); + glPixelStorei = cast(typeof(glPixelStorei))load("glPixelStorei"); + glReadBuffer = cast(typeof(glReadBuffer))load("glReadBuffer"); + glReadPixels = cast(typeof(glReadPixels))load("glReadPixels"); + glGetBooleanv = cast(typeof(glGetBooleanv))load("glGetBooleanv"); + glGetDoublev = cast(typeof(glGetDoublev))load("glGetDoublev"); + glGetError = cast(typeof(glGetError))load("glGetError"); + glGetFloatv = cast(typeof(glGetFloatv))load("glGetFloatv"); + glGetIntegerv = cast(typeof(glGetIntegerv))load("glGetIntegerv"); + glGetString = cast(typeof(glGetString))load("glGetString"); + glGetTexImage = cast(typeof(glGetTexImage))load("glGetTexImage"); + glGetTexParameterfv = cast(typeof(glGetTexParameterfv))load("glGetTexParameterfv"); + glGetTexParameteriv = cast(typeof(glGetTexParameteriv))load("glGetTexParameteriv"); + glGetTexLevelParameterfv = cast(typeof(glGetTexLevelParameterfv))load("glGetTexLevelParameterfv"); + glGetTexLevelParameteriv = cast(typeof(glGetTexLevelParameteriv))load("glGetTexLevelParameteriv"); + glIsEnabled = cast(typeof(glIsEnabled))load("glIsEnabled"); + glDepthRange = cast(typeof(glDepthRange))load("glDepthRange"); + glViewport = cast(typeof(glViewport))load("glViewport"); + glNewList = cast(typeof(glNewList))load("glNewList"); + glEndList = cast(typeof(glEndList))load("glEndList"); + glCallList = cast(typeof(glCallList))load("glCallList"); + glCallLists = cast(typeof(glCallLists))load("glCallLists"); + glDeleteLists = cast(typeof(glDeleteLists))load("glDeleteLists"); + glGenLists = cast(typeof(glGenLists))load("glGenLists"); + glListBase = cast(typeof(glListBase))load("glListBase"); + glBegin = cast(typeof(glBegin))load("glBegin"); + glBitmap = cast(typeof(glBitmap))load("glBitmap"); + glColor3b = cast(typeof(glColor3b))load("glColor3b"); + glColor3bv = cast(typeof(glColor3bv))load("glColor3bv"); + glColor3d = cast(typeof(glColor3d))load("glColor3d"); + glColor3dv = cast(typeof(glColor3dv))load("glColor3dv"); + glColor3f = cast(typeof(glColor3f))load("glColor3f"); + glColor3fv = cast(typeof(glColor3fv))load("glColor3fv"); + glColor3i = cast(typeof(glColor3i))load("glColor3i"); + glColor3iv = cast(typeof(glColor3iv))load("glColor3iv"); + glColor3s = cast(typeof(glColor3s))load("glColor3s"); + glColor3sv = cast(typeof(glColor3sv))load("glColor3sv"); + glColor3ub = cast(typeof(glColor3ub))load("glColor3ub"); + glColor3ubv = cast(typeof(glColor3ubv))load("glColor3ubv"); + glColor3ui = cast(typeof(glColor3ui))load("glColor3ui"); + glColor3uiv = cast(typeof(glColor3uiv))load("glColor3uiv"); + glColor3us = cast(typeof(glColor3us))load("glColor3us"); + glColor3usv = cast(typeof(glColor3usv))load("glColor3usv"); + glColor4b = cast(typeof(glColor4b))load("glColor4b"); + glColor4bv = cast(typeof(glColor4bv))load("glColor4bv"); + glColor4d = cast(typeof(glColor4d))load("glColor4d"); + glColor4dv = cast(typeof(glColor4dv))load("glColor4dv"); + glColor4f = cast(typeof(glColor4f))load("glColor4f"); + glColor4fv = cast(typeof(glColor4fv))load("glColor4fv"); + glColor4i = cast(typeof(glColor4i))load("glColor4i"); + glColor4iv = cast(typeof(glColor4iv))load("glColor4iv"); + glColor4s = cast(typeof(glColor4s))load("glColor4s"); + glColor4sv = cast(typeof(glColor4sv))load("glColor4sv"); + glColor4ub = cast(typeof(glColor4ub))load("glColor4ub"); + glColor4ubv = cast(typeof(glColor4ubv))load("glColor4ubv"); + glColor4ui = cast(typeof(glColor4ui))load("glColor4ui"); + glColor4uiv = cast(typeof(glColor4uiv))load("glColor4uiv"); + glColor4us = cast(typeof(glColor4us))load("glColor4us"); + glColor4usv = cast(typeof(glColor4usv))load("glColor4usv"); + glEdgeFlag = cast(typeof(glEdgeFlag))load("glEdgeFlag"); + glEdgeFlagv = cast(typeof(glEdgeFlagv))load("glEdgeFlagv"); + glEnd = cast(typeof(glEnd))load("glEnd"); + glIndexd = cast(typeof(glIndexd))load("glIndexd"); + glIndexdv = cast(typeof(glIndexdv))load("glIndexdv"); + glIndexf = cast(typeof(glIndexf))load("glIndexf"); + glIndexfv = cast(typeof(glIndexfv))load("glIndexfv"); + glIndexi = cast(typeof(glIndexi))load("glIndexi"); + glIndexiv = cast(typeof(glIndexiv))load("glIndexiv"); + glIndexs = cast(typeof(glIndexs))load("glIndexs"); + glIndexsv = cast(typeof(glIndexsv))load("glIndexsv"); + glNormal3b = cast(typeof(glNormal3b))load("glNormal3b"); + glNormal3bv = cast(typeof(glNormal3bv))load("glNormal3bv"); + glNormal3d = cast(typeof(glNormal3d))load("glNormal3d"); + glNormal3dv = cast(typeof(glNormal3dv))load("glNormal3dv"); + glNormal3f = cast(typeof(glNormal3f))load("glNormal3f"); + glNormal3fv = cast(typeof(glNormal3fv))load("glNormal3fv"); + glNormal3i = cast(typeof(glNormal3i))load("glNormal3i"); + glNormal3iv = cast(typeof(glNormal3iv))load("glNormal3iv"); + glNormal3s = cast(typeof(glNormal3s))load("glNormal3s"); + glNormal3sv = cast(typeof(glNormal3sv))load("glNormal3sv"); + glRasterPos2d = cast(typeof(glRasterPos2d))load("glRasterPos2d"); + glRasterPos2dv = cast(typeof(glRasterPos2dv))load("glRasterPos2dv"); + glRasterPos2f = cast(typeof(glRasterPos2f))load("glRasterPos2f"); + glRasterPos2fv = cast(typeof(glRasterPos2fv))load("glRasterPos2fv"); + glRasterPos2i = cast(typeof(glRasterPos2i))load("glRasterPos2i"); + glRasterPos2iv = cast(typeof(glRasterPos2iv))load("glRasterPos2iv"); + glRasterPos2s = cast(typeof(glRasterPos2s))load("glRasterPos2s"); + glRasterPos2sv = cast(typeof(glRasterPos2sv))load("glRasterPos2sv"); + glRasterPos3d = cast(typeof(glRasterPos3d))load("glRasterPos3d"); + glRasterPos3dv = cast(typeof(glRasterPos3dv))load("glRasterPos3dv"); + glRasterPos3f = cast(typeof(glRasterPos3f))load("glRasterPos3f"); + glRasterPos3fv = cast(typeof(glRasterPos3fv))load("glRasterPos3fv"); + glRasterPos3i = cast(typeof(glRasterPos3i))load("glRasterPos3i"); + glRasterPos3iv = cast(typeof(glRasterPos3iv))load("glRasterPos3iv"); + glRasterPos3s = cast(typeof(glRasterPos3s))load("glRasterPos3s"); + glRasterPos3sv = cast(typeof(glRasterPos3sv))load("glRasterPos3sv"); + glRasterPos4d = cast(typeof(glRasterPos4d))load("glRasterPos4d"); + glRasterPos4dv = cast(typeof(glRasterPos4dv))load("glRasterPos4dv"); + glRasterPos4f = cast(typeof(glRasterPos4f))load("glRasterPos4f"); + glRasterPos4fv = cast(typeof(glRasterPos4fv))load("glRasterPos4fv"); + glRasterPos4i = cast(typeof(glRasterPos4i))load("glRasterPos4i"); + glRasterPos4iv = cast(typeof(glRasterPos4iv))load("glRasterPos4iv"); + glRasterPos4s = cast(typeof(glRasterPos4s))load("glRasterPos4s"); + glRasterPos4sv = cast(typeof(glRasterPos4sv))load("glRasterPos4sv"); + glRectd = cast(typeof(glRectd))load("glRectd"); + glRectdv = cast(typeof(glRectdv))load("glRectdv"); + glRectf = cast(typeof(glRectf))load("glRectf"); + glRectfv = cast(typeof(glRectfv))load("glRectfv"); + glRecti = cast(typeof(glRecti))load("glRecti"); + glRectiv = cast(typeof(glRectiv))load("glRectiv"); + glRects = cast(typeof(glRects))load("glRects"); + glRectsv = cast(typeof(glRectsv))load("glRectsv"); + glTexCoord1d = cast(typeof(glTexCoord1d))load("glTexCoord1d"); + glTexCoord1dv = cast(typeof(glTexCoord1dv))load("glTexCoord1dv"); + glTexCoord1f = cast(typeof(glTexCoord1f))load("glTexCoord1f"); + glTexCoord1fv = cast(typeof(glTexCoord1fv))load("glTexCoord1fv"); + glTexCoord1i = cast(typeof(glTexCoord1i))load("glTexCoord1i"); + glTexCoord1iv = cast(typeof(glTexCoord1iv))load("glTexCoord1iv"); + glTexCoord1s = cast(typeof(glTexCoord1s))load("glTexCoord1s"); + glTexCoord1sv = cast(typeof(glTexCoord1sv))load("glTexCoord1sv"); + glTexCoord2d = cast(typeof(glTexCoord2d))load("glTexCoord2d"); + glTexCoord2dv = cast(typeof(glTexCoord2dv))load("glTexCoord2dv"); + glTexCoord2f = cast(typeof(glTexCoord2f))load("glTexCoord2f"); + glTexCoord2fv = cast(typeof(glTexCoord2fv))load("glTexCoord2fv"); + glTexCoord2i = cast(typeof(glTexCoord2i))load("glTexCoord2i"); + glTexCoord2iv = cast(typeof(glTexCoord2iv))load("glTexCoord2iv"); + glTexCoord2s = cast(typeof(glTexCoord2s))load("glTexCoord2s"); + glTexCoord2sv = cast(typeof(glTexCoord2sv))load("glTexCoord2sv"); + glTexCoord3d = cast(typeof(glTexCoord3d))load("glTexCoord3d"); + glTexCoord3dv = cast(typeof(glTexCoord3dv))load("glTexCoord3dv"); + glTexCoord3f = cast(typeof(glTexCoord3f))load("glTexCoord3f"); + glTexCoord3fv = cast(typeof(glTexCoord3fv))load("glTexCoord3fv"); + glTexCoord3i = cast(typeof(glTexCoord3i))load("glTexCoord3i"); + glTexCoord3iv = cast(typeof(glTexCoord3iv))load("glTexCoord3iv"); + glTexCoord3s = cast(typeof(glTexCoord3s))load("glTexCoord3s"); + glTexCoord3sv = cast(typeof(glTexCoord3sv))load("glTexCoord3sv"); + glTexCoord4d = cast(typeof(glTexCoord4d))load("glTexCoord4d"); + glTexCoord4dv = cast(typeof(glTexCoord4dv))load("glTexCoord4dv"); + glTexCoord4f = cast(typeof(glTexCoord4f))load("glTexCoord4f"); + glTexCoord4fv = cast(typeof(glTexCoord4fv))load("glTexCoord4fv"); + glTexCoord4i = cast(typeof(glTexCoord4i))load("glTexCoord4i"); + glTexCoord4iv = cast(typeof(glTexCoord4iv))load("glTexCoord4iv"); + glTexCoord4s = cast(typeof(glTexCoord4s))load("glTexCoord4s"); + glTexCoord4sv = cast(typeof(glTexCoord4sv))load("glTexCoord4sv"); + glVertex2d = cast(typeof(glVertex2d))load("glVertex2d"); + glVertex2dv = cast(typeof(glVertex2dv))load("glVertex2dv"); + glVertex2f = cast(typeof(glVertex2f))load("glVertex2f"); + glVertex2fv = cast(typeof(glVertex2fv))load("glVertex2fv"); + glVertex2i = cast(typeof(glVertex2i))load("glVertex2i"); + glVertex2iv = cast(typeof(glVertex2iv))load("glVertex2iv"); + glVertex2s = cast(typeof(glVertex2s))load("glVertex2s"); + glVertex2sv = cast(typeof(glVertex2sv))load("glVertex2sv"); + glVertex3d = cast(typeof(glVertex3d))load("glVertex3d"); + glVertex3dv = cast(typeof(glVertex3dv))load("glVertex3dv"); + glVertex3f = cast(typeof(glVertex3f))load("glVertex3f"); + glVertex3fv = cast(typeof(glVertex3fv))load("glVertex3fv"); + glVertex3i = cast(typeof(glVertex3i))load("glVertex3i"); + glVertex3iv = cast(typeof(glVertex3iv))load("glVertex3iv"); + glVertex3s = cast(typeof(glVertex3s))load("glVertex3s"); + glVertex3sv = cast(typeof(glVertex3sv))load("glVertex3sv"); + glVertex4d = cast(typeof(glVertex4d))load("glVertex4d"); + glVertex4dv = cast(typeof(glVertex4dv))load("glVertex4dv"); + glVertex4f = cast(typeof(glVertex4f))load("glVertex4f"); + glVertex4fv = cast(typeof(glVertex4fv))load("glVertex4fv"); + glVertex4i = cast(typeof(glVertex4i))load("glVertex4i"); + glVertex4iv = cast(typeof(glVertex4iv))load("glVertex4iv"); + glVertex4s = cast(typeof(glVertex4s))load("glVertex4s"); + glVertex4sv = cast(typeof(glVertex4sv))load("glVertex4sv"); + glClipPlane = cast(typeof(glClipPlane))load("glClipPlane"); + glColorMaterial = cast(typeof(glColorMaterial))load("glColorMaterial"); + glFogf = cast(typeof(glFogf))load("glFogf"); + glFogfv = cast(typeof(glFogfv))load("glFogfv"); + glFogi = cast(typeof(glFogi))load("glFogi"); + glFogiv = cast(typeof(glFogiv))load("glFogiv"); + glLightf = cast(typeof(glLightf))load("glLightf"); + glLightfv = cast(typeof(glLightfv))load("glLightfv"); + glLighti = cast(typeof(glLighti))load("glLighti"); + glLightiv = cast(typeof(glLightiv))load("glLightiv"); + glLightModelf = cast(typeof(glLightModelf))load("glLightModelf"); + glLightModelfv = cast(typeof(glLightModelfv))load("glLightModelfv"); + glLightModeli = cast(typeof(glLightModeli))load("glLightModeli"); + glLightModeliv = cast(typeof(glLightModeliv))load("glLightModeliv"); + glLineStipple = cast(typeof(glLineStipple))load("glLineStipple"); + glMaterialf = cast(typeof(glMaterialf))load("glMaterialf"); + glMaterialfv = cast(typeof(glMaterialfv))load("glMaterialfv"); + glMateriali = cast(typeof(glMateriali))load("glMateriali"); + glMaterialiv = cast(typeof(glMaterialiv))load("glMaterialiv"); + glPolygonStipple = cast(typeof(glPolygonStipple))load("glPolygonStipple"); + glShadeModel = cast(typeof(glShadeModel))load("glShadeModel"); + glTexEnvf = cast(typeof(glTexEnvf))load("glTexEnvf"); + glTexEnvfv = cast(typeof(glTexEnvfv))load("glTexEnvfv"); + glTexEnvi = cast(typeof(glTexEnvi))load("glTexEnvi"); + glTexEnviv = cast(typeof(glTexEnviv))load("glTexEnviv"); + glTexGend = cast(typeof(glTexGend))load("glTexGend"); + glTexGendv = cast(typeof(glTexGendv))load("glTexGendv"); + glTexGenf = cast(typeof(glTexGenf))load("glTexGenf"); + glTexGenfv = cast(typeof(glTexGenfv))load("glTexGenfv"); + glTexGeni = cast(typeof(glTexGeni))load("glTexGeni"); + glTexGeniv = cast(typeof(glTexGeniv))load("glTexGeniv"); + glFeedbackBuffer = cast(typeof(glFeedbackBuffer))load("glFeedbackBuffer"); + glSelectBuffer = cast(typeof(glSelectBuffer))load("glSelectBuffer"); + glRenderMode = cast(typeof(glRenderMode))load("glRenderMode"); + glInitNames = cast(typeof(glInitNames))load("glInitNames"); + glLoadName = cast(typeof(glLoadName))load("glLoadName"); + glPassThrough = cast(typeof(glPassThrough))load("glPassThrough"); + glPopName = cast(typeof(glPopName))load("glPopName"); + glPushName = cast(typeof(glPushName))load("glPushName"); + glClearAccum = cast(typeof(glClearAccum))load("glClearAccum"); + glClearIndex = cast(typeof(glClearIndex))load("glClearIndex"); + glIndexMask = cast(typeof(glIndexMask))load("glIndexMask"); + glAccum = cast(typeof(glAccum))load("glAccum"); + glPopAttrib = cast(typeof(glPopAttrib))load("glPopAttrib"); + glPushAttrib = cast(typeof(glPushAttrib))load("glPushAttrib"); + glMap1d = cast(typeof(glMap1d))load("glMap1d"); + glMap1f = cast(typeof(glMap1f))load("glMap1f"); + glMap2d = cast(typeof(glMap2d))load("glMap2d"); + glMap2f = cast(typeof(glMap2f))load("glMap2f"); + glMapGrid1d = cast(typeof(glMapGrid1d))load("glMapGrid1d"); + glMapGrid1f = cast(typeof(glMapGrid1f))load("glMapGrid1f"); + glMapGrid2d = cast(typeof(glMapGrid2d))load("glMapGrid2d"); + glMapGrid2f = cast(typeof(glMapGrid2f))load("glMapGrid2f"); + glEvalCoord1d = cast(typeof(glEvalCoord1d))load("glEvalCoord1d"); + glEvalCoord1dv = cast(typeof(glEvalCoord1dv))load("glEvalCoord1dv"); + glEvalCoord1f = cast(typeof(glEvalCoord1f))load("glEvalCoord1f"); + glEvalCoord1fv = cast(typeof(glEvalCoord1fv))load("glEvalCoord1fv"); + glEvalCoord2d = cast(typeof(glEvalCoord2d))load("glEvalCoord2d"); + glEvalCoord2dv = cast(typeof(glEvalCoord2dv))load("glEvalCoord2dv"); + glEvalCoord2f = cast(typeof(glEvalCoord2f))load("glEvalCoord2f"); + glEvalCoord2fv = cast(typeof(glEvalCoord2fv))load("glEvalCoord2fv"); + glEvalMesh1 = cast(typeof(glEvalMesh1))load("glEvalMesh1"); + glEvalPoint1 = cast(typeof(glEvalPoint1))load("glEvalPoint1"); + glEvalMesh2 = cast(typeof(glEvalMesh2))load("glEvalMesh2"); + glEvalPoint2 = cast(typeof(glEvalPoint2))load("glEvalPoint2"); + glAlphaFunc = cast(typeof(glAlphaFunc))load("glAlphaFunc"); + glPixelZoom = cast(typeof(glPixelZoom))load("glPixelZoom"); + glPixelTransferf = cast(typeof(glPixelTransferf))load("glPixelTransferf"); + glPixelTransferi = cast(typeof(glPixelTransferi))load("glPixelTransferi"); + glPixelMapfv = cast(typeof(glPixelMapfv))load("glPixelMapfv"); + glPixelMapuiv = cast(typeof(glPixelMapuiv))load("glPixelMapuiv"); + glPixelMapusv = cast(typeof(glPixelMapusv))load("glPixelMapusv"); + glCopyPixels = cast(typeof(glCopyPixels))load("glCopyPixels"); + glDrawPixels = cast(typeof(glDrawPixels))load("glDrawPixels"); + glGetClipPlane = cast(typeof(glGetClipPlane))load("glGetClipPlane"); + glGetLightfv = cast(typeof(glGetLightfv))load("glGetLightfv"); + glGetLightiv = cast(typeof(glGetLightiv))load("glGetLightiv"); + glGetMapdv = cast(typeof(glGetMapdv))load("glGetMapdv"); + glGetMapfv = cast(typeof(glGetMapfv))load("glGetMapfv"); + glGetMapiv = cast(typeof(glGetMapiv))load("glGetMapiv"); + glGetMaterialfv = cast(typeof(glGetMaterialfv))load("glGetMaterialfv"); + glGetMaterialiv = cast(typeof(glGetMaterialiv))load("glGetMaterialiv"); + glGetPixelMapfv = cast(typeof(glGetPixelMapfv))load("glGetPixelMapfv"); + glGetPixelMapuiv = cast(typeof(glGetPixelMapuiv))load("glGetPixelMapuiv"); + glGetPixelMapusv = cast(typeof(glGetPixelMapusv))load("glGetPixelMapusv"); + glGetPolygonStipple = cast(typeof(glGetPolygonStipple))load("glGetPolygonStipple"); + glGetTexEnvfv = cast(typeof(glGetTexEnvfv))load("glGetTexEnvfv"); + glGetTexEnviv = cast(typeof(glGetTexEnviv))load("glGetTexEnviv"); + glGetTexGendv = cast(typeof(glGetTexGendv))load("glGetTexGendv"); + glGetTexGenfv = cast(typeof(glGetTexGenfv))load("glGetTexGenfv"); + glGetTexGeniv = cast(typeof(glGetTexGeniv))load("glGetTexGeniv"); + glIsList = cast(typeof(glIsList))load("glIsList"); + glFrustum = cast(typeof(glFrustum))load("glFrustum"); + glLoadIdentity = cast(typeof(glLoadIdentity))load("glLoadIdentity"); + glLoadMatrixf = cast(typeof(glLoadMatrixf))load("glLoadMatrixf"); + glLoadMatrixd = cast(typeof(glLoadMatrixd))load("glLoadMatrixd"); + glMatrixMode = cast(typeof(glMatrixMode))load("glMatrixMode"); + glMultMatrixf = cast(typeof(glMultMatrixf))load("glMultMatrixf"); + glMultMatrixd = cast(typeof(glMultMatrixd))load("glMultMatrixd"); + glOrtho = cast(typeof(glOrtho))load("glOrtho"); + glPopMatrix = cast(typeof(glPopMatrix))load("glPopMatrix"); + glPushMatrix = cast(typeof(glPushMatrix))load("glPushMatrix"); + glRotated = cast(typeof(glRotated))load("glRotated"); + glRotatef = cast(typeof(glRotatef))load("glRotatef"); + glScaled = cast(typeof(glScaled))load("glScaled"); + glScalef = cast(typeof(glScalef))load("glScalef"); + glTranslated = cast(typeof(glTranslated))load("glTranslated"); + glTranslatef = cast(typeof(glTranslatef))load("glTranslatef"); + return; +} + +void load_GL_VERSION_1_1(Loader load) { + if(!GL_VERSION_1_1) return; + glDrawArrays = cast(typeof(glDrawArrays))load("glDrawArrays"); + glDrawElements = cast(typeof(glDrawElements))load("glDrawElements"); + glGetPointerv = cast(typeof(glGetPointerv))load("glGetPointerv"); + glPolygonOffset = cast(typeof(glPolygonOffset))load("glPolygonOffset"); + glCopyTexImage1D = cast(typeof(glCopyTexImage1D))load("glCopyTexImage1D"); + glCopyTexImage2D = cast(typeof(glCopyTexImage2D))load("glCopyTexImage2D"); + glCopyTexSubImage1D = cast(typeof(glCopyTexSubImage1D))load("glCopyTexSubImage1D"); + glCopyTexSubImage2D = cast(typeof(glCopyTexSubImage2D))load("glCopyTexSubImage2D"); + glTexSubImage1D = cast(typeof(glTexSubImage1D))load("glTexSubImage1D"); + glTexSubImage2D = cast(typeof(glTexSubImage2D))load("glTexSubImage2D"); + glBindTexture = cast(typeof(glBindTexture))load("glBindTexture"); + glDeleteTextures = cast(typeof(glDeleteTextures))load("glDeleteTextures"); + glGenTextures = cast(typeof(glGenTextures))load("glGenTextures"); + glIsTexture = cast(typeof(glIsTexture))load("glIsTexture"); + glArrayElement = cast(typeof(glArrayElement))load("glArrayElement"); + glColorPointer = cast(typeof(glColorPointer))load("glColorPointer"); + glDisableClientState = cast(typeof(glDisableClientState))load("glDisableClientState"); + glEdgeFlagPointer = cast(typeof(glEdgeFlagPointer))load("glEdgeFlagPointer"); + glEnableClientState = cast(typeof(glEnableClientState))load("glEnableClientState"); + glIndexPointer = cast(typeof(glIndexPointer))load("glIndexPointer"); + glInterleavedArrays = cast(typeof(glInterleavedArrays))load("glInterleavedArrays"); + glNormalPointer = cast(typeof(glNormalPointer))load("glNormalPointer"); + glTexCoordPointer = cast(typeof(glTexCoordPointer))load("glTexCoordPointer"); + glVertexPointer = cast(typeof(glVertexPointer))load("glVertexPointer"); + glAreTexturesResident = cast(typeof(glAreTexturesResident))load("glAreTexturesResident"); + glPrioritizeTextures = cast(typeof(glPrioritizeTextures))load("glPrioritizeTextures"); + glIndexub = cast(typeof(glIndexub))load("glIndexub"); + glIndexubv = cast(typeof(glIndexubv))load("glIndexubv"); + glPopClientAttrib = cast(typeof(glPopClientAttrib))load("glPopClientAttrib"); + glPushClientAttrib = cast(typeof(glPushClientAttrib))load("glPushClientAttrib"); + return; +} + +void load_GL_VERSION_1_2(Loader load) { + if(!GL_VERSION_1_2) return; + glDrawRangeElements = cast(typeof(glDrawRangeElements))load("glDrawRangeElements"); + glTexImage3D = cast(typeof(glTexImage3D))load("glTexImage3D"); + glTexSubImage3D = cast(typeof(glTexSubImage3D))load("glTexSubImage3D"); + glCopyTexSubImage3D = cast(typeof(glCopyTexSubImage3D))load("glCopyTexSubImage3D"); + return; +} + +void load_GL_VERSION_1_3(Loader load) { + if(!GL_VERSION_1_3) return; + glActiveTexture = cast(typeof(glActiveTexture))load("glActiveTexture"); + glSampleCoverage = cast(typeof(glSampleCoverage))load("glSampleCoverage"); + glCompressedTexImage3D = cast(typeof(glCompressedTexImage3D))load("glCompressedTexImage3D"); + glCompressedTexImage2D = cast(typeof(glCompressedTexImage2D))load("glCompressedTexImage2D"); + glCompressedTexImage1D = cast(typeof(glCompressedTexImage1D))load("glCompressedTexImage1D"); + glCompressedTexSubImage3D = cast(typeof(glCompressedTexSubImage3D))load("glCompressedTexSubImage3D"); + glCompressedTexSubImage2D = cast(typeof(glCompressedTexSubImage2D))load("glCompressedTexSubImage2D"); + glCompressedTexSubImage1D = cast(typeof(glCompressedTexSubImage1D))load("glCompressedTexSubImage1D"); + glGetCompressedTexImage = cast(typeof(glGetCompressedTexImage))load("glGetCompressedTexImage"); + glClientActiveTexture = cast(typeof(glClientActiveTexture))load("glClientActiveTexture"); + glMultiTexCoord1d = cast(typeof(glMultiTexCoord1d))load("glMultiTexCoord1d"); + glMultiTexCoord1dv = cast(typeof(glMultiTexCoord1dv))load("glMultiTexCoord1dv"); + glMultiTexCoord1f = cast(typeof(glMultiTexCoord1f))load("glMultiTexCoord1f"); + glMultiTexCoord1fv = cast(typeof(glMultiTexCoord1fv))load("glMultiTexCoord1fv"); + glMultiTexCoord1i = cast(typeof(glMultiTexCoord1i))load("glMultiTexCoord1i"); + glMultiTexCoord1iv = cast(typeof(glMultiTexCoord1iv))load("glMultiTexCoord1iv"); + glMultiTexCoord1s = cast(typeof(glMultiTexCoord1s))load("glMultiTexCoord1s"); + glMultiTexCoord1sv = cast(typeof(glMultiTexCoord1sv))load("glMultiTexCoord1sv"); + glMultiTexCoord2d = cast(typeof(glMultiTexCoord2d))load("glMultiTexCoord2d"); + glMultiTexCoord2dv = cast(typeof(glMultiTexCoord2dv))load("glMultiTexCoord2dv"); + glMultiTexCoord2f = cast(typeof(glMultiTexCoord2f))load("glMultiTexCoord2f"); + glMultiTexCoord2fv = cast(typeof(glMultiTexCoord2fv))load("glMultiTexCoord2fv"); + glMultiTexCoord2i = cast(typeof(glMultiTexCoord2i))load("glMultiTexCoord2i"); + glMultiTexCoord2iv = cast(typeof(glMultiTexCoord2iv))load("glMultiTexCoord2iv"); + glMultiTexCoord2s = cast(typeof(glMultiTexCoord2s))load("glMultiTexCoord2s"); + glMultiTexCoord2sv = cast(typeof(glMultiTexCoord2sv))load("glMultiTexCoord2sv"); + glMultiTexCoord3d = cast(typeof(glMultiTexCoord3d))load("glMultiTexCoord3d"); + glMultiTexCoord3dv = cast(typeof(glMultiTexCoord3dv))load("glMultiTexCoord3dv"); + glMultiTexCoord3f = cast(typeof(glMultiTexCoord3f))load("glMultiTexCoord3f"); + glMultiTexCoord3fv = cast(typeof(glMultiTexCoord3fv))load("glMultiTexCoord3fv"); + glMultiTexCoord3i = cast(typeof(glMultiTexCoord3i))load("glMultiTexCoord3i"); + glMultiTexCoord3iv = cast(typeof(glMultiTexCoord3iv))load("glMultiTexCoord3iv"); + glMultiTexCoord3s = cast(typeof(glMultiTexCoord3s))load("glMultiTexCoord3s"); + glMultiTexCoord3sv = cast(typeof(glMultiTexCoord3sv))load("glMultiTexCoord3sv"); + glMultiTexCoord4d = cast(typeof(glMultiTexCoord4d))load("glMultiTexCoord4d"); + glMultiTexCoord4dv = cast(typeof(glMultiTexCoord4dv))load("glMultiTexCoord4dv"); + glMultiTexCoord4f = cast(typeof(glMultiTexCoord4f))load("glMultiTexCoord4f"); + glMultiTexCoord4fv = cast(typeof(glMultiTexCoord4fv))load("glMultiTexCoord4fv"); + glMultiTexCoord4i = cast(typeof(glMultiTexCoord4i))load("glMultiTexCoord4i"); + glMultiTexCoord4iv = cast(typeof(glMultiTexCoord4iv))load("glMultiTexCoord4iv"); + glMultiTexCoord4s = cast(typeof(glMultiTexCoord4s))load("glMultiTexCoord4s"); + glMultiTexCoord4sv = cast(typeof(glMultiTexCoord4sv))load("glMultiTexCoord4sv"); + glLoadTransposeMatrixf = cast(typeof(glLoadTransposeMatrixf))load("glLoadTransposeMatrixf"); + glLoadTransposeMatrixd = cast(typeof(glLoadTransposeMatrixd))load("glLoadTransposeMatrixd"); + glMultTransposeMatrixf = cast(typeof(glMultTransposeMatrixf))load("glMultTransposeMatrixf"); + glMultTransposeMatrixd = cast(typeof(glMultTransposeMatrixd))load("glMultTransposeMatrixd"); + return; +} + +void load_GL_VERSION_1_4(Loader load) { + if(!GL_VERSION_1_4) return; + glBlendFuncSeparate = cast(typeof(glBlendFuncSeparate))load("glBlendFuncSeparate"); + glMultiDrawArrays = cast(typeof(glMultiDrawArrays))load("glMultiDrawArrays"); + glMultiDrawElements = cast(typeof(glMultiDrawElements))load("glMultiDrawElements"); + glPointParameterf = cast(typeof(glPointParameterf))load("glPointParameterf"); + glPointParameterfv = cast(typeof(glPointParameterfv))load("glPointParameterfv"); + glPointParameteri = cast(typeof(glPointParameteri))load("glPointParameteri"); + glPointParameteriv = cast(typeof(glPointParameteriv))load("glPointParameteriv"); + glFogCoordf = cast(typeof(glFogCoordf))load("glFogCoordf"); + glFogCoordfv = cast(typeof(glFogCoordfv))load("glFogCoordfv"); + glFogCoordd = cast(typeof(glFogCoordd))load("glFogCoordd"); + glFogCoorddv = cast(typeof(glFogCoorddv))load("glFogCoorddv"); + glFogCoordPointer = cast(typeof(glFogCoordPointer))load("glFogCoordPointer"); + glSecondaryColor3b = cast(typeof(glSecondaryColor3b))load("glSecondaryColor3b"); + glSecondaryColor3bv = cast(typeof(glSecondaryColor3bv))load("glSecondaryColor3bv"); + glSecondaryColor3d = cast(typeof(glSecondaryColor3d))load("glSecondaryColor3d"); + glSecondaryColor3dv = cast(typeof(glSecondaryColor3dv))load("glSecondaryColor3dv"); + glSecondaryColor3f = cast(typeof(glSecondaryColor3f))load("glSecondaryColor3f"); + glSecondaryColor3fv = cast(typeof(glSecondaryColor3fv))load("glSecondaryColor3fv"); + glSecondaryColor3i = cast(typeof(glSecondaryColor3i))load("glSecondaryColor3i"); + glSecondaryColor3iv = cast(typeof(glSecondaryColor3iv))load("glSecondaryColor3iv"); + glSecondaryColor3s = cast(typeof(glSecondaryColor3s))load("glSecondaryColor3s"); + glSecondaryColor3sv = cast(typeof(glSecondaryColor3sv))load("glSecondaryColor3sv"); + glSecondaryColor3ub = cast(typeof(glSecondaryColor3ub))load("glSecondaryColor3ub"); + glSecondaryColor3ubv = cast(typeof(glSecondaryColor3ubv))load("glSecondaryColor3ubv"); + glSecondaryColor3ui = cast(typeof(glSecondaryColor3ui))load("glSecondaryColor3ui"); + glSecondaryColor3uiv = cast(typeof(glSecondaryColor3uiv))load("glSecondaryColor3uiv"); + glSecondaryColor3us = cast(typeof(glSecondaryColor3us))load("glSecondaryColor3us"); + glSecondaryColor3usv = cast(typeof(glSecondaryColor3usv))load("glSecondaryColor3usv"); + glSecondaryColorPointer = cast(typeof(glSecondaryColorPointer))load("glSecondaryColorPointer"); + glWindowPos2d = cast(typeof(glWindowPos2d))load("glWindowPos2d"); + glWindowPos2dv = cast(typeof(glWindowPos2dv))load("glWindowPos2dv"); + glWindowPos2f = cast(typeof(glWindowPos2f))load("glWindowPos2f"); + glWindowPos2fv = cast(typeof(glWindowPos2fv))load("glWindowPos2fv"); + glWindowPos2i = cast(typeof(glWindowPos2i))load("glWindowPos2i"); + glWindowPos2iv = cast(typeof(glWindowPos2iv))load("glWindowPos2iv"); + glWindowPos2s = cast(typeof(glWindowPos2s))load("glWindowPos2s"); + glWindowPos2sv = cast(typeof(glWindowPos2sv))load("glWindowPos2sv"); + glWindowPos3d = cast(typeof(glWindowPos3d))load("glWindowPos3d"); + glWindowPos3dv = cast(typeof(glWindowPos3dv))load("glWindowPos3dv"); + glWindowPos3f = cast(typeof(glWindowPos3f))load("glWindowPos3f"); + glWindowPos3fv = cast(typeof(glWindowPos3fv))load("glWindowPos3fv"); + glWindowPos3i = cast(typeof(glWindowPos3i))load("glWindowPos3i"); + glWindowPos3iv = cast(typeof(glWindowPos3iv))load("glWindowPos3iv"); + glWindowPos3s = cast(typeof(glWindowPos3s))load("glWindowPos3s"); + glWindowPos3sv = cast(typeof(glWindowPos3sv))load("glWindowPos3sv"); + glBlendColor = cast(typeof(glBlendColor))load("glBlendColor"); + glBlendEquation = cast(typeof(glBlendEquation))load("glBlendEquation"); + return; +} + +void load_GL_VERSION_1_5(Loader load) { + if(!GL_VERSION_1_5) return; + glGenQueries = cast(typeof(glGenQueries))load("glGenQueries"); + glDeleteQueries = cast(typeof(glDeleteQueries))load("glDeleteQueries"); + glIsQuery = cast(typeof(glIsQuery))load("glIsQuery"); + glBeginQuery = cast(typeof(glBeginQuery))load("glBeginQuery"); + glEndQuery = cast(typeof(glEndQuery))load("glEndQuery"); + glGetQueryiv = cast(typeof(glGetQueryiv))load("glGetQueryiv"); + glGetQueryObjectiv = cast(typeof(glGetQueryObjectiv))load("glGetQueryObjectiv"); + glGetQueryObjectuiv = cast(typeof(glGetQueryObjectuiv))load("glGetQueryObjectuiv"); + glBindBuffer = cast(typeof(glBindBuffer))load("glBindBuffer"); + glDeleteBuffers = cast(typeof(glDeleteBuffers))load("glDeleteBuffers"); + glGenBuffers = cast(typeof(glGenBuffers))load("glGenBuffers"); + glIsBuffer = cast(typeof(glIsBuffer))load("glIsBuffer"); + glBufferData = cast(typeof(glBufferData))load("glBufferData"); + glBufferSubData = cast(typeof(glBufferSubData))load("glBufferSubData"); + glGetBufferSubData = cast(typeof(glGetBufferSubData))load("glGetBufferSubData"); + glMapBuffer = cast(typeof(glMapBuffer))load("glMapBuffer"); + glUnmapBuffer = cast(typeof(glUnmapBuffer))load("glUnmapBuffer"); + glGetBufferParameteriv = cast(typeof(glGetBufferParameteriv))load("glGetBufferParameteriv"); + glGetBufferPointerv = cast(typeof(glGetBufferPointerv))load("glGetBufferPointerv"); + return; +} + +void load_GL_VERSION_2_0(Loader load) { + if(!GL_VERSION_2_0) return; + glBlendEquationSeparate = cast(typeof(glBlendEquationSeparate))load("glBlendEquationSeparate"); + glDrawBuffers = cast(typeof(glDrawBuffers))load("glDrawBuffers"); + glStencilOpSeparate = cast(typeof(glStencilOpSeparate))load("glStencilOpSeparate"); + glStencilFuncSeparate = cast(typeof(glStencilFuncSeparate))load("glStencilFuncSeparate"); + glStencilMaskSeparate = cast(typeof(glStencilMaskSeparate))load("glStencilMaskSeparate"); + glAttachShader = cast(typeof(glAttachShader))load("glAttachShader"); + glBindAttribLocation = cast(typeof(glBindAttribLocation))load("glBindAttribLocation"); + glCompileShader = cast(typeof(glCompileShader))load("glCompileShader"); + glCreateProgram = cast(typeof(glCreateProgram))load("glCreateProgram"); + glCreateShader = cast(typeof(glCreateShader))load("glCreateShader"); + glDeleteProgram = cast(typeof(glDeleteProgram))load("glDeleteProgram"); + glDeleteShader = cast(typeof(glDeleteShader))load("glDeleteShader"); + glDetachShader = cast(typeof(glDetachShader))load("glDetachShader"); + glDisableVertexAttribArray = cast(typeof(glDisableVertexAttribArray))load("glDisableVertexAttribArray"); + glEnableVertexAttribArray = cast(typeof(glEnableVertexAttribArray))load("glEnableVertexAttribArray"); + glGetActiveAttrib = cast(typeof(glGetActiveAttrib))load("glGetActiveAttrib"); + glGetActiveUniform = cast(typeof(glGetActiveUniform))load("glGetActiveUniform"); + glGetAttachedShaders = cast(typeof(glGetAttachedShaders))load("glGetAttachedShaders"); + glGetAttribLocation = cast(typeof(glGetAttribLocation))load("glGetAttribLocation"); + glGetProgramiv = cast(typeof(glGetProgramiv))load("glGetProgramiv"); + glGetProgramInfoLog = cast(typeof(glGetProgramInfoLog))load("glGetProgramInfoLog"); + glGetShaderiv = cast(typeof(glGetShaderiv))load("glGetShaderiv"); + glGetShaderInfoLog = cast(typeof(glGetShaderInfoLog))load("glGetShaderInfoLog"); + glGetShaderSource = cast(typeof(glGetShaderSource))load("glGetShaderSource"); + glGetUniformLocation = cast(typeof(glGetUniformLocation))load("glGetUniformLocation"); + glGetUniformfv = cast(typeof(glGetUniformfv))load("glGetUniformfv"); + glGetUniformiv = cast(typeof(glGetUniformiv))load("glGetUniformiv"); + glGetVertexAttribdv = cast(typeof(glGetVertexAttribdv))load("glGetVertexAttribdv"); + glGetVertexAttribfv = cast(typeof(glGetVertexAttribfv))load("glGetVertexAttribfv"); + glGetVertexAttribiv = cast(typeof(glGetVertexAttribiv))load("glGetVertexAttribiv"); + glGetVertexAttribPointerv = cast(typeof(glGetVertexAttribPointerv))load("glGetVertexAttribPointerv"); + glIsProgram = cast(typeof(glIsProgram))load("glIsProgram"); + glIsShader = cast(typeof(glIsShader))load("glIsShader"); + glLinkProgram = cast(typeof(glLinkProgram))load("glLinkProgram"); + glShaderSource = cast(typeof(glShaderSource))load("glShaderSource"); + glUseProgram = cast(typeof(glUseProgram))load("glUseProgram"); + glUniform1f = cast(typeof(glUniform1f))load("glUniform1f"); + glUniform2f = cast(typeof(glUniform2f))load("glUniform2f"); + glUniform3f = cast(typeof(glUniform3f))load("glUniform3f"); + glUniform4f = cast(typeof(glUniform4f))load("glUniform4f"); + glUniform1i = cast(typeof(glUniform1i))load("glUniform1i"); + glUniform2i = cast(typeof(glUniform2i))load("glUniform2i"); + glUniform3i = cast(typeof(glUniform3i))load("glUniform3i"); + glUniform4i = cast(typeof(glUniform4i))load("glUniform4i"); + glUniform1fv = cast(typeof(glUniform1fv))load("glUniform1fv"); + glUniform2fv = cast(typeof(glUniform2fv))load("glUniform2fv"); + glUniform3fv = cast(typeof(glUniform3fv))load("glUniform3fv"); + glUniform4fv = cast(typeof(glUniform4fv))load("glUniform4fv"); + glUniform1iv = cast(typeof(glUniform1iv))load("glUniform1iv"); + glUniform2iv = cast(typeof(glUniform2iv))load("glUniform2iv"); + glUniform3iv = cast(typeof(glUniform3iv))load("glUniform3iv"); + glUniform4iv = cast(typeof(glUniform4iv))load("glUniform4iv"); + glUniformMatrix2fv = cast(typeof(glUniformMatrix2fv))load("glUniformMatrix2fv"); + glUniformMatrix3fv = cast(typeof(glUniformMatrix3fv))load("glUniformMatrix3fv"); + glUniformMatrix4fv = cast(typeof(glUniformMatrix4fv))load("glUniformMatrix4fv"); + glValidateProgram = cast(typeof(glValidateProgram))load("glValidateProgram"); + glVertexAttrib1d = cast(typeof(glVertexAttrib1d))load("glVertexAttrib1d"); + glVertexAttrib1dv = cast(typeof(glVertexAttrib1dv))load("glVertexAttrib1dv"); + glVertexAttrib1f = cast(typeof(glVertexAttrib1f))load("glVertexAttrib1f"); + glVertexAttrib1fv = cast(typeof(glVertexAttrib1fv))load("glVertexAttrib1fv"); + glVertexAttrib1s = cast(typeof(glVertexAttrib1s))load("glVertexAttrib1s"); + glVertexAttrib1sv = cast(typeof(glVertexAttrib1sv))load("glVertexAttrib1sv"); + glVertexAttrib2d = cast(typeof(glVertexAttrib2d))load("glVertexAttrib2d"); + glVertexAttrib2dv = cast(typeof(glVertexAttrib2dv))load("glVertexAttrib2dv"); + glVertexAttrib2f = cast(typeof(glVertexAttrib2f))load("glVertexAttrib2f"); + glVertexAttrib2fv = cast(typeof(glVertexAttrib2fv))load("glVertexAttrib2fv"); + glVertexAttrib2s = cast(typeof(glVertexAttrib2s))load("glVertexAttrib2s"); + glVertexAttrib2sv = cast(typeof(glVertexAttrib2sv))load("glVertexAttrib2sv"); + glVertexAttrib3d = cast(typeof(glVertexAttrib3d))load("glVertexAttrib3d"); + glVertexAttrib3dv = cast(typeof(glVertexAttrib3dv))load("glVertexAttrib3dv"); + glVertexAttrib3f = cast(typeof(glVertexAttrib3f))load("glVertexAttrib3f"); + glVertexAttrib3fv = cast(typeof(glVertexAttrib3fv))load("glVertexAttrib3fv"); + glVertexAttrib3s = cast(typeof(glVertexAttrib3s))load("glVertexAttrib3s"); + glVertexAttrib3sv = cast(typeof(glVertexAttrib3sv))load("glVertexAttrib3sv"); + glVertexAttrib4Nbv = cast(typeof(glVertexAttrib4Nbv))load("glVertexAttrib4Nbv"); + glVertexAttrib4Niv = cast(typeof(glVertexAttrib4Niv))load("glVertexAttrib4Niv"); + glVertexAttrib4Nsv = cast(typeof(glVertexAttrib4Nsv))load("glVertexAttrib4Nsv"); + glVertexAttrib4Nub = cast(typeof(glVertexAttrib4Nub))load("glVertexAttrib4Nub"); + glVertexAttrib4Nubv = cast(typeof(glVertexAttrib4Nubv))load("glVertexAttrib4Nubv"); + glVertexAttrib4Nuiv = cast(typeof(glVertexAttrib4Nuiv))load("glVertexAttrib4Nuiv"); + glVertexAttrib4Nusv = cast(typeof(glVertexAttrib4Nusv))load("glVertexAttrib4Nusv"); + glVertexAttrib4bv = cast(typeof(glVertexAttrib4bv))load("glVertexAttrib4bv"); + glVertexAttrib4d = cast(typeof(glVertexAttrib4d))load("glVertexAttrib4d"); + glVertexAttrib4dv = cast(typeof(glVertexAttrib4dv))load("glVertexAttrib4dv"); + glVertexAttrib4f = cast(typeof(glVertexAttrib4f))load("glVertexAttrib4f"); + glVertexAttrib4fv = cast(typeof(glVertexAttrib4fv))load("glVertexAttrib4fv"); + glVertexAttrib4iv = cast(typeof(glVertexAttrib4iv))load("glVertexAttrib4iv"); + glVertexAttrib4s = cast(typeof(glVertexAttrib4s))load("glVertexAttrib4s"); + glVertexAttrib4sv = cast(typeof(glVertexAttrib4sv))load("glVertexAttrib4sv"); + glVertexAttrib4ubv = cast(typeof(glVertexAttrib4ubv))load("glVertexAttrib4ubv"); + glVertexAttrib4uiv = cast(typeof(glVertexAttrib4uiv))load("glVertexAttrib4uiv"); + glVertexAttrib4usv = cast(typeof(glVertexAttrib4usv))load("glVertexAttrib4usv"); + glVertexAttribPointer = cast(typeof(glVertexAttribPointer))load("glVertexAttribPointer"); + return; +} + +void load_GL_VERSION_2_1(Loader load) { + if(!GL_VERSION_2_1) return; + glUniformMatrix2x3fv = cast(typeof(glUniformMatrix2x3fv))load("glUniformMatrix2x3fv"); + glUniformMatrix3x2fv = cast(typeof(glUniformMatrix3x2fv))load("glUniformMatrix3x2fv"); + glUniformMatrix2x4fv = cast(typeof(glUniformMatrix2x4fv))load("glUniformMatrix2x4fv"); + glUniformMatrix4x2fv = cast(typeof(glUniformMatrix4x2fv))load("glUniformMatrix4x2fv"); + glUniformMatrix3x4fv = cast(typeof(glUniformMatrix3x4fv))load("glUniformMatrix3x4fv"); + glUniformMatrix4x3fv = cast(typeof(glUniformMatrix4x3fv))load("glUniformMatrix4x3fv"); + return; +} + +void load_GL_VERSION_3_0(Loader load) { + if(!GL_VERSION_3_0) return; + glColorMaski = cast(typeof(glColorMaski))load("glColorMaski"); + glGetBooleani_v = cast(typeof(glGetBooleani_v))load("glGetBooleani_v"); + glGetIntegeri_v = cast(typeof(glGetIntegeri_v))load("glGetIntegeri_v"); + glEnablei = cast(typeof(glEnablei))load("glEnablei"); + glDisablei = cast(typeof(glDisablei))load("glDisablei"); + glIsEnabledi = cast(typeof(glIsEnabledi))load("glIsEnabledi"); + glBeginTransformFeedback = cast(typeof(glBeginTransformFeedback))load("glBeginTransformFeedback"); + glEndTransformFeedback = cast(typeof(glEndTransformFeedback))load("glEndTransformFeedback"); + glBindBufferRange = cast(typeof(glBindBufferRange))load("glBindBufferRange"); + glBindBufferBase = cast(typeof(glBindBufferBase))load("glBindBufferBase"); + glTransformFeedbackVaryings = cast(typeof(glTransformFeedbackVaryings))load("glTransformFeedbackVaryings"); + glGetTransformFeedbackVarying = cast(typeof(glGetTransformFeedbackVarying))load("glGetTransformFeedbackVarying"); + glClampColor = cast(typeof(glClampColor))load("glClampColor"); + glBeginConditionalRender = cast(typeof(glBeginConditionalRender))load("glBeginConditionalRender"); + glEndConditionalRender = cast(typeof(glEndConditionalRender))load("glEndConditionalRender"); + glVertexAttribIPointer = cast(typeof(glVertexAttribIPointer))load("glVertexAttribIPointer"); + glGetVertexAttribIiv = cast(typeof(glGetVertexAttribIiv))load("glGetVertexAttribIiv"); + glGetVertexAttribIuiv = cast(typeof(glGetVertexAttribIuiv))load("glGetVertexAttribIuiv"); + glVertexAttribI1i = cast(typeof(glVertexAttribI1i))load("glVertexAttribI1i"); + glVertexAttribI2i = cast(typeof(glVertexAttribI2i))load("glVertexAttribI2i"); + glVertexAttribI3i = cast(typeof(glVertexAttribI3i))load("glVertexAttribI3i"); + glVertexAttribI4i = cast(typeof(glVertexAttribI4i))load("glVertexAttribI4i"); + glVertexAttribI1ui = cast(typeof(glVertexAttribI1ui))load("glVertexAttribI1ui"); + glVertexAttribI2ui = cast(typeof(glVertexAttribI2ui))load("glVertexAttribI2ui"); + glVertexAttribI3ui = cast(typeof(glVertexAttribI3ui))load("glVertexAttribI3ui"); + glVertexAttribI4ui = cast(typeof(glVertexAttribI4ui))load("glVertexAttribI4ui"); + glVertexAttribI1iv = cast(typeof(glVertexAttribI1iv))load("glVertexAttribI1iv"); + glVertexAttribI2iv = cast(typeof(glVertexAttribI2iv))load("glVertexAttribI2iv"); + glVertexAttribI3iv = cast(typeof(glVertexAttribI3iv))load("glVertexAttribI3iv"); + glVertexAttribI4iv = cast(typeof(glVertexAttribI4iv))load("glVertexAttribI4iv"); + glVertexAttribI1uiv = cast(typeof(glVertexAttribI1uiv))load("glVertexAttribI1uiv"); + glVertexAttribI2uiv = cast(typeof(glVertexAttribI2uiv))load("glVertexAttribI2uiv"); + glVertexAttribI3uiv = cast(typeof(glVertexAttribI3uiv))load("glVertexAttribI3uiv"); + glVertexAttribI4uiv = cast(typeof(glVertexAttribI4uiv))load("glVertexAttribI4uiv"); + glVertexAttribI4bv = cast(typeof(glVertexAttribI4bv))load("glVertexAttribI4bv"); + glVertexAttribI4sv = cast(typeof(glVertexAttribI4sv))load("glVertexAttribI4sv"); + glVertexAttribI4ubv = cast(typeof(glVertexAttribI4ubv))load("glVertexAttribI4ubv"); + glVertexAttribI4usv = cast(typeof(glVertexAttribI4usv))load("glVertexAttribI4usv"); + glGetUniformuiv = cast(typeof(glGetUniformuiv))load("glGetUniformuiv"); + glBindFragDataLocation = cast(typeof(glBindFragDataLocation))load("glBindFragDataLocation"); + glGetFragDataLocation = cast(typeof(glGetFragDataLocation))load("glGetFragDataLocation"); + glUniform1ui = cast(typeof(glUniform1ui))load("glUniform1ui"); + glUniform2ui = cast(typeof(glUniform2ui))load("glUniform2ui"); + glUniform3ui = cast(typeof(glUniform3ui))load("glUniform3ui"); + glUniform4ui = cast(typeof(glUniform4ui))load("glUniform4ui"); + glUniform1uiv = cast(typeof(glUniform1uiv))load("glUniform1uiv"); + glUniform2uiv = cast(typeof(glUniform2uiv))load("glUniform2uiv"); + glUniform3uiv = cast(typeof(glUniform3uiv))load("glUniform3uiv"); + glUniform4uiv = cast(typeof(glUniform4uiv))load("glUniform4uiv"); + glTexParameterIiv = cast(typeof(glTexParameterIiv))load("glTexParameterIiv"); + glTexParameterIuiv = cast(typeof(glTexParameterIuiv))load("glTexParameterIuiv"); + glGetTexParameterIiv = cast(typeof(glGetTexParameterIiv))load("glGetTexParameterIiv"); + glGetTexParameterIuiv = cast(typeof(glGetTexParameterIuiv))load("glGetTexParameterIuiv"); + glClearBufferiv = cast(typeof(glClearBufferiv))load("glClearBufferiv"); + glClearBufferuiv = cast(typeof(glClearBufferuiv))load("glClearBufferuiv"); + glClearBufferfv = cast(typeof(glClearBufferfv))load("glClearBufferfv"); + glClearBufferfi = cast(typeof(glClearBufferfi))load("glClearBufferfi"); + glGetStringi = cast(typeof(glGetStringi))load("glGetStringi"); + glIsRenderbuffer = cast(typeof(glIsRenderbuffer))load("glIsRenderbuffer"); + glBindRenderbuffer = cast(typeof(glBindRenderbuffer))load("glBindRenderbuffer"); + glDeleteRenderbuffers = cast(typeof(glDeleteRenderbuffers))load("glDeleteRenderbuffers"); + glGenRenderbuffers = cast(typeof(glGenRenderbuffers))load("glGenRenderbuffers"); + glRenderbufferStorage = cast(typeof(glRenderbufferStorage))load("glRenderbufferStorage"); + glGetRenderbufferParameteriv = cast(typeof(glGetRenderbufferParameteriv))load("glGetRenderbufferParameteriv"); + glIsFramebuffer = cast(typeof(glIsFramebuffer))load("glIsFramebuffer"); + glBindFramebuffer = cast(typeof(glBindFramebuffer))load("glBindFramebuffer"); + glDeleteFramebuffers = cast(typeof(glDeleteFramebuffers))load("glDeleteFramebuffers"); + glGenFramebuffers = cast(typeof(glGenFramebuffers))load("glGenFramebuffers"); + glCheckFramebufferStatus = cast(typeof(glCheckFramebufferStatus))load("glCheckFramebufferStatus"); + glFramebufferTexture1D = cast(typeof(glFramebufferTexture1D))load("glFramebufferTexture1D"); + glFramebufferTexture2D = cast(typeof(glFramebufferTexture2D))load("glFramebufferTexture2D"); + glFramebufferTexture3D = cast(typeof(glFramebufferTexture3D))load("glFramebufferTexture3D"); + glFramebufferRenderbuffer = cast(typeof(glFramebufferRenderbuffer))load("glFramebufferRenderbuffer"); + glGetFramebufferAttachmentParameteriv = cast(typeof(glGetFramebufferAttachmentParameteriv))load("glGetFramebufferAttachmentParameteriv"); + glGenerateMipmap = cast(typeof(glGenerateMipmap))load("glGenerateMipmap"); + glBlitFramebuffer = cast(typeof(glBlitFramebuffer))load("glBlitFramebuffer"); + glRenderbufferStorageMultisample = cast(typeof(glRenderbufferStorageMultisample))load("glRenderbufferStorageMultisample"); + glFramebufferTextureLayer = cast(typeof(glFramebufferTextureLayer))load("glFramebufferTextureLayer"); + glMapBufferRange = cast(typeof(glMapBufferRange))load("glMapBufferRange"); + glFlushMappedBufferRange = cast(typeof(glFlushMappedBufferRange))load("glFlushMappedBufferRange"); + glBindVertexArray = cast(typeof(glBindVertexArray))load("glBindVertexArray"); + glDeleteVertexArrays = cast(typeof(glDeleteVertexArrays))load("glDeleteVertexArrays"); + glGenVertexArrays = cast(typeof(glGenVertexArrays))load("glGenVertexArrays"); + glIsVertexArray = cast(typeof(glIsVertexArray))load("glIsVertexArray"); + return; +} + +void load_GL_VERSION_3_1(Loader load) { + if(!GL_VERSION_3_1) return; + glDrawArraysInstanced = cast(typeof(glDrawArraysInstanced))load("glDrawArraysInstanced"); + glDrawElementsInstanced = cast(typeof(glDrawElementsInstanced))load("glDrawElementsInstanced"); + glTexBuffer = cast(typeof(glTexBuffer))load("glTexBuffer"); + glPrimitiveRestartIndex = cast(typeof(glPrimitiveRestartIndex))load("glPrimitiveRestartIndex"); + glCopyBufferSubData = cast(typeof(glCopyBufferSubData))load("glCopyBufferSubData"); + glGetUniformIndices = cast(typeof(glGetUniformIndices))load("glGetUniformIndices"); + glGetActiveUniformsiv = cast(typeof(glGetActiveUniformsiv))load("glGetActiveUniformsiv"); + glGetActiveUniformName = cast(typeof(glGetActiveUniformName))load("glGetActiveUniformName"); + glGetUniformBlockIndex = cast(typeof(glGetUniformBlockIndex))load("glGetUniformBlockIndex"); + glGetActiveUniformBlockiv = cast(typeof(glGetActiveUniformBlockiv))load("glGetActiveUniformBlockiv"); + glGetActiveUniformBlockName = cast(typeof(glGetActiveUniformBlockName))load("glGetActiveUniformBlockName"); + glUniformBlockBinding = cast(typeof(glUniformBlockBinding))load("glUniformBlockBinding"); + glBindBufferRange = cast(typeof(glBindBufferRange))load("glBindBufferRange"); + glBindBufferBase = cast(typeof(glBindBufferBase))load("glBindBufferBase"); + glGetIntegeri_v = cast(typeof(glGetIntegeri_v))load("glGetIntegeri_v"); + return; +} + +void load_GL_VERSION_3_2(Loader load) { + if(!GL_VERSION_3_2) return; + glDrawElementsBaseVertex = cast(typeof(glDrawElementsBaseVertex))load("glDrawElementsBaseVertex"); + glDrawRangeElementsBaseVertex = cast(typeof(glDrawRangeElementsBaseVertex))load("glDrawRangeElementsBaseVertex"); + glDrawElementsInstancedBaseVertex = cast(typeof(glDrawElementsInstancedBaseVertex))load("glDrawElementsInstancedBaseVertex"); + glMultiDrawElementsBaseVertex = cast(typeof(glMultiDrawElementsBaseVertex))load("glMultiDrawElementsBaseVertex"); + glProvokingVertex = cast(typeof(glProvokingVertex))load("glProvokingVertex"); + glFenceSync = cast(typeof(glFenceSync))load("glFenceSync"); + glIsSync = cast(typeof(glIsSync))load("glIsSync"); + glDeleteSync = cast(typeof(glDeleteSync))load("glDeleteSync"); + glClientWaitSync = cast(typeof(glClientWaitSync))load("glClientWaitSync"); + glWaitSync = cast(typeof(glWaitSync))load("glWaitSync"); + glGetInteger64v = cast(typeof(glGetInteger64v))load("glGetInteger64v"); + glGetSynciv = cast(typeof(glGetSynciv))load("glGetSynciv"); + glGetInteger64i_v = cast(typeof(glGetInteger64i_v))load("glGetInteger64i_v"); + glGetBufferParameteri64v = cast(typeof(glGetBufferParameteri64v))load("glGetBufferParameteri64v"); + glFramebufferTexture = cast(typeof(glFramebufferTexture))load("glFramebufferTexture"); + glTexImage2DMultisample = cast(typeof(glTexImage2DMultisample))load("glTexImage2DMultisample"); + glTexImage3DMultisample = cast(typeof(glTexImage3DMultisample))load("glTexImage3DMultisample"); + glGetMultisamplefv = cast(typeof(glGetMultisamplefv))load("glGetMultisamplefv"); + glSampleMaski = cast(typeof(glSampleMaski))load("glSampleMaski"); + return; +} + +void load_GL_VERSION_3_3(Loader load) { + if(!GL_VERSION_3_3) return; + glBindFragDataLocationIndexed = cast(typeof(glBindFragDataLocationIndexed))load("glBindFragDataLocationIndexed"); + glGetFragDataIndex = cast(typeof(glGetFragDataIndex))load("glGetFragDataIndex"); + glGenSamplers = cast(typeof(glGenSamplers))load("glGenSamplers"); + glDeleteSamplers = cast(typeof(glDeleteSamplers))load("glDeleteSamplers"); + glIsSampler = cast(typeof(glIsSampler))load("glIsSampler"); + glBindSampler = cast(typeof(glBindSampler))load("glBindSampler"); + glSamplerParameteri = cast(typeof(glSamplerParameteri))load("glSamplerParameteri"); + glSamplerParameteriv = cast(typeof(glSamplerParameteriv))load("glSamplerParameteriv"); + glSamplerParameterf = cast(typeof(glSamplerParameterf))load("glSamplerParameterf"); + glSamplerParameterfv = cast(typeof(glSamplerParameterfv))load("glSamplerParameterfv"); + glSamplerParameterIiv = cast(typeof(glSamplerParameterIiv))load("glSamplerParameterIiv"); + glSamplerParameterIuiv = cast(typeof(glSamplerParameterIuiv))load("glSamplerParameterIuiv"); + glGetSamplerParameteriv = cast(typeof(glGetSamplerParameteriv))load("glGetSamplerParameteriv"); + glGetSamplerParameterIiv = cast(typeof(glGetSamplerParameterIiv))load("glGetSamplerParameterIiv"); + glGetSamplerParameterfv = cast(typeof(glGetSamplerParameterfv))load("glGetSamplerParameterfv"); + glGetSamplerParameterIuiv = cast(typeof(glGetSamplerParameterIuiv))load("glGetSamplerParameterIuiv"); + glQueryCounter = cast(typeof(glQueryCounter))load("glQueryCounter"); + glGetQueryObjecti64v = cast(typeof(glGetQueryObjecti64v))load("glGetQueryObjecti64v"); + glGetQueryObjectui64v = cast(typeof(glGetQueryObjectui64v))load("glGetQueryObjectui64v"); + glVertexAttribDivisor = cast(typeof(glVertexAttribDivisor))load("glVertexAttribDivisor"); + glVertexAttribP1ui = cast(typeof(glVertexAttribP1ui))load("glVertexAttribP1ui"); + glVertexAttribP1uiv = cast(typeof(glVertexAttribP1uiv))load("glVertexAttribP1uiv"); + glVertexAttribP2ui = cast(typeof(glVertexAttribP2ui))load("glVertexAttribP2ui"); + glVertexAttribP2uiv = cast(typeof(glVertexAttribP2uiv))load("glVertexAttribP2uiv"); + glVertexAttribP3ui = cast(typeof(glVertexAttribP3ui))load("glVertexAttribP3ui"); + glVertexAttribP3uiv = cast(typeof(glVertexAttribP3uiv))load("glVertexAttribP3uiv"); + glVertexAttribP4ui = cast(typeof(glVertexAttribP4ui))load("glVertexAttribP4ui"); + glVertexAttribP4uiv = cast(typeof(glVertexAttribP4uiv))load("glVertexAttribP4uiv"); + glVertexP2ui = cast(typeof(glVertexP2ui))load("glVertexP2ui"); + glVertexP2uiv = cast(typeof(glVertexP2uiv))load("glVertexP2uiv"); + glVertexP3ui = cast(typeof(glVertexP3ui))load("glVertexP3ui"); + glVertexP3uiv = cast(typeof(glVertexP3uiv))load("glVertexP3uiv"); + glVertexP4ui = cast(typeof(glVertexP4ui))load("glVertexP4ui"); + glVertexP4uiv = cast(typeof(glVertexP4uiv))load("glVertexP4uiv"); + glTexCoordP1ui = cast(typeof(glTexCoordP1ui))load("glTexCoordP1ui"); + glTexCoordP1uiv = cast(typeof(glTexCoordP1uiv))load("glTexCoordP1uiv"); + glTexCoordP2ui = cast(typeof(glTexCoordP2ui))load("glTexCoordP2ui"); + glTexCoordP2uiv = cast(typeof(glTexCoordP2uiv))load("glTexCoordP2uiv"); + glTexCoordP3ui = cast(typeof(glTexCoordP3ui))load("glTexCoordP3ui"); + glTexCoordP3uiv = cast(typeof(glTexCoordP3uiv))load("glTexCoordP3uiv"); + glTexCoordP4ui = cast(typeof(glTexCoordP4ui))load("glTexCoordP4ui"); + glTexCoordP4uiv = cast(typeof(glTexCoordP4uiv))load("glTexCoordP4uiv"); + glMultiTexCoordP1ui = cast(typeof(glMultiTexCoordP1ui))load("glMultiTexCoordP1ui"); + glMultiTexCoordP1uiv = cast(typeof(glMultiTexCoordP1uiv))load("glMultiTexCoordP1uiv"); + glMultiTexCoordP2ui = cast(typeof(glMultiTexCoordP2ui))load("glMultiTexCoordP2ui"); + glMultiTexCoordP2uiv = cast(typeof(glMultiTexCoordP2uiv))load("glMultiTexCoordP2uiv"); + glMultiTexCoordP3ui = cast(typeof(glMultiTexCoordP3ui))load("glMultiTexCoordP3ui"); + glMultiTexCoordP3uiv = cast(typeof(glMultiTexCoordP3uiv))load("glMultiTexCoordP3uiv"); + glMultiTexCoordP4ui = cast(typeof(glMultiTexCoordP4ui))load("glMultiTexCoordP4ui"); + glMultiTexCoordP4uiv = cast(typeof(glMultiTexCoordP4uiv))load("glMultiTexCoordP4uiv"); + glNormalP3ui = cast(typeof(glNormalP3ui))load("glNormalP3ui"); + glNormalP3uiv = cast(typeof(glNormalP3uiv))load("glNormalP3uiv"); + glColorP3ui = cast(typeof(glColorP3ui))load("glColorP3ui"); + glColorP3uiv = cast(typeof(glColorP3uiv))load("glColorP3uiv"); + glColorP4ui = cast(typeof(glColorP4ui))load("glColorP4ui"); + glColorP4uiv = cast(typeof(glColorP4uiv))load("glColorP4uiv"); + glSecondaryColorP3ui = cast(typeof(glSecondaryColorP3ui))load("glSecondaryColorP3ui"); + glSecondaryColorP3uiv = cast(typeof(glSecondaryColorP3uiv))load("glSecondaryColorP3uiv"); + return; +} + + +} /* private */ + +bool gladLoadGLES2(Loader load) { + glGetString = cast(typeof(glGetString))load("glGetString"); + if(glGetString is null) { return false; } + if(glGetString(GL_VERSION) is null) { return false; } + + find_coreGLES2(); + load_GL_ES_VERSION_2_0(load); + load_GL_ES_VERSION_3_0(load); + + find_extensionsGLES2(); + return GLVersion.major != 0 || GLVersion.minor != 0; +} + +private { + +void find_coreGLES2() { + + // Thank you @elmindreda + // https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 + // https://github.com/glfw/glfw/blob/master/src/context.c#L36 + int i; + const(char)* glversion; + const(char)*[3] prefixes = [ + "OpenGL ES-CM ".ptr, + "OpenGL ES-CL ".ptr, + "OpenGL ES ".ptr, + ]; + + glversion = cast(const(char)*)glGetString(GL_VERSION); + if (glversion is null) return; + + foreach(prefix; prefixes) { + size_t length = strlen(prefix); + if (strncmp(glversion, prefix, length) == 0) { + glversion += length; + break; + } + } + + int major = glversion[0] - '0'; + int minor = glversion[2] - '0'; + GLVersion.major = major; GLVersion.minor = minor; + GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GL_ES_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + return; +} + +void find_extensionsGLES2() { + return; +} + +void load_GL_ES_VERSION_2_0(Loader load) { + if(!GL_ES_VERSION_2_0) return; + glActiveTexture = cast(typeof(glActiveTexture))load("glActiveTexture"); + glAttachShader = cast(typeof(glAttachShader))load("glAttachShader"); + glBindAttribLocation = cast(typeof(glBindAttribLocation))load("glBindAttribLocation"); + glBindBuffer = cast(typeof(glBindBuffer))load("glBindBuffer"); + glBindFramebuffer = cast(typeof(glBindFramebuffer))load("glBindFramebuffer"); + glBindRenderbuffer = cast(typeof(glBindRenderbuffer))load("glBindRenderbuffer"); + glBindTexture = cast(typeof(glBindTexture))load("glBindTexture"); + glBlendColor = cast(typeof(glBlendColor))load("glBlendColor"); + glBlendEquation = cast(typeof(glBlendEquation))load("glBlendEquation"); + glBlendEquationSeparate = cast(typeof(glBlendEquationSeparate))load("glBlendEquationSeparate"); + glBlendFunc = cast(typeof(glBlendFunc))load("glBlendFunc"); + glBlendFuncSeparate = cast(typeof(glBlendFuncSeparate))load("glBlendFuncSeparate"); + glBufferData = cast(typeof(glBufferData))load("glBufferData"); + glBufferSubData = cast(typeof(glBufferSubData))load("glBufferSubData"); + glCheckFramebufferStatus = cast(typeof(glCheckFramebufferStatus))load("glCheckFramebufferStatus"); + glClear = cast(typeof(glClear))load("glClear"); + glClearColor = cast(typeof(glClearColor))load("glClearColor"); + glClearDepthf = cast(typeof(glClearDepthf))load("glClearDepthf"); + glClearStencil = cast(typeof(glClearStencil))load("glClearStencil"); + glColorMask = cast(typeof(glColorMask))load("glColorMask"); + glCompileShader = cast(typeof(glCompileShader))load("glCompileShader"); + glCompressedTexImage2D = cast(typeof(glCompressedTexImage2D))load("glCompressedTexImage2D"); + glCompressedTexSubImage2D = cast(typeof(glCompressedTexSubImage2D))load("glCompressedTexSubImage2D"); + glCopyTexImage2D = cast(typeof(glCopyTexImage2D))load("glCopyTexImage2D"); + glCopyTexSubImage2D = cast(typeof(glCopyTexSubImage2D))load("glCopyTexSubImage2D"); + glCreateProgram = cast(typeof(glCreateProgram))load("glCreateProgram"); + glCreateShader = cast(typeof(glCreateShader))load("glCreateShader"); + glCullFace = cast(typeof(glCullFace))load("glCullFace"); + glDeleteBuffers = cast(typeof(glDeleteBuffers))load("glDeleteBuffers"); + glDeleteFramebuffers = cast(typeof(glDeleteFramebuffers))load("glDeleteFramebuffers"); + glDeleteProgram = cast(typeof(glDeleteProgram))load("glDeleteProgram"); + glDeleteRenderbuffers = cast(typeof(glDeleteRenderbuffers))load("glDeleteRenderbuffers"); + glDeleteShader = cast(typeof(glDeleteShader))load("glDeleteShader"); + glDeleteTextures = cast(typeof(glDeleteTextures))load("glDeleteTextures"); + glDepthFunc = cast(typeof(glDepthFunc))load("glDepthFunc"); + glDepthMask = cast(typeof(glDepthMask))load("glDepthMask"); + glDepthRangef = cast(typeof(glDepthRangef))load("glDepthRangef"); + glDetachShader = cast(typeof(glDetachShader))load("glDetachShader"); + glDisable = cast(typeof(glDisable))load("glDisable"); + glDisableVertexAttribArray = cast(typeof(glDisableVertexAttribArray))load("glDisableVertexAttribArray"); + glDrawArrays = cast(typeof(glDrawArrays))load("glDrawArrays"); + glDrawElements = cast(typeof(glDrawElements))load("glDrawElements"); + glEnable = cast(typeof(glEnable))load("glEnable"); + glEnableVertexAttribArray = cast(typeof(glEnableVertexAttribArray))load("glEnableVertexAttribArray"); + glFinish = cast(typeof(glFinish))load("glFinish"); + glFlush = cast(typeof(glFlush))load("glFlush"); + glFramebufferRenderbuffer = cast(typeof(glFramebufferRenderbuffer))load("glFramebufferRenderbuffer"); + glFramebufferTexture2D = cast(typeof(glFramebufferTexture2D))load("glFramebufferTexture2D"); + glFrontFace = cast(typeof(glFrontFace))load("glFrontFace"); + glGenBuffers = cast(typeof(glGenBuffers))load("glGenBuffers"); + glGenerateMipmap = cast(typeof(glGenerateMipmap))load("glGenerateMipmap"); + glGenFramebuffers = cast(typeof(glGenFramebuffers))load("glGenFramebuffers"); + glGenRenderbuffers = cast(typeof(glGenRenderbuffers))load("glGenRenderbuffers"); + glGenTextures = cast(typeof(glGenTextures))load("glGenTextures"); + glGetActiveAttrib = cast(typeof(glGetActiveAttrib))load("glGetActiveAttrib"); + glGetActiveUniform = cast(typeof(glGetActiveUniform))load("glGetActiveUniform"); + glGetAttachedShaders = cast(typeof(glGetAttachedShaders))load("glGetAttachedShaders"); + glGetAttribLocation = cast(typeof(glGetAttribLocation))load("glGetAttribLocation"); + glGetBooleanv = cast(typeof(glGetBooleanv))load("glGetBooleanv"); + glGetBufferParameteriv = cast(typeof(glGetBufferParameteriv))load("glGetBufferParameteriv"); + glGetError = cast(typeof(glGetError))load("glGetError"); + glGetFloatv = cast(typeof(glGetFloatv))load("glGetFloatv"); + glGetFramebufferAttachmentParameteriv = cast(typeof(glGetFramebufferAttachmentParameteriv))load("glGetFramebufferAttachmentParameteriv"); + glGetIntegerv = cast(typeof(glGetIntegerv))load("glGetIntegerv"); + glGetProgramiv = cast(typeof(glGetProgramiv))load("glGetProgramiv"); + glGetProgramInfoLog = cast(typeof(glGetProgramInfoLog))load("glGetProgramInfoLog"); + glGetRenderbufferParameteriv = cast(typeof(glGetRenderbufferParameteriv))load("glGetRenderbufferParameteriv"); + glGetShaderiv = cast(typeof(glGetShaderiv))load("glGetShaderiv"); + glGetShaderInfoLog = cast(typeof(glGetShaderInfoLog))load("glGetShaderInfoLog"); + glGetShaderPrecisionFormat = cast(typeof(glGetShaderPrecisionFormat))load("glGetShaderPrecisionFormat"); + glGetShaderSource = cast(typeof(glGetShaderSource))load("glGetShaderSource"); + glGetString = cast(typeof(glGetString))load("glGetString"); + glGetTexParameterfv = cast(typeof(glGetTexParameterfv))load("glGetTexParameterfv"); + glGetTexParameteriv = cast(typeof(glGetTexParameteriv))load("glGetTexParameteriv"); + glGetUniformfv = cast(typeof(glGetUniformfv))load("glGetUniformfv"); + glGetUniformiv = cast(typeof(glGetUniformiv))load("glGetUniformiv"); + glGetUniformLocation = cast(typeof(glGetUniformLocation))load("glGetUniformLocation"); + glGetVertexAttribfv = cast(typeof(glGetVertexAttribfv))load("glGetVertexAttribfv"); + glGetVertexAttribiv = cast(typeof(glGetVertexAttribiv))load("glGetVertexAttribiv"); + glGetVertexAttribPointerv = cast(typeof(glGetVertexAttribPointerv))load("glGetVertexAttribPointerv"); + glHint = cast(typeof(glHint))load("glHint"); + glIsBuffer = cast(typeof(glIsBuffer))load("glIsBuffer"); + glIsEnabled = cast(typeof(glIsEnabled))load("glIsEnabled"); + glIsFramebuffer = cast(typeof(glIsFramebuffer))load("glIsFramebuffer"); + glIsProgram = cast(typeof(glIsProgram))load("glIsProgram"); + glIsRenderbuffer = cast(typeof(glIsRenderbuffer))load("glIsRenderbuffer"); + glIsShader = cast(typeof(glIsShader))load("glIsShader"); + glIsTexture = cast(typeof(glIsTexture))load("glIsTexture"); + glLineWidth = cast(typeof(glLineWidth))load("glLineWidth"); + glLinkProgram = cast(typeof(glLinkProgram))load("glLinkProgram"); + glPixelStorei = cast(typeof(glPixelStorei))load("glPixelStorei"); + glPolygonOffset = cast(typeof(glPolygonOffset))load("glPolygonOffset"); + glReadPixels = cast(typeof(glReadPixels))load("glReadPixels"); + glReleaseShaderCompiler = cast(typeof(glReleaseShaderCompiler))load("glReleaseShaderCompiler"); + glRenderbufferStorage = cast(typeof(glRenderbufferStorage))load("glRenderbufferStorage"); + glSampleCoverage = cast(typeof(glSampleCoverage))load("glSampleCoverage"); + glScissor = cast(typeof(glScissor))load("glScissor"); + glShaderBinary = cast(typeof(glShaderBinary))load("glShaderBinary"); + glShaderSource = cast(typeof(glShaderSource))load("glShaderSource"); + glStencilFunc = cast(typeof(glStencilFunc))load("glStencilFunc"); + glStencilFuncSeparate = cast(typeof(glStencilFuncSeparate))load("glStencilFuncSeparate"); + glStencilMask = cast(typeof(glStencilMask))load("glStencilMask"); + glStencilMaskSeparate = cast(typeof(glStencilMaskSeparate))load("glStencilMaskSeparate"); + glStencilOp = cast(typeof(glStencilOp))load("glStencilOp"); + glStencilOpSeparate = cast(typeof(glStencilOpSeparate))load("glStencilOpSeparate"); + glTexImage2D = cast(typeof(glTexImage2D))load("glTexImage2D"); + glTexParameterf = cast(typeof(glTexParameterf))load("glTexParameterf"); + glTexParameterfv = cast(typeof(glTexParameterfv))load("glTexParameterfv"); + glTexParameteri = cast(typeof(glTexParameteri))load("glTexParameteri"); + glTexParameteriv = cast(typeof(glTexParameteriv))load("glTexParameteriv"); + glTexSubImage2D = cast(typeof(glTexSubImage2D))load("glTexSubImage2D"); + glUniform1f = cast(typeof(glUniform1f))load("glUniform1f"); + glUniform1fv = cast(typeof(glUniform1fv))load("glUniform1fv"); + glUniform1i = cast(typeof(glUniform1i))load("glUniform1i"); + glUniform1iv = cast(typeof(glUniform1iv))load("glUniform1iv"); + glUniform2f = cast(typeof(glUniform2f))load("glUniform2f"); + glUniform2fv = cast(typeof(glUniform2fv))load("glUniform2fv"); + glUniform2i = cast(typeof(glUniform2i))load("glUniform2i"); + glUniform2iv = cast(typeof(glUniform2iv))load("glUniform2iv"); + glUniform3f = cast(typeof(glUniform3f))load("glUniform3f"); + glUniform3fv = cast(typeof(glUniform3fv))load("glUniform3fv"); + glUniform3i = cast(typeof(glUniform3i))load("glUniform3i"); + glUniform3iv = cast(typeof(glUniform3iv))load("glUniform3iv"); + glUniform4f = cast(typeof(glUniform4f))load("glUniform4f"); + glUniform4fv = cast(typeof(glUniform4fv))load("glUniform4fv"); + glUniform4i = cast(typeof(glUniform4i))load("glUniform4i"); + glUniform4iv = cast(typeof(glUniform4iv))load("glUniform4iv"); + glUniformMatrix2fv = cast(typeof(glUniformMatrix2fv))load("glUniformMatrix2fv"); + glUniformMatrix3fv = cast(typeof(glUniformMatrix3fv))load("glUniformMatrix3fv"); + glUniformMatrix4fv = cast(typeof(glUniformMatrix4fv))load("glUniformMatrix4fv"); + glUseProgram = cast(typeof(glUseProgram))load("glUseProgram"); + glValidateProgram = cast(typeof(glValidateProgram))load("glValidateProgram"); + glVertexAttrib1f = cast(typeof(glVertexAttrib1f))load("glVertexAttrib1f"); + glVertexAttrib1fv = cast(typeof(glVertexAttrib1fv))load("glVertexAttrib1fv"); + glVertexAttrib2f = cast(typeof(glVertexAttrib2f))load("glVertexAttrib2f"); + glVertexAttrib2fv = cast(typeof(glVertexAttrib2fv))load("glVertexAttrib2fv"); + glVertexAttrib3f = cast(typeof(glVertexAttrib3f))load("glVertexAttrib3f"); + glVertexAttrib3fv = cast(typeof(glVertexAttrib3fv))load("glVertexAttrib3fv"); + glVertexAttrib4f = cast(typeof(glVertexAttrib4f))load("glVertexAttrib4f"); + glVertexAttrib4fv = cast(typeof(glVertexAttrib4fv))load("glVertexAttrib4fv"); + glVertexAttribPointer = cast(typeof(glVertexAttribPointer))load("glVertexAttribPointer"); + glViewport = cast(typeof(glViewport))load("glViewport"); + return; +} + +void load_GL_ES_VERSION_3_0(Loader load) { + if(!GL_ES_VERSION_3_0) return; + glReadBuffer = cast(typeof(glReadBuffer))load("glReadBuffer"); + glDrawRangeElements = cast(typeof(glDrawRangeElements))load("glDrawRangeElements"); + glTexImage3D = cast(typeof(glTexImage3D))load("glTexImage3D"); + glTexSubImage3D = cast(typeof(glTexSubImage3D))load("glTexSubImage3D"); + glCopyTexSubImage3D = cast(typeof(glCopyTexSubImage3D))load("glCopyTexSubImage3D"); + glCompressedTexImage3D = cast(typeof(glCompressedTexImage3D))load("glCompressedTexImage3D"); + glCompressedTexSubImage3D = cast(typeof(glCompressedTexSubImage3D))load("glCompressedTexSubImage3D"); + glGenQueries = cast(typeof(glGenQueries))load("glGenQueries"); + glDeleteQueries = cast(typeof(glDeleteQueries))load("glDeleteQueries"); + glIsQuery = cast(typeof(glIsQuery))load("glIsQuery"); + glBeginQuery = cast(typeof(glBeginQuery))load("glBeginQuery"); + glEndQuery = cast(typeof(glEndQuery))load("glEndQuery"); + glGetQueryiv = cast(typeof(glGetQueryiv))load("glGetQueryiv"); + glGetQueryObjectuiv = cast(typeof(glGetQueryObjectuiv))load("glGetQueryObjectuiv"); + glUnmapBuffer = cast(typeof(glUnmapBuffer))load("glUnmapBuffer"); + glGetBufferPointerv = cast(typeof(glGetBufferPointerv))load("glGetBufferPointerv"); + glDrawBuffers = cast(typeof(glDrawBuffers))load("glDrawBuffers"); + glUniformMatrix2x3fv = cast(typeof(glUniformMatrix2x3fv))load("glUniformMatrix2x3fv"); + glUniformMatrix3x2fv = cast(typeof(glUniformMatrix3x2fv))load("glUniformMatrix3x2fv"); + glUniformMatrix2x4fv = cast(typeof(glUniformMatrix2x4fv))load("glUniformMatrix2x4fv"); + glUniformMatrix4x2fv = cast(typeof(glUniformMatrix4x2fv))load("glUniformMatrix4x2fv"); + glUniformMatrix3x4fv = cast(typeof(glUniformMatrix3x4fv))load("glUniformMatrix3x4fv"); + glUniformMatrix4x3fv = cast(typeof(glUniformMatrix4x3fv))load("glUniformMatrix4x3fv"); + glBlitFramebuffer = cast(typeof(glBlitFramebuffer))load("glBlitFramebuffer"); + glRenderbufferStorageMultisample = cast(typeof(glRenderbufferStorageMultisample))load("glRenderbufferStorageMultisample"); + glFramebufferTextureLayer = cast(typeof(glFramebufferTextureLayer))load("glFramebufferTextureLayer"); + glMapBufferRange = cast(typeof(glMapBufferRange))load("glMapBufferRange"); + glFlushMappedBufferRange = cast(typeof(glFlushMappedBufferRange))load("glFlushMappedBufferRange"); + glBindVertexArray = cast(typeof(glBindVertexArray))load("glBindVertexArray"); + glDeleteVertexArrays = cast(typeof(glDeleteVertexArrays))load("glDeleteVertexArrays"); + glGenVertexArrays = cast(typeof(glGenVertexArrays))load("glGenVertexArrays"); + glIsVertexArray = cast(typeof(glIsVertexArray))load("glIsVertexArray"); + glGetIntegeri_v = cast(typeof(glGetIntegeri_v))load("glGetIntegeri_v"); + glBeginTransformFeedback = cast(typeof(glBeginTransformFeedback))load("glBeginTransformFeedback"); + glEndTransformFeedback = cast(typeof(glEndTransformFeedback))load("glEndTransformFeedback"); + glBindBufferRange = cast(typeof(glBindBufferRange))load("glBindBufferRange"); + glBindBufferBase = cast(typeof(glBindBufferBase))load("glBindBufferBase"); + glTransformFeedbackVaryings = cast(typeof(glTransformFeedbackVaryings))load("glTransformFeedbackVaryings"); + glGetTransformFeedbackVarying = cast(typeof(glGetTransformFeedbackVarying))load("glGetTransformFeedbackVarying"); + glVertexAttribIPointer = cast(typeof(glVertexAttribIPointer))load("glVertexAttribIPointer"); + glGetVertexAttribIiv = cast(typeof(glGetVertexAttribIiv))load("glGetVertexAttribIiv"); + glGetVertexAttribIuiv = cast(typeof(glGetVertexAttribIuiv))load("glGetVertexAttribIuiv"); + glVertexAttribI4i = cast(typeof(glVertexAttribI4i))load("glVertexAttribI4i"); + glVertexAttribI4ui = cast(typeof(glVertexAttribI4ui))load("glVertexAttribI4ui"); + glVertexAttribI4iv = cast(typeof(glVertexAttribI4iv))load("glVertexAttribI4iv"); + glVertexAttribI4uiv = cast(typeof(glVertexAttribI4uiv))load("glVertexAttribI4uiv"); + glGetUniformuiv = cast(typeof(glGetUniformuiv))load("glGetUniformuiv"); + glGetFragDataLocation = cast(typeof(glGetFragDataLocation))load("glGetFragDataLocation"); + glUniform1ui = cast(typeof(glUniform1ui))load("glUniform1ui"); + glUniform2ui = cast(typeof(glUniform2ui))load("glUniform2ui"); + glUniform3ui = cast(typeof(glUniform3ui))load("glUniform3ui"); + glUniform4ui = cast(typeof(glUniform4ui))load("glUniform4ui"); + glUniform1uiv = cast(typeof(glUniform1uiv))load("glUniform1uiv"); + glUniform2uiv = cast(typeof(glUniform2uiv))load("glUniform2uiv"); + glUniform3uiv = cast(typeof(glUniform3uiv))load("glUniform3uiv"); + glUniform4uiv = cast(typeof(glUniform4uiv))load("glUniform4uiv"); + glClearBufferiv = cast(typeof(glClearBufferiv))load("glClearBufferiv"); + glClearBufferuiv = cast(typeof(glClearBufferuiv))load("glClearBufferuiv"); + glClearBufferfv = cast(typeof(glClearBufferfv))load("glClearBufferfv"); + glClearBufferfi = cast(typeof(glClearBufferfi))load("glClearBufferfi"); + glGetStringi = cast(typeof(glGetStringi))load("glGetStringi"); + glCopyBufferSubData = cast(typeof(glCopyBufferSubData))load("glCopyBufferSubData"); + glGetUniformIndices = cast(typeof(glGetUniformIndices))load("glGetUniformIndices"); + glGetActiveUniformsiv = cast(typeof(glGetActiveUniformsiv))load("glGetActiveUniformsiv"); + glGetUniformBlockIndex = cast(typeof(glGetUniformBlockIndex))load("glGetUniformBlockIndex"); + glGetActiveUniformBlockiv = cast(typeof(glGetActiveUniformBlockiv))load("glGetActiveUniformBlockiv"); + glGetActiveUniformBlockName = cast(typeof(glGetActiveUniformBlockName))load("glGetActiveUniformBlockName"); + glUniformBlockBinding = cast(typeof(glUniformBlockBinding))load("glUniformBlockBinding"); + glDrawArraysInstanced = cast(typeof(glDrawArraysInstanced))load("glDrawArraysInstanced"); + glDrawElementsInstanced = cast(typeof(glDrawElementsInstanced))load("glDrawElementsInstanced"); + glFenceSync = cast(typeof(glFenceSync))load("glFenceSync"); + glIsSync = cast(typeof(glIsSync))load("glIsSync"); + glDeleteSync = cast(typeof(glDeleteSync))load("glDeleteSync"); + glClientWaitSync = cast(typeof(glClientWaitSync))load("glClientWaitSync"); + glWaitSync = cast(typeof(glWaitSync))load("glWaitSync"); + glGetInteger64v = cast(typeof(glGetInteger64v))load("glGetInteger64v"); + glGetSynciv = cast(typeof(glGetSynciv))load("glGetSynciv"); + glGetInteger64i_v = cast(typeof(glGetInteger64i_v))load("glGetInteger64i_v"); + glGetBufferParameteri64v = cast(typeof(glGetBufferParameteri64v))load("glGetBufferParameteri64v"); + glGenSamplers = cast(typeof(glGenSamplers))load("glGenSamplers"); + glDeleteSamplers = cast(typeof(glDeleteSamplers))load("glDeleteSamplers"); + glIsSampler = cast(typeof(glIsSampler))load("glIsSampler"); + glBindSampler = cast(typeof(glBindSampler))load("glBindSampler"); + glSamplerParameteri = cast(typeof(glSamplerParameteri))load("glSamplerParameteri"); + glSamplerParameteriv = cast(typeof(glSamplerParameteriv))load("glSamplerParameteriv"); + glSamplerParameterf = cast(typeof(glSamplerParameterf))load("glSamplerParameterf"); + glSamplerParameterfv = cast(typeof(glSamplerParameterfv))load("glSamplerParameterfv"); + glGetSamplerParameteriv = cast(typeof(glGetSamplerParameteriv))load("glGetSamplerParameteriv"); + glGetSamplerParameterfv = cast(typeof(glGetSamplerParameterfv))load("glGetSamplerParameterfv"); + glVertexAttribDivisor = cast(typeof(glVertexAttribDivisor))load("glVertexAttribDivisor"); + glBindTransformFeedback = cast(typeof(glBindTransformFeedback))load("glBindTransformFeedback"); + glDeleteTransformFeedbacks = cast(typeof(glDeleteTransformFeedbacks))load("glDeleteTransformFeedbacks"); + glGenTransformFeedbacks = cast(typeof(glGenTransformFeedbacks))load("glGenTransformFeedbacks"); + glIsTransformFeedback = cast(typeof(glIsTransformFeedback))load("glIsTransformFeedback"); + glPauseTransformFeedback = cast(typeof(glPauseTransformFeedback))load("glPauseTransformFeedback"); + glResumeTransformFeedback = cast(typeof(glResumeTransformFeedback))load("glResumeTransformFeedback"); + glGetProgramBinary = cast(typeof(glGetProgramBinary))load("glGetProgramBinary"); + glProgramBinary = cast(typeof(glProgramBinary))load("glProgramBinary"); + glProgramParameteri = cast(typeof(glProgramParameteri))load("glProgramParameteri"); + glInvalidateFramebuffer = cast(typeof(glInvalidateFramebuffer))load("glInvalidateFramebuffer"); + glInvalidateSubFramebuffer = cast(typeof(glInvalidateSubFramebuffer))load("glInvalidateSubFramebuffer"); + glTexStorage2D = cast(typeof(glTexStorage2D))load("glTexStorage2D"); + glTexStorage3D = cast(typeof(glTexStorage3D))load("glTexStorage3D"); + glGetInternalformativ = cast(typeof(glGetInternalformativ))load("glGetInternalformativ"); + return; +} + + +} /* private */ + diff --git a/demos/external/sources/glad/gl/types.d b/demos/external/sources/glad/gl/types.d new file mode 100644 index 0000000..043a2a1 --- /dev/null +++ b/demos/external/sources/glad/gl/types.d @@ -0,0 +1,46 @@ +module glad.gl.types; + + +alias GLvoid = void; +alias GLintptr = ptrdiff_t; +alias GLsizei = int; +alias GLchar = char; +alias GLcharARB = byte; +alias GLushort = ushort; +alias GLint64EXT = long; +alias GLshort = short; +alias GLuint64 = ulong; +alias GLhalfARB = ushort; +alias GLubyte = ubyte; +alias GLdouble = double; +alias GLhandleARB = uint; +alias GLint64 = long; +alias GLenum = uint; +alias GLeglImageOES = void*; +alias GLintptrARB = ptrdiff_t; +alias GLsizeiptr = ptrdiff_t; +alias GLint = int; +alias GLboolean = ubyte; +alias GLbitfield = uint; +alias GLsizeiptrARB = ptrdiff_t; +alias GLfloat = float; +alias GLuint64EXT = ulong; +alias GLclampf = float; +alias GLbyte = byte; +alias GLclampd = double; +alias GLuint = uint; +alias GLvdpauSurfaceNV = ptrdiff_t; +alias GLfixed = int; +alias GLhalf = ushort; +alias GLclampx = int; +alias GLhalfNV = ushort; +struct ___GLsync; alias __GLsync = ___GLsync*; +alias GLsync = __GLsync*; +struct __cl_context; alias _cl_context = __cl_context*; +struct __cl_event; alias _cl_event = __cl_event*; +extern(System) { +alias GLDEBUGPROC = void function(GLenum, GLenum, GLuint, GLenum, GLsizei, in GLchar*, GLvoid*); +alias GLDEBUGPROCARB = GLDEBUGPROC; +alias GLDEBUGPROCKHR = GLDEBUGPROC; +alias GLDEBUGPROCAMD = void function(GLuint, GLenum, GLenum, GLsizei, in GLchar*, GLvoid*); +} diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d new file mode 100644 index 0000000..9156674 --- /dev/null +++ b/demos/external/sources/mmutils/thread_pool.d @@ -0,0 +1,1831 @@ +module mmutils.thread_pool; + +import std.algorithm : map; + +version = MM_NO_LOGS; // Disable log creation +//version = MM_USE_POSIX_THREADS; // Use posix threads insted of standard library, required for betterC + +version (WebAssembly) +{ + version = MM_NO_LOGS; + version = MM_USE_POSIX_THREADS; + extern(C) struct FILE + { + + } +} +else +{ + import core.stdc.stdio; +} + +////////////////////////////////////////////// +/////////////// BetterC Support ////////////// +////////////////////////////////////////////// + +version (D_BetterC) +{ + version (Posix) version = MM_USE_POSIX_THREADS; + + extern (C) void free(void*) @nogc nothrow @system; + extern (C) void* malloc(size_t size) @nogc nothrow @system; + extern (C) void* realloc(void*, size_t size) @nogc nothrow @system; + extern (C) void* memcpy(return void*, scope const void*, size_t size) @nogc nothrow @system; + + //hacks for LDC + /*extern (C) __gshared int _d_eh_personality(int, int, size_t, void*, void*) + { + return 0; + } + + extern (C) __gshared void _d_eh_resume_unwind(void*) + { + return; + } + + extern (C) void* _d_allocmemory(size_t sz) + { + return malloc(sz); + }*/ +} +else +{ + import core.stdc.stdlib; + import core.stdc.string; +} + +////////////////////////////////////////////// +/////////////// Atomics ////////////////////// +////////////////////////////////////////////// + +version (ECSEmscripten) +{ + import std.traits; + + enum MemoryOrder + { + acq, + acq_rel, + raw, + rel, + seq + } + + extern (C) ubyte emscripten_atomic_cas_u8(void* addr, ubyte oldVal, ubyte newVal) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_cas_u16(void* addr, ushort oldVal, ushort newVal) @nogc nothrow pure; + extern (C) uint emscripten_atomic_cas_u32(void* addr, uint oldVal, uint newVal) @nogc nothrow pure; + + extern (C) ubyte emscripten_atomic_load_u8(const void* addr) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_load_u16(const void* addr) @nogc nothrow pure; + extern (C) uint emscripten_atomic_load_u32(const void* addr) @nogc nothrow pure; + + extern (C) ubyte emscripten_atomic_store_u8(void* addr, ubyte val) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_store_u16(void* addr, ushort val) @nogc nothrow pure; + extern (C) uint emscripten_atomic_store_u32(void* addr, uint val) @nogc nothrow pure; + + extern (C) ubyte emscripten_atomic_add_u8(void* addr, ubyte val) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_add_u16(void* addr, ushort val) @nogc nothrow pure; + extern (C) uint emscripten_atomic_add_u32(void* addr, uint val) @nogc nothrow pure; + + extern (C) ubyte emscripten_atomic_sub_u8(void* addr, ubyte val) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_sub_u16(void* addr, ushort val) @nogc nothrow pure; + extern (C) uint emscripten_atomic_sub_u32(void* addr, uint val) @nogc nothrow pure; + + public pure nothrow @nogc Unqual!T atomicOp(string op, T, V1)(ref shared T val, V1 mod) + { + static if (op == "+=") + { + static if (is(T == byte) || is(T == ubyte)) + return cast(Unqual!T)(emscripten_atomic_add_u8(cast(void*)&val, + cast(Unqual!T) mod) + 1); + else static if (is(T == short) || is(T == ushort)) + return cast(Unqual!T)(emscripten_atomic_add_u16(cast(void*)&val, + cast(Unqual!T) mod) + 1); + else static if (is(T == int) || is(T == uint)) + return cast(Unqual!T)(emscripten_atomic_add_u32(cast(void*)&val, + cast(Unqual!T) mod) + 1); + else + static assert(0); + } + else static if (op == "-=") + { + static if (is(T == byte) || is(T == ubyte)) + return cast(Unqual!T)(emscripten_atomic_sub_u8(cast(void*)&val, + cast(Unqual!T) mod) - 1); + else static if (is(T == short) || is(T == ushort)) + return cast(Unqual!T)(emscripten_atomic_sub_u16(cast(void*)&val, + cast(Unqual!T) mod) - 1); + else static if (is(T == int) || is(T == uint)) + return cast(Unqual!T)(emscripten_atomic_sub_u32(cast(void*)&val, + cast(Unqual!T) mod) - 1); + else + static assert(0); + } + } + + public pure nothrow @nogc @trusted void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref T val, + V newval) + { + alias UT = Unqual!T; + static if (is(UT == bool) || is(UT == byte) || is(UT == ubyte)) + emscripten_atomic_store_u8(cast(void*)&val, cast(UT) newval); + else static if (is(UT == short) || is(UT == ushort)) + emscripten_atomic_store_u16(cast(void*)&val, cast(UT) newval); + else static if (is(UT == int) || is(UT == uint)) + emscripten_atomic_store_u32(cast(void*)&val, cast(UT) newval); + else + static assert(0); + } + + public pure nothrow @nogc @trusted T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)( + ref const T val) + { + alias UT = Unqual!T; + static if (is(UT == bool)) + return emscripten_atomic_load_u8(cast(const void*)&val) != 0; + else static if (is(UT == byte) || is(UT == ubyte)) + return emscripten_atomic_load_u8(cast(const void*)&val); + else static if (is(UT == short) || is(UT == ushort)) + return emscripten_atomic_load_u16(cast(const void*)&val); + else static if (is(UT == int) || is(UT == uint)) + return emscripten_atomic_load_u32(cast(const void*)&val); + else + static assert(0); + } + + public pure nothrow @nogc @trusted bool cas(MemoryOrder succ = MemoryOrder.seq, + MemoryOrder fail = MemoryOrder.seq, T, V1, V2)(T* here, V1 ifThis, V2 writeThis) + { + alias UT = Unqual!T; + static if (is(UT == bool)) + return emscripten_atomic_cas_u8(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else static if (is(UT == byte) || is(UT == ubyte)) + return emscripten_atomic_cas_u8(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else static if (is(UT == short) || is(UT == ushort)) + return emscripten_atomic_cas_u16(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else static if (is(UT == int) || is(UT == uint)) + return emscripten_atomic_cas_u32(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else + static assert(0); + } +} +else +{ + public import core.atomic; +} + +////////////////////////////////////////////////// +//////////////////// Allocator /////////////////// +////////////////////////////////////////////////// +T* makeVar(T)(T init) +{ + T* el = cast(T*) malloc(T.sizeof); + memcpy(el, &init, T.sizeof); + return el; +} + +T* makeVar(T)() +{ + T init; + T* el = cast(T*) malloc(T.sizeof); + memcpy(el, &init, T.sizeof); + return el; +} + +T[] makeVarArray(T)(int num, T init = T.init) +{ + T* ptr = cast(T*) malloc(num * (T.sizeof + T.sizeof % T.alignof)); + T[] arr = ptr[0 .. num]; + foreach (ref el; arr) + { + memcpy(&el, &init, T.sizeof); + } + return arr; +} + +void disposeVar(T)(T* var) +{ + free(var); +} + +void disposeArray(T)(T[] var) +{ + free(var.ptr); +} +////////////////////////////////////////////// +//////////////////// Timer /////////////////// +////////////////////////////////////////////// + +version (WebAssembly) +{ + alias int time_t; + alias int clockid_t; + enum CLOCK_REALTIME = 0; + + struct timespec + { + time_t tv_sec; + int tv_nsec; + } + + extern(C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; + + extern(C) double emscripten_get_now() @nogc nothrow @system; + +} + +/// High precison timer +long useconds() +{ + version (WebAssembly) + { + return cast(long)(emscripten_get_now() * 1000.0); + } + else version (Posix) + { + import core.sys.posix.sys.time : gettimeofday, timeval; + + timeval t; + gettimeofday(&t, null); + return t.tv_sec * 1_000_000 + t.tv_usec; + } + else version (Windows) + { + //TODO: implement timer on windows + /*import core.sys.windows.windows : QueryPerformanceFrequency; + + __gshared double mul = -1; + if (mul < 0) + { + long frequency; + int ok = QueryPerformanceFrequency(&frequency); + assert(ok); + mul = 1_000_000.0 / frequency; + } + long ticks; + int ok = QueryPerformanceCounter(&ticks); + assert(ok); + return cast(long)(ticks * mul);*/ + return 0; + } + else + { + static assert("OS not supported."); + } +} + +////////////////////////////////////////////// +//////////////////// Pause /////////////////// +////////////////////////////////////////////// + +void instructionPause() +{ + version (X86_64) + { + version (LDC) + { + import ldc.gccbuiltins_x86 : __builtin_ia32_pause; + + __builtin_ia32_pause(); + } + else version(GNU) + { + import gcc.builtins; + + __builtin_ia32_pause(); + } + else version (DigitalMars) + { + asm + { + rep; + nop; + } + } + else + { + static assert(0); + } + } + else version (Android) + { + version(LDC) + { + import ldc.attributes; + @optStrategy("none") + static void nop() + { + int i; + i++; + } + nop(); + } + else static assert(0); + } + else version(WebAssembly) + { + version(LDC) + { + import ldc.attributes; + @optStrategy("none") + static void nop() + { + int i; + i++; +} + nop(); + } + else static assert(0); + } + else static assert(0); +} + +////////////////////////////////////////////// +///////////// Semaphore + Thread ///////////// +////////////////////////////////////////////// + +version (MM_USE_POSIX_THREADS) +{ + version (WebAssembly) + { + extern(C): + + struct pthread_attr_t + { + union + { + int[10] __i; + uint[10] __s; + } + } + + struct pthread_t + { + void* p; + uint x; + } + + // pthread + int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*); + int pthread_join(pthread_t, void**); + void pthread_exit(void *retval); + + struct sem_t + { + shared int[4] __val; + } + int sem_init(sem_t*, int, uint); + int sem_wait(sem_t*); + int sem_trywait(sem_t*); + int sem_post(sem_t*); + int sem_destroy(sem_t*); + int sem_timedwait(sem_t* sem, const timespec* abstime); + } + else version (Posix) + { + import core.sys.posix.pthread; + import core.sys.posix.semaphore; + } + else version (Windows) + { + extern (C): + alias uint time_t; + struct pthread_attr_t + { + + } + + struct pthread_t + { + void* p; + uint x; + } + + struct timespec + { + time_t tv_sec; + int tv_nsec; + } + + // pthread + int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*); + int pthread_join(pthread_t, void**); + void pthread_exit(void *retval); + + // semaphore.h + alias sem_t = void*; + int sem_init(sem_t*, int, uint); + int sem_wait(sem_t*); + int sem_trywait(sem_t*); + int sem_post(sem_t*); + int sem_destroy(sem_t*); + int sem_timedwait(sem_t* sem, const timespec* abstime); + } + else + { + static assert(false); + } + + struct Semaphore + { + sem_t mutex; + + void initialize() + { + sem_init(&mutex, 0, 0); + } + + void wait() + { + int ret = sem_wait(&mutex); + assert(ret == 0); + } + + bool tryWait() + { + int ret = sem_trywait(&mutex); + return (ret == 0); + } + + bool timedWait(int usecs) + { + timespec tv; + // if there is no such a function look at it: https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows + clock_gettime(CLOCK_REALTIME, &tv); + tv.tv_sec += usecs / 1_000_000; + tv.tv_nsec += (usecs % 1_000_000) * 1_000; + + int ret = sem_timedwait(&mutex, &tv); + return (ret == 0); + } + + void post() + { + int ret = sem_post(&mutex); + assert(ret >= 0); + } + + void destroy() + { + sem_destroy(&mutex); + } + } + + private extern (C) void* threadRunFunc(void* threadVoid) + { + Thread* th = cast(Thread*) threadVoid; + + th.threadStart(); + + pthread_exit(null); + return null; + } + + struct Thread + { + alias DG = void delegate(); + + DG threadStart; + pthread_t handle; + + void start(DG dg) + { + threadStart = dg; + int err = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this); + if(err)handle = pthread_t(); + //assert(ok == 0); + } + + void join() + { + pthread_join(handle, null); + handle = handle.init; + threadStart = null; + } + } +} +else version(D_BetterC) +{ + version(Windows) + { + import core.stdc.stdint : uintptr_t; + import core.sys.windows.windows; + extern (Windows) alias btex_fptr = uint function(void*); + extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow @nogc; + + struct Semaphore + { + HANDLE handle; + + void initialize() + { + handle = CreateSemaphoreA( null, 0, int.max, null ); + assert ( handle != handle.init ); + //throw new SyncError( "Unable to create semaphore" ); + } + + void wait() + { + DWORD rc = WaitForSingleObject( handle, INFINITE ); + //int ret = sem_wait(&mutex); + assert(rc == WAIT_OBJECT_0); + } + + bool tryWait() + { + switch ( WaitForSingleObject( handle, 0 ) ) + { + case WAIT_OBJECT_0: + return true; + case WAIT_TIMEOUT: + return false; + default: + assert(0);//throw new SyncError( "Unable to wait for semaphore" ); + } + } + + bool timedWait(int usecs) + { + /*timespec tv; + // if there is no such a function look at it: https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows + clock_gettime(CLOCK_REALTIME, &tv); + tv.tv_sec += usecs / 1_000_000; + tv.tv_nsec += (usecs % 1_000_000) * 1_000; + + int ret = sem_timedwait(&mutex, &tv); + return (ret == 0);*/ + + switch ( WaitForSingleObject( handle, cast(uint) usecs / 1000 ) ) + { + case WAIT_OBJECT_0: + return true; + case WAIT_TIMEOUT: + return false; + default: + assert(0, "Unable to wait for semaphore" ); + } + } + + void post() + { + assert(ReleaseSemaphore( handle, 1, null )); + } + + void destroy() + { + BOOL rc = CloseHandle( handle ); + assert( rc, "Unable to destroy semaphore" ); + } + } + + private extern (Windows) uint threadRunFunc(void* threadVoid) + { + Thread* th = cast(Thread*) threadVoid; + + th.threadStart(); + + ExitThread(0); + return 0; + } + + struct Thread + { + alias DG = void delegate(); + + DG threadStart; + HANDLE handle; + + void start(DG dg) + { + threadStart = dg; + handle = cast(HANDLE) _beginthreadex( null, 0, &threadRunFunc, cast(void*)&this, 0, null ); + } + + void join() + { + if ( WaitForSingleObject( handle, INFINITE ) == WAIT_OBJECT_0 )assert(0); + CloseHandle( handle ); + + handle = handle.init; + threadStart = null; + } + } + } + else + { + static assert(0, "Platform is unsupported in betterC mode!"); + } +} +else +{ + import core.thread : D_Thread = Thread; + import core.sync.semaphore : D_Semaphore = Semaphore; + import core.time : dur; + import std.experimental.allocator; + import std.experimental.allocator.mallocator; + + struct Semaphore + { + D_Semaphore sem; + + void initialize() + { + sem = Mallocator.instance.make!D_Semaphore(); + } + + void wait() + { + sem.wait(); + } + + bool tryWait() + { + return sem.tryWait(); + } + + bool timedWait(int usecs) + { + return sem.wait(dur!"usecs"(usecs)); + } + + void post() + { + sem.notify(); + } + + void destroy() + { + Mallocator.instance.dispose(sem); + } + } + + struct Thread + { + alias DG = void delegate(); + + DG threadStart; + D_Thread thread; + + void start(DG dg) + { + thread = Mallocator.instance.make!D_Thread(dg); + thread.start(); + } + + void join() + { + thread.join(); + } + } +} + +////////////////////////////////////////////// +///////////////// ThreadPool ///////////////// +////////////////////////////////////////////// + +private enum gMaxThreadsNum = 64; + +alias JobDelegate = void delegate(ThreadData*, JobData*); + +// Structure to store job start and end time +struct JobLog +{ + string name; /// Name of job + ulong time; /// Time started (us) + ulong duration; /// Took time (us) +} + +/// First in first out queue with atomic lock +struct JobQueue +{ + alias LockType = int; + align(64) shared LockType lock; /// Lock for accesing list of Jobs + align(64) JobData* first; /// Fist element in list of Jobs + + /// Check if empty without locking, doesn't give guarantee that list is truly empty + bool emptyRaw() + { + bool isEmpty = first == null; + return isEmpty; + } + + /// Check if empty + bool empty() + { + while (!cas(&lock, cast(LockType) false, cast(LockType) true)) + instructionPause(); + + bool isEmpty = first == null; + atomicStore!(MemoryOrder.rel)(lock, cast(LockType) false); + return isEmpty; + } + + /// Add job to queue + void add(JobData* t) + { + while (!cas(&lock, cast(LockType) false, cast(LockType) true)) + instructionPause(); + + t.next = first; + first = t; + + atomicStore!(MemoryOrder.rel)(lock, cast(LockType) false); + } + + /// Add range of jobs to queue + void addRange(Range)(Range arr) + { + if (arr.length == 0) + return; + + JobData* start = arr[0]; + JobData* last = start; + + foreach (t; arr[1 .. $]) + { + last.next = t; + last = t; + } + + while (!cas(&lock, cast(LockType) false, cast(LockType) true)) + instructionPause(); + last.next = first; + first = start; + atomicStore!(MemoryOrder.rel)(lock, cast(LockType) false); + } + + /// Pop job from queue + JobData* pop() + { + while (!cas(&lock, cast(LockType) false, cast(LockType) true)) + instructionPause(); + + if (first == null) + { + atomicStore!(MemoryOrder.rel)(lock, cast(LockType) false); + return null; + } + + JobData* result = first; + first = first.next; + + atomicStore!(MemoryOrder.rel)(lock, cast(LockType) false); + return result; + } + +} + +/// Structure containing job data +/// JobData memory is allocated by user +/// JobData lifetime is managed by user +/// JobData has to live as long as it's group or end of job execution +/// JobData fields can be changed in del delegate and job can be added to thread pool again, to continue execution (call same function again or another if del was changed) +struct JobData +{ + JobDelegate del; /// Delegate to execute + string name; /// Name of job + private JobsGroup* group; /// Group to which this job belongs + private align(64) JobData* next; /// JobData makes a list of jobs to be done by thread +} + +/// Structure responsible for thread in thread pool +/// Stores jobs to be executed by this thread (jobs can be stolen by another thread) +/// Stores cache for logs +struct ThreadData +{ +public: + ThreadPool* threadPool; /// Pool this thread belongs to + int threadId; /// Thread id. Valid only for this thread pool + + /// Function starting execution of thread main loop + /// External threads can call this function to start executing jobs + void threadStartFunc() + { + //end = false; + threadFunc(&this); + } + +private: + JobQueue jobsQueue; /// Queue of jobs to be done, jobs can be stolen from another thread + JobQueue jobsExclusiveQueue; /// Queue of jobs to be done, jobs can't be stolen + align(64) Semaphore semaphore; /// Semaphore to wake/sleep this thread + align(64) Thread thread; /// Systemn thread handle + JobLog[] logs; /// Logs cache + int lastLogIndex = -1; /// Last created log index + int jobsDoneCount; + + shared bool end; /// Check if thread has to exit. Thread will exit only if end is true and jobsToDo is empty + shared bool acceptJobs; /// Check if thread should accept new jobs, If false thread won't steal jobs from other threads and will sleep longer if queue js empty + bool externalThread; /// Thread not allocated by thread pool + +} + +/// Thread Pool +/// Manages bounch of threads to execute given jobs as quickly as possible +/// There are no priorities beetween jobs. Jobs added to queues in same order as they are in slices, but due to job stealing and uneven speed of execution beetween threads jobs execution order is unspecified. +/// Number of threads executing jobs can be dynamically changed in any time. Threads removed from execution will work until the end of the program but shouldn't accept new jobs. +struct ThreadPool +{ + alias FlushLogsDelegaste = void delegate(ThreadData* threadData, JobLog[] logs); /// Type of delegate to flush logs + FlushLogsDelegaste onFlushLogs; /// User custom delegate to flush logs, if overriden defaultFlushLogs will be used. Can be sset after initialize() call + int logsCacheNum; /// Number of log cache entries. Should be set before setThreadsNum is called + int tryWaitCount = 2000; ///Number of times which tryWait are called before timedWait call. Higher value sets better response but takes CPU time even if there are no jobs. +private: + ThreadData*[gMaxThreadsNum] threadsData; /// Data for threads + align(64) shared int threadsNum; /// Number of threads currentlu accepting jobs + align(64) shared bool threadsDataLock; /// Any modification of threadsData array (change in size or pointer modification) had to be locked + align(64) shared int threadSelector; /// Index of thread to which add next job + FILE* logFile; /// File handle for defaultFlushLogs log file + JobData[4] resumeJobs; /// Dummu jobs to resume some thread + +public: + + static int getCPUCoresCount() + { + version(Windows) + { + import core.sys.windows.winbase : SYSTEM_INFO, GetSystemInfo; + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; + } + else version (linux) + { + version(D_BetterC) + { + import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf; + return cast(int)sysconf(_SC_NPROCESSORS_ONLN); + } + else + { + import core.sys.linux.sched : CPU_COUNT, cpu_set_t, sched_getaffinity; + import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf; + + cpu_set_t set = void; + if (sched_getaffinity(0, cpu_set_t.sizeof, &set) == 0) + { + int count = CPU_COUNT(&set); + if (count > 0) + return cast(uint) count; + } + return cast(int)sysconf(_SC_NPROCESSORS_ONLN); + } + } + else version(Posix) + { + import core.sys.posix.unistd; + return cast(int)sysconf(_SC_NPROCESSORS_ONLN); + } + else return -1; + } + + int jobsDoneCount() + { + int sum; + foreach (i, ref ThreadData* th; threadsData) + { + if (th is null) + continue; + + sum += th.jobsDoneCount; + } + return sum; + } + + void jobsDoneCountReset() + { + foreach (i, ref ThreadData* th; threadsData) + { + if (th is null) + continue; + th.jobsDoneCount = 0; + } + } + /// Initialize thread pool + void initialize() + { + + foreach (ref JobData j; resumeJobs) + j = JobData(&dummyJob, "Dummy-Resume"); + + version (MM_NO_LOGS) + { + logsCacheNum = 0; + } + else + { + onFlushLogs = &defaultFlushLogs; + logsCacheNum = 1024; + + logFile = fopen("trace.json", "w"); + fprintf(logFile, "["); + fclose(logFile); + logFile = fopen("trace.json", "a"); + assert(logFile !is null); + } + } + + /// Clean ups ThreadPool + ~this() + { + version (MM_NO_LOGS) + { + + } + else if (logFile) + { + fclose(logFile); + logFile = null; + } + + + } + + /// Registers external thread to thread pool array. There will be allocated data for this thread and it will have specified id + /// External threads are not joined at the end of thread pool execution + /// Returns ThreadData corresponding to external thread. To acually start executing, external thread had to call threadStartFunc() from returned variable + ThreadData* registerExternalThread() + { + lockThreadsData(); + //scope (exit) + + + ThreadData* threadData = makeThreadData(); + threadData.threadPool = &this; + threadData.semaphore.initialize(); + threadData.externalThread = true; + atomicStore(threadData.acceptJobs, true); + //threadData.acceptJobs = true; + + int threadNum = atomicOp!"+="(threadsNum, 1) - 1; + + threadData.threadId = threadNum; + + threadsData[threadNum] = threadData; + + unlockThreadsData(); + + return threadData; + } + + /// Unregisters external thread. Can be called only when external thread have left the thread pool + void unregistExternalThread(ThreadData* threadData) + { + lockThreadsData(); + //scope (exit) + // unlockThreadsData(); + + disposeThreadData(threadData); + unlockThreadsData(); + } + + /// Allows external threads to return from threadStartFunc + void releaseExternalThreads() + { + lockThreadsData(); + //scope (exit) + // unlockThreadsData(); + + // Release external threads (including main thread) + foreach (i, ref ThreadData* th; threadsData) + { + if (th is null) + continue; + if (!th.externalThread) + continue; + + auto rng = resumeJobs[].map!((ref a) => &a); + addJobsRange(rng, cast(int) i); + atomicStore(th.end, true); + } + unlockThreadsData(); + } + + /// Waits for all threads to finish and joins them (excluding external threads) + void waitThreads() + { + lockThreadsData(); + //scope (exit) + // unlockThreadsData(); + foreach (i, ref ThreadData* th; threadsData) + { + if (th is null) + continue; + + atomicStore(th.acceptJobs, false); + atomicStore(th.end, true); + } + foreach (i, ref ThreadData* th; threadsData) + { + if (th is null || th.externalThread) + continue; + + th.thread.join(); + disposeThreadData(th); + } + unlockThreadsData(); + } + + /// Sets number of threads to accept new jobs + /// If there were never so much threads created, they will be created + /// If number of threads set is smaller than there was threads before, they are not joined but they stop getting new jobs, they stop stealing jobs and they sleep longer + /// Locking operation + void setThreadsNum(int num) + { + assert(num <= gMaxThreadsNum); + assert(num > 0); + + lockThreadsData(); + //scope (exit) + // unlockThreadsData(); + + foreach (i, ref ThreadData* th; threadsData) + { + if (th) + { + // Exists but has to be disabled + atomicStore(th.acceptJobs, i < num); + continue; + } + else if (i >= num) + { + // Doesn't exist and is not required + continue; + } + // Doesn't exist and is required + th = makeThreadData(); + th.threadPool = &this; + th.threadId = cast(int) i; + atomicStore(th.acceptJobs, true); + //th.acceptJobs = true; + th.semaphore.initialize(); + + th.thread.start(&th.threadStartFunc); + } + + atomicStore(threadsNum, num); + unlockThreadsData(); + } + + /// Adds job to be executed by thread pool, such a job won't be synchronized with any group or job + /// If threadNum is different than -1 only thread with threadNum will be able to execute given job + /// It is advised to use synchronized group of jobs + void addJobAsynchronous(JobData* data, int threadNum = -1) + { + if (threadNum == -1) + { + ThreadData* threadData = getThreadDataToAddJobTo(); + threadData.jobsQueue.add(data); + threadData.semaphore.post(); + return; + } + ThreadData* threadData = threadsData[threadNum]; + assert(threadData !is null); + threadData.jobsExclusiveQueue.add(data); + threadData.semaphore.post(); + } + + /// Adds job to be executed by thread pool, group specified in group data won't be finished until this job ends + /// If threadNum is different than -1 only thread with threadNum will be able to execute given job + void addJob(JobData* data, int threadNum = -1) + { + assert(data.group); + atomicOp!"+="(data.group.jobsToBeDoneCount, 1); + addJobAsynchronous(data, threadNum); + } + + /// Adds multiple jobs at once + /// Range has to return JobData* + /// Range has to have length property + /// Range is used so there is no need to allocate JobData*[] + /// All jobs has to belong to one group + /// If threadNum is different than -1 only thread with threadNum will be able to execute given jobs + void addJobsRange(Range)(Range rng, int threadNum = -1) + { + if (threadNum != -1) + { + ThreadData* threadData = threadsData[threadNum]; + assert(threadData !is null); + threadData.jobsExclusiveQueue.addRange(rng); + foreach (sInc; 0 .. rng.length) + threadData.semaphore.post(); + + return; + } + + if (rng.length == 0) + { + return; + } + + foreach (JobData* threadData; rng) + { + assert(rng[0].group == threadData.group); + } + + atomicOp!"+="(rng[0].group.jobsToBeDoneCount, cast(int) rng.length); + int threadsNumLocal = atomicLoad(threadsNum); + int part = cast(int) rng.length / threadsNumLocal; + if (part > 0) + { + foreach (i, ThreadData* threadData; threadsData[0 .. threadsNumLocal]) + { + auto slice = rng[i * part .. (i + 1) * part]; + threadData.jobsQueue.addRange(slice); + + foreach (sInc; 0 .. part) + threadData.semaphore.post(); + + } + rng = rng[part * threadsNumLocal .. $]; + } + foreach (i, ThreadData* threadData; threadsData[0 .. rng.length]) + { + threadData.jobsQueue.add(rng[i]); + threadData.semaphore.post(); + } + + } + + /// Adds group of jobs to threadPool, group won't be synchronized + void addGroupAsynchronous(JobsGroup* group) + { + group.thPool = &this; + + if (group.jobs.length == 0) + { + // Immediately call group end + group.onGroupFinish(); + return; + } + group.setUpJobs(); + auto rng = group.jobs[].map!((ref a) => &a); + addJobsRange(rng, group.executeOnThreadNum); + } + + /// Adds group of jobs to threadPool + /// Spwaning group will finish after this group have finished + void addGroup(JobsGroup* group, JobsGroup* spawnedByGroup) + { + assert(spawnedByGroup); + group.spawnedByGroup = spawnedByGroup; + atomicOp!"+="(spawnedByGroup.jobsToBeDoneCount, 1); // Increase by one, so 'spawning group' will wait for 'newly added group' to finish + addGroupAsynchronous(group); // Synchronized by jobsToBeDoneCount atomic variable + } + + /// Explicitly calls onFlushLogs on all threads + void flushAllLogs() + { + lockThreadsData(); + //scope (exit) + // unlockThreadsData(); + foreach (thNum; 0 .. atomicLoad(threadsNum)) + { + ThreadData* th = threadsData[thNum]; + onThreadFlushLogs(th); + } + + foreach (i, ref ThreadData* th; threadsData) + { + if (th is null) + continue; + + onThreadFlushLogs(th); + } + unlockThreadsData(); + } + + /// Default implementation of flushing logs + /// Saves logs to trace.json file in format acceptable by Google Chrome tracking tool chrome://tracing/ + /// Logs can be watched even if apllication crashed, but might require removing last log entry from trace.json + void defaultFlushLogs(ThreadData* threadData, JobLog[] logs) + { + version (MM_NO_LOGS) + { + } + else + { + // (log rows num) * (static json length * time length * duration length) + long start = useconds(); + size_t size = (logs.length + 1) * (128 + 20 + 20); + size_t used = 0; + + foreach (ref log; logs) + { + size += log.name.length + 1; // size of name + } + + char* buffer = cast(char*) malloc(size); + + foreach (ref log; logs) + { + char[100] name_buffer; + name_buffer[0 .. log.name.length] = log.name; + name_buffer[log.name.length] = 0; + size_t charWritten = snprintf(buffer + used, size - used, + `{"name":"%s", "pid":1, "tid":%lld, "ph":"X", "ts":%lld, "dur":%lld }, %s`, + name_buffer.ptr, threadData.threadId + 1, log.time, log.duration, "\n".ptr); + used += charWritten; + } + + long end = useconds(); + size_t charWritten = snprintf(buffer + used, size - used, + `{"name":"logFlush", "pid":1, "tid":%lld, "ph":"X", "ts":%lld, "dur":%lld }, %s`, + threadData.threadId + 1, start, end - start, "\n".ptr); + used += charWritten; + fwrite(buffer, 1, used, logFile); + } + } + +private: + /// Atomic lock + void lockThreadsData() + { + // Only one thread at a time can change threads number in a threadpool + while (!cas(&threadsDataLock, false, true)) + { + } + } + + /// Atomic unlock + void unlockThreadsData() + { + atomicStore(threadsDataLock, false); + } + + /// Allocate ThreadData + ThreadData* makeThreadData() + { + ThreadData* threadData = makeVar!ThreadData(); + threadData.logs = makeVarArray!(JobLog)(logsCacheNum); + return threadData; + } + + /// Dispose ThreadData + void disposeThreadData(ThreadData* threadData) + { + disposeArray(threadData.logs); + return disposeVar(threadData); + } + + /// Get thread most suiting to add job to + ThreadData* getThreadDataToAddJobTo() + { + int threadNum = atomicOp!"+="(threadSelector, 1); + + foreach (i; 0 .. 1_000) + { + if (threadNum >= atomicLoad(threadsNum)) + { + threadNum = 0; + atomicStore(threadSelector, 0); + } + ThreadData* threadData = threadsData[threadNum]; + if (threadData != null) + { + return threadData; + } + threadNum++; + } + assert(0); + } + + /// Create log on start of job + void onStartJob(JobData* data, ThreadData* threadData) + { + + threadData.jobsDoneCount++; + version (MM_NO_LOGS) + { + } + else + { + if (cast(int) threadData.logs.length <= 0) + { + return; + } + if (threadData.lastLogIndex >= cast(int) threadData.logs.length - 1) + { + onThreadFlushLogs(threadData); + } + + threadData.lastLogIndex++; + + JobLog log; + log.name = data.name; + log.time = useconds(); + threadData.logs[threadData.lastLogIndex] = log; + } + } + + /// Set log finish time on end of job + void onEndJob(JobData* data, ThreadData* threadData) + { + version (MM_NO_LOGS) + { + } + else + { + if (cast(int) threadData.logs.length <= 0) + { + return; + } + assert(threadData.lastLogIndex < threadData.logs.length); + JobLog* log = &threadData.logs[threadData.lastLogIndex]; + log.duration = useconds() - log.time; + } + } + + /// Flush logs + void onThreadFlushLogs(ThreadData* threadData) + { + /*scope (exit) + { + threadData.lastLogIndex = -1; + }*/ + + assert(threadData); + + if (threadData.lastLogIndex < 0 || onFlushLogs is null) + { + return; + } + + onFlushLogs(threadData, threadData.logs[0 .. threadData.lastLogIndex + 1]); + + threadData.lastLogIndex = -1; + } + + /// Does nothing + void dummyJob(ThreadData* threadData, JobData* data) + { + + } + + /// Steal job from another thread + JobData* stealJob(int threadNum) + { + foreach (thSteal; 0 .. atomicLoad(threadsNum)) + { + if (thSteal == threadNum) + continue; // Do not steal from requesting thread + + ThreadData* threadData = threadsData[thSteal]; + + if (threadData is null || !threadData.semaphore.tryWait()) + continue; + + JobData* data = threadData.jobsQueue.pop(); + + if (data is null) + threadData.semaphore.post(); + + return data; + } + return null; + } +} + +/// Adding groups of jobs is faster and groups can have dependencies between each other +struct JobsGroup +{ +public: + string name; /// Name of group + JobData[] jobs; /// Jobs to be executed by this group, jobs have to live as long as group lives + void delegate(JobsGroup* group) onFinish; // Delegate called when group will finish, can be used to free memory + ThreadPool* thPool; /// Thread pool of this group + int executeOnThreadNum = -1; /// Thread num to execute jobs on + + this(string name, JobData[] jobs = [], int executeOnThreadNum = -1) + { + this.name = name; + this.jobs = jobs; + this.executeOnThreadNum = executeOnThreadNum; + //jobsToBeDoneCount = 0; + //dependenciesWaitCount = 0; + atomicStore(jobsToBeDoneCount,0); + atomicStore(dependenciesWaitCount,0); + } + + ~this() nothrow + { + free(children.ptr); + children = null; + } + + /// Make this group dependant from another group + /// Dependant group won't start untill its dependencies will be fulfilled + void dependantOn(JobsGroup* parent) + { + size_t newLen = parent.children.length + 1; + JobsGroup** ptr = cast(JobsGroup**) realloc(parent.children.ptr, + newLen * (JobsGroup*).sizeof); + parent.children = ptr[0 .. newLen]; + parent.children[$ - 1] = &this; + // parent.children ~= &this; + atomicOp!"+="(dependenciesWaitCount, 1); + } + + /// Returns number of dependencies this group is waiting for + int getDependenciesWaitCount() + { + return atomicLoad(dependenciesWaitCount); + } + +private: + JobsGroup* spawnedByGroup; /// Group which spawned this group, if present spwaning group is waiting for this group to finish + JobsGroup*[] children; /// Groups depending on this group + align(64) shared int dependenciesWaitCount; /// Count of dependencies this group waits for + align(64) shared int jobsToBeDoneCount; /// Number of this group jobs still executing + + /// Checks if depending groups or spawning group have to be started + /// Executes user onFinish function + void onGroupFinish() + { + + decrementChildrendependencies(); + if (spawnedByGroup) + { + auto num = atomicOp!"-="(spawnedByGroup.jobsToBeDoneCount, 1); + assert(num >= 0); + if (num == 0) + { + spawnedByGroup.onGroupFinish(); + } + } + if (onFinish) + onFinish(&this); + } + + /// Check if decrement dependencies counter and start them if theirs dependencies are fulfilled + void decrementChildrendependencies() + { + foreach (JobsGroup* group; children) + { + auto num = atomicOp!"-="(group.dependenciesWaitCount, 1); + assert(num >= 0); + if (num == 0) + { + thPool.addGroupAsynchronous(group); // All dependencies of this group are fulfilled, so is already synchronized + } + } + } + /// Prepare jobs data for adding to thread pool + void setUpJobs() + { + foreach (i; 0 .. jobs.length) + { + jobs[i].group = &this; + } + } + +} + +/// Main function executed by thread present in thread pool +/// Executes functions from its own queue +/// If there are no jobs in its queue, steals from another thread +/// If there is nothing to steal, sleeps on its semaphore for a while (stage when cpu is not used) +/// Sleep time is longer for jobs not accepting jobs, they don't exit because it is hard to guarantee that nobody is adding to them some job (thread might exit but job will be added anyway and application will malfunctio +/// Thread end only when it's queue is empty. Jobs shouldn't be added to queue after ThreadPool.waitThreads() call +private void threadFunc(ThreadData* threadData) +{ + ThreadPool* threadPool = threadData.threadPool; + int threadNum = threadData.threadId; + + while (!atomicLoad!(MemoryOrder.raw)(threadData.end) + || !threadData.jobsQueue.empty() || !threadData.jobsExclusiveQueue.empty()) + { + JobData* data; + if (threadData.semaphore.tryWait()) + { + if (!threadData.jobsExclusiveQueue.emptyRaw()) + data = threadData.jobsExclusiveQueue.pop(); + + if (data is null) + data = threadData.jobsQueue.pop(); + + if (data is null) + threadData.semaphore.post(); + + assert(data !is null); + } + else + { + bool acceptJobs = atomicLoad!(MemoryOrder.raw)(threadData.acceptJobs); + if (acceptJobs) + { + data = threadPool.stealJob(threadNum); + } + + if (data is null) + { + // Thread does not have own job and can not steal it, so wait for a job + int tryWait = 0; + //bool ok = threadData.semaphore.timedWait(1_000 + !acceptJobs * 10_000); + bool ok = true; + while(!threadData.semaphore.tryWait()) + { + tryWait++; + if(tryWait>threadPool.tryWaitCount) + { + ok = false; + break; + } + static foreach(i;0..10)instructionPause(); + } + if(!ok)ok = threadData.semaphore.timedWait(1_000 + !acceptJobs * 10_000); + + if (ok) + { + + if (!threadData.jobsExclusiveQueue.emptyRaw()) + data = threadData.jobsExclusiveQueue.pop(); + + if (data is null) + data = threadData.jobsQueue.pop(); + + if (data is null) + threadData.semaphore.post(); + } + } + } + + // Nothing to do + if (data is null) + { + continue; + } + + // Do the job + threadPool.onStartJob(data, threadData); + data.del(threadData, data); + threadPool.onEndJob(data, threadData); + if (data.group) + { + auto num = atomicOp!"-="(data.group.jobsToBeDoneCount, 1); + if (num == 0) + { + data.group.onGroupFinish(); + } + } + + } + //threadData.end = false; + atomicStore(threadData.end, false); + assert(threadData.jobsQueue.empty()); +} + +////////////////////////////////////////////// +//////////////////// Test //////////////////// +////////////////////////////////////////////// +/* +void testThreadPool() +{ + enum jobsNum = 1024 * 4; + + ThreadPool thPool; + thPool.initialize(); + + ThreadData* mainThread = thPool.registerExternalThread(); // Register main thread as thread 0 + JobData startFrameJobData; // Variable to store job starting the TestApp + + JobData[jobsNum] frameJobs; // Array to store jobs created in TestApp.continueFrameInOtherJob + shared int frameNum; // Simulate game loop, run jobs for few frames and exit + + // App starts as one job &startFrame + // Then using own JobData memory spawns 'continueFrameInOtherJob' job + // 'continueFrameInOtherJob' job fills frameJobs array with &importantTask jobs. Group created to run this jobs is freed using JobsGroup.onFinish delegate + // 'importantTask' allocate new jobs (&importantTaskSubTask) and group, they all deallocated using JobsGroup.onFinish delegate + // 'continueFrameInOtherJob' waits for all 'importantTask'. All 'importantTask' wait for all 'importantTaskSubTask'. + // So after all 'importantTaskSubTask' and 'importantTask' are done 'continueFrameInOtherJob' ends and spawns &finishFrame + // 'finishFrame' spawn new frame or exits application + struct TestApp + { + // First job in frame + // Do some stuff and spawn some other job + // 1 - Number of jobs of this kind in frame + void startFrame(ThreadData* threadData, JobData* startFrameJobData) + { + startFrameJobData.del = &continueFrameInOtherJobAAA; + startFrameJobData.name = "cont frmAAA"; + thPool.addJobAsynchronous(startFrameJobData, thPool.threadsNum - 1); /// startFrame is the only job in thread pool no synchronization is required + } + + void continueFrameInOtherJobAAA(ThreadData* threadData, JobData* startFrameJobData) + { + + static struct JobGroupMemory + { + JobsGroup[6] groups; + JobData[1][6] groupsJobs; + TestApp* app; + JobData* startFrameJobData; + + void spawnCont(JobsGroup* group) + { + // startFrameJobData.del = &continueFrameInOtherJob; + startFrameJobData.del = &app.finishFrame; + startFrameJobData.name = "cont frm"; + group.thPool.addJobAsynchronous(startFrameJobData); /// startFrame is the only job in thread pool no synchronization is required + + } + } + + JobGroupMemory* memory = makeVar!JobGroupMemory(); + memory.app = &this; + memory.startFrameJobData = startFrameJobData; + + with (memory) + { + groups[0] = JobsGroup("dependant 0", groupsJobs[0]); + groups[1] = JobsGroup("dependant 1", groupsJobs[1]); + groups[2] = JobsGroup("dependant 2", groupsJobs[2]); + groups[3] = JobsGroup("dependant 3", groupsJobs[3]); + groups[4] = JobsGroup("dependant 4", groupsJobs[4]); + groups[5] = JobsGroup("dependant 5", groupsJobs[5]); + groups[5].onFinish = &spawnCont; + + groups[2].dependantOn(&groups[0]); + groups[2].dependantOn(&groups[1]); + + groups[3].dependantOn(&groups[0]); + groups[3].dependantOn(&groups[1]); + groups[3].dependantOn(&groups[2]); + + groups[4].dependantOn(&groups[1]); + groups[4].dependantOn(&groups[3]); + + groups[5].dependantOn(&groups[0]); + groups[5].dependantOn(&groups[1]); + groups[5].dependantOn(&groups[2]); + groups[5].dependantOn(&groups[3]); + groups[5].dependantOn(&groups[4]); + + foreach (ref jobs; groupsJobs) + foreach (ref j; jobs) + j = JobData(&this.importantTaskSubTask, "n"); + + thPool.addGroupAsynchronous(&groups[0]); + thPool.addGroupAsynchronous(&groups[1]); + } + } + + // Job for some big system + // Spawns some jobs and when they are done spawns finishFrame job + // 1 - Number of jobs of this kind in frame + void continueFrameInOtherJob(ThreadData* threadData, JobData* startFrameJobData) + { + static struct JobGroupMemory + { + JobsGroup group; + TestApp* app; + JobData* startFrameJobData; + + void freeAndContinue(JobsGroup* group) + { + startFrameJobData.del = &app.finishFrame; + startFrameJobData.name = "finishFrame"; + group.thPool.addJobAsynchronous(startFrameJobData, group.thPool.threadsNum - 1); /// startFrameJobData is continuation of 'startFrame data', all important jobs finished so it is the only job, no synchronization required. Always spawn on last thread + disposeVar!(JobGroupMemory)(&this); + } + } + + JobGroupMemory* important = makeVar!JobGroupMemory(); + important.app = &this; + important.startFrameJobData = startFrameJobData; + + foreach (ref j; frameJobs) + j = JobData(&this.importantTask, "vip"); + + important.group = JobsGroup("a lot of jobs", frameJobs[]); + important.group.onFinish = &important.freeAndContinue; + + thPool.addGroupAsynchronous(&important.group); // No Synchronization required continueFrameInOtherJob is the only job + } + + // Some task which by itself does a lot of computation so it spawns few more jobs + // jobsNum - Number of jobs of this kind in frame + void importantTask(ThreadData* threadData, JobData* data) + { + // All tasks created here will, make 'importantTask' wait with finish untill this jobs will finish + + /// Add 10 tasks in group + static struct JobGroupMemory + { + JobsGroup group; + JobData[128] jobs; + + void freeMee(JobsGroup* group) + { + disposeVar!(JobGroupMemory)(&this); + } + } + + JobGroupMemory* subGroup = makeVar!JobGroupMemory(); + + foreach (ref j; subGroup.jobs) + j = JobData(&this.importantTaskSubTask, "vip sub"); + + subGroup.group = JobsGroup("128 jobs", subGroup.jobs[]); + subGroup.group.onFinish = &subGroup.freeMee; + thPool.addGroup(&subGroup.group, data.group); + + /// Add single tasks + data.del = &importantTaskSubTask; + data.name = "sub"; + thPool.addJob(data); + } + + // Job which simply does some work + // jobsNum * 128 - Number of jobs of this kind in frame + void importantTaskSubTask(ThreadData* threadData, JobData* data) + { + } + + // Finish frame + // 1 - Number of jobs of this kind in frame + void finishFrame(ThreadData* threadData, JobData* startFrameJobData) + { + auto num = atomicOp!"+="(frameNum, 1); + if (num == 10) + { + thPool.releaseExternalThreads(); // After 10 frames exit application + return; + } + *startFrameJobData = JobData(&startFrame, "StartFrame"); // + thPool.addJobAsynchronous(startFrameJobData); // Start next frame, there should't be any other tasks execept of this one, so no synchronization is required + + } + + // Func to test if dynamic changing of threads number works + // void changeThreadsNum() + // { + // import std.random : uniform; + + // bool change = uniform(0, 100) == 3; + // if (!change) + // return; + + // int threadsNum = uniform(3, 5); + // thPool.setThreadsNum(threadsNum); + + // } + } + + void testThreadsNum(int threadsNum) + { + frameNum = 0; + thPool.jobsDoneCountReset(); + thPool.setThreadsNum(threadsNum); + + TestApp testApp = TestApp(); + startFrameJobData = JobData(&testApp.startFrame, "StartFrame"); // Start first frame, will live as long as main thread won't exit from threadStartFunc() + + ulong start = useconds(); + thPool.addJobAsynchronous(&startFrameJobData); // Synchronization is made by groupEnd (last job in pool) which calls thPool.releaseExternalThreads(); + mainThread.threadStartFunc(); + ulong end = useconds(); + printf("Threads Num: %2d. Jobs: %d. Time: %5.2f ms. jobs/ms: %5.2f\n", threadsNum, thPool.jobsDoneCount, + (end - start) / 1000.0f, thPool.jobsDoneCount / ((end - start) / 1000.0f)); + } + + while (1) + { + // foreach (i; 1 .. 32) + // testThreadsNum(i); + + testThreadsNum(1); + testThreadsNum(4); + testThreadsNum(16); + } + thPool.flushAllLogs(); + thPool.waitThreads(); + thPool.unregistExternalThread(mainThread); +} + +version (D_BetterC) +{ + + extern (C) int main(int argc, char*[] argv) // for betterC + { + testThreadPool(); + return 0; + } +} +else +{ + int main() + { + testThreadPool(); + return 0; + } +}//*/ +// Compile +// -fsanitize=address +// rdmd -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool +// ldmd2 -release -inline -checkaction=C -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool +// ldmd2 -checkaction=C -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/package.d b/demos/external/wasm_imports/bindbc/sdl/bind/package.d new file mode 100644 index 0000000..1a6697c --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/package.d @@ -0,0 +1,46 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind; + +public +import bindbc.sdl.bind.sdl, + bindbc.sdl.bind.sdlassert, + bindbc.sdl.bind.sdlaudio, + bindbc.sdl.bind.sdlblendmode, + bindbc.sdl.bind.sdlclipboard, + bindbc.sdl.bind.sdlcpuinfo, + bindbc.sdl.bind.sdlerror, + bindbc.sdl.bind.sdlevents, + bindbc.sdl.bind.sdlfilesystem, + bindbc.sdl.bind.sdlgamecontroller, + bindbc.sdl.bind.sdlgesture, + bindbc.sdl.bind.sdlhaptic, + bindbc.sdl.bind.sdlhints, + bindbc.sdl.bind.sdljoystick, + bindbc.sdl.bind.sdlkeyboard, + bindbc.sdl.bind.sdlkeycode, + bindbc.sdl.bind.sdlloadso, + bindbc.sdl.bind.sdllog, + bindbc.sdl.bind.sdlmessagebox, + bindbc.sdl.bind.sdlmouse, + bindbc.sdl.bind.sdlpixels, + bindbc.sdl.bind.sdlplatform, + bindbc.sdl.bind.sdlpower, + bindbc.sdl.bind.sdlrect, + bindbc.sdl.bind.sdlrender, + bindbc.sdl.bind.sdlrwops, + bindbc.sdl.bind.sdlscancode, + bindbc.sdl.bind.sdlshape, + bindbc.sdl.bind.sdlstdinc, + bindbc.sdl.bind.sdlsurface, + bindbc.sdl.bind.sdlsystem, + bindbc.sdl.bind.sdlsyswm, + bindbc.sdl.bind.sdltimer, + bindbc.sdl.bind.sdltouch, + bindbc.sdl.bind.sdlversion, + bindbc.sdl.bind.sdlvideo, + bindbc.sdl.bind.sdlvulkan; \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdl.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdl.d new file mode 100644 index 0000000..7b384ef --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdl.d @@ -0,0 +1,69 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdl; + +import bindbc.sdl.config; + +static if(sdlSupport >= SDLSupport.sdl209) { + enum : uint { + SDL_INIT_TIMER = 0x00000001, + SDL_INIT_AUDIO = 0x00000010, + SDL_INIT_VIDEO = 0x00000020, + SDL_INIT_JOYSTICK = 0x00000200, + SDL_INIT_HAPTIC = 0x00001000, + SDL_INIT_GAMECONTROLLER = 0x00002000, + SDL_INIT_EVENTS = 0x00004000, + SDL_INIT_SENSOR = 0x00008000, + SDL_INIT_NOPARACHUTE = 0x00100000, + SDL_INIT_EVERYTHING = + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | + SDL_INIT_EVENTS | SDL_INIT_SENSOR + } +} else { + enum : uint { + SDL_INIT_TIMER = 0x00000001, + SDL_INIT_AUDIO = 0x00000010, + SDL_INIT_VIDEO = 0x00000020, + SDL_INIT_JOYSTICK = 0x00000200, + SDL_INIT_HAPTIC = 0x00001000, + SDL_INIT_GAMECONTROLLER = 0x00002000, + SDL_INIT_EVENTS = 0x00004000, + SDL_INIT_NOPARACHUTE = 0x00100000, + SDL_INIT_EVERYTHING = + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | + SDL_INIT_EVENTS + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_Init(uint); + int SDL_InitSubSystem(uint); + void SDL_QuitSubSystem(uint); + uint SDL_WasInit(uint); + void SDL_Quit(); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_Init = int function(uint); + alias pSDL_InitSubSystem = int function(uint); + alias pSDL_QuitSubSystem = void function(uint); + alias pSDL_WasInit = uint function(uint); + alias pSDL_Quit = void function(); + } + + __gshared { + pSDL_Init SDL_Init; + pSDL_InitSubSystem SDL_InitSubSystem; + pSDL_QuitSubSystem SDL_QuitSubSystem; + pSDL_WasInit SDL_WasInit; + pSDL_Quit SDL_Quit; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlassert.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlassert.d new file mode 100644 index 0000000..784e0e8 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlassert.d @@ -0,0 +1,70 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlassert; + +import bindbc.sdl.config; + +enum SDL_assert_state : uint { + SDL_ASSERTION_RETRY = 0, + SDL_ASSERTION_BREAK = 1, + SDL_ASSERTION_ABORT = 2, + SDL_ASSERTION_IGNORE = 3, + SDL_ASSERTION_ALWAYS_IGNORE = 4 +} +alias SDL_AssertState = SDL_assert_state; +mixin(expandEnum!SDL_AssertState); + +struct SDL_assert_data { + int always_ignore; + uint trigger_count; + const(char) *condition; + const(char) *filename; + int linenum; + const(char) *function_; + const(SDL_assert_data) *next; +} +alias SDL_AssertData = SDL_assert_data; + +extern(C) nothrow alias SDL_AssertionHandler = SDL_AssertState function(const(SDL_AssertData)* data, void* userdata); + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + void SDL_SetAssertionHandler(SDL_AssertionHandler,void*); + const(SDL_assert_data)* SDL_GetAssertionReport(); + void SDL_ResetAssertionReport(); + + static if(sdlSupport >= SDLSupport.sdl202) { + SDL_AssertionHandler SDL_GetAssertionHandler(void**); + SDL_AssertionHandler SDL_GetDefaultAssertionHandler(); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_SetAssertionHandler = void function(SDL_AssertionHandler,void*); + alias pSDL_GetAssertionReport = const(SDL_assert_data)* function(); + alias pSDL_ResetAssertionReport = void function(); + } + + __gshared { + pSDL_SetAssertionHandler SDL_SetAssertionHandler; + pSDL_GetAssertionReport SDL_GetAssertionReport; + pSDL_ResetAssertionReport SDL_ResetAssertionReport; + } + + static if(sdlSupport >= SDLSupport.sdl202) { + extern(C) @nogc nothrow { + alias pSDL_GetAssertionHandler = SDL_AssertionHandler function(void**); + alias pSDL_GetDefaultAssertionHandler = SDL_AssertionHandler function(); + } + + __gshared { + pSDL_GetAssertionHandler SDL_GetAssertionHandler; + pSDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler; + } + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlaudio.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlaudio.d new file mode 100644 index 0000000..3cb37d8 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlaudio.d @@ -0,0 +1,283 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlaudio; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlrwops; + +enum : ushort { + SDL_AUDIO_MASK_BITSIZE = 0xFF, + SDL_AUDIO_MASK_DATATYPE = 1<<8, + SDL_AUDIO_MASK_ENDIAN = 1<<12, + SDL_AUDIO_MASK_SIGNED = 1<<15, +} + +enum SDL_AudioFormat : ushort { + AUDIO_U8 = 0x0008, + AUDIO_S8 = 0x8008, + AUDIO_U16LSB = 0x0010, + AUDIO_S16LSB = 0x8010, + AUDIO_U16MSB = 0x1010, + AUDIO_S16MSB = 0x9010, + AUDIO_U16 = AUDIO_U16LSB, + AUDIO_S16 = AUDIO_S16LSB, + AUDIO_S32LSB = 0x8020, + AUDIO_S32MSB = 0x9020, + AUDIO_S32 = AUDIO_S32LSB, + AUDIO_F32LSB = 0x8120, + AUDIO_F32MSB = 0x9120, + AUDIO_F32 = AUDIO_F32LSB, +} +mixin(expandEnum!SDL_AudioFormat); + +version(LittleEndian) { + alias AUDIO_U16SYS = AUDIO_U16LSB; + alias AUDIO_S16SYS = AUDIO_S16LSB; + alias AUDIO_S32SYS = AUDIO_S32LSB; + alias AUDIO_F32SYS = AUDIO_F32LSB; +} else { + alias AUDIO_U16SYS = AUDIO_U16MSB; + alias AUDIO_S16SYS = AUDIO_S16MSB; + alias AUDIO_S32SYS = AUDIO_S32MSB; + alias AUDIO_F32SYS = AUDIO_F32MSB; +} + +enum SDL_AUDIO_BITSIZE(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_BITSIZE; +enum SDL_AUDIO_ISFLOAT(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_DATATYPE; +enum SDL_AUDIO_ISBIGENDIAN(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_ENDIAN; +enum SDL_AUDIO_ISSIGNED(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_SIGNED; +enum SDL_AUDIO_ISINT(SDL_AudioFormat x) = !SDL_AUDIO_ISFLOAT!x; +enum SDL_AUDIO_ISLITTLEENDIAN(SDL_AudioFormat x) = !SDL_AUDIO_ISBIGENDIAN!x; +enum SDL_AUDIO_ISUNSIGNED(SDL_AudioFormat x) = !SDL_AUDIO_ISSIGNED!x; + +static if(sdlSupport >= SDLSupport.sdl209) { + enum { + SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001, + SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002, + SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004, + SDL_AUDIO_ALLOW_SAMPLES_CHANGE = 0x00000008, + SDL_AUDIO_ALLOW_ANY_CHANGE = SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | + SDL_AUDIO_ALLOW_FORMAT_CHANGE | + SDL_AUDIO_ALLOW_CHANNELS_CHANGE | + SDL_AUDIO_ALLOW_SAMPLES_CHANGE, + } +} +else { + enum { + SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001, + SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002, + SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004, + SDL_AUDIO_ALLOW_ANY_CHANGE = SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | + SDL_AUDIO_ALLOW_FORMAT_CHANGE | + SDL_AUDIO_ALLOW_CHANNELS_CHANGE, + } +} + +extern(C) nothrow alias SDL_AudioCallback = void function(void* userdata, ubyte* stream, int len); +struct SDL_AudioSpec { + int freq; + SDL_AudioFormat format; + ubyte channels; + ubyte silence; + ushort samples; + ushort padding; + uint size; + SDL_AudioCallback callback; + void* userdata; +} + +// Declared in 2.0.6, but doesn't hurt to use here +enum SDL_AUDIOCVT_MAX_FILTERS = 9; + +extern(C) nothrow alias SDL_AudioFilter = void function(SDL_AudioCVT* cvt, SDL_AudioFormat format); +struct SDL_AudioCVT { + int needed; + SDL_AudioFormat src_format; + SDL_AudioFormat dst_format; + double rate_incr; + ubyte* buf; + int len; + int len_cvt; + int len_mult; + double len_ratio; + SDL_AudioFilter[SDL_AUDIOCVT_MAX_FILTERS + 1] filters; + int filter_index; +} + +alias SDL_AudioDeviceID = uint; + +enum SDL_AudioStatus { + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED, +} +mixin(expandEnum!SDL_AudioStatus); + +enum SDL_MIX_MAXVOLUME = 128; + +static if(sdlSupport >= SDLSupport.sdl207) { + struct SDL_AudioStream; +} + +@nogc nothrow +SDL_AudioSpec* SDL_LoadWAV(const(char)* file, SDL_AudioSpec* spec, ubyte** audio_buf, uint* len) { + pragma(inline, true); + return SDL_LoadWAV_RW(SDL_RWFromFile(file,"rb"),1,spec,audio_buf,len); +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_GetNumAudioDrivers(); + const(char)* SDL_GetAudioDriver(int); + int SDL_AudioInit(const(char)*); + void SDL_AudioQuit(); + const(char)* SDL_GetCurrentAudioDriver(); + int SDL_OpenAudio(SDL_AudioSpec*,SDL_AudioSpec*); + int SDL_GetNumAudioDevices(int); + const(char)* SDL_GetAudioDeviceName(int,int); + SDL_AudioDeviceID SDL_OpenAudioDevice(const(char)*,int,const(SDL_AudioSpec)*,SDL_AudioSpec*,int); + SDL_AudioStatus SDL_GetAudioStatus(); + SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID); + void SDL_PauseAudio(int); + void SDL_PauseAudioDevice(SDL_AudioDeviceID,int); + SDL_AudioSpec* SDL_LoadWAV_RW(SDL_RWops*,int,SDL_AudioSpec*,ubyte**,uint*); + void SDL_FreeWAV(ubyte*); + int SDL_BuildAudioCVT(SDL_AudioCVT*,SDL_AudioFormat,ubyte,int,SDL_AudioFormat,ubyte,int); + int SDL_ConvertAudio(SDL_AudioCVT*); + void SDL_MixAudio(ubyte*,const(ubyte)*,uint,int); + void SDL_MixAudioFormat(ubyte*,const(ubyte)*,SDL_AudioFormat,uint,int); + void SDL_LockAudio(); + void SDL_LockAudioDevice(SDL_AudioDeviceID); + void SDL_UnlockAudio(); + void SDL_UnlockAudioDevice(SDL_AudioDeviceID); + void SDL_CloseAudio(); + void SDL_CloseAudioDevice(SDL_AudioDeviceID); + + static if(sdlSupport >= SDLSupport.sdl204) { + int SDL_ClearQueuedAudio(SDL_AudioDeviceID); + int SDL_GetQueuedAudioSize(SDL_AudioDeviceID); + int SDL_QueueAudio(SDL_AudioDeviceID,const (void)*,uint); + } + + static if(sdlSupport >= SDLSupport.sdl205) { + uint SDL_DequeueAudio(SDL_AudioDeviceID,void*,uint); + } + + static if(sdlSupport >= SDLSupport.sdl207) { + SDL_AudioStream* SDL_NewAudioStream(const(SDL_AudioFormat),const(ubyte),const(int),const(SDL_AudioFormat),const(ubyte),const(int)); + int SDL_AudioStreamPut(SDL_AudioStream*,const(void)*,int); + int SDL_AudioStreamGet(SDL_AudioStream*,void*,int); + int SDL_AudioStreamAvailable(SDL_AudioStream*); + int SDL_AudioStreamFlush(SDL_AudioStream*); + void SDL_AudioStreamClear(SDL_AudioStream*); + void SDL_FreeAudioStream(SDL_AudioStream*); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetNumAudioDrivers = int function(); + alias pSDL_GetAudioDriver = const(char)* function(int); + alias pSDL_AudioInit = int function(const(char)*); + alias pSDL_AudioQuit = void function(); + alias pSDL_GetCurrentAudioDriver = const(char)* function(); + alias pSDL_OpenAudio = int function(SDL_AudioSpec*,SDL_AudioSpec*); + alias pSDL_GetNumAudioDevices = int function(int); + alias pSDL_GetAudioDeviceName = const(char)* function(int,int); + alias pSDL_OpenAudioDevice = SDL_AudioDeviceID function(const(char)*,int,const(SDL_AudioSpec)*,SDL_AudioSpec*,int); + alias pSDL_GetAudioStatus = SDL_AudioStatus function(); + alias pSDL_GetAudioDeviceStatus = SDL_AudioStatus function(SDL_AudioDeviceID); + alias pSDL_PauseAudio = void function(int); + alias pSDL_PauseAudioDevice = void function(SDL_AudioDeviceID,int); + alias pSDL_LoadWAV_RW = SDL_AudioSpec* function(SDL_RWops*,int,SDL_AudioSpec*,ubyte**,uint*); + alias pSDL_FreeWAV = void function(ubyte*); + alias pSDL_BuildAudioCVT = int function(SDL_AudioCVT*,SDL_AudioFormat,ubyte,int,SDL_AudioFormat,ubyte,int); + alias pSDL_ConvertAudio = int function(SDL_AudioCVT*); + alias pSDL_MixAudio = void function(ubyte*,const(ubyte)*,uint,int); + alias pSDL_MixAudioFormat = void function(ubyte*,const(ubyte)*,SDL_AudioFormat,uint,int); + alias pSDL_LockAudio = void function(); + alias pSDL_LockAudioDevice = void function(SDL_AudioDeviceID); + alias pSDL_UnlockAudio = void function(); + alias pSDL_UnlockAudioDevice = void function(SDL_AudioDeviceID); + alias pSDL_CloseAudio = void function(); + alias pSDL_CloseAudioDevice = void function(SDL_AudioDeviceID); + } + + __gshared { + pSDL_GetNumAudioDrivers SDL_GetNumAudioDrivers; + pSDL_GetAudioDriver SDL_GetAudioDriver; + pSDL_AudioInit SDL_AudioInit; + pSDL_AudioQuit SDL_AudioQuit; + pSDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver; + pSDL_OpenAudio SDL_OpenAudio; + pSDL_GetNumAudioDevices SDL_GetNumAudioDevices; + pSDL_GetAudioDeviceName SDL_GetAudioDeviceName; + pSDL_OpenAudioDevice SDL_OpenAudioDevice; + pSDL_GetAudioStatus SDL_GetAudioStatus; + pSDL_GetAudioDeviceStatus SDL_GetAudioDeviceStatus; + pSDL_PauseAudio SDL_PauseAudio; + pSDL_PauseAudioDevice SDL_PauseAudioDevice; + pSDL_LoadWAV_RW SDL_LoadWAV_RW; + pSDL_FreeWAV SDL_FreeWAV; + pSDL_BuildAudioCVT SDL_BuildAudioCVT; + pSDL_ConvertAudio SDL_ConvertAudio; + pSDL_MixAudio SDL_MixAudio; + pSDL_MixAudioFormat SDL_MixAudioFormat; + pSDL_LockAudio SDL_LockAudio; + pSDL_LockAudioDevice SDL_LockAudioDevice; + pSDL_UnlockAudio SDL_UnlockAudio; + pSDL_UnlockAudioDevice SDL_UnlockAudioDevice; + pSDL_CloseAudio SDL_CloseAudio; + pSDL_CloseAudioDevice SDL_CloseAudioDevice; + } + + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_ClearQueuedAudio = int function(SDL_AudioDeviceID); + alias pSDL_GetQueuedAudioSize = int function(SDL_AudioDeviceID); + alias pSDL_QueueAudio = int function(SDL_AudioDeviceID,const (void)*,uint); + } + + __gshared { + pSDL_ClearQueuedAudio SDL_ClearQueuedAudio; + pSDL_GetQueuedAudioSize SDL_GetQueuedAudioSize; + pSDL_QueueAudio SDL_QueueAudio; + } + } + + static if(sdlSupport >= SDLSupport.sdl205) { + extern(C) @nogc nothrow { + alias pSDL_DequeueAudio = uint function(SDL_AudioDeviceID,void*,uint); + } + + __gshared { + pSDL_DequeueAudio SDL_DequeueAudio; + } + } + + static if(sdlSupport >= SDLSupport.sdl207) { + extern(C) @nogc nothrow { + alias pSDL_NewAudioStream = SDL_AudioStream* function(const(SDL_AudioFormat),const(ubyte),const(int),const(SDL_AudioFormat),const(ubyte),const(int)); + alias pSDL_AudioStreamPut = int function(SDL_AudioStream*,const(void)*,int); + alias pSDL_AudioStreamGet = int function(SDL_AudioStream*,void*,int); + alias pSDL_AudioStreamAvailable = int function(SDL_AudioStream*); + alias pSDL_AudioStreamFlush = int function(SDL_AudioStream*); + alias pSDL_AudioStreamClear = void function(SDL_AudioStream*); + alias pSDL_FreeAudioStream = void function(SDL_AudioStream*); + } + + __gshared { + pSDL_NewAudioStream SDL_NewAudioStream; + pSDL_AudioStreamPut SDL_AudioStreamPut; + pSDL_AudioStreamGet SDL_AudioStreamGet; + pSDL_AudioStreamAvailable SDL_AudioStreamAvailable; + pSDL_AudioStreamFlush SDL_AudioStreamFlush; + pSDL_AudioStreamClear SDL_AudioStreamClear; + pSDL_FreeAudioStream SDL_FreeAudioStream; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlblendmode.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlblendmode.d new file mode 100644 index 0000000..a3360c2 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlblendmode.d @@ -0,0 +1,71 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlblendmode; + +import bindbc.sdl.config; + +static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_BlendMode { + SDL_BLENDMODE_NONE = 0x00000000, + SDL_BLENDMODE_BLEND = 0x00000001, + SDL_BLENDMODE_ADD = 0x00000002, + SDL_BLENDMODE_MOD = 0x00000004, + SDL_BLENDMODE_INVALID = 0x7FFFFFFF, + } + mixin(expandEnum!SDL_BlendMode); + + enum SDL_BlendOperation { + SDL_BLENDOPERATION_ADD = 0x1, + SDL_BLENDOPERATION_SUBTRACT = 0x2, + SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, + SDL_BLENDOPERATION_MINIMUM = 0x4, + SDL_BLENDOPERATION_MAXIMUM = 0x5, + } + mixin(expandEnum!SDL_BlendOperation); + + enum SDL_BlendFactor { + SDL_BLENDFACTOR_ZERO = 0x1, + SDL_BLENDFACTOR_ONE = 0x2, + SDL_BLENDFACTOR_SRC_COLOR = 0x3, + SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, + SDL_BLENDFACTOR_SRC_ALPHA = 0x5, + SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, + SDL_BLENDFACTOR_DST_COLOR = 0x7, + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, + SDL_BLENDFACTOR_DST_ALPHA = 0x9, + SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA, + } + mixin(expandEnum!SDL_BlendFactor); +} +else { + enum SDL_BlendMode { + SDL_BLENDMODE_NONE = 0x00000000, + SDL_BLENDMODE_BLEND = 0x00000001, + SDL_BLENDMODE_ADD = 0x00000002, + SDL_BLENDMODE_MOD = 0x00000004, + } + mixin(expandEnum!SDL_BlendMode); +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + static if(sdlSupport >= SDLSupport.sdl206) { + SDL_BlendMode SDL_ComposeCustomBlendMode(SDL_BlendFactor,SDL_BlendFactor,SDL_BlendOperation,SDL_BlendFactor,SDL_BlendFactor,SDL_BlendOperation); + } + } +} +else { + static if(sdlSupport >= SDLSupport.sdl206) { + extern(C) @nogc nothrow { + alias pSDL_ComposeCustomBlendMode = SDL_BlendMode function(SDL_BlendFactor,SDL_BlendFactor,SDL_BlendOperation,SDL_BlendFactor,SDL_BlendFactor,SDL_BlendOperation); + } + + __gshared { + pSDL_ComposeCustomBlendMode SDL_ComposeCustomBlendMode; + } + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlclipboard.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlclipboard.d new file mode 100644 index 0000000..345c1ac --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlclipboard.d @@ -0,0 +1,31 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlclipboard; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_SetClipboardText(const(char)*); + char* SDL_GetClipboardText(); + SDL_bool SDL_HasClipboardText(); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_SetClipboardText = int function(const(char)*); + alias pSDL_GetClipboardText = char* function(); + alias pSDL_HasClipboardText = SDL_bool function(); + } + + __gshared { + pSDL_SetClipboardText SDL_SetClipboardText; + pSDL_GetClipboardText SDL_GetClipboardText; + pSDL_HasClipboardText SDL_HasClipboardText; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlcpuinfo.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlcpuinfo.d new file mode 100644 index 0000000..433ade0 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlcpuinfo.d @@ -0,0 +1,130 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlcpuinfo; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +enum SDL_CACHELINE_SIZE = 128; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_GetCPUCount(); + int SDL_GetCPUCacheLineSize(); + SDL_bool SDL_HasRDTSC(); + SDL_bool SDL_HasAltiVec(); + SDL_bool SDL_HasMMX(); + SDL_bool SDL_Has3DNow(); + SDL_bool SDL_HasSSE(); + SDL_bool SDL_HasSSE2(); + SDL_bool SDL_HasSSE3(); + SDL_bool SDL_HasSSE41(); + SDL_bool SDL_HasSSE42(); + + static if(sdlSupport >= SDLSupport.sdl201) { + int SDL_GetSystemRAM(); + } + static if(sdlSupport >= SDLSupport.sdl202) { + SDL_bool SDL_HasAVX(); + } + static if(sdlSupport >= SDLSupport.sdl204) { + SDL_bool SDL_HasAVX2(); + } + static if(sdlSupport >= SDLSupport.sdl206) { + SDL_bool SDL_HasNEON(); + } + static if(sdlSupport >= SDLSupport.sdl209) { + SDL_bool SDL_HasAVX512F(); + } + static if(sdlSupport >= SDLSupport.sdl2010) { + size_t SDL_SIMDGetAlignment(); + void* SDL_SIMDAlloc(const(size_t)); + void SDL_SIMDFree(void*); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetCPUCount = int function(); + alias pSDL_GetCPUCacheLineSize = int function(); + alias pSDL_HasRDTSC = SDL_bool function(); + alias pSDL_HasAltiVec = SDL_bool function(); + alias pSDL_HasMMX = SDL_bool function(); + alias pSDL_Has3DNow = SDL_bool function(); + alias pSDL_HasSSE = SDL_bool function(); + alias pSDL_HasSSE2 = SDL_bool function(); + alias pSDL_HasSSE3 = SDL_bool function(); + alias pSDL_HasSSE41 = SDL_bool function(); + alias pSDL_HasSSE42 = SDL_bool function(); + } + + __gshared { + pSDL_GetCPUCount SDL_GetCPUCount; + pSDL_GetCPUCacheLineSize SDL_GetCPUCacheLineSize; + pSDL_HasRDTSC SDL_HasRDTSC; + pSDL_HasAltiVec SDL_HasAltiVec; + pSDL_HasMMX SDL_HasMMX; + pSDL_Has3DNow SDL_Has3DNow; + pSDL_HasSSE SDL_HasSSE; + pSDL_HasSSE2 SDL_HasSSE2; + pSDL_HasSSE3 SDL_HasSSE3; + pSDL_HasSSE41 SDL_HasSSE41; + pSDL_HasSSE42 SDL_HasSSE42; + } + static if(sdlSupport >= SDLSupport.sdl201) { + extern(C) @nogc nothrow { + alias pSDL_GetSystemRAM = int function(); + } + __gshared { + pSDL_GetSystemRAM SDL_GetSystemRAM; + } + } + static if(sdlSupport >= SDLSupport.sdl202) { + extern(C) @nogc nothrow { + alias pSDL_HasAVX = SDL_bool function(); + } + __gshared { + pSDL_HasAVX SDL_HasAVX; + } + } + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_HasAVX2 = SDL_bool function(); + } + __gshared { + pSDL_HasAVX2 SDL_HasAVX2; + } + } + static if(sdlSupport >= SDLSupport.sdl206) { + extern(C) @nogc nothrow { + alias pSDL_HasNEON = SDL_bool function(); + } + __gshared { + pSDL_HasNEON SDL_HasNEON; + } + } + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_HasAVX512F = SDL_bool function(); + } + __gshared { + pSDL_HasAVX512F SDL_HasAVX512F; + } + } + static if(sdlSupport >= SDLSupport.sdl2010) { + extern(C) @nogc nothrow { + alias pSDL_SIMDGetAlignment = size_t function(); + alias pSDL_SIMDAlloc = void* function(const(size_t)); + alias pSDL_SIMDFree = void function(void*); + } + __gshared { + pSDL_SIMDGetAlignment SDL_SIMDGetAlignment; + pSDL_SIMDAlloc SDL_SIMDAlloc; + pSDL_SIMDFree SDL_SIMDFree; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlerror.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlerror.d new file mode 100644 index 0000000..09b61e3 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlerror.d @@ -0,0 +1,28 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlerror; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + void SDL_SetError(const(char)*,...); + const(char)* SDL_GetError(); + void SDL_ClearError(); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_SetError = void function(const(char)*,...); + alias pSDL_GetError = const(char)* function(); + alias pSDL_ClearError = void function(); + } + + __gshared { + pSDL_SetError SDL_SetError; + pSDL_GetError SDL_GetError; + pSDL_ClearError SDL_ClearError; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlevents.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlevents.d new file mode 100644 index 0000000..0fb7ce2 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlevents.d @@ -0,0 +1,674 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlevents; + +import bindbc.sdl.config; + +import bindbc.sdl.bind.sdlgesture, + bindbc.sdl.bind.sdljoystick, + bindbc.sdl.bind.sdlkeyboard, + bindbc.sdl.bind.sdlkeycode, + bindbc.sdl.bind.sdlstdinc, + bindbc.sdl.bind.sdlsyswm, + bindbc.sdl.bind.sdltouch, + bindbc.sdl.bind.sdlvideo; + +enum { + SDL_RELEASED = 0, + SDL_PRESSED = 1, +} + +static if(sdlSupport >= SDLSupport.sdl209) { + enum SDL_EventType { + SDL_FIRSTEVENT = 0, + SDL_QUIT = 0x100, + SDL_APP_TERMINATING, + SDL_APP_LOWMEMORY, + SDL_APP_WILLENTERBACKGROUND, + SDL_APP_DIDENTERBACKGROUND, + SDL_APP_WILLENTERFOREGROUND, + SDL_APP_DIDENTERFOREGROUND, + SDL_DISPLAYEVENT = 0x150, + SDL_WINDOWEVENT = 0x200, + SDL_SYSWMEVENT, + SDL_KEYDOWN = 0x300, + SDL_KEYUP, + SDL_TEXTEDITING, + SDL_TEXTINPUT, + SDL_KEYMAPCHANGED, + SDL_MOUSEMOTION = 0x400, + SDL_MOUSEBUTTONDOWN, + SDL_MOUSEBUTTONUP, + SDL_MOUSEWHEEL, + SDL_JOYAXISMOTION = 0x600, + SDL_JOYBALLMOTION, + SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, + SDL_JOYBUTTONUP, + SDL_JOYDEVICEADDED, + SDL_JOYDEVICEREMOVED, + SDL_CONTROLLERAXISMOTION = 0x650, + SDL_CONTROLLERBUTTONDOWN, + SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, + SDL_CONTROLLERDEVICEREMOVED, + SDL_CONTROLLERDEVICEREMAPPED, + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + SDL_CLIPBOARDUPDATE = 0x900, + SDL_DROPFILE = 0x1000, + SDL_DROPTEXT, + SDL_DROPBEGIN, + SDL_DROPCOMPLETE, + SDL_AUDIODEVICEADDED = 0x1100, + SDL_AUDIODEVICEREMOVED, + SDL_SENSORUPDATE = 0x1200, + SDL_RENDER_TARGETS_RESET = 0x2000, + SDL_RENDER_DEVICE_RESET, + SDL_USEREVENT = 0x8000, + SDL_LASTEVENT = 0xFFFF + } +} +else static if(sdlSupport >= SDLSupport.sdl205) { + enum SDL_EventType { + SDL_FIRSTEVENT = 0, + SDL_QUIT = 0x100, + SDL_APP_TERMINATING, + SDL_APP_LOWMEMORY, + SDL_APP_WILLENTERBACKGROUND, + SDL_APP_DIDENTERBACKGROUND, + SDL_APP_WILLENTERFOREGROUND, + SDL_APP_DIDENTERFOREGROUND, + SDL_WINDOWEVENT = 0x200, + SDL_SYSWMEVENT, + SDL_KEYDOWN = 0x300, + SDL_KEYUP, + SDL_TEXTEDITING, + SDL_TEXTINPUT, + SDL_KEYMAPCHANGED, + SDL_MOUSEMOTION = 0x400, + SDL_MOUSEBUTTONDOWN, + SDL_MOUSEBUTTONUP, + SDL_MOUSEWHEEL, + SDL_JOYAXISMOTION = 0x600, + SDL_JOYBALLMOTION, + SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, + SDL_JOYBUTTONUP, + SDL_JOYDEVICEADDED, + SDL_JOYDEVICEREMOVED, + SDL_CONTROLLERAXISMOTION = 0x650, + SDL_CONTROLLERBUTTONDOWN, + SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, + SDL_CONTROLLERDEVICEREMOVED, + SDL_CONTROLLERDEVICEREMAPPED, + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + SDL_CLIPBOARDUPDATE = 0x900, + SDL_DROPFILE = 0x1000, + SDL_DROPTEXT, + SDL_DROPBEGIN, + SDL_DROPCOMPLETE, + SDL_AUDIODEVICEADDED = 0x1100, + SDL_AUDIODEVICEREMOVED, + SDL_RENDER_TARGETS_RESET = 0x2000, + SDL_RENDER_DEVICE_RESET, + SDL_USEREVENT = 0x8000, + SDL_LASTEVENT = 0xFFFF + } +} +else static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_EventType { + SDL_FIRSTEVENT = 0, + SDL_QUIT = 0x100, + SDL_APP_TERMINATING, + SDL_APP_LOWMEMORY, + SDL_APP_WILLENTERBACKGROUND, + SDL_APP_DIDENTERBACKGROUND, + SDL_APP_WILLENTERFOREGROUND, + SDL_APP_DIDENTERFOREGROUND, + SDL_WINDOWEVENT = 0x200, + SDL_SYSWMEVENT, + SDL_KEYDOWN = 0x300, + SDL_KEYUP, + SDL_TEXTEDITING, + SDL_TEXTINPUT, + SDL_KEYMAPCHANGED, + SDL_MOUSEMOTION = 0x400, + SDL_MOUSEBUTTONDOWN, + SDL_MOUSEBUTTONUP, + SDL_MOUSEWHEEL, + SDL_JOYAXISMOTION = 0x600, + SDL_JOYBALLMOTION, + SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, + SDL_JOYBUTTONUP, + SDL_JOYDEVICEADDED, + SDL_JOYDEVICEREMOVED, + SDL_CONTROLLERAXISMOTION = 0x650, + SDL_CONTROLLERBUTTONDOWN, + SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, + SDL_CONTROLLERDEVICEREMOVED, + SDL_CONTROLLERDEVICEREMAPPED, + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + SDL_CLIPBOARDUPDATE = 0x900, + SDL_DROPFILE = 0x1000, + SDL_AUDIODEVICEADDED = 0x1100, + SDL_AUDIODEVICEREMOVED, + SDL_RENDER_TARGETS_RESET = 0x2000, + SDL_RENDER_DEVICE_RESET, + SDL_USEREVENT = 0x8000, + SDL_LASTEVENT = 0xFFFF + } +} +else static if(sdlSupport >= SDLSupport.sdl201) { + enum SDL_EventType { + SDL_FIRSTEVENT = 0, + SDL_QUIT = 0x100, + SDL_APP_TERMINATING, + SDL_APP_LOWMEMORY, + SDL_APP_WILLENTERBACKGROUND, + SDL_APP_DIDENTERBACKGROUND, + SDL_APP_WILLENTERFOREGROUND, + SDL_APP_DIDENTERFOREGROUND, + SDL_WINDOWEVENT = 0x200, + SDL_SYSWMEVENT, + SDL_KEYDOWN = 0x300, + SDL_KEYUP, + SDL_TEXTEDITING, + SDL_TEXTINPUT, + SDL_MOUSEMOTION = 0x400, + SDL_MOUSEBUTTONDOWN, + SDL_MOUSEBUTTONUP, + SDL_MOUSEWHEEL, + SDL_JOYAXISMOTION = 0x600, + SDL_JOYBALLMOTION, + SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, + SDL_JOYBUTTONUP, + SDL_JOYDEVICEADDED, + SDL_JOYDEVICEREMOVED, + SDL_CONTROLLERAXISMOTION = 0x650, + SDL_CONTROLLERBUTTONDOWN, + SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, + SDL_CONTROLLERDEVICEREMOVED, + SDL_CONTROLLERDEVICEREMAPPED, + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + SDL_CLIPBOARDUPDATE = 0x900, + SDL_DROPFILE = 0x1000, + SDL_RENDER_TARGETS_RESET = 0x2000, + SDL_USEREVENT = 0x8000, + SDL_LASTEVENT = 0xFFFF + } +} +else { + enum SDL_EventType { + SDL_FIRSTEVENT = 0, + SDL_QUIT = 0x100, + SDL_APP_TERMINATING, + SDL_APP_LOWMEMORY, + SDL_APP_WILLENTERBACKGROUND, + SDL_APP_DIDENTERBACKGROUND, + SDL_APP_WILLENTERFOREGROUND, + SDL_APP_DIDENTERFOREGROUND, + SDL_WINDOWEVENT = 0x200, + SDL_SYSWMEVENT, + SDL_KEYDOWN = 0x300, + SDL_KEYUP, + SDL_TEXTEDITING, + SDL_TEXTINPUT, + SDL_MOUSEMOTION = 0x400, + SDL_MOUSEBUTTONDOWN, + SDL_MOUSEBUTTONUP, + SDL_MOUSEWHEEL, + SDL_JOYAXISMOTION = 0x600, + SDL_JOYBALLMOTION, + SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, + SDL_JOYBUTTONUP, + SDL_JOYDEVICEADDED, + SDL_JOYDEVICEREMOVED, + SDL_CONTROLLERAXISMOTION = 0x650, + SDL_CONTROLLERBUTTONDOWN, + SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, + SDL_CONTROLLERDEVICEREMOVED, + SDL_CONTROLLERDEVICEREMAPPED, + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + SDL_CLIPBOARDUPDATE = 0x900, + SDL_DROPFILE = 0x1000, + SDL_USEREVENT = 0x8000, + SDL_LASTEVENT = 0xFFFF + } +} +mixin(expandEnum!SDL_EventType); + +struct SDL_CommonEvent { + SDL_EventType type; + uint timestamp; +} + +static if(sdlSupport >= SDLSupport.sdl209) { + struct SDL_DisplayEvent { + SDL_EventType type; + uint timestamp; + uint display; + ubyte event; + ubyte padding1; + ubyte padding2; + ubyte padding3; + int data1; + } +} + +struct SDL_WindowEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + SDL_WindowEventID event; + ubyte padding1; + ubyte padding2; + ubyte padding3; + int data1; + int data2; +} + +struct SDL_KeyboardEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + ubyte state; + ubyte repeat; + ubyte padding2; + ubyte padding3; + SDL_Keysym keysym; +} + +enum SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32; +struct SDL_TextEditingEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + char[SDL_TEXTEDITINGEVENT_TEXT_SIZE] text; + int start; + int length; +} + +enum SDL_TEXTINPUTEVENT_TEXT_SIZE = 32; +struct SDL_TextInputEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + char[SDL_TEXTINPUTEVENT_TEXT_SIZE] text; +} + +struct SDL_MouseMotionEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + uint which; + uint state; + int x; + int y; + int xrel; + int yrel; +} + +struct SDL_MouseButtonEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + uint which; + ubyte button; + ubyte state; + static if(sdlSupport == SDLSupport.sdl200) { + ubyte padding1; + ubyte padding2; + } + else { + ubyte clicks; + ubyte padding1; + } + int x; + int y; +} + +struct SDL_MouseWheelEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + uint which; + int x; + int y; + static if(sdlSupport >= SDLSupport.sdl204) { + uint direction; + } +} + +struct SDL_JoyAxisEvent { + SDL_EventType type; + uint timestamp; + SDL_JoystickID which; + ubyte axis; + ubyte padding1; + ubyte padding2; + ubyte padding3; + short value; + ushort padding4; +} + +struct SDL_JoyBallEvent { + SDL_EventType type; + uint timestamp; + SDL_JoystickID which; + ubyte ball; + ubyte padding1; + ubyte padding2; + ubyte padding3; + short xrel; + short yrel; +} + +struct SDL_JoyHatEvent { + SDL_EventType type; + uint timestamp; + SDL_JoystickID which; + ubyte hat; + ubyte value; + ubyte padding1; + ubyte padding2; +} + +struct SDL_JoyButtonEvent { + SDL_EventType type; + uint timestamp; + SDL_JoystickID which; + ubyte button; + ubyte state; + ubyte padding1; + ubyte padding2; +} + +struct SDL_JoyDeviceEvent { + SDL_EventType type; + uint timestamp; + int which; +} + +struct SDL_ControllerAxisEvent { + SDL_EventType type; + uint timestamp; + SDL_JoystickID which; + ubyte axis; + ubyte padding1; + ubyte padding2; + ubyte padding3; + short value; + ushort padding4; +} + +struct SDL_ControllerButtonEvent { + SDL_EventType type; + uint timestamp; + SDL_JoystickID which; + ubyte button; + ubyte state; + ubyte padding1; + ubyte padding2; +} + +struct SDL_ControllerDeviceEvent { + SDL_EventType type; + uint timestamp; + int which; +} + +static if(sdlSupport >= SDLSupport.sdl204) { + struct SDL_AudioDeviceEvent { + uint type; + uint timestamp; + uint which; + ubyte iscapture; + ubyte padding1; + ubyte padding2; + ubyte padding3; + } +} + +struct SDL_TouchFingerEvent { + SDL_EventType type; + uint timestamp; + SDL_TouchID touchId; + SDL_FingerID fingerId; + float x; + float y; + float dx; + float dy; + float pressure; +} + +struct SDL_MultiGestureEvent { + SDL_EventType type; + uint timestamp; + SDL_TouchID touchId; + float dTheta; + float dDist; + float x; + float y; + ushort numFingers; + ushort padding; +} + +struct SDL_DollarGestureEvent { + SDL_EventType type; + uint timestamp; + SDL_TouchID touchId; + SDL_GestureID gestureId; + uint numFingers; + float error; + float x; + float y; +} + +struct SDL_DropEvent { + SDL_EventType type; + uint timestamp; + char* file; + static if(sdlSupport >= SDLSupport.sdl205) { + uint windowID; + } +} + +struct SDL_SensorEvent { + SDL_EventType type; + uint timestamp; + int which; + float[6] data; +} + +struct SDL_QuitEvent { + SDL_EventType type; + uint timestamp; +} + +struct SDL_OSEvent { + SDL_EventType type; + uint timestamp; +} + +struct SDL_UserEvent { + SDL_EventType type; + uint timestamp; + uint windowID; + int code; + void* data1; + void* data2; +} + +struct SDL_SysWMEvent { + SDL_EventType type; + uint timestamp; + SDL_SysWMmsg* msg; +} + +union SDL_Event { + SDL_EventType type; + SDL_CommonEvent common; + static if(sdlSupport >= SDLSupport.sdl209) { + SDL_DisplayEvent display; + } + SDL_WindowEvent window; + SDL_KeyboardEvent key; + SDL_TextEditingEvent edit; + SDL_TextInputEvent text; + SDL_MouseMotionEvent motion; + SDL_MouseButtonEvent button; + SDL_MouseWheelEvent wheel; + SDL_JoyAxisEvent jaxis; + SDL_JoyBallEvent jball; + SDL_JoyHatEvent jhat; + SDL_JoyButtonEvent jbutton; + SDL_JoyDeviceEvent jdevice; + SDL_ControllerAxisEvent caxis; + SDL_ControllerButtonEvent cbutton; + SDL_ControllerDeviceEvent cdevice; + static if(sdlSupport >= SDLSupport.sdl204) { + SDL_AudioDeviceEvent adevice; + } + static if(sdlSupport >= SDLSupport.sdl209) { + SDL_SensorEvent sensor; + } + SDL_QuitEvent quit; + SDL_UserEvent user; + SDL_SysWMEvent syswm; + SDL_TouchFingerEvent tfinger; + SDL_MultiGestureEvent mgesture; + SDL_DollarGestureEvent dgesture; + SDL_DropEvent drop; + + ubyte[56] padding; +} + +enum SDL_eventaction { + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} +alias SDL_EventAction = SDL_eventaction; +mixin(expandEnum!SDL_EventAction); + +extern(C) nothrow alias SDL_EventFilter = int function(void* userdata, SDL_Event* event); + +enum { + SDL_QUERY = -1, + SDL_IGNORE = 0, + SDL_DISABLE = 0, + SDL_ENABLE = 1, +} + +@nogc nothrow { + int SDL_GetEventState(SDL_EventType type) { + pragma(inline, true); + return SDL_EventState(type, SDL_QUERY); + } + + // This is implemented in SDL_quit.h, but works better here. + bool SDL_QuitRequested() { + pragma(inline, true); + SDL_PumpEvents(); + return SDL_PeepEvents(null,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0; + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + void SDL_PumpEvents(); + int SDL_PeepEvents(SDL_Event*,int,SDL_eventaction,uint,uint); + SDL_bool SDL_HasEvent(uint); + SDL_bool SDL_HasEvents(uint,uint); + void SDL_FlushEvent(uint); + void SDL_FlushEvents(uint,uint); + int SDL_PollEvent(SDL_Event*); + int SDL_WaitEvent(SDL_Event*); + int SDL_WaitEventTimeout(SDL_Event*,int); + int SDL_PushEvent(SDL_Event*); + void SDL_SetEventFilter(SDL_EventFilter,void*); + SDL_bool SDL_GetEventFilter(SDL_EventFilter*,void**); + void SDL_AddEventWatch(SDL_EventFilter,void*); + void SDL_DelEventWatch(SDL_EventFilter,void*); + void SDL_FilterEvents(SDL_EventFilter,void*); + ubyte SDL_EventState(uint,int); + uint SDL_RegisterEvents(int); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_PumpEvents = void function(); + alias pSDL_PeepEvents = int function(SDL_Event*,int,SDL_eventaction,uint,uint); + alias pSDL_HasEvent = SDL_bool function(uint); + alias pSDL_HasEvents = SDL_bool function(uint,uint); + alias pSDL_FlushEvent = void function(uint); + alias pSDL_FlushEvents = void function(uint,uint); + alias pSDL_PollEvent = int function(SDL_Event*); + alias pSDL_WaitEvent = int function(SDL_Event*); + alias pSDL_WaitEventTimeout = int function(SDL_Event*,int); + alias pSDL_PushEvent = int function(SDL_Event*); + alias pSDL_SetEventFilter = void function(SDL_EventFilter,void*); + alias pSDL_GetEventFilter = SDL_bool function(SDL_EventFilter*,void**); + alias pSDL_AddEventWatch = void function(SDL_EventFilter,void*); + alias pSDL_DelEventWatch = void function(SDL_EventFilter,void*); + alias pSDL_FilterEvents = void function(SDL_EventFilter,void*); + alias pSDL_EventState = ubyte function(uint,int); + alias pSDL_RegisterEvents = uint function(int); + } + + __gshared { + pSDL_PumpEvents SDL_PumpEvents; + pSDL_PeepEvents SDL_PeepEvents; + pSDL_HasEvent SDL_HasEvent; + pSDL_HasEvents SDL_HasEvents; + pSDL_FlushEvent SDL_FlushEvent; + pSDL_FlushEvents SDL_FlushEvents; + pSDL_PollEvent SDL_PollEvent; + pSDL_WaitEvent SDL_WaitEvent; + pSDL_WaitEventTimeout SDL_WaitEventTimeout; + pSDL_PushEvent SDL_PushEvent; + pSDL_SetEventFilter SDL_SetEventFilter; + pSDL_GetEventFilter SDL_GetEventFilter; + pSDL_AddEventWatch SDL_AddEventWatch; + pSDL_DelEventWatch SDL_DelEventWatch; + pSDL_FilterEvents SDL_FilterEvents; + pSDL_EventState SDL_EventState; + pSDL_RegisterEvents SDL_RegisterEvents; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlfilesystem.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlfilesystem.d new file mode 100644 index 0000000..a3edcdc --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlfilesystem.d @@ -0,0 +1,31 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlfilesystem; + +import bindbc.sdl.config; + +version(BindSDL_Static){ + extern(C) @nogc nothrow { + static if(sdlSupport >= SDLSupport.sdl201) { + char* SDL_GetBasePath(); + char* SDL_GetPrefPath(const(char)* org,const(char)* app); + } + } +} +else { + static if(sdlSupport >= SDLSupport.sdl201) { + extern(C) @nogc nothrow { + alias pSDL_GetBasePath = char* function(); + alias pSDL_GetPrefPath = char* function(const(char)* org,const(char)* app); + } + + __gshared { + pSDL_GetBasePath SDL_GetBasePath; + pSDL_GetPrefPath SDL_GetPrefPath; + } + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlgamecontroller.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlgamecontroller.d new file mode 100644 index 0000000..295d117 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlgamecontroller.d @@ -0,0 +1,225 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlgamecontroller; + +import bindbc.sdl.config; + +import bindbc.sdl.bind.sdljoystick, + bindbc.sdl.bind.sdlrwops; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +struct SDL_GameController; + +enum SDL_GameControllerBindType { + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT, +} +mixin(expandEnum!SDL_GameControllerBindType); + +struct SDL_GameControllerButtonBind { + SDL_GameControllerBindType bindType; + union value { + int button; + int axis; + struct hat { + int hat; + int hat_mask; + } + } + alias button = value.button; + alias axis = value.axis; + alias hat = value.hat; +} + +enum SDL_GameControllerAxis { + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} +mixin(expandEnum!SDL_GameControllerAxis); + +enum SDL_GameControllerButton { + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MAX +} +mixin(expandEnum!SDL_GameControllerButton); + +static if(sdlSupport >= SDLSupport.sdl202) { + @nogc nothrow + int SDL_GameControllerAddMappingsFromFile(const(char)* file) { + pragma(inline, true); + return SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file,"rb"),1); + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_GameControllerAddMapping(const(char)*); + char* SDL_GameControllerMappingForGUID(SDL_JoystickGUID); + char* SDL_GameControllerMapping(SDL_GameController*); + SDL_bool SDL_IsGameController(int); + const(char)* SDL_GameControllerNameForIndex(int); + SDL_GameController* SDL_GameControllerOpen(int); + const(char)* SDL_GameControllerName(SDL_GameController*); + SDL_bool SDL_GameControllerGetAttached(SDL_GameController*); + SDL_Joystick* SDL_GameControllerGetJoystick(SDL_GameController*); + int SDL_GameControllerEventState(int); + void SDL_GameControllerUpdate(); + SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const(char)*); + const(char)* SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis); + SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController*,SDL_GameControllerAxis); + short SDL_GameControllerGetAxis(SDL_GameController*,SDL_GameControllerAxis); + SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const(char*)); + const(char)* SDL_GameControllerGetStringForButton(SDL_GameControllerButton); + SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController*,SDL_GameControllerButton); + ubyte SDL_GameControllerGetButton(SDL_GameController*,SDL_GameControllerButton); + void SDL_GameControllerClose(SDL_GameController*); + + static if(sdlSupport >= SDLSupport.sdl202) { + int SDL_GameControllerAddMappingsFromRW(SDL_RWops*,int); + } + static if(sdlSupport >= SDLSupport.sdl204) { + SDL_GameController* SDL_GameControllerFromInstanceID(SDL_JoystickID); + } + static if(sdlSupport >= SDLSupport.sdl206) { + ushort SDL_GameControllerGetProduct(SDL_GameController*); + ushort SDL_GameControllerGetProductVersion(SDL_GameController*); + ushort SDL_GameControllerGetVendor(SDL_GameController*); + char* SDL_GameControllerMappingForIndex(int); + int SDL_GameControllerNumMappings(); + } + static if(sdlSupport >= SDLSupport.sdl209) { + char* SDL_GameControllerMappingForDeviceIndex(int); + int SDL_GameControllerRumble(SDL_GameController*,ushort,ushort,uint); + } + static if(sdlSupport >= SDLSupport.sdl2010) { + int SDL_GameControllerGetPlayerIndex(SDL_GameController*); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GameControllerAddMapping = int function(const(char)*); + alias pSDL_GameControllerMappingForGUID = char* function(SDL_JoystickGUID); + alias pSDL_GameControllerMapping = char* function(SDL_GameController*); + alias pSDL_IsGameController = SDL_bool function(int); + alias pSDL_GameControllerNameForIndex = const(char)* function(int); + alias pSDL_GameControllerOpen = SDL_GameController* function(int); + alias pSDL_GameControllerName = const(char)* function(SDL_GameController*); + alias pSDL_GameControllerGetAttached = SDL_bool function(SDL_GameController*); + alias pSDL_GameControllerGetJoystick = SDL_Joystick* function(SDL_GameController*); + alias pSDL_GameControllerEventState = int function(int); + alias pSDL_GameControllerUpdate = void function(); + alias pSDL_GameControllerGetAxisFromString = SDL_GameControllerAxis function(const(char)*); + alias pSDL_GameControllerGetStringForAxis = const(char)* function(SDL_GameControllerAxis); + alias pSDL_GameControllerGetBindForAxis = SDL_GameControllerButtonBind function(SDL_GameController*,SDL_GameControllerAxis); + alias pSDL_GameControllerGetAxis = short function(SDL_GameController*,SDL_GameControllerAxis); + alias pSDL_GameControllerGetButtonFromString = SDL_GameControllerButton function(const(char*)); + alias pSDL_GameControllerGetStringForButton = const(char)* function(SDL_GameControllerButton); + alias pSDL_GameControllerGetBindForButton = SDL_GameControllerButtonBind function(SDL_GameController*,SDL_GameControllerButton); + alias pSDL_GameControllerGetButton = ubyte function(SDL_GameController*,SDL_GameControllerButton); + alias pSDL_GameControllerClose = void function(SDL_GameController*); + } + __gshared { + pSDL_GameControllerAddMapping SDL_GameControllerAddMapping; + pSDL_GameControllerMappingForGUID SDL_GameControllerMappingForGUID; + pSDL_GameControllerMapping SDL_GameControllerMapping; + pSDL_IsGameController SDL_IsGameController; + pSDL_GameControllerNameForIndex SDL_GameControllerNameForIndex; + pSDL_GameControllerOpen SDL_GameControllerOpen; + pSDL_GameControllerName SDL_GameControllerName; + pSDL_GameControllerGetAttached SDL_GameControllerGetAttached; + pSDL_GameControllerGetJoystick SDL_GameControllerGetJoystick; + pSDL_GameControllerEventState SDL_GameControllerEventState; + pSDL_GameControllerUpdate SDL_GameControllerUpdate; + pSDL_GameControllerGetAxisFromString SDL_GameControllerGetAxisFromString; + pSDL_GameControllerGetStringForAxis SDL_GameControllerGetStringForAxis; + pSDL_GameControllerGetBindForAxis SDL_GameControllerGetBindForAxis; + pSDL_GameControllerGetAxis SDL_GameControllerGetAxis; + pSDL_GameControllerGetButtonFromString SDL_GameControllerGetButtonFromString; + pSDL_GameControllerGetStringForButton SDL_GameControllerGetStringForButton; + pSDL_GameControllerGetBindForButton SDL_GameControllerGetBindForButton; + pSDL_GameControllerGetButton SDL_GameControllerGetButton; + pSDL_GameControllerClose SDL_GameControllerClose; + } + static if(sdlSupport >= SDLSupport.sdl202) { + extern(C) @nogc nothrow { + alias pSDL_GameControllerAddMappingsFromRW = int function(SDL_RWops*,int); + } + + __gshared { + pSDL_GameControllerAddMappingsFromRW SDL_GameControllerAddMappingsFromRW; + } + } + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_GameControllerFromInstanceID = SDL_GameController* function(SDL_JoystickID); + } + + __gshared { + pSDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID; + } + } + static if(sdlSupport >= SDLSupport.sdl206) { + extern(C) @nogc nothrow { + alias pSDL_GameControllerGetProduct = ushort function(SDL_GameController*); + alias pSDL_GameControllerGetProductVersion = ushort function(SDL_GameController*); + alias pSDL_GameControllerGetVendor = ushort function(SDL_GameController*); + alias pSDL_GameControllerMappingForIndex = char* function(int); + alias pSDL_GameControllerNumMappings = int function(); + } + + __gshared { + pSDL_GameControllerGetProduct SDL_GameControllerGetProduct; + pSDL_GameControllerGetProductVersion SDL_GameControllerGetProductVersion; + pSDL_GameControllerGetVendor SDL_GameControllerGetVendor; + pSDL_GameControllerMappingForIndex SDL_GameControllerMappingForIndex; + pSDL_GameControllerNumMappings SDL_GameControllerNumMappings; + } + } + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_GameControllerMappingForDeviceIndex = char* function(int); + alias pSDL_GameControllerRumble = int function(SDL_GameController*,ushort,ushort,uint); + } + + __gshared { + pSDL_GameControllerMappingForDeviceIndex SDL_GameControllerMappingForDeviceIndex; + pSDL_GameControllerRumble SDL_GameControllerRumble; + } + } + static if(sdlSupport >= SDLSupport.sdl2010) { + extern(C) @nogc nothrow { + alias pSDL_GameControllerGetPlayerIndex = int function(SDL_GameController*); + } + __gshared { + pSDL_GameControllerGetPlayerIndex SDL_GameControllerGetPlayerIndex; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlgesture.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlgesture.d new file mode 100644 index 0000000..62ea0e5 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlgesture.d @@ -0,0 +1,36 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlgesture; + +import bindbc.sdl.bind.sdltouch : SDL_TouchID; +import bindbc.sdl.bind.sdlrwops : SDL_RWops; + +alias SDL_GestureID = long; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_RecordGesture(SDL_TouchID); + int SDL_SaveAllDollarTemplates(SDL_RWops*); + int SDL_SaveDollarTemplate(SDL_GestureID,SDL_RWops*); + int SDL_LoadDollarTemplates(SDL_TouchID,SDL_RWops*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_RecordGesture = int function(SDL_TouchID); + alias pSDL_SaveAllDollarTemplates = int function(SDL_RWops*); + alias pSDL_SaveDollarTemplate = int function(SDL_GestureID,SDL_RWops*); + alias pSDL_LoadDollarTemplates = int function(SDL_TouchID,SDL_RWops*); + } + + __gshared { + pSDL_RecordGesture SDL_RecordGesture; + pSDL_SaveAllDollarTemplates SDL_SaveAllDollarTemplates; + pSDL_SaveDollarTemplate SDL_SaveDollarTemplate; + pSDL_LoadDollarTemplates SDL_LoadDollarTemplates; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlhaptic.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlhaptic.d new file mode 100644 index 0000000..f706080 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlhaptic.d @@ -0,0 +1,240 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlhaptic; + +import bindbc.sdl.bind.sdljoystick : SDL_Joystick; + +struct SDL_Haptic; + +enum : ushort { + SDL_HAPTIC_CONSTANT = 1u<<0, + SDL_HAPTIC_SINE = 1u<<1, + SDL_HAPTIC_LEFTRIGHT = 1u<<2, + SDL_HAPTIC_TRIANGLE = 1u<<3, + SDL_HAPTIC_SAWTOOTHUP = 1u<<4, + SDL_HAPTIC_SAWTOOTHDOWN = 1u<<5, + SDL_HAPTIC_RAMP = 1u<<6, + SDL_HAPTIC_SPRING = 1u<<7, + SDL_HAPTIC_DAMPER = 1u<<8, + SDL_HAPTIC_INERTIA = 1u<<9, + SDL_HAPTIC_FRICTION = 1u<<10, + SDL_HAPTIC_CUSTOM = 1u<<11, + SDL_HAPTIC_GAIN = 1u<<12, + SDL_HAPTIC_AUTOCENTER = 1u<<13, + SDL_HAPTIC_STATUS = 1u<<14, + SDL_HAPTIC_PAUSE = 1u<<15, +} + +enum { + SDL_HAPTIC_POLAR = 0, + SDL_HAPTIC_CARTESIAN = 1, + SDL_HAPTIC_SPHERICAL = 2, +} + +enum SDL_HAPTIC_INFINITY = 4294967295U; + +struct SDL_HapticDirection { + ubyte type; + int[3] dir; +} + +struct SDL_HapticConstant { + ushort type; + SDL_HapticDirection direction; + uint length; + ushort delay; + ushort button; + ushort interval; + short level; + ushort attack_length; + ushort attack_level; + ushort fade_length; + ushort fade_level; +} + +struct SDL_HapticPeriodic { + ushort type; + SDL_HapticDirection direction; + uint length; + uint delay; + ushort button; + ushort interval; + ushort period; + short magnitude; + short offset; + ushort phase; + ushort attack_length; + ushort attack_level; + ushort fade_length; + ushort fade_level; +} + +struct SDL_HapticCondition { + ushort type; + SDL_HapticDirection direciton; + uint length; + ushort delay; + ushort button; + ushort interval; + ushort[3] right_sat; + ushort[3] left_sat; + short[3] right_coeff; + short[3] left_coeff; + ushort[3] deadband; + ushort[3] center; +} + +struct SDL_HapticRamp { + ushort type; + SDL_HapticDirection direction; + uint length; + ushort delay; + ushort button; + ushort interval; + short start; + short end; + ushort attack_length; + ushort attack_level; + ushort fade_length; + ushort fade_level; +} + +struct SDL_HapticLeftRight { + ushort type; + uint length; + ushort large_magnitude; + ushort small_magnitude; +} + +struct SDL_HapticCustom { + ushort type; + SDL_HapticDirection direction; + uint length; + ushort delay; + ushort button; + ushort interval; + ubyte channels; + ushort period; + ushort samples; + ushort* data; + ushort attack_length; + ushort attack_level; + ushort fade_length; + ushort fade_level; +} + +union SDL_HapticEffect { + ushort type; + SDL_HapticConstant constant; + SDL_HapticPeriodic periodic; + SDL_HapticCondition condition; + SDL_HapticRamp ramp; + SDL_HapticLeftRight leftright; + SDL_HapticCustom custom; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_NumHaptics(); + const(char)* SDL_HapticName(int); + SDL_Haptic* SDL_HapticOpen(int); + int SDL_HapticOpened(int); + int SDL_HapticIndex(SDL_Haptic*); + int SDL_MouseIsHaptic(); + SDL_Haptic* SDL_HapticOpenFromMouse(); + int SDL_JoystickIsHaptic(SDL_Joystick*); + SDL_Haptic* SDL_HapticOpenFromJoystick(SDL_Joystick*); + int SDL_HapticClose(SDL_Haptic*); + int SDL_HapticNumEffects(SDL_Haptic*); + int SDL_HapticNumEffectsPlaying(SDL_Haptic*); + uint SDL_HapticQuery(SDL_Haptic*); + int SDL_HapticNumAxes(SDL_Haptic*); + int SDL_HapticEffectSupported(SDL_Haptic*,SDL_HapticEffect*); + int SDL_HapticNewEffect(SDL_Haptic*,SDL_HapticEffect*); + int SDL_HapticUpdateEffect(SDL_Haptic*,int,SDL_HapticEffect*); + int SDL_HapticRunEffect(SDL_Haptic*,int,uint); + int SDL_HapticStopEffect(SDL_Haptic*,int); + int SDL_HapticDestroyEffect(SDL_Haptic*,int); + int SDL_HapticGetEffectStatus(SDL_Haptic*,int); + int SDL_HapticSetGain(SDL_Haptic*,int); + int SDL_HapticSetAutocenter(SDL_Haptic*,int); + int SDL_HapticPause(SDL_Haptic*); + int SDL_HapticUnpause(SDL_Haptic*); + int SDL_HapticStopAll(SDL_Haptic*); + int SDL_HapticRumbleSupported(SDL_Haptic*); + int SDL_HapticRumbleInit(SDL_Haptic*); + int SDL_HapticRumblePlay(SDL_Haptic*,float,uint); + int SDL_HapticRumbleStop(SDL_Haptic*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_NumHaptics = int function(); + alias pSDL_HapticName = const(char)* function(int); + alias pSDL_HapticOpen = SDL_Haptic* function(int); + alias pSDL_HapticOpened = int function(int); + alias pSDL_HapticIndex = int function(SDL_Haptic*); + alias pSDL_MouseIsHaptic = int function(); + alias pSDL_HapticOpenFromMouse = SDL_Haptic* function(); + alias pSDL_JoystickIsHaptic = int function(SDL_Joystick*); + alias pSDL_HapticOpenFromJoystick = SDL_Haptic* function(SDL_Joystick*); + alias pSDL_HapticClose = int function(SDL_Haptic*); + alias pSDL_HapticNumEffects = int function(SDL_Haptic*); + alias pSDL_HapticNumEffectsPlaying = int function(SDL_Haptic*); + alias pSDL_HapticQuery = uint function(SDL_Haptic*); + alias pSDL_HapticNumAxes = int function(SDL_Haptic*); + alias pSDL_HapticEffectSupported = int function(SDL_Haptic*,SDL_HapticEffect*); + alias pSDL_HapticNewEffect = int function(SDL_Haptic*,SDL_HapticEffect*); + alias pSDL_HapticUpdateEffect = int function(SDL_Haptic*,int,SDL_HapticEffect*); + alias pSDL_HapticRunEffect = int function(SDL_Haptic*,int,uint); + alias pSDL_HapticStopEffect = int function(SDL_Haptic*,int); + alias pSDL_HapticDestroyEffect = int function(SDL_Haptic*,int); + alias pSDL_HapticGetEffectStatus = int function(SDL_Haptic*,int); + alias pSDL_HapticSetGain = int function(SDL_Haptic*,int); + alias pSDL_HapticSetAutocenter = int function(SDL_Haptic*,int); + alias pSDL_HapticPause = int function(SDL_Haptic*); + alias pSDL_HapticUnpause = int function(SDL_Haptic*); + alias pSDL_HapticStopAll = int function(SDL_Haptic*); + alias pSDL_HapticRumbleSupported = int function(SDL_Haptic*); + alias pSDL_HapticRumbleInit = int function(SDL_Haptic*); + alias pSDL_HapticRumblePlay = int function(SDL_Haptic*,float,uint); + alias pSDL_HapticRumbleStop = int function(SDL_Haptic*); + } + + __gshared { + pSDL_NumHaptics SDL_NumHaptics; + pSDL_HapticName SDL_HapticName; + pSDL_HapticOpen SDL_HapticOpen; + pSDL_HapticOpened SDL_HapticOpened; + pSDL_HapticIndex SDL_HapticIndex; + pSDL_MouseIsHaptic SDL_MouseIsHaptic; + pSDL_HapticOpenFromMouse SDL_HapticOpenFromMouse; + pSDL_JoystickIsHaptic SDL_JoystickIsHaptic; + pSDL_HapticOpenFromJoystick SDL_HapticOpenFromJoystick; + pSDL_HapticClose SDL_HapticClose; + pSDL_HapticNumEffects SDL_HapticNumEffects; + pSDL_HapticNumEffectsPlaying SDL_HapticNumEffectsPlaying; + pSDL_HapticQuery SDL_HapticQuery; + pSDL_HapticNumAxes SDL_HapticNumAxes; + pSDL_HapticEffectSupported SDL_HapticEffectSupported; + pSDL_HapticNewEffect SDL_HapticNewEffect; + pSDL_HapticUpdateEffect SDL_HapticUpdateEffect; + pSDL_HapticRunEffect SDL_HapticRunEffect; + pSDL_HapticStopEffect SDL_HapticStopEffect; + pSDL_HapticDestroyEffect SDL_HapticDestroyEffect; + pSDL_HapticGetEffectStatus SDL_HapticGetEffectStatus; + pSDL_HapticSetGain SDL_HapticSetGain; + pSDL_HapticSetAutocenter SDL_HapticSetAutocenter; + pSDL_HapticPause SDL_HapticPause; + pSDL_HapticUnpause SDL_HapticUnpause; + pSDL_HapticStopAll SDL_HapticStopAll; + pSDL_HapticRumbleSupported SDL_HapticRumbleSupported; + pSDL_HapticRumbleInit SDL_HapticRumbleInit; + pSDL_HapticRumblePlay SDL_HapticRumblePlay; + pSDL_HapticRumbleStop SDL_HapticRumbleStop; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlhints.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlhints.d new file mode 100644 index 0000000..e5aad86 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlhints.d @@ -0,0 +1,186 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlhints; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +enum SDL_HINT_FRAMEBUFFER_ACCELERATION = "SDL_FRAMEBUFFER_ACCELERATION"; +enum SDL_HINT_RENDER_DRIVER = "SDL_RENDER_DRIVER"; +enum SDL_HINT_RENDER_OPENGL_SHADERS = "SDL_RENDER_OPENGL_SHADERS"; +enum SDL_HINT_RENDER_SCALE_QUALITY = "SDL_RENDER_SCALE_QUALITY"; +enum SDL_HINT_RENDER_VSYNC = "SDL_RENDER_VSYNC"; +enum SDL_HINT_VIDEO_X11_XVIDMODE = "SDL_VIDEO_X11_XVIDMODE"; +enum SDL_HINT_VIDEO_X11_XINERAMA = "SDL_VIDEO_X11_XINERAMA"; +enum SDL_HINT_VIDEO_X11_XRANDR = "SDL_VIDEO_X11_XRANDR"; +enum SDL_HINT_GRAB_KEYBOARD = "SDL_GRAB_KEYBOARD"; +enum SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS = "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS"; +enum SDL_HINT_IDLE_TIMER_DISABLED = "SDL_IOS_IDLE_TIMER_DISABLED"; +enum SDL_HINT_ORIENTATIONS = "SDL_IOS_ORIENTATIONS"; +enum SDL_HINT_XINPUT_ENABLED = "SDL_XINPUT_ENABLED"; +enum SDL_HINT_GAMECONTROLLERCONFIG = "SDL_GAMECONTROLLERCONFIG"; +enum SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS = "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"; +enum SDL_HINT_ALLOW_TOPMOST = "SDL_ALLOW_TOPMOST"; +enum SDL_HINT_TIMER_RESOLUTION = "SDL_TIMER_RESOLUTION"; + +static if(sdlSupport >= SDLSupport.sdl201) { + enum SDL_HINT_RENDER_DIRECT3D_THREADSAFE = "SDL_RENDER_DIRECT3D_THREADSAFE"; + enum SDL_HINT_VIDEO_HIGHDPI_DISABLED = "SDL_VIDEO_HIGHDPI_DISABLED"; +} + +static if(sdlSupport >= SDLSupport.sdl202) { + enum SDL_HINT_VIDEO_ALLOW_SCREENSAVER = "SDL_VIDEO_ALLOW_SCREENSAVER"; + enum SDL_HINT_MOUSE_RELATIVE_MODE_WARP = "SDL_MOUSE_RELATIVE_MODE_WARP"; + enum SDL_HINT_ACCELEROMETER_AS_JOYSTICK = "SDL_ACCELEROMETER_AS_JOYSTICK"; + enum SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK = "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK"; + enum SDL_HINT_VIDEO_WIN_D3DCOMPILER = "SDL_VIDEO_WIN_D3DCOMPILER"; + enum SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT = "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT"; + enum SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES = "SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES"; +} + +// This is *intended* to be == and not >=. The values for all of these changed in 2.0.4. +static if(sdlSupport == SDLSupport.sdl203) { + enum SDL_HINT_RENDER_DIRECT3D11_DEBUG = "SDL_HINT_RENDER_DIRECT3D11_DEBUG"; + enum SDL_HINT_WINRT_PRIVACY_POLICY_URL = "SDL_HINT_WINRT_PRIVACY_POLICY_URL"; + enum SDL_HINT_WINRT_PRIVACY_POLICY_LABEL = "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL"; + enum SDL_HINT_WINRT_HANDLE_BACK_BUTTON = "SDL_HINT_WINRT_HANDLE_BACK_BUTTON"; +} + +static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_HINT_VIDEO_X11_NET_WM_PING = "SDL_VIDEO_X11_NET_WM_PING"; + enum SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN = "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN"; + enum SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP = "SDL_WINDOWS_ENABLE_MESSAGELOOP"; + enum SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING = "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING"; + enum SDL_HINT_THREAD_STACK_SIZE = "SDL_THREAD_STACK_SIZE"; + enum SDL_HINT_MAC_BACKGROUND_APP = "SDL_MAC_BACKGROUND_APP"; + enum SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION = "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"; + enum SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION = "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"; + enum SDL_HINT_IME_INTERNAL_EDITING = "SDL_IME_INTERNAL_EDITING"; + enum SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT = "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"; + enum SDL_HINT_NO_SIGNAL_HANDLERS = "SDL_NO_SIGNAL_HANDLERS"; + enum SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 = "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"; + + // Changed values from those introduced in 2.0.3 + enum SDL_HINT_RENDER_DIRECT3D11_DEBUG = "SDL_RENDER_DIRECT3D11_DEBUG"; + enum SDL_HINT_WINRT_PRIVACY_POLICY_URL = "SDL_WINRT_PRIVACY_POLICY_URL"; + enum SDL_HINT_WINRT_PRIVACY_POLICY_LABEL = "SDL_WINRT_PRIVACY_POLICY_LABEL"; + enum SDL_HINT_WINRT_HANDLE_BACK_BUTTON = "SDL_WINRT_HANDLE_BACK_BUTTON"; +} + +static if(sdlSupport >= SDLSupport.sdl205) { + enum SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH = "SDL_MOUSE_FOCUS_CLICKTHROUGH"; + enum SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS = "SDL_APPLE_TV_CONTROLLER_UI_EVENTS"; + enum SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION = "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"; + enum SDL_HINT_BMP_SAVE_LEGACY_FORMAT = "SDL_BMP_SAVE_LEGACY_FORMAT"; + enum SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING = "SDL_WINDOWS_DISABLE_THREAD_NAMING"; + enum SDL_HINT_RPI_VIDEO_LAYER = "SDL_RPI_VIDEO_LAYER"; +} + +static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_HINT_RENDER_LOGICAL_SIZE_MODE = "SDL_RENDER_LOGICAL_SIZE_MODE"; + enum SDL_HINT_WINDOWS_INTRESOURCE_ICON = "SDL_WINDOWS_INTRESOURCE_ICON"; + enum SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL = "SDL_WINDOWS_INTRESOURCE_ICON_SMALL"; + enum SDL_HINT_MOUSE_NORMAL_SPEED_SCALE = "SDL_MOUSE_NORMAL_SPEED_SCALE"; + enum SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE = "SDL_MOUSE_RELATIVE_SPEED_SCALE"; + enum SDL_HINT_TOUCH_MOUSE_EVENTS = "SDL_TOUCH_MOUSE_EVENTS"; + enum SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES = "SDL_GAMECONTROLLER_IGNORE_DEVICES"; + enum SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT = "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT"; + enum SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION = "SDL_QTWAYLAND_CONTENT_ORIENTATION"; + enum SDL_HINT_QTWAYLAND_WINDOW_FLAGS = "SDL_QTWAYLAND_WINDOW_FLAGS"; + enum SDL_HINT_OPENGL_ES_DRIVER = "SDL_OPENGL_ES_DRIVER"; + enum SDL_HINT_AUDIO_RESAMPLING_MODE = "SDL_AUDIO_RESAMPLING_MODE"; + enum SDL_HINT_AUDIO_CATEGORY = "SDL_AUDIO_CATEGORY"; +} + +static if(sdlSupport >= SDLSupport.sdl208) { + enum SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR = "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"; + enum SDL_HINT_IOS_HIDE_HOME_INDICATOR = "SDL_IOS_HIDE_HOME_INDICATOR"; + enum SDL_HINT_TV_REMOTE_AS_JOYSTICK = "SDL_TV_REMOTE_AS_JOYSTICK"; + enum SDL_HINT_RETURN_KEY_HIDES_IME = "SDL_RETURN_KEY_HIDES_IME"; + enum SDL_HINT_VIDEO_DOUBLE_BUFFER = "SDL_VIDEO_DOUBLE_BUFFER"; +} + +static if(sdlSupport >= SDLSupport.sdl209) { + enum SDL_HINT_MOUSE_DOUBLE_CLICK_TIME = "SDL_MOUSE_DOUBLE_CLICK_TIME"; + enum SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS = "SDL_MOUSE_DOUBLE_CLICK_RADIUS"; + enum SDL_HINT_JOYSTICK_HIDAPI = "SDL_JOYSTICK_HIDAPI"; + enum SDL_HINT_JOYSTICK_HIDAPI_PS4 = "SDL_JOYSTICK_HIDAPI_PS4"; + enum SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE = "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE"; + enum SDL_HINT_JOYSTICK_HIDAPI_STEAM = "SDL_JOYSTICK_HIDAPI_STEAM"; + enum SDL_HINT_JOYSTICK_HIDAPI_SWITCH = "SDL_JOYSTICK_HIDAPI_SWITCH"; + enum SDL_HINT_JOYSTICK_HIDAPI_XBOX = "SDL_JOYSTICK_HIDAPI_XBOX"; + enum SDL_HINT_ENABLE_STEAM_CONTROLLERS = "SDL_ENABLE_STEAM_CONTROLLERS"; + enum SDL_HINT_ANDROID_TRAP_BACK_BUTTON = "SDL_ANDROID_TRAP_BACK_BUTTON"; +} + +static if(sdlSupport >= SDLSupport.sdl2010) { + enum SDL_HINT_MOUSE_TOUCH_EVENTS = "SDL_MOUSE_TOUCH_EVENTS"; + enum SDL_HINT_GAMECONTROLLERCONFIG_FILE = "SDL_GAMECONTROLLERCONFIG_FILE"; + enum SDL_HINT_ANDROID_BLOCK_ON_PAUSE = "SDL_ANDROID_BLOCK_ON_PAUSE"; + enum SDL_HINT_RENDER_BATCHING = "SDL_RENDER_BATCHING"; + enum SDL_HINT_EVENT_LOGGING = "SDL_EVENT_LOGGING"; + enum SDL_HINT_WAVE_RIFF_CHUNK_SIZE = "SDL_WAVE_RIFF_CHUNK_SIZE"; + enum SDL_HINT_WAVE_TRUNCATION = "SDL_WAVE_TRUNCATION"; + enum SDL_HINT_WAVE_FACT_CHUNK = "SDL_WAVE_FACT_CHUNK"; +} +else static if(sdlSupport >= SDLSupport.sdl204) { + // Added in 2.0.4, removed in 2.0.10. + enum SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH = "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"; +} + +enum SDL_HintPriority { + SDL_HINT_DEFAULT, + SDL_HINT_NORMAL, + SDL_HINT_OVERRIDE, +} +mixin(expandEnum!SDL_HintPriority); + +extern(C) nothrow alias SDL_HintCallback = void function(void*, const(char)*, const(char)*); + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_bool SDL_SetHintWithPriority(const(char)*,const(char)*,SDL_HintPriority); + SDL_bool SDL_SetHint(const(char)*,const(char)*); + const(char)* SDL_GetHint(const(char)*); + void SDL_AddHintCallback(const(char)*,SDL_HintCallback,void*); + void SDL_DelHintCallback(const(char)*,SDL_HintCallback,void*); + void SDL_ClearHints(); + + static if(sdlSupport >= SDLSupport.sdl205) { + SDL_bool SDL_GetHintBoolean(const(char)*,SDL_bool); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_SetHintWithPriority = SDL_bool function(const(char)*,const(char)*,SDL_HintPriority); + alias pSDL_SetHint = SDL_bool function(const(char)*,const(char)*); + alias pSDL_GetHint = const(char)* function(const(char)*); + alias pSDL_AddHintCallback = void function(const(char)*,SDL_HintCallback,void*); + alias pSDL_DelHintCallback = void function(const(char)*,SDL_HintCallback,void*); + alias pSDL_ClearHints = void function(); + } + + __gshared { + pSDL_SetHintWithPriority SDL_SetHintWithPriority; + pSDL_SetHint SDL_SetHint; + pSDL_GetHint SDL_GetHint; + pSDL_AddHintCallback SDL_AddHintCallback; + pSDL_DelHintCallback SDL_DelHintCallback; + pSDL_ClearHints SDL_ClearHints; + } + + static if(sdlSupport >= SDLSupport.sdl205) { + extern(C) @nogc nothrow { + alias pSDL_GetHintBoolean = SDL_bool function(const(char)*,SDL_bool); + } + + __gshared { + pSDL_GetHintBoolean SDL_GetHintBoolean; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdljoystick.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdljoystick.d new file mode 100644 index 0000000..32f54ec --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdljoystick.d @@ -0,0 +1,231 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdljoystick; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +struct SDL_Joystick; + +struct SDL_JoystickGUID { + ubyte[16] data; +} + +alias SDL_JoystickID = int; + +enum : ubyte { + SDL_HAT_CENTERED = 0x00, + SDL_HAT_UP = 0x01, + SDL_HAT_RIGHT = 0x02, + SDL_HAT_DOWN = 0x04, + SDL_HAT_LEFT = 0x08, + SDL_HAT_RIGHTUP = (SDL_HAT_RIGHT|SDL_HAT_UP), + SDL_HAT_RIGHTDOWN = (SDL_HAT_RIGHT|SDL_HAT_DOWN), + SDL_HAT_LEFTUP = (SDL_HAT_LEFT|SDL_HAT_UP), + SDL_HAT_LEFTDOWN = (SDL_HAT_LEFT|SDL_HAT_DOWN), +} + +static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_JoystickPowerLevel { + SDL_JOYSTICK_POWER_UNKNOWN = -1, + SDL_JOYSTICK_POWER_EMPTY, + SDL_JOYSTICK_POWER_LOW, + SDL_JOYSTICK_POWER_MEDIUM, + SDL_JOYSTICK_POWER_FULL, + SDL_JOYSTICK_POWER_WIRED, + SDL_JOYSTICK_POWER_MAX + } + mixin(expandEnum!SDL_JoystickPowerLevel); +} + +static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_JoystickType { + SDL_JOYSTICK_TYPE_UNKNOWN, + SDL_JOYSTICK_TYPE_GAMECONTROLLER, + SDL_JOYSTICK_TYPE_WHEEL, + SDL_JOYSTICK_TYPE_ARCADE_STICK, + SDL_JOYSTICK_TYPE_FLIGHT_STICK, + SDL_JOYSTICK_TYPE_DANCE_PAD, + SDL_JOYSTICK_TYPE_GUITAR, + SDL_JOYSTICK_TYPE_DRUM_KIT, + SDL_JOYSTICK_TYPE_ARCADE_PAD, + SDL_JOYSTICK_TYPE_THROTTLE, + } + mixin(expandEnum!SDL_JoystickType); + + enum { + SDL_JOYSTICK_AXIS_MAX = 32767, + SDL_JOYSTICK_AXIS_MIN = -32768, + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_NumJoysticks(); + const(char)* SDL_JoystickNameForIndex(int); + SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int); + SDL_Joystick* SDL_JoystickOpen(int); + const(char)* SDL_JoystickName(SDL_Joystick*); + SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick*); + char* SDL_JoystickGetGUIDString(SDL_JoystickGUID); + SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const(char)*); + SDL_bool SDL_JoystickGetAttached(SDL_Joystick*); + SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick*); + int SDL_JoystickNumAxes(SDL_Joystick*); + int SDL_JoystickNumBalls(SDL_Joystick*); + int SDL_JoystickNumHats(SDL_Joystick*); + int SDL_JoystickNumButtons(SDL_Joystick*); + void SDL_JoystickUpdate(); + int SDL_JoystickEventState(int); + short SDL_JoystickGetAxis(SDL_Joystick*,int); + ubyte SDL_JoystickGetHat(SDL_Joystick*,int); + int SDL_JoystickGetBall(SDL_Joystick*,int,int*,int*); + ubyte SDL_JoystickGetButton(SDL_Joystick*,int); + void SDL_JoystickClose(SDL_Joystick*); + + static if(sdlSupport >= SDLSupport.sdl204) { + SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick*); + SDL_Joystick* SDL_JoystickFromInstanceID(SDL_JoystickID); + } + static if(sdlSupport >= SDLSupport.sdl206) { + SDL_bool SDL_JoystickGetAxisInitialState(SDL_Joystick*,int,short*); + SDL_JoystickType SDL_JoystickGetDeviceInstanceID(int); + ushort SDL_JoystickGetDeviceProduct(int); + ushort SDL_JoystickGetDeviceProductVersion(int); + SDL_JoystickType SDL_JoystickGetDeviceType(int); + ushort SDL_JoystickGetDeviceVendor(int); + ushort SDL_JoystickGetProduct(SDL_Joystick*); + ushort SDL_JoystickGetProductVersion(SDL_Joystick*); + SDL_JoystickType SDL_JoystickGetType(SDL_Joystick*); + ushort SDL_JoystickGetVendor(SDL_Joystick*); + } + static if(sdlSupport >= SDLSupport.sdl207) { + void SDL_LockJoysticks(); + void SDL_UnlockJoysticks(); + } + static if(sdlSupport >= SDLSupport.sdl209) { + int SDL_JoystickRumble(SDL_Joystick*,ushort,ushort,uint); + } + static if(sdlSupport >= SDLSupport.sdl2010) { + int SDL_JoystickGetDevicePlayerIndex(int); + int SDL_JoystickGetPlayerIndex(SDL_Joystick*); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_NumJoysticks = int function(); + alias pSDL_JoystickNameForIndex = const(char)* function(int); + alias pSDL_JoystickGetDeviceGUID = SDL_JoystickGUID function(int); + alias pSDL_JoystickOpen = SDL_Joystick* function(int); + alias pSDL_JoystickName = const(char)* function(SDL_Joystick*); + alias pSDL_JoystickGetGUID = SDL_JoystickGUID function(SDL_Joystick*); + alias pSDL_JoystickGetGUIDString = char* function(SDL_JoystickGUID); + alias pSDL_JoystickGetGUIDFromString = SDL_JoystickGUID function(const(char)*); + alias pSDL_JoystickGetAttached = SDL_bool function(SDL_Joystick*); + alias pSDL_JoystickInstanceID = SDL_JoystickID function(SDL_Joystick*); + alias pSDL_JoystickNumAxes = int function(SDL_Joystick*); + alias pSDL_JoystickNumBalls = int function(SDL_Joystick*); + alias pSDL_JoystickNumHats = int function(SDL_Joystick*); + alias pSDL_JoystickNumButtons = int function(SDL_Joystick*); + alias pSDL_JoystickUpdate = void function(); + alias pSDL_JoystickEventState = int function(int); + alias pSDL_JoystickGetAxis = short function(SDL_Joystick*,int); + alias pSDL_JoystickGetHat = ubyte function(SDL_Joystick*,int); + alias pSDL_JoystickGetBall = int function(SDL_Joystick*,int,int*,int*); + alias pSDL_JoystickGetButton = ubyte function(SDL_Joystick*,int); + alias pSDL_JoystickClose = void function(SDL_Joystick*); + } + __gshared { + pSDL_NumJoysticks SDL_NumJoysticks; + pSDL_JoystickNameForIndex SDL_JoystickNameForIndex; + pSDL_JoystickGetDeviceGUID SDL_JoystickGetDeviceGUID; + pSDL_JoystickOpen SDL_JoystickOpen; + pSDL_JoystickName SDL_JoystickName; + pSDL_JoystickGetGUID SDL_JoystickGetGUID; + pSDL_JoystickGetGUIDString SDL_JoystickGetGUIDString; + pSDL_JoystickGetGUIDFromString SDL_JoystickGetGUIDFromString; + pSDL_JoystickGetAttached SDL_JoystickGetAttached; + pSDL_JoystickInstanceID SDL_JoystickInstanceID; + pSDL_JoystickNumAxes SDL_JoystickNumAxes; + pSDL_JoystickNumBalls SDL_JoystickNumBalls; + pSDL_JoystickNumHats SDL_JoystickNumHats; + pSDL_JoystickNumButtons SDL_JoystickNumButtons; + pSDL_JoystickUpdate SDL_JoystickUpdate; + pSDL_JoystickEventState SDL_JoystickEventState; + pSDL_JoystickGetAxis SDL_JoystickGetAxis; + pSDL_JoystickGetHat SDL_JoystickGetHat; + pSDL_JoystickGetBall SDL_JoystickGetBall; + pSDL_JoystickGetButton SDL_JoystickGetButton; + pSDL_JoystickClose SDL_JoystickClose; + } + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_JoystickCurrentPowerLevel = SDL_JoystickPowerLevel function(SDL_Joystick*); + alias pSDL_JoystickFromInstanceID = SDL_Joystick* function(SDL_JoystickID); + } + __gshared { + pSDL_JoystickCurrentPowerLevel SDL_JoystickCurrentPowerLevel; + pSDL_JoystickFromInstanceID SDL_JoystickFromInstanceID; + } + } + static if(sdlSupport >= SDLSupport.sdl206) { + extern(C) @nogc nothrow { + alias pSDL_JoystickGetAxisInitialState = SDL_bool function(SDL_Joystick*,int,short*); + alias pSDL_JoystickGetDeviceInstanceID = SDL_JoystickType function(int); + alias pSDL_JoystickGetDeviceProduct = ushort function(int); + alias pSDL_JoystickGetDeviceProductVersion = ushort function(int); + alias pSDL_JoystickGetDeviceType = SDL_JoystickType function(int); + alias pSDL_JoystickGetDeviceVendor = ushort function(int); + alias pSDL_JoystickGetProduct = ushort function(SDL_Joystick*); + alias pSDL_JoystickGetProductVersion = ushort function(SDL_Joystick*); + alias pSDL_JoystickGetType = SDL_JoystickType function(SDL_Joystick*); + alias pSDL_JoystickGetVendor = ushort function(SDL_Joystick*); + } + __gshared { + pSDL_JoystickGetAxisInitialState SDL_JoystickGetAxisInitialState; + pSDL_JoystickGetDeviceInstanceID SDL_JoystickGetDeviceInstanceID; + pSDL_JoystickGetDeviceProduct SDL_JoystickGetDeviceProduct; + pSDL_JoystickGetDeviceProductVersion SDL_JoystickGetDeviceProductVersion; + pSDL_JoystickGetDeviceType SDL_JoystickGetDeviceType; + pSDL_JoystickGetDeviceVendor SDL_JoystickGetDeviceVendor; + pSDL_JoystickGetProduct SDL_JoystickGetProduct; + pSDL_JoystickGetProductVersion SDL_JoystickGetProductVersion; + pSDL_JoystickGetType SDL_JoystickGetType; + pSDL_JoystickGetVendor SDL_JoystickGetVendor; + } + } + static if(sdlSupport >= SDLSupport.sdl207) { + extern(C) @nogc nothrow { + alias pSDL_LockJoysticks = void function(); + alias pSDL_UnlockJoysticks = void function(); + } + __gshared { + pSDL_LockJoysticks SDL_LockJoysticks; + pSDL_UnlockJoysticks SDL_UnlockJoysticks; + } + } + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_JoystickRumble = int function(SDL_Joystick*,ushort,ushort,uint); + } + __gshared { + pSDL_JoystickRumble SDL_JoystickRumble; + } + } + + static if(sdlSupport >= SDLSupport.sdl2010) { + extern(C) @nogc nothrow { + alias pSDL_JoystickGetDevicePlayerIndex = int function(int); + alias pSDL_JoystickGetPlayerIndex = int function(SDL_Joystick*); + } + __gshared { + pSDL_JoystickGetDevicePlayerIndex SDL_JoystickGetDevicePlayerIndex; + pSDL_JoystickGetPlayerIndex SDL_JoystickGetPlayerIndex; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlkeyboard.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlkeyboard.d new file mode 100644 index 0000000..4f4fabe --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlkeyboard.d @@ -0,0 +1,80 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlkeyboard; + +import bindbc.sdl.bind.sdlkeycode : SDL_Keycode, SDL_Keymod; +import bindbc.sdl.bind.sdlrect : SDL_Rect; +import bindbc.sdl.bind.sdlscancode : SDL_Scancode; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +struct SDL_Keysym { + SDL_Scancode scancode; + SDL_Keycode sym; + ushort mod; + uint unused; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_Window* SDL_GetKeyboardFocus(); + ubyte* SDL_GetKeyboardState(int*); + SDL_Keymod SDL_GetModState(); + void SDL_SetModState(SDL_Keymod); + SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode); + SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode); + const(char)* SDL_GetScancodeName(SDL_Scancode); + SDL_Scancode SDL_GetScancodeFromName(const(char)*); + const(char)* SDL_GetKeyName(SDL_Keycode); + SDL_Keycode SDL_GetKeyFromName(const(char)*); + void SDL_StartTextInput(); + SDL_bool SDL_IsTextInputActive(); + void SDL_StopTextInput(); + void SDL_SetTextInputRect(SDL_Rect*); + SDL_bool SDL_HasScreenKeyboardSupport(); + SDL_bool SDL_IsScreenKeyboardShown(SDL_Window*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetKeyboardFocus = SDL_Window* function(); + alias pSDL_GetKeyboardState = ubyte* function(int*); + alias pSDL_GetModState = SDL_Keymod function(); + alias pSDL_SetModState = void function(SDL_Keymod); + alias pSDL_GetKeyFromScancode = SDL_Keycode function(SDL_Scancode); + alias pSDL_GetScancodeFromKey = SDL_Scancode function(SDL_Keycode); + alias pSDL_GetScancodeName = const(char)* function(SDL_Scancode); + alias pSDL_GetScancodeFromName = SDL_Scancode function(const(char)*); + alias pSDL_GetKeyName = const(char)* function(SDL_Keycode); + alias pSDL_GetKeyFromName = SDL_Keycode function(const(char)*); + alias pSDL_StartTextInput = void function(); + alias pSDL_IsTextInputActive = SDL_bool function(); + alias pSDL_StopTextInput = void function(); + alias pSDL_SetTextInputRect = void function(SDL_Rect*); + alias pSDL_HasScreenKeyboardSupport = SDL_bool function(); + alias pSDL_IsScreenKeyboardShown = SDL_bool function(SDL_Window*); + } + + __gshared { + pSDL_GetKeyboardFocus SDL_GetKeyboardFocus; + pSDL_GetKeyboardState SDL_GetKeyboardState; + pSDL_GetModState SDL_GetModState; + pSDL_SetModState SDL_SetModState; + pSDL_GetKeyFromScancode SDL_GetKeyFromScancode; + pSDL_GetScancodeFromKey SDL_GetScancodeFromKey; + pSDL_GetScancodeName SDL_GetScancodeName; + pSDL_GetScancodeFromName SDL_GetScancodeFromName; + pSDL_GetKeyName SDL_GetKeyName; + pSDL_GetKeyFromName SDL_GetKeyFromName; + pSDL_StartTextInput SDL_StartTextInput; + pSDL_IsTextInputActive SDL_IsTextInputActive; + pSDL_StopTextInput SDL_StopTextInput; + pSDL_SetTextInputRect SDL_SetTextInputRect; + pSDL_HasScreenKeyboardSupport SDL_HasScreenKeyboardSupport; + pSDL_IsScreenKeyboardShown SDL_IsScreenKeyboardShown; + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlkeycode.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlkeycode.d new file mode 100644 index 0000000..127067e --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlkeycode.d @@ -0,0 +1,288 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlkeycode; + +import bindbc.sdl.config, + bindbc.sdl.bind.sdlscancode; + +enum SDLK_SCANCODE_MASK = 1<<30; + +enum SDL_SCANCODE_TO_KEYCODE(SDL_Scancode x) = x | SDLK_SCANCODE_MASK; + +enum SDL_Keycode { + SDLK_UNKNOWN = 0, + SDLK_RETURN = '\r', + SDLK_ESCAPE = '\033', + SDLK_BACKSPACE = '\b', + SDLK_TAB = '\t', + SDLK_SPACE = ' ', + SDLK_EXCLAIM = '!', + SDLK_QUOTEDBL = '"', + SDLK_HASH = '#', + SDLK_PERCENT = '%', + SDLK_DOLLAR = '$', + SDLK_AMPERSAND = '&', + SDLK_QUOTE = '\'', + SDLK_LEFTPAREN = '(', + SDLK_RIGHTPAREN = ')', + SDLK_ASTERISK = '*', + SDLK_PLUS = '+', + SDLK_COMMA = ',', + SDLK_MINUS = '-', + SDLK_PERIOD = '.', + SDLK_SLASH = '/', + SDLK_0 = '0', + SDLK_1 = '1', + SDLK_2 = '2', + SDLK_3 = '3', + SDLK_4 = '4', + SDLK_5 = '5', + SDLK_6 = '6', + SDLK_7 = '7', + SDLK_8 = '8', + SDLK_9 = '9', + SDLK_COLON = ':', + SDLK_SEMICOLON = ';', + SDLK_LESS = '<', + SDLK_EQUALS = '=', + SDLK_GREATER = '>', + SDLK_QUESTION = '?', + SDLK_AT = '@', + + SDLK_LEFTBRACKET = '[', + SDLK_BACKSLASH = '\\', + SDLK_RIGHTBRACKET = ']', + SDLK_CARET = '^', + SDLK_UNDERSCORE = '_', + SDLK_BACKQUOTE = '`', + SDLK_a = 'a', + SDLK_b = 'b', + SDLK_c = 'c', + SDLK_d = 'd', + SDLK_e = 'e', + SDLK_f = 'f', + SDLK_g = 'g', + SDLK_h = 'h', + SDLK_i = 'i', + SDLK_j = 'j', + SDLK_k = 'k', + SDLK_l = 'l', + SDLK_m = 'm', + SDLK_n = 'n', + SDLK_o = 'o', + SDLK_p = 'p', + SDLK_q = 'q', + SDLK_r = 'r', + SDLK_s = 's', + SDLK_t = 't', + SDLK_u = 'u', + SDLK_v = 'v', + SDLK_w = 'w', + SDLK_x = 'x', + SDLK_y = 'y', + SDLK_z = 'z', + + SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CAPSLOCK), + + SDLK_F1 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F1), + SDLK_F2 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F2), + SDLK_F3 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F3), + SDLK_F4 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F4), + SDLK_F5 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F5), + SDLK_F6 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F6), + SDLK_F7 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F7), + SDLK_F8 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F8), + SDLK_F9 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F9), + SDLK_F10 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F10), + SDLK_F11 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F11), + SDLK_F12 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F12), + + SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_PRINTSCREEN), + SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_SCROLLLOCK), + SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_PAUSE), + SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_INSERT), + SDLK_HOME = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_HOME), + SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_PAGEUP), + SDLK_DELETE = '\177', + SDLK_END = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_END), + SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_PAGEDOWN), + SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_RIGHT), + SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_LEFT), + SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_DOWN), + SDLK_UP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_UP), + + SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR), + SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_DIVIDE), + SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY), + SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MINUS), + SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_PLUS), + SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_ENTER), + SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_1), + SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_2), + SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_3), + SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_4), + SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_5), + SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_6), + SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_7), + SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_8), + SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_9), + SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_0), + SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_PERIOD), + + SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_APPLICATION), + SDLK_POWER = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_POWER), + SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_EQUALS), + SDLK_F13 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F13), + SDLK_F14 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F14), + SDLK_F15 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F15), + SDLK_F16 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F16), + SDLK_F17 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F17), + SDLK_F18 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F18), + SDLK_F19 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F19), + SDLK_F20 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F20), + SDLK_F21 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F21), + SDLK_F22 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F22), + SDLK_F23 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F23), + SDLK_F24 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_F24), + SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_EXECUTE), + SDLK_HELP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_HELP), + SDLK_MENU = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_MENU), + SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_SELECT), + SDLK_STOP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_STOP), + SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AGAIN), + SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_UNDO), + SDLK_CUT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CUT), + SDLK_COPY = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_COPY), + SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_PASTE), + SDLK_FIND = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_FIND), + SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_MUTE), + SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_VOLUMEUP), + SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_VOLUMEDOWN), + SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_COMMA), + SDLK_KP_EQUALSAS400 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_EQUALSAS400), + + SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_ALTERASE), + SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_SYSREQ), + SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CANCEL), + SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CLEAR), + SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_PRIOR), + SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_RETURN2), + SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_SEPARATOR), + SDLK_OUT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_OUT), + SDLK_OPER = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_OPER), + SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CLEARAGAIN), + SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CRSEL), + SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_EXSEL), + + SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_00), + SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_000), + SDLK_THOUSANDSSEPARATOR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_THOUSANDSSEPARATOR), + SDLK_DECIMALSEPARATOR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_DECIMALSEPARATOR), + SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CURRENCYUNIT), + SDLK_CURRENCYSUBUNIT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CURRENCYSUBUNIT), + SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_LEFTPAREN), + SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_RIGHTPAREN), + SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_LEFTBRACE), + SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_RIGHTBRACE), + SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_TAB), + SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_BACKSPACE), + SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_A), + SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_B), + SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_C), + SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_D), + SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_E), + SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_F), + SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_XOR), + SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_POWER), + SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_PERCENT), + SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_LESS), + SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_GREATER), + SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_AMPERSAND), + SDLK_KP_DBLAMPERSAND = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_DBLAMPERSAND), + SDLK_KP_VERTICALBAR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_VERTICALBAR), + SDLK_KP_DBLVERTICALBAR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_DBLVERTICALBAR), + SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_COLON), + SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_HASH), + SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_SPACE), + SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_AT), + SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_EXCLAM), + SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMSTORE), + SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMRECALL), + SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMCLEAR), + SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMADD), + SDLK_KP_MEMSUBTRACT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMSUBTRACT), + SDLK_KP_MEMMULTIPLY = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMMULTIPLY), + SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_MEMDIVIDE), + SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_PLUSMINUS), + SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_CLEAR), + SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_CLEARENTRY), + SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_BINARY), + SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_OCTAL), + SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_DECIMAL), + SDLK_KP_HEXADECIMAL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KP_HEXADECIMAL), + + SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_LCTRL), + SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_LSHIFT), + SDLK_LALT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_LALT), + SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_LGUI), + SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_RCTRL), + SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_RSHIFT), + SDLK_RALT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_RALT), + SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_RGUI), + + SDLK_MODE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_MODE), + + SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AUDIONEXT), + SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AUDIOPREV), + SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AUDIOSTOP), + SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AUDIOPLAY), + SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AUDIOMUTE), + SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_MEDIASELECT), + SDLK_WWW = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_WWW), + SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_MAIL), + SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_CALCULATOR), + SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_COMPUTER), + SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_SEARCH), + SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_HOME), + SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_BACK), + SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_FORWARD), + SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_STOP), + SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_REFRESH), + SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_AC_BOOKMARKS), + + SDLK_BRIGHTNESSDOWN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_BRIGHTNESSDOWN), + SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_BRIGHTNESSUP), + SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_DISPLAYSWITCH), + SDLK_KBDILLUMTOGGLE = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KBDILLUMTOGGLE), + SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KBDILLUMDOWN), + SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_KBDILLUMUP), + SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_EJECT), + SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE!(SDL_Scancode.SDL_SCANCODE_SLEEP), +} +mixin(expandEnum!SDL_Keycode); + +enum SDL_Keymod { + KMOD_NONE = 0x0000, + KMOD_LSHIFT = 0x0001, + KMOD_RSHIFT = 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LGUI = 0x0400, + KMOD_RGUI = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000, + + KMOD_CTRL = (KMOD_LCTRL|KMOD_RCTRL), + KMOD_SHIFT = (KMOD_LSHIFT|KMOD_RSHIFT), + KMOD_ALT = (KMOD_LALT|KMOD_RALT), + KMOD_GUI = (KMOD_LGUI|KMOD_RGUI), +} +mixin(expandEnum!SDL_Keymod); \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlloadso.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlloadso.d new file mode 100644 index 0000000..02f9b62 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlloadso.d @@ -0,0 +1,28 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlloadso; + +version(BindSDL_Static){ + extern(C) @nogc nothrow { + void* SDL_LoadObject(const(char)*); + void* SDL_LoadFunction(void*,const(char*)); + void SDL_UnloadObject(void*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_LoadObject = void* function(const(char)*); + alias pSDL_LoadFunction = void* function(void*,const(char*)); + alias pSDL_UnloadObject = void function(void*); + } + + __gshared { + pSDL_LoadObject SDL_LoadObject; + pSDL_LoadFunction SDL_LoadFunction; + pSDL_UnloadObject SDL_UnloadObject; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d new file mode 100644 index 0000000..36bf76d --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d @@ -0,0 +1,111 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdllog; + +version(WebAssembly) +{ + alias va_list = char*; +} +else import core.stdc.stdarg : va_list; +import bindbc.sdl.config; + +enum SDL_MAX_LOG_MESSAGE = 4096; + +enum { + SDL_LOG_CATEGORY_APPLICATION, + SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, + SDL_LOG_CATEGORY_SYSTEM, + SDL_LOG_CATEGORY_AUDIO, + SDL_LOG_CATEGORY_VIDEO, + SDL_LOG_CATEGORY_RENDER, + SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, + + SDL_LOG_CATEGORY_RESERVED1, + SDL_LOG_CATEGORY_RESERVED2, + SDL_LOG_CATEGORY_RESERVED3, + SDL_LOG_CATEGORY_RESERVED4, + SDL_LOG_CATEGORY_RESERVED5, + SDL_LOG_CATEGORY_RESERVED6, + SDL_LOG_CATEGORY_RESERVED7, + SDL_LOG_CATEGORY_RESERVED8, + SDL_LOG_CATEGORY_RESERVED9, + SDL_LOG_CATEGORY_RESERVED10, + + SDL_LOG_CATEGORY_CUSTOM +} + +enum SDL_LogPriority { + SDL_LOG_PRIORITY_VERBOSE = 1, + SDL_LOG_PRIORITY_DEBUG, + SDL_LOG_PRIORITY_INFO, + SDL_LOG_PRIORITY_WARN, + SDL_LOG_PRIORITY_ERROR, + SDL_LOG_PRIORITY_CRITICAL, + SDL_NUM_LOG_PRIORITIES +} +mixin(expandEnum!SDL_LogPriority); + +extern(C) nothrow alias SDL_LogOutputFunction = void function(void*, int, SDL_LogPriority, const(char)*); + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + void SDL_LogSetAllPriority(SDL_LogPriority); + void SDL_LogSetPriority(int,SDL_LogPriority); + SDL_LogPriority SDL_LogGetPriority(int); + void SDL_LogResetPriorities(); + void SDL_Log(const(char)*,...); + void SDL_LogVerbose(int,const(char)*,...); + void SDL_LogDebug(int,const(char)*,...); + void SDL_LogInfo(int,const(char)*,...); + void SDL_LogWarn(int,const(char)*,...); + void SDL_LogError(int,const(char)*,...); + void SDL_LogCritical(int,const(char)*,...); + void SDL_LogMessage(int,SDL_LogPriority,const(char)*,...); + void SDL_LogMessageV(int,SDL_LogPriority,const(char)*,va_list); + void SDL_LogGetOutputFunction(SDL_LogOutputFunction,void**); + void SDL_LogSetOutputFunction(SDL_LogOutputFunction,void*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_LogSetAllPriority = void function(SDL_LogPriority); + alias pSDL_LogSetPriority = void function(int,SDL_LogPriority); + alias pSDL_LogGetPriority = SDL_LogPriority function(int); + alias pSDL_LogResetPriorities = void function(); + alias pSDL_Log = void function(const(char)*,...); + alias pSDL_LogVerbose = void function(int,const(char)*,...); + alias pSDL_LogDebug = void function(int,const(char)*,...); + alias pSDL_LogInfo = void function(int,const(char)*,...); + alias pSDL_LogWarn = void function(int,const(char)*,...); + alias pSDL_LogError = void function(int,const(char)*,...); + alias pSDL_LogCritical = void function(int,const(char)*,...); + alias pSDL_LogMessage = void function(int,SDL_LogPriority,const(char)*,...); + alias pSDL_LogMessageV = void function(int,SDL_LogPriority,const(char)*,va_list); + alias pSDL_LogGetOutputFunction = void function(SDL_LogOutputFunction,void**); + alias pSDL_LogSetOutputFunction = void function(SDL_LogOutputFunction,void*); + } + + __gshared { + pSDL_LogSetAllPriority SDL_LogSetAllPriority; + pSDL_LogSetPriority SDL_LogSetPriority; + pSDL_LogGetPriority SDL_LogGetPriority; + pSDL_LogResetPriorities SDL_LogResetPriorities; + pSDL_Log SDL_Log; + pSDL_LogVerbose SDL_LogVerbose; + pSDL_LogDebug SDL_LogDebug; + pSDL_LogInfo SDL_LogInfo; + pSDL_LogWarn SDL_LogWarn; + pSDL_LogError SDL_LogError; + pSDL_LogCritical SDL_LogCritical; + pSDL_LogMessage SDL_LogMessage; + pSDL_LogMessageV SDL_LogMessageV; + pSDL_LogGetOutputFunction SDL_LogGetOutputFunction; + pSDL_LogSetOutputFunction SDL_LogSetOutputFunction; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlmessagebox.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlmessagebox.d new file mode 100644 index 0000000..89636f5 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlmessagebox.d @@ -0,0 +1,75 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlmessagebox; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +enum SDL_MessageBoxFlags { + SDL_MESSAGEBOX_ERROR = 0x00000010, + SDL_MESSAGEBOX_WARNING = 0x00000020, + SDL_MESSAGEBOX_INFORMATION = 0x00000040, +} +mixin(expandEnum!SDL_MessageBoxFlags); + +enum SDL_MessageBoxButtonFlags { + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002, +} +mixin(expandEnum!SDL_MessageBoxButtonFlags); + +struct SDL_MessageBoxButtonData { + uint flags; + int buttonid; + const(char)* text; +} + +struct SDL_MessageBoxColor { + ubyte r, g, b; +} + +enum SDL_MessageBoxColorType { + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX, +} +mixin(expandEnum!SDL_MessageBoxColorType); + +struct SDL_MessageBoxColorScheme { + SDL_MessageBoxColor[SDL_MESSAGEBOX_COLOR_MAX] colors; +} + +struct SDL_MessageBoxData { + uint flags; + SDL_Window* window; + const(char)* title; + const(char)* message; + int numbuttons; + const(SDL_MessageBoxButtonData)* buttons; + const(SDL_MessageBoxColorScheme)* colorScheme; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_ShowMessageBox(const(SDL_MessageBoxData)*,int*); + int SDL_ShowSimpleMessageBox(uint,const(char)*,const(char)*,SDL_Window*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_ShowMessageBox = int function(const(SDL_MessageBoxData)*,int*); + alias pSDL_ShowSimpleMessageBox = int function(uint,const(char)*,const(char)*,SDL_Window*); + } + + __gshared { + pSDL_ShowMessageBox SDL_ShowMessageBox; + pSDL_ShowSimpleMessageBox SDL_ShowSimpleMessageBox; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlmouse.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlmouse.d new file mode 100644 index 0000000..f9fc492 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlmouse.d @@ -0,0 +1,140 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlmouse; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlsurface : SDL_Surface; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +struct SDL_Cursor; + +enum SDL_SystemCursor { + SDL_SYSTEM_CURSOR_ARROW, + SDL_SYSTEM_CURSOR_IBEAM, + SDL_SYSTEM_CURSOR_WAIT, + SDL_SYSTEM_CURSOR_CROSSHAIR, + SDL_SYSTEM_CURSOR_WAITARROW, + SDL_SYSTEM_CURSOR_SIZENWSE, + SDL_SYSTEM_CURSOR_SIZENESW, + SDL_SYSTEM_CURSOR_SIZEWE, + SDL_SYSTEM_CURSOR_SIZENS, + SDL_SYSTEM_CURSOR_SIZEALL, + SDL_SYSTEM_CURSOR_NO, + SDL_SYSTEM_CURSOR_HAND, + SDL_NUM_SYSTEM_CURSORS +} + +alias SDL_SYSTEM_CURSOR_ARROW = SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW; +alias SDL_SYSTEM_CURSOR_IBEAM = SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM; +alias SDL_SYSTEM_CURSOR_WAIT = SDL_SystemCursor.SDL_SYSTEM_CURSOR_WAIT; +alias SDL_SYSTEM_CURSOR_CROSSHAIR = SDL_SystemCursor.SDL_SYSTEM_CURSOR_CROSSHAIR; +alias SDL_SYSTEM_CURSOR_WAITARROW = SDL_SystemCursor.SDL_SYSTEM_CURSOR_WAITARROW; +alias SDL_SYSTEM_CURSOR_SIZENWSE = SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE; +alias SDL_SYSTEM_CURSOR_SIZENESW = SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW; +alias SDL_SYSTEM_CURSOR_SIZEWE = SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE; +alias SDL_SYSTEM_CURSOR_SIZENS = SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS; +alias SDL_SYSTEM_CURSOR_SIZEALL = SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEALL; +alias SDL_SYSTEM_CURSOR_NO = SDL_SystemCursor.SDL_SYSTEM_CURSOR_NO; +alias SDL_SYSTEM_CURSOR_HAND = SDL_SystemCursor.SDL_SYSTEM_CURSOR_HAND; +alias SDL_NUM_SYSTEM_CURSORS = SDL_SystemCursor.SDL_NUM_SYSTEM_CURSORS; + +enum SDL_BUTTON(ubyte x) = 1 << (x-1); + +enum : ubyte { + SDL_BUTTON_LEFT = 1, + SDL_BUTTON_MIDDLE = 2, + SDL_BUTTON_RIGHT = 3, + SDL_BUTTON_X1 = 4, + SDL_BUTTON_X2 = 5, + SDL_BUTTON_LMASK = SDL_BUTTON!(SDL_BUTTON_LEFT), + SDL_BUTTON_MMASK = SDL_BUTTON!(SDL_BUTTON_MIDDLE), + SDL_BUTTON_RMASK = SDL_BUTTON!(SDL_BUTTON_RIGHT), + SDL_BUTTON_X1MASK = SDL_BUTTON!(SDL_BUTTON_X1), + SDL_BUTTON_X2MASK = SDL_BUTTON!(SDL_BUTTON_X2), +} + +static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_MouseWheelDirection { + SDL_MOUSEWHEEL_NORMAL, + SDL_MOUSEWHEEL_FLIPPED, + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_Window* SDL_GetMouseFocus(); + uint SDL_GetMouseState(int*,int*); + uint SDL_GetRelativeMouseState(int*,int*); + void SDL_WarpMouseInWindow(SDL_Window*,int,int); + int SDL_SetRelativeMouseMode(SDL_bool); + SDL_bool SDL_GetRelativeMouseMode(); + SDL_Cursor* SDL_CreateCursor(const(ubyte)*,const(ubyte)*,int,int,int,int); + SDL_Cursor* SDL_CreateColorCursor(SDL_Surface*,int,int); + SDL_Cursor* SDL_CreateSystemCursor(SDL_SystemCursor); + void SDL_SetCursor(SDL_Cursor*); + SDL_Cursor* SDL_GetCursor(); + SDL_Cursor* SDL_GetDefaultCursor(); + void SDL_FreeCursor(SDL_Cursor*); + int SDL_ShowCursor(int); + + static if(sdlSupport >= SDLSupport.sdl204) { + int SDL_CaptureMouse(SDL_bool); + uint SDL_GetGlobalMouseState(int*,int*); + void SDL_WarpMouseGlobal(int,int); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetMouseFocus = SDL_Window* function(); + alias pSDL_GetMouseState = uint function(int*,int*); + alias pSDL_GetRelativeMouseState = uint function(int*,int*); + alias pSDL_WarpMouseInWindow = void function(SDL_Window*,int,int); + alias pSDL_SetRelativeMouseMode = int function(SDL_bool); + alias pSDL_GetRelativeMouseMode = SDL_bool function(); + alias pSDL_CreateCursor = SDL_Cursor* function(const(ubyte)*,const(ubyte)*,int,int,int,int); + alias pSDL_CreateColorCursor = SDL_Cursor* function(SDL_Surface*,int,int); + alias pSDL_CreateSystemCursor = SDL_Cursor* function(SDL_SystemCursor); + alias pSDL_SetCursor = void function(SDL_Cursor*); + alias pSDL_GetCursor = SDL_Cursor* function(); + alias pSDL_GetDefaultCursor = SDL_Cursor* function(); + alias pSDL_FreeCursor = void function(SDL_Cursor*); + alias pSDL_ShowCursor = int function(int); + } + + __gshared { + pSDL_GetMouseFocus SDL_GetMouseFocus; + pSDL_GetMouseState SDL_GetMouseState; + pSDL_GetRelativeMouseState SDL_GetRelativeMouseState; + pSDL_WarpMouseInWindow SDL_WarpMouseInWindow; + pSDL_SetRelativeMouseMode SDL_SetRelativeMouseMode; + pSDL_GetRelativeMouseMode SDL_GetRelativeMouseMode; + pSDL_CreateCursor SDL_CreateCursor; + pSDL_CreateColorCursor SDL_CreateColorCursor; + pSDL_CreateSystemCursor SDL_CreateSystemCursor; + pSDL_SetCursor SDL_SetCursor; + pSDL_GetCursor SDL_GetCursor; + pSDL_GetDefaultCursor SDL_GetDefaultCursor; + pSDL_FreeCursor SDL_FreeCursor; + pSDL_ShowCursor SDL_ShowCursor; + } + + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_CaptureMouse = int function(SDL_bool); + alias pSDL_GetGlobalMouseState = uint function(int*,int*); + alias pSDL_WarpMouseGlobal = void function(int,int); + } + + __gshared { + pSDL_CaptureMouse SDL_CaptureMouse; + pSDL_GetGlobalMouseState SDL_GetGlobalMouseState; + pSDL_WarpMouseGlobal SDL_WarpMouseGlobal; + } + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlpixels.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlpixels.d new file mode 100644 index 0000000..7d65753 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlpixels.d @@ -0,0 +1,283 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlpixels; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_FOURCC, SDL_bool; + +enum SDL_ALPHA_OPAQUE = 255; +enum SDL_ALPHA_TRANSPARENT = 0; + +enum { + SDL_PIXELTYPE_UNKNOWN, + SDL_PIXELTYPE_INDEX1, + SDL_PIXELTYPE_INDEX4, + SDL_PIXELTYPE_INDEX8, + SDL_PIXELTYPE_PACKED8, + SDL_PIXELTYPE_PACKED16, + SDL_PIXELTYPE_PACKED32, + SDL_PIXELTYPE_ARRAYU8, + SDL_PIXELTYPE_ARRAYU16, + SDL_PIXELTYPE_ARRAYU32, + SDL_PIXELTYPE_ARRAYF16, + SDL_PIXELTYPE_ARRAYF32 +} + +enum { + SDL_BITMAPORDER_NONE, + SDL_BITMAPORDER_4321, + SDL_BITMAPORDER_1234 +} + +enum { + SDL_PACKEDORDER_NONE, + SDL_PACKEDORDER_XRGB, + SDL_PACKEDORDER_RGBX, + SDL_PACKEDORDER_ARGB, + SDL_PACKEDORDER_RGBA, + SDL_PACKEDORDER_XBGR, + SDL_PACKEDORDER_BGRX, + SDL_PACKEDORDER_ABGR, + SDL_PACKEDORDER_BGRA +} + +enum { + SDL_ARRAYORDER_NONE, + SDL_ARRAYORDER_RGB, + SDL_ARRAYORDER_RGBA, + SDL_ARRAYORDER_ARGB, + SDL_ARRAYORDER_BGR, + SDL_ARRAYORDER_BGRA, + SDL_ARRAYORDER_ABGR +} + +enum { + SDL_PACKEDLAYOUT_NONE, + SDL_PACKEDLAYOUT_332, + SDL_PACKEDLAYOUT_4444, + SDL_PACKEDLAYOUT_1555, + SDL_PACKEDLAYOUT_5551, + SDL_PACKEDLAYOUT_565, + SDL_PACKEDLAYOUT_8888, + SDL_PACKEDLAYOUT_2101010, + SDL_PACKEDLAYOUT_1010102 +} + +alias SDL_DEFINE_PIXELFOURCC = SDL_FOURCC; + +enum uint SDL_DEFINE_PIXELFORMAT(int type, int order, int layout, int bits, int bytes) = + (1 << 28) | (type << 24) | (order << 20) | (layout << 16) | (bits << 8) | (bytes << 0); + +enum uint SDL_PIXELFLAG(uint x) = (x >> 28) & 0x0F; +enum uint SDL_PIXELTYPE(uint x) = (x >> 24) & 0x0F; +enum uint SDL_PIXELORDER(uint x) = (x >> 20) & 0x0F; +enum uint SDL_PIXELLAYOUT(uint x) = (x >> 16) & 0x0F; +enum uint SDL_BITSPERPIXEL(uint x) = (x >> 8) & 0xFF; + +template SDL_BYTESPERPIXEL(uint x) { + static if(SDL_ISPIXELFORMAT_FOURCC!x) { + static if(x == SDL_PIXELFORMAT_YUY2 || x == SDL_PIXELFORMAT_UYVY || x == SDL_PIXELFORMAT_YVYU) + enum SDL_BYTESPERPIXEL = 2; + else enum SDL_BYTESPERPIXEL = 1; + } + else enum SDL_BYTESPERPIXEL = (x >> 0) & 0xFF; +} + +template SDL_ISPIXELFORMAT_INDEXED(uint format) { + static if(SDL_ISPIXELFORMAT_FOURCC!format) { + enum SDL_ISPIXELFORMAT_INDEXED = SDL_PIXELTYPE!format == SDL_PIXELTYPE_INDEX1 || SDL_PIXELTYPE!format == SDL_PIXELTYPE_INDEX4 || + SDL_PIXELTYPE!format == SDL_PIXELTYPE_INDEX8; + } + else enum SDL_ISPIXELFORMAT_INDEXED = false; +} + +template SDL_ISPIXELFORMAT_PACKED(uint format) { + static if(SDL_ISPIXELFORMAT_FOURCC!format) { + enum SDL_ISPIXELFORMAT_PACKED = SDL_PIXELTYPE!format == SDL_PIXELTYPE_PACKED8 || SDL_PIXELTYPE!format == SDL_PIXELTYPE_PACKED16 || + SDL_PIXELTYPE!format == SDL_PIXELTYPE_PACKED32; + } + else enum SDL_ISPIXELFORMAT_PACKED = false; +} + +static if(sdlSupport >= SDLSupport.sdl204) { + template SDL_ISPIXELFORMAT_ARRAY(uint format) { + static if(SDL_ISPIXELFORMAT_FOURCC!format) { + enum SDL_ISPIXELFORMAT_ARRAY = SDL_PIXELTYPE!format == SDL_PIXELTYPE_ARRAYU8 || SDL_PIXELTYPE!format == SDL_PIXELTYPE_ARRAYU16 || + SDL_PIXELTYPE!format == SDL_PIXELTYPE_ARRAYU32 || SDL_PIXELTYPE!format == SDL_PIXELTYPE_ARRAYF16 || + SDL_PIXELTYPE!format == SDL_PIXELTYPE_ARRAYF32; + } + else enum SDL_ISPIXELFORMAT_ARRAY = false; + } +} + +template SDL_ISPIXELFORMAT_ALPHA(uint format) { + static if(SDL_ISPIXELFORMAT_PACKED!format) { + enum SDL_ISPIXELFORMAT_ALPHA = (SDL_PIXELORDER!format == SDL_PACKEDORDER_ARGB || SDL_PIXELORDER!format == SDL_PACKEDORDER_RGBA || + SDL_PIXELORDER!format == SDL_PACKEDORDER_ABGR || SDL_PIXELORDER!format == SDL_PACKEDORDER_BGRA); + } + else static if(sdlSupport >= SDLSupport.sdl204 && SDL_ISPIXELFORMAT_ARRAY!format) { + enum SDL_ISPIXELFORMAT_ALPHA = (SDL_PIXELORDER!format == SDL_ARRAYORDER_ARGB || SDL_PIXELORDER!format == SDL_ARRAYORDER_RGBA || + SDL_PIXELORDER!format == SDL_ARRAYORDER_ABGR || SDL_PIXELORDER!format == SDL_ARRAYORDER_BGRA); + } + else enum SDL_ISPIXELFORMAT_ALPHA = false; +} + +enum SDL_ISPIXELFORMAT_FOURCC(uint format) = format && !(format & 0x80000000); + +enum SDL_PIXELFORMAT_UNKNOWN = 0; +enum SDL_PIXELFORMAT_INDEX1LSB = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, 1, 0); +enum SDL_PIXELFORMAT_INDEX1MSB = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, 1, 0); +enum SDL_PIXELFORMAT_INDEX4LSB = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, 4, 0); +enum SDL_PIXELFORMAT_INDEX4MSB = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, 4, 0); +enum SDL_PIXELFORMAT_INDEX8 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1); +enum SDL_PIXELFORMAT_RGB332 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_332, 8, 1); +enum SDL_PIXELFORMAT_RGB444 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_4444, 12, 2); +enum SDL_PIXELFORMAT_RGB555 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_1555, 15, 2); +enum SDL_PIXELFORMAT_BGR555 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_1555, 15, 2); +enum SDL_PIXELFORMAT_ARGB4444 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_4444, 16, 2); +enum SDL_PIXELFORMAT_RGBA4444 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_4444, 16, 2); +enum SDL_PIXELFORMAT_ABGR4444 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_4444, 16, 2); +enum SDL_PIXELFORMAT_BGRA4444 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_4444, 16, 2); +enum SDL_PIXELFORMAT_ARGB1555 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_1555, 16, 2); +enum SDL_PIXELFORMAT_RGBA5551 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_5551, 16, 2); +enum SDL_PIXELFORMAT_ABGR1555 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_1555, 16, 2); +enum SDL_PIXELFORMAT_BGRA5551 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_5551, 16, 2); +enum SDL_PIXELFORMAT_RGB565 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_565, 16, 2); +enum SDL_PIXELFORMAT_BGR565 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_565, 16, 2); +enum SDL_PIXELFORMAT_RGB24 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, 24, 3); +enum SDL_PIXELFORMAT_BGR24 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, 24, 3); +enum SDL_PIXELFORMAT_RGB888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_8888, 24, 4); +enum SDL_PIXELFORMAT_RGBX8888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, SDL_PACKEDLAYOUT_8888, 24, 4); +enum SDL_PIXELFORMAT_BGR888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_8888, 24, 4); +enum SDL_PIXELFORMAT_BGRX8888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, SDL_PACKEDLAYOUT_8888, 24, 4); +enum SDL_PIXELFORMAT_ARGB8888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_8888, 32, 4); +enum SDL_PIXELFORMAT_RGBA8888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_8888, 32, 4); +enum SDL_PIXELFORMAT_ABGR8888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_8888, 32, 4); +enum SDL_PIXELFORMAT_BGRA8888 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_8888, 32, 4); +enum SDL_PIXELFORMAT_ARGB2101010 = SDL_DEFINE_PIXELFORMAT!(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_2101010, 32, 4); + +enum SDL_PIXELFORMAT_YV12 = SDL_DEFINE_PIXELFOURCC!('Y', 'V', '1', '2'); +enum SDL_PIXELFORMAT_IYUV = SDL_DEFINE_PIXELFOURCC!('I', 'Y', 'U', 'V'); +enum SDL_PIXELFORMAT_YUY2 = SDL_DEFINE_PIXELFOURCC!('Y', 'U', 'Y', '2'); +enum SDL_PIXELFORMAT_UYVY = SDL_DEFINE_PIXELFOURCC!('U', 'Y', 'V', 'Y'); +enum SDL_PIXELFORMAT_YVYU = SDL_DEFINE_PIXELFOURCC!('Y', 'V', 'Y', 'U'); + +static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_PIXELFORMAT_NV12 = SDL_DEFINE_PIXELFOURCC!('N', 'V', '1', '2'); + enum SDL_PIXELFORMAT_NV21 = SDL_DEFINE_PIXELFOURCC!('N', 'V', '2', '1'); +} + +static if(sdlSupport >= SDLSupport.sdl208) { + enum SDL_PIXELFORMAT_EXTERNAL_OES = SDL_DEFINE_PIXELFOURCC!('O', 'E', 'S', ' '); +} + +static assert(SDL_PIXELFORMAT_BGRX8888 == 0x16661804); + +// Added in SDL 2.0.5, but doesn't hurt to make available for every version. +version(BigEndian) { + alias SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888; + alias SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888; + alias SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888; + alias SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888; +} +else { + alias SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888; + alias SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888; + alias SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888; + alias SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888; +} + +struct SDL_Color { + ubyte r; + ubyte g; + ubyte b; + ubyte a; +} +alias SDL_Colour = SDL_Color; + +struct SDL_Palette { + int ncolors; + SDL_Color* colors; + uint version_; // NOTE: original was named 'version' + int refcount; +} + +struct SDL_PixelFormat { + uint format; + SDL_Palette *palette; + ubyte BitsPerPixel; + ubyte BytesPerPixel; + ubyte[2] padding; + uint Rmask; + uint Gmask; + uint Bmask; + uint Amask; + ubyte Rloss; + ubyte Gloss; + ubyte Bloss; + ubyte Aloss; + ubyte Rshift; + ubyte Gshift; + ubyte Bshift; + ubyte Ashift; + int refcount; + SDL_PixelFormat* next; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + const(char)* SDL_GetPixelFormatName(uint); + SDL_bool SDL_PixelFormatEnumToMasks(uint,int*,uint*,uint*,uint*,uint*); + uint SDL_MasksToPixelFormatEnum(int,uint,uint,uint,uint); + SDL_PixelFormat* SDL_AllocFormat(uint); + void SDL_FreeFormat(SDL_PixelFormat*); + SDL_Palette* SDL_AllocPalette(int); + int SDL_SetPixelFormatPalette(SDL_PixelFormat*,SDL_Palette*); + int SDL_SetPaletteColors(SDL_Palette*,const(SDL_Color)*,int,int); + void SDL_FreePalette(SDL_Palette*); + uint SDL_MapRGB(const(SDL_PixelFormat)*,ubyte,ubyte,ubyte); + uint SDL_MapRGBA(const(SDL_PixelFormat)*,ubyte,ubyte,ubyte,ubyte); + void SDL_GetRGB(uint,const(SDL_PixelFormat)*,ubyte*,ubyte*,ubyte*); + void SDL_GetRGBA(uint,const(SDL_PixelFormat)*,ubyte*,ubyte*,ubyte*,ubyte*); + void SDL_CalculateGammaRamp(float,ushort*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetPixelFormatName = const(char)* function(uint); + alias pSDL_PixelFormatEnumToMasks = SDL_bool function(uint,int*,uint*,uint*,uint*,uint*); + alias pSDL_MasksToPixelFormatEnum = uint function(int,uint,uint,uint,uint); + alias pSDL_AllocFormat = SDL_PixelFormat* function(uint); + alias pSDL_FreeFormat = void function(SDL_PixelFormat*); + alias pSDL_AllocPalette = SDL_Palette* function(int); + alias pSDL_SetPixelFormatPalette = int function(SDL_PixelFormat*,SDL_Palette*); + alias pSDL_SetPaletteColors = int function(SDL_Palette*,const(SDL_Color)*,int,int); + alias pSDL_FreePalette = void function(SDL_Palette*); + alias pSDL_MapRGB = uint function(const(SDL_PixelFormat)*,ubyte,ubyte,ubyte); + alias pSDL_MapRGBA = uint function(const(SDL_PixelFormat)*,ubyte,ubyte,ubyte,ubyte); + alias pSDL_GetRGB = void function(uint,const(SDL_PixelFormat)*,ubyte*,ubyte*,ubyte*); + alias pSDL_GetRGBA = void function(uint,const(SDL_PixelFormat)*,ubyte*,ubyte*,ubyte*,ubyte*); + alias pSDL_CalculateGammaRamp = void function(float,ushort*); + } + + __gshared { + pSDL_GetPixelFormatName SDL_GetPixelFormatName; + pSDL_PixelFormatEnumToMasks SDL_PixelFormatEnumToMasks; + pSDL_MasksToPixelFormatEnum SDL_MasksToPixelFormatEnum; + pSDL_AllocFormat SDL_AllocFormat; + pSDL_FreeFormat SDL_FreeFormat; + pSDL_AllocPalette SDL_AllocPalette; + pSDL_SetPixelFormatPalette SDL_SetPixelFormatPalette; + pSDL_SetPaletteColors SDL_SetPaletteColors; + pSDL_FreePalette SDL_FreePalette; + pSDL_MapRGB SDL_MapRGB; + pSDL_MapRGBA SDL_MapRGBA; + pSDL_GetRGB SDL_GetRGB; + pSDL_GetRGBA SDL_GetRGBA; + pSDL_CalculateGammaRamp SDL_CalculateGammaRamp; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlplatform.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlplatform.d new file mode 100644 index 0000000..da23ff7 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlplatform.d @@ -0,0 +1,22 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlplatform; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + const(char)* SDL_GetPlatform(); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetPlatform = const(char)* function(); + } + + __gshared { + pSDL_GetPlatform SDL_GetPlatform; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlpower.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlpower.d new file mode 100644 index 0000000..b6eac3b --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlpower.d @@ -0,0 +1,33 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlpower; + +import bindbc.sdl.config; + +enum SDL_PowerState { + SDL_POWERSTATE_UNKNOWN, + SDL_POWERSTATE_ON_BATTERY, + SDL_POWERSTATE_NO_BATTERY, + SDL_POWERSTATE_CHARGING, + SDL_POWERSTATE_CHARGED +} +mixin(expandEnum!SDL_PowerState); + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_PowerState SDL_GetPowerInfo(int*,int*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetPowerInfo = SDL_PowerState function(int*,int*); + } + + __gshared { + pSDL_GetPowerInfo SDL_GetPowerInfo; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlrect.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlrect.d new file mode 100644 index 0000000..5122fa6 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlrect.d @@ -0,0 +1,80 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlrect; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +struct SDL_Point { + int x; + int y; +} + +struct SDL_Rect { + int x, y; + int w, h; +} + +static if(sdlSupport >= SDLSupport.sdl2010) { + struct SDL_FPoint { + float x, y; + } + + struct SDL_FRect { + float x, y; + float w, h; + } +} + +@nogc nothrow pure { + // This macro was added to SDL_rect.h in 2.0.4, but hurts nothing to implement for + // all versions. + bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) { + pragma(inline, true); + return ((p.x >= r.x) && (p.x < (r.x + r.w)) && + (p.y >= r.y) && (p.y < (r.y + r.h))); + } + + bool SDL_RectEmpty(const(SDL_Rect)* X) { + pragma(inline, true); + return !X || (X.w <= 0) || (X.h <= 0); + } + + bool SDL_RectEquals(const(SDL_Rect)* A, const(SDL_Rect)* B) { + pragma(inline, true); + return A && B && + (A.x == B.x) && (A.y == B.y) && + (A.w == B.w) && (A.h == B.h); + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_bool SDL_HasIntersection(const(SDL_Rect)*,const(SDL_Rect)*); + SDL_bool SDL_IntersectRect(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); + void SDL_UnionRect(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); + SDL_bool SDL_EnclosePoints(const(SDL_Point)*,int,const(SDL_Rect)*,SDL_Rect*); + SDL_bool SDL_IntersectRectAndLine(const(SDL_Rect)*,int*,int*,int*,int*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_HasIntersection = SDL_bool function(const(SDL_Rect)*,const(SDL_Rect)*); + alias pSDL_IntersectRect = SDL_bool function(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); + alias pSDL_UnionRect = void function(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); + alias pSDL_EnclosePoints = SDL_bool function(const(SDL_Point)*,int,const(SDL_Rect)*,SDL_Rect*); + alias pSDL_IntersectRectAndLine = SDL_bool function(const(SDL_Rect)*,int*,int*,int*,int*); + } + + __gshared { + pSDL_HasIntersection SDL_HasIntersection; + pSDL_IntersectRect SDL_IntersectRect; + pSDL_UnionRect SDL_UnionRect; + pSDL_EnclosePoints SDL_EnclosePoints; + pSDL_IntersectRectAndLine SDL_IntersectRectAndLine; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlrender.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlrender.d new file mode 100644 index 0000000..b6b4d65 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlrender.d @@ -0,0 +1,316 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlrender; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlblendmode : SDL_BlendMode; +import bindbc.sdl.bind.sdlrect; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlsurface : SDL_Surface; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +enum SDL_RendererFlags : uint { + SDL_RENDERER_SOFTWARE = 0x00000001, + SDL_RENDERER_ACCELERATED = 0x00000002, + SDL_RENDERER_PRESENTVSYNC = 0x00000004, + SDL_RENDERER_TARGETTEXTURE = 0x00000008, +} + +mixin(expandEnum!SDL_RendererFlags); + +struct SDL_RendererInfo { + const(char)* name; + SDL_RendererFlags flags; + uint num_texture_formats; + uint[16] texture_formats; + int max_texture_width; + int max_texture_height; +} + +enum SDL_TextureAccess { + SDL_TEXTUREACCESS_STATIC, + SDL_TEXTUREACCESS_STREAMING, + SDL_TEXTUREACCESS_TARGET, +} +mixin(expandEnum!SDL_TextureAccess); + +enum SDL_TextureModulate { + SDL_TEXTUREMODULATE_NONE = 0x00000000, + SDL_TEXTUREMODULATE_COLOR = 0x00000001, + SDL_TEXTUREMODULATE_ALPHA = 0x00000002 +} +mixin(expandEnum!SDL_TextureModulate); + +enum SDL_RendererFlip { + SDL_FLIP_NONE = 0x00000000, + SDL_FLIP_HORIZONTAL = 0x00000001, + SDL_FLIP_VERTICAL = 0x00000002, +} +mixin(expandEnum!SDL_RendererFlip); + +struct SDL_Renderer; +struct SDL_Texture; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_GetNumRenderDrivers(); + int SDL_GetRenderDriverInfo(int,SDL_RendererInfo*); + int SDL_CreateWindowAndRenderer(int,int,uint,SDL_Window**,SDL_Renderer**); + SDL_Renderer* SDL_CreateRenderer(SDL_Window*,int,SDL_RendererFlags); + SDL_Renderer* SDL_CreateSoftwareRenderer(SDL_Surface*); + SDL_Renderer* SDL_GetRenderer(SDL_Window*); + int SDL_GetRendererInfo(SDL_Renderer*,SDL_RendererInfo*); + int SDL_GetRendererOutputSize(SDL_Renderer*,int*,int*); + SDL_Texture* SDL_CreateTexture(SDL_Renderer*,uint,SDL_TextureAccess,int,int); + SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer*,SDL_Surface*); + int SDL_QueryTexture(SDL_Texture*,uint*,int*,int*,int*); + int SDL_SetTextureColorMod(SDL_Texture*,ubyte,ubyte,ubyte); + int SDL_GetTextureColorMod(SDL_Texture*,ubyte*,ubyte*,ubyte*); + int SDL_SetTextureAlphaMod(SDL_Texture*,ubyte); + int SDL_GetTextureAlphaMod(SDL_Texture*,ubyte*); + int SDL_SetTextureBlendMode(SDL_Texture*,SDL_BlendMode); + int SDL_GetTextureBlendMode(SDL_Texture*,SDL_BlendMode*); + int SDL_UpdateTexture(SDL_Texture*,const(SDL_Rect)*,const(void)*,int); + int SDL_LockTexture(SDL_Texture*,const(SDL_Rect)*,void**,int*); + void SDL_UnlockTexture(SDL_Texture*); + SDL_bool SDL_RenderTargetSupported(SDL_Renderer*); + int SDL_SetRenderTarget(SDL_Renderer*,SDL_Texture*); + SDL_Texture* SDL_GetRenderTarget(SDL_Renderer*); + int SDL_RenderSetClipRect(SDL_Renderer*,const(SDL_Rect)*); + void SDL_RenderGetClipRect(SDL_Renderer* renderer,SDL_Rect*); + int SDL_RenderSetLogicalSize(SDL_Renderer*,int,int); + void SDL_RenderGetLogicalSize(SDL_Renderer*,int*,int*); + int SDL_RenderSetViewport(SDL_Renderer*,const(SDL_Rect)*); + void SDL_RenderGetViewport(SDL_Renderer*,SDL_Rect*); + int SDL_RenderSetScale(SDL_Renderer*,float,float); + int SDL_RenderGetScale(SDL_Renderer*,float*,float*); + int SDL_SetRenderDrawColor(SDL_Renderer*,ubyte,ubyte,ubyte,ubyte); + int SDL_GetRenderDrawColor(SDL_Renderer*,ubyte*,ubyte*,ubyte*,ubyte*); + int SDL_SetRenderDrawBlendMode(SDL_Renderer*,SDL_BlendMode); + int SDL_GetRenderDrawBlendMode(SDL_Renderer*,SDL_BlendMode*); + int SDL_RenderClear(SDL_Renderer*); + int SDL_RenderDrawPoint(SDL_Renderer*,int,int); + int SDL_RenderDrawPoints(SDL_Renderer*,const(SDL_Point)*,int); + int SDL_RenderDrawLine(SDL_Renderer*,int,int,int,int); + int SDL_RenderDrawLines(SDL_Renderer*,const(SDL_Point)*,int); + int SDL_RenderDrawRect(SDL_Renderer*,const(SDL_Rect)*); + int SDL_RenderDrawRects(SDL_Renderer*,const(SDL_Rect)*,int); + int SDL_RenderFillRect(SDL_Renderer*,const(SDL_Rect)*); + int SDL_RenderFillRects(SDL_Renderer*,const(SDL_Rect)*,int); + int SDL_RenderCopy(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect*)); + int SDL_RenderCopyEx(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect)*,const(double),const(SDL_Point)*,const(SDL_RendererFlip)); + int SDL_RenderReadPixels(SDL_Renderer*,const(SDL_Rect)*,uint,void*,int); + void SDL_RenderPresent(SDL_Renderer*); + void SDL_DestroyTexture(SDL_Texture*); + void SDL_DestroyRenderer(SDL_Renderer*); + int SDL_GL_BindTexture(SDL_Texture*,float*,float*); + int SDL_GL_UnbindTexture(SDL_Texture*); + + static if(sdlSupport >= SDLSupport.sdl201) { + int SDL_UpdateYUVTexture(SDL_Texture*,const(SDL_Rect)*,const(ubyte)*,int,const(ubyte)*,int,const(ubyte)*,int); + } + static if(sdlSupport >= SDLSupport.sdl204) { + SDL_bool SDL_RenderIsClipEnabled(SDL_Renderer*); + } + static if(sdlSupport >= SDLSupport.sdl205) { + SDL_bool SDL_RenderGetIntegerScale(SDL_Renderer*); + int SDL_RenderSetIntegerScale(SDL_Renderer*,SDL_bool); + } + static if(sdlSupport >= SDLSupport.sdl208) { + void* SDL_RenderGetMetalLayer(SDL_Renderer*); + void* SDL_RenderGetMetalCommandEncoder(SDL_Renderer*); + } + static if(sdlSupport >= SDLSupport.sdl2010) { + int SDL_RenderDrawPointF(SDL_Renderer*,float,float); + int SDL_RenderDrawPointsF(SDL_Renderer*,const(SDL_FPoint)*,int); + int SDL_RenderDrawLineF(SDL_Renderer*,float,float,float,float); + int SDL_RenderDrawLinesF(SDL_Renderer*,const(SDL_FPoint)*,int); + int SDL_RenderDrawRectF(SDL_Renderer*,const(SDL_FRect)*); + int SDL_RenderDrawRectsF(SDL_Renderer*,const(SDL_FRect)*,int); + int SDL_RenderFillRectF(SDL_Renderer*,const(SDL_FRect)*); + int SDL_RenderFillRectsF(SDL_Renderer*,const(SDL_FRect)*,int); + int SDL_RenderCopyF(SDL_Renderer*,SDL_Texture*,const(SDL_FRect)*,const(SDL_FRect)*); + int SDL_RenderCopyExF(SDL_Renderer*,SDL_Texture*,const(SDL_FRect)*,const(SDL_FRect)*,const(double),const(SDL_FPoint)*,const(SDL_RendererFlip)); + int SDL_RenderFlush(SDL_Renderer*); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetNumRenderDrivers = int function(); + alias pSDL_GetRenderDriverInfo = int function(int,SDL_RendererInfo*); + alias pSDL_CreateWindowAndRenderer = int function(int,int,uint,SDL_Window**,SDL_Renderer**); + alias pSDL_CreateRenderer = SDL_Renderer* function(SDL_Window*,int,SDL_RendererFlags); + alias pSDL_CreateSoftwareRenderer = SDL_Renderer* function(SDL_Surface*); + alias pSDL_GetRenderer = SDL_Renderer* function(SDL_Window*); + alias pSDL_GetRendererInfo = int function(SDL_Renderer*,SDL_RendererInfo*); + alias pSDL_GetRendererOutputSize = int function(SDL_Renderer*,int*,int*); + alias pSDL_CreateTexture = SDL_Texture* function(SDL_Renderer*,uint,SDL_TextureAccess,int,int); + alias pSDL_CreateTextureFromSurface = SDL_Texture* function(SDL_Renderer*,SDL_Surface*); + alias pSDL_QueryTexture = int function(SDL_Texture*,uint*,int*,int*,int*); + alias pSDL_SetTextureColorMod = int function(SDL_Texture*,ubyte,ubyte,ubyte); + alias pSDL_GetTextureColorMod = int function(SDL_Texture*,ubyte*,ubyte*,ubyte*); + alias pSDL_SetTextureAlphaMod = int function(SDL_Texture*,ubyte); + alias pSDL_GetTextureAlphaMod = int function(SDL_Texture*,ubyte*); + alias pSDL_SetTextureBlendMode = int function(SDL_Texture*,SDL_BlendMode); + alias pSDL_GetTextureBlendMode = int function(SDL_Texture*,SDL_BlendMode*); + alias pSDL_UpdateTexture = int function(SDL_Texture*,const(SDL_Rect)*,const(void)*,int); + alias pSDL_LockTexture = int function(SDL_Texture*,const(SDL_Rect)*,void**,int*); + alias pSDL_UnlockTexture = void function(SDL_Texture*); + alias pSDL_RenderTargetSupported = SDL_bool function(SDL_Renderer*); + alias pSDL_SetRenderTarget = int function(SDL_Renderer*,SDL_Texture*); + alias pSDL_GetRenderTarget = SDL_Texture* function(SDL_Renderer*); + alias pSDL_RenderSetClipRect = int function(SDL_Renderer*,const(SDL_Rect)*); + alias pSDL_RenderGetClipRect = void function(SDL_Renderer* renderer,SDL_Rect*); + alias pSDL_RenderSetLogicalSize = int function(SDL_Renderer*,int,int); + alias pSDL_RenderGetLogicalSize = void function(SDL_Renderer*,int*,int*); + alias pSDL_RenderSetViewport = int function(SDL_Renderer*,const(SDL_Rect)*); + alias pSDL_RenderGetViewport = void function(SDL_Renderer*,SDL_Rect*); + alias pSDL_RenderSetScale = int function(SDL_Renderer*,float,float); + alias pSDL_RenderGetScale = int function(SDL_Renderer*,float*,float*); + alias pSDL_SetRenderDrawColor = int function(SDL_Renderer*,ubyte,ubyte,ubyte,ubyte); + alias pSDL_GetRenderDrawColor = int function(SDL_Renderer*,ubyte*,ubyte*,ubyte*,ubyte*); + alias pSDL_SetRenderDrawBlendMode = int function(SDL_Renderer*,SDL_BlendMode); + alias pSDL_GetRenderDrawBlendMode = int function(SDL_Renderer*,SDL_BlendMode*); + alias pSDL_RenderClear = int function(SDL_Renderer*); + alias pSDL_RenderDrawPoint = int function(SDL_Renderer*,int,int); + alias pSDL_RenderDrawPoints = int function(SDL_Renderer*,const(SDL_Point)*,int); + alias pSDL_RenderDrawLine = int function(SDL_Renderer*,int,int,int,int); + alias pSDL_RenderDrawLines = int function(SDL_Renderer*,const(SDL_Point)*,int); + alias pSDL_RenderDrawRect = int function(SDL_Renderer*,const(SDL_Rect)*); + alias pSDL_RenderDrawRects = int function(SDL_Renderer*,const(SDL_Rect)*,int); + alias pSDL_RenderFillRect = int function(SDL_Renderer*,const(SDL_Rect)*); + alias pSDL_RenderFillRects = int function(SDL_Renderer*,const(SDL_Rect)*,int); + alias pSDL_RenderCopy = int function(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect*)); + alias pSDL_RenderCopyEx = int function(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect)*,const(double),const(SDL_Point)*,const(SDL_RendererFlip)); + alias pSDL_RenderReadPixels = int function(SDL_Renderer*,const(SDL_Rect)*,uint,void*,int); + alias pSDL_RenderPresent = void function(SDL_Renderer*); + alias pSDL_DestroyTexture = void function(SDL_Texture*); + alias pSDL_DestroyRenderer = void function(SDL_Renderer*); + alias pSDL_GL_BindTexture = int function(SDL_Texture*,float*,float*); + alias pSDL_GL_UnbindTexture = int function(SDL_Texture*); + } + + __gshared { + pSDL_GetNumRenderDrivers SDL_GetNumRenderDrivers; + pSDL_GetRenderDriverInfo SDL_GetRenderDriverInfo; + pSDL_CreateWindowAndRenderer SDL_CreateWindowAndRenderer; + pSDL_CreateRenderer SDL_CreateRenderer; + pSDL_CreateSoftwareRenderer SDL_CreateSoftwareRenderer; + pSDL_GetRenderer SDL_GetRenderer; + pSDL_GetRendererInfo SDL_GetRendererInfo; + pSDL_GetRendererOutputSize SDL_GetRendererOutputSize; + pSDL_CreateTexture SDL_CreateTexture; + pSDL_CreateTextureFromSurface SDL_CreateTextureFromSurface; + pSDL_QueryTexture SDL_QueryTexture; + pSDL_SetTextureColorMod SDL_SetTextureColorMod; + pSDL_GetTextureColorMod SDL_GetTextureColorMod; + pSDL_SetTextureAlphaMod SDL_SetTextureAlphaMod; + pSDL_GetTextureAlphaMod SDL_GetTextureAlphaMod; + pSDL_SetTextureBlendMode SDL_SetTextureBlendMode; + pSDL_GetTextureBlendMode SDL_GetTextureBlendMode; + pSDL_UpdateTexture SDL_UpdateTexture; + pSDL_LockTexture SDL_LockTexture; + pSDL_UnlockTexture SDL_UnlockTexture; + pSDL_RenderTargetSupported SDL_RenderTargetSupported; + pSDL_SetRenderTarget SDL_SetRenderTarget; + pSDL_GetRenderTarget SDL_GetRenderTarget; + pSDL_RenderSetClipRect SDL_RenderSetClipRect; + pSDL_RenderGetClipRect SDL_RenderGetClipRect; + pSDL_RenderSetLogicalSize SDL_RenderSetLogicalSize; + pSDL_RenderGetLogicalSize SDL_RenderGetLogicalSize; + pSDL_RenderSetViewport SDL_RenderSetViewport; + pSDL_RenderGetViewport SDL_RenderGetViewport; + pSDL_RenderSetScale SDL_RenderSetScale; + pSDL_RenderGetScale SDL_RenderGetScale; + pSDL_SetRenderDrawColor SDL_SetRenderDrawColor; + pSDL_GetRenderDrawColor SDL_GetRenderDrawColor; + pSDL_SetRenderDrawBlendMode SDL_SetRenderDrawBlendMode; + pSDL_GetRenderDrawBlendMode SDL_GetRenderDrawBlendMode; + pSDL_RenderClear SDL_RenderClear; + pSDL_RenderDrawPoint SDL_RenderDrawPoint; + pSDL_RenderDrawPoints SDL_RenderDrawPoints; + pSDL_RenderDrawLine SDL_RenderDrawLine; + pSDL_RenderDrawLines SDL_RenderDrawLines; + pSDL_RenderDrawRect SDL_RenderDrawRect; + pSDL_RenderDrawRects SDL_RenderDrawRects; + pSDL_RenderFillRect SDL_RenderFillRect; + pSDL_RenderFillRects SDL_RenderFillRects; + pSDL_RenderCopy SDL_RenderCopy; + pSDL_RenderCopyEx SDL_RenderCopyEx; + pSDL_RenderReadPixels SDL_RenderReadPixels; + pSDL_RenderPresent SDL_RenderPresent; + pSDL_DestroyTexture SDL_DestroyTexture; + pSDL_DestroyRenderer SDL_DestroyRenderer; + pSDL_GL_BindTexture SDL_GL_BindTexture; + pSDL_GL_UnbindTexture SDL_GL_UnbindTexture; + } + static if(sdlSupport >= SDLSupport.sdl201) { + extern(C) @nogc nothrow { + alias pSDL_UpdateYUVTexture = int function(SDL_Texture*,const(SDL_Rect)*,const(ubyte)*,int,const(ubyte)*,int,const(ubyte)*,int); + } + __gshared { + pSDL_UpdateYUVTexture SDL_UpdateYUVTexture; + } + } + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_RenderIsClipEnabled = SDL_bool function(SDL_Renderer*); + } + __gshared { + pSDL_RenderIsClipEnabled SDL_RenderIsClipEnabled; + } + } + static if(sdlSupport >= SDLSupport.sdl205) { + extern(C) @nogc nothrow { + alias pSDL_RenderGetIntegerScale = SDL_bool function(SDL_Renderer*); + alias pSDL_RenderSetIntegerScale = int function(SDL_Renderer*,SDL_bool); + } + __gshared { + pSDL_RenderGetIntegerScale SDL_RenderGetIntegerScale; + pSDL_RenderSetIntegerScale SDL_RenderSetIntegerScale; + } + } + static if(sdlSupport >= SDLSupport.sdl208) { + extern(C) @nogc nothrow { + alias pSDL_RenderGetMetalLayer = void* function(SDL_Renderer*); + alias pSDL_RenderGetMetalCommandEncoder = void* function(SDL_Renderer*); + } + __gshared { + pSDL_RenderGetMetalLayer SDL_RenderGetMetalLayer; + pSDL_RenderGetMetalCommandEncoder SDL_RenderGetMetalCommandEncoder; + } + } + static if(sdlSupport >= SDLSupport.sdl2010) { + extern(C) @nogc nothrow { + alias pSDL_RenderDrawPointF = int function(SDL_Renderer*,float,float); + alias pSDL_RenderDrawPointsF = int function(SDL_Renderer*,const(SDL_FPoint)*,int); + alias pSDL_RenderDrawLineF = int function(SDL_Renderer*,float,float,float,float); + alias pSDL_RenderDrawLinesF = int function(SDL_Renderer*,const(SDL_FPoint)*,int); + alias pSDL_RenderDrawRectF = int function(SDL_Renderer*,const(SDL_FRect)*); + alias pSDL_RenderDrawRectsF = int function(SDL_Renderer*,const(SDL_FRect)*,int); + alias pSDL_RenderFillRectF = int function(SDL_Renderer*,const(SDL_FRect)*); + alias pSDL_RenderFillRectsF = int function(SDL_Renderer*,const(SDL_FRect)*,int); + alias pSDL_RenderCopyF = int function(SDL_Renderer*,SDL_Texture*,const(SDL_FRect)*,const(SDL_FRect)*); + alias pSDL_RenderCopyExF = int function(SDL_Renderer*,SDL_Texture*,const(SDL_FRect)*,const(SDL_FRect)*,const(double),const(SDL_FPoint)*,const(SDL_RendererFlip)); + alias pSDL_RenderFlush = int function(SDL_Renderer*); + } + __gshared { + pSDL_RenderDrawPointF SDL_RenderDrawPointF; + pSDL_RenderDrawPointsF SDL_RenderDrawPointsF; + pSDL_RenderDrawLineF SDL_RenderDrawLineF; + pSDL_RenderDrawLinesF SDL_RenderDrawLinesF; + pSDL_RenderDrawRectF SDL_RenderDrawRectF; + pSDL_RenderDrawRectsF SDL_RenderDrawRectsF; + pSDL_RenderFillRectF SDL_RenderFillRectF; + pSDL_RenderFillRectsF SDL_RenderFillRectsF; + pSDL_RenderCopyF SDL_RenderCopyF; + pSDL_RenderCopyExF SDL_RenderCopyExF; + pSDL_RenderFlush SDL_RenderFlush; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlrwops.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlrwops.d new file mode 100644 index 0000000..47ddd20 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlrwops.d @@ -0,0 +1,208 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlrwops; + +//import core.stdc.stdio : FILE; + +struct FILE +{ +} + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +enum : uint { + SDL_RWOPS_UNKNOWN = 0, + SDL_RWOPS_WINFILE = 1, + SDL_RWOPS_STDFILE = 2, + SDL_RWOPS_JNIFILE = 3, + SDL_RWOPS_MEMORY = 4, + SDL_RWOPS_MEMORY_RO = 5, +} + +struct SDL_RWops { + extern(C) @nogc nothrow { + long function(SDL_RWops*) size; + long function(SDL_RWops*, long, int) seek; + size_t function(SDL_RWops*, void*, size_t, size_t) read; + size_t function(SDL_RWops*, const(void)*, size_t, size_t) write; + int function(SDL_RWops*) close; + } + + uint type; + + union Hidden { + // version(Android) + version(Windows) { + struct Windowsio { + int append; + void* h; + struct Buffer { + void* data; + size_t size; + size_t left; + } + Buffer buffer; + } + Windowsio windowsio; + } + + struct Stdio { + int autoclose; + FILE* fp; + } + Stdio stdio; + + struct Mem { + ubyte* base; + ubyte* here; + ubyte* stop; + } + Mem mem; + + struct Unknown { + void* data1; + void* data2; + } + Unknown unknown; + } + Hidden hidden; +} + +enum { + RW_SEEK_SET = 0, + RW_SEEK_CUR = 1, + RW_SEEK_END = 2, +} + +static if(sdlSupport < SDLSupport.sdl2010) { + @nogc nothrow { + long SDL_RWsize(SDL_RWops* ctx) { return ctx.size(ctx); } + long SDL_RWseek(SDL_RWops* ctx, long offset, int whence) { return ctx.seek(ctx, offset, whence); } + long SDL_RWtell(SDL_RWops* ctx) { return ctx.seek(ctx, 0, RW_SEEK_CUR); } + size_t SDL_RWread(SDL_RWops* ctx, void* ptr, size_t size, size_t n) { return ctx.read(ctx, ptr, size, n); } + size_t SDL_RWwrite(SDL_RWops* ctx, const(void)* ptr, size_t size, size_t n) { return ctx.write(ctx, ptr, size, n); } + int SDL_RWclose(SDL_RWops* ctx) { return ctx.close(ctx); } + } +} + +static if(sdlSupport >= SDLSupport.sdl206) { + @nogc nothrow + void* SDL_LoadFile(const(char)* filename, size_t datasize) { + pragma(inline, true); + return SDL_LoadFile_RW(SDL_RWFromFile(filename, "rb"), datasize, 1); + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_RWops* SDL_RWFromFile(const(char)*,const(char)*); + SDL_RWops* SDL_RWFromFP(FILE*,SDL_bool); + SDL_RWops* SDL_RWFromMem(void*,int); + SDL_RWops* SDL_RWFromConstMem(const(void)*,int); + SDL_RWops* SDL_AllocRW(); + void SDL_FreeRW(SDL_RWops*); + ubyte SDL_ReadU8(SDL_RWops*); + ushort SDL_ReadLE16(SDL_RWops*); + ushort SDL_ReadBE16(SDL_RWops*); + uint SDL_ReadLE32(SDL_RWops*); + uint SDL_ReadBE32(SDL_RWops*); + ulong SDL_ReadLE64(SDL_RWops*); + ulong SDL_ReadBE64(SDL_RWops*); + size_t SDL_WriteU8(SDL_RWops*,ubyte); + size_t SDL_WriteLE16(SDL_RWops*,ushort); + size_t SDL_WriteBE16(SDL_RWops*,ushort); + size_t SDL_WriteLE32(SDL_RWops*,uint); + size_t SDL_WriteBE32(SDL_RWops*,uint); + size_t SDL_WriteLE64(SDL_RWops*,ulong); + size_t SDL_WriteBE64(SDL_RWops*,ulong); + + static if(sdlSupport >= SDLSupport.sdl206) { + void* SDL_LoadFile_RW(SDL_RWops*,size_t,int); + } + static if(sdlSupport >= SDLSupport.sdl2010) { + long SDL_RWsize(SDL_RWops*); + long SDL_RWseek(SDL_RWops*,long,int); + long SDL_RWtell(SDL_RWops*); + size_t SDL_RWread(SDL_RWops*,void*,size_t,size_t); + size_t SDL_RWwrite(SDL_RWops*,const(void)*,size_t,size_t); + int SDL_RWclose(SDL_RWops*); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_RWFromFile = SDL_RWops* function(const(char)*,const(char)*); + alias pSDL_RWFromFP = SDL_RWops* function(FILE*,SDL_bool); + alias pSDL_RWFromMem = SDL_RWops* function(void*,int); + alias pSDL_RWFromConstMem = SDL_RWops* function(const(void)*,int); + alias pSDL_AllocRW = SDL_RWops* function(); + alias pSDL_FreeRW = void function(SDL_RWops*); + alias pSDL_ReadU8 = ubyte function(SDL_RWops*); + alias pSDL_ReadLE16 = ushort function(SDL_RWops*); + alias pSDL_ReadBE16 = ushort function(SDL_RWops*); + alias pSDL_ReadLE32 = uint function(SDL_RWops*); + alias pSDL_ReadBE32 = uint function(SDL_RWops*); + alias pSDL_ReadLE64 = ulong function(SDL_RWops*); + alias pSDL_ReadBE64 = ulong function(SDL_RWops*); + alias pSDL_WriteU8 = size_t function(SDL_RWops*,ubyte); + alias pSDL_WriteLE16 = size_t function(SDL_RWops*,ushort); + alias pSDL_WriteBE16 = size_t function(SDL_RWops*,ushort); + alias pSDL_WriteLE32 = size_t function(SDL_RWops*,uint); + alias pSDL_WriteBE32 = size_t function(SDL_RWops*,uint); + alias pSDL_WriteLE64 = size_t function(SDL_RWops*,ulong); + alias pSDL_WriteBE64 = size_t function(SDL_RWops*,ulong); + } + __gshared { + pSDL_RWFromFile SDL_RWFromFile; + pSDL_RWFromFP SDL_RWFromFP; + pSDL_RWFromMem SDL_RWFromMem; + pSDL_RWFromConstMem SDL_RWFromConstMem; + pSDL_AllocRW SDL_AllocRW; + pSDL_FreeRW SDL_FreeRW; + pSDL_ReadU8 SDL_ReadU8; + pSDL_ReadLE16 SDL_ReadLE16; + pSDL_ReadBE16 SDL_ReadBE16; + pSDL_ReadLE32 SDL_ReadLE32; + pSDL_ReadBE32 SDL_ReadBE32; + pSDL_ReadLE64 SDL_ReadLE64; + pSDL_ReadBE64 SDL_ReadBE64; + pSDL_WriteU8 SDL_WriteU8; + pSDL_WriteLE16 SDL_WriteLE16; + pSDL_WriteBE16 SDL_WriteBE16; + pSDL_WriteLE32 SDL_WriteLE32; + pSDL_WriteBE32 SDL_WriteBE32; + pSDL_WriteLE64 SDL_WriteLE64; + pSDL_WriteBE64 SDL_WriteBE64; + } + static if(sdlSupport >= SDLSupport.sdl206) { + extern(C) @nogc nothrow { + alias pSDL_LoadFile_RW = void* function(SDL_RWops*,size_t,int); + } + __gshared { + pSDL_LoadFile_RW SDL_LoadFile_RW; + } + } + static if(sdlSupport >= SDLSupport.sdl2010) { + extern(C) @nogc nothrow { + alias pSDL_RWsize = long function(SDL_RWops*); + alias pSDL_RWseek = long function(SDL_RWops*,long,int); + alias pSDL_RWtell = long function(SDL_RWops*); + alias pSDL_RWread = size_t function(SDL_RWops*,void*,size_t,size_t); + alias pSDL_RWwrite = size_t function(SDL_RWops*,const(void)*,size_t,size_t); + alias pSDL_RWclose = int function(SDL_RWops*); + } + __gshared { + pSDL_RWsize SDL_RWsize; + pSDL_RWseek SDL_RWseek; + pSDL_RWtell SDL_RWtell; + pSDL_RWread SDL_RWread; + pSDL_RWwrite SDL_RWwrite; + pSDL_RWclose SDL_RWclose; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlscancode.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlscancode.d new file mode 100644 index 0000000..fc188dd --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlscancode.d @@ -0,0 +1,542 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlscancode; + +import bindbc.sdl.config; + +static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_Scancode { + SDL_SCANCODE_UNKNOWN = 0, + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, + SDL_SCANCODE_NONUSHASH = 50, + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, + SDL_SCANCODE_APPLICATION = 101, + SDL_SCANCODE_POWER = 102, + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, + SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, + SDL_SCANCODE_AGAIN = 121, + SDL_SCANCODE_UNDO = 122, + SDL_SCANCODE_CUT = 123, + SDL_SCANCODE_COPY = 124, + SDL_SCANCODE_PASTE = 125, + SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, + SDL_SCANCODE_LANG2 = 145, + SDL_SCANCODE_LANG3 = 146, + SDL_SCANCODE_LANG4 = 147, + SDL_SCANCODE_LANG5 = 148, + SDL_SCANCODE_LANG6 = 149, + SDL_SCANCODE_LANG7 = 150, + SDL_SCANCODE_LANG8 = 151, + SDL_SCANCODE_LANG9 = 152, + + SDL_SCANCODE_ALTERASE = 153, + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, + SDL_SCANCODE_LGUI = 227, + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, + SDL_SCANCODE_RGUI = 231, + + SDL_SCANCODE_MODE = 257, + + SDL_SCANCODE_AUDIONEXT = 258, + SDL_SCANCODE_AUDIOPREV = 259, + SDL_SCANCODE_AUDIOSTOP = 260, + SDL_SCANCODE_AUDIOPLAY = 261, + SDL_SCANCODE_AUDIOMUTE = 262, + SDL_SCANCODE_MEDIASELECT = 263, + SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_MAIL = 265, + SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_COMPUTER = 267, + SDL_SCANCODE_AC_SEARCH = 268, + SDL_SCANCODE_AC_HOME = 269, + SDL_SCANCODE_AC_BACK = 270, + SDL_SCANCODE_AC_FORWARD = 271, + SDL_SCANCODE_AC_STOP = 272, + SDL_SCANCODE_AC_REFRESH = 273, + SDL_SCANCODE_AC_BOOKMARKS = 274, + + SDL_SCANCODE_BRIGHTNESSDOWN = 275, + SDL_SCANCODE_BRIGHTNESSUP = 276, + SDL_SCANCODE_DISPLAYSWITCH = 277, + SDL_SCANCODE_KBDILLUMTOGGLE = 278, + SDL_SCANCODE_KBDILLUMDOWN = 279, + SDL_SCANCODE_KBDILLUMUP = 280, + SDL_SCANCODE_EJECT = 281, + SDL_SCANCODE_SLEEP = 282, + + SDL_SCANCODE_APP1 = 283, + SDL_SCANCODE_APP2 = 284, + + SDL_SCANCODE_AUDIOREWIND = 285, + SDL_SCANCODE_AUDIOFASTFORWARD = 286, + + SDL_NUM_SCANCODES = 512 + } +} +else { + enum SDL_Scancode { + SDL_SCANCODE_UNKNOWN = 0, + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, + SDL_SCANCODE_NONUSHASH = 50, + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, + SDL_SCANCODE_APPLICATION = 101, + SDL_SCANCODE_POWER = 102, + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, + SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, + SDL_SCANCODE_AGAIN = 121, + SDL_SCANCODE_UNDO = 122, + SDL_SCANCODE_CUT = 123, + SDL_SCANCODE_COPY = 124, + SDL_SCANCODE_PASTE = 125, + SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, + SDL_SCANCODE_LANG2 = 145, + SDL_SCANCODE_LANG3 = 146, + SDL_SCANCODE_LANG4 = 147, + SDL_SCANCODE_LANG5 = 148, + SDL_SCANCODE_LANG6 = 149, + SDL_SCANCODE_LANG7 = 150, + SDL_SCANCODE_LANG8 = 151, + SDL_SCANCODE_LANG9 = 152, + + SDL_SCANCODE_ALTERASE = 153, + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, + SDL_SCANCODE_LGUI = 227, + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, + SDL_SCANCODE_RGUI = 231, + + SDL_SCANCODE_MODE = 257, + + SDL_SCANCODE_AUDIONEXT = 258, + SDL_SCANCODE_AUDIOPREV = 259, + SDL_SCANCODE_AUDIOSTOP = 260, + SDL_SCANCODE_AUDIOPLAY = 261, + SDL_SCANCODE_AUDIOMUTE = 262, + SDL_SCANCODE_MEDIASELECT = 263, + SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_MAIL = 265, + SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_COMPUTER = 267, + SDL_SCANCODE_AC_SEARCH = 268, + SDL_SCANCODE_AC_HOME = 269, + SDL_SCANCODE_AC_BACK = 270, + SDL_SCANCODE_AC_FORWARD = 271, + SDL_SCANCODE_AC_STOP = 272, + SDL_SCANCODE_AC_REFRESH = 273, + SDL_SCANCODE_AC_BOOKMARKS = 274, + + SDL_SCANCODE_BRIGHTNESSDOWN = 275, + SDL_SCANCODE_BRIGHTNESSUP = 276, + SDL_SCANCODE_DISPLAYSWITCH = 277, + SDL_SCANCODE_KBDILLUMTOGGLE = 278, + SDL_SCANCODE_KBDILLUMDOWN = 279, + SDL_SCANCODE_KBDILLUMUP = 280, + SDL_SCANCODE_EJECT = 281, + SDL_SCANCODE_SLEEP = 282, + + SDL_SCANCODE_APP1 = 283, + SDL_SCANCODE_APP2 = 284, + + SDL_NUM_SCANCODES = 512 + } +} +mixin(expandEnum!SDL_Scancode); \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlshape.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlshape.d new file mode 100644 index 0000000..aed3410 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlshape.d @@ -0,0 +1,63 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlshape; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlpixels : SDL_Color; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlsurface : SDL_Surface; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +enum { + SDL_NONSHAPEABLE_WINDOW = -1, + SDL_INVALID_SHAPE_ARGUMENT = -2, + SDL_WINDOW_LACKS_SHAPE = -3, +} + +enum WindowShapeMode { + ShapeModeDefault, + ShapeModeBinarizeAlpha, + ShapeModeReverseBinarizeAlpha, + ShapeModeColorKey +} +mixin(expandEnum!WindowShapeMode); + +enum SDL_SHAPEMODEALPHA(WindowShapeMode mode) = (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha); + +union SDL_WindowShapeParams { + ubyte binarizationCutoff; + SDL_Color colorKey; +} + +struct SDL_WindowShapeMode { + WindowShapeMode mode; + SDL_WindowShapeParams parameters; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_Window* SDL_CreateShapedWindow(const(char)*,uint,uint,uint,uint,uint); + SDL_bool SDL_IsShapedWindow(const(SDL_Window)*); + int SDL_SetWindowShape(SDL_Window*,SDL_Surface*,SDL_WindowShapeMode*); + int SDL_GetShapedWindowMode(SDL_Window*,SDL_WindowShapeMode*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_CreateShapedWindow = SDL_Window* function(const(char)*,uint,uint,uint,uint,uint); + alias pSDL_IsShapedWindow = SDL_bool function(const(SDL_Window)*); + alias pSDL_SetWindowShape = int function(SDL_Window*,SDL_Surface*,SDL_WindowShapeMode*); + alias pSDL_GetShapedWindowMode = int function(SDL_Window*,SDL_WindowShapeMode*); + } + + __gshared { + pSDL_CreateShapedWindow SDL_CreateShapedWindow; + pSDL_IsShapedWindow SDL_IsShapedWindow; + pSDL_SetWindowShape SDL_SetWindowShape; + pSDL_GetShapedWindowMode SDL_GetShapedWindowMode; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlstdinc.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlstdinc.d new file mode 100644 index 0000000..68d77d8 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlstdinc.d @@ -0,0 +1,42 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlstdinc; + +import bindbc.sdl.config; + +enum SDL_bool { + SDL_FALSE = 0, + SDL_TRUE = 1 +} + +mixin(expandEnum!SDL_bool); + +alias Sint8 = byte; +alias Uint8 = ubyte; +alias Sint16 = short; +alias Uint16 = ushort; +alias Sint32 = int; +alias Uint32 = uint; +alias Sint64 = long; +alias Uint64 = ulong; + +enum SDL_FOURCC(char A, char B, char C, char D) = ((A << 0) | (B << 8) | (C << 16) | (D << 24)); + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + void SDL_free(void* mem); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_free = void function(void* mem); + } + + __gshared { + pSDL_free SDL_free; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlsurface.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlsurface.d new file mode 100644 index 0000000..1b5cc5a --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlsurface.d @@ -0,0 +1,230 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlsurface; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlblendmode : SDL_BlendMode; +import bindbc.sdl.bind.sdlrect : SDL_Rect; +import bindbc.sdl.bind.sdlrwops; +import bindbc.sdl.bind.sdlpixels : SDL_Palette, SDL_PixelFormat; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +enum { + SDL_SWSURFACE = 0, + SDL_PREALLOC = 0x00000001, + SDL_RLEACCEL = 0x00000002, + SDL_DONTFREE = 0x00000004, +} + +@nogc nothrow pure +bool SDL_MUSTLOCK(const(SDL_Surface)* S) +{ + pragma(inline, true); + return (S.flags & SDL_RLEACCEL) != 0; +} + +struct SDL_BlitMap; +struct SDL_Surface { + int flags; + SDL_PixelFormat* format; + int w, h; + int pitch; + void* pixels; + void* userdata; + int locked; + void* lock_data; + SDL_Rect clip_rect; + SDL_BlitMap* map; + int refcount; +} + +extern(C) nothrow alias SDL_blit = int function(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect); + +@nogc nothrow { + SDL_Surface* SDL_LoadBMP(const(char)* file) { + pragma(inline, true); + return SDL_LoadBMP_RW(SDL_RWFromFile(file,"rb"),1); + } + + int SDL_SaveBMP(SDL_Surface* surface,const(char)* file) { + pragma(inline, true); + return SDL_SaveBMP_RW(surface,SDL_RWFromFile(file,"wb"),1); + } +} + +alias SDL_BlitSurface = SDL_UpperBlit; +alias SDL_BlitScaled = SDL_UpperBlitScaled; + +static if(sdlSupport >= SDLSupport.sdl208) { + enum SDL_YUV_CONVERSION_MODE { + SDL_YUV_CONVERSION_JPEG, + SDL_YUV_CONVERSION_BT601, + SDL_YUV_CONVERSION_BT709, + SDL_YUV_CONVERSION_AUTOMATIC, + } + mixin(expandEnum!SDL_YUV_CONVERSION_MODE); +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_Surface* SDL_CreateRGBSurface(uint,int,int,int,uint,uint,uint,uint); + SDL_Surface* SDL_CreateRGBSurfaceFrom(void*,int,int,int,int,uint,uint,uint,uint); + void SDL_FreeSurface(SDL_Surface*); + int SDL_SetSurfacePalette(SDL_Surface*,SDL_Palette*); + int SDL_LockSurface(SDL_Surface*); + int SDL_UnlockSurface(SDL_Surface*); + SDL_Surface* SDL_LoadBMP_RW(SDL_RWops*,int); + int SDL_SaveBMP_RW(SDL_Surface*,SDL_RWops*,int); + int SDL_SetSurfaceRLE(SDL_Surface*,int); + int SDL_SetColorKey(SDL_Surface*,int,uint); + int SDL_GetColorKey(SDL_Surface*,uint*); + int SDL_SetSurfaceColorMod(SDL_Surface*,ubyte,ubyte,ubyte); + int SDL_GetSurfaceColorMod(SDL_Surface*,ubyte*,ubyte*,ubyte*); + int SDL_SetSurfaceAlphaMod(SDL_Surface*,ubyte); + int SDL_GetSurfaceAlphaMod(SDL_Surface*,ubyte*); + int SDL_SetSurfaceBlendMode(SDL_Surface*,SDL_BlendMode); + int SDL_GetSurfaceBlendMode(SDL_Surface*,SDL_BlendMode*); + SDL_bool SDL_SetClipRect(SDL_Surface*,const(SDL_Rect)*); + void SDL_GetClipRect(SDL_Surface*,SDL_Rect*); + SDL_Surface* SDL_ConvertSurface(SDL_Surface*,const(SDL_PixelFormat)*,uint); + SDL_Surface* SDL_ConvertSurfaceFormat(SDL_Surface*,uint,uint); + int SDL_ConvertPixels(int,int,uint,const(void)*,int,uint,void*,int); + int SDL_FillRect(SDL_Surface*,const(SDL_Rect)*,uint); + int SDL_FillRects(SDL_Surface*,const(SDL_Rect)*,int,uint); + int SDL_UpperBlit(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); + int SDL_LowerBlit(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); + int SDL_SoftStretch(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,const(SDL_Rect)*); + int SDL_UpperBlitScaled(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); + int SDL_LowerBlitScaled(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); + + static if(sdlSupport >= SDLSupport.sdl205) { + SDL_Surface* SDL_CreateRGBSurfaceWithFormat(uint,int,int,int,uint); + SDL_Surface* SDL_CreateRGBSurfaceWithFormatFrom(void*,int,int,int,int,uint); + } + static if(sdlSupport >= SDLSupport.sdl205) { + SDL_Surface* SDL_DuplicateSurface(SDL_Surface*); + } + static if(sdlSupport >= SDLSupport.sdl208) { + void SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE); + SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionMode(); + SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionModeForResolution(int,int); + } + static if(sdlSupport >= SDLSupport.sdl209) { + SDL_bool SDL_HasColorKey(SDL_Surface*); + } + } +} +else { + extern(C) @nogc nothrow {alias pSDL_CreateRGBSurface = SDL_Surface* function(uint,int,int,int,uint,uint,uint,uint); + alias pSDL_CreateRGBSurfaceFrom = SDL_Surface* function(void*,int,int,int,int,uint,uint,uint,uint); + alias pSDL_FreeSurface = void function(SDL_Surface*); + alias pSDL_SetSurfacePalette = int function(SDL_Surface*,SDL_Palette*); + alias pSDL_LockSurface = int function(SDL_Surface*); + alias pSDL_UnlockSurface = int function(SDL_Surface*); + alias pSDL_LoadBMP_RW = SDL_Surface* function(SDL_RWops*,int); + alias pSDL_SaveBMP_RW = int function(SDL_Surface*,SDL_RWops*,int); + alias pSDL_SetSurfaceRLE = int function(SDL_Surface*,int); + alias pSDL_SetColorKey = int function(SDL_Surface*,int,uint); + alias pSDL_GetColorKey = int function(SDL_Surface*,uint*); + alias pSDL_SetSurfaceColorMod = int function(SDL_Surface*,ubyte,ubyte,ubyte); + alias pSDL_GetSurfaceColorMod = int function(SDL_Surface*,ubyte*,ubyte*,ubyte*); + alias pSDL_SetSurfaceAlphaMod = int function(SDL_Surface*,ubyte); + alias pSDL_GetSurfaceAlphaMod = int function(SDL_Surface*,ubyte*); + alias pSDL_SetSurfaceBlendMode = int function(SDL_Surface*,SDL_BlendMode); + alias pSDL_GetSurfaceBlendMode = int function(SDL_Surface*,SDL_BlendMode*); + alias pSDL_SetClipRect = SDL_bool function(SDL_Surface*,const(SDL_Rect)*); + alias pSDL_GetClipRect = void function(SDL_Surface*,SDL_Rect*); + alias pSDL_ConvertSurface = SDL_Surface* function(SDL_Surface*,const(SDL_PixelFormat)*,uint); + alias pSDL_ConvertSurfaceFormat = SDL_Surface* function(SDL_Surface*,uint,uint); + alias pSDL_ConvertPixels = int function(int,int,uint,const(void)*,int,uint,void*,int); + alias pSDL_FillRect = int function(SDL_Surface*,const(SDL_Rect)*,uint); + alias pSDL_FillRects = int function(SDL_Surface*,const(SDL_Rect)*,int,uint); + alias pSDL_UpperBlit = int function(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); + alias pSDL_LowerBlit = int function(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); + alias pSDL_SoftStretch = int function(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,const(SDL_Rect)*); + alias pSDL_UpperBlitScaled = int function(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); + alias pSDL_LowerBlitScaled = int function(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); + } + + __gshared { + pSDL_CreateRGBSurface SDL_CreateRGBSurface; + pSDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom; + pSDL_FreeSurface SDL_FreeSurface; + pSDL_SetSurfacePalette SDL_SetSurfacePalette; + pSDL_LockSurface SDL_LockSurface; + pSDL_UnlockSurface SDL_UnlockSurface; + pSDL_LoadBMP_RW SDL_LoadBMP_RW; + pSDL_SaveBMP_RW SDL_SaveBMP_RW; + pSDL_SetSurfaceRLE SDL_SetSurfaceRLE; + pSDL_SetColorKey SDL_SetColorKey; + pSDL_GetColorKey SDL_GetColorKey; + pSDL_SetSurfaceColorMod SDL_SetSurfaceColorMod; + pSDL_GetSurfaceColorMod SDL_GetSurfaceColorMod; + pSDL_SetSurfaceAlphaMod SDL_SetSurfaceAlphaMod; + pSDL_GetSurfaceAlphaMod SDL_GetSurfaceAlphaMod; + pSDL_SetSurfaceBlendMode SDL_SetSurfaceBlendMode; + pSDL_GetSurfaceBlendMode SDL_GetSurfaceBlendMode; + pSDL_SetClipRect SDL_SetClipRect; + pSDL_GetClipRect SDL_GetClipRect; + pSDL_ConvertSurface SDL_ConvertSurface; + pSDL_ConvertSurfaceFormat SDL_ConvertSurfaceFormat; + pSDL_ConvertPixels SDL_ConvertPixels; + pSDL_FillRect SDL_FillRect; + pSDL_FillRects SDL_FillRects; + pSDL_UpperBlit SDL_UpperBlit; + pSDL_LowerBlit SDL_LowerBlit; + pSDL_SoftStretch SDL_SoftStretch; + pSDL_UpperBlitScaled SDL_UpperBlitScaled; + pSDL_LowerBlitScaled SDL_LowerBlitScaled; + } + + static if(sdlSupport >= SDLSupport.sdl205) { + extern(C) @nogc nothrow { + alias pSDL_CreateRGBSurfaceWithFormat = SDL_Surface* function(uint,int,int,int,uint); + alias pSDL_CreateRGBSurfaceWithFormatFrom = SDL_Surface* function(void*,int,int,int,int,uint); + } + + __gshared { + pSDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat; + pSDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom; + } + } + + static if(sdlSupport >= SDLSupport.sdl205) { + extern(C) @nogc nothrow { + alias pSDL_DuplicateSurface = SDL_Surface* function(SDL_Surface*); + } + + __gshared { + pSDL_DuplicateSurface SDL_DuplicateSurface; + } + } + + static if(sdlSupport >= SDLSupport.sdl208) { + extern(C) @nogc nothrow { + alias pSDL_SetYUVConversionMode = void function(SDL_YUV_CONVERSION_MODE); + alias pSDL_GetYUVConversionMode = SDL_YUV_CONVERSION_MODE function(); + alias pSDL_GetYUVConversionModeForResolution = SDL_YUV_CONVERSION_MODE function(int,int); + } + + __gshared { + pSDL_SetYUVConversionMode SDL_SetYUVConversionMode; + pSDL_GetYUVConversionMode SDL_GetYUVConversionMode; + pSDL_GetYUVConversionModeForResolution SDL_GetYUVConversionModeForResolution; + } + } + + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_HasColorKey = SDL_bool function(SDL_Surface*); + } + + __gshared { + pSDL_HasColorKey SDL_HasColorKey; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlsystem.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlsystem.d new file mode 100644 index 0000000..39eb0b3 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlsystem.d @@ -0,0 +1,152 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlsystem; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlrender : SDL_Renderer; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +version(Android) { + enum int SDL_ANDROID_EXTERNAL_STORAGE_READ = 0x01; + enum int SDL_ANDROID_EXTERNAL_STORAGE_WRITE = 0x02; +} + +static if(sdlSupport >= SDLSupport.sdl201) { + version(Windows) struct IDirect3DDevice9; +} + +static if(sdlSupport >= SDLSupport.sdl204) { + version(Windows) { + extern(C) nothrow alias SDL_WindowsMessageHook = void function(void*,void*,uint,ulong,long); + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + version(Android) { + void* SDL_AndroidGetJNIEnv(); + void* SDL_AndroidGetActivity(); + const(char)* SDL_AndroidGetInternalStoragePath(); + int SDL_AndroidGetInternalStorageState(); + const(char)* SDL_AndroidGetExternalStoragePath(); + + static if(sdlSupport >= SDLSupport.sdl208) { + SDL_bool SDL_IsAndroidTV(); + } + static if(sdlSupport >= SDLSupport.sdl209) { + SDL_bool SDL_IsChromebook(); + SDL_bool SDL_IsDeXMode(); + void SDL_AndroidBackButton(); + } + } + else version(Windows) { + static if(sdlSupport >= SDLSupport.sdl201) { + int SDL_Direct3D9GetAdapterIndex(int); + IDirect3DDevice9* SDL_RenderGetD3D9Device(SDL_Renderer*); + } + static if(sdlSupport >= SDLSupport.sdl202) { + SDL_bool SDL_DXGIGetOutputInfo(int,int*,int*); + } + static if(sdlSupport >= SDLSupport.sdl204) { + void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook,void*); + } + } + else version(linux) { + static if(sdlSupport >= SDLSupport.sdl209) { + int SDL_LinuxSetThreadPriority(long,int); + } + } + } +} +else { + version(Android) { + extern(C) @nogc nothrow { + alias pSDL_AndroidGetJNIEnv = void* function(); + alias pSDL_AndroidGetActivity = void* function(); + alias pSDL_AndroidGetInternalStoragePath = const(char)* function(); + alias pSDL_AndroidGetInternalStorageState = int function(); + alias pSDL_AndroidGetExternalStoragePath = const(char)* function(); + } + + __gshared { + pSDL_AndroidGetJNIEnv SDL_AndroidGetJNIEnv; + pSDL_AndroidGetActivity SDL_AndroidGetActivity; + + pSDL_AndroidGetInternalStoragePath SDL_AndroidGetInternalStoragePath; + pSDL_AndroidGetInternalStorageState SDL_AndroidGetInternalStorageState; + pSDL_AndroidGetExternalStoragePath SDL_AndroidGetExternalStoragePath; + } + + static if(sdlSupport >= SDLSupport.sdl208) { + extern(C) @nogc nothrow { + alias pSDL_IsAndroidTV = SDL_bool function(); + } + + __gshared { + pSDL_IsAndroidTV SDL_IsAndroidTV; + } + } + + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_IsChromebook = SDL_bool function(); + alias pSDL_IsDeXMode = SDL_bool function(); + alias pSDL_AndroidBackButton = void function(); + } + + __gshared { + pSDL_IsChromebook SDL_IsChromebook; + pSDL_IsDeXMode SDL_IsDeXMode; + pSDL_AndroidBackButton SDL_AndroidBackButton; + } + } + } + else version(Windows) { + static if(sdlSupport >= SDLSupport.sdl201) { + extern(C) @nogc nothrow { + alias pSDL_Direct3D9GetAdapterIndex = int function(int); + alias pSDL_RenderGetD3D9Device = IDirect3DDevice9* function(SDL_Renderer*); + } + + __gshared { + pSDL_Direct3D9GetAdapterIndex SDL_Direct3D9GetAdapterIndex ; + pSDL_RenderGetD3D9Device SDL_RenderGetD3D9Device; + } + } + + static if(sdlSupport >= SDLSupport.sdl202) { + extern(C) @nogc nothrow { + alias pSDL_DXGIGetOutputInfo = SDL_bool function(int,int*,int*); + } + + __gshared { + pSDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo; + } + } + + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_SetWindowsMessageHook = void function(SDL_WindowsMessageHook,void*); + } + + __gshared { + pSDL_SetWindowsMessageHook SDL_SetWindowsMessageHook; + } + } + } + else version(linux) { + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_LinuxSetThreadPriority = int function(long,int); + } + + __gshared { + pSDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority; + } + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlsyswm.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlsyswm.d new file mode 100644 index 0000000..02951c8 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlsyswm.d @@ -0,0 +1,240 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlsyswm; + +//import core.stdc.config : c_long; +alias int c_long; +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlversion : SDL_version; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +static if(sdlSupport >= SDLSupport.sdl205) { + enum SDL_SYSWM_TYPE { + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE, + SDL_SYSWM_OS2, + } +} +else static if(sdlSupport >= SDLSupport.sdl205) { + enum SDL_SYSWM_TYPE { + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE, + } +} +else static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_SYSWM_TYPE { + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + } +} +else static if(sdlSupport >= SDLSupport.sdl203) { + enum SDL_SYSWM_TYPE { + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, + SDL_SYSWM_WINRT, + } +} +else static if(sdlSupport >= SDLSupport.sdl202) { + enum SDL_SYSWM_TYPE { + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, + } +} +else { + enum SDL_SYSWM_TYPE { + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + } +} +mixin(expandEnum!SDL_SYSWM_TYPE); + +version(Windows) { + // I don't want to import core.sys.windows.windows just for these + version(Win64) { + alias wparam = ulong; + alias lparam = long; + }else { + alias wparam = uint; + alias lparam = int; + } +} + +struct SDL_SysWMmsg { + SDL_version version_; + SDL_SYSWM_TYPE subsystem; + union msg_ { + version(Windows) { + struct win_ { + void* hwnd; + uint msg; + wparam wParam; + lparam lParam; + } + win_ win; + } + else version(OSX) { + struct cocoa_ { + int dummy; + } + cocoa_ cocoa; + } + else version(linux) { + struct dfb_ { + void* event; + } + dfb_ dfb; + } + + version(Posix) { + struct x11_ { + c_long[24] pad; // sufficient size for any X11 event + } + x11_ x11; + } + + static if(sdlSupport >= SDLSupport.sdl205) { + struct vivante_ { + int dummy; + } + vivante_ vivante; + } + + int dummy; + } + msg_ msg; +} + +struct SDL_SysWMinfo { + SDL_version version_; + SDL_SYSWM_TYPE subsystem; + + union info_ { + version(Windows) { + struct win_ { + void* window; + static if(sdlSupport >= SDLSupport.sdl204) void* hdc; + static if(sdlSupport >= SDLSupport.sdl206) void* hinstance; + } + win_ win; + } + else version(OSX) { + struct cocoa_ { + void* window; + } + cocoa_ cocoa; + + struct uikit_ { + void *window; + } + uikit_ uikit; + + } + else version(linux) { + struct dfb_ { + void *dfb; + void *window; + void *surface; + } + dfb_ dfb; + + static if(sdlSupport >= SDLSupport.sdl202) { + struct wl_ { + void *display; + void *surface; + void *shell_surface; + } + wl_ wl; + + struct mir_ { + void *connection; + void *surface; + } + mir_ mir; + } + } + + version(Posix) { + struct x11_ { + void* display; + uint window; + } + x11_ x11; + } + + static if(sdlSupport >= SDLSupport.sdl204) { + version(Android) { + struct android_ { + void* window; + void* surface; + } + android_ android; + } + } + + static if(sdlSupport >= SDLSupport.sdl206) ubyte[64] dummy; + else int dummy; + } + info_ info; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_bool SDL_GetWindowWMInfo(SDL_Window*,SDL_SysWMinfo*); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetWindowWMInfo = SDL_bool function(SDL_Window*,SDL_SysWMinfo*); + } + + __gshared { + pSDL_GetWindowWMInfo SDL_GetWindowWMInfo; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdltimer.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdltimer.d new file mode 100644 index 0000000..1661a41 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdltimer.d @@ -0,0 +1,51 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdltimer; + +import bindbc.sdl.bind.sdlstdinc : SDL_bool; + +extern(C) nothrow alias SDL_TimerCallback = uint function(uint interval, void* param); +alias SDL_TimerID = int; + +// This was added to SDL 2.0.1 as a macro, but it's +// useful & has no dependency on the library version, +// so it's here for 2.0.0 as well. +@nogc nothrow pure +bool SDL_TICKS_PASSED(uint A, uint B) { + pragma(inline, true); + return cast(int)(B - A) <= 0; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + uint SDL_GetTicks(); + ulong SDL_GetPerformanceCounter(); + ulong SDL_GetPerformanceFrequency(); + void SDL_Delay(uint); + SDL_TimerID SDL_AddTimer(uint,SDL_TimerCallback,void*); + SDL_bool SDL_RemoveTimer(SDL_TimerID); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetTicks = uint function(); + alias pSDL_GetPerformanceCounter = ulong function(); + alias pSDL_GetPerformanceFrequency = ulong function(); + alias pSDL_Delay = void function(uint); + alias pSDL_AddTimer = SDL_TimerID function(uint,SDL_TimerCallback,void*); + alias pSDL_RemoveTimer = SDL_bool function(SDL_TimerID); + } + + __gshared { + pSDL_GetTicks SDL_GetTicks; + pSDL_GetPerformanceCounter SDL_GetPerformanceCounter; + pSDL_GetPerformanceFrequency SDL_GetPerformanceFrequency; + pSDL_Delay SDL_Delay; + pSDL_AddTimer SDL_AddTimer; + pSDL_RemoveTimer SDL_RemoveTimer; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdltouch.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdltouch.d new file mode 100644 index 0000000..182e08f --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdltouch.d @@ -0,0 +1,67 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdltouch; + +import bindbc.sdl.config; + +alias SDL_TouchID = long; +alias SDL_FingerID = long; + +struct SDL_Finger { + SDL_FingerID id; + float x; + float y; + float pressure; +} + +enum DL_TOUCH_MOUSEID = cast(uint)-1; + +static if(sdlSupport >= SDLSupport.sdl2010) { + enum SDL_TouchDeviceType { + SDL_TOUCH_DEVICE_INVALID = -1, + SDL_TOUCH_DEVICE_DIRECT, + SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, + SDL_TOUCH_DEVICE_INDIRECT_RELATIVE, + } + mixin(expandEnum!SDL_TouchDeviceType); + + enum SDL_MOUSE_TOUCHID = -1L; +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_GetNumTouchDevices(); + SDL_TouchID SDL_GetTouchDevice(int); + int SDL_GetNumTouchFingers(SDL_TouchID); + SDL_Finger* SDL_GetTouchFinger(SDL_TouchID,int); + } + static if(sdlSupport >= SDLSupport.sdl2010) { + SDL_TouchDeviceType SDL_GetTouchDeviceType(SDL_TouchID); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetNumTouchDevices = int function(); + alias pSDL_GetTouchDevice = SDL_TouchID function(int); + alias pSDL_GetNumTouchFingers = int function(SDL_TouchID); + alias pSDL_GetTouchFinger = SDL_Finger* function(SDL_TouchID,int); + } + __gshared { + pSDL_GetNumTouchDevices SDL_GetNumTouchDevices; + pSDL_GetTouchDevice SDL_GetTouchDevice; + pSDL_GetNumTouchFingers SDL_GetNumTouchFingers; + pSDL_GetTouchFinger SDL_GetTouchFinger; + } + static if(sdlSupport >= SDLSupport.sdl2010) { + extern(C) @nogc nothrow { + alias pSDL_GetTouchDeviceType = SDL_TouchDeviceType function(SDL_TouchID); + } + __gshared { + pSDL_GetTouchDeviceType SDL_GetTouchDeviceType; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlversion.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlversion.d new file mode 100644 index 0000000..dd05628 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlversion.d @@ -0,0 +1,83 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlversion; + +struct SDL_version { + ubyte major; + ubyte minor; + ubyte patch; +} + +enum SDL_MAJOR_VERSION = 2; +enum SDL_MINOR_VERSION = 0; + +version(SDL_201) { + enum ubyte SDL_PATCHLEVEL = 1; +} +else version(SDL_202) { + enum ubyte SDL_PATCHLEVEL = 2; +} +else version(SDL_203) { + enum ubyte SDL_PATCHLEVEL = 3; +} +else version(SDL_204) { + enum ubyte SDL_PATCHLEVEL = 4; +} +else version(SDL_205) { + enum ubyte SDL_PATCHLEVEL = 5; +} +else version(SDL_206) { + enum ubyte SDL_PATCHLEVEL = 6; +} +else version(SDL_207) { + enum ubyte SDL_PATCHLEVEL = 7; +} +else version(SDL_208) { + enum ubyte SDL_PATCHLEVEL = 8; +} +else version(SDL_209) { + enum ubyte SDL_PATCHLEVEL = 9; +} +else version(SDL_2010) { + enum ubyte SDL_PATCHLEVEL = 10; +} +else { + enum ubyte SDL_PATCHLEVEL = 0; +} + +@nogc nothrow pure +void SDL_VERSION(SDL_version* x) { + pragma(inline, true); + x.major = SDL_MAJOR_VERSION; + x.minor = SDL_MINOR_VERSION; + x.patch = SDL_PATCHLEVEL; +} + +enum SDL_VERSIONNUM(ubyte X, ubyte Y, ubyte Z) = X*1000 + Y*100 + Z; +enum SDL_COMPILEDVERSION = SDL_VERSIONNUM!(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); +enum SDL_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z) = SDL_COMPILEDVERSION >= SDL_VERSIONNUM!(X, Y, Z); + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + void SDL_GetVersion(SDL_version*); + const(char)* SDL_GetRevision(); + int SDL_GetRevisionNumber(); + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetVersion = void function(SDL_version*); + alias pSDL_GetRevision = const(char)* function(); + alias pSDL_GetRevisionNumber = int function(); + } + + __gshared { + pSDL_GetVersion SDL_GetVersion; + pSDL_GetRevision SDL_GetRevision; + pSDL_GetRevisionNumber SDL_GetRevisionNumber; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlvideo.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlvideo.d new file mode 100644 index 0000000..3384d8e --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlvideo.d @@ -0,0 +1,677 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlvideo; + +import bindbc.sdl.config; + +import bindbc.sdl.bind.sdlrect : SDL_Rect; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlsurface : SDL_Surface; + +struct SDL_DisplayMode { + uint format; + int w; + int h; + int refresh_rate; + void* driverdata; +} + +struct SDL_Window; + +static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_WindowFlags { + SDL_WINDOW_FULLSCREEN = 0x00000001, + SDL_WINDOW_OPENGL = 0x00000002, + SDL_WINDOW_SHOWN = 0x00000004, + SDL_WINDOW_HIDDEN = 0x00000008, + SDL_WINDOW_BORDERLESS = 0x00000010, + SDL_WINDOW_RESIZABLE = 0x00000020, + SDL_WINDOW_MINIMIZED = 0x00000040, + SDL_WINDOW_MAXIMIZED = 0x00000080, + SDL_WINDOW_INPUT_GRABBED = 0x00000100, + SDL_WINDOW_INPUT_FOCUS = 0x00000200, + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, + SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN | 0x00001000, + SDL_WINDOW_FOREIGN = 0x00000800, + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, + SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, + SDL_WINDOW_SKIP_TASKBAR = 0x00010000, + SDL_WINDOW_UTILITY = 0x00020000, + SDL_WINDOW_TOOLTIP = 0x00040000, + SDL_WINDOW_POPUP_MENU = 0x00080000, + SDL_WINDOW_VULKAN = 0x10000000, + } +} +else static if(sdlSupport >= SDLSupport.sdl205) { + enum SDL_WindowFlags { + SDL_WINDOW_FULLSCREEN = 0x00000001, + SDL_WINDOW_OPENGL = 0x00000002, + SDL_WINDOW_SHOWN = 0x00000004, + SDL_WINDOW_HIDDEN = 0x00000008, + SDL_WINDOW_BORDERLESS = 0x00000010, + SDL_WINDOW_RESIZABLE = 0x00000020, + SDL_WINDOW_MINIMIZED = 0x00000040, + SDL_WINDOW_MAXIMIZED = 0x00000080, + SDL_WINDOW_INPUT_GRABBED = 0x00000100, + SDL_WINDOW_INPUT_FOCUS = 0x00000200, + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, + SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN | 0x00001000, + SDL_WINDOW_FOREIGN = 0x00000800, + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, + SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, + SDL_WINDOW_SKIP_TASKBAR = 0x00010000, + SDL_WINDOW_UTILITY = 0x00020000, + SDL_WINDOW_TOOLTIP = 0x00040000, + SDL_WINDOW_POPUP_MENU = 0x00080000, + } +} +else static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_WindowFlags { + SDL_WINDOW_FULLSCREEN = 0x00000001, + SDL_WINDOW_OPENGL = 0x00000002, + SDL_WINDOW_SHOWN = 0x00000004, + SDL_WINDOW_HIDDEN = 0x00000008, + SDL_WINDOW_BORDERLESS = 0x00000010, + SDL_WINDOW_RESIZABLE = 0x00000020, + SDL_WINDOW_MINIMIZED = 0x00000040, + SDL_WINDOW_MAXIMIZED = 0x00000080, + SDL_WINDOW_INPUT_GRABBED = 0x00000100, + SDL_WINDOW_INPUT_FOCUS = 0x00000200, + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, + SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN | 0x00001000, + SDL_WINDOW_FOREIGN = 0x00000800, + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, + } +} +else static if(sdlSupport >= SDLSupport.sdl201) { + enum SDL_WindowFlags { + SDL_WINDOW_FULLSCREEN = 0x00000001, + SDL_WINDOW_OPENGL = 0x00000002, + SDL_WINDOW_SHOWN = 0x00000004, + SDL_WINDOW_HIDDEN = 0x00000008, + SDL_WINDOW_BORDERLESS = 0x00000010, + SDL_WINDOW_RESIZABLE = 0x00000020, + SDL_WINDOW_MINIMIZED = 0x00000040, + SDL_WINDOW_MAXIMIZED = 0x00000080, + SDL_WINDOW_INPUT_GRABBED = 0x00000100, + SDL_WINDOW_INPUT_FOCUS = 0x00000200, + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, + SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN | 0x00001000, + SDL_WINDOW_FOREIGN = 0x00000800, + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, + } +} +else { + enum SDL_WindowFlags { + SDL_WINDOW_FULLSCREEN = 0x00000001, + SDL_WINDOW_OPENGL = 0x00000002, + SDL_WINDOW_SHOWN = 0x00000004, + SDL_WINDOW_HIDDEN = 0x00000008, + SDL_WINDOW_BORDERLESS = 0x00000010, + SDL_WINDOW_RESIZABLE = 0x00000020, + SDL_WINDOW_MINIMIZED = 0x00000040, + SDL_WINDOW_MAXIMIZED = 0x00000080, + SDL_WINDOW_INPUT_GRABBED = 0x00000100, + SDL_WINDOW_INPUT_FOCUS = 0x00000200, + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, + SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN | 0x00001000, + SDL_WINDOW_FOREIGN = 0x00000800, + } +} +mixin(expandEnum!SDL_WindowFlags); + +enum uint SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000; +enum uint SDL_WINDOWPOS_UNDEFINED_DISPLAY(uint x) = SDL_WINDOWPOS_UNDEFINED_MASK | x; +enum uint SDL_WINDOWPOS_UNDEFINED = SDL_WINDOWPOS_UNDEFINED_DISPLAY!(0); +enum uint SDL_WINDOWPOS_ISUNDEFINED(uint x) = (x & 0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK; + +enum uint SDL_WINDOWPOS_CENTERED_MASK = 0x2FFF0000; +enum uint SDL_WINDOWPOS_CENTERED_DISPLAY(uint x) = SDL_WINDOWPOS_CENTERED_MASK | x; +enum uint SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED_DISPLAY!(0); +enum uint SDL_WINDOWPOS_ISCENTERED(uint x) = (x & 0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK; + +static if(sdlSupport >= SDLSupport.sdl205) { + enum SDL_WindowEventID : ubyte { + SDL_WINDOWEVENT_NONE, + SDL_WINDOWEVENT_SHOWN, + SDL_WINDOWEVENT_HIDDEN, + SDL_WINDOWEVENT_EXPOSED, + SDL_WINDOWEVENT_MOVED, + SDL_WINDOWEVENT_RESIZED, + SDL_WINDOWEVENT_SIZE_CHANGED, + SDL_WINDOWEVENT_MINIMIZED, + SDL_WINDOWEVENT_MAXIMIZED, + SDL_WINDOWEVENT_RESTORED, + SDL_WINDOWEVENT_ENTER, + SDL_WINDOWEVENT_LEAVE, + SDL_WINDOWEVENT_FOCUS_GAINED, + SDL_WINDOWEVENT_FOCUS_LOST, + SDL_WINDOWEVENT_CLOSE, + SDL_WINDOWEVENT_TAKE_FOCUS, + SDL_WINDOWEVENT_HIT_TEST, + } + +} +else { + enum SDL_WindowEventID : ubyte { + SDL_WINDOWEVENT_NONE, + SDL_WINDOWEVENT_SHOWN, + SDL_WINDOWEVENT_HIDDEN, + SDL_WINDOWEVENT_EXPOSED, + SDL_WINDOWEVENT_MOVED, + SDL_WINDOWEVENT_RESIZED, + SDL_WINDOWEVENT_SIZE_CHANGED, + SDL_WINDOWEVENT_MINIMIZED, + SDL_WINDOWEVENT_MAXIMIZED, + SDL_WINDOWEVENT_RESTORED, + SDL_WINDOWEVENT_ENTER, + SDL_WINDOWEVENT_LEAVE, + SDL_WINDOWEVENT_FOCUS_GAINED, + SDL_WINDOWEVENT_FOCUS_LOST, + SDL_WINDOWEVENT_CLOSE, + } +} +mixin(expandEnum!SDL_WindowEventID); + +static if(sdlSupport >= SDLSupport.sdl209) { + enum SDL_DisplayEventID { + SDL_DISPLAYEVENT_NONE, + SDL_DISPLAYEVENT_ORIENTATION, + } + mixin(expandEnum!SDL_DisplayEventID); + + enum SDL_DisplayOrientation { + SDL_ORIENTATION_UNKNOWN, + SDL_ORIENTATION_LANDSCAPE, + SDL_ORIENTATION_LANDSCAPE_FLIPPED, + SDL_ORIENTATION_PORTRAIT, + SDL_ORIENTATION_PORTRAIT_FLIPPED, + } + mixin(expandEnum!SDL_DisplayOrientation); +} + +alias SDL_GLContext = void*; + +static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_GLattr { + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_RELEASE_BEHAVIOR, + SDL_GL_CONTEXT_RESET_NOTIFICATION, + SDL_GL_CONTEXT_NO_ERROR, + } +} +else static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_GLattr { + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_RELEASE_BEHAVIOR, + } +} +else static if(sdlSupport >= SDLSupport.sdl201) { + enum SDL_GLattr { + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + } +} +else { + enum SDL_GLattr { + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + } +} +mixin(expandEnum!SDL_GLattr); + +enum SDL_GLprofile { + SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, + SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + SDL_GL_CONTEXT_PROFILE_ES = 0x0004, +} +mixin(expandEnum!SDL_GLprofile); + +enum SDL_GLcontextFlag { + SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008, +} +mixin(expandEnum!SDL_GLcontextFlag); + +static if(sdlSupport >= SDLSupport.sdl204) { + enum SDL_GLcontextReleaseFlag { + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001, + } + mixin(expandEnum!SDL_GLcontextReleaseFlag); + + enum SDL_HitTestResult { + SDL_HITTEST_NORMAL, + SDL_HITTEST_DRAGGABLE, + SDL_HITTEST_RESIZE_TOPLEFT, + SDL_HITTEST_RESIZE_TOP, + SDL_HITTEST_RESIZE_TOPRIGHT, + SDL_HITTEST_RESIZE_RIGHT, + SDL_HITTEST_RESIZE_BOTTOMRIGHT, + SDL_HITTEST_RESIZE_BOTTOM, + SDL_HITTEST_RESIZE_BOTTOMLEFT, + SDL_HITTEST_RESIZE_LEFT, + } + mixin(expandEnum!SDL_HitTestResult); + + import bindbc.sdl.bind.sdlrect : SDL_Point; + extern(C) nothrow alias SDL_HitTest = SDL_HitTestResult function(SDL_Window*,const(SDL_Point)*,void*); +} + + static if(sdlSupport >= SDLSupport.sdl206) { + enum SDL_GLContextResetNotification { + SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, + SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001, + } + mixin(expandEnum!SDL_GLContextResetNotification); +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int SDL_GetNumVideoDrivers(); + const(char)* SDL_GetVideoDriver(int); + int SDL_VideoInit(const(char)*); + void SDL_VideoQuit(); + const(char)* SDL_GetCurrentVideoDriver(); + int SDL_GetNumVideoDisplays(); + const(char)* SDL_GetDisplayName(int); + int SDL_GetDisplayBounds(int,SDL_Rect*); + int SDL_GetNumDisplayModes(int); + int SDL_GetDisplayMode(int,int,SDL_DisplayMode*); + int SDL_GetDesktopDisplayMode(int,SDL_DisplayMode*); + int SDL_GetCurrentDisplayMode(int,SDL_DisplayMode*); + SDL_DisplayMode* SDL_GetClosestDisplayMode(int,const(SDL_DisplayMode)*,SDL_DisplayMode*); + int SDL_GetWindowDisplayIndex(SDL_Window*); + int SDL_SetWindowDisplayMode(SDL_Window*,const(SDL_DisplayMode)*); + int SDL_GetWindowDisplayMode(SDL_Window*,SDL_DisplayMode*); + uint SDL_GetWindowPixelFormat(SDL_Window*); + SDL_Window* SDL_CreateWindow(const(char)*,int,int,int,int,SDL_WindowFlags); + SDL_Window* SDL_CreateWindowFrom(const(void)*); + uint SDL_GetWindowID(SDL_Window*); + SDL_Window* SDL_GetWindowFromID(uint); + SDL_WindowFlags SDL_GetWindowFlags(SDL_Window*); + void SDL_SetWindowTitle(SDL_Window*,const(char)*); + const(char)* SDL_GetWindowTitle(SDL_Window*); + void SDL_SetWindowIcon(SDL_Window*,SDL_Surface*); + void* SDL_SetWindowData(SDL_Window*,const(char)*,void*); + void* SDL_GetWindowData(SDL_Window*,const(char)*); + void SDL_SetWindowPosition(SDL_Window*,int,int); + void SDL_GetWindowPosition(SDL_Window*,int*,int*); + void SDL_SetWindowSize(SDL_Window*,int,int); + void SDL_GetWindowSize(SDL_Window*,int*,int*); + void SDL_SetWindowMinimumSize(SDL_Window*,int,int); + void SDL_GetWindowMinimumSize(SDL_Window*,int*,int*); + void SDL_SetWindowMaximumSize(SDL_Window*,int,int); + void SDL_GetWindowMaximumSize(SDL_Window*,int*,int*); + void SDL_SetWindowBordered(SDL_Window*,SDL_bool); + void SDL_ShowWindow(SDL_Window*); + void SDL_HideWindow(SDL_Window*); + void SDL_RaiseWindow(SDL_Window*); + void SDL_MaximizeWindow(SDL_Window*); + void SDL_MinimizeWindow(SDL_Window*); + void SDL_RestoreWindow(SDL_Window*); + int SDL_SetWindowFullscreen(SDL_Window*,uint); + SDL_Surface* SDL_GetWindowSurface(SDL_Window*); + int SDL_UpdateWindowSurface(SDL_Window*); + int SDL_UpdateWindowSurfaceRects(SDL_Window*,SDL_Rect*,int); + void SDL_SetWindowGrab(SDL_Window*,SDL_bool); + SDL_bool SDL_GetWindowGrab(SDL_Window*); + int SDL_SetWindowBrightness(SDL_Window*,float); + float SDL_GetWindowBrightness(SDL_Window*); + int SDL_SetWindowGammaRamp(SDL_Window*,const(ushort)*,const(ushort)*,const(ushort)*); + int SDL_GetWindowGammaRamp(SDL_Window*,ushort*,ushort*,ushort*); + void SDL_DestroyWindow(SDL_Window*); + SDL_bool SDL_IsScreenSaverEnabled(); + void SDL_EnableScreenSaver(); + void SDL_DisableScreenSaver(); + int SDL_GL_LoadLibrary(const(char)*); + void* SDL_GL_GetProcAddress(const(char)*); + void SDL_GL_UnloadLibrary(); + SDL_bool SDL_GL_ExtensionSupported(const(char)*); + int SDL_GL_SetAttribute(SDL_GLattr,int); + int SDL_GL_GetAttribute(SDL_GLattr,int*); + SDL_GLContext SDL_GL_CreateContext(SDL_Window*); + int SDL_GL_MakeCurrent(SDL_Window*,SDL_GLContext); + SDL_Window* SDL_GL_GetCurrentWindow(); + SDL_GLContext SDL_GL_GetCurrentContext(); + int SDL_GL_SetSwapInterval(int); + int SDL_GL_GetSwapInterval(); + void SDL_GL_SwapWindow(SDL_Window*); + void SDL_GL_DeleteContext(SDL_GLContext); + + static if(sdlSupport >= SDLSupport.sdl201) { + void SDL_GL_GetDrawableSize(SDL_Window*,int*,int*); + } + static if(sdlSupport >= SDLSupport.sdl202) { + void SDL_GL_ResetAttributes(); + } + static if(sdlSupport >= SDLSupport.sdl204) { + int SDL_GetDisplayDPI(int,float*,float*,float*); + SDL_Window* SDL_GetGrabbedWindow(); + int SDL_SetWindowHitTest(SDL_Window*,SDL_HitTest,void*); + } + static if(sdlSupport >= SDLSupport.sdl205) { + int SDL_GetDisplayUsableBounds(int,SDL_Rect*); + int SDL_GetWindowBordersSize(SDL_Window*,int*,int*,int*,int*); + int SDL_GetWindowOpacity(SDL_Window*,float*); + int SDL_SetWindowInputFocus(SDL_Window*); + int SDL_SetWindowModalFor(SDL_Window*,SDL_Window*); + int SDL_SetWindowOpacity(SDL_Window*,float); + void SDL_SetWindowResizable(SDL_Window*,SDL_bool); + } + static if(sdlSupport >= SDLSupport.sdl209) { + SDL_DisplayOrientation SDL_GetDisplayOrientation(int); + } + } +} +else { + extern(C) @nogc nothrow { + alias pSDL_GetNumVideoDrivers = int function(); + alias pSDL_GetVideoDriver = const(char)* function(int); + alias pSDL_VideoInit = int function(const(char)*); + alias pSDL_VideoQuit = void function(); + alias pSDL_GetCurrentVideoDriver = const(char)* function(); + alias pSDL_GetNumVideoDisplays = int function(); + alias pSDL_GetDisplayName = const(char)* function(int); + alias pSDL_GetDisplayBounds = int function(int,SDL_Rect*); + alias pSDL_GetNumDisplayModes = int function(int); + alias pSDL_GetDisplayMode = int function(int,int,SDL_DisplayMode*); + alias pSDL_GetDesktopDisplayMode = int function(int,SDL_DisplayMode*); + alias pSDL_GetCurrentDisplayMode = int function(int,SDL_DisplayMode*); + alias pSDL_GetClosestDisplayMode = SDL_DisplayMode* function(int,const(SDL_DisplayMode)*,SDL_DisplayMode*); + alias pSDL_GetWindowDisplayIndex = int function(SDL_Window*); + alias pSDL_SetWindowDisplayMode = int function(SDL_Window*,const(SDL_DisplayMode)*); + alias pSDL_GetWindowDisplayMode = int function(SDL_Window*,SDL_DisplayMode*); + alias pSDL_GetWindowPixelFormat = uint function(SDL_Window*); + alias pSDL_CreateWindow = SDL_Window* function(const(char)*,int,int,int,int,SDL_WindowFlags); + alias pSDL_CreateWindowFrom = SDL_Window* function(const(void)*); + alias pSDL_GetWindowID = uint function(SDL_Window*); + alias pSDL_GetWindowFromID = SDL_Window* function(uint); + alias pSDL_GetWindowFlags = SDL_WindowFlags function(SDL_Window*); + alias pSDL_SetWindowTitle = void function(SDL_Window*,const(char)*); + alias pSDL_GetWindowTitle = const(char)* function(SDL_Window*); + alias pSDL_SetWindowIcon = void function(SDL_Window*,SDL_Surface*); + alias pSDL_SetWindowData = void* function(SDL_Window*,const(char)*,void*); + alias pSDL_GetWindowData = void* function(SDL_Window*,const(char)*); + alias pSDL_SetWindowPosition = void function(SDL_Window*,int,int); + alias pSDL_GetWindowPosition = void function(SDL_Window*,int*,int*); + alias pSDL_SetWindowSize = void function(SDL_Window*,int,int); + alias pSDL_GetWindowSize = void function(SDL_Window*,int*,int*); + alias pSDL_SetWindowMinimumSize = void function(SDL_Window*,int,int); + alias pSDL_GetWindowMinimumSize = void function(SDL_Window*,int*,int*); + alias pSDL_SetWindowMaximumSize = void function(SDL_Window*,int,int); + alias pSDL_GetWindowMaximumSize = void function(SDL_Window*,int*,int*); + alias pSDL_SetWindowBordered = void function(SDL_Window*,SDL_bool); + alias pSDL_ShowWindow = void function(SDL_Window*); + alias pSDL_HideWindow = void function(SDL_Window*); + alias pSDL_RaiseWindow = void function(SDL_Window*); + alias pSDL_MaximizeWindow = void function(SDL_Window*); + alias pSDL_MinimizeWindow = void function(SDL_Window*); + alias pSDL_RestoreWindow = void function(SDL_Window*); + alias pSDL_SetWindowFullscreen = int function(SDL_Window*,uint); + alias pSDL_GetWindowSurface = SDL_Surface* function(SDL_Window*); + alias pSDL_UpdateWindowSurface = int function(SDL_Window*); + alias pSDL_UpdateWindowSurfaceRects = int function(SDL_Window*,SDL_Rect*,int); + alias pSDL_SetWindowGrab = void function(SDL_Window*,SDL_bool); + alias pSDL_GetWindowGrab = SDL_bool function(SDL_Window*); + alias pSDL_SetWindowBrightness = int function(SDL_Window*,float); + alias pSDL_GetWindowBrightness = float function(SDL_Window*); + alias pSDL_SetWindowGammaRamp = int function(SDL_Window*,const(ushort)*,const(ushort)*,const(ushort)*); + alias pSDL_GetWindowGammaRamp = int function(SDL_Window*,ushort*,ushort*,ushort*); + alias pSDL_DestroyWindow = void function(SDL_Window*); + alias pSDL_IsScreenSaverEnabled = SDL_bool function(); + alias pSDL_EnableScreenSaver = void function(); + alias pSDL_DisableScreenSaver = void function(); + alias pSDL_GL_LoadLibrary = int function(const(char)*); + alias pSDL_GL_GetProcAddress = void* function(const(char)*); + alias pSDL_GL_UnloadLibrary = void function(); + alias pSDL_GL_ExtensionSupported = SDL_bool function(const(char)*); + alias pSDL_GL_SetAttribute = int function(SDL_GLattr,int); + alias pSDL_GL_GetAttribute = int function(SDL_GLattr,int*); + alias pSDL_GL_CreateContext = SDL_GLContext function(SDL_Window*); + alias pSDL_GL_MakeCurrent = int function(SDL_Window*,SDL_GLContext); + alias pSDL_GL_GetCurrentWindow = SDL_Window* function(); + alias pSDL_GL_GetCurrentContext = SDL_GLContext function(); + alias pSDL_GL_SetSwapInterval = int function(int); + alias pSDL_GL_GetSwapInterval = int function(); + alias pSDL_GL_SwapWindow = void function(SDL_Window*); + alias pSDL_GL_DeleteContext = void function(SDL_GLContext); + } + + __gshared { + pSDL_GetNumVideoDrivers SDL_GetNumVideoDrivers; + pSDL_GetVideoDriver SDL_GetVideoDriver; + pSDL_VideoInit SDL_VideoInit; + pSDL_VideoQuit SDL_VideoQuit; + pSDL_GetCurrentVideoDriver SDL_GetCurrentVideoDriver; + pSDL_GetNumVideoDisplays SDL_GetNumVideoDisplays; + pSDL_GetDisplayName SDL_GetDisplayName; + pSDL_GetDisplayBounds SDL_GetDisplayBounds; + pSDL_GetNumDisplayModes SDL_GetNumDisplayModes; + pSDL_GetDisplayMode SDL_GetDisplayMode; + pSDL_GetDesktopDisplayMode SDL_GetDesktopDisplayMode; + pSDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode; + pSDL_GetClosestDisplayMode SDL_GetClosestDisplayMode; + pSDL_GetWindowDisplayIndex SDL_GetWindowDisplayIndex; + pSDL_SetWindowDisplayMode SDL_SetWindowDisplayMode; + pSDL_GetWindowDisplayMode SDL_GetWindowDisplayMode; + pSDL_GetWindowPixelFormat SDL_GetWindowPixelFormat; + pSDL_CreateWindow SDL_CreateWindow; + pSDL_CreateWindowFrom SDL_CreateWindowFrom; + pSDL_GetWindowID SDL_GetWindowID; + pSDL_GetWindowFromID SDL_GetWindowFromID; + pSDL_GetWindowFlags SDL_GetWindowFlags; + pSDL_SetWindowTitle SDL_SetWindowTitle; + pSDL_GetWindowTitle SDL_GetWindowTitle; + pSDL_SetWindowIcon SDL_SetWindowIcon; + pSDL_SetWindowData SDL_SetWindowData; + pSDL_GetWindowData SDL_GetWindowData; + pSDL_SetWindowPosition SDL_SetWindowPosition; + pSDL_GetWindowPosition SDL_GetWindowPosition; + pSDL_SetWindowSize SDL_SetWindowSize; + pSDL_GetWindowSize SDL_GetWindowSize; + pSDL_SetWindowMinimumSize SDL_SetWindowMinimumSize; + pSDL_GetWindowMinimumSize SDL_GetWindowMinimumSize; + pSDL_SetWindowMaximumSize SDL_SetWindowMaximumSize; + pSDL_GetWindowMaximumSize SDL_GetWindowMaximumSize; + pSDL_SetWindowBordered SDL_SetWindowBordered; + pSDL_ShowWindow SDL_ShowWindow; + pSDL_HideWindow SDL_HideWindow; + pSDL_RaiseWindow SDL_RaiseWindow; + pSDL_MaximizeWindow SDL_MaximizeWindow; + pSDL_MinimizeWindow SDL_MinimizeWindow; + pSDL_RestoreWindow SDL_RestoreWindow; + pSDL_SetWindowFullscreen SDL_SetWindowFullscreen; + pSDL_GetWindowSurface SDL_GetWindowSurface; + pSDL_UpdateWindowSurface SDL_UpdateWindowSurface; + pSDL_UpdateWindowSurfaceRects SDL_UpdateWindowSurfaceRects; + pSDL_SetWindowGrab SDL_SetWindowGrab; + pSDL_GetWindowGrab SDL_GetWindowGrab; + pSDL_SetWindowBrightness SDL_SetWindowBrightness; + pSDL_GetWindowBrightness SDL_GetWindowBrightness; + pSDL_SetWindowGammaRamp SDL_SetWindowGammaRamp; + pSDL_GetWindowGammaRamp SDL_GetWindowGammaRamp; + pSDL_DestroyWindow SDL_DestroyWindow; + pSDL_IsScreenSaverEnabled SDL_IsScreenSaverEnabled; + pSDL_EnableScreenSaver SDL_EnableScreenSaver; + pSDL_DisableScreenSaver SDL_DisableScreenSaver; + pSDL_GL_LoadLibrary SDL_GL_LoadLibrary; + pSDL_GL_GetProcAddress SDL_GL_GetProcAddress; + pSDL_GL_UnloadLibrary SDL_GL_UnloadLibrary; + pSDL_GL_ExtensionSupported SDL_GL_ExtensionSupported; + pSDL_GL_SetAttribute SDL_GL_SetAttribute; + pSDL_GL_GetAttribute SDL_GL_GetAttribute; + pSDL_GL_CreateContext SDL_GL_CreateContext; + pSDL_GL_MakeCurrent SDL_GL_MakeCurrent; + pSDL_GL_GetCurrentWindow SDL_GL_GetCurrentWindow; + pSDL_GL_GetCurrentContext SDL_GL_GetCurrentContext; + pSDL_GL_SetSwapInterval SDL_GL_SetSwapInterval; + pSDL_GL_GetSwapInterval SDL_GL_GetSwapInterval; + pSDL_GL_SwapWindow SDL_GL_SwapWindow; + pSDL_GL_DeleteContext SDL_GL_DeleteContext; + } + + static if(sdlSupport >= SDLSupport.sdl201) { + extern(C) @nogc nothrow { + alias pSDL_GL_GetDrawableSize = void function(SDL_Window*,int*,int*); + } + + __gshared { + pSDL_GL_GetDrawableSize SDL_GL_GetDrawableSize; + } + } + + static if(sdlSupport >= SDLSupport.sdl202) { + extern(C) @nogc nothrow { + alias pSDL_GL_ResetAttributes = void function(); + } + + __gshared { + pSDL_GL_ResetAttributes SDL_GL_ResetAttributes; + } + } + + static if(sdlSupport >= SDLSupport.sdl204) { + extern(C) @nogc nothrow { + alias pSDL_GetDisplayDPI = int function(int,float*,float*,float*); + alias pSDL_GetGrabbedWindow = SDL_Window* function(); + alias pSDL_SetWindowHitTest = int function(SDL_Window*,SDL_HitTest,void*); + } + + __gshared { + pSDL_GetDisplayDPI SDL_GetDisplayDPI; + pSDL_GetGrabbedWindow SDL_GetGrabbedWindow; + pSDL_SetWindowHitTest SDL_SetWindowHitTest; + } + } + + static if(sdlSupport >= SDLSupport.sdl205) { + extern(C) @nogc nothrow { + alias pSDL_GetDisplayUsableBounds = int function(int,SDL_Rect*); + alias pSDL_GetWindowBordersSize = int function(SDL_Window*,int*,int*,int*,int*); + alias pSDL_GetWindowOpacity = int function(SDL_Window*,float*); + alias pSDL_SetWindowInputFocus = int function(SDL_Window*); + alias pSDL_SetWindowModalFor = int function(SDL_Window*,SDL_Window*); + alias pSDL_SetWindowOpacity = int function(SDL_Window*,float); + alias pSDL_SetWindowResizable = void function(SDL_Window*,SDL_bool); + } + + __gshared { + pSDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds; + pSDL_GetWindowBordersSize SDL_GetWindowBordersSize; + pSDL_GetWindowOpacity SDL_GetWindowOpacity; + pSDL_SetWindowInputFocus SDL_SetWindowInputFocus; + pSDL_SetWindowModalFor SDL_SetWindowModalFor; + pSDL_SetWindowOpacity SDL_SetWindowOpacity; + pSDL_SetWindowResizable SDL_SetWindowResizable; + } + } + + static if(sdlSupport >= SDLSupport.sdl209) { + extern(C) @nogc nothrow { + alias pSDL_GetDisplayOrientation = SDL_DisplayOrientation function(int); + } + + __gshared { + pSDL_GetDisplayOrientation SDL_GetDisplayOrientation; + } + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdlvulkan.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdlvulkan.d new file mode 100644 index 0000000..0dc287d --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdlvulkan.d @@ -0,0 +1,45 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.bind.sdlvulkan; + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlvideo : SDL_Window; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + static if(sdlSupport >= SDLSupport.sdl206) { + SDL_bool SDL_Vulkan_CreateSurface(SDL_Window*,void*,void*); + void SDL_Vulkan_GetDrawableSize(SDL_Window*,int*,int*); + SDL_bool SDL_Vulkan_GetInstanceExtensions(SDL_Window*,uint*,const(char)**); + void* SDL_Vulkan_GetVkGetInstanceProcAddr(); + int SDL_Vulkan_LoadLibrary(const(char)*); + void SDL_Vulkan_UnloadLibrary(); + } + } +} +else { + static if(sdlSupport >= SDLSupport.sdl206) { + extern(C) @nogc nothrow { + alias pSDL_Vulkan_CreateSurface = SDL_bool function(SDL_Window*,void*,void*); + alias pSDL_Vulkan_GetDrawableSize = void function(SDL_Window*,int*,int*); + alias pSDL_Vulkan_GetInstanceExtensions = SDL_bool function(SDL_Window*,uint*,const(char)**); + alias pSDL_Vulkan_GetVkGetInstanceProcAddr = void* function(); + alias pSDL_Vulkan_LoadLibrary = int function(const(char)*); + alias pSDL_Vulkan_UnloadLibrary = void function(); + } + + __gshared { + pSDL_Vulkan_CreateSurface SDL_Vulkan_CreateSurface; + pSDL_Vulkan_GetDrawableSize SDL_Vulkan_GetDrawableSize; + pSDL_Vulkan_GetInstanceExtensions SDL_Vulkan_GetInstanceExtensions; + pSDL_Vulkan_GetVkGetInstanceProcAddr SDL_Vulkan_GetVkGetInstanceProcAddr; + pSDL_Vulkan_LoadLibrary SDL_Vulkan_LoadLibrary; + pSDL_Vulkan_UnloadLibrary SDL_Vulkan_UnloadLibrary; + } + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/config.d b/demos/external/wasm_imports/bindbc/sdl/config.d new file mode 100644 index 0000000..1a76433 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/config.d @@ -0,0 +1,44 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.config; + +enum SDLSupport { + noLibrary, + badLibrary, + sdl200 = 200, + sdl201 = 201, + sdl202 = 202, + sdl203 = 203, + sdl204 = 204, + sdl205 = 205, + sdl206 = 206, + sdl207 = 207, + sdl208 = 208, + sdl209 = 209, + sdl2010 = 2010, +} + +version(SDL_2010) enum sdlSupport = SDLSupport.sdl2010; +else version(SDL_209) enum sdlSupport = SDLSupport.sdl209; +else version(SDL_208) enum sdlSupport = SDLSupport.sdl208; +else version(SDL_207) enum sdlSupport = SDLSupport.sdl207; +else version(SDL_206) enum sdlSupport = SDLSupport.sdl206; +else version(SDL_205) enum sdlSupport = SDLSupport.sdl205; +else version(SDL_204) enum sdlSupport = SDLSupport.sdl204; +else version(SDL_203) enum sdlSupport = SDLSupport.sdl203; +else version(SDL_202) enum sdlSupport = SDLSupport.sdl202; +else version(SDL_201) enum sdlSupport = SDLSupport.sdl201; +else enum sdlSupport = SDLSupport.sdl200; + +enum expandEnum(EnumType, string fqnEnumType = EnumType.stringof) = (){ + string expandEnum = "enum {"; + foreach(m;__traits(allMembers, EnumType)) { + expandEnum ~= m ~ " = " ~ fqnEnumType ~ "." ~ m ~ ","; + } + expandEnum ~= "}"; + return expandEnum; +}(); \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/dynload.d b/demos/external/wasm_imports/bindbc/sdl/dynload.d new file mode 100644 index 0000000..3a15c97 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/dynload.d @@ -0,0 +1,712 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.dynload; + +version(BindSDL_Static) {} +else: + +import bindbc.loader; +import bindbc.sdl.config, + bindbc.sdl.bind; + +private { + __gshared SharedLib lib; + __gshared SDLSupport loadedVersion; +} + +void unloadSDL() +{ + if(lib != invalidHandle) { + lib.unload(); + } +} + +SDLSupport loadedSDLVersion() { return loadedVersion; } + +bool isSDLLoaded() +{ + return lib != invalidHandle; +} + +SDLSupport loadSDL() +{ + // #1778 prevents me from using static arrays here :( + version(Windows) { + const(char)[][1] libNames = ["SDL2.dll"]; + } + else version(OSX) { + const(char)[][7] libNames = [ + "libSDL2.dylib", + "/usr/local/lib/libSDL2.dylib", + "/usr/local/lib/libSDL2/libSDL2.dylib", + "../Frameworks/SDL2.framework/SDL2", + "/Library/Frameworks/SDL2.framework/SDL2", + "/System/Library/Frameworks/SDL2.framework/SDL2", + "/opt/local/lib/libSDL2.dylib" + ]; + } + else version(Posix) { + const(char)[][6] libNames = [ + "libSDL2.so", + "/usr/local/lib/libSDL2.so", + "libSDL2-2.0.so", + "/usr/local/lib/libSDL2-2.0.so", + "libSDL2-2.0.so.0", + "/usr/local/lib/libSDL2-2.0.so.0" + ]; + } + else static assert(0, "bindbc-sdl is not yet supported on this platform."); + + SDLSupport ret; + foreach(name; libNames) { + ret = loadSDL(name.ptr); + if(ret != SDLSupport.noLibrary) break; + } + return ret; +} + +SDLSupport loadSDL(const(char)* libName) +{ + lib = load(libName); + if(lib == invalidHandle) { + return SDLSupport.noLibrary; + } + + auto errCount = errorCount(); + loadedVersion = SDLSupport.badLibrary; + + lib.bindSymbol(cast(void**)&SDL_Init, "SDL_Init"); + lib.bindSymbol(cast(void**)&SDL_InitSubSystem, "SDL_InitSubSystem"); + lib.bindSymbol(cast(void**)&SDL_QuitSubSystem, "SDL_QuitSubSystem"); + lib.bindSymbol(cast(void**)&SDL_WasInit, "SDL_WasInit"); + lib.bindSymbol(cast(void**)&SDL_Quit, "SDL_Quit"); + lib.bindSymbol(cast(void**)&SDL_SetAssertionHandler, "SDL_SetAssertionHandler"); + lib.bindSymbol(cast(void**)&SDL_GetAssertionReport, "SDL_GetAssertionReport"); + lib.bindSymbol(cast(void**)&SDL_ResetAssertionReport, "SDL_ResetAssertionReport"); + lib.bindSymbol(cast(void**)&SDL_GetNumAudioDrivers, "SDL_GetNumAudioDrivers"); + lib.bindSymbol(cast(void**)&SDL_GetAudioDriver, "SDL_GetAudioDriver"); + lib.bindSymbol(cast(void**)&SDL_AudioInit, "SDL_AudioInit"); + lib.bindSymbol(cast(void**)&SDL_AudioQuit, "SDL_AudioQuit"); + lib.bindSymbol(cast(void**)&SDL_GetCurrentAudioDriver, "SDL_GetCurrentAudioDriver"); + lib.bindSymbol(cast(void**)&SDL_OpenAudio, "SDL_OpenAudio"); + lib.bindSymbol(cast(void**)&SDL_GetNumAudioDevices, "SDL_GetNumAudioDevices"); + lib.bindSymbol(cast(void**)&SDL_GetAudioDeviceName, "SDL_GetAudioDeviceName"); + lib.bindSymbol(cast(void**)&SDL_OpenAudioDevice, "SDL_OpenAudioDevice"); + lib.bindSymbol(cast(void**)&SDL_GetAudioStatus, "SDL_GetAudioStatus"); + lib.bindSymbol(cast(void**)&SDL_GetAudioDeviceStatus, "SDL_GetAudioDeviceStatus"); + lib.bindSymbol(cast(void**)&SDL_PauseAudio, "SDL_PauseAudio"); + lib.bindSymbol(cast(void**)&SDL_PauseAudioDevice, "SDL_PauseAudioDevice"); + lib.bindSymbol(cast(void**)&SDL_LoadWAV_RW, "SDL_LoadWAV_RW"); + lib.bindSymbol(cast(void**)&SDL_FreeWAV, "SDL_FreeWAV"); + lib.bindSymbol(cast(void**)&SDL_BuildAudioCVT, "SDL_BuildAudioCVT"); + lib.bindSymbol(cast(void**)&SDL_ConvertAudio, "SDL_ConvertAudio"); + lib.bindSymbol(cast(void**)&SDL_MixAudio, "SDL_MixAudio"); + lib.bindSymbol(cast(void**)&SDL_MixAudioFormat, "SDL_MixAudioFormat"); + lib.bindSymbol(cast(void**)&SDL_LockAudio, "SDL_LockAudio"); + lib.bindSymbol(cast(void**)&SDL_LockAudioDevice, "SDL_LockAudioDevice"); + lib.bindSymbol(cast(void**)&SDL_UnlockAudio, "SDL_UnlockAudio"); + lib.bindSymbol(cast(void**)&SDL_UnlockAudioDevice, "SDL_UnlockAudioDevice"); + lib.bindSymbol(cast(void**)&SDL_CloseAudio, "SDL_CloseAudio"); + lib.bindSymbol(cast(void**)&SDL_CloseAudioDevice, "SDL_CloseAudioDevice"); + lib.bindSymbol(cast(void**)&SDL_SetClipboardText, "SDL_SetClipboardText"); + lib.bindSymbol(cast(void**)&SDL_GetClipboardText, "SDL_GetClipboardText"); + lib.bindSymbol(cast(void**)&SDL_HasClipboardText, "SDL_HasClipboardText"); + lib.bindSymbol(cast(void**)&SDL_GetCPUCount, "SDL_GetCPUCount"); + lib.bindSymbol(cast(void**)&SDL_GetCPUCacheLineSize, "SDL_GetCPUCacheLineSize"); + lib.bindSymbol(cast(void**)&SDL_HasRDTSC, "SDL_HasRDTSC"); + lib.bindSymbol(cast(void**)&SDL_HasAltiVec, "SDL_HasAltiVec"); + lib.bindSymbol(cast(void**)&SDL_HasMMX, "SDL_HasMMX"); + lib.bindSymbol(cast(void**)&SDL_Has3DNow, "SDL_Has3DNow"); + lib.bindSymbol(cast(void**)&SDL_HasSSE, "SDL_HasSSE"); + lib.bindSymbol(cast(void**)&SDL_HasSSE2, "SDL_HasSSE2"); + lib.bindSymbol(cast(void**)&SDL_HasSSE3, "SDL_HasSSE3"); + lib.bindSymbol(cast(void**)&SDL_HasSSE41, "SDL_HasSSE41"); + lib.bindSymbol(cast(void**)&SDL_HasSSE42, "SDL_HasSSE42"); + lib.bindSymbol(cast(void**)&SDL_SetError, "SDL_SetError"); + lib.bindSymbol(cast(void**)&SDL_GetError, "SDL_GetError"); + lib.bindSymbol(cast(void**)&SDL_ClearError, "SDL_ClearError"); + lib.bindSymbol(cast(void**)&SDL_PumpEvents, "SDL_PumpEvents"); + lib.bindSymbol(cast(void**)&SDL_PeepEvents, "SDL_PeepEvents"); + lib.bindSymbol(cast(void**)&SDL_HasEvent, "SDL_HasEvent"); + lib.bindSymbol(cast(void**)&SDL_HasEvents, "SDL_HasEvents"); + lib.bindSymbol(cast(void**)&SDL_FlushEvent, "SDL_FlushEvent"); + lib.bindSymbol(cast(void**)&SDL_FlushEvents, "SDL_FlushEvents"); + lib.bindSymbol(cast(void**)&SDL_PollEvent, "SDL_PollEvent"); + lib.bindSymbol(cast(void**)&SDL_WaitEvent, "SDL_WaitEvent"); + lib.bindSymbol(cast(void**)&SDL_WaitEventTimeout, "SDL_WaitEventTimeout"); + lib.bindSymbol(cast(void**)&SDL_PushEvent, "SDL_PushEvent"); + lib.bindSymbol(cast(void**)&SDL_SetEventFilter, "SDL_SetEventFilter"); + lib.bindSymbol(cast(void**)&SDL_GetEventFilter, "SDL_GetEventFilter"); + lib.bindSymbol(cast(void**)&SDL_AddEventWatch, "SDL_AddEventWatch"); + lib.bindSymbol(cast(void**)&SDL_DelEventWatch, "SDL_DelEventWatch"); + lib.bindSymbol(cast(void**)&SDL_FilterEvents, "SDL_FilterEvents"); + lib.bindSymbol(cast(void**)&SDL_EventState, "SDL_EventState"); + lib.bindSymbol(cast(void**)&SDL_RegisterEvents, "SDL_RegisterEvents"); + lib.bindSymbol(cast(void**)&SDL_GameControllerAddMapping, "SDL_GameControllerAddMapping"); + lib.bindSymbol(cast(void**)&SDL_GameControllerMappingForGUID, "SDL_GameControllerMappingForGUID"); + lib.bindSymbol(cast(void**)&SDL_GameControllerMapping, "SDL_GameControllerMapping"); + lib.bindSymbol(cast(void**)&SDL_IsGameController, "SDL_IsGameController"); + lib.bindSymbol(cast(void**)&SDL_GameControllerNameForIndex, "SDL_GameControllerNameForIndex"); + lib.bindSymbol(cast(void**)&SDL_GameControllerOpen, "SDL_GameControllerOpen"); + lib.bindSymbol(cast(void**)&SDL_GameControllerName, "SDL_GameControllerName"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetAttached, "SDL_GameControllerGetAttached"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetJoystick, "SDL_GameControllerGetJoystick"); + lib.bindSymbol(cast(void**)&SDL_GameControllerEventState, "SDL_GameControllerEventState"); + lib.bindSymbol(cast(void**)&SDL_GameControllerUpdate, "SDL_GameControllerUpdate"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetAxisFromString, "SDL_GameControllerGetAxisFromString"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetStringForAxis, "SDL_GameControllerGetStringForAxis"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetBindForAxis, "SDL_GameControllerGetBindForAxis"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetAxis, "SDL_GameControllerGetAxis"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetButtonFromString, "SDL_GameControllerGetButtonFromString"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetStringForButton, "SDL_GameControllerGetStringForButton"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetBindForButton, "SDL_GameControllerGetBindForButton"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetButton, "SDL_GameControllerGetButton"); + lib.bindSymbol(cast(void**)&SDL_GameControllerClose, "SDL_GameControllerClose"); + lib.bindSymbol(cast(void**)&SDL_RecordGesture, "SDL_RecordGesture"); + lib.bindSymbol(cast(void**)&SDL_SaveAllDollarTemplates, "SDL_SaveAllDollarTemplates"); + lib.bindSymbol(cast(void**)&SDL_SaveDollarTemplate, "SDL_SaveDollarTemplate"); + lib.bindSymbol(cast(void**)&SDL_LoadDollarTemplates, "SDL_LoadDollarTemplates"); + lib.bindSymbol(cast(void**)&SDL_NumHaptics, "SDL_NumHaptics"); + lib.bindSymbol(cast(void**)&SDL_HapticName, "SDL_HapticName"); + lib.bindSymbol(cast(void**)&SDL_HapticOpen, "SDL_HapticOpen"); + lib.bindSymbol(cast(void**)&SDL_HapticOpened, "SDL_HapticOpened"); + lib.bindSymbol(cast(void**)&SDL_HapticIndex, "SDL_HapticIndex"); + lib.bindSymbol(cast(void**)&SDL_MouseIsHaptic, "SDL_MouseIsHaptic"); + lib.bindSymbol(cast(void**)&SDL_HapticOpenFromMouse, "SDL_HapticOpenFromMouse"); + lib.bindSymbol(cast(void**)&SDL_JoystickIsHaptic, "SDL_JoystickIsHaptic"); + lib.bindSymbol(cast(void**)&SDL_HapticOpenFromJoystick, "SDL_HapticOpenFromJoystick"); + lib.bindSymbol(cast(void**)&SDL_HapticClose, "SDL_HapticClose"); + lib.bindSymbol(cast(void**)&SDL_HapticNumEffects, "SDL_HapticNumEffects"); + lib.bindSymbol(cast(void**)&SDL_HapticNumEffectsPlaying, "SDL_HapticNumEffectsPlaying"); + lib.bindSymbol(cast(void**)&SDL_HapticQuery, "SDL_HapticQuery"); + lib.bindSymbol(cast(void**)&SDL_HapticNumAxes, "SDL_HapticNumAxes"); + lib.bindSymbol(cast(void**)&SDL_HapticEffectSupported, "SDL_HapticEffectSupported"); + lib.bindSymbol(cast(void**)&SDL_HapticNewEffect, "SDL_HapticNewEffect"); + lib.bindSymbol(cast(void**)&SDL_HapticUpdateEffect, "SDL_HapticUpdateEffect"); + lib.bindSymbol(cast(void**)&SDL_HapticRunEffect, "SDL_HapticRunEffect"); + lib.bindSymbol(cast(void**)&SDL_HapticStopEffect, "SDL_HapticStopEffect"); + lib.bindSymbol(cast(void**)&SDL_HapticDestroyEffect, "SDL_HapticDestroyEffect"); + lib.bindSymbol(cast(void**)&SDL_HapticGetEffectStatus, "SDL_HapticGetEffectStatus"); + lib.bindSymbol(cast(void**)&SDL_HapticSetGain, "SDL_HapticSetGain"); + lib.bindSymbol(cast(void**)&SDL_HapticSetAutocenter, "SDL_HapticSetAutocenter"); + lib.bindSymbol(cast(void**)&SDL_HapticPause, "SDL_HapticPause"); + lib.bindSymbol(cast(void**)&SDL_HapticUnpause, "SDL_HapticUnpause"); + lib.bindSymbol(cast(void**)&SDL_HapticStopAll, "SDL_HapticStopAll"); + lib.bindSymbol(cast(void**)&SDL_HapticRumbleSupported, "SDL_HapticRumbleSupported"); + lib.bindSymbol(cast(void**)&SDL_HapticRumbleInit, "SDL_HapticRumbleInit"); + lib.bindSymbol(cast(void**)&SDL_HapticRumblePlay, "SDL_HapticRumblePlay"); + lib.bindSymbol(cast(void**)&SDL_HapticRumbleStop, "SDL_HapticRumbleStop"); + lib.bindSymbol(cast(void**)&SDL_SetHintWithPriority, "SDL_SetHintWithPriority"); + lib.bindSymbol(cast(void**)&SDL_SetHint, "SDL_SetHint"); + lib.bindSymbol(cast(void**)&SDL_GetHint, "SDL_GetHint"); + lib.bindSymbol(cast(void**)&SDL_AddHintCallback, "SDL_AddHintCallback"); + lib.bindSymbol(cast(void**)&SDL_DelHintCallback, "SDL_DelHintCallback"); + lib.bindSymbol(cast(void**)&SDL_ClearHints, "SDL_ClearHints"); + lib.bindSymbol(cast(void**)&SDL_NumJoysticks, "SDL_NumJoysticks"); + lib.bindSymbol(cast(void**)&SDL_JoystickNameForIndex, "SDL_JoystickNameForIndex"); + lib.bindSymbol(cast(void**)&SDL_JoystickOpen, "SDL_JoystickOpen"); + lib.bindSymbol(cast(void**)&SDL_JoystickName, "SDL_JoystickName"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceGUID, "SDL_JoystickGetDeviceGUID"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetGUID, "SDL_JoystickGetGUID"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetGUIDString, "SDL_JoystickGetGUIDString"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetGUIDFromString, "SDL_JoystickGetGUIDFromString"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetAttached, "SDL_JoystickGetAttached"); + lib.bindSymbol(cast(void**)&SDL_JoystickInstanceID, "SDL_JoystickInstanceID"); + lib.bindSymbol(cast(void**)&SDL_JoystickNumAxes, "SDL_JoystickNumAxes"); + lib.bindSymbol(cast(void**)&SDL_JoystickNumBalls, "SDL_JoystickNumBalls"); + lib.bindSymbol(cast(void**)&SDL_JoystickNumHats, "SDL_JoystickNumHats"); + lib.bindSymbol(cast(void**)&SDL_JoystickNumButtons, "SDL_JoystickNumButtons"); + lib.bindSymbol(cast(void**)&SDL_JoystickUpdate, "SDL_JoystickUpdate"); + lib.bindSymbol(cast(void**)&SDL_JoystickEventState, "SDL_JoystickEventState"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetAxis, "SDL_JoystickGetAxis"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetHat, "SDL_JoystickGetHat"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetBall, "SDL_JoystickGetBall"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetButton, "SDL_JoystickGetButton"); + lib.bindSymbol(cast(void**)&SDL_JoystickClose, "SDL_JoystickClose"); + lib.bindSymbol(cast(void**)&SDL_GetKeyboardFocus, "SDL_GetKeyboardFocus"); + lib.bindSymbol(cast(void**)&SDL_GetKeyboardState, "SDL_GetKeyboardState"); + lib.bindSymbol(cast(void**)&SDL_GetModState, "SDL_GetModState"); + lib.bindSymbol(cast(void**)&SDL_SetModState, "SDL_SetModState"); + lib.bindSymbol(cast(void**)&SDL_GetKeyFromScancode, "SDL_GetKeyFromScancode"); + lib.bindSymbol(cast(void**)&SDL_GetScancodeFromKey, "SDL_GetScancodeFromKey"); + lib.bindSymbol(cast(void**)&SDL_GetScancodeName, "SDL_GetScancodeName"); + lib.bindSymbol(cast(void**)&SDL_GetScancodeFromName, "SDL_GetScancodeFromName"); + lib.bindSymbol(cast(void**)&SDL_GetKeyName, "SDL_GetKeyName"); + lib.bindSymbol(cast(void**)&SDL_GetKeyFromName, "SDL_GetKeyFromName"); + lib.bindSymbol(cast(void**)&SDL_StartTextInput, "SDL_StartTextInput"); + lib.bindSymbol(cast(void**)&SDL_IsTextInputActive, "SDL_IsTextInputActive"); + lib.bindSymbol(cast(void**)&SDL_StopTextInput, "SDL_StopTextInput"); + lib.bindSymbol(cast(void**)&SDL_SetTextInputRect, "SDL_SetTextInputRect"); + lib.bindSymbol(cast(void**)&SDL_HasScreenKeyboardSupport, "SDL_HasScreenKeyboardSupport"); + lib.bindSymbol(cast(void**)&SDL_IsScreenKeyboardShown, "SDL_IsScreenKeyboardShown"); + lib.bindSymbol(cast(void**)&SDL_LoadObject, "SDL_LoadObject"); + lib.bindSymbol(cast(void**)&SDL_LoadFunction, "SDL_LoadFunction"); + lib.bindSymbol(cast(void**)&SDL_UnloadObject, "SDL_UnloadObject"); + lib.bindSymbol(cast(void**)&SDL_LogSetAllPriority, "SDL_LogSetAllPriority"); + lib.bindSymbol(cast(void**)&SDL_LogSetPriority, "SDL_LogSetPriority"); + lib.bindSymbol(cast(void**)&SDL_LogGetPriority, "SDL_LogGetPriority"); + lib.bindSymbol(cast(void**)&SDL_LogResetPriorities, "SDL_LogResetPriorities"); + lib.bindSymbol(cast(void**)&SDL_Log, "SDL_Log"); + lib.bindSymbol(cast(void**)&SDL_LogVerbose, "SDL_LogVerbose"); + lib.bindSymbol(cast(void**)&SDL_LogDebug, "SDL_LogDebug"); + lib.bindSymbol(cast(void**)&SDL_LogInfo, "SDL_LogInfo"); + lib.bindSymbol(cast(void**)&SDL_LogWarn, "SDL_LogWarn"); + lib.bindSymbol(cast(void**)&SDL_LogError, "SDL_LogError"); + lib.bindSymbol(cast(void**)&SDL_LogCritical, "SDL_LogCritical"); + lib.bindSymbol(cast(void**)&SDL_LogMessage, "SDL_LogMessage"); + lib.bindSymbol(cast(void**)&SDL_LogMessageV, "SDL_LogMessageV"); + lib.bindSymbol(cast(void**)&SDL_LogGetOutputFunction, "SDL_LogGetOutputFunction"); + lib.bindSymbol(cast(void**)&SDL_LogSetOutputFunction, "SDL_LogSetOutputFunction"); + lib.bindSymbol(cast(void**)&SDL_ShowMessageBox, "SDL_ShowMessageBox"); + lib.bindSymbol(cast(void**)&SDL_ShowSimpleMessageBox, "SDL_ShowSimpleMessageBox"); + lib.bindSymbol(cast(void**)&SDL_GetMouseFocus, "SDL_GetMouseFocus"); + lib.bindSymbol(cast(void**)&SDL_GetMouseState, "SDL_GetMouseState"); + lib.bindSymbol(cast(void**)&SDL_GetRelativeMouseState, "SDL_GetRelativeMouseState"); + lib.bindSymbol(cast(void**)&SDL_WarpMouseInWindow, "SDL_WarpMouseInWindow"); + lib.bindSymbol(cast(void**)&SDL_SetRelativeMouseMode, "SDL_SetRelativeMouseMode"); + lib.bindSymbol(cast(void**)&SDL_GetRelativeMouseMode, "SDL_GetRelativeMouseMode"); + lib.bindSymbol(cast(void**)&SDL_CreateCursor, "SDL_CreateCursor"); + lib.bindSymbol(cast(void**)&SDL_CreateColorCursor, "SDL_CreateColorCursor"); + lib.bindSymbol(cast(void**)&SDL_CreateSystemCursor, "SDL_CreateSystemCursor"); + lib.bindSymbol(cast(void**)&SDL_SetCursor, "SDL_SetCursor"); + lib.bindSymbol(cast(void**)&SDL_GetCursor, "SDL_GetCursor"); + lib.bindSymbol(cast(void**)&SDL_GetDefaultCursor, "SDL_GetDefaultCursor"); + lib.bindSymbol(cast(void**)&SDL_FreeCursor, "SDL_FreeCursor"); + lib.bindSymbol(cast(void**)&SDL_ShowCursor, "SDL_ShowCursor"); + lib.bindSymbol(cast(void**)&SDL_GetPixelFormatName, "SDL_GetPixelFormatName"); + lib.bindSymbol(cast(void**)&SDL_PixelFormatEnumToMasks, "SDL_PixelFormatEnumToMasks"); + lib.bindSymbol(cast(void**)&SDL_MasksToPixelFormatEnum, "SDL_MasksToPixelFormatEnum"); + lib.bindSymbol(cast(void**)&SDL_AllocFormat, "SDL_AllocFormat"); + lib.bindSymbol(cast(void**)&SDL_FreeFormat, "SDL_FreeFormat"); + lib.bindSymbol(cast(void**)&SDL_AllocPalette, "SDL_AllocPalette"); + lib.bindSymbol(cast(void**)&SDL_SetPixelFormatPalette, "SDL_SetPixelFormatPalette"); + lib.bindSymbol(cast(void**)&SDL_SetPaletteColors, "SDL_SetPaletteColors"); + lib.bindSymbol(cast(void**)&SDL_FreePalette, "SDL_FreePalette"); + lib.bindSymbol(cast(void**)&SDL_MapRGB, "SDL_MapRGB"); + lib.bindSymbol(cast(void**)&SDL_MapRGBA, "SDL_MapRGBA"); + lib.bindSymbol(cast(void**)&SDL_GetRGB, "SDL_GetRGB"); + lib.bindSymbol(cast(void**)&SDL_GetRGBA, "SDL_GetRGBA"); + lib.bindSymbol(cast(void**)&SDL_CalculateGammaRamp, "SDL_CalculateGammaRamp"); + lib.bindSymbol(cast(void**)&SDL_GetPlatform, "SDL_GetPlatform"); + lib.bindSymbol(cast(void**)&SDL_GetPowerInfo, "SDL_GetPowerInfo"); + lib.bindSymbol(cast(void**)&SDL_HasIntersection, "SDL_HasIntersection"); + lib.bindSymbol(cast(void**)&SDL_IntersectRect, "SDL_IntersectRect"); + lib.bindSymbol(cast(void**)&SDL_UnionRect, "SDL_UnionRect"); + lib.bindSymbol(cast(void**)&SDL_EnclosePoints, "SDL_EnclosePoints"); + lib.bindSymbol(cast(void**)&SDL_IntersectRectAndLine, "SDL_IntersectRectAndLine"); + lib.bindSymbol(cast(void**)&SDL_GetNumRenderDrivers, "SDL_GetNumRenderDrivers"); + lib.bindSymbol(cast(void**)&SDL_GetRenderDriverInfo, "SDL_GetRenderDriverInfo"); + lib.bindSymbol(cast(void**)&SDL_CreateWindowAndRenderer, "SDL_CreateWindowAndRenderer"); + lib.bindSymbol(cast(void**)&SDL_CreateRenderer, "SDL_CreateRenderer"); + lib.bindSymbol(cast(void**)&SDL_CreateSoftwareRenderer, "SDL_CreateSoftwareRenderer"); + lib.bindSymbol(cast(void**)&SDL_GetRenderer, "SDL_GetRenderer"); + lib.bindSymbol(cast(void**)&SDL_GetRendererInfo, "SDL_GetRendererInfo"); + lib.bindSymbol(cast(void**)&SDL_GetRendererOutputSize, "SDL_GetRendererOutputSize"); + lib.bindSymbol(cast(void**)&SDL_CreateTexture, "SDL_CreateTexture"); + lib.bindSymbol(cast(void**)&SDL_CreateTextureFromSurface, "SDL_CreateTextureFromSurface"); + lib.bindSymbol(cast(void**)&SDL_QueryTexture, "SDL_QueryTexture"); + lib.bindSymbol(cast(void**)&SDL_SetTextureColorMod, "SDL_SetTextureColorMod"); + lib.bindSymbol(cast(void**)&SDL_GetTextureColorMod, "SDL_GetTextureColorMod"); + lib.bindSymbol(cast(void**)&SDL_SetTextureAlphaMod, "SDL_SetTextureAlphaMod"); + lib.bindSymbol(cast(void**)&SDL_GetTextureAlphaMod, "SDL_GetTextureAlphaMod"); + lib.bindSymbol(cast(void**)&SDL_SetTextureBlendMode, "SDL_SetTextureBlendMode"); + lib.bindSymbol(cast(void**)&SDL_GetTextureBlendMode, "SDL_GetTextureBlendMode"); + lib.bindSymbol(cast(void**)&SDL_UpdateTexture, "SDL_UpdateTexture"); + lib.bindSymbol(cast(void**)&SDL_LockTexture, "SDL_LockTexture"); + lib.bindSymbol(cast(void**)&SDL_UnlockTexture, "SDL_UnlockTexture"); + lib.bindSymbol(cast(void**)&SDL_RenderTargetSupported, "SDL_RenderTargetSupported"); + lib.bindSymbol(cast(void**)&SDL_SetRenderTarget, "SDL_SetRenderTarget"); + lib.bindSymbol(cast(void**)&SDL_GetRenderTarget, "SDL_GetRenderTarget"); + lib.bindSymbol(cast(void**)&SDL_RenderSetClipRect, "SDL_RenderSetClipRect"); + lib.bindSymbol(cast(void**)&SDL_RenderGetClipRect, "SDL_RenderGetClipRect"); + lib.bindSymbol(cast(void**)&SDL_RenderSetLogicalSize, "SDL_RenderSetLogicalSize"); + lib.bindSymbol(cast(void**)&SDL_RenderGetLogicalSize, "SDL_RenderGetLogicalSize"); + lib.bindSymbol(cast(void**)&SDL_RenderSetViewport, "SDL_RenderSetViewport"); + lib.bindSymbol(cast(void**)&SDL_RenderGetViewport, "SDL_RenderGetViewport"); + lib.bindSymbol(cast(void**)&SDL_RenderSetScale, "SDL_RenderSetScale"); + lib.bindSymbol(cast(void**)&SDL_RenderGetScale, "SDL_RenderGetScale"); + lib.bindSymbol(cast(void**)&SDL_SetRenderDrawColor, "SDL_SetRenderDrawColor"); + lib.bindSymbol(cast(void**)&SDL_GetRenderDrawColor, "SDL_GetRenderDrawColor"); + lib.bindSymbol(cast(void**)&SDL_SetRenderDrawBlendMode, "SDL_SetRenderDrawBlendMode"); + lib.bindSymbol(cast(void**)&SDL_GetRenderDrawBlendMode, "SDL_GetRenderDrawBlendMode"); + lib.bindSymbol(cast(void**)&SDL_RenderClear, "SDL_RenderClear"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawPoint, "SDL_RenderDrawPoint"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawPoints, "SDL_RenderDrawPoints"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawLine, "SDL_RenderDrawLine"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawLines, "SDL_RenderDrawLines"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawRect, "SDL_RenderDrawRect"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawRects, "SDL_RenderDrawRects"); + lib.bindSymbol(cast(void**)&SDL_RenderFillRect, "SDL_RenderFillRect"); + lib.bindSymbol(cast(void**)&SDL_RenderFillRects, "SDL_RenderFillRects"); + lib.bindSymbol(cast(void**)&SDL_RenderCopy, "SDL_RenderCopy"); + lib.bindSymbol(cast(void**)&SDL_RenderCopyEx, "SDL_RenderCopyEx"); + lib.bindSymbol(cast(void**)&SDL_RenderReadPixels, "SDL_RenderReadPixels"); + lib.bindSymbol(cast(void**)&SDL_RenderPresent, "SDL_RenderPresent"); + lib.bindSymbol(cast(void**)&SDL_DestroyTexture, "SDL_DestroyTexture"); + lib.bindSymbol(cast(void**)&SDL_DestroyRenderer, "SDL_DestroyRenderer"); + lib.bindSymbol(cast(void**)&SDL_GL_BindTexture, "SDL_GL_BindTexture"); + lib.bindSymbol(cast(void**)&SDL_GL_UnbindTexture, "SDL_GL_UnbindTexture"); + lib.bindSymbol(cast(void**)&SDL_RWFromFile, "SDL_RWFromFile"); + lib.bindSymbol(cast(void**)&SDL_RWFromFP, "SDL_RWFromFP"); + lib.bindSymbol(cast(void**)&SDL_RWFromMem, "SDL_RWFromMem"); + lib.bindSymbol(cast(void**)&SDL_RWFromConstMem, "SDL_RWFromConstMem"); + lib.bindSymbol(cast(void**)&SDL_AllocRW, "SDL_AllocRW"); + lib.bindSymbol(cast(void**)&SDL_FreeRW, "SDL_FreeRW"); + lib.bindSymbol(cast(void**)&SDL_ReadU8, "SDL_ReadU8"); + lib.bindSymbol(cast(void**)&SDL_ReadLE16, "SDL_ReadLE16"); + lib.bindSymbol(cast(void**)&SDL_ReadBE16, "SDL_ReadBE16"); + lib.bindSymbol(cast(void**)&SDL_ReadLE32, "SDL_ReadLE32"); + lib.bindSymbol(cast(void**)&SDL_ReadBE32, "SDL_ReadBE32"); + lib.bindSymbol(cast(void**)&SDL_ReadLE64, "SDL_ReadLE64"); + lib.bindSymbol(cast(void**)&SDL_ReadBE64, "SDL_ReadBE64"); + lib.bindSymbol(cast(void**)&SDL_WriteU8, "SDL_WriteU8"); + lib.bindSymbol(cast(void**)&SDL_WriteLE16, "SDL_WriteLE16"); + lib.bindSymbol(cast(void**)&SDL_WriteBE16, "SDL_WriteBE16"); + lib.bindSymbol(cast(void**)&SDL_WriteLE32, "SDL_WriteLE32"); + lib.bindSymbol(cast(void**)&SDL_WriteBE32, "SDL_WriteBE32"); + lib.bindSymbol(cast(void**)&SDL_WriteLE64, "SDL_WriteLE64"); + lib.bindSymbol(cast(void**)&SDL_WriteBE64, "SDL_WriteBE64"); + lib.bindSymbol(cast(void**)&SDL_CreateShapedWindow, "SDL_CreateShapedWindow"); + lib.bindSymbol(cast(void**)&SDL_IsShapedWindow, "SDL_IsShapedWindow"); + lib.bindSymbol(cast(void**)&SDL_SetWindowShape, "SDL_SetWindowShape"); + lib.bindSymbol(cast(void**)&SDL_GetShapedWindowMode, "SDL_GetShapedWindowMode"); + lib.bindSymbol(cast(void**)&SDL_free, "SDL_free"); + lib.bindSymbol(cast(void**)&SDL_CreateRGBSurface, "SDL_CreateRGBSurface"); + lib.bindSymbol(cast(void**)&SDL_CreateRGBSurfaceFrom, "SDL_CreateRGBSurfaceFrom"); + lib.bindSymbol(cast(void**)&SDL_FreeSurface, "SDL_FreeSurface"); + lib.bindSymbol(cast(void**)&SDL_SetSurfacePalette, "SDL_SetSurfacePalette"); + lib.bindSymbol(cast(void**)&SDL_LockSurface, "SDL_LockSurface"); + lib.bindSymbol(cast(void**)&SDL_UnlockSurface, "SDL_UnlockSurface"); + lib.bindSymbol(cast(void**)&SDL_LoadBMP_RW, "SDL_LoadBMP_RW"); + lib.bindSymbol(cast(void**)&SDL_SaveBMP_RW, "SDL_SaveBMP_RW"); + lib.bindSymbol(cast(void**)&SDL_SetSurfaceRLE, "SDL_SetSurfaceRLE"); + lib.bindSymbol(cast(void**)&SDL_SetColorKey, "SDL_SetColorKey"); + lib.bindSymbol(cast(void**)&SDL_GetColorKey, "SDL_GetColorKey"); + lib.bindSymbol(cast(void**)&SDL_SetSurfaceColorMod, "SDL_SetSurfaceColorMod"); + lib.bindSymbol(cast(void**)&SDL_GetSurfaceColorMod, "SDL_GetSurfaceColorMod"); + lib.bindSymbol(cast(void**)&SDL_SetSurfaceAlphaMod, "SDL_SetSurfaceAlphaMod"); + lib.bindSymbol(cast(void**)&SDL_GetSurfaceAlphaMod, "SDL_GetSurfaceAlphaMod"); + lib.bindSymbol(cast(void**)&SDL_SetSurfaceBlendMode, "SDL_SetSurfaceBlendMode"); + lib.bindSymbol(cast(void**)&SDL_GetSurfaceBlendMode, "SDL_GetSurfaceBlendMode"); + lib.bindSymbol(cast(void**)&SDL_SetClipRect, "SDL_SetClipRect"); + lib.bindSymbol(cast(void**)&SDL_GetClipRect, "SDL_GetClipRect"); + lib.bindSymbol(cast(void**)&SDL_ConvertSurface, "SDL_ConvertSurface"); + lib.bindSymbol(cast(void**)&SDL_ConvertSurfaceFormat, "SDL_ConvertSurfaceFormat"); + lib.bindSymbol(cast(void**)&SDL_ConvertPixels, "SDL_ConvertPixels"); + lib.bindSymbol(cast(void**)&SDL_FillRect, "SDL_FillRect"); + lib.bindSymbol(cast(void**)&SDL_FillRects, "SDL_FillRects"); + lib.bindSymbol(cast(void**)&SDL_UpperBlit, "SDL_UpperBlit"); + lib.bindSymbol(cast(void**)&SDL_LowerBlit, "SDL_LowerBlit"); + lib.bindSymbol(cast(void**)&SDL_SoftStretch, "SDL_SoftStretch"); + lib.bindSymbol(cast(void**)&SDL_UpperBlitScaled, "SDL_UpperBlitScaled"); + lib.bindSymbol(cast(void**)&SDL_LowerBlitScaled, "SDL_LowerBlitScaled"); + version(Android) { + lib.bindSymbol(cast(void**)&SDL_AndroidGetJNIEnv, "SDL_AndroidGetJNIEnv"); + lib.bindSymbol(cast(void**)&SDL_AndroidGetActivity, "SDL_AndroidGetActivity"); + + lib.bindSymbol(cast(void**)&SDL_AndroidGetInternalStoragePath, "SDL_AndroidGetInternalStoragePath"); + lib.bindSymbol(cast(void**)&SDL_AndroidGetInternalStorageState, "SDL_AndroidGetInternalStorageState"); + lib.bindSymbol(cast(void**)&SDL_AndroidGetExternalStoragePath, "SDL_AndroidGetExternalStoragePath"); + } + + lib.bindSymbol(cast(void**)&SDL_GetWindowWMInfo, "SDL_GetWindowWMInfo"); + lib.bindSymbol(cast(void**)&SDL_GetTicks, "SDL_GetTicks"); + lib.bindSymbol(cast(void**)&SDL_GetPerformanceCounter, "SDL_GetPerformanceCounter"); + lib.bindSymbol(cast(void**)&SDL_GetPerformanceFrequency, "SDL_GetPerformanceFrequency"); + lib.bindSymbol(cast(void**)&SDL_Delay, "SDL_Delay"); + lib.bindSymbol(cast(void**)&SDL_AddTimer, "SDL_AddTimer"); + lib.bindSymbol(cast(void**)&SDL_RemoveTimer, "SDL_RemoveTimer"); + lib.bindSymbol(cast(void**)&SDL_GetNumTouchDevices, "SDL_GetNumTouchDevices"); + lib.bindSymbol(cast(void**)&SDL_GetTouchDevice, "SDL_GetTouchDevice"); + lib.bindSymbol(cast(void**)&SDL_GetNumTouchFingers, "SDL_GetNumTouchFingers"); + lib.bindSymbol(cast(void**)&SDL_GetTouchFinger, "SDL_GetTouchFinger"); + lib.bindSymbol(cast(void**)&SDL_GetVersion, "SDL_GetVersion"); + lib.bindSymbol(cast(void**)&SDL_GetRevision, "SDL_GetRevision"); + lib.bindSymbol(cast(void**)&SDL_GetRevisionNumber, "SDL_GetRevisionNumber"); + lib.bindSymbol(cast(void**)&SDL_GetNumVideoDrivers, "SDL_GetNumVideoDrivers"); + lib.bindSymbol(cast(void**)&SDL_GetVideoDriver, "SDL_GetVideoDriver"); + lib.bindSymbol(cast(void**)&SDL_VideoInit, "SDL_VideoInit"); + lib.bindSymbol(cast(void**)&SDL_VideoQuit, "SDL_VideoQuit"); + lib.bindSymbol(cast(void**)&SDL_GetCurrentVideoDriver, "SDL_GetCurrentVideoDriver"); + lib.bindSymbol(cast(void**)&SDL_GetNumVideoDisplays, "SDL_GetNumVideoDisplays"); + lib.bindSymbol(cast(void**)&SDL_GetDisplayName, "SDL_GetDisplayName"); + lib.bindSymbol(cast(void**)&SDL_GetDisplayBounds, "SDL_GetDisplayBounds"); + lib.bindSymbol(cast(void**)&SDL_GetNumDisplayModes, "SDL_GetNumDisplayModes"); + lib.bindSymbol(cast(void**)&SDL_GetDisplayMode, "SDL_GetDisplayMode"); + lib.bindSymbol(cast(void**)&SDL_GetDesktopDisplayMode, "SDL_GetDesktopDisplayMode"); + lib.bindSymbol(cast(void**)&SDL_GetCurrentDisplayMode, "SDL_GetCurrentDisplayMode"); + lib.bindSymbol(cast(void**)&SDL_GetClosestDisplayMode, "SDL_GetClosestDisplayMode"); + lib.bindSymbol(cast(void**)&SDL_GetWindowDisplayIndex, "SDL_GetWindowDisplayIndex"); + lib.bindSymbol(cast(void**)&SDL_SetWindowDisplayMode, "SDL_SetWindowDisplayMode"); + lib.bindSymbol(cast(void**)&SDL_GetWindowDisplayMode, "SDL_GetWindowDisplayMode"); + lib.bindSymbol(cast(void**)&SDL_GetWindowPixelFormat, "SDL_GetWindowPixelFormat"); + lib.bindSymbol(cast(void**)&SDL_CreateWindow, "SDL_CreateWindow"); + lib.bindSymbol(cast(void**)&SDL_CreateWindowFrom, "SDL_CreateWindowFrom"); + lib.bindSymbol(cast(void**)&SDL_GetWindowID, "SDL_GetWindowID"); + lib.bindSymbol(cast(void**)&SDL_GetWindowFromID, "SDL_GetWindowFromID"); + lib.bindSymbol(cast(void**)&SDL_GetWindowFlags, "SDL_GetWindowFlags"); + lib.bindSymbol(cast(void**)&SDL_SetWindowTitle, "SDL_SetWindowTitle"); + lib.bindSymbol(cast(void**)&SDL_GetWindowTitle, "SDL_GetWindowTitle"); + lib.bindSymbol(cast(void**)&SDL_SetWindowIcon, "SDL_SetWindowIcon"); + lib.bindSymbol(cast(void**)&SDL_SetWindowData, "SDL_SetWindowData"); + lib.bindSymbol(cast(void**)&SDL_GetWindowData, "SDL_GetWindowData"); + lib.bindSymbol(cast(void**)&SDL_SetWindowPosition, "SDL_SetWindowPosition"); + lib.bindSymbol(cast(void**)&SDL_GetWindowPosition, "SDL_GetWindowPosition"); + lib.bindSymbol(cast(void**)&SDL_SetWindowSize, "SDL_SetWindowSize"); + lib.bindSymbol(cast(void**)&SDL_GetWindowSize, "SDL_GetWindowSize"); + lib.bindSymbol(cast(void**)&SDL_SetWindowMinimumSize, "SDL_SetWindowMinimumSize"); + lib.bindSymbol(cast(void**)&SDL_GetWindowMinimumSize, "SDL_GetWindowMinimumSize"); + lib.bindSymbol(cast(void**)&SDL_SetWindowMaximumSize, "SDL_SetWindowMaximumSize"); + lib.bindSymbol(cast(void**)&SDL_GetWindowMaximumSize, "SDL_GetWindowMaximumSize"); + lib.bindSymbol(cast(void**)&SDL_SetWindowBordered, "SDL_SetWindowBordered"); + lib.bindSymbol(cast(void**)&SDL_ShowWindow, "SDL_ShowWindow"); + lib.bindSymbol(cast(void**)&SDL_HideWindow, "SDL_HideWindow"); + lib.bindSymbol(cast(void**)&SDL_RaiseWindow, "SDL_RaiseWindow"); + lib.bindSymbol(cast(void**)&SDL_MaximizeWindow, "SDL_MaximizeWindow"); + lib.bindSymbol(cast(void**)&SDL_MinimizeWindow, "SDL_MinimizeWindow"); + lib.bindSymbol(cast(void**)&SDL_RestoreWindow, "SDL_RestoreWindow"); + lib.bindSymbol(cast(void**)&SDL_SetWindowFullscreen, "SDL_SetWindowFullscreen"); + lib.bindSymbol(cast(void**)&SDL_GetWindowSurface, "SDL_GetWindowSurface"); + lib.bindSymbol(cast(void**)&SDL_UpdateWindowSurface, "SDL_UpdateWindowSurface"); + lib.bindSymbol(cast(void**)&SDL_UpdateWindowSurfaceRects, "SDL_UpdateWindowSurfaceRects"); + lib.bindSymbol(cast(void**)&SDL_SetWindowGrab, "SDL_SetWindowGrab"); + lib.bindSymbol(cast(void**)&SDL_GetWindowGrab, "SDL_GetWindowGrab"); + lib.bindSymbol(cast(void**)&SDL_SetWindowBrightness, "SDL_SetWindowBrightness"); + lib.bindSymbol(cast(void**)&SDL_GetWindowBrightness, "SDL_GetWindowBrightness"); + lib.bindSymbol(cast(void**)&SDL_SetWindowGammaRamp, "SDL_SetWindowGammaRamp"); + lib.bindSymbol(cast(void**)&SDL_GetWindowGammaRamp, "SDL_GetWindowGammaRamp"); + lib.bindSymbol(cast(void**)&SDL_DestroyWindow, "SDL_DestroyWindow"); + lib.bindSymbol(cast(void**)&SDL_IsScreenSaverEnabled, "SDL_IsScreenSaverEnabled"); + lib.bindSymbol(cast(void**)&SDL_EnableScreenSaver, "SDL_EnableScreenSaver"); + lib.bindSymbol(cast(void**)&SDL_DisableScreenSaver, "SDL_DisableScreenSaver"); + lib.bindSymbol(cast(void**)&SDL_GL_LoadLibrary, "SDL_GL_LoadLibrary"); + lib.bindSymbol(cast(void**)&SDL_GL_GetProcAddress, "SDL_GL_GetProcAddress"); + lib.bindSymbol(cast(void**)&SDL_GL_UnloadLibrary, "SDL_GL_UnloadLibrary"); + lib.bindSymbol(cast(void**)&SDL_GL_ExtensionSupported, "SDL_GL_ExtensionSupported"); + lib.bindSymbol(cast(void**)&SDL_GL_SetAttribute, "SDL_GL_SetAttribute"); + lib.bindSymbol(cast(void**)&SDL_GL_GetAttribute, "SDL_GL_GetAttribute"); + lib.bindSymbol(cast(void**)&SDL_GL_CreateContext, "SDL_GL_CreateContext"); + lib.bindSymbol(cast(void**)&SDL_GL_MakeCurrent, "SDL_GL_MakeCurrent"); + lib.bindSymbol(cast(void**)&SDL_GL_GetCurrentWindow, "SDL_GL_GetCurrentWindow"); + lib.bindSymbol(cast(void**)&SDL_GL_GetCurrentContext, "SDL_GL_GetCurrentContext"); + lib.bindSymbol(cast(void**)&SDL_GL_SetSwapInterval, "SDL_GL_SetSwapInterval"); + lib.bindSymbol(cast(void**)&SDL_GL_GetSwapInterval, "SDL_GL_GetSwapInterval"); + lib.bindSymbol(cast(void**)&SDL_GL_SwapWindow, "SDL_GL_SwapWindow"); + lib.bindSymbol(cast(void**)&SDL_GL_DeleteContext, "SDL_GL_DeleteContext"); + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl200; + + static if(sdlSupport >= SDLSupport.sdl201) { + lib.bindSymbol(cast(void**)&SDL_GetSystemRAM, "SDL_GetSystemRAM"); + lib.bindSymbol(cast(void**)&SDL_GetBasePath, "SDL_GetBasePath"); + lib.bindSymbol(cast(void**)&SDL_GetPrefPath, "SDL_GetPrefPath"); + lib.bindSymbol(cast(void**)&SDL_UpdateYUVTexture, "SDL_UpdateYUVTexture"); + lib.bindSymbol(cast(void**)&SDL_GL_GetDrawableSize, "SDL_GL_GetDrawableSize"); + + version(Windows) { + lib.bindSymbol(cast(void**)&SDL_Direct3D9GetAdapterIndex, "SDL_Direct3D9GetAdapterIndex") ; + lib.bindSymbol(cast(void**)&SDL_RenderGetD3D9Device, "SDL_RenderGetD3D9Device"); + } + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl201; + } + + static if(sdlSupport >= SDLSupport.sdl202) { + lib.bindSymbol(cast(void**)&SDL_GetDefaultAssertionHandler, "SDL_GetDefaultAssertionHandler"); + lib.bindSymbol(cast(void**)&SDL_GetAssertionHandler, "SDL_GetAssertionHandler"); + lib.bindSymbol(cast(void**)&SDL_HasAVX, "SDL_HasAVX"); + lib.bindSymbol(cast(void**)&SDL_GameControllerAddMappingsFromRW, "SDL_GameControllerAddMappingsFromRW"); + lib.bindSymbol(cast(void**)&SDL_GL_ResetAttributes, "SDL_GL_ResetAttributes"); + + version(Windows) { + lib.bindSymbol(cast(void**)&SDL_DXGIGetOutputInfo, "SDL_DXGIGetOutputInfo"); + } + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl202; + } + + static if(sdlSupport >= SDLSupport.sdl203) { + loadedVersion = SDLSupport.sdl203; + } + + static if(sdlSupport >= SDLSupport.sdl204) { + lib.bindSymbol(cast(void**)&SDL_ClearQueuedAudio, "SDL_ClearQueuedAudio"); + lib.bindSymbol(cast(void**)&SDL_GetQueuedAudioSize, "SDL_GetQueuedAudioSize"); + lib.bindSymbol(cast(void**)&SDL_QueueAudio, "SDL_QueueAudio"); + lib.bindSymbol(cast(void**)&SDL_HasAVX2, "SDL_HasAVX2"); + lib.bindSymbol(cast(void**)&SDL_GameControllerFromInstanceID, "SDL_GameControllerFromInstanceID"); + lib.bindSymbol(cast(void**)&SDL_JoystickCurrentPowerLevel, "SDL_JoystickCurrentPowerLevel"); + lib.bindSymbol(cast(void**)&SDL_JoystickFromInstanceID, "SDL_JoystickFromInstanceID"); + lib.bindSymbol(cast(void**)&SDL_CaptureMouse, "SDL_CaptureMouse"); + lib.bindSymbol(cast(void**)&SDL_GetGlobalMouseState, "SDL_GetGlobalMouseState"); + lib.bindSymbol(cast(void**)&SDL_WarpMouseGlobal, "SDL_WarpMouseGlobal"); + lib.bindSymbol(cast(void**)&SDL_RenderIsClipEnabled, "SDL_RenderIsClipEnabled"); + lib.bindSymbol(cast(void**)&SDL_GetDisplayDPI, "SDL_GetDisplayDPI"); + lib.bindSymbol(cast(void**)&SDL_GetGrabbedWindow, "SDL_GetGrabbedWindow"); + lib.bindSymbol(cast(void**)&SDL_SetWindowHitTest, "SDL_SetWindowHitTest"); + + version(Windows) { + lib.bindSymbol(cast(void**)&SDL_SetWindowsMessageHook, "SDL_SetWindowsMessageHook"); + } + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl204; + } + + static if(sdlSupport >= SDLSupport.sdl205) { + lib.bindSymbol(cast(void**)&SDL_DequeueAudio, "SDL_DequeueAudio"); + lib.bindSymbol(cast(void**)&SDL_GetHintBoolean, "SDL_GetHintBoolean"); + lib.bindSymbol(cast(void**)&SDL_RenderGetIntegerScale, "SDL_RenderGetIntegerScale"); + lib.bindSymbol(cast(void**)&SDL_RenderSetIntegerScale, "SDL_RenderSetIntegerScale"); + lib.bindSymbol(cast(void**)&SDL_CreateRGBSurfaceWithFormat, "SDL_CreateRGBSurfaceWithFormat"); + lib.bindSymbol(cast(void**)&SDL_CreateRGBSurfaceWithFormatFrom, "SDL_CreateRGBSurfaceWithFormatFrom"); + lib.bindSymbol(cast(void**)&SDL_GetDisplayUsableBounds, "SDL_GetDisplayUsableBounds"); + lib.bindSymbol(cast(void**)&SDL_GetWindowBordersSize, "SDL_GetWindowBordersSize"); + lib.bindSymbol(cast(void**)&SDL_GetWindowOpacity, "SDL_GetWindowOpacity"); + lib.bindSymbol(cast(void**)&SDL_SetWindowInputFocus, "SDL_SetWindowInputFocus"); + lib.bindSymbol(cast(void**)&SDL_SetWindowModalFor, "SDL_SetWindowModalFor"); + lib.bindSymbol(cast(void**)&SDL_SetWindowOpacity, "SDL_SetWindowOpacity"); + lib.bindSymbol(cast(void**)&SDL_SetWindowResizable, "SDL_SetWindowResizable"); + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl205; + } + + static if(sdlSupport >= SDLSupport.sdl206) { + lib.bindSymbol(cast(void**)&SDL_ComposeCustomBlendMode, "SDL_ComposeCustomBlendMode"); + lib.bindSymbol(cast(void**)&SDL_HasNEON, "SDL_HasNEON"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetVendor, "SDL_GameControllerGetVendor"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetProduct, "SDL_GameControllerGetProduct"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetProductVersion, "SDL_GameControllerGetProductVersion"); + lib.bindSymbol(cast(void**)&SDL_GameControllerMappingForIndex, "SDL_GameControllerMappingForIndex"); + lib.bindSymbol(cast(void**)&SDL_GameControllerNumMappings, "SDL_GameControllerNumMappings"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetAxisInitialState, "SDL_JoystickGetAxisInitialState"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceVendor, "SDL_JoystickGetDeviceVendor"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceProduct, "SDL_JoystickGetDeviceProduct"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceProductVersion, "SDL_JoystickGetDeviceProductVersion"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceInstanceID, "SDL_JoystickGetDeviceInstanceID"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceType, "SDL_JoystickGetDeviceType"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetProduct, "SDL_JoystickGetProduct"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetProductVersion, "SDL_JoystickGetProductVersion"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetType, "SDL_JoystickGetType"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetVendor, "SDL_JoystickGetVendor"); + lib.bindSymbol(cast(void**)&SDL_LoadFile_RW, "SDL_LoadFile_RW"); + lib.bindSymbol(cast(void**)&SDL_DuplicateSurface, "SDL_DuplicateSurface"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_CreateSurface, "SDL_Vulkan_CreateSurface"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_GetDrawableSize, "SDL_Vulkan_GetDrawableSize"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_GetInstanceExtensions, "SDL_Vulkan_GetInstanceExtensions"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_GetVkGetInstanceProcAddr, "SDL_Vulkan_GetVkGetInstanceProcAddr"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_LoadLibrary, "SDL_Vulkan_LoadLibrary"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_UnloadLibrary, "SDL_Vulkan_UnloadLibrary"); + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl206; + } + + static if(sdlSupport >= SDLSupport.sdl207) { + lib.bindSymbol(cast(void**)&SDL_NewAudioStream, "SDL_NewAudioStream"); + lib.bindSymbol(cast(void**)&SDL_AudioStreamPut, "SDL_AudioStreamPut"); + lib.bindSymbol(cast(void**)&SDL_AudioStreamGet, "SDL_AudioStreamGet"); + lib.bindSymbol(cast(void**)&SDL_AudioStreamAvailable, "SDL_AudioStreamAvailable"); + lib.bindSymbol(cast(void**)&SDL_AudioStreamFlush, "SDL_AudioStreamFlush"); + lib.bindSymbol(cast(void**)&SDL_AudioStreamClear, "SDL_AudioStreamClear"); + lib.bindSymbol(cast(void**)&SDL_FreeAudioStream, "SDL_FreeAudioStream"); + lib.bindSymbol(cast(void**)&SDL_LockJoysticks, "SDL_LockJoysticks"); + lib.bindSymbol(cast(void**)&SDL_UnlockJoysticks, "SDL_UnlockJoysticks"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceProduct, "SDL_JoystickGetDeviceProduct"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceProductVersion, "SDL_JoystickGetDeviceProductVersion"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceInstanceID, "SDL_JoystickGetDeviceInstanceID"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDeviceType, "SDL_JoystickGetDeviceType"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetProduct, "SDL_JoystickGetProduct"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetProductVersion, "SDL_JoystickGetProductVersion"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetType, "SDL_JoystickGetType"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetVendor, "SDL_JoystickGetVendor"); + lib.bindSymbol(cast(void**)&SDL_LoadFile_RW, "SDL_LoadFile_RW"); + lib.bindSymbol(cast(void**)&SDL_DuplicateSurface, "SDL_DuplicateSurface"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_CreateSurface, "SDL_Vulkan_CreateSurface"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_GetDrawableSize, "SDL_Vulkan_GetDrawableSize"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_GetInstanceExtensions, "SDL_Vulkan_GetInstanceExtensions"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_GetVkGetInstanceProcAddr, "SDL_Vulkan_GetVkGetInstanceProcAddr"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_LoadLibrary, "SDL_Vulkan_LoadLibrary"); + lib.bindSymbol(cast(void**)&SDL_Vulkan_UnloadLibrary, "SDL_Vulkan_UnloadLibrary"); + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl207; + } + + static if(sdlSupport >= SDLSupport.sdl208) { + lib.bindSymbol(cast(void**)&SDL_RenderGetMetalLayer, "SDL_RenderGetMetalLayer"); + lib.bindSymbol(cast(void**)&SDL_RenderGetMetalCommandEncoder, "SDL_RenderGetMetalCommandEncoder"); + lib.bindSymbol(cast(void**)&SDL_SetYUVConversionMode, "SDL_SetYUVConversionMode"); + lib.bindSymbol(cast(void**)&SDL_GetYUVConversionMode, "SDL_GetYUVConversionMode"); + lib.bindSymbol(cast(void**)&SDL_GetYUVConversionModeForResolution, "SDL_GetYUVConversionModeForResolution"); + + version(Android) { + lib.bindSymbol(cast(void**)&SDL_IsAndroidTV, "SDL_IsAndroidTV"); + } + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl208; + } + + static if(sdlSupport >= SDLSupport.sdl209) { + lib.bindSymbol(cast(void**)&SDL_HasAVX512F, "SDL_HasAVX512F"); + lib.bindSymbol(cast(void**)&SDL_GameControllerMappingForDeviceIndex, "SDL_GameControllerMappingForDeviceIndex"); + lib.bindSymbol(cast(void**)&SDL_GameControllerRumble, "SDL_GameControllerRumble"); + lib.bindSymbol(cast(void**)&SDL_JoystickRumble, "SDL_JoystickRumble"); + lib.bindSymbol(cast(void**)&SDL_HasColorKey, "SDL_HasColorKey"); + lib.bindSymbol(cast(void**)&SDL_GetDisplayOrientation, "SDL_GetDisplayOrientation"); + + version(Android) { + lib.bindSymbol(cast(void**)&SDL_IsChromebook, "SDL_IsChromebook"); + lib.bindSymbol(cast(void**)&SDL_IsDeXMode, "SDL_IsDeXMode"); + lib.bindSymbol(cast(void**)&SDL_AndroidBackButton, "SDL_AndroidBackButton"); + } + else version(linux) { + lib.bindSymbol(cast(void**)&SDL_LinuxSetThreadPriority, "SDL_LinuxSetThreadPriority"); + } + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl209; + } + + static if(sdlSupport >= SDLSupport.sdl2010) { + lib.bindSymbol(cast(void**)&SDL_SIMDGetAlignment, "SDL_SIMDGetAlignment"); + lib.bindSymbol(cast(void**)&SDL_SIMDAlloc, "SDL_SIMDAlloc"); + lib.bindSymbol(cast(void**)&SDL_SIMDFree, "SDL_SIMDFree"); + lib.bindSymbol(cast(void**)&SDL_GameControllerGetPlayerIndex, "SDL_GameControllerGetPlayerIndex"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetDevicePlayerIndex, "SDL_JoystickGetDevicePlayerIndex"); + lib.bindSymbol(cast(void**)&SDL_JoystickGetPlayerIndex, "SDL_JoystickGetPlayerIndex"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawPointF, "SDL_RenderDrawPointF"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawPointsF, "SDL_RenderDrawPointsF"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawLineF, "SDL_RenderDrawLineF"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawLinesF, "SDL_RenderDrawLinesF"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawRectF, "SDL_RenderDrawRectF"); + lib.bindSymbol(cast(void**)&SDL_RenderDrawRectsF, "SDL_RenderDrawRectsF"); + lib.bindSymbol(cast(void**)&SDL_RenderFillRectF, "SDL_RenderFillRectF"); + lib.bindSymbol(cast(void**)&SDL_RenderFillRectsF, "SDL_RenderFillRectsF"); + lib.bindSymbol(cast(void**)&SDL_RenderCopyF, "SDL_RenderCopyF"); + lib.bindSymbol(cast(void**)&SDL_RenderCopyExF, "SDL_RenderCopyExF"); + lib.bindSymbol(cast(void**)&SDL_RenderFlush, "SDL_RenderFlush");lib.bindSymbol(cast(void**)&SDL_Vulkan_CreateSurface, "SDL_Vulkan_CreateSurface"); + lib.bindSymbol(cast(void**)&SDL_RWsize, "SDL_RWsize"); + lib.bindSymbol(cast(void**)&SDL_RWseek, "SDL_RWseek"); + lib.bindSymbol(cast(void**)&SDL_RWtell, "SDL_RWtell"); + lib.bindSymbol(cast(void**)&SDL_RWread, "SDL_RWread"); + lib.bindSymbol(cast(void**)&SDL_RWwrite, "SDL_RWwrite"); + lib.bindSymbol(cast(void**)&SDL_RWclose, "SDL_RWclose"); + lib.bindSymbol(cast(void**)&SDL_GetTouchDeviceType, "SDL_GetTouchDeviceType"); + + + if(errorCount() != errCount) return SDLSupport.badLibrary; + else loadedVersion = SDLSupport.sdl2010; + } + + return loadedVersion; +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/image.d b/demos/external/wasm_imports/bindbc/sdl/image.d new file mode 100644 index 0000000..8af6e81 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/image.d @@ -0,0 +1,353 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.image; + +version(BindSDL_Image): + +import bindbc.sdl.bind.sdlerror : SDL_GetError, SDL_SetError; +import bindbc.sdl.bind.sdlrender : SDL_Renderer, SDL_Texture; +import bindbc.sdl.bind.sdlrwops : SDL_RWops; +import bindbc.sdl.bind.sdlsurface : SDL_Surface; +import bindbc.sdl.bind.sdlversion : SDL_version, SDL_VERSIONNUM; + +alias IMG_SetError = SDL_SetError; +alias IMG_GetError = SDL_GetError; + +enum SDLImageSupport { + noLibrary, + badLibrary, + sdlImage200 = 200, + sdlImage201, + sdlImage202, +} + +enum ubyte SDL_IMAGE_MAJOR_VERSION = 2; +enum ubyte SDL_IMAGE_MINOR_VERSION = 0; + +version(SDL_Image_202) { + enum sdlImageSupport = SDLImageSupport.sdlImage202; + enum ubyte SDL_IMAGE_PATCHLEVEL = 2; +} +else version(SDL_Image_201) { + enum sdlImageSupport = SDLImageSupport.sdlImage201; + enum ubyte SDL_IMAGE_PATCHLEVEL = 1; +} +else { + enum sdlImageSupport = SDLImageSupport.sdlImage200; + enum ubyte SDL_IMAGE_PATCHLEVEL = 0; +} + +@nogc nothrow void SDL_IMAGE_VERSION(SDL_version* X) +{ + X.major = SDL_IMAGE_MAJOR_VERSION; + X.minor = SDL_IMAGE_MINOR_VERSION; + X.patch = SDL_IMAGE_PATCHLEVEL; +} + +// These were implemented in SDL_image 2.0.2, but are fine for all versions. +enum SDL_IMAGE_COMPILEDVERSION = SDL_VERSIONNUM!(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL); +enum SDL_IMAGE_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z) = SDL_IMAGE_COMPILEDVERSION >= SDL_VERSIONNUM!(X, Y, Z); + +enum { + IMG_INIT_JPG = 0x00000001, + IMG_INIT_PNG = 0x00000002, + IMG_INIT_TIF = 0x00000004, + IMG_INIT_WEBP = 0x00000008, +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + int IMG_Init(int); + int IMG_Quit(); + const(SDL_version)* IMG_Linked_Version(); + SDL_Surface* IMG_LoadTyped_RW(SDL_RWops*,int,const(char)*); + SDL_Surface* IMG_Load(const(char)*); + SDL_Surface* IMG_Load_RW(SDL_RWops*,int); + + SDL_Texture* IMG_LoadTexture(SDL_Renderer*,const(char)*); + SDL_Texture* IMG_LoadTexture_RW(SDL_Renderer*,SDL_RWops*,int); + SDL_Texture* IMG_LoadTextureTyped_RW(SDL_Renderer*,SDL_RWops*,int,const(char)*); + + int IMG_isICO(SDL_RWops*); + int IMG_isCUR(SDL_RWops*); + int IMG_isBMP(SDL_RWops*); + int IMG_isGIF(SDL_RWops*); + int IMG_isJPG(SDL_RWops*); + int IMG_isLBM(SDL_RWops*); + int IMG_isPCX(SDL_RWops*); + int IMG_isPNG(SDL_RWops*); + int IMG_isPNM(SDL_RWops*); + int IMG_isTIF(SDL_RWops*); + int IMG_isXCF(SDL_RWops*); + int IMG_isXPM(SDL_RWops*); + int IMG_isXV(SDL_RWops*); + int IMG_isWEBP(SDL_RWops*); + + SDL_Surface* IMG_LoadICO_RW(SDL_RWops*); + SDL_Surface* IMG_LoadCUR_RW(SDL_RWops*); + SDL_Surface* IMG_LoadBMP_RW(SDL_RWops*); + SDL_Surface* IMG_LoadGIF_RW(SDL_RWops*); + SDL_Surface* IMG_LoadJPG_RW(SDL_RWops*); + SDL_Surface* IMG_LoadLBM_RW(SDL_RWops*); + SDL_Surface* IMG_LoadPCX_RW(SDL_RWops*); + SDL_Surface* IMG_LoadPNG_RW(SDL_RWops*); + SDL_Surface* IMG_LoadPNM_RW(SDL_RWops*); + SDL_Surface* IMG_LoadTGA_RW(SDL_RWops*); + SDL_Surface* IMG_LoadTIF_RW(SDL_RWops*); + SDL_Surface* IMG_LoadXCF_RW(SDL_RWops*); + SDL_Surface* IMG_LoadXPM_RW(SDL_RWops*); + SDL_Surface* IMG_LoadXV_RW(SDL_RWops*); + SDL_Surface* IMG_LoadWEBP_RW(SDL_RWops*); + + SDL_Surface* IMG_ReadXPMFromArray(char**); + + int IMG_SavePNG(SDL_Surface*,const(char)*); + int IMG_SavePNG_RW(SDL_Surface*,SDL_RWops*,int); + + static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { + int IMG_isSVG(SDL_RWops*); + SDL_Surface* IMG_LoadSVG(SDL_RWops*); + int IMG_SaveJPG(SDL_Surface*,const(char)*,int); + int IMG_SaveJPG_RW(SDL_Surface*,SDL_RWops*,int,int); + } + } +} +else { + import bindbc.loader; + + extern(C) @nogc nothrow { + alias pIMG_Init = int function(int); + alias pIMG_Quit = int function(); + alias pIMG_Linked_Version = const(SDL_version)* function(); + alias pIMG_LoadTyped_RW = SDL_Surface* function(SDL_RWops*,int,const(char)*); + alias pIMG_Load = SDL_Surface* function(const(char)*); + alias pIMG_Load_RW = SDL_Surface* function(SDL_RWops*,int); + + alias pIMG_LoadTexture = SDL_Texture* function(SDL_Renderer*,const(char)*); + alias pIMG_LoadTexture_RW = SDL_Texture* function(SDL_Renderer*,SDL_RWops*,int); + alias pIMG_LoadTextureTyped_RW = SDL_Texture* function(SDL_Renderer*,SDL_RWops*,int,const(char)*); + + alias pIMG_isICO = int function(SDL_RWops*); + alias pIMG_isCUR = int function(SDL_RWops*); + alias pIMG_isBMP = int function(SDL_RWops*); + alias pIMG_isGIF = int function(SDL_RWops*); + alias pIMG_isJPG = int function(SDL_RWops*); + alias pIMG_isLBM = int function(SDL_RWops*); + alias pIMG_isPCX = int function(SDL_RWops*); + alias pIMG_isPNG = int function(SDL_RWops*); + alias pIMG_isPNM = int function(SDL_RWops*); + alias pIMG_isTIF = int function(SDL_RWops*); + alias pIMG_isXCF = int function(SDL_RWops*); + alias pIMG_isXPM = int function(SDL_RWops*); + alias pIMG_isXV = int function(SDL_RWops*); + alias pIMG_isWEBP = int function(SDL_RWops*); + + alias pIMG_LoadICO_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadCUR_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadBMP_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadGIF_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadJPG_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadLBM_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadPCX_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadPNG_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadPNM_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadTGA_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadTIF_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadXCF_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadXPM_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadXV_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_LoadWEBP_RW = SDL_Surface* function(SDL_RWops*); + + alias pIMG_ReadXPMFromArray = SDL_Surface* function(char**); + + alias pIMG_SavePNG = int function(SDL_Surface*,const(char)*); + alias pIMG_SavePNG_RW = int function(SDL_Surface*,SDL_RWops*,int); + } + + __gshared { + pIMG_Init IMG_Init; + pIMG_Quit IMG_Quit; + pIMG_Linked_Version IMG_Linked_Version; + pIMG_LoadTyped_RW IMG_LoadTyped_RW; + pIMG_Load IMG_Load; + pIMG_Load_RW IMG_Load_RW; + pIMG_LoadTexture IMG_LoadTexture; + pIMG_LoadTexture_RW IMG_LoadTexture_RW; + pIMG_LoadTextureTyped_RW IMG_LoadTextureTyped_RW; + pIMG_isICO IMG_isICO; + pIMG_isCUR IMG_isCUR; + pIMG_isBMP IMG_isBMP; + pIMG_isGIF IMG_isGIF; + pIMG_isJPG IMG_isJPG; + pIMG_isLBM IMG_isLBM; + pIMG_isPCX IMG_isPCX; + pIMG_isPNG IMG_isPNG; + pIMG_isPNM IMG_isPNM; + pIMG_isTIF IMG_isTIF; + pIMG_isXCF IMG_isXCF; + pIMG_isXPM IMG_isXPM; + pIMG_isXV IMG_isXV; + pIMG_isWEBP IMG_isWEBP; + pIMG_LoadICO_RW IMG_LoadICO_RW; + pIMG_LoadCUR_RW IMG_LoadCUR_RW; + pIMG_LoadBMP_RW IMG_LoadBMP_RW; + pIMG_LoadGIF_RW IMG_LoadGIF_RW; + pIMG_LoadJPG_RW IMG_LoadJPG_RW; + pIMG_LoadLBM_RW IMG_LoadLBM_RW; + pIMG_LoadPCX_RW IMG_LoadPCX_RW; + pIMG_LoadPNG_RW IMG_LoadPNG_RW; + pIMG_LoadPNM_RW IMG_LoadPNM_RW; + pIMG_LoadTGA_RW IMG_LoadTGA_RW; + pIMG_LoadTIF_RW IMG_LoadTIF_RW; + pIMG_LoadXCF_RW IMG_LoadXCF_RW; + pIMG_LoadXPM_RW IMG_LoadXPM_RW; + pIMG_LoadXV_RW IMG_LoadXV_RW; + pIMG_LoadWEBP_RW IMG_LoadWEBP_RW; + pIMG_ReadXPMFromArray IMG_ReadXPMFromArray; + pIMG_SavePNG IMG_SavePNG; + pIMG_SavePNG_RW IMG_SavePNG_RW; + } + + static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { + extern(C) @nogc nothrow { + alias pIMG_isSVG = int function(SDL_RWops*); + alias pIMG_LoadSVG_RW = SDL_Surface* function(SDL_RWops*); + alias pIMG_SaveJPG = int function(SDL_Surface*,const(char)*,int); + alias pIMG_SaveJPG_RW = int function(SDL_Surface*,SDL_RWops*,int,int); + } + + __gshared { + pIMG_isSVG IMG_isSVG; + pIMG_LoadSVG_RW IMG_LoadSVG; + pIMG_SaveJPG IMG_SaveJPG; + pIMG_SaveJPG_RW IMG_SaveJPG_RW; + } + } + + private { + __gshared SharedLib lib; + __gshared SDLImageSupport loadedVersion; + } + + void unloadSDLImage() + { + if(lib != invalidHandle) { + lib.unload(); + } + } + + SDLImageSupport loadedSDLImageVersion() { return loadedVersion; } + + bool isSDLImageLoaded() + { + return lib != invalidHandle; + } + + + SDLImageSupport loadSDLImage() + { + version(Windows) { + const(char)[][1] libNames = ["SDL2_image.dll"]; + } + else version(OSX) { + const(char)[][6] libNames = [ + "libSDL2_image.dylib", + "/usr/local/lib/libSDL2_image.dylib", + "../Frameworks/SDL2_image.framework/SDL2_image", + "/Library/Frameworks/SDL2_image.framework/SDL2_image", + "/System/Library/Frameworks/SDL2_image.framework/SDL2_image", + "/opt/local/lib/libSDL2_image.dylib" + ]; + } + else version(Posix) { + const(char)[][6] libNames = [ + "libSDL2_image.so", + "/usr/local/lib/libSDL2_image.so", + "libSDL2_image-2.0.so", + "/usr/local/lib/libSDL2_image-2.0.so", + "libSDL2_image-2.0.so.0", + "/usr/local/lib/libSDL2_image-2.0.so.0" + ]; + } + else static assert(0, "bindbc-sdl is not yet supported on this platform."); + + SDLImageSupport ret; + foreach(name; libNames) { + ret = loadSDLImage(name.ptr); + if(ret != SDLImageSupport.noLibrary) break; + } + return ret; + } + + SDLImageSupport loadSDLImage(const(char)* libName) + { + lib = load(libName); + if(lib == invalidHandle) { + return SDLImageSupport.noLibrary; + } + + auto errCount = errorCount(); + loadedVersion = SDLImageSupport.badLibrary; + + lib.bindSymbol(cast(void**)&IMG_Init,"IMG_Init"); + lib.bindSymbol(cast(void**)&IMG_Quit,"IMG_Quit"); + lib.bindSymbol(cast(void**)&IMG_Linked_Version,"IMG_Linked_Version"); + lib.bindSymbol(cast(void**)&IMG_LoadTyped_RW,"IMG_LoadTyped_RW"); + lib.bindSymbol(cast(void**)&IMG_Load,"IMG_Load"); + lib.bindSymbol(cast(void**)&IMG_Load_RW,"IMG_Load_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadTexture,"IMG_LoadTexture"); + lib.bindSymbol(cast(void**)&IMG_LoadTexture_RW,"IMG_LoadTexture_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadTextureTyped_RW,"IMG_LoadTextureTyped_RW"); + lib.bindSymbol(cast(void**)&IMG_isICO,"IMG_isICO"); + lib.bindSymbol(cast(void**)&IMG_isCUR,"IMG_isCUR"); + lib.bindSymbol(cast(void**)&IMG_isBMP,"IMG_isBMP"); + lib.bindSymbol(cast(void**)&IMG_isGIF,"IMG_isGIF"); + lib.bindSymbol(cast(void**)&IMG_isJPG,"IMG_isJPG"); + lib.bindSymbol(cast(void**)&IMG_isLBM,"IMG_isLBM"); + lib.bindSymbol(cast(void**)&IMG_isPCX,"IMG_isPCX"); + lib.bindSymbol(cast(void**)&IMG_isPNG,"IMG_isPNG"); + lib.bindSymbol(cast(void**)&IMG_isPNM,"IMG_isPNM"); + lib.bindSymbol(cast(void**)&IMG_isTIF,"IMG_isTIF"); + lib.bindSymbol(cast(void**)&IMG_isXCF,"IMG_isXCF"); + lib.bindSymbol(cast(void**)&IMG_isXPM,"IMG_isXPM"); + lib.bindSymbol(cast(void**)&IMG_isXV,"IMG_isXV"); + lib.bindSymbol(cast(void**)&IMG_isWEBP,"IMG_isWEBP"); + lib.bindSymbol(cast(void**)&IMG_LoadICO_RW,"IMG_LoadICO_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadCUR_RW,"IMG_LoadCUR_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadBMP_RW,"IMG_LoadBMP_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadGIF_RW,"IMG_LoadGIF_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadJPG_RW,"IMG_LoadJPG_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadLBM_RW,"IMG_LoadLBM_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadPCX_RW,"IMG_LoadPCX_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadPNG_RW,"IMG_LoadPNG_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadPNM_RW,"IMG_LoadPNM_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadTGA_RW,"IMG_LoadTGA_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadTIF_RW,"IMG_LoadTIF_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadXCF_RW,"IMG_LoadXCF_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadXPM_RW,"IMG_LoadXPM_RW"); + lib.bindSymbol(cast(void**)&IMG_LoadXV_RW,"IMG_LoadXV_RW"); + lib.bindSymbol(cast(void**)&IMG_isXV,"IMG_isXV"); + lib.bindSymbol(cast(void**)&IMG_LoadWEBP_RW,"IMG_LoadWEBP_RW"); + lib.bindSymbol(cast(void**)&IMG_SavePNG,"IMG_SavePNG"); + lib.bindSymbol(cast(void**)&IMG_SavePNG_RW,"IMG_SavePNG_RW"); + + if(errorCount() != errCount) return SDLImageSupport.badLibrary; + else loadedVersion = SDLImageSupport.sdlImage200; + + static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { + lib.bindSymbol(cast(void**)&IMG_isSVG,"IMG_isSVG"); + lib.bindSymbol(cast(void**)&IMG_LoadSVG,"IMG_LoadSVG_RW"); + lib.bindSymbol(cast(void**)&IMG_SaveJPG,"IMG_SaveJPG"); + lib.bindSymbol(cast(void**)&IMG_SaveJPG_RW,"IMG_SaveJPG_RW"); + + if(errorCount() != errCount) return SDLImageSupport.badLibrary; + else loadedVersion = SDLImageSupport.sdlImage202; + } + + return loadedVersion; + } +} diff --git a/demos/external/wasm_imports/bindbc/sdl/mixer.d b/demos/external/wasm_imports/bindbc/sdl/mixer.d new file mode 100644 index 0000000..ed531b5 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/mixer.d @@ -0,0 +1,569 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.mixer; + +version(BindSDL_Mixer): + +import bindbc.sdl.config; +import bindbc.sdl.bind.sdlaudio : AUDIO_S16LSB, SDL_MIX_MAXVOLUME; +import bindbc.sdl.bind.sdlerror : SDL_GetError, SDL_SetError, SDL_ClearError; +import bindbc.sdl.bind.sdlrwops : SDL_RWops, SDL_RWFromFile; +import bindbc.sdl.bind.sdlstdinc : SDL_bool; +import bindbc.sdl.bind.sdlversion : SDL_version, SDL_VERSIONNUM; + +alias Mix_SetError = SDL_SetError; +alias Mix_GetError = SDL_GetError; +alias Mix_ClearError = SDL_ClearError; + +enum SDLMixerSupport { + noLibrary, + badLibrary, + sdlMixer200 = 200, + sdlMixer201 = 201, + sdlMixer202 = 202, +} + +enum ubyte SDL_MIXER_MAJOR_VERSION = 2; +enum ubyte SDL_MIXER_MINOR_VERSION = 0; + +version(SDL_Mixer_202) { + enum sdlMixerSupport = SDLMixerSupport.sdlMixer202; + enum ubyte SDL_MIXER_PATCHLEVEL = 2; +} +else version(SDL_Mixer_201) { + enum sdlMixerSupport = SDLMixerSupport.sdlMixer201; + enum ubyte SDL_MIXER_PATCHLEVEL = 1; +} +else { + enum sdlMixerSupport = SDLMixerSupport.sdlMixer200; + enum ubyte SDL_MIXER_PATCHLEVEL = 0; +} + +alias MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION; +alias MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION; +alias MIX_PATCH_LEVEL = SDL_MIXER_PATCHLEVEL; + +@nogc nothrow void SDL_MIXER_VERSION(SDL_version* X) +{ + X.major = SDL_MIXER_MAJOR_VERSION; + X.minor = SDL_MIXER_MINOR_VERSION; + X.patch = SDL_MIXER_PATCHLEVEL; +} +alias SDL_MIX_VERSION = SDL_MIX_MAXVOLUME; + +// These were implemented in SDL_mixer 2.0.2, but are fine for all versions. +enum SDL_MIXER_COMPILEDVERSION = SDL_VERSIONNUM!(SDL_MIXER_MAJOR_VERSION, SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL); +enum SDL_MIXER_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z) = SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM!(X, Y, Z); + +static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) { + enum Mix_InitFlags { + MIX_INIT_FLAC = 0x00000001, + MIX_INIT_MOD = 0x00000002, + MIX_INIT_MP3 = 0x00000008, + MIX_INIT_OGG = 0x00000010, + MIX_INIT_MID = 0x00000020, + } +} +else { + enum Mix_InitFlags { + MIX_INIT_FLAC = 0x00000001, + MIX_INIT_MOD = 0x00000002, + MIX_INIT_MODPLUG = 0x00000004, + MIX_INIT_MP3 = 0x00000008, + MIX_INIT_OGG = 0x00000010, + MIX_INIT_FLUIDSYNTH = 0x00000020, + } +} +mixin(expandEnum!Mix_InitFlags); + +enum { + MIX_CHANNELS = 8, + MIX_DEFAULT_FREQUENCY = 22050, + MIX_DEFAULT_CHANNELS = 2, + MIX_MAX_VOLUME = 128, + MIX_CHANNEL_POST = -2, +} + +version(LittleEndian) { + enum MIX_DEFAULT_FORMAT = AUDIO_S16LSB; +} else { + enum MIX_DEFAULT_FORMAT = AUDIO_S16MSB; +} + +struct Mix_Chunk { + int allocated; + ubyte* abuf; + uint alen; + ubyte volume; +} + +enum Mix_Fading { + MIX_NO_FADING, + MIX_FADING_OUT, + MIX_FADING_IN +} +mixin(expandEnum!Mix_Fading); + +static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) { + enum Mix_MusicType { + MUS_NONE, + MUS_CMD, + MUS_WAV, + MUS_MOD, + MUS_MID, + MUS_OGG, + MUS_MP3, + MUS_MP3_MAD_UNUSED, + MUS_FLAC, + MUS_MODPLUG_UNUSED, + } +} +else { + enum Mix_MusicType { + MUS_NONE, + MUS_CMD, + MUS_WAV, + MUS_MOD, + MUS_MID, + MUS_OGG, + MUS_MP3, + MUS_MP3_MAD, + MUS_FLAC, + MUS_MODPLUG, + } +} +mixin(expandEnum!Mix_MusicType); + +struct Mix_Music; +enum MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED"; + +extern(C) nothrow { + alias Mix_EffectFunc_t = void function(int,void*,int,void*); + alias Mix_EffectDone_t = void function(int,void*); + + // These aren't in SDL_mixer.h and are just here as a convenient and + // visible means to add the proper attributes these callbacks. + alias callbackI = void function(int); + alias callbackVUi8I = void function(void*,ubyte*,int); + alias callbackN = void function(); +} + +@nogc nothrow { + Mix_Chunk* Mix_LoadWAV(const(char)* file) { + pragma(inline, true); + return Mix_LoadWAV_RW(SDL_RWFromFile(file,"rb"),1); + } + + int Mix_PlayChannel(int channel,Mix_Chunk* chunk,int loops) { + pragma(inline, true); + return Mix_PlayChannelTimed(channel,chunk,loops,-1); + } + + int Mix_FadeInChannel(int channel,Mix_Chunk* chunk,int loops,int ms) { + pragma(inline, true); + return Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1); + } +} + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + const(SDL_version)* Mix_Linked_Version(); + int Mix_Init(int); + void Mix_Quit(); + int Mix_OpenAudio(int,ushort,int,int); + int Mix_AllocateChannels(int); + int Mix_QuerySpec(int*,ushort*,int*); + Mix_Chunk* Mix_LoadWAV_RW(SDL_RWops*,int); + Mix_Music* Mix_LoadMUS(const(char)*); + Mix_Music* Mix_LoadMUS_RW(SDL_RWops*,int); + Mix_Music* Mix_LoadMUSType_RW(SDL_RWops*,Mix_MusicType,int); + Mix_Chunk* Mix_QuickLoad_WAV(ubyte*); + Mix_Chunk* Mix_QuickLoad_RAW(ubyte*,uint); + void Mix_FreeChunk(Mix_Chunk*); + void Mix_FreeMusic(Mix_Music*); + int Mix_GetNumChunkDecoders(); + const(char)* Mix_GetChunkDecoder(int); + int Mix_GetNumMusicDecoders(); + const(char)* Mix_GetMusicDecoder(int); + Mix_MusicType Mix_GetMusicType(const(Mix_Music)*); + void Mix_SetPostMix(callbackVUi8I,void*); + void Mix_HookMusic(callbackVUi8I,void*); + void Mix_HookMusicFinished(callbackN); + void* Mix_GetMusicHookData(); + void Mix_ChannelFinished(callbackI); + int Mix_RegisterEffect(int,Mix_EffectFunc_t,Mix_EffectDone_t,void*); + int Mix_UnregisterEffect(int,Mix_EffectFunc_t); + int Mix_UnregisterAllEffects(int); + int Mix_SetPanning(int,ubyte,ubyte); + int Mix_SetPosition(int,short,ubyte); + int Mix_SetDistance(int,ubyte); + int Mix_SetReverseStereo(int,int); + int Mix_ReserveChannels(int); + int Mix_GroupChannel(int,int); + int Mix_GroupChannels(int,int,int); + int Mix_GroupAvailable(int); + int Mix_GroupCount(int); + int Mix_GroupOldest(int); + int Mix_GroupNewer(int); + int Mix_PlayChannelTimed(int,Mix_Chunk*,int,int); + int Mix_PlayMusic(Mix_Music*,int); + int Mix_FadeInMusic(Mix_Music*,int,int); + int Mix_FadeInMusicPos(Mix_Music*,int,int,double); + int Mix_FadeInChannelTimed(int,Mix_Chunk*,int,int,int); + int Mix_Volume(int,int); + int Mix_VolumeChunk(Mix_Chunk*,int); + int Mix_VolumeMusic(int); + int Mix_HaltChannel(int); + int Mix_HaltGroup(int); + int Mix_HaltMusic(); + int Mix_ExpireChannel(int,int); + int Mix_FadeOutChannel(int,int); + int Mix_FadeOutGroup(int,int); + int Mix_FadeOutMusic(int); + Mix_Fading Mix_FadingMusic(); + Mix_Fading Mix_FadingChannel(int); + void Mix_Pause(int); + void Mix_Resume(int); + int Mix_Paused(int); + void Mix_PauseMusic(); + void Mix_ResumeMusic(); + void Mix_RewindMusic(); + int Mix_PausedMusic(); + int Mix_SetMusicPosition(double); + int Mix_Playing(int); + int Mix_PlayingMusic(); + int Mix_SetMusicCMD(in char*); + int Mix_SetSynchroValue(int); + int Mix_GetSynchroValue(); + Mix_Chunk* Mix_GetChunk(int); + void Mix_CloseAudio(); + + static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) { + int Mix_OpenAudioDevice(int,ushort,int,int,const(char)*,int); + SDL_bool Mix_HasChunkDecoder(const(char)*); + + // Declared in SDL_mixer.h, but not implemented + // SDL_bool Mix_HasMusicDecoder(const(char)*); + } + } +} +else { + import bindbc.loader; + + extern(C) @nogc nothrow { + alias pMix_Linked_Version = const(SDL_version)* function(); + alias pMix_Init = int function(int); + alias pMix_Quit = void function(); + alias pMix_OpenAudio = int function(int,ushort,int,int); + alias pMix_AllocateChannels = int function(int); + alias pMix_QuerySpec = int function(int*,ushort*,int*); + alias pMix_LoadWAV_RW = Mix_Chunk* function(SDL_RWops*,int); + alias pMix_LoadMUS = Mix_Music* function(const(char)*); + alias pMix_LoadMUS_RW = Mix_Music* function(SDL_RWops*,int); + alias pMix_LoadMUSType_RW = Mix_Music* function(SDL_RWops*,Mix_MusicType,int); + alias pMix_QuickLoad_WAV = Mix_Chunk* function(ubyte*); + alias pMix_QuickLoad_RAW = Mix_Chunk* function(ubyte*,uint); + alias pMix_FreeChunk = void function(Mix_Chunk*); + alias pMix_FreeMusic = void function(Mix_Music*); + alias pMix_GetNumChunkDecoders = int function(); + alias pMix_GetChunkDecoder = const(char)* function(int); + alias pMix_GetNumMusicDecoders = int function(); + alias pMix_GetMusicDecoder = const(char)* function(int); + alias pMix_GetMusicType = Mix_MusicType function(const(Mix_Music)*); + alias pMix_SetPostMix = void function(callbackVUi8I,void*); + alias pMix_HookMusic = void function(callbackVUi8I,void*); + alias pMix_HookMusicFinished = void function(callbackN); + alias pMix_GetMusicHookData = void* function(); + alias pMix_ChannelFinished = void function(callbackI); + alias pMix_RegisterEffect = int function(int,Mix_EffectFunc_t,Mix_EffectDone_t,void*); + alias pMix_UnregisterEffect = int function(int,Mix_EffectFunc_t); + alias pMix_UnregisterAllEffects = int function(int); + alias pMix_SetPanning = int function(int,ubyte,ubyte); + alias pMix_SetPosition = int function(int,short,ubyte); + alias pMix_SetDistance = int function(int,ubyte); + alias pMix_SetReverseStereo = int function(int,int); + alias pMix_ReserveChannels = int function(int); + alias pMix_GroupChannel = int function(int,int); + alias pMix_GroupChannels = int function(int,int,int); + alias pMix_GroupAvailable = int function(int); + alias pMix_GroupCount = int function(int); + alias pMix_GroupOldest = int function(int); + alias pMix_GroupNewer = int function(int); + alias pMix_PlayChannelTimed = int function(int,Mix_Chunk*,int,int); + alias pMix_PlayMusic = int function(Mix_Music*,int); + alias pMix_FadeInMusic = int function(Mix_Music*,int,int); + alias pMix_FadeInMusicPos = int function(Mix_Music*,int,int,double); + alias pMix_FadeInChannelTimed = int function(int,Mix_Chunk*,int,int,int); + alias pMix_Volume = int function(int,int); + alias pMix_VolumeChunk = int function(Mix_Chunk*,int); + alias pMix_VolumeMusic = int function(int); + alias pMix_HaltChannel = int function(int); + alias pMix_HaltGroup = int function(int); + alias pMix_HaltMusic = int function(); + alias pMix_ExpireChannel = int function(int,int); + alias pMix_FadeOutChannel = int function(int,int); + alias pMix_FadeOutGroup = int function(int,int); + alias pMix_FadeOutMusic = int function(int); + alias pMix_FadingMusic = Mix_Fading function(); + alias pMix_FadingChannel = Mix_Fading function(int); + alias pMix_Pause = void function(int); + alias pMix_Resume = void function(int); + alias pMix_Paused = int function(int); + alias pMix_PauseMusic = void function(); + alias pMix_ResumeMusic = void function(); + alias pMix_RewindMusic = void function(); + alias pMix_PausedMusic = int function(); + alias pMix_SetMusicPosition = int function(double); + alias pMix_Playing = int function(int); + alias pMix_PlayingMusic = int function(); + alias pMix_SetMusicCMD = int function(in char*); + alias pMix_SetSynchroValue = int function(int); + alias pMix_GetSynchroValue = int function(); + alias pMix_GetChunk = Mix_Chunk* function(int); + alias pMix_CloseAudio = void function(); + } + + __gshared { + pMix_Linked_Version Mix_Linked_Version; + pMix_Init Mix_Init; + pMix_Quit Mix_Quit; + pMix_OpenAudio Mix_OpenAudio; + pMix_AllocateChannels Mix_AllocateChannels; + pMix_QuerySpec Mix_QuerySpec; + pMix_LoadWAV_RW Mix_LoadWAV_RW; + pMix_LoadMUS Mix_LoadMUS; + pMix_LoadMUS_RW Mix_LoadMUS_RW; + pMix_LoadMUSType_RW Mix_LoadMUSType_RW; + pMix_QuickLoad_WAV Mix_QuickLoad_WAV; + pMix_QuickLoad_RAW Mix_QuickLoad_RAW; + pMix_FreeChunk Mix_FreeChunk; + pMix_FreeMusic Mix_FreeMusic; + pMix_GetNumChunkDecoders Mix_GetNumChunkDecoders; + pMix_GetChunkDecoder Mix_GetChunkDecoder; + pMix_GetNumMusicDecoders Mix_GetNumMusicDecoders; + pMix_GetMusicDecoder Mix_GetMusicDecoder; + pMix_GetMusicType Mix_GetMusicType; + pMix_SetPostMix Mix_SetPostMix; + pMix_HookMusic Mix_HookMusic; + pMix_HookMusicFinished Mix_HookMusicFinished; + pMix_GetMusicHookData Mix_GetMusicHookData; + pMix_ChannelFinished Mix_ChannelFinished; + pMix_RegisterEffect Mix_RegisterEffect; + pMix_UnregisterEffect Mix_UnregisterEffect; + pMix_UnregisterAllEffects Mix_UnregisterAllEffects; + pMix_SetPanning Mix_SetPanning; + pMix_SetPosition Mix_SetPosition; + pMix_SetDistance Mix_SetDistance; + pMix_SetReverseStereo Mix_SetReverseStereo; + pMix_ReserveChannels Mix_ReserveChannels; + pMix_GroupChannel Mix_GroupChannel; + pMix_GroupChannels Mix_GroupChannels; + pMix_GroupAvailable Mix_GroupAvailable; + pMix_GroupCount Mix_GroupCount; + pMix_GroupOldest Mix_GroupOldest; + pMix_GroupNewer Mix_GroupNewer; + pMix_PlayChannelTimed Mix_PlayChannelTimed; + pMix_PlayMusic Mix_PlayMusic; + pMix_FadeInMusic Mix_FadeInMusic; + pMix_FadeInMusicPos Mix_FadeInMusicPos; + pMix_FadeInChannelTimed Mix_FadeInChannelTimed; + pMix_Volume Mix_Volume; + pMix_VolumeChunk Mix_VolumeChunk; + pMix_VolumeMusic Mix_VolumeMusic; + pMix_HaltChannel Mix_HaltChannel; + pMix_HaltGroup Mix_HaltGroup; + pMix_HaltMusic Mix_HaltMusic; + pMix_ExpireChannel Mix_ExpireChannel; + pMix_FadeOutChannel Mix_FadeOutChannel; + pMix_FadeOutGroup Mix_FadeOutGroup; + pMix_FadeOutMusic Mix_FadeOutMusic; + pMix_FadingMusic Mix_FadingMusic; + pMix_FadingChannel Mix_FadingChannel; + pMix_Pause Mix_Pause; + pMix_Resume Mix_Resume; + pMix_Paused Mix_Paused; + pMix_PauseMusic Mix_PauseMusic; + pMix_ResumeMusic Mix_ResumeMusic; + pMix_RewindMusic Mix_RewindMusic; + pMix_PausedMusic Mix_PausedMusic; + pMix_SetMusicPosition Mix_SetMusicPosition; + pMix_Playing Mix_Playing; + pMix_PlayingMusic Mix_PlayingMusic; + pMix_SetMusicCMD Mix_SetMusicCMD; + pMix_SetSynchroValue Mix_SetSynchroValue; + pMix_GetSynchroValue Mix_GetSynchroValue; + pMix_GetChunk Mix_GetChunk; + pMix_CloseAudio Mix_CloseAudio; + } + + + static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) { + extern(C) @nogc nothrow { + alias pMix_OpenAudioDevice = int function(int,ushort,int,int,const(char)*,int); + alias pMix_HasChunkDecoder = SDL_bool function(const(char)*); + + // Declared in SDL_mixer.h, but not implemented + //alias pMix_HasMusicDecoder = SDL_bool function(const(char)*); + } + + __gshared { + pMix_OpenAudioDevice Mix_OpenAudioDevice; + pMix_HasChunkDecoder Mix_HasChunkDecoder; + //pMix_HasMusicDecoder Mix_HasMusicDecoder; + } + } + + private { + SharedLib lib; + SDLMixerSupport loadedVersion; + } + + void unloadSDLMixer() + { + if(lib != invalidHandle) { + lib.unload(); + } + } + + SDLMixerSupport loadedSDLMixerVersion() { return loadedVersion; } + + bool isSDLMixerLoaded() + { + return lib != invalidHandle; + } + + + SDLMixerSupport loadSDLMixer() + { + version(Windows) { + const(char)[][1] libNames = ["SDL2_mixer.dll"]; + } + else version(OSX) { + const(char)[][6] libNames = [ + "libSDL2_mixer.dylib", + "/usr/local/lib/libSDL2_mixer.dylib", + "../Frameworks/SDL2_mixer.framework/SDL2_mixer", + "/Library/Frameworks/SDL2_mixer.framework/SDL2_mixer", + "/System/Library/Frameworks/SDL2_mixer.framework/SDL2_mixer", + "/opt/local/lib/libSDL2_mixer.dylib" + ]; + } + else version(Posix) { + const(char)[][6] libNames = [ + "libSDL2_mixer.so", + "/usr/local/lib/libSDL2_mixer.so", + "libSDL2-2.0_mixer.so", + "/usr/local/lib/libSDL2-2.0_mixer.so", + "libSDL2-2.0_mixer.so.0", + "/usr/local/lib/libSDL2-2.0_mixer.so.0" + ]; + } + else static assert(0, "bindbc-sdl is not yet supported on this platform."); + + SDLMixerSupport ret; + foreach(name; libNames) { + ret = loadSDLMixer(name.ptr); + if(ret != SDLMixerSupport.noLibrary) break; + } + return ret; + } + + SDLMixerSupport loadSDLMixer(const(char)* libName) + { + lib = load(libName); + if(lib == invalidHandle) { + return SDLMixerSupport.noLibrary; + } + + auto errCount = errorCount(); + loadedVersion = SDLMixerSupport.badLibrary; + + lib.bindSymbol(cast(void**)&Mix_Linked_Version,"Mix_Linked_Version"); + lib.bindSymbol(cast(void**)&Mix_Init,"Mix_Init"); + lib.bindSymbol(cast(void**)&Mix_Quit,"Mix_Quit"); + lib.bindSymbol(cast(void**)&Mix_OpenAudio,"Mix_OpenAudio"); + lib.bindSymbol(cast(void**)&Mix_AllocateChannels,"Mix_AllocateChannels"); + lib.bindSymbol(cast(void**)&Mix_QuerySpec,"Mix_QuerySpec"); + lib.bindSymbol(cast(void**)&Mix_LoadWAV_RW,"Mix_LoadWAV_RW"); + lib.bindSymbol(cast(void**)&Mix_LoadMUS,"Mix_LoadMUS"); + lib.bindSymbol(cast(void**)&Mix_LoadMUS_RW,"Mix_LoadMUS_RW"); + lib.bindSymbol(cast(void**)&Mix_LoadMUSType_RW,"Mix_LoadMUSType_RW"); + lib.bindSymbol(cast(void**)&Mix_QuickLoad_WAV,"Mix_QuickLoad_WAV"); + lib.bindSymbol(cast(void**)&Mix_QuickLoad_RAW,"Mix_QuickLoad_RAW"); + lib.bindSymbol(cast(void**)&Mix_FreeChunk,"Mix_FreeChunk"); + lib.bindSymbol(cast(void**)&Mix_FreeMusic,"Mix_FreeMusic"); + lib.bindSymbol(cast(void**)&Mix_GetNumChunkDecoders,"Mix_GetNumChunkDecoders"); + lib.bindSymbol(cast(void**)&Mix_GetChunkDecoder,"Mix_GetChunkDecoder"); + lib.bindSymbol(cast(void**)&Mix_GetNumMusicDecoders,"Mix_GetNumMusicDecoders"); + lib.bindSymbol(cast(void**)&Mix_GetMusicDecoder,"Mix_GetMusicDecoder"); + lib.bindSymbol(cast(void**)&Mix_GetMusicType,"Mix_GetMusicType"); + lib.bindSymbol(cast(void**)&Mix_SetPostMix,"Mix_SetPostMix"); + lib.bindSymbol(cast(void**)&Mix_HookMusic,"Mix_HookMusic"); + lib.bindSymbol(cast(void**)&Mix_HookMusicFinished,"Mix_HookMusicFinished"); + lib.bindSymbol(cast(void**)&Mix_GetMusicHookData,"Mix_GetMusicHookData"); + lib.bindSymbol(cast(void**)&Mix_ChannelFinished,"Mix_ChannelFinished"); + lib.bindSymbol(cast(void**)&Mix_RegisterEffect,"Mix_RegisterEffect"); + lib.bindSymbol(cast(void**)&Mix_UnregisterEffect,"Mix_UnregisterEffect"); + lib.bindSymbol(cast(void**)&Mix_UnregisterAllEffects,"Mix_UnregisterAllEffects"); + lib.bindSymbol(cast(void**)&Mix_SetPanning,"Mix_SetPanning"); + lib.bindSymbol(cast(void**)&Mix_SetPosition,"Mix_SetPosition"); + lib.bindSymbol(cast(void**)&Mix_SetDistance,"Mix_SetDistance"); + lib.bindSymbol(cast(void**)&Mix_SetReverseStereo,"Mix_SetReverseStereo"); + lib.bindSymbol(cast(void**)&Mix_ReserveChannels,"Mix_ReserveChannels"); + lib.bindSymbol(cast(void**)&Mix_GroupChannel,"Mix_GroupChannel"); + lib.bindSymbol(cast(void**)&Mix_GroupChannels,"Mix_GroupChannels"); + lib.bindSymbol(cast(void**)&Mix_GroupAvailable,"Mix_GroupAvailable"); + lib.bindSymbol(cast(void**)&Mix_GroupCount,"Mix_GroupCount"); + lib.bindSymbol(cast(void**)&Mix_GroupOldest,"Mix_GroupOldest"); + lib.bindSymbol(cast(void**)&Mix_GroupNewer,"Mix_GroupNewer"); + lib.bindSymbol(cast(void**)&Mix_PlayChannelTimed,"Mix_PlayChannelTimed"); + lib.bindSymbol(cast(void**)&Mix_PlayMusic,"Mix_PlayMusic"); + lib.bindSymbol(cast(void**)&Mix_FadeInMusic,"Mix_FadeInMusic"); + lib.bindSymbol(cast(void**)&Mix_FadeInMusicPos,"Mix_FadeInMusicPos"); + lib.bindSymbol(cast(void**)&Mix_FadeInChannelTimed,"Mix_FadeInChannelTimed"); + lib.bindSymbol(cast(void**)&Mix_Volume,"Mix_Volume"); + lib.bindSymbol(cast(void**)&Mix_VolumeChunk,"Mix_VolumeChunk"); + lib.bindSymbol(cast(void**)&Mix_VolumeMusic,"Mix_VolumeMusic"); + lib.bindSymbol(cast(void**)&Mix_HaltChannel,"Mix_HaltChannel"); + lib.bindSymbol(cast(void**)&Mix_HaltGroup,"Mix_HaltGroup"); + lib.bindSymbol(cast(void**)&Mix_HaltMusic,"Mix_HaltMusic"); + lib.bindSymbol(cast(void**)&Mix_ExpireChannel,"Mix_ExpireChannel"); + lib.bindSymbol(cast(void**)&Mix_FadeOutChannel,"Mix_FadeOutChannel"); + lib.bindSymbol(cast(void**)&Mix_FadeOutGroup,"Mix_FadeOutGroup"); + lib.bindSymbol(cast(void**)&Mix_FadeOutMusic,"Mix_FadeOutMusic"); + lib.bindSymbol(cast(void**)&Mix_FadingMusic,"Mix_FadingMusic"); + lib.bindSymbol(cast(void**)&Mix_FadingChannel,"Mix_FadingChannel"); + lib.bindSymbol(cast(void**)&Mix_Pause,"Mix_Pause"); + lib.bindSymbol(cast(void**)&Mix_Resume,"Mix_Resume"); + lib.bindSymbol(cast(void**)&Mix_Paused,"Mix_Paused"); + lib.bindSymbol(cast(void**)&Mix_PauseMusic,"Mix_PauseMusic"); + lib.bindSymbol(cast(void**)&Mix_ResumeMusic,"Mix_ResumeMusic"); + lib.bindSymbol(cast(void**)&Mix_RewindMusic,"Mix_RewindMusic"); + lib.bindSymbol(cast(void**)&Mix_PausedMusic,"Mix_PausedMusic"); + lib.bindSymbol(cast(void**)&Mix_SetMusicPosition,"Mix_SetMusicPosition"); + lib.bindSymbol(cast(void**)&Mix_Playing,"Mix_Playing"); + lib.bindSymbol(cast(void**)&Mix_PlayingMusic,"Mix_PlayingMusic"); + lib.bindSymbol(cast(void**)&Mix_SetMusicCMD,"Mix_SetMusicCMD"); + lib.bindSymbol(cast(void**)&Mix_SetSynchroValue,"Mix_SetSynchroValue"); + lib.bindSymbol(cast(void**)&Mix_GetSynchroValue,"Mix_GetSynchroValue"); + lib.bindSymbol(cast(void**)&Mix_GetChunk,"Mix_GetChunk"); + lib.bindSymbol(cast(void**)&Mix_CloseAudio,"Mix_CloseAudio"); + + if(errorCount() != errCount) return SDLMixerSupport.badLibrary; + else loadedVersion = SDLMixerSupport.sdlMixer200; + + static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) { + lib.bindSymbol(cast(void**)&Mix_OpenAudioDevice,"Mix_OpenAudioDevice"); + lib.bindSymbol(cast(void**)&Mix_HasChunkDecoder,"Mix_HasChunkDecoder"); + + if(errorCount() != errCount) return SDLMixerSupport.badLibrary; + else loadedVersion = SDLMixerSupport.sdlMixer202; + } + + return loadedVersion; + } +} \ No newline at end of file diff --git a/demos/external/wasm_imports/bindbc/sdl/package.d b/demos/external/wasm_imports/bindbc/sdl/package.d new file mode 100644 index 0000000..6bba9ad --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/package.d @@ -0,0 +1,18 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl; + +public import bindbc.sdl.config, + bindbc.sdl.bind; + +version(BindSDL_Static) {} +else public import bindbc.sdl.dynload; + +version(BindSDL_Image) public import bindbc.sdl.image; +version(BindSDL_Mixer) public import bindbc.sdl.mixer; +version(BindSDL_TTF) public import bindbc.sdl.ttf; + diff --git a/demos/external/wasm_imports/bindbc/sdl/ttf.d b/demos/external/wasm_imports/bindbc/sdl/ttf.d new file mode 100644 index 0000000..bd63ff3 --- /dev/null +++ b/demos/external/wasm_imports/bindbc/sdl/ttf.d @@ -0,0 +1,368 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.sdl.ttf; + +version(BindSDL_TTF): + +import core.stdc.config; +import bindbc.sdl.bind.sdlerror : SDL_GetError, SDL_SetError; +import bindbc.sdl.bind.sdlpixels : SDL_Color; +import bindbc.sdl.bind.sdlrwops : SDL_RWops; +import bindbc.sdl.bind.sdlsurface : SDL_Surface; +import bindbc.sdl.bind.sdlversion : SDL_version; + +alias TTF_SetError = SDL_SetError; +alias TTF_GetError = SDL_GetError; + +enum SDLTTFSupport { + noLibrary, + badLibrary, + sdlTTF2012 = 2012, + sdlTTF2013 = 2013, + sdlTTF2014 = 2014, +} + +enum ubyte SDL_TTF_MAJOR_VERSION = 2; +enum ubyte SDL_TTF_MINOR_VERSION = 0; + +version(SDL_TTF_2014) { + enum sdlTTFSupport = SDLTTFSupport.sdlTTF2014; + enum ubyte SDL_TTF_PATCHLEVEL = 14; +} +else version(SDL_TTF_2013) { + enum sdlTTFSupport = SDLTTFSupport.sdlTTF2013; + enum ubyte SDL_TTF_PATCHLEVEL = 13; +} +else { + enum sdlTTFSupport = SDLTTFSupport.sdlTTF2012; + enum ubyte SDL_TTF_PATCHLEVEL = 12; +} + +alias TTF_MAJOR_VERSION = SDL_TTF_MAJOR_VERSION; +alias TTF_MINOR_VERSION = SDL_TTF_MINOR_VERSION; +alias TTF_PATCHLEVEL = SDL_TTF_PATCHLEVEL; + +@nogc nothrow +void SDL_TTF_VERSION(SDL_version* X) { + X.major = SDL_TTF_MAJOR_VERSION; + X.minor = SDL_TTF_MINOR_VERSION; + X.patch = SDL_TTF_PATCHLEVEL; +} +alias TTF_VERSION = SDL_TTF_VERSION; + +enum { + UNICODE_BOM_NATIVE = 0xFEFF, + UNICODE_BOM_SWAPPED = 0xFFFE, + TTF_STYLE_NORMAL = 0x00, + TTF_STYLE_BOLD = 0x01, + TTF_STYLE_ITALIC = 0x02, + TTF_STYLE_UNDERLINE = 0x04, + TTF_STYLE_STRIKETHROUGH = 0x08, +} + +enum { + TTF_HINTING_NORMAL = 0, + TTF_HINTING_LIGHT = 1, + TTF_HINTING_MONO = 2, + TTF_HINTING_NONE = 3, +} + +struct TTF_Font; + +version(BindSDL_Static) { + extern(C) @nogc nothrow { + SDL_version* TTF_Linked_Version(); + void TTF_ByteSwappedUNICODE(int); + int TTF_Init(); + TTF_Font * TTF_OpenFont(const(char)*,int); + TTF_Font * TTF_OpenFontIndex(const(char)*,int,c_long ); + TTF_Font * TTF_OpenFontRW(SDL_RWops*,int,int); + TTF_Font * TTF_OpenFontIndexRW(SDL_RWops*,int,int,c_long); + int TTF_GetFontStyle(const(TTF_Font)*); + void TTF_SetFontStyle(const(TTF_Font)*,int style); + int TTF_GetFontOutline(const(TTF_Font)*); + void TTF_SetFontOutline(TTF_Font*,int); + int TTF_GetFontHinting(const(TTF_Font)*); + void TTF_SetFontHinting(TTF_Font*,int); + int TTF_FontHeight(const(TTF_Font)*); + int TTF_FontAscent(const(TTF_Font)*); + int TTF_FontDescent(const(TTF_Font)*); + int TTF_FontLineSkip(const(TTF_Font)*); + int TTF_GetFontKerning(const(TTF_Font)*); + void TTF_SetFontKerning(TTF_Font*,int); + int TTF_FontFaces(const(TTF_Font)*); + int TTF_FontFaceIsFixedWidth(const(TTF_Font)*); + char* TTF_FontFaceFamilyName(const(TTF_Font)*); + char* TTF_FontFaceStyleName(const(TTF_Font)*); + int TTF_GlyphIsProvided(const(TTF_Font)*,ushort); + int TTF_GlyphMetrics(TTF_Font*,ushort,int*,int*,int*,int*,int*); + int TTF_SizeText(TTF_Font*,const(char)*,int*,int*); + int TTF_SizeUTF8(TTF_Font*,const(char)*,int*,int*); + int TTF_SizeUNICODE(TTF_Font*,ushort*,int*,int*); + SDL_Surface* TTF_RenderText_Solid(TTF_Font*,const(char)*,SDL_Color); + SDL_Surface* TTF_RenderUTF8_Solid(TTF_Font*,const(char)*,SDL_Color); + SDL_Surface* TTF_RenderUNICODE_Solid(TTF_Font*,const(ushort)*,SDL_Color); + SDL_Surface* TTF_RenderGlyph_Solid(TTF_Font*,ushort,SDL_Color); + SDL_Surface* TTF_RenderText_Shaded(TTF_Font*,const(char)*,SDL_Color,SDL_Color); + SDL_Surface* TTF_RenderUTF8_Shaded(TTF_Font*,const(char)*,SDL_Color,SDL_Color); + SDL_Surface* TTF_RenderUNICODE_Shaded(TTF_Font*,const(ushort)*,SDL_Color,SDL_Color); + SDL_Surface* TTF_RenderGlyph_Shaded(TTF_Font*,ushort,SDL_Color,SDL_Color); + SDL_Surface* TTF_RenderText_Blended(TTF_Font*,const(char)*,SDL_Color); + SDL_Surface* TTF_RenderUTF8_Blended(TTF_Font*,const(char)*,SDL_Color); + SDL_Surface* TTF_RenderUNICODE_Blended(TTF_Font*,const(ushort)*,SDL_Color); + SDL_Surface* TTF_RenderText_Blended_Wrapped(TTF_Font*,const(char)*,SDL_Color,uint); + SDL_Surface* TTF_RenderUTF8_Blended_Wrapped(TTF_Font*,const(char)*,SDL_Color,uint); + SDL_Surface* TTF_RenderUNICODE_Blended_Wrapped(TTF_Font*,const(ushort)*,SDL_Color,uint); + SDL_Surface* TTF_RenderGlyph_Blended(TTF_Font*,ushort,SDL_Color); + void TTF_CloseFont(TTF_Font*); + void TTF_Quit(); + int TTF_WasInit(); + int TTF_GetFontKerningSize(TTF_Font*,int,int); + + static if(sdlTTFSupport >= SDLTTFSupport.sdlTTF2014) { + int TTF_GetFontKerningSizeGlyphs(TTF_Font*,ushort,ushort); + } + } +} +else { + import bindbc.loader; + + extern(C) @nogc nothrow { + alias pTTF_Linked_Version = SDL_version* function(); + alias pTTF_ByteSwappedUNICODE = void function(int); + alias pTTF_Init = int function(); + alias pTTF_OpenFont = TTF_Font * function(const(char)*,int); + alias pTTF_OpenFontIndex = TTF_Font * function(const(char)*,int,c_long ); + alias pTTF_OpenFontRW = TTF_Font * function(SDL_RWops*,int,int); + alias pTTF_OpenFontIndexRW = TTF_Font * function(SDL_RWops*,int,int,c_long); + alias pTTF_GetFontStyle = int function(const(TTF_Font)*); + alias pTTF_SetFontStyle = void function(const(TTF_Font)*,int style); + alias pTTF_GetFontOutline = int function(const(TTF_Font)*); + alias pTTF_SetFontOutline = void function(TTF_Font*,int); + alias pTTF_GetFontHinting = int function(const(TTF_Font)*); + alias pTTF_SetFontHinting = void function(TTF_Font*,int); + alias pTTF_FontHeight = int function(const(TTF_Font)*); + alias pTTF_FontAscent = int function(const(TTF_Font)*); + alias pTTF_FontDescent = int function(const(TTF_Font)*); + alias pTTF_FontLineSkip = int function(const(TTF_Font)*); + alias pTTF_GetFontKerning = int function(const(TTF_Font)*); + alias pTTF_SetFontKerning = void function(TTF_Font*,int); + alias pTTF_FontFaces = int function(const(TTF_Font)*); + alias pTTF_FontFaceIsFixedWidth = int function(const(TTF_Font)*); + alias pTTF_FontFaceFamilyName = char* function(const(TTF_Font)*); + alias pTTF_FontFaceStyleName = char* function(const(TTF_Font)*); + alias pTTF_GlyphIsProvided = int function(const(TTF_Font)*,ushort); + alias pTTF_GlyphMetrics = int function(TTF_Font*,ushort,int*,int*,int*,int*,int*); + alias pTTF_SizeText = int function(TTF_Font*,const(char)*,int*,int*); + alias pTTF_SizeUTF8 = int function(TTF_Font*,const(char)*,int*,int*); + alias pTTF_SizeUNICODE = int function(TTF_Font*,ushort*,int*,int*); + alias pTTF_RenderText_Solid = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); + alias pTTF_RenderUTF8_Solid = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); + alias pTTF_RenderUNICODE_Solid = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color); + alias pTTF_RenderGlyph_Solid = SDL_Surface* function(TTF_Font*,ushort,SDL_Color); + alias pTTF_RenderText_Shaded = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,SDL_Color); + alias pTTF_RenderUTF8_Shaded = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,SDL_Color); + alias pTTF_RenderUNICODE_Shaded = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color,SDL_Color); + alias pTTF_RenderGlyph_Shaded = SDL_Surface* function(TTF_Font*,ushort,SDL_Color,SDL_Color); + alias pTTF_RenderText_Blended = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); + alias pTTF_RenderUTF8_Blended = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); + alias pTTF_RenderUNICODE_Blended = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color); + alias pTTF_RenderText_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,uint); + alias pTTF_RenderUTF8_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,uint); + alias pTTF_RenderUNICODE_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color,uint); + alias pTTF_RenderGlyph_Blended = SDL_Surface* function(TTF_Font*,ushort,SDL_Color); + alias pTTF_CloseFont = void function(TTF_Font*); + alias pTTF_Quit = void function(); + alias pTTF_WasInit = int function(); + alias pTTF_GetFontKerningSize = int function(TTF_Font*,int,int); + } + + __gshared { + pTTF_Linked_Version TTF_Linked_Version; + pTTF_ByteSwappedUNICODE TTF_ByteSwappedUNICODE; + pTTF_Init TTF_Init; + pTTF_OpenFont TTF_OpenFont; + pTTF_OpenFontIndex TTF_OpenFontIndex; + pTTF_OpenFontRW TTF_OpenFontRW; + pTTF_OpenFontIndexRW TTF_OpenFontIndexRW; + pTTF_GetFontStyle TTF_GetFontStyle; + pTTF_SetFontStyle TTF_SetFontStyle; + pTTF_GetFontOutline TTF_GetFontOutline; + pTTF_SetFontOutline TTF_SetFontOutline; + pTTF_GetFontHinting TTF_GetFontHinting; + pTTF_SetFontHinting TTF_SetFontHinting; + pTTF_FontHeight TTF_FontHeight; + pTTF_FontAscent TTF_FontAscent; + pTTF_FontDescent TTF_FontDescent; + pTTF_FontLineSkip TTF_FontLineSkip; + pTTF_GetFontKerning TTF_GetFontKerning; + pTTF_SetFontKerning TTF_SetFontKerning; + pTTF_FontFaces TTF_FontFaces; + pTTF_FontFaceIsFixedWidth TTF_FontFaceIsFixedWidth; + pTTF_FontFaceFamilyName TTF_FontFaceFamilyName; + pTTF_FontFaceStyleName TTF_FontFaceStyleName; + pTTF_GlyphIsProvided TTF_GlyphIsProvided; + pTTF_GlyphMetrics TTF_GlyphMetrics; + pTTF_SizeText TTF_SizeText; + pTTF_SizeUTF8 TTF_SizeUTF8; + pTTF_SizeUNICODE TTF_SizeUNICODE; + pTTF_RenderText_Solid TTF_RenderText_Solid; + pTTF_RenderUTF8_Solid TTF_RenderUTF8_Solid; + pTTF_RenderUNICODE_Solid TTF_RenderUNICODE_Solid; + pTTF_RenderGlyph_Solid TTF_RenderGlyph_Solid; + pTTF_RenderText_Shaded TTF_RenderText_Shaded; + pTTF_RenderUTF8_Shaded TTF_RenderUTF8_Shaded; + pTTF_RenderUNICODE_Shaded TTF_RenderUNICODE_Shaded; + pTTF_RenderGlyph_Shaded TTF_RenderGlyph_Shaded; + pTTF_RenderText_Blended TTF_RenderText_Blended; + pTTF_RenderUTF8_Blended TTF_RenderUTF8_Blended; + pTTF_RenderUNICODE_Blended TTF_RenderUNICODE_Blended; + pTTF_RenderText_Blended_Wrapped TTF_RenderText_Blended_Wrapped; + pTTF_RenderUTF8_Blended_Wrapped TTF_RenderUTF8_Blended_Wrapped; + pTTF_RenderUNICODE_Blended_Wrapped TTF_RenderUNICODE_Blended_Wrapped; + pTTF_RenderGlyph_Blended TTF_RenderGlyph_Blended; + pTTF_CloseFont TTF_CloseFont; + pTTF_Quit TTF_Quit; + pTTF_WasInit TTF_WasInit; + pTTF_GetFontKerningSize TTF_GetFontKerningSize; + } + + static if(sdlTTFSupport >= SDLTTFSupport.sdlTTF2014) { + extern(C) @nogc nothrow { + alias pTTF_GetFontKerningSizeGlyphs = int function(TTF_Font*,ushort,ushort); + } + + __gshared { + pTTF_GetFontKerningSizeGlyphs TTF_GetFontKerningSizeGlyphs; + } + } + + private { + SharedLib lib; + SDLTTFSupport loadedVersion; + } + + void unloadSDLTTF() + { + if(lib != invalidHandle) { + lib.unload(); + } + } + + SDLTTFSupport loadedSDLTTFVersion() { return loadedVersion; } + + bool isSDLTTFLoaded() + { + return lib != invalidHandle; + } + + SDLTTFSupport loadSDLTTF() + { + version(Windows) { + const(char)[][1] libNames = ["SDL2_ttf.dll"]; + } + else version(OSX) { + const(char)[][6] libNames = [ + "libSDL2_ttf.dylib", + "/usr/local/lib/libSDL2_ttf.dylib", + "../Frameworks/SDL2_ttf.framework/SDL2_ttf", + "/Library/Frameworks/SDL2_ttf.framework/SDL2_ttf", + "/System/Library/Frameworks/SDL2_ttf.framework/SDL2_ttf", + "/opt/local/lib/libSDL2_ttf.dylib" + ]; + } + else version(Posix) { + const(char)[][6] libNames = [ + "libSDL2_ttf.so", + "/usr/local/lib/libSDL2_ttf.so", + "libSDL2-2.0_ttf.so", + "/usr/local/lib/libSDL2-2.0_ttf.so", + "libSDL2-2.0_ttf.so.0", + "/usr/local/lib/libSDL2-2.0_ttf.so.0" + ]; + } + else static assert(0, "bindbc-sdl is not yet supported on this platform."); + + SDLTTFSupport ret; + foreach(name; libNames) { + ret = loadSDLTTF(name.ptr); + if(ret != SDLTTFSupport.noLibrary) break; + } + return ret; + } + + SDLTTFSupport loadSDLTTF(const(char)* libName) + { + lib = load(libName); + if(lib == invalidHandle) { + return SDLTTFSupport.noLibrary; + } + + auto errCount = errorCount(); + loadedVersion = SDLTTFSupport.badLibrary; + + lib.bindSymbol(cast(void**)&TTF_Linked_Version,"TTF_Linked_Version"); + lib.bindSymbol(cast(void**)&TTF_ByteSwappedUNICODE,"TTF_ByteSwappedUNICODE"); + lib.bindSymbol(cast(void**)&TTF_Init,"TTF_Init"); + lib.bindSymbol(cast(void**)&TTF_OpenFont,"TTF_OpenFont"); + lib.bindSymbol(cast(void**)&TTF_OpenFontIndex,"TTF_OpenFontIndex"); + lib.bindSymbol(cast(void**)&TTF_OpenFontRW,"TTF_OpenFontRW"); + lib.bindSymbol(cast(void**)&TTF_OpenFontIndexRW,"TTF_OpenFontIndexRW"); + lib.bindSymbol(cast(void**)&TTF_GetFontStyle,"TTF_GetFontStyle"); + lib.bindSymbol(cast(void**)&TTF_SetFontStyle,"TTF_SetFontStyle"); + lib.bindSymbol(cast(void**)&TTF_GetFontOutline,"TTF_GetFontOutline"); + lib.bindSymbol(cast(void**)&TTF_SetFontOutline,"TTF_SetFontOutline"); + lib.bindSymbol(cast(void**)&TTF_GetFontHinting,"TTF_GetFontHinting"); + lib.bindSymbol(cast(void**)&TTF_SetFontHinting,"TTF_SetFontHinting"); + lib.bindSymbol(cast(void**)&TTF_FontHeight,"TTF_FontHeight"); + lib.bindSymbol(cast(void**)&TTF_FontAscent,"TTF_FontAscent"); + lib.bindSymbol(cast(void**)&TTF_FontDescent,"TTF_FontDescent"); + lib.bindSymbol(cast(void**)&TTF_FontLineSkip,"TTF_FontLineSkip"); + lib.bindSymbol(cast(void**)&TTF_GetFontKerning,"TTF_GetFontKerning"); + lib.bindSymbol(cast(void**)&TTF_SetFontKerning,"TTF_SetFontKerning"); + lib.bindSymbol(cast(void**)&TTF_FontFaces,"TTF_FontFaces"); + lib.bindSymbol(cast(void**)&TTF_FontFaceIsFixedWidth,"TTF_FontFaceIsFixedWidth"); + lib.bindSymbol(cast(void**)&TTF_FontFaceFamilyName,"TTF_FontFaceFamilyName"); + lib.bindSymbol(cast(void**)&TTF_FontFaceStyleName,"TTF_FontFaceStyleName"); + lib.bindSymbol(cast(void**)&TTF_GlyphIsProvided,"TTF_GlyphIsProvided"); + lib.bindSymbol(cast(void**)&TTF_GlyphMetrics,"TTF_GlyphMetrics"); + lib.bindSymbol(cast(void**)&TTF_SizeText,"TTF_SizeText"); + lib.bindSymbol(cast(void**)&TTF_SizeUTF8,"TTF_SizeUTF8"); + lib.bindSymbol(cast(void**)&TTF_SizeUNICODE,"TTF_SizeUNICODE"); + lib.bindSymbol(cast(void**)&TTF_RenderText_Solid,"TTF_RenderText_Solid"); + lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Solid,"TTF_RenderUTF8_Solid"); + lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Solid,"TTF_RenderUNICODE_Solid"); + lib.bindSymbol(cast(void**)&TTF_RenderGlyph_Solid,"TTF_RenderGlyph_Solid"); + lib.bindSymbol(cast(void**)&TTF_RenderText_Shaded,"TTF_RenderText_Shaded"); + lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Shaded,"TTF_RenderUTF8_Shaded"); + lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Shaded,"TTF_RenderUNICODE_Shaded"); + lib.bindSymbol(cast(void**)&TTF_RenderGlyph_Shaded,"TTF_RenderGlyph_Shaded"); + lib.bindSymbol(cast(void**)&TTF_RenderText_Blended,"TTF_RenderText_Blended"); + lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Blended,"TTF_RenderUTF8_Blended"); + lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Blended,"TTF_RenderUNICODE_Blended"); + lib.bindSymbol(cast(void**)&TTF_RenderText_Blended_Wrapped,"TTF_RenderText_Blended_Wrapped"); + lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Blended_Wrapped,"TTF_RenderUTF8_Blended_Wrapped"); + lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Blended_Wrapped,"TTF_RenderUNICODE_Blended_Wrapped"); + lib.bindSymbol(cast(void**)&TTF_RenderGlyph_Blended,"TTF_RenderGlyph_Blended"); + lib.bindSymbol(cast(void**)&TTF_CloseFont,"TTF_CloseFont"); + lib.bindSymbol(cast(void**)&TTF_Quit,"TTF_Quit"); + lib.bindSymbol(cast(void**)&TTF_WasInit,"TTF_WasInit"); + lib.bindSymbol(cast(void**)&TTF_GetFontKerningSize,"TTF_GetFontKerningSize"); + + if(errorCount() != errCount) return SDLTTFSupport.badLibrary; + else loadedVersion = SDLTTFSupport.sdlTTF2012; + + static if(sdlTTFSupport >= SDLTTFSupport.sdlTTF2014) { + lib.bindSymbol(cast(void**)&TTF_GetFontKerningSizeGlyphs,"TTF_GetFontKerningSizeGlyphs"); + + if(errorCount() != errCount) return SDLTTFSupport.badLibrary; + else loadedVersion = SDLTTFSupport.sdlTTF2014; + } + + return loadedVersion; + } +} \ No newline at end of file diff --git a/demos/libpng16-16.dll b/demos/libpng16-16.dll new file mode 100644 index 0000000..709f724 Binary files /dev/null and b/demos/libpng16-16.dll differ diff --git a/demos/libs/armeabi-v7a/libcimgui.so b/demos/libs/armeabi-v7a/libcimgui.so new file mode 100755 index 0000000..5dca812 Binary files /dev/null and b/demos/libs/armeabi-v7a/libcimgui.so differ diff --git a/demos/libs/linux/x64/libcimgui.so b/demos/libs/linux/x64/libcimgui.so new file mode 100755 index 0000000..9c2a0bc Binary files /dev/null and b/demos/libs/linux/x64/libcimgui.so differ diff --git a/demos/libs/windows/x64/SDL2.lib b/demos/libs/windows/x64/SDL2.lib new file mode 100644 index 0000000..89f7d37 Binary files /dev/null and b/demos/libs/windows/x64/SDL2.lib differ diff --git a/demos/libs/windows/x64/SDL2_image.lib b/demos/libs/windows/x64/SDL2_image.lib new file mode 100644 index 0000000..6d00aed Binary files /dev/null and b/demos/libs/windows/x64/SDL2_image.lib differ diff --git a/demos/libs/windows/x64/SDL2main.lib b/demos/libs/windows/x64/SDL2main.lib new file mode 100644 index 0000000..4d07170 Binary files /dev/null and b/demos/libs/windows/x64/SDL2main.lib differ diff --git a/demos/libs/windows/x64/SDL2test.lib b/demos/libs/windows/x64/SDL2test.lib new file mode 100644 index 0000000..f3ad021 Binary files /dev/null and b/demos/libs/windows/x64/SDL2test.lib differ diff --git a/demos/libs/windows/x64/cimgui.lib b/demos/libs/windows/x64/cimgui.lib new file mode 100644 index 0000000..3a6b57c Binary files /dev/null and b/demos/libs/windows/x64/cimgui.lib differ diff --git a/demos/meson.build b/demos/meson.build new file mode 100644 index 0000000..8a3642d --- /dev/null +++ b/demos/meson.build @@ -0,0 +1,35 @@ +# Files +demos_src = files() +external_src = files() +subdir('source') +subdir('external') + +demos_inc = include_directories('source/') +external_inc = include_directories('external/sources/') + +# Argumesnts +versions = ['BindSDL_Image','SDL_208', 'BindBC_Static', 'BindSDL_Static'] + +# Dependencies +bindbc_loader_dep = dependency('bindbc-loader') +bindbc_sdl_dep = dependency('bindbc-sdl') +cimgui_dep = dependency('cimgui') +sdl2_dep = dependency('SDL2') +sdl2_image_dep = dependency('SDL2_image') + +subdir('utils') # Utils library + +executable('BubelECSDemos', [demos_src, external_src], + include_directories : [demos_inc, external_inc], + d_module_versions : versions, + link_with : [ecs_lib, ecs_utils_lib], + dependencies : [ + bindbc_loader_dep, + bindbc_sdl_dep, + cimgui_dep, + bubel_ecs_dep, + ecs_utils_dep, + sdl2_dep, + sdl2_image_dep, + ], +) \ No newline at end of file diff --git a/demos/source/app.d b/demos/source/app.d new file mode 100644 index 0000000..6f2322b --- /dev/null +++ b/demos/source/app.d @@ -0,0 +1,1453 @@ +module app; + +import bindbc.sdl; + +import cimgui.cimgui; + +import game_core.basic; +import game_core.job_updater; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.std; + +import ecs_utils.gfx.renderer; +import ecs_utils.imgui_bind; +import ecs_utils.imgui_styles; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import glad.gl.gl; +import glad.gl.gles2; +import glad.gl.loader; + +import gui.manager; +import gui.tool_circle; + +extern (C) : + +enum Tool +{ + entity_spawner, + component_manipulator, + selector +} + +__gshared const (char)*[3] tool_strings = ["Entity spawner", "Component manipulator", "Selector"]; + +struct Mouse +{ + vec2 position; + bool left, right, middle; +} + +struct DemoCallbacks +{ + void function() register; + void function() initialize; + void function() deinitialize; + bool function() loop; + void function(SDL_Event*) event; + const (char)* tips; +} + +struct Launcher +{ + ECSJobUpdater* job_updater; + GUIManager* gui_manager; + ImGuiContext* context; + SDL_Window* window; + SDL_GLContext gl_context; + /*bool function() loop; + void function() end; + void function(SDL_Event*) event;*/ + //void function(vec2, Tool, int, bool) tool; + float scalling; + ivec2 window_size = ivec2(1024,768); + Renderer renderer; + ubyte[] keys; + uint style = 3; + uint entities_count; + bool multithreading; + int threads = 1; + ulong timer_freq; + double delta_time; + uint fps; + vec2 render_position; + bool play = true; + + Tool used_tool; + int tool_size = 100; + float tool_repeat = 0; + float repeat_time = 0; + bool tool_show = true; + bool override_ = true; + bool tool_mode = true; + ToolCircle* tool_circle; + bool show_filtered; + EntityID selected_entity; + + bool swap_interval = true; + + float windows_alpha = 0.75; + + //const (char)* tips; + + bool show_stat_wnd = true; + bool show_tips = true; + bool show_demo_wnd = true; + bool show_tools_wnd = true; + bool show_virtual_keys_wnd = false; + bool show_profile_wnd = true; + + int plot_index; + PlotStruct[] plot_values; + + Mouse mouse; + + struct PlotStruct + { + float delta_time = 0; + float loop_time = 0; + float draw_time = 0; + } + + double deltaTime() + { + return delta_time * play; + } + + DemoCallbacks demo; + + void switchDemo(DemoCallbacks callbacks)//void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips) + { + show_tips = true; + gui_manager.clear(); + //launcher.ent + + gEntityManager.begin(); + gEntityManager.update("clean"); + gEntityManager.end(); + + if(this.demo.deinitialize)this.demo.deinitialize(); + + foreach(ref system; gEntityManager.systems) + { + if(system.id != becsID!CountSystem && system.id != becsID!CleanSystem)system.disable(); + } + + /*gEntityManager.getSystem(becsID!CountSystem).enable(); + gEntityManager.getSystem(becsID!CleanSystem).enable();//*/ + + if(callbacks.register)callbacks.register(); + if(callbacks.initialize)callbacks.initialize(); + demo = callbacks; + /*this.loop = loop; + this.end = end; + this.event = event; + this.tips = tips;*/ + //this.tool = tool; + } + + bool filterEntity(ref const Entity entity) + { + EntityMeta meta = entity.getMeta(); + foreach(id;gui_manager.filter_list) + { + if(!meta.hasComponent(id))return false; + } + if(used_tool == Tool.component_manipulator) + { + if(!meta.hasComponent(gui_manager.getSelectedComponent().component_id))return false; + } + return true; + } + + void processTool(vec2 position, bool mode) + { + static struct Iterator + { + float size2; + vec2 position; + ComponentRef[] add_comps; + ushort[] rem_comps; + ushort[] filter; + float distance = float.max; + + bool filterEntity(ref const Entity entity) + { + EntityMeta meta = entity.getMeta(); + foreach(id;filter) + { + if(!meta.hasComponent(id))return false; + } + return true; + } + + void removeEntity(IteratorSystem.EntitiesData data) + { + if(!filterEntity(data.entity[0]))return; + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < size2)gEntityManager.removeEntity(data.entity[i].id); + } + } + + void addComponent(IteratorSystem.EntitiesData data) + { + if(!filterEntity(data.entity[0]))return; + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < size2)gEntityManager.addComponents(data.entity[i].id, add_comps); + } + } + + void overrideComponent(IteratorSystem.EntitiesData data) + { + if(!filterEntity(data.entity[0]))return; + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < size2) + { + gEntityManager.removeComponents(data.entity[i].id, rem_comps); + gEntityManager.addComponents(data.entity[i].id, add_comps); + } + } + } + + void removeComponent(IteratorSystem.EntitiesData data) + { + if(!filterEntity(data.entity[0]))return; + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < size2)gEntityManager.removeComponents(data.entity[i].id, rem_comps); + } + } + + void selectEntity(IteratorSystem.EntitiesData data) + { + if(!filterEntity(data.entity[0]))return; + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < distance) + { + distance = length; + launcher.selected_entity = data.entity[i].id; + } + } + } + } + + float half_size = tool_size * 0.5; + float size2 = half_size * half_size; + Iterator iterator; + iterator.size2 = size2; + iterator.position = position; + iterator.filter = gui_manager.filter_list[]; + + switch(used_tool) + { + case Tool.entity_spawner: + if(mode) + { + if(gui_manager.templates.length == 0)return; + EntityTemplate* tmpl = gui_manager.getSelectedTemplate(); + CLocation* location = tmpl.getComponent!CLocation; + if(location) + { + position += randomCircularSample() * half_size; + //if(position.y < 16)position.y = 16; + //else if(position.y > 299)position.y = 299; + *location = position; + } + gEntityManager.addEntity(tmpl); + } + else + { + gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.removeEntity); + } + break; + case Tool.component_manipulator: + { + if(gui_manager.components.length == 0)return; + if(mode) + { + ComponentRef[1] comps = [gui_manager.getSelectedComponent()]; + iterator.add_comps = comps; + if(launcher.override_) + { + ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id]; + iterator.rem_comps = rcomps; + gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent); + } + else gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); + } + else + { + ushort[1] comps = [gui_manager.getSelectedComponent().component_id]; + iterator.rem_comps = comps; + gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.removeComponent); + } + } + break; + case Tool.selector: + iterator.distance = size2; + gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.selectEntity); + break; + default: + break; + } + } + + bool getKeyState(SDL_Scancode key) + { + if(keys[key])return true; + else return false; + } + + void setStyle(uint index) + { + style = index; + .setStyle(index); + } + + double getTime() + { + ulong local_freq = timer_freq / 1000_000; + //return cast(double)(SDL_GetPerformanceCounter() & 0x00FFFFFF) / timer_freq; + if(local_freq == 0)return cast(double)(SDL_GetPerformanceCounter() / timer_freq * 1000); + else return cast(double)(SDL_GetPerformanceCounter() / local_freq) / 1000; + } +} + +__gshared Launcher launcher; + +struct CountSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + } + + bool onBegin() + { + launcher.entities_count = 0; + return true; + } + + void onUpdate(EntitiesData data) + { + launcher.entities_count += data.length; + } +} + +struct CleanSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + Entity[] entities; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + gEntityManager.removeEntity(data.entities[i].id); + } + } +} + +struct IteratorSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + CLocation[] location; + } + + bool onBegin() + { + return false; + } + + void onUpdate(EntitiesData) + { + + } +} + +void mainLoop(void* arg) +{ + __gshared double time = 0; + launcher.delta_time = launcher.getTime() - time; + time = launcher.getTime(); + + if(launcher.delta_time > 1000)launcher.delta_time = 1000; + + __gshared uint temp_fps = 0; + __gshared double fps_time = 0; + temp_fps++; + fps_time += launcher.delta_time; + while(fps_time > 1000) + { + fps_time -= 1000; + launcher.fps = temp_fps; + temp_fps = 0; + } + + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if(launcher.demo.event)launcher.demo.event(&event); + if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) { + quit(); + *cast(bool*)arg = false; + return; + } + else if(event.type == SDL_KEYDOWN) + { + if(event.key.state) + { + if(SDL_GetModState() & KMOD_CTRL) + { + switch(event.key.keysym.scancode) + { + case SDL_SCANCODE_1:launcher.used_tool=Tool.entity_spawner;break; + case SDL_SCANCODE_2:launcher.used_tool=Tool.component_manipulator;break; + case SDL_SCANCODE_3:launcher.used_tool=Tool.selector;break; + default:break; + } + } + else + { + switch(event.key.keysym.scancode) + { + case SDL_SCANCODE_1:break; + case SDL_SCANCODE_2:break; + case SDL_SCANCODE_3:break; + case SDL_SCANCODE_4:break; + default:break; + } + } + } + } + else if(event.type == SDL_WINDOWEVENT) + { + switch(event.window.event) + { + case SDL_WINDOWEVENT_RESIZED: + //launcher.renderer.resize(ivec2(event.window.data1,event.window.data2)); + launcher.window_size = ivec2(event.window.data1,event.window.data2); + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + //launcher.renderer.resize(ivec2(event.window.data1,event.window.data2)); + launcher.window_size = ivec2(event.window.data1,event.window.data2); + break; + default:break; + } + } + else if(event.type == SDL_MOUSEBUTTONDOWN) + { + switch(event.button.button) + { + case SDL_BUTTON_LEFT:launcher.mouse.left = true;break; + case SDL_BUTTON_RIGHT:launcher.mouse.right = true;break; + case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;break; + default:break; + } + if(!igIsAnyItemHovered())igSetWindowFocus(); + if(!igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) + { + launcher.repeat_time = 0; + if(event.button.button == SDL_BUTTON_LEFT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,launcher.tool_mode); + else if(event.button.button == SDL_BUTTON_RIGHT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,!launcher.tool_mode); + } + } + else if(event.type == SDL_MOUSEBUTTONUP) + { + switch(event.button.button) + { + case SDL_BUTTON_LEFT:launcher.mouse.left = false;break; + case SDL_BUTTON_RIGHT:launcher.mouse.right = false;break; + case SDL_BUTTON_MIDDLE:launcher.mouse.middle = false;break; + default:break; + } + } + else if(event.type == SDL_MOUSEMOTION) + { + launcher.mouse.position = vec2(event.motion.x, launcher.window_size.y - event.motion.y); + }else if(event.type == SDL_MOUSEWHEEL) + { + if(!igIsAnyItemHovered() && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow)) + { + if(SDL_GetModState() & KMOD_CTRL) + { + float sign = 1; + if(event.wheel.y < 0)sign = -1; + float val = /*sign * event.wheel.y */ launcher.tool_repeat * 0.25; + if(val < 0.1)val = 0.1; + launcher.tool_repeat -= sign * val; + if(launcher.tool_repeat < 0)launcher.tool_repeat = 0; + else if(launcher.tool_repeat > 1000)launcher.tool_repeat = 1000; + } + else if(SDL_GetModState() & KMOD_SHIFT) + { + int sign = 1; + if(event.wheel.y < 0)sign = -1; + switch(launcher.used_tool) + { + case Tool.entity_spawner: + launcher.gui_manager.selectTemplate(launcher.gui_manager.selected_template-sign); + break; + case Tool.component_manipulator: + launcher.gui_manager.selectComponent(launcher.gui_manager.selected_component-sign); + break; + default:break; + } + } + else + { + int sign = 1; + if(event.wheel.y < 0)sign = -1; + int val = /*sign * event.wheel.y */ launcher.tool_size / 4; + if(val < 1)val = 1; + launcher.tool_size -= sign * val; + if(launcher.tool_size < 1)launcher.tool_size = 1; + else if(launcher.tool_size > 256)launcher.tool_size = 256; + } + } + } + } + + if(launcher.tool_repeat != 0 && (launcher.mouse.left || launcher.mouse.right) && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) + { + bool mode = launcher.tool_mode; + if(launcher.mouse.right)mode = !mode; + float range = 500.0 / cast(float)launcher.tool_repeat; + launcher.repeat_time += launcher.delta_time; + if(launcher.used_tool != Tool.entity_spawner || !mode) + { + if(launcher.repeat_time > range)launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode); + while(launcher.repeat_time > range)launcher.repeat_time -= range; + } + else + { + while(launcher.repeat_time > range) + { + launcher.repeat_time -= range; + launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode); + } + } + } + + version(WebAssembly) + { + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL2_NewFrame(launcher.window); + } + else + { + //ImGuiImplOpenGL2NewFrame(); + ImGui_ImplOpenGL3_NewFrame(); + ImGuiImplSDL2NewFrame(launcher.window); + } + + igNewFrame(); + + if(igBeginMainMenuBar()) + { + if(igBeginMenu("File",true)) + { + if(igMenuItemBool("Close","esc",false,true)) + { + quit(); + *cast(bool*)arg = false; + return; + } + igEndMenu(); + } + if(igBeginMenu("Demos",true)) + { + if(igMenuItemBool("Simpe",null,false,true)) + { + import demos.simple; + launcher.switchDemo(getSimpleDemo());//&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); + } + if(igMenuItemBool("Snake",null,false,true)) + { + import demos.snake; + launcher.switchDemo(getSnakeDemo());//&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,Snake.tips); + } + if(igMenuItemBool("Space Invaders",null,false,true)) + { + import demos.space_invaders; + launcher.switchDemo(getSpaceInvadersDemo());//&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); + } + if(igMenuItemBool("Particles",null,false,true)) + { + import demos.particles; + launcher.switchDemo(getParticlesDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + } + if(igMenuItemBool("Brick Breaker",null,false,true)) + { + import demos.brick_breaker; + launcher.switchDemo(getBrickBreakerDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + } + if(igMenuItemBool("Sandbox",null,false,true)) + { + import demos.sandbox; + launcher.switchDemo(getSanboxDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + } + igEndMenu(); + } + if(igBeginMenu("Options",true)) + { + if(igMenuItemBool("VSync", null, launcher.swap_interval, true)) + { + launcher.swap_interval = !launcher.swap_interval; + SDL_GL_SetSwapInterval(launcher.swap_interval); + } + if(igMenuItemBool("Multithreading", null, launcher.multithreading, true)) + { + launcher.multithreading = !launcher.multithreading; + if(launcher.multithreading) + { + launcher.job_updater.pool.setThreadsNum(launcher.threads); + } + else + { + launcher.job_updater.pool.setThreadsNum(1); + } + } + igSetNextItemWidth(0); + igLabelText("Threads:",null); + igSameLine(0,4); + if(igSliderInt("##Threads",&launcher.threads, 1, 32, null))//"Multithreading", null, launcher.multithreading, true)) + { + launcher.job_updater.pool.setThreadsNum(launcher.threads); + //launcher.threads = !launcher.multithreading; + } + if(igBeginMenu("Show",true)) + { + igMenuItemBoolPtr("Statistics",null,&launcher.show_stat_wnd,true); + igMenuItemBoolPtr("Demo",null,&launcher.show_demo_wnd,true); + igMenuItemBoolPtr("Tips",null,&launcher.show_tips,true); + igMenuItemBoolPtr("Virual keys",null,&launcher.show_virtual_keys_wnd,true); + igMenuItemBoolPtr("Profile",null,&launcher.show_profile_wnd,true); + igEndMenu(); + } + if(igBeginMenu("Style",true)) + { + if(igMenuItemBool("Classic",null,launcher.style == 0,true)) + { + launcher.setStyle(0); + } + else if(igMenuItemBool("Dark",null,launcher.style == 1,true)) + { + launcher.setStyle(1); + } + else if(igMenuItemBool("Light",null,launcher.style == 2,true)) + { + launcher.setStyle(2); + } + else if(igMenuItemBool("Default",null,launcher.style == 3,true)) + { + launcher.setStyle(3); + } + igEndMenu(); + } + igEndMenu(); + } + igEndMainMenuBar(); + } + + if(launcher.show_virtual_keys_wnd) + { + igSetNextWindowPos(ImVec2(launcher.window_size.x - 400, launcher.window_size.y - 200), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(64*4+128, 168), ImGuiCond_Once); + igSetNextWindowBgAlpha(launcher.windows_alpha); + ImGuiStyle * style = igGetStyle(); + style.Colors[ImGuiCol_Button].w = 0.8; + if(igBegin("Virtual keys",&launcher.show_virtual_keys_wnd, 0)) + { + igColumns(2,null,0); + igSetColumnWidth(0,64*3+16); + igIndent(64+4); + if(igButton("W",ImVec2(64,64)) || igIsItemDeactivated()) + { + launcher.keys[SDL_SCANCODE_W] = false; + } + else if(igIsItemActive()) + { + launcher.keys[SDL_SCANCODE_W] = true; + } + igUnindent(64+4); + if(igButton("A",ImVec2(64,64)) || igIsItemDeactivated()) + { + launcher.keys[SDL_SCANCODE_A] = false; + } + else if(igIsItemActive()) + { + launcher.keys[SDL_SCANCODE_A] = true; + } + igSameLine(0,4); + if(igButton("S",ImVec2(64,64)) || igIsItemDeactivated()) + { + launcher.keys[SDL_SCANCODE_S] = false; + } + else if(igIsItemActive()) + { + launcher.keys[SDL_SCANCODE_S] = true; + } + igSameLine(0,4); + if(igButton("D",ImVec2(64,64)) || igIsItemDeactivated()) + { + launcher.keys[SDL_SCANCODE_D] = false; + } + else if(igIsItemActive()) + { + launcher.keys[SDL_SCANCODE_D] = true; + } + igNextColumn(); + if(igButton("Space",ImVec2(-1,128)) || igIsItemDeactivated()) + { + launcher.keys[SDL_SCANCODE_SPACE] = false; + } + else if(igIsItemActive()) + { + launcher.keys[SDL_SCANCODE_SPACE] = true; + } + igColumns(1,null,0); + } + igEnd(); + style.Colors[ImGuiCol_Button].w = 1.0; + } + + if(launcher.show_tips) + { + igSetNextWindowPos(ImVec2(launcher.window_size.x /2 -250, 100), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(500, -1), ImGuiCond_Once); + igSetNextWindowBgAlpha(0.95); + if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) + { + // igBeginChild("",ImVec2(0,0),0,0); + igTextWrapped(launcher.demo.tips); + // igEndChild(); + } + igEnd(); + } + + if(launcher.show_demo_wnd) + { + igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, 30), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(250, 300), ImGuiCond_Once); + if(igBegin("Demo",&launcher.show_demo_wnd,0)) + { + igCheckbox("Play",&launcher.play); + ImDrawList* draw_list = igGetWindowDrawList(); + igBeginGroup(); + launcher.gui_manager.gui(); + igEndGroup(); + ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1); + + //ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), -1, 0, 1); + //igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow); + //igBeginChild("Tool frame",ImVec2(-1,-1),true,0); + // igBeginGroup(); + // if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) + // { + // igIndent(8); + /*if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0)) + { + if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.entity_spawner; + } + if(igSelectable("Component manipulator",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.component_manipulator; + } + if(igSelectable("Selector",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.selector; + } + igEndCombo(); + }*/ + /*if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.entity_spawner; + } + if(igSelectable("Component manipulator",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.component_manipulator; + } + if(igSelectable("Selector",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.selector; + }*/ + /*if(igBeginTabBar("Tool",ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) + { + if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); + bool a = 1; + //this is used as hack to make CTRL+1/2/3 tab selection possible + static Tool prev_tool = Tool.entity_spawner; + bool different = prev_tool != launcher.used_tool; + Tool tool; + if(igBeginTabItem("Entity spawner", &a, launcher.used_tool == Tool.entity_spawner && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.entity_spawner; + igEndTabItem(); + } + if(igBeginTabItem("Component manipulator", &a, launcher.used_tool == Tool.component_manipulator && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.component_manipulator; + igEndTabItem(); + } + if(igBeginTabItem("Selector", &a, launcher.used_tool == Tool.selector && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.selector; + igEndTabItem(); + } + launcher.used_tool = tool; + prev_tool = launcher.used_tool; + } + igEndTabBar(); + + + igCheckbox("Show Tool", &launcher.tool_show); + if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); + igSameLine(0,4); + igCheckbox("Show Filtered", &launcher.show_filtered); + if(igIsItemHovered(0))igSetTooltip("Show/hide filtered entities"); + if(launcher.used_tool == Tool.component_manipulator) + { + igCheckbox("Override", &launcher.override_); + } + + //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); + if(launcher.used_tool != Tool.selector) + { + if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; + if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)"); + igSameLine(0,4); + if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; + if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)"); + } + + igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); + igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); + launcher.gui_manager.toolGui();*/ + + // igUnindent(8); + // } + // igEndGroup(); + ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); + + //igBeginGroup(); + if(igCollapsingHeader("Filter", ImGuiTreeNodeFlags_SpanAvailWidth)) + { + igIndent(8); + launcher.gui_manager.filterGUI(); + igUnindent(8); + } + //igEndGroup(); + //ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); + + //igEndChild(); + //igEndChildFrame(); + if(igButton("Clear",ImVec2(-1,0))) + { + gEntityManager.begin(); + gEntityManager.update("clean"); + gEntityManager.end(); + } + } + igEnd(); + } + + if(launcher.show_tools_wnd) + { + + igSetNextWindowPos(ImVec2(launcher.window_size.x - 300, 340), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(300, launcher.window_size.y - 370), ImGuiCond_Once); + if(igBegin("Tools", &launcher.show_tools_wnd, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) + { + if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); + + if(igBeginTabBar("Tool",ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) + { + bool a = 1; + //this is used as hack to make CTRL+1/2/3 tab selection possible + static Tool prev_tool = Tool.entity_spawner; + bool different = prev_tool != launcher.used_tool; + Tool tool; + if(igBeginTabItem("Entity spawner", &a, launcher.used_tool == Tool.entity_spawner && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.entity_spawner; + igEndTabItem(); + } + if(igBeginTabItem("Component manipulator", &a, launcher.used_tool == Tool.component_manipulator && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.component_manipulator; + igEndTabItem(); + } + if(igBeginTabItem("Selector", &a, launcher.used_tool == Tool.selector && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.selector; + igEndTabItem(); + } + launcher.used_tool = tool; + prev_tool = launcher.used_tool; + } + igEndTabBar(); + + + igCheckbox("Show Tool", &launcher.tool_show); + if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); + igSameLine(0,4); + igCheckbox("Show Filtered", &launcher.show_filtered); + if(igIsItemHovered(0))igSetTooltip("Show/hide filtered entities"); + if(launcher.used_tool == Tool.component_manipulator) + { + igCheckbox("Override", &launcher.override_); + } + + //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); + if(launcher.used_tool != Tool.selector) + { + if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; + if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)"); + igSameLine(0,4); + if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; + if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)"); + } + + igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); + igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); + + if(igBeginChild("",ImVec2(0,0),1,0)) + { + launcher.gui_manager.toolGui(); + } + igEndChild(); + } + igEnd(); + } + + if(launcher.show_profile_wnd) + { + //igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowPos(ImVec2(8, launcher.window_size.y - 258), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(250, 250), ImGuiCond_Once); + if(igBegin("Profile",&launcher.show_profile_wnd,0)) + { + if(igBeginTabBar("ProfileTabBar",ImGuiTabBarFlags_FittingPolicyScroll)) + { + + if(igBeginTabItem("Plots", null, 0)) + { + if(igBeginChild("ProfileChild",ImVec2(-1,-1),0,0)) + { + igPlotLines("Delta time",&launcher.plot_values[0].delta_time,100,launcher.plot_index,"Delta time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof); + igPlotLines("Loop time",&launcher.plot_values[0].loop_time,100,launcher.plot_index,"Loop time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof); + igPlotLines("Draw time",&launcher.plot_values[0].draw_time,100,launcher.plot_index,"Draw time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof); + } + igEndChild(); + igEndTabItem(); + } + if(igBeginTabItem("Multithreading graph", null, 0)) + { + if(igBeginChild("ProfileChild",ImVec2(-1,-1),0,0)) + { + igText("Work in proggress"); + } + igEndChild(); + igEndTabItem(); + } + + igEndTabBar(); + } + } + igEnd(); + } + + launcher.renderer.resize(launcher.window_size); + //launcher.renderer.view(vec2(0,0),vec2(launcher.window_size.x,launcher.window_size.y)); + //if(384, 768, 1152, 1536) + //576 960 1344 1728 + //float scalling; + if(launcher.window_size.y < 360)launcher.scalling = 1; + else launcher.scalling = 1.0 / ((launcher.window_size.y+120)/360); + launcher.renderer.view(launcher.render_position,vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling); + //launcher.renderer.view(vec2(0,0),vec2(1024*launcher.window_size.x/launcher.window_size.y,768)); + //glClear(GL_COLOR_BUFFER_BIT); + launcher.renderer.clear(); + + double loop_time = launcher.getTime(); + launcher.job_updater.pool.tryWaitCount = 10000; + if(launcher.play) + { + if(launcher.demo.loop && !launcher.demo.loop()) + { + quit(); + *cast(bool*)arg = false; + } + } + else + { + gEntityManager.begin(); + import game_core.rendering; + DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; + gEntityManager.callEntitiesFunction!DrawSystem(&draw_system.onUpdate); + gEntityManager.end(); + } + launcher.job_updater.pool.tryWaitCount = 0; + + loop_time = launcher.getTime() - loop_time; + + double draw_time = launcher.getTime(); + launcher.renderer.present(); + draw_time = launcher.getTime() - draw_time; + + if(launcher.tool_show)launcher.tool_circle.draw(&launcher.renderer, (launcher.mouse.position*launcher.scalling)-launcher.render_position, cast(float)launcher.tool_size, launcher.renderer.view_size.y*6*launcher.scalling); + + __gshared float plot_time = 0; + __gshared uint plot_samples = 0; + plot_time += launcher.delta_time; + plot_samples++; + launcher.plot_values[100].delta_time += launcher.delta_time; + launcher.plot_values[100].loop_time += loop_time; + launcher.plot_values[100].draw_time += draw_time; + if(plot_time > 100) + { + launcher.plot_values[launcher.plot_index].delta_time = launcher.plot_values[100].delta_time / cast(float)plot_samples; + launcher.plot_values[launcher.plot_index].loop_time = launcher.plot_values[100].loop_time / cast(float)plot_samples; + launcher.plot_values[launcher.plot_index].draw_time = launcher.plot_values[100].draw_time / cast(float)plot_samples; + launcher.plot_values[100].delta_time = 0; + launcher.plot_values[100].loop_time = 0; + launcher.plot_values[100].draw_time = 0; + + plot_samples = 0; + plot_time -= 100; + launcher.plot_index++; + if(launcher.plot_index >= 100)launcher.plot_index = 0; + } + + if(launcher.show_stat_wnd) + { + igSetNextWindowPos(ImVec2(10, 30), ImGuiCond_Appearing, ImVec2(0,0)); + igSetNextWindowContentSize(ImVec2(150, 0.0f)); + igSetNextWindowBgAlpha(launcher.windows_alpha); + if(igBegin("Statistics", &launcher.show_stat_wnd, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) + { + igColumns(2,null,0); + igSetColumnWidth(0,100); + igText("FPS: "); + igText("Entities: "); + igText("Loop time: "); + igText("Draw time: "); + igText("Delta time: "); + igNextColumn(); + igText("%u",launcher.fps); + igText("%u",launcher.entities_count); + igText("%2.2fms",loop_time); + igText("%2.2fms",draw_time); + igText("%2.2fms",launcher.delta_time); + igColumns(1,null,0); + } + igEnd(); + } + + glUseProgram(0); + import ecs_utils.gfx.buffer; + Buffer.unbind(Buffer.BindTarget.array); + Buffer.unbind(Buffer.BindTarget.element_array); + + igRender(); + version(WebAssembly)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); + else version(Android)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); + else ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); + //ImGuiImplOpenGL2RenderDrawData(igGetDrawData()); + + //launcher.renderer.clear(); + //launcher.renderer.present(); + + SDL_GL_SwapWindow(launcher.window); + +} + +void quit() +{ + import game_core.rendering : TexCoordsManager; + launcher.gui_manager.clear(); + Mallocator.dispose(launcher.gui_manager); + + if(launcher.demo.deinitialize)launcher.demo.deinitialize(); + + gEntityManager.destroy(); + gEntityManager = null; + + TexCoordsManager.destroy(); + + SDL_Quit(); + + version(WebAssembly)emscripten_cancel_main_loop(); +} + +version(Android) +{ + export extern (C) int SDL_main(int argc, char** args) + { + return app_main(argc,args); + } + + import ldc.attributes; + + extern (C) __gshared + { + @section(".tdata") + int _tlsstart = 0; + @section(".tcommon") + int _tlsend = 0; + } + +} +else +{ + extern (C) int main(int argc, char** argv) + { + return app_main(argc,argv); + } +} + +int app_main(int argc, char** argv) +//int main(int argc, char** argv) +{ + + version(BindSDL_Static){} + else + { + loadSDL(); + loadSDLImage(); + } + + if (SDL_Init(SDL_INIT_VIDEO) < 0) + { + printf("SDL could not initialize! SDL_Error: %s", SDL_GetError()); + return -1; + } + SDL_version sdl_version; + SDL_GetVersion(&sdl_version); + printf("SDL version: %u.%u.%u\n",cast(uint)sdl_version.major,cast(uint)sdl_version.minor,cast(uint)sdl_version.patch); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + launcher.window = SDL_CreateWindow("Simple", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, launcher.window_size.x, launcher.window_size.y, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + SDL_MaximizeWindow(launcher.window); + + launcher.gl_context = SDL_GL_CreateContext(launcher.window); + launcher.context = igCreateContext(null); + launcher.timer_freq = SDL_GetPerformanceFrequency(); + + launcher.plot_values = Mallocator.makeArray!(Launcher.PlotStruct)(101); + + SDL_GetWindowSize(launcher.window, &launcher.window_size.x, &launcher.window_size.y); + + version(WebAssembly) + { + gladLoadGLES2(x => SDL_GL_GetProcAddress(x)); + if(!ImGui_ImplSDL2_InitForOpenGL(launcher.window,launcher.gl_context)) + { + printf("ImGui initialization failed!"); + return -2; + } + if(!ImGui_ImplOpenGL3_Init()) + { + printf("ImGui OpenGL initialization failed!"); + return -3; + } + } + else version(Android) + { + //gladLoadGL(); + gladLoadGLES2(x => SDL_GL_GetProcAddress(x)); + if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context)) + { + printf("ImGui initialization failed!"); + return -2; + } + if(!ImGui_ImplOpenGL3_Init("#version 100")) + { + printf("ImGui OpenGL initialization failed!"); + return -3; + } + } + else + { + gladLoadGL(); + if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context)) + { + printf("ImGui initialization failed!"); + return -2; + } + //if(!ImGuiImplOpenGL2Init()) + if(!ImGui_ImplOpenGL3_Init("#version 120")) + { + printf("ImGui OpenGL initialization failed!"); + return -3; + } + } + + //ImFontConfig* config = ImFontConfig_ImFontConfig(); + ImGuiIO* io = igGetIO(); + const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts); + ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, null, font_ranges); + //ImFontConfig_destroy(config); + + setStyle(3); + + launcher.job_updater = Mallocator.make!ECSJobUpdater(1); + //launcher.job_updater.onCreate(); + + EntityManager.initialize(32, 1<<16); + //gEntityManager = gEntityManager; + + //gEntityManager.m_thread_id_func = &launcher.job_updater.getThreadID; + //gEntityManager.setJobDispachFunc(&launcher.job_updater.dispatch); + gEntityManager.setMultithreadingCallbacks(&launcher.job_updater.dispatch, &launcher.job_updater.getThreadID); + + gEntityManager.beginRegister(); + + gEntityManager.registerPass("clean"); + + gEntityManager.registerComponent!CLocation; + + gEntityManager.registerSystem!CountSystem(10000); + gEntityManager.registerSystem!CleanSystem(0,"clean"); + gEntityManager.registerSystem!IteratorSystem(0,"clean"); + + gEntityManager.endRegister(); + + loadGFX(); + + launcher.renderer.initialize(); + import game_core.rendering : TexCoordsManager; + TexCoordsManager.initialize(); + + import mmutils.thread_pool : ThreadPool; + launcher.threads = ThreadPool.getCPUCoresCount(); + if(launcher.threads < 2)launcher.threads = 2; + + launcher.gui_manager = Mallocator.make!GUIManager(); + + { + import demos.simple; + import demos.space_invaders; + import demos.particles; + import demos.brick_breaker; + // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); + // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); + // launcher.switchDemo(getParticlesDemo()); + // launcher.switchDemo(getSimpleDemo()); + launcher.switchDemo(getSimpleDemo()); + } + + int key_num; + ubyte* keys = SDL_GetKeyboardState(&key_num); + launcher.keys = keys[0..key_num]; + + version(WebAssembly) + { + /*EmscriptenFullscreenStrategy strategy; + strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH; + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; + strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST;*/ + + //int result = emscripten_request_fullscreen_strategy(null, true, &strategy); + //emscripten_enter_soft_fullscreen(null, &strategy); + //printf("Fullscreen request: %s.\n", emscripten_result_to_string(result)); + emscripten_set_main_loop_arg(&mainLoop, null, 0, 1); + } + else + { + bool arg = true; + while(arg == true) + { + mainLoop(&arg); + } + } + + return 0; +} + +void loadGFX() +{ + import ecs_utils.gfx.texture; + import ecs_utils.gfx.vertex; + import ecs_utils.gfx.shader; + import ecs_utils.gfx.material; + import ecs_utils.gfx.config; + import ecs_utils.gfx.mesh; + + Texture.__loadBackend(); + Renderer.__loadBackend(); + + GfxConfig.materials = Mallocator.makeArray!Material(3); + GfxConfig.meshes = Mallocator.makeArray!Mesh(1); + + float[16] vertices = [-0.5,-0.5, 0,1, -0.5,0.5, 0,0, 0.5,-0.5, 1,1, 0.5,0.5, 1,0]; + GfxConfig.meshes[0].vertices = Mallocator.makeArray(vertices); + ushort[6] indices = [0,1,2,1,2,3]; + GfxConfig.meshes[0].indices = Mallocator.makeArray(indices); + GfxConfig.meshes[0].uploadData(); + + Shader vsh; + vsh.create(); + vsh.load("assets/shaders/base.vp"); + vsh.compile(); + + Shader fsh; + fsh.create(); + fsh.load("assets/shaders/base.fp"); + fsh.compile(); + + GfxConfig.materials[0].create(); + GfxConfig.materials[0].data.blend_mode = Material.BlendMode.opaque; + GfxConfig.materials[0].data.mode = Material.TransformMode.position; + Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)]; + GfxConfig.materials[0].attachModules(modules); + //GfxConfig.materials[0]. + //GfxConfig.materials[0].load(load_data.materials[i].str); + GfxConfig.materials[0].compile(); + GfxConfig.materials[0].bindAttribLocation("positions",0); + GfxConfig.materials[0].bindAttribLocation("tex_coords",1); + GfxConfig.materials[0].bindAttribLocation("depth",2); + GfxConfig.materials[0].bindAttribLocation("vcolor",3); + GfxConfig.materials[0].link(); + + /* import std.stdio; + writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); + writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); + writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); + writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ + + GfxConfig.materials[0].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3); + GfxConfig.materials[0].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0); + GfxConfig.materials[0].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16); + GfxConfig.materials[0].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); + GfxConfig.materials[0].data.bindings = Mallocator.makeArray!(int)(1); + GfxConfig.materials[0].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); + + + Shader vsh2; + vsh2.create(); + vsh2.load("assets/shaders/circle.vp"); + vsh2.compile(); + + Shader fsh2; + fsh2.create(); + fsh2.load("assets/shaders/circle.fp"); + fsh2.compile(); + + GfxConfig.materials[1].create(); + GfxConfig.materials[1].data.blend_mode = Material.BlendMode.mixed; + GfxConfig.materials[1].data.mode = Material.TransformMode.position; + Material.ShaderModule[1] modules2 = [Material.ShaderModule(vsh2,fsh2)]; + GfxConfig.materials[1].attachModules(modules2); + //GfxConfig.materials[0]. + //GfxConfig.materials[0].load(load_data.materials[i].str); + GfxConfig.materials[1].compile(); + GfxConfig.materials[1].bindAttribLocation("positions",0); + //GfxConfig.materials[1].bindAttribLocation("tex_coords",1); + //GfxConfig.materials[1].bindAttribLocation("depth",2); + //GfxConfig.materials[1].bindAttribLocation("vcolor",3); + GfxConfig.materials[1].link(); + + /* import std.stdio; + writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); + writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); + writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); + writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ + + GfxConfig.materials[1].data.uniforms = Mallocator.makeArray!(Material.Uniform)(2); + GfxConfig.materials[1].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_1"), 0); + GfxConfig.materials[1].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_2"), 16); + //GfxConfig.materials[1].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); + //GfxConfig.materials[1].data.bindings = Mallocator.makeArray!(int)(1); + //GfxConfig.materials[1].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); + + + + + + Shader vsh3; + vsh3.create(); + vsh3.load("assets/shaders/additive_particles.vp"); + vsh3.compile(); + + Shader fsh3; + fsh3.create(); + fsh3.load("assets/shaders/additive_particles.fp"); + fsh3.compile(); + + GfxConfig.materials[2].create(); + GfxConfig.materials[2].data.blend_mode = Material.BlendMode.opaque; + GfxConfig.materials[2].data.mode = Material.TransformMode.position; + Material.ShaderModule[1] modules3 = [Material.ShaderModule(vsh3,fsh3)]; + GfxConfig.materials[2].attachModules(modules3); + //GfxConfig.materials[0]. + //GfxConfig.materials[0].load(load_data.materials[i].str); + GfxConfig.materials[2].compile(); + GfxConfig.materials[2].bindAttribLocation("positions",0); + GfxConfig.materials[2].bindAttribLocation("tex_coords",1); + GfxConfig.materials[2].bindAttribLocation("depth",2); + GfxConfig.materials[2].bindAttribLocation("vcolor",3); + GfxConfig.materials[2].link(); + + /* import std.stdio; + writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); + writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); + writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); + writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ + + GfxConfig.materials[2].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3); + GfxConfig.materials[2].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0); + GfxConfig.materials[2].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16); + GfxConfig.materials[2].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); + GfxConfig.materials[2].data.bindings = Mallocator.makeArray!(int)(1); + GfxConfig.materials[2].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); + GfxConfig.materials[2].data.blend_mode = Material.BlendMode.additive; + + + + + + + /*glUseProgram(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/ + + launcher.tool_circle = Mallocator.make!ToolCircle; +} \ No newline at end of file diff --git a/demos/source/demos/brick_breaker.d b/demos/source/demos/brick_breaker.d new file mode 100644 index 0000000..2c84036 --- /dev/null +++ b/demos/source/demos/brick_breaker.d @@ -0,0 +1,486 @@ +module demos.brick_breaker; + +import app; + +import bindbc.sdl; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import cimgui.cimgui; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; +import game_core.rendering; +import game_core.collision; + +extern(C): + +private enum float px = 1.0/512.0; + +float clamp(float v, float min, float max) +{ + if(vmax)return max; + else return v; +} + +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ + +/*struct CLocation +{ + mixin ECS.Component; + + alias location this; + + vec2 location; +}*/ + +struct CBrick +{ + mixin ECS.Component; +} + +struct CPaddle +{ + mixin ECS.Component; +} + +struct CBall +{ + mixin ECS.Component; + + //ubyte radius; +} + +struct CHitPoints +{ + mixin ECS.Component; + + alias value this; + + short value; +} + +// struct CVelocityFactor +// { +// mixin ECS.Component; + +// alias value this; + +// vec2 value = vec2(1); +// } + +// struct CVelocity +// { +// mixin ECS.Component; + +// alias value this; + +// vec2 value = vec2(0); +// } + +struct EDamage +{ + mixin ECS.Event; + + ubyte damage = 1; +} + +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ + +// struct MoveSystem +// { +// mixin ECS.System!64; + +// struct EntitiesData +// { +// uint length; +// CLocation[] location; +// @readonly CVelocity[] velocity; +// @optional @readonly CVelocityFactor[] vel_factor; +// } + +// void onUpdate(EntitiesData data) +// { +// if(data.vel_factor) +// { +// foreach(i; 0..data.length) +// { +// data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time; +// } +// } +// else +// { +// foreach(i; 0..data.length) +// { +// data.location[i] += data.velocity[i] * launcher.delta_time; +// } +// } +// } +// } + +struct EdgeCollisionSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CLocation[] location; + CVelocity[] velocity; + //CBall[] ball_flag; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + if(data.location[i].x < 0) + { + if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x; + data.location[i].x = 0; + } + else if(data.location[i].x > 400) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + data.location[i].x = 400; + } + + if(data.location[i].y < 0) + { + if(data.velocity[i].y < 0)data.velocity[i].y = -data.velocity[i].y; + data.location[i].y = 0; + } + else if(data.location[i].y > 300) + { + if(data.velocity[i].y > 0)data.velocity[i].y = -data.velocity[i].y; + data.location[i].y = 300; + } + } + } +} + +struct BallCollisionSystem +{ + mixin ECS.System!64; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency, BVHDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + CVelocity[] velocity; + @readonly CLocation[] location; + @readonly CScale[] scale; + @readonly CBall[] ball_flag; + } + + struct State + { + bool test(EntityID id) + { + if(id == data.entity[i].id)return true; + Entity* entity = gEntityManager.getEntity(id); + if(entity) + { + CLocation* location = entity.getComponent!CLocation; + CScale* scale = entity.getComponent!CScale; + if(location && scale) + { + float radius = data.scale[i].x*0.5; + vec2 rel_pos = *location - data.location[i]; + + vec2 half_scale = *scale * 0.5f; + + vec2 nearest_point; + nearest_point.x = clamp(rel_pos.x, -half_scale.x, half_scale.x); + nearest_point.y = clamp(rel_pos.y, -half_scale.y, half_scale.y); + + vec2 vector; + if(nearest_point == rel_pos) + { + vector = nearest_point; + radius = float.max; + } + else vector = nearest_point - rel_pos; + float pow_dist = dot(vector, vector); + + if(dot(data.velocity[i], vector) > 0.01)return true; + + if(pow_dist < radius*radius) + { + vector = vector / sqrtf(pow_dist); + data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i])); + gEntityManager.sendEvent(id,EDamage(1)); + return cast(bool)(hits--); + } + } + } + return true; + } + + EntitiesData data; + uint i; + uint hits; + } + + ShootGrid* grid; + BVHTree* tree; + BVHTree* static_tree; + + bool onBegin() + { + tree = gEntityManager.getSystem!BVHBuilder().tree; + static_tree = gEntityManager.getSystem!StaticBVHBuilder().tree; + if(tree is null || static_tree is null)return false; + else return true; + } + + void onUpdate(EntitiesData data) + { + State state; + state.data = data; + foreach(i; 0..data.length) + { + state.i = i; + state.hits = 1; + AABB bounding = AABB(data.location[i]-data.scale[i], data.location[i]+data.scale[i]); + tree.test(bounding, cast(bool delegate(EntityID id))&state.test); + static_tree.test(bounding, cast(bool delegate(EntityID id))&state.test); + } + } +} + +struct DamageSystem +{ + mixin ECS.System!64; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + CHitPoints[] hit_points; + } + + void handleEvent(Entity* entity, EDamage event) + { + EntityMeta meta = entity.getMeta(); + CHitPoints* hp = meta.getComponent!CHitPoints; + hp.value -= event.damage; + if(hp.value < 0)gEntityManager.removeEntity(entity.id); + } + +} + +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct BrickBreakerDemo +{ + __gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks. + +This demo is usnfinished yet but collision works well. Bricks can be destroyed. Spawning thousands of bricks and then thousands of balls is good way to try demo. +Bricks uses StaticBVH, ball don't collide witch each other, paddle is added to dynamic BVH and collide with balls. But nothing keeps you from adding dynamic collision for balls. +Currently dynamic collisions are pretty slow as dynamic BVH is rebuilded every frame on single thread."; + + //EntityTemplate* tmpl; + Texture texture; +} + +__gshared BrickBreakerDemo* demo; + +void brickBreakerRegister() +{ + demo = Mallocator.make!BrickBreakerDemo; + + demo.texture.create(); + demo.texture.load("assets/textures/atlas.png"); + + gEntityManager.beginRegister(); + + registerRenderingModule(gEntityManager); + registerCollisionModule(gEntityManager); + + gEntityManager.registerComponent!CLocation; + gEntityManager.registerComponent!CRotation; + gEntityManager.registerComponent!CScale; + gEntityManager.registerComponent!CTexCoords; + gEntityManager.registerComponent!CTexCoordsIndex; + gEntityManager.registerComponent!CVelocity; + gEntityManager.registerComponent!CInput; + gEntityManager.registerComponent!CPaddle; + gEntityManager.registerComponent!CDamping; + gEntityManager.registerComponent!CVelocityFactor; + gEntityManager.registerComponent!CBall; + gEntityManager.registerComponent!CHitPoints; + + gEntityManager.registerEvent!EDamage; + + gEntityManager.registerSystem!MoveSystem(-100); + gEntityManager.registerSystem!EdgeCollisionSystem(-99); + gEntityManager.registerSystem!BallCollisionSystem(-79); + gEntityManager.registerSystem!InputMovementSystem(-120); + gEntityManager.registerSystem!DampingSystem(-120); + gEntityManager.registerSystem!DamageSystem(-120); + + gEntityManager.endRegister(); +} + +void brickBreakerStart() +{ + DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; + draw_system.default_data.color = 0x80808080; + draw_system.default_data.texture = demo.texture; + draw_system.default_data.size = vec2(16,16); + draw_system.default_data.coords = vec4(246,64,2,2)*px; + draw_system.default_data.material_id = 0; + + EntityTemplate* brick_tmpl = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CScale, becsID!CColor, + becsID!CTexCoordsIndex, becsID!CBVH, becsID!CHitPoints, + becsID!CAABB, becsID!CStatic].staticArray + ); + brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,40,16,8)*px); + brick_tmpl.getComponent!CColor().value = 0x80206020; + brick_tmpl.getComponent!CScale().value = vec2(16,8); + brick_tmpl.getComponent!CHitPoints().value = 2; + //brick_tmpl.getComponent!CAABB().bounding = AABB(vec2(),vec2()); + + EntityTemplate* big_brick_tmpl = gEntityManager.allocateTemplate(brick_tmpl); + big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px); + big_brick_tmpl.getComponent!CScale().value = vec2(16,16); + + EntityTemplate* paddle_tmpl = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CScale, becsID!CInput, + becsID!CTexCoordsIndex, becsID!CPaddle, becsID!CVelocity, + becsID!CDamping, becsID!CVelocityFactor, becsID!CBVH, + becsID!CAABB].staticArray + ); + paddle_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(272,48,64,10)*px); + paddle_tmpl.getComponent!CScale().value = vec2(64,10); + paddle_tmpl.getComponent!CDamping().value = 14; + paddle_tmpl.getComponent!CVelocityFactor().value = vec2(1,0); + + EntityTemplate* ball_tmpl = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CScale, //becsID!CDamping, + becsID!CTexCoordsIndex, becsID!CBall, becsID!CVelocity].staticArray + ); + ball_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,32,8,8)*px); + ball_tmpl.getComponent!CScale().value = vec2(8,8); + ball_tmpl.getComponent!CVelocity().value = vec2(0.1,0.1); + // paddle_tmpl.getComponent!CDamping().value = 14; + + launcher.gui_manager.addComponent(CLocation(), "Location"); + launcher.gui_manager.addComponent(CRotation(), "Rotation"); + launcher.gui_manager.addComponent(CScale(), "Scale"); + launcher.gui_manager.addComponent(CColor(), "Color"); + launcher.gui_manager.addComponent(CTexCoords(), "Tex Coords"); + launcher.gui_manager.addComponent(CTexCoordsIndex(), "Tex Coords Index"); + launcher.gui_manager.addComponent(CVelocity(), "Velocity"); + launcher.gui_manager.addComponent(CInput(), "Input"); + launcher.gui_manager.addComponent(CPaddle(), "Paddle"); + launcher.gui_manager.addComponent(CDamping(), "Damping"); + launcher.gui_manager.addComponent(CBall(), "Ball"); + launcher.gui_manager.addComponent(CBVH(), "BVH"); + launcher.gui_manager.addComponent(CAABB(), "AABB"); + launcher.gui_manager.addComponent(CStatic(), "Static Flag"); + launcher.gui_manager.addComponent(CVelocityFactor(), "Velocity Factor"); + launcher.gui_manager.addComponent(CHitPoints(), "Hit Points"); + + launcher.gui_manager.addSystem(becsID!MoveSystem, "Move System"); + launcher.gui_manager.addSystem(becsID!EdgeCollisionSystem, "Edge Collision System"); + launcher.gui_manager.addSystem(becsID!BallCollisionSystem, "Ball Collision System"); + launcher.gui_manager.addSystem(becsID!InputMovementSystem, "Input Movement System"); + launcher.gui_manager.addSystem(becsID!DampingSystem, "Damping System"); + launcher.gui_manager.addSystem(becsID!DamageSystem, "Damage System"); + + launcher.gui_manager.addTemplate(brick_tmpl, "Brick"); + launcher.gui_manager.addTemplate(big_brick_tmpl, "Big Brick"); + launcher.gui_manager.addTemplate(paddle_tmpl, "Paddle"); + launcher.gui_manager.addTemplate(ball_tmpl, "Ball"); + + foreach(i;0..10) + { + CColor color; + final switch(i) + { + case 0:color = 0x80206020;break; + case 1:color = 0x80602020;break; + case 2:color = 0x80202060;break; + case 3:color = 0x80206060;break; + case 4:color = 0x80606020;break; + case 5:color = 0x80602060;break; + case 6:color = 0x80606060;break; + case 7:color = 0x80202020;break; + case 8:color = 0x80008030;break; + case 9:color = 0x80206080;break; + } + foreach (j; 0..20) + { + gEntityManager.addEntity(brick_tmpl,[CLocation(vec2(j*18,300-i*10)).ref_, color.ref_].staticArray); + } + } + + gEntityManager.addEntity(paddle_tmpl,[CLocation(vec2(190,20)).ref_].staticArray); + gEntityManager.addEntity(ball_tmpl,[CLocation(vec2(190,40)).ref_].staticArray); + +} + +void brickBreakerEnd() +{ + demo.texture.destroy(); + + Mallocator.dispose(demo); +} + +void brickBreakerEvent(SDL_Event* event) +{ +} + +bool brickBreakerLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + gEntityManager.begin(); + if(launcher.multithreading) + { + launcher.job_updater.begin(); + gEntityManager.updateMT(); + launcher.job_updater.call(); + } + else + { + gEntityManager.update(); + } + gEntityManager.end(); + + return true; +} + +DemoCallbacks getBrickBreakerDemo() +{ + DemoCallbacks demo; + demo.register = &brickBreakerRegister; + demo.initialize = &brickBreakerStart; + demo.deinitialize = &brickBreakerEnd; + demo.loop = &brickBreakerLoop; + demo.tips = .demo.tips; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/bullet_madnes.d b/demos/source/demos/bullet_madnes.d new file mode 100644 index 0000000..420d6a3 --- /dev/null +++ b/demos/source/demos/bullet_madnes.d @@ -0,0 +1,19 @@ +module demos.bullet_madnes; + +import app; + +import bindbc.sdl; + +import cimgui.cimgui; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +extern(C): \ No newline at end of file diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d new file mode 100644 index 0000000..5fc2a09 --- /dev/null +++ b/demos/source/demos/particles.d @@ -0,0 +1,500 @@ +module demos.particles; + +import app; + +import bindbc.sdl; + +import cimgui.cimgui; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; +import game_core.rendering; + +import gui.attributes; + +extern(C): + +private enum float px = 1.0/512.0; + +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ + +/*struct CLocation +{ + mixin ECS.Component; + + alias location this; + + vec2 location; +} + +struct CColor +{ + mixin ECS.Component; + + alias value this; + + @GUIColor uint value = uint.max; +} + +struct CTexCoords +{ + mixin ECS.Component; + + vec4 value; +}*/ + +// struct CVelocity +// { +// mixin ECS.Component; + +// alias value this; + +// vec2 value = vec2(0); +// } + +struct CForceRange +{ + mixin ECS.Component; + + vec2 range = vec2(20,200); +} + +struct CAttractor +{ + mixin ECS.Component; + + //alias value this; + float strength = 0.2; +} + +struct CVortex +{ + mixin ECS.Component; + + float strength = 0.6; +} + +// struct CDamping +// { +// mixin ECS.Component; + +// alias power this; + +// @GUIRange(0,9) ubyte power = 0; +// } + +struct CGravity +{ + mixin ECS.Component; +} + +struct CParticleLife +{ + mixin ECS.Component; + + this(float life_in_secs) + { + life = cast(int)(life_in_secs * 1000_000); + } + + alias life this; + + int life = 1000000; +} + +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct MouseAttractSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + @readonly CLocation[] locations; + CVelocity[] velocity; + } + + vec2 mouse_pos; + + bool onBegin() + { + if(!launcher.getKeyState(SDL_SCANCODE_SPACE))return false; + mouse_pos = launcher.mouse.position; + mouse_pos = vec2(mouse_pos.x, mouse_pos.y) * launcher.scalling - launcher.render_position; + return true; + } + + void onUpdate(EntitiesData data) + { + float speed = launcher.deltaTime * 0.01; + foreach(i;0..data.length) + { + vec2 rel_pos = mouse_pos - data.locations[i]; + float len2 = rel_pos.x * rel_pos.x + rel_pos.y * rel_pos.y; + if(len2 < 0.1)len2 = 0.1; + data.velocity[i] = data.velocity[i] + rel_pos / len2 * speed; + } + } +} + +struct AttractSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + @readonly CLocation[] locations; + CVelocity[] velocity; + } + + struct Updater + { + AttractSystem.EntitiesData data; + + void onUpdate(AttractorIterator.EntitiesData adata) + { + float speed = launcher.deltaTime * 0.00004; + if(adata.vortex) + { + foreach(i;0..data.length) + { + foreach(j;0..adata.length) + { + vec2 rel_pos = data.locations[i] - adata.locations[j]; + float len2 = rel_pos.length2(); + float inv_len = rsqrt(len2); + + if(1 < adata.force_range[j].range.y*inv_len) + { + float dist = (adata.force_range[j].range.y - 0.4)*inv_len - 1; + + vec2 vec = rel_pos * inv_len; + vec2 cvec = vec2(-vec.y,vec.x); + + float sign = -1; + if(1 < adata.force_range[j].range.x*inv_len)sign = 1; + + float str = adata.attractor[j].strength * sign; + float vortex_str = adata.vortex[j].strength; + data.velocity[i] = data.velocity[i] + (rel_pos * str + cvec * vortex_str) * speed * dist; + } + } + } + } + else + { + foreach(i;0..data.length) + { + foreach(j;0..adata.length) + { + vec2 rel_pos = data.locations[i] - adata.locations[j]; + float len2 = rel_pos.length2(); + float inv_len = rsqrt(len2); + + if(1 < adata.force_range[j].range.y*inv_len) + { + float dist = (adata.force_range[j].range.y - 0.4)*inv_len - 1; + + vec2 vec = rel_pos; + + float sign = -1; + if(1 < adata.force_range[j].range.x*inv_len)sign = 1; + + float str = adata.attractor[j].strength * speed * dist * sign; + data.velocity[i] = data.velocity[i] + vec * str; + } + } + } + } + } + } + + void onUpdate(EntitiesData data) + { + Updater updater; + updater.data = data; + gEntityManager.callEntitiesFunction!AttractorIterator(&updater.onUpdate); + } +} + +struct AttractorIterator +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CLocation[] locations; + @readonly CAttractor[] attractor; + @readonly CForceRange[] force_range; + @optional @readonly CVortex[] vortex; + } + + bool onBegin() + { + return false; + } + + void onUpdate(EntitiesData data) + { + + } +} + +struct PlayAreaSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + Entity[] entity; + @readonly CLocation[] locations; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + if(data.locations[i].x > 440)gEntityManager.removeEntity(data.entity[i].id); + else if(data.locations[i].x < -40)gEntityManager.removeEntity(data.entity[i].id); + if(data.locations[i].y > 340)gEntityManager.removeEntity(data.entity[i].id); + else if(data.locations[i].y < -40)gEntityManager.removeEntity(data.entity[i].id); + } + } +} + +struct ParticleLifeSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + CParticleLife[] life; + } + + int delta_time; + + bool onBegin() + { + delta_time = cast(int)(launcher.deltaTime * 1000); + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.life[i] -= delta_time; + if(data.life[i] < 0)gEntityManager.removeEntity(data.entity[i].id); + } + } +} + +struct GravitySystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + @readonly CGravity[] gravity; + CVelocity[] velocity; + } + + void onUpdate(EntitiesData data) + { + float delta_time = launcher.deltaTime * 0.00_092; + foreach(i; 0..data.length) + { + data.velocity[i].y -= delta_time; + } + } +} + +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct ParticlesDemo +{ + __gshared const (char)* tips = "Particles by default have no velocity. You can spawn \"Attractor\" which attract particles, or \"Vortex\" which attracts and spin particles. +Please do not spawn to many of them as every \"Attractor\" iterate over all particles (brute force)."; + + Texture texture; +} + +__gshared ParticlesDemo* particles_demo; + +void particlesRegister() +{ + particles_demo = Mallocator.make!ParticlesDemo; + + particles_demo.texture.create(); + particles_demo.texture.load("assets/textures/atlas.png"); + + gEntityManager.beginRegister(); + + registerRenderingModule(gEntityManager); + + gEntityManager.registerComponent!CLocation; + //gEntityManager.registerComponent!CTexCoords; + gEntityManager.registerComponent!CColor; + gEntityManager.registerComponent!CVelocity; + gEntityManager.registerComponent!CScale; + gEntityManager.registerComponent!CTexCoords; + gEntityManager.registerComponent!CTexCoordsIndex; + gEntityManager.registerComponent!CRotation; + gEntityManager.registerComponent!CDepth; + gEntityManager.registerComponent!CAttractor; + gEntityManager.registerComponent!CDamping; + gEntityManager.registerComponent!CGravity; + gEntityManager.registerComponent!CVortex; + gEntityManager.registerComponent!CParticleLife; + gEntityManager.registerComponent!CForceRange; + gEntityManager.registerComponent!CMaterialIndex; + gEntityManager.registerComponent!CVelocityFactor; + + gEntityManager.registerSystem!MoveSystem(0); + gEntityManager.registerSystem!DrawSystem(100); + gEntityManager.registerSystem!PlayAreaSystem(102); + gEntityManager.registerSystem!AttractSystem(-1); + gEntityManager.registerSystem!MouseAttractSystem(1); + gEntityManager.registerSystem!DampingSystem(101); + gEntityManager.registerSystem!ParticleLifeSystem(-10); + gEntityManager.registerSystem!GravitySystem(-2); + + gEntityManager.registerSystem!AttractorIterator(-1); + + gEntityManager.endRegister(); +} + +void particlesStart() +{ + DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; + draw_system.default_data.size = vec2(2,2); + draw_system.default_data.coords = vec4(246,64,2,2)*px; + draw_system.default_data.material_id = 2; + draw_system.default_data.texture = particles_demo.texture; + + launcher.gui_manager.addSystem(becsID!MoveSystem,"Move System"); + launcher.gui_manager.addSystem(becsID!DrawSystem,"Draw System"); + launcher.gui_manager.addSystem(becsID!PlayAreaSystem,"Play Area System"); + launcher.gui_manager.addSystem(becsID!AttractSystem,"Attract System"); + launcher.gui_manager.addSystem(becsID!MouseAttractSystem,"Mouse Attract System"); + launcher.gui_manager.addSystem(becsID!DampingSystem,"Damping System"); + launcher.gui_manager.addSystem(becsID!ParticleLifeSystem,"Particle Life System"); + launcher.gui_manager.addSystem(becsID!GravitySystem,"Gravity System"); + + // launcher.gui_manager.addComponent(CColor(),"Color (white)"); + // launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)"); + // launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)"); + // launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)"); + launcher.gui_manager.addComponent(CLocation(),"Location"); + launcher.gui_manager.addComponent(CScale(),"Scale"); + launcher.gui_manager.addComponent(CTexCoords(),"Texture Coords"); + launcher.gui_manager.addComponent(CTexCoordsIndex(),"Texture Coords Index"); + launcher.gui_manager.addComponent(CRotation(),"Rotation"); + launcher.gui_manager.addComponent(CDepth(),"Depth"); + launcher.gui_manager.addComponent(CMaterialIndex(),"Material ID"); + launcher.gui_manager.addComponent(CVelocityFactor(),"Velocity Factor"); + launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor"); + launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange"); + launcher.gui_manager.addComponent(CVelocity(),"Velocity"); + launcher.gui_manager.addComponent(CDamping(),"Damping"); + launcher.gui_manager.addComponent(CVortex(),"Vortex"); + launcher.gui_manager.addComponent(CParticleLife(),"Particle Life"); + launcher.gui_manager.addComponent(CGravity(),"Gravity"); + + EntityTemplate* tmpl; + EntityTemplate* base_tmpl = gEntityManager.allocateTemplate([becsID!CTexCoords, becsID!CLocation, becsID!CColor, becsID!CVelocity, becsID!CDamping, becsID!CScale, becsID!CMaterialIndex].staticArray); + base_tmpl.getComponent!CColor().value = 0xFF251010; + base_tmpl.getComponent!CScale().value = vec2(2); + base_tmpl.getComponent!CTexCoords().value = vec4(246,64,2,2)*px; + base_tmpl.getComponent!CMaterialIndex().value = 2; + launcher.gui_manager.addTemplate(base_tmpl,"Particle"); + // tmpl = gEntityManager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF251010; + // launcher.gui_manager.addTemplate(tmpl,"Particle (blue)"); + // tmpl = gEntityManager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF102010; + // launcher.gui_manager.addTemplate(tmpl,"Particle (green)"); + // tmpl = gEntityManager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF101540; + // launcher.gui_manager.addTemplate(tmpl,"Particle (red)"); + // tmpl = gEntityManager.allocateTemplate(tmpl, [becsID!CDamping].staticArray); + // launcher.gui_manager.addTemplate(tmpl,"Particle (damping)"); + // tmpl = gEntityManager.allocateTemplate(tmpl); + // tmpl.getComponent!CDamping().power = 4; + // launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); + tmpl = gEntityManager.allocateTemplate([becsID!CAttractor, becsID!CLocation, becsID!CForceRange, becsID!CScale].staticArray); + tmpl.getComponent!CScale().value = vec2(4); + launcher.gui_manager.addTemplate(tmpl,"Attractor"); + tmpl = gEntityManager.allocateTemplate(tmpl, [becsID!CVortex].staticArray); + launcher.gui_manager.addTemplate(tmpl,"Vortex"); + // tmpl = gEntityManager.allocateTemplate(tmpl); + // tmpl.getComponent!CVortex().strength = -0.6; + // launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)"); + +} + +void particlesEnd() +{ + particles_demo.texture.destroy(); + + //gEntityManager.freeTemplate(simple.tmpl); + Mallocator.dispose(particles_demo); +} + +void particlesEvent(SDL_Event* event) +{ +} + +bool particlesLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + gEntityManager.begin(); + if(launcher.multithreading) + { + launcher.job_updater.begin(); + gEntityManager.updateMT(); + launcher.job_updater.call(); + } + else + { + gEntityManager.update(); + } + gEntityManager.end(); + + return true; +} + +DemoCallbacks getParticlesDemo() +{ + DemoCallbacks demo; + demo.register = &particlesRegister; + demo.initialize = &particlesStart; + demo.deinitialize = &particlesEnd; + demo.loop = &particlesLoop; + demo.tips = ParticlesDemo.tips; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/physics.d b/demos/source/demos/physics.d new file mode 100644 index 0000000..5fccc0b --- /dev/null +++ b/demos/source/demos/physics.d @@ -0,0 +1,19 @@ +module demos.physics; + +import app; + +import bindbc.sdl; + +import cimgui.cimgui; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +extern(C): \ No newline at end of file diff --git a/demos/source/demos/sandbox.d b/demos/source/demos/sandbox.d new file mode 100644 index 0000000..878684c --- /dev/null +++ b/demos/source/demos/sandbox.d @@ -0,0 +1,104 @@ +module demos.sandbox; + +import bindbc.sdl; + +import bubel.ecs.core; + +import demos.simple; +import demos.snake; +import demos.space_invaders; +import demos.particles; +import demos.brick_breaker; + +import game_core.rendering; + +import app; + +import ecs_utils.math.vector; + +extern(C): + +void sandboxStart() +{ + simpleRegister(); + snakeRegister(); + spaceInvadersRegister(); + particlesRegister(); + brickBreakerRegister(); + + simpleStart(); + snakeStart(); + spaceInvadersStart(); + particlesStart(); + brickBreakerStart(); + + DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; + draw_system.default_data.size = vec2(16,16); + draw_system.default_data.coords = vec4(0,48,16,16)*demos.simple.px; + draw_system.default_data.material_id = 0; + draw_system.default_data.texture = particles_demo.texture; + draw_system.default_data.color = 0x80808080; + + gEntityManager.getSystem(becsID!MouseAttractSystem).disable(); + gEntityManager.getSystem(becsID!(demos.simple.MoveSystem)).disable(); + +} + +void sandboxEnd() +{ + simpleEnd(); + snakeEnd(); + spaceInvadersEnd(); + particlesEnd(); +} +/* +void sandboxEvent(SDL_Event* event) +{ +}*/ + +bool sandboxLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + gEntityManager.begin(); + + float delta_time = launcher.delta_time; + if(delta_time > 2000)delta_time = 2000; + __gshared float time = 0; + + /*if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3; + else */ + time += delta_time; + + while(time > 200) + { + time -= 200; + + gEntityManager.update("fixed"); + } + + if(launcher.multithreading) + { + launcher.job_updater.begin(); + gEntityManager.updateMT(); + launcher.job_updater.call(); + } + else + { + gEntityManager.update(); + } + gEntityManager.end(); + + return true; +} + +DemoCallbacks getSanboxDemo() +{ + DemoCallbacks demo; + demo.initialize = &sandboxStart; + demo.deinitialize = &sandboxEnd; + demo.loop = &sandboxLoop; + demo.tips = "This demo contains all components, systems and events from previous demos. They was not designed for that kind of coexisting. Some system collide with other making some weird things. +This gives biggest opportunities. You can add tower on top of snake, or lasers to paddle from BrickBreaker. This will be improved in next versions of ECS demo."; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d new file mode 100644 index 0000000..010bae4 --- /dev/null +++ b/demos/source/demos/simple.d @@ -0,0 +1,283 @@ +module demos.simple; + +import app; + +import bindbc.sdl; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import cimgui.cimgui; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; +import game_core.rendering; + +extern(C): + +enum float px = 1.0/512.0; + +/************************************************** +All demos uses same patten. Every demo is self contained except systems and components which was splitted into different files to enable sharing them between demos. +Every demo has same functions: + * register - called on start for registering proces + * initialize - called after register to initialize demo data + * deinitiliaze - called when demo is switching. There data is deisposed + * loop - it's called every frame + + Demos uses some non-ECS functions to register components, systems and templates into GUI. Then components are showing by GUI and can be added to entities. +*/ + +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ + +//CLocation component was moved to game_code.basic +/*struct CLocation +{ + mixin ECS.Component; + + alias location this; + + vec2 location; +}*/ + +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ +//DrawSystem was moved to game_code.basic +/* +struct DrawSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + //uint thread_id; + uint job_id; + @readonly CLocation[] locations; + } + + void onUpdate(EntitiesData data) + { + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.coords = vec4(0,0,1,1); + draw_data.color = 0x80808080; + draw_data.material_id = 0; + draw_data.thread_id = data.job_id; + draw_data.texture = simple.texture; + + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = cast(ushort)(data.locations[i].y); + launcher.renderer.draw(draw_data); + } + } +}*/ + +//simple system which moves entities +struct MoveSystem +{ + //system will generate up to 64 jobs for multithreaded extecution + mixin ECS.System!64; + + //structe contains components used by system + struct EntitiesData + { + uint length; + //system will use one component which is required. Only entities with CLocation component will be processed by this system + CLocation[] locations; + } + + //onUpdate is called several times and covers all entities + void onUpdate(EntitiesData data) + { + //loop over entities in batch + foreach(i; 0..data.length) + { + //inscrease entity position in 'y' coordinate + data.locations[i].y = data.locations[i].y + 1; + //move entity to 0 if exceeded 300 + if(data.locations[i].y > 300)data.locations[i].y = 0; + } + } +} + +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct Simple +{ + //tips showed in GUI + __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Demo\" window. +\"Tools\" window exists of three tools which can be used to manipulate game. +Options: + * Show Tool - enable/disable rendering of blue circle around cursor + * Show Filtered - enable/disable higliting filtered entities. For \"Component manipulator\" tool it shows entities which has selected component. + * Add/Remove - select primary action. LMB - primary action, RMB - secondary action + * Tools size - size of tool + * Tool repeat - how many times in one second tool should take action (e.g. 1000 means every second \"Entity spawner\" will spawn 1000 enties) + * Override - enabled means that \"Component manipulator\" will override components data if entity already has that component +Tools: + * Entity spawner - used to spawn new entities + * Component manipulator - used to add/remove components to/from entities + * Selector - allow to select entity, show and modify his data. Only one entity can be selected, selector selects entity nearest co cursor. + +ShortCuts: + * CRTL*1/2/3 - change tool + * Mouse wheel - change tool size + * SHIFT + Mouse wheel - change entity/component in tool list + * LBM - primary action (default: add entity / add component) + * RMB - secondary action (default: remove entity / remove component) + +\"Statistic\" windows shows FPS and entities count. + +From top menu bar (upper left corner) you can select different demos or change some options. Multihtreading is highly recommended, but it can not working on mobile phones or Firefox browser. + +Demo is capable rendering of hundreds of thousands of entities. Playable area is heavily too small to show that count of entities, but you can try it :)"; + + EntityTemplate* tmpl; + Texture texture; +} + +__gshared Simple* simple; + +//called when demo starts +void simpleRegister() +{ + simple = Mallocator.make!Simple; + + //load texture (atlas) + simple.texture.create(); + simple.texture.load("assets/textures/atlas.png"); + + //start registering process + gEntityManager.beginRegister(); + + //register basic components and systems + registerRenderingModule(gEntityManager); + + //register location component. It also registered inside registerRenderingModule() function, but it's there for clarity + gEntityManager.registerComponent!CLocation; + + gEntityManager.registerSystem!MoveSystem(0); + // DrawSystem is registered as RenderingModule + // gEntityManager.registerSystem!DrawSystem(1); + + //end registering process + gEntityManager.endRegister(); +} + +//called after simpleRegister +void simpleStart() +{ + //get DrawSystem instance and change some data + DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; + draw_system.default_data.color = 0x80808080; + draw_system.default_data.texture = simple.texture; + draw_system.default_data.size = vec2(16,16); + draw_system.default_data.coords = vec4(0,48,16,16)*px;//vec4(0,0,1,1); + + //add systems to GUI. It's non ECS part + launcher.gui_manager.addSystem(becsID!MoveSystem,"Move Up System"); + launcher.gui_manager.addSystem(becsID!DrawSystem,"Draw System"); + + //add components to GUI. It's non ECS part + launcher.gui_manager.addComponent(CLocation(), "Location"); + launcher.gui_manager.addComponent(CDrawDefault(), "DrawDefault"); + + //allocate new template with two components + simple.tmpl = gEntityManager.allocateTemplate([becsID!CLocation, becsID!CDrawDefault].staticArray); + + //add template to GUI. It's non ECS part + launcher.gui_manager.addTemplate(simple.tmpl, "Basic"); + + //add 100 entities + foreach(i; 0..10) + foreach(j; 0..10) + { + //add entities in grid locations. "ref_" return ComponentRef structure. I'm not sure if adding component inside array generation isn't undefined behaviour but it works on tested platforms + gEntityManager.addEntity(simple.tmpl,[CLocation(vec2(i*16+64,j*16+64)).ref_].staticArray); + } +} + +//called when demo is switched to different one +void simpleEnd() +{ + //disable systems used by this demo. + gEntityManager.getSystem(becsID!MoveSystem).disable(); + gEntityManager.getSystem(becsID!DrawSystem).disable(); + + //free texture memory + simple.texture.destroy(); + + //GUI manager will free template + //gEntityManager.freeTemplate(simple.tmpl); + Mallocator.dispose(simple); +} + +void simpleEvent(SDL_Event* event) +{ +} + +void spawnEntity() +{ + //spawn entity in random location + gEntityManager.addEntity(simple.tmpl,[CLocation(vec2(randomf() * 400,0)).ref_].staticArray); +} + +bool simpleLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + if(launcher.getKeyState(SDL_SCANCODE_SPACE)) + { + foreach(i;0..20)spawnEntity(); + } + + //begin frame + gEntityManager.begin(); + //if multithreading is enabled different path is used + if(launcher.multithreading) + { + //prepare data for multithreading. Clear previous jobs data. + launcher.job_updater.begin(); + //generate jobs + gEntityManager.updateMT(); + //call jobs in multithreaded fashion + launcher.job_updater.call(); + } + else + { + //update call will call inUpdate for all systems + gEntityManager.update(); + + } + //end ECS frame + gEntityManager.end(); + + return true; +} + +DemoCallbacks getSimpleDemo() +{ + DemoCallbacks demo; + demo.register = &simpleRegister; + demo.initialize = &simpleStart; + demo.deinitialize = &simpleEnd; + demo.loop = &simpleLoop; + demo.tips = simple.tips; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d new file mode 100644 index 0000000..78b6d3e --- /dev/null +++ b/demos/source/demos/snake.d @@ -0,0 +1,1021 @@ +module demos.snake; + +import app; + +import bindbc.sdl; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; +import bubel.ecs.vector; + +import cimgui.cimgui; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; + +import gui.attributes; +//import std.array : staticArray; + +enum float px = 1.0/512.0; + +extern(C): + +//Map is simple grid. Every cell has type and id to entity. +struct MapElement +{ + enum Type + { + empty = 0, + apple = 1, + wall = 2, + snake = 3, + } + Type type; + EntityID id; +} + +//snake part is corresponding to graphical representation of snake +enum SnakePart : ubyte +{ + head_up = 0, + head_down = 1, + head_left = 2, + head_right = 3, + tail_up = 4, + tail_down = 5, + tail_left = 6, + tail_right = 7, + turn_ld = 8, + turn_lu = 9, + turn_rd = 10, + turn_ru = 11, + vertical = 12, + horizontal = 13 +} + +struct Snake +{ + __gshared const (char)* tips = "Use \"WASD\" keys to move. If you loose you can always spawn new snake... or several snakes. +This demo is an example that in ECS you can make very \"non-ECS\" game"; + + EntityTemplate* apple_tmpl; + EntityTemplate* snake_tmpl; + EntityTemplate* snake_destroy_particle; + Texture texture; + + vec4[] snake_destroy_particle_frames; + vec4[] smoke_frames; + + + bool move_system = true; + bool draw_system = true; + + enum int map_size = 18; + + MapElement[map_size * map_size] map; + + ~this() @nogc nothrow + { + if(snake_destroy_particle_frames)Mallocator.dispose(snake_destroy_particle_frames); + if(smoke_frames)Mallocator.dispose(smoke_frames); + if(apple_tmpl)gEntityManager.freeTemplate(apple_tmpl); + if(snake_tmpl)gEntityManager.freeTemplate(snake_tmpl); + if(snake_destroy_particle)gEntityManager.freeTemplate(snake_destroy_particle); + texture.destroy(); + } + + MapElement element(ivec2 pos) + { + uint index = pos.x + pos.y * map_size; + if(index >= map.length)index = map.length - 1; + return map[index]; + } + + void element(MapElement el, ivec2 pos) + { + uint index = pos.x + pos.y * map_size; + if(index >= map.length)index = map.length - 1; + map[index] = el; + } + + void addApple() + { + ivec2 random_pos = ivec2(rand()%map_size,rand()%map_size); + ivec2 base_pos = random_pos; + while(element(random_pos).type != MapElement.Type.empty) + { + random_pos.x += 1; + if(random_pos.x > map_size) + { + random_pos.x = 0; + random_pos.y += 1; + if(random_pos.y > map_size)random_pos.y = 0; + } + if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return; + } + gEntityManager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray); + } +} + +struct Animation +{ + +} + +//component has array of frames (texture coordinates) and time used for selection frames +struct CAnimation +{ + mixin ECS.Component; + + vec4[] frames; + @GUIRangeF(0,float.max)float time = 0; +} + +//CIlocation is integer location used as grid cell coordination +struct CILocation +{ + mixin ECS.Component; + + alias location this; + + ivec2 location; +} + +// struct CLocation +// { +// mixin ECS.Component; + +// alias location this; + +// vec2 location = vec2(0,0); +// } + +struct CSnake +{ + void onCreate() + { + parts.array = Mallocator.makeArray!ivec2(100); + } + + void onDestroy() + { + Mallocator.dispose(parts.array); + } + + mixin ECS.Component; + + + struct Parts + { + uint length = 0; + ivec2[] array; + + ivec2 opIndex(size_t ind) const + { + return array[ind]; + } + + ivec2[] opSlice() + { + return array[0 .. length]; + } + + void opIndexAssign(ivec2 vec, size_t ind) + { + array[ind] = vec; + } + + size_t opDollar() const + { + return length; + } + + void add(ivec2 v) + { + length++; + array[length-1] = v; + } + } + + Parts parts; + @GUIRange(0,3)CMovement.Direction direction; +} + +//flag for apple +struct CApple +{ + mixin ECS.Component; +} + +//particle is removed when life drops below 0 +struct CParticle +{ + mixin ECS.Component; + + float life = 0; +} + +//vector for particle movement +struct CParticleVector +{ + mixin ECS.Component; + + vec2 velocity = vec2(0,0); +} + +//contains current movement direction for snake +struct CMovement +{ + mixin ECS.Component; + + enum Direction : byte + { + up, + down, + left, + right + } + + @GUIRange(0,3)Direction direction; +} + +// struct CInput +// { +// mixin ECS.Component; +// } + +//this system has no onUpdate and only processing events. It responsible for adding and removing applce from grid. +struct AppleSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly Entity[] entity; + @readonly CApple[] apple; + @readonly CILocation[] location; + } + + //called when entity was created + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.apple,data.entity[i].id),data.location[i]); + else gEntityManager.removeEntity(data.entity[i].id); + } + } + + //called when entity was removed + void onRemoveEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i].location).id == data.entity[i].id) + snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location); + } + } +} + +//system is responsible for killing particles when their life drops below 0 +struct ParticleSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly Entity[] entities; + CParticle[] particle; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.particle[i].life -= launcher.deltaTime; + if(data.particle[i].life < 0)gEntityManager.removeEntity(data.entities[i].id); + } + } +} + +//system responsible for moving particles +struct ParticleMovementSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly Entity[] entities; + @readonly CParticleVector[] movement; + CLocation[] location; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.location[i] -= data.movement[i].velocity; + } + } +} + + +struct AnimationSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + CAnimation[] animation; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.animation[i].time += launcher.deltaTime * 0.01; + while(data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; + } + } +} + + +struct AnimationRenderSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CAnimation[] animation; + @readonly CLocation[] location; + } + + void onUpdate(EntitiesData data) + { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + //draw_data.coords = vec4(0,0,1,1)*px; + draw_data.color = 0x80808080; + draw_data.material_id = 0; + draw_data.thread_id = 0; + draw_data.texture = snake.texture; + draw_data.depth = -1; + foreach(i;0..data.length) + { + uint frame = cast(uint)(data.animation[i].time); + if(frame >= data.animation[i].frames.length)frame = cast(uint)data.animation[i].frames.length - 1; + draw_data.position = data.location[i]; + draw_data.coords = data.animation[i].frames[frame]; + launcher.renderer.draw(draw_data); + } + } +} + +struct MoveSystem +{ + mixin ECS.System!64; + + EntityTemplate* destroy_template; + + struct EntitiesData + { + uint length; + @readonly Entity[] entities; + @readonly CMovement[] movement; + @optional CSnake[] snakes; + CILocation[] location; + } + + void setTemplates() + { + //template is used for adding particles when snake will collide with himself + destroy_template = snake.snake_destroy_particle; + } + + void moveLocation(ref CILocation location, CMovement.Direction direction) + { + final switch(direction) + { + case CMovement.Direction.down: + location.y -= 1; + if(location.y < 0)location.y = snake.map_size - 1; + break; + case CMovement.Direction.up: + location.y += 1; + if(location.y >= snake.map_size)location.y = 0; + break; + case CMovement.Direction.left: + location.x -= 1; + if(location.x < 0)location.x = snake.map_size - 1; + break; + case CMovement.Direction.right: + location.x += 1; + if(location.x >= snake.map_size)location.x = 0; + break; + } + } + + void moveSnake(ref CSnake snake, ivec2 location) + { + if(snake.parts.length) + { + .snake.element(MapElement(),snake.parts[0]); + foreach(j; 0 .. snake.parts.length - 1) + { + snake.parts[j] = snake.parts[j + 1]; + } + snake.parts[$-1] = location; + } + else .snake.element(MapElement(),location); + } + + void onUpdate(EntitiesData data) + { + if(data.snakes) + { + foreach(i; 0..data.length) + { + data.snakes[i].direction = data.movement[i].direction; + ivec2 new_location = data.location[i]; + moveLocation(data.location[i], data.movement[i].direction); + final switch(snake.element(data.location[i].location).type) + { + case MapElement.Type.snake: + foreach(loc; data.snakes[i].parts) + { + //destroy_location.x = loc.x * 16; + //destroy_location.y = loc.y * 16; + snake.element(MapElement(MapElement.Type.empty, EntityID()),loc); + gEntityManager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(loc * 16)).ref_].staticArray); + + CLocation destroy_location; + foreach(j;0..10) + { + destroy_location.x = loc.x * 16 + randomf() * 8 - 4; + destroy_location.y = loc.y * 16 + randomf() * 8 - 4; + //destroy_vector.velocity = vec2(randomf(),randomf())*0.4-0.2; + snake.element(MapElement(MapElement.Type.empty, EntityID()),loc); + gEntityManager.addEntity(snake.snake_destroy_particle, [destroy_location.ref_, CParticleVector(vec2(randomf(),randomf())*0.4-0.2).ref_].staticArray); + } + + } + //destroy_location.x = new_location.x * 16; + //destroy_location.y = new_location.y * 16; + snake.element(MapElement(MapElement.Type.empty, EntityID()),new_location); + gEntityManager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(new_location * 16)).ref_].staticArray); + gEntityManager.removeEntity(data.entities[i].id); + break; + + case MapElement.Type.wall:break; + + case MapElement.Type.empty: + moveSnake(data.snakes[i], new_location); + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.location[i].location); + if(data.snakes[i].parts.length > 1) + { + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[$-1]); + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[0]); + } + else if(data.snakes[i].parts.length == 1) + { + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[0]); + } + break; + case MapElement.Type.apple: + gEntityManager.removeEntity(snake.element(data.location[i].location).id); + if(data.snakes[i].parts.length >= 99) + { + snake.addApple(); + goto case(MapElement.Type.empty); + } + data.snakes[i].parts.add(new_location); + + if(data.snakes[i].parts.length > 1) + { + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[$-1]); + } + else if(data.snakes[i].parts.length == 1) + { + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),new_location); + } + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.location[i].location); + snake.addApple(); + break; + } + } + } + else + { + foreach(i; 0..data.length) + { + final switch(data.movement[i].direction) + { + case CMovement.Direction.down:data.location[i].y -= 1;break; + case CMovement.Direction.up:data.location[i].y += 1;break; + case CMovement.Direction.left:data.location[i].x -= 1;break; + case CMovement.Direction.right:data.location[i].x += 1;break; + } + } + } + } +} + +struct SnakeSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + Entity[] entity; + @readonly CSnake[] snake; + @readonly CILocation[] location; + } + + void onAddSystem(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.snake,data.entity[i].id),data.location[i]); + else gEntityManager.removeEntity(data.entity[i].id); + } + } + + void onRemoveEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i].location).id == data.entity[i].id) + snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location); + foreach(part; data.snake[i].parts.array) + if(snake.element(part).id == data.entity[i].id) + snake.element(MapElement(MapElement.Type.empty, EntityID()),part); + } + } +} + +struct InputSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CMovement[] movement; + @readonly CInput[] input; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + if(launcher.getKeyState(SDL_SCANCODE_W)) + { + data.movement[i].direction = CMovement.Direction.up; + } + else if(launcher.getKeyState(SDL_SCANCODE_S)) + { + data.movement[i].direction = CMovement.Direction.down; + } + else if(launcher.getKeyState(SDL_SCANCODE_A)) + { + data.movement[i].direction = CMovement.Direction.left; + } + else if(launcher.getKeyState(SDL_SCANCODE_D)) + { + data.movement[i].direction = CMovement.Direction.right; + } + } + } +} + +struct FixSnakeDirectionSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CMovement[] movement; + @readonly CILocation[] location; + const (CSnake)[] snake; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + ivec2 last_location; + if(data.snake[i].parts.length)last_location = data.snake[i].parts[$ - 1]; + else continue; + ivec2 next_location = data.location[i]; + + final switch(data.movement[i].direction) + { + case CMovement.Direction.up: + next_location.y += 1; + if(next_location.y >= snake.map_size)next_location.y = 0; + if(next_location.x == last_location.x && next_location.y == last_location.y) + { + data.movement[i].direction = CMovement.Direction.down; + } + break; + case CMovement.Direction.down: + next_location.y -= 1; + if(next_location.y < 0)next_location.y = snake.map_size - 1; + if(next_location.x == last_location.x && next_location.y == last_location.y) + { + data.movement[i].direction = CMovement.Direction.up; + } + break; + case CMovement.Direction.left: + next_location.x -= 1; + if(next_location.x < 0)next_location.x = snake.map_size - 1; + if(next_location.x == last_location.x && next_location.y == last_location.y) + { + data.movement[i].direction = CMovement.Direction.right; + } + break; + case CMovement.Direction.right: + next_location.x += 1; + if(next_location.x >= snake.map_size)next_location.x = 0; + if(next_location.x == last_location.x && next_location.y == last_location.y) + { + data.movement[i].direction = CMovement.Direction.left; + } + break; + } + } + } +} + +struct DrawAppleSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CILocation[] location; + const (CApple)[] apple; + } + + void onUpdate(EntitiesData data) + { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.coords = vec4(0,32*px,16*px,16*px); + draw_data.color = 0x80808080; + draw_data.material_id = 0; + draw_data.thread_id = 0; + draw_data.texture = snake.texture; + foreach(i; 0..data.location.length) + { + draw_data.position = vec2(data.location[i].x*16,data.location[i].y*16); + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0x80808080, 0); + } + } +} + +struct DrawSnakeSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CILocation[] location; + const (CSnake)[] snake; + } + + static CMovement.Direction getDirection(ivec2 p1, ivec2 p2) + { + if(p1.x - p2.x == -1)return CMovement.direction.right; + else if(p1.x - p2.x == 1)return CMovement.direction.left; + else if(p1.y - p2.y == -1)return CMovement.direction.up; + else if(p1.y - p2.y == 1)return CMovement.direction.down; + else if(p1.x - p2.x > 1)return CMovement.direction.right; + else if(p1.x - p2.x < -1)return CMovement.direction.left; + else if(p1.y - p2.y > 1)return CMovement.direction.up; + else return CMovement.direction.down; + } + + static SnakePart snakePart(ivec2 p1, ivec2 p2, ivec2 p3) + { + CMovement.Direction direction = getDirection(p1, p2); + CMovement.Direction direction2 = getDirection(p1, p3); + uint case_ = direction*4 + direction2; + final switch(case_) + { + case 0:return SnakePart.horizontal; + case 1:return SnakePart.horizontal; + case 2:return SnakePart.turn_lu; + case 3:return SnakePart.turn_ru; + case 4:return SnakePart.horizontal; + case 5:return SnakePart.horizontal; + case 6:return SnakePart.turn_ld; + case 7:return SnakePart.turn_rd; + case 8:return SnakePart.turn_lu; + case 9:return SnakePart.turn_ld; + case 10:return SnakePart.vertical; + case 11:return SnakePart.vertical; + case 12:return SnakePart.turn_ru; + case 13:return SnakePart.turn_rd; + case 14:return SnakePart.vertical; + case 15:return SnakePart.vertical; + } + } + + static SnakePart snakeTail(ivec2 p1, ivec2 p2) + { + CMovement.Direction direction = getDirection(p1, p2); + final switch(direction) + { + case CMovement.Direction.up:return SnakePart.tail_up; + case CMovement.Direction.down:return SnakePart.tail_down; + case CMovement.Direction.left:return SnakePart.tail_left; + case CMovement.Direction.right:return SnakePart.tail_right; + } + } + + static void drawElement(ivec2 loc, SnakePart part) + { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.color = 0x80808080; + draw_data.texture = snake.texture; + draw_data.position = cast(vec2)loc; + final switch(cast(ubyte)part) + { + case SnakePart.tail_up:draw_data.coords = vec4(16,112,16,16)*px;break; + case SnakePart.tail_down:draw_data.coords = vec4(0,112,16,16)*px;break; + case SnakePart.tail_left:draw_data.coords = vec4(32,112,16,16)*px;break; + case SnakePart.tail_right:draw_data.coords = vec4(0,144,16,16)*px;break; + case SnakePart.turn_ld:draw_data.coords = vec4(64,128,16,16)*px;break; + case SnakePart.turn_lu:draw_data.coords = vec4(32,144,16,16)*px;break; + case SnakePart.turn_rd:draw_data.coords = vec4(16,144,16,16)*px;break; + case SnakePart.turn_ru:draw_data.coords = vec4(64,112,16,16)*px;break; + case SnakePart.vertical:draw_data.coords = vec4(16,128,16,16)*px;break; + case SnakePart.horizontal:draw_data.coords = vec4(48,128,16,16)*px;break; + } + launcher.renderer.draw(draw_data); + } + + void onUpdate(EntitiesData data) + { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.color = 0x80808080; + draw_data.texture = snake.texture; + + foreach(i; 0..data.length) + { + const (CSnake)* snake = &data.snake[i]; + scope vec2 loc = cast(vec2)(data.location[i].location * 16); + draw_data.position = loc; + final switch(snake.direction) + { + case CMovement.Direction.up:draw_data.coords = vec4(48,112,16,16)*px;break; + case CMovement.Direction.down:draw_data.coords = vec4(48,144,16,16)*px;break; + case CMovement.Direction.left:draw_data.coords = vec4(0,128,16,16)*px;break; + case CMovement.Direction.right:draw_data.coords = vec4(32,128,16,16)*px;break; + } + launcher.renderer.draw(draw_data); + if(snake.parts.length >1) + { + foreach(j;1..snake.parts.length - 1)drawElement(snake.parts[j]*16, snakePart(snake.parts[j], snake.parts[j+1], snake.parts[j-1])); + drawElement(snake.parts[$-1]*16, snakePart(snake.parts[$-1], data.location[i], snake.parts[$-2])); + drawElement(snake.parts[0]*16, snakeTail(snake.parts[1], snake.parts[0])); + } + else if(snake.parts.length == 1) + { + drawElement(snake.parts[0]*16, snakeTail(data.location[i], snake.parts[0])); + } + + } + } +} + +struct CleanSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + Entity[] entities; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + gEntityManager.removeEntity(data.entities[i].id); + } + } +} + +struct CopyLocationSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + CLocation[] location; + @readonly CILocation[] ilocation; + } + + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + data.ilocation[i] = cast(ivec2)(data.location[i] / 16); + } + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.location[i] = cast(vec2)(data.ilocation[i] * 16); + } + } +} + +__gshared Snake* snake; + +void snakeRegister() +{ + import game_core.rendering; + + snake = Mallocator.make!Snake; + + snake.texture.create(); + snake.texture.load("assets/textures/atlas.png"); + + gEntityManager.beginRegister(); + + gEntityManager.registerPass("fixed"); + + registerRenderingModule(gEntityManager); + + gEntityManager.registerComponent!CLocation; + gEntityManager.registerComponent!CILocation; + gEntityManager.registerComponent!CSnake; + gEntityManager.registerComponent!CApple; + gEntityManager.registerComponent!CParticle; + gEntityManager.registerComponent!CParticleVector; + gEntityManager.registerComponent!CMovement; + gEntityManager.registerComponent!CInput; + gEntityManager.registerComponent!CAnimation; + + gEntityManager.registerSystem!MoveSystem(0,"fixed"); + gEntityManager.registerSystem!InputSystem(-100); + gEntityManager.registerSystem!FixSnakeDirectionSystem(-1,"fixed"); + gEntityManager.registerSystem!AnimationRenderSystem(100); + gEntityManager.registerSystem!AnimationSystem(-1); + gEntityManager.registerSystem!ParticleSystem(-1); + gEntityManager.registerSystem!ParticleMovementSystem(-1); + gEntityManager.registerSystem!DrawAppleSystem(99); + gEntityManager.registerSystem!DrawSnakeSystem(101); + + gEntityManager.registerSystem!CopyLocationSystem(100); + //gEntityManager.registerSystem!AppleRemoveSystem(100); + gEntityManager.registerSystem!AppleSystem(101); + gEntityManager.registerSystem!SnakeSystem(101); + + gEntityManager.endRegister(); +} + +void snakeStart() +{ + launcher.gui_manager.addComponent(CApple(),"Apple"); + launcher.gui_manager.addComponent(CSnake(),"Snake"); + launcher.gui_manager.addComponent(CParticle(1000),"Particle"); + launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector"); + launcher.gui_manager.addComponent(CInput(),"Input"); + launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement"); + launcher.gui_manager.addComponent(CAnimation(),"Animation"); + launcher.gui_manager.addComponent(CILocation(),"Int Location"); + launcher.gui_manager.addComponent(CLocation(),"Location"); + + launcher.gui_manager.addSystem(becsID!MoveSystem,"Move System"); + launcher.gui_manager.addSystem(becsID!InputSystem,"Input System"); + launcher.gui_manager.addSystem(becsID!FixSnakeDirectionSystem,"Fix Direction System"); + launcher.gui_manager.addSystem(becsID!AnimationRenderSystem,"Animation Render System"); + launcher.gui_manager.addSystem(becsID!AnimationSystem,"Animation System"); + launcher.gui_manager.addSystem(becsID!ParticleSystem,"Particle Life System"); + launcher.gui_manager.addSystem(becsID!ParticleMovementSystem,"Particle Movement System"); + launcher.gui_manager.addSystem(becsID!DrawAppleSystem,"Draw Apple System"); + launcher.gui_manager.addSystem(becsID!DrawSnakeSystem,"Draw Snake System"); + launcher.gui_manager.addSystem(becsID!CopyLocationSystem,"Copy Location System"); + //launcher.gui_manager.addSystem(becsID!AppleSystem,"Apple System"); + //launcher.gui_manager.addSystem(becsID!SnakeSystem,"Snake System"); + + snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray); + + { + ushort[5] components = [becsID!CILocation, becsID!CSnake, becsID!CMovement, becsID!CInput, becsID!CLocation]; + snake.snake_tmpl = gEntityManager.allocateTemplate(components); + gEntityManager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray); + } + + { + snake.snake_destroy_particle = gEntityManager.allocateTemplate([becsID!CLocation, becsID!CParticle, becsID!CParticleVector, becsID!CAnimation, becsID!CLocation].staticArray); + CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation; + canim.frames = snake.snake_destroy_particle_frames; + CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle; + particle.life = 400; + } + + { + ushort[3] components = [becsID!CILocation, becsID!CApple, becsID!CLocation]; + snake.apple_tmpl = gEntityManager.allocateTemplate(components); + snake.addApple(); + } + + launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(snake.snake_tmpl), "Snake"); + launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(snake.apple_tmpl), "Apple"); + launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(snake.snake_destroy_particle), "Particle"); + + MoveSystem* move_system = gEntityManager.getSystem!MoveSystem(); + move_system.setTemplates(); +} + +void snakeEnd() +{ + //gEntityManager.freeTemplate(simple.tmpl); + Mallocator.dispose(snake); +} + +void snakeEvent(SDL_Event* event) +{ + +} + +bool snakeLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(288,288)) * 0.5; + + // if(launcher.show_demo_wnd) + // { + // igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0)); + // igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once); + // if(igBegin("Snake",&launcher.show_demo_wnd,0)) + // { + + // } + // igEnd(); + // } + + gEntityManager.begin(); + + float delta_time = launcher.deltaTime; + if(delta_time > 2000)delta_time = 2000; + __gshared float time = 0; + + if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3; + else time += delta_time; + + while(time > 200) + { + time -= 200; + + gEntityManager.update("fixed"); + } + + gEntityManager.update(); + + gEntityManager.end(); + + return true; +} + +DemoCallbacks getSnakeDemo() +{ + DemoCallbacks demo; + demo.register = &snakeRegister; + demo.initialize = &snakeStart; + demo.deinitialize = &snakeEnd; + demo.loop = &snakeLoop; + demo.tips = snake.tips; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d new file mode 100644 index 0000000..83f1e7a --- /dev/null +++ b/demos/source/demos/space_invaders.d @@ -0,0 +1,2449 @@ +module demos.space_invaders; + +import app; + +import bindbc.sdl; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import cimgui.cimgui; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; +import game_core.rendering; +import game_core.collision; + +import gui.attributes; + +private enum float px = 1.0/512.0; + + +extern(C): + +/*####################################################################################################################### +------------------------------------------------ Types ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct SpaceInvaders +{ + __gshared const (char)* tips = "Use \"WASD\" keys to move and \"Space\" for shooting. +On start there is not to much to do. But you can spawn thousands of entities. You can even change guild for enemies to make them kilking themselves. +You can add any component to any entity which sometimes can give fun results. This demo wasn't created with such combination in mind, but that is something which comes naturally with ECS."; + + EntityTemplate* enemy_tmpl; + EntityTemplate* ship_tmpl; + EntityTemplate* laser_tmpl; + EntityTemplate*[5] bullet_tmpl; + Texture texture; + + ShootGrid* shoot_grid; + + bool move_system = true; + bool draw_system = true; + + const vec2 map_size = vec2(400,300); + const float cell_size = 60; + + EntityID player_ship; + + ~this() @nogc nothrow + { + // if(shoot_grid)Mallocator.dispose(shoot_grid); + if(enemy_tmpl)gEntityManager.freeTemplate(enemy_tmpl); + if(ship_tmpl)gEntityManager.freeTemplate(ship_tmpl); + if(laser_tmpl)gEntityManager.freeTemplate(laser_tmpl); + foreach (EntityTemplate* tmpl; bullet_tmpl) + { + if(tmpl)gEntityManager.freeTemplate(tmpl); + } + texture.destroy(); + } +} + +struct SceneGrid +{ + struct Element + { + EntityID entity; + int guild; + vec2 min; + vec2 max; + } + + struct Cell + { + Element[20] elements; + } + + void create() + { + cells_count.x = cast(int)((space_invaders.map_size.x - 0.01f) / space_invaders.cell_size) + 1; + cells_count.y = cast(int)((space_invaders.map_size.y - 0.01f) / space_invaders.cell_size) + 1; + cells = Mallocator.makeArray!Cell(cells_count.x * cells_count.y); + } + + void destroy() + { + if(cells) + { + Mallocator.dispose(cells); + cells = null; + } + } + + ivec2 cells_count; + Cell[] cells; +} + +enum Direction : byte +{ + up, + down, + left, + right +} + +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ + +/*struct CLocation +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(0); +} + +struct CScale +{ + mixin ECS.Component; + + ///use component as it value + alias value this; + + vec2 value = vec2(16,16); +} + +struct CDepth +{ + mixin ECS.Component; + + alias depth this; + + short depth; +} + +struct CRotation +{ + mixin ECS.Component; + + ///use component as it value + alias value this; + + float value = 0; +} + +struct CTexture +{ + mixin ECS.Component; + + //Texture tex; + uint id; + vec4 coords = vec4(0,0,0,1); +}*/ + +// struct CVelocity +// { +// mixin ECS.Component; + +// alias value this; + +// vec2 value = vec2(0,0); +// } + +struct CEnemy +{ + mixin ECS.Component; +} + +struct CShip +{ + mixin ECS.Component; +} + +struct CAutoShoot +{ + mixin ECS.Component; +} + +struct CGuild +{ + mixin ECS.Component; + + byte guild; +} + +struct CBullet +{ + mixin ECS.Component; + + int damage = 1; +} + +struct CWeapon +{ + mixin ECS.Component; + + static struct Level + { + float reload_time; + float dispersion; + int damage; + } + + __gshared Level[12] levels = [Level(4000,0),Level(4000,0.1), + Level(500,0),Level(350,0),Level(250,0.02),Level(175,0.03),Level(110,0.04), + Level(80,0.05),Level(50,0.08),Level(20,0.1),Level(10,0.12),Level(2,0.14)]; + + enum Type : ubyte + { + laser, + enemy_laser, + blaster, + canon, + plasma + } + + float shoot_time = 0; + @GUIRange(0, 4) Type type; + @GUIRange(0, 11) ubyte level = 1; +} + +struct CWeaponLocation +{ + mixin ECS.Component; + + vec2 rel_pos = vec2(0,0); +} + +struct CShootDirection +{ + mixin ECS.Component; + + @GUIRange(0, 3) Direction direction; +} + +struct CSideMove +{ + mixin ECS.Component; + + byte group = -1; +} + +struct CTargetParent +{ + mixin ECS.Component; + + EntityID parent; + vec2 rel_pos = vec2(0,0); +} + + +struct CHitPoints +{ + mixin ECS.Component; + + alias value this; + + int value = 3; +} + +struct CMaxHitPoints +{ + mixin ECS.Component; + + alias value this; + + int value = 3; +} + +struct CHitMark +{ + mixin ECS.Component; + + alias value this; + + ubyte value = 0; +} + +struct CUpgrade +{ + mixin ECS.Component; + + alias value this; + + enum Upgrade : ubyte + { + hit_points, + regeneration, + laser + } + + Upgrade value; +} + +struct CAnimation +{ + mixin ECS.Component; + + vec4[] frames; + @GUIRangeF(0, float.max)float time = 0; + @GUIRangeF(0, float.max)float speed = 1; +} + +struct CAnimationLooped +{ + mixin ECS.Component; +} + + + +struct CParticle +{ + mixin ECS.Component; + + float life = 0; +} + +struct CTarget +{ + mixin ECS.Component; + + EntityID target; +} + +struct CTargetPlayerShip +{ + mixin ECS.Component; +} + +struct CChildren +{ + mixin ECS.Component; + + EntityID[] childern; +} + +struct CBoss +{ + mixin ECS.Component; +} + +struct CParts +{ + mixin ECS.Component; + + @GUIDisabled ubyte count; +} + +struct CInit +{ + mixin ECS.Component; + + enum Type + { + space_ship, + tower, + boss + } + + @GUIRange(0, 2)Type type; +} + +struct CParticleEmitter +{ + mixin ECS.Component; + + vec2 range = vec2(0,0); + vec2 time_range = vec2(500,1000); + ///It can be array of tempaltes or (like in this demo) simply index of template; + //uint tmpl_id; + //EntityTemplate* tmpl; +} + +///Due to perfarmance reason emitter time and attributes are divided into seprate components. +///Beyon that both components are considerd to be used together. +struct CParticleEmitterTime +{ + mixin ECS.Component; + + float time = 0; +} + +///You can create separate component for every kind of spawned entities but it's not practial due to archetype fragmentation. +///Second approach can be commented code. It's gives good flexibility inchoosing entity, but it limits to one entity. +///Instead of entity it can be array of templates which is good solution, but if possibilities is known at time of game development it +///can be simply index/enum for type of spawn. Bad thing about this solution is problem witch merging multiple spawning types during +///gameplay, i.e. giving buff which cast firebols upon death. +struct CSpawnUponDeath +{ + mixin ECS.Component; + + enum Type + { + flashes_emitter, + } + + //EntityID parent; + //EntityTemplate* tmpl; + @GUIRange(0,0) Type type; +} + +///This component can be replaced by "CSpawnUponDeath" but I want to gives possibility to add this component to every entity +///during gameplay. End application works exacly the same way for every demo so I can't use different way as adding component. +struct CShootWaveUponDeath +{ + mixin ECS.Component; + + @GUIRange(0, 4) CWeapon.Type bullet_type; +} + +/*####################################################################################################################### +------------------------------------------------ Events ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct EChangeDirection +{ + mixin ECS.Event; + + this(Direction direction) + { + this.direction = direction; + } + + Direction direction; +} + +struct EUpgrade +{ + mixin ECS.Event; +} + +struct EDeath +{ + mixin ECS.Event; +} + +struct EDamage +{ + mixin ECS.Event; + + this(uint damage) + { + this.damage = damage; + } + + uint damage = 0; +} + +struct EBulletHit +{ + mixin ECS.Event; + + this(EntityID id, uint damage) + { + this.id = id; + this.damage = damage; + } + + EntityID id; + uint damage; +} + +struct EDestroyedChild +{ + mixin ECS.Event; + + this(EntityID id) + { + this.id = id; + } + + EntityID id; +} + +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct ParentOwnerSystem +{ + mixin ECS.System; + + struct EntitiesData + { + CChildren[] children; + } + + void onRemoveEntity(EntitiesData data) + { + //currently EntitiesData always has only one element + foreach(child; data.children[0].childern) + { + gEntityManager.removeEntity(child); + } + if(data.children[0].childern.length)Mallocator.dispose(data.children[0].childern); + } +} + +struct ShipWeaponSystem +{ + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + CInit[] init; + //CShip[] ship; + CChildren[] children; + } + + struct Ship + { + EntityTemplate* laser1_tmpl; + EntityTemplate* laser2_tmpl; + EntityTemplate* main_weapon_tmpl; + + void add(Entity* entity) + { + CChildren* children = entity.getComponent!CChildren; + if(children is null || children.childern.length != 0)return; + EntityID[3] weapons; + laser1_tmpl.getComponent!CTargetParent().parent = entity.id; + laser2_tmpl.getComponent!CTargetParent().parent = entity.id; + main_weapon_tmpl.getComponent!CTargetParent().parent = entity.id; + weapons[0] = gEntityManager.addEntity(laser1_tmpl).id; + weapons[1] = gEntityManager.addEntity(laser2_tmpl).id; + weapons[2] = gEntityManager.addEntity(main_weapon_tmpl).id; + children.childern = Mallocator.makeArray(weapons); + } + + void create() + { + laser1_tmpl = gEntityManager.allocateTemplate([becsID!CWeapon, becsID!CLocation, becsID!CShootDirection, becsID!CTargetParent, becsID!CGuild, becsID!CVelocity].staticArray); + main_weapon_tmpl = gEntityManager.allocateTemplate([becsID!CLocation, becsID!CShootDirection, becsID!CTargetParent, becsID!CGuild, becsID!CVelocity].staticArray); + *laser1_tmpl.getComponent!CWeapon = CWeapon(0,CWeapon.Type.laser,3); + laser1_tmpl.getComponent!CTargetParent().rel_pos = vec2(10,13); + main_weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,4); + laser2_tmpl = gEntityManager.allocateTemplate(laser1_tmpl); + laser2_tmpl.getComponent!CTargetParent().rel_pos = vec2(-10,13); + } + + ~this() + { + gEntityManager.freeTemplate(laser1_tmpl); + gEntityManager.freeTemplate(laser2_tmpl); + gEntityManager.freeTemplate(main_weapon_tmpl); + } + } + + struct Tower + { + EntityTemplate* weapon_tmpl; + EntityTemplate* top_tmpl; + + void add(Entity* entity) + { + CChildren* children = entity.getComponent!CChildren; + if(children is null || children.childern.length != 0)return; + CDepth* depth = entity.getComponent!CDepth; + EntityID[2] weapons; + weapon_tmpl.getComponent!CTargetParent().parent = entity.id; + if(depth)weapon_tmpl.getComponent!CDepth().value = cast(short)(depth.value - 1); + else weapon_tmpl.getComponent!CDepth().value = -1; + top_tmpl.getComponent!CTargetParent().parent = entity.id; + if(depth)top_tmpl.getComponent!CDepth().value = cast(short)(depth.value - 2); + else top_tmpl.getComponent!CDepth().value = -2; + + weapons[0] = gEntityManager.addEntity(weapon_tmpl).id; + weapons[1] = gEntityManager.addEntity(top_tmpl).id; + children.childern = Mallocator.makeArray(weapons); + } + + void create() + { + weapon_tmpl = gEntityManager.allocateTemplate( + [becsID!CWeapon, becsID!CLocation, becsID!CShootDirection, + becsID!CTargetParent, becsID!CGuild, becsID!CVelocity, + becsID!CAutoShoot, becsID!CTarget, becsID!CTargetPlayerShip, + becsID!CRotation, becsID!CScale, becsID!CTexCoords, + becsID!CDepth, becsID!CWeaponLocation].staticArray); + *weapon_tmpl.getComponent!CWeapon = CWeapon(0,CWeapon.Type.laser,3); + weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,0); + weapon_tmpl.getComponent!CGuild().guild = 1; + weapon_tmpl.getComponent!CScale().value = vec2(4,16); + //weapon_tmpl.getComponent!CWeapon().level = 1; + *weapon_tmpl.getComponent!CWeapon() = CWeapon(0,CWeapon.Type.canon,1); + weapon_tmpl.getComponent!CDepth().value = -1; + weapon_tmpl.getComponent!CTexCoords().value = vec4(136,96,4,16)*px; + weapon_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,12); + + top_tmpl = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CTargetParent, becsID!CScale, + becsID!CTexCoords, becsID!CDepth].staticArray); + top_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,1); + top_tmpl.getComponent!CScale().value = vec2(10,11); + top_tmpl.getComponent!CDepth().value = -2; + top_tmpl.getComponent!CTexCoords().value = vec4(112,96,10,11)*px; + + } + + ~this() + { + gEntityManager.freeTemplate(weapon_tmpl); + gEntityManager.freeTemplate(top_tmpl); + } + } + + struct Boss + { + EntityTemplate* tower1_tmpl; + EntityTemplate* tower2_tmpl; + EntityTemplate* tower3_tmpl; + EntityTemplate* tower4_tmpl; + + void add(Entity* entity) + { + CChildren* children = entity.getComponent!CChildren; + if(children is null || children.childern.length != 0)return; + CParts* parts = entity.getComponent!CParts; + if(parts)parts.count = 4; + EntityID[4] towers; + tower1_tmpl.getComponent!CTargetParent().parent = entity.id; + tower2_tmpl.getComponent!CTargetParent().parent = entity.id; + tower3_tmpl.getComponent!CTargetParent().parent = entity.id; + tower4_tmpl.getComponent!CTargetParent().parent = entity.id; + towers[0] = gEntityManager.addEntity(tower1_tmpl).id; + towers[1] = gEntityManager.addEntity(tower2_tmpl).id; + towers[2] = gEntityManager.addEntity(tower3_tmpl).id; + towers[3] = gEntityManager.addEntity(tower4_tmpl).id; + children.childern = Mallocator.makeArray(towers); + } + + void create() + { + tower1_tmpl = gEntityManager.allocateTemplate( + [becsID!CColor, becsID!CHitMark, becsID!CHitPoints, becsID!CLocation, + becsID!CTexCoords, becsID!CScale, becsID!CEnemy, + becsID!CShootGrid, becsID!CGuild, becsID!CInit, + becsID!CChildren, becsID!CDepth, becsID!CTargetParent, + becsID!CSpawnUponDeath, becsID!CShootWaveUponDeath, becsID!CShootGridMask].staticArray + ); + + tower1_tmpl.getComponent!CTexCoords().value = vec4(96*px,96*px,16*px,16*px); + tower1_tmpl.getComponent!CLocation().value = vec2(64,space_invaders.map_size.y - 16); + tower1_tmpl.getComponent!CGuild().guild = 1; + tower1_tmpl.getComponent!CInit().type = CInit.Type.tower; + tower1_tmpl.getComponent!CHitPoints().value = 10; + tower1_tmpl.getComponent!CDepth().value = -2; + tower1_tmpl.getComponent!CShootWaveUponDeath().bullet_type = CWeapon.Type.canon; + tower1_tmpl.getComponent!CTargetParent().rel_pos = vec2(-33,2); + + tower2_tmpl = gEntityManager.allocateTemplate(tower1_tmpl); + tower2_tmpl.getComponent!CTargetParent().rel_pos = vec2(33,2); + + tower3_tmpl = gEntityManager.allocateTemplate(tower1_tmpl); + tower3_tmpl.getComponent!CDepth().value = 0; + tower3_tmpl.getComponent!CTargetParent().rel_pos = vec2(-40,-15); + + tower4_tmpl = gEntityManager.allocateTemplate(tower1_tmpl); + tower4_tmpl.getComponent!CDepth().value = 0; + tower4_tmpl.getComponent!CTargetParent().rel_pos = vec2(40,-15); + } + + ~this() + { + gEntityManager.freeTemplate(tower1_tmpl); + gEntityManager.freeTemplate(tower2_tmpl); + gEntityManager.freeTemplate(tower3_tmpl); + gEntityManager.freeTemplate(tower4_tmpl); + } + } + + Ship ship; + Tower tower; + Boss boss; + + void onCreate() + { + ship.create(); + tower.create(); + boss.create(); + } + + void onDestroy() + { + __xdtor(); + } + + void onAddEntity(EntitiesData data) + { + foreach(i; 0..data.length) + { + final switch(data.init[i].type) + { + case CInit.Type.space_ship:ship.add(&data.entity[i]);break; + case CInit.Type.tower:tower.add(&data.entity[i]);break; + case CInit.Type.boss:boss.add(&data.entity[i]);break; + } + } + } +} + +struct MoveToParentTargetSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + int length; + CLocation[] location; + @optional CVelocity[] velocity; + @readonly CTargetParent[] target; + } + + void onUpdate(EntitiesData data) + { + if(data.velocity) + { + foreach(i;0..data.length) + { + Entity* target = gEntityManager.getEntity(data.target[i].parent); + if(target) + { + CLocation* target_loc = target.getComponent!CLocation; + if(target_loc != null) + { + data.location[i] = *target_loc + data.target[i].rel_pos; + } + CVelocity* target_vel = target.getComponent!CVelocity; + if(target_vel != null) + { + data.velocity[i] = *target_vel; + } + } + } + } + else + foreach(i;0..data.length) + { + Entity* target = gEntityManager.getEntity(data.target[i].parent); + if(target) + { + CLocation* target_loc = target.getComponent!CLocation; + if(target_loc != null) + { + data.location[i] = *target_loc + data.target[i].rel_pos; + } + } + } + } +} +/* +struct DrawSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + //uint thread_id; + uint job_id; + @readonly CTexCoords[] textures; + @readonly CLocation[] locations; + @readonly CScale[] scale; + @readonly @optional CRotation[] rotation; + @readonly @optional CDepth[] depth; + @readonly @optional CHitMark[] hit_mark; + } + + void onUpdate(EntitiesData data) + { + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.color = 0x80808080; + draw_data.thread_id = data.job_id; + draw_data.texture = space_invaders.texture; + //uint color_mask = 0xFCFCFCFC; + uint const_map = 0x80A08080;//0x80808080; + if(!data.depth) + { + if(data.hit_mark) + { + foreach(i; 0..data.length) + { + draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + draw_data.depth = cast(short)(data.locations[i].y); + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color|const_map, 0, 0, 0, data.job_id); + } + } + else if(data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.depth = cast(short)(data.locations[i].y); + draw_data.angle = data.rotation[i]; + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, data.rotation[i], 0, 0, data.job_id); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.depth = cast(short)(data.locations[i].y); + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, 0, 0, 0, data.job_id); + } + } + } + else + { + if(data.hit_mark) + { + if(data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + draw_data.angle = data.rotation[i]; + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color|const_map, data.rotation[i], 0, 0, data.job_id); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color|const_map, 0, 0, 0, data.job_id); + } + } + } + else if(data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.angle = data.rotation[i]; + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, data.rotation[i], 0, 0, data.job_id); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].value; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, 0, 0, 0, data.job_id); + } + } + } + //if(data.thread_id == 0)launcher.renderer.pushData(); + } +}*/ + +struct CollisionSystem +{ + mixin ECS.System; + + struct EntitiesData + { + + } + + void onUpdate(EntitiesData data) + { + + } +} + +struct ShootingSystem +{ + mixin ECS.System!32; + + bool shoot = false; + + __gshared vec4[] fire_frames = [vec4(96,64,8,16)*px,vec4(104,64,8,16)*px,vec4(112,64,8,16)*px,vec4(120,64,8,16)*px,vec4(128,64,8,16)*px, + vec4(136,64,8,16)*px,vec4(144,64,8,16)*px,vec4(152,64,8,16)*px,vec4(160,64,8,16)*px]; + + // __gshared vec4[] fire_frames = [vec4(0,160,8,16)*px,vec4(16,160,16,16)*px,vec4(32,160,16,16)*px,vec4(48,160,16,16)*px,vec4(64,160,16,16)*px, + // vec4(80,160,16,16)*px,vec4(96,160,16,16)*px,vec4(112,160,16,16)*px]; + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + CWeapon[] laser; + @readonly CLocation[] location; + @readonly CGuild[] guild; + + @optional @readonly CShootDirection[] shoot_direction; + @optional @readonly CWeaponLocation[] weapon_location; + @optional @readonly CAutoShoot[] auto_shoot; + @optional @readonly CVelocity[] velocity; + @optional @readonly CRotation[] rotation; + } + + EntityTemplate* fire_tmpl; + + ///Called inside "registerSystem" function + void onCreate() + { + fire_tmpl = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CTexCoords, becsID!CScale, + becsID!CAnimation, becsID!CParticle, becsID!CRotation, + becsID!CVelocity, becsID!CDamping].staticArray + ); + + fire_tmpl.getComponent!CTexCoords().value = vec4(96,64,8,16)*px; + fire_tmpl.getComponent!CScale().value = vec2(8,16); + fire_tmpl.getComponent!(CParticle).life = 300; + *fire_tmpl.getComponent!(CAnimation) = CAnimation(fire_frames, 0, 3); + } + + void onDestroy() + { + gEntityManager.freeTemplate(fire_tmpl); + } + + bool onBegin() + { + if(launcher.getKeyState(SDL_SCANCODE_SPACE)) + { + shoot = true; + } + else shoot = false; + return true; + } + + void onUpdate(EntitiesData data) + { + //conditional branch for whole entities block + if(shoot || data.auto_shoot) + { + foreach(i;0..data.length) + { + CWeapon* laser = &data.laser[i]; + laser.shoot_time += launcher.deltaTime; + while(laser.shoot_time > CWeapon.levels[laser.level - 1].reload_time) + { + CVelocity laser_velocity; + CGuild laser_guild; + CLocation laser_location; + CVelocity fire_velocity; + CLocation fire_location; + CRotation fire_rotation; + + laser.shoot_time -= CWeapon.levels[laser.level - 1].reload_time; + laser_location.value = data.location[i]; + + laser_velocity.value = vec2((randomf()*2-1) * CWeapon.levels[laser.level - 1].dispersion,0.5);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down)laser_velocity.y = -0.5; + + laser_guild.guild = data.guild[i].guild; + + if(laser.level < 3)laser_velocity.value = laser_velocity.value * 0.4f; + + if(data.velocity) + { + fire_velocity.value = data.velocity[i]; + //laser_velocity.value += data.velocity[i] * 0.5; + } + else fire_velocity.value = vec2(0,0); + + fire_location.value = data.location[i]; + if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down) + { + fire_rotation.value = PI; + //fire_location.value.y -= 16; + } + else + { + fire_rotation.value = 0; + //fire_location.value.y += 24; + } + + if(data.rotation) + { + float sinn = sinf(data.rotation[i]); + float coss = cosf(data.rotation[i]); + float x = laser_velocity.y*sinn + laser_velocity.x*coss; + float y = laser_velocity.y*coss + laser_velocity.x*sinn; + laser_velocity.value = vec2(x,y); + fire_rotation.value = data.rotation[i]; + if(data.weapon_location) + { + vec2 rel_pos = vec2(data.weapon_location[i].rel_pos.y*sinn+data.weapon_location[i].rel_pos.x*coss, data.weapon_location[i].rel_pos.y*coss+data.weapon_location[i].rel_pos.x*sinn); + laser_location.value += rel_pos; + fire_location.value += rel_pos; + } + } + else if(data.weapon_location) + { + laser_location.value += data.weapon_location[i].rel_pos; + fire_location.value += data.weapon_location[i].rel_pos; + } + + gEntityManager.addEntity(space_invaders.bullet_tmpl[data.laser[i].type],[laser_velocity.ref_, laser_guild.ref_, laser_location.ref_].staticArray); + gEntityManager.addEntity(fire_tmpl,[fire_location.ref_, fire_rotation.ref_, fire_velocity.ref_].staticArray); + } + } + } + else + { + foreach(i;0..data.length) + { + CWeapon* laser = &data.laser[i]; + laser.shoot_time += launcher.delta_time; + if(laser.shoot_time > CWeapon.levels[laser.level - 1].reload_time)laser.shoot_time = CWeapon.levels[laser.level - 1].reload_time; + } + } + + } +} + +struct BulletsCollisionSystem +{ + mixin ECS.System!32; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + @readonly CLocation[] location; + @readonly CBullet[] bullet; + @readonly CGuild[] guild; + } + + void onUpdate(EntitiesData data) + { + EntityID id; + foreach(i; 0..data.length) + { + if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(~(1 << data.guild[i].guild)))) + { + gEntityManager.sendEvent(id, EBulletHit(data.entity[i].id,data.bullet[i].damage)); + //gEntityManager.removeEntity(data.entity[i].id); + } + } + } +} + +struct CollisionMaskSystem +{ + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + CShootGridMask[] mask; + @readonly CGuild[] guild; + } + + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + data.mask[i] = cast(ubyte)(1 << data.guild[i].guild); + } + } +} + +struct ParticleEmittingSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + //uint thread_id; + CParticleEmitterTime[] emit_time; + @readonly CLocation[] location; + @readonly CParticleEmitter[] emitter; + + @optional @readonly CVelocity[] velocity; + @optional @readonly CDepth[] depth; + } + + __gshared vec4[] flashes = [vec4(224,0,16,16)*px,vec4(240,0,16,16)*px,vec4(256,0,16,16)*px,vec4(272,0,16,16)*px,vec4(288,0,16,16)*px, + vec4(304,0,16,16)*px,vec4(320,0,16,16)*px]; + + EntityTemplate*[1] templates; + + void onCreate() + { + templates[0] = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CTexCoords, becsID!CScale, + becsID!CAnimation, becsID!CParticle, becsID!CRotation, + becsID!CVelocity, becsID!CDamping, becsID!CDepth].staticArray); + *templates[0].getComponent!CAnimation() = CAnimation(flashes,0,2); + *templates[0].getComponent!CParticle() = CParticle(350); + //*templates[0].getComponent!CDepth() = CDepth(-3); + } + + void onDestroy() + { + foreach(tmpl; templates) + { + gEntityManager.freeTemplate(tmpl); + } + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.emit_time[i].time -= launcher.delta_time; + while(data.emit_time[i].time < 0) + { + CVelocity velocity; + CDepth depth; + + CParticleEmitter* emitter = &data.emitter[i]; + data.emit_time[i].time += emitter.time_range.x + randomf() * emitter.time_range.y; + + if(data.velocity) + { + velocity.value = data.velocity[i]; + } + + if(data.depth) + { + depth.value = data.depth[i]; + } + + gEntityManager.addEntity(templates[0],[data.location[i].ref_,velocity.ref_,depth.ref_].staticArray); + } + } + } +} + +struct UpgradeCollisionSystem +{ + mixin ECS.System!32; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + @readonly CLocation[] location; + @readonly CUpgrade[] upgrade; + } + + void onUpdate(EntitiesData data) + { + EntityID id; + foreach(i; 0..data.length) + { + if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(0xFF))) + { + Entity* entity = gEntityManager.getEntity(id); + if(entity && entity.hasComponent(becsID!CShip)) + { + gEntityManager.sendEvent(id, EUpgrade()); + gEntityManager.removeEntity(data.entity[i].id); + } + } + } + } +} + +struct UpgradeSystem +{ + mixin ECS.System; + + struct EntitiesData + { + const (Entity)[] entity; + //@readonly CShip[] ship; + } + + void handleEvent(Entity* entity, EUpgrade event) + { + CWeapon* laser = entity.getComponent!CWeapon; + if(laser) + { + if(laser.level < CWeapon.levels.length)laser.level++; + } + CShip* ship = entity.getComponent!CShip; + if(ship) + { + CChildren* children = entity.getComponent!CChildren; + if(children) + { + foreach(child;children.childern) + { + gEntityManager.sendEvent(child,EUpgrade()); + } + } + } + } +} + +struct ChangeDirectionSystem +{ + mixin ECS.System!32; + + Direction[8] groups_directions; + bool has_changes; + + struct EntitiesData + { + uint length; + const (Entity)[] entities; + const (CLocation)[] locations; + CVelocity[] velocity; + + const(CSideMove)[] side_move; + @optional const(CScale)[] scale; + } + + void onCreate() + { + foreach(ref direction; groups_directions) + { + direction = cast(Direction)-1; + } + } + + void onEnd() + { + if(has_changes) + { + foreach(ref direction; groups_directions) + { + direction = cast(Direction)-1; + } + } + has_changes = false; + foreach(ref direction; groups_directions) + { + if(direction != cast(Direction)-1) + { + has_changes = true; + } + } + } + + void onUpdate(EntitiesData data) + { + //if(!data.side_move)return; + if(has_changes) + foreach(i;0..data.length) + { + byte group = data.side_move[i].group; + if(group == -1) + { + if(data.locations[i].x < 0) + { + if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x; + } + else if(data.locations[i].x > space_invaders.map_size.x) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + } + } + else + { + Direction direction = groups_directions[group]; + if(direction != cast(Direction)-1) + { + CVelocity* velocity = &data.velocity[i]; + final switch(direction) + { + case Direction.up: + if(velocity.value.y > 0)velocity.value.y = -velocity.value.y; + break; + case Direction.down: + if(velocity.value.y < 0)velocity.value.y = -velocity.value.y; + break; + case Direction.left: + if(velocity.value.x > 0)velocity.value.x = -velocity.value.x; + break; + case Direction.right: + if(velocity.value.x < 0)velocity.value.x = -velocity.value.x; + break; + } + } + } + } + else if(data.scale) + { + foreach(i;0..data.length) + { + if(data.locations[i].x - data.scale[i].x * 0.5 < 0) + { + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + groups_directions[data.side_move[i].group] = Direction.right; + } + } + else if(data.locations[i].x + data.scale[i].x * 0.5 > space_invaders.map_size.x) + { + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + groups_directions[data.side_move[i].group] = Direction.left; + } + } + } + } + else + { + foreach(i;0..data.length) + { + if(data.locations[i].x < 0) + { + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + groups_directions[data.side_move[i].group] = Direction.right; + } + } + else if(data.locations[i].x > space_invaders.map_size.x) + { + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + groups_directions[data.side_move[i].group] = Direction.left; + } + } + } + } + } +} + +struct HitMarkingSystem +{ + mixin ECS.System!16; + + struct EntitiesData + { + uint length; + CHitMark[] mark; + CColor[] color; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + //if(data.mark[i] < 10)data.mark[i] = 0; + //else data.mark[i] -= 1; + data.mark[i] = cast(ubyte)(data.mark[i] * 0.9); + data.color[i] = 0x80808080 + 0x01010101 * data.mark[i]; + } + } +} + +struct HitPointsSystem +{ + mixin ECS.System; + + __gshared vec4[] upgrade_laser_frames = [vec4(96,80,16,16)*px,vec4(112,80,16,16)*px,vec4(128,80,16,16)*px,vec4(144,80,16,16)*px,vec4(128,80,16,16)*px,vec4(112,80,16,16)*px]; + __gshared vec4[] explosion_laser_frames = [vec4(80,128,16,16)*px,vec4(96,128,16,16)*px,vec4(112,128,16,16)*px,vec4(128,128,16,16)*px,vec4(144,128,16,16)*px,vec4(160,128,16,16)*px,vec4(176,128,16,16)*px,vec4(192,128,16,16)*px,vec4(208,128,16,16)*px]; + + EntityTemplate* upgrade_tmpl; + EntityTemplate* explosion_tmpl; + + struct EntitiesData + { + CHitPoints[] hp; + } + + void onCreate() + { + upgrade_tmpl = gEntityManager.allocateTemplate( + [becsID!CVelocity, becsID!CLocation, becsID!CTexCoords, + becsID!CScale, becsID!CUpgrade, becsID!CAnimation, + becsID!CAnimationLooped].staticArray); + //tex_comp.tex = space_invaders.texture;//ship_tex; + upgrade_tmpl.getComponent!CTexCoords().value = vec4(0*px,32*px,16*px,16*px); + *upgrade_tmpl.getComponent!CAnimation = CAnimation(upgrade_laser_frames, 0, 1); + upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.05); + + explosion_tmpl = gEntityManager.allocateTemplate( + [becsID!CDepth, becsID!CParticle, becsID!CLocation, + becsID!CTexCoords, becsID!CScale, becsID!CAnimation].staticArray); + //explosion_tmpl.getComponent!(CTexCoords).tex = space_invaders.texture; + *explosion_tmpl.getComponent!CAnimation = CAnimation(explosion_laser_frames, 0, 1.333); + explosion_tmpl.getComponent!(CParticle).life = 600; + *explosion_tmpl.getComponent!CDepth = -1; + } + + void onDestroy() + { + gEntityManager.freeTemplate(upgrade_tmpl); + gEntityManager.freeTemplate(explosion_tmpl); + } + + /*void handleEvent(Entity* entity, EDamage event) + { + CHitPoints* hp = entity.getComponent!CHitPoints; + if(*hp <= 0)return; + *hp -= event.damage; + if(*hp <= 0) + { + gEntityManager.sendEvent(entity.id, EDeath()); + //gEntityManager.removeEntity(entity.id); + } + CHitMark* hit_mark = entity.getComponent!CHitMark; + if(hit_mark)hit_mark.value = 127; + }*/ + + void handleEvent(Entity* entity, EBulletHit event) + { + CHitPoints* hp = entity.getComponent!CHitPoints; + if(*hp <= 0)return; + gEntityManager.removeEntity(event.id); + *hp -= event.damage; + if(*hp <= 0) + { + gEntityManager.sendEvent(entity.id, EDeath()); + //gEntityManager.removeEntity(entity.id); + } + CHitMark* hit_mark = entity.getComponent!CHitMark; + if(hit_mark)hit_mark.value = 127; + } + + void handleEvent(Entity* entity, EDeath event) + { + CEnemy* enemy = entity.getComponent!CEnemy; + if(enemy) + { + CLocation* location = entity.getComponent!CLocation; + if(location) + { + if(randomRange(0, 1000) < 5) + { + gEntityManager.addEntity(upgrade_tmpl,[location.ref_].staticArray); + } + gEntityManager.addEntity(explosion_tmpl,[location.ref_].staticArray); + } + } + gEntityManager.removeEntity(entity.id); + } +} + +struct ChildDestroySystem +{ + mixin ECS.System; + + struct EntitiesData + { + CTargetParent[] parent; + } + + void handleEvent(Entity* entity, EDeath event) + { + CTargetParent* parent = entity.getComponent!CTargetParent; + if(parent) + { + gEntityManager.sendEvent(parent.parent, EDestroyedChild(entity.id)); + } + } +} + +struct ShootWaveSystem +{ + mixin ECS.System; + + struct EntitiesData + { + CLocation[] location; + CShootWaveUponDeath[] shoot_wave; + } + + vec2[] dirs; + + void onCreate() + { + enum count = 24; + dirs = Mallocator.makeArray!vec2(count); + float step = 2 * PI / cast(float)count; + foreach(i;0..count) + { + float angle = step * i; + dirs[i] = vec2(sinf(angle),cosf(angle)) * 0.2; + } + } + + void onDestroy() + { + Mallocator.dispose(dirs); + } + + void handleEvent(Entity* entity, EDeath event) + { + + CShootWaveUponDeath* wave = entity.getComponent!CShootWaveUponDeath; + CLocation* location = entity.getComponent!CLocation; + CGuild* guild = entity.getComponent!CGuild; + + //ShootingSystem.bullet_tmpl + EntityTemplate* tmpl = space_invaders.bullet_tmpl[wave.bullet_type]; + foreach(dir;dirs) + { + if(guild)gEntityManager.addEntity(tmpl,[location.ref_,guild.ref_,CVelocity(dir).ref_].staticArray); + else gEntityManager.addEntity(tmpl,[location.ref_,CVelocity(dir).ref_].staticArray); + } + //gEntityManager.addEntity(tmpl);//,[location.ref_].staticArray); + + //gEntityManager.addEntity(space_invaders.bullet_tmpl[0]); + } +} + +struct PartsDestroySystem +{ + mixin ECS.System; + + struct EntitiesData + { + CInit[] init; + CChildren[] children; + CParts[] parts; + } + + EntityTemplate* flashes_emitter; + + void onCreate() + { + flashes_emitter = gEntityManager.allocateTemplate( + [ + becsID!CVelocity, becsID!CLocation, becsID!CParticleEmitter, + becsID!CParticleEmitterTime, becsID!CTargetParent, becsID!CDepth + ].staticArray); + *flashes_emitter.getComponent!CParticleEmitter() = CParticleEmitter(vec2(0,0), vec2(800,1600)); + } + + void onDestroy() + { + gEntityManager.freeTemplate(flashes_emitter); + } + + void handleEvent(Entity* entity, EDestroyedChild event) + { + CParts* parts = entity.getComponent!CParts; + parts.count--; + + CInit* init = entity.getComponent!CInit; + if(init.type == CInit.Type.boss) + { + CChildren* children = entity.getComponent!CChildren; + foreach(ref EntityID child; children.childern) + { + if(child == event.id) + { + Entity* child_entity = gEntityManager.getEntity(child); + if(child_entity) + { + CLocation location; + CTargetParent* target_parent = child_entity.getComponent!CTargetParent; + CDepth* target_depth = child_entity.getComponent!CDepth; + CLocation* target_location = child_entity.getComponent!CLocation; + //CVelocity* velocity = child_entity.getComponent!CTargetParent; + + if(target_location)location = *target_location; + + *flashes_emitter.getComponent!CTargetParent() = *target_parent; + if(target_depth)child = gEntityManager.addEntity(flashes_emitter, [target_depth.ref_, location.ref_].staticArray).id; + else child = gEntityManager.addEntity(flashes_emitter, [location.ref_].staticArray).id; + } + break; + } + } + } + + if(parts.count == 0) + { + if(init.type == CInit.Type.boss) + { + gEntityManager.addComponents(entity.id, CHitPoints(100), CShootGrid()); + } + } + } +} + +struct ClampPositionSystem +{ + mixin ECS.System!32; + mixin ECS.ExcludedComponents!(CSideMove); + + struct EntitiesData + { + uint length; + const (Entity)[] entities; + //components are treated as required by default + CLocation[] locations; + + @optional @readonly CColliderScale[] collider_scale; + @optional @readonly CScale[] scale; + @optional const (CBullet)[] laser; + @optional const (CUpgrade)[] upgrade; + //@optional CVelocity[] velocity; + //@optional const (CSideMove)[] side_move; + } + + //ChangeDirectionSystem change_direction_system; + + void onUpdate(EntitiesData data) + { + if(data.laser || data.upgrade) + { + foreach(i;0..data.length) + { + if(data.locations[i].x < 0 || data.locations[i].x > space_invaders.map_size.x || + data.locations[i].y < 0 || data.locations[i].y > space_invaders.map_size.y)gEntityManager.removeEntity(data.entities[i].id); + } + } + /*else if(data.side_move) + { + foreach(i;0..data.length) + { + if(data.locations[i].x < 0) + { + //data.locations[i].x = 0; + //gEntityManager.sendEvent(data.entities[i].id,EChangeDirection(Direction.right)); + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + change_direction_system.groups_directions[data.side_move[i].group] = Direction.left; + } + } + else if(data.locations[i].x > space_invaders.map_size.x) + { + //data.locations[i].x = space_invaders.map_size.x; + //gEntityManager.sendEvent(data.entities[i].id,EChangeDirection(Direction.left)); + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + change_direction_system.groups_directions[data.side_move[i].group] = Direction.right; + } + } + if(data.locations[i].y < 0) data.locations[i].y = 0; + else if(data.locations[i].y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y; + } + }*/ + else if(data.collider_scale) + { + foreach(i;0..data.length) + { + vec2 hscale = data.collider_scale[i] * 0.5; + if(data.locations[i].x - hscale.x < 0)data.locations[i].x = hscale.x; + else if(data.locations[i].x + hscale.x > space_invaders.map_size.x)data.locations[i].x = space_invaders.map_size.x - hscale.x; + if(data.locations[i].y - hscale.y < 0)data.locations[i].y = hscale.y; + else if(data.locations[i].y + hscale.y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y - hscale.y; + } + } + else if(data.scale) + { + foreach(i;0..data.length) + { + vec2 hscale = data.scale[i] * 0.5; + if(data.locations[i].x - hscale.x < 0)data.locations[i].x = hscale.x; + else if(data.locations[i].x + hscale.x > space_invaders.map_size.x)data.locations[i].x = space_invaders.map_size.x - hscale.x; + if(data.locations[i].y - hscale.y < 0)data.locations[i].y = hscale.y; + else if(data.locations[i].y + hscale.y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y - hscale.y; + } + } + else + { + foreach(i;0..data.length) + { + if(data.locations[i].x < 0)data.locations[i].x = 0; + else if(data.locations[i].x > space_invaders.map_size.x)data.locations[i].x = space_invaders.map_size.x; + if(data.locations[i].y < 0)data.locations[i].y = 0; + else if(data.locations[i].y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y; + } + } + } +} + +// struct MovementSystem +// { +// mixin ECS.System!32; + +// struct EntitiesData +// { +// uint length; +// //read only components can be marked with @readonly attribute or with const expression instead +// const (CVelocity)[] velocity; +// //components are treated as required by default +// CLocation[] locations; +// //@optional const (CBullet)[] laser; +// const (Entity)[] entities; + +// //@optional CSideMove[] side_move; +// } + +// void onUpdate(EntitiesData data) +// { +// foreach(i;0..data.length) +// { +// data.locations[i].x += data.velocity[i].x * launcher.delta_time * 0.5; +// data.locations[i].y += data.velocity[i].y * launcher.delta_time * 0.5; +// } +// } +// } + +struct AnimationSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + CAnimation[] animation; + //CTexture[] texture; + CTexCoords[] texcoords; + @optional @readonly CAnimationLooped[] looped; + } + + void onUpdate(EntitiesData data) + { + float dt = launcher.deltaTime * 0.01; + if(data.looped) + { + foreach(i;0..data.length) + { + data.animation[i].time += dt * data.animation[i].speed; + while(cast(uint)data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; + //if(cast(uint)(data.animation[i].time) >= data.animation[i].frames.length)assert(0); + assert(cast(uint)(data.animation[i].time) < data.animation[i].frames.length); + uint index = cast(uint)(data.animation[i].time); + if(index < data.animation[i].frames.length)data.texcoords[i].value = data.animation[i].frames[index]; + } + } + else + { + foreach(i;0..data.length) + { + data.animation[i].time += dt * data.animation[i].speed; + if(cast(uint)data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time = data.animation[i].frames.length - 0.9; + uint index = cast(uint)(data.animation[i].time); + if(index < data.animation[i].frames.length)data.texcoords[i].value = data.animation[i].frames[index]; + } + } + + } +} + +struct ParticleSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + @readonly Entity[] entitiy; + CParticle[] particle; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.particle[i].life -= launcher.deltaTime; + if(data.particle[i].life < 0)gEntityManager.removeEntity(data.entitiy[i].id); + } + } +} + +struct RotateToTargetSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + int length; + @readonly CTarget[] target; + @readonly CLocation[] location; + CRotation[] rotation; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + Entity* target = gEntityManager.getEntity(data.target[i].target); + if(target) + { + CLocation* target_loc = target.getComponent!CLocation; + if(target_loc) + { + vec2 rel_pos = target_loc.value - data.location[i]; + float length = sqrtf(rel_pos.x*rel_pos.x + rel_pos.y*rel_pos.y); + if(rel_pos.x > 0)data.rotation[i] = acosf(rel_pos.y/length); + else data.rotation[i] = 2 * PI - acosf(rel_pos.y/length); + + } + } + //CLocation* target_loc = + //vec2 rel_pos = d + //data.rotation = 0; + } + } +} + +struct ShipTargetSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + int length; + @readonly CTargetPlayerShip[] target_player; + CTarget[] target; + } + + EntityID player_ship; + + void iterateShips(CShipIterator.EntitiesData data) + { + player_ship = data.entity[0].id; + } + + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + data.target[i].target = player_ship; + } + } + + bool onBegin() + { + Entity* ship = gEntityManager.getEntity(player_ship); + if(ship is null) + { + gEntityManager.callEntitiesFunction!CShipIterator(&iterateShips); + ship = gEntityManager.getEntity(player_ship); + if(ship is null)return false; + return true; + } + return false; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.target[i].target = player_ship; + } + } +} + +struct CShipIterator +{ + mixin ECS.System!1; + + struct EntitiesData + { + @readonly Entity[] entity; + @readonly CShip[] ship; + } + + bool onBegin() + { + return false; + } + + void onUpdate(EntitiesData data) + { + + } +} + +/*struct SpawnUponDeathSystem +{ + mixin ECS.System; + + struct EntitiesData + { + @readonly CSpawnUponDeath[] spawn; + @optional CTargetParent[] parent; + } + + EntityTemplate* flashes_emitter; + + void onCreate() + { + flashes_emitter = gEntityManager.allocateTemplate( + [ + becsID!CVelocity, becsID!CLocation, becsID!CParticleEmitter, + becsID!CParticleEmitterTime, becsID!CTargetParent + ].staticArray); + *flashes_emitter.getComponent!CParticleEmitter() = CParticleEmitter(vec2(0,0), vec2(400,400), 0); + } + + void onDestroy() + { + gEntityManager.freeTemplate(flashes_emitter); + } + + void onRemoveEntity(EntitiesData data) + { + //CSpawnUponDeath[] spawn = + switch(data.spawn[0].type) + { + case CSpawnUponDeath.Type.flashes_emitter: + if(data.parent) + { + /*Entity* parent_entity = gEntityManager.getEntity(data.parent[0].parent); + CChildren* children = entity.getComponent!CChildren; + foreach(ref EntityID child; children.childern) + { + if(child == event.id) + { + Entity* child_entity = gEntityManager.getEntity(child); + if(child_entity) + { + *flashes_emitter.getComponent!CTargetParent = data.parent[0]; + gEntityManager.addEntity(flashes_emitter); + //child = gEntityManager.addEntity(flashes_emitter); + } + break; + } + } + } + break; + default:break; + } + } + + //void handleEvent(Entity* entity, ) +}//*/ + +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +__gshared SpaceInvaders* space_invaders; + +void spaceInvadersRegister() +{ + + space_invaders = Mallocator.make!SpaceInvaders; + + space_invaders.texture.create(); + space_invaders.texture.load("assets/textures/atlas.png"); + + gEntityManager.beginRegister(); + + gEntityManager.registerDependency(ShootGridDependency); + + registerRenderingModule(gEntityManager); + + gEntityManager.registerComponent!CLocation; + gEntityManager.registerComponent!CTexCoords; + //gEntityManager.registerComponent!CTexture; + gEntityManager.registerComponent!CInput; + gEntityManager.registerComponent!CShip; + gEntityManager.registerComponent!CEnemy; + gEntityManager.registerComponent!CScale; + gEntityManager.registerComponent!CShootDirection; + gEntityManager.registerComponent!CAutoShoot; + gEntityManager.registerComponent!CWeapon; + gEntityManager.registerComponent!CVelocity; + gEntityManager.registerComponent!CBullet; + gEntityManager.registerComponent!CSideMove; + gEntityManager.registerComponent!CDepth; + gEntityManager.registerComponent!CShootGrid; + gEntityManager.registerComponent!CGuild; + gEntityManager.registerComponent!CHitPoints; + gEntityManager.registerComponent!CHitMark; + gEntityManager.registerComponent!CUpgrade; + gEntityManager.registerComponent!CParticle; + gEntityManager.registerComponent!CMaxHitPoints; + gEntityManager.registerComponent!CAnimation; + gEntityManager.registerComponent!CRotation; + gEntityManager.registerComponent!CAnimationLooped; + gEntityManager.registerComponent!CDamping; + gEntityManager.registerComponent!CTargetParent; + gEntityManager.registerComponent!CTarget; + gEntityManager.registerComponent!CTargetPlayerShip; + gEntityManager.registerComponent!CChildren; + gEntityManager.registerComponent!CWeaponLocation; + gEntityManager.registerComponent!CVelocityFactor; + gEntityManager.registerComponent!CInit; + gEntityManager.registerComponent!CBoss; + gEntityManager.registerComponent!CParts; + gEntityManager.registerComponent!CColliderScale; + gEntityManager.registerComponent!CParticleEmitter; + gEntityManager.registerComponent!CParticleEmitterTime; + gEntityManager.registerComponent!CSpawnUponDeath; + gEntityManager.registerComponent!CShootWaveUponDeath; + gEntityManager.registerComponent!CShootGridMask; + + gEntityManager.registerEvent!EChangeDirection; + gEntityManager.registerEvent!EDamage; + gEntityManager.registerEvent!EUpgrade; + gEntityManager.registerEvent!EDeath; + gEntityManager.registerEvent!EDestroyedChild; + gEntityManager.registerEvent!EBulletHit; + + //gEntityManager.registerSystem!MoveSystem(0); + gEntityManager.registerSystem!DrawSystem(100); + gEntityManager.registerSystem!InputMovementSystem(-100); + //gEntityManager.registerSystem!MovementSystem(-99); + gEntityManager.registerSystem!MoveSystem(-99); + gEntityManager.registerSystem!ClampPositionSystem(-90); + gEntityManager.registerSystem!ShootingSystem(0); + gEntityManager.registerSystem!ChangeDirectionSystem(0); + gEntityManager.registerSystem!BulletsCollisionSystem(-70); + gEntityManager.registerSystem!ShootGridManager(-80); + gEntityManager.registerSystem!ShootGridCleaner(-101); + gEntityManager.registerSystem!HitPointsSystem(0); + gEntityManager.registerSystem!HitMarkingSystem(-100); + gEntityManager.registerSystem!UpgradeCollisionSystem(-70); + gEntityManager.registerSystem!UpgradeSystem(-100); + gEntityManager.registerSystem!ParticleSystem(-100); + gEntityManager.registerSystem!AnimationSystem(-100); + gEntityManager.registerSystem!DampingSystem(-101); + gEntityManager.registerSystem!MoveToParentTargetSystem(-98); + gEntityManager.registerSystem!ParentOwnerSystem(-101); + gEntityManager.registerSystem!ShipWeaponSystem(-100); + gEntityManager.registerSystem!ParticleEmittingSystem(-95); + gEntityManager.registerSystem!RotateToTargetSystem(-100); + gEntityManager.registerSystem!ShipTargetSystem(-110); + gEntityManager.registerSystem!CShipIterator(-100); + gEntityManager.registerSystem!PartsDestroySystem(-80); + gEntityManager.registerSystem!ChildDestroySystem(-110); + gEntityManager.registerSystem!ShootWaveSystem(-100); + //gEntityManager.registerSystem!SpawnUponDeathSystem(-110); + gEntityManager.registerSystem!CollisionMaskSystem(-100); + + gEntityManager.endRegister(); +} + +void spaceInvadersStart() +{ + + // space_invaders.shoot_grid = Mallocator.make!ShootGrid; + // space_invaders.shoot_grid.create(ivec2(80,60), vec2(5,5)); + + space_invaders.shoot_grid = gEntityManager.getSystem!ShootGridManager().grid; + + DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; + draw_system.default_data.color = 0x80808080; + draw_system.default_data.texture = space_invaders.texture; + + launcher.gui_manager.addComponent(CLocation(),"Location"); + launcher.gui_manager.addComponent(CRotation(),"Rotation"); + launcher.gui_manager.addComponent(CTexCoords(),"TexCoords"); + launcher.gui_manager.addComponent(CInput(),"Input"); + launcher.gui_manager.addComponent(CShip(),"Ship"); + launcher.gui_manager.addComponent(CEnemy(),"Enemy"); + launcher.gui_manager.addComponent(CShootDirection(),"Shoot Direction"); + launcher.gui_manager.addComponent(CAutoShoot(),"Auto Shoot"); + launcher.gui_manager.addComponent(CWeapon(0, CWeapon.Type.laser),"Weapon (laser)"); + launcher.gui_manager.addComponent(CVelocity(vec2(0,0)),"Velocity (0,0)"); + launcher.gui_manager.addComponent(CBullet(),"Bullet (dmg1)"); + launcher.gui_manager.addComponent(CSideMove(),"Side Move"); + launcher.gui_manager.addComponent(CSideMove(0),"Side Move (g1)"); + launcher.gui_manager.addComponent(CSideMove(1),"Side Move (g2)"); + launcher.gui_manager.addComponent(CDepth(),"Depth"); + launcher.gui_manager.addComponent(CShootGrid(),"Shoot Grid"); + launcher.gui_manager.addComponent(CGuild(),"Guild (Player)"); + launcher.gui_manager.addComponent(CGuild(1),"Guild (Enemy)"); + launcher.gui_manager.addComponent(CHitPoints(10),"Hit Points (10)"); + launcher.gui_manager.addComponent(CHitMark(),"Hit Mark"); + launcher.gui_manager.addComponent(CUpgrade(CUpgrade.Upgrade.laser),"Upgrade (laser)"); + launcher.gui_manager.addComponent(CParticle(1000),"Particle (1s)"); + launcher.gui_manager.addComponent(CMaxHitPoints(),"Max Hit Points"); + launcher.gui_manager.addComponent(CAnimation(),"Animation"); + launcher.gui_manager.addComponent(CDamping(0),"Damping (0)"); + launcher.gui_manager.addComponent(CDamping(4),"Damping (4)"); + launcher.gui_manager.addComponent(CDamping(8),"Damping (8)"); + launcher.gui_manager.addComponent(CAnimationLooped(),"Animation loop flag"); + launcher.gui_manager.addComponent(CTargetParent(),"Target Parent"); + launcher.gui_manager.addComponent(CTargetPlayerShip(),"Target Player Ship"); + launcher.gui_manager.addComponent(CTarget(),"Target"); + launcher.gui_manager.addComponent(CChildren(),"Children"); + launcher.gui_manager.addComponent(CVelocityFactor(),"Velocity Factor"); + launcher.gui_manager.addComponent(CWeaponLocation(vec2(0,16)),"Weapon Location (0,16)"); + launcher.gui_manager.addComponent(CInit(CInit.Type.space_ship),"Init (Ship)"); + launcher.gui_manager.addComponent(CInit(CInit.Type.boss),"Init (Boss)"); + launcher.gui_manager.addComponent(CInit(CInit.Type.tower),"Init (Tower)"); + launcher.gui_manager.addComponent(CBoss(),"Boss"); + launcher.gui_manager.addComponent(CParts(),"Parts"); + launcher.gui_manager.addComponent(CColliderScale(),"Collider Scale"); + launcher.gui_manager.addComponent(CParticleEmitter(),"Particle Emitter"); + launcher.gui_manager.addComponent(CParticleEmitterTime(),"Particle Emitter Time"); + launcher.gui_manager.addComponent(CSpawnUponDeath(),"Spawn Upon Death"); + launcher.gui_manager.addComponent(CShootWaveUponDeath(CWeapon.Type.canon),"Wave Upon Death"); + launcher.gui_manager.addComponent(CShootGridMask(),"Shoot grid mask"); + + launcher.gui_manager.addSystem(becsID!DrawSystem,"Draw System"); + launcher.gui_manager.addSystem(becsID!InputMovementSystem,"Input Movement"); + launcher.gui_manager.addSystem(becsID!ShootingSystem,"Shooting System"); + //launcher.gui_manager.addSystem(becsID!MovementSystem,"Movement System"); + launcher.gui_manager.addSystem(becsID!MoveSystem,"Move System"); + launcher.gui_manager.addSystem(becsID!ClampPositionSystem,"Clamp Position System"); + launcher.gui_manager.addSystem(becsID!ChangeDirectionSystem,"Change Direction System"); + launcher.gui_manager.addSystem(becsID!BulletsCollisionSystem,"Bullets Collision System"); + launcher.gui_manager.addSystem(becsID!ShootGridManager,"Shoot Grid Manager"); + launcher.gui_manager.addSystem(becsID!ShootGridCleaner,"Shoot Grid Cleaner"); + launcher.gui_manager.addSystem(becsID!HitPointsSystem,"Hit Points System"); + launcher.gui_manager.addSystem(becsID!HitMarkingSystem,"Hit Marking System"); + launcher.gui_manager.addSystem(becsID!UpgradeCollisionSystem,"Upgrade Collision System"); + launcher.gui_manager.addSystem(becsID!UpgradeSystem,"Upgrade System"); + launcher.gui_manager.addSystem(becsID!ParticleSystem,"Particle System"); + launcher.gui_manager.addSystem(becsID!AnimationSystem,"Animation System"); + launcher.gui_manager.addSystem(becsID!DampingSystem,"Damping System"); + launcher.gui_manager.addSystem(becsID!MoveToParentTargetSystem,"Move To Target System"); + launcher.gui_manager.addSystem(becsID!ParentOwnerSystem,"Parent Owner System"); + launcher.gui_manager.addSystem(becsID!ShipWeaponSystem,"Ship Weapon System"); + launcher.gui_manager.addSystem(becsID!ParticleEmittingSystem,"Particle Emitting System"); + launcher.gui_manager.addSystem(becsID!RotateToTargetSystem,"Rotate To Target System"); + launcher.gui_manager.addSystem(becsID!ShipTargetSystem,"Ship Target System"); + launcher.gui_manager.addSystem(becsID!PartsDestroySystem,"Parts Destroy System"); + launcher.gui_manager.addSystem(becsID!ChildDestroySystem,"Child Destroy System"); + launcher.gui_manager.addSystem(becsID!ShootWaveSystem,"Shoot Wave System"); + //launcher.gui_manager.addSystem(becsID!SpawnUponDeathSystem,"Child Destroy System"); + //launcher.gui_manager.addSystem(becsID!CollisionMaskSystem,"Collision Mask"); + + //gEntityManager.getSystem(becsID!CleanSystem).disable(); + { + space_invaders.ship_tmpl = gEntityManager.allocateTemplate( + [becsID!CVelocity, becsID!CColor, becsID!CHitMark, becsID!CHitPoints, + becsID!CLocation, becsID!CTexCoords, becsID!CInput, + becsID!CShip, becsID!CScale, becsID!CColliderScale, + becsID!CShootDirection, becsID!CShootGrid, becsID!CGuild, + becsID!CDamping, becsID!CChildren, becsID!CInit, + becsID!CShootGridMask, becsID!CVelocityFactor].staticArray + ); + space_invaders.ship_tmpl.getComponent!CTexCoords().value = vec4(0,80,48,32)*px; + space_invaders.ship_tmpl.getComponent!CScale().value = vec2(48,32); + space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; + space_invaders.ship_tmpl.getComponent!CDamping().value = 14; + space_invaders.ship_tmpl.getComponent!CInit().type = CInit.Type.space_ship; + space_invaders.ship_tmpl.getComponent!CColliderScale().value = vec2(26,24); + space_invaders.ship_tmpl.getComponent!CVelocityFactor().value = vec2(0.5,0.5); + + gEntityManager.addEntity(space_invaders.ship_tmpl,[CLocation(vec2(64,64)).ref_].staticArray); + } + + { + ushort[6] components = [becsID!CLocation, becsID!CTexCoords, becsID!CVelocity, becsID!CScale, becsID!CBullet, becsID!CGuild]; + space_invaders.laser_tmpl = gEntityManager.allocateTemplate(components); + + space_invaders.laser_tmpl.getComponent!CTexCoords().value = vec4(0,24,2,8)*px; + space_invaders.laser_tmpl.getComponent!CScale().value = vec2(2,8); + space_invaders.laser_tmpl.getComponent!CVelocity().value = vec2(0,0.5); + } + + EntityTemplate* enemy_tmpl; + EntityTemplate* grouped_tmpl; + EntityTemplate* tower_tmpl; + EntityTemplate* boss_tmpl; + //EntityTemplate* tower_weapon_tmpl; + EntityID enemy_id; + EntityID grouped_id; + + { + boss_tmpl = gEntityManager.allocateTemplate( + [becsID!CColor, becsID!CHitMark, becsID!CParts, becsID!CLocation, + becsID!CTexCoords, becsID!CScale, becsID!CEnemy, + becsID!CBoss, becsID!CGuild, becsID!CInit, + becsID!CChildren, becsID!CSideMove, becsID!CVelocity, + becsID!CDepth].staticArray + ); + + //CTexture* tex_comp = boss_tmpl.getComponent!CTexture; + //tex_comp.tex = space_invaders.texture;//ship_tex; + //tex_comp.coords = vec4(128*px,0*px,96*px,48*px); + //CLocation* loc_comp = boss_tmpl.getComponent!CLocation; + //loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + boss_tmpl.getComponent!CTexCoords().value = vec4(128,0,96,48)*px; + boss_tmpl.getComponent!CGuild().guild = 1; + boss_tmpl.getComponent!CInit().type = CInit.Type.boss; + boss_tmpl.getComponent!CScale().value = vec2(96,48); + boss_tmpl.getComponent!CDepth().value = -1; + boss_tmpl.getComponent!CParts().count = 4; + boss_tmpl.getComponent!CVelocity().value = vec2(0.025,0); + } + + { + tower_tmpl = gEntityManager.allocateTemplate( + [becsID!CColor, becsID!CHitMark, becsID!CHitPoints, becsID!CLocation, + becsID!CTexCoords, becsID!CScale, becsID!CEnemy, + becsID!CShootGrid, becsID!CGuild, becsID!CInit, + becsID!CChildren, becsID!CShootGridMask].staticArray + ); + + tower_tmpl.getComponent!CTexCoords().value = vec4(96,96,16,16)*px; + tower_tmpl.getComponent!CGuild().guild = 1; + tower_tmpl.getComponent!CInit().type = CInit.Type.tower; + tower_tmpl.getComponent!CHitPoints().value = 10; + } + + { + space_invaders.enemy_tmpl = gEntityManager.allocateTemplate( + [becsID!CWeaponLocation, becsID!CColor, becsID!CHitMark, becsID!CHitPoints, + becsID!CVelocity, becsID!CAutoShoot, becsID!CLocation, + becsID!CTexCoords, becsID!CScale, becsID!CWeapon, + becsID!CEnemy, becsID!CShootDirection, becsID!CShootGrid, + becsID!CGuild, becsID!CShootGridMask].staticArray + ); + + space_invaders.enemy_tmpl.getComponent!CTexCoords().value = vec4(32,32,16,16)*px; + space_invaders.enemy_tmpl.getComponent!CShootDirection().direction = Direction.down; + space_invaders.enemy_tmpl.getComponent!CVelocity().value = vec2(0.05,0); + space_invaders.enemy_tmpl.getComponent!CGuild().guild = 1; + space_invaders.enemy_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,-15); + + Entity* current_entity; + + current_entity = gEntityManager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(32,space_invaders.map_size.y - 16)).ref_].staticArray); + gEntityManager.addComponents(current_entity.id,CSideMove(0)); + + //loc_comp.value = vec2(128,space_invaders.map_size.y - 16); + current_entity = gEntityManager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(128,space_invaders.map_size.y - 16)).ref_].staticArray); + gEntityManager.addComponents(current_entity.id,CSideMove(-1)); + + enemy_id = current_entity.id; + //enemy_tmpl = gEntityManager.allocateTemplate(current_entity.id); + + //loc_comp.value = vec2(256,space_invaders.map_size.y - 16); + gEntityManager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(256,space_invaders.map_size.y - 16)).ref_].staticArray); + + //loc_comp.value = vec2(0,space_invaders.map_size.y - 16); + current_entity = gEntityManager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(0,space_invaders.map_size.y - 16)).ref_].staticArray); + gEntityManager.addComponents(current_entity.id,CSideMove(0)); + + grouped_id = current_entity.id; + //grouped_tmpl = gEntityManager.allocateTemplate(current_entity.id); + } + + EntityTemplate* upgrade_tmpl; + + { + upgrade_tmpl = gEntityManager.allocateTemplate([becsID!CVelocity, becsID!CLocation, becsID!CTexCoords, becsID!CScale, becsID!CUpgrade, becsID!CAnimationLooped, becsID!CAnimation].staticArray); + upgrade_tmpl.getComponent!CTexCoords().value = vec4(0,32,16,16)*px; + upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.05); + *upgrade_tmpl.getComponent!CAnimation = CAnimation(HitPointsSystem.upgrade_laser_frames, 0, 0.75); + } + + gEntityManager.commit(); + + enemy_tmpl = gEntityManager.allocateTemplate(enemy_id); + grouped_tmpl = gEntityManager.allocateTemplate(grouped_id); + + space_invaders.bullet_tmpl[0] = gEntityManager.allocateTemplate( + [becsID!CLocation, becsID!CTexCoords, becsID!CVelocity, + becsID!CScale, becsID!CBullet, becsID!CGuild].staticArray + ); + space_invaders.bullet_tmpl[0].getComponent!CTexCoords().value = vec4(0,24,2,8)*px; + space_invaders.bullet_tmpl[0].getComponent!CScale().value = vec2(2,8); + + space_invaders.bullet_tmpl[1] = gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[0]); + space_invaders.bullet_tmpl[2] = gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[0]); + space_invaders.bullet_tmpl[2].getComponent!CTexCoords().value = vec4(64,32,8,16)*px; + space_invaders.bullet_tmpl[2].getComponent!CScale().value = vec2(8,16); + space_invaders.bullet_tmpl[3] = gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[0]); + space_invaders.bullet_tmpl[3].getComponent!CTexCoords().value = vec4(56,32,2,2)*px; + space_invaders.bullet_tmpl[3].getComponent!CScale().value = vec2(2,2); + // bullet_tmpl[3].getComponent!CTexCoords().value = vec4(48,32,8,8)*px; + // bullet_tmpl[3].getComponent!CScale().value = vec2(8,8); + space_invaders.bullet_tmpl[4] = gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[0]); + + launcher.gui_manager.addTemplate(enemy_tmpl,"Enemy"); + launcher.gui_manager.addTemplate(grouped_tmpl,"Grouped enemy"); + launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(space_invaders.ship_tmpl),"Ship"); + launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(space_invaders.laser_tmpl),"Laser"); + launcher.gui_manager.addTemplate(upgrade_tmpl,"Upgrade"); + launcher.gui_manager.addTemplate(tower_tmpl,"Tower"); + launcher.gui_manager.addTemplate(boss_tmpl,"Boss"); + launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[3]),"Cannon bullet"); + //launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[4]),"Laser"); + //launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(space_invaders.bullet_tmpl[5]),"Laser"); +} + +void spaceInvadersEnd() +{ + /*gEntityManager.getSystem(becsID!DrawSystem).disable(); + gEntityManager.getSystem(becsID!InputMovementSystem).disable(); + gEntityManager.getSystem(becsID!ShootingSystem).disable(); + gEntityManager.getSystem(becsID!MovementSystem).disable(); + gEntityManager.getSystem(becsID!ClampPositionSystem).disable(); + gEntityManager.getSystem(becsID!ShootGridCleaner).disable();*/ + + //gEntityManager.freeTemplate(space_invaders.enemy_tmpl); + Mallocator.dispose(space_invaders); + space_invaders = null; +} + +void spaceInvadersEvent(SDL_Event* event) +{ + +} + +bool spaceInvadersLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + /*if(launcher.show_demo_wnd) + { + igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once); + if(igBegin("Simple",&launcher.show_demo_wnd,0)) + { + if(igCheckbox("Move system",&simple.move_system)) + { + if(simple.move_system)gEntityManager.getSystem(becsID!MoveSystem).enable(); + else gEntityManager.getSystem(becsID!MoveSystem).disable(); + } + if(igCheckbox("Draw system",&simple.draw_system)) + { + if(simple.draw_system)gEntityManager.getSystem(becsID!DrawSystem).enable(); + else gEntityManager.getSystem(becsID!DrawSystem).disable(); + } + igPushButtonRepeat(true); + igColumns(3,null,0); + if(igButton("Spawn",ImVec2(-1,0))) + { + spawnEntity(); + } + igNextColumn(); + if(igButton("+10",ImVec2(-1,0))) + { + foreach(i;0..10)spawnEntity(); + } + igNextColumn(); + if(igButton("+100",ImVec2(-1,0))) + { + foreach(i;0..100)spawnEntity(); + } + igPopButtonRepeat(); + igColumns(1,null,0); + if(igButton("Clear",ImVec2(-1,0))) + { + gEntityManager.getSystem(becsID!CleanSystem).enable(); + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.end(); + gEntityManager.getSystem(becsID!CleanSystem).disable(); + } + } + igEnd(); + }*/ + + /*if(launcher.show_tips) + { + igSetNextWindowPos(ImVec2(800 - 550, 80), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(300, 0), ImGuiCond_Once); + if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) + { + igTextWrapped("Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window."); + } + igEnd(); + }*/ + + gEntityManager.begin(); + if(launcher.multithreading) + { + launcher.job_updater.begin(); + gEntityManager.updateMT(); + launcher.job_updater.call(); + } + else + { + gEntityManager.update(); + } + gEntityManager.end(); + + /*foreach(i;0..1000)//13000) + { + launcher.renderer.draw(simple.texture,vec2(i%100*32,i/100*32),vec2(32,32),vec4(0,0,1,1),0.0); + }*/ + + return true; +} + +DemoCallbacks getSpaceInvadersDemo() +{ + DemoCallbacks demo; + demo.register = &spaceInvadersRegister; + demo.initialize = &spaceInvadersStart; + demo.deinitialize = &spaceInvadersEnd; + demo.loop = &spaceInvadersLoop; + demo.tips = space_invaders.tips; + return demo; +} \ No newline at end of file diff --git a/demos/source/game_core/basic.d b/demos/source/game_core/basic.d new file mode 100644 index 0000000..feaa9ed --- /dev/null +++ b/demos/source/game_core/basic.d @@ -0,0 +1,260 @@ +module game_core.basic; + +import bubel.ecs.core; +import bubel.ecs.attributes; + +import ecs_utils.math.vector; + +import gui.attributes; + +import ecs_utils.utils; + +import app : launcher; + +import bindbc.sdl; + +//position component +struct CLocation +{ + //adds some extra functionality. Not required. Will be probably removed from library in the future. + mixin ECS.Component; + + alias value this;//use component as it value + + //default values work properly + vec2 value = vec2(0); +} + +//scale component +struct CScale +{ + mixin ECS.Component; + + alias value this;//use component as it value + + vec2 value = vec2(16,16); +} + +//rotation component +struct CRotation +{ + mixin ECS.Component; + + alias value this;//use component as it value + + float value = 0; +} + +//depth component. Entity with higher depth will be rendered on top +struct CDepth +{ + mixin ECS.Component; + + alias value this; + + short value; +} + +//color component +struct CColor +{ + mixin ECS.Component; + + alias value this; + + @GUIColor uint value; +} + +//component used for selection +struct CSelected +{ + mixin ECS.Component; + + bool value = false; +} + +//component indicating that entity should receive input from mouse, keyboard, etc. +struct CInput +{ + mixin ECS.Component; +} + +//component with damping value +struct CDamping +{ + mixin ECS.Component; + + alias value this; + + @GUIRange(0,9) byte value = 1; +} + +//velocity component +struct CVelocity +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(0,0); +} + +//factor which is used for velocity masking +struct CVelocityFactor +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(1); +} + +//flag indicating that entity is static and shouldn't be updated by most systems in every frame +struct CStatic +{ + mixin ECS.Component; +} + +//system which slowing down entities +struct DampingSystem +{ + //system will generate up to 32 jobs + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; //entity is readonly + @readonly CDamping[] damping;//damping is readonly. Marking with @readonly will help multithreading algorithm + CVelocity[] velocity;//velocity is wirtable as it will be modified for entities in this system + } + + //20 predefined damping speeds. Gives possibility to store damping as single byte. + float[20] damp = 0; + + bool onBegin() + { + //calculate damping values + foreach(i;0..20) + { + damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.deltaTime*0.1); + } + + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + //constantly slow down entity + data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; + } + } +} + +//system used for entity movement +struct MoveSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CLocation[] location; + @readonly CVelocity[] velocity; + @optional @readonly CVelocityFactor[] vel_factor;//CVeclocityFactor is not required so entites without this component will be also updated + } + + void onUpdate(EntitiesData data) + { + //split into two loops for two types of entities. Doing it in "normal" way by testing data.vel_factor inside loop in every iteration will be probably compiled as same machine code in release build (it works in LDC) + if(data.vel_factor) + { + foreach(i; 0..data.length) + { + data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.deltaTime; + } + } + else + { + foreach(i; 0..data.length) + { + data.location[i] += data.velocity[i] * launcher.deltaTime; + } + } + } +} + +/** +*System is responsible for movement of objects with CInput component. +*In this example every entity has same speed when using movement system. +*/ +struct InputMovementSystem +{ + mixin ECS.System!32; + + vec2 move_vector; + + struct EntitiesData + { + uint length; + //read only components can be marked with @readonly attribute or with const expression instead + const (CInput)[] input; + //components are treated as required by default + //CLocation[] locations; + CVelocity[] velocity; + //CTexture[] textures; + } + + /** + *onBegin gives opportunity to check keys once and call update on entities only when + *one key is pressed. + */ + bool onBegin() + { + move_vector = vec2(0,0); + if(launcher.getKeyState(SDL_SCANCODE_W)) + { + move_vector += vec2(0,1); + } + else if(launcher.getKeyState(SDL_SCANCODE_S)) + { + move_vector += vec2(0,-1); + } + if(launcher.getKeyState(SDL_SCANCODE_A)) + { + move_vector += vec2(-1,0); + } + else if(launcher.getKeyState(SDL_SCANCODE_D)) + { + move_vector += vec2(1,0); + } + + if(move_vector.x != 0 ||move_vector.y != 0) + { + move_vector = move_vector / sqrtf(move_vector.x * move_vector.x + move_vector.y * move_vector.y); + return true; + } + //don't call system update because no key pressed + return false; + } + + /** + *Update is called multiple times in one "manager.update()" call. + *Number of "onUpdate" calls is count of buffers which must be updated during pass. + *When multithreading is used, number of "onUpdate" calls can be greater due to fact that + *JobSystem can split buffers for better data packing. + */ + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.velocity[i] += move_vector * launcher.deltaTime * 0.005; + if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5; + else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5; + if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5; + else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5; + } + } +} \ No newline at end of file diff --git a/demos/source/game_core/collision.d b/demos/source/game_core/collision.d new file mode 100644 index 0000000..bd82624 --- /dev/null +++ b/demos/source/game_core/collision.d @@ -0,0 +1,1022 @@ +module game_core.collision; + +import bubel.ecs.attributes; +import bubel.ecs.block_allocator; +import bubel.ecs.core; +import bubel.ecs.std; +import bubel.ecs.vector; + +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; + +import gui.attributes; + +void registerCollisionModule(EntityManager* manager) +{ + manager.registerDependency(ShootGridDependency); + manager.registerDependency(BVHDependency); + manager.registerDependency(StaticBVHDependency); + + manager.registerComponent!CShootGrid; + manager.registerComponent!CShootGridMask; + manager.registerComponent!CColliderScale; + manager.registerComponent!CBVH; + manager.registerComponent!CAABB; + manager.registerComponent!CStatic; + + manager.registerSystem!ShootGridManager(-80); + manager.registerSystem!ShootGridCleaner(-101); + manager.registerSystem!BVHBuilder(-80); + manager.registerSystem!StaticBVHBuilder(-80); + //manager.registerSystem!BVHBuilder2(-79); + manager.registerSystem!AABBUpdater(-81); +} + +enum ShootGridDependency = "ShootGridDependency"; +enum BVHDependency = "BVHDependency"; +enum StaticBVHDependency = "StaticBVHDependency"; + +struct CShootGrid +{ + mixin ECS.Component; +} + +struct CBVH +{ + mixin ECS.Component; + + @GUIDisabled uint index; +} + +struct CAABB +{ + mixin ECS.Component; + + alias bounding this; + + AABB bounding; +} + +struct CShootGridMask +{ + mixin ECS.Component; + + alias value this; + + @GUIDisabled ubyte value; +} + +struct CColliderScale +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(16,16); +} + + +struct ShootGrid +{ + + ~this() @nogc nothrow + { + if(nodes)Mallocator.dispose(nodes); + if(masks)Mallocator.dispose(masks); + } + + struct Node + { + alias entity this; + + EntityID entity; + } + + void create(ivec2 nodes_count, vec2 node_size) + { + this.size = nodes_count; + this.node_size = node_size; + inv_node_size = vec2(1.0/node_size.x, 1.0/node_size.y); + nodes = Mallocator.makeArray!Node(nodes_count.x * nodes_count.y); + masks = Mallocator.makeArray!ubyte(nodes.length); + } + + void mark(EntityID id, vec2 beg, vec2 end, ubyte mask) + { + ivec2 ibeg = cast(ivec2)(beg * inv_node_size); + ivec2 iend = cast(ivec2)(end * inv_node_size + 0.5); + if(ibeg.x < 0)ibeg.x = 0; + if(ibeg.y < 0)ibeg.y = 0; + if(iend.x > size.x)iend.x = size.x; + if(iend.y > size.y)iend.y = size.y; + foreach(i; ibeg.y .. iend.y) + { + foreach(j; ibeg.x .. iend.x) + { + nodes[i * size.x + j] = id; + masks[i * size.x + j] = mask; + } + } + } + + void clear() + { + size_t size = nodes.length * EntityID.sizeof; + memset(nodes.ptr, 0, size); + memset(masks.ptr, 0, masks.length); + } + + bool test(out EntityID id, vec2 beg, vec2 end, ubyte mask) + { + ivec2 ibeg = cast(ivec2)(beg * inv_node_size); + ivec2 iend = cast(ivec2)(end * inv_node_size + 0.5); + if(ibeg.x < 0)ibeg.x = 0; + if(ibeg.y < 0)ibeg.y = 0; + if(iend.x > size.x)iend.x = size.x; + if(iend.y > size.y)iend.y = size.y; + foreach(i; ibeg.y .. iend.y) + { + foreach(j; ibeg.x .. iend.x) + { + uint index = i * size.x + j; + if(nodes[index].id != 0) + { + if((masks[index] & mask) == 0)continue; + id = nodes[index]; + return true; + } + } + } + return false; + } + + bool test(out EntityID id, vec2 pos, ubyte mask) + { + ivec2 ipos = cast(ivec2)(pos * inv_node_size - 0.5); + if(ipos.x < 0)ipos.x = 0; + if(ipos.y < 0)ipos.y = 0; + if(ipos.x >= size.x)ipos.x = size.x - 1; + if(ipos.y >= size.y)ipos.y = size.y - 1; + size_t index = ipos.y * size.x + ipos.x; + if((masks[index] & mask) == 0)return false; + if(nodes[index].id != 0) + { + id = nodes[index]; + return true; + } + return false; + } + + vec2 inv_node_size; + ivec2 size; + vec2 node_size; + Node[] nodes; + ubyte[] masks; +} + +struct ShootGridCleaner +{ + mixin ECS.System!1; + + struct EntitiesData + { + + } + + ShootGrid* grid; + + bool onBegin() + { + grid = gEntityManager.getSystem!ShootGridManager().grid; + if(grid != null)return true; + else return false; + } + + void onUpdate(EntitiesData data) + { + if(grid)grid.clear(); + } +} + +struct ShootGridManager +{ + mixin ECS.System!128; + + mixin ECS.WritableDependencies!(ShootGridDependency); + + struct EntitiesData + { + uint length; + //uint thread_id; + const (Entity)[] entity; + @readonly CLocation[] locations; + @readonly CShootGrid[] grid_flag; + //@readonly CGuild[] guild; + @optional @readonly CShootGridMask[] mask; + @optional @readonly CScale[] scale; + @optional @readonly CColliderScale[] collider_scale; + } + + ShootGrid* grid; + + void onCreate() + { + //grid = space_invaders.shoot_grid; + grid = Mallocator.make!ShootGrid; + grid.create(ivec2(80,60), vec2(5,5)); + } + + void onDestroy() + { + Mallocator.dispose(grid); + } + + // bool onBegin() + // { + // //if(!grid)return false; + // //grid.clear(); + // return true; + // } + + void onUpdate(EntitiesData data) + { + vec2[] scale; + if(data.collider_scale)scale = cast(vec2[])data.collider_scale; + else if(data.scale)scale = cast(vec2[])data.scale; + else return; + if(data.mask is null) + { + foreach(i; 0..data.length) + { + vec2 half_scale = scale[i] * 0.5; + grid.mark(data.entity[i].id, data.locations[i] - half_scale, data.locations[i] + half_scale, ubyte.max);//cast(ubyte)(1 << data.guild[i].guild)); + } + } + else foreach(i; 0..data.length) + { + vec2 half_scale = scale[i] * 0.5; + grid.mark(data.entity[i].id, data.locations[i] - half_scale, data.locations[i] + half_scale, data.mask[i]);//cast(ubyte)(1 << data.guild[i].guild)); + } + + } +} + +struct AABB +{ + vec2 size() + { + return max-min; + } + + vec2 center() + { + return (max+min) * 0.5; + } + + float area() + { + return size.x * size.y; + } + + void set(ref AABB base, vec2 position, float angle, vec2 scale) + { + import std.algorithm.comparison : max; + + float sr = sinf(angle); + float cr = cosf(angle); + /*mat2 m = mat2(cr,-sr, + sr,cr);*/ + + + //vec2 pos = ;//m * ((base.max + base.min)*0.5*scale); + vec2 size = (base.max - base.min)*scale; + vec2[2] axis = [vec2(cr*size.x,sr*size.y),vec2(-sr*size.x,cr*size.y)]; + + this.max.x = max(fabs(axis[0].x),fabs(axis[1].x)); + this.max.y = max(fabs(axis[0].y),fabs(axis[1].y)); + + this.min = -this.max; + + this.min += center + position; + this.max += center + position; + } + + void set(ref AABB base, vec2 position, vec2 scale) + { + vec2 size = (base.max - base.min)*scale; + + this.min = -size; + this.max = size; + + this.min += center + position; + this.max += center + position; + } + + void set(ref AABB base, vec2 position, float angle) + { + import std.algorithm.comparison : max; + + float sr = sinf(angle); + float cr = cosf(angle); + /*mat2 m = mat2(cr,-sr, + sr,cr);*/ + + + //vec2 pos = ;//m * ((base.max + base.min)*0.5*scale); + vec2 size = (base.max - base.min);//*scale; + vec2[2] axis = [vec2(cr*size.x,sr*size.y),vec2(-sr*size.x,cr*size.y)]; + + this.max.x = max(fabs(axis[0].x),fabs(axis[1].x)); + this.max.y = max(fabs(axis[0].y),fabs(axis[1].y)); + + this.min = -this.max; + + this.min += center + position; + this.max += center + position; + } + + void set(ref AABB base, vec2 position) + { + min = base.min + position; + max = base.max + position; + } + + vec2 min; + vec2 max; +} + +bool test(AABB a, AABB b) +{ + if((a.max.x>b.min.x && a.max.y>b.min.y) && + (a.min.x b.max.x && a.max.y > b.max.y)return 2; + else if((a.max.x>b.min.x && a.max.y>b.min.y) && + (a.min.xb.min.x && point.y>b.min.y) && + (point.x coords.length)return vec4(0,0,1,1); + else return coords[index]; + } + + ushort getCoordIndex(vec4 coords) + { + ushort ret = coords_map.get(coords, ushort.max); + if(ret != ushort.max) + { + return ret; + } + this.coords.add(coords); + coords_map.add(coords, cast(ushort)(this.coords.length - 1)); + return cast(ushort)(this.coords.length - 1); + } + + Vector!vec4 coords; + HashMap!(vec4,ushort) coords_map; +} + +struct DrawSystem +{ + mixin ECS.System!32; + + import ecs_utils.gfx.renderer : Renderer; + + struct EntitiesData + { + uint length; + //uint thread_id; + uint job_id; + const(Entity)[] entity; + @readonly CLocation[] locations; + @readonly @optional CScale[] scale; + // @readonly CTexCoords[] texcoord; + @readonly @optional CTexCoords[] texcoord; + @readonly @optional CTexCoordsIndex[] texcoord_index; + @readonly @optional CRotation[] rotation; + @readonly @optional CDepth[] depth; + @readonly @optional CColor[] color; + @readonly @optional CMaterialIndex[] material; + @readonly @optional CDrawDefault[] draw_default; + } + + Renderer.DrawData default_data; + float color_time = 0; + uint select_color = 0; + + bool onBegin() + { + import app : launcher; + color_time += launcher.delta_time * 0.001; + color_time = color_time - cast(int)(color_time*0.5)*2; + float ratio = color_time - cast(int)color_time; + if(color_time > 1)ratio = 1 - ratio; + uint multipler = cast(uint)(0x60 * ratio); + select_color = 0xA0A0A0A0 + cast(uint)(0x01010101 * multipler); + return true; + } + + void onUpdate(EntitiesData data) + { + import app : launcher; + + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + Renderer.DrawData draw_data = default_data; + draw_data.thread_id = data.job_id; + + if(launcher.show_filtered && launcher.filterEntity(data.entity[0])) + { + draw_data.color = select_color; + data.color = null; + } + //import std.stdio; + //writeln(data.draw_default); + //if(data.draw_default is null && data.texcoord is null && data.texcoord_index is null && !data.entity[0].hasComponent(CDrawDefault.component_id))return; + + if(data.texcoord is null && data.texcoord_index is null && data.draw_default is null)return; + + + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + if(data.color)draw_data.color = data.color[i]; + if(data.depth)draw_data.depth = data.depth[i]; + if(data.rotation)draw_data.angle = data.rotation[i]; + if(data.scale)draw_data.size = data.scale[i]; + if(data.texcoord)draw_data.coords = data.texcoord[i]; + else if(data.texcoord_index)draw_data.coords = TexCoordsManager.instance.get(data.texcoord_index[i]); + if(data.material)draw_data.material_id = data.material[i]; + launcher.renderer.draw(draw_data); + }//*/ + + /* + ubyte mode; + if(data.scale)mode |= 0x01; + if(data.texcoord)mode |= 0x02; + if(data.texcoord_index)mode |= 0x04; + if(data.rotation)mode |= 0x08; + if(data.depth)mode |= 0x10; + if(data.color)mode |= 0x20; + + if(launcher.show_filtered && launcher.filterEntity(data.entity[0])) + { + draw_data.color = select_color; + mode &= ~0x20; + //goto draw_nocolor; + } + + switch(mode) + { + case 0: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + break; + + case 0b000001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + + case 0b000010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b000011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + + case 0b001000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b001001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b001010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b001011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + + + case 0b010000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b010001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b010010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b010011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + + + case 0b100000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b100001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b100010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b100011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + default:break; + }//*/ +/* + if(!data.color) + { + draw_nocolor: + if(!data.depth) + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + else + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + } + else + { + if(!data.depth) + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + else + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + }*/ + } +} \ No newline at end of file diff --git a/demos/source/gui/attributes.d b/demos/source/gui/attributes.d new file mode 100644 index 0000000..4c4c269 --- /dev/null +++ b/demos/source/gui/attributes.d @@ -0,0 +1,23 @@ +module gui.attributes; + +enum GUIColor = "GUIColor"; + +struct GUIRange +{ + struct + { + int min; + int max; + } +} + +struct GUIRangeF +{ + struct + { + float minf; + float maxf; + } +} + +enum GUIDisabled = "GUIDisabled"; diff --git a/demos/source/gui/component.d b/demos/source/gui/component.d new file mode 100644 index 0000000..fdae1c2 --- /dev/null +++ b/demos/source/gui/component.d @@ -0,0 +1,64 @@ +module gui.component; + +import ecs_utils.utils; + +struct ComponentGUI +{ + const (char)* name; + void* data; + ushort component_id; +} + +struct ComponentEditGUI +{ + const (char)* name; + VariableGUI[] variables; + uint used; +} + +struct VariableGUI +{ + struct Int + { + int min; + int max; + } + + struct Float + { + float min; + float max; + } + + struct Enum + { + const (char)[][] strings; + } + + enum Type + { + byte_, + ubyte_, + short_, + ushort_, + int_, + uint_, + float_, + enum_, + color, + vec2, + ivec2, + vec4, + ivec4 + } + Type type; + const (char)* name; + ushort offset; + bool disabled = false; + union + { + Int int_; + Float float_; + Enum enum_; + } +} diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d new file mode 100644 index 0000000..52e7f55 --- /dev/null +++ b/demos/source/gui/manager.d @@ -0,0 +1,548 @@ +module gui.manager; + +import app; + +import cimgui.cimgui; + +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; +import bubel.ecs.system; +import bubel.ecs.vector; + +import ecs_utils.math.vector; + +import gui.attributes; +import gui.component; +import gui.system; +import gui.template_; + +import std.traits; + +extern(C): + +struct GUIManager +{ + Vector!SystemGUI systems; + Vector!ComponentGUI components; + Vector!TemplateGUI templates; + Vector!ComponentEditGUI edit_components; + Vector!bool filter; + Vector!ushort filter_list; + + int selected_template = 0; + int selected_component = 0; + + ~this() + { + clear(); + } + + void selectTemplate(int id) + { + if(templates.length == 0)return; + selected_template = id; + while(selected_template < 0)selected_template += cast(int)templates.length; + while(selected_template >= templates.length)selected_template -= cast(int)templates.length; + } + + void selectComponent(int id) + { + if(components.length == 0)return; + selected_component = id; + while(selected_component < 0)selected_component += cast(int)components.length; + while(selected_component >= components.length)selected_component -= cast(int)components.length; + } + + void clear() + { + foreach(tmpl; templates) + { + gEntityManager.freeTemplate(tmpl.tmpl); + } + foreach(comp; components) + { + free(comp.data); + } + foreach(ref comp; edit_components) + { + if(comp.variables)Mallocator.dispose(comp.variables); + comp.variables = null; + comp.used = 0; + comp.name = null; + } + foreach(ref comp; filter) + { + comp = false; + } + + filter_list.clear(); + systems.clear(); + templates.clear(); + components.clear(); + selected_template = 0; + selected_component = 0; + } + + EntityTemplate* getSelectedTemplate() + { + if(templates.length > selected_template)return templates[selected_template].tmpl; + else return null; + } + + ComponentRef getSelectedComponent() + { + if(components.length > selected_component)return ComponentRef(components[selected_component].data, components[selected_component].component_id); + else return ComponentRef(null, ushort.max); + } + + void addSystem(ushort id, const (char)* name, bool enabled = true) + { + foreach(ref sys; systems) + { + if(sys.id == id)return; + } + System* system = gEntityManager.getSystem(id); + //const (char)* name = + systems.add(SystemGUI(name,id,enabled)); + } + + void addTemplate(ushort[] components, const (char)* name) + { + templates.add(TemplateGUI(name, gEntityManager.allocateTemplate(components))); + } + + void addTemplate(EntityTemplate* tmpl, const (char)* name) + { + templates.add(TemplateGUI(name, tmpl)); + } + + // void addComponent(ComponentRef comp, const (char)* name) + // { + // uint size = gEntityManager.components[becsID(comp)].size; + // void* data = malloc(size); + // memcpy(data, comp.ptr, size); + // components.add(ComponentGUI(name, data, becsID(comp))); + // } + + void addComponent(T)(T comp, const (char)* name) + { + uint size = gEntityManager.components[becsID(comp)].size; + void* data = malloc(size); + memcpy(data, &comp, size); + components.add(ComponentGUI(name, data, becsID(comp))); + + if(edit_components.length <= becsID(comp)) + { + edit_components.length = becsID(comp)+1;//.extend(becsID(comp) + 1); + } + //edit_components[becsID(comp)] = ComponentEditGUI(name); + if(edit_components[becsID(comp)].variables)return; + ComponentEditGUI comp_edit; + comp_edit.name = T.stringof; + //enum fields = __traits(allMembers, T); + alias fields = FieldNameTuple!T; + //pragma(msg,fields); + comp_edit.variables = Mallocator.makeArray!VariableGUI(fields.length); + foreach(member_str; fields) + { + alias member = __traits(getMember, T, member_str); + alias member_type = typeof(member); + //pragma(msg,member); + //pragma(msg,member_type); + //pragma(msg,__traits(getMember, T, member).offsetof); + ushort offset = member.offsetof;//cast(ushort)__traits(getMember, T, member).offsetof; + + static if(is(member_type == vec2)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec2,member_str,offset); + } + else static if(is(member_type == ivec2)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ivec2,member_str,offset); + } + else static if(is(member_type == vec4)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec4,member_str,offset); + } + else static if(is(member_type == ivec4)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ivec4,member_str,offset); + } + else static if(__traits(isIntegral,member_type)) + { + static if(__traits(isUnsigned, member_type)) + { + static if(hasUDA!(member,GUIColor)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.color,member_str,offset); + } + else switch(member_type.sizeof) + { + case 1: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ubyte_,member_str,offset);break; + case 2: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ushort_,member_str,offset);break; + case 4: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.uint_,member_str,offset);break; + default:break; + } + static if(hasUDA!(member,GUIRange)) + { + comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min; + comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[0].max; + } + else + { + comp_edit.variables[comp_edit.used-1].int_.min = 0; + comp_edit.variables[comp_edit.used-1].int_.max = int.max; + } + } + else + { + switch(member_type.sizeof) + { + case 1: + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.byte_,member_str,offset); + comp_edit.variables[comp_edit.used-1].int_.min = byte.min; + comp_edit.variables[comp_edit.used-1].int_.max = byte.max; + break; + case 2: + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.short_,member_str,offset); + comp_edit.variables[comp_edit.used-1].int_.min = short.min; + comp_edit.variables[comp_edit.used-1].int_.max = short.max; + break; + case 4: + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.int_,member_str,offset); + comp_edit.variables[comp_edit.used-1].int_.min = int.min; + comp_edit.variables[comp_edit.used-1].int_.max = int.max; + break; + default:break; + } + static if(hasUDA!(member,GUIRange)) + { + comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min; + comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[0].max; + } + /*{ + comp_edit.variables[comp_edit.used-1].int_.min = int.min; + comp_edit.variables[comp_edit.used-1].int_.max = int.max; + }*/ + } + } + else static if(__traits(isScalar,member_type)) + { + switch(member_type.sizeof) + { + case 4:comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.float_,member_str,offset);break; + case 8: + default:break; + } + static if(hasUDA!(member,GUIRange)) + { + comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRange)[0].min; + comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRange)[0].max; + } + else static if(hasUDA!(member,GUIRangeF)) + { + comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRangeF)[0].minf; + comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRangeF)[0].maxf; + } + else { + comp_edit.variables[comp_edit.used-1].float_.min = -float.max; + comp_edit.variables[comp_edit.used-1].float_.max = float.max; + } + } + static if(hasUDA!(member,GUIDisabled))comp_edit.variables[comp_edit.used - 1].disabled = true; + } + edit_components[becsID(comp)] = comp_edit; + } + + void gui() + { + if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_DefaultOpen)) + { + //bool true_ = true; + igIndent(8); + foreach(ref SystemGUI system;systems) + { + igPushIDPtr(&system); + if(igCheckbox(system.name,&system.enabled)) + { + System* sys = gEntityManager.getSystem(system.id); + if(system.enabled)sys.enable(); + else sys.disable(); + } + igPopID(); + } + igUnindent(8); + } + } + + static vec4 colorUintToVec4(uint color) + { + // color = *cast(uint*)(comp_ptr+var.offset); + return vec4(cast(float)(color & 0xFF) / 255, + cast(float)(color >> 8 & 0xFF) / 255, + cast(float)(color >> 16 & 0xFF) / 255, + cast(float)(color >> 24 & 0xFF) / 255); + } + + static uint colorVec4ToUint(vec4 color) + { + return cast(uint)(color.x * 255) | + cast(uint)(color.y * 255) << 8 | + cast(uint)(color.z * 255) << 16 | + cast(uint)(color.w * 255) << 24; + } + + static bool igDragScalarClamp(const(char)* label, ImGuiDataType data_type, void* v, float v_speed, const(void)* v_min, const(void)* v_max, const(char)* format, float power) + { + ubyte[8] v_backup;// = *v; + final switch(data_type) + { + case ImGuiDataType_S8:memcpy(v_backup.ptr, v, 1);break; + case ImGuiDataType_S16:memcpy(v_backup.ptr, v, 2);break; + case ImGuiDataType_S32:memcpy(v_backup.ptr, v, 4);break; + case ImGuiDataType_U8:memcpy(v_backup.ptr, v, 1);break; + case ImGuiDataType_U16:memcpy(v_backup.ptr, v, 2);break; + case ImGuiDataType_U32:memcpy(v_backup.ptr, v, 4);break; + case ImGuiDataType_Float:memcpy(v_backup.ptr, v, 4);break; + } + if (!igDragScalar(label, data_type, v, v_speed, v_min, v_max, format, power)) + return false; + + final switch(data_type) + { + case ImGuiDataType_S8: + if(*cast(byte*)v < *cast(byte*)v_min)*cast(byte*)v = *cast(byte*)v_min; + else if(*cast(byte*)v > *cast(byte*)v_max)*cast(byte*)v = *cast(byte*)v_max; + return *cast(byte*)v != *cast(byte*)v_backup.ptr; + case ImGuiDataType_S16: + if(*cast(short*)v < *cast(short*)v_min)*cast(short*)v = *cast(short*)v_min; + else if(*cast(short*)v > *cast(short*)v_max)*cast(short*)v = *cast(short*)v_max; + return *cast(short*)v != *cast(short*)v_backup.ptr; + case ImGuiDataType_S32: + if(*cast(int*)v < *cast(int*)v_min)*cast(int*)v = *cast(int*)v_min; + else if(*cast(int*)v > *cast(int*)v_max)*cast(int*)v = *cast(int*)v_max; + return *cast(int*)v != *cast(int*)v_backup.ptr; + case ImGuiDataType_U8: + if(*cast(ubyte*)v < *cast(ubyte*)v_min)*cast(ubyte*)v = *cast(ubyte*)v_min; + else if(*cast(ubyte*)v > *cast(ubyte*)v_max)*cast(ubyte*)v = *cast(ubyte*)v_max; + return *cast(ubyte*)v != *cast(ubyte*)v_backup.ptr; + case ImGuiDataType_U16: + if(*cast(ushort*)v < *cast(ushort*)v_min)*cast(ushort*)v = *cast(ushort*)v_min; + else if(*cast(ushort*)v > *cast(ushort*)v_max)*cast(ushort*)v = *cast(ushort*)v_max; + return *cast(ushort*)v != *cast(ushort*)v_backup.ptr; + case ImGuiDataType_U32: + if(*cast(uint*)v < *cast(uint*)v_min)*cast(uint*)v = *cast(uint*)v_min; + else if(*cast(uint*)v > *cast(uint*)v_max)*cast(uint*)v = *cast(uint*)v_max; + return *cast(uint*)v != *cast(uint*)v_backup.ptr; + case ImGuiDataType_Float: + if(*cast(float*)v < *cast(float*)v_min)*cast(float*)v = *cast(float*)v_min; + else if(*cast(float*)v > *cast(float*)v_max)*cast(float*)v = *cast(float*)v_max; + return *cast(float*)v != *cast(float*)v_backup.ptr; + } + } + + void componentGUI(ushort comp_id, void* data_ptr) + { + vec4 color; + if(comp_id >= edit_components.length)return; + //if(edit_components[comp_id].used) + if(edit_components[comp_id].name) + { + if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) + { + igIndent(8); + foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used]) + { + + igPushIDPtr(&var); + switch(var.type) + { + case VariableGUI.Type.byte_: + igDragScalarClamp(var.name, ImGuiDataType_S8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ubyte_: + if(var.disabled) + { + ubyte v = *cast(ubyte*)(data_ptr+var.offset); + igDragScalarClamp(var.name, ImGuiDataType_U8, &v, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + } + else igDragScalarClamp(var.name, ImGuiDataType_U8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.short_: + igDragScalarClamp(var.name, ImGuiDataType_S16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ushort_: + igDragScalarClamp(var.name, ImGuiDataType_U16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.int_: + igDragScalarClamp(var.name, ImGuiDataType_S32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.uint_: + if(var.disabled) + { + uint v = *cast(uint*)(data_ptr+var.offset); + igDragScalarClamp(var.name, ImGuiDataType_U32, &v, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + } + else igDragScalarClamp(var.name, ImGuiDataType_U32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.float_: + igDragScalarClamp(var.name, ImGuiDataType_Float, data_ptr+var.offset, 0.1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, "%2.2f", 1); + break; + case VariableGUI.Type.color: + color = colorUintToVec4(*cast(uint*)(data_ptr+var.offset)); + if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) + *cast(uint*)(data_ptr+var.offset) = colorVec4ToUint(color); + break; + case VariableGUI.Type.vec2: + igDragFloat2(var.name, (cast(float*)(data_ptr+var.offset))[0..2], 0.1, -float.max, float.max, null, 1); + break; + case VariableGUI.Type.ivec2: + igDragInt2(var.name, (cast(int*)(data_ptr+var.offset))[0..2], 0.1, int.min, int.max, null); + break; + case VariableGUI.Type.vec4: + igDragFloat4(var.name, (cast(float*)(data_ptr+var.offset))[0..4], 0.1, -float.max, float.max, null, 1); + break; + case VariableGUI.Type.ivec4: + igDragInt4(var.name, (cast(int*)(data_ptr+var.offset))[0..4], 0.1, int.min, int.max, null); + break; + default:break; + } + igPopID(); + } + //igPopID(); + igUnindent(8); + } + } + } + + void templateComponentsGUI() + { + if(selected_template >= templates.length)return; + EntityTemplate* tmpl = templates[selected_template].tmpl; + EntityManager.EntityInfo* info = tmpl.info; + foreach(comp_id; info.components) + { + void* data_ptr = tmpl.entity_data.ptr; + void* comp_ptr = data_ptr + info.tmpl_deltas[comp_id]; + componentGUI(comp_id, comp_ptr); + } + } + + void entityComponentsGUI(Entity* entity) + { + if(!entity)return; + EntityMeta meta = entity.getMeta(); + EntityManager.EntityInfo* info = meta.block.type_info; + foreach(comp_id; info.components) + { + // void* data_ptr = tmpl.entity_data.ptr; + void* comp_ptr = meta.getComponent(comp_id);//data_ptr + info.tmpl_deltas[comp_id]; + componentGUI(comp_id, comp_ptr); + } + } + + void toolGui() + { + ImGuiStyle * style = igGetStyle(); + ImVec4 col = style.Colors[ImGuiCol_Header]; + style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg]; + //style. + //ImDrawList* draw_list = igGetWindowDrawList(); + final switch(launcher.used_tool) + { + case Tool.entity_spawner: + if(templates.length) + { + { + if(igListBoxHeaderInt("Template",cast(int)templates.length,cast(int)templates.length)) + { + foreach(i, tmpl; templates) + { + if(igSelectable(tmpl.name,selected_template == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0))) + { + selected_template = cast(uint)i; + } + } + igListBoxFooter(); + } + } + if(igIsItemHovered(0))igSetTooltip("Select entity to spawn (SHIFT + Scroll)"); + } + style.Colors[ImGuiCol_Header] = col; + templateComponentsGUI(); + break; + case Tool.component_manipulator: + if(components.length) + { + if(igListBoxHeaderInt("Components",cast(int)components.length,cast(int)components.length)) + { + foreach(i, comp; components) + { + if(igSelectable(comp.name,selected_component == i,0,ImVec2(0,0))) + { + selected_component = cast(uint)i; + } + } + igListBoxFooter(); + } + if(igIsItemHovered(0))igSetTooltip("Select component to add/remove (SHIFT + Scroll)"); + } + style.Colors[ImGuiCol_Header] = col; + if(selected_component < components.length)componentGUI(components[selected_component].component_id, components[selected_component].data); + break; + case Tool.selector: + { + Entity* entity = gEntityManager.getEntity(launcher.selected_entity); + style.Colors[ImGuiCol_Header] = col; + entityComponentsGUI(entity); + } + break; + } + + style.Colors[ImGuiCol_Header] = col; + } + + private void genFilterList() + { + filter_list.clear(); + foreach(i, comp; filter) + { + if(comp) + { + filter_list.add(cast(ushort)i); + } + } + } + + void filterGUI() + { + ImGuiStyle * style = igGetStyle(); + ImVec4 col = style.Colors[ImGuiCol_Header]; + style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg]; + + if(filter.length < edit_components.length)filter.length(edit_components.length); + + int length = 0; + foreach(comp; edit_components) + { + if(comp.name !is null)length++; + } + + if(length && igListBoxHeaderInt("Components##FilterComponents",cast(int)length,cast(int)length)) + { + foreach(i, ref comp; edit_components) + { + if(comp.name is null)continue; + if(igSelectableBoolPtr(comp.name,&filter[i],0,ImVec2(0,0))) + { + genFilterList(); + } + } + igListBoxFooter(); + } + if(igIsItemHovered(0))igSetTooltip("Select components to filter while tool work.\nComponents are only changed for filtered entities."); + + style.Colors[ImGuiCol_Header] = col; + } +} \ No newline at end of file diff --git a/demos/source/gui/system.d b/demos/source/gui/system.d new file mode 100644 index 0000000..b4899fb --- /dev/null +++ b/demos/source/gui/system.d @@ -0,0 +1,12 @@ +module gui.system; + +import bubel.ecs.system; + +struct SystemGUI +{ + const (char)* name; + //System* system; + ushort id; + + bool enabled = true; +} \ No newline at end of file diff --git a/demos/source/gui/template_.d b/demos/source/gui/template_.d new file mode 100644 index 0000000..4d3de11 --- /dev/null +++ b/demos/source/gui/template_.d @@ -0,0 +1,9 @@ +module gui.template_; + +import bubel.ecs.entity; + +struct TemplateGUI +{ + const (char)* name; + EntityTemplate* tmpl; +} \ No newline at end of file diff --git a/demos/source/gui/tool_circle.d b/demos/source/gui/tool_circle.d new file mode 100644 index 0000000..c8968d4 --- /dev/null +++ b/demos/source/gui/tool_circle.d @@ -0,0 +1,53 @@ +module gui.tool_circle; + +import ecs_utils.gfx.buffer; +import ecs_utils.gfx.shader; +import ecs_utils.gfx.config; +import ecs_utils.gfx.renderer; + +import ecs_utils.math.vector; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +struct ToolCircle +{ + //Buffer vbo; + //Buffer ibo; + + uint material_id = 1; + uint mesh_id = 0; + + /*/void generate() + { + ushort[] + }*/ + + void draw(Renderer* renderer, vec2 position, float size, float edge = 1) + { + glDisable(GL_DEPTH_TEST); + position = position * renderer.view_size + renderer.view_pos; + vec2 sizes = renderer.view_size * size; + vec2 sizes2 = vec2(edge,0); + + import core.stdc.string; + ubyte[32] uniform_block; + void* ptr = uniform_block.ptr; + *cast(float*)(ptr) = sizes.x; + *cast(float*)(ptr+4) = 0; + *cast(float*)(ptr+8) = 0; + *cast(float*)(ptr+12) = sizes.y; + memcpy(ptr+16,position.data.ptr,8); + memcpy(ptr+24,sizes2.data.ptr,8); + glEnableVertexAttribArray(0); + + GfxConfig.meshes[mesh_id].bind(); + GfxConfig.materials[material_id].bind(); + GfxConfig.materials[material_id].pushBindings(); + GfxConfig.materials[material_id].pushUniforms(uniform_block.ptr); + //glDisable(GL_DEPTH_TEST); + + glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null); + } +} \ No newline at end of file diff --git a/demos/source/meson.build b/demos/source/meson.build new file mode 100644 index 0000000..e578ca0 --- /dev/null +++ b/demos/source/meson.build @@ -0,0 +1,20 @@ +demos_src += files( + 'app.d', + 'demos/brick_breaker.d', + 'demos/bullet_madnes.d', + 'demos/particles.d', + 'demos/physics.d', + 'demos/sandbox.d', + 'demos/simple.d', + 'demos/snake.d', + 'demos/space_invaders.d', + 'game_core/basic.d', + 'game_core/collision.d', + 'game_core/job_updater.d', + 'game_core/rendering.d', + 'gui/component.d', + 'gui/manager.d', + 'gui/system.d', + 'gui/template_.d', + 'gui/tool_circle.d', +) \ No newline at end of file diff --git a/demos/utils/dub.json b/demos/utils/dub.json new file mode 100644 index 0000000..749bd4b --- /dev/null +++ b/demos/utils/dub.json @@ -0,0 +1,48 @@ +{ + "name": "ecs_utils", + "authors": [ + "Michał Masiukiewicz", "Dawid Masiukiewicz" + ], + "description": "Dynamic Entity Component System examples utils", + "copyright": "Copyright © 2018-2019, Michał Masiukiewicz, Dawid Masiukiewicz", + "license": "BSD 3-clause", + "sourcePaths" : [ + "source", + "../external/sources" + ], + "importPaths": [ + "source", + "../external/sources" + ], + "dependencies": { + "bindbc-sdl":"0.19.0", + "bubel_ecs":{"path":"../../"} + }, + "versions": [ + "BindSDL_Image", + "SDL_2010" + ], + "configurations" : [ + { + "name" : "default", + "targetType" : "library", + "subConfigurations": + { + "bindbc-sdl": "static", + "bubel_ecs":"library" + } + }, + { + "name" : "betterC", + "targetType" : "library", + "dflags": [ + "-betterC" + ], + "subConfigurations": + { + "bindbc-sdl": "staticBC", + "bubel_ecs":"library-betterC" + } + } + ] +} \ No newline at end of file diff --git a/demos/utils/meson.build b/demos/utils/meson.build new file mode 100644 index 0000000..708fc85 --- /dev/null +++ b/demos/utils/meson.build @@ -0,0 +1,25 @@ +# Files +utils_src = files() +subdir('source/ecs_utils') + +utils_inc = include_directories('source/') + +# Dependencies +ecs_utils_lib = library('ECSUtils', utils_src, + include_directories : [demos_inc, external_inc, utils_inc], + link_args : link_args, + d_module_versions : versions, + dependencies : [ + bubel_ecs_dep, + bindbc_loader_dep, + bindbc_sdl_dep, + ] +) + +ecs_utils_dep = declare_dependency( + include_directories : utils_inc, + link_with : ecs_utils_lib, +) +#shared_library('ecs_utils', utils_src, include_directories : [utils_inc], d_args: args, link_args: link_args, link_with: ecs_lib) + + diff --git a/demos/utils/source/ecs_utils/gfx/buffer.d b/demos/utils/source/ecs_utils/gfx/buffer.d new file mode 100644 index 0000000..76cab50 --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/buffer.d @@ -0,0 +1,138 @@ +module ecs_utils.gfx.buffer; + +import bubel.ecs.std; + +//import glad.gl.gl; +//import glad.gl.gles2; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +extern(C): + +struct Buffer +{ + + void create() nothrow + { + data = Mallocator.make!Data; + data.gl_handle = 0; + glGenBuffers(1,&data.gl_handle); + data.elem_size = 0; + } + + //--------------------------------------------------------------------------------------------------------------------------------------------------- + + void destroy() nothrow + { + if(data.gl_handle)glDeleteBuffers(1,&data.gl_handle); + } + + //--------------------------------------------------------------------------------------------------------------------------------------------------- + + void bind(BindTarget target) nothrow + { + //if(vbo != this)glBindBuffer(GL_ARRAY_BUFFER,data.gl_handle); + //vbo = this; + glBindBuffer(target,data.gl_handle); + } + + void bindRange(BindTarget target, uint index, uint offset, uint size) nothrow + { + glBindBufferRange(target, index, data.gl_handle, offset, size); + } + + //--------------------------------------------------------------------------------------------------------------------------------------------------- + + void bufferData(BindTarget target, uint size, uint count, uint usage, void* data) nothrow + { + bind(target); + this.data.elem_size = size; + glBufferData(target,size*count,data,usage); + } + + /*void bufferStorage(uint size, uint count, void* data, uint flags = StorageFlagBits.write) + { + bind(BindTarget.array); + this.data.elem_size = size; + glBufferStorage(GL_ARRAY_BUFFER,size*count,data, flags); + }*/ + + void bufferSubData(BindTarget target, uint size, uint offset, void* data) nothrow + { + bind(target); + glBufferSubData(target,offset,size,data); + } + + void map(BindTarget target) nothrow + { + bind(target); + version(Android){}else version(WebAssembly){}else data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY); + } + + void map(uint offset, uint size, BindTarget target, uint flags = MapFlagBits.write | MapFlagBits.flush_explict | MapFlagBits.invalidate_buffer) nothrow + { + bind(target); + version(Android){}else data.map_ptr = glMapBufferRange(target,offset,size,flags); + } + + void flush(uint offset, uint size, BindTarget target) nothrow + { + glFlushMappedBufferRange(target, offset, size); + } + + void unmap(BindTarget target) nothrow + { + bind(target); + glUnmapBuffer(target); + data.map_ptr = null; + } + + void* mappedPointer() nothrow + { + return data.map_ptr; + } + + //--------------------------------------------------------------------------------------------------------------------------------------------------- + + static void unbind(BindTarget target) nothrow + { + //vbo = 0; + glBindBuffer(target,0); + } + + enum BindTarget + { + array = GL_ARRAY_BUFFER, + element_array = GL_ELEMENT_ARRAY_BUFFER, + uniform = GL_UNIFORM_BUFFER, + //shader_storage = GL_SHADER_STORAGE_BUFFER, + //indirect = GL_DRAW_INDIRECT_BUFFER + } + + enum MapFlagBits + { + write = GL_MAP_WRITE_BIT, + invalidate_buffer = GL_MAP_INVALIDATE_BUFFER_BIT, + flush_explict = GL_MAP_FLUSH_EXPLICIT_BIT, + //coherent = GL_MAP_COHERENT_BIT, + //persistent = GL_MAP_PERSISTENT_BIT + } + + enum StorageFlagBits + { + write = GL_MAP_WRITE_BIT, + //coherent = GL_MAP_COHERENT_BIT, + //persistent = GL_MAP_PERSISTENT_BIT + } + + struct Data + { + uint elem_size; + uint gl_handle; + void* map_ptr; + } + + Data* data; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/config.d b/demos/utils/source/ecs_utils/gfx/config.d new file mode 100644 index 0000000..0683647 --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/config.d @@ -0,0 +1,102 @@ +module ecs_utils.gfx.config; + +import bindbc.sdl; + +import bubel.ecs.std; + +import ecs_utils.gfx.material; +import ecs_utils.gfx.mesh; +import ecs_utils.gfx.texture; + +//import mutils.serializer.json; + +extern(C): + +enum LayerType +{ + normal, + sorted +} + +import bubel.ecs.vector; + +static struct GfxConfig +{ + extern(C): + __gshared: + Vector!LayerType layers; + //Vector!Mesh meshes; + //Vector!Material materials; + Mesh[] meshes; + Material[] materials; + + static bool load(const (char)[] path) nothrow + { + struct LoadData + { + struct Str + { + @("malloc") string str; + } + + @("malloc") Str[] materials; + @("malloc") Str[] meshes; + int inter; + + void dispose() nothrow + { + /*if(blend_mode)Mallocator.instance.dispose(cast(char[])blend_mode); + if(vertex)Mallocator.instance.dispose(cast(char[])vertex); + if(fragment)Mallocator.instance.dispose(cast(char[])fragment);*/ + } + } + + char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; + cpath[0..$-1] = path[0..$]; + cpath[$-1] = 0; + + SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r"); + if(file) + { + size_t size = cast(size_t)SDL_RWsize(file); + char[] buffer = Mallocator.makeArray!char(size); + SDL_RWread(file,buffer.ptr,size,1); + + LoadData load_data; + scope(exit)load_data.dispose(); + + /*JSONSerializer serializer = Mallocator.make!JSONSerializer; + scope(exit)Mallocator.dispose(serializer); + serializer.serialize!(Load.yes, true)(load_data,buffer);*/ + + //if(__ecs_used_backend == Backend.opengl) + { + meshes = Mallocator.makeArray!Mesh(load_data.meshes.length); + foreach(i,ref mesh; meshes) + { + mesh.load(load_data.meshes[i].str); + mesh.uploadData(); + } + } + + materials = Mallocator.makeArray!Material(load_data.materials.length); + foreach(i,ref material; materials) + { + material.create(); + material.load(load_data.materials[i].str); + material.compile(); + } + + SDL_RWclose(file); + load_data.dispose(); + return true; + } + else return false; + } + + static int addLayer(LayerType type) + { + layers.add(type); + return cast(int)(layers.length-1); + } +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/material.d b/demos/utils/source/ecs_utils/gfx/material.d new file mode 100644 index 0000000..0fca5fb --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/material.d @@ -0,0 +1,219 @@ +module ecs_utils.gfx.material; + +import bindbc.sdl; + +import bubel.ecs.std; + +import ecs_utils.gfx.shader; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +//import mutils.serializer.json; + +struct Material +{ + + void create() nothrow + { + data = Mallocator.make!Data; + } + + bool load(const char[] path) nothrow + { + struct LoadData + { + @("malloc") string blend_mode; + @("malloc") string vertex; + @("malloc") string fragment; + + void dispose() nothrow + { + //if(blend_mode)Mallocator.instance.dispose(cast(char[])blend_mode); + //if(vertex)Mallocator.instance.dispose(cast(char[])vertex); + //if(fragment)Mallocator.instance.dispose(cast(char[])fragment); + } + } + + char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; + cpath[0..$-1] = path[0..$]; + cpath[$-1] = 0; + + SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r"); + if(file) + { + size_t size = cast(size_t)SDL_RWsize(file); + char[] buffer = Mallocator.makeArray!char(size); + SDL_RWread(file,buffer.ptr,size,1); + + LoadData load_data; + scope(exit)load_data.dispose(); + + /*JSONSerializer serializer = Mallocator.make!JSONSerializer; + scope(exit)Mallocator.dispose(serializer); + serializer.serialize!(Load.yes, true)(load_data,buffer);*/ + + //if(__ecs_used_backend == Backend.opengl) + { + Shader vsh; + vsh.load(load_data.vertex); + vsh.compile(); + + Shader fsh; + fsh.load(load_data.fragment); + fsh.compile(); + + Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)]; + + attachModules(modules); + } + + SDL_RWclose(file); + load_data.dispose(); + return true; + } + else return false; + } + + void bind() nothrow + { + final switch(data.blend_mode) + { + case BlendMode.mixed: + glDepthMask(0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case BlendMode.opaque: + glDepthMask(1); + glDisable(GL_BLEND); + break; + case BlendMode.additive: + glDepthMask(0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + //glBlendFunc(GL_ONE, GL_ONE); + break; + } + + glUseProgram(data.modules[0].gl_handle); + } + + enum BlendMode + { + opaque, + additive, + mixed + } + + enum TransformMode + { + position, + matrix + } + + struct ShaderModule + { + Shader fragment_shader; + Shader vertex_shader; + uint gl_handle; + } + + void attachModules(scope ShaderModule[] modules) nothrow + { + data.modules = Mallocator.makeArray(modules); + } + + bool compile() nothrow + { + foreach(ref module_;data.modules) + { + module_.gl_handle = glCreateProgram(); + glAttachShader(module_.gl_handle, module_.vertex_shader.data.gl_handle); + glAttachShader(module_.gl_handle, module_.fragment_shader.data.gl_handle); + } + + return true; + } + + void bindAttribLocation(const char* name, uint location) nothrow + { + foreach(ref module_;data.modules) + { + glBindAttribLocation(module_.gl_handle, location, name); + } + } + + bool link() nothrow + { + foreach(ref module_;data.modules) + { + glLinkProgram(module_.gl_handle); + + GLint ok = 0; + glGetProgramiv(module_.gl_handle, GL_LINK_STATUS, &ok); + if(!ok) + { + SDL_Log("Program link error!"); + return false; + } + } + + return true; + } + + int getLocation(const char* name) + { + foreach(ref module_;data.modules) + { + int location = glGetUniformLocation(module_.gl_handle,name); + if(location != -1)return location; + } + return -1; + } + + void pushBindings() + { + foreach(i;0..data.bindings.length) + { + glUniform1i(data.bindings[i],cast(int)i); + } + } + + void pushUniforms(void* ptr) + { + foreach(ref Uniform uniform; data.uniforms) + { + void* local_ptr = ptr + uniform.offset; + glUniform4fv(uniform.location,1,cast(float*)local_ptr); + } + } + + enum Type + { + float_, + float4 + } + + struct Uniform + { + Type type; + int location; + uint offset; + } + + struct Data + { + BlendMode blend_mode = BlendMode.opaque; + + ShaderModule[] modules; + + TransformMode mode; + + Uniform[] uniforms; + int[] bindings; + } + + Data* data; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/mesh.d b/demos/utils/source/ecs_utils/gfx/mesh.d new file mode 100644 index 0000000..e953778 --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/mesh.d @@ -0,0 +1,123 @@ +module ecs_utils.gfx.mesh; + +import bindbc.sdl; + +import bubel.ecs.std; + +import ecs_utils.gfx.buffer; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; +//import mutils.serializer.json; + +extern(C): + +struct Mesh +{ + bool load(const char[] path) nothrow + { + struct LoadData + { + /*struct Vertex + { + struct Binding + { + @("malloc") string type; + uint stride; + } + @("malloc") Binding[] bindings; + } + Vertex vertex;*/ + @("malloc") ushort[] indices; + @("malloc") float[] vertices; + //int i; + + void dispose() nothrow + { + if(indices)Mallocator.dispose(indices); + if(vertices)Mallocator.dispose(vertices); + + /*foreach(binding; vertex.bindings)Mallocator.instance.dispose(cast(char[])binding.type); + + if(vertex.bindings)Mallocator.instance.dispose(vertex.bindings);*/ + } + } + + char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; + cpath[0..$-1] = path[0..$]; + cpath[$-1] = 0; + + SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r");//SDL_LoadFile(cpath.ptr,); + if(file) + { + size_t size = cast(size_t)SDL_RWsize(file); + //data.code = Mallocator.instance.makeArray!char(size); + //data.code[$-1] = 0; + char[] buffer = Mallocator.makeArray!char(size); + SDL_RWread(file,buffer.ptr,size,1); + + LoadData load_data; + scope(exit)load_data.dispose(); + + /*JSONSerializer serializer = Mallocator.make!JSONSerializer; + scope(exit)Mallocator.dispose(serializer); + serializer.serialize!(Load.yes, true)(load_data,buffer);*/ + + indices = Mallocator.makeArray(load_data.indices); + /*vertex.create(); + Vertex.Binding[] bindings = (cast(Vertex.Binding*)alloca(Vertex.Binding.sizeof*load_data.vertex.bindings.length))[0..load_data.vertex.bindings.length]; + uint vertex_size = 0; + uint alignment = 4; + foreach(i, binding;load_data.vertex.bindings) + { + uint new_size = binding.stride; + bindings[i].stride = binding.stride; + if(binding.type == "float_rg") + { + bindings[i].type = Vertex.Type.float_rg; + new_size += 8; + } + if(new_size > vertex_size)vertex_size = new_size; + //new_size = new_size + (3 - (new_size)%alignment) + } + vertex.data.size = vertex_size; + vertex.attachBindings(bindings);*/ + + vertices = Mallocator.makeArray(load_data.vertices); + /*vertices = Mallocator.instance.makeArray!ubyte(vertex_size * load_data.vertices.length); + { + foreach() + }*/ + + SDL_RWclose(file); + load_data.dispose(); + return true; + } + else return false; + } + + void uploadData() nothrow + { + vbo.create(); + vbo.bufferData(Buffer.BindTarget.array,16,cast(uint)vertices.length,GL_STATIC_DRAW,vertices.ptr); + + ibo.create(); + ibo.bufferData(Buffer.BindTarget.element_array,2,cast(uint)indices.length,GL_STATIC_DRAW,indices.ptr); + } + + void bind() nothrow + { + vbo.bind(Buffer.BindTarget.array); + ibo.bind(Buffer.BindTarget.element_array); + + glVertexAttribPointer(0,2,GL_FLOAT,false,16,null); + glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)8); + } + + float[] vertices; + ushort[] indices; + Buffer vbo; + Buffer ibo; + //Vertex vertex; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/mesh_module.d b/demos/utils/source/ecs_utils/gfx/mesh_module.d new file mode 100644 index 0000000..ecb4a3a --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/mesh_module.d @@ -0,0 +1,12 @@ +module ecs_utils.gfx.mesh_module; + +import ecs_utils.gfx.material; +import ecs_utils.gfx.texture; +import ecs_utils.gfx.mesh; + +struct MeshModule +{ + Mesh* mesh; + Material* material; + Texture texture; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/render_list.d b/demos/utils/source/ecs_utils/gfx/render_list.d new file mode 100644 index 0000000..f5ffabf --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/render_list.d @@ -0,0 +1,29 @@ +module ecs_utils.gfx.render_list; + +import ecs_utils.gfx.mesh_module; +import ecs_utils.math.vector; +import ecs_utils.math.matrix; +import ecs_utils.gfx.config; + +struct RenderList +{ + struct Data + { + MeshModule* module_; + uint index; + } + + struct LocScale + { + vec2 location; + vec2 scale; + } + + struct Layer + { + LayerType type; + Data[] list; + LocScale[] loc_scale; + mat3[] matrices; + } +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d new file mode 100644 index 0000000..6e7bd23 --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -0,0 +1,1135 @@ +module ecs_utils.gfx.renderer; + +import bindbc.sdl; + +import bubel.ecs.std; + +//import ecs_utils.core : Backend; +import ecs_utils.gfx.buffer; +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; + +import bubel.ecs.block_allocator; +import bubel.ecs.vector; +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +version = ver1; +/*version(ver5)version = vv2; +else version(ver6)version = vv2;*/ + +extern(C) float sinf(float); +extern(C) float cosf(float); + +enum RenderTechnique +{ + simple,//1 + simple_array,//2 + vbo_batch,//3 + instanced_attrib_divisor,//4 + uniform_buffer,//5 + uniform_buffer_indexed,//6 + uniform_buffer_multi_draw,//7 + uniform_buffer_instanced,//8 + uniform_buffer_instanced_mapped_gl2,//9 + uniform_buffer_instanced_mapped,//10 + uniform_buffer_instanced_persistent_mapped,//11 + uniform_buffer_instanced_persistent_mapped_coherent,//12 + ssbo_instanced,//13 + uniform_buffer_draw_indirect,//14 + uniform_buffer_multi_draw_indirect,//15 + uniform_buffer_multi_draw_indirect_arb_draw_parameters//16 +} + +struct Renderer +{ + //static SDL_Renderer* main_sdl_renderer; + BlockAllocator allocator; + + enum MaxObjects = 1024 * 64 * 4; + enum BufferUsage = GL_DYNAMIC_DRAW; + + //SDL_Window* sdl_window; + //SDL_Renderer* sdl_renderer; + ivec2 resolution; + vec2 dres; + vec4 sdl_transform; + vec2 view_pos = vec2(-1,-1); + vec2 view_size = vec2(1,1); + + enum block_size = 2^^16; + enum batch_size = block_size/68;//963;//16_384; + //uint[2] time_queries; + + struct VertexBlock + { + enum max_items = batch_size;//963; + byte[] batch_vertices; + ushort[] batch_indices; + void* memory = null; + uint items = 0; + uint material_id; + uint texture_id; + } + + Mutex* get_block_mutex; + Mutex* block_stack_mutex; + + VertexBlock getBlock() + { + VertexBlock block; + get_block_mutex.lock(); + block.memory = allocator.getBlock(); + get_block_mutex.unlock(); + block.batch_vertices = (cast(byte*)block.memory)[0 .. VertexBlock.max_items * 4 * 14]; + block.batch_indices = (cast(ushort*)block.memory)[VertexBlock.max_items * 4 * 7 .. VertexBlock.max_items * (4 * 7 + 6)]; + return block; + } + + Vector!VertexBlock blocks; + uint current_block = 0; + uint render_blocks = 0; + + void pushBlock(VertexBlock block) + { + block_stack_mutex.lock(); + prepared_items += block.items; + blocks.add(block); + render_blocks++; + block_stack_mutex.unlock(); + } + + bool isRemainingBlocks() + { + if(render_blocks <= current_block)return false; + return true; + } + + VertexBlock fetchBlock() + { + block_stack_mutex.lock(); + VertexBlock block = blocks[current_block]; + current_block++; + block_stack_mutex.unlock(); + return block; + } + + void freeBlocks() + { + /*block_stack_mutex.lock(); + render_blocks = 0; + current_block = 0; + foreach(VertexBlock block; blocks) + { + allocator.freeBlock(block.memory); + } + blocks.clear; + prepared_items=0; + draw_list.clear(); + block_stack_mutex.unlock();*/ + foreach(ref Thread thread; threads) + { + foreach(VertexBlock block; thread.filled_blocks) + { + allocator.freeBlock(block.memory); + } + thread.filled_blocks.clear(); + } + render_blocks = 0; + current_block = 0; + prepared_items = 0; + draw_list.clear(); + } + + void pushData() + { + foreach(ref Thread thread; threads) + { + foreach(VertexBlock block; thread.filled_blocks) + { + uint items = block.items; + if(items + item_id >= MaxObjects)items = MaxObjects - item_id; + batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); + batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); + draw_list.add(DrawCall(block.texture_id,block.material_id,item_id,items)); + item_id += items; + } + //thread.blocks.clear(); + } + //if(!isRemainingBlocks())return; + /* while(isRemainingBlocks()) + { + VertexBlock block = fetchBlock(); + uint items = block.items; + if(items + item_id >= MaxObjects)items = MaxObjects - item_id; + batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); + batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); + draw_list.add(DrawCall(item_id,items)); + item_id += items; + }*/ + } + + void pushThreadsBlocks() + { + foreach(i, ref Thread thread; threads) + { + //pushBlock(thread.block); + foreach(ref block; thread.blocks) + { + if(block.items > 0) + { + thread.filled_blocks.add(block); + block.items = 0; + } + } + //thread.blocks = getBlock(); + } + } + + struct DrawData + { + Texture texture; + vec2 position; + vec2 size; + vec4 coords; + short depth = 0; + uint color = uint.max; + float angle = 0; + uint material_id = 0; + uint mesh_id = 0; + uint thread_id = 0; + } + + struct Thread + { + //Vector!VertexBlock block; + RenderData[] render_list; + VertexBlock[] blocks; + Vector!VertexBlock filled_blocks; + } + Thread[] threads; + + + Buffer[2] ubos; + int block_alignment = 1; + int block_max_size = 16384; + + struct IndirectDraw + { + uint count = 6; + uint instances = 1; + uint first_index = 0; + uint base_vertex = 0; + uint base_instance = 0; + } + + Buffer[2] batch_vbo; + Buffer[2] batch_ibo; + + ubyte[] batch_vertices; + ushort[] batch_indices; + + Buffer indirect_buffer; + IndirectDraw[] indirect_block; + + Buffer id_buffer; + + int data_offset = 48; + int data_index; + ubyte[] uniform_block; + + struct RenderData + { + Texture texture; + uint material_id; + uint mesh_id; + } + + struct DrawCall + { + uint texture_id; + uint material_id; + uint start; + uint count; + } + + Vector!DrawCall draw_list; + + RenderData[] render_list; + uint item_id; + uint prepared_items; + + uint[] multi_count; + uint[] multi_offset; + + alias Technique = RenderTechnique; + + __gshared Technique technique = Technique.vbo_batch; + void* data_ptr; + + //import ecs_utils.core : RenderTechnique; + + + + void initialize() + { + import ecs_utils.gfx.config; + //this.technique = __ecs_used_technique; + __initialize(this); + + get_block_mutex = Mallocator.make!Mutex(); + block_stack_mutex = Mallocator.make!Mutex(); + get_block_mutex.initialize(); + block_stack_mutex.initialize(); + + + threads = Mallocator.makeArray!Thread(32); + foreach(ref Thread thread;threads) + { + //thread.blocks = getBlock(); + thread.blocks = Mallocator.makeArray!VertexBlock(GfxConfig.materials.length); + } + } + + private static void __initialize_gl(ref Renderer this_) + { + with(this_) + { + //glGenQueries(2, time_queries.ptr); + + version(WebAssembly) + { + + } + else + { + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &block_max_size); + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &block_alignment); + } + + //ubos[0].bufferStorage(1,64*MaxObjects,null); + + switch(technique) + { + case Technique.simple: + uniform_block = Mallocator.makeArray!ubyte(64*MaxObjects); + data_ptr = uniform_block.ptr; + data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment)); + break; + case Technique.simple_array: + goto case(Technique.simple); + case Technique.vbo_batch: + batch_vbo[0].create(); + batch_ibo[0].create(); + batch_vbo[0].bufferData(Buffer.BindTarget.array,14,4*MaxObjects,BufferUsage,null); + batch_ibo[0].bufferData(Buffer.BindTarget.element_array,2,6*MaxObjects,BufferUsage,null); + + batch_vbo[1].create(); + batch_ibo[1].create(); + batch_vbo[1].bufferData(Buffer.BindTarget.array,14,4*MaxObjects,BufferUsage,null); + batch_ibo[1].bufferData(Buffer.BindTarget.element_array,2,6*MaxObjects,BufferUsage,null); + + //batch_vertices = Mallocator.makeArray!ubyte(14*4*MaxObjects); + //batch_indices = Mallocator.makeArray!ushort(6*MaxObjects); + break; + case Technique.instanced_attrib_divisor: + goto case(Technique.uniform_buffer_indexed); + case Technique.uniform_buffer: + ubos[0].create(); + ubos[0].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); + ubos[1].create(); + ubos[1].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); + goto case(Technique.simple); + case Technique.uniform_buffer_indexed: + ubos[0].create(); + ubos[0].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); + ubos[1].create(); + ubos[1].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); + uniform_block = Mallocator.makeArray!ubyte(64*MaxObjects); + data_ptr = uniform_block.ptr; + break; + /*case Technique.uniform_buffer_multi_draw: + multi_count = Mallocator.makeArray!uint(992,6); + multi_offset = Mallocator.makeArray!uint(992,0); + + { + uint[] indices = Mallocator.makeArray!uint(992); + scope(exit)Mallocator.dispose(indices); + foreach(i;0..992)indices[i]=i; + id_buffer.create(); + id_buffer.bufferData(uint.sizeof,992,BufferUsage,indices.ptr); + } + goto case(Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters);*/ + case Technique.uniform_buffer_instanced: + goto case(Technique.uniform_buffer_indexed); + case Technique.uniform_buffer_instanced_mapped_gl2: + ubos[0].create(); + ubos[0].bufferData(Buffer.BindTarget.uniform,1,512*MaxObjects,BufferUsage,null); + ubos[0].map(Buffer.BindTarget.uniform); + ubos[1].create(); + ubos[1].bufferData(Buffer.BindTarget.uniform,1,512*MaxObjects,BufferUsage,null); + ubos[1].map(Buffer.BindTarget.uniform); + data_ptr = ubos[0].mappedPointer(); + break; + case Technique.uniform_buffer_instanced_mapped: + ubos[0].create(); + ubos[0].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); + ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); + ubos[1].create(); + ubos[1].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); + ubos[1].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); + data_ptr = ubos[0].mappedPointer(); + break; + /*case Technique.uniform_buffer_instanced_persistent_mapped: + ubos[0].create(); + ubos[0].bufferStorage(1,64*MaxObjects,null,Buffer.StorageFlagBits.write|Buffer.StorageFlagBits.persistent); + ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform, Buffer.MapFlagBits.write | Buffer.MapFlagBits.persistent | Buffer.MapFlagBits.flush_explict); + data_ptr = ubos[0].mappedPointer(); + break; + case Technique.uniform_buffer_instanced_persistent_mapped_coherent: + ubos[0].create(); + ubos[0].bufferStorage(1,64*MaxObjects,null,Buffer.StorageFlagBits.write|Buffer.StorageFlagBits.persistent|Buffer.StorageFlagBits.coherent); + ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform, Buffer.MapFlagBits.write | Buffer.MapFlagBits.persistent | Buffer.MapFlagBits.flush_explict | Buffer.MapFlagBits.coherent); + ubos[1].create(); + ubos[1].bufferStorage(1,64*MaxObjects,null,Buffer.StorageFlagBits.write|Buffer.StorageFlagBits.persistent|Buffer.StorageFlagBits.coherent); + ubos[1].map(0, 64*MaxObjects, Buffer.BindTarget.uniform, Buffer.MapFlagBits.write | Buffer.MapFlagBits.persistent | Buffer.MapFlagBits.flush_explict | Buffer.MapFlagBits.coherent); + data_ptr = ubos[0].mappedPointer(); + break; + case Technique.ssbo_instanced: + goto case(Technique.uniform_buffer_indexed); + case Technique.uniform_buffer_draw_indirect: + indirect_block = Mallocator.makeArray!IndirectDraw(1); + indirect_buffer.create(); + indirect_buffer.bufferData(IndirectDraw.sizeof,1,BufferUsage,indirect_block.ptr); + indirect_buffer.bind(Buffer.BindTarget.indirect); + goto case(Technique.uniform_buffer); + case Technique.uniform_buffer_multi_draw_indirect: + goto case(Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters); + case Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: + indirect_block = Mallocator.makeArray!IndirectDraw(992); + foreach(i;0..992) + { + IndirectDraw* idraw = &indirect_block[i]; + idraw.base_instance = i; + } + indirect_buffer.create(); + indirect_buffer.bufferData(IndirectDraw.sizeof,992,BufferUsage,indirect_block.ptr); + indirect_buffer.bind(Buffer.BindTarget.indirect); + goto case(Technique.uniform_buffer_indexed);*/ + default:break; + }//*/ + + // if(batching)data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment)); + //data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment)); + + /*version(ver4){} + else version(ver5){} + else version(ver6){} + else data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment));//*/ + //data_offset = (data_offset + block_alignment - 1) - data_offset % block_alignment; + + render_list = Mallocator.makeArray!RenderData(MaxObjects); + + SDL_Log("Uniform block alignment: %u",block_alignment); + SDL_Log("Uniform block max size: %u",block_max_size); + SDL_Log("Data offset: %u",data_offset); + + allocator = BlockAllocator(block_size, 32); + } + } + + private static void __initialize_sdl(ref Renderer this_) + { + + } + + //void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) + void draw(scope ref const(DrawData) data) + { + if(prepared_items >= MaxObjects)return; + if(threads[data.thread_id].blocks.length <= data.material_id)return; + __draw(this,data);//tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id); + } + + //private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) + private static void __draw_sdl(ref Renderer this_, scope ref const(DrawData) data) + { + /*with(this_) + { + SDL_Rect rect = SDL_Rect(cast(int)(coords.x*tex.data.size.x),cast(int)(coords.y*tex.data.size.y),cast(int)(coords.z*tex.data.size.x),cast(int)(coords.w*tex.data.size.y)); + SDL_Rect rect2 = SDL_Rect(cast(int)((pos.x-size.x*0.5)), + cast(int)(resolution.y - pos.y - size.y*0.5), + cast(int)(size.x), + cast(int)(size.y)); + + SDL_RenderCopyEx(sdl_renderer, + tex.data.texture, + &rect, + &rect2, + angle*360, + null, + SDL_FLIP_NONE); + }*/ + } + + // private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) + private static void __draw_gl(ref Renderer this_, scope ref const(DrawData) data) + { + //import core.stdc.string; + with(this_) + { + //pos += view_pos; + vec2 pos = void; + vec2 size = void; + size.x = data.size.x * view_size.x; + size.y = data.size.y * view_size.y; + pos.x = data.position.x * view_size.x + view_pos.x; + pos.y = data.position.y * view_size.y + view_pos.y;//*/ + + /*version(ver6)void* ptr = ubos[0].mappedPointer() + data_index; + else void* ptr = uniform_block.ptr + data_index;*/ + if(data_ptr is null)return; + void* ptr = data_ptr + data_index; + if(data.angle == 0) + { + *cast(float*)ptr = size.x; + *cast(float*)(ptr+4) = 0; + *cast(float*)(ptr+8) = 0; + *cast(float*)(ptr+12) = size.y; + } + else + { + //import core.stdc.math; + float sinn = sinf(data.angle); + float coss = cosf(data.angle); + *cast(float*)ptr = coss * size.x; + *cast(float*)(ptr+4) = -sinn * size.y; + *cast(float*)(ptr+8) = sinn * size.x; + *cast(float*)(ptr+12) = coss * size.y; + } + + //memcpy(ptr,); + memcpy(ptr+16,pos.data.ptr,8); + memcpy(ptr+32,data.coords.data.ptr,16); + + //render_list[item_id] = RenderData(tex,material_id,mesh_id); + render_list[item_id].texture = *cast(Texture*)&data.texture; + render_list[item_id].material_id = data.material_id; + render_list[item_id].mesh_id = data.mesh_id; + + data_index += data_offset; + item_id++; + prepared_items++; + } + } + + // private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) + private static void __draw_gl_vbo_batch(ref Renderer this_, scope ref const(DrawData) data) + { + import ecs_utils.gfx.config; + + //import core.stdc.string; + with(this_) + { + uint thread_id = data.thread_id; + //if(item_id >= MaxObjects)return; + //pos += view_pos; + Thread* thread = &threads[thread_id]; + VertexBlock* block; + assert(thread.blocks.length > data.material_id); + block = &thread.blocks[data.material_id]; + if(block.items == 0) + { + thread.blocks[data.material_id] = getBlock(); + block = &thread.blocks[data.material_id]; + block.material_id = data.material_id; + } + else if(block.items >= VertexBlock.max_items) + { + //pushBlock(thread.block); + prepared_items += block.items; + thread.filled_blocks.add(*block); + thread.blocks[data.material_id] = getBlock(); + block = &thread.blocks[data.material_id]; + block.material_id = data.material_id; + } + + short[3] mem = [data.depth, *cast(short*)&data.color, *(cast(short*)&data.color + 1)]; + + vec2 pos = void; + vec2 size = void; + pos.x = data.position.x * view_size.x + view_pos.x; + pos.y = data.position.y * view_size.y + view_pos.y;//*/ + + /*void* ptr = data_ptr + data_index; + *cast(float*)ptr = size.x; + *cast(float*)(ptr+4) = 0; + *cast(float*)(ptr+8) = 0; + *cast(float*)(ptr+12) = size.y; + //memcpy(ptr,); + memcpy(ptr+16,pos.data.ptr,8); + memcpy(ptr+32,coords.data.ptr,16);*/ + + short[] verts = (cast(short*)block.batch_vertices.ptr)[0..block.batch_vertices.length>>1]; + uint item_id = block.items; + + uint mesh_id = data.mesh_id; + vec4 coords = data.coords; + + if(data.angle == 0) + { + size.x = data.size.x * view_size.x; + size.y = data.size.y * view_size.y; + + verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191); + verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191); + verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); + verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+4,mem.ptr,6); + + + verts[item_id*28+7] = cast(short)((GfxConfig.meshes[mesh_id].vertices[4] * size.x + pos.x) * 8191); + verts[item_id*28+8] = cast(short)((GfxConfig.meshes[mesh_id].vertices[5] * size.y + pos.y) * 8191); + verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); + verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+11,mem.ptr,6); + + + verts[item_id*28+14] = cast(short)((GfxConfig.meshes[mesh_id].vertices[8] * size.x + pos.x) * 8191); + verts[item_id*28+15] = cast(short)((GfxConfig.meshes[mesh_id].vertices[9] * size.y + pos.y) * 8191); + verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); + verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+18,mem.ptr,6); + + + verts[item_id*28+21] = cast(short)((GfxConfig.meshes[mesh_id].vertices[12] * size.x + pos.x) * 8191); + verts[item_id*28+22] = cast(short)((GfxConfig.meshes[mesh_id].vertices[13] * size.y + pos.y) * 8191); + verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); + verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+25,mem.ptr,6); + } + else + { + //import core.stdc.math; + float angle = data.angle; + float sinx = sinf(angle) * data.size.x * view_size.y; + float cosx = cosf(angle) * data.size.x * view_size.x; + float siny = sinf(angle) * data.size.y * view_size.x; + float cosy = cosf(angle) * data.size.y * view_size.y; + + /*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x; + batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y; + batch_vertices[item_id*28+4] = GfxConfig.meshes[mesh_id].vertices[4] * size.x; + batch_vertices[item_id*28+5] = GfxConfig.meshes[mesh_id].vertices[5] * size.y; + batch_vertices[item_id*28+8] = GfxConfig.meshes[mesh_id].vertices[8] * size.x; + batch_vertices[item_id*28+9] = GfxConfig.meshes[mesh_id].vertices[9] * size.y; + batch_vertices[item_id*28+12] = GfxConfig.meshes[mesh_id].vertices[12] * size.x; + batch_vertices[item_id*28+13] = GfxConfig.meshes[mesh_id].vertices[13] * size.y;*/ + + verts[item_id*28] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[0] * cosx + GfxConfig.meshes[mesh_id].vertices[1] * siny) + pos.x) * 8191); + verts[item_id*28+1] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[1] * cosy - GfxConfig.meshes[mesh_id].vertices[0] * sinx) + pos.y) * 8191); + verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); + verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+4,mem.ptr,6); + + + verts[item_id*28+7] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[4] * cosx + GfxConfig.meshes[mesh_id].vertices[5] * siny) + pos.x) * 8191); + verts[item_id*28+8] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[5] * cosy - GfxConfig.meshes[mesh_id].vertices[4] * sinx) + pos.y) * 8191); + verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); + verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+11,mem.ptr,6); + + + verts[item_id*28+14] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[8] * cosx + GfxConfig.meshes[mesh_id].vertices[9] * siny) + pos.x) * 8191); + verts[item_id*28+15] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[9] * cosy - GfxConfig.meshes[mesh_id].vertices[8] * sinx) + pos.y) * 8191); + verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); + verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+18,mem.ptr,6); + + + verts[item_id*28+21] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[12] * cosx + GfxConfig.meshes[mesh_id].vertices[13] * siny) + pos.x) * 8191); + verts[item_id*28+22] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[13] * cosy - GfxConfig.meshes[mesh_id].vertices[12] * sinx) + pos.y) * 8191); + verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); + verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+25,mem.ptr,6); + } + + /*verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); + verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); + verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); + verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); + verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); + verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); + verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); + verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767);*/ + + /*verts[item_id*28+4] = depth; + verts[item_id*28+11] = depth; + verts[item_id*28+18] = depth; + verts[item_id*28+25] = depth; + + *cast(uint*)&verts[item_id*28+5] = color; + *cast(uint*)&verts[item_id*28+12] = color; + *cast(uint*)&verts[item_id*28+19] = color; + *cast(uint*)&verts[item_id*28+26] = color; + + memcpy(verts.ptr+item_id*28+4,mem.ptr,6); + memcpy(verts.ptr+item_id*28+11,mem.ptr,6); + memcpy(verts.ptr+item_id*28+18,mem.ptr,6); + memcpy(verts.ptr+item_id*28+25,mem.ptr,6);*/ + + uint ind_id = (item_id % batch_size)*4; + + ushort[] indices = block.batch_indices; + + indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id); + indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id); + indices[item_id*6+2] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[2] + ind_id); + indices[item_id*6+3] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[3] + ind_id); + indices[item_id*6+4] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[4] + ind_id); + indices[item_id*6+5] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[5] + ind_id); + + //render_list[item_id] = RenderData(tex,material_id,mesh_id); + //render_list[item_id].texture = tex; + //render_list[item_id].material_id = material_id; + //render_list[item_id].mesh_id = mesh_id; + + //data_index += 1;//data_offset; + block.items++; + } + } + + void clear() + { + __clear(this); + } + + private static void __clear_sdl(ref Renderer this_) + { + //SDL_RenderClear(this_.sdl_renderer); + } + + private static void __clear_gl(ref Renderer this_) + { + glClearColor(0,0,0,0); + glViewport(0,0,this_.resolution.x,this_.resolution.y); + glDepthMask(1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //glDisable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDepthFunc(GL_LESS); + + version(WebAssembly) + { + glDepthRangef(0,1); + } + else version(Android) + { + glDepthRangef(0,1); + } + else + { + glDepthRange(0,1); + } + //glDepthRange(0,1); + //glClearDepth(1); + } + + void present() + { + __present(this); + } + + private static void __present_sdl(ref Renderer this_) + { + //+SDL_RenderPresent(this_.sdl_renderer); + } + + private static void __present_gl(ref Renderer this_) + { + + this_.pushThreadsBlocks(); + this_.pushData(); + + glViewport(0,0,this_.resolution.x,this_.resolution.y); + //glEnable(GL_ALPHA_TEST); + //glAlphaFunc(GL_GREATER, 0.01); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + import ecs_utils.gfx.config; + with(this_) + { + bool instanced = false; + bool indirect = false; + bool multi_draw = false; + Buffer.BindTarget buffer_target = Buffer.BindTarget.uniform; + + switch(technique) + { + case Technique.simple: + break; + case Technique.simple_array: + break; + case Technique.vbo_batch: + //if(data_index){ + //batch_vbo[0].bufferSubData(Buffer.BindTarget.array,item_id*4*14,0,batch_vertices.ptr); + //batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,item_id*6*2,0,batch_indices.ptr); + + batch_vbo[0].bind(Buffer.BindTarget.array); + batch_ibo[0].bind(Buffer.BindTarget.element_array); + + //glVertexAttribPointer(0,2,GL_SHORT,true,14,null); + //glVertexAttribPointer(1,2,GL_SHORT,true,14,cast(void*)4);//} + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + //glVertexAttribPointer(2,1,GL_SHORT,true,14,cast(void*)6);//} + break; + case Technique.instanced_attrib_divisor: + ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); + ubos[0].bind(Buffer.BindTarget.uniform); + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); + + glVertexAttribPointer(2,4,GL_FLOAT,false,48,null); + glVertexAttribPointer(3,4,GL_FLOAT,false,48,cast(void*)16); + glVertexAttribPointer(4,4,GL_FLOAT,false,48,cast(void*)32); + glVertexAttribDivisor(2,1); + glVertexAttribDivisor(3,1); + glVertexAttribDivisor(4,1); + //ubos[0].bindRange(Buffer.BindTarget.uniform,0,0,block_max_size); + break; + case Technique.uniform_buffer: + //ubos[0].bufferData(1,64*MaxObjects,BufferUsage,null); + /*if(data_index)*/ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); + break; + case Technique.uniform_buffer_indexed: + ubos[0].bindRange(Buffer.BindTarget.uniform,0,0,block_max_size); + goto case(Technique.uniform_buffer); + case Technique.uniform_buffer_multi_draw: + id_buffer.bind(Buffer.BindTarget.array); + glEnableVertexAttribArray(2); + + glVertexAttribIPointer(2,1,GL_UNSIGNED_INT,cast(uint)uint.sizeof,cast(void*)0); + glVertexAttribDivisor(2,1); + multi_draw = true; + goto case(Technique.uniform_buffer_instanced); + case Technique.uniform_buffer_instanced: + instanced = true; + goto case(Technique.uniform_buffer); + case Technique.uniform_buffer_instanced_mapped_gl2: + instanced = true; + ubos[0].unmap(Buffer.BindTarget.uniform); + break; + case Technique.uniform_buffer_instanced_mapped: + instanced = true; + ubos[0].flush(0,data_index,Buffer.BindTarget.uniform); + ubos[0].unmap(Buffer.BindTarget.uniform); + break; + /*case Technique.uniform_buffer_instanced_persistent_mapped: + instanced = true; + ubos[0].flush(0,data_index,Buffer.BindTarget.uniform); + //glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); + break; + case Technique.uniform_buffer_instanced_persistent_mapped_coherent: + instanced = true; + break; + //ubos[0].flush(0,data_index,Buffer.BindTarget.uniform); + //goto case(Technique.uniform_buffer_instanced_mapped); + case Technique.ssbo_instanced: + //buffer_target = Buffer.BindTarget.shader_storage; + ubos[0].bindRange(Buffer.BindTarget.shader_storage,0,0,48*MaxObjects); + goto case(Technique.uniform_buffer_instanced); + case Technique.uniform_buffer_draw_indirect: + goto case(Technique.uniform_buffer); + case Technique.uniform_buffer_multi_draw_indirect: + indirect_buffer.bind(Buffer.BindTarget.array); + glEnableVertexAttribArray(2); + + glVertexAttribIPointer(2,1,GL_UNSIGNED_INT,cast(uint)IndirectDraw.sizeof,cast(void*)(4*uint.sizeof)); + glVertexAttribDivisor(2,1); + goto case(Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters); + case Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: + indirect = true; + goto case(Technique.uniform_buffer_instanced);*/ + default:break; + } + + data_index = 0; + + int mesh_id = -1; + int material_id = -1; + int ubo_start = -1; + Texture texture; + uint item_ubo_id = 0; + + /*Buffer tmpb = ubos[0]; + ubos[0] = ubos[1]; + ubos[1] = tmpb; + + tmpb = batch_vbo[0]; + batch_vbo[0] = batch_vbo[1]; + batch_vbo[1] = tmpb; + + tmpb = batch_ibo[0]; + batch_ibo[0] = batch_ibo[1]; + batch_ibo[1] = tmpb;//*/ + //glFinish(); + + //glBeginQuery(GL_TIME_ELAPSED, time_queries[0]); + if(technique == Technique.vbo_batch) + { + //uint items = item_id/batch_size+1; + foreach(i; 0..draw_list.length) + { + if(material_id != draw_list[i].material_id) + { + material_id = draw_list[i].material_id; + GfxConfig.materials[material_id].bind(); + float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1]; + GfxConfig.materials[material_id].pushUniforms(data.ptr); + } + if(texture.data != render_list[i].texture.data) + { + texture.data = render_list[i].texture.data; + render_list[i].texture.bind(); + } + + /*uint instance_count = batch_size; + if((i+1)*batch_size > item_id) + { + instance_count = item_id%batch_size; + }*/ + + // glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16)); + // glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16+8)); + glVertexAttribPointer(0,2,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14)); + glVertexAttribPointer(1,2,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14+4)); + glVertexAttribPointer(2,1,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14+8)); + glVertexAttribPointer(3,4,GL_UNSIGNED_BYTE,true,14,cast(void*)(draw_list[i].start*4*14+10)); + + glDrawElements(GL_TRIANGLES,draw_list[i].count*6,GL_UNSIGNED_SHORT,cast(void*)(draw_list[i].start*6*2)); + + //glDrawElementsBaseVertex(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2),i*16_384*4); + } + } + else if(technique == Technique.ssbo_instanced || technique == Technique.instanced_attrib_divisor) + { + if(mesh_id != render_list[0].mesh_id) + { + mesh_id = render_list[0].mesh_id; + GfxConfig.meshes[mesh_id].bind(); + } + if(material_id != render_list[0].material_id) + { + material_id = render_list[0].material_id; + GfxConfig.materials[material_id].bind(); + } + if(texture.data != render_list[0].texture.data) + { + texture.data = render_list[0].texture.data; + render_list[0].texture.bind(); + } + glDrawArraysInstanced(GL_TRIANGLE_STRIP,0,4,item_id); + //glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null,item_id); + } + else if(instanced) + { + uint items = item_id/992+1; + foreach(i; 0..items) + { + if(mesh_id != render_list[i].mesh_id) + { + mesh_id = render_list[i].mesh_id; + GfxConfig.meshes[mesh_id].bind(); + } + if(material_id != render_list[i].material_id) + { + material_id = render_list[i].material_id; + GfxConfig.materials[material_id].bind(); + } + if(texture.data != render_list[i].texture.data) + { + texture.data = render_list[0].texture.data; + render_list[i].texture.bind(); + } + ubos[0].bindRange(buffer_target,0,data_index,block_max_size); + + uint instance_count = 992; + if(i*992 > item_id) + { + instance_count = i*992 - item_id; + } + + /*if(indirect)glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, cast(void*)0, instance_count, 0); + else if(multi_draw)glMultiDrawElements(GL_TRIANGLES,cast(int*)multi_count.ptr,GL_UNSIGNED_SHORT,cast(void**)multi_offset.ptr,instance_count); + //glMultiDrawElementsBaseVertex(GL_TRIANGLES,cast(int*)multi_count.ptr,GL_UNSIGNED_SHORT,cast(void**)multi_offset.ptr,instance_count,cast(int*)multi_offset.ptr); + else */glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null,instance_count); + //glDrawArraysInstanced(GL_TRIANGLES,0,6,instance_count); + data_index += data_offset * 992; + } + } + else + foreach(item; render_list[0..item_id]) + { + if(mesh_id != item.mesh_id) + { + mesh_id = item.mesh_id; + GfxConfig.meshes[mesh_id].bind(); + } + if(material_id != item.material_id) + { + material_id = item.material_id; + GfxConfig.materials[material_id].bind(); + GfxConfig.materials[material_id].pushBindings(); + } + if(texture.data != item.texture.data) + { + texture.data = render_list[0].texture.data; + item.texture.bind(); + } + + switch(technique) + { + case Technique.simple: + /*glUniform4f(0, *cast(float*)&uniform_block[data_index], *cast(float*)&uniform_block[data_index+4], *cast(float*)&uniform_block[data_index+8], *cast(float*)&uniform_block[data_index+12]); + glUniform4f(1, *cast(float*)&uniform_block[data_index+16], *cast(float*)&uniform_block[data_index+20], *cast(float*)&uniform_block[data_index+24], *cast(float*)&uniform_block[data_index+28]); + glUniform4f(2, *cast(float*)&uniform_block[data_index+32], *cast(float*)&uniform_block[data_index+36], *cast(float*)&uniform_block[data_index+40], *cast(float*)&uniform_block[data_index+44]); + */ + GfxConfig.materials[material_id].pushUniforms(&uniform_block[data_index]);break; + case Technique.simple_array: + glUniform4fv(0,12,cast(float*)(uniform_block.ptr+data_index)); + break; + case Technique.uniform_buffer: + ubos[0].bindRange(Buffer.BindTarget.uniform,0,data_index,data_offset); + break; + /*case Technique.uniform_buffer_draw_indirect: + ubos[0].bindRange(Buffer.BindTarget.uniform,0,data_index,data_offset); + glDrawElementsIndirect(GL_TRIANGLES,GL_UNSIGNED_SHORT,null); + data_index += data_offset; + continue;*/ + case Technique.uniform_buffer_indexed: + if(item_ubo_id >= 992) + { + item_ubo_id = 0; + ubo_start = data_index; + ubos[0].bindRange(Buffer.BindTarget.uniform,0,ubo_start,block_max_size); + } + glUniform1i(0,item_ubo_id++); + break; + default:break; + }//*/ + + /*version(ver3)ubos[0].bindRange(Buffer.BindTarget.uniform,0,data_index,data_offset); + else version(ver1) + { + glUniform4f(0, *cast(float*)&uniform_block[data_index], *cast(float*)&uniform_block[data_index+4], *cast(float*)&uniform_block[data_index+8], *cast(float*)&uniform_block[data_index+12]); + glUniform4f(1, *cast(float*)&uniform_block[data_index+16], *cast(float*)&uniform_block[data_index+20], *cast(float*)&uniform_block[data_index+24], *cast(float*)&uniform_block[data_index+28]); + glUniform4f(2, *cast(float*)&uniform_block[data_index+32], *cast(float*)&uniform_block[data_index+36], *cast(float*)&uniform_block[data_index+40], *cast(float*)&uniform_block[data_index+44]); + } + else version(ver2)glUniform4fv(0,12,cast(float*)(uniform_block.ptr+data_index)); + else version(ver4) + { + if(item_ubo_id >= 992) + { + item_ubo_id = 0; + ubo_start = data_index; + ubos[0].bindRange(Buffer.BindTarget.uniform,0,ubo_start,block_max_size); + } + glUniform1i(0,item_ubo_id++); + }//*/ + + glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null); + //glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + data_index += data_offset; + } + //glEndQuery(GL_TIME_ELAPSED); + //uint tmpq = time_queries[0]; + //time_queries[0] = time_queries[1]; + //time_queries[1] = tmpq; + /*Buffer tmpb = ubos[0]; + ubos[0] = ubos[1]; + ubos[1] = tmpb;//*/ + + data_index = 0; + //data_offset = 0; + item_id = 0; + //SDL_GL_SwapWindow(sdl_window); + //glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); + //version(ver6)ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); + //ubos[0].map(Buffer.BindTarget.uniform); + + switch(technique) + { + case Technique.uniform_buffer_instanced_mapped_gl2: + ubos[0].map(Buffer.BindTarget.uniform); + //data_ptr = ubos[0].mappedPointer(); + break; + case Technique.uniform_buffer_instanced_mapped: + ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); + //data_ptr = ubos[0].mappedPointer(); + break; + default:break; + } + + if(ubos[0].data && ubos[0].mappedPointer) + { + data_ptr = ubos[0].mappedPointer; + } + + /*switch(technique) + { + case Technique.simple: + case Technique.simple_array: + case Technique.uniform_buffer: + case Technique.uniform_buffer_indexed: + case Technique.uniform_buffer_instanced: + case Technique.uniform_buffer_instanced_mapped: + case Technique.uniform_buffer_instanced_persistent_mapped: + default:break; + }*/ + } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(3); + this_.freeBlocks(); + /*glUseProgram(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/ + //glDisable(GL_ALPHA_TEST); + } + + void resize(ivec2 size) + { + resolution = size; + dres = vec2(1.0/cast(float)size.x,1.0/cast(float)size.y); + } + + void view(vec2 pos, vec2 size) + { + //view_pos = pos * size - 1; + view_size = vec2(2/size.x,2/size.y); + sdl_transform = vec4(0,0,1.0/size.x,1.0/size.y); + view_pos = (pos - size * 0.5) * view_size; + } + + // __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw; + __gshared void function(ref Renderer this_, scope ref const(DrawData) data) __draw; + __gshared void function(ref Renderer this_) __present; + __gshared void function(ref Renderer this_) __clear; + __gshared void function(ref Renderer this_) __initialize; + + static void __loadBackend() + { + //this.technique = __ecs_used_technique; + if(technique == Technique.vbo_batch)__draw = &__draw_gl_vbo_batch; + else __draw = &__draw_gl; + __present = &__present_gl; + __clear = &__clear_gl; + __initialize = &__initialize_gl; + } + +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/shader.d b/demos/utils/source/ecs_utils/gfx/shader.d new file mode 100644 index 0000000..c3d656a --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/shader.d @@ -0,0 +1,180 @@ +module ecs_utils.gfx.shader; + +import bindbc.sdl; + +import bubel.ecs.std; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +//version = ver1; + +struct Shader +{ + + void create() nothrow + { + data = Mallocator.make!Data; + } + + bool load(const char[] path) nothrow + { + if(data is null)data = Mallocator.make!Data; + + char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; + cpath[0..$-1] = path[0..$]; + cpath[$-1] = 0; + + int ind = cast(int)path.length - 1; + for(;ind>0;ind--) + { + if(path[ind] == '.')break; + } + if(ind < 0)return false; + ind++; + if(ind + 2 > path.length)return false; + + char[2] ext = path[ind .. ind + 2]; + if(ext[0] == 'v' && ext[1] == 'p')data.type = Type.vertex; + else if(ext[0] == 'f' && ext[1] == 'p')data.type = Type.fragment; + else return false; + + SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r");//SDL_LoadFile(cpath.ptr,); + if(file) + { + size_t size = cast(size_t)SDL_RWsize(file); + data.code = Mallocator.makeArray!char(size+1); + data.code[$-1] = 0; + SDL_RWread(file,data.code.ptr,size,1); + + SDL_RWclose(file); + return true; + } + else return false; + + } + + bool compile() nothrow + { + switch(data.type) + { + case Type.vertex: + data.gl_handle = glCreateShader(GL_VERTEX_SHADER); + break; + case Type.fragment: + data.gl_handle = glCreateShader(GL_FRAGMENT_SHADER); + break; + default: return false; + } + + version(WebAssembly)const char* glsl = "#version 100\n"; + else version(Android)const char* glsl = "#version 100\n"; + else const char* glsl = "#version 120\n"; + const char* buffer = data.code.ptr; + char* ver; + version(WebAssembly)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; + else version(Android)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; + else ver = cast(char*)"#define ver1 1\n".ptr; + /*switch(__ecs_used_technique) + { + case RenderTechnique.simple: + ver = cast(char*)"#define ver1 1\n".ptr; + break; + case RenderTechnique.simple_array: + ver = cast(char*)"#define ver2 1\n".ptr; + break; + case RenderTechnique.vbo_batch: + ver = cast(char*)"#define ver10 1\n".ptr; + break; + case RenderTechnique.instanced_attrib_divisor: + ver = cast(char*)"#define ver8 1\n".ptr; + break; + case RenderTechnique.uniform_buffer: + ver = cast(char*)"#define ver3 1\n".ptr; + break; + case RenderTechnique.uniform_buffer_indexed: + ver = cast(char*)"#define ver4 1\n".ptr; + break; + case RenderTechnique.uniform_buffer_multi_draw: + goto case(RenderTechnique.uniform_buffer_multi_draw_indirect); + case RenderTechnique.uniform_buffer_instanced: + ver = cast(char*)"#define ver5 1\n".ptr; + break; + case RenderTechnique.uniform_buffer_instanced_mapped_gl2: + goto case(RenderTechnique.uniform_buffer_instanced); + case RenderTechnique.uniform_buffer_instanced_mapped: + goto case(RenderTechnique.uniform_buffer_instanced); + case RenderTechnique.uniform_buffer_instanced_persistent_mapped: + goto case(RenderTechnique.uniform_buffer_instanced); + case RenderTechnique.uniform_buffer_instanced_persistent_mapped_coherent: + goto case(RenderTechnique.uniform_buffer_instanced); + case RenderTechnique.ssbo_instanced: + ver = cast(char*)"#define ver6 1\n".ptr; + break; + case RenderTechnique.uniform_buffer_draw_indirect: + goto case(RenderTechnique.uniform_buffer); + case RenderTechnique.uniform_buffer_multi_draw_indirect: + ver = cast(char*)"#define ver9 1\n".ptr; + break; + case RenderTechnique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: + ver = cast(char*)"#define ver7 1\n".ptr; + break; + default:break; + }*/ + /*version(ver1)const char* ver = "#define ver1 1\n"; + version(ver2)const char* ver = "#define ver2 1\n"; + version(ver3)const char* ver = "#define ver3 1\n"; + version(ver4)const char* ver = "#define ver4 1\n"; + version(ver5)const char* ver = "#define ver5 1\n"; + version(ver6)const char* ver = "#define ver5 1\n";*/ + + const char*[3] input = [glsl,ver,buffer]; + + glShaderSource(data.gl_handle,3,input.ptr,null); + + glCompileShader(data.gl_handle); + + int compile; + glGetShaderiv(data.gl_handle,GL_COMPILE_STATUS,&compile); + if(compile == GL_FALSE) + { + SDL_Log("Shader compile error! %u %s",data.type,glsl); + char[256] log; + int log_len; + glGetShaderInfoLog(data.gl_handle, 256, &log_len, log.ptr); + import ecs_utils.utils; + if(log_len)printf("%s",log.ptr); + return false; + } + + return true; + } + + void destroy() nothrow + { + if(data) + { + if(data.gl_handle)glDeleteShader(data.gl_handle); + Mallocator.dispose(data); + data = null; + } + } + + enum Type + { + vertex, + fragment, + geometry + } + + struct Data + { + char[] code; + Type type; + + uint gl_handle; + } + + Data* data; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/sprite.d b/demos/utils/source/ecs_utils/gfx/sprite.d new file mode 100644 index 0000000..06c0804 --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/sprite.d @@ -0,0 +1,11 @@ +module ecs_utils.gfx.sprite; + +import ecs_utils.math.matrix; +import ecs_utils.gfx.mesh_module; + +struct sprite +{ + MeshModule* mesh; + + mat3 matrix; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/texture.d b/demos/utils/source/ecs_utils/gfx/texture.d new file mode 100644 index 0000000..73e9a54 --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/texture.d @@ -0,0 +1,125 @@ +module ecs_utils.gfx.texture; + +import bindbc.sdl; + +import bubel.ecs.std; + +import ecs_utils.math.vector; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +extern(C): + +struct Texture +{ + + void create() + { + data = Mallocator.make!Data; + } + + bool load(const char[] path) + { + char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; + cpath[0..$-1] = path[0..$]; + cpath[$-1] = 0; + + return __load(this, cpath); + } + + /*static bool __load_sdl(ref Texture this_, const char[] path) + { + import ecs_utils.gfx.renderer; + SDL_Surface* surf = IMG_Load(path.ptr); + if(!surf)return false; + + this_.data.size = ivec2(surf.w,surf.h); + + this_.data.texture = SDL_CreateTextureFromSurface(Renderer.main_sdl_renderer,surf); + if(!this_.data.texture)return false; + //this_.data.texture = surf; + + return true; + }*/ + + static bool __load_gl(ref Texture this_, const char[] path) + { + SDL_Surface* surf = IMG_Load(path.ptr); + if(!surf)return false; + + with(this_) + { + data.size = ivec2(surf.w,surf.h); + data.bpp = surf.format.BytesPerPixel; + data.data = Mallocator.makeArray!ubyte(surf.w*surf.h*surf.format.BytesPerPixel); + data.data[0..$] = (cast(ubyte*)surf.pixels)[0..data.data.length]; + data.size = ivec2(surf.w, surf.h); + + SDL_FreeSurface(surf); + + glGenTextures(1, &data.gl_handle); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,data.gl_handle); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + if(data.bpp == 3)glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,data.size.x,data.size.y,0,GL_RGB,GL_UNSIGNED_BYTE,data.data.ptr); + else if(data.bpp == 4)glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,data.size.x,data.size.y,0,GL_RGBA,GL_UNSIGNED_BYTE,data.data.ptr); + else return false; + } + + + return true; + } + + void bind() + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, data.gl_handle); + } + + void destroy() @nogc nothrow + { + if(data) + { + glDeleteTextures(1, &data.gl_handle); + if(data.data)Mallocator.dispose(data.data); + Mallocator.dispose(data); + data = null; + } + } + + __gshared bool function(ref Texture this_, const char[] path) __load; + + struct Data + { + ubyte[] data; + + ivec2 size; + uint bpp; + + union + { + SDL_Texture* texture; + uint gl_handle; + } + } + + static void __loadBackend() + { + __load = &__load_gl; + /*switch(backend) + { + case Backend.opengl:__load = &__load_gl;break; + case Backend.sdl:__load = &__load_sdl;break; + default:goto case(Backend.opengl); + }*/ + } + + Data* data; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/vertex.d b/demos/utils/source/ecs_utils/gfx/vertex.d new file mode 100644 index 0000000..b63803c --- /dev/null +++ b/demos/utils/source/ecs_utils/gfx/vertex.d @@ -0,0 +1,64 @@ +module ecs_utils.gfx.vertex; + +import bubel.ecs.std; + +struct Vertex +{ + void create() + { + data = Mallocator.make!Data; + } + + void bind() + { + + } + + void enableStates() + { + + } + + void attachBindings(scope Binding[] bindings) + { + data.bindings = Mallocator.makeArray(bindings); + } + + enum Type + { + byte_r_snorm, + byte_r_unorm, + byte_rg_snorm, + byte_rg_unorm, + byte_rgb_snorm, + byte_rgb_unorm, + byte_rgba_snorm, + byte_rgba_unorm, + short_r_snorm, + short_r_unorm, + short_rg_snorm, + short_rg_unorm, + short_rgb_snorm, + short_rgb_unorm, + short_rgba_snorm, + short_rgba_unorm, + float_r, + float_rg, + float_rgb, + float_rgba + } + + struct Binding + { + Type type; + uint stride; + } + + struct Data + { + Binding[] bindings; + uint size; + } + + Data* data; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/imgui_bind.d b/demos/utils/source/ecs_utils/imgui_bind.d new file mode 100644 index 0000000..a65b6b2 --- /dev/null +++ b/demos/utils/source/ecs_utils/imgui_bind.d @@ -0,0 +1,850 @@ +module ecs_utils.imgui_bind; + +import bindbc.sdl; +import cimgui.cimgui; + +version(WebAssembly) +{ + extern(C): + bool ImGui_ImplOpenGL3_Init(const char* glsl_version = null); + void ImGui_ImplOpenGL3_Shutdown(); + void ImGui_ImplOpenGL3_NewFrame(); + void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); + + bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); + bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window); + bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window); + void ImGui_ImplSDL2_Shutdown(); + void ImGui_ImplSDL2_NewFrame(SDL_Window* window); + bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); +} +else : + +import bindbc.sdl; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +import cimgui.cimgui; + +extern(C): + +__gshared SDL_Window* g_Window; +__gshared ulong g_Time; +__gshared bool[3] g_MousePressed; +__gshared SDL_Cursor*[ImGuiMouseCursor_COUNT] g_MouseCursors; +__gshared char* g_ClipboardTextData; +__gshared GLuint g_FontTexture = 0; + +const (char)* ImGuiImplSDL2GetClipboardText(void*) +{ + if (g_ClipboardTextData) + SDL_free(g_ClipboardTextData); + g_ClipboardTextData = SDL_GetClipboardText(); + return g_ClipboardTextData; +} + +void ImGuiImplSDL2SetClipboardText(void*, const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) +{ + ImGuiIO* io = igGetIO(); + switch (event.type) + { + case SDL_MOUSEWHEEL: + { + if (event.wheel.x > 0) io.MouseWheelH += 1; + if (event.wheel.x < 0) io.MouseWheelH -= 1; + if (event.wheel.y > 0) io.MouseWheel += 1; + if (event.wheel.y < 0) io.MouseWheel -= 1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event.button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event.button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event.button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + ImGuiIO_AddInputCharactersUTF8(io,event.text.text.ptr); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event.key.keysym.scancode; + //IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); + io.KeysDown[key] = (event.type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + default:break; + } + return false; +} + +bool ImGuiImplSDL2Init(SDL_Window* window) +{ + g_Window = window; + + // Setup back-end capabilities flags + ImGuiIO* io = igGetIO(); + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + io.BackendPlatformName = "imgui_impl_sdl"; + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. + io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; + io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE; + io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE; + io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE; + io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_RETURN2; + io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A; + io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C; + io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V; + io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X; + io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; + io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; + + io.SetClipboardTextFn = &ImGuiImplSDL2SetClipboardText; + io.GetClipboardTextFn = &ImGuiImplSDL2GetClipboardText; + io.ClipboardUserData = null; + + g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + + //#ifdef _WIN32 + version(WebAssembly) + { + + } + else version(Windows) + { + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version_); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; + } + //#else + //(void)window; + //#endif + + return true; +} + +bool ImGuiImplSDL2InitForOpenGL(SDL_Window* window, void* sdl_gl_context) +{ + //(void)sdl_gl_context; // Viewport branch will need this. + return ImGuiImplSDL2Init(window); +} + +void ImGuiImplSDL2Shutdown() +{ + g_Window = null; + + // Destroy last known clipboard data + if (g_ClipboardTextData) + SDL_free(g_ClipboardTextData); + g_ClipboardTextData = null; + + // Destroy SDL mouse cursors + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) + SDL_FreeCursor(g_MouseCursors[cursor_n]); + //memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); +} + +static void ImGui_ImplSDL2_UpdateMousePosAndButtons() +{ + ImGuiIO* io = igGetIO(); + + // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + if (io.WantSetMousePos) + SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); + else + io.MousePos = ImVec2(-float.max, -float.max); + + int mx, my; + Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & (SDL_PRESSED<<(SDL_BUTTON_LEFT-1))) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & (SDL_PRESSED<<(SDL_BUTTON_RIGHT-1))) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & (SDL_PRESSED<<(SDL_BUTTON_MIDDLE-1))) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + //#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) + /*SDL_Window* focused_window = SDL_GetKeyboardFocus(); + if (g_Window == focused_window) + { + // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) + // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. + int wx, wy; + SDL_GetWindowPosition(focused_window, &wx, &wy); + SDL_GetGlobalMouseState(&mx, &my); + mx -= wx; + my -= wy; + io.MousePos = ImVec2((float)mx, (float)my); + } + + // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor. + // The function is only supported from SDL 2.0.4 (released Jan 2016) + bool any_mouse_button_down = ImGui.IsAnyMouseDown(); + SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE); +//#else*/ + if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) + io.MousePos = ImVec2(cast(float)mx, cast(float)my); +//#endif +} + +static void ImGui_ImplSDL2_UpdateMouseCursor() +{ + ImGuiIO* io = igGetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return; + + ImGuiMouseCursor imgui_cursor = igGetMouseCursor(); + if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + SDL_ShowCursor(SDL_FALSE); + } + else + { + // Show OS mouse cursor + SDL_SetCursor(g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + SDL_ShowCursor(SDL_TRUE); + } +} + +static void ImGui_ImplSDL2_UpdateGamepads() +{ + ImGuiIO* io = igGetIO(); + //memset(io.NavInputs, 0, sizeof(io.NavInputs)); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + + // Get gamepad + SDL_GameController* game_controller = SDL_GameControllerOpen(0); + if (!game_controller) + { + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; + return; + } + + // Update gamepad inputs + /*#define MAP_BUTTON(NAV_NO, BUTTON_NO) { io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0) ? 1.0f : 0.0f; } + #define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } + const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value. + MAP_BUTTON(ImGuiNavInput_Activate, SDL_CONTROLLER_BUTTON_A); // Cross / A + MAP_BUTTON(ImGuiNavInput_Cancel, SDL_CONTROLLER_BUTTON_B); // Circle / B + MAP_BUTTON(ImGuiNavInput_Menu, SDL_CONTROLLER_BUTTON_X); // Square / X + MAP_BUTTON(ImGuiNavInput_Input, SDL_CONTROLLER_BUTTON_Y); // Triangle / Y + MAP_BUTTON(ImGuiNavInput_DpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); // D-Pad Left + MAP_BUTTON(ImGuiNavInput_DpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); // D-Pad Right + MAP_BUTTON(ImGuiNavInput_DpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); // D-Pad Up + MAP_BUTTON(ImGuiNavInput_DpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); // D-Pad Down + MAP_BUTTON(ImGuiNavInput_FocusPrev, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB + MAP_BUTTON(ImGuiNavInput_FocusNext, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB + MAP_BUTTON(ImGuiNavInput_TweakSlow, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB + MAP_BUTTON(ImGuiNavInput_TweakFast, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB + MAP_ANALOG(ImGuiNavInput_LStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiNavInput_LStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiNavInput_LStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32767); + MAP_ANALOG(ImGuiNavInput_LStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767); + + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + #undef MAP_BUTTON + #undef MAP_ANALOG*/ +} + + +__gshared private long frequency; + +void ImGuiImplSDL2NewFrame(SDL_Window* window) +{ + ImGuiIO* io = igGetIO(); + assert(ImFontAtlas_IsBuilt(io.Fonts), "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + // SDL_GL_GetDrawableSize(window, &display_w, &display_h); FIXME: you see + io.DisplaySize = ImVec2(cast(float)w, cast(float)h); + // if (w > 0 && h > 0) + // io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h); + io.DisplayFramebufferScale = ImVec2(1,1); + + // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) + frequency = SDL_GetPerformanceFrequency(); + long current_time = SDL_GetPerformanceCounter(); + io.DeltaTime = g_Time > 0 ? cast(float)(cast(double)(current_time - g_Time) / frequency) : cast(float)(1.0f / 60.0f); + g_Time = current_time; + + ImGui_ImplSDL2_UpdateMousePosAndButtons(); + ImGui_ImplSDL2_UpdateMouseCursor(); + + // Update game controllers (if enabled and available) + ImGui_ImplSDL2_UpdateGamepads(); +} + + +__gshared GLuint g_GlVersion = 0; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) +__gshared char[32] g_GlslVersionString = ""; // Specified by user or detected based on compile time GL settings. +//__gshared GLuint g_FontTexture = 0; +__gshared GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +__gshared int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location +__gshared int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location +__gshared uint g_VboHandle = 0, g_ElementsHandle = 0; + +bool ImGui_ImplOpenGL3_Init(const char* glsl_version) +{ + // Setup back-end capabilities flags + ImGuiIO* io = igGetIO(); + io.BackendRendererName = "imgui_impl_opengl3"; + + + // Store GLSL version string so we can refer to it later in case we recreate shaders. + // Note: GLSL version is NOT the same as GL version. Leave this to null if unsure. +/*#if defined(IMGUI_IMPL_OPENGL_ES2) + if (glsl_version == null) + glsl_version = "#version 100"; +#elif defined(IMGUI_IMPL_OPENGL_ES3) + if (glsl_version == null) + glsl_version = "#version 300 es"; +#elif defined(__APPLE__) + if (glsl_version == null) + glsl_version = "#version 150"; +#else + if (glsl_version == null) + glsl_version = "#version 130"; +#endif + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));*/ + //const (char)*glsl_version = "#version 100"; + import core.stdc.string; + strcpy(g_GlslVersionString.ptr, glsl_version); + strcat(g_GlslVersionString.ptr, "\n"); + + // Dummy construct to make it easily visible in the IDE and debugger which GL loader has been selected. + // The code actually never uses the 'gl_loader' variable! It is only here so you can read it! + // If auto-detection fails or doesn't select the same GL loader file as used by your application, + // you are likely to get a crash below. + // You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. + /*const char* gl_loader = "Unknown"; + IM_UNUSED(gl_loader); +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) + gl_loader = "GL3W"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) + gl_loader = "GLEW"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) + gl_loader = "GLAD"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + gl_loader = "glbinding2"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) + gl_loader = "glbinding3"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) + gl_loader = "custom"; +#else + gl_loader = "none"; +#endif*/ + + // Make a dummy GL call (we don't actually need the result) + // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code. + // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. + /*GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);*/ + + return true; +} + +static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); +// #ifdef GL_POLYGON_MODE +// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// #endif + + // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + bool clip_origin_lower_left = true; +// #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) +// GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin); +// if (current_clip_origin == GL_UPPER_LEFT) +// clip_origin_lower_left = false; +// #endif + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data.DisplayPos (top left) to draw_data.DisplayPos+data_data.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height); + float L = draw_data.DisplayPos.x; + float R = draw_data.DisplayPos.x + draw_data.DisplaySize.x; + float T = draw_data.DisplayPos.y; + float B = draw_data.DisplayPos.y + draw_data.DisplaySize.y; + if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left + const float[4][4] ortho_projection = + [ + [ 2.0f/(R-L), 0.0f, 0.0f, 0.0f ], + [ 0.0f, 2.0f/(T-B), 0.0f, 0.0f ], + [ 0.0f, 0.0f, -1.0f, 0.0f ], + [ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f ], + ]; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); +// #ifdef GL_SAMPLER_BINDING +// glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. +// #endif + +// (void)vertex_array_object; +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glBindVertexArray(vertex_array_object); +// #endif + + // Bind vertex/index buffers and setup attributes for ImDrawVert + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glEnableVertexAttribArray(g_AttribLocationVtxPos); + glEnableVertexAttribArray(g_AttribLocationVtxUV); + glEnableVertexAttribArray(g_AttribLocationVtxColor); + glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.pos.offsetof); + glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.uv.offsetof); + glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.col.offsetof); +} + + +void ImGui_ImplOpenGL3_Shutdown() +{ + ImGui_ImplOpenGL3_DestroyDeviceObjects(); +} + +void ImGui_ImplOpenGL3_NewFrame() +{ + if (!g_ShaderHandle) + ImGui_ImplOpenGL3_CreateDeviceObjects(); +} + +bool ImGui_ImplOpenGL3_CreateDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// GLint last_vertex_array; +// glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); +// #endif + + // Parse GLSL version string + import core.stdc.stdio; + int glsl_version = 130; + sscanf(g_GlslVersionString.ptr, "#version %d", &glsl_version); + + const GLchar* vertex_shader_glsl_120 = + "uniform mat4 ProjMtx;\n + attribute vec2 Position;\n + attribute vec2 UV;\n + attribute vec4 Color;\n + varying vec2 Frag_UV;\n + varying vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* vertex_shader_glsl_130 = + "uniform mat4 ProjMtx;\n + in vec2 Position;\n + in vec2 UV;\n + in vec4 Color;\n + out vec2 Frag_UV;\n + out vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* vertex_shader_glsl_300_es = + "precision mediump float;\n + layout (location = 0) in vec2 Position;\n + layout (location = 1) in vec2 UV;\n + layout (location = 2) in vec4 Color;\n + uniform mat4 ProjMtx;\n + out vec2 Frag_UV;\n + out vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* vertex_shader_glsl_410_core = + "layout (location = 0) in vec2 Position;\n + layout (location = 1) in vec2 UV;\n + layout (location = 2) in vec4 Color;\n + uniform mat4 ProjMtx;\n + out vec2 Frag_UV;\n + out vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* fragment_shader_glsl_120 = + "#ifdef GL_ES\n + precision mediump float;\n + #endif\n + uniform sampler2D Texture;\n + varying vec2 Frag_UV;\n + varying vec4 Frag_Color;\n + void main()\n + {\n + gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n + }\n"; + + const GLchar* fragment_shader_glsl_130 = + "uniform sampler2D Texture;\n + in vec2 Frag_UV;\n + in vec4 Frag_Color;\n + out vec4 Out_Color;\n + void main()\n + {\n + Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n + }\n"; + + const GLchar* fragment_shader_glsl_300_es = + "precision mediump float;\n + uniform sampler2D Texture;\n + in vec2 Frag_UV;\n + in vec4 Frag_Color;\n + layout (location = 0) out vec4 Out_Color;\n + void main()\n + {\n + Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n + }\n"; + + const GLchar* fragment_shader_glsl_410_core = + "in vec2 Frag_UV;\n + in vec4 Frag_Color;\n + uniform sampler2D Texture;\n + layout (location = 0) out vec4 Out_Color;\n + void main()\n + {\n + Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n + }\n"; + + // Select shaders matching our GLSL versions + const (char)* vertex_shader = null; + const (char)* fragment_shader = null; + if (glsl_version < 130) + { + vertex_shader = vertex_shader_glsl_120; + fragment_shader = fragment_shader_glsl_120; + } + else if (glsl_version >= 410) + { + vertex_shader = vertex_shader_glsl_410_core; + fragment_shader = fragment_shader_glsl_410_core; + } + else if (glsl_version == 300) + { + vertex_shader = vertex_shader_glsl_300_es; + fragment_shader = fragment_shader_glsl_300_es; + } + else + { + vertex_shader = vertex_shader_glsl_130; + fragment_shader = fragment_shader_glsl_130; + } + + // Create shaders + const (char)*[2] vertex_shader_with_version = [ g_GlslVersionString.ptr, vertex_shader ]; + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version.ptr, null); + glCompileShader(g_VertHandle); + CheckShader(g_VertHandle, "vertex shader"); + + const (char)*[2] fragment_shader_with_version = [ g_GlslVersionString.ptr, fragment_shader ]; + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version.ptr, null); + glCompileShader(g_FragHandle); + CheckShader(g_FragHandle, "fragment shader"); + + g_ShaderHandle = glCreateProgram(); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + CheckProgram(g_ShaderHandle, "shader program"); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + // Create buffers + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + ImGui_ImplOpenGL3_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glBindVertexArray(last_vertex_array); +// #endif + + return true; +} + +void ImGui_ImplOpenGL3_DestroyDeviceObjects() +{ + if (g_VboHandle) { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; } + if (g_ElementsHandle) { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; } + if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); } + if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); } + if (g_VertHandle) { glDeleteShader(g_VertHandle); g_VertHandle = 0; } + if (g_FragHandle) { glDeleteShader(g_FragHandle); g_FragHandle = 0; } + if (g_ShaderHandle) { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; } + + ImGui_ImplOpenGL3_DestroyFontsTexture(); +} + +static bool CheckShader(GLuint handle, const char* desc) +{ + GLint status = 0, log_length = 0; + glGetShaderiv(handle, GL_COMPILE_STATUS, &status); + glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); + /*if (cast(GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); + if (log_length > 1) + { + ImVector buf; + buf.resize(cast(int)(log_length + 1)); + glGetShaderInfoLog(handle, log_length, null, cast(GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + }*/ + return cast(GLboolean)status == GL_TRUE; +} + +// If you get an error please report on GitHub. You may try different GL context version or GLSL version. +static bool CheckProgram(GLuint handle, const char* desc) +{ + GLint status = 0, log_length = 0; + glGetProgramiv(handle, GL_LINK_STATUS, &status); + glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); + /*if (cast(GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString); + if (log_length > 1) + { + ImVector buf; + buf.resize(cast(int)(log_length + 1)); + glGetProgramInfoLog(handle, log_length, null, cast(GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + }*/ + return cast(GLboolean)status == GL_TRUE; +} + +bool ImGui_ImplOpenGL3_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO* io = igGetIO(); + ubyte* pixels; + int width, height, bpp; + + ImFontAtlas_GetTexDataAsRGBA32(io.Fonts,&pixels, &width, &height, &bpp); + //io.Fonts.GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// #ifdef GL_UNPACK_ROW_LENGTH +// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); +// #endif + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts.TexID = cast(ImTextureID)cast(sizediff_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL3_DestroyFontsTexture() +{ + if (g_FontTexture) + { + ImGuiIO* io = igGetIO(); + glDeleteTextures(1, &g_FontTexture); + io.Fonts.TexID = null; + g_FontTexture = 0; + } +} + +void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = cast(int)(draw_data.DisplaySize.x * draw_data.FramebufferScale.x); + int fb_height = cast(int)(draw_data.DisplaySize.y * draw_data.FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + // Backup GL state + GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, cast(GLint*)&last_active_texture); + glActiveTexture(GL_TEXTURE0); + GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); +// #ifdef GL_SAMPLER_BINDING +// GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); +// #endif + GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); +// #endif +// #ifdef GL_POLYGON_MODE +// GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +// #endif + GLint[4] last_viewport; glGetIntegerv(GL_VIEWPORT, last_viewport.ptr); + GLint[4] last_scissor_box; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box.ptr); + GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, cast(GLint*)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, cast(GLint*)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, cast(GLint*)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, cast(GLint*)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, cast(GLint*)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, cast(GLint*)&last_blend_equation_alpha); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + + // Setup desired GL state + // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts) + // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound. + GLuint vertex_array_object = 0; +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glGenVertexArrays(1, &vertex_array_object); +// #endif + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data.DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data.FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + for (int n = 0; n < draw_data.CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data.CmdLists[n]; + + // Upload vertex/index buffers + glBufferData(GL_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.VtxBuffer.Size * ImDrawVert.sizeof, cast(const GLvoid*)cmd_list.VtxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.IdxBuffer.Size * ImDrawIdx.sizeof, cast(const GLvoid*)cmd_list.IdxBuffer.Data, GL_STREAM_DRAW); + + for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list.CmdBuffer.Data[cmd_i]; + if (pcmd.UserCallback != null) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + // if (pcmd.UserCallback == ImDrawCallback_ResetRenderState) + // ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + // else + pcmd.UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec4 clip_rect = ImVec4(0,0,0,0); + clip_rect.x = (pcmd.ClipRect.x - clip_off.x) * clip_scale.x; + clip_rect.y = (pcmd.ClipRect.y - clip_off.y) * clip_scale.y; + clip_rect.z = (pcmd.ClipRect.z - clip_off.x) * clip_scale.x; + clip_rect.w = (pcmd.ClipRect.w - clip_off.y) * clip_scale.y; + + if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) + { + // Apply scissor/clipping rectangle + glScissor(cast(int)clip_rect.x, cast(int)(fb_height - clip_rect.w), cast(int)(clip_rect.z - clip_rect.x), cast(int)(clip_rect.w - clip_rect.y)); + + // Bind texture, Draw + glBindTexture(GL_TEXTURE_2D, cast(GLuint)cast(sizediff_t)pcmd.TextureId); +// #if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET +// if (g_GlVersion >= 320) +// glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd.ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd.IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd.VtxOffset); +// else +// #endif + glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, cast(void*)cast(sizediff_t)(pcmd.IdxOffset * ImDrawIdx.sizeof)); + } + } + } + } + + // Destroy the temporary VAO +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glDeleteVertexArrays(1, &vertex_array_object); +// #endif + + // Restore modified GL state + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); +// #ifdef GL_SAMPLER_BINDING +// glBindSampler(0, last_sampler); +// #endif + glActiveTexture(last_active_texture); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glBindVertexArray(last_vertex_array_object); +// #endif + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); + if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); + if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); + if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); +// #ifdef GL_POLYGON_MODE +// glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); +// #endif + glViewport(last_viewport[0], last_viewport[1], cast(GLsizei)last_viewport[2], cast(GLsizei)last_viewport[3]); + glScissor(last_scissor_box[0], last_scissor_box[1], cast(GLsizei)last_scissor_box[2], cast(GLsizei)last_scissor_box[3]); +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/imgui_styles.d b/demos/utils/source/ecs_utils/imgui_styles.d new file mode 100644 index 0000000..0520ec6 --- /dev/null +++ b/demos/utils/source/ecs_utils/imgui_styles.d @@ -0,0 +1,95 @@ +module ecs_utils.imgui_styles; + +import cimgui.cimgui; + +void setStyle(uint index) +{ + ImGuiStyle * style = igGetStyle(); + ImVec4 * colors = style.Colors.ptr; + + switch(index) + { + case 0: + igStyleColorsClassic(style); + break; + case 1: + igStyleColorsDark(style); + break; + case 2: + igStyleColorsLight(style); + break; + case 3: + colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f); + colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); + + style.PopupRounding = 3; + + style.WindowPadding = ImVec2(4, 4); + style.FramePadding = ImVec2(6, 4); + style.ItemSpacing = ImVec2(6, 2); + + style.ScrollbarSize = 18; + + style.WindowBorderSize = 1; + style.ChildBorderSize = 1; + style.PopupBorderSize = 1; + style.FrameBorderSize = 0; + + style.WindowRounding = 3; + style.ChildRounding = 3; + style.FrameRounding = 4; + style.ScrollbarRounding = 2; + style.GrabRounding = 4; + break; + default: + igStyleColorsClassic(style); + break; + } + +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/math/matrix.d b/demos/utils/source/ecs_utils/math/matrix.d new file mode 100644 index 0000000..8a8e13b --- /dev/null +++ b/demos/utils/source/ecs_utils/math/matrix.d @@ -0,0 +1,6 @@ +module ecs_utils.math.matrix; + +struct mat3 +{ + float[9] data; +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/math/vector.d b/demos/utils/source/ecs_utils/math/vector.d new file mode 100644 index 0000000..dcec8df --- /dev/null +++ b/demos/utils/source/ecs_utils/math/vector.d @@ -0,0 +1,216 @@ +module ecs_utils.math.vector; + +import ecs_utils.utils; + +struct vec2 +{ + this(float v) @nogc nothrow + { + x = v; + y = v; + } + + this(float x, float y) @nogc nothrow + { + this.x = x; + this.y = y; + } + + union + { + struct + { + float x; + float y; + } + float[2] data; + } + + vec2 opBinary(string op)(vec2 v) + { + static if (op == "+") return vec2(x + v.x, y + v.y); + else static if (op == "-") return vec2(x - v.x, y - v.y); + else static if (op == "*") return vec2(x * v.x, y * v.y); + else static if (op == "/") return vec2(x / v.x, y / v.y); + else static assert(0, "Operator "~op~" not implemented"); + } + + vec2 opBinary(string op)(float v) + { + static if (op == "+") return vec2(x + v, y + v); + else static if (op == "-") return vec2(x - v, y - v); + else static if (op == "*") return vec2(x * v, y * v); + else static if (op == "/") return vec2(x / v, y / v); + else static assert(0, "Operator "~op~" not implemented"); + } + + vec2 opUnary(string op)()if (op == "-") + { + return vec2(-x,-y); + } + + ivec2 opCast() + { + return ivec2(cast(int)x,cast(int)y); + } + + void opOpAssign(string op)(vec2 v) + { + static if (op == "+") + { + x += v.x; + y += v.y; + } + else static if (op == "-") + { + x -= v.x; + y -= v.y; + } + else static if (op == "*") + { + x *= v.x; + y *= v.y; + } + else static if (op == "/") + { + x /= v.x; + y /= v.y; + } + else static assert(0, "Operator "~op~" not implemented"); + } + + float length2() + { + return x*x + y*y; + } + + float length() + { + return sqrtf(length2); + } + + float fastSqrLength() + { + return rsqrt(length2); + } + + vec2 normalize() + { + return this * fastSqrLength(); + } +} + +float dot(vec2 a, vec2 b) +{ + return a.x*b.x + a.y*b.y; +} + +struct vec4 +{ + union + { + struct + { + float x; + float y; + float z; + float w; + } + float[4] data; + } + + this(float v) @nogc nothrow + { + x = v; + y = v; + z = v; + w = v; + } + + this(float x, float y, float z, float w) @nogc nothrow + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + vec4 opBinary(string op)(float v) + { + static if (op == "+") return vec4(x + v, y + v, z + v, w + v); + else static if (op == "-") return vec4(x - v, y - v, z - v, w - v); + else static if (op == "*") return vec4(x * v, y * v, z * v, w * v); + else static if (op == "/") return vec4(x / v, y / v, z / v, w / v); + else static assert(0, "Operator "~op~" not implemented"); + } +} + +struct ivec2 +{ + union + { + struct + { + int x; + int y; + } + int[2] data; + } + + this(int v) @nogc nothrow + { + x = v; + y = v; + } + + this(int x, int y) @nogc nothrow + { + this.x = x; + this.y = y; + } + + ivec2 opBinary(string op, T)(T v) + { + static if (op == "+") return ivec2(x + v, y + v); + else static if (op == "-") return ivec2(x - v, y - v); + else static if (op == "*") return ivec2(x * v, y * v); + else static if (op == "/") return ivec2(x / v, y / v); + else static assert(0, "Operator "~op~" not implemented"); + } + + vec2 opCast() + { + return vec2(x,y); + } +} + +struct ivec4 +{ + union + { + struct + { + int x; + int y; + int z; + int w; + } + int[4] data; + } + + this(int v) @nogc nothrow + { + x = v; + y = v; + z = v; + w = v; + } + + this(int x, int y, int z, int w) @nogc nothrow + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/meson.build b/demos/utils/source/ecs_utils/meson.build new file mode 100644 index 0000000..14d443d --- /dev/null +++ b/demos/utils/source/ecs_utils/meson.build @@ -0,0 +1,18 @@ +utils_src += files( + 'gfx/mesh.d', + 'gfx/sprite.d', + 'gfx/mesh_module.d', + 'gfx/material.d', + 'gfx/shader.d', + 'gfx/vertex.d', + 'gfx/config.d', + 'gfx/buffer.d', + 'gfx/render_list.d', + 'gfx/renderer.d', + 'gfx/texture.d', + 'utils.d', + 'math/matrix.d', + 'math/vector.d', + 'imgui_styles.d', + 'imgui_bind.d', +) \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/utils.d b/demos/utils/source/ecs_utils/utils.d new file mode 100644 index 0000000..1896856 --- /dev/null +++ b/demos/utils/source/ecs_utils/utils.d @@ -0,0 +1,261 @@ +module ecs_utils.utils; + +extern(C): + +import ecs_utils.math.vector; + +enum PI = 3.141592653589793238462643383279502884197169399375105820; + +extern(C) float sqrtf(float x) @nogc nothrow @system; +extern(C) float acosf(float x) @nogc nothrow @system; +extern(C) float sinf(float x) @nogc nothrow @system; +extern(C) float cosf(float x) @nogc nothrow @system; +extern(C) float powf(float x, float y) @nogc nothrow @system; +extern(C) float fabs(float x) @nogc nothrow @system; +extern(C) float log2f(float arg) @nogc nothrow @system; + + +int randomRange(int min, int max) nothrow @nogc @trusted +{ + int range = max - min; + return rand() % range - min; +} + +float randomf() nothrow @nogc @trusted +{ + const float scale = 1.0 / 32_767.0; + return cast(float)(rand() & 0x007FFF) * scale; +} + +/* +float randomRangef(float min, float max) +{ + //int range = max - min; + return rand()%4096; +}*/ + +float mix(float x, float y, float a) +{ + //return x*a + y*(a-1); + //return x*a + y*a - y; + return x*(a+y) - y; +} + +float rsqrt(float number) +{ + long i; + float x2, y; + const float threehalfs = 1.5F; + + x2 = number * 0.5F; + y = number; + i = * cast( long * ) &y; // evil floating point bit level hacking + i = 0x5f3759df - ( i >> 1 ); // what the fuck? + y = * cast( float * ) &i; + y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration + + return y; +} + +vec2 randomCircularSample() nothrow @nogc @trusted +{ + float angle = 2 * PI * randomf; + float radius = sqrtf(randomf); + float s = sinf(angle); + float c = cosf(angle); + return vec2(c,s)*radius; +} + +version(GNU) +{ + public import core.stdc.stdio : printf; + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else +{ + extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; + // public import std.array : staticArray; + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +extern(C) int rand() nothrow @nogc @trusted; + +version(D_BetterC) +{ + version(LDC) + { + extern(C) bool _d_enter_cleanup(void*) + { + return true; + } + + extern(C) void _d_leave_cleanup(void*) + { + + } + + extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz) + { + import ldc.intrinsics : llvm_memcpy; + llvm_memcpy!size_t(dst, src, dstlen * elemsz, 0); + } + } +} + +version(Android) +{ + alias pthread_key_t = uint; + + extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; + extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; + extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; + extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; +} + +version(WebAssembly) +{ + alias pthread_key_t = uint; + + extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; + extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; + extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; + extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; + + enum EMSCRIPTEN_RESULT_SUCCESS = 0; + enum EMSCRIPTEN_RESULT_DEFERRED = 1; + enum EMSCRIPTEN_RESULT_NOT_SUPPORTED = -1; + enum EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED = -2; + enum EMSCRIPTEN_RESULT_INVALID_TARGET = -3; + enum EMSCRIPTEN_RESULT_UNKNOWN_TARGET = -4; + enum EMSCRIPTEN_RESULT_INVALID_PARAM = -5; + enum EMSCRIPTEN_RESULT_FAILED = -6; + enum EMSCRIPTEN_RESULT_NO_DATA = -7; + enum EMSCRIPTEN_RESULT_TIMED_OUT = -8; + + alias EMSCRIPTEN_FULLSCREEN_SCALE = int; + enum EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT = 0; + enum EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH = 1; + enum EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT = 2; + enum EMSCRIPTEN_FULLSCREEN_SCALE_CENTER = 3; + + alias EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE = int; + enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE = 0; + enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF = 1; + enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF = 2; + + alias EMSCRIPTEN_FULLSCREEN_FILTERING = int; + enum EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT = 0; + enum EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST = 1; + enum EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR = 2; + + alias em_canvasresized_callback_func = extern(C) bool function (int eventType, const void *reserved, void *userData); + + struct EmscriptenFullscreenStrategy { + EMSCRIPTEN_FULLSCREEN_SCALE scaleMode; + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE canvasResolutionScaleMode; + EMSCRIPTEN_FULLSCREEN_FILTERING filteringMode; + em_canvasresized_callback_func canvasResizedCallback; + void *canvasResizedCallbackUserData; + } + + extern (C) const (char)* emscripten_result_to_string(int result) { + if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS"; + if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED"; + if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED"; + if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED"; + if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET"; + if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET"; + if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM"; + if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED"; + if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA"; + return "Unknown EMSCRIPTEN_RESULT!"; + } + + extern (C) alias em_callback_func = void function(); + extern (C) alias em_arg_callback_func = void function(void*); + extern (C) void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop); + extern (C) void emscripten_set_main_loop_arg(em_arg_callback_func func, void *arg, int fps, int simulate_infinite_loop); + extern (C) int emscripten_set_main_loop_timing(int mode, int value); + extern (C) void emscripten_cancel_main_loop(); + extern (C) int emscripten_request_fullscreen_strategy(const char *target, bool deferUntilInEventHandler, const EmscriptenFullscreenStrategy *fullscreenStrategy); + extern (C) int emscripten_enter_soft_fullscreen(const char *target, const EmscriptenFullscreenStrategy *fullscreenStrategy); + extern (C) void emscripten_main_thread_process_queued_calls(); + extern (C) void emscripten_pause_main_loop(); + extern (C) void emscripten_resume_main_loop(); + + alias int time_t; + alias int clockid_t; + enum CLOCK_REALTIME = 0; + + struct timespec + { + time_t tv_sec; + int tv_nsec; + } + + extern(C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; + + struct Time + { + + + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000; + + /*LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000);*/ + } + } +} +else version(Windows) +{ + import core.stdc.stdio : printf; + import core.sys.windows.windows; + struct Time + { + static long getUSecTime() + { + LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000); + } + } +} +else version(Posix) +{ + import core.stdc.stdio : printf; + import core.sys.posix.time; + struct Time + { + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000; + + /*LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000);*/ + } + } +} \ No newline at end of file diff --git a/demos/zlib1.dll b/demos/zlib1.dll new file mode 100644 index 0000000..e7493de Binary files /dev/null and b/demos/zlib1.dll differ diff --git a/dub.json b/dub.json index 6812a0d..602117d 100755 --- a/dub.json +++ b/dub.json @@ -1,14 +1,15 @@ { - "name": "ecs", + "name": "bubel-ecs", + "targetName" : "BubelECS", "authors": [ "Michał Masiukiewicz", "Dawid Masiukiewicz" ], "description": "Dynamic Entity Component System", - "copyright": "Copyright © 2017-2018, Michał Masiukiewicz, Dawid Masiukiewicz", - "license": "BSD", + "copyright": "Copyright © 2018-2023, Michał Masiukiewicz, Dawid Masiukiewicz", + "license": "BSD 3-clause", "sourcePaths" : ["source\/"], - "dflags-posix-ldc": [ - "-defaultlib=phobos2-ldc,druntime-ldc" + "excludedSourceFiles":[ + "source\/ecs\/traits.d" ], "configurations" : [ { @@ -17,7 +18,7 @@ }, { "name" : "tests", - "sourcePaths" : ["source\/","tests\/"], + "sourceFiles" : ["tests/tests.d"], "targetType" : "executable", "excludedSourceFiles":[ "source\/win_dll.d" @@ -25,7 +26,10 @@ }, { "name" : "dynlib", - "targetType" : "dynamicLibrary" + "targetType" : "dynamicLibrary", + "dflags-linux-ldc" : [ + "-defaultlib=phobos2-ldc" + ] }, { "name" : "sources", @@ -34,6 +38,96 @@ "-Hdimport/", "-op" ] + }, + { + "name": "unittest-runner", + "targetType" : "executable", + "sourcePaths": ["source/","tests/"], + "mainSourceFile":"tests/runner.d", + "excludedSourceFiles":[ + "source\/win_dll.d", + "tests/tests.d" + ], + "dflags": [ + "-unittest" + ] + }, + { + "name": "unittest-runner-cov", + "targetType" : "executable", + "sourcePaths": ["source/","tests/"], + "mainSourceFile":"tests/runner.d", + "excludedSourceFiles":[ + "source\/win_dll.d", + "tests/tests.d" + ], + "dflags": [ + "-unittest", + "-cov=ctfe" + ] + }, + { + "name" : "library-betterC", + "targetType" : "library", + "excludedSourceFiles":[ + "source\/win_dll.d" + ], + "dflags": [ + "-betterC", + "-defaultlib=" + ], + "dflags-gdc": [ + "-fno-druntime" + ] + }, + { + "name" : "dynlib-betterC", + "targetType" : "dynamicLibrary", + "dflags": [ + "-betterC" + ], + "dflags-ldc": [ + "--fvisibility=hidden", + "-link-defaultlib-shared" + ], + "dflags-gdc": [ + "-fno-druntime", + "-fvisibility=hidden", + "-lpthread" + ] + }, + { + "name" : "tests-betterC", + "targetType" : "executable", + "sourceFiles" : ["tests/tests.d"], + "excludedSourceFiles":[ + "source\/win_dll.d" + ], + "dflags": [ + "-betterC" + ], + "dflags-gdc": [ + "-fno-druntime", + "-lpthread" + ] + }, + { + "name": "unittest-runner-betterC", + "targetType" : "executable", + "dflags": [ + "-betterC", + "-unittest" + ], + "dflags-gdc": [ + "-fno-druntime", + "-lpthread" + ], + "sourcePaths": ["source/","tests/"], + "mainSourceFile":"tests/runner.d", + "excludedSourceFiles":[ + "source\/win_dll.d", + "tests/tests.d" + ] } ] } \ No newline at end of file diff --git a/import/ecs/ecs.di b/import/ecs/ecs.di deleted file mode 100644 index 13041de..0000000 --- a/import/ecs/ecs.di +++ /dev/null @@ -1,112 +0,0 @@ -// D import file generated from 'source\ecs\ecs.d' -module ecs.ecs; -import std.stdio; -version (Design) -{ - alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart); - struct HasComponentsStore - { - ulong[4] bits; - bool has(HasComponentsStore components); - bool notIn(HasComponentsStore components); - int length(); - } - struct ComponentInfo - { - int size; - int aligment; - SerializeJSON funsSerJ; - SerializeBiN funcSerB; - } - struct System - { - HasComponentsStore requiredComponents; - HasComponentsStore absenComponents; - HasComponentsStore maybeComponents; - bool enabled; - int priority; - SytemFuncType func; - } - struct SystemCallData - { - System* system; - int[] componentsDt; - } - struct EntityTypeData - { - HasComponentsStore components; - int[] deltas; - int totalSize; - int totalAligment = 8; - SystemCallData[] systems; - } - struct EntitiesBlock - { - EntityTypeData* typeData; - Entity* freeEntitySlot; - EntitiesBlock* nextBlock; - } - struct EntityID - { - ulong id = (ulong).max; - static immutable notUsedValue = EntityID((ulong).max); - } - struct Entity - { - EntityID entityID = EntityID.notUsedValue; - union - { - string name; - Entity* nextFreeSlot; - } - uint group; - EntityID entityID; - } - struct Template - { - HasComponentsStore hasComp; - Entity* entity; - } - struct Manager - { - EntityAllocator entityArrayAllcoator; - ComponentInfo[] components; - System[] systems; - HashMap!(HasComponentsStore, EntitiesBlock*) entitiesDatas; - HashMapTwoWays!(string, Entity*) nameMap; - HashMapTwoWays!(EntityID, Entity*) idMap; - EntitiesBlock* getEntitiesBlock(HasComponentsStore hasComponents); - EntitiesBlock* addNewBlock(HasComponentsStore hasComponents, EntitiesBlock* firstBlock); - void alignNum(ref int num, int aligment); - EntityTypeData* newEntityTypeData(HasComponentsStore hasComponents); - void addEntity(Template* templ); - void addSystem(Func)(int priority) - { - HasComponentsStore requiredComponents; - HasComponentsStore absenComponents; - HasComponentsStore maybeComponents; - void systemCaller(ref SystemCallData data, void* componentsStart); - System* system = new System(&systemCaller, entTypeData); - systems ~= system; - foreach (ref entTypeData; entitiesDatas) - { - if (!entTypeData.hasComp.has(requiredComponents) || !entTypeData.hasComp.notIn(absenComponents)) - { - continue; - } - entTypeData.systems ~= system; - } - } - } - void someSystem(CompA a, CompB b, CompC* c); - void main(); - class System - { - void start(); - void end(); - void update(ref ObjRend a); - void useEvent(EventData evvv, ref ObjRend a); - } - alias SerializeVector = ubyte[]; - __gshared EntityManager gEntityManager; -} diff --git a/import/ecs/entity.di b/import/ecs/entity.di deleted file mode 100644 index db6208b..0000000 --- a/import/ecs/entity.di +++ /dev/null @@ -1,30 +0,0 @@ -// D import file generated from 'source\ecs\entity.d' -module ecs.entity; -import ecs.manager; -struct EntityID -{ - uint id; - uint counter; -} -struct Entity -{ - EntityID id; - void updateID(); - T* getComponent(T)() - { - EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); - EntityManager.EntityInfo* info = block.type_data; - if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) - return null; - return cast(T*)(cast(void*)&this + info.deltas[T.component_id]); - } -} -export struct EntityTemplate -{ - ubyte[] entity_data; - EntityManager.EntityInfo* info; - T* getComponent(T)() - { - return cast(T*)(entity_data.ptr + info.deltas[T.component_id]); - } -} diff --git a/import/ecs/entity_allocator.di b/import/ecs/entity_allocator.di deleted file mode 100644 index 66472fd..0000000 --- a/import/ecs/entity_allocator.di +++ /dev/null @@ -1,11 +0,0 @@ -// D import file generated from 'source\ecs\entity_allocator.d' -module ecs.entity_allocator; -import ecs.manager; -import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; -struct EntityAllocator -{ - void* next_block; - void* getBlock(); - private void allocBlock(); -} diff --git a/import/ecs/events.di b/import/ecs/events.di deleted file mode 100644 index 73085c6..0000000 --- a/import/ecs/events.di +++ /dev/null @@ -1,9 +0,0 @@ -// D import file generated from 'source\ecs\events.d' -module ecs.events; -struct Event -{ - uint type; -} -class EventManager -{ -} diff --git a/import/ecs/id_manager.di b/import/ecs/id_manager.di deleted file mode 100644 index 55a00ef..0000000 --- a/import/ecs/id_manager.di +++ /dev/null @@ -1,20 +0,0 @@ -// D import file generated from 'source\ecs\id_manager.d' -module ecs.id_manager; -import ecs.entity; -import ecs.vector; -struct IDManager -{ - EntityID getNewID(); - void releaseID(EntityID id); - void update(ref Entity entity); - Entity* getEntityPointer(EntityID id); - bool isExist(EntityID id); - struct Data - { - uint counter = 0; - uint next_id = (uint).max; - Entity* entity = null; - } - private uint m_next_id = 0; - Vector!Data m_ids_array; -} diff --git a/import/ecs/manager.di b/import/ecs/manager.di deleted file mode 100644 index 801bc1d..0000000 --- a/import/ecs/manager.di +++ /dev/null @@ -1,287 +0,0 @@ -// D import file generated from 'source\ecs\manager.d' -module ecs.manager; -import std.algorithm : max; -import std.conv : to; -import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; -import std.traits; -import core.stdc.stdlib; -import core.stdc.string; -import ecs.entity; -import ecs.entity_allocator; -import ecs.hash_map; -import ecs.id_manager; -import ecs.system; -import ecs.vector; -alias gEM = EntityManager.instance; -alias SerializeVector = ecs.vector.Vector!ubyte; -class EntityManager -{ - export static void initialize(); - export static void destroy(); - export void registerSystem(Sys)(int priority) - { - alias types = Parameters!(Sys.update); - alias storages = ParameterStorageClassTuple!(Sys.update); - alias STC = ParameterStorageClass; - System system; - static string genCall()() - { - string ret = "s.update(*cast(Entity*)data_pointer,"; - uint i = 0; - uint req = 0; - uint opt = 0; - static foreach (param; Parameters!(Sys.update)[1..$]) - { - i++; - if (isPointer!param) - { - ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ opt++.to!string ~ "]),"; - } - else - { - ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ req++.to!string ~ "]),"; - } - } - ret ~= ");"; - return ret; - } - static string genCompList()() - { - string ret = "ushort comp;uint req;uint opt;"; - foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= "\x0a static if(isPointer!(types[" ~ i.to!string ~ "]))opt++;\x0a else static if(storages[" ~ i.to!string ~ "] == STC.ref_)req++;\x0a\x0a else static assert(0,\"Can't register system \\\"" ~ Sys.stringof ~ "\\\". Unsupported parameter type \\\"\"~types[" ~ i.to!string ~ "].stringof~\"\\\".\");"; - } - ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; - ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; - ret ~= "opt = 0;req = 0;"; - foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= "\x0a static if(isPointer!(types[" ~ i.to!string ~ "]))\x0a {\x0a comp = components_map.get(PointerTarget!(types[" ~ i.to!string ~ "]).stringof, ushort.max);\x0a\x0a if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof ~ "\\\" due to non existing component \\\"\"~types[" ~ i.to!string ~ "].stringof~\"\\\".\");\x0a system.m_optional_components[opt++] = comp;\x0a }\x0a else static if(storages[" ~ i.to!string ~ "] == STC.ref_)\x0a {\x0a comp = components_map.get(types[" ~ i.to!string ~ "].stringof, ushort.max);\x0a\x0a if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof ~ "\\\" due to non existing component \\\"\"~types[" ~ i.to!string ~ "].stringof~\"\\\".\");\x0a system.m_components[req++] = comp;\x0a }"; - } - return ret; - } - static string catchFunc()(string member, string func) - { - string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\"))\x0a {\x0a static void call" ~ func ~ "(void* system_pointer)\x0a {\x0a\x0a Sys* s = cast(Sys*) system_pointer;\x0a s." ~ func ~ "();\x0a }\x0a\x0a system." ~ member ~ " = &call" ~ func ~ ";\x0a }"; - return ret; - } - static if (hasMember!(Sys, "update")) - { - static void callUpdate(ref CallData data, void* entity) - { - static if (hasMember!(Sys, "update")) - { - Sys* s = cast(Sys*) data.system.m_system_pointer; - - void*[] pointers = (cast(void**) alloca(data.system.m_components.length * (void*) - .sizeof))[0 .. data.system.m_components.length]; - void*[] optional_pointers = (cast(void**) alloca( - data.system.m_optional_components.length * (void*).sizeof))[0 - .. data.system.m_optional_components.length]; - - EntitiesBlock* block = data.info.first_block; - while (block !is null) - { - uint size = block.type_data.size; - void* data_pointer = block.dataBegin(); - foreach (i, ref pointer; pointers) - { - pointer = data_pointer + data.deltas[i]; - } - foreach (i, ref pointer; optional_pointers) - { - uint ind = cast(uint)(i + pointers.length); - if (data.deltas[ind] != uint.max) - pointer = data_pointer + data.deltas[ind]; - else - pointer = null; - } - foreach (i; 0 .. block.entities_count) - { - mixin(genCall()); - data_pointer += size; //data.info.size; - foreach (ref pointer; pointers) - pointer += size; - foreach (ref pointer; optional_pointers) - if (pointer != null) - pointer += size; - } - block = block.next_block; - } - - } - } - system.m_update = &callUpdate; - } - - mixin(catchFunc("m_enable", "onEnable")); - mixin(catchFunc("m_disable", "onDisable")); - mixin(catchFunc("m_create", "onCreate")); - mixin(catchFunc("m_destroy", "onDestroy")); - mixin(catchFunc("m_begin", "onBegin")); - mixin(catchFunc("m_end", "onEnd")); - system.m_system_pointer = cast(void*)Mallocator.instance.make!Sys; - system.m_priority = priority; - mixin(genCompList()); - ushort sys_id = systems_map.get(Sys.stringof, (ushort).max); - if (sys_id < systems.length) - { - system.enable(); - systems[sys_id] = system; - } - else - { - systems_map.add(Sys.stringof, cast(ushort)systems.length); - systems.add(system); - if (system.m_create) - system.m_create(system.m_system_pointer); - systems[$ - 1].enable(); - foreach (info; &entities_infos.byValue) - { - addEntityCaller(*info, cast(uint)systems.length - 1); - } - } - updateEntityCallers(); - } - void registerComponent(Comp)() - { - ComponentInfo info; - static if (!hasMember!(Comp, "component_id") || !is(typeof(Comp.component_id) == ushort)) - { - static assert(0, "Component should have \"__gshared ushort component_id"); - } - - static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy) && is(ReturnType!(Comp.onDestroy) == void) && (Parameters!(Comp.onDestroy).length == 0)) - { - static void callDestroy(void* pointer) - { - (cast(Comp*) pointer).onDestroy(); - } - info.destroy_callback = &callDestroy; - } - - info.size = Comp.sizeof; - info.aligment = Comp.alignof; - info.init_data = Mallocator.instance.makeArray!ubyte(Comp.sizeof); - *cast(Comp*)info.init_data.ptr = Comp.init; - ushort comp_id = components_map.get(Comp.stringof, (ushort).max); - if (comp_id < components.length) - { - Comp.component_id = comp_id; - } - else - { - components.add(info); - Comp.component_id = cast(ushort)(components.length - 1); - components_map.add(Comp.stringof, cast(ushort)(components.length - 1)); - } - } - export void update(); - static void alignNum(ref ushort num, ushort aligment); - extern (C) static int compareUShorts(const void* a, const void* b); - export EntityTemplate* allocateTemplate(ushort[] components_ids); - export EntityInfo* getEntityInfo(ushort[] ids); - export void updateEntityCallers(); - export void addEntityCaller(ref EntityInfo entity, uint system_id); - export Entity* getEntity(EntityID id); - export void removeComponents(EntityID entity_id, ushort[] del_ids); - private void __removeComponents(EntityID entity_id, ushort[] del_ids); - void removeComponents(Components...)(EntityID entity_id) - { - const uint num = Components.length; - ushort[num] del_ids; - static foreach (i, comp; Components) - { - del_ids[i] = comp.component_id; - } - removeComponents(entity_id, del_ids); - } - private void __addComponents(EntityID entity_id, ushort[] new_ids, void*[] data_pointers); - void addComponents(Components...)(EntityID entity_id, Components comps) - { - const uint num = Components.length; - Entity* entity = id_manager.getEntityPointer(entity_id); - EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_data; - ushort[] ids = (cast(ushort*)alloca((ushort).sizeof * (info.components.length + num)))[0..info.components.length + num]; - ushort[num] new_ids; - static foreach (i, comp; Components) - { - new_ids[i] = comp.component_id; - } - change_entities_list.add(1); - change_entities_list.add((cast(ubyte*)&entity_id)[0..8]); - change_entities_list.add((cast(ubyte*)&num)[0..4]); - change_entities_list.add(cast(ubyte[])new_ids); - static foreach (i, comp; comps) - { - change_entities_list.add((cast(ubyte*)&comp)[0..comp.sizeof]); - } - } - export void freeTemplate(EntityTemplate* template_); - export ref Entity addEntity(EntityTemplate* tmpl); - private EntitiesBlock* findBlockWithFreeSpace(EntityInfo* info); - export void removeEntity(EntityID id); - private void __removeEntity(EntityID id); - private void removeEntityNoID(Entity* entity, EntitiesBlock* block, bool call_destructors = false); - export EntitiesBlock* getMetaData(void* pointer); - private void changeEntites(); - private void updateBlocks(); - private void removeEntities(); - export void begin(); - export void end(); - struct ComponentInfo - { - ushort size; - ushort aligment; - ubyte[] init_data; - void function(void* pointer) destroy_callback; - } - struct EntityInfo - { - ushort[] components; - ushort[] deltas; - ushort alignment; - ushort size; - EntitiesBlock* first_block; - EntitiesBlock* first_with_free_space; - Vector!CallData callers; - } - struct EntitiesBlock - { - uint dataDelta(); - void* dataBegin(); - EntityInfo* type_data; - ushort entities_count; - ushort added_count; - uint id; - EntitiesBlock* next_block; - } - struct CallData - { - uint system_id; - System* system; - EntityManager.EntityInfo* info; - ushort[] deltas; - } - alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity); - enum page_size = 4096; - enum pages_in_block = 128; - IDManager id_manager; - EntityAllocator allocator; - Vector!EntityID entities_to_remove; - Vector!(EntitiesBlock*) blocks_to_update; - Vector!ubyte change_entities_list; - HashMap!(ushort[], EntityInfo*) entities_infos; - HashMap!(string, ushort) systems_map; - HashMap!(string, ushort) components_map; - Vector!System systems; - Vector!ComponentInfo components; - __gshared EntityManager instance; -} -version (Windows) -{ - extern (Windows) bool DllMain(void* hInstance, uint ulReason, void*); -} diff --git a/import/ecs/package.di b/import/ecs/package.di deleted file mode 100644 index 41d9943..0000000 --- a/import/ecs/package.di +++ /dev/null @@ -1,7 +0,0 @@ -// D import file generated from 'source\ecs\package.d' -module ecs; -public import ecs.manager; -public import ecs.entity; -public import ecs.system; -import ecs.id_manager; -import ecs.events; diff --git a/import/ecs/string_intern.di b/import/ecs/string_intern.di deleted file mode 100644 index 665bfc5..0000000 --- a/import/ecs/string_intern.di +++ /dev/null @@ -1,31 +0,0 @@ -// D import file generated from 'source\ecs\string_intern.d' -module ecs.string_intern; -import ecs.hash_map; -import ecs.traits : isForeachDelegateWithI; -import std.experimental.allocator; -import std.experimental.allocator.mallocator; -import std.traits : Parameters; -private static __gshared HashMap!(const(char)[], StringIntern) gStringInterns; -struct StringIntern -{ - private const(char)* strPtr; - this(const(char)[] fromStr) - { - opAssign(fromStr); - } - void reset(); - size_t length(); - const(char)[] str(); - const(char)[] cstr(); - bool opEquals()(auto ref const StringIntern s) - { - return strPtr == s.strPtr; - } - bool opEquals()(auto ref const(char[]) s) - { - return str() == s; - } - void opAssign(const(char)[] fromStr); - const(char)[] opSlice(); - private const(char)[] allocStr(const(char)[] fromStr); -} diff --git a/import/ecs/system.di b/import/ecs/system.di deleted file mode 100644 index fd28e8a..0000000 --- a/import/ecs/system.di +++ /dev/null @@ -1,26 +0,0 @@ -// D import file generated from 'source\ecs\system.d' -module ecs.system; -import ecs.entity; -import ecs.manager; -struct System -{ - export bool enabled(); - export void enable(); - export void disable(); - export int priority(); - package - { - bool m_enabled = false; - int m_priority; - void* m_system_pointer; - ushort[] m_components; - ushort[] m_optional_components; - void* m_update; - void function(void* system_pointer) m_enable; - void function(void* system_pointer) m_disable; - void function(void* system_pointer) m_create; - void function(void* system_pointer) m_destroy; - void function(void* system_pointer) m_begin; - void function(void* system_pointer) m_end; - } -} diff --git a/import/ecs/traits.di b/import/ecs/traits.di deleted file mode 100644 index 7eef028..0000000 --- a/import/ecs/traits.di +++ /dev/null @@ -1,20 +0,0 @@ -// D import file generated from 'source\ecs\traits.d' -module ecs.traits; -import std.traits; -bool isForeachDelegateWithI(DG)() -{ - return is(DG == delegate) && is(ReturnType!DG == int) && (Parameters!DG.length == 2) && isIntegral!(Parameters!DG[0]); -} -bool isForeachDelegateWithoutI(DG)() -{ - return is(DG == delegate) && is(ReturnType!DG == int) && (Parameters!DG.length == 1); -} -bool isForeachDelegateWithTypes(DG, Types...)() -{ - return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types); -} -auto assumeNoGC(T)(T t) if (isFunctionPointer!T || isDelegate!T) -{ - enum attrs = functionAttributes!T | FunctionAttribute.nogc; - return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs))t; -} diff --git a/import/ecs/vector.di b/import/ecs/vector.di deleted file mode 100644 index cb0917e..0000000 --- a/import/ecs/vector.di +++ /dev/null @@ -1,274 +0,0 @@ -// D import file generated from 'source\ecs\vector.d' -module ecs.vector; -import core.bitop; -import core.stdc.stdlib : free, malloc; -import core.stdc.string : memcpy, memset; -import std.algorithm : swap; -import std.conv : emplace; -import std.traits : hasMember, isCopyable, TemplateOf, Unqual; -export pure nothrow @nogc @safe size_t nextPow2(size_t num); -__gshared size_t gVectorsCreated = 0; -__gshared size_t gVectorsDestroyed = 0; -struct Vector(T) -{ - T[] array; - size_t used; - public - { - export this()(T t) - { - add(t); - } - export this(X)(X[] t) if (is(Unqual!X == Unqual!T)) - { - add(t); - } - static if (isCopyable!T) - { - export this(this) - { - T[] tmp = array[0..used]; - array = null; - used = 0; - add(tmp); - } - } - else - { - @disable this(this); - } - export ~this() - { - clear(); - } - export void clear() - { - removeAll(); - } - export void removeAll() - { - if (array !is null) - { - foreach (ref el; array[0..used]) - { - destroy(el); - } - freeData(cast(void[])array); - gVectorsDestroyed++; - } - array = null; - used = 0; - } - export bool empty() - { - return used == 0; - } - export size_t length() - { - return used; - } - export void length(size_t newLength) - { - if (newLength > used) - { - reserve(newLength); - foreach (ref el; array[used..newLength]) - { - emplace(&el); - } - } - else - { - foreach (ref el; array[newLength..used]) - { - destroy(el); - } - } - used = newLength; - } - export void reset() - { - used = 0; - } - export void reserve(size_t numElements) - { - if (numElements > array.length) - { - extend(numElements); - } - } - export size_t capacity() - { - return array.length - used; - } - export void extend(size_t newNumOfElements) - { - auto oldArray = manualExtend(array, newNumOfElements); - if (oldArray !is null) - { - freeData(oldArray); - } - } - export @nogc void freeData(void[] data) - { - memset(data.ptr, 15, data.length); - free(data.ptr); - } - export static void[] manualExtend(ref T[] array, size_t newNumOfElements = 0) - { - if (newNumOfElements == 0) - newNumOfElements = 2; - if (array.length == 0) - gVectorsCreated++; - T[] oldArray = array; - size_t oldSize = oldArray.length * T.sizeof; - size_t newSize = newNumOfElements * T.sizeof; - T* memory = cast(T*)malloc(newSize); - memcpy(cast(void*)memory, cast(void*)oldArray.ptr, oldSize); - array = memory[0..newNumOfElements]; - return cast(void[])oldArray; - } - export Vector!T copy()() - { - Vector!T duplicate; - duplicate.reserve(used); - duplicate ~= array[0..used]; - return duplicate; - } - export bool canAddWithoutRealloc(uint elemNum = 1) - { - return used + elemNum <= array.length; - } - export void add()(T t) - { - if (used >= array.length) - { - extend(nextPow2(used + 1)); - } - emplace(&array[used], t); - used++; - } - export void add()(T t, size_t pos) - { - assert(pos <= used); - if (used >= array.length) - { - extend(array.length * 2); - } - foreach_reverse (size_t i; pos .. used) - { - array[i + 1] = array[i]; - } - emplace(&array[pos], t); - used++; - } - export void add(X)(X[] t) if (is(Unqual!X == Unqual!T)) - { - if (used + t.length > array.length) - { - extend(nextPow2(used + t.length)); - } - foreach (i; 0 .. t.length) - { - emplace(&array[used + i], t[i]); - } - used += t.length; - } - export void remove(size_t elemNum) - { - destroy(array[elemNum]); - swap(array[elemNum], array[used - 1]); - used--; - } - export void removeStable()(size_t elemNum) - { - used--; - foreach (i; 0 .. used) - { - array[i] = array[i + 1]; - } - } - export bool tryRemoveElement()(T elem) - { - foreach (i, ref el; array[0..used]) - { - if (el == elem) - { - remove(i); - return true; - } - } - return false; - } - export void removeElement()(T elem) - { - bool ok = tryRemoveElement(elem); - assert(ok, "There is no such an element in vector"); - } - export ref T opIndex(size_t elemNum) - { - assert(elemNum < used, "Range violation [index]"); - return array.ptr[elemNum]; - } - export auto opSlice() - { - return array.ptr[0..used]; - } - export T[] opSlice(size_t x, size_t y) - { - assert(y <= used); - return array.ptr[x..y]; - } - export size_t opDollar() - { - return used; - } - export void opAssign(X)(X[] slice) - { - reset(); - this ~= slice; - } - export void opOpAssign(string op)(T obj) - { - static assert(op == "~"); - add(obj); - } - export void opOpAssign(string op, X)(X[] obj) - { - static assert(op == "~"); - add(obj); - } - export void opIndexAssign()(T obj, size_t elemNum) - { - assert(elemNum < used, "Range viloation"); - array[elemNum] = obj; - } - export void opSliceAssign()(T[] obj, size_t a, size_t b) - { - assert(b <= used && (a <= b), "Range viloation"); - array.ptr[a..b] = obj; - } - export const bool opEquals()(auto ref const Vector!T r) - { - return used == r.used && (array.ptr[0..used] == r.array.ptr[0..r.used]); - } - export const nothrow @trusted size_t toHash() - { - return hashOf(cast(Unqual!T[])array.ptr[0..used]); - } - import std.format : FormatSpec, formatValue; - export void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) - { - static if (__traits(compiles, formatValue(sink, array[0..used], fmt))) - { - formatValue(sink, array[0..used], fmt); - } - - } - } -} -private pure nothrow @nogc @safe T[n] s(T, size_t n)(auto ref T[n] array) -{ - return array; -} -enum string checkVectorAllocations = "\x0a//assert(gVectorsCreated==gVectorsDestroyed);\x0agVectorsCreated=gVectorsDestroyed=0;\x0ascope(exit){if(gVectorsCreated!=gVectorsDestroyed){\x09\x0a\x09import std.stdio : writefln;\x0a\x09writefln(\"created==destroyed %s==%s\", gVectorsCreated, gVectorsDestroyed);\x0a\x09assert(gVectorsCreated==gVectorsDestroyed, \"Vector memory leak\");\x0a}}\x0a"; diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..141cb25 --- /dev/null +++ b/meson.build @@ -0,0 +1,90 @@ +project('bubel-ecs', 'd', version : '0.5.0') + +# Options +betterC_opt = get_option('betterC') +BuildDemos_opt = get_option('BuildDemos') +BuildTests_opt = get_option('BuildTests') +LTO_otp = get_option('LTO') + +summary('betterC enabled', betterC_opt) +summary('build demos', BuildDemos_opt) +summary('build tests', BuildTests_opt) +summary('LTO enabled', LTO_otp) + +meson_minimum_version = '>=0.57.1' +assert(meson.version().version_compare(meson_minimum_version), 'Newer verson of meson required, current version: @0@, required: @1@'.format(meson.version(), meson_minimum_version)) + +# Files +src = files() +subdir('source') + +inc = include_directories('source/') + +# Arguments +args = [] +link_args = [] + +comp = meson.get_compiler('d') +comp_id = comp.get_id() + +if LTO_otp + if comp_id == 'gcc' + args += '-flto' + link_args += '-flto' + elif comp_id == 'llvm' + args += '-flto=thin' + link_args += '-flto=thin' + else + assert(false, 'Compiler "@0@" doesn\'t support LTO'.format(comp_id)) + endif +endif + +if betterC_opt + if comp_id == 'gcc' + args += ['-fno-druntime'] + link_args += ['-fno-druntime'] + else + args += '-betterC' + link_args += '-betterC' + endif +endif + +add_project_arguments(args, language : 'd') +add_project_link_arguments(link_args, language : 'd') + +# Dependencies +threads_dep = dependency('threads') + +d_versions = [] +deps = [] +if host_machine.cpu_family() == 'wasm32' + +else + # meson incorectly adds "-s USE_PTHREADS=1" to ldc2 invocation whe pthreads is added as dependency + # add it for non wasm builds + deps += threads_dep +endif + +ecs_lib = library('BubelECS', + src, + d_module_versions : d_versions, + include_directories : [inc], +) + +bubel_ecs_dep = declare_dependency( + include_directories : [inc], + link_with : ecs_lib, + dependencies : deps, +) + +meson.override_dependency('bubel-ecs', bubel_ecs_dep) + +# Tests +if BuildTests_opt + subdir('tests') +endif + +# Demos +if BuildDemos_opt + subdir('demos') +endif diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..335f32b --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,4 @@ +option('betterC', type: 'boolean', value: false) +option('BuildDemos', type: 'boolean', value: false) +option('BuildTests', type: 'boolean', value: false) +option('LTO', type: 'boolean', value: false) diff --git a/skeleton.html b/skeleton.html new file mode 100644 index 0000000..02f57a2 --- /dev/null +++ b/skeleton.html @@ -0,0 +1,36 @@ + + + + BubelECS + + + + + + + + + + +
+
+
+ +
+ + + diff --git a/source/bubel/ecs/atomic.d b/source/bubel/ecs/atomic.d new file mode 100644 index 0000000..d8995ae --- /dev/null +++ b/source/bubel/ecs/atomic.d @@ -0,0 +1,13 @@ +/************************************************************************************************************************ +It's internal code. Can be used for atomics if emscripten backend will be used. + +This module contain atomic operations which include support for emscripten atomics functions. +Emscripten functions are contained in API similar to druntime. + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.atomic; + +public import core.atomic; + diff --git a/source/bubel/ecs/attributes.d b/source/bubel/ecs/attributes.d new file mode 100644 index 0000000..1a041d4 --- /dev/null +++ b/source/bubel/ecs/attributes.d @@ -0,0 +1,28 @@ +/************************************************************************************************************************ +This module contain attributes used to mark components. +Currently only two attributes are supported: +$(LIST + * optional: mark component as optional for system update + * readonly: mark component access as read only (used for multithreading) +) + +By default components are required and mutable. "const" attribute can be used insteac od readonly mark. + +--- +Struct EntitiesData +{ + Comp1[] cmp; //mutable required component + @readonly @optional Comp2[] cmp2; //optional read only component + @optional const (Comp3)[] cmp3; //same as cmp2 +} +--- + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.attributes; + +///Used to mark optional components for system. +enum optional = "optional"; +///Used to mark readonly components for system. "const" can be used insted. +enum readonly = "readonly"; diff --git a/source/bubel/ecs/block_allocator.d b/source/bubel/ecs/block_allocator.d new file mode 100644 index 0000000..0ab735e --- /dev/null +++ b/source/bubel/ecs/block_allocator.d @@ -0,0 +1,100 @@ +/************************************************************************************************************************ +It's internal code. + +Module contain memory allocator. + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.block_allocator; + +import bubel.ecs.manager; +import bubel.ecs.std; + +/************************************************************************************************************************ +Allocator allocate large blocks and return smaller blocks. When there is no more blocks then next large block is allocated. +By default freeing memory only returns it to allocator. To free large memory chunks freeMemory function is used. +freeMemory function return to system memory even if chunk blocks wasn't freed. +*/ +struct BlockAllocator +{ + /************************************************************************************************************************ + Get new block. Allocator automatically allocate next memory chunk if needed. + */ + void* getBlock() nothrow @nogc + { + if (next_block is null) + allocBlock(); + void* ret = next_block; + next_block = *cast(void**) next_block; + return ret; + } + + /************************************************************************************************************************ + Return block to allocator for further use. + */ + void freeBlock(void* block) nothrow @nogc + { + *cast(void**) block = next_block; + next_block = block; + } + + /************************************************************************************************************************ + Free whole used memory. This function return to system all memory chunks even if not every black was freed. + */ + void freeMemory() nothrow @nogc + { + while (pointers) + { + foreach (i; 0 .. pointers.numberof) + { + Mallocator.alignDispose(pointers.blocks[i]); + } + BlockPointers* next_pointers = pointers.next_pointers; + Mallocator.dispose(pointers); + pointers = next_pointers; + } + next_block = null; + } + +private: + + void allocBlock() nothrow @nogc + { + next_block = cast(void*) Mallocator.alignAlloc(block_size * blocks_in_allocation, + block_size); + if (next_block is null) + assert(0); + + if (pointers is null) + pointers = Mallocator.make!BlockPointers; + if (pointers.numberof >= 32) + { + BlockPointers* new_pointers = Mallocator.make!BlockPointers; + new_pointers.next_pointers = pointers; + pointers = new_pointers; + } + pointers.blocks[pointers.numberof++] = next_block; + + foreach (i; 0 .. blocks_in_allocation - 1) + { + void** pointer = cast(void**)(next_block + i * block_size); + *pointer = next_block + (i + 1) * block_size; + } + void** pointer = cast(void**)(next_block + (blocks_in_allocation - 1) * block_size); + *pointer = null; + } + + struct BlockPointers + { + void*[32] blocks; + uint numberof = 0; + BlockPointers* next_pointers = null; + } + + uint block_size; + uint blocks_in_allocation; + + void* next_block = null; + BlockPointers* pointers = null; +} diff --git a/source/bubel/ecs/core.d b/source/bubel/ecs/core.d new file mode 100644 index 0000000..c796423 --- /dev/null +++ b/source/bubel/ecs/core.d @@ -0,0 +1,134 @@ +/************************************************************************************************************************ +This module contain main helper templates for user. +There are three structure templates (mixins) which can be added on top of structure: +$(LIST + * System: make system structure + * Component: make component structure + * Event: make event structure +) +This mixins are optional and are used to adding some additional capabilities, e.g. ECS.System is used to configuring default number of jobs for system. + +--- +Struct System1 +{ + mixin!ECS.System; +} + +Struct System2 +{ + mixin!ECS.System(16);//set number of jobs generated for system by multithreaded update +} + +Struct Component1 +{ + mixin!ECS.Component; +} + +Struct Event1 +{ + mixin!ECS.Event; +} +--- + +There is also template for generating list of excluded components "ExcludedComponets(T...)". +This template takes component structure types and making list of excluded components used in "registerSystem" function. + +--- +Struct System1 +{ + mixin!ECS.System; + + struct EntitiesData + { + ... //used components + } + + ExcludedComponets!(Comp1, Comp2); +} +--- + +Templates ReadOnlyDependencies nad WritableDependencies are used to create list of dependencies for System. +Writable dependencies are bloking parallel execution of system which has same dependency (as writable or readonly). +This dependencies works same as Component dependencies but can be used for creating external dependencies (e.g. dependency on spatial partitioning tree access). + +--- +enum ExternalDependency1 = "ExternalDependency1"; + +Struct System1 +{ + mixin!ECS.System; + + struct EntitiesData + { + ... //used components + } + + ReadOnlyDependencies!(ExternalDependency1); +} +--- + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.core; + +public import bubel.ecs.manager; +public import bubel.ecs.entity; +public import bubel.ecs.traits : becsID; + +/************************************************************************************************************************ +Main struct used as namespace for templates. +*/ +static struct ECS +{ + /************************************************************************************************************************ + Set default system parameters (number of parallel jobs) + */ + mixin template System(uint jobs_count = 32) + { + __gshared uint __becs_jobs_count = jobs_count; + } + + /************************************************************************************************************************ + Mark structure as Component + */ + mixin template Component() + { + deprecated ComponentRef ref_() @nogc nothrow return + { + return ComponentRef(&this, becsID!(typeof(this))); + } + } + + /************************************************************************************************************************ + Mark structure as Event + */ + mixin template Event() + { + + } + + /************************************************************************************************************************ + Make list of excluded components. This template get structure types as argument. Should be added inside System structure. + */ + mixin template ExcludedComponents(T...) + { + alias ExcludedComponents = T; + } + + /************************************************************************************************************************ + Make list of readonly ependencies. This template get strings as arguments. Should be added inside System structure. + */ + mixin template ReadOnlyDependencies(T...) + { + alias ReadOnlyDependencies = T; + } + + /************************************************************************************************************************ + Make list of writable ependencies. This template get strings as arguments. Should be added inside System structure. + */ + mixin template WritableDependencies(T...) + { + alias WritableDependencies = T; + } +} diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d new file mode 100644 index 0000000..76a8a2f --- /dev/null +++ b/source/bubel/ecs/entity.d @@ -0,0 +1,152 @@ +/************************************************************************************************************************ +Entity module. + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.entity; + +import bubel.ecs.system; +import bubel.ecs.manager; +public import bubel.ecs.traits : becsID; + +/************************************************************************************************************************ +Entity ID structure. Used as reference to Entity. Pointer to entity should be ever used to store entity reference! +*/ +struct EntityID +{ + ///Index to entity in IDManager. + uint id; + ///Counter required for reusing ID. + uint counter; +} + +/************************************************************************************************************************ +Structure of Entity. It's have only ID, but have full konwlege to get to components memory (If pointer to it is proper). +*/ +struct Entity +{ + ///Entity ID. + EntityID id; + + /************************************************************************************************************************ + Get specified component. If component doesn't exist function retun null. Pointer is valid only before next "commit()", "begin()" or "end()" + function is called. Returned pointer shouldn't be used to store reference to entity data. + */ + T* getComponent(T)() const + { + /*EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(&this); + EntityManager.EntityInfo* info = block.type_info; + if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) + return null; + + return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof);*/ + return cast(T*)getComponent(becsID!T); + } + + export void* getComponent(ushort component_id) const + { + EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(&this); + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0) + return null; + + return (cast(void*)block + info.deltas[component_id] + block.entityIndex(&this) * gEntityManager.components[component_id].size); + } + + export bool hasComponent(ushort component_id) const + { + EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(&this); + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; + return true; + } + + export EntityMeta getMeta() const + { + EntityMeta meta; + meta.block = gEntityManager.getMetaData(&this); + meta.index = meta.block.entityIndex(&this); + return meta; + } +} + +struct EntityMeta +{ + EntityManager.EntitiesBlock* block; + ushort index; + + T* getComponent(T)() const + { + /*const (EntityManager.EntityInfo)* info = block.type_info; + if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) + return null; + return cast(T*)(cast(void*)block + info.deltas[T.component_id] + index * T.sizeof);*/ + return cast(T*)getComponent(becsID!T); + } + + export void* getComponent(ushort component_id) const + { + const (EntityManager.EntityInfo)* info = block.type_info; + + if (component_id >= info.deltas.length || info.deltas[component_id] == 0) + return null; + + return (cast(void*)block + info.deltas[component_id] + index * gEntityManager.components[component_id].size); + } + + export bool hasComponent(ushort component_id) const + { + const EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; + return true; + } +} + +/************************************************************************************************************************ +Entity template structure. + +Entity contain whole information needed to create new entity. Allocating EntityTemplate is considered as more expensive operation +than adding entity. Whole components memory is stored in EntityTemplate and is copyied to newly added entity. +If you want to place several entity with small difference in data then you should take pointer to component and change it before every +entity addition. + +There is no restriction about number of allocated templates. Single template can be used from multiple threads, but if you +want to changes some components data before add entity (entity position for example) it's better to use multiple templates. +*/ +export struct EntityTemplate +{ + ///Entity components data + ubyte[] entity_data; + ///Pointer to entity type info. + EntityManager.EntityInfo* info; + + /************************************************************************************************************************ + Get specified component. If component doesn't exist function return null. Returned pointer is valid during EntityTemplate lifetime. + */ + T* getComponent(T)() nothrow @nogc + { + if(becsID!T >= info.tmpl_deltas.length || info.tmpl_deltas[becsID!T] == ushort.max)return null; + return cast(T*)(entity_data.ptr + info.tmpl_deltas[becsID!T]); + } + + /************************************************************************************************************************ + Get specified component. If component doesn't exist function return null. Returned pointer is valid during EntityTemplate lifetime. + */ + export void* getComponent(ushort component_id) const nothrow @nogc + { + if(component_id >= info.tmpl_deltas.length || info.tmpl_deltas[component_id] == ushort.max)return null; + return cast(void*)(entity_data.ptr + info.tmpl_deltas[component_id]); + } +} + +/************************************************************************************************************************ +ComponentRef contain component ID and pointer to it. It used to add component data to entity. +*/ +export struct ComponentRef +{ + ///pointer to component + void* ptr; + ///component index + ushort component_id; +} diff --git a/source/bubel/ecs/events.d b/source/bubel/ecs/events.d new file mode 100644 index 0000000..11816a1 --- /dev/null +++ b/source/bubel/ecs/events.d @@ -0,0 +1,193 @@ +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.events; + +import bubel.ecs.block_allocator; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; +import bubel.ecs.traits : becsID; + +import std.algorithm.comparison : max; + +package struct EventManager +{ + + void initialize(EntityManager* m) nothrow @nogc + { + allocator = BlockAllocator(events_block_size, events_blocks_in_allocation); + event_block_alloc_mutex = Mallocator.make!Mutex; + event_block_alloc_mutex.initialize(); + manager = m; + } + + void destroy() nothrow @nogc + { + if (event_block_alloc_mutex) + { + event_block_alloc_mutex.destroy(); + Mallocator.dispose(event_block_alloc_mutex); + event_block_alloc_mutex = null; + } + } + + export void sendEvent(Ev)(EntityID id, Ev event, uint thread_id = 0) nothrow @nogc + { + uint block_id = current_index + thread_id; + + EventData* data = &events[becsID!Ev]; + EventBlock* block = data.blocks[block_id]; + //EntityManager.EventInfo* info = &manager.events[Ev.event_id]; + //event.entity_id = id; + + if (block is null) + { + event_block_alloc_mutex.lock(); + block = cast(EventBlock*) allocator.getBlock(); + event_block_alloc_mutex.unlock(); + + *block = EventBlock(); + data.first_blocks[block_id] = block; + data.blocks[block_id] = block; + } + + if (block.count >= data.max_events) + { + event_block_alloc_mutex.lock(); + EventBlock* new_block = cast(EventBlock*) allocator.getBlock(); + event_block_alloc_mutex.unlock(); + + *new_block = EventBlock(); + block.next = new_block; + block = new_block; + data.blocks[block_id] = block; + } + + uint size = Ev.sizeof + EntityID.sizeof; + void* ptr = cast(void*) block + data.data_offset + block.count * size; + *cast(EntityID*)ptr = id; + *cast(Ev*)(ptr + EntityID.sizeof) = event; + //Ev* event_array = cast(Ev*)(cast(void*) block + data.data_offset); + //event_array[block.count] = event; + block.count++; + } + + void swapCurrent() nothrow @nogc + { + uint threads_count = cast(uint) manager.threads.length; + if (current_index == 0) + current_index = threads_count; + else + current_index = 0; + + foreach (ref event; events) + { + foreach (ref first_block; event.first_blocks[current_index + .. current_index + threads_count]) + { + EventBlock* block = first_block; + while (block) + { + EventBlock* to_dispose = block; + block = block.next; + allocator.freeBlock(to_dispose); + } + first_block = null; + } + foreach (ref block; event.blocks[current_index .. current_index + threads_count]) + { + block = null; + } + } + } + + void clearEvents() nothrow @nogc + { + //uint threads_count = cast(uint)manager.threads.length; + foreach (ref event; events) + { + foreach (ref first_block; event.first_blocks) + { + EventBlock* block = first_block; + while (block) + { + EventBlock* to_dispose = block; + block = block.next; + allocator.freeBlock(to_dispose); + } + first_block = null; + } + foreach (ref block; event.blocks) + { + block = null; + } + } + } + + void allocateData(uint threads_count) nothrow @nogc + { + disposeData(); + events = Mallocator.makeArray!EventData(manager.events.length); + foreach (i, ref event; events) + { + event.blocks = Mallocator.makeArray!(EventBlock*)(threads_count * 2); + event.first_blocks = Mallocator.makeArray!(EventBlock*)(threads_count * 2); + event.data_offset = EventBlock.sizeof; //manager.events[i]. + manager.alignNum(event.data_offset, manager.events[i].alignment); + + uint size = manager.events[i].size + EntityID.sizeof; + event.max_events = cast(ushort)( + (events_block_size - event.data_offset) / size); + } + } + + private void disposeData() nothrow @nogc + { + clearEvents(); + if (events) + { + foreach (ref event; events) + { + Mallocator.dispose(event.blocks); + Mallocator.dispose(event.first_blocks); + } + Mallocator.dispose(events); + } + allocator.freeMemory(); + } + + ~this() nothrow @nogc + { + disposeData(); + } + + ///Single page size. Must be power of two. + enum events_block_size = 1 << 14; + ///Number of pages in block. + enum events_blocks_in_allocation = 128; + + struct EventBlock + { + EventBlock* next; + ushort count = 0; + } + + struct EventData + { + ushort data_offset; + ushort max_events; + EventBlock*[] blocks; + EventBlock*[] first_blocks; + + //EventBlock*[] current_blocks; + } + + uint current_index = 0; + EventData[] events; + Mutex* event_block_alloc_mutex; + + BlockAllocator allocator; + EntityManager* manager; +} diff --git a/import/ecs/hash_map.di b/source/bubel/ecs/hash_map.d old mode 100644 new mode 100755 similarity index 65% rename from import/ecs/hash_map.di rename to source/bubel/ecs/hash_map.d index d621ad8..7ba6137 --- a/import/ecs/hash_map.di +++ b/source/bubel/ecs/hash_map.d @@ -1,63 +1,101 @@ -// D import file generated from 'source\ecs\hash_map.d' -module ecs.hash_map; +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.hash_map; + import std.traits; -import ecs.vector; -import ecs.traits; + +import bubel.ecs.vector; +import bubel.ecs.traits; + enum doNotInline = "version(DigitalMars)pragma(inline,false);version(LDC)pragma(LDC_never_inline);"; + private enum HASH_EMPTY = 0; -private enum HASH_DELETED = 1; -private enum HASH_FILLED_MARK = ulong(1) << 8 * (ulong).sizeof - 1; -export ulong defaultHashFunc(T)(auto ref T t) +private enum HASH_DELETED = 0x1; +private enum HASH_FILLED_MARK = ulong(1) << 8 * ulong.sizeof - 1; + +export ulong defaultHashFunc(T)(auto ref T t) nothrow @nogc { - static if (isIntegral!T) + static if (isIntegral!(T)) { return hashInt(t); } else { - return hashInt(t.hashOf); + static if(isArray!T)return hashInt(hash((cast(byte*)t.ptr)[0 .. t.length * ForeachType!(T).sizeof])); + else return hashInt(hash((cast(byte*)&t)[0 .. T.sizeof])); //hashInt(t.hashOf); // hashOf is not giving proper distribution between H1 and H2 hash parts } } -export nothrow @nogc @safe ulong hashInt(ulong x); + +export ulong hash(byte[] array) nothrow @nogc +{ + ulong hash = 0; + + foreach(c;array) + hash = c + (hash << 6) + (hash << 16) - hash; + + return hash; +} + +// Can turn bad hash function to good one +export ulong hashInt(ulong x) nothrow @nogc @safe +{ + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + x = x ^ (x >> 31); + return x; +} + struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { alias Key = KeyPar; alias Value = ValuePar; +nothrow: + enum rehashFactor = 0.75; enum size_t getIndexEmptyValue = size_t.max; + static struct KeyVal { Key key; Value value; } + static struct Bucket { ulong hash; KeyVal keyValue; } - Vector!Bucket elements; - size_t length; + + Vector!Bucket elements; // Length should be always power of 2 + size_t length; // Used to compute loadFactor size_t markerdDeleted; + export void clear() { elements.clear(); length = 0; markerdDeleted = 0; } + export void reset() { elements.reset(); length = 0; markerdDeleted = 0; } + export bool isIn(ref Key el) { return getIndex(el) != getIndexEmptyValue; } + export bool isIn(Key el) { return getIndex(el) != getIndexEmptyValue; } + export Value* getPtr()(auto ref Key k) { size_t index = getIndex(k); @@ -70,16 +108,20 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) return &elements[index].keyValue.value; } } + export ref Value get()(auto ref Key k) { size_t index = getIndex(k); assert(index != getIndexEmptyValue); return elements[index].keyValue.value; } - deprecated("Use get with second parameter.") export auto ref Value getDefault()(auto ref Key k, auto ref Value defaultValue) + + deprecated("Use get with second parameter.") export auto ref Value getDefault()( + auto ref Key k, auto ref Value defaultValue) { return get(k, defaultValue); } + export auto ref Value get()(auto ref Key k, auto ref Value defaultValue) { size_t index = getIndex(k); @@ -92,6 +134,7 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) return elements[index].keyValue.value; } } + export ref Value getInsertDefault()(auto ref Key k, auto ref Value defaultValue) { size_t index = getIndex(k); @@ -102,7 +145,9 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) index = getIndex(k); assert(index != getIndexEmptyValue); return elements[index].keyValue.value; + } + export bool tryRemove(Key el) { size_t index = getIndex(el); @@ -115,35 +160,43 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) markerdDeleted++; return true; } + export void remove(Key el) { bool ok = tryRemove(el); assert(ok); } + export ref Value opIndex()(auto ref Key key) { return get(key); } + export void opIndexAssign()(auto ref Value value, auto ref Key key) { add(key, value); } + export void add()(auto ref Key key, auto ref Value value) { size_t index = getIndex(key); if (index != getIndexEmptyValue) { elements[index].keyValue.value = value; - return ; + return; } - if (getLoadFactor(length + 1) > rehashFactor || getLoadFactor(length + markerdDeleted) > rehashFactor) + + if (getLoadFactor(length + 1) > rehashFactor + || getLoadFactor(length + markerdDeleted) > rehashFactor) { rehash(); } length++; + immutable ulong hash = hashFunc(key) | HASH_FILLED_MARK; immutable size_t rotateMask = elements.length - 1; - index = hash & rotateMask; + index = hash & rotateMask; // Starting point + while (true) { Bucket* gr = &elements[index]; @@ -156,31 +209,43 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) gr.hash = hash; gr.keyValue.key = key; gr.keyValue.value = value; - return ; + return; } + index++; index = index & rotateMask; } } + + // For debug + //int numA; + //int numB; + export size_t getIndex(Key el) { return getIndex(el); } + export size_t getIndex(ref Key el) { mixin(doNotInline); + immutable size_t groupsLength = elements.length; if (groupsLength == 0) { return getIndexEmptyValue; } + immutable ulong hash = hashFunc(el) | HASH_FILLED_MARK; immutable size_t rotateMask = groupsLength - 1; - size_t index = hash & rotateMask; + size_t index = hash & rotateMask; // Starting point + + //numA++; while (true) { + //numB++; Bucket* gr = &elements[index]; - if (gr.hash == hash && (gr.keyValue.key == el)) + if (gr.hash == hash && gr.keyValue.key == el) { return index; } @@ -188,23 +253,29 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return getIndexEmptyValue; } + index++; index = index & rotateMask; } + } + export float getLoadFactor(size_t forElementsNum) { if (elements.length == 0) { return 1; } - return cast(float)forElementsNum / elements.length; + return cast(float) forElementsNum / (elements.length); } - export void rehash() + + export void rehash()() { mixin(doNotInline); + // Get all elements Vector!KeyVal allElements; allElements.reserve(elements.length); + foreach (ref Bucket el; elements) { if ((el.hash & HASH_FILLED_MARK) == 0) @@ -214,11 +285,15 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) } el.hash = HASH_EMPTY; allElements ~= el.keyValue; + } + if (getLoadFactor(length + 1) > rehashFactor) - { - elements.length = (elements.length ? elements.length : 4) << 1; + { // Reallocate + elements.length = (elements.length ? elements.length : 4) << 1; // Power of two, initially 8 elements } + + // Insert elements foreach (i, ref el; allElements) { add(el.key, el.value); @@ -226,6 +301,8 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) length = allElements.length; markerdDeleted = 0; } + + // foreach support export int opApply(DG)(scope DG dg) { int result; @@ -239,90 +316,59 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { result = dg(gr.keyValue.key); } + else static if (isForeachDelegateWithTypes!(DG, Value)) + { + result = dg(gr.keyValue.value); + } + else static if (isForeachDelegateWithTypes!(DG, Key, Value)) + { + result = dg(gr.keyValue.key, gr.keyValue.value); + } else { - static if (isForeachDelegateWithTypes!(DG, Value)) - { - result = dg(gr.keyValue.value); - } - else - { - static if (isForeachDelegateWithTypes!(DG, Key, Value)) - { - result = dg(gr.keyValue.key, gr.keyValue.value); - } - else - { - static assert(0); - } - } + static assert(0); } if (result) break; + } + return result; } - export int byKey(scope int delegate(Key k) dg) + + export int byKey(scope int delegate(ref Key k) dg) { int result; foreach (ref Key k; this) { - result = dg(k); + result = (cast(int delegate(ref Key k) nothrow @nogc)dg)(k); if (result) break; } return result; } - export int byValue(scope int delegate(ref Value k) dg) + + export int byValue(scope int delegate(ref Value v) dg) { int result; foreach (ref Value v; this) { - result = dg(v); + result = (cast(int delegate(ref Value v) nothrow @nogc)dg)(v); if (result) break; } return result; } + export int byKeyValue(scope int delegate(ref Key k, ref Value v) dg) { int result; foreach (ref Key k, ref Value v; this) { - result = dg(k, v); + result = (cast(int delegate(ref Key k, ref Value v) nothrow @nogc)dg)(k, v); if (result) break; } return result; } - import std.format : FormatSpec, formatValue; - export void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) - { - formatValue(sink, '[', fmt); - foreach (ref k, ref v; &byKeyValue) - { - formatValue(sink, k, fmt); - formatValue(sink, ':', fmt); - formatValue(sink, v, fmt); - formatValue(sink, ", ", fmt); - } - formatValue(sink, ']', fmt); - } -} -static void dumpHashMapToJson(T)(ref T map, string path = "HashMapDump.json") -{ - Vector!char data; - import std.file; - import mutils.serializer.json; - JSONSerializer.instance.serialize!(Load.no)(map, data); - std.file.write(path, data[]); -} -static void printHashMap(T)(ref T map) -{ - import std.stdio; - writeln(T.stringof, " dump:\x0a"); - foreach (k, v; &map.byKeyValue) - { - writefln("%20s : %20s", k, v); - } } diff --git a/source/bubel/ecs/id_manager.d b/source/bubel/ecs/id_manager.d new file mode 100644 index 0000000..2054cbb --- /dev/null +++ b/source/bubel/ecs/id_manager.d @@ -0,0 +1,237 @@ +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.id_manager; + +import bubel.ecs.entity; +import bubel.ecs.std; +import bubel.ecs.vector; + +import bubel.ecs.atomic; +import core.stdc.string : memcpy; + +/************************************************************************************************************************ +IDManager is responsible for assignment and removing IDs. IDs are unique throughtout a whole duration of the program. +*/ +struct IDManager +{ + /************************************************************************************************************************ + Get new ID. + */ + EntityID getNewID() nothrow @nogc + { + int current = m_stack_top.atomicOp!"-="(1) + 1; + if (current < 0) + { + uint add_id = m_last_id.atomicOp!"+="(1) - 1; + + if (add_id >= m_ids_array.length) + { + uint local_id = add_id - cast(uint) m_ids_array.length; + uint block_id = local_id >> 16; + if (block_id >= m_blocks_count) + { + add_mutex.lock(); + if (block_id >= m_blocks_count) + { + m_blocks[m_blocks_count].alloc(); + m_blocks_count++; + } + add_mutex.unlock(); + } + } + + EntityID id; + id.id = add_id; + id.counter = 0; + return id; + } + + uint index = m_free_stack[current]; + EntityID id; + id.id = index; + id.counter = m_ids_array[index].counter; + return id; + } + + /************************************************************************************************************************ + Release ID. + */ + void releaseID(EntityID id) nothrow @nogc + { + optimize(); + Data* data = &m_ids_array[id.id]; + if (data.counter != id.counter) + return; + data.counter++; + data.entity = null; + + m_stack_top.atomicOp!"+="(1); + m_free_stack[m_stack_top] = id.id; + } + + /************************************************************************************************************************ + Update pointer to entity. The purpose of this function is to ensure that pointer to entity is always correct. + */ + void update(ref Entity entity) nothrow @nogc + { + if (entity.id.id >= cast(uint) m_ids_array.length) + { + uint local_id = entity.id.id - cast(uint) m_ids_array.length; + uint block_id = local_id >> 16; + local_id -= block_id << 16; + m_blocks[block_id].data[local_id].entity = &entity; + } + else //if (entity.id.counter == m_ids_array[entity.id.id].counter) + m_ids_array[entity.id.id].entity = &entity; + } + + /************************************************************************************************************************ + Returns pointer to entity. + */ + export Entity* getEntityPointer(EntityID id) nothrow @nogc + { + if (id.id >= m_ids_array.length) + { + uint local_id = id.id - cast(uint) m_ids_array.length; + uint block_id = local_id >> 16; + assert(block_id < m_blocks_count); + if (block_id >= m_blocks_count) + return null; + local_id -= block_id << 16; + if (m_blocks[block_id].data[local_id].counter != id.counter) + return null; + return m_blocks[block_id].data[local_id].entity; + } + + Data* data = &m_ids_array[id.id]; + if (data.counter != id.counter) + return null; + else + return data.entity; + } + + /************************************************************************************************************************ + Check if entity with specified ID exist. + */ + export bool isExist(EntityID id) nothrow @nogc + { + if (id.id >= m_ids_array.length) + return false; + Data* data = &m_ids_array[id.id]; + if (data.entity is null) + return false; + return data.counter == id.counter; + } + + /************************************************************************************************************************ + Initialize manager. + */ + void initialize() nothrow @nogc + { + m_ids_array = Mallocator.makeArray!Data(65536); + m_free_stack = Mallocator.makeArray!uint(65536); + m_blocks = Mallocator.makeArray!Block(64); + foreach (ref block; m_blocks) + block = Block(); + m_blocks_count = 1; + m_blocks[0].alloc(); + + add_mutex = Mallocator.make!Mutex(); + add_mutex.initialize(); + + getNewID(); + optimize(); + } + + /************************************************************************************************************************ + Free manager memory. + */ + void deinitialize() @trusted @nogc nothrow + { + if (m_ids_array) + Mallocator.dispose(m_ids_array); + if (m_free_stack) + Mallocator.dispose(m_free_stack); + if (m_blocks) + { + foreach (ref block; m_blocks) + { + if (block.data) + block.free(); + } + Mallocator.dispose(m_blocks); + } + if (add_mutex) + { + add_mutex.destroy(); + Mallocator.dispose(add_mutex); //cast(void*)add_mutex); //workaround for compiler bug + add_mutex = null; + } + } + + /************************************************************************************************************************ + Optimize memory. Must be called if any ID was added and some ID will be removed. + */ + void optimize() nothrow @nogc + { + if (m_stack_top < -1) + m_stack_top = -1; + if (m_last_id > m_ids_array.length) + { + uint begin = cast(uint) m_ids_array.length; + + m_ids_array = Mallocator.resizeArray(m_ids_array, begin + (m_blocks_count << 16)); + m_free_stack = Mallocator.resizeArray(m_free_stack, m_ids_array.length); + + foreach (block; m_blocks[0 .. m_blocks_count - 1]) + { + memcpy(cast(void*) m_ids_array.ptr + begin * Data.sizeof, + block.data.ptr, 65536 * Data.sizeof); + begin += 65536; + } + memcpy(cast(void*) m_ids_array.ptr + begin * Data.sizeof, + m_blocks[m_blocks_count - 1].data.ptr, (m_last_id - begin) * Data.sizeof); + foreach (ref block; m_blocks[1 .. m_blocks_count]) + block.free(); + m_blocks_count = 1; + } + } + + private static struct Block + { + void alloc() nothrow @nogc + { + assert(data is null); + data = Mallocator.makeArray!Data(65536); + } + + void free() nothrow @nogc + { + assert(data !is null); + Mallocator.dispose(data); + data = null; + } + + Data[] data = null; //65536 + } + + private static struct Data + { + uint counter = 0; + //uint next_id = uint.max; + Entity* entity = null; + } + +private: + Mutex* add_mutex; + + Data[] m_ids_array = null; + uint m_blocks_count = 0; + Block[] m_blocks; + uint[] m_free_stack = null; + + align(64) shared uint m_last_id = 0; + align(64) shared int m_stack_top = -1; +} diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d new file mode 100644 index 0000000..b5220f4 --- /dev/null +++ b/source/bubel/ecs/manager.d @@ -0,0 +1,3888 @@ +/************************************************************************************************************************ +Most important module. Almost every function is called from EntityManager. + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.manager; + +import std.algorithm : max; +import std.conv : to; +import std.traits; + +import bubel.ecs.system; //not ordered as forward reference bug workaround +import bubel.ecs.block_allocator; +import bubel.ecs.entity; +import bubel.ecs.events; +import bubel.ecs.hash_map; +import bubel.ecs.id_manager; +import bubel.ecs.simple_vector; +import bubel.ecs.std; +import bubel.ecs.traits; +import bubel.ecs.vector; +import bubel.ecs.atomic; + +alias SerializeVector = bubel.ecs.vector.Vector!ubyte; + +///Global EntityManager used for everything. +export __gshared EntityManager* gEntityManager = null; + +version(D_BetterC) version = NoDRuntime; + +/************************************************************************************************************************ +Entity manager is responsible for everything. + +Entity manager can be in three states: + - registration: time between beginRegister() and endRegister() calls. + - update: time between being() and end() calls. + - default: when it's not in registration or update time + +Manager can be only in one state simultaneously. + +Manager must be initialized before use. There is global instance of EntityManager: gEntityManager or gEntityManager as alias. + +Registration process consist of registration of passes, systems, entities and events. + +Pass is group of system which should be used inside one update() call. Passes are added as name (string) and can be referenced by name or id. +System is structure responsible for update of specified group of entities. System consist of EntitiesData structure which contain components used +by system and some callback. Main callback is onUpdate() which is called by update() entity manager function. Other callbacks are used as listeners for +adding entites, tracking system lifetime and events handling. + +Component is basicly small fraction of data which is considered to be used as whole. In best scenario every byte of component is used when it's refered to. +In practice sometimes it's better to join data into one component even if it's can be accessed separetly. +Events are structures with data used to handle events. Event can contain for exmaple one floating point number used as damage dealt to entity. +Entity is group of components. In memory entity is only ID which makes it's possible to take it's components. Components are grouped into chunks, and +grouped by component type so entity can be fracted in big memory chunk. + +There is two types of update: + - update(): function used to call update pass. + - updateMT(): function used to call update pass multithreaded. This call only generates jobs which must be called by user. + + WARNING! No fileds from EntityManager should be used directly, they are not private for special, advanced things which are not implemented in library. + So if you don't need anything special, simply use only EntityManager methods. +*/ +export struct EntityManager +{ + /************************************************************************************************************************ + Initialize ECS. + */ + export static void initialize(uint threads_count = 1, uint page_size = 32768, + uint block_pages_count = 128) + { + if (gEntityManager is null) + { + gEntityManager = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count); + + with (gEntityManager) + { + UpdatePass* pass = Mallocator.make!UpdatePass; + pass.name = Mallocator.makeArray(cast(char[]) "update"); + passes.add(pass); + passes_map.add(cast(const(char)[]) pass.name, cast(ushort)(passes.length - 1)); + } + } + } + + /************************************************************************************************************************ + Deinitialize and destroy ECS. This function release whole memory. + */ + export static void destroy() nothrow @nogc + { + if (gEntityManager is null) + return; + + with (gEntityManager) + { + foreach (ref system; systems) + { + system.destroy(); + } + + foreach (EntityInfo* info; &entities_infos.byValue) + { + //if(info.components)Mallocator.dispose(info.components); + + Mallocator.dispose(info); + } + + foreach (UpdatePass* pass; passes) + { + Mallocator.dispose(pass); + } + passes.clear(); + + foreach (ComponentInfo info; components) + { + if (info.init_data) + Mallocator.dispose(info.init_data); + } + + foreach (EventInfo info; events) + { + if (info.callers) + Mallocator.dispose(info.callers); + } + + foreach (name; &components_map.byKey) + { + if (name) + Mallocator.dispose(name); + } + } + + Mallocator.dispose(gEntityManager); + gEntityManager = null; + } + + /************************************************************************************************************************ + Begin registering process. Every register function should be called between beginRegister() and endRegister(). + */ + export void beginRegister() nothrow @nogc + { + assert(!register_state, "beginRegister() can't be called twice before endRegister();"); + register_state = true; + + foreach (pass; passes) + { + foreach (caller; pass.system_callers) + { + Mallocator.dispose(caller); + } + pass.system_callers.clear(); + } + } + + /************************************************************************************************************************ + End registering process. Every register function should be called between beginRegister() and endRegister(). + */ + export void endRegister() + { + assert(register_state, "beginRegister() should be called before endRegister();"); + register_state = false; + + foreach (ref info; &entities_infos.byValue) + { + if (info.systems) + Mallocator.dispose(info.systems); + info.systems = Mallocator.makeArray!bool(systems.length); + } + + foreach (ref system; systems) + { + if (system.isAlive() == false) + continue; + if (system.m_empty) + { + if (system.m_update) + addSystemCaller(system.id); + continue; + } + if (system.m_update is null) + { + if (system.m_add_entity || system.m_remove_entity + || system.m_change_entity || system.m_event_callers.length) + { + foreach (info; &entities_infos.byValue) + { + connectListenerToEntityInfo(*info, system.id); + } + } + continue; + } + + /*bool added = false; + foreach (i, caller; passes[system.m_pass].system_callers) + { + if (systems[caller.system_id].priority > system.priority) + { + SystemCaller* sys_caller = Mallocator.make!SystemCaller; + sys_caller.system_id = system.id; + sys_caller.job_group.caller = sys_caller; + system.m_any_system_caller = sys_caller; + passes[system.m_pass].system_callers.add(sys_caller, i); + added = true; + break; + } + } + if (!added) + { + SystemCaller* sys_caller = Mallocator.make!SystemCaller; + sys_caller.system_id = system.id; + sys_caller.job_group.caller = sys_caller; + system.m_any_system_caller = sys_caller; + passes[system.m_pass].system_callers.add(sys_caller); + }*/ + addSystemCaller(system.id); + + foreach (info; &entities_infos.byValue) + { + addSystemCaller(*info, system.id); + //info.systems[system.id] = true; + } + } + + event_manager.allocateData(cast(uint) threads.length); + + foreach (ref info; events) + { + Mallocator.dispose(info.callers); + } + + ushort[] event_callers = (cast(ushort*) alloca(ushort.sizeof * events.length))[0 + .. events.length]; + foreach (ref caller; event_callers) + caller = 0; + + foreach (ref system; systems) + { + if (system.isAlive() == false) + continue; + foreach (caller; system.m_event_callers) + { + event_callers[caller.id]++; + } + } + + foreach (i, ref info; events) + { + info.callers = Mallocator.makeArray!(EventCaller)(event_callers[i]); + } + + foreach (ref caller; event_callers) + caller = 0; + + foreach (ref system; systems) + { + if (system.isAlive() == false) + continue; + foreach (caller; system.m_event_callers) + { + events[caller.id].callers[event_callers[caller.id]].callback = caller.callback; + events[caller.id].callers[event_callers[caller.id]].system = &system; + event_callers[caller.id]++; + } + } + + extern (C) static int comapreEventCaller(const void* a, const void* b) nothrow @nogc + { + EventCaller _a = *cast(EventCaller*) a; + EventCaller _b = *cast(EventCaller*) b; + if (_a.system.priority < _b.system.priority) + return -1; + else if (_a.system.priority == _b.system.priority) + return 0; + else + return 1; + } + + foreach (ref event; events) + { + qsort(event.callers.ptr, event.callers.length, + EventCaller.sizeof, &comapreEventCaller); + } + //qsort(event_callers.ptr, event_callers.length, EventInfo.sizeof, &compareUShorts); + + foreach (EntityInfo* info; &entities_infos.byValue) + { + generateListeners(info); + } + + generateDependencies(); + } + + /************************************************************************************************************************ + *Default constructor. + */ + export this(uint threads_count, uint page_size, uint block_pages_count) nothrow @nogc + { + if (threads_count == 0) + threads_count = 1; + threads = Mallocator.makeArray!ThreadData(threads_count); + + m_page_size = page_size; + m_pages_in_block = block_pages_count; + + id_manager.initialize(); + event_manager.initialize(&this); + + allocator = BlockAllocator(m_page_size, m_pages_in_block); + + //add_mutex = Mallocator.make!Mutex; + entity_block_alloc_mutex = Mallocator.make!Mutex; + entity_block_alloc_mutex.initialize(); + //event_manager = EventManager(this); + //event_manager.manager = this; + } + + export ~this() nothrow @nogc + { + id_manager.deinitialize(); + event_manager.destroy(); + + if (threads) + Mallocator.dispose(threads); + if (entity_block_alloc_mutex) + { + entity_block_alloc_mutex.destroy(); + Mallocator.dispose(entity_block_alloc_mutex); + entity_block_alloc_mutex = null; + } + + allocator.freeMemory(); + } + + /************************************************************************************************************************ + Unregister given system form EntityManager. + */ + void unregisterSystem(Sys)() + { + ushort system_id = becsID!Sys; + System* system = getSystem(system_id); + + unregisterSystem(system); + } + + /************************************************************************************************************************ + Unregister given system form EntityManager. + */ + export void unregisterSystem(System* system) nothrow @nogc + { + assert(register_state, "unregisterSystem must be called between beginRegister() and endRegister()."); + assert(system !is null, "System was not registered"); + assert(system.isAlive, "System already unregistered"); + + //disable, destroy and dispose user created system but keep name and other data + system.destroySystemData(); + } + + /************************************************************************************************************************ + Same as "void registerSystem(Sys)(int priority, int pass = 0)" but use pass name instead of id. + */ + void registerSystem(Sys)(int priority, const(char)[] pass_name) + { + ushort pass = passes_map.get(pass_name, ushort.max); + version (NoDRuntime) + assert(pass != ushort.max, "Update pass doesn't exist."); + else + assert(pass != ushort.max, "Update pass (Name " ~ pass_name ~ ") doesn't exist."); + registerSystem!(Sys)(priority, pass); + } + + /************************************************************************************************************************ + Register new System into EntityManager. This funcion generate glue between EntityManager and System. + Systems can be registered from external dynamic library, and can be registered after adding entities too. + System mustn't be registered before components which system want to use, in this case functions call assertion. + + Params: + priority = system priority. Priority determines order of execution of systems updates + pass = index of UpdatePass which sholud call system update + */ + void registerSystem(Sys)(int priority, ushort pass = 0) + { + //alias STC = ParameterStorageClass; + + assert(register_state, + "registerSystem must be called between beginRegister() and endRegister()."); + version (NoDRuntime) + assert(pass < passes.length, "Update pass doesn't exist."); + else + assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist."); + + // enum SystemName = fullyQualifiedName!Sys; + enum SystemName = fullName!Sys; + //enum SystemName = Sys.stringof; + + System system = System(); + system.m_pass = pass; + + // static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort)) + // { + // static assert(0, "Add \"mixin ECS.System;\" in top of system structure;"); + // } + + static if (!(hasMember!(Sys, "EntitiesData"))) + { + static assert(0, "System should gave \"EntitiesData\" struct for input components"); + } + + static if (hasMember!(Sys, "handleEvent")) + { + static void callEventHandler(Type)(ref EventCallData data) + { + Sys* data_system = cast(Sys*) data.system_pointer; + + Type* event = cast(Type*) data.event; + data_system.handleEvent(data.entity, *event); + } + + void setEventCallers(Sys)(ref System system) + { + enum event_handlers_num = __traits(getOverloads, Sys, "handleEvent").length; + System.EventCaller[] callers = (cast(System.EventCaller*) alloca( + event_handlers_num * System.EventCaller.sizeof))[0 .. event_handlers_num]; + int i = 0; + + foreach (j, func; __traits(getOverloads, Sys, "handleEvent")) + { + alias Params = Parameters!(__traits(getOverloads, Sys, "handleEvent")[j]); + static if (Params.length == 2 && is(Params[0] == Entity*)) + { + alias EventParamType = Params[1]; + enum EventName = fullName!(Unqual!(EventParamType)); + // enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; + ushort evt = events_map.get(cast(char[]) EventName, ushort.max); + assert(evt != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing event \"" ~ EventName ~ "\"."); + + callers[i].callback = cast(void*)&callEventHandler!(EventParamType); + callers[i].id = becsID!EventParamType; + i++; + } + } + + system.m_event_callers = Mallocator.makeArray(callers[0 .. i]); + } + + static if (__traits(hasMember, Sys, "handleEvent")) + { + setEventCallers!(Sys)(system); + } + } + + static struct CompInfo + { + string name; + string type; + } + + static struct ComponentsCounts + { + //one more than should be to prevent null arrays (zero length arrays) + uint readonly = 1; + uint mutable = 1; + uint excluded = 1; + uint optional = 1; + uint req = 1; + uint readonly_dep = 1; + uint writable_dep = 1; + } + + static ComponentsCounts getComponentsCounts() + { + ComponentsCounts components_counts; + + bool checkExcludedComponentsSomething(Sys)() + { + return __traits(compiles, allSameType!(string, typeof(Sys.ExcludedComponents))) && allSameType!(string, + typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents); + } + + foreach (member; __traits(allMembers, Sys.EntitiesData)) + { + alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); + if (member == "length" || member == "thread_id" || member == "job_id" + || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) + { + //continue; + } + else + { + string name; + static if (isArray!MemberType) + { // Workaround. This code is never called with: not an array type, but compiler prints an error + // name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));//.stringof; + name = fullName!(Unqual!(typeof(MemberType.init[0]))); + } + + bool is_optional; + bool is_read_only; + + if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) + { + is_read_only = true; + } + + foreach (att; __traits(getAttributes, __traits(getMember, + Sys.EntitiesData, member))) + { + if (att == "optional") + { + is_optional = true; + } + if (att == "readonly") + { + is_read_only = true; + } + } + if (is_read_only) + { + components_counts.readonly++; + } + else + { + components_counts.mutable++; + } + if (is_optional) + { + components_counts.optional++; + } + else + { + components_counts.req++; + } + } + } + + static if (__traits(hasMember, Sys, "ExcludedComponents")) + { + static if (is(Sys.ExcludedComponents == enum)) + { + foreach (str; __traits(allMembers, Sys.ExcludedComponents)) + { + components_counts.excluded++; + } + } + else //static if (checkExcludedComponentsSomething!Sys) + { + foreach (str; Sys.ExcludedComponents) + { + components_counts.excluded++; + } + } + } + + static if (__traits(hasMember, Sys, "ReadOnlyDependencies")) + { + foreach (str; Sys.ReadOnlyDependencies) + { + components_counts.readonly_dep++; + } + } + + static if (__traits(hasMember, Sys, "WritableDependencies")) + { + foreach (str; Sys.WritableDependencies) + { + components_counts.writable_dep++; + } + } + + return components_counts; + } + + enum ComponentsCounts component_counts = getComponentsCounts(); + + static struct ComponentsIndices(ComponentsCounts counts) + { + CompInfo[] readonly() + { + return m_readonly[0 .. m_readonly_counter]; + } + + CompInfo[] mutable() + { + return m_mutable[0 .. m_mutable_counter]; + } + + CompInfo[] excluded() + { + return m_excluded[0 .. m_excluded_counter]; + } + + CompInfo[] optional() + { + return m_optional[0 .. m_optional_counter]; + } + + CompInfo[] req() + { + return m_req[0 .. m_req_counter]; + } + + CompInfo[] readonlyDeps() + { + return m_readonly_dep[0 .. m_readonly_dep_counter]; + } + + CompInfo[] writableDeps() + { + return m_writable_dep[0 .. m_writable_dep_counter]; + } + + void addReadonly(CompInfo info) + { + m_readonly[m_readonly_counter++] = info; + } + + void addMutable(CompInfo info) + { + m_mutable[m_mutable_counter++] = info; + } + + void addExcluded(CompInfo info) + { + m_excluded[m_excluded_counter++] = info; + } + + void addOptional(CompInfo info) + { + m_optional[m_optional_counter++] = info; + } + + void addReq(CompInfo info) + { + m_req[m_req_counter++] = info; + } + + void addReadonlyDep(CompInfo info) + { + m_readonly_dep[m_readonly_dep_counter++] = info; + } + + void addWritableDep(CompInfo info) + { + m_writable_dep[m_writable_dep_counter++] = info; + } + + CompInfo[counts.readonly] m_readonly; + CompInfo[counts.mutable] m_mutable; + CompInfo[counts.excluded] m_excluded; + CompInfo[counts.optional] m_optional; + CompInfo[counts.req] m_req; + CompInfo[counts.readonly_dep] m_readonly_dep; + CompInfo[counts.writable_dep] m_writable_dep; + + uint m_readonly_counter; + uint m_mutable_counter; + uint m_excluded_counter; + uint m_optional_counter; + uint m_req_counter; + uint m_readonly_dep_counter; + uint m_writable_dep_counter; + + string entites_array; + } + + static void allocateSystemComponents(ComponentsIndices!component_counts components_info)( + ref System system) + { + size_t req = components_info.req.length; + size_t opt = components_info.optional.length; + size_t excluded = components_info.excluded.length; + size_t read_only = components_info.readonly.length; + size_t writable = components_info.mutable.length; + size_t read_only_deps = components_info.readonlyDeps.length; + size_t writable_deps = components_info.writableDeps.length; + + if (req > 0) + system.m_components = Mallocator.makeArray!ushort(req); + if (opt > 0) + system.m_optional_components = Mallocator.makeArray!ushort(opt); + if (excluded > 0) + system.m_excluded_components = Mallocator.makeArray!ushort(excluded); + if (read_only > 0) + system.m_read_only_components = Mallocator.makeArray!ushort(read_only); + if (writable > 0) + system.m_writable_components = Mallocator.makeArray!ushort(writable); + if (read_only_deps > 0) + system.m_readonly_dependencies = Mallocator.makeArray!ushort(read_only_deps); + if (writable_deps > 0) + system.m_writable_dependencies = Mallocator.makeArray!ushort(writable_deps); + + } + + static ComponentsIndices!component_counts getComponentsInfo() + { + ComponentsIndices!component_counts components_info; + + bool checkExcludedComponentsSomething(Sys)() + { + return __traits(compiles, allSameType!(string, typeof(Sys.ExcludedComponents))) && allSameType!(string, + typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents); + } + + foreach (member; __traits(allMembers, Sys.EntitiesData)) + { + alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); + if (member == "length" || member == "thread_id" || member == "job_id" + || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) + { + if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) + components_info.entites_array = member; + //continue; + } + else + { + string name; + static if (isArray!MemberType) + { // Workaround. This code is never called with: not an array type, but compiler prints an error + // name = fullyQualifiedName!(Unqual!(ForeachType!MemberType)); + name = fullName!(Unqual!(typeof(MemberType.init[0]))); + //name = Unqual!(ForeachType!MemberType).stringof; + } + + bool is_optional; + bool is_read_only; + + if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) + { + is_read_only = true; + } + + foreach (att; __traits(getAttributes, __traits(getMember, + Sys.EntitiesData, member))) + { + if (att == "optional") + { + is_optional = true; + } + if (att == "readonly") + { + is_read_only = true; + } + } + if (is_read_only) + { + components_info.addReadonly(CompInfo(member, name)); + } + else + { + components_info.addMutable(CompInfo(member, name)); + } + if (is_optional) + { + components_info.addOptional(CompInfo(member, name)); + } + else + { + components_info.addReq(CompInfo(member, name)); + } + } + } + + static if (__traits(hasMember, Sys, "ExcludedComponents")) + { + static if (is(Sys.ExcludedComponents == enum)) + { + foreach (str; __traits(allMembers, Sys.ExcludedComponents)) + { + components_info.addExcluded(CompInfo(str, str)); + } + } + else //static if (checkExcludedComponentsSomething!Sys) + { + foreach (str; Sys.ExcludedComponents) + { + components_info.addExcluded(CompInfo(str.stringof, fullName!str)); + // components_info.addExcluded(CompInfo(str.stringof, str.stringof)); + } + + } + } + + static if (__traits(hasMember, Sys, "ReadOnlyDependencies")) + { + foreach (str; Sys.ReadOnlyDependencies) + { + components_info.addReadonlyDep(CompInfo(str, str)); + } + } + + static if (__traits(hasMember, Sys, "WritableDependencies")) + { + foreach (str; Sys.WritableDependencies) + { + components_info.addWritableDep(CompInfo(str, str)); + } + } + + return components_info; + } + + enum ComponentsIndices!component_counts components_info = getComponentsInfo(); + + static void genCompList(ref System system, ref HashMap!(char[], ushort) components_map) + { + + foreach (member; __traits(allMembers, Sys.EntitiesData)) + { + alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); + + static if (isFunction!(__traits(getMember, Sys.EntitiesData, member))) + static assert(0, "EntitiesData can't have any function!"); + else static if (member == "length") + { + static assert(isIntegral!(MemberType), + "EntitiesData 'length' member must be integral type."); + static assert(MemberType.sizeof > 1, + "EntitiesData 'length' member can't be byte or ubyte."); + } + else static if (member == "thread_id") + { + static assert(isIntegral!(MemberType), + "EntitiesData 'thread_id' member must be integral type."); + static assert(MemberType.sizeof > 1, + "EntitiesData 'thread_id' member can't be byte or ubyte."); + } + else static if (member == "job_id") + { + static assert(isIntegral!(MemberType), + "EntitiesData 'job_id' member must be integral type."); + static assert(MemberType.sizeof > 1, + "EntitiesData 'job_id' member can't be byte or ubyte."); + } + else static if (!(isArray!(MemberType))) + static assert(0, "EntitiesData members should be arrays of elements!"); + } + + //enum ComponentsIndices components_info = getComponentsInfo(); + allocateSystemComponents!(components_info)(system); + + foreach (iii, comp_info; components_info.req) + { + ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing component."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); + system.m_components[iii] = comp; + } + foreach (iii, comp_info; components_info.excluded) + { + ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing component."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); + system.m_excluded_components[iii] = comp; + } + foreach (iii, comp_info; components_info.optional) + { + ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing component."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); + system.m_optional_components[iii] = comp; + } + foreach (iii, comp_info; components_info.readonly) + { + ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing component."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); + system.m_read_only_components[iii] = comp; + } + foreach (iii, comp_info; components_info.mutable) + { + ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing component."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); + system.m_writable_components[iii] = comp; + } + } + + static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info, + EntitiesBlock* block, uint offset, uint entities_count, System* system) + { + //enum ComponentsIndices components_info = getComponentsInfo(); + + static if (components_info.entites_array) + { + __traits(getMember, input_data, components_info.entites_array) = ( + cast(Entity*) block.dataBegin())[offset .. entities_count]; + } + + static if (hasMember!(Sys.EntitiesData, "length")) + { + input_data.length = cast(typeof(input_data.length))(entities_count - offset); + } + + /*static if (hasMember!(Sys.EntitiesData, "thread_id")) + { + input_data.thread_id = cast(typeof(input_data.thread_id))threadID(); + }//*/ + + ///FIXME: should be "components_info.req()" but it's not compile with GCC + static foreach (iii, comp_info; components_info.m_req[0 + .. components_info.m_req_counter]) + { + __traits(getMember, input_data, comp_info.name) = ( + cast(typeof( + (typeof(__traits(getMember, Sys.EntitiesData, comp_info.name))).init[0] + )*)(cast(void*) block + info.deltas[system.m_components[iii]]) + )[offset .. entities_count]; + } + + static foreach (iii, comp_info; components_info.m_optional[0 + .. components_info.m_optional_counter]) + { + if (system.m_optional_components[iii] < info.deltas.length + && info.deltas[system.m_optional_components[iii]] != 0) + { + __traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember, + Sys.EntitiesData, comp_info.name)))*)(cast( + void*) block + info.deltas[system.m_optional_components[iii]]))[offset + .. entities_count]; + + } + } + } + + /*bool checkOnUpdateParams() + { + bool ret = false; + foreach (func; __traits(getOverloads, Sys, "onUpdate")) + { + if ((Parameters!(func)).length == 1 && is(Parameters!(func)[0] == Sys.EntitiesData)) + { + ret = true; + break; + } + } + return ret; + }*/ + + int getOnUpdateOverload()() + { + int ret = -1; + foreach (i, func; __traits(getOverloads, Sys, "onUpdate")) + { + if ((Parameters!(func)).length == 1 && is(Parameters!(func)[0] == Sys.EntitiesData)) + { + ret = i; + break; + } + } + return ret; + } + + static if (hasMember!(Sys, "onUpdate")) + enum OnUpdateOverloadNum = getOnUpdateOverload(); + else + enum OnUpdateOverloadNum = -1; + //enum HasOnUpdate = (hasMember!(Sys, "onUpdate") && checkOnUpdateParams()); + enum IsEmpty = components_info.req.length == 0 && components_info.optional.length == 0 + && components_info.excluded.length == 0 && components_info.entites_array.length == 0; + + static if (IsEmpty) + system.m_empty = true; + + static if (OnUpdateOverloadNum != -1) + { + static if (!IsEmpty) + { + static void callUpdate(ref CallData data) + { + Sys* s = cast(Sys*) data.system.m_system_pointer; + + Sys.EntitiesData input_data; + EntityInfo* info = data.info; //block.type_info; + System* system = data.system; + + EntitiesBlock* block; + if (data.first_block) + block = data.first_block; + else + block = info.first_block; + + uint offset = data.begin; + uint entities_count; + uint blocks; + if (data.blocks) + blocks = data.blocks; + else + blocks = uint.max; + + while (block !is null && blocks > 0) + { + if (blocks == 1) + { + if (data.end) + entities_count = data.end; + else + entities_count = block.entities_count; + } + else + entities_count = block.entities_count; + + if (entities_count > 0) + { + assert(entities_count <= block.entities_count + && offset < block.entities_count); + assert(entities_count > offset); + + fillInputData(input_data, info, block, offset, entities_count, system); + + static if (hasMember!(Sys.EntitiesData, "thread_id")) + { + input_data.thread_id = cast( + typeof(input_data.thread_id)) data.thread_id; + } + + static if (hasMember!(Sys.EntitiesData, "job_id")) + { + input_data.job_id = cast(typeof(input_data.job_id)) data.job_id; + } + + //s.onUpdate(input_data); + (cast(typeof(&__traits(getOverloads, s, + "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)( + input_data); + } + block = block.next_block; + offset = 0; + blocks--; + } + } + } + else + { + static void callUpdate(ref CallData data) + { + Sys* s = cast(Sys*) data.system.m_system_pointer; + + Sys.EntitiesData input_data; + + /*static if (hasMember!(Sys.EntitiesData, "length")) + { + input_data.length = 0; + }//*/ + + static if (hasMember!(Sys.EntitiesData, "thread_id")) + { + input_data.thread_id = cast(typeof(input_data.thread_id)) data.thread_id; + } + + static if (hasMember!(Sys.EntitiesData, "job_id")) + { + input_data.job_id = cast(typeof(input_data.job_id)) data.job_id; + } + + (cast(typeof(&__traits(getOverloads, s, + "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data); + } + } + + system.m_update = &callUpdate; + } + + static void catchFunction(string func_name, RetType = void)(void** member) + { + static if (hasMember!(Sys, func_name)) + { + foreach (func; __traits(getOverloads, Sys, func_name)) + { + static if ((Parameters!(func)).length == 0 && is(ReturnType!(func) == RetType)) + { + static RetType callFunc(void* system_pointer) + { + Sys* s = cast(Sys*) system_pointer; + static if (is(RetTyp == void)) + mixin("s." ~ func_name ~ "()"); + else + return mixin("s." ~ func_name ~ "()"); + } + + *member = cast(void*)&callFunc; + break; + } + } + } + } + + static void catchEntityFunction(string func_name, RetType = void)(void** member) + { + static if (hasMember!(Sys, func_name)) + { + foreach (func; __traits(getOverloads, Sys, func_name)) + { + static if ((Parameters!(func)).length == 1 + && is(Parameters!(func)[0] == Sys.EntitiesData) + && is(ReturnType!(func) == RetType)) + { + static RetType callFunc(ref ListenerCallData data) + { + Sys* s = cast(Sys*) data.system.m_system_pointer; + Sys.EntitiesData input_data; + fillInputData(input_data, data.block.type_info, + data.block, data.begin, data.end, data.system); + static if (is(RetTyp == void)) + mixin("s." ~ func_name ~ "(input_data)"); + else + return mixin("s." ~ func_name ~ "(input_data)"); + } + + *member = cast(void*)&callFunc; + break; + } + } + } + } + + static void catchEntityFilterFunction(string func_name, RetType = void)(void** member) + { + static if (hasMember!(Sys, func_name)) + { + foreach (func; __traits(getOverloads, Sys, func_name)) + { + static if ((Parameters!(func)).length == 1 + && is(Parameters!(func)[0] == EntityInfo*) + && is(ReturnType!(func) == RetType)) + { + static RetType callFunc(void* system_pointer, EntityInfo* info) + { + Sys* s = cast(Sys*) system_pointer; + static if (is(RetTyp == void)) + mixin("s." ~ func_name ~ "(info)"); + else + return mixin("s." ~ func_name ~ "(info)"); + } + + *member = cast(void*)&callFunc; + break; + } + } + } + } + + catchFunction!("onEnable")(&system.m_enable); + catchFunction!("onDisable")(&system.m_disable); + catchFunction!("onCreate")(&system.m_create); + catchFunction!("onDestroy")(&system.m_destroy); + catchFunction!("onBegin", bool)(&system.m_begin); + catchFunction!("onEnd")(&system.m_end); + + catchEntityFunction!("onAddEntity")(&system.m_add_entity); + catchEntityFunction!("onRemoveEntity")(&system.m_remove_entity); + catchEntityFunction!("onChangeEntity")(&system.m_change_entity); + + catchEntityFilterFunction!("filterEntity", bool)(&system.m_filter_entity); + + system.m_system_pointer = cast(void*) Mallocator.make!Sys; + system.m_priority = priority; + //(cast(Sys*) system.m_system_pointer).__ecsInitialize(); + //system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs; + static if (__traits(hasMember, Sys, "__becs_jobs_count")) + system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count); + else + system.jobs = Mallocator.makeArray!(Job)(32); + + static if (OnUpdateOverloadNum != -1) + { + Sys* s = cast(Sys*) system.m_system_pointer; + system.m_update_delegate = cast(void delegate())&__traits(getOverloads, + s, "onUpdate")[OnUpdateOverloadNum]; + } + + genCompList(system, components_map); + + foreach (iii, comp_info; components_info.readonlyDeps) + { + ushort comp = external_dependencies_map.get(cast(const(char)[]) comp_info.type, + ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing dependency."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); + system.m_readonly_dependencies[iii] = comp; + } + + foreach (iii, comp_info; components_info.writableDeps) + { + ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max); + version (NoDRuntime) + assert(comp != ushort.max, + "Can't register system \"" ~ SystemName + ~ "\" due to non existing dependency."); + else + assert(comp != ushort.max, "Can't register system \"" ~ SystemName + ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); + system.m_writable_dependencies[iii] = comp; + } + + ushort sys_id = systems_map.get(cast(char[]) SystemName, ushort.max); + if (sys_id < systems.length) + { + system.m_name = systems[sys_id].m_name; + systems[sys_id].m_name = null; + systems[sys_id].destroy(); + + if (system.m_create) + (cast(void function(void*)) system.m_create)(system.m_system_pointer); + + system.enable(); + + system.m_id = sys_id; + systems[sys_id] = system; + } + else + { + system.m_name = Mallocator.makeArray(cast(char[]) SystemName); + + systems_map.add(system.m_name, cast(ushort) systems.length); + + system.m_id = cast(ushort)(systems.length); + + systems.add(system); + + if (system.m_create) + (cast(void function(void*)) system.m_create)(system.m_system_pointer); + + systems[$ - 1].enable(); + } + becsID!Sys = system.id; + } + + /************************************************************************************************************************ + Return system ECS api by id. + System pointer might become invalid after registration process. It should be get once again after new systems are registered. + */ + export System* getSystem(ushort id) nothrow @nogc + { + if (id >= systems.length) + return null; + return &systems[id]; + } + + /************************************************************************************************************************ + Return pointer to system registered in manager + */ + Sys* getSystem(Sys)() nothrow @nogc + { + if (becsID!Sys >= systems.length) + return null; + return cast(Sys*) systems[becsID!Sys].m_system_pointer; + } + + export ushort registerPass(const(char)[] name) + { + UpdatePass* pass = Mallocator.make!UpdatePass; + pass.name = Mallocator.makeArray(cast(char[]) name); + passes.add(pass); + passes_map.add(name, cast(ushort)(passes.length - 1)); + return cast(ushort)(passes.length - 1); + } + + export void registerDependency(const(char)[] name) + { + return external_dependencies_map.add(name, cast(ushort) external_dependencies_map.length); + } + + /************************************************************************************************************************ + Register component into EntityManager. + */ + void registerComponent(Comp)() + { + ComponentInfo info; + + // enum ComponentName = fullyQualifiedName!Comp; + enum ComponentName = fullName!Comp; + // enum ComponentName = Comp.stringof; + + // static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort)) + // { + // static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;"); + // } + + static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy) + && is(ReturnType!(Comp.onDestroy) == void) + && Parameters!(Comp.onDestroy).length == 0) + { + static void callDestroy(void* pointer) nothrow @nogc + { + (cast(void delegate() nothrow @nogc)&(cast(Comp*) pointer).onDestroy)(); + } + + info.destroy_callback = &callDestroy; + } + + static if (hasMember!(Comp, "onCreate") && isFunction!(Comp.onCreate) + && is(ReturnType!(Comp.onCreate) == void) && Parameters!(Comp.onCreate).length == 0) + { + static void callCreate(void* pointer) nothrow @nogc + { + (cast(void delegate() nothrow @nogc)&(cast(Comp*) pointer).onCreate)(); + } + + info.create_callback = &callCreate; + } + + static if (Comp.sizeof == 1 && Fields!(Comp).length == 0) + info.size = 0; + else + info.size = Comp.sizeof; + info.alignment = Comp.alignof; //8; + info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof); + __gshared Comp init_memory; + memcpy(info.init_data.ptr, &init_memory, Comp.sizeof); + + ushort comp_id = components_map.get(cast(char[]) ComponentName, ushort.max); + if (comp_id < components.length) + { + becsID!Comp = comp_id; + if (components[comp_id].init_data) + Mallocator.dispose(components[comp_id].init_data); + components[comp_id] = info; + } + else + { + components.add(info); + becsID!Comp = cast(ushort)(components.length - 1); + char[] name = Mallocator.makeArray(cast(char[]) ComponentName); + components_map.add(name, cast(ushort)(components.length - 1)); + } + } + + void registerEvent(Ev)() + { + EventInfo info; + + // static if (!(hasMember!(Ev, "event_id")) || !is(typeof(Ev.event_id) == ushort)) + // { + // static assert(0, "Add \"mixin ECS.Event;\" in top of event structure;"); + // } + + static if (hasMember!(Ev, "onDestroy") && isFunction!(Ev.onDestroy) + && is(ReturnType!(Ev.onDestroy) == void) && Parameters!(Ev.onDestroy).length == 0) + { + static void callDestroy(void* pointer) + { + (cast(Ev*) pointer).onDestroy(); + } + + info.destroy_callback = cast(void function(void*) nothrow @nogc)&callDestroy; + } + + info.size = Ev.sizeof; + info.alignment = Ev.alignof; + + //ushort event_id = events_map.get(Ev.stringof, ushort.max); + ushort event_id = events_map.get(fullName!Ev, ushort.max); + if (event_id < events.length) + { + becsID!Ev = event_id; + } + else + { + events.add(info); + becsID!Ev = cast(ushort)(events.length - 1); + // events_map.add(Ev.stringof, cast(ushort)(events.length - 1)); + events_map.add(fullName!Ev, cast(ushort)(events.length - 1)); + } + } + + export void callEntitiesFunction(Sys, T)(T func) + { + //TODO: check if onUpdate function is good + Sys* s; + static assert(isDelegate!func, "Function must be delegate."); + static assert(__traits(hasMember, Sys, "EntitiesData"), + "Can't call function with system which hasn't EntitesData structure."); + ///TODO: make possibly to call function to group without system with onUpdate function + static assert(__traits(hasMember, Sys, "onUpdate"), + "Can't call function with system which hasn't onUpdate function callback."); + // static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate), + // functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)), + // "Function must match system update function."); FIXME: It's lead to crash on android build + // static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type."); + + System* system = getSystem(becsID!Sys); + assert(system != null, + "System must be registered in EntityManager before any funcion can be called."); + assert(system.isAlive(), "System must be alive (registered) in order to call entities function on its entities"); + + if (!system.m_any_system_caller) + return; + + foreach (info; system.m_any_system_caller.infos) + { + CallData data = CallData(system.id, system, info, cast(void delegate()) func); + data.update(); + } + } + + /************************************************************************************************************************ + Same as "void update(int pass = 0)" but use pass name instead of id. + */ + export void update(const(char)[] pass_name) nothrow @nogc + { + ushort pass = passes_map.get(pass_name, ushort.max); + assert(pass != ushort.max); + update(pass); + } + + /************************************************************************************************************************ + Update systems. Should be called only between begin() and end(). + */ + export void update(ushort pass = 0) nothrow @nogc + { + assert(!register_state); + assert(pass < passes.length); + foreach (caller; passes[pass].system_callers) + { + System* sys = &systems[caller.system_id]; + if (sys.enabled && sys.willExecute) + { + if (sys.m_empty) + { + CallData data = CallData(caller.system_id, sys, null, sys.m_update_delegate); + data.update(); + } + else + foreach (info; caller.infos) + { + CallData data = CallData(caller.system_id, sys, info, + sys.m_update_delegate); + data.update(); + } + } + } + } + + /************************************************************************************************************************ + Same as "void updateMT(int pass = 0)" but use pass name instead of id. + */ + export void updateMT(const(char)[] pass_name) nothrow @nogc + { + ushort pass = passes_map.get(pass_name, ushort.max); + assert(pass != ushort.max); + updateMT(pass); + } + + export void updateMT(ushort pass = 0) nothrow @nogc + { + assert(!register_state); + assert(pass < passes.length); + assert(m_dispatch_jobs, + "Can't update with multithreading without JobDispatch function. Please use setJobDispatchFunc()."); + Vector!CallData tmp_datas; + tmp_datas.reserve(8); + + foreach (caller; passes[pass].system_callers) + { + System* sys = &systems[caller.system_id]; + if (sys.enabled && sys.willExecute) + { + uint job_id = 0; + void nextJob() + { + CallData[] callers = m_call_data_allocator.getCallData( + cast(uint) tmp_datas.length); + //callers[0 .. $] = tmp_datas[0 .. $]; + memcpy(callers.ptr, &tmp_datas[0], CallData.sizeof * tmp_datas.length); + tmp_datas.clear(); + sys.jobs[job_id].callers = callers; + sys.jobs[job_id].id = job_id; + job_id++; + } + + if (sys.m_empty) + { + tmp_datas.add(CallData(caller.system_id, sys, null, sys.m_update_delegate)); + nextJob(); + caller.job_group.jobs = sys.jobs[0 .. 1]; + (cast(void delegate(JobGroup) nothrow @nogc) m_dispatch_jobs)(caller.job_group); + continue; + } + uint entities_count = 0; + foreach (info; caller.infos) + { + uint blocks_count = info.nonEmptyBlocksCount(); + if (blocks_count == 0) + continue; + if (blocks_count > 1) + entities_count += (blocks_count - 1) * info.max_entities; + entities_count += info.last_block.entities_count; + } + + if (!entities_count) + continue; + + uint jobs_count = cast(uint) sys.jobs.length; + uint entities_per_job = entities_count / jobs_count + 1; + + if (entities_per_job <= 4) + { + jobs_count = entities_count / 4; + if (jobs_count == 0) + jobs_count = 1; + entities_per_job = entities_count / jobs_count + 1; + } + + entities_count = 0; + + foreach (info; caller.infos) + { + uint blocks_count = info.nonEmptyBlocksCount(); + EntitiesBlock* first_block = info.first_block; + uint first_elem = 0; + begin: + if (first_block is null || blocks_count == 0) + continue; + + //if this info will fill job + if ((blocks_count - 1) * info.max_entities + entities_count + + info.last_block.entities_count - first_elem >= entities_per_job) + { + int reamaining_entities = (entities_per_job - entities_count - ( + first_block.entities_count - first_elem)); + + //if first block don't fill job + if (reamaining_entities > 0) + { + //take as many full blocks as possible + int full_blocks_count = reamaining_entities / info.max_entities; + EntitiesBlock* block = first_block; + foreach (i; 0 .. full_blocks_count + 1) + block = block.next_block; + + //if full block + actual contained entities + remaining entities form first block > entities count per job + if (full_blocks_count * info.max_entities + entities_count + ( + first_block.entities_count - first_elem) >= entities_per_job) + { + assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + ( + first_block.entities_count - first_elem)); + CallData data = CallData(caller.system_id, sys, + info, sys.m_update_delegate, first_block, + cast(ushort)(full_blocks_count + 1), + cast(ushort) first_elem, 0); + tmp_datas.add(data); + first_elem = 0; + blocks_count -= full_blocks_count + 1; + first_block = block; + } + else + { + entities_count += full_blocks_count * info.max_entities + ( + first_block.entities_count - first_elem); // - first_elem; + uint last_elem = entities_per_job - entities_count; // + first_elem - 1; + assert(last_elem > 0); + assert(last_elem <= block.entities_count); + CallData data = CallData(caller.system_id, sys, + info, sys.m_update_delegate, first_block, + cast(ushort)(full_blocks_count + 2), + cast(ushort) first_elem, cast(ushort) last_elem); + tmp_datas.add(data); + first_elem = last_elem; + blocks_count -= full_blocks_count + 1; + first_block = block; + if (last_elem == block.entities_count) + { + assert(block.next_block == null); + first_block = null; + } + } + } + else + { + uint last_elem = entities_per_job - entities_count; + assert(last_elem > 0); + CallData data = CallData(caller.system_id, sys, + info, sys.m_update_delegate, first_block, 1, + cast(ushort) first_elem, cast(ushort)(first_elem + last_elem)); + tmp_datas.add(data); + first_elem += last_elem; + assert(first_elem <= first_block.entities_count); + //if job takes every entity, take next block + if (first_elem == first_block.entities_count) + { + first_elem = 0; + first_block = first_block.next_block; + blocks_count--; + } + } + nextJob(); + entities_count = 0; + goto begin; + } + else + { + //take whole info blocks + CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, + first_block, cast(ushort) blocks_count, cast(ushort) first_elem); + tmp_datas.add(data); + entities_count += (blocks_count - 1) * info.max_entities + + info.last_block.entities_count - first_elem; + } + } + nextJob(); + + caller.job_group.jobs = sys.jobs[0 .. job_id]; + (cast(void delegate(JobGroup) nothrow @nogc) m_dispatch_jobs)(caller.job_group); //sys.jobs[0 .. job_id]); + } + } + } + + export void setMultithreadingCallbacks(void delegate(JobGroup) dispatch_callback, + uint delegate() get_id_callback) + { + m_dispatch_jobs = cast(void delegate(JobGroup jobs) nothrow @nogc) dispatch_callback; + m_thread_id_func = cast(uint delegate() nothrow @nogc) get_id_callback; + } + + /************************************************************************************************************************ + Return size of single page (block). Every entity data block has size of page. + */ + uint pageSize() + { + return m_page_size; + } + + /************************************************************************************************************************ + Return number of pages in single block allocation. Library allocate defined number of pages at once and assign it's + for entities. + */ + uint pagesInBlock() + { + return m_pages_in_block; + } + + static void alignNum(ref ushort num, ushort alignment) nothrow @nogc pure + { + num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1)); + } + + extern (C) static int compareUShorts(const void* a, const void* b) nothrow @nogc + { + ushort _a = *cast(ushort*) a; + ushort _b = *cast(ushort*) b; + if (_a < _b) + return -1; + else if (_a == _b) + return 0; + else + return 1; + } + + /************************************************************************************************************************ + Allocate EntityTemplate with all components from entity witch it's data and returns pointer to it. + + Params: + entity_id = ID of entity from which should be created template + fill_default = if true, components will be filled with default data, instead entity data will be taken + */ + export EntityTemplate* allocateTemplate(EntityID entity_id, bool fill_default = false) + { + Entity* entity = getEntity(entity_id); + EntitiesBlock* block = getMetaData(entity); + EntityInfo* info = block.type_info; + + EntityTemplate* temp = Mallocator.make!EntityTemplate; + temp.entity_data = Mallocator.makeArray!ubyte(info.size); + temp.info = info; + + if (fill_default) + { + //fill components with default data + foreach (comp; info.components) + { + if (components[comp].size == 0) + continue; + memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], + components[comp].init_data.ptr, components[comp].size); + } + } + else + { + ushort index = block.entityIndex(entity); + foreach (comp; info.components) + { + if (components[comp].size == 0) + continue; + memcpy(cast(void*) temp.entity_data.ptr + info.tmpl_deltas[comp], + cast(void*) block + info.deltas[comp] + components[comp].size * index, + components[comp].size); + } + } + + return temp; + } + + /************************************************************************************************************************ + Allocate EntityTemplate with specifed components and returns pointer to it. + + Params: + components_ids = array of components allocated with template + */ + export EntityTemplate* allocateTemplate(ushort[] components_ids) + { + + ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * components_ids.length))[0 + .. components_ids.length]; + memcpy(ids.ptr, components_ids.ptr, ushort.sizeof * components_ids.length); + //ids[0 .. $] = components_ids[]; + qsort(ids.ptr, ids.length, ushort.sizeof, &compareUShorts); + { + uint j = 1; + foreach (i; 1 .. ids.length) + { + assert(ids[i] != ushort.max); + if (ids[i] != ids[j - 1]) + { + ids[j] = ids[i]; + j++; + } + //else + // debug assert(0, "Duplicated components in template!!!"); + } + ids = ids[0 .. j]; + } + + EntityInfo* info = getEntityInfo(ids); + + EntityTemplate* temp = Mallocator.make!EntityTemplate; + temp.entity_data = Mallocator.makeArray!ubyte(info.size); + temp.info = info; + + //fill components with default data + foreach (comp; info.components) + { + if (components[comp].size == 0) + continue; + memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], + components[comp].init_data.ptr, components[comp].size); + } + + return temp; + } + + /************************************************************************************************************************ + Allocate EntityTemplate from basic Template with modifications by adding and removing some components and returns pointer to it. + Arrays of components needen't to be checked for repeated components, as function itself check if components exist in base template. + + Params: + base_tmpl = template from which components sould be copied + components_ids = array of new components to add + remove_components_ids = array of components to remove from base template + */ + export EntityTemplate* allocateTemplate(EntityTemplate* base_tmpl, + ushort[] components_ids, ushort[] remove_components_ids = null) + { + size_t len = base_tmpl.info.components.length + components_ids.length; + ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * len))[0 .. len]; + memcpy(ids.ptr, base_tmpl.info.components.ptr, + ushort.sizeof * base_tmpl.info.components.length); + memcpy(ids.ptr + base_tmpl.info.components.length, components_ids.ptr, + ushort.sizeof * components_ids.length); + + qsort(ids.ptr, ids.length, ushort.sizeof, &compareUShorts); + qsort(remove_components_ids.ptr, remove_components_ids.length, + ushort.sizeof, &compareUShorts); + { + uint k = 0; + uint j = 1; + foreach (i; 1 .. ids.length) + { + assert(ids[i] != ushort.max); + if (k < remove_components_ids.length) + { + while (k < remove_components_ids.length && remove_components_ids[k] < ids[i]) + { + k++; + } + if (k < remove_components_ids.length) + { + if (remove_components_ids[k] == ids[i]) + continue; + } + } + if (ids[i] != ids[j - 1]) + { + ids[j] = ids[i]; + j++; + } + //else + // debug assert(0, "Duplicated components in template!!!"); + } + ids = ids[0 .. j]; + } + + EntityInfo* info = getEntityInfo(ids); + + EntityTemplate* temp = Mallocator.make!EntityTemplate; + temp.entity_data = Mallocator.makeArray!ubyte(info.size); + temp.info = info; + + //fill components with default data and copy from base template + foreach (comp; info.components) + { + if (comp < base_tmpl.info.tmpl_deltas.length + && base_tmpl.info.tmpl_deltas[comp] != ushort.max) //copy data from base component + { + if (components[comp].size == 0) + continue; + memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], + base_tmpl.entity_data.ptr + base_tmpl.info.tmpl_deltas[comp], + components[comp].size); + } + else //fill with default data + { + if (components[comp].size == 0) + continue; + memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], + components[comp].init_data.ptr, components[comp].size); + } + } + + return temp; + } + + /************************************************************************************************************************ + Allocate EntityTemplate copy. + + Params: + copy_tmpl = template which should be copied + */ + export EntityTemplate* allocateTemplate(EntityTemplate* copy_tmpl) + { + assert(copy_tmpl, "copy_tmpl can't be null"); + EntityTemplate* tmpl = Mallocator.make!EntityTemplate; + tmpl.info = copy_tmpl.info; + tmpl.entity_data = Mallocator.makeArray(copy_tmpl.entity_data); + return tmpl; + } + + /************************************************************************************************************************ + Returns entity type info. + + Params: + ids = array of components + */ + export EntityInfo* getEntityInfo(ushort[] ids) + { + if(ids.length == 0)ids = null; + EntityInfo* info = entities_infos.get(ids, null); + if (info is null) + { + info = Mallocator.make!EntityInfo; + + info.size = EntityID.sizeof; + info.alignment = EntityID.alignof; + + if(ids is null) + { + uint block_memory = cast(uint)( + m_page_size - EntitiesBlock.sizeof - info.size); + uint entites_in_block = block_memory / info.size; + info.max_entities = cast(ushort) entites_in_block; + } + else + { + uint components_size = EntityID.sizeof; + + info.components = Mallocator.makeArray(ids); + info.deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1); + info.tmpl_deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1, ushort.max); + + foreach (i, id; ids) + { + info.alignment = max(info.alignment, components[id].alignment); + alignNum(info.size, components[id].alignment); + info.tmpl_deltas[id] = info.size; + info.size += components[id].size; + components_size += components[id].size; + } + alignNum(info.size, info.alignment); + + uint block_memory = cast(uint)( + m_page_size - EntitiesBlock.sizeof - (info.size - components_size)); + //uint entity_comps_size = EntityID.sizeof; + uint mem_begin = EntitiesBlock.sizeof; + + uint entites_in_block = block_memory / info.size; //entity_comps_size; + info.max_entities = cast(ushort) entites_in_block; + ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof); + + foreach (i, id; ids) + { + if (current_delta == 0) + current_delta = ushort.max; + alignNum(current_delta, components[id].alignment); + info.deltas[id] = cast(ushort) current_delta; + current_delta += entites_in_block * components[id].size; + } + + info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length); + info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length); + + foreach (comp; info.components) + { + info.comp_add_info[comp] = info; + info.comp_rem_info[comp] = null; + } + } + + info.systems = Mallocator.makeArray!bool(systems.length); + + foreach (i, ref system; systems) + { + if (system.isAlive() == false) + continue; + if (system.m_empty) + continue; + if (system.m_update is null) + { + if (system.m_add_entity || system.m_remove_entity + || system.m_change_entity || system.m_event_callers.length) + connectListenerToEntityInfo(*info, cast(uint) i); + continue; + } + addSystemCaller(*info, cast(uint) i); + } + + entities_infos.add(info.components, info); + + generateListeners(info); + } + return info; + } + + private void generateListeners(EntityInfo* info) nothrow + { + if (info.add_listeners) + { + Mallocator.dispose(info.add_listeners); + info.add_listeners = null; + } + if (info.remove_listeners) + { + Mallocator.dispose(info.remove_listeners); + info.remove_listeners = null; + } + if (info.change_listeners) + { + Mallocator.dispose(info.change_listeners); + info.change_listeners = null; + } + //allocate local data + ushort[] tmp_add = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0 + .. systems.length]; + ushort[] tmp_rem = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0 + .. systems.length]; + ushort[] tmp_ch = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0 .. systems + .length]; + int add_len = 0; + int rem_len = 0; + int ch_len = 0; + //assign listeners to lists + foreach (i; 0 .. systems.length) + { + if (info.systems[i]) + { + System* system = &systems[i]; + //onAddEntity listener + if (system.m_add_entity) + { + //find listener position by priority + int j; + for (j = 0; j < add_len; j++) + { + if (systems[i].priority < systems[tmp_add[j]].priority) + break; + } + add_len++; + //move elements after new listener + if (add_len < tmp_add.length) + for (int k = add_len; k > j; k--) + { + tmp_add[k] = tmp_add[k - 1]; + } + //assign listener + tmp_add[j] = cast(ushort) i; + } + //onRemoveEntity listener + if (system.m_remove_entity) + { + //find listener position by priority + int j; + for (j = 0; j < rem_len; j++) + { + if (systems[i].priority < systems[tmp_rem[j]].priority) + break; + } + rem_len++; + //move elements after new listener + if (rem_len < tmp_add.length) + for (int k = rem_len; k > j; k--) + { + tmp_rem[k] = tmp_rem[k - 1]; + } + //assign listener + tmp_rem[j] = cast(ushort) i; + } + //onChangeEntity listener + if (system.m_change_entity) + { + //find listener position by priority + int j; + for (j = 0; j < ch_len; j++) + { + if (systems[i].priority < systems[tmp_ch[j]].priority) + break; + } + ch_len++; + //move elements after new listener + if (ch_len < tmp_add.length) + for (int k = ch_len; k > j; k--) + { + tmp_ch[k] = tmp_ch[k - 1]; + } + //assign listener + tmp_ch[j] = cast(ushort) i; + } + } + } + + if (add_len) + { + info.add_listeners = Mallocator.makeArray!ushort(add_len); + memcpy(info.add_listeners.ptr, tmp_add.ptr, add_len * ushort.sizeof); + } + + if (rem_len) + { + info.remove_listeners = Mallocator.makeArray!ushort(rem_len); + memcpy(info.remove_listeners.ptr, tmp_rem.ptr, rem_len * ushort.sizeof); + } + + if (ch_len) + { + info.change_listeners = Mallocator.makeArray!ushort(ch_len); + memcpy(info.change_listeners.ptr, tmp_ch.ptr, ch_len * ushort.sizeof); + } + } + + export void connectListenerToEntityInfo(ref EntityInfo entity, uint system_id) nothrow @nogc + { + System* system = &systems[system_id]; + + if (system.m_excluded_components) + { + foreach (id; system.m_excluded_components) + { + foreach (id2; entity.components) + { + if (id == id2) + return; + } + } + } + + foreach (id; system.m_components) + { + foreach (i2, id2; entity.components) + { + if (id2 == id) + goto is_; + } + return; + is_: + } + + ///call Custom Entity Filter test if function exists + if (system.m_filter_entity && !(cast(bool function(void* system_pointer, EntityInfo* info) @nogc nothrow) system + .m_filter_entity)(system, &entity)) + return; + + entity.systems[system_id] = true; + } + + export void addSystemCaller(uint system_id) nothrow @nogc + { + System* system = &systems[system_id]; + + uint index = 0; + for (; index < passes[system.m_pass].system_callers.length; index++) + { + if (passes[system.m_pass].system_callers[index].system_id == system_id) + return; + } + + bool added = false; + foreach (i, caller; passes[system.m_pass].system_callers) + { + if (systems[caller.system_id].priority > system.priority) + { + SystemCaller* sys_caller = Mallocator.make!SystemCaller; + sys_caller.system_id = system.id; + sys_caller.job_group.caller = sys_caller; + system.m_any_system_caller = sys_caller; + passes[system.m_pass].system_callers.add(sys_caller, i); + added = true; + break; + } + } + if (!added) + { + SystemCaller* sys_caller = Mallocator.make!SystemCaller; + sys_caller.system_id = system.id; + sys_caller.job_group.caller = sys_caller; + system.m_any_system_caller = sys_caller; + passes[system.m_pass].system_callers.add(sys_caller); + } + } + + export void addSystemCaller(ref EntityInfo info, uint system_id) nothrow @nogc + { + System* system = &systems[system_id]; + + connectListenerToEntityInfo(info, system_id); + if (!info.systems[system_id]) + return; + + uint index = 0; + for (; index < passes[system.m_pass].system_callers.length; index++) + { + if (passes[system.m_pass].system_callers[index].system_id == system_id) + break; + } + + if (index < passes[system.m_pass].system_callers.length) + { + passes[system.m_pass].system_callers[index].infos.add(&info); + } + + } + + /************************************************************************************************************************ + Returns pointer to entity. + + Params: + id = ID of entity + */ + export Entity* getEntity(EntityID id) nothrow @nogc + { + return cast(Entity*) id_manager.getEntityPointer(id); + } + + /************************************************************************************************************************ + Remove components from entity by IDs. Components will be removed on end of frame. + + Params: + entity_id = ID of entity + del_ids = array of components IDs + */ + export void removeComponents(EntityID entity_id, ushort[] del_ids) nothrow @nogc + { + ThreadData* data = &threads[threadID]; + uint num = cast(uint) del_ids.length; + data.changeEntitiesList.add(0); + data.changeEntitiesList.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.changeEntitiesList.add((cast(ubyte*)&num)[0 .. uint.sizeof]); + data.changeEntitiesList.add((cast(ubyte*) del_ids.ptr)[0 .. num * 2]); + } + + private void __removeComponents(EntityID entity_id, ushort[] del_ids) + { + Entity* entity = id_manager.getEntityPointer(entity_id); + if (!entity) + return; + EntitiesBlock* block = getMetaData(entity); + EntityInfo* info = block.type_info; + + //remove non-existing components + uint num = cast(uint) del_ids.length; + foreach_reverse (i; 0 .. num) + { + if (info.deltas.length <= del_ids[i] || info.deltas[del_ids[i]] == 0) + { + num--; + del_ids[i] = del_ids[num]; + } + } + + if (num == 0) + return; + del_ids = del_ids[0 .. num]; + + //sort components + qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts); + + EntityInfo* new_info = info; + + foreach (id; del_ids) + { + new_info = new_info.getNewInfoRemove(id); + } + + /*if (new_info == info) + return;*/ + + EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); + updateEntityInfoBlocks(new_info); + assert(new_block.added_count == 0); + + void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; + + Entity* new_entity = cast(Entity*) start; + new_entity.id = entity.id; + id_manager.update(*new_entity); + + uint ind = block.entityIndex(entity); + + if (info.remove_listeners) + { + foreach (listener; info.remove_listeners) + { + if (!new_info.systems[listener]) + { + callRemoveEntityListener(&systems[listener], info, block, ind, ind + 1); + } + } + } + + foreach (comp; new_info.components) + { + uint comp_size = components[comp].size; + if (comp_size == 0) + continue; + memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size, + cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); + } + + new_block.entities_count++; + if (new_block != new_info.update_block) + new_info.update_block = new_block; + + if (new_info.add_listeners) + { + foreach (listener; new_info.add_listeners) + { + if (!info.systems[listener]) + { + callAddEntityListener(&systems[listener], new_info, new_block, + new_block.entities_count - 1, new_block.entities_count); + } + } + } + + if (new_info.change_listeners) + { + foreach (listener; new_info.change_listeners) + { + if (info.systems[listener]) + { + callChangeEntityListener(&systems[listener], new_info, new_block, + new_block.entities_count - 1, new_block.entities_count, del_ids); + } + } + } + + removeEntityNoID(entity, block); + } + + /************************************************************************************************************************ + Remove coponents from entity. + + Params: + Components = components types to remove + entity_id = ID of entity + */ + void removeComponents(Components...)(EntityID entity_id) + { + const uint num = Components.length; + ushort[num] del_ids; + static foreach (i, comp; Components) + { + del_ids[i] = becsID!comp; + } + + removeComponents(entity_id, del_ids); + } + + private void __addComponents(EntityID entity_id, ushort[] new_ids, void*[] data_pointers) + { + uint num = cast(uint) new_ids.length; + Entity* entity = id_manager.getEntityPointer(entity_id); + if (!entity) + return; + EntitiesBlock* block = getMetaData(entity); + EntityInfo* info = block.type_info; + + foreach_reverse (i; 0 .. num) + { + if (info.deltas.length > new_ids[i] && info.deltas[new_ids[i]] != 0) + { + num--; + new_ids[i] = new_ids[num]; + data_pointers[i] = data_pointers[num]; + } + } + + if (num == 0) + return; + new_ids = new_ids[0 .. num]; + + foreach (int i; 0 .. num) + { + ushort min = new_ids[i]; + int pos = i; + foreach (int j; i .. num) + { + if (new_ids[j] < min) + { + min = new_ids[j]; + pos = j; + } + } + if (pos != i) + { + ushort id = new_ids[i]; + new_ids[i] = new_ids[pos]; + new_ids[pos] = id; + void* ptr = data_pointers[i]; + data_pointers[i] = data_pointers[pos]; + data_pointers[pos] = ptr; + } + } + + EntityInfo* new_info = info; + + foreach (id; new_ids) + { + new_info = new_info.getNewInfoAdd(id); + } + + assert(new_info != info); + /*if (new_info == info) + return;*/ + + //EntityInfo* new_info = getEntityInfo(ids[0 .. len]); + + EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); + updateEntityInfoBlocks(new_info); + assert(new_block.added_count == 0); + + void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; + + Entity* new_entity = cast(Entity*) start; + new_entity.id = entity.id; + id_manager.update(*new_entity); + + uint j = 0; + uint k = 0; + uint ind = block.entityIndex(entity); + + if (info.remove_listeners) + { + foreach (listener; info.remove_listeners) + { + if (!new_info.systems[listener]) + { + callRemoveEntityListener(&systems[listener], info, block, ind, ind + 1); + } + } + } + + foreach (id; new_info.components) //ids[0 .. len]) + { + uint size = components[id].size; + void* dst = void; + if (size != 0) + dst = cast(void*) new_block + new_info.deltas[id] + (new_block.entities_count) + * size; + + if (k >= new_ids.length) + { + if (size != 0) + memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); + j++; + } + else if (j >= info.components.length || id == new_ids[k]) + { + if (size != 0) + memcpy(dst, data_pointers[k], size); + k++; + } + else + { + assert(id != new_ids[0]); + if (size != 0) + memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); + j++; + } + } + + new_block.entities_count++; + if (new_block != new_info.update_block) + new_info.update_block = new_block; + + if (new_info.add_listeners) + { + foreach (listener; new_info.add_listeners) + { + if (!info.systems[listener]) + { + callAddEntityListener(&systems[listener], new_info, new_block, + new_block.entities_count - 1, new_block.entities_count); + } + } + } + + if (new_info.change_listeners) + { + foreach (listener; new_info.change_listeners) + { + if (info.systems[listener]) + { + callChangeEntityListener(&systems[listener], new_info, new_block, + new_block.entities_count - 1, new_block.entities_count, new_ids); + } + } + } + + removeEntityNoID(entity, block); + } + + /************************************************************************************************************************ + Add components to entity. Components will be added on end of frame. + + Params: + entity_id = ID of entity to remove + comps = components to add + */ + void addComponents(Components...)(const EntityID entity_id, Components comps) nothrow @nogc + { + const uint num = Components.length; + + ComponentRef[num] _comps; + static foreach (i, comp; comps) + { + _comps[i] = ComponentRef(&comp, becsID!(typeof(comp))); + } + addComponents(entity_id, _comps); + + } + + export void addComponents(const EntityID entity_id, ComponentRef[] comps) nothrow @nogc + { + uint num = cast(uint) comps.length; + ThreadData* data = &threads[threadID]; + data.changeEntitiesList.add(cast(ubyte) 1u); + data.changeEntitiesList.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.changeEntitiesList.add((cast(ubyte*)&num)[0 .. uint.sizeof]); + foreach (ref_; comps) + { + data.changeEntitiesList.add((cast(ubyte*)&ref_.component_id)[0 .. ushort.sizeof]); + } + foreach (ref_; comps) + { + if (components[ref_.component_id].size != 0) + data.changeEntitiesList.add( + (cast(ubyte*) ref_.ptr)[0 .. components[ref_.component_id].size]); + } + } + + /************************************************************************************************************************ + Free template memory. + + Params: + template_ = pointer entity template allocated by EntityManager. + */ + export void freeTemplate(EntityTemplate* template_) @nogc nothrow + { + Mallocator.dispose(template_.entity_data); + Mallocator.dispose(template_); + } + + /************************************************************************************************************************ + Add copy of entity to system and returns pointer to it. Added copy has same data as copied entity. Returen pointer is + valid only before one from commit(), begin() or end() will be called. To save entity to further use you should save ID + instead of pointer. + * + *Params: + *id = ID of entity to be copyied. + */ + export Entity* addEntityCopy(EntityID id) + { + Entity* entity = getEntity(id); + EntitiesBlock* block = getMetaData(entity); + EntityInfo* info = block.type_info; + + ushort index = block.entityIndex(entity); + + ushort new_index = 0; + EntitiesBlock* new_block; + do + { + new_block = findBlockWithFreeSpaceMT(info); + new_index = new_block.added_count.atomicOp!"+="(1); + } + while (new_block.entities_count + new_index > info.max_entities); + + ushort new_id = cast(ushort)(new_block.entities_count + new_index - 1); + const void* data_begin = new_block.dataBegin(); + const void* start = data_begin + EntityID.sizeof * new_id; + + foreach (i, comp; info.components) + { + ushort size = components[comp].size; + if (size != 0) + memcpy(cast(void*) new_block + info.deltas[comp] + new_id * size, + cast(void*) block + info.deltas[comp] + size * index, size); + + if (components[comp].create_callback) + { + components[comp].create_callback( + cast(void*) new_block + info.deltas[comp] + new_id * size); + } + } + + if (new_index == 1 && info.update_block == new_block) + threads[threadID].infosToUpdate.add(info); + + Entity* new_entity = cast(Entity*) start; + new_entity.id = id_manager.getNewID(); + id_manager.update(*new_entity); + + return new_entity; + } + + /************************************************************************************************************************ + Add entity to system. Returen pointer is valid only before one from commit(), begin() or end() will be called. To save entity to further + use you should save ID instead of pointer. + + Params: + tmpl = pointer entity template allocated by EntityManager. Can be null in which case empty entity would be added (entity without components) + */ + export Entity* addEntity(EntityTemplate* tmpl) + { + return addEntity(tmpl, null); + } + + /************************************************************************************************************************ + Add entity to system. Returen pointer is valid only before one from commit(), begin() or end() will be called. To save entity to further + use you should save ID instead of pointer. + + Params: + tmpl = pointer entity template allocated by EntityManager. Can be null in which case empty entity would be added (entity without components) + replacement = list of components references to used. Memory form list replace data from template inside new entity. Should be used only for data which vary between most entities (like 3D position etc.) + */ + export Entity* addEntity(EntityTemplate* tmpl, ComponentRef[] replacement) + { + EntityInfo* info = void; + if(tmpl)info = tmpl.info; + else info = getEntityInfo(null); + + ushort index = 0; + EntitiesBlock* block; + do + { + block = findBlockWithFreeSpaceMT(info); + index = block.added_count.atomicOp!"+="(1); + } + while (block.entities_count + index > info.max_entities); + + uint id = (block.entities_count + index - 1); //block.added_count); + + void* data_begin = block.dataBegin(); + void* start = data_begin + EntityID.sizeof * id; + + foreach (comp; info.components) + { + uint size = components[comp].size; + if (size != 0) + memcpy(cast(void*) block + info.deltas[comp] + size * id, + tmpl.entity_data.ptr + info.tmpl_deltas[comp], size); + } + + foreach (comp; replacement) + { + if (comp.component_id < info.deltas.length) + { + ushort delta = info.deltas[comp.component_id]; + if (delta != 0) + { + uint size = components[comp.component_id].size; + if (size != 0) + memcpy(cast(void*) block + delta + size * id, comp.ptr, size); + } + } + } + + foreach (i, comp; info.components) + { + if (components[comp].create_callback) + { + components[comp].create_callback( + cast(void*) block + info.deltas[comp] + id * components[comp].size); + } + } + + if (index == 1 && info.update_block == block) + threads[threadID].infosToUpdate.add(info); + + Entity* entity = cast(Entity*) start; + entity.id = id_manager.getNewID(); + id_manager.update(*entity); + + return entity; + } + + /************************************************************************************************************************ + Return block with free space for selected EntityInfo. + */ + private EntitiesBlock* findBlockWithFreeSpace(EntityInfo* info) nothrow @nogc + { + EntitiesBlock* block = info.last_block; + + if (block is null) + { + block = cast(EntitiesBlock*) allocator.getBlock(); + *block = EntitiesBlock(info); + block.id = 0; + info.first_block = block; + info.last_block = block; + info.update_block = block; + } + else if (block.entities_count >= info.max_entities) + { + EntitiesBlock* new_block = cast(EntitiesBlock*) allocator.getBlock(); + *new_block = EntitiesBlock(info); + new_block.prev_block = block; + block.next_block = new_block; + new_block.id = cast(ushort)(block.id + 1); + block = new_block; + info.last_block = block; + ///make sure that update_block point to unfilled block + if (info.update_block.entities_count == info.max_entities) + { + assert(!info.update_block.added_count); + info.update_block = block; + } + } + return block; + } + + /************************************************************************************************************************ + Return block with free space for selected EntityInfo. Additional this function is multithread safe. + */ + private EntitiesBlock* findBlockWithFreeSpaceMT(EntityInfo* info) + { + EntitiesBlock* block = info.last_block; + + if (block is null) + { + entity_block_alloc_mutex.lock(); + scope (exit) + entity_block_alloc_mutex.unlock(); + + if (info.last_block != null) + return info.last_block; + + block = cast(EntitiesBlock*) allocator.getBlock(); + *block = EntitiesBlock(info); + block.id = 0; + info.first_block = block; + info.last_block = block; + info.update_block = block; + } + else if (block.entities_count + block.added_count >= info.max_entities) + { + EntitiesBlock* last_block = info.last_block; + + entity_block_alloc_mutex.lock(); + scope (exit) + entity_block_alloc_mutex.unlock(); + + if (info.last_block !is last_block) + return info.last_block; + + EntitiesBlock* new_block = cast(EntitiesBlock*) allocator.getBlock(); + *new_block = EntitiesBlock(info); + new_block.prev_block = block; + block.next_block = new_block; + new_block.id = cast(ushort)(block.id + 1); + block = new_block; + info.last_block = block; + ///make sure that update_block point to unfilled block + if (info.update_block.entities_count == info.max_entities) + { + assert(!info.update_block.added_count); + info.update_block = block; + } + } + return block; + } + + /************************************************************************************************************************ + Remove entity by ID. Entity will be removed on frame end. + + Params: + id = id of entity to remove + */ + export void removeEntity(EntityID id) + { + threads[threadID].entitesToRemove.add(id); + } + + private void __removeEntity(EntityID id) nothrow @nogc + { + //get entity and block meta data pointers + Entity* entity = id_manager.getEntityPointer(id); + + if (entity is null) + return; //return if entity doesn't exist + + EntitiesBlock* block = getMetaData(entity); + + EntityInfo* info = block.type_info; + if (info.remove_listeners) + { + uint pos = block.entityIndex(entity); + + callRemoveEntityListeners(info, block, pos, pos + 1); + } + + id_manager.releaseID(id); //release id from manager + + removeEntityNoID(entity, block, true); + } + + private void removeEntityNoID(Entity* entity, EntitiesBlock* block, + bool call_destructors = false) nothrow @nogc + { + EntityInfo* info = block.type_info; + + updateEntityInfoBlocks(info); + + assert(info.last_block.added_count == 0); + assert(info.last_block.entities_count > 0); + + info.last_block.entities_count--; + + uint pos = block.entityIndex(entity); + + if (call_destructors) + { + foreach (comp; info.components) + { + if (components[comp].destroy_callback) + { + components[comp].destroy_callback(cast( + void*) block + info.deltas[comp] + pos * components[comp].size); + } + } + } + + if (block !is info.last_block || pos != block.entities_count) + { + foreach (comp; info.components) + { + uint size = components[comp].size; + if (size == 0) + continue; + void* src = cast(void*) info.last_block + info.deltas[comp]; + void* dst = cast(void*) block + info.deltas[comp]; + memcpy(dst + pos * size, src + info.last_block.entities_count * size, size); + } + + block = info.last_block; + entity.id = *cast(EntityID*)(block.dataBegin() + block.entities_count * EntityID.sizeof); + + id_manager.update(*entity); + } + + block = info.last_block; + if (block.entities_count == 0) + { + assert(info.update_block is block); + info.last_block = block.prev_block; + if (info.first_block is block) + { + info.first_block = null; + } + if (block.prev_block) + { + block.prev_block.next_block = null; + info.update_block = block.prev_block; + assert(block.prev_block.added_count == 0); + //block.prev_block.added_count.atomicStore(cast(ushort)0); + } + allocator.freeBlock(block); + } + } + + /************************************************************************************************************************ + functions return MetaData of page. + + Params: + pointer = pointer to any data of entity (i.e. component data pointer) + */ + export EntitiesBlock* getMetaData(const void* pointer) nothrow @nogc + { + return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(m_page_size - 1))); + } + + private bool changeEntities() + { + bool has_work = false; + //foreach (ref ThreadData thread; threads)thread.swapToChange(); + foreach (ref ThreadData thread; threads) + { + uint index = 0; + uint len = cast(uint) thread.changeEntitiesListPrev.length; + if (len) + has_work = true; + void*[32] pointers; // = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; + while (index < len) + { + if (!thread.changeEntitiesListPrev[index++]) + { + EntityID id = *cast(EntityID*)&thread.changeEntitiesListPrev[index]; + index += EntityID.sizeof; + uint num = *cast(uint*)&thread.changeEntitiesListPrev[index]; + index += uint.sizeof; + ushort[] ids; // = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; + ids = (cast(ushort*)&thread.changeEntitiesListPrev[index])[0 .. num]; + index += ushort.sizeof * num; + __removeComponents(id, ids); + } + else + { + EntityID id = *cast(EntityID*)&thread.changeEntitiesListPrev[index]; + index += EntityID.sizeof; + uint num = *cast(uint*)&thread.changeEntitiesListPrev[index]; + index += uint.sizeof; + ushort[] ids; // = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; + ids = (cast(ushort*)&thread.changeEntitiesListPrev[index])[0 .. num]; + index += ushort.sizeof * num; + //void*[] pointers = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; + foreach (i; 0 .. num) + { + pointers[i] = &thread.changeEntitiesListPrev[index]; + index += components[ids[i]].size; + } + + __addComponents(id, ids, pointers[0 .. num]); + } + } + thread.changeEntitiesListPrev.clear(); + } + return has_work; + } + + private void callAddEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow + { + foreach (listener; info.add_listeners) + { + System* system = &systems[listener]; + callAddEntityListener(system, info, block, begin, end); + } + } + + private static void callAddEntityListener(System* system, EntityInfo* info, + EntitiesBlock* block, int begin, int end) @nogc nothrow + { + ListenerCallData data; + data.system = system; + data.block = block; + data.begin = begin; + data.end = end; + (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_add_entity)(data); + } + + private void callRemoveEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, + int end) @nogc nothrow + { + foreach (listener; info.remove_listeners) + { + System* system = &systems[listener]; + callRemoveEntityListener(system, info, block, begin, end); + } + } + + private static void callRemoveEntityListener(System* system, + EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow + { + ListenerCallData data; + data.system = system; + data.block = block; + data.begin = begin; + data.end = end; + (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_remove_entity)(data); + } + + private void callChangeEntityListener(System* system, EntityInfo* info, + EntitiesBlock* block, int begin, int end, ushort[] ch_ids) @nogc nothrow + { + int i = 0; + int j = 0; + bool is_ = false; + while (1) + { + if (ch_ids[i] == system.m_optional_components[j]) + { + is_ = true; + break; + } + else if (ch_ids[i] > system.m_optional_components[j]) + { + j++; + if (j >= system.m_optional_components.length) + break; + } + else + { + i++; + if (i >= ch_ids.length) + break; + } + } + if (!is_) + return; + + ListenerCallData data; + data.system = system; + data.block = block; + data.begin = begin; + data.end = end; + (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data); + } + + private void updateEntityInfoBlocks(EntityInfo* info) nothrow @nogc + { + while (info.last_block.added_count) + { + EntitiesBlock* block = info.update_block; + assert(block !is null); + if (block.entities_count == info.max_entities) + { + assert(!block.added_count); + block = block.next_block; + } + assert(!block.prev_block || !block.prev_block.added_count); + info.update_block = info.last_block; + + while (block) + { + assert(block.added_count.atomicLoad() > 0); + updateBlock(block); + block = block.next_block; + } + } + assert(info.last_block is info.update_block); + } + + private void updateBlock(EntitiesBlock* block) @nogc nothrow + { + //if(block.added_count == 0)return; + assert(block.added_count != 0); + EntityInfo* info = block.type_info; + ushort entities_count = block.entities_count; + block.entities_count += block.added_count; + if (block.entities_count > block.type_info.max_entities) + { + block.entities_count = block.type_info.max_entities; + } + block.added_count.atomicStore(cast(ushort) 0); + + if (info.add_listeners) + { + callAddEntityListeners(info, block, entities_count, block.entities_count); + } + } + + private bool updateBlocks() + { + bool has_work = false; + foreach (ref ThreadData thread; threads) + { + if (thread.infosToUpdatePrev.length) + has_work = true; + foreach (info; thread.infosToUpdatePrev) + { + updateEntityInfoBlocks(info); + } + thread.infosToUpdatePrev.clear(); + } + return has_work; + } + + private bool removeEntities() nothrow @nogc + { + bool has_work = false; + //foreach (ref ThreadData thread; threads)thread.swapToRemove(); + foreach (ref ThreadData thread; threads) + { + if (thread.entitiesToRemovePrev.length) + has_work = true; + foreach (id; thread.entitiesToRemovePrev) + { + __removeEntity(id); + } + thread.entitiesToRemovePrev.clear(); + } + return has_work; + } + + private bool updateEvents() nothrow @nogc + { + bool has_work = false; + // bool empty = true; + //while (1) + //{ + //event_manager.swapCurrent(); + uint current_index; + if (event_manager.current_index == 0) + current_index = cast(uint) threads.length; + else + current_index = 0; + foreach (i, event; event_manager.events) + { + foreach (first_block; event.first_blocks[current_index .. current_index + threads + .length]) + { + EventManager.EventBlock* block = first_block; + if (block) + has_work = true; + // { + // has_work = true; + // //empty = false; + // } + while (block) + { + EventCallData call_data; + void* event_pointer = cast(void*) block + event.data_offset; + foreach (j; 0 .. block.count) + { + call_data.event = event_pointer + EntityID.sizeof; + EntityID entity_id = *cast(EntityID*)(event_pointer); + Entity* entity = id_manager.getEntityPointer(entity_id); + if (entity) + { + call_data.block = getMetaData(entity); + call_data.id = call_data.block.entityIndex(entity); + call_data.entity = entity; + + foreach (caller; events[i].callers) + { + if (call_data.block.type_info.systems[caller.system.m_id] == false + || !caller.system.enabled || !caller.system.willExecute) + continue; + call_data.system_pointer = caller.system.m_system_pointer; + (cast(void function(ref EventCallData) nothrow @nogc) caller + .callback)(call_data); + } + } + if (events[i].destroy_callback) + events[i].destroy_callback(event_pointer); + event_pointer += events[i].size + EntityID.sizeof; + } + block = block.next; + } + } + } + // if (empty) + // break; + // empty = true; + //} + return has_work; + } + + private void swapData() nothrow @nogc + { + event_manager.swapCurrent(); + foreach (ref ThreadData thread; threads) + { + thread.swapData(); + } + } + + export void commit() + { + bool has_work = true; + while (has_work) + { + swapData(); + + has_work = false; + has_work |= updateBlocks(); + // has_work |= changeEntities(); + // has_work |= removeEntities(); + has_work |= updateEvents(); + + id_manager.optimize(); + has_work |= updateBlocks(); + has_work |= changeEntities(); + has_work |= removeEntities(); + } + event_manager.clearEvents(); + } + + /************************************************************************************************************************ + Begin of update process. Should be called before any update is called. + */ + export void begin() + { + + commit(); + m_call_data_allocator.clear(); + + foreach (ref system; systems) + { + if (system.isAlive() == false) + continue; + if (system.enabled && system.m_begin) + system.m_execute = (cast(bool function(void*)) system.m_begin)( + system.m_system_pointer); + } + } + + /************************************************************************************************************************ + End of update process. Should be called after every update function. + */ + export void end() + { + + foreach (ref system; systems) + { + if (system.isAlive() == false) + continue; + + if (system.enabled && system.m_end) + (cast(void function(void*)) system.m_end)(system.m_system_pointer); + } + + commit(); + } + + /*private void getThreadID() nothrow @nogc + { + if (m_thread_id_func) + thread_id = (cast(uint delegate() nothrow @nogc) m_thread_id_func)(); + else + thread_id = 0; + }*/ + + void sendEvent(Ev)(EntityID id, Ev event) nothrow @nogc + { + event_manager.sendEvent(id, event, threadID); + } + + private void generateDependencies() nothrow @nogc + { + foreach (pass_id, pass; passes) + { + foreach (caller; pass.system_callers) + { + caller.system = &systems[caller.system_id]; + if (caller.exclusion) + Mallocator.dispose(caller.exclusion); + if (caller.dependencies) + Mallocator.dispose(caller.dependencies); + } + uint index = 0; + SystemCaller*[] exclusion; + exclusion = (cast(SystemCaller**) alloca((SystemCaller*) + .sizeof * pass.system_callers.length))[0 .. pass.system_callers.length]; + foreach (caller; pass.system_callers) + { + index = 0; + ///gets systems which are excluding each other + out_for: foreach (caller2; pass.system_callers) + { + if (caller is caller2) + continue; + + ///check for external dependencies + foreach (cmp; caller.system.m_readonly_dependencies) + { + foreach (cmp2; caller2.system.m_writable_dependencies) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + } + foreach (cmp; caller.system.m_writable_dependencies) + { + foreach (cmp2; caller2.system.m_readonly_dependencies) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + foreach (cmp2; caller2.system.m_writable_dependencies) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + } + + ///check for component dependencies + foreach (cmp; caller.system.m_read_only_components) + { + foreach (cmp2; caller2.system.m_writable_components) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + } + foreach (cmp; caller.system.m_writable_components) + { + foreach (cmp2; caller2.system.m_read_only_components) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + foreach (cmp2; caller2.system.m_writable_components) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + } + } + + if (index > 0) + { + caller.exclusion = Mallocator.makeArray(exclusion[0 .. index]); + } + else + caller.exclusion = null; + } + + extern (C) static int compareSystems(const void* a, const void* b) + { + SystemCaller* _a = *cast(SystemCaller**) a; + SystemCaller* _b = *cast(SystemCaller**) b; + if (_a.system.priority < _b.system.priority) + return -1; + else if (_a.system.priority == _b.system.priority) + { + if (_a.exclusion.length < _b.exclusion.length) + return -1; + else if (_a.exclusion.length == _b.exclusion.length) + return 0; + else + return 1; + } + else + return 1; + } + + qsort(pass.system_callers.array.ptr, pass.system_callers.length, + (SystemCaller*).sizeof, &compareSystems); + + foreach (i, caller; pass.system_callers) + caller.job_group.id = cast(uint) i; + + int priority = int.min; + uint beg = 0; + index = 0; + foreach (i, caller; pass.system_callers) + { + index = 0; + foreach (ex; caller.exclusion) + { + if (ex.job_group.id > caller.job_group.id) + continue; + + exclusion[index++] = ex; + } + + if (index > 0) + { + caller.dependencies = Mallocator.makeArray(exclusion[0 .. index]); + caller.job_group.dependencies = Mallocator.makeArray!(JobGroup*)(index); + + foreach (j, dep; caller.dependencies) + { + caller.job_group.dependencies[j] = &dep.job_group; + } + } + else + caller.dependencies = null; + } + } + } + + const(UpdatePass)* getPass(const(char)[] name) + { + ushort id = getPassID(name); + if (id == ushort.max) + return null; + return passes[id]; + } + + ushort getPassID(const(char)[] name) + { + return passes_map.get(name, ushort.max); + } + + /************************************************************************************************************************ + Component info; + */ + struct ComponentInfo + { + export ~this() nothrow @nogc + { + } + + export void opAssign(ComponentInfo c) + { + size = c.size; + alignment = c.alignment; + init_data = c.init_data; + destroy_callback = c.destroy_callback; + create_callback = c.create_callback; + } + + ///Component size + ushort size; + ///Component data alignment + ushort alignment; + ///Initialization data + ubyte[] init_data; + ///Pointer to component destroy callback + void function(void* pointer) nothrow @nogc destroy_callback; + //void* destroy_callback; + ///Pointer to component create callback + void function(void* pointer) nothrow @nogc create_callback; + //void* create_callback; + } + + struct EventCaller + { + System* system; + void* callback; + } + + struct EventCallData + { + EntitiesBlock* block; + void* system_pointer; + void* event; + Entity* entity; + ushort id; + } + + struct EventInfo + { + ushort size; + ushort alignment; + EventCaller[] callers; + void function(void* pointer) nothrow @nogc destroy_callback; + } + + /************************************************************************************************************************ + Entity type info. + */ + struct EntityInfo + { + ///Returns number of blocks + uint blocksCount() nothrow @nogc + { + if (last_block) + return last_block.id + 1; + else + return 0; + } + + ///Returns number of non empty blocks + uint nonEmptyBlocksCount() nothrow @nogc + { + EntitiesBlock* block = last_block; + while (1) + { + if (block is null) + return 0; + if (block.entities_count == 0) + block = block.prev_block; + else + return block.id + 1; + } + } + + EntityInfo* getNewInfoAdd(ushort id) + { + if (comp_add_info.length <= id) + { + EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)( + gEntityManager.components.length); + if (comp_add_info !is null) + { + //new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $]; + memcpy(new_infos.ptr, comp_add_info.ptr, (EntityInfo*) + .sizeof * comp_add_info.length); + Mallocator.dispose(comp_add_info); + } + comp_add_info = new_infos; + } + if (comp_add_info[id]) + return comp_add_info[id]; + + ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length + 1)))[0 + .. components.length + 1]; + uint len = 0; + + foreach (comp; components) + { + if (id > comp) + { + ids[len++] = comp; + } + else + { + ids[len++] = id; + ids[len++] = comp; + foreach (comp2; components[len - 1 .. $]) + { + ids[len++] = comp2; + } + break; + } + } + if (components.length == 0 || id > components[$ - 1]) + ids[len++] = id; + + assert(len == components.length + 1); + + EntityInfo* new_info = gEntityManager.getEntityInfo(ids); + + comp_add_info[id] = new_info; + return new_info; + } + + EntityInfo* getNewInfoRemove(ushort id) return + { + /*if (comp_rem_info.length <= id) + { + EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)( + gEntityManager.components.length, &this); + if (comp_rem_info !is null) + { + //new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $]; + memcpy(new_infos.ptr, comp_rem_info.ptr, (EntityInfo*) + .sizeof * comp_rem_info.length); + Mallocator.dispose(comp_rem_info); + } + comp_rem_info = new_infos; + }*/ + if (comp_rem_info[id]) + return comp_rem_info[id]; + + ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length - 1)))[0 + .. components.length - 1]; + uint len = 0; + + foreach (comp; components) + { + if (id != comp) + { + ids[len++] = comp; + } + } + assert(len != components.length); + //if (len == components.length) + // return &this; + + assert(len == components.length - 1); + + EntityInfo* new_info = gEntityManager.getEntityInfo(ids[0 .. len]); + + comp_rem_info[id] = new_info; + return new_info; + } + + export bool hasComponent(ushort component_id) + { + if (component_id >= deltas.length || !deltas[component_id]) + return false; + return true; + } + + export ~this() @nogc nothrow + { + if (components) + Mallocator.dispose(components); + if (deltas) + Mallocator.dispose(deltas); + if (tmpl_deltas) + Mallocator.dispose(tmpl_deltas); + if (comp_add_info) + Mallocator.dispose(comp_add_info); + if (comp_rem_info) + Mallocator.dispose(comp_rem_info); + if (systems) + Mallocator.dispose(systems); + if (add_listeners) + Mallocator.dispose(add_listeners); + if (remove_listeners) + Mallocator.dispose(remove_listeners); + if (change_listeners) + Mallocator.dispose(change_listeners); + } + + ///entity components + ushort[] components; + + ///deltas in memory for components in EntitiesBlock + ushort[] deltas; + ///deltas in memory for components in EntityTemplate + ushort[] tmpl_deltas; + + ///cached new infos after adding component + EntityInfo*[] comp_add_info; + ///cached new infos after removing component + EntityInfo*[] comp_rem_info; + + ///alignment of whole entity + ushort alignment; //unused in linear-layout TODO: to remove + ///size of entity (with alignment respect) + ushort size; + ///max number of entities in block + ushort max_entities; + + ///array of systems which will update this entity + bool[] systems; + ///systems which are listening for added entities + ushort[] add_listeners; + ///systems which are listening for removed entities + ushort[] remove_listeners; + ///systems which are listening for changed entities (changed in term of contained components) + ushort[] change_listeners; + + ///pointer to first block/page + EntitiesBlock* first_block; + ///pointer to last block + EntitiesBlock* last_block; + ///pointer to last updated block + EntitiesBlock* update_block; + } + + /************************************************************************************************************************ + Meta data of every block of entities (contained at the begining of block). + */ + struct EntitiesBlock + { + ///return pointer to first element in block + export void* dataBegin() nothrow @nogc pure return + { + ushort dif = EntitiesBlock.sizeof; + return cast(void*)&this + dif; + } + + export ushort entityIndex(const(Entity)* entity) nothrow @nogc pure + { + static if (EntityID.sizeof == 8) + return cast(ushort)((cast(void*) entity - dataBegin()) >> 3); + else + return cast(ushort)((cast(void*) entity - dataBegin()) / EntityID.sizeof()); + } + + ///pointer to Entity type info + EntityInfo* type_info = null; + ///number of entities in block + ushort entities_count = 0; + ///number of new entities in block + shared ushort added_count = 0; + //ushort added_count = 0; + ///block id + ushort id = 0; + ///maximum number of entities in block + //ushort max_entities = 0; + ///pointer to next block/page + EntitiesBlock* next_block = null; + ///pointer to next block/page + EntitiesBlock* prev_block = null; + //there is a loooot of data (some kB of memory, pure magic) + } + + /************************************************************************************************************************ + Structure with data used to calling System calls. + + first_block, begin, end, blocks parameters are used + to call partial info update + */ + struct CallData + { + export void update() nothrow @nogc + { + (cast(SytemFuncType) system.m_update)(this); + } + + ///system ID. Used to update system pointer after system reload. + uint system_id; + ///pointer to used system + System* system; + ///poiner to Entity type info + EntityManager.EntityInfo* info; + ///delegate function to call (by default it's delegate to onUpdate call) + void delegate() update_delegate; + + ///pointer to first block into process (if 0 then first block will be used) + EntitiesBlock* first_block; + ///number of blocks to update (if 0 then update all) + ushort blocks; + ///index of first element in first block + ushort begin; + ///index of last element in last block + ushort end; + ///current thread index + uint thread_id; + //current job index + uint job_id; + } + + struct ListenerCallData + { + System* system; + EntitiesBlock* block; + uint begin; + uint end; + } + + struct Job + { + CallData[] callers; + uint id; + + export void execute() nothrow @nogc + { + foreach (ref caller; callers) + { + caller.thread_id = gEntityManager.threadID(); + caller.job_id = id; + caller.update(); + } + } + } + + struct JobGroup + { + Job[] jobs; + JobGroup*[] dependencies; + uint id; + SystemCaller* caller; + //uint max_jobs; + } + + struct SystemCaller + { + export ~this() nothrow @nogc + { + if (dependencies) + { + Mallocator.dispose(dependencies); + } + if (exclusion) + { + Mallocator.dispose(exclusion); + } + if (job_group.dependencies) + Mallocator.dispose(job_group.dependencies); + } + + uint system_id; + System* system; + Vector!(EntityInfo*) infos; + SystemCaller*[] dependencies; + SystemCaller*[] exclusion; + JobGroup job_group; + } + + struct ThreadData + { + ref Vector!EntityID entitesToRemove() @nogc nothrow return + { + return entities_to_remove[data_index]; + } + + ref SimpleVector changeEntitiesList() @nogc nothrow return + { + return change_entities_list[data_index]; + } + + ref Vector!(EntityInfo*) infosToUpdate() @nogc nothrow return + { + return infos_to_update[data_index]; + } + + ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow return + { + return entities_to_remove[1 - data_index]; + } + + ref SimpleVector changeEntitiesListPrev() @nogc nothrow return + { + return change_entities_list[1 - data_index]; + } + + ref Vector!(EntityInfo*) infosToUpdatePrev() @nogc nothrow return + { + return infos_to_update[1 - data_index]; + } + + private: + + void swapData() @nogc nothrow + { + data_index = cast(ubyte)(1 - data_index); + } + + Vector!EntityID[2] entities_to_remove; + SimpleVector[2] change_entities_list; + Vector!(EntityInfo*)[2] infos_to_update; + + ubyte data_index = 0; + } + + export struct UpdatePass + { + export ~this() nothrow @nogc + { + assert(name); + if (name) + Mallocator.dispose(name); + foreach (caller; system_callers) + { + Mallocator.dispose(caller); + } + system_callers.clear(); + } + + char[] name; + Vector!(SystemCaller*) system_callers; + } + + export uint threadID() @nogc nothrow + { + if (m_thread_id_func) + return m_thread_id_func(); + else + return 0; + } + + ThreadData[] threads; + + Vector!(UpdatePass*) passes; + + bool register_state = false; + + alias SytemFuncType = void function(ref EntityManager.CallData data) nothrow @nogc; + + ///Single page size. Must be power of two. + int m_page_size = 32768; //32768; //4096; + ///Number of pages in block. + int m_pages_in_block = 128; + + IDManager id_manager; + BlockAllocator allocator; + + EventManager event_manager; + + void delegate(JobGroup jobs) nothrow @nogc m_dispatch_jobs; + uint delegate() nothrow @nogc m_thread_id_func; + + HashMap!(ushort[], EntityInfo*) entities_infos; + HashMap!(char[], ushort) systems_map; + HashMap!(char[], ushort) components_map; + HashMap!(const(char)[], ushort) events_map; + HashMap!(const(char)[], ushort) passes_map; + HashMap!(const(char)[], ushort) external_dependencies_map; + Vector!System systems; + Vector!ComponentInfo components; + Vector!EventInfo events; + + //Mutex add_mutex; + Mutex* entity_block_alloc_mutex; + + CallDataAllocator m_call_data_allocator; + struct CallDataAllocator + { + struct Block + { + CallData[256] data; + uint allocated = 0; + } + + export ~this() nothrow @nogc + { + foreach (block; blocks) + { + Mallocator.dispose(block); + } + blocks.clear(); + } + + Vector!(Block*) blocks; + uint id; + + void clear() nothrow @nogc + { + if (blocks.length > 0) + foreach (block; blocks[0 .. id + 1]) + { + block.allocated = 0; + } + id = 0; + //blocks.clear(); + } + + CallData[] getCallData(uint num) nothrow @nogc + { + if (blocks.length == 0) + { + Block* new_block = Mallocator.make!Block; + blocks.add(new_block); + } + + Block* block = blocks[id]; + if (block.allocated + num >= 256) + { + id++; + if (id == blocks.length) + { + Block* new_block = Mallocator.make!Block; + blocks.add(new_block); + } + block = blocks[id]; + } + + CallData[] ret = block.data[block.allocated .. block.allocated + num]; + block.allocated += num; + return ret; + } + } + +} diff --git a/source/bubel/ecs/package.d b/source/bubel/ecs/package.d new file mode 100644 index 0000000..e2d8893 --- /dev/null +++ b/source/bubel/ecs/package.d @@ -0,0 +1,14 @@ +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module ecs; + +public import bubel.ecs.core; +public import bubel.ecs.entity; +public import bubel.ecs.manager; +public import bubel.ecs.system; + +import bubel.ecs.events; +import bubel.ecs.id_manager; +import bubel.ecs.std; diff --git a/source/bubel/ecs/simple_vector.d b/source/bubel/ecs/simple_vector.d new file mode 100644 index 0000000..2fdaf31 --- /dev/null +++ b/source/bubel/ecs/simple_vector.d @@ -0,0 +1,87 @@ +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.simple_vector; + +import bubel.ecs.std; + +//import core.stdc.string; + +/************************************************************************************************************************ +Vector for byte data. Simpler than standard template-based implementation designed for better performance. \ +Rellocates 1024 elements at once instead of doubling size. +*/ +struct SimpleVector +{ + + @disable this(this); + + ~this() nothrow @nogc + { + if(data) + Mallocator.dispose(data); + } + + ///Add element to vector + void add(ubyte el) nothrow @nogc + { + while (used >= data.length) + { + if (data is null) + data = Mallocator.makeArray!ubyte(1024); + else + data = Mallocator.expandArray(data, data.length); + } + data[used++] = el; + } + + ///Add array of elements to vector + void add(ubyte[] el) nothrow @nogc + { + while (used + el.length >= data.length) + { + if (data is null) + data = Mallocator.makeArray!ubyte(1024); + else + data = Mallocator.expandArray(data, data.length); + } + memcpy(data.ptr + used, el.ptr, el.length); + used += el.length; + } + + ///Return vector length + size_t length() nothrow @nogc + { + return used; + } + + export ref ubyte opIndex(size_t pos) nothrow @nogc + { + return data[pos]; + } + + export ubyte[] opSlice() nothrow @nogc + { + return data[0 .. used]; + } + + export ubyte[] opSlice(size_t x, size_t y) nothrow @nogc + { + return data[x .. y]; + } + + export size_t opDollar() nothrow @nogc + { + return used; + } + + ///set vector length to 0 + void clear() nothrow @nogc + { + used = 0; + } + + ubyte[] data = null; + size_t used = 0; +} diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d new file mode 100644 index 0000000..8a3e207 --- /dev/null +++ b/source/bubel/ecs/std.d @@ -0,0 +1,451 @@ +/************************************************************************************************************************ +It's internal code! +This module contain implementation of standard functionality. + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.std; + +import std.traits; + +version (Emscripten) +{ + extern (C) struct pthread_mutex_t + { + union + { + int[6] __i; + void[6]* __p; + } + } + + extern (C) struct pthread_mutexattr_t + { + uint __attr; + } + + extern (C) int memcmp(const void* s1, const void* s2, size_t size); + extern (C) void exit(int status) nothrow @nogc; + + extern (C) void free(void*) @nogc nothrow @system; + extern (C) void* malloc(size_t size) @nogc nothrow @system; + extern (C) void* realloc(void*, size_t size) @nogc nothrow @system; + extern (C) void* memcpy(return void*, scope const void*, size_t size) @nogc nothrow @system; + extern (C) void* memset(void*, int val, size_t size) @nogc nothrow @system; + extern (C) int posix_memalign(void**, size_t, size_t) @nogc nothrow @system; + extern (C) void qsort(void* base, size_t num, size_t size, + int function(const void*, const void*) compar) @nogc nothrow @system; + + extern (C) int pthread_mutex_lock(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) int pthread_mutex_trylock(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) int pthread_mutex_unlock(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) void pthread_mutexattr_settype(pthread_mutexattr_t* attr, int type) @nogc nothrow; + extern (C) void pthread_mutexattr_destroy(pthread_mutexattr_t* attr) @nogc nothrow; + extern (C) int pthread_mutexattr_init(pthread_mutexattr_t* attr) @nogc nothrow; + extern (C) int pthread_mutex_destroy(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr) @nogc nothrow; + +} +else +{ + public import core.stdc.stdlib : malloc, free, realloc; + public import core.stdc.string : memcpy, memset; + public import core.stdc.stdlib : qsort; +} + +version (Emscripten) +{ +} +else version (Windows) +{ + import core.sys.windows.windows; + + extern (Windows) void* _aligned_malloc(size_t size, size_t alignment) @nogc nothrow @system; + extern (Windows) void _aligned_free(void* ptr) @nogc nothrow @system; + + version (LDC) + { + /*extern(Windows) void* __alloca(size_t size) @nogc nothrow @system; + alias alloca = __alloca;*/ + + extern (Windows) void ___chkstk_ms() @nogc nothrow @system; + + extern (Windows) void __chkstk() + { + ___chkstk_ms(); + } + } +} +else version (Posix) +{ + import core.sys.posix.pthread; + import core.sys.posix.stdlib : posix_memalign; +} + +version (Emscripten) +{ + private const uint max_alloca = 10000; + private __gshared byte[max_alloca] alloca_array; + private __gshared uint alloca_pos = 0; + export extern (C) void* alloca(size_t length) @nogc nothrow + { + if (alloca_pos + length > max_alloca) + alloca_pos = 0; + void* ret = &alloca_array[alloca_pos]; + alloca_pos += length; + return ret; + } + //extern(C) void* alloca(size_t size) @nogc nothrow; + /*export extern(C) void* alloca(size_t length) @nogc nothrow + { + return null; + }*/ +} +else version (D_BetterC) +{ + private const uint max_alloca = 10000; + private __gshared byte[max_alloca] alloca_array; + private __gshared uint alloca_pos = 0; + export extern (C) void* __alloca(size_t length) @nogc nothrow + { + if (alloca_pos + length > max_alloca) + alloca_pos = 0; + void* ret = &alloca_array[alloca_pos]; + alloca_pos += length; + return ret; + } + + alias alloca = __alloca; + + version (DigitalMars) + { + export extern (C) float* _memsetFloat(float* p, float value, size_t count) @nogc nothrow + { + float* pstart = p; + float* ptop; + + for (ptop = &p[count]; p < ptop; p++) + *p = value; + return pstart; + } + } + + version (GNU) + { + extern (C) void __gdc_personality_v0() + { + + } + } +} +else +{ + public import core.stdc.stdlib : alloca; +} + +static struct Mallocator +{ + static T[] resizeArray(T)(T[] array, size_t length) nothrow @nogc + { + T[] ret; + + if (length > array.length) + { + ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; + static if (__traits(isPOD, T)) + { + __gshared immutable T init = T.init; + + foreach (i; array.length .. ret.length) + { + memcpy(&ret[i], &init, T.sizeof); + } + } + else + { + static import std.conv; + + foreach (i; array.length .. ret.length) + { + std.conv.emplace(&ret[i]); + } + } + } + else + { + static if (__traits(hasMember, T, "__xdtor")) + { + foreach (i; length .. array.length) + { + array[i].__xdtor(); + } + } + else static if (__traits(hasMember, T, "__dtor")) + { + foreach (i; length .. array.length) + { + array[i].__dtor(); + } + } + ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; + } + + return ret; + } + + static T[] makeArray(T)(size_t length) nothrow @nogc + { + T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length]; + + static if (__traits(isPOD, T)) + { + __gshared immutable T init = T.init; + + foreach (i; 0 .. ret.length) + { + memcpy(&ret[i], &init, T.sizeof); + } + } + else + { + static import std.conv; + + foreach (i; 0 .. ret.length) + { + std.conv.emplace(&ret[i]); + } + } + return ret; + } + + static T[] alignMakeArray(T)(size_t length, size_t alignment) nothrow @nogc + { + T[] ret = (cast(T*) alignAlloc(T.sizeof * length, alignment))[0 .. length]; + + static if (__traits(isPOD, T)) + { + __gshared immutable T init = T.init; + + foreach (i; 0 .. ret.length) + { + memcpy(&ret[i], &init, T.sizeof); + } + } + else + { + static import std.conv; + + foreach (i; 0 .. ret.length) + { + std.conv.emplace(&ret[i]); + } + } + return ret; + } + + static T[] makeArray(T)(size_t length, T initializer) nothrow @nogc + { + T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length]; + foreach (ref v; ret) + v = initializer; + return ret; + } + + static T[] expandArray(T)(T[] array, size_t length) nothrow @nogc + { + size_t new_length = array.length + length; + return (cast(T*) realloc(array.ptr, T.sizeof * new_length))[0 .. new_length]; + } + + static T[] makeArray(T)(T[] array) nothrow @nogc + { + T[] ret = (cast(T*) malloc(T.sizeof * array.length))[0 .. array.length]; //Mallocator.makeArray!(T)(array.length); + foreach (i, ref v; ret) + v = array[i]; + return ret; + } + + static T* make(T, Args...)(Args args) + { + T* ret = cast(T*) malloc(T.sizeof); + static import std.conv; + + static if (__traits(isPOD, T)) + { + __gshared immutable T init = T.init; + memcpy(ret, &init, T.sizeof); + } + else static if (is(T == struct)) + std.conv.emplace(ret, args); + return ret; + } + + static void* alignAlloc(size_t length, size_t alignment) nothrow @nogc + { + void* ret; + version (Posix) + posix_memalign(&ret, alignment, length); //ret = aligned_alloc(alignment, length); + else version (Windows) + ret = _aligned_malloc(length, alignment); + else version (Emscripten) + posix_memalign(&ret, alignment, length); //malloc(length); + else + static assert(0, "Unimplemented platform!"); + return ret; + } + + static void dispose(T)(T object) + { + static if (isArray!T) + { + alias TT = PointerTarget!(typeof(object.ptr)); + static if (!isPointer!TT) + { + static if (__traits(hasMember, TT, "__xdtor")) + { + foreach (ref TT t; object) + t.__xdtor(); + } + else static if (__traits(hasMember, TT, "__dtor")) + { + foreach (TT t; object) + t.__dtor(); + } + } + free(cast(void*) object.ptr); + } + else + { + static if (__traits(hasMember, T, "__xdtor")) + object.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + object.__dtor(); + free(cast(void*) object); + } + } + + static void alignDispose(T)(T object) + { + static if (__traits(hasMember, T, "__xdtor")) + object.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + object.__dtor(); + version (Posix) + free(cast(void*) object); + else version (Windows) + _aligned_free(cast(void*) object); + else version (Emscripten) + free(cast(void*) object); + else + static assert(0, "Unimplemented platform!"); + } +} + +struct Mutex +{ + + version (Emscripten) + { + void initialize() nothrow @nogc + { + pthread_mutexattr_t attr = void; + + //pthread_mutexattr_init(&attr); + + //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(cast(pthread_mutex_t*)&m_handle, &attr); + + //pthread_mutexattr_destroy(&attr); + } + + void destroy() nothrow @nogc + { + pthread_mutex_destroy(&m_handle); + } + + void lock() nothrow @nogc + { + pthread_mutex_lock(&m_handle); + } + + void unlock() nothrow @nogc + { + pthread_mutex_unlock(&m_handle); + } + + int tryLock() nothrow @nogc + { + return pthread_mutex_trylock(&m_handle) == 0; + } + + private pthread_mutex_t m_handle; + } + else version (Windows) + { + void initialize() nothrow @nogc + { + InitializeCriticalSection(cast(CRITICAL_SECTION*)&m_handle); + } + + void destroy() nothrow @nogc + { + DeleteCriticalSection(&m_handle); + } + + void lock() nothrow @nogc + { + EnterCriticalSection(&m_handle); + } + + void unlock() nothrow @nogc + { + LeaveCriticalSection(&m_handle); + } + + int tryLock() nothrow @nogc + { + return TryEnterCriticalSection(&m_handle) != 0; + } + + CRITICAL_SECTION m_handle; + } + else version (Posix) + { + void initialize() nothrow @nogc + { + pthread_mutexattr_t attr = void; + + pthread_mutexattr_init(&attr); + + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(cast(pthread_mutex_t*)&m_handle, &attr); + + pthread_mutexattr_destroy(&attr); + } + + void destroy() nothrow @nogc + { + pthread_mutex_destroy(&m_handle); + } + + void lock() nothrow @nogc + { + pthread_mutex_lock(&m_handle); + } + + void unlock() nothrow @nogc + { + pthread_mutex_unlock(&m_handle); + } + + int tryLock() nothrow @nogc + { + return pthread_mutex_trylock(&m_handle) == 0; + } + + private pthread_mutex_t m_handle; + } + else + static assert(0, "unsupported platform!"); +} diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d new file mode 100644 index 0000000..310b53a --- /dev/null +++ b/source/bubel/ecs/system.d @@ -0,0 +1,265 @@ +/************************************************************************************************************************ +System module. + +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.system; + +import bubel.ecs.entity; +import bubel.ecs.manager; + +/************************************************************************************************************************ +System contain data required to proper glue EntityManager with Systems. +System callbacks: +$(LIST + * void onUpdate(EntitiesData); + * void onEnable() - called inside system.enable() function + * void onDisable() - called inside system.disable() function + * bool onBegin() - called inside manager.begin() + * void onEnd() - called inside manager.end() + * void onCreate() - called after registration inside registerSystem function + * void onDestroy() - called during re-registration and inside manager destructor + * void onAddEntity(EntitiesData) - called for every entity which are assigned to system (by adding new entity or changing its components) + * void onRemoveEntity(EntitiesData) - called for every entity removed from system update process + * void onChangeEntity(EntitiesData) - called for every entity which components are changed but it was previously assigned to system + * void handleEvent(Entity*, Event) - called for every event supported by system +) +*/ +struct System +{ + + /************************************************************************************************************************ + Check if system is enabled. + */ + export bool enabled() nothrow @nogc + { + return m_enabled; + } + + /************************************************************************************************************************ + Enable system. If actually it is enabled function do nothing. + */ + export void enable() nothrow @nogc + { + if (!m_enabled && m_enable) + (cast(void function(void*) nothrow @nogc) m_enable)(m_system_pointer); + m_enabled = true; + } + + /************************************************************************************************************************ + Disable system. If actually it is disabled function do nothing. + */ + export void disable() nothrow @nogc + { + if (m_enabled && m_disable) + (cast(void function(void*) nothrow @nogc) m_disable)(m_system_pointer); + m_enabled = false; + } + + /************************************************************************************************************************ + Get system priority. + */ + export int priority() nothrow @nogc + { + return m_priority; + } + + /************************************************************************************************************************ + Get if system will be executed during current frame. Should be checked after manager.begin(). Its value is setted as result of manager.onBegin() callback. + */ + export bool willExecute() nothrow @nogc + { + return m_execute; + } + + /************************************************************************************************************************ + Get system id. + */ + export ushort id() nothrow @nogc + { + return m_id; + } + + /************************************************************************************************************************ + Get system name. + */ + export const(char)[] name() nothrow @nogc + { + return cast(const(char)[]) m_name; + } + + /************************************************************************************************************************ + Return false if system was unregistered, true otherwise. + */ + export bool isAlive() nothrow @nogc + { + return m_system_pointer != null; + } + + /************************************************************************************************************************ + Return pointer to user side system object + */ + export void* ptr() nothrow @nogc + { + return m_system_pointer; + } + +package: + + ///destory system. Dispose all data + export void destroy() nothrow @nogc + { + import bubel.ecs.std : Mallocator; + + destroySystemData(); + + if (m_name) + { + Mallocator.dispose(m_name); + m_name = null; + } + } + + ///destroy all system data but keeps name which is used for case of system re-registration + void destroySystemData() nothrow @nogc + { + import bubel.ecs.std : Mallocator; + disable(); + if (m_destroy) + { + (cast(void function(void*) nothrow @nogc) m_destroy)(m_system_pointer); + m_destroy = null; + } + + if (m_components) + { + Mallocator.dispose(m_components); + m_components = null; + } + if (m_excluded_components) + { + Mallocator.dispose(m_excluded_components); + m_excluded_components = null; + } + if (m_optional_components) + { + Mallocator.dispose(m_optional_components); + m_optional_components = null; + } + if (jobs) + { + Mallocator.dispose(jobs); + jobs = null; + } + if (m_read_only_components) + { + Mallocator.dispose(m_read_only_components); + m_read_only_components = null; + } + if (m_writable_components) + { + Mallocator.dispose(m_writable_components); + m_writable_components = null; + } + if (m_readonly_dependencies) + { + Mallocator.dispose(m_readonly_dependencies); + m_readonly_dependencies = null; + } + if (m_writable_dependencies) + { + Mallocator.dispose(m_writable_dependencies); + m_writable_dependencies = null; + } + if (m_event_callers) + { + Mallocator.dispose(m_event_callers); + m_event_callers = null; + } + + if (m_system_pointer) + { + Mallocator.dispose(m_system_pointer); + m_system_pointer = null; + } + } + + struct EventCaller + { + ushort id; + void* callback; + } + + ///should system be executed in current update? + bool m_execute = true; + ///system id + ushort m_id; + ///is system empty? Empty systems don't update entities, and is called once per update + bool m_empty = false; + + ///should system update and catch events? + bool m_enabled = false; + ///system priority + int m_priority; + ///pointer to system implementation + void* m_system_pointer; + ///system pass index + int m_pass; + + ///system name + char[] m_name; + + ///required components + ushort[] m_components; + ///excluded components + ushort[] m_excluded_components; + ///optional components + ushort[] m_optional_components; + + EntityManager.Job[] jobs; + + //System*[] m_dependencies; + ushort[] m_read_only_components; + ushort[] m_writable_components; + + ushort[] m_readonly_dependencies; + ushort[] m_writable_dependencies; + + EntityManager.SystemCaller* m_any_system_caller; + + EventCaller[] m_event_callers; + + //void function(ref EntityManager.CallData data) m_update; + void* m_update; ///workaroud for DMD bug with upper line + void delegate() m_update_delegate; + + //void function(void* system_pointer) m_enable; + //void function(void* system_pointer) m_disable; + + //void function(void* system_pointer) m_create; + //void function(void* system_pointer) m_destroy; + + //void function(void* system_pointer) m_begin; + //void function(void* system_pointer) m_end; + + void* m_enable; + void* m_disable; + + void* m_create; + void* m_destroy; + + void* m_begin; + void* m_end; + + void* m_add_entity; + void* m_remove_entity; + void* m_change_entity; + + void* m_filter_entity; + + //void function(ref EntityManager.CallData data) m_initialize; + //void function(ref EntityManager.CallData data) m_deinitilize; + void* m_initialize; + void* m_deinitilize; +} diff --git a/source/bubel/ecs/traits.d b/source/bubel/ecs/traits.d new file mode 100644 index 0000000..79901db --- /dev/null +++ b/source/bubel/ecs/traits.d @@ -0,0 +1,96 @@ +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.traits; + +import std.traits; + +/************************************************************************************************************************ + Return Component/System/Event unique ID +*/ +ref ushort becsID(T)() +{ + /// Embed id in struct so export can be added to variable definition + static struct LocalStruct { + export __gshared ushort id = ushort.max; + } + return LocalStruct.id; +} + +/************************************************************************************************************************ + Return Component/System/Event unique ID +*/ +ref ushort becsID(T)(T obj) +{ + static if(isPointer!T)return becsID!(PointerTarget!T); + else return becsID!T; +} + +bool isForeachDelegateWithTypes(DG, Types...)() +{ + return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types); +} + +unittest +{ + assert(isForeachDelegateWithTypes!(int delegate(int, int), int, int)); + assert(isForeachDelegateWithTypes!(int delegate(ref int, ref int), int, int)); + assert(!isForeachDelegateWithTypes!(int delegate(double), int, int)); +} + +/************************************************************************************************************************ + Returns index of Component/Entity array in System's EntitiesData struct +*/ +static long getIndexOfTypeInEntitiesData(EntitiesData, Type)() +{ + alias EntitiesDataFields = Fields!(EntitiesData); + long index = -1; + foreach (fieldNum, FieldType; Fields!(EntitiesData)) + { + + static if (!isBasicType!(FieldType)) // Not basic type + { + // FieldType should be something like: 'const(SomeComponent)[]' + enum bool entitiesMatches = is(Type == Unqual!(ForeachType!(FieldType))); + static if (entitiesMatches) + { + index = fieldNum; + break; + } + } + } + return index; +} + +static string attachParentName(alias T, string str)() +{ + alias parent = __traits(parent, T); + enum parent_str = parent.stringof; + static if(parent_str[0..7] == "module ") + { + static if(__traits(compiles, __traits(parent, parent))) + { + return attachParentName!(parent, parent_str[7 .. $] ~ '.' ~ str); + } + else return parent_str[7 .. $] ~ '.' ~ str; + } + else static if(parent_str[0..8] == "package ") + { + static if(__traits(compiles, __traits(parent, parent))) + { + return attachParentName!(parent, parent_str[8 .. $] ~ '.' ~ str); + } + else return parent_str[8 .. $] ~ '.' ~ str; + } + else static if(__traits(compiles, __traits(parent, parent))) + { + return attachParentName!(parent, parent_str ~ '.' ~ str); + } + else return parent_str ~ '.' ~ str; +} + +static string fullName(T)() +{ + return attachParentName!(T, T.stringof); +} \ No newline at end of file diff --git a/source/bubel/ecs/vector.d b/source/bubel/ecs/vector.d new file mode 100644 index 0000000..6cf6274 --- /dev/null +++ b/source/bubel/ecs/vector.d @@ -0,0 +1,313 @@ +/************************************************************************************************************************ +Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz +License: BSD 3-clause, see LICENSE file in project root folder. +*/ +module bubel.ecs.vector; + +import core.bitop; + +//import core.stdc.stdlib : free, malloc; +import bubel.ecs.std; + +//import core.stdc.string : memcpy, memset; +//import std.algorithm : swap; +import std.conv : emplace; +import std.traits : hasMember, isCopyable, TemplateOf, Unqual; + +export @nogc @safe nothrow pure size_t nextPow2(size_t num) +{ + return 1 << bsr(num) + 1; +} + +export __gshared size_t gVectorsCreated = 0; +export __gshared size_t gVectorsDestroyed = 0; + +struct Vector(T) +{ + T[] array; + size_t used; +public: + + export this()(T t) + { + add(t); + } + + export this(X)(X[] t) if (is(Unqual!X == Unqual!T)) + { + add(t); + + } + + /*static if (isCopyable!T) { + export this(this) { + T[] tmp = array[0 .. used]; + array = null; + used = 0; + add(tmp); + } + } else { + @disable this(this); + }*/ + + @disable this(this); + + export ~this() + { + clear(); + } + + export void clear() + { + removeAll(); + } + + export void removeAll() + { + if (array !is null) + { + /*foreach (ref el; array[0 .. used]) { + destroy(el); + }*/ + //freeData(cast(void[]) array); + freeData((cast(void*) array.ptr)[0 .. array.length * T.sizeof]); + gVectorsDestroyed++; + } + array = null; + used = 0; + } + + export bool empty() const + { + return (used == 0); + } + + export size_t length() const + { + return used; + } + + export void length(size_t newLength) + { + if (newLength > used) + { + reserve(newLength); + foreach (ref el; array[used .. newLength]) + { + emplace(&el); + } + } + else + { + foreach (ref el; array[newLength .. used]) + { + //destroy(el); + static if (__traits(hasMember, T, "__xdtor")) + el.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + el.__dtor(); + } + } + used = newLength; + } + + export void reset() + { + used = 0; + } + + export void reserve(size_t numElements) + { + if (numElements > array.length) + { + extend(numElements); + } + } + + export size_t capacity() + { + return array.length - used; + } + + export void extend(size_t newNumOfElements) + { + auto oldArray = manualExtend(array, newNumOfElements); + if (oldArray !is null) + { + freeData(oldArray); + } + } + + export @nogc void freeData(void[] data) + { + // 0x0F probably invalid value for pointers and other types + memset(data.ptr, 0x0F, data.length); // Makes bugs show up xD + free(data.ptr); + } + + export static void[] manualExtend(ref T[] array, size_t newNumOfElements = 0) + { + if (newNumOfElements == 0) + newNumOfElements = 2; + if (array.length == 0) + gVectorsCreated++; + T[] oldArray = array; + size_t oldSize = oldArray.length * T.sizeof; + size_t newSize = newNumOfElements * T.sizeof; + T* memory = cast(T*) malloc(newSize); + memcpy(cast(void*) memory, cast(void*) oldArray.ptr, oldSize); + array = memory[0 .. newNumOfElements]; + //return cast(void[]) oldArray; + return (cast(void*) oldArray.ptr)[0 .. oldArray.length * T.sizeof]; + } + + export Vector!T copy()() + { + Vector!T duplicate; + duplicate.reserve(used); + duplicate ~= array[0 .. used]; + return duplicate; + } + + /*export bool canAddWithoutRealloc(uint elemNum = 1) + { + return used + elemNum <= array.length; + }*/ + + export void add()(T t) + { + if (used >= array.length) + { + extend(nextPow2(used + 1)); + } + emplace(&array[used], t); + used++; + } + + /// Add element at given position moving others + export void add()(T t, size_t pos) + { + assert(pos <= used); + if (used >= array.length) + { + extend(array.length * 2); + } + foreach_reverse (size_t i; pos .. used) + { + //swap(array[i + 1], array[i]); + array[i + 1] = array[i]; + } + emplace(&array[pos], t); + used++; + } + + export void add(X)(X[] t) if (is(Unqual!X == Unqual!T)) + { + if (used + t.length > array.length) + { + extend(nextPow2(used + t.length)); + } + foreach (i; 0 .. t.length) + { + emplace(&array[used + i], t[i]); + } + used += t.length; + } + + export void remove(size_t elemNum) + { + //destroy(array[elemNum]); + static if (__traits(hasMember, T, "__xdtor")) + array[elemNum].__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + array[elemNum].__dtor(); + //swap(array[elemNum], array[used - 1]); + array[elemNum] = array[used - 1]; + used--; + } + + export void removeStable()(size_t elemNum) + { + used--; + foreach (i; 0 .. used) + { + array[i] = array[i + 1]; + } + } + + export bool tryRemoveElement()(T elem) + { + foreach (i, ref el; array[0 .. used]) + { + if (el == elem) + { + remove(i); + return true; + } + } + return false; + } + + export void removeElement()(T elem) + { + bool ok = tryRemoveElement(elem); + assert(ok, "There is no such an element in vector"); + } + + export ref T opIndex(size_t elemNum) const + { + //debug assert(elemNum < used, "Range violation [index]"); + return *cast(T*)&array.ptr[elemNum]; + } + + export auto opSlice() + { + return array.ptr[0 .. used]; + } + + export T[] opSlice(size_t x, size_t y) + { + assert(y <= used); + return array.ptr[x .. y]; + } + + export size_t opDollar() + { + return used; + } + + export void opAssign(X)(X[] slice) + { + reset(); + this ~= slice; + } + + export void opOpAssign(string op)(T obj) + { + //static assert(op == "~"); + add(obj); + } + + export void opOpAssign(string op, X)(X[] obj) + { + //static assert(op == "~"); + add(obj); + } + + export void opIndexAssign()(T obj, size_t elemNum) + { + assert(elemNum < used, "Range viloation"); + array[elemNum] = obj; + } + + export void opSliceAssign()(T[] obj, size_t a, size_t b) + { + assert(b <= used && a <= b, "Range viloation"); + array.ptr[a .. b] = obj; + } + + export bool opEquals()(auto ref const Vector!(T) r) const + { + return used == r.used && array.ptr[0 .. used] == r.array.ptr[0 .. r.used]; + } +} diff --git a/source/ecs/block_allocator.d b/source/ecs/block_allocator.d deleted file mode 100644 index 30afcc8..0000000 --- a/source/ecs/block_allocator.d +++ /dev/null @@ -1,40 +0,0 @@ -module ecs.block_allocator; - -import ecs.manager; - -import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; - -struct BlockAllocator(uint block_size, uint blocks_in_allocation) -{ - void* next_block = null; - - void* getBlock() - { - if (next_block is null) - allocBlock(); - void* ret = next_block; - next_block = *cast(void**) next_block; - return ret; - } - - void freeBlock(void* block) - { - *cast(void**)block = next_block; - next_block = block; - } - - private void allocBlock() - { - next_block = cast(void*) AlignedMallocator.instance.alignedAllocate( - block_size * blocks_in_allocation, block_size); - foreach (i; 0 .. blocks_in_allocation - 1) - { - void** pointer = cast(void**)(next_block + i * block_size); - *pointer = next_block + (i + 1) * block_size; - } - void** pointer = cast(void**)( - next_block + (blocks_in_allocation - 1) * block_size); - *pointer = null; - } -} diff --git a/source/ecs/ecs.d b/source/ecs/ecs.d deleted file mode 100644 index 60d0f6a..0000000 --- a/source/ecs/ecs.d +++ /dev/null @@ -1,339 +0,0 @@ -module ecs.ecs; - -import std.stdio; - -version(Design): - -alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart); - -struct HasComponentsStore -{ - ulong[4] bits; //256 components - - bool has(HasComponentsStore components) - { - return true; - } - - bool notIn(HasComponentsStore components) - { - return true; - } - - int length() - { - assert(0); - } -} - -// Informacje o kompnencie -struct ComponentInfo -{ - int size; - int aligment; - SerializeJSON funsSerJ; - SerializeBiN funcSerB; -} - -struct System -{ - HasComponentsStore requiredComponents; - HasComponentsStore absenComponents; - HasComponentsStore maybeComponents; - bool enabled; - int priority; - SytemFuncType func; -} -// Informacje o systemie dla konkretnego entitiesa -struct SystemCallData -{ - System* system; - int[] componentsDt; -} - -// Informacje o entitiesie danego typu -struct EntityTypeData -{ - HasComponentsStore components; - int[] deltas; - int totalSize; - int totalAligment = 8; - SystemCallData[] systems; -} - -struct EntitiesBlock -{ - EntityTypeData* typeData; - Entity* freeEntitySlot; - EntitiesBlock* nextBlock; -} - -struct EntityID -{ - ulong id = ulong.max; - static immutable notUsedValue = EntityID(ulong.max); -} - -// Dane konkretnego Entitiesa -struct Entity -{ - EntityID entityID = EntityID.notUsedValue; - union - { - string name; - Entity* nextFreeSlot; - } - - //string eventOnDestroy; - uint group; - EntityID entityID; - //ubyte[XX] thereIsComponentsMemory; -} - -struct Template -{ - HasComponentsStore hasComp; - Entity* entity; -} - -struct Manager -{ - EntityAllocator entityArrayAllcoator; - - ComponentInfo[] components; - System[] systems; - HashMap!(HasComponentsStore, EntitiesBlock*) entitiesDatas; - HashMapTwoWays!(string, Entity*) nameMap; - HashMapTwoWays!(EntityID, Entity*) idMap; - - EntitiesBlock* getEntitiesBlock(HasComponentsStore hasComponents) - { - EntitiesBlock* block = entitiesDatas.get(hasComponents, null); - if (block is null) - { - // If such component combination was never present, add it - block = addNewBlock(hasComponents, block); - return block; - } - // Iterate over list of components until free slot is found or lists ends - do - { - if (block.freeEntitySlot !is null) - { - return block; - } - if (block.nextBlock is null) - { - block = addNewBlock(hasComponents); - return block; - } - block = block.nextBlock; - } - while (block.nextBlock !is null); - - } - - EntitiesBlock* addNewBlock(HasComponentsStore hasComponents, EntitiesBlock* firstBlock) - { - // Get last block so order of blocks is preserved, and first blocks are filled first - EntitiesBlock* lastBlock = firstBlock; - if (lastBlock !is null) - { - while (lastBlock.nextBlock !is null) - { - lastBlock = lastBlock.nextBlock; - } - } - assert(lastBlock is null || lastBlock.nextBlock is null); - - ubyte[] memory = new ubyte[](4096); - EntitiesBlock* block = cast(EntitiesBlock*) memory.ptr; - if (lastBlock is null) - { - EntityTypeData* entityTypeData = newEntityTypeData(hasComponents); - block.typeData = entityTypeData; - block.nextBlock = null; - entitiesDatas.add(hasComponents, block); - } - else - { - lastBlock.nextBlock = block; - block.typeData = lastBlock.typeData; - block.nextBlock = null; - } - } - - void alignNum(ref int num, int aligment) - { - int reminder = num % aligment; - if (reminder != 0) - { - num += aligment - reminder; - } - } - - EntityTypeData* newEntityTypeData(HasComponentsStore hasComponents) - { - EntityTypeData* typeData = new EntityTypeData(); - typeData.components = hasComponents; - ComponentInfo[] components = getComponentsInfo(hasComponents); - typeData.deltas.length = hasComponents.length; - - foreach (i, comp; components) - { - typeData.deltas[i] = typeData.totalSize; - typeData.totalAligment.max(comp.aligment); - typeData.totalSize += comp.size; - alignNum(typeData.totalSize, comp.aligment); - } - alignNum(typeData.totalSize, typeData.totalAligment); - - foreach (sys; systems) - { - if (!typeData.hasComp.has(sys.requiredComponents) - || !typeData.hasComp.notIn(sys.absenComponents)) - { - continue; - } - entTypeData.systems ~= sys; - } - - return typeData; - } - - void addEntity(Template* templ) - { - EntitiesBlock* block = getEntitiesBlock(templ.hasComp); - Entity* newEntity = block.freeEntitySlot; - block.freeEntitySlot = newEntity.nextFreeSlot; - // from to size - memcpy(temp.entity, newEntity, block.typeData.totalSize); - } - - void addSystem(Func)(int priority) - { - HasComponentsStore requiredComponents; - HasComponentsStore absenComponents; - HasComponentsStore maybeComponents; - - void systemCaller(ref SystemCallData data, void * componentsStart) - { - Func(cast(FUnc.par1Type)(componentsStart + data.componentsDt[0]), - cast(FUnc.par1Type)(componentsStart + data.componentsDt[1])/*...*/); - } - System* system = new System(&systemCaller, entTypeData); - systems ~= system; - - foreach (ref entTypeData; entitiesDatas) - { - if (!entTypeData.hasComp.has(requiredComponents) - || !entTypeData.hasComp.notIn(absenComponents)) - { - continue; - } - entTypeData.systems ~= system; - } - } -} - -void someSystem(CompA a, CompB b, CompC* c) -{ -} - -void main() -{ - writeln("Edit source/app.d to start your project."); -} - -class System -{ - - void start() - { - - } - - void end() - { - - } - - void update(ref ObjRend a) - { - - } - - void useEvent(EventData evvv, ref ObjRend a) - { - - } -} - -alias SerializeVector = ubyte[]; - -__gshared EntityManager gEntityManager; - -unittest -{ - struct ComponentA - { - __gshared static int component_id; - int a; - ulong b; - - static void serializeComponent(ref ComponentA comp, SerializeVector output) - { - - } - - static void deerializeComponent(ref ComponentA comp, ubyte[] data) - { - - } - - } - - gEM.addComponet!ComponentA(); - assert(ComponentA.component_id == 0); - ComponentData* ccc = &gEM.componnets[ComponentA.component_id]; - assert(ccc.totalAligment == 8); - assert(ccc.totalSize == 8); - - HasComponentsStore hasComponents; - hasComponents.addComponet(ComponentA.component_id); - EntityTempalte* tmpl = gEM.allocateTemplate(hasComponents); - - ComponentA* comp = tmpl.getComponent!ComponentA(ComponentA.component_id); - comp.a = 111; - comp.b = 222; - - gEM.addEntity(tmpl); - - struct SystemAdd - { - void update(ref ComponentA a) - { - a.a+=1000; - b.b+=2000; - - } - - void handleEvent(EventData evvv, ref ComponentA a) - { - } - } - - int priority=10; - gEM.registerSystem!(SystemAdd)(priority); - gEM.updateStepAll(); - foreach(EntityID id; gEM.IterateByAllEntiteis){ - assert(id.getComponent(ComponentA.component_id)); - ComponentA* ccc=id.getComponent(ComponentA.component_id); - assert(ccc.a==1111); - assert(ccc.b==2222); - } - - - -} - diff --git a/source/ecs/entity.d b/source/ecs/entity.d deleted file mode 100644 index 5e85211..0000000 --- a/source/ecs/entity.d +++ /dev/null @@ -1,45 +0,0 @@ -module ecs.entity; - -import ecs.manager; - -struct EntityID -{ - uint id; - uint counter; -} - -struct Entity -{ - EntityID id; - - void updateID() - { - EntityManager.instance.id_manager.update(this); - } - - T* getComponent(T)() - { - EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); - EntityManager.EntityInfo* info = block.type_info; - if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) - return null; - - static if (EntityID.sizeof == 8) - uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3); - else - uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof()); - return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof); - } -} - -export struct EntityTemplate -{ - ubyte[] entity_data; - EntityManager.EntityInfo* info; - - T* getComponent(T)() - { - if(T.component_id >= info.tmpl_deltas.length)return null; - return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]); - } -} diff --git a/source/ecs/events.d b/source/ecs/events.d deleted file mode 100644 index 3a09bc8..0000000 --- a/source/ecs/events.d +++ /dev/null @@ -1,125 +0,0 @@ -module ecs.events; - -import ecs.manager; -import ecs.block_allocator; -import ecs.entity; - -import std.algorithm.comparison : max; - -/* -struct Event -{ - uint type; -}*/ - -mixin template EventManagerCode() -{ - - //@disable this(); - - this(EntityManager m) - { - manager = m; - } - - void sendSelfEvent(Ev)(EntityID id, Ev event) - { - ushort size = cast(ushort)(Ev.sizeof); // + EntityID.sizeof + ushort.sizeof); - ushort alignment = cast(ushort)(Ev.alignof); - - EventList* list = &process_events; - - if (list.current_block is null) - { - list.current_block = cast(EventBlock*) allocator.getBlock(); - list.first_block = list.current_block; - list.current_block.index = cast(ushort)((void*).sizeof + ushort.sizeof); - } - - ushort index = cast(ushort)( - list.current_block.index + ushort.sizeof + EntityID.sizeof + ushort.sizeof); - - ushort aligned_index = index; //cast(ushort)(list.current_block.index); - alignNum(aligned_index, alignment); - - if (aligned_index + Ev.sizeof > events_block_size) - { - list.current_block.next = cast(EventBlock*) allocator.getBlock(); - list.current_block = list.current_block.next; - list.current_block.index = cast(ushort)((void*).sizeof + ushort.sizeof); - - index = cast(ushort)((void*) - .sizeof + ushort.sizeof + ushort.sizeof + EntityID.sizeof + ushort.sizeof); // + EntityID.sizeof + ushort.sizeof; - - aligned_index = index; - alignNum(aligned_index, alignment); - /*if(alignment > EntityID.sizeof + uint.sizeof)aligned_index = alignment; - else aligned_index = uint.sizeof * 4;*/ - } - - EventBlock* block = list.current_block; - - ushort align_ = cast(ushort)(aligned_index - index); - *cast(ushort*)&block.data[block.index] = align_; - index = cast(ushort)(aligned_index - (EntityID.sizeof + ushort.sizeof)); - *cast(ushort*)&block.data[index] = Ev.event_id; - *cast(EntityID*)&block.data[index + 2] = id; - *cast(Ev*)&block.data[aligned_index] = event; - block.index = cast(ushort)(aligned_index + Ev.sizeof); - } - - void clearEvents() - { - EventList tmp = current_events; - current_events = process_events; - process_events = tmp; - - EventBlock* block = process_events.first_block; - - /*if(block) - { - import std.stdio; - writeln(block.data); - }*/ - - while (block) - { - EventBlock* free = block; - block = block.next; - allocator.freeBlock(free); - } - process_events.first_block = null; - process_events.current_block = null; - } - - ///Single page size. Must be power of two. - enum events_block_size = 1 << 12; - ///Number of pages in block. - enum events_blocks_in_allocation = 128; - - struct EventBlock - { - union - { - struct - { - EventBlock* next; - ushort index = 2; - } - - ubyte[events_block_size] data; - } - } - - struct EventList - { - EventBlock* first_block; - EventBlock* current_block; - } - - EventList current_events; - EventList process_events; - - BlockAllocator!(events_block_size, events_blocks_in_allocation) allocator; - EntityManager manager; -} diff --git a/source/ecs/hash_map.d b/source/ecs/hash_map.d deleted file mode 100755 index 2a62201..0000000 --- a/source/ecs/hash_map.d +++ /dev/null @@ -1,396 +0,0 @@ -module ecs.hash_map; - -import std.traits; - -import ecs.vector; -import ecs.traits; - -enum doNotInline = "version(DigitalMars)pragma(inline,false);version(LDC)pragma(LDC_never_inline);"; - -private enum HASH_EMPTY = 0; -private enum HASH_DELETED = 0x1; -private enum HASH_FILLED_MARK = ulong(1) << 8 * ulong.sizeof - 1; - -export ulong defaultHashFunc(T)(auto ref T t) { - static if (isIntegral!(T)) { - return hashInt(t); - } else { - return hashInt(t.hashOf); // hashOf is not giving proper distribution between H1 and H2 hash parts - } -} - -// Can turn bad hash function to good one -export ulong hashInt(ulong x) nothrow @nogc @safe { - x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; - x = (x ^ (x >> 27)) * 0x94d049bb133111eb; - x = x ^ (x >> 31); - return x; -} - -struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { - alias Key = KeyPar; - alias Value = ValuePar; - - enum rehashFactor = 0.75; - enum size_t getIndexEmptyValue = size_t.max; - - static struct KeyVal { - Key key; - Value value; - } - - static struct Bucket { - ulong hash; - KeyVal keyValue; - } - - Vector!Bucket elements; // Length should be always power of 2 - size_t length; // Used to compute loadFactor - size_t markerdDeleted; - - export void clear() { - elements.clear(); - length = 0; - markerdDeleted = 0; - } - - export void reset() { - elements.reset(); - length = 0; - markerdDeleted = 0; - } - - export bool isIn(ref Key el) { - return getIndex(el) != getIndexEmptyValue; - } - - export bool isIn(Key el) { - return getIndex(el) != getIndexEmptyValue; - } - - export Value* getPtr()(auto ref Key k) { - size_t index = getIndex(k); - if (index == getIndexEmptyValue) { - return null; - } else { - return &elements[index].keyValue.value; - } - } - - export ref Value get()(auto ref Key k) { - size_t index = getIndex(k); - assert(index != getIndexEmptyValue); - return elements[index].keyValue.value; - } - - deprecated("Use get with second parameter.") export auto ref Value getDefault()( - auto ref Key k, auto ref Value defaultValue) { - return get(k, defaultValue); - } - - export auto ref Value get()(auto ref Key k, auto ref Value defaultValue) { - size_t index = getIndex(k); - if (index == getIndexEmptyValue) { - return defaultValue; - } else { - return elements[index].keyValue.value; - } - } - - export ref Value getInsertDefault()(auto ref Key k, auto ref Value defaultValue) { - size_t index = getIndex(k); - if (index == getIndexEmptyValue) { - add(k, defaultValue); - } - index = getIndex(k); - assert(index != getIndexEmptyValue); - return elements[index].keyValue.value; - - } - - export bool tryRemove(Key el) { - size_t index = getIndex(el); - if (index == getIndexEmptyValue) { - return false; - } - length--; - elements[index].hash = HASH_DELETED; - markerdDeleted++; - return true; - } - - export void remove(Key el) { - bool ok = tryRemove(el); - assert(ok); - } - - export ref Value opIndex()(auto ref Key key) { - return get(key); - } - - export void opIndexAssign()(auto ref Value value, auto ref Key key) { - add(key, value); - } - - export void add()(auto ref Key key, auto ref Value value) { - size_t index = getIndex(key); - if (index != getIndexEmptyValue) { - elements[index].keyValue.value = value; - return; - } - - if (getLoadFactor(length + 1) > rehashFactor - || getLoadFactor(length + markerdDeleted) > rehashFactor) { - rehash(); - } - length++; - - immutable ulong hash = hashFunc(key) | HASH_FILLED_MARK; - immutable size_t rotateMask = elements.length - 1; - index = hash & rotateMask; // Starting point - - while (true) { - Bucket* gr = &elements[index]; - if ((gr.hash & HASH_FILLED_MARK) == 0) { - if (gr.hash == HASH_DELETED) { - markerdDeleted--; - } - gr.hash = hash; - gr.keyValue.key = key; - gr.keyValue.value = value; - return; - } - - index++; - index = index & rotateMask; - } - } - - // For debug - //int numA; - //int numB; - - export size_t getIndex(Key el) { - return getIndex(el); - } - - export size_t getIndex(ref Key el) { - mixin(doNotInline); - - immutable size_t groupsLength = elements.length; - if (groupsLength == 0) { - return getIndexEmptyValue; - } - - immutable ulong hash = hashFunc(el) | HASH_FILLED_MARK; - immutable size_t rotateMask = groupsLength - 1; - size_t index = hash & rotateMask; // Starting point - - //numA++; - while (true) { - //numB++; - Bucket* gr = &elements[index]; - if (gr.hash == hash && gr.keyValue.key == el) { - return index; - } - if (gr.hash == HASH_EMPTY) { - return getIndexEmptyValue; - } - - index++; - index = index & rotateMask; - } - - } - - export float getLoadFactor(size_t forElementsNum) { - if (elements.length == 0) { - return 1; - } - return cast(float) forElementsNum / (elements.length); - } - - export void rehash() { - mixin(doNotInline); - // Get all elements - Vector!KeyVal allElements; - allElements.reserve(elements.length); - - foreach (ref Bucket el; elements) { - if ((el.hash & HASH_FILLED_MARK) == 0) { - el.hash = HASH_EMPTY; - continue; - } - el.hash = HASH_EMPTY; - allElements ~= el.keyValue; - - } - - if (getLoadFactor(length + 1) > rehashFactor) { // Reallocate - elements.length = (elements.length ? elements.length : 4) << 1; // Power of two, initially 8 elements - } - - // Insert elements - foreach (i, ref el; allElements) { - add(el.key, el.value); - } - length = allElements.length; - markerdDeleted = 0; - } - - // foreach support - export int opApply(DG)(scope DG dg) { - int result; - foreach (ref Bucket gr; elements) { - if ((gr.hash & HASH_FILLED_MARK) == 0) { - continue; - } - static if (isForeachDelegateWithTypes!(DG, Key)) { - result = dg(gr.keyValue.key); - } else static if (isForeachDelegateWithTypes!(DG, Value)) { - result = dg(gr.keyValue.value); - } else static if (isForeachDelegateWithTypes!(DG, Key, Value)) { - result = dg(gr.keyValue.key, gr.keyValue.value); - } else { - static assert(0); - } - if (result) - break; - - } - - return result; - } - - export int byKey(scope int delegate(Key k) dg) { - int result; - foreach (ref Key k; this) { - result = dg(k); - if (result) - break; - } - return result; - } - - export int byValue(scope int delegate(ref Value k) dg) { - int result; - foreach (ref Value v; this) { - result = dg(v); - if (result) - break; - } - return result; - } - - export int byKeyValue(scope int delegate(ref Key k, ref Value v) dg) { - int result; - foreach (ref Key k, ref Value v; this) { - result = dg(k, v); - if (result) - break; - } - return result; - } - - import std.format : FormatSpec, formatValue; - - /** - * Preety print - */ - export void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) { - formatValue(sink, '[', fmt); - foreach (ref k, ref v; &byKeyValue) { - formatValue(sink, k, fmt); - formatValue(sink, ':', fmt); - formatValue(sink, v, fmt); - formatValue(sink, ", ", fmt); - } - formatValue(sink, ']', fmt); - } - -} - -static void dumpHashMapToJson(T)(ref T map, string path = "HashMapDump.json") { - Vector!char data; - import std.file; - import mutils.serializer.json; - - JSONSerializer.instance.serialize!(Load.no)(map, data); - std.file.write(path, data[]); -} - -static void printHashMap(T)(ref T map) { - import std.stdio; - - writeln(T.stringof, " dump:\n"); - foreach (k, v; &map.byKeyValue) { - writefln("%20s : %20s", k, v); - } -} - -unittest { - HashMap!(int, int) map; - - assert(map.isIn(123) == false); - assert(map.markerdDeleted == 0); - map.add(123, 1); - map.add(123, 1); - assert(map.isIn(123) == true); - assert(map.isIn(122) == false); - assert(map.length == 1); - map.remove(123); - assert(map.markerdDeleted == 1); - assert(map.isIn(123) == false); - assert(map.length == 0); - assert(map.tryRemove(500) == false); - map.add(123, 1); - assert(map.markerdDeleted == 0); - assert(map.tryRemove(123) == true); - - foreach (i; 1 .. 130) { - map.add(i, 1); - } - - foreach (i; 1 .. 130) { - assert(map.isIn(i)); - } - - foreach (i; 130 .. 500) { - assert(!map.isIn(i)); - } - - foreach (int el; map) { - assert(map.isIn(el)); - } -} - -unittest { - HashMap!(int, int) map; - map.add(1, 10); - assert(map.get(1) == 10); - assert(map.get(2, 20) == 20); - assert(!map.isIn(2)); - assert(map.getInsertDefault(2, 20) == 20); - assert(map.get(2) == 20); - map[5] = 50; - assert(map[5] == 50); - foreach (k; &map.byKey) { - } - foreach (k, v; &map.byKeyValue) { - } - foreach (v; &map.byValue) { - } -} - -unittest { - HashMap!(Vector!char, int) map; - Vector!char vecA; - - vecA ~= "AAA"; - map.add(vecA, 10); - assert(map[vecA] == 10); - map.add(vecA, 20); - assert(map[vecA] == 20); - //assert(vecA=="AAA"); - //assert(map["AAA"]==10);// TODO hashMap Vector!char and string -} diff --git a/source/ecs/id_manager.d b/source/ecs/id_manager.d deleted file mode 100644 index 86542e3..0000000 --- a/source/ecs/id_manager.d +++ /dev/null @@ -1,86 +0,0 @@ -module ecs.id_manager; - -import ecs.entity; -import ecs.vector; - -struct IDManager -{ - EntityID getNewID() - { - if (m_next_id >= m_ids_array.length) - m_ids_array.add(Data()); - EntityID id; - id.id = m_next_id; - id.counter = /*++*/m_ids_array[m_next_id].counter; - m_next_id = m_ids_array[m_next_id].next_id; - if (m_next_id == uint.max) - m_next_id = cast(uint) m_ids_array.length; - return id; - } - - void releaseID(EntityID id) - { - Data* data = &m_ids_array[id.id]; - if (data.counter != id.counter) - return; - data.counter++; - data.next_id = m_next_id; - data.entity = null; - m_next_id = id.id; - } - - void update(ref Entity entity) - { - if(entity.id.counter == m_ids_array[entity.id.id].counter)m_ids_array[entity.id.id].entity = &entity; - } - - export Entity* getEntityPointer(EntityID id) - { - Data* data = &m_ids_array[id.id]; - if (data.counter != id.counter) - return null; - else - return data.entity; - } - - export bool isExist(EntityID id) - { - Data* data = &m_ids_array[id.id]; - return data.counter == id.counter; - } - - struct Data - { - uint counter = 0; - uint next_id = uint.max; - Entity* entity = null; - } - - private uint m_next_id = 0; - Vector!Data m_ids_array; -} - -unittest -{ - IDManager manager; - EntityID id1 = manager.getNewID(); - EntityID id2 = manager.getNewID(); - EntityID id3 = manager.getNewID(); - - assert(id1 == EntityID(0, 1)); - assert(id2 == EntityID(1, 1)); - assert(id3 == EntityID(2, 1)); - - manager.releaseID(id2); - manager.releaseID(id1); - - id2 = manager.getNewID(); - id1 = manager.getNewID(); - - assert(id1 == EntityID(1, 2)); - assert(id2 == EntityID(0, 2)); - assert(id3 == EntityID(2, 1)); - assert(manager.isExist(id3)); - assert(!manager.isExist(EntityID(0, 1))); - -} diff --git a/source/ecs/manager.d b/source/ecs/manager.d deleted file mode 100644 index 2ba41fa..0000000 --- a/source/ecs/manager.d +++ /dev/null @@ -1,1231 +0,0 @@ -module ecs.manager; - -import std.algorithm : max; -import std.conv : to; -import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; -import std.traits; - -import core.stdc.stdlib; -import core.stdc.string; - -import ecs.entity; -import ecs.block_allocator; -import ecs.hash_map; -import ecs.id_manager; -import ecs.system; -import ecs.vector; -import ecs.events; - -alias gEM = EntityManager.instance; -alias SerializeVector = ecs.vector.Vector!ubyte; - -class EntityManager -{ - - export static void initialize() - { - if (instance is null) - instance = Mallocator.instance.make!EntityManager; - } - - export static void destroy() - { - if (instance is null) - return; - - foreach (ref system; instance.systems) - { - system.disable(); - } - - foreach (ref system; instance.systems) - { - if (system.m_destroy) - system.m_destroy(system.m_system_pointer); - } - - Mallocator.instance.dispose(instance); - instance = null; - } - - this() - { - //event_manager = EventManager(this); - //event_manager.manager = this; - } - - void registerSystem(Sys)(int priority) - { - alias STC = ParameterStorageClass; - - System system; - - static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort)) - { - static assert(0, "System should have \"__gshared ushort system_id"); - } - - static if (hasMember!(Sys, "update")) - { - alias types = Parameters!(Sys.update); - alias storages = ParameterStorageClassTuple!(Sys.update); - static string genCall()() - { - string ret; - { - uint i = 0; - uint opt = 0; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "if(opt_array" ~ opt.to!string ~ " !is null)opt_ptr" - ~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];"; - opt++; - } - } - } - - /*foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1) - .to!string ~ "]),"; - }*/ - uint i = 0; - uint req = 0; - uint opt = 0; - ret ~= "s.update(id_array[i],"; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "opt_ptr" ~ (opt++).to!string ~ ","; - } - else - { - ret ~= "array" ~ (req++).to!string ~ "[i],"; - } - } - - - ret ~= ");"; - return ret; - } - - static string genArrays()() - { - string ret; - - uint i = 0; - uint req = 0; - uint opt = 0; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "PointerTarget!(types[" ~ i.to!string - ~ "])[] opt_array" ~ opt.to!string ~ " = null;"; - ret ~= "if(info.deltas[types[" ~ i.to!string ~ "].component_id] != 0)opt_array" - ~ opt.to!string ~ " - = (cast(types[" ~ i.to!string ~ "])(cast(void*)block + info.deltas[types[" - ~ i.to!string ~ "].component_id]))[0..block.entities_count];"; - ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";"; - opt++; - } - else - { - ret ~= "types[" ~ i.to!string ~ "][] array" ~ req.to!string ~ " = (cast(types[" - ~ i.to!string ~ "]*)(cast(void*)block + info.deltas[types[" - ~ i.to!string ~ "].component_id]))[0..block.entities_count];"; - req++; - } - } - return ret; - } - - static string genCompList()() - { - string ret = "ushort comp;uint req;uint opt;"; - foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= " - static if(isPointer!(types[" ~ i.to!string - ~ "]))opt++; - else static if(storages[" ~ i.to!string ~ "] == STC.ref_)req++;\n - else static assert(0,\"Can't register system \\\"" ~ Sys.stringof - ~ "\\\". Unsupported parameter type \\\"\"~types[" - ~ i.to!string ~ "].stringof~\"\\\".\");"; - } - ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; - ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; - ret ~= "opt = 0;req = 0;"; - foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= " - static if(isPointer!(types[" ~ i.to!string ~ "])) - { - comp = components_map.get(PointerTarget!(types[" - ~ i.to!string ~ "]).stringof, ushort.max);\n - if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof - ~ "\\\" due to non existing component \\\"\"~types[" ~ i.to!string ~ "].stringof~\"\\\".\"); - system.m_optional_components[opt++] = comp; - } - else static if(storages[" - ~ i.to!string ~ "] == STC.ref_) - { - comp = components_map.get(types[" ~ i.to!string ~ "].stringof, ushort.max);\n - if(comp == ushort.max)assert(0,\"Can't register system \\\"" - ~ Sys.stringof ~ "\\\" due to non existing component \\\"\"~types[" - ~ i.to!string ~ "].stringof~\"\\\".\"); - system.m_components[req++] = comp; - }"; - } - return ret; - } - - static void callUpdate(ref CallData data, void* entity) - { - static if (hasMember!(Sys, "update")) - { - Sys* s = cast(Sys*) data.system.m_system_pointer; - - void*[] pointers = (cast(void**) alloca(data.system.m_components.length * (void*) - .sizeof))[0 .. data.system.m_components.length]; - void*[] optional_pointers = (cast(void**) alloca( - data.system.m_optional_components.length * (void*).sizeof))[0 - .. data.system.m_optional_components.length]; - - EntitiesBlock* block = data.info.first_block; - while (block !is null) - { - EntityInfo* info = block.type_info; - Entity[] id_array = (cast(Entity*) block.dataBegin())[0 - .. block.entities_count]; - mixin(genArrays()); - foreach (i; 0 .. block.entities_count) - { - mixin(genCall()); - //data_pointer += EntityID.sizeof; //data.info.size; - /*foreach (ref pointer; pointers) - pointer += size; - foreach (ref pointer; optional_pointers) - if (pointer != null) - pointer += size;*/ - } - - block = block.next_block; - } - - } - } - - system.m_update = &callUpdate; - } - - static string catchFunc()(string member, string func) - { - string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\")) - { - static void call" ~ func - ~ "(void* system_pointer) - { - - Sys* s = cast(Sys*) system_pointer; - s." ~ func ~ "(); - } - - system." - ~ member ~ " = &call" ~ func ~ "; - }"; - return ret; - } - - mixin(catchFunc("m_enable", "onEnable")); - mixin(catchFunc("m_disable", "onDisable")); - mixin(catchFunc("m_create", "onCreate")); - mixin(catchFunc("m_destroy", "onDestroy")); - mixin(catchFunc("m_begin", "onBegin")); - mixin(catchFunc("m_end", "onEnd")); - - system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys; - system.m_priority = priority; - - //system.m_components = Mallocator.instance.makeArray!uint(types.length - 1); - static if (hasMember!(Sys, "update")) - { - mixin(genCompList()); - } - - ushort sys_id = systems_map.get(Sys.stringof, ushort.max); - if (sys_id < systems.length) - { - system.enable(); - - /*if (systems[sys_id].m_destroy) - systems[sys_id].m_destroy(systems[sys_id].m_system_pointer);*/ - if (system.m_create) - system.m_create(system.m_system_pointer); - - systems[sys_id] = system; - Sys.system_id = sys_id; - } - else - { - string name = Mallocator.instance.makeArray(Sys.stringof); - systems_map.add(name, cast(ushort) systems.length); - - systems.add(system); - - if (system.m_create) - system.m_create(system.m_system_pointer); - - systems[$ - 1].enable(); - - Sys.system_id = cast(ushort)(systems.length - 1); - - foreach (info; &entities_infos.byValue) - { - addEntityCaller(*info, cast(uint) systems.length - 1); - } - } - - updateEntityCallers(); - } - - System* getSystem(ushort id) - { - return &systems[id]; - } - - Sys* getSystem(Sys)() - { - return cast(Sys*) systems[Sys.system_id].m_system_pointer; - } - - void registerComponent(Comp)() - { - ComponentInfo info; - - static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort)) - { - static assert(0, "Component should have \"__gshared ushort component_id"); - } - - static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy) - && is(ReturnType!(Comp.onDestroy) == void) - && Parameters!(Comp.onDestroy).length == 0) - { - static void callDestroy(void* pointer) - { - (cast(Comp*) pointer).onDestroy(); - } - - info.destroy_callback = &callDestroy; - } - - info.size = Comp.sizeof; - info.alignment = Comp.alignof; //8; - info.init_data = Mallocator.instance.makeArray!ubyte(Comp.sizeof); - *cast(Comp*) info.init_data.ptr = Comp.init; // = Comp(); - - ushort comp_id = components_map.get(Comp.stringof, ushort.max); - if (comp_id < components.length) - { - Comp.component_id = comp_id; - components[comp_id] = info; - } - else - { - components.add(info); - Comp.component_id = cast(ushort)(components.length - 1); - string name = Mallocator.instance.makeArray(Comp.stringof); - components_map.add(name, cast(ushort)(components.length - 1)); - } - } - - void registerEvent(Ev)() - { - EventInfo info; - - static if (!(hasMember!(Ev, "event_id")) || !is(typeof(Ev.event_id) == ushort)) - { - static assert(0, "Event should have \"__gshared ushort event_id"); - } - - static if (hasMember!(Ev, "onDestroy") && isFunction!(Ev.onDestroy) - && is(ReturnType!(Ev.onDestroy) == void) && Parameters!(Ev.onDestroy).length == 0) - { - static void callDestroy(void* pointer) - { - (cast(Ev*) pointer).onDestroy(); - } - - info.destroy_callback = &callDestroy; - } - - info.size = Ev.sizeof; - info.alignment = Ev.alignof; - - ushort event_id = events_map.get(Ev.stringof, ushort.max); - if (event_id < events.length) - { - Ev.event_id = event_id; - } - else - { - events.add(info); - Ev.event_id = cast(ushort)(events.length - 1); - events_map.add(Ev.stringof, cast(ushort)(events.length - 1)); - } - } - - export void update() - { - foreach (info; &entities_infos.byValue) - { - foreach (data; info.callers) - { - if (data.system.enabled) - (cast(SytemFuncType) data.system.m_update)(data, null); //caller(call_data,null); - } - } - } - - static void alignNum(ref ushort num, ushort alignment) - { - num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1)); - } - - static ushort alignedNum(ushort num, ushort alignment) - { - return cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); - } - - extern (C) static int compareUShorts(const void* a, const void* b) - { - ushort _a = *cast(ushort*) a; - ushort _b = *cast(ushort*) b; - if (_a < _b) - return -1; - else if (_a == _b) - return 0; - else - return 1; - } - - export EntityTemplate* allocateTemplate(ushort[] components_ids) - { - - ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * components_ids.length))[0 - .. components_ids.length]; - ids[0 .. $] = components_ids[]; - qsort(ids.ptr, ids.length, ushort.sizeof, &compareUShorts); - { - uint j = 1; - foreach (i; 1 .. ids.length) - { - if (ids[i] != ids[j - 1]) - { - ids[j] = ids[i]; - j++; - } - else - debug assert(0, "Duplicated components in template!!!"); - } - ids = ids[0 .. j]; - } - - EntityInfo* info = getEntityInfo(ids); - - EntityTemplate* temp = Mallocator.instance.make!EntityTemplate; - temp.entity_data = Mallocator.instance.makeArray!ubyte(info.size); - temp.info = info; - - //fill components with default data - foreach (comp; info.components) - { - temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size] - = components[comp].init_data; - } - - - return temp; - } - - export EntityInfo* getEntityInfo(ushort[] ids) - { - EntityInfo* info = entities_infos.get(ids, null); - if (info is null) - { - info = Mallocator.instance.make!EntityInfo; - - info.components = Mallocator.instance.makeArray(ids); - info.deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1); - - info.size = EntityID.sizeof; - info.alignment = EntityID.alignof; - - info.tmpl_deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1); - uint components_size = EntityID.sizeof; - - foreach (i, id; ids) - { - info.alignment = max(info.alignment, components[id].alignment); - alignNum(info.size, components[id].alignment); - info.tmpl_deltas[id] = info.size; - info.size += components[id].size; - components_size += components[id].size; - } - alignNum(info.size, info.alignment); - - /**/ - - uint block_memory = cast(uint)( - page_size - EntitiesBlock.sizeof - (info.size - components_size)); - //uint entity_comps_size = EntityID.sizeof; - uint mem_begin = EntitiesBlock.sizeof; - - /*foreach (id; ids) - { - entity_comps_size += components[id].size; - }*/ - - uint entites_in_block = block_memory / info.size; //entity_comps_size; - info.max_entities = cast(ushort) entites_in_block; - ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof); - - foreach (i, id; ids) - { - alignNum(current_delta, components[id].alignment); - info.deltas[id] = cast(ushort) current_delta; - current_delta += entites_in_block * components[id].size; - } - - - foreach (uint i, ref system; systems) - { - if (system.m_update is null) - continue; - addEntityCaller(*info, i); - } - - updateEntityCallers(); - - entities_infos.add(info.components, info); - } - return info; - } - - export void updateEntityCallers() - { - foreach (entity; &entities_infos.byValue) - { - foreach (ref caller; entity.callers) - { - caller.system = &systems[caller.system_id]; - } - } - } - - export void addEntityCaller(ref EntityInfo entity, uint system_id) - { - System* system = &systems[system_id]; - CallData call_data = CallData(system_id, system, &entity, null); - uint num = cast(uint)(system.m_components.length + system.m_optional_components.length); - ushort[] deltas = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - uint delta_id = 0; - - foreach (id; system.m_components) - { - deltas[delta_id] = ushort.max; - foreach (i2, id2; entity.components) - { - if (id2 == id) - { - deltas[delta_id] = entity.deltas[id2]; - break; - } - } - if (deltas[delta_id] == ushort.max) - { - deltas = null; - break; - } - delta_id++; - } - if (deltas is null) - return; - - foreach (id; system.m_optional_components) - { - deltas[delta_id] = ushort.max; - foreach (i2, id2; entity.components) - { - if (id2 == id) - { - deltas[delta_id] = entity.deltas[id2]; - break; - } - } - /*if (deltas[delta_id] == ushort.max) - { - deltas = null; - break; - }*/ - delta_id++; - } - - call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.m_components.length); - - uint index = 0; - for (; index < entity.callers.length; index++) - { - CallData* caller = &entity.callers[index]; - if (caller.system.priority >= call_data.system.priority) - break; - } - entity.callers.add(call_data, index); - } - - export Entity* getEntity(EntityID id) - { - return cast(Entity*) id_manager.getEntityPointer(id); - } - - export void removeComponents(EntityID entity_id, ushort[] del_ids) - { - uint num = cast(uint) del_ids.length; - change_entities_list.add(0); - change_entities_list.add((cast(ubyte*)&entity_id)[0 .. 8]); - change_entities_list.add((cast(ubyte*)&num)[0 .. 4]); - change_entities_list.add(cast(ubyte[]) del_ids); - } - - private void __removeComponents(EntityID entity_id, ushort[] del_ids) - { - Entity* entity = id_manager.getEntityPointer(entity_id); - if (!entity) - return; - EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_info; - - qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts); - - ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length)))[0 - .. info.components.length]; - - uint j = 0; - uint k = 0; - foreach (id; info.components) - { - while (k < del_ids.length && del_ids[k] < id) - k++; - if (k >= del_ids.length) - { - ids[j++] = id; - } - else if (del_ids[k] == info.components[j]) - { - k++; - } - else - ids[j++] = id; - } - - if (j == info.components.length) - return; - - EntityInfo* new_info = getEntityInfo(ids[0 .. j]); - - EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); - - void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; - - Entity* new_entity = cast(Entity*) start; - new_entity.id = entity.id; - new_entity.updateID(); - - static if (EntityID.sizeof == 8) - uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3); - else - uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof()); - foreach (comp; new_info.components) - { - uint comp_size = components[comp].size; - memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size, - cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); - } - - new_block.entities_count++; - - removeEntityNoID(entity, block); - } - - void removeComponents(Components...)(EntityID entity_id) - { - const uint num = Components.length; - ushort[num] del_ids; - static foreach (i, comp; Components) - { - del_ids[i] = comp.component_id; - } - - /*change_entities_list.add(0); - change_entities_list.add((cast(ubyte*)&entity_id)[0..8]); - change_entities_list.add((cast(ubyte*)&num)[0..4]); - change_entities_list.add(cast(ubyte[])del_ids);*/ - removeComponents(entity_id, del_ids); - } - - private void __addComponents(EntityID entity_id, ushort[] new_ids, void*[] data_pointers) - { - uint num = cast(uint) new_ids.length; - Entity* entity = id_manager.getEntityPointer(entity_id); - if (!entity) - return; - EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_info; - ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 - .. info.components.length + num]; - /*ushort[num] new_ids; - - static foreach (i, comp; Components) - { - new_ids[i] = comp.component_id; - }*/ - - /*void*[num] pointers; - - static foreach (i, comp; comps) - { - pointers[i] = ∁ - }*/ - - foreach (int i; 0 .. num) - { - ushort min = new_ids[i]; - int pos = i; - foreach (int j; i .. num) - { - if (new_ids[j] < min) - { - min = new_ids[j]; - pos = j; - } - } - if (pos != i) - { - ushort id = new_ids[i]; - new_ids[i] = new_ids[pos]; - new_ids[pos] = id; - void* ptr = data_pointers[i]; - data_pointers[i] = data_pointers[pos]; - data_pointers[pos] = ptr; - } - } - - uint j = 0; - uint k = 0; - foreach (ref id; ids) - { - if (k >= new_ids.length) - { - id = info.components[j++]; - continue; - } - if (j >= info.components.length) - { - id = new_ids[k++]; - continue; - } - debug if (new_ids[k] == info.components[j]) - assert(0, "Trying to add already existing component!"); - if (new_ids[k] < info.components[j]) - { - id = new_ids[k++]; - } - else - id = info.components[j++]; - } - - EntityInfo* new_info = getEntityInfo(ids); - - EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); - - //removeEntityNoID(entity, block); - - void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; - - Entity* new_entity = cast(Entity*) start; - new_entity.id = entity.id; - new_entity.updateID(); - - j = 0; - k = 0; - static if (EntityID.sizeof == 8) - uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3); - else - uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof()); - foreach (ref id; ids) - { - void* dst = cast(void*) new_block + new_info.deltas[id] + ( - new_block.entities_count + new_block.added_count) * components[id].size; - uint size = components[id].size; - if (k >= new_ids.length) - { - memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); - j++; - } - else if (j >= info.components.length) - { - memcpy(dst, data_pointers[k], size); - k++; - } - else if (id == new_ids[k]) - { - memcpy(dst, data_pointers[k], size); - k++; - } - else - { - memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); - j++; - } - } - - - new_block.entities_count++; - removeEntityNoID(entity, block); - } - - void addComponents(Components...)(EntityID entity_id, Components comps) - { - const uint num = Components.length; - Entity* entity = id_manager.getEntityPointer(entity_id); - EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_info; - ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 - .. info.components.length + num]; - ushort[num] new_ids; - - static foreach (i, comp; Components) - { - new_ids[i] = comp.component_id; - } - - /*void*[num] pointers; - - static foreach (i, comp; comps) - { - pointers[i] = ∁ - }*/ - - change_entities_list.add(1); - change_entities_list.add((cast(ubyte*)&entity_id)[0 .. 8]); - change_entities_list.add((cast(ubyte*)&num)[0 .. 4]); - change_entities_list.add(cast(ubyte[]) new_ids); - static foreach (i, comp; comps) - { - change_entities_list.add((cast(ubyte*)&comp)[0 .. comp.sizeof]); - } - - //__addComponents(entity_id, new_ids, pointers); - } - - export void freeTemplate(EntityTemplate* template_) - { - Mallocator.instance.dispose(template_.entity_data); - Mallocator.instance.dispose(template_); - } - - export ref Entity addEntity(EntityTemplate* tmpl) - { - EntitiesBlock* block = findBlockWithFreeSpace(tmpl.info); - uint id = (block.entities_count + block.added_count); - EntityInfo* info = tmpl.info; - - void* data_begin = block.dataBegin(); - void* start = data_begin + EntityID.sizeof * id; - //memcpy(data_begin + EntityID.sizeof * id, tmpl.entity_data.ptr, EntityID.sizeof); - foreach (i, comp; info.components) - { - memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id, - tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size); - } - - - if (!block.added_count) - blocks_to_update.add(block); - - Entity* entity = cast(Entity*) start; - entity.id = id_manager.getNewID(); - entity.updateID(); - block.added_count++; - //block.entities_count++; - return *entity; - } - - private EntitiesBlock* findBlockWithFreeSpace(EntityInfo* info) - { - EntitiesBlock* previous_block; - EntitiesBlock* block = info.first_with_free_space; - - while (1) - { - if (block is null) - { - block = cast(EntitiesBlock*) allocator.getBlock(); //AlignedMallocator.instance.alignedAllocate(page_size, page_size); - *block = EntitiesBlock(info); - if (previous_block is null) - { - info.first_block = block; - block.id = 0; - } - else - { - previous_block.next_block = block; - block.prev_block = previous_block; - block.id = cast(ushort)(previous_block.id + 1); - } - info.first_with_free_space = block; - break; // new block certainly has free space - } - // check if there is enought space - /*if (block.dataDelta() + ( - block.entities_count + block.added_count + 1) * info.size > page_size)*/ - if (block.entities_count + block.added_count >= block.type_info.max_entities) - { - previous_block = block; - block = block.next_block; - continue; - } - - info.first_with_free_space = block; - break; // block exists and bounds check passed - } - - return block; - } - - export void removeEntity(EntityID id) - { - entities_to_remove.add(id); - } - - private void __removeEntity(EntityID id) - { - //get entity and block meta data pointers - Entity* entity = id_manager.getEntityPointer(id); - if (entity is null) - return; //return if entity doesn't exist - EntitiesBlock* block = getMetaData(entity); - id_manager.releaseID(id); //release id from manager - - removeEntityNoID(entity, block, true); - } - - private void removeEntityNoID(Entity* entity, EntitiesBlock* block, - bool call_destructors = false) - { - //pos is Entity number in block - void* data_begin = block.dataBegin(); - EntityInfo* info = block.type_info; - - block.entities_count--; - - //set "first_with_free_space" if should it be - if (info.first_with_free_space.id > block.id) - info.first_with_free_space = block; - - static if (EntityID.sizeof == 8) - uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3); - else - uint pos = cast(uint)((cast(void*) entity - data_begin) / EntityID.sizeof()); - - if (call_destructors) - { - //void* data = data_begin + pos * info.size; - foreach (comp; info.components) - { - if (components[comp].destroy_callback) - { - //components[comp].destroy_callback(data + info.deltas[comp]); - components[comp].destroy_callback(cast( - void*) block + info.deltas[comp] + pos * components[comp].size); - } - } - } - - - if (block.entities_count == 0) - { - if (info.first_block is block) - { - info.first_block = block.next_block; - } - if (info.first_with_free_space is block) - { - info.first_with_free_space = block.next_block; //info.first_block; - } - if (block.prev_block) - { - block.prev_block.next_block = block.next_block; - } - if (block.next_block) - { - block.next_block.prev_block = block.prev_block; - } - allocator.freeBlock(block); - return; - } - - if (pos == block.entities_count) - return; - - foreach (comp; info.components) - { - void* ptr = cast(void*) block + info.deltas[comp]; - uint size = components[comp].size; - memcpy(ptr + pos * size, ptr + block.entities_count * size, size); - } - - entity.id = *cast(EntityID*)(data_begin + block.entities_count * EntityID.sizeof); - - //update pointer for moved entity ID - //entity = cast(Entity*) dst; - entity.updateID(); - } - - /************************************************************************************************************************ - *functions return MetaData of page. - * - *params: - *pointer = pointer to any data of entity (i.e. component data pointer) - */ - export EntitiesBlock* getMetaData(void* pointer) - { - return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(page_size - 1))); - } - - private void changeEntites() - { - uint index = 0; - uint len = cast(uint) change_entities_list.length; - while (index < len) - { - if (!change_entities_list[index++]) - { - EntityID id = *cast(EntityID*)&change_entities_list[index]; - index += EntityID.sizeof; - uint num = *cast(uint*)&change_entities_list[index]; - index += uint.sizeof; - ushort[] ids = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - ids[0 .. $] = (cast(ushort*)&change_entities_list[index])[0 .. num]; - index += ushort.sizeof * num; - __removeComponents(id, ids); - } - else - { - EntityID id = *cast(EntityID*)&change_entities_list[index]; - index += EntityID.sizeof; - uint num = *cast(uint*)&change_entities_list[index]; - index += uint.sizeof; - ushort[] ids = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - ids[0 .. $] = (cast(ushort*)&change_entities_list[index])[0 .. num]; - index += ushort.sizeof * num; - void*[] pointers = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; - foreach (i; 0 .. num) - { - pointers[i] = &change_entities_list[index]; - index += components[ids[i]].size; - } - __addComponents(id, ids, pointers); - } - } - change_entities_list.clear(); - } - - private void updateBlocks() - { - foreach (block; blocks_to_update) - { - block.entities_count += block.added_count; - block.added_count = 0; - } - blocks_to_update.clear(); - } - - private void removeEntities() - { - foreach (id; entities_to_remove) - { - __removeEntity(id); - } - entities_to_remove.clear(); - } - - export void begin() - { - updateBlocks(); - removeEntities(); - changeEntites(); - foreach (ref system; instance.systems) - { - if (system.m_begin) - system.m_begin(system.m_system_pointer); - } - } - - export void end() - { - foreach (ref system; instance.systems) - { - if (system.m_end) - system.m_end(system.m_system_pointer); - } - updateBlocks(); - removeEntities(); - changeEntites(); - - //clearEvents(); - } - - struct ComponentInfo - { - ushort size; - ushort alignment; - ubyte[] init_data; - void function(void* pointer) destroy_callback; - } - - struct EventInfo - { - ushort size; - ushort alignment; - void function(void* pointer) destroy_callback; - } - - /************************************************************************************************************************ - *Entity type info. - */ - struct EntityInfo - { - ///entity components - ushort[] components; - - ///deltas in memory for components in EntitiesBlock - ushort[] deltas; - ///deltas in memory for components in EntityTemplate - ushort[] tmpl_deltas; - - ///alignment of whole entity - ushort alignment; //unused in linear-layout - ///size of entity (with alignment respect) - ushort size; - ///max number of entities in block - ushort max_entities; - - ///pointer to first block/page - EntitiesBlock* first_block; - ///a hint for allocations - EntitiesBlock* first_with_free_space; // a hint for allocations, should have empty space in it but doesn't have to - ///array of CallData. Contain data for System calls. - Vector!(CallData) callers; - } - - /************************************************************************************************************************ - *Meta data of every block of entities (contained at the begining of block). - */ - struct EntitiesBlock - { - ///return distance (in bytes) from begin of block to data - uint dataDelta() - { - ushort dif = EntitiesBlock.sizeof; - alignNum(dif, type_info.alignment); - return dif; - } - - ///return pointer to first element in block - export void* dataBegin() - { - ushort dif = EntitiesBlock.sizeof; - return cast(void*)&this + dif; - } - - ///pointer to Entity type info - EntityInfo* type_info = null; - ///number of entities in block - ushort entities_count = 0; - ///number of new entities in block - ushort added_count = 0; - ///block id - ushort id = 0; - ///maximum number of entities in block - //ushort max_entities = 0; - ///pointer to next block/page - EntitiesBlock* next_block = null; - ///pointer to next block/page - EntitiesBlock* prev_block = null; - //there is a loooot of data (some kB of memory, pure magic) - } - - /************************************************************************************************************************ - *Structure with data used to calling System calls. - */ - struct CallData - { - ///system ID. Used to update system pointer after system reload. - uint system_id; - ///pointer to used system - System* system; - ///poiner to Entity type info - EntityManager.EntityInfo* info; - ///deltas for components - ushort[] deltas; //unused in linear-layout - } - - alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity); - - //alias sendSelfEvent = instance.event_manager.sendSelfEvent; - - //alias event_manager this; - - ///Single page size. Must be power of two. - enum page_size = 32768; //4096; - ///Number of pages in block. - enum pages_in_block = 128; - - IDManager id_manager; - BlockAllocator!(page_size, pages_in_block) allocator; - - //EventManager event_manager; - mixin EventManagerCode; - - Vector!EntityID entities_to_remove; - Vector!(EntitiesBlock*) blocks_to_update; - Vector!ubyte change_entities_list; - - HashMap!(ushort[], EntityInfo*) entities_infos; - HashMap!(string, ushort) systems_map; - HashMap!(string, ushort) components_map; - HashMap!(string, ushort) events_map; - Vector!System systems; - Vector!ComponentInfo components; - Vector!EventInfo events; - __gshared EntityManager instance = null; -} - -/* -static ulong defaultHashFunc(T)(auto ref T t) -{ - ulong ret = 0; - foreach(id;t) - { - ret = ret - } -}*/ diff --git a/source/ecs/package.d b/source/ecs/package.d deleted file mode 100644 index e043ec9..0000000 --- a/source/ecs/package.d +++ /dev/null @@ -1,7 +0,0 @@ -module ecs; - -public import ecs.manager; -public import ecs.entity; -public import ecs.system; -import ecs.id_manager; -import ecs.events; \ No newline at end of file diff --git a/source/ecs/string_intern.d b/source/ecs/string_intern.d deleted file mode 100644 index 49dc21b..0000000 --- a/source/ecs/string_intern.d +++ /dev/null @@ -1,137 +0,0 @@ -module ecs.string_intern; - -import ecs.hash_map; -import ecs.traits : isForeachDelegateWithI; -import std.experimental.allocator; -import std.experimental.allocator.mallocator; -import std.traits : Parameters; - -private __gshared static HashMap!(const(char)[], StringIntern) gStringInterns; - -struct StringIntern { - private const(char)* strPtr; - - this(const(char)[] fromStr) { - opAssign(fromStr); - } - - void reset() { - strPtr=null; - } - - size_t length() { - if (strPtr is null) { - return 0; - } - return *cast(size_t*)(strPtr - 8); - } - - const(char)[] str() { - if (strPtr is null) { - return null; - } - return strPtr[0 .. length]; - } - - const(char)[] cstr() { - if (strPtr is null) { - return "\0"; - } - return strPtr[0 .. length + 1]; - } - - bool opEquals()(auto ref const StringIntern s) { - return strPtr == s.strPtr; - } - - bool opEquals()(auto ref const(char[]) s) { - return str() == s; - } - - void opAssign(const(char)[] fromStr) { - if (fromStr.length == 0) { - return; - } - StringIntern defaultValue; - StringIntern internedStr = gStringInterns.get(fromStr, defaultValue); - - if (internedStr.length == 0) { - internedStr.strPtr = allocStr(fromStr).ptr; - gStringInterns.add(internedStr.str, internedStr); - } - - strPtr = internedStr.strPtr; - } - - const(char)[] opSlice() { - if (strPtr is null) { - return null; - } - return strPtr[0 .. length]; - } - - private const(char)[] allocStr(const(char)[] fromStr) { - char[] data = Mallocator.instance.makeArray!(char)(fromStr.length + size_t.sizeof + 1); - size_t* len = cast(size_t*) data.ptr; - *len = fromStr.length; - data[size_t.sizeof .. $ - 1] = fromStr; - data[$ - 1] = '\0'; - return data[size_t.sizeof .. $ - 1]; - } -} - -unittest { - static assert(StringIntern.sizeof == size_t.sizeof); - const(char)[] chA = ['a', 'a']; - char[] chB = ['o', 't', 'h', 'e', 'r']; - const(char)[] chC = ['o', 't', 'h', 'e', 'r']; - string chD = "other"; - - StringIntern strA; - StringIntern strB = StringIntern(""); - StringIntern strC = StringIntern("a"); - StringIntern strD = "a"; - StringIntern strE = "aa"; - StringIntern strF = chA; - StringIntern strG = chB; - - assert(strA == strB); - assert(strA != strC); - assert(strC == strD); - assert(strD != strE); - assert(strE == strF); - - assert(strD.length == 1); - assert(strE.length == 2); - assert(strG.length == 5); - - strA = "other"; - assert(strA == "other"); - assert(strA == chB); - assert(strA == chC); - assert(strA == chD); - assert(strA.str.ptr[strA.str.length] == '\0'); - assert(strA.cstr[$ - 1] == '\0'); - - foreach (char c; strA) { - } - foreach (int i, char c; strA) { - } - foreach (ubyte i, char c; strA) { - } - foreach (c; strA) { - } -} - -unittest { - import ecs.hash_map : HashMap; - - HashMap!(StringIntern, StringIntern) map; - - map.add(StringIntern("aaa"), StringIntern("bbb")); - map.add(StringIntern("aaa"), StringIntern("bbb")); - - assert(map.length == 1); - assert(map.get(StringIntern("aaa")) == StringIntern("bbb")); - -} diff --git a/source/ecs/system.d b/source/ecs/system.d deleted file mode 100644 index 83bcd7d..0000000 --- a/source/ecs/system.d +++ /dev/null @@ -1,55 +0,0 @@ -module ecs.system; - -import ecs.entity; -import ecs.manager; - -struct System -{ - export bool enabled() - { - return m_enabled; - } - - export void enable() - { - if (!m_enabled && m_enable) - m_enable(m_system_pointer); - m_enabled = true; - } - - export void disable() - { - if (m_enabled && m_disable) - m_disable(m_system_pointer); - m_enabled = false; - } - - export int priority() - { - return m_priority; - } - -package: - - ///should system update and catch events? - bool m_enabled = false; - ///system priority - int m_priority; - ///pointer to system implementation - void* m_system_pointer; - - ushort[] m_components; - ushort[] m_optional_components; - - //void function(ref EntityManager.CallData data, void* entity) update; - void* m_update; ///workaroud for DMD bug with upper line - - void function(void* system_pointer) m_enable; - void function(void* system_pointer) m_disable; - - void function(void* system_pointer) m_create; - void function(void* system_pointer) m_destroy; - - void function(void* system_pointer) m_begin; - void function(void* system_pointer) m_end; -} diff --git a/source/ecs/traits.d b/source/ecs/traits.d deleted file mode 100644 index cb5da91..0000000 --- a/source/ecs/traits.d +++ /dev/null @@ -1,39 +0,0 @@ -module ecs.traits; - -import std.traits; - -bool isForeachDelegateWithI(DG)() { - return is(DG == delegate) && is(ReturnType!DG == int) - && Parameters!DG.length == 2 && isIntegral!(Parameters!(DG)[0]); -} - -unittest { - assert(isForeachDelegateWithI!(int delegate(int, double))); - assert(isForeachDelegateWithI!(int delegate(int, double) @nogc nothrow)); - assert(!isForeachDelegateWithI!(int delegate(double, double))); -} - -bool isForeachDelegateWithoutI(DG)() { - return is(DG == delegate) && is(ReturnType!DG == int) && Parameters!DG.length == 1; -} - -unittest { - assert(isForeachDelegateWithoutI!(int delegate(int))); - assert(isForeachDelegateWithoutI!(int delegate(size_t) @nogc nothrow)); - assert(!isForeachDelegateWithoutI!(void delegate(int))); -} - -bool isForeachDelegateWithTypes(DG, Types...)() { - return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types); -} - -unittest { - assert(isForeachDelegateWithTypes!(int delegate(int, int), int, int)); - assert(isForeachDelegateWithTypes!(int delegate(ref int, ref int), int, int)); - assert(!isForeachDelegateWithTypes!(int delegate(double), int, int)); -} - -auto assumeNoGC(T)(T t) if (isFunctionPointer!T || isDelegate!T) { - enum attrs = functionAttributes!T | FunctionAttribute.nogc; - return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; -} diff --git a/source/ecs/vector.d b/source/ecs/vector.d deleted file mode 100644 index ef6a238..0000000 --- a/source/ecs/vector.d +++ /dev/null @@ -1,400 +0,0 @@ -module ecs.vector; - -import core.bitop; -import core.stdc.stdlib : free, malloc; -import core.stdc.string : memcpy, memset; -import std.algorithm : swap; -import std.conv : emplace; -import std.traits : hasMember, isCopyable, TemplateOf, Unqual; - -export @nogc @safe nothrow pure size_t nextPow2(size_t num) { - return 1 << bsr(num) + 1; -} - -__gshared size_t gVectorsCreated = 0; -__gshared size_t gVectorsDestroyed = 0; - -struct Vector(T) { - T[] array; - size_t used; -public: - - export this()(T t) { - add(t); - } - - export this(X)(X[] t) if (is(Unqual!X == Unqual!T)) { - add(t); - - } - - static if (isCopyable!T) { - export this(this) { - T[] tmp = array[0 .. used]; - array = null; - used = 0; - add(tmp); - } - } else { - @disable this(this); - } - - export ~this() { - clear(); - } - - export void clear() { - removeAll(); - } - - export void removeAll() { - if (array !is null) { - foreach (ref el; array[0 .. used]) { - destroy(el); - } - freeData(cast(void[]) array); - gVectorsDestroyed++; - } - array = null; - used = 0; - } - - export bool empty() { - return (used == 0); - } - - export size_t length() { - return used; - } - - export void length(size_t newLength) { - if (newLength > used) { - reserve(newLength); - foreach (ref el; array[used .. newLength]) { - emplace(&el); - } - } else { - foreach (ref el; array[newLength .. used]) { - destroy(el); - } - } - used = newLength; - } - - export void reset() { - used = 0; - } - - export void reserve(size_t numElements) { - if (numElements > array.length) { - extend(numElements); - } - } - - export size_t capacity() { - return array.length - used; - } - - export void extend(size_t newNumOfElements) { - auto oldArray = manualExtend(array, newNumOfElements); - if (oldArray !is null) { - freeData(oldArray); - } - } - - export @nogc void freeData(void[] data) { - // 0x0F probably invalid value for pointers and other types - memset(data.ptr, 0x0F, data.length); // Makes bugs show up xD - free(data.ptr); - } - - export static void[] manualExtend(ref T[] array, size_t newNumOfElements = 0) { - if (newNumOfElements == 0) - newNumOfElements = 2; - if (array.length == 0) - gVectorsCreated++; - T[] oldArray = array; - size_t oldSize = oldArray.length * T.sizeof; - size_t newSize = newNumOfElements * T.sizeof; - T* memory = cast(T*) malloc(newSize); - memcpy(cast(void*) memory, cast(void*) oldArray.ptr, oldSize); - array = memory[0 .. newNumOfElements]; - return cast(void[]) oldArray; - } - - export Vector!T copy()() { - Vector!T duplicate; - duplicate.reserve(used); - duplicate ~= array[0 .. used]; - return duplicate; - } - - export bool canAddWithoutRealloc(uint elemNum = 1) { - return used + elemNum <= array.length; - } - - export void add()(T t) { - if (used >= array.length) { - extend(nextPow2(used + 1)); - } - emplace(&array[used], t); - used++; - } - - /// Add element at given position moving others - export void add()(T t, size_t pos) { - assert(pos <= used); - if (used >= array.length) { - extend(array.length * 2); - } - foreach_reverse (size_t i; pos .. used) { - //swap(array[i + 1], array[i]); - array[i+1] = array[i]; - } - emplace(&array[pos], t); - used++; - } - - export void add(X)(X[] t) if (is(Unqual!X == Unqual!T)) { - if (used + t.length > array.length) { - extend(nextPow2(used + t.length)); - } - foreach (i; 0 .. t.length) { - emplace(&array[used + i], t[i]); - } - used += t.length; - } - - export void remove(size_t elemNum) { - destroy(array[elemNum]); - swap(array[elemNum], array[used - 1]); - used--; - } - - export void removeStable()(size_t elemNum) { - used--; - foreach (i; 0 .. used) { - array[i] = array[i + 1]; - } - } - - export bool tryRemoveElement()(T elem) { - foreach (i, ref el; array[0 .. used]) { - if (el == elem) { - remove(i); - return true; - } - } - return false; - } - - export void removeElement()(T elem) { - bool ok = tryRemoveElement(elem); - assert(ok, "There is no such an element in vector"); - } - - export ref T opIndex(size_t elemNum) { - debug assert(elemNum < used, "Range violation [index]"); - return array.ptr[elemNum]; - } - - export auto opSlice() { - return array.ptr[0 .. used]; - } - - export T[] opSlice(size_t x, size_t y) { - assert(y <= used); - return array.ptr[x .. y]; - } - - export size_t opDollar() { - return used; - } - - export void opAssign(X)(X[] slice) { - reset(); - this ~= slice; - } - - export void opOpAssign(string op)(T obj) { - static assert(op == "~"); - add(obj); - } - - export void opOpAssign(string op, X)(X[] obj) { - static assert(op == "~"); - add(obj); - } - - export void opIndexAssign()(T obj, size_t elemNum) { - assert(elemNum < used, "Range viloation"); - array[elemNum] = obj; - } - - export void opSliceAssign()(T[] obj, size_t a, size_t b) { - assert(b <= used && a <= b, "Range viloation"); - array.ptr[a .. b] = obj; - } - - export bool opEquals()(auto ref const Vector!(T) r) const { - return used == r.used && array.ptr[0 .. used] == r.array.ptr[0 .. r.used]; - } - - export size_t toHash() const nothrow @trusted { - return hashOf(cast(Unqual!(T)[]) array.ptr[0 .. used]); - } - - import std.format : FormatSpec, formatValue; - - /** - * Preety print - */ - export void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) { - static if (__traits(compiles, formatValue(sink, array[0 .. used], fmt))) { - formatValue(sink, array[0 .. used], fmt); - } - } - -} - -// Helper to avoid GC -private T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow @nogc @safe { - return array; -} - -@nogc nothrow unittest { - Vector!int vec; - assert(vec.empty); - vec.add(0); - vec.add(1); - vec.add(2); - vec.add(3); - vec.add(4); - vec.add(5); - assert(vec.length == 6); - assert(vec[3] == 3); - assert(vec[5] == 5); - assert(vec[] == [0, 1, 2, 3, 4, 5].s); - assert(!vec.empty); - vec.remove(3); - assert(vec.length == 5); - assert(vec[] == [0, 1, 2, 5, 4].s); //unstable remove -} - -@nogc nothrow unittest { - Vector!int vec; - assert(vec.empty); - vec ~= [0, 1, 2, 3, 4, 5].s; - assert(vec[] == [0, 1, 2, 3, 4, 5].s); - assert(vec.length == 6); - vec ~= 6; - assert(vec[] == [0, 1, 2, 3, 4, 5, 6].s); - -} - -@nogc nothrow unittest { - Vector!int vec; - vec ~= [0, 1, 2, 3, 4, 5].s; - vec[3] = 33; - assert(vec[3] == 33); -} - -@nogc nothrow unittest { - Vector!char vec; - vec ~= "abcd"; - assert(vec[] == cast(char[]) "abcd"); -} - -@nogc nothrow unittest { - Vector!int vec; - vec ~= [0, 1, 2, 3, 4, 5].s; - vec.length = 2; - assert(vec[] == [0, 1].s); -} -/////////////////////////////////////////// - -enum string checkVectorAllocations = ` -//assert(gVectorsCreated==gVectorsDestroyed); -gVectorsCreated=gVectorsDestroyed=0; -scope(exit){if(gVectorsCreated!=gVectorsDestroyed){ - import std.stdio : writefln; - writefln("created==destroyed %s==%s", gVectorsCreated, gVectorsDestroyed); - assert(gVectorsCreated==gVectorsDestroyed, "Vector memory leak"); -}} -`; - -unittest { - mixin(checkVectorAllocations); - Vector!int vecA = Vector!int([0, 1, 2, 3, 4, 5].s); - assert(vecA[] == [0, 1, 2, 3, 4, 5].s); - Vector!int vecB; - vecB = vecA; - assert(vecB[] == [0, 1, 2, 3, 4, 5].s); - assert(vecB.array.ptr != vecA.array.ptr); - assert(vecB.used == vecA.used); - Vector!int vecC = vecA; - assert(vecC[] == [0, 1, 2, 3, 4, 5].s); - assert(vecC.array.ptr != vecA.array.ptr); - assert(vecC.used == vecA.used); - Vector!int vecD = vecA.init; -} - -unittest { - static int numInit = 0; - static int numDestroy = 0; - scope (exit) { - assert(numInit == numDestroy); - } - static struct CheckDestructor { - int num = 1; - - this(this) { - numInit++; - } - - this(int n) { - num = n; - numInit++; - - } - - ~this() { - numDestroy++; - } - } - - CheckDestructor[2] arr = [CheckDestructor(1), CheckDestructor(1)]; - Vector!CheckDestructor vec; - vec ~= CheckDestructor(1); - vec ~= arr; - vec.remove(1); -} - -unittest { - assert(gVectorsCreated == gVectorsDestroyed); - gVectorsCreated = 0; - gVectorsDestroyed = 0; - scope (exit) { - assert(gVectorsCreated == gVectorsDestroyed); - } - string strA = "aaa bbb"; - string strB = "ccc"; - Vector!(Vector!char) vecA = Vector!(Vector!char)(Vector!char(cast(char[]) strA)); - assert(vecA[0] == Vector!char(cast(char[]) strA)); - Vector!(Vector!char) vecB; - vecB = vecA; - assert(vecB[0] == Vector!char(cast(char[]) strA)); - assert(vecA.array.ptr != vecB.array.ptr); - assert(vecB.used == vecA.used); - assert(vecB[0].array.ptr != vecA[0].array.ptr); - assert(vecB[0].used == vecA[0].used); -} - -unittest { - static struct Test { - int num; - @disable this(this); - } - - Vector!Test test; -} diff --git a/source/meson.build b/source/meson.build new file mode 100644 index 0000000..de5da33 --- /dev/null +++ b/source/meson.build @@ -0,0 +1,17 @@ +src += files( + 'bubel/ecs/atomic.d', + 'bubel/ecs/attributes.d', + 'bubel/ecs/block_allocator.d', + 'bubel/ecs/core.d', + 'bubel/ecs/entity.d', + 'bubel/ecs/events.d', + 'bubel/ecs/hash_map.d', + 'bubel/ecs/id_manager.d', + 'bubel/ecs/manager.d', + 'bubel/ecs/package.d', + 'bubel/ecs/simple_vector.d', + 'bubel/ecs/std.d', + 'bubel/ecs/system.d', + 'bubel/ecs/traits.d', + 'bubel/ecs/vector.d', +) \ No newline at end of file diff --git a/source/win_dll.d b/source/win_dll.d index c417b45..1ff8ce4 100644 --- a/source/win_dll.d +++ b/source/win_dll.d @@ -7,7 +7,7 @@ import core.sys.windows.windows; extern(Windows) bool DllMain(void* hInstance, uint ulReason, void*) { - switch (ulReason) + /*switch (ulReason) { default: assert(0); case DLL_PROCESS_ATTACH: @@ -26,5 +26,6 @@ extern(Windows) bool DllMain(void* hInstance, uint ulReason, void*) dll_thread_detach( true, true ); break; } - return true; + return true;*/ + return 0; } \ No newline at end of file diff --git a/subprojects/bindbc-loader.wrap b/subprojects/bindbc-loader.wrap new file mode 100644 index 0000000..b99f744 --- /dev/null +++ b/subprojects/bindbc-loader.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://github.com/BindBC/bindbc-loader.git +revision = 9a51af991acce3c67e51695c07bf3fa6419ef938 +patch_directory = bindbc-loader + +[provide] +dependency_names = bindbc-loader diff --git a/subprojects/bindbc-sdl.wrap b/subprojects/bindbc-sdl.wrap new file mode 100644 index 0000000..3b159a0 --- /dev/null +++ b/subprojects/bindbc-sdl.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://github.com/BindBC/bindbc-sdl.git +revision = 5c936064b7226630f5080f4b12b77ee39c8ac64b +patch_directory = bindbc-sdl + +[provide] +dependency_names = bindbc-sdl diff --git a/subprojects/cimgui.wrap b/subprojects/cimgui.wrap new file mode 100644 index 0000000..67d2107 --- /dev/null +++ b/subprojects/cimgui.wrap @@ -0,0 +1,8 @@ +[wrap-git] +url = https://github.com/cimgui/cimgui.git +revision = 1c65ee2bdc719fb3ef62b4615d66fe8effa21148 +clone-recursive = true +patch_directory = cimgui + +[provide] +dependency_names = cimgui diff --git a/subprojects/packagefiles/bindbc-loader/meson.build b/subprojects/packagefiles/bindbc-loader/meson.build new file mode 100644 index 0000000..ce3bdf0 --- /dev/null +++ b/subprojects/packagefiles/bindbc-loader/meson.build @@ -0,0 +1,24 @@ +project('bindbc-loader', 'd', version : '0.3.2', default_options: ['default_library=static']) + +# Files +src = files( + 'source/bindbc/loader/package.d', + 'source/bindbc/loader/sharedlib.d', + 'source/bindbc/loader/system.d', +) + +inc = include_directories('source') + +# Dependencies +lib = library('bindbc-loader', src, + include_directories : [inc], + pic : true, + d_module_versions: ['BindBC_Static'], +) + +bindbc_loader_dep = declare_dependency( + include_directories : [inc], + link_with : lib, +) + +meson.override_dependency('bindbc-loader', bindbc_loader_dep) \ No newline at end of file diff --git a/subprojects/packagefiles/bindbc-sdl/meson.build b/subprojects/packagefiles/bindbc-sdl/meson.build new file mode 100644 index 0000000..0c95cc5 --- /dev/null +++ b/subprojects/packagefiles/bindbc-sdl/meson.build @@ -0,0 +1,72 @@ +project('bindbc-sdl', 'd', version : '0.19.2', default_options: ['default_library=static']) + +# Files +src = files( + 'source/bindbc/sdl/bind/package.d', + 'source/bindbc/sdl/bind/sdl.d', + 'source/bindbc/sdl/bind/sdlassert.d', + 'source/bindbc/sdl/bind/sdlatomic.d', + 'source/bindbc/sdl/bind/sdlaudio.d', + 'source/bindbc/sdl/bind/sdlblendmode.d', + 'source/bindbc/sdl/bind/sdlclipboard.d', + 'source/bindbc/sdl/bind/sdlcpuinfo.d', + 'source/bindbc/sdl/bind/sdlerror.d', + 'source/bindbc/sdl/bind/sdlevents.d', + 'source/bindbc/sdl/bind/sdlfilesystem.d', + 'source/bindbc/sdl/bind/sdlgamecontroller.d', + 'source/bindbc/sdl/bind/sdlgesture.d', + 'source/bindbc/sdl/bind/sdlhaptic.d', + 'source/bindbc/sdl/bind/sdlhints.d', + 'source/bindbc/sdl/bind/sdljoystick.d', + 'source/bindbc/sdl/bind/sdlkeyboard.d', + 'source/bindbc/sdl/bind/sdlkeycode.d', + 'source/bindbc/sdl/bind/sdlloadso.d', + 'source/bindbc/sdl/bind/sdllog.d', + 'source/bindbc/sdl/bind/sdlmessagebox.d', + 'source/bindbc/sdl/bind/sdlmouse.d', + 'source/bindbc/sdl/bind/sdlmutex.d', + 'source/bindbc/sdl/bind/sdlpixels.d', + 'source/bindbc/sdl/bind/sdlplatform.d', + 'source/bindbc/sdl/bind/sdlpower.d', + 'source/bindbc/sdl/bind/sdlrect.d', + 'source/bindbc/sdl/bind/sdlrender.d', + 'source/bindbc/sdl/bind/sdlrwops.d', + 'source/bindbc/sdl/bind/sdlscancode.d', + 'source/bindbc/sdl/bind/sdlshape.d', + 'source/bindbc/sdl/bind/sdlstdinc.d', + 'source/bindbc/sdl/bind/sdlsurface.d', + 'source/bindbc/sdl/bind/sdlsystem.d', + 'source/bindbc/sdl/bind/sdlsyswm.d', + 'source/bindbc/sdl/bind/sdlthread.d', + 'source/bindbc/sdl/bind/sdltimer.d', + 'source/bindbc/sdl/bind/sdltouch.d', + 'source/bindbc/sdl/bind/sdlversion.d', + 'source/bindbc/sdl/bind/sdlvideo.d', + 'source/bindbc/sdl/bind/sdlvulkan.d', + 'source/bindbc/sdl/config.d', + 'source/bindbc/sdl/dynload.d', + 'source/bindbc/sdl/image.d', + 'source/bindbc/sdl/mixer.d', + 'source/bindbc/sdl/net.d', + 'source/bindbc/sdl/package.d', + 'source/bindbc/sdl/ttf.d', +) + +inc = include_directories('source') + +# Dependencies +bindbc_loader_dep = dependency('bindbc-loader') + +lib = library('bindbc-sdl', src, + dependencies : bindbc_loader_dep, + include_directories : [inc], + d_module_versions: ['BindBC_Static'], + pic : true, +) + +bindbc_sdl_dep = declare_dependency( + include_directories : [inc], + link_with : lib, +) + +meson.override_dependency('bindbc-sdl', bindbc_sdl_dep) \ No newline at end of file diff --git a/subprojects/packagefiles/cimgui/meson.build b/subprojects/packagefiles/cimgui/meson.build new file mode 100644 index 0000000..e4c1a41 --- /dev/null +++ b/subprojects/packagefiles/cimgui/meson.build @@ -0,0 +1,29 @@ +project('cimgui', 'cpp', version : '1.73.0', default_options: ['default_library=shared', 'warning_level=1']) + +# Files +src = [ + 'cimgui.cpp', + 'imgui/imgui.cpp', + 'imgui/imgui_draw.cpp', + 'imgui/imgui_demo.cpp', + 'imgui/imgui_widgets.cpp', +] + +inc = [ '.' ] +pub_inc = [ 'imgui' ] + +# Dependencies +# bindbc_loader_dep = dependency('bindbc-loader') + +lib = shared_library('cimgui', src, + # dependencies : bindbc_loader_dep, + include_directories : [inc, pub_inc], + # pic : true, +) + +cimgui_dep = declare_dependency( + include_directories : [pub_inc], + link_with : lib, +) + +meson.override_dependency('cimgui', cimgui_dep) \ No newline at end of file diff --git a/tests/access_perf.d b/tests/access_perf.d new file mode 100644 index 0000000..87a0a75 --- /dev/null +++ b/tests/access_perf.d @@ -0,0 +1,135 @@ +module tests.access_perf; + +import tests.runner; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.entity; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +import core.stdc.stdio; + +struct CLong +{ + mixin ECS.Component; + + alias value this; + + long value = 10; +} + +struct CInt +{ + mixin ECS.Component; + + alias value this; + + int value = 10; +} + +struct CUInt +{ + mixin ECS.Component; + + alias value this; + + uint value = 12; +} + +struct CBig +{ + mixin ECS.Component; + uint[32] data; +} + +EntityTemplate* tmpl; + +void beforeEveryTest() +{ + gEntityManager.initialize(0); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CLong; + gEntityManager.registerComponent!CInt; + gEntityManager.registerComponent!CUInt; + gEntityManager.registerComponent!CBig; + + gEntityManager.endRegister(); + + tmpl = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray); + foreach(i; 0 .. 100_000)gEntityManager.addEntity(tmpl); +} + +void afterEveryTest() +{ + if(tmpl)gEntityManager.freeTemplate(tmpl); + tmpl = null; + gEntityManager.destroy(); +} + +@("DirectAccess100k1comp") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0)); + CUInt* comp1 = entity.getComponent!CUInt; + comp1.value = 4; + } +} + +@("DirectAccess100k4comp") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0)); + CUInt* comp1 = entity.getComponent!CUInt; + comp1.value = 4; + CInt* comp2 = entity.getComponent!CInt; + comp2.value = 3; + CLong* comp3 = entity.getComponent!CLong; + comp3.value = 1; + CBig* comp4 = entity.getComponent!CBig; + comp4.data[0] = 2; + } +} + +@("DirectAccess100k1compWithMeta") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0)); + EntityMeta meta = entity.getMeta(); + CUInt* comp1 = meta.getComponent!CUInt; + comp1.value = 4; + } +} + +@("DirectAccess100k4compWithMeta") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0)); + EntityMeta meta = entity.getMeta(); + CUInt* comp1 = meta.getComponent!CUInt; + comp1.value = 4; + CInt* comp2 = meta.getComponent!CInt; + comp2.value = 3; + CLong* comp3 = meta.getComponent!CLong; + comp3.value = 1; + CBig* comp4 = meta.getComponent!CBig; + comp4.data[0] = 2; + } +} \ No newline at end of file diff --git a/tests/basic.d b/tests/basic.d new file mode 100644 index 0000000..ea54382 --- /dev/null +++ b/tests/basic.d @@ -0,0 +1,1828 @@ +module tests.basic; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.system; +import bubel.ecs.attributes; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +struct CInt +{ + // mixin ECS.Component; + + alias value this; + + int value = 1; +} + +struct CFloat +{ + // mixin ECS.Component; + + alias value this; + + float value = 2.0; +} + +struct CDouble +{ + // mixin ECS.Component; + + alias value this; + + double value = 3.0; +} + +struct CLong +{ + // mixin ECS.Component; + + alias value this; + + long value = 10; +} + +struct CShort +{ + // mixin ECS.Component; + + alias value this; + + short value = 12; +} + +struct CUnregistered +{ + // mixin ECS.Component; + + alias value this; + + short value = 12; +} + +struct CFlag +{ + // mixin ECS.Component; +} + +struct LongAddSystem +{ + mixin ECS.System; + + struct EntitiesData + { + int length; + + CLong[] long_; + } + + void onUpdate(EntitiesData data) + { + updates_count++; + foreach(i;0..data.length) + { + data.long_[i] += 1; + } + } + + int updates_count = 0; +} + +struct EmptySystem +{ + mixin ECS.System!16; + + struct EntitiesData + { + int thread_id; + } + + void onUpdate(EntitiesData data) + { + count++; + } + + int count = 0; +} + +struct EntityCounterSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + int thread_id; + uint length; + Entity[] entity; + } + + bool onBegin() + { + count = 0; + return true; + } + + void onUpdate(EntitiesData data) + { + count += data.length; + } + + int count = 0; +} + +void beforeEveryTest() +{ + becsID!CUnregistered = ushort.max; + gEntityManager.initialize(0); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CInt; + gEntityManager.registerComponent!CFloat; + gEntityManager.registerComponent!CDouble; + gEntityManager.registerComponent!CLong; + gEntityManager.registerComponent!CShort; + gEntityManager.registerComponent!CFlag; + + gEntityManager.endRegister(); +} + +void afterEveryTest() +{ + gEntityManager.destroy(); +} + +@("EntityMeta") +unittest +{ + EntityTemplate* tmpl_ = gEntityManager.allocateTemplate([becsID!CInt, becsID!CFloat, becsID!CFlag].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_); + Entity* entity = gEntityManager.addEntity(tmpl_); + EntityMeta meta = entity.getMeta(); + assert(meta.hasComponent(becsID!CInt)); + assert(meta.getComponent!CInt); + assert(meta.hasComponent(becsID!CFloat)); + assert(meta.getComponent!CFloat); + assert(!meta.getComponent!CLong); + assert(!meta.hasComponent(becsID!CLong)); + assert(!meta.getComponent!CUnregistered); + assert(!meta.hasComponent(becsID!CUnregistered)); + assert(*meta.getComponent!CInt == 1); + assert(*meta.getComponent!CFloat == 2.0); +} + +@("AddEntity") +unittest +{ + EntityTemplate* tmpl_ = gEntityManager.allocateTemplate([becsID!CInt, becsID!CFloat, becsID!CFlag].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_); + assert(tmpl_.info.components.length == 3); + assert(tmpl_.info.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof)); + assert(tmpl_.getComponent!CInt); + assert(tmpl_.getComponent!CFloat); + assert(tmpl_.getComponent!CFlag); + assert(!tmpl_.getComponent!CLong); + assert(!tmpl_.getComponent!CUnregistered); + assert(*tmpl_.getComponent!CInt == 1); + assert(*tmpl_.getComponent!CFloat == 2.0); + + Entity* entity = gEntityManager.addEntity(tmpl_); + assert(entity.getComponent!CInt); + assert(entity.getComponent!CFloat); + assert(*entity.getComponent!CInt == 1); + assert(*entity.getComponent!CFloat == 2.0); + *entity.getComponent!CInt = 2; + + Entity* entity2 = gEntityManager.addEntityCopy(entity.id); + assert(entity2.getComponent!CInt); + assert(entity2.getComponent!CFloat); + assert(*entity2.getComponent!CInt == 2); + assert(*entity2.getComponent!CFloat == 2.0); + + CInt int1 = CInt(10); + CLong long1 = CLong(); + CFlag flag1 = CFlag(); + Entity* entity3 = gEntityManager.addEntity(tmpl_, [ComponentRef(&int1, becsID(int1)), ComponentRef(&long1, becsID(long1)), ComponentRef(&flag1, becsID(flag1))].staticArray); + EntityID id = entity3.id; + assert(entity3.hasComponent(becsID!CInt)); + assert(entity3.hasComponent(becsID!CFloat)); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + + CShort short1 = CShort(2); + gEntityManager.addComponents(entity3.id, [ComponentRef(&flag1, becsID(flag1)),ComponentRef(&short1, becsID(short1))].staticArray); + gEntityManager.commit(); + entity3 = gEntityManager.getEntity(id); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(entity3.getComponent!CFlag); + assert(entity3.getComponent!CShort); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + assert(*entity3.getComponent!CShort == 2); + + gEntityManager.removeComponents(entity3.id, [becsID!CFlag,becsID!CShort].staticArray); + gEntityManager.commit(); + entity3 = gEntityManager.getEntity(id); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(!entity3.getComponent!CFlag); + assert(!entity3.getComponent!CShort); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + + gEntityManager.addComponents(entity3.id, [ComponentRef(&flag1, becsID(flag1)),ComponentRef(&short1, becsID(short1))].staticArray); + gEntityManager.removeComponents(entity3.id, [becsID!CUnregistered].staticArray); + gEntityManager.commit(); + entity3 = gEntityManager.getEntity(id); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(entity3.getComponent!CFlag); + assert(entity3.getComponent!CShort); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + assert(*entity3.getComponent!CShort == 2); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CUnregistered; + + gEntityManager.endRegister(); + + CUnregistered unregistered1 = CUnregistered(4); + gEntityManager.addComponents(entity3.id, [ComponentRef(&unregistered1, becsID(unregistered1))].staticArray); + gEntityManager.commit(); + entity3 = gEntityManager.getEntity(id); + assert(entity3.getComponent!CUnregistered); + assert(*entity3.getComponent!CUnregistered == 4); + + gEntityManager.removeComponents(entity3.id, [becsID!CUnregistered].staticArray); + gEntityManager.commit(); + entity3 = gEntityManager.getEntity(id); + assert(!entity3.getComponent!CUnregistered); +} + +@("AddEmptyEntity") +unittest +{ + struct OnAddRemoveChangeCounter + { + mixin ECS.System!1; + + struct EntitiesData + { + int thread_id; + uint length; + Entity[] entity; + } + + void onAddEntity(EntitiesData data) + { + add += data.length; + } + + void onRemoveEntity(EntitiesData data) + { + assert(0, "It's impossible to remove entity from being updated by system which accept empty entity"); + } + + int add = 0; + } + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!EntityCounterSystem(0); + gEntityManager.registerSystem!OnAddRemoveChangeCounter(1); + + gEntityManager.endRegister(); + + CLong long_component = CLong(3); + + Entity* entity = null; + EntityID entity_id = gEntityManager.addEntity(null).id; + + EntityCounterSystem* system = gEntityManager.getSystem!EntityCounterSystem; + assert(system !is null); + assert(system.count == 0); + + OnAddRemoveChangeCounter* add_remove_change_system = gEntityManager.getSystem!OnAddRemoveChangeCounter; + assert(add_remove_change_system !is null); + assert(add_remove_change_system.add == 0); + + gEntityManager.commit(); + assert(add_remove_change_system.add == 1); + + entity = gEntityManager.getEntity(entity_id); + assert(!entity.hasComponent(becsID!CLong)); + assert(entity.getComponent(becsID!CLong) is null); + + + gEntityManager.begin(); + gEntityManager.update(); + assert(system.count == 1); + gEntityManager.end(); + + gEntityManager.addEntityCopy(entity_id); + gEntityManager.addEntityCopy(entity_id); + gEntityManager.addComponents(entity_id, [ComponentRef(&long_component, becsID(long_component))].staticArray); + gEntityManager.commit(); + assert(add_remove_change_system.add == 3, "onAddEntity missed"); + + entity = gEntityManager.getEntity(entity_id); + assert(entity.hasComponent(becsID!CLong)); + assert(*entity.getComponent!CLong == 3); + + gEntityManager.begin(); + gEntityManager.update(); + assert(system.count == 3); + gEntityManager.end(); +} + +//allocate templates +@("AllocateTemplates") +unittest +{ + //basic template allocation + ushort[2] ids = [becsID!CInt, becsID!CFloat]; + EntityTemplate* tmpl_ = gEntityManager.allocateTemplate(ids); + EntityTemplate* tmpl_d = gEntityManager.allocateTemplate([becsID!CFloat, becsID!CInt, becsID!CFloat].staticArray); + EntityTemplate* tmpl_cp = gEntityManager.allocateTemplate(tmpl_); + assert(tmpl_d.info == tmpl_.info); + assert(tmpl_cp.info == tmpl_cp.info); + assert(tmpl_.info.components.length == 2); + assert(tmpl_.getComponent!CInt); + assert(tmpl_.getComponent!CFloat); + assert(*tmpl_.getComponent!CInt == 1); + assert(*tmpl_.getComponent!CFloat == 2.0); + assert(tmpl_cp.getComponent!CFloat); + assert(tmpl_cp.getComponent!CInt); + assert(tmpl_.getComponent!CInt != tmpl_cp.getComponent!CInt); + assert(tmpl_.getComponent!CFloat != tmpl_cp.getComponent!CFloat); + assert(*tmpl_.getComponent!CInt == *tmpl_cp.getComponent!CInt); + assert(*tmpl_.getComponent!CFloat == *tmpl_cp.getComponent!CFloat); + *tmpl_.getComponent!CInt = 4; + *tmpl_.getComponent!CFloat = 5.0; + + //allocate template from template with additional components + ushort[2] ids2 = [becsID!CDouble,becsID!CFlag]; + EntityTemplate* tmpl_2 = gEntityManager.allocateTemplate(tmpl_, ids2); + assert(tmpl_2.info.components.length == 4); + assert(tmpl_2.getComponent!CInt); + assert(tmpl_2.getComponent!CFloat); + assert(tmpl_2.getComponent!CDouble); + assert(tmpl_2.getComponent!CFlag); + assert(*tmpl_2.getComponent!CInt == 4); + assert(*tmpl_2.getComponent!CFloat == 5.0); + assert(*tmpl_2.getComponent!CDouble == 3.0); + + assert(tmpl_.info.blocksCount() == 0); + + Entity* entity = gEntityManager.addEntity(tmpl_); + gEntityManager.addComponents(entity.id, CFloat(100)); + gEntityManager.addComponents(entity.id, CDouble(8.0), CFloat(100)); + + assert(tmpl_.info.blocksCount() == 1); + + //apply entity changes + gEntityManager.commit(); + + assert(tmpl_.info.blocksCount() == 0); + + //allocate template as entity copy + EntityTemplate* tmpl_3 = gEntityManager.allocateTemplate(entity.id); + assert(tmpl_3.info.components.length == 3); + assert(tmpl_3.getComponent!CInt); + assert(tmpl_3.getComponent!CFloat); + assert(tmpl_3.getComponent!CDouble); + assert(*tmpl_3.getComponent!CInt == 4); + assert(*tmpl_3.getComponent!CFloat == 5.0); + assert(*tmpl_3.getComponent!CDouble == 8.0); + + //allocate template with entity data but default values + EntityTemplate* tmpl_4 = gEntityManager.allocateTemplate(entity.id, true); + assert(tmpl_4.info.components.length == 3); + assert(tmpl_4.getComponent!CInt); + assert(tmpl_4.getComponent!CFloat); + assert(tmpl_4.getComponent!CDouble); + assert(*tmpl_4.getComponent!CInt == 1); + assert(*tmpl_4.getComponent!CFloat == 2.0); + assert(*tmpl_4.getComponent!CDouble == 3.0); + + //allocate template from template with three additional component + ushort[3] ids3 = [becsID!CDouble, becsID!CLong, becsID!CShort]; + EntityTemplate* tmpl_5 = gEntityManager.allocateTemplate(tmpl_2, ids3); + assert(tmpl_5.info.components.length == 6); + assert(tmpl_5.getComponent!CInt); + assert(tmpl_5.getComponent!CFloat); + assert(tmpl_5.getComponent!CDouble); + assert(tmpl_5.getComponent!CLong); + assert(tmpl_5.getComponent!CShort); + assert(*tmpl_5.getComponent!CInt == 4); + assert(*tmpl_5.getComponent!CFloat == 5.0); + assert(*tmpl_5.getComponent!CDouble == 3.0); + assert(*tmpl_5.getComponent!CLong == 10); + assert(*tmpl_5.getComponent!CShort == 12); + + //allocate template from template without one component + ushort[1] rem_ids = [becsID!CFloat]; + EntityTemplate* tmpl_6 = gEntityManager.allocateTemplate(tmpl_, null, rem_ids); + assert(tmpl_6.info.components.length == 1); + assert(tmpl_6.getComponent!CInt); + assert(*tmpl_6.getComponent!CInt == 4); + + //allocate template from template without one component and two additional + EntityTemplate* tmpl_7 = gEntityManager.allocateTemplate(tmpl_, ids3, rem_ids); + assert(tmpl_7.info.components.length == 4); + assert(tmpl_7.getComponent!CInt); + assert(tmpl_7.getComponent!CDouble); + assert(tmpl_7.getComponent!CLong); + assert(*tmpl_7.getComponent!CInt == 4); + assert(*tmpl_7.getComponent!CDouble == 3.0); + assert(*tmpl_7.getComponent!CLong == 10); + + gEntityManager.freeTemplate(tmpl_d); + gEntityManager.freeTemplate(tmpl_cp); + gEntityManager.freeTemplate(tmpl_); + gEntityManager.freeTemplate(tmpl_2); + gEntityManager.freeTemplate(tmpl_3); + gEntityManager.freeTemplate(tmpl_4); + gEntityManager.freeTemplate(tmpl_5); + gEntityManager.freeTemplate(tmpl_6); + gEntityManager.freeTemplate(tmpl_7); +} + +@("UnsortedComponentIDs") +unittest +{ + //basic template allocation + ushort[2] ids = [becsID!CFloat, becsID!CInt]; + ushort[2] ids2 = [becsID!CInt, becsID!CFloat]; + EntityTemplate* tmpl_ = gEntityManager.allocateTemplate(ids); + EntityTemplate* tmpl_2 = gEntityManager.allocateTemplate(ids2); + assert(tmpl_.info.components.length == 2); + assert(tmpl_.getComponent!CInt); + assert(tmpl_.getComponent!CFloat); + assert(*tmpl_.getComponent!CInt == 1); + assert(*tmpl_.getComponent!CFloat == 2.0); + assert(tmpl_.info == tmpl_2.info); + gEntityManager.freeTemplate(tmpl_); + gEntityManager.freeTemplate(tmpl_2); +} + +@("MultiRegister") +unittest +{ + gEntityManager.beginRegister(); + + gEntityManager.endRegister(); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CLong; + gEntityManager.registerComponent!CShort; + + gEntityManager.endRegister(); +} + +@("EmptySystem") +unittest +{ + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!EmptySystem(0); + + gEntityManager.endRegister(); + + EmptySystem* system = gEntityManager.getSystem!EmptySystem; + assert(system !is null); + assert(system.count == 0); + + System* ecs_system = gEntityManager.getSystem(becsID!EmptySystem); + assert(ecs_system !is null); + assert(ecs_system.id == becsID!EmptySystem); + assert(ecs_system.name == "tests.basic.EmptySystem"); + + gEntityManager.begin(); + + gEntityManager.update(); + + gEntityManager.end(); + + assert(system.count == 1); +} + +@("SystemCallbacks") +unittest +{ + struct TestSystem + { + mixin ECS.System!16; + + mixin ECS.ExcludedComponents!(CShort); + + struct EntitiesData + { + int length; + CLong[] long_; + @optional CInt[] int_; + } + + void onCreate() + { + create++; + } + + void onDestroy() + { + if(destroy)(*destroy)++; + } + + void onEnable() + { + enable++; + } + + void onDisable() + { + disable++; + } + + bool onBegin() + { + begin++; + update = 0; + return pass; + } + + void onEnd() + { + end++; + } + + void onUpdate(EntitiesData data) + { + update++; + } + + int create = 0; + int* destroy; + int update = 0; + int begin = 0; + int end = 0; + int enable = 0; + int disable = 0; + bool pass = true; + } + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!TestSystem(0); + + gEntityManager.endRegister(); + + TestSystem* system = gEntityManager.getSystem!TestSystem; + int destroy = 0; + system.destroy = &destroy; + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!TestSystem(0); + + gEntityManager.endRegister(); + + system = gEntityManager.getSystem!TestSystem; + system.destroy = &destroy; + assert(system !is null); + assert(system.create == 1); + assert(system.begin == 0); + assert(system.end == 0); + assert(system.enable == 1); + assert(system.disable == 0); + //FIXME: currently destroy is only called with Manager.destory which is bug, but there is no workaround for this by now + //assert(destroy == 1); + + System* ecs_system = gEntityManager.getSystem(system.becsID); + + ecs_system.enable(); + assert(system.enable == 1); + ecs_system.disable(); + ecs_system.disable(); + ecs_system.enable(); + assert(system.enable == 2); + assert(system.disable == 1); + + + ushort[2] ids = [becsID!CLong,becsID!CFloat]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + scope (exit) gEntityManager.freeTemplate(tmpl); + gEntityManager.addEntity(tmpl); + + gEntityManager.begin(); + assert(system.begin == 1); + + gEntityManager.update(); + assert(system.update == 1); + + gEntityManager.end(); + assert(system.end == 1); + + ushort[2] ids2 = [becsID!CLong, becsID!CInt]; + EntityTemplate* tmpl2 = gEntityManager.allocateTemplate(ids2); + scope (exit) gEntityManager.freeTemplate(tmpl2); + gEntityManager.addEntity(tmpl2); + gEntityManager.addEntity(tmpl2); + + gEntityManager.begin(); + assert(system.begin == 2); + + gEntityManager.update(); + assert(system.update == 2);//system is updated number of entity blocks times + + gEntityManager.end(); + assert(system.end == 2); + + ushort[2] ids3 = [becsID!CLong, becsID!CShort]; + EntityTemplate* tmpl3 = gEntityManager.allocateTemplate(ids3); + scope (exit) gEntityManager.freeTemplate(tmpl3); + gEntityManager.addEntity(tmpl3); + + //entity with excluded component shouldn't be updated + gEntityManager.begin(); + assert(system.begin == 3); + + gEntityManager.update(); + assert(system.update == 2); + + gEntityManager.end(); + assert(system.end == 3); + + //system can be disable form update in onBegin() callback, onEnd() callback is called + system.pass = false; + gEntityManager.begin(); + assert(system.begin == 4); + + gEntityManager.update(); + assert(system.update == 0); + + gEntityManager.end(); + assert(system.end == 4); + system.pass = true; + + //disabled system is't called + ecs_system.disable(); + gEntityManager.begin(); + assert(system.begin == 4); + + gEntityManager.update(); + assert(system.update == 0); + + gEntityManager.end(); + assert(system.end == 4); + ecs_system.enable(); + system.destroy = null; +} + +@("CustomPass") +unittest +{ + gEntityManager.beginRegister(); + + gEntityManager.registerPass("custom"); + gEntityManager.registerSystem!LongAddSystem(-1,"custom"); + + gEntityManager.endRegister(); + + assert(gEntityManager.getPass("custom")); + assert(!gEntityManager.getPass("custommm")); + + + LongAddSystem* system = gEntityManager.getSystem!LongAddSystem; + assert(system !is null); + assert(system.updates_count == 0); + + System* ecs_system = gEntityManager.getSystem(becsID!LongAddSystem); + assert(ecs_system !is null); + assert(ecs_system.id == becsID!LongAddSystem); + assert(ecs_system.priority == -1); + assert(ecs_system.name == "tests.basic.LongAddSystem"); + + ushort[1] ids = [becsID!CLong]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + scope (exit) gEntityManager.freeTemplate(tmpl); + gEntityManager.addEntity(tmpl); + + gEntityManager.begin(); + + gEntityManager.update(); + assert(system.updates_count == 0); + gEntityManager.update("custom"); + assert(system.updates_count == 1); + + gEntityManager.end(); +} + +@("SystemEntityCallbacks") +unittest +{ + static int add_order = 0; + static int rem_order = 0; + static int change_order = 0; + struct TestSystem + { + mixin ECS.System!16; + + mixin ECS.ExcludedComponents!(CShort); + + struct EntitiesData + { + int length; + CLong[] long_; + @optional CInt[] int_; + } + + void onAddEntity(EntitiesData data) + { + add++; + assert(add_order == 1); + add_order++; + } + + void onRemoveEntity(EntitiesData data) + { + remove++; + assert(rem_order == 1); + rem_order++; + } + + void onChangeEntity(EntitiesData data) + { + change++; + assert(change_order == 1); + change_order++; + } + + void onUpdate(EntitiesData data) + { + } + + int add = 0; + int remove = 0; + int change = 0; + } + + struct TestSystem2 + { + mixin ECS.System!16; + + mixin ECS.ExcludedComponents!(CShort); + + struct EntitiesData + { + int length; + CLong[] long_; + @optional CInt[] int_; + } + + void onAddEntity(EntitiesData data) + { + assert(add_order == 2); + add_order = 0; + } + + void onRemoveEntity(EntitiesData data) + { + assert(rem_order == 2); + rem_order = 0 ; + } + + void onChangeEntity(EntitiesData data) + { + assert(change_order == 2); + change_order = 0; + } + + void onUpdate(EntitiesData data) + { + } + } + + struct TestSystem3 + { + mixin ECS.System!16; + + mixin ECS.ExcludedComponents!(CShort); + + struct EntitiesData + { + int length; + CLong[] long_; + @optional CInt[] int_; + } + + void onAddEntity(EntitiesData data) + { + assert(add_order == 0); + add_order++; + } + + void onRemoveEntity(EntitiesData data) + { + assert(rem_order == 0); + rem_order++; + } + + void onChangeEntity(EntitiesData data) + { + assert(change_order == 0); + change_order++; + } + + void onUpdate(EntitiesData data) + { + } + } + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!TestSystem3(-1); + gEntityManager.registerSystem!TestSystem(0); + gEntityManager.registerSystem!TestSystem2(1); + + gEntityManager.endRegister(); + + TestSystem* system = gEntityManager.getSystem!TestSystem; + assert(system !is null); + assert(system.add == 0); + assert(system.remove == 0); + assert(system.change == 0); + + EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!CLong,becsID!CFloat].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl); + EntityID id0 = gEntityManager.addEntity(tmpl).id; + gEntityManager.commit(); + assert(system.add == 1); + + EntityTemplate* tmpl2 = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl2); + EntityID id1 = gEntityManager.addEntity(tmpl2).id; + gEntityManager.commit(); + assert(system.add == 2); + + EntityTemplate* tmpl3 = gEntityManager.allocateTemplate([becsID!CLong, becsID!CShort].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl3); + EntityID id2 = gEntityManager.addEntity(tmpl3).id; + gEntityManager.commit(); + assert(system.add == 2); + + gEntityManager.beginRegister(); + gEntityManager.endRegister(); + + gEntityManager.removeComponents(id0, [becsID!CFloat].staticArray); + gEntityManager.commit(); + assert(system.add == 2); + assert(system.remove == 0); + assert(system.change == 0); + + gEntityManager.removeComponents(id1, [becsID!CInt].staticArray); + gEntityManager.commit(); + assert(system.add == 2); + assert(system.remove == 0); + assert(system.change == 1); + + gEntityManager.removeComponents(id2, [becsID!CShort].staticArray); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 0); + assert(system.change == 1); + + gEntityManager.addComponents(id2, CShort(1)); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 1); + assert(system.change == 1); + + gEntityManager.removeEntity(id0); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 2); + assert(system.change == 1); + + gEntityManager.addComponents(id1, CInt(1)); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 2); + assert(system.change == 2); + + gEntityManager.addComponents(id0, CFloat(1)); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 2); + assert(system.change == 2); + + gEntityManager.removeEntity(id1); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 3); + assert(system.change == 2); + + gEntityManager.removeEntity(id2); + gEntityManager.commit(); + assert(system.add == 3); + assert(system.remove == 3); + assert(system.change == 2); +} + +@("TemplateCoverage") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + @readonly CLong[] long_; + @optional CInt[] int_; + @readonly CFloat[] float_; + } + + mixin ECS.ExcludedComponents!(CUnregistered); + + void onUpdate(EntitiesData data) + { + + } + } + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CUnregistered; + + gEntityManager.registerSystem!TestSystem(0); + + gEntityManager.endRegister(); +} + +@("UnregisteredSystem") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + @readonly CLong[] long_; + @optional CInt[] int_; + @readonly CFloat[] float_; + } + + void onUpdate(EntitiesData data) + { + + } + } + + assert(gEntityManager.getSystem!TestSystem is null); + assert(gEntityManager.getSystem(becsID!TestSystem) is null); +} + +@("MultithreadedUpdate") +unittest +{ + struct TestSystem + { + mixin ECS.System!64; + + struct EntitiesData + { + int length; + Entity[] entity; + @readonly CLong[] long_; + @optional CInt[] int_; + @readonly CFloat[] float_; + } + + void onUpdate(EntitiesData data) + { + update++; + entities += data.length; + } + + int update = 0; + int entities = 0; + } + + struct TestEmptySystem + { + mixin ECS.System; + + struct EntitiesData + { + int length; + } + + void onUpdate(EntitiesData data) + { + update++; + } + + int update = 0; + } + + void dispatch(EntityManager.JobGroup grp) + { + foreach(job; grp.jobs) + { + job.execute(); + } + } + + uint getID() + { + return 0; + } + + gEntityManager.setMultithreadingCallbacks(&dispatch, &getID); + + gEntityManager.beginRegister(); + + gEntityManager.registerPass("custom"); + gEntityManager.registerSystem!TestSystem(-1,"custom"); + gEntityManager.registerSystem!TestEmptySystem(1,"custom"); + + gEntityManager.endRegister(); + + TestSystem* system = gEntityManager.getSystem!TestSystem; + TestEmptySystem* empty_system = gEntityManager.getSystem!TestEmptySystem; + + ushort[2] ids = [becsID!CLong,becsID!CFloat]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + scope (exit) gEntityManager.freeTemplate(tmpl); + EntityTemplate* tmpl2 = gEntityManager.allocateTemplate([becsID!CLong,becsID!CInt,becsID!CShort,becsID!CFloat].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl2); + + gEntityManager.begin(); + + gEntityManager.updateMT("custom"); + + gEntityManager.end(); + + assert(system.update == 0); + assert(system.entities == 0); + assert(empty_system.update == 1); + + gEntityManager.addEntity(tmpl); + + gEntityManager.begin(); + + gEntityManager.updateMT("custom"); + + gEntityManager.end(); + + assert(system.update == 1); + assert(system.entities == 1); + assert(empty_system.update == 2); + system.entities = 0; + + foreach(i;0..2000)gEntityManager.addEntity(tmpl); + + gEntityManager.begin(); + + gEntityManager.updateMT("custom"); + + gEntityManager.end(); + + assert(system.update > 2); + assert(system.entities == 2001); + assert(empty_system.update == 3); + system.entities = 0; + + // foreach(i;0..10000)gEntityManager.addEntity(tmpl); + + // gEntityManager.begin(); + + // gEntityManager.updateMT("custom"); + + // gEntityManager.end(); + + // assert(system.entities == 12001); + + void clearEntities(TestSystem.EntitiesData data) + { + foreach(i;0..data.length) + { + gEntityManager.removeEntity(data.entity[i].id); + } + } + gEntityManager.callEntitiesFunction!TestSystem(&clearEntities); + gEntityManager.commit(); + + foreach(i;0..2000) + { + gEntityManager.addEntity(tmpl); + + gEntityManager.begin(); + gEntityManager.updateMT("custom"); + gEntityManager.end(); + + assert(system.entities == i+1); + system.entities = 0; + } + + foreach(i;0..90000)gEntityManager.addEntity(tmpl); + + foreach(i;0..2000) + { + gEntityManager.addEntity(tmpl); + + gEntityManager.begin(); + gEntityManager.updateMT("custom"); + gEntityManager.end(); + + assert(system.entities == i+92001); + system.entities = 0; + } +} + +unittest +{ + assert(gEntityManager.pageSize == 32768); + assert(gEntityManager.pagesInBlock == 128); +} + +@("AddRemoveEntities") +unittest +{ + ushort[3] ids = [becsID!CLong,becsID!CFloat,becsID!CShort]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + scope (exit) gEntityManager.freeTemplate(tmpl); + + EntityID[5000] entities; + + foreach(i;0..4) + { + foreach(j;0..5000) + { + entities[j] = gEntityManager.addEntity(tmpl).id; + } + gEntityManager.commit(); + foreach(j;0..5000) + { + gEntityManager.removeEntity(entities[j]); + } + gEntityManager.commit(); + } +} + +@("ChangeEntityComponents") +unittest +{ + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CUnregistered; + + gEntityManager.endRegister(); + + ushort[1] ids = [becsID!CLong]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + scope (exit) gEntityManager.freeTemplate(tmpl); + + EntityID id = gEntityManager.addEntity(tmpl).id; + gEntityManager.commit(); + Entity* entity = gEntityManager.getEntity(id); + assert(entity.id == id); + assert(entity.getComponent!CLong !is null); + assert(entity.getComponent!CFloat is null); + assert(entity.getComponent!CUnregistered is null); + assert(entity.getComponent!CShort is null); + assert(entity.getComponent!CInt is null); + assert(*entity.getComponent!CLong == 10); + + gEntityManager.addComponents(id, CShort(15), CFloat(13)); + gEntityManager.commit(); + + entity = gEntityManager.getEntity(id); + assert(entity.id == id); + assert(entity.getComponent!CLong !is null); + assert(entity.getComponent!CFloat !is null); + assert(entity.getComponent!CUnregistered is null); + assert(entity.getComponent!CShort !is null); + assert(entity.getComponent!CInt is null); + assert(*entity.getComponent!CLong == 10); + assert(*entity.getComponent!CShort == 15); + assert(*entity.getComponent!CFloat == 13); + + ushort[3] ids2 = [becsID!CFloat, becsID!CLong, becsID!CUnregistered]; + gEntityManager.removeComponents(id, ids2); + gEntityManager.commit(); + + entity = gEntityManager.getEntity(id); + assert(entity.id == id); + assert(entity.getComponent!CLong is null); + assert(entity.getComponent!CFloat is null); + assert(entity.getComponent!CUnregistered is null); + assert(entity.getComponent!CShort !is null); + assert(entity.getComponent!CInt is null); + assert(*entity.getComponent!CShort == 15); + + gEntityManager.removeComponents(id, ids2); + gEntityManager.addComponents(id, CShort(11), CLong(2)); //wrong order of components + gEntityManager.commit(); + + entity = gEntityManager.getEntity(id); + assert(entity.id == id); + assert(entity.getComponent!CLong !is null); + assert(entity.getComponent!CFloat is null); + assert(entity.getComponent!CUnregistered is null); + assert(entity.getComponent!CShort !is null); + assert(entity.getComponent!CInt is null); + assert(*entity.getComponent!CLong == 2); + assert(*entity.getComponent!CShort == 15); + + gEntityManager.removeEntity(id); + + entity = gEntityManager.getEntity(id); + assert(entity !is null); + assert(entity.id == id); + + gEntityManager.commit(); + entity = gEntityManager.getEntity(id); + assert(entity is null); +} + +@("EventCallbacks") +unittest +{ + struct ETest + { + // mixin ECS.Event; + } + + struct ETest2 + { + // mixin ECS.Event; + + void onDestroy() + { + destory++; + } + + int super_liczba = 0; + static int destory = 0; + } + + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + @readonly CLong[] long_; + @optional CInt[] int_; + } + + void onUpdate(EntitiesData data) + { + + } + + void handleEvent(Entity* entity, ETest event) + { + CLong* long_ = entity.getComponent!CLong; + CInt* int_ = entity.getComponent!CInt; + *long_ += 16; + if(int_)*int_ += 6; + } + + void handleEvent(Entity* entity, ETest2 event) + { + CLong* long_ = entity.getComponent!CLong; + CInt* int_ = entity.getComponent!CInt; + *long_ += event.super_liczba * 2; + if(int_)*int_ += event.super_liczba * 4; + } + } + + struct TestSystem2 + { + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + CShort[] short_; + @optional CInt[] int_; + } + + void handleEvent(Entity* entity, ETest event) + { + CShort* short_ = entity.getComponent!CShort; + CInt* int_ = entity.getComponent!CInt; + *short_ += 8; + if(int_)*int_ += 2; + } + + void handleEvent(Entity* entity, ETest2 event) + { + CShort* short_ = entity.getComponent!CShort; + CInt* int_ = entity.getComponent!CInt; + *short_ += event.super_liczba; + if(int_)*int_ *= event.super_liczba; + } + } + + gEntityManager.beginRegister(); + + gEntityManager.registerEvent!ETest; + gEntityManager.registerEvent!ETest2; + + gEntityManager.registerEvent!ETest; + gEntityManager.registerEvent!ETest2; + + gEntityManager.registerSystem!TestSystem2(1); + gEntityManager.registerSystem!TestSystem(0); + + gEntityManager.endRegister(); + + ushort[1] ids = [becsID!CLong]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + scope (exit) gEntityManager.freeTemplate(tmpl); + ushort[1] ids2 = [becsID!CShort]; + EntityTemplate* tmpl2 = gEntityManager.allocateTemplate(ids2); + scope (exit) gEntityManager.freeTemplate(tmpl2); + + Entity* entity = gEntityManager.addEntity(tmpl); + EntityID id = entity.id; + assert(*entity.getComponent!CLong == 10); + Entity* entity2 = gEntityManager.addEntity(tmpl2); + EntityID id2 = entity2.id; + assert(*entity2.getComponent!CShort == 12); + + gEntityManager.sendEvent(id,ETest()); + gEntityManager.sendEvent(id,ETest2(10)); + gEntityManager.sendEvent(id2,ETest()); + gEntityManager.sendEvent(id2,ETest2(12)); + gEntityManager.commit(); + assert(ETest2.destory == 2); + + entity = gEntityManager.getEntity(id); + entity2 = gEntityManager.getEntity(id2); + assert(*entity.getComponent!CLong == 46); + assert(*entity2.getComponent!CShort == 32); + + gEntityManager.addComponents(id, CInt(2), CShort(1)); + gEntityManager.sendEvent(id,ETest()); + gEntityManager.sendEvent(id,ETest2(2)); + gEntityManager.commit(); + assert(ETest2.destory == 3); + + entity = gEntityManager.getEntity(id); + assert(*entity.getComponent!CLong == 66); + assert(*entity.getComponent!CInt == 2);//36); + + //test for multiple event blocks + long result = *entity.getComponent!CLong; + foreach(i;0..10000) + { + gEntityManager.sendEvent(id,ETest()); + gEntityManager.sendEvent(id,ETest2(4)); + result += 16; + result += 8; + } + gEntityManager.commit(); + assert(ETest2.destory == 10003); + entity = gEntityManager.getEntity(id); + assert(*entity.getComponent!CLong == result); + + //cover funcion to clearEvents before destroying manager + gEntityManager.sendEvent(id,ETest()); +} + +@("EntitiesFunction") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + void func1(TestSystem.EntitiesData entities) + { + foreach(i;0 .. entities.length) + { + entities.int_[i] += entities.int_[i] / 2; + } + } + + void func2(TestSystem.EntitiesData entities) + { + foreach(i;0 .. entities.length) + { + entities.int_[i] += 8; + } + } + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!TestSystem(1); + + gEntityManager.endRegister(); + + EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!CInt].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl); + EntityID id1 = gEntityManager.addEntity(tmpl).id; + + EntityTemplate* tmpl2 = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong].staticArray); + scope (exit) gEntityManager.freeTemplate(tmpl2); + EntityID id2 = gEntityManager.addEntity(tmpl2).id; + + gEntityManager.begin(); + + Entity* entity1 = gEntityManager.getEntity(id1); + Entity* entity2 = gEntityManager.getEntity(id2); + assert(*entity1.getComponent!CInt == 1); + assert(*entity2.getComponent!CInt == 1); + + gEntityManager.callEntitiesFunction!TestSystem(&func2); + assert(*entity1.getComponent!CInt == 9); + assert(*entity2.getComponent!CInt == 9); + + gEntityManager.callEntitiesFunction!TestSystem(&func1); + assert(*entity1.getComponent!CInt == 13); + assert(*entity2.getComponent!CInt == 13); + + gEntityManager.end(); +} + +@("SystemDependencies") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem2 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem3 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem4 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + CInt[] int_; + CLong[] long_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem5 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @readonly CLong[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!TestSystem(0); + gEntityManager.registerSystem!TestSystem2(1); + gEntityManager.registerSystem!TestSystem3(2); + gEntityManager.registerSystem!TestSystem4(3); + gEntityManager.registerSystem!TestSystem5(4); + + gEntityManager.endRegister(); + + const (EntityManager.UpdatePass)* pass = gEntityManager.getPass("update"); + assert(pass != null); + assert(pass.system_callers.length == 5); + assert(pass.system_callers[0].system_id == becsID!TestSystem); + assert(pass.system_callers[1].system_id == becsID!TestSystem2); + assert(pass.system_callers[2].system_id == becsID!TestSystem3); + assert(pass.system_callers[3].system_id == becsID!TestSystem4); + assert(pass.system_callers[4].system_id == becsID!TestSystem5); + assert(pass.system_callers[0].dependencies.length == 0); + assert(pass.system_callers[1].dependencies.length == 1); + assert(pass.system_callers[2].dependencies.length == 1); + assert(pass.system_callers[3].dependencies.length == 3); + assert(pass.system_callers[4].dependencies.length == 1); + assert(pass.system_callers[1].dependencies[0].system_id == becsID!TestSystem); + assert(pass.system_callers[2].dependencies[0].system_id == becsID!TestSystem2); + assert(pass.system_callers[3].dependencies[0].system_id == becsID!TestSystem); + assert(pass.system_callers[3].dependencies[1].system_id == becsID!TestSystem2); + assert(pass.system_callers[3].dependencies[2].system_id == becsID!TestSystem3); + assert(pass.system_callers[4].dependencies[0].system_id == becsID!TestSystem4); +} + +@("ExternalSystemDependencies") +unittest +{ + enum TestDependency = "TestDepencency"; + + struct TestSystem + { + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem2 + { + mixin ECS.System; + + mixin ECS.WritableDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem3 + { + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(TestDependency); + + struct EntitiesData + { + uint thread_id; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem4 + { + mixin ECS.System; + + mixin ECS.WritableDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem5 + { + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CLong[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + gEntityManager.beginRegister(); + + gEntityManager.registerDependency(TestDependency); + + gEntityManager.registerSystem!TestSystem(0); + gEntityManager.registerSystem!TestSystem2(1); + gEntityManager.registerSystem!TestSystem3(2); + gEntityManager.registerSystem!TestSystem4(3); + gEntityManager.registerSystem!TestSystem5(4); + + gEntityManager.endRegister(); + + const (EntityManager.UpdatePass)* pass = gEntityManager.getPass("update"); + assert(pass != null); + assert(pass.system_callers.length == 5); + assert(pass.system_callers[0].system_id == becsID!TestSystem); + assert(pass.system_callers[1].system_id == becsID!TestSystem2); + assert(pass.system_callers[2].system_id == becsID!TestSystem3); + assert(pass.system_callers[3].system_id == becsID!TestSystem4); + assert(pass.system_callers[4].system_id == becsID!TestSystem5); + assert(pass.system_callers[0].dependencies.length == 0); + assert(pass.system_callers[1].dependencies.length == 1); + assert(pass.system_callers[2].dependencies.length == 1); + assert(pass.system_callers[3].dependencies.length == 3); + assert(pass.system_callers[4].dependencies.length == 2); + assert(pass.system_callers[1].dependencies[0].system_id == becsID!TestSystem); + assert(pass.system_callers[2].dependencies[0].system_id == becsID!TestSystem2); + assert(pass.system_callers[3].dependencies[0].system_id == becsID!TestSystem); + assert(pass.system_callers[3].dependencies[1].system_id == becsID!TestSystem2); + assert(pass.system_callers[3].dependencies[2].system_id == becsID!TestSystem3); + assert(pass.system_callers[4].dependencies[0].system_id == becsID!TestSystem2); + assert(pass.system_callers[4].dependencies[1].system_id == becsID!TestSystem4); +} + + +@("CustomFilter") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @optional CInt[] int_; + @optional CLong[] long_; + @optional CFloat[] float_; + @optional CDouble[] double_; + } + + bool filterEntity(EntityManager.EntityInfo* info) + { + if(!info.hasComponent(becsID!CInt))return false; + int one_from = 0; + if(info.hasComponent(becsID!CLong))one_from++; + if(info.hasComponent(becsID!CFloat))one_from++; + if(info.hasComponent(becsID!CDouble))one_from++; + if(one_from == 1)return true; + return false; + } + + void onUpdate(EntitiesData entities) + { + updates++; + } + + uint updates = 0; + } + + struct TestSystem2 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @optional CInt[] int_; + @optional CLong[] long_; + @optional CFloat[] float_; + @optional CDouble[] double_; + } + + bool filterEntity(EntityManager.EntityInfo* info) + { + if(info.hasComponent(becsID!CInt) && info.hasComponent(becsID!CFloat) && !info.hasComponent(becsID!CLong) && !info.hasComponent(becsID!CDouble))return true; + if(info.hasComponent(becsID!CLong) && info.hasComponent(becsID!CDouble) && !info.hasComponent(becsID!CInt) && !info.hasComponent(becsID!CFloat))return true; + return false; + } + + void onUpdate(EntitiesData entities) + { + updates++; + } + + uint updates = 0; + } + + gEntityManager.beginRegister(); + + gEntityManager.registerSystem!TestSystem(0); + gEntityManager.registerSystem!TestSystem2(1); + + gEntityManager.endRegister(); + + + EntityTemplate* tmpl_ = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong, becsID!CFloat, becsID!CDouble].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_); + EntityTemplate* tmpl_2 = gEntityManager.allocateTemplate([becsID!CInt, becsID!CFloat].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_2); + EntityTemplate* tmpl_3 = gEntityManager.allocateTemplate([becsID!CLong, becsID!CDouble].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_3); + EntityTemplate* tmpl_4 = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong, becsID!CDouble].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_4); + EntityTemplate* tmpl_5 = gEntityManager.allocateTemplate([becsID!CInt, becsID!CDouble].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_5); + EntityTemplate* tmpl_6 = gEntityManager.allocateTemplate([becsID!CDouble].staticArray); + scope(exit)gEntityManager.freeTemplate(tmpl_6); + + gEntityManager.addEntity(tmpl_); + gEntityManager.addEntity(tmpl_2); + gEntityManager.addEntity(tmpl_3); + gEntityManager.addEntity(tmpl_4); + gEntityManager.addEntity(tmpl_5); + gEntityManager.addEntity(tmpl_6); + + TestSystem* test_system = gEntityManager.getSystem!TestSystem; + TestSystem2* test_system2 = gEntityManager.getSystem!TestSystem2; + + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.end(); + + assert(test_system.updates == 2); + assert(test_system2.updates == 2); +} diff --git a/tests/bugs.d b/tests/bugs.d new file mode 100644 index 0000000..10a3c62 --- /dev/null +++ b/tests/bugs.d @@ -0,0 +1,175 @@ +module tests.bugs; + +import tests.basic; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.system; +import bubel.ecs.attributes; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +@("Bug0001") +unittest +{ + struct Event1 + { + // mixin ECS.Event; + + EntityID id; + } + + struct Event2 + { + // mixin ECS.Event; + } + + struct System1 + { + mixin ECS.System; + + struct EntitiesData + { + CInt[] int_; + } + + EntityTemplate* tmpl; + EntityID id; + + void onCreate() + { + tmpl = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong].staticArray); + } + + void onDestroy() + { + gEntityManager.freeTemplate(tmpl); + } + + void handleEvent(Entity* entity, Event1 event) + { + gEntityManager.removeEntity(event.id); + gEntityManager.sendEvent(entity.id,Event2()); + } + + void handleEvent(Entity* entity, Event2 event) + { + id = gEntityManager.addEntity(tmpl).id; + } + } + + struct System2 + { + mixin ECS.System; + + struct EntitiesData + { + Entity[] entity; + } + + ///check if every entity was removed correctly + void onUpdate(EntitiesData data) + { + assert(0); + } + } + + struct System3 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + Entity[] entity; + } + + ///remove every entity + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length)gEntityManager.removeEntity(data.entity[i].id); + } + } + + gEntityManager.initialize(0); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CInt; + gEntityManager.registerComponent!CFloat; + gEntityManager.registerComponent!CDouble; + gEntityManager.registerComponent!CLong; + gEntityManager.registerComponent!CShort; + gEntityManager.registerComponent!CFlag; + + gEntityManager.registerEvent!Event1; + gEntityManager.registerEvent!Event2; + + gEntityManager.registerSystem!System1(0); + gEntityManager.registerSystem!System2(-200); + gEntityManager.registerSystem!System3(-200); + + gEntityManager.endRegister(); + + EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong].staticArray); + + CLong clong = CLong(10); + CInt cint = CInt(6); + CInt cint2 = CInt(4); + EntityID id = gEntityManager.addEntity(tmpl,[ComponentRef(&clong, becsID(clong)), ComponentRef(&cint, becsID(cint))].staticArray).id; + EntityID id2 = gEntityManager.addEntity(tmpl,[ComponentRef(&cint2, becsID(cint2))].staticArray).id; + gEntityManager.freeTemplate(tmpl); + gEntityManager.commit(); + + gEntityManager.sendEvent(id2, Event1(id)); + + gEntityManager.getSystem(becsID!System2).disable(); + + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.end(); + + gEntityManager.getSystem(becsID!System2).enable(); + + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.end(); + + gEntityManager.destroy(); +} + +@("2-empty-entity-crash") +unittest +{ + + gEntityManager.initialize(0); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CInt; + gEntityManager.registerComponent!CFloat; + + gEntityManager.endRegister(); + + + EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!CInt, becsID!CFloat].staticArray); + scope(exit) gEntityManager.freeTemplate(tmpl); + + EntityID id = gEntityManager.addEntity(tmpl).id; + // EntityID id2 = gEntityManager.addEntity().id; + + gEntityManager.commit(); + + gEntityManager.removeComponents(id, [becsID!CInt, becsID!CFloat].staticArray); + + gEntityManager.commit(); + + gEntityManager.destroy(); +} \ No newline at end of file diff --git a/tests/id_manager.d b/tests/id_manager.d new file mode 100644 index 0000000..b0f97d5 --- /dev/null +++ b/tests/id_manager.d @@ -0,0 +1,36 @@ +module tests.id_manager; + +import bubel.ecs.id_manager; +import bubel.ecs.entity; + +unittest +{ + IDManager manager; + manager.initialize(); + EntityID id1 = manager.getNewID(); + EntityID id2 = manager.getNewID(); + EntityID id3 = manager.getNewID(); + + assert(id1 == EntityID(1, 0)); + assert(id2 == EntityID(2, 0)); + assert(id3 == EntityID(3, 0)); + + manager.optimize(); + manager.releaseID(id2); + manager.releaseID(id1); + + id2 = manager.getNewID(); + id1 = manager.getNewID(); + + Entity e; + e.id = id3; + manager.update(e); + + assert(id1 == EntityID(2, 1)); + assert(id2 == EntityID(1, 1)); + assert(id3 == EntityID(3, 0)); + assert(manager.isExist(id3)); + assert(!manager.isExist(EntityID(1, 0))); + assert(!manager.isExist(EntityID(0, 0))); + manager.deinitialize(); +} diff --git a/tests/map.d b/tests/map.d new file mode 100644 index 0000000..a82985b --- /dev/null +++ b/tests/map.d @@ -0,0 +1,53 @@ +module tests.map; + +import bubel.ecs.hash_map; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +@("HashMap") +unittest +{ + HashMap!(string, int) map; + + assert(map.length == 0); + map.add("asd",1); + assert(map.length == 1); + map.clear(); + assert(map.length == 0); + map.add("asd",1); + assert(map.length == 1); + map.reset(); + assert(map.length == 0); + + map.add("asd",1); + string asd = "asd"; + assert(map.isIn("asd")); + assert(map.isIn(asd)); + assert(!map.isIn("asdf")); + map.tryRemove("asdf"); + map.tryRemove("asd"); + assert(map.length == 0); + map.add("asdf",1); + map.add("asd",2); + assert(map["asd"] == 2); + assert(map["asdf"] == 1); + assert(map.length == 2); + map.tryRemove("asdf"); + assert(map.length == 1); + map.remove("asd"); + assert(map.length == 0); + + map.add("asd",1); + map.add("asdwwghe",6); + foreach(k,v;&map.byKeyValue) + { + assert(map[k] == v); + } +} \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..ff1a3a1 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,21 @@ +tests_src = files( + 'access_perf.d', + 'basic.d', + 'bugs.d', + 'id_manager.d', + 'map.d', + 'perf.d', + 'runner.d', + 'time.d', + 'vector.d' +) + +exe = executable('BubelECSTests', + tests_src, + include_directories : [inc, include_directories('..')], + d_args : args, + link_args : link_args, + dependencies : decs_dep, +) + +test('basic-tests', exe) diff --git a/tests/perf.d b/tests/perf.d new file mode 100644 index 0000000..695b46e --- /dev/null +++ b/tests/perf.d @@ -0,0 +1,185 @@ +module tests.perf; + +import tests.runner; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.entity; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +import core.stdc.stdio; + +struct CLong +{ + mixin ECS.Component; + + alias value this; + + long value = 10; +} + +struct CShort +{ + mixin ECS.Component; + + alias value this; + + short value = 12; +} + +struct CInt +{ + mixin ECS.Component; + + alias value this; + + int value = 10; +} + +struct CUInt +{ + mixin ECS.Component; + + alias value this; + + uint value = 12; +} + +struct CBig +{ + mixin ECS.Component; + uint[32] data; +} + +EntityTemplate* tmpl; + +void beforeEveryTest() +{ + gEntityManager.initialize(0); + + gEntityManager.beginRegister(); + + gEntityManager.registerComponent!CLong; + gEntityManager.registerComponent!CShort; + gEntityManager.registerComponent!CInt; + gEntityManager.registerComponent!CUInt; + gEntityManager.registerComponent!CBig; + + gEntityManager.endRegister(); + tmpl = null; +} + +void afterEveryTest() +{ + if(tmpl)gEntityManager.freeTemplate(tmpl); + tmpl = null; + gEntityManager.destroy(); +} + +void smallTmpl() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CShort].staticArray); +} + +void bigTmpl() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CBig].staticArray); +} + +void multiSmallTmpl() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CShort, becsID!CLong, becsID!CInt, becsID!CUInt].staticArray); +} + +void multiBigTmpl() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray); +} + +@("AddEntities100k1comp2b") @(before, &smallTmpl) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +@("AddEntities100k1comp128b") @(before, &bigTmpl) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +@("AddEntities100k4comp18b") @(before, &multiSmallTmpl) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +@("AddEntities100k4comp144b") @(before, &multiBigTmpl) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +void allocDealloc100k() +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); + gEntityManager.commit(); + foreach(i; 0..100_000)gEntityManager.removeEntity(EntityID(i + 1,0)); + gEntityManager.commit(); +} + +void smallTmplPreAlloc() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CShort].staticArray); + allocDealloc100k(); +} + +void bigTmplPreAlloc() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CBig].staticArray); + allocDealloc100k(); +} + +void multiSmallTmplPreAlloc() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CShort, becsID!CLong, becsID!CInt, becsID!CUInt].staticArray); + allocDealloc100k(); +} + +void multiBigTmplPreAlloc() +{ + tmpl = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray); + allocDealloc100k(); +} + +@("AddEntities100k1comp2bPreAlloc") @(before, &smallTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +@("AddEntities100k1comp128bPreAlloc") @(before, &bigTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +@("AddEntities100k4comp18bPreAlloc") @(before, &multiSmallTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} + +@("AddEntities100k4comp144bPreAlloc") @(before, &multiBigTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEntityManager.addEntity(tmpl); +} \ No newline at end of file diff --git a/tests/runner.d b/tests/runner.d new file mode 100644 index 0000000..b779056 --- /dev/null +++ b/tests/runner.d @@ -0,0 +1,481 @@ +// Example usage: dub -c unittest-runner -b unittest +module tests.runner; + +import core.stdc.stdio; +import core.stdc.string; + +import bubel.ecs.vector; +import bubel.ecs.simple_vector; +import bubel.ecs.std; + +import std.traits; + +import tests.time; + +version (LDC) +{ + import ldc.attributes; +} +else +{ + enum optStrategy = 0; +} + +enum int ASSERTED = 123; +enum string OUT_FILE = "test_report.xml"; + +version (D_BetterC) +{ + version(Posix) + { + import core.sys.posix.setjmp; + } + else version(Windows) + { + version(X86) + alias jmp_buf = ubyte[64]; + else version(X86_64) + alias jmp_buf = ubyte[256]; + else version(IA64) + alias jmp_buf = ubyte[512]; + + extern (C) { + int _setjmp(ref jmp_buf); + void longjmp(ref jmp_buf, int); + } + alias setjmp = _setjmp; + } + + static jmp_buf gEnvBuffer; + static AssertInfo gAssertInfo; + + extern (C) void __assert(const char* msg, const char* file, int line) + { + gAssertInfo = AssertInfo(msg, file, line); + longjmp(gEnvBuffer, ASSERTED); + } +} +else version = notBetterC; + +struct AssertInfo +{ + const(char)* msg; + const(char)* file; + int line; +} + +struct Test +{ + string file; + string msg; + int file_line; + string name; + //string classname; + int time; + bool passed; +} + +struct TestSuite +{ + string name; + uint passed = 0; + uint failed = 0; + uint skipped = 0; + Vector!Test tests; +} + +string copyString(const char* str) +{ + auto length = strlen(str); + char[] arr = cast(char[]) str[0 .. length + 1]; + return cast(string) Mallocator.makeArray(arr); +} + +string copyString(string str) +{ + return cast(string) Mallocator.makeArray((cast(char*)str)[0 .. str.length + 1]); +} + +struct TestRunner(Args...) +{ + void generateJUnit() + { + write("\n\n"); + + write("\n"); + + foreach (ref TestSuite suite; suites) + { + write("\t\n"); + + foreach (ref Test test; suite.tests) + { + write("\t\t"); + if (test.msg) + { + write("\n\t\t\t"); + write("Assert! File: "); + write(test.file[0 .. $ - 1]); + write(":"); + write(test.file_line); + write(" Message: "); + write(test.msg[0 .. $ - 1]); + write("\n"); + write("\t\t\n"); + } + else write("\n"); + + } + + write("\t\n"); + } + + write(""); + } + + @(optStrategy,"none") + void runTests(string[] include = null, string[] exclude = null) + { + foreach (i, module_; Args) + { + TestSuite* suite = &suites[i]; + suite.name = module_.stringof; + + void function() before; + void function() after; + + foreach (index, unittest_; __traits(getUnitTests, module_)) + { + enum attributes = __traits(getAttributes, unittest_); + + static if (attributes.length != 0) + { + foreach(attr_id, attr; attributes) + { + static if(isFunctionPointer!(attr)){} + else static if(attr == "_tr_before") + { + static assert(attr_id+1 < attributes.length); + enum attr2 = attributes[attr_id + 1]; + //static assert(__traits(hasMember, module_, attr2)); + //alias func = __traits(getMember, module_, attr2); + //attr2(); + before = attr2; + //static assert(is(typeof(__traits(getMember, module_, attr2)) == void function())); + } + else + { + if (include.length > 0) + { + bool matched = false; + foreach (str; include) + { + if (match(str, attr)) + { + matched = true; + break; + } + } + + foreach (str; exclude) + { + if (match(str, attr)) + { + matched = false; + break; + } + } + + if (!matched) + { + suite.skipped++; + continue; + } + } + } + } + } + else if (include.length > 0) + { + suite.skipped++; + continue; + } + + Test test; + + static if (attributes.length == 0) + test.name = "None"; + else + test.name = attributes[0]; + + static if (__traits(hasMember, module_, "beforeEveryTest") && __traits(compiles, module_.beforeEveryTest())) + module_.beforeEveryTest(); + if(before)before(); + + version(D_BetterC) + { + // Save calling environment for longjmp + int jmp_ret = setjmp(gEnvBuffer); + + if (jmp_ret == ASSERTED) + { + test.passed = false; + test.file = copyString(gAssertInfo.file); + test.file_line = gAssertInfo.line; + test.msg = copyString(gAssertInfo.msg); + } + else + { + long time = Time.getUSecTime(); + unittest_(); + test.passed = true; + test.time = cast(int)(Time.getUSecTime() - time); + } + } + else + { + import core.exception : AssertError, RangeError; + try + { + unittest_(); + test.passed = true; + } + catch(AssertError error) + { + test.passed = false; + test.file = copyString(error.file); + test.file_line = cast(int)error.line; + test.msg = copyString(error.msg); + } + catch(RangeError error) + { + test.passed = false; + test.file = copyString(error.file); + test.file_line = cast(int)error.line; + test.msg = copyString(error.msg); + } + } + + if (test.passed) + suite.passed++; + else + suite.failed++; + suite.tests ~= test; + static if (__traits(hasMember, module_, "afterEveryTest") && __traits(compiles, module_.beforeEveryTest())) + module_.afterEveryTest(); + } + passed += suite.passed; + failed += suite.failed; + skipped += suite.skipped; + } + } + + void writeFile() + { + if (junit.length == 0) + generateJUnit(); + auto file = fopen(OUT_FILE, "w"); + fwrite(junit.data.ptr, junit.length, 1, file); + fclose(file); + } + + void writeOutput() + { + foreach (ref TestSuite suite; suites) + { + printf("Suite: \"%s\" Passed: %u/%u Skipped: %u\n", suite.name.ptr, + suite.passed, suite.passed + suite.failed, suite.skipped); + foreach (ref Test test; suite.tests) + { + if (!test.passed) + { + printf("\tTest: \"%s\" Failed! Line: %u Message: %s\n", + test.name.ptr, test.file_line, test.msg.ptr); + } + } + } + printf("Passed %u/%u tests. Skipped: %u.\n", passed, passed + failed, skipped); + } + + bool match(string a, string b) + { + uint i = 0; + foreach (char c; b) + { + if (i > a.length) + return false; + if (a[i] == c) + i++; + else + { + if (a[i] == '*') + { + if (i + 1 >= a.length) + return true; + else if (a[i + 1] == c) + i += 2; + } + else + return false; + } + } + return i == a.length; + } + + void write(string txt) + { + junit.add(cast(ubyte[]) txt); + } + + void write(double num) + { + ubyte[40] buffer; + int len; + len = sprintf(cast(char*) buffer.ptr, "%2.8lf", num); + junit.add(buffer[0 .. len]); + } + + void write(uint num) + { + ubyte[20] buffer; + int len; + len = sprintf(cast(char*) buffer.ptr, "%u", num); + junit.add(buffer[0 .. len]); + } + + TestSuite[Args.length] suites; + uint passed = 0; + uint failed = 0; + uint skipped = 0; + + SimpleVector junit; +} + +version (notBetterC) +{ + extern (C) int rt_init(); + extern (C) int rt_term(); + version (D_Coverage) extern (C) void dmd_coverDestPath(string path); +} + +enum before = "_tr_before"; + +void extractStrings(ref Vector!string container, string str) +{ + uint s = 0; + foreach (j, char c; str) + { + if (c == ',') + { + if (s < j) + { + container.add(str[s .. j]); + } + s = cast(uint) j + 1; + } + } + if (s < str.length) + { + container.add(str[s .. $]); + } +} + +extern (C) int main(int argc, char** args) +{ + Vector!string include; + Vector!string exclude; + + version (notBetterC) + { + rt_init(); + version (D_Coverage) + dmd_coverDestPath("reports"); + } + + for (int i = 1; i < argc; i++) + { + string arg = cast(string) args[i][0 .. strlen(args[i])]; + if (arg.length < 2) + continue; + else if (arg == "-i") + { + if (i + 1 >= argc) + break; + i++; + arg = cast(string) args[i][0 .. strlen(args[i])]; + extractStrings(include, arg); + } + else if (arg == "-e") + { + if (i + 1 >= argc) + break; + i++; + arg = cast(string) args[i][0 .. strlen(args[i])]; + extractStrings(exclude, arg); + } + else if (arg.length < 10) + continue; + else if (arg[0 .. 10] == "--include=") + { + extractStrings(include, arg[10 .. $]); + } + else if (arg[0 .. 10] == "--exclude=") + { + extractStrings(exclude, arg[10 .. $]); + } + } + + static import tests.id_manager; + static import tests.vector; + static import tests.basic; + static import tests.perf; + static import tests.access_perf; + static import tests.bugs; + static import tests.map; + TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs, tests.map) runner; + + runner.runTests(include[], exclude[]); + + runner.writeFile(); + + runner.writeOutput(); + + version (notBetterC) + rt_term(); + + if (!runner.failed) + return 0; + else + return 1; +} + +version (D_BetterC) +{ + version(LDC) + { + extern (C) __gshared int _d_eh_personality(int, int, size_t, void*, void*) + { + return 0; + } + } +} \ No newline at end of file diff --git a/tests/tests.d b/tests/tests.d index 5fc09f9..164eb30 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -1,308 +1,853 @@ module tests.tests; +/* +import std.experimental.allocator; +import std.experimental.allocator.mallocator;*/ -import ecs.entity; -import ecs.events; -import ecs.manager; -import ecs.system; +import bubel.ecs.entity; +import bubel.ecs.events; +import bubel.ecs.manager; +import bubel.ecs.system; +import bubel.ecs.attributes; +import bubel.ecs.core; -import core.time; -import std.stdio; +version (WebAssembly) +{ + extern (C) int printf(scope const char* format, ...) @nogc nothrow @system; -int main() + alias int time_t; + alias int clockid_t; + enum CLOCK_REALTIME = 0; + + struct timespec + { + time_t tv_sec; + int tv_nsec; + } + + extern (C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; + + struct Time + { + + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000; + } + } + + extern (C) void _start() + { + } +} +else version (Windows) +{ + import core.stdc.stdio : printf; + import core.sys.windows.windows; + + struct Time + { + static long getUSecTime() + { + LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000); + } + } +} +else version (Posix) +{ + import core.stdc.stdio : printf; + import core.sys.posix.time; + + struct Time + { + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000; + } + } +} + +struct TestEvent +{ + mixin ECS.Event; //__gshared ushort event_id; + int a; +} + +struct TestEvent2 +{ + mixin ECS.Event; //__gshared ushort event_id; + float a; +} + +static struct CPosition +{ + mixin ECS.Component; + float x; + float y; +} + +static struct TestComp +{ + mixin ECS.Component; //__gshared becsID!ushort; + int a = 1; + ulong b = 2; + + static void serializeComponent(SerializeVector output) + { + + } + + static void deserializeComponent(ubyte[] data) + { + + } +} + +static struct TestComp2 +{ + mixin ECS.Component; //__gshared becsID!ushort; + int b = 3; + int a = 4; + + static void serializeComponent(ref TestComp comp, SerializeVector output) + { + + } + + static void deserializeComponent(ref TestComp comp, ubyte[] data) + { + + } +} + +static struct TestComp3 +{ + mixin ECS.Component; //__gshared becsID!ushort; + uint gg = 5; //good game + uint bg = 6; //bad game + + void serializeComponent(SerializeVector output) + { + + } + + void deserializeComponent(ubyte[] data) + { + + } +} + +static struct TestComp4 +{ + mixin ECS.Component; //__gshared becsID!ushort; + uint gg = 7; //good game + uint bg = 8; //bad game + ulong a = 9; + ulong b = 10; + ulong c = 11; + ulong g = 12; + + static void serializeComponent(ref TestComp comp, SerializeVector output) + { + + } + + static void deserializeComponent(ref TestComp comp, ubyte[] data) + { + + } +} + +static struct TestComp5 +{ + mixin ECS.Component; //__gshared becsID!ushort; + uint gg = 7; //good game + uint bg = 8; //bad game + ulong a = 9; + ulong b = 10; + ulong c = 11; + ulong g = 12; + + static void serializeComponent(ref TestComp comp, SerializeVector output) + { + + } + + static void deserializeComponent(ref TestComp comp, ubyte[] data) + { + + } +} + +struct EverySystem +{ + mixin ECS.System; + + struct EntitiesData + { + uint length; + Entity[] entity; + CPosition[] pos; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.pos[i].x++; + data.pos[i].y++; + } + } + + void iterate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.pos[i].x++; + data.pos[i].y++; + } + } + + void free(EntitiesData data) + { + foreach(i;0..data.length) + { + gEntityManager.removeEntity(data.entity[i].id); + } + } + + void addOne(EntitiesData data) + { + foreach(i;0..data.length) + { + gEntityManager.addComponents(data.entity[i].id, TestComp2()); + } + } +} + +struct ChangeTestSystem +{ + mixin ECS.System!16; //__gshared ushort system_id; + + void onCreate() + { + //writeln("On Change Test System create."); + printf("On Change Test System create.\n"); + } + + void onCreate(int i) + { + //writeln("On Change Test System create."); + printf("On Change Test System create.\n"); + } + + void onDestroy() + { + //writeln("On Change Test System destroy."); + printf("On Change Test System destroy.\n"); + } + + void onAddEntity(EntitiesData data) + { + //printf("Entity added! ID: "); + foreach (i; 0 .. data.length) + printf("Entity added! ID: %u\n", cast(uint) data.entites[i].id.id); + ////writeln("Entity added! ID: ", data.entites[i].id); + } + + void onRemoveEntity(EntitiesData data) + { + ////writeln("Entity removed! ID: ", data.entites[0].id); + printf("Entity removed! ID: %u\n", cast(uint) data.entites[0].id.id); + } + + void onChangeEntity(EntitiesData data) + { + ////writeln("Entity changed! ID: ", data.entites[0].id); + printf("Entity changed! ID: %u\n", cast(uint) data.entites[0].id.id); + } + + bool onBegin() + { + ////writeln("On Test System begin."); + return true; + } + + void onEnd() + { + ////writeln("On Test System end."); + } + + void initialize(ref Entity entity, ref TestComp comp) + { + + } + + static struct EntitiesData + { + size_t length; + const(Entity)[] entites; + TestComp4[] test4; + @optional TestComp5[] test5; + } + + void onUpdate(EntitiesData data) + { + foreach (i; 0 .. data.length) + { + + } + } +} + +struct TestSystem +{ + mixin ECS.System!16; //__gshared ushort system_id; + + void onCreate() + { + //writeln("On Test System create."); + printf("On Change Test System create.\n"); + } + + void onDestroy() + { + //writeln("On Test System destroy."); + printf("On Change Test System destroy.\n"); + } + + void onAddEntity(EntitiesData data) + { + //foreach(i;0..data.length) + ////writeln("Entity added ID: ",data.entites[i].id.id); + } + /* + void onRemoveEntity(EntitiesData data) + { + ////writeln("Entity destroyed ID: ",data.entites[0].id); + }*/ + + bool onBegin() + { + ////writeln("On Test System begin."); + return true; + } + + void onEnd() + { + ////writeln("On Test System end."); + } + + void initialize(ref Entity entity, ref TestComp comp) + { + + } + + static struct EntitiesData + { + size_t length; + const(Entity)[] entites; + TestComp[] test; + TestComp2[] test2; + @readonly @optional const(TestComp3)[] test3; + //@excluded TestComp4[] test4; + } + + void onUpdate(ref Entity entity, ref TestComp test, ref TestComp2 test2) //, TestComp3* test3) //ref TestComp comp) + { + //assert(cast(size_t)&test % TestComp.alignof == 0); + //assert(cast(size_t)&test2 % TestComp2.alignof == 0); + + test.a += 1000; + test.b += 2000; + test2.b += 2; + test2.a = 8; + } + + void onUpdate(EntitiesData data) + { + foreach (i; 0 .. data.length) + { + data.test[i].a += 1000; + data.test[i].b += 2000; + data.test2[i].b += 2; + data.test2[i].a = 8; + } + } + + void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) + { + + } +} + +struct TestSystemWithHighPriority +{ + mixin ECS.System!16; //__gshared ushort system_id; + + static struct EntitiesData + { + TestComp[] test; + } + + void initialize(ref Entity entity, ref TestComp comp) + { + int o = 1; + } + + void onUpdate(EntitiesData data) + { + + } +} + +struct Sys1 +{ + mixin ECS.System; + + struct EntitiesData + { + TestComp[] comp; + } + + void onAddEntity(EntitiesData data) + { + + } +} + +struct Sys2 +{ + mixin ECS.System; + + struct EntitiesData + { + TestComp[] comp; + } + + void onAddEntity(EntitiesData data) + { + + } +} + +struct Sys3 +{ + mixin ECS.System; + + struct EntitiesData + { + TestComp[] comp; + } + + void onAddEntity(EntitiesData data) + { + + } + + void onUpdate(EntitiesData data) + { + + } +} + +struct EmptyEventSystem +{ + mixin ECS.System; + + bool handled = false; + + struct EntitiesData + { + uint thread_id; + } + + void handleEvent(Entity* entity, TestEvent event) + { + if (!handled) + { + printf("EmptyEventSystem.handleEvent() called!\n"); + handled = true; + } + assert(0, "this shouldn't be called!"); + } +} + +struct EventSystem +{ + mixin ECS.System; + + bool handled = false; + + struct EntitiesData + { + uint thread_id; + TestComp[] comp; + } + + void handleEvent(Entity* entity, TestEvent event) + { + if (!handled) + { + printf("EventSystem.handleEvent() called!\n"); + handled = true; + } + } + + /*void onUpdate(EntitiesData) + { + + }*/ +} + +struct EmptySystem +{ + mixin ECS.System; + + struct EntitiesData + { + uint thread_id; + } + + void onUpdate(EntitiesData data) + { + printf("EmptySystem.onUpdate() - this should be called once per update\n"); + } +} + +import std.meta; + +struct TestSystem2 +{ + mixin ECS.System!16; //__gshared ushort system_id; + + /*enum ExcludedComponents + { + TestComp, + TestComp4 + }*/ + + //alias ExcludedComponents = AliasSeq!("TestComp", "TestComp4"); + /* + string ExcludedComponents2;*/ + + static struct EntitiesData + { + short length; + const(Entity)[] entity; + TestComp3[] test; + //@excluded TestComp[] testt; + } + + static struct EventInput + { + Entity* entity; + TestComp3* test; + //TestComp* tt; + } + + void handleEvent(Entity* entity, TestEvent event) + { + TestComp3* test = entity.getComponent!TestComp3; + test.bg = event.a; + TestEvent2 event2; + event2.a = event.a + 8; + gEntityManager.sendEvent(entity.id, event2); + } + + void handleEvent(Entity* entity, TestEvent2 event) + { + TestComp3* test = entity.getComponent!TestComp3; + test.gg = cast(uint) event.a; + } + + void onEnable() + { + + //writeln("TestSystem2 enabled"); + printf("TestSystem2 enabled\n"); + } + + void onDisable() + { + + //writeln("TestSystem2 disabled"); + printf("TestSystem2 disabled\n"); + } + + void initialize(ref Entity entity, ref TestComp comp) + { + + } + + void onUpdate(EntitiesData data) + { + foreach (i; 0 .. data.test.length) + { + data.test[i].gg += 14; + TestEvent event; + event.a = data.test[i].gg + 4; + gEntityManager.sendEvent(data.entity[i].id, event); //*/ + /*TestEvent2 event2; + event2.a = data.test[i].gg + 8; + gEntityManager.sendEvent(data.entity[i].id, event2);//*/ + //gEntityManager.sendEvent!(TestEvent)(data.entity[i].id, event); + //gEntityManager.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); + } + } + + void lateUpdate(ref EntitiesData data) + { + foreach (i; 0 .. data.test.length) + { + data.test[i].gg -= 1; + //gEntityManager.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); + } + } + +} + +struct ExternalUpdateCallTest +{ + int print_count = 3; + + void update(TestSystem2.EntitiesData data) + { + if (print_count > 0) + { + print_count--; + printf("ExternalUpdateCallTest %u %u\n", data.test[0].gg, cast(uint) data.length); + } + } +} + +version (unittest) +{ + void main() + { + + } +} +else: + extern (C) int main() { - struct TestEvent + void dispatch(EntityManager.JobGroup jobs) nothrow @nogc { - __gshared ushort event_id; - int a; - } - - struct TestEvent2 - { - __gshared ushort event_id; - float a; - } - - static struct TestComp - { - __gshared ushort component_id; - int a = 1; - ulong b = 2; - - static void serializeComponent(SerializeVector output) + foreach (job; jobs.jobs) { - - } - - static void deserializeComponent(ubyte[] data) - { - + ////writeln(job); + job.execute(); } } - static struct TestComp2 + uint getID() nothrow @nogc { - __gshared ushort component_id; - int b = 3; - int a = 4; - - static void serializeComponent(ref TestComp comp, SerializeVector output) - { - - } - - static void deserializeComponent(ref TestComp comp, ubyte[] data) - { - - } - } - - static struct TestComp3 - { - __gshared ushort component_id; - uint gg = 5; //good game - uint bg = 6; //bad game - - void serializeComponent(SerializeVector output) - { - - } - - void deserializeComponent(ubyte[] data) - { - - } - } - - static struct TestComp4 - { - __gshared ushort component_id; - uint gg = 7; //good game - uint bg = 8; //bad game - ulong a = 9; - ulong b = 10; - ulong c = 11; - ulong g = 12; - - static void serializeComponent(ref TestComp comp, SerializeVector output) - { - - } - - static void deserializeComponent(ref TestComp comp, ubyte[] data) - { - - } - } - - struct TestSystem - { - __gshared ushort system_id; - - void onCreate() - { - writeln("On Test System create."); - } - - void onDestroy() - { - writeln("On Test System destroy."); - } - - void onBegin() - { - //writeln("On Test System begin."); - } - - void onEnd() - { - //writeln("On Test System end."); - } - - void initialize(ref Entity entity, ref TestComp comp) - { - - } - - struct InputData - { - TestComp* test; - TestComp2* test2; - @("optional") TestComp3* test3; - } - - void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp) - { - assert(cast(size_t)&test % TestComp.alignof == 0); - assert(cast(size_t)&test2 % TestComp2.alignof == 0); - import std.stdio; - - //writeln("Jakis tekst! ",test.b); - test.a += 1000; - test.b += 2000; - //writeln("Jakis tekst! ",test.b); - test2.b += 2; - test2.a = 8; - //writeln("Jakis tekst! ",test2.b); - //writeln("Low priority tekst! "); - /*if (test3) - { - test3.gg = 200; - test3.bg += 1; - }*/ - - } - - void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) - { - - } - } - - struct TestSystemWithHighPriority - { - __gshared ushort system_id; - - void initialize(ref Entity entity, ref TestComp comp) - { - - } - - void update(ref Entity entity, ref TestComp test) //ref TestComp comp) - { - assert(cast(size_t)&test % TestComp.alignof == 0); - - //writeln("High priority tekst! "); - } - - /*void handleEvent(Event event, ref TestComp comp) - { - - }*/ - } - - struct TestSystem2 - { - __gshared ushort system_id; - - void onEnable() - { - import std.stdio; - - writeln("TestSystem2 enabled"); - } - - void onDisable() - { - import std.stdio; - - writeln("TestSystem2 disabled"); - } - - void initialize(ref Entity entity, ref TestComp comp) - { - - } - - void update(ref Entity entity, ref TestComp3 test) //ref TestComp comp) - { - //writeln("TestSystem2 update"); - test.gg += 14; - gEM.sendSelfEvent!(TestEvent)(entity.id, TestEvent()); - } - - /*void handleEvent(Event event, ref TestComp comp) - { - - }*/ + return 0; } void writeEntityComponents(Entity* entity) { - write(entity.id); + + printf("EntityID(%u, %u)", cast(uint) entity.id.id, cast(uint) entity.id.counter); + //write(entity.id); TestComp* test_comp = entity.getComponent!TestComp; - if(test_comp)write(*test_comp); + if (test_comp) + printf("TestComp(%u, %u)", cast(uint) test_comp.a, cast(uint) test_comp.b); //write(*test_comp); TestComp2* test_comp2 = entity.getComponent!TestComp2; - if(test_comp2)write(*test_comp2); + if (test_comp2) + printf("TestComp2(%u, %u)", cast(uint) test_comp2.b, cast(uint) test_comp2.a); //write(*test_comp2); TestComp3* test_comp3 = entity.getComponent!TestComp3; - if(test_comp3)write(*test_comp3); + if (test_comp3) + printf("TestComp3(%u, %u)", cast(uint) test_comp3.gg, cast(uint) test_comp3.bg); //write(*test_comp3); TestComp4* test_comp4 = entity.getComponent!TestComp4; - if(test_comp4)write(*test_comp4); - writeln(); - //writeln((cast(uint*) pp)[0 .. 14], " ", pp); + if (test_comp4) + printf("TestComp4(%u, %u, %u, %u, %u, %u)", test_comp4.gg, test_comp4.bg, + cast(uint) test_comp4.a, cast(uint) test_comp4.b, + cast(uint) test_comp4.c, cast(uint) test_comp4.g); //write(*test_comp4); + printf("\n"); + //writeln(); + ////writeln((cast(uint*) pp)[0 .. 14], " ", pp); } - EntityManager.initialize(); - assert(gEM !is null); + EntityManager.initialize(1); - MonoTime time = MonoTime.currTime; + //gEntityManager.setJobDispachFunc(&dispatch); + gEntityManager.setMultithreadingCallbacks(&dispatch, &getID); + //assert(gEntityManager !is null); - gEM.registerComponent!TestComp2; - gEM.registerComponent!TestComp4; - gEM.registerComponent!TestComp; - gEM.registerComponent!TestComp3; + gEntityManager.beginRegister(); + gEntityManager.registerPass("fixed"); - gEM.registerEvent!TestEvent; - gEM.registerEvent!TestEvent2; + //MonoTime time = MonoTime.currTime; + long time = Time.getUSecTime(); - ulong dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Components register: ", dur, " usecs"); + gEntityManager.registerComponent!TestComp2; + gEntityManager.registerComponent!TestComp4; + gEntityManager.registerComponent!TestComp; + gEntityManager.registerComponent!TestComp3; + gEntityManager.registerComponent!TestComp5; + gEntityManager.registerComponent!CPosition; - time = MonoTime.currTime; + gEntityManager.registerEvent!TestEvent; + gEntityManager.registerEvent!TestEvent2; - gEM.registerSystem!TestSystemWithHighPriority(100); - gEM.registerSystem!TestSystem(0); - //gEM.registerSystem!TestSystemWithHighPriority(100); - //gEM.registerSystem!TestSystem2(0); + /*ulong dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Components register: ", dur, " usecs"); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Systems register: ", dur, " usecs"); + time = MonoTime.currTime;*/ - time = MonoTime.currTime; + printf("Components register: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); - //ushort[3] ids = [TestComp2.component_id, TestComp.component_id, TestComp4.component_id]; - ushort[2] ids = [TestComp2.component_id, TestComp.component_id]; - EntityTemplate* tmpl = gEM.allocateTemplate(ids); + gEntityManager.registerSystem!TestSystemWithHighPriority(100, "fixed"); + gEntityManager.registerSystem!TestSystem(0); + gEntityManager.registerSystem!ChangeTestSystem(0); + gEntityManager.registerSystem!Sys1(10); + gEntityManager.registerSystem!Sys2(-100); + gEntityManager.registerSystem!Sys3(-2); + gEntityManager.registerSystem!EmptySystem(2); + gEntityManager.registerSystem!EmptyEventSystem(2); + gEntityManager.registerSystem!EventSystem(2); + gEntityManager.registerSystem!EverySystem(0); + //gEntityManager.registerSystem!TestSystemWithHighPriority(100); + //gEntityManager.registerSystem!TestSystem2(0); + gEntityManager.endRegister(); - //ushort[3] ids2 = [TestComp3.component_id, TestComp.component_id, TestComp4.component_id]; - ushort[2] ids2 = [TestComp3.component_id, TestComp.component_id]; - EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2); - //writeln(tmpl.info.components[]); + /*dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Systems register: ", dur, " usecs"); + + time = MonoTime.currTime;*/ + printf("Systems register: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); + + //ushort[3] ids = [becsID!TestComp2, becsID!TestComp, becsID!TestComp4]; + ushort[2] ids = [becsID!TestComp2, becsID!TestComp]; + EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids); + + //ushort[3] ids2 = [becsID!TestComp3, becsID!TestComp, becsID!TestComp4]; + ushort[2] ids2 = [becsID!TestComp3, becsID!TestComp]; + EntityTemplate* tmpl2 = gEntityManager.allocateTemplate(ids2); + ////writeln(tmpl.info.components[]); //*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Template allocating: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Template allocating: ", dur, " usecs"); + printf("Template allocating: %f usecs\n", cast(float)(Time.getUSecTime() - time)); - Entity entity; + + time = Time.getUSecTime(); + ushort[1] empty_ids = [becsID!CPosition]; + EntityTemplate* tmpl_empty = gEntityManager.allocateTemplate(empty_ids); + + gEntityManager.commit(); + + time = Time.getUSecTime(); + + foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty); + gEntityManager.commit(); + foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty); + gEntityManager.commit(); + foreach(i;0..2_000_000)gEntityManager.addEntity(tmpl_empty); + gEntityManager.commit(); + + printf("Adding 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEntityManager.commit(); + time = Time.getUSecTime(); + gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().iterate); + printf("Iterate 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEntityManager.begin(); + time = Time.getUSecTime(); + gEntityManager.update(); + printf("Iterate 1M entities (update): %f usecs\n", cast(float)(Time.getUSecTime() - time)); + gEntityManager.end(); + + time = Time.getUSecTime(); + gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().free); + gEntityManager.commit(); + printf("Deleting 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + time = Time.getUSecTime(); + + foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty); + gEntityManager.commit(); + foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty); + gEntityManager.commit(); + foreach(i;0..2_000_000)gEntityManager.addEntity(tmpl_empty); + gEntityManager.commit(); + + printf("Adding 1M entities (prealloc): %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEntityManager.commit(); + time = Time.getUSecTime(); + gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().addOne); + gEntityManager.commit(); + printf("Adding 1M component: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEntityManager.commit(); + gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().free); + gEntityManager.commit(); + + time = Time.getUSecTime(); + + EntityID entity; { - entity = gEM.addEntity(tmpl); - writeEntityComponents(gEM.getEntity(entity.id)); - } - - time = MonoTime.currTime; - - //foreach(i; 0..1_000_000)gEM.addEntity(tmpl); - - //foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id); - - EntityID[1000] idss; - - foreach (i; 0 .. 1_000) - { - gEM.begin(); - foreach (j; 0 .. 1_000) - idss[j] = gEM.addEntity(tmpl).id; - foreach (j; 0 .. 1_000) - gEM.removeEntity(idss[j]); - gEM.end(); + entity = gEntityManager.addEntity(tmpl).id; + writeEntityComponents(gEntityManager.getEntity(entity)); + EntityManager.EntitiesBlock* block = gEntityManager.getMetaData( + gEntityManager.getEntity(entity)); + EntityManager.EntityInfo* info = block.type_info; + //writeln(info.add_listeners); + //if(info)assert(0); } - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Entities adding: ", dur, " usecs"); + //time = MonoTime.currTime; + time = Time.getUSecTime(); + + //foreach(i; 0..1_000_000)gEntityManager.addEntity(tmpl); + + //foreach(i; 0..1_000_000)gEntityManager.removeEntity(gEntityManager.addEntity(tmpl).id); + + import bubel.ecs.std; + + EntityID[] idss = Mallocator.makeArray!EntityID(5000); //[5000] + //scope(exit)Mallocator.dispose(idss); + + foreach (i; 0 .. 200) + { + gEntityManager.begin(); + foreach (j; 0 .. 5_000) + idss[j] = gEntityManager.addEntity(tmpl).id; + foreach (j; 0 .. 5_000) + gEntityManager.removeEntity(idss[j]); + gEntityManager.end(); + } + gEntityManager.commit(); + + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Entities adding: ", dur, " usecs"); + printf("Entities adding: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); uint blocks = 0; - foreach (info; &gEM.entities_infos.byValue) + foreach (info; &gEntityManager.entities_infos.byValue) { EntityManager.EntitiesBlock* block = info.first_block; while (block !is null) @@ -311,84 +856,174 @@ int main() blocks++; } } - writeln("Entities blocks: ", blocks); + //writeln("Entities blocks: ", blocks); + printf("Entities blocks: %u\n", blocks); - //foreach(j; 0..1_000)gEM.addEntity(tmpl); + //foreach(j; 0..1_000)gEntityManager.addEntity(tmpl); - gEM.registerSystem!TestSystem2(0); + gEntityManager.beginRegister(); + gEntityManager.registerSystem!TestSystem2(0); + gEntityManager.endRegister(); + + //gEntityManager.generateDependencies(); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1)); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1)); + EntityID entity2; + + //time = MonoTime.currTime; + time = Time.getUSecTime(); + + EntityID[] entities = Mallocator.makeArray!EntityID(1_000_000); foreach (i; 0 .. 500_000) { - gEM.addEntity(tmpl); - gEM.addEntity(tmpl2); + entity2 = gEntityManager.addEntity(tmpl).id; + entities[i * 2] = entity2; + entities[i * 2 + 1] = gEntityManager.addEntity(tmpl2).id; } - time = MonoTime.currTime; + gEntityManager.commit(); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Entities adding2: ", dur, " usecs"); - gEM.begin(); - gEM.update(); - gEM.end(); + //time = MonoTime.currTime; + printf("Entities adding2: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); + foreach (i; 0 .. 1_000_000) + { + gEntityManager.addComponents(entities[i], TestComp5()); + if ((i & 0x00FFFF) == 0) + gEntityManager.commit(); + } - time = MonoTime.currTime; + gEntityManager.commit(); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Components adding: ", dur, " usecs"); - gEM.begin(); - gEM.update(); - gEM.end(); + //time = MonoTime.currTime; + printf("Components adding: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); + foreach (i; 0 .. 1_000_000) + { + gEntityManager.removeComponents!TestComp5(entities[i]); + //if((i & 0x00FFFF) == 0)gEntityManager.commit(); + } - time = MonoTime.currTime; + gEntityManager.commit(); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Components removing: ", dur, " usecs"); + printf("Components removing: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); - gEM.begin(); - gEM.update(); - gEM.end(); + Mallocator.dispose(entities); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); + //time = MonoTime.currTime; + time = Time.getUSecTime(); - writeEntityComponents(gEM.getEntity(entity.id)); + gEntityManager.begin(); + //gEntityManager.updateMT(); + gEntityManager.update(); + gEntityManager.end(); - entity = gEM.addEntity(tmpl); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Update: ", dur, " usecs"); + printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time)); - gEM.begin(); - gEM.update(); - gEM.end(); + writeEntityComponents(gEntityManager.getEntity(entity2)); - //Entity* pp;// = gEM.getEntity(entity.id); - //writeln((cast(uint*) pp)[0 .. 14], " ", pp); - writeEntityComponents(gEM.getEntity(entity.id)); + //time = MonoTime.currTime; + time = Time.getUSecTime(); - gEM.addEntity(tmpl); + gEntityManager.begin(); + gEntityManager.updateMT(); + //gEntityManager.update(); + gEntityManager.end(); - gEM.addComponents(entity.id, TestComp4()); - gEM.addComponents(entity.id, TestComp3()); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Update: ", dur, " usecs"); + printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time)); - gEM.begin(); - gEM.update(); - gEM.end(); + writeEntityComponents(gEntityManager.getEntity(entity2)); - writeEntityComponents(gEM.getEntity(entity.id)); + //time = MonoTime.currTime; + time = Time.getUSecTime(); - gEM.removeComponents!(TestComp)(entity.id); - gEM.addComponents(entity.id, TestComp()); + gEntityManager.begin(); + gEntityManager.updateMT(); + //gEntityManager.update(); + gEntityManager.end(); - gEM.begin(); - gEM.update(); - gEM.end(); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Update: ", dur, " usecs"); + printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time)); - writeEntityComponents(gEM.getEntity(entity.id)); + writeEntityComponents(gEntityManager.getEntity(entity2)); + entity = gEntityManager.addEntity(tmpl).id; + + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.end(); + + //Entity* pp;// = gEntityManager.getEntity(entity.id); + ////writeln((cast(uint*) pp)[0 .. 14], " ", pp); + writeEntityComponents(gEntityManager.getEntity(entity)); + + //writeln("Entity, its copy, and template, and default filled tempalte"); + gEntityManager.addEntity(tmpl); + writeEntityComponents(gEntityManager.getEntity(entity)); + writeEntityComponents(gEntityManager.addEntityCopy(entity)); + EntityTemplate* copy_tempalte = gEntityManager.allocateTemplate(entity); + writeEntityComponents(gEntityManager.addEntity(copy_tempalte)); + EntityTemplate* copy_default_tempalte = gEntityManager.allocateTemplate(entity, true); + writeEntityComponents(gEntityManager.addEntity(copy_default_tempalte)); + + gEntityManager.addComponents(entity, TestComp4()); + gEntityManager.addComponents(entity, TestComp3()); + + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.end(); + + writeEntityComponents(gEntityManager.getEntity(entity)); + + gEntityManager.removeComponents!(TestComp)(entity); + gEntityManager.addComponents(entity, TestComp()); + gEntityManager.addComponents(entity, TestComp5()); + + gEntityManager.begin(); + gEntityManager.update(); + gEntityManager.update("fixed"); + gEntityManager.end(); + + gEntityManager.removeComponents!(TestComp4)(entity); + + gEntityManager.commit(); + + System* sys = gEntityManager.getSystem(becsID!TestSystem2); + + ExternalUpdateCallTest external_update_test; + + gEntityManager.callEntitiesFunction!TestSystem2(&external_update_test.update); + + printf("pre end\n"); + + writeEntityComponents(gEntityManager.getEntity(entity)); //import std.stdio; - //writeln((cast(uint*)tmpl.info.first_block)[0..48]); - gEM.freeTemplate(tmpl); + ////writeln((cast(uint*)tmpl.info.first_block)[0..48]); + gEntityManager.freeTemplate(tmpl_empty); + gEntityManager.freeTemplate(tmpl); + gEntityManager.freeTemplate(tmpl2); + gEntityManager.freeTemplate(copy_tempalte); + gEntityManager.freeTemplate(copy_default_tempalte); EntityManager.destroy(); + Mallocator.dispose(idss); + + printf("end\n"); //*/ + return 0; -} \ No newline at end of file +} diff --git a/tests/time.d b/tests/time.d new file mode 100644 index 0000000..e91b76e --- /dev/null +++ b/tests/time.d @@ -0,0 +1,66 @@ +module tests.time; + + +version (WebAssembly) +{ + alias int time_t; + alias int clockid_t; + enum CLOCK_REALTIME = 0; + + struct timespec + { + time_t tv_sec; + int tv_nsec; + } + + extern (C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; + + struct Time + { + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000; + } + } +} +else version (Windows) +{ + import core.stdc.stdio : printf; + import core.sys.windows.windows; + + struct Time + { + static long getUSecTime() + { + LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000); + } + } +} +else version (Posix) +{ + import core.stdc.stdio : printf; + import core.sys.posix.time; + + struct Time + { + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000; + } + } +} \ No newline at end of file diff --git a/tests/vector.d b/tests/vector.d new file mode 100644 index 0000000..1756518 --- /dev/null +++ b/tests/vector.d @@ -0,0 +1,79 @@ +module tests.vector; + +import bubel.ecs.simple_vector; +import bubel.ecs.vector; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +@("simple-vector") +unittest +{ + SimpleVector vector; + vector.add(cast(ubyte[]) "a"); + vector.add(cast(ubyte[]) "bsdf"); + assert(vector[0 .. 5] == cast(ubyte[]) "absdf"); + assert(vector[4] == 'f'); + assert(vector[] == cast(ubyte[]) "absdf"); + assert(vector[$ - 1] == 'f'); + + vector.clear(); + assert(vector.length == 0); + + ubyte[1025] array; + foreach(i;0..cast(uint)array.length)array[i] = cast(ubyte)i; + vector.add(array); + assert(vector.length == 1025); + assert(vector[] == array[]); + + SimpleVector vector2; + vector2.clear(); + vector2.add(array[0..1023]); + vector2.add('a'); + vector2.add('b'); + assert(vector2.length == 1025); + assert(vector2[0..1023] == array[0..1023]); + assert(vector2[1023] == 'a'); + assert(vector2[1024] == 'b'); +} + +@("Vector") +unittest +{ + struct G + { + int a; + } + + Vector!G vector; + assert(vector.empty()); + vector.add(G(1)); + assert(!vector.empty()); + vector.clear(); + assert(vector.empty()); + vector.add(G(1)); + assert(!vector.empty()); + vector.reset(); + assert(vector.empty()); + + vector.add(G(1)); + vector.add([G(2),G(5)].staticArray); + assert(vector.length == 3); + assert(vector.capacity == 1); + + Vector!G vector2; + vector2.add([G(1),G(2),G(5)].staticArray); + assert(vector == vector2); + vector2.remove(1); + assert(vector != vector2); + assert(vector2.length == 2); + assert(vector2[1] == G(5)); + vector2.add(G(2),1); + assert(vector == vector2); +}