From 251b88bcb430ac0fa6c7cd6752f48f6e4cc835e0 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sat, 18 Nov 2023 15:11:00 +0100 Subject: [PATCH 001/278] Purego rlgl implemented --- raylib/raylib_purego.go | 2 + raylib/rlgl.go | 874 --------------------------------------- raylib/rlgl_cgo.go | 875 ++++++++++++++++++++++++++++++++++++++++ raylib/rlgl_purego.go | 787 ++++++++++++++++++++++++++++++++++++ 4 files changed, 1664 insertions(+), 874 deletions(-) create mode 100644 raylib/rlgl_cgo.go create mode 100644 raylib/rlgl_purego.go diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 3d5ef2a..ad307fe 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -512,6 +512,8 @@ var detachAudioMixedProcessor func(processor uintptr) func init() { raylibDll = loadLibrary() + initRlglPurego() + purego.RegisterLibFunc(&initWindow, raylibDll, "InitWindow") purego.RegisterLibFunc(&closeWindow, raylibDll, "CloseWindow") purego.RegisterLibFunc(&windowShouldClose, raylibDll, "WindowShouldClose") diff --git a/raylib/rlgl.go b/raylib/rlgl.go index 40366d9..2a25948 100644 --- a/raylib/rlgl.go +++ b/raylib/rlgl.go @@ -1,49 +1,5 @@ package rl -/* -#include "raylib.h" -#include "rlgl.h" -#include -*/ -import "C" -import ( - "unsafe" -) - -// SetMatrixProjection - Set a custom projection matrix (replaces internal projection matrix) -func SetMatrixProjection(proj Matrix) { - cproj := proj.cptr() - C.rlSetMatrixProjection(*cproj) -} - -// SetMatrixModelview - Set a custom modelview matrix (replaces internal modelview matrix) -func SetMatrixModelview(view Matrix) { - cview := view.cptr() - C.rlSetMatrixModelview(*cview) -} - -// BeginShaderMode - Begin custom shader drawing -func BeginShaderMode(shader Shader) { - cshader := shader.cptr() - C.BeginShaderMode(*cshader) -} - -// EndShaderMode - End custom shader drawing (use default shader) -func EndShaderMode() { - C.EndShaderMode() -} - -// BeginBlendMode - Begin blending mode (alpha, additive, multiplied) -func BeginBlendMode(mode BlendMode) { - cmode := (C.int)(mode) - C.BeginBlendMode(cmode) -} - -// EndBlendMode - End blending mode (reset to default: alpha blending) -func EndBlendMode() { - C.EndBlendMode() -} - const ( // Texture parameters (equivalent to OpenGL defines) TextureWrapS = 0x2802 // GL_TEXTURE_WRAP_S @@ -179,833 +135,3 @@ const ( ) type rlFramebufferAttachTextureType = int32 - -// MatrixMode - Choose the current matrix to be transformed -func MatrixMode(mode int32) { - cmode := C.int(mode) - C.rlMatrixMode(cmode) -} - -// PushMatrix - Push the current matrix to stack -func PushMatrix() { - C.rlPushMatrix() -} - -// PopMatrix - Pop lattest inserted matrix from stack -func PopMatrix() { - C.rlPopMatrix() -} - -// LoadIdentity - Reset current matrix to identity matrix -func LoadIdentity() { - C.rlLoadIdentity() -} - -// Translatef - Multiply the current matrix by a translation matrix -func Translatef(x float32, y float32, z float32) { - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - C.rlTranslatef(cx, cy, cz) -} - -// Rotatef - Multiply the current matrix by a rotation matrix -func Rotatef(angle float32, x float32, y float32, z float32) { - cangle := C.float(angle) - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - C.rlRotatef(cangle, cx, cy, cz) -} - -// Scalef - Multiply the current matrix by a scaling matrix -func Scalef(x float32, y float32, z float32) { - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - C.rlScalef(cx, cy, cz) -} - -// Frustum . -func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { - cleft := C.double(left) - cright := C.double(right) - cbottom := C.double(bottom) - ctop := C.double(top) - cznear := C.double(znear) - czfar := C.double(zfar) - C.rlFrustum(cleft, cright, cbottom, ctop, cznear, czfar) -} - -// Ortho . -func Ortho(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { - cleft := C.double(left) - cright := C.double(right) - cbottom := C.double(bottom) - ctop := C.double(top) - cznear := C.double(znear) - czfar := C.double(zfar) - C.rlOrtho(cleft, cright, cbottom, ctop, cznear, czfar) -} - -// Viewport - Set the viewport area -func Viewport(x int32, y int32, width int32, height int32) { - cx := C.int(x) - cy := C.int(y) - cwidth := C.int(width) - cheight := C.int(height) - C.rlViewport(cx, cy, cwidth, cheight) -} - -// Begin - Initialize drawing mode (how to organize vertex) -func Begin(mode int32) { - cmode := C.int(mode) - C.rlBegin(cmode) -} - -// End - Finish vertex providing -func End() { - C.rlEnd() -} - -// Vertex2i - Define one vertex (position) - 2 int -func Vertex2i(x int32, y int32) { - cx := C.int(x) - cy := C.int(y) - C.rlVertex2i(cx, cy) -} - -// Vertex2f - Define one vertex (position) - 2 float -func Vertex2f(x float32, y float32) { - cx := C.float(x) - cy := C.float(y) - C.rlVertex2f(cx, cy) -} - -// Vertex3f - Define one vertex (position) - 3 float -func Vertex3f(x float32, y float32, z float32) { - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - C.rlVertex3f(cx, cy, cz) -} - -// TexCoord2f - Define one vertex (texture coordinate) - 2 float -func TexCoord2f(x float32, y float32) { - cx := C.float(x) - cy := C.float(y) - C.rlTexCoord2f(cx, cy) -} - -// Normal3f - Define one vertex (normal) - 3 float -func Normal3f(x float32, y float32, z float32) { - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - C.rlNormal3f(cx, cy, cz) -} - -// Color4ub - Define one vertex (color) - 4 byte -func Color4ub(r uint8, g uint8, b uint8, a uint8) { - cr := C.uchar(r) - cg := C.uchar(g) - cb := C.uchar(b) - ca := C.uchar(a) - C.rlColor4ub(cr, cg, cb, ca) -} - -// Color3f - Define one vertex (color) - 3 float -func Color3f(x float32, y float32, z float32) { - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - C.rlColor3f(cx, cy, cz) -} - -// Color4f - Define one vertex (color) - 4 float -func Color4f(x float32, y float32, z float32, w float32) { - cx := C.float(x) - cy := C.float(y) - cz := C.float(z) - cw := C.float(w) - C.rlColor4f(cx, cy, cz, cw) -} - -// EnableVertexArray - Enable vertex array (VAO, if supported) -func EnableVertexArray(vaoId uint32) bool { - cvaoId := C.uint(vaoId) - return bool(C.rlEnableVertexArray(cvaoId)) -} - -// DisableVertexArray - Disable vertex array (VAO, if supported) -func DisableVertexArray() { - C.rlDisableVertexArray() -} - -// EnableVertexBuffer - Enable vertex buffer (VBO) -func EnableVertexBuffer(id uint32) { - cid := C.uint(id) - C.rlEnableVertexBuffer(cid) -} - -// DisableVertexBuffer - Disable vertex buffer (VBO) -func DisableVertexBuffer() { - C.rlDisableVertexBuffer() -} - -// EnableVertexBufferElement - Enable vertex buffer element (VBO element) -func EnableVertexBufferElement(id uint32) { - cid := C.uint(id) - C.rlEnableVertexBufferElement(cid) -} - -// DisableVertexBufferElement - Disable vertex buffer element (VBO element) -func DisableVertexBufferElement() { - C.rlDisableVertexBufferElement() -} - -// EnableVertexAttribute - Enable vertex attribute index -func EnableVertexAttribute(index uint32) { - cindex := C.uint(index) - C.rlEnableVertexAttribute(cindex) -} - -// DisableVertexAttribute - Disable vertex attribute index -func DisableVertexAttribute(index uint32) { - cindex := C.uint(index) - C.rlDisableVertexAttribute(cindex) -} - -// ActiveTextureSlot - Select and active a texture slot -func ActiveTextureSlot(slot int32) { - cslot := C.int(slot) - C.rlActiveTextureSlot(cslot) -} - -// EnableTexture - Enable texture -func EnableTexture(id uint32) { - cid := C.uint(id) - C.rlEnableTexture(cid) -} - -// DisableTexture - Disable texture -func DisableTexture() { - C.rlDisableTexture() -} - -// EnableTextureCubemap - Enable texture cubemap -func EnableTextureCubemap(id uint32) { - cid := C.uint(id) - C.rlEnableTextureCubemap(cid) -} - -// DisableTextureCubemap - Disable texture cubemap -func DisableTextureCubemap() { - C.rlDisableTextureCubemap() -} - -// TextureParameters - Set texture parameters (filter, wrap) -func TextureParameters(id uint32, param int32, value int32) { - cid := C.uint(id) - cparam := C.int(param) - cvalue := C.int(value) - C.rlTextureParameters(cid, cparam, cvalue) -} - -// CubemapParameters - Set cubemap parameters (filter, wrap) -func CubemapParameters(id uint32, param int32, value int32) { - cid := C.uint(id) - cparam := C.int(param) - cvalue := C.int(value) - C.rlCubemapParameters(cid, cparam, cvalue) -} - -// EnableShader - Enable shader program -func EnableShader(id uint32) { - cid := C.uint(id) - C.rlEnableShader(cid) -} - -// DisableShader - Disable shader program -func DisableShader() { - C.rlDisableShader() -} - -// EnableFramebuffer - Enable render texture (fbo) -func EnableFramebuffer(id uint32) { - cid := C.uint(id) - C.rlEnableFramebuffer(cid) -} - -// DisableFramebuffer - Disable render texture (fbo), return to default framebuffer -func DisableFramebuffer() { - C.rlDisableFramebuffer() -} - -// ActiveDrawBuffers - Activate multiple draw color buffers -func ActiveDrawBuffers(count int32) { - ccount := C.int(count) - C.rlActiveDrawBuffers(ccount) -} - -// EnableColorBlend - Enable color blending -func EnableColorBlend() { - C.rlEnableColorBlend() -} - -// DisableColorBlend - Disable color blending -func DisableColorBlend() { - C.rlDisableColorBlend() -} - -// EnableDepthTest - Enable depth test -func EnableDepthTest() { - C.rlEnableDepthTest() -} - -// DisableDepthTest - Disable depth test -func DisableDepthTest() { - C.rlDisableDepthTest() -} - -// EnableDepthMask - Enable depth write -func EnableDepthMask() { - C.rlEnableDepthMask() -} - -// DisableDepthMask - Disable depth write -func DisableDepthMask() { - C.rlDisableDepthMask() -} - -// EnableBackfaceCulling - Enable backface culling -func EnableBackfaceCulling() { - C.rlEnableBackfaceCulling() -} - -// DisableBackfaceCulling - Disable backface culling -func DisableBackfaceCulling() { - C.rlDisableBackfaceCulling() -} - -// SetCullFace - Set face culling mode -func SetCullFace(mode int32) { - cmode := C.int(mode) - C.rlSetCullFace(cmode) -} - -// EnableScissorTest - Enable scissor test -func EnableScissorTest() { - C.rlEnableScissorTest() -} - -// DisableScissorTest - Disable scissor test -func DisableScissorTest() { - C.rlDisableScissorTest() -} - -// Scissor - Scissor test -func Scissor(x int32, y int32, width int32, height int32) { - cx := C.int(x) - cy := C.int(y) - cwidth := C.int(width) - cheight := C.int(height) - C.rlScissor(cx, cy, cwidth, cheight) -} - -// EnableWireMode - Enable wire mode -func EnableWireMode() { - C.rlEnableWireMode() -} - -// EnablePointMode - Enable point mode -func EnablePointMode() { - C.rlEnablePointMode() -} - -// DisableWireMode - Disable wire mode -func DisableWireMode() { - C.rlDisableWireMode() -} - -// SetLineWidth - Set the line drawing width -func SetLineWidth(width float32) { - cwidth := C.float(width) - C.rlSetLineWidth(cwidth) -} - -// GetLineWidth - Get the line drawing width -func GetLineWidth() float32 { - return float32(C.rlGetLineWidth()) -} - -// EnableSmoothLines - Enable line aliasing -func EnableSmoothLines() { - C.rlEnableSmoothLines() -} - -// DisableSmoothLines - Disable line aliasing -func DisableSmoothLines() { - C.rlDisableSmoothLines() -} - -// EnableStereoRender - Enable stereo rendering -func EnableStereoRender() { - C.rlEnableStereoRender() -} - -// DisableStereoRender - Disable stereo rendering -func DisableStereoRender() { - C.rlDisableStereoRender() -} - -// IsStereoRenderEnabled - Check if stereo render is enabled -func IsStereoRenderEnabled() bool { - return bool(C.rlIsStereoRenderEnabled()) -} - -// ClearColor - Clear color buffer with color -func ClearColor(r uint8, g uint8, b uint8, a uint8) { - cr := C.uchar(r) - cg := C.uchar(g) - cb := C.uchar(b) - ca := C.uchar(a) - C.rlClearColor(cr, cg, cb, ca) -} - -// ClearScreenBuffers - Clear used screen buffers (color and depth) -func ClearScreenBuffers() { - C.rlClearScreenBuffers() -} - -// CheckErrors - Check and log OpenGL error codes -func CheckErrors() { - C.rlCheckErrors() -} - -// SetBlendMode - Set blending mode -func SetBlendMode(mode int32) { - cmode := C.int(mode) - C.rlSetBlendMode(cmode) -} - -// SetBlendFactors - Set blending mode factor and equation (using OpenGL factors) -func SetBlendFactors(glSrcFactor int32, glDstFactor int32, glEquation int32) { - cglSrcFactor := C.int(glSrcFactor) - cglDstFactor := C.int(glDstFactor) - cglEquation := C.int(glEquation) - C.rlSetBlendFactors(cglSrcFactor, cglDstFactor, cglEquation) -} - -// SetBlendFactorsSeparate - Set blending mode factors and equations separately (using OpenGL factors) -func SetBlendFactorsSeparate(glSrcRGB int32, glDstRGB int32, glSrcAlpha int32, glDstAlpha int32, glEqRGB int32, glEqAlpha int32) { - cglSrcRGB := C.int(glSrcRGB) - cglDstRGB := C.int(glDstRGB) - cglSrcAlpha := C.int(glSrcAlpha) - cglDstAlpha := C.int(glDstAlpha) - cglEqRGB := C.int(glEqRGB) - cglEqAlpha := C.int(glEqAlpha) - C.rlSetBlendFactorsSeparate(cglSrcRGB, cglDstRGB, cglSrcAlpha, cglDstAlpha, cglEqRGB, cglEqAlpha) -} - -// glInit - Initialize rlgl (buffers, shaders, textures, states) -func glInit(width int32, height int32) { - cwidth := C.int(width) - cheight := C.int(height) - C.rlglInit(cwidth, cheight) -} - -// glClose - De-inititialize rlgl (buffers, shaders, textures) -func glClose() { - C.rlglClose() -} - -// GetVersion - Get current OpenGL version -func GetVersion() int32 { - return int32(C.rlGetVersion()) -} - -// SetFramebufferWidth - Set current framebuffer width -func SetFramebufferWidth(width int32) { - cwidth := C.int(width) - C.rlSetFramebufferWidth(cwidth) -} - -// GetFramebufferWidth - Get default framebuffer width -func GetFramebufferWidth() int32 { - return int32(C.rlGetFramebufferWidth()) -} - -// SetFramebufferHeight - Set current framebuffer height -func SetFramebufferHeight(height int32) { - cheight := C.int(height) - C.rlSetFramebufferHeight(cheight) -} - -// GetFramebufferHeight - Get default framebuffer height -func GetFramebufferHeight() int32 { - return int32(C.rlGetFramebufferHeight()) -} - -// GetTextureIdDefault - Get default texture id -func GetTextureIdDefault() uint32 { - return uint32(C.rlGetTextureIdDefault()) -} - -// GetShaderIdDefault - Get default shader id -func GetShaderIdDefault() uint32 { - return uint32(C.rlGetShaderIdDefault()) -} - -// DrawRenderBatchActive - Update and draw internal render batch -func DrawRenderBatchActive() { - C.rlDrawRenderBatchActive() -} - -// CheckRenderBatchLimit - Check internal buffer overflow for a given number of vertex -func CheckRenderBatchLimit(vCount int32) bool { - cvCount := C.int(vCount) - return bool(C.rlCheckRenderBatchLimit(cvCount)) -} - -// SetTexture - Set current texture for render batch and check buffers limits -func SetTexture(id uint32) { - cid := C.uint(id) - C.rlSetTexture(cid) -} - -// LoadVertexArray - Load vertex array (vao) if supported -func LoadVertexArray() uint32 { - return uint32(C.rlLoadVertexArray()) -} - -// UnloadVertexBuffer . -func UnloadVertexBuffer(vboId uint32) { - cvboId := C.uint(vboId) - C.rlUnloadVertexBuffer(cvboId) -} - -// SetVertexAttributeDivisor . -func SetVertexAttributeDivisor(index uint32, divisor int32) { - cindex := C.uint(index) - cdivisor := C.int(divisor) - C.rlSetVertexAttributeDivisor(cindex, cdivisor) -} - -// LoadTextureDepth - Load depth texture/renderbuffer (to be attached to fbo) -func LoadTextureDepth(width, height int32, useRenderBuffer bool) { - cwidth := C.int(width) - cheight := C.int(height) - cuseRenderBuffer := C.bool(useRenderBuffer) - C.rlLoadTextureDepth(cwidth, cheight, cuseRenderBuffer) -} - -// LoadFramebuffer - Load an empty framebuffer -func LoadFramebuffer(width int32, height int32) uint32 { - cwidth := C.int(width) - cheight := C.int(height) - return uint32(C.rlLoadFramebuffer(cwidth, cheight)) -} - -// FramebufferAttach - Attach texture/renderbuffer to a framebuffer -func FramebufferAttach(fboId uint32, texId uint32, attachType int32, texType int32, mipLevel int32) { - cfboId := C.uint(fboId) - ctexId := C.uint(texId) - cattachType := C.int(attachType) - ctexType := C.int(texType) - cmipLevel := C.int(mipLevel) - C.rlFramebufferAttach(cfboId, ctexId, cattachType, ctexType, cmipLevel) -} - -// FramebufferComplete - Verify framebuffer is complete -func FramebufferComplete(id uint32) bool { - cid := C.uint(id) - return bool(C.rlFramebufferComplete(cid)) -} - -// UnloadFramebuffer - Delete framebuffer from GPU -func UnloadFramebuffer(id uint32) { - cid := C.uint(id) - C.rlUnloadFramebuffer(cid) -} - -// LoadShaderCode - Load shader from code strings -func LoadShaderCode(vsCode string, fsCode string) uint32 { - cvsCode := C.CString(vsCode) - defer C.free(unsafe.Pointer(cvsCode)) - cfsCode := C.CString(fsCode) - defer C.free(unsafe.Pointer(cfsCode)) - return uint32(C.rlLoadShaderCode(cvsCode, cfsCode)) -} - -// CompileShader - Compile custom shader and return shader id (type: VERTEX_SHADER, FRAGMENT_SHADER, COMPUTE_SHADER) -func CompileShader(shaderCode string, type_ int32) uint32 { - cshaderCode := C.CString(shaderCode) - defer C.free(unsafe.Pointer(cshaderCode)) - ctype_ := C.int(type_) - return uint32(C.rlCompileShader(cshaderCode, ctype_)) -} - -// LoadShaderProgram - Load custom shader program -func LoadShaderProgram(vShaderId uint32, fShaderId uint32) uint32 { - cvShaderId := C.uint(vShaderId) - cfShaderId := C.uint(fShaderId) - return uint32(C.rlLoadShaderProgram(cvShaderId, cfShaderId)) -} - -// UnloadShaderProgram - Unload shader program -func UnloadShaderProgram(id uint32) { - cid := C.uint(id) - C.rlUnloadShaderProgram(cid) -} - -// GetLocationUniform - Get shader location uniform -func GetLocationUniform(shaderId uint32, uniformName string) int32 { - cshaderId := C.uint(shaderId) - cuniformName := C.CString(uniformName) - defer C.free(unsafe.Pointer(cuniformName)) - return int32(C.rlGetLocationUniform(cshaderId, cuniformName)) -} - -// GetLocationAttrib - Get shader location attribute -func GetLocationAttrib(shaderId uint32, attribName string) int32 { - cshaderId := C.uint(shaderId) - cattribName := C.CString(attribName) - defer C.free(unsafe.Pointer(cattribName)) - return int32(C.rlGetLocationAttrib(cshaderId, cattribName)) -} - -// SetUniformSampler - Set shader value sampler -func SetUniformSampler(locIndex int32, textureId uint32) { - clocIndex := C.int(locIndex) - ctextureId := C.uint(textureId) - C.rlSetUniformSampler(clocIndex, ctextureId) -} - -// ComputeShaderDispatch - Dispatch compute shader (equivalent to *draw* for graphics pilepine) -func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { - cgroupX := C.uint(groupX) - cgroupY := C.uint(groupY) - cgroupZ := C.uint(groupZ) - C.rlComputeShaderDispatch(cgroupX, cgroupY, cgroupZ) -} - -// GetShaderBufferSize - Get SSBO buffer size -func GetShaderBufferSize(id uint32) uint32 { - cid := C.uint(id) - return uint32(C.rlGetShaderBufferSize(cid)) -} - -// BindImageTexture - Bind image texture -func BindImageTexture(id uint32, index uint32, format int32, readonly bool) { - cid := C.uint(id) - cindex := C.uint(index) - cformat := C.int(format) - creadonly := C.bool(readonly) - C.rlBindImageTexture(cid, cindex, cformat, creadonly) -} - -// GetMatrixModelview - Get internal modelview matrix -func GetMatrixModelview() Matrix { - cResult := C.rlGetMatrixModelview() - var goRes Matrix - goRes.M4 = float32(cResult.m4) - goRes.M2 = float32(cResult.m2) - goRes.M14 = float32(cResult.m14) - goRes.M3 = float32(cResult.m3) - goRes.M7 = float32(cResult.m7) - goRes.M12 = float32(cResult.m12) - goRes.M6 = float32(cResult.m6) - goRes.M15 = float32(cResult.m15) - goRes.M5 = float32(cResult.m5) - goRes.M9 = float32(cResult.m9) - goRes.M13 = float32(cResult.m13) - goRes.M10 = float32(cResult.m10) - goRes.M11 = float32(cResult.m11) - goRes.M0 = float32(cResult.m0) - goRes.M8 = float32(cResult.m8) - goRes.M1 = float32(cResult.m1) - return goRes -} - -// GetMatrixProjection - Get internal projection matrix -func GetMatrixProjection() Matrix { - cResult := C.rlGetMatrixProjection() - var goRes Matrix - goRes.M13 = float32(cResult.m13) - goRes.M10 = float32(cResult.m10) - goRes.M11 = float32(cResult.m11) - goRes.M15 = float32(cResult.m15) - goRes.M5 = float32(cResult.m5) - goRes.M9 = float32(cResult.m9) - goRes.M1 = float32(cResult.m1) - goRes.M0 = float32(cResult.m0) - goRes.M8 = float32(cResult.m8) - goRes.M14 = float32(cResult.m14) - goRes.M3 = float32(cResult.m3) - goRes.M7 = float32(cResult.m7) - goRes.M4 = float32(cResult.m4) - goRes.M2 = float32(cResult.m2) - goRes.M12 = float32(cResult.m12) - goRes.M6 = float32(cResult.m6) - return goRes -} - -// GetMatrixTransform - Get internal accumulated transform matrix -func GetMatrixTransform() Matrix { - cResult := C.rlGetMatrixTransform() - var goRes Matrix - goRes.M0 = float32(cResult.m0) - goRes.M8 = float32(cResult.m8) - goRes.M1 = float32(cResult.m1) - goRes.M7 = float32(cResult.m7) - goRes.M4 = float32(cResult.m4) - goRes.M2 = float32(cResult.m2) - goRes.M14 = float32(cResult.m14) - goRes.M3 = float32(cResult.m3) - goRes.M12 = float32(cResult.m12) - goRes.M6 = float32(cResult.m6) - goRes.M11 = float32(cResult.m11) - goRes.M15 = float32(cResult.m15) - goRes.M5 = float32(cResult.m5) - goRes.M9 = float32(cResult.m9) - goRes.M13 = float32(cResult.m13) - goRes.M10 = float32(cResult.m10) - return goRes -} - -// GetMatrixProjectionStereo - Get internal projection matrix for stereo render (selected eye) -func GetMatrixProjectionStereo(eye int32) Matrix { - ceye := C.int(eye) - cResult := C.rlGetMatrixProjectionStereo(ceye) - var goRes Matrix - goRes.M12 = float32(cResult.m12) - goRes.M6 = float32(cResult.m6) - goRes.M15 = float32(cResult.m15) - goRes.M5 = float32(cResult.m5) - goRes.M9 = float32(cResult.m9) - goRes.M13 = float32(cResult.m13) - goRes.M10 = float32(cResult.m10) - goRes.M11 = float32(cResult.m11) - goRes.M0 = float32(cResult.m0) - goRes.M8 = float32(cResult.m8) - goRes.M1 = float32(cResult.m1) - goRes.M4 = float32(cResult.m4) - goRes.M2 = float32(cResult.m2) - goRes.M14 = float32(cResult.m14) - goRes.M3 = float32(cResult.m3) - goRes.M7 = float32(cResult.m7) - return goRes -} - -// GetMatrixViewOffsetStereo - Get internal view offset matrix for stereo render (selected eye) -func GetMatrixViewOffsetStereo(eye int32) Matrix { - ceye := C.int(eye) - cResult := C.rlGetMatrixViewOffsetStereo(ceye) - var goRes Matrix - goRes.M0 = float32(cResult.m0) - goRes.M8 = float32(cResult.m8) - goRes.M1 = float32(cResult.m1) - goRes.M4 = float32(cResult.m4) - goRes.M2 = float32(cResult.m2) - goRes.M14 = float32(cResult.m14) - goRes.M3 = float32(cResult.m3) - goRes.M7 = float32(cResult.m7) - goRes.M12 = float32(cResult.m12) - goRes.M6 = float32(cResult.m6) - goRes.M5 = float32(cResult.m5) - goRes.M9 = float32(cResult.m9) - goRes.M13 = float32(cResult.m13) - goRes.M10 = float32(cResult.m10) - goRes.M11 = float32(cResult.m11) - goRes.M15 = float32(cResult.m15) - return goRes -} - -// SetMatrixProjectionStereo - Set eyes projection matrices for stereo rendering -func SetMatrixProjectionStereo(right Matrix, left Matrix) { - var cright C.struct_Matrix - cright.m12 = C.float(right.M12) - cright.m6 = C.float(right.M6) - cright.m5 = C.float(right.M5) - cright.m9 = C.float(right.M9) - cright.m13 = C.float(right.M13) - cright.m10 = C.float(right.M10) - cright.m11 = C.float(right.M11) - cright.m15 = C.float(right.M15) - cright.m0 = C.float(right.M0) - cright.m8 = C.float(right.M8) - cright.m1 = C.float(right.M1) - cright.m4 = C.float(right.M4) - cright.m2 = C.float(right.M2) - cright.m14 = C.float(right.M14) - cright.m3 = C.float(right.M3) - cright.m7 = C.float(right.M7) - var cleft C.struct_Matrix - cleft.m10 = C.float(left.M10) - cleft.m11 = C.float(left.M11) - cleft.m15 = C.float(left.M15) - cleft.m5 = C.float(left.M5) - cleft.m9 = C.float(left.M9) - cleft.m13 = C.float(left.M13) - cleft.m0 = C.float(left.M0) - cleft.m8 = C.float(left.M8) - cleft.m1 = C.float(left.M1) - cleft.m3 = C.float(left.M3) - cleft.m7 = C.float(left.M7) - cleft.m4 = C.float(left.M4) - cleft.m2 = C.float(left.M2) - cleft.m14 = C.float(left.M14) - cleft.m12 = C.float(left.M12) - cleft.m6 = C.float(left.M6) - C.rlSetMatrixProjectionStereo(cright, cleft) -} - -// SetMatrixViewOffsetStereo - Set eyes view offsets matrices for stereo rendering -func SetMatrixViewOffsetStereo(right Matrix, left Matrix) { - var cright C.struct_Matrix - cright.m12 = C.float(right.M12) - cright.m6 = C.float(right.M6) - cright.m5 = C.float(right.M5) - cright.m9 = C.float(right.M9) - cright.m13 = C.float(right.M13) - cright.m10 = C.float(right.M10) - cright.m11 = C.float(right.M11) - cright.m15 = C.float(right.M15) - cright.m0 = C.float(right.M0) - cright.m8 = C.float(right.M8) - cright.m1 = C.float(right.M1) - cright.m4 = C.float(right.M4) - cright.m2 = C.float(right.M2) - cright.m14 = C.float(right.M14) - cright.m3 = C.float(right.M3) - cright.m7 = C.float(right.M7) - var cleft C.struct_Matrix - cleft.m12 = C.float(left.M12) - cleft.m6 = C.float(left.M6) - cleft.m5 = C.float(left.M5) - cleft.m9 = C.float(left.M9) - cleft.m13 = C.float(left.M13) - cleft.m10 = C.float(left.M10) - cleft.m11 = C.float(left.M11) - cleft.m15 = C.float(left.M15) - cleft.m0 = C.float(left.M0) - cleft.m8 = C.float(left.M8) - cleft.m1 = C.float(left.M1) - cleft.m4 = C.float(left.M4) - cleft.m2 = C.float(left.M2) - cleft.m14 = C.float(left.M14) - cleft.m3 = C.float(left.M3) - cleft.m7 = C.float(left.M7) - C.rlSetMatrixViewOffsetStereo(cright, cleft) -} - -// LoadDrawCube - Load and draw a cube -func LoadDrawCube() { - C.rlLoadDrawCube() -} - -// LoadDrawQuad - Load and draw a quad -func LoadDrawQuad() { - C.rlLoadDrawQuad() -} diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go new file mode 100644 index 0000000..6efcadd --- /dev/null +++ b/raylib/rlgl_cgo.go @@ -0,0 +1,875 @@ +package rl + +/* +#include "raylib.h" +#include "rlgl.h" +#include +*/ +import "C" +import ( + "unsafe" +) + +// SetMatrixProjection - Set a custom projection matrix (replaces internal projection matrix) +func SetMatrixProjection(proj Matrix) { + cproj := proj.cptr() + C.rlSetMatrixProjection(*cproj) +} + +// SetMatrixModelview - Set a custom modelview matrix (replaces internal modelview matrix) +func SetMatrixModelview(view Matrix) { + cview := view.cptr() + C.rlSetMatrixModelview(*cview) +} + +// BeginShaderMode - Begin custom shader drawing +func BeginShaderMode(shader Shader) { + cshader := shader.cptr() + C.BeginShaderMode(*cshader) +} + +// EndShaderMode - End custom shader drawing (use default shader) +func EndShaderMode() { + C.EndShaderMode() +} + +// BeginBlendMode - Begin blending mode (alpha, additive, multiplied) +func BeginBlendMode(mode BlendMode) { + cmode := (C.int)(mode) + C.BeginBlendMode(cmode) +} + +// EndBlendMode - End blending mode (reset to default: alpha blending) +func EndBlendMode() { + C.EndBlendMode() +} + +// MatrixMode - Choose the current matrix to be transformed +func MatrixMode(mode int32) { + cmode := C.int(mode) + C.rlMatrixMode(cmode) +} + +// PushMatrix - Push the current matrix to stack +func PushMatrix() { + C.rlPushMatrix() +} + +// PopMatrix - Pop lattest inserted matrix from stack +func PopMatrix() { + C.rlPopMatrix() +} + +// LoadIdentity - Reset current matrix to identity matrix +func LoadIdentity() { + C.rlLoadIdentity() +} + +// Translatef - Multiply the current matrix by a translation matrix +func Translatef(x float32, y float32, z float32) { + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + C.rlTranslatef(cx, cy, cz) +} + +// Rotatef - Multiply the current matrix by a rotation matrix +func Rotatef(angle float32, x float32, y float32, z float32) { + cangle := C.float(angle) + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + C.rlRotatef(cangle, cx, cy, cz) +} + +// Scalef - Multiply the current matrix by a scaling matrix +func Scalef(x float32, y float32, z float32) { + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + C.rlScalef(cx, cy, cz) +} + +// Frustum . +func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { + cleft := C.double(left) + cright := C.double(right) + cbottom := C.double(bottom) + ctop := C.double(top) + cznear := C.double(znear) + czfar := C.double(zfar) + C.rlFrustum(cleft, cright, cbottom, ctop, cznear, czfar) +} + +// Ortho . +func Ortho(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { + cleft := C.double(left) + cright := C.double(right) + cbottom := C.double(bottom) + ctop := C.double(top) + cznear := C.double(znear) + czfar := C.double(zfar) + C.rlOrtho(cleft, cright, cbottom, ctop, cznear, czfar) +} + +// Viewport - Set the viewport area +func Viewport(x int32, y int32, width int32, height int32) { + cx := C.int(x) + cy := C.int(y) + cwidth := C.int(width) + cheight := C.int(height) + C.rlViewport(cx, cy, cwidth, cheight) +} + +// Begin - Initialize drawing mode (how to organize vertex) +func Begin(mode int32) { + cmode := C.int(mode) + C.rlBegin(cmode) +} + +// End - Finish vertex providing +func End() { + C.rlEnd() +} + +// Vertex2i - Define one vertex (position) - 2 int +func Vertex2i(x int32, y int32) { + cx := C.int(x) + cy := C.int(y) + C.rlVertex2i(cx, cy) +} + +// Vertex2f - Define one vertex (position) - 2 float +func Vertex2f(x float32, y float32) { + cx := C.float(x) + cy := C.float(y) + C.rlVertex2f(cx, cy) +} + +// Vertex3f - Define one vertex (position) - 3 float +func Vertex3f(x float32, y float32, z float32) { + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + C.rlVertex3f(cx, cy, cz) +} + +// TexCoord2f - Define one vertex (texture coordinate) - 2 float +func TexCoord2f(x float32, y float32) { + cx := C.float(x) + cy := C.float(y) + C.rlTexCoord2f(cx, cy) +} + +// Normal3f - Define one vertex (normal) - 3 float +func Normal3f(x float32, y float32, z float32) { + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + C.rlNormal3f(cx, cy, cz) +} + +// Color4ub - Define one vertex (color) - 4 byte +func Color4ub(r uint8, g uint8, b uint8, a uint8) { + cr := C.uchar(r) + cg := C.uchar(g) + cb := C.uchar(b) + ca := C.uchar(a) + C.rlColor4ub(cr, cg, cb, ca) +} + +// Color3f - Define one vertex (color) - 3 float +func Color3f(x float32, y float32, z float32) { + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + C.rlColor3f(cx, cy, cz) +} + +// Color4f - Define one vertex (color) - 4 float +func Color4f(x float32, y float32, z float32, w float32) { + cx := C.float(x) + cy := C.float(y) + cz := C.float(z) + cw := C.float(w) + C.rlColor4f(cx, cy, cz, cw) +} + +// EnableVertexArray - Enable vertex array (VAO, if supported) +func EnableVertexArray(vaoId uint32) bool { + cvaoId := C.uint(vaoId) + return bool(C.rlEnableVertexArray(cvaoId)) +} + +// DisableVertexArray - Disable vertex array (VAO, if supported) +func DisableVertexArray() { + C.rlDisableVertexArray() +} + +// EnableVertexBuffer - Enable vertex buffer (VBO) +func EnableVertexBuffer(id uint32) { + cid := C.uint(id) + C.rlEnableVertexBuffer(cid) +} + +// DisableVertexBuffer - Disable vertex buffer (VBO) +func DisableVertexBuffer() { + C.rlDisableVertexBuffer() +} + +// EnableVertexBufferElement - Enable vertex buffer element (VBO element) +func EnableVertexBufferElement(id uint32) { + cid := C.uint(id) + C.rlEnableVertexBufferElement(cid) +} + +// DisableVertexBufferElement - Disable vertex buffer element (VBO element) +func DisableVertexBufferElement() { + C.rlDisableVertexBufferElement() +} + +// EnableVertexAttribute - Enable vertex attribute index +func EnableVertexAttribute(index uint32) { + cindex := C.uint(index) + C.rlEnableVertexAttribute(cindex) +} + +// DisableVertexAttribute - Disable vertex attribute index +func DisableVertexAttribute(index uint32) { + cindex := C.uint(index) + C.rlDisableVertexAttribute(cindex) +} + +// ActiveTextureSlot - Select and active a texture slot +func ActiveTextureSlot(slot int32) { + cslot := C.int(slot) + C.rlActiveTextureSlot(cslot) +} + +// EnableTexture - Enable texture +func EnableTexture(id uint32) { + cid := C.uint(id) + C.rlEnableTexture(cid) +} + +// DisableTexture - Disable texture +func DisableTexture() { + C.rlDisableTexture() +} + +// EnableTextureCubemap - Enable texture cubemap +func EnableTextureCubemap(id uint32) { + cid := C.uint(id) + C.rlEnableTextureCubemap(cid) +} + +// DisableTextureCubemap - Disable texture cubemap +func DisableTextureCubemap() { + C.rlDisableTextureCubemap() +} + +// TextureParameters - Set texture parameters (filter, wrap) +func TextureParameters(id uint32, param int32, value int32) { + cid := C.uint(id) + cparam := C.int(param) + cvalue := C.int(value) + C.rlTextureParameters(cid, cparam, cvalue) +} + +// CubemapParameters - Set cubemap parameters (filter, wrap) +func CubemapParameters(id uint32, param int32, value int32) { + cid := C.uint(id) + cparam := C.int(param) + cvalue := C.int(value) + C.rlCubemapParameters(cid, cparam, cvalue) +} + +// EnableShader - Enable shader program +func EnableShader(id uint32) { + cid := C.uint(id) + C.rlEnableShader(cid) +} + +// DisableShader - Disable shader program +func DisableShader() { + C.rlDisableShader() +} + +// EnableFramebuffer - Enable render texture (fbo) +func EnableFramebuffer(id uint32) { + cid := C.uint(id) + C.rlEnableFramebuffer(cid) +} + +// DisableFramebuffer - Disable render texture (fbo), return to default framebuffer +func DisableFramebuffer() { + C.rlDisableFramebuffer() +} + +// ActiveDrawBuffers - Activate multiple draw color buffers +func ActiveDrawBuffers(count int32) { + ccount := C.int(count) + C.rlActiveDrawBuffers(ccount) +} + +// EnableColorBlend - Enable color blending +func EnableColorBlend() { + C.rlEnableColorBlend() +} + +// DisableColorBlend - Disable color blending +func DisableColorBlend() { + C.rlDisableColorBlend() +} + +// EnableDepthTest - Enable depth test +func EnableDepthTest() { + C.rlEnableDepthTest() +} + +// DisableDepthTest - Disable depth test +func DisableDepthTest() { + C.rlDisableDepthTest() +} + +// EnableDepthMask - Enable depth write +func EnableDepthMask() { + C.rlEnableDepthMask() +} + +// DisableDepthMask - Disable depth write +func DisableDepthMask() { + C.rlDisableDepthMask() +} + +// EnableBackfaceCulling - Enable backface culling +func EnableBackfaceCulling() { + C.rlEnableBackfaceCulling() +} + +// DisableBackfaceCulling - Disable backface culling +func DisableBackfaceCulling() { + C.rlDisableBackfaceCulling() +} + +// SetCullFace - Set face culling mode +func SetCullFace(mode int32) { + cmode := C.int(mode) + C.rlSetCullFace(cmode) +} + +// EnableScissorTest - Enable scissor test +func EnableScissorTest() { + C.rlEnableScissorTest() +} + +// DisableScissorTest - Disable scissor test +func DisableScissorTest() { + C.rlDisableScissorTest() +} + +// Scissor - Scissor test +func Scissor(x int32, y int32, width int32, height int32) { + cx := C.int(x) + cy := C.int(y) + cwidth := C.int(width) + cheight := C.int(height) + C.rlScissor(cx, cy, cwidth, cheight) +} + +// EnableWireMode - Enable wire mode +func EnableWireMode() { + C.rlEnableWireMode() +} + +// EnablePointMode - Enable point mode +func EnablePointMode() { + C.rlEnablePointMode() +} + +// DisableWireMode - Disable wire mode +func DisableWireMode() { + C.rlDisableWireMode() +} + +// SetLineWidth - Set the line drawing width +func SetLineWidth(width float32) { + cwidth := C.float(width) + C.rlSetLineWidth(cwidth) +} + +// GetLineWidth - Get the line drawing width +func GetLineWidth() float32 { + return float32(C.rlGetLineWidth()) +} + +// EnableSmoothLines - Enable line aliasing +func EnableSmoothLines() { + C.rlEnableSmoothLines() +} + +// DisableSmoothLines - Disable line aliasing +func DisableSmoothLines() { + C.rlDisableSmoothLines() +} + +// EnableStereoRender - Enable stereo rendering +func EnableStereoRender() { + C.rlEnableStereoRender() +} + +// DisableStereoRender - Disable stereo rendering +func DisableStereoRender() { + C.rlDisableStereoRender() +} + +// IsStereoRenderEnabled - Check if stereo render is enabled +func IsStereoRenderEnabled() bool { + return bool(C.rlIsStereoRenderEnabled()) +} + +// ClearColor - Clear color buffer with color +func ClearColor(r uint8, g uint8, b uint8, a uint8) { + cr := C.uchar(r) + cg := C.uchar(g) + cb := C.uchar(b) + ca := C.uchar(a) + C.rlClearColor(cr, cg, cb, ca) +} + +// ClearScreenBuffers - Clear used screen buffers (color and depth) +func ClearScreenBuffers() { + C.rlClearScreenBuffers() +} + +// CheckErrors - Check and log OpenGL error codes +func CheckErrors() { + C.rlCheckErrors() +} + +// SetBlendMode - Set blending mode +func SetBlendMode(mode int32) { + cmode := C.int(mode) + C.rlSetBlendMode(cmode) +} + +// SetBlendFactors - Set blending mode factor and equation (using OpenGL factors) +func SetBlendFactors(glSrcFactor int32, glDstFactor int32, glEquation int32) { + cglSrcFactor := C.int(glSrcFactor) + cglDstFactor := C.int(glDstFactor) + cglEquation := C.int(glEquation) + C.rlSetBlendFactors(cglSrcFactor, cglDstFactor, cglEquation) +} + +// SetBlendFactorsSeparate - Set blending mode factors and equations separately (using OpenGL factors) +func SetBlendFactorsSeparate(glSrcRGB int32, glDstRGB int32, glSrcAlpha int32, glDstAlpha int32, glEqRGB int32, glEqAlpha int32) { + cglSrcRGB := C.int(glSrcRGB) + cglDstRGB := C.int(glDstRGB) + cglSrcAlpha := C.int(glSrcAlpha) + cglDstAlpha := C.int(glDstAlpha) + cglEqRGB := C.int(glEqRGB) + cglEqAlpha := C.int(glEqAlpha) + C.rlSetBlendFactorsSeparate(cglSrcRGB, cglDstRGB, cglSrcAlpha, cglDstAlpha, cglEqRGB, cglEqAlpha) +} + +// glInit - Initialize rlgl (buffers, shaders, textures, states) +func glInit(width int32, height int32) { + cwidth := C.int(width) + cheight := C.int(height) + C.rlglInit(cwidth, cheight) +} + +// glClose - De-inititialize rlgl (buffers, shaders, textures) +func glClose() { + C.rlglClose() +} + +// GetVersion - Get current OpenGL version +func GetVersion() int32 { + return int32(C.rlGetVersion()) +} + +// SetFramebufferWidth - Set current framebuffer width +func SetFramebufferWidth(width int32) { + cwidth := C.int(width) + C.rlSetFramebufferWidth(cwidth) +} + +// GetFramebufferWidth - Get default framebuffer width +func GetFramebufferWidth() int32 { + return int32(C.rlGetFramebufferWidth()) +} + +// SetFramebufferHeight - Set current framebuffer height +func SetFramebufferHeight(height int32) { + cheight := C.int(height) + C.rlSetFramebufferHeight(cheight) +} + +// GetFramebufferHeight - Get default framebuffer height +func GetFramebufferHeight() int32 { + return int32(C.rlGetFramebufferHeight()) +} + +// GetTextureIdDefault - Get default texture id +func GetTextureIdDefault() uint32 { + return uint32(C.rlGetTextureIdDefault()) +} + +// GetShaderIdDefault - Get default shader id +func GetShaderIdDefault() uint32 { + return uint32(C.rlGetShaderIdDefault()) +} + +// DrawRenderBatchActive - Update and draw internal render batch +func DrawRenderBatchActive() { + C.rlDrawRenderBatchActive() +} + +// CheckRenderBatchLimit - Check internal buffer overflow for a given number of vertex +func CheckRenderBatchLimit(vCount int32) bool { + cvCount := C.int(vCount) + return bool(C.rlCheckRenderBatchLimit(cvCount)) +} + +// SetTexture - Set current texture for render batch and check buffers limits +func SetTexture(id uint32) { + cid := C.uint(id) + C.rlSetTexture(cid) +} + +// LoadVertexArray - Load vertex array (vao) if supported +func LoadVertexArray() uint32 { + return uint32(C.rlLoadVertexArray()) +} + +// UnloadVertexBuffer . +func UnloadVertexBuffer(vboId uint32) { + cvboId := C.uint(vboId) + C.rlUnloadVertexBuffer(cvboId) +} + +// SetVertexAttributeDivisor . +func SetVertexAttributeDivisor(index uint32, divisor int32) { + cindex := C.uint(index) + cdivisor := C.int(divisor) + C.rlSetVertexAttributeDivisor(cindex, cdivisor) +} + +// LoadTextureDepth - Load depth texture/renderbuffer (to be attached to fbo) +func LoadTextureDepth(width, height int32, useRenderBuffer bool) { + cwidth := C.int(width) + cheight := C.int(height) + cuseRenderBuffer := C.bool(useRenderBuffer) + C.rlLoadTextureDepth(cwidth, cheight, cuseRenderBuffer) +} + +// LoadFramebuffer - Load an empty framebuffer +func LoadFramebuffer(width int32, height int32) uint32 { + cwidth := C.int(width) + cheight := C.int(height) + return uint32(C.rlLoadFramebuffer(cwidth, cheight)) +} + +// FramebufferAttach - Attach texture/renderbuffer to a framebuffer +func FramebufferAttach(fboId uint32, texId uint32, attachType int32, texType int32, mipLevel int32) { + cfboId := C.uint(fboId) + ctexId := C.uint(texId) + cattachType := C.int(attachType) + ctexType := C.int(texType) + cmipLevel := C.int(mipLevel) + C.rlFramebufferAttach(cfboId, ctexId, cattachType, ctexType, cmipLevel) +} + +// FramebufferComplete - Verify framebuffer is complete +func FramebufferComplete(id uint32) bool { + cid := C.uint(id) + return bool(C.rlFramebufferComplete(cid)) +} + +// UnloadFramebuffer - Delete framebuffer from GPU +func UnloadFramebuffer(id uint32) { + cid := C.uint(id) + C.rlUnloadFramebuffer(cid) +} + +// LoadShaderCode - Load shader from code strings +func LoadShaderCode(vsCode string, fsCode string) uint32 { + cvsCode := C.CString(vsCode) + defer C.free(unsafe.Pointer(cvsCode)) + cfsCode := C.CString(fsCode) + defer C.free(unsafe.Pointer(cfsCode)) + return uint32(C.rlLoadShaderCode(cvsCode, cfsCode)) +} + +// CompileShader - Compile custom shader and return shader id (type: VERTEX_SHADER, FRAGMENT_SHADER, COMPUTE_SHADER) +func CompileShader(shaderCode string, type_ int32) uint32 { + cshaderCode := C.CString(shaderCode) + defer C.free(unsafe.Pointer(cshaderCode)) + ctype_ := C.int(type_) + return uint32(C.rlCompileShader(cshaderCode, ctype_)) +} + +// LoadShaderProgram - Load custom shader program +func LoadShaderProgram(vShaderId uint32, fShaderId uint32) uint32 { + cvShaderId := C.uint(vShaderId) + cfShaderId := C.uint(fShaderId) + return uint32(C.rlLoadShaderProgram(cvShaderId, cfShaderId)) +} + +// UnloadShaderProgram - Unload shader program +func UnloadShaderProgram(id uint32) { + cid := C.uint(id) + C.rlUnloadShaderProgram(cid) +} + +// GetLocationUniform - Get shader location uniform +func GetLocationUniform(shaderId uint32, uniformName string) int32 { + cshaderId := C.uint(shaderId) + cuniformName := C.CString(uniformName) + defer C.free(unsafe.Pointer(cuniformName)) + return int32(C.rlGetLocationUniform(cshaderId, cuniformName)) +} + +// GetLocationAttrib - Get shader location attribute +func GetLocationAttrib(shaderId uint32, attribName string) int32 { + cshaderId := C.uint(shaderId) + cattribName := C.CString(attribName) + defer C.free(unsafe.Pointer(cattribName)) + return int32(C.rlGetLocationAttrib(cshaderId, cattribName)) +} + +// SetUniformSampler - Set shader value sampler +func SetUniformSampler(locIndex int32, textureId uint32) { + clocIndex := C.int(locIndex) + ctextureId := C.uint(textureId) + C.rlSetUniformSampler(clocIndex, ctextureId) +} + +// ComputeShaderDispatch - Dispatch compute shader (equivalent to *draw* for graphics pilepine) +func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { + cgroupX := C.uint(groupX) + cgroupY := C.uint(groupY) + cgroupZ := C.uint(groupZ) + C.rlComputeShaderDispatch(cgroupX, cgroupY, cgroupZ) +} + +// GetShaderBufferSize - Get SSBO buffer size +func GetShaderBufferSize(id uint32) uint32 { + cid := C.uint(id) + return uint32(C.rlGetShaderBufferSize(cid)) +} + +// BindImageTexture - Bind image texture +func BindImageTexture(id uint32, index uint32, format int32, readonly bool) { + cid := C.uint(id) + cindex := C.uint(index) + cformat := C.int(format) + creadonly := C.bool(readonly) + C.rlBindImageTexture(cid, cindex, cformat, creadonly) +} + +// GetMatrixModelview - Get internal modelview matrix +func GetMatrixModelview() Matrix { + cResult := C.rlGetMatrixModelview() + var goRes Matrix + goRes.M4 = float32(cResult.m4) + goRes.M2 = float32(cResult.m2) + goRes.M14 = float32(cResult.m14) + goRes.M3 = float32(cResult.m3) + goRes.M7 = float32(cResult.m7) + goRes.M12 = float32(cResult.m12) + goRes.M6 = float32(cResult.m6) + goRes.M15 = float32(cResult.m15) + goRes.M5 = float32(cResult.m5) + goRes.M9 = float32(cResult.m9) + goRes.M13 = float32(cResult.m13) + goRes.M10 = float32(cResult.m10) + goRes.M11 = float32(cResult.m11) + goRes.M0 = float32(cResult.m0) + goRes.M8 = float32(cResult.m8) + goRes.M1 = float32(cResult.m1) + return goRes +} + +// GetMatrixProjection - Get internal projection matrix +func GetMatrixProjection() Matrix { + cResult := C.rlGetMatrixProjection() + var goRes Matrix + goRes.M13 = float32(cResult.m13) + goRes.M10 = float32(cResult.m10) + goRes.M11 = float32(cResult.m11) + goRes.M15 = float32(cResult.m15) + goRes.M5 = float32(cResult.m5) + goRes.M9 = float32(cResult.m9) + goRes.M1 = float32(cResult.m1) + goRes.M0 = float32(cResult.m0) + goRes.M8 = float32(cResult.m8) + goRes.M14 = float32(cResult.m14) + goRes.M3 = float32(cResult.m3) + goRes.M7 = float32(cResult.m7) + goRes.M4 = float32(cResult.m4) + goRes.M2 = float32(cResult.m2) + goRes.M12 = float32(cResult.m12) + goRes.M6 = float32(cResult.m6) + return goRes +} + +// GetMatrixTransform - Get internal accumulated transform matrix +func GetMatrixTransform() Matrix { + cResult := C.rlGetMatrixTransform() + var goRes Matrix + goRes.M0 = float32(cResult.m0) + goRes.M8 = float32(cResult.m8) + goRes.M1 = float32(cResult.m1) + goRes.M7 = float32(cResult.m7) + goRes.M4 = float32(cResult.m4) + goRes.M2 = float32(cResult.m2) + goRes.M14 = float32(cResult.m14) + goRes.M3 = float32(cResult.m3) + goRes.M12 = float32(cResult.m12) + goRes.M6 = float32(cResult.m6) + goRes.M11 = float32(cResult.m11) + goRes.M15 = float32(cResult.m15) + goRes.M5 = float32(cResult.m5) + goRes.M9 = float32(cResult.m9) + goRes.M13 = float32(cResult.m13) + goRes.M10 = float32(cResult.m10) + return goRes +} + +// GetMatrixProjectionStereo - Get internal projection matrix for stereo render (selected eye) +func GetMatrixProjectionStereo(eye int32) Matrix { + ceye := C.int(eye) + cResult := C.rlGetMatrixProjectionStereo(ceye) + var goRes Matrix + goRes.M12 = float32(cResult.m12) + goRes.M6 = float32(cResult.m6) + goRes.M15 = float32(cResult.m15) + goRes.M5 = float32(cResult.m5) + goRes.M9 = float32(cResult.m9) + goRes.M13 = float32(cResult.m13) + goRes.M10 = float32(cResult.m10) + goRes.M11 = float32(cResult.m11) + goRes.M0 = float32(cResult.m0) + goRes.M8 = float32(cResult.m8) + goRes.M1 = float32(cResult.m1) + goRes.M4 = float32(cResult.m4) + goRes.M2 = float32(cResult.m2) + goRes.M14 = float32(cResult.m14) + goRes.M3 = float32(cResult.m3) + goRes.M7 = float32(cResult.m7) + return goRes +} + +// GetMatrixViewOffsetStereo - Get internal view offset matrix for stereo render (selected eye) +func GetMatrixViewOffsetStereo(eye int32) Matrix { + ceye := C.int(eye) + cResult := C.rlGetMatrixViewOffsetStereo(ceye) + var goRes Matrix + goRes.M0 = float32(cResult.m0) + goRes.M8 = float32(cResult.m8) + goRes.M1 = float32(cResult.m1) + goRes.M4 = float32(cResult.m4) + goRes.M2 = float32(cResult.m2) + goRes.M14 = float32(cResult.m14) + goRes.M3 = float32(cResult.m3) + goRes.M7 = float32(cResult.m7) + goRes.M12 = float32(cResult.m12) + goRes.M6 = float32(cResult.m6) + goRes.M5 = float32(cResult.m5) + goRes.M9 = float32(cResult.m9) + goRes.M13 = float32(cResult.m13) + goRes.M10 = float32(cResult.m10) + goRes.M11 = float32(cResult.m11) + goRes.M15 = float32(cResult.m15) + return goRes +} + +// SetMatrixProjectionStereo - Set eyes projection matrices for stereo rendering +func SetMatrixProjectionStereo(right Matrix, left Matrix) { + var cright C.struct_Matrix + cright.m12 = C.float(right.M12) + cright.m6 = C.float(right.M6) + cright.m5 = C.float(right.M5) + cright.m9 = C.float(right.M9) + cright.m13 = C.float(right.M13) + cright.m10 = C.float(right.M10) + cright.m11 = C.float(right.M11) + cright.m15 = C.float(right.M15) + cright.m0 = C.float(right.M0) + cright.m8 = C.float(right.M8) + cright.m1 = C.float(right.M1) + cright.m4 = C.float(right.M4) + cright.m2 = C.float(right.M2) + cright.m14 = C.float(right.M14) + cright.m3 = C.float(right.M3) + cright.m7 = C.float(right.M7) + var cleft C.struct_Matrix + cleft.m10 = C.float(left.M10) + cleft.m11 = C.float(left.M11) + cleft.m15 = C.float(left.M15) + cleft.m5 = C.float(left.M5) + cleft.m9 = C.float(left.M9) + cleft.m13 = C.float(left.M13) + cleft.m0 = C.float(left.M0) + cleft.m8 = C.float(left.M8) + cleft.m1 = C.float(left.M1) + cleft.m3 = C.float(left.M3) + cleft.m7 = C.float(left.M7) + cleft.m4 = C.float(left.M4) + cleft.m2 = C.float(left.M2) + cleft.m14 = C.float(left.M14) + cleft.m12 = C.float(left.M12) + cleft.m6 = C.float(left.M6) + C.rlSetMatrixProjectionStereo(cright, cleft) +} + +// SetMatrixViewOffsetStereo - Set eyes view offsets matrices for stereo rendering +func SetMatrixViewOffsetStereo(right Matrix, left Matrix) { + var cright C.struct_Matrix + cright.m12 = C.float(right.M12) + cright.m6 = C.float(right.M6) + cright.m5 = C.float(right.M5) + cright.m9 = C.float(right.M9) + cright.m13 = C.float(right.M13) + cright.m10 = C.float(right.M10) + cright.m11 = C.float(right.M11) + cright.m15 = C.float(right.M15) + cright.m0 = C.float(right.M0) + cright.m8 = C.float(right.M8) + cright.m1 = C.float(right.M1) + cright.m4 = C.float(right.M4) + cright.m2 = C.float(right.M2) + cright.m14 = C.float(right.M14) + cright.m3 = C.float(right.M3) + cright.m7 = C.float(right.M7) + var cleft C.struct_Matrix + cleft.m12 = C.float(left.M12) + cleft.m6 = C.float(left.M6) + cleft.m5 = C.float(left.M5) + cleft.m9 = C.float(left.M9) + cleft.m13 = C.float(left.M13) + cleft.m10 = C.float(left.M10) + cleft.m11 = C.float(left.M11) + cleft.m15 = C.float(left.M15) + cleft.m0 = C.float(left.M0) + cleft.m8 = C.float(left.M8) + cleft.m1 = C.float(left.M1) + cleft.m4 = C.float(left.M4) + cleft.m2 = C.float(left.M2) + cleft.m14 = C.float(left.M14) + cleft.m3 = C.float(left.M3) + cleft.m7 = C.float(left.M7) + C.rlSetMatrixViewOffsetStereo(cright, cleft) +} + +// LoadDrawCube - Load and draw a cube +func LoadDrawCube() { + C.rlLoadDrawCube() +} + +// LoadDrawQuad - Load and draw a quad +func LoadDrawQuad() { + C.rlLoadDrawQuad() +} diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go new file mode 100644 index 0000000..0f1b885 --- /dev/null +++ b/raylib/rlgl_purego.go @@ -0,0 +1,787 @@ +//go:build !cgo && windows +// +build !cgo,windows + +package rl + +import ( + "unsafe" + + "github.com/ebitengine/purego" +) + +var rlMatrixMode func(mode int32) +var rlPushMatrix func() +var rlPopMatrix func() +var rlLoadIdentity func() +var rlTranslatef func(x float32, y float32, z float32) +var rlRotatef func(angle float32, x float32, y float32, z float32) +var rlScalef func(x float32, y float32, z float32) +var rlFrustum func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) +var rlOrtho func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) +var rlViewport func(x int32, y int32, width int32, height int32) +var rlBegin func(mode int32) +var rlEnd func() +var rlVertex2i func(x int32, y int32) +var rlVertex2f func(x float32, y float32) +var rlVertex3f func(x float32, y float32, z float32) +var rlTexCoord2f func(x float32, y float32) +var rlNormal3f func(x float32, y float32, z float32) +var rlColor4ub func(r byte, g byte, b byte, a byte) +var rlColor3f func(x float32, y float32, z float32) +var rlColor4f func(x float32, y float32, z float32, w float32) +var rlEnableVertexArray func(vaoId uint32) bool +var rlDisableVertexArray func() +var rlEnableVertexBuffer func(id uint32) +var rlDisableVertexBuffer func() +var rlEnableVertexBufferElement func(id uint32) +var rlDisableVertexBufferElement func() +var rlEnableVertexAttribute func(index uint32) +var rlDisableVertexAttribute func(index uint32) +var rlActiveTextureSlot func(slot int32) +var rlEnableTexture func(id uint32) +var rlDisableTexture func() +var rlEnableTextureCubemap func(id uint32) +var rlDisableTextureCubemap func() +var rlTextureParameters func(id uint32, param int32, value int32) +var rlCubemapParameters func(id uint32, param int32, value int32) +var rlEnableShader func(id uint32) +var rlDisableShader func() +var rlEnableFramebuffer func(id uint32) +var rlDisableFramebuffer func() +var rlActiveDrawBuffers func(count int32) +var rlEnableColorBlend func() +var rlDisableColorBlend func() +var rlEnableDepthTest func() +var rlDisableDepthTest func() +var rlEnableDepthMask func() +var rlDisableDepthMask func() +var rlEnableBackfaceCulling func() +var rlDisableBackfaceCulling func() +var rlSetCullFace func(mode int32) +var rlEnableScissorTest func() +var rlDisableScissorTest func() +var rlScissor func(x int32, y int32, width int32, height int32) +var rlEnableWireMode func() +var rlEnablePointMode func() +var rlDisableWireMode func() +var rlSetLineWidth func(width float32) +var rlGetLineWidth func() float32 +var rlEnableSmoothLines func() +var rlDisableSmoothLines func() +var rlEnableStereoRender func() +var rlDisableStereoRender func() +var rlIsStereoRenderEnabled func() bool +var rlClearColor func(r byte, g byte, b byte, a byte) +var rlClearScreenBuffers func() +var rlCheckErrors func() +var rlSetBlendMode func(mode int32) +var rlSetBlendFactors func(glSrcFactor int32, glDstFactor int32, glEquation int32) +var rlSetBlendFactorsSeparate func(glSrcRGB int32, glDstRGB int32, glSrcAlpha int32, glDstAlpha int32, glEqRGB int32, glEqAlpha int32) +var rlglInit func(width int32, height int32) +var rlglClose func() +var rlGetVersion func() int32 +var rlSetFramebufferWidth func(width int32) +var rlGetFramebufferWidth func() int32 +var rlSetFramebufferHeight func(height int32) +var rlGetFramebufferHeight func() int32 +var rlGetTextureIdDefault func() uint32 +var rlGetShaderIdDefault func() uint32 +var rlDrawRenderBatchActive func() +var rlCheckRenderBatchLimit func(vCount int32) bool +var rlSetTexture func(id uint32) +var rlLoadVertexArray func() uint32 +var rlUnloadVertexBuffer func(vboId uint32) +var rlSetVertexAttributeDivisor func(index uint32, divisor int32) +var rlLoadTextureDepth func(width int32, height int32, useRenderBuffer bool) uint32 +var rlLoadFramebuffer func(width int32, height int32) uint32 +var rlFramebufferAttach func(fboId uint32, texId uint32, attachType int32, texType int32, mipLevel int32) +var rlFramebufferComplete func(id uint32) bool +var rlUnloadFramebuffer func(id uint32) +var rlLoadShaderCode func(vsCode string, fsCode string) uint32 +var rlCompileShader func(shaderCode string, _type int32) uint32 +var rlLoadShaderProgram func(vShaderId uint32, fShaderId uint32) uint32 +var rlUnloadShaderProgram func(id uint32) +var rlGetLocationUniform func(shaderId uint32, uniformName string) int32 +var rlGetLocationAttrib func(shaderId uint32, attribName string) int32 +var rlSetUniformSampler func(locIndex int32, textureId uint32) +var rlComputeShaderDispatch func(groupX uint32, groupY uint32, groupZ uint32) +var rlGetShaderBufferSize func(id uint32) uint32 +var rlBindImageTexture func(id uint32, index uint32, format int32, readonly bool) +var rlGetMatrixModelview func(matrix uintptr) +var rlGetMatrixProjection func(matrix uintptr) +var rlGetMatrixTransform func(matrix uintptr) +var rlGetMatrixProjectionStereo func(matrix uintptr, eye int32) +var rlGetMatrixViewOffsetStereo func(matrix uintptr, eye int32) +var rlSetMatrixProjection func(proj uintptr) +var rlSetMatrixModelview func(view uintptr) +var rlSetMatrixProjectionStereo func(right uintptr, left uintptr) +var rlSetMatrixViewOffsetStereo func(right uintptr, left uintptr) +var rlLoadDrawCube func() +var rlLoadDrawQuad func() + +func initRlglPurego() { + purego.RegisterLibFunc(&rlMatrixMode, raylibDll, "rlMatrixMode") + purego.RegisterLibFunc(&rlPushMatrix, raylibDll, "rlPushMatrix") + purego.RegisterLibFunc(&rlPopMatrix, raylibDll, "rlPopMatrix") + purego.RegisterLibFunc(&rlLoadIdentity, raylibDll, "rlLoadIdentity") + purego.RegisterLibFunc(&rlTranslatef, raylibDll, "rlTranslatef") + purego.RegisterLibFunc(&rlRotatef, raylibDll, "rlRotatef") + purego.RegisterLibFunc(&rlScalef, raylibDll, "rlScalef") + purego.RegisterLibFunc(&rlFrustum, raylibDll, "rlFrustum") + purego.RegisterLibFunc(&rlOrtho, raylibDll, "rlOrtho") + purego.RegisterLibFunc(&rlViewport, raylibDll, "rlViewport") + purego.RegisterLibFunc(&rlBegin, raylibDll, "rlBegin") + purego.RegisterLibFunc(&rlEnd, raylibDll, "rlEnd") + purego.RegisterLibFunc(&rlVertex2i, raylibDll, "rlVertex2i") + purego.RegisterLibFunc(&rlVertex2f, raylibDll, "rlVertex2f") + purego.RegisterLibFunc(&rlVertex3f, raylibDll, "rlVertex3f") + purego.RegisterLibFunc(&rlTexCoord2f, raylibDll, "rlTexCoord2f") + purego.RegisterLibFunc(&rlNormal3f, raylibDll, "rlNormal3f") + purego.RegisterLibFunc(&rlColor4ub, raylibDll, "rlColor4ub") + purego.RegisterLibFunc(&rlColor3f, raylibDll, "rlColor3f") + purego.RegisterLibFunc(&rlColor4f, raylibDll, "rlColor4f") + purego.RegisterLibFunc(&rlEnableVertexArray, raylibDll, "rlEnableVertexArray") + purego.RegisterLibFunc(&rlDisableVertexArray, raylibDll, "rlDisableVertexArray") + purego.RegisterLibFunc(&rlEnableVertexBuffer, raylibDll, "rlEnableVertexBuffer") + purego.RegisterLibFunc(&rlDisableVertexBuffer, raylibDll, "rlDisableVertexBuffer") + purego.RegisterLibFunc(&rlEnableVertexBufferElement, raylibDll, "rlEnableVertexBufferElement") + purego.RegisterLibFunc(&rlDisableVertexBufferElement, raylibDll, "rlDisableVertexBufferElement") + purego.RegisterLibFunc(&rlEnableVertexAttribute, raylibDll, "rlEnableVertexAttribute") + purego.RegisterLibFunc(&rlDisableVertexAttribute, raylibDll, "rlDisableVertexAttribute") + purego.RegisterLibFunc(&rlActiveTextureSlot, raylibDll, "rlActiveTextureSlot") + purego.RegisterLibFunc(&rlEnableTexture, raylibDll, "rlEnableTexture") + purego.RegisterLibFunc(&rlDisableTexture, raylibDll, "rlDisableTexture") + purego.RegisterLibFunc(&rlEnableTextureCubemap, raylibDll, "rlEnableTextureCubemap") + purego.RegisterLibFunc(&rlDisableTextureCubemap, raylibDll, "rlDisableTextureCubemap") + purego.RegisterLibFunc(&rlTextureParameters, raylibDll, "rlTextureParameters") + purego.RegisterLibFunc(&rlCubemapParameters, raylibDll, "rlCubemapParameters") + purego.RegisterLibFunc(&rlEnableShader, raylibDll, "rlEnableShader") + purego.RegisterLibFunc(&rlDisableShader, raylibDll, "rlDisableShader") + purego.RegisterLibFunc(&rlEnableFramebuffer, raylibDll, "rlEnableFramebuffer") + purego.RegisterLibFunc(&rlDisableFramebuffer, raylibDll, "rlDisableFramebuffer") + purego.RegisterLibFunc(&rlActiveDrawBuffers, raylibDll, "rlActiveDrawBuffers") + purego.RegisterLibFunc(&rlEnableColorBlend, raylibDll, "rlEnableColorBlend") + purego.RegisterLibFunc(&rlDisableColorBlend, raylibDll, "rlDisableColorBlend") + purego.RegisterLibFunc(&rlEnableDepthTest, raylibDll, "rlEnableDepthTest") + purego.RegisterLibFunc(&rlDisableDepthTest, raylibDll, "rlDisableDepthTest") + purego.RegisterLibFunc(&rlEnableDepthMask, raylibDll, "rlEnableDepthMask") + purego.RegisterLibFunc(&rlDisableDepthMask, raylibDll, "rlDisableDepthMask") + purego.RegisterLibFunc(&rlEnableBackfaceCulling, raylibDll, "rlEnableBackfaceCulling") + purego.RegisterLibFunc(&rlDisableBackfaceCulling, raylibDll, "rlDisableBackfaceCulling") + purego.RegisterLibFunc(&rlSetCullFace, raylibDll, "rlSetCullFace") + purego.RegisterLibFunc(&rlEnableScissorTest, raylibDll, "rlEnableScissorTest") + purego.RegisterLibFunc(&rlDisableScissorTest, raylibDll, "rlDisableScissorTest") + purego.RegisterLibFunc(&rlScissor, raylibDll, "rlScissor") + purego.RegisterLibFunc(&rlEnableWireMode, raylibDll, "rlEnableWireMode") + purego.RegisterLibFunc(&rlEnablePointMode, raylibDll, "rlEnablePointMode") + purego.RegisterLibFunc(&rlDisableWireMode, raylibDll, "rlDisableWireMode") + purego.RegisterLibFunc(&rlSetLineWidth, raylibDll, "rlSetLineWidth") + purego.RegisterLibFunc(&rlGetLineWidth, raylibDll, "rlGetLineWidth") + purego.RegisterLibFunc(&rlEnableSmoothLines, raylibDll, "rlEnableSmoothLines") + purego.RegisterLibFunc(&rlDisableSmoothLines, raylibDll, "rlDisableSmoothLines") + purego.RegisterLibFunc(&rlEnableStereoRender, raylibDll, "rlEnableStereoRender") + purego.RegisterLibFunc(&rlDisableStereoRender, raylibDll, "rlDisableStereoRender") + purego.RegisterLibFunc(&rlIsStereoRenderEnabled, raylibDll, "rlIsStereoRenderEnabled") + purego.RegisterLibFunc(&rlClearColor, raylibDll, "rlClearColor") + purego.RegisterLibFunc(&rlClearScreenBuffers, raylibDll, "rlClearScreenBuffers") + purego.RegisterLibFunc(&rlCheckErrors, raylibDll, "rlCheckErrors") + purego.RegisterLibFunc(&rlSetBlendMode, raylibDll, "rlSetBlendMode") + purego.RegisterLibFunc(&rlSetBlendFactors, raylibDll, "rlSetBlendFactors") + purego.RegisterLibFunc(&rlSetBlendFactorsSeparate, raylibDll, "rlSetBlendFactorsSeparate") + purego.RegisterLibFunc(&rlglInit, raylibDll, "rlglInit") + purego.RegisterLibFunc(&rlglClose, raylibDll, "rlglClose") + purego.RegisterLibFunc(&rlGetVersion, raylibDll, "rlGetVersion") + purego.RegisterLibFunc(&rlSetFramebufferWidth, raylibDll, "rlSetFramebufferWidth") + purego.RegisterLibFunc(&rlGetFramebufferWidth, raylibDll, "rlGetFramebufferWidth") + purego.RegisterLibFunc(&rlSetFramebufferHeight, raylibDll, "rlSetFramebufferHeight") + purego.RegisterLibFunc(&rlGetFramebufferHeight, raylibDll, "rlGetFramebufferHeight") + purego.RegisterLibFunc(&rlGetTextureIdDefault, raylibDll, "rlGetTextureIdDefault") + purego.RegisterLibFunc(&rlGetShaderIdDefault, raylibDll, "rlGetShaderIdDefault") + purego.RegisterLibFunc(&rlDrawRenderBatchActive, raylibDll, "rlDrawRenderBatchActive") + purego.RegisterLibFunc(&rlCheckRenderBatchLimit, raylibDll, "rlCheckRenderBatchLimit") + purego.RegisterLibFunc(&rlSetTexture, raylibDll, "rlSetTexture") + purego.RegisterLibFunc(&rlLoadVertexArray, raylibDll, "rlLoadVertexArray") + purego.RegisterLibFunc(&rlUnloadVertexBuffer, raylibDll, "rlUnloadVertexBuffer") + purego.RegisterLibFunc(&rlSetVertexAttributeDivisor, raylibDll, "rlSetVertexAttributeDivisor") + purego.RegisterLibFunc(&rlLoadTextureDepth, raylibDll, "rlLoadTextureDepth") + purego.RegisterLibFunc(&rlLoadFramebuffer, raylibDll, "rlLoadFramebuffer") + purego.RegisterLibFunc(&rlFramebufferAttach, raylibDll, "rlFramebufferAttach") + purego.RegisterLibFunc(&rlFramebufferComplete, raylibDll, "rlFramebufferComplete") + purego.RegisterLibFunc(&rlUnloadFramebuffer, raylibDll, "rlUnloadFramebuffer") + purego.RegisterLibFunc(&rlLoadShaderCode, raylibDll, "rlLoadShaderCode") + purego.RegisterLibFunc(&rlCompileShader, raylibDll, "rlCompileShader") + purego.RegisterLibFunc(&rlLoadShaderProgram, raylibDll, "rlLoadShaderProgram") + purego.RegisterLibFunc(&rlUnloadShaderProgram, raylibDll, "rlUnloadShaderProgram") + purego.RegisterLibFunc(&rlGetLocationUniform, raylibDll, "rlGetLocationUniform") + purego.RegisterLibFunc(&rlGetLocationAttrib, raylibDll, "rlGetLocationAttrib") + purego.RegisterLibFunc(&rlSetUniformSampler, raylibDll, "rlSetUniformSampler") + purego.RegisterLibFunc(&rlComputeShaderDispatch, raylibDll, "rlComputeShaderDispatch") + purego.RegisterLibFunc(&rlGetShaderBufferSize, raylibDll, "rlGetShaderBufferSize") + purego.RegisterLibFunc(&rlBindImageTexture, raylibDll, "rlBindImageTexture") + purego.RegisterLibFunc(&rlGetMatrixModelview, raylibDll, "rlGetMatrixModelview") + purego.RegisterLibFunc(&rlGetMatrixProjection, raylibDll, "rlGetMatrixProjection") + purego.RegisterLibFunc(&rlGetMatrixTransform, raylibDll, "rlGetMatrixTransform") + purego.RegisterLibFunc(&rlGetMatrixProjectionStereo, raylibDll, "rlGetMatrixProjectionStereo") + purego.RegisterLibFunc(&rlGetMatrixViewOffsetStereo, raylibDll, "rlGetMatrixViewOffsetStereo") + purego.RegisterLibFunc(&rlSetMatrixProjection, raylibDll, "rlSetMatrixProjection") + purego.RegisterLibFunc(&rlSetMatrixModelview, raylibDll, "rlSetMatrixModelview") + purego.RegisterLibFunc(&rlSetMatrixProjectionStereo, raylibDll, "rlSetMatrixProjectionStereo") + purego.RegisterLibFunc(&rlSetMatrixViewOffsetStereo, raylibDll, "rlSetMatrixViewOffsetStereo") + purego.RegisterLibFunc(&rlLoadDrawCube, raylibDll, "rlLoadDrawCube") + purego.RegisterLibFunc(&rlLoadDrawQuad, raylibDll, "rlLoadDrawQuad") +} + +// SetMatrixProjection - Set a custom projection matrix (replaces internal projection matrix) +func SetMatrixProjection(proj Matrix) { + rlSetMatrixProjection(uintptr(unsafe.Pointer(&proj))) +} + +// SetMatrixModelview - Set a custom modelview matrix (replaces internal modelview matrix) +func SetMatrixModelview(view Matrix) { + rlSetMatrixModelview(uintptr(unsafe.Pointer(&view))) +} + +// MatrixMode - Choose the current matrix to be transformed +func MatrixMode(mode int32) { + rlMatrixMode(mode) +} + +// PushMatrix - Push the current matrix to stack +func PushMatrix() { + rlPushMatrix() +} + +// PopMatrix - Pop lattest inserted matrix from stack +func PopMatrix() { + rlPopMatrix() +} + +// LoadIdentity - Reset current matrix to identity matrix +func LoadIdentity() { + rlLoadIdentity() +} + +// Translatef - Multiply the current matrix by a translation matrix +func Translatef(x float32, y float32, z float32) { + rlTranslatef(x, y, z) +} + +// Rotatef - Multiply the current matrix by a rotation matrix +func Rotatef(angle float32, x float32, y float32, z float32) { + rlRotatef(angle, x, y, z) +} + +// Scalef - Multiply the current matrix by a scaling matrix +func Scalef(x float32, y float32, z float32) { + rlScalef(x, y, z) +} + +// Frustum . +func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { + rlFrustum(left, right, bottom, top, znear, zfar) +} + +// Ortho . +func Ortho(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { + rlOrtho(left, right, bottom, top, znear, zfar) +} + +// Viewport - Set the viewport area +func Viewport(x int32, y int32, width int32, height int32) { + rlViewport(x, y, width, height) +} + +// Begin - Initialize drawing mode (how to organize vertex) +func Begin(mode int32) { + rlBegin(mode) +} + +// End - Finish vertex providing +func End() { + rlEnd() +} + +// Vertex2i - Define one vertex (position) - 2 int +func Vertex2i(x int32, y int32) { + rlVertex2i(x, y) +} + +// Vertex2f - Define one vertex (position) - 2 float +func Vertex2f(x float32, y float32) { + rlVertex2f(x, y) +} + +// Vertex3f - Define one vertex (position) - 3 float +func Vertex3f(x float32, y float32, z float32) { + rlVertex3f(x, y, z) +} + +// TexCoord2f - Define one vertex (texture coordinate) - 2 float +func TexCoord2f(x float32, y float32) { + rlTexCoord2f(x, y) +} + +// Normal3f - Define one vertex (normal) - 3 float +func Normal3f(x float32, y float32, z float32) { + rlNormal3f(x, y, z) +} + +// Color4ub - Define one vertex (color) - 4 byte +func Color4ub(r uint8, g uint8, b uint8, a uint8) { + rlColor4ub(r, g, b, a) +} + +// Color3f - Define one vertex (color) - 3 float +func Color3f(x float32, y float32, z float32) { + rlColor3f(x, y, z) +} + +// Color4f - Define one vertex (color) - 4 float +func Color4f(x float32, y float32, z float32, w float32) { + rlColor4f(x, y, z, w) +} + +// EnableVertexArray - Enable vertex array (VAO, if supported) +func EnableVertexArray(vaoId uint32) bool { + return rlEnableVertexArray(vaoId) +} + +// DisableVertexArray - Disable vertex array (VAO, if supported) +func DisableVertexArray() { + rlDisableVertexArray() +} + +// EnableVertexBuffer - Enable vertex buffer (VBO) +func EnableVertexBuffer(id uint32) { + rlEnableVertexBuffer(id) +} + +// DisableVertexBuffer - Disable vertex buffer (VBO) +func DisableVertexBuffer() { + rlDisableVertexBuffer() +} + +// EnableVertexBufferElement - Enable vertex buffer element (VBO element) +func EnableVertexBufferElement(id uint32) { + rlEnableVertexBufferElement(id) +} + +// DisableVertexBufferElement - Disable vertex buffer element (VBO element) +func DisableVertexBufferElement() { + rlDisableVertexBufferElement() +} + +// EnableVertexAttribute - Enable vertex attribute index +func EnableVertexAttribute(index uint32) { + rlEnableVertexAttribute(index) +} + +// DisableVertexAttribute - Disable vertex attribute index +func DisableVertexAttribute(index uint32) { + rlDisableVertexAttribute(index) +} + +// ActiveTextureSlot - Select and active a texture slot +func ActiveTextureSlot(slot int32) { + rlActiveTextureSlot(slot) +} + +// EnableTexture - Enable texture +func EnableTexture(id uint32) { + rlEnableTexture(id) +} + +// DisableTexture - Disable texture +func DisableTexture() { + rlDisableTexture() +} + +// EnableTextureCubemap - Enable texture cubemap +func EnableTextureCubemap(id uint32) { + rlEnableTextureCubemap(id) +} + +// DisableTextureCubemap - Disable texture cubemap +func DisableTextureCubemap() { + rlDisableTextureCubemap() +} + +// TextureParameters - Set texture parameters (filter, wrap) +func TextureParameters(id uint32, param int32, value int32) { + rlTextureParameters(id, param, value) +} + +// CubemapParameters - Set cubemap parameters (filter, wrap) +func CubemapParameters(id uint32, param int32, value int32) { + rlCubemapParameters(id, param, value) +} + +// EnableShader - Enable shader program +func EnableShader(id uint32) { + rlEnableShader(id) +} + +// DisableShader - Disable shader program +func DisableShader() { + rlDisableShader() +} + +// EnableFramebuffer - Enable render texture (fbo) +func EnableFramebuffer(id uint32) { + rlEnableFramebuffer(id) +} + +// DisableFramebuffer - Disable render texture (fbo), return to default framebuffer +func DisableFramebuffer() { + rlDisableFramebuffer() +} + +// ActiveDrawBuffers - Activate multiple draw color buffers +func ActiveDrawBuffers(count int32) { + rlActiveDrawBuffers(count) +} + +// EnableColorBlend - Enable color blending +func EnableColorBlend() { + rlEnableColorBlend() +} + +// DisableColorBlend - Disable color blending +func DisableColorBlend() { + rlDisableColorBlend() +} + +// EnableDepthTest - Enable depth test +func EnableDepthTest() { + rlEnableDepthTest() +} + +// DisableDepthTest - Disable depth test +func DisableDepthTest() { + rlDisableDepthTest() +} + +// EnableDepthMask - Enable depth write +func EnableDepthMask() { + rlEnableDepthMask() +} + +// DisableDepthMask - Disable depth write +func DisableDepthMask() { + rlDisableDepthMask() +} + +// EnableBackfaceCulling - Enable backface culling +func EnableBackfaceCulling() { + rlEnableBackfaceCulling() +} + +// DisableBackfaceCulling - Disable backface culling +func DisableBackfaceCulling() { + rlDisableBackfaceCulling() +} + +// SetCullFace - Set face culling mode +func SetCullFace(mode int32) { + rlSetCullFace(mode) +} + +// EnableScissorTest - Enable scissor test +func EnableScissorTest() { + rlEnableScissorTest() +} + +// DisableScissorTest - Disable scissor test +func DisableScissorTest() { + rlDisableScissorTest() +} + +// Scissor - Scissor test +func Scissor(x int32, y int32, width int32, height int32) { + rlScissor(x, y, width, height) +} + +// EnableWireMode - Enable wire mode +func EnableWireMode() { + rlEnableWireMode() +} + +// EnablePointMode - Enable point mode +func EnablePointMode() { + rlEnablePointMode() +} + +// DisableWireMode - Disable wire mode +func DisableWireMode() { + rlDisableWireMode() +} + +// SetLineWidth - Set the line drawing width +func SetLineWidth(width float32) { + rlSetLineWidth(width) +} + +// GetLineWidth - Get the line drawing width +func GetLineWidth() float32 { + return rlGetLineWidth() +} + +// EnableSmoothLines - Enable line aliasing +func EnableSmoothLines() { + rlEnableSmoothLines() +} + +// DisableSmoothLines - Disable line aliasing +func DisableSmoothLines() { + rlDisableSmoothLines() +} + +// EnableStereoRender - Enable stereo rendering +func EnableStereoRender() { + rlEnableStereoRender() +} + +// DisableStereoRender - Disable stereo rendering +func DisableStereoRender() { + rlDisableStereoRender() +} + +// IsStereoRenderEnabled - Check if stereo render is enabled +func IsStereoRenderEnabled() bool { + return rlIsStereoRenderEnabled() +} + +// ClearColor - Clear color buffer with color +func ClearColor(r uint8, g uint8, b uint8, a uint8) { + rlClearColor(r, g, b, a) +} + +// ClearScreenBuffers - Clear used screen buffers (color and depth) +func ClearScreenBuffers() { + rlClearScreenBuffers() +} + +// CheckErrors - Check and log OpenGL error codes +func CheckErrors() { + rlCheckErrors() +} + +// SetBlendMode - Set blending mode +func SetBlendMode(mode int32) { + rlSetBlendMode(mode) +} + +// SetBlendFactors - Set blending mode factor and equation (using OpenGL factors) +func SetBlendFactors(glSrcFactor int32, glDstFactor int32, glEquation int32) { + rlSetBlendFactors(glSrcFactor, glDstFactor, glEquation) +} + +// SetBlendFactorsSeparate - Set blending mode factors and equations separately (using OpenGL factors) +func SetBlendFactorsSeparate(glSrcRGB int32, glDstRGB int32, glSrcAlpha int32, glDstAlpha int32, glEqRGB int32, glEqAlpha int32) { + rlSetBlendFactorsSeparate(glSrcRGB, glDstRGB, glSrcAlpha, glDstAlpha, glEqRGB, glEqAlpha) +} + +// glInit - Initialize rlgl (buffers, shaders, textures, states) +func glInit(width int32, height int32) { + rlglInit(width, height) +} + +// glClose - De-inititialize rlgl (buffers, shaders, textures) +func glClose() { + rlglClose() +} + +// GetVersion - Get current OpenGL version +func GetVersion() int32 { + return rlGetVersion() +} + +// SetFramebufferWidth - Set current framebuffer width +func SetFramebufferWidth(width int32) { + rlSetFramebufferWidth(width) +} + +// GetFramebufferWidth - Get default framebuffer width +func GetFramebufferWidth() int32 { + return rlGetFramebufferWidth() +} + +// SetFramebufferHeight - Set current framebuffer height +func SetFramebufferHeight(height int32) { + rlSetFramebufferHeight(height) +} + +// GetFramebufferHeight - Get default framebuffer height +func GetFramebufferHeight() int32 { + return rlGetFramebufferHeight() +} + +// GetTextureIdDefault - Get default texture id +func GetTextureIdDefault() uint32 { + return rlGetTextureIdDefault() +} + +// GetShaderIdDefault - Get default shader id +func GetShaderIdDefault() uint32 { + return rlGetShaderIdDefault() +} + +// DrawRenderBatchActive - Update and draw internal render batch +func DrawRenderBatchActive() { + rlDrawRenderBatchActive() +} + +// CheckRenderBatchLimit - Check internal buffer overflow for a given number of vertex +func CheckRenderBatchLimit(vCount int32) bool { + return rlCheckRenderBatchLimit(vCount) +} + +// SetTexture - Set current texture for render batch and check buffers limits +func SetTexture(id uint32) { + rlSetTexture(id) +} + +// LoadVertexArray - Load vertex array (vao) if supported +func LoadVertexArray() uint32 { + return rlLoadVertexArray() +} + +// UnloadVertexBuffer . +func UnloadVertexBuffer(vboId uint32) { + rlUnloadVertexBuffer(vboId) +} + +// SetVertexAttributeDivisor . +func SetVertexAttributeDivisor(index uint32, divisor int32) { + rlSetVertexAttributeDivisor(index, divisor) +} + +// LoadTextureDepth - Load depth texture/renderbuffer (to be attached to fbo) +func LoadTextureDepth(width, height int32, useRenderBuffer bool) { + rlLoadTextureDepth(width, height, useRenderBuffer) +} + +// LoadFramebuffer - Load an empty framebuffer +func LoadFramebuffer(width int32, height int32) uint32 { + return rlLoadFramebuffer(width, height) +} + +// FramebufferAttach - Attach texture/renderbuffer to a framebuffer +func FramebufferAttach(fboId uint32, texId uint32, attachType int32, texType int32, mipLevel int32) { + rlFramebufferAttach(fboId, texId, attachType, texType, mipLevel) +} + +// FramebufferComplete - Verify framebuffer is complete +func FramebufferComplete(id uint32) bool { + return rlFramebufferComplete(id) +} + +// UnloadFramebuffer - Delete framebuffer from GPU +func UnloadFramebuffer(id uint32) { + rlUnloadFramebuffer(id) +} + +// LoadShaderCode - Load shader from code strings +func LoadShaderCode(vsCode string, fsCode string) uint32 { + return rlLoadShaderCode(vsCode, fsCode) +} + +// CompileShader - Compile custom shader and return shader id (type: VERTEX_SHADER, FRAGMENT_SHADER, COMPUTE_SHADER) +func CompileShader(shaderCode string, type_ int32) uint32 { + return rlCompileShader(shaderCode, type_) +} + +// LoadShaderProgram - Load custom shader program +func LoadShaderProgram(vShaderId uint32, fShaderId uint32) uint32 { + return rlLoadShaderProgram(vShaderId, fShaderId) +} + +// UnloadShaderProgram - Unload shader program +func UnloadShaderProgram(id uint32) { + rlUnloadShaderProgram(id) +} + +// GetLocationUniform - Get shader location uniform +func GetLocationUniform(shaderId uint32, uniformName string) int32 { + return rlGetLocationUniform(shaderId, uniformName) +} + +// GetLocationAttrib - Get shader location attribute +func GetLocationAttrib(shaderId uint32, attribName string) int32 { + return rlGetLocationAttrib(shaderId, attribName) +} + +// SetUniformSampler - Set shader value sampler +func SetUniformSampler(locIndex int32, textureId uint32) { + rlSetUniformSampler(locIndex, textureId) +} + +// ComputeShaderDispatch - Dispatch compute shader (equivalent to *draw* for graphics pilepine) +func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { + rlComputeShaderDispatch(groupX, groupY, groupZ) +} + +// GetShaderBufferSize - Get SSBO buffer size +func GetShaderBufferSize(id uint32) uint32 { + return rlGetShaderBufferSize(id) +} + +// BindImageTexture - Bind image texture +func BindImageTexture(id uint32, index uint32, format int32, readonly bool) { + rlBindImageTexture(id, index, format, readonly) +} + +// GetMatrixModelview - Get internal modelview matrix +func GetMatrixModelview() Matrix { + var matrix Matrix + rlGetMatrixModelview(uintptr(unsafe.Pointer(&matrix))) + return matrix +} + +// GetMatrixProjection - Get internal projection matrix +func GetMatrixProjection() Matrix { + var matrix Matrix + rlGetMatrixProjection(uintptr(unsafe.Pointer(&matrix))) + return matrix +} + +// GetMatrixTransform - Get internal accumulated transform matrix +func GetMatrixTransform() Matrix { + var matrix Matrix + rlGetMatrixTransform(uintptr(unsafe.Pointer(&matrix))) + return matrix +} + +// GetMatrixProjectionStereo - Get internal projection matrix for stereo render (selected eye) +func GetMatrixProjectionStereo(eye int32) Matrix { + var matrix Matrix + rlGetMatrixProjectionStereo(uintptr(unsafe.Pointer(&matrix)), eye) + return matrix +} + +// GetMatrixViewOffsetStereo - Get internal view offset matrix for stereo render (selected eye) +func GetMatrixViewOffsetStereo(eye int32) Matrix { + var matrix Matrix + rlGetMatrixViewOffsetStereo(uintptr(unsafe.Pointer(&matrix)), eye) + return matrix +} + +// SetMatrixProjectionStereo - Set eyes projection matrices for stereo rendering +func SetMatrixProjectionStereo(right Matrix, left Matrix) { + rlSetMatrixProjectionStereo(uintptr(unsafe.Pointer(&right)), uintptr(unsafe.Pointer(&left))) +} + +// SetMatrixViewOffsetStereo - Set eyes view offsets matrices for stereo rendering +func SetMatrixViewOffsetStereo(right Matrix, left Matrix) { + rlSetMatrixViewOffsetStereo(uintptr(unsafe.Pointer(&right)), uintptr(unsafe.Pointer(&left))) +} + +// LoadDrawCube - Load and draw a cube +func LoadDrawCube() { + rlLoadDrawCube() +} + +// LoadDrawQuad - Load and draw a quad +func LoadDrawQuad() { + rlLoadDrawQuad() +} From 79286ba625b53f958b4fb7d76ddcc564d0ddfc6a Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:27:35 +0100 Subject: [PATCH 002/278] Make rlgl types public and add missung functions --- raylib/rlgl.go | 58 +++++++++++++++++++++++-------------------- raylib/rlgl_cgo.go | 29 +++++++++++++++++++--- raylib/rlgl_purego.go | 38 +++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 35 deletions(-) diff --git a/raylib/rlgl.go b/raylib/rlgl.go index 2a25948..1b639a4 100644 --- a/raylib/rlgl.go +++ b/raylib/rlgl.go @@ -52,36 +52,36 @@ const ( ComputeShader = 0x91B9 // GL_COMPUTE_SHADER ) -// rlVertexBuffer - Dynamic vertex buffers (position + texcoords + colors + indices arrays) -type rlVertexBuffer struct { - elementCount int32 - vertices []float32 - texcoords []float32 - colors []uint8 - indices []uint32 - vaoId uint32 - vboId [4]uint32 +// VertexBuffer - Dynamic vertex buffers (position + texcoords + colors + indices arrays) +type VertexBuffer struct { + ElementCount int32 + Vertices *float32 + Texcoords *float32 + Colors *uint8 + Indices *uint32 + VaoId uint32 + VboId [4]uint32 } -// rlDrawCall - Draw call type +// DrawCall - Draw call type // NOTE: Only texture changes register a new draw, other state-change-related elements are not // used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any // of those state-change happens (this is done in core module) -type rlDrawCall struct { - mode int32 - vertexCount int32 - vertexAlignment int32 - textureId uint32 +type DrawCall struct { + Mode int32 + VertexCount int32 + VertexAlignment int32 + TextureId uint32 } -// rlRenderBatch type -type rlRenderBatch struct { - bufferCount int32 - currentBuffer int32 - vertexBuffer []rlVertexBuffer - draws []rlDrawCall - drawCounter int32 - currentDepth float32 +// RenderBatch type +type RenderBatch struct { + BufferCount int32 + CurrentBuffer int32 + VertexBuffer *VertexBuffer + Draws *DrawCall + DrawCounter int32 + DurrentDepth float32 } // OpenGL version @@ -93,7 +93,8 @@ const ( OpenglEs20 int32 = 5 ) -type rlGlVersion = int32 +// GlVersion type +type GlVersion = int32 // Shader attribute data types const ( @@ -103,7 +104,8 @@ const ( ShaderAttribVec4 int32 = 3 ) -type rlShaderAttributeDataType = int32 +// ShaderAttributeDataType type +type ShaderAttributeDataType = int32 // Framebuffer attachment type // NOTE: By default up to 8 color channels defined but it can be more @@ -120,7 +122,8 @@ const ( AttachmentStencil int32 = 200 ) -type rlFramebufferAttachType = int32 +// FramebufferAttachType type +type FramebufferAttachType = int32 // Framebuffer texture attachment type const ( @@ -134,4 +137,5 @@ const ( AttachmentRenderbuffer int32 = 200 ) -type rlFramebufferAttachTextureType = int32 +// FramebufferAttachTextureType type +type FramebufferAttachTextureType = int32 diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index 6efcadd..defc8ef 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -472,15 +472,15 @@ func SetBlendFactorsSeparate(glSrcRGB int32, glDstRGB int32, glSrcAlpha int32, g C.rlSetBlendFactorsSeparate(cglSrcRGB, cglDstRGB, cglSrcAlpha, cglDstAlpha, cglEqRGB, cglEqAlpha) } -// glInit - Initialize rlgl (buffers, shaders, textures, states) -func glInit(width int32, height int32) { +// GlInit - Initialize rlgl (buffers, shaders, textures, states) +func GlInit(width int32, height int32) { cwidth := C.int(width) cheight := C.int(height) C.rlglInit(cwidth, cheight) } -// glClose - De-inititialize rlgl (buffers, shaders, textures) -func glClose() { +// GlClose - De-inititialize rlgl (buffers, shaders, textures) +func GlClose() { C.rlglClose() } @@ -521,6 +521,27 @@ func GetShaderIdDefault() uint32 { return uint32(C.rlGetShaderIdDefault()) } +// LoadRenderBatch - Load a render batch system +func LoadRenderBatch(numBuffers int32, bufferElements int32) RenderBatch { + ret := C.rlLoadRenderBatch(C.int(numBuffers), C.int(bufferElements)) + return *(*RenderBatch)(unsafe.Pointer(&ret)) +} + +// UnloadRenderBatch - Unload render batch system +func UnloadRenderBatch(batch RenderBatch) { + C.rlUnloadRenderBatch(*(*C.rlRenderBatch)(unsafe.Pointer(&batch))) +} + +// DrawRenderBatch - Draw render batch data (Update->Draw->Reset) +func DrawRenderBatch(batch *RenderBatch) { + C.rlDrawRenderBatch((*C.rlRenderBatch)(unsafe.Pointer(batch))) +} + +// SetRenderBatchActive - Set the active render batch for rlgl (NULL for default internal) +func SetRenderBatchActive(batch *RenderBatch) { + C.rlSetRenderBatchActive((*C.rlRenderBatch)(unsafe.Pointer(batch))) +} + // DrawRenderBatchActive - Update and draw internal render batch func DrawRenderBatchActive() { C.rlDrawRenderBatchActive() diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index 0f1b885..d79c1d3 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -86,6 +86,10 @@ var rlSetFramebufferHeight func(height int32) var rlGetFramebufferHeight func() int32 var rlGetTextureIdDefault func() uint32 var rlGetShaderIdDefault func() uint32 +var rlLoadRenderBatch func(batch uintptr, numBuffers int32, bufferElements int32) +var rlUnloadRenderBatch func(batch uintptr) +var rlDrawRenderBatch func(batch *RenderBatch) +var rlSetRenderBatchActive func(batch *RenderBatch) var rlDrawRenderBatchActive func() var rlCheckRenderBatchLimit func(vCount int32) bool var rlSetTexture func(id uint32) @@ -197,6 +201,10 @@ func initRlglPurego() { purego.RegisterLibFunc(&rlGetFramebufferHeight, raylibDll, "rlGetFramebufferHeight") purego.RegisterLibFunc(&rlGetTextureIdDefault, raylibDll, "rlGetTextureIdDefault") purego.RegisterLibFunc(&rlGetShaderIdDefault, raylibDll, "rlGetShaderIdDefault") + purego.RegisterLibFunc(&rlLoadRenderBatch, raylibDll, "rlLoadRenderBatch") + purego.RegisterLibFunc(&rlUnloadRenderBatch, raylibDll, "rlUnloadRenderBatch") + purego.RegisterLibFunc(&rlDrawRenderBatch, raylibDll, "rlDrawRenderBatch") + purego.RegisterLibFunc(&rlSetRenderBatchActive, raylibDll, "rlSetRenderBatchActive") purego.RegisterLibFunc(&rlDrawRenderBatchActive, raylibDll, "rlDrawRenderBatchActive") purego.RegisterLibFunc(&rlCheckRenderBatchLimit, raylibDll, "rlCheckRenderBatchLimit") purego.RegisterLibFunc(&rlSetTexture, raylibDll, "rlSetTexture") @@ -581,13 +589,13 @@ func SetBlendFactorsSeparate(glSrcRGB int32, glDstRGB int32, glSrcAlpha int32, g rlSetBlendFactorsSeparate(glSrcRGB, glDstRGB, glSrcAlpha, glDstAlpha, glEqRGB, glEqAlpha) } -// glInit - Initialize rlgl (buffers, shaders, textures, states) -func glInit(width int32, height int32) { +// GlInit - Initialize rlgl (buffers, shaders, textures, states) +func GlInit(width int32, height int32) { rlglInit(width, height) } -// glClose - De-inititialize rlgl (buffers, shaders, textures) -func glClose() { +// GlClose - De-inititialize rlgl (buffers, shaders, textures) +func GlClose() { rlglClose() } @@ -626,6 +634,28 @@ func GetShaderIdDefault() uint32 { return rlGetShaderIdDefault() } +// LoadRenderBatch - Load a render batch system +func LoadRenderBatch(numBuffers int32, bufferElements int32) RenderBatch { + var batch RenderBatch + rlLoadRenderBatch(uintptr(unsafe.Pointer(&batch)), numBuffers, bufferElements) + return batch +} + +// UnloadRenderBatch - Unload render batch system +func UnloadRenderBatch(batch RenderBatch) { + rlUnloadRenderBatch(uintptr(unsafe.Pointer(&batch))) +} + +// DrawRenderBatch - Draw render batch data (Update->Draw->Reset) +func DrawRenderBatch(batch *RenderBatch) { + rlDrawRenderBatch(batch) +} + +// rlSetRenderBatchActive - Set the active render batch for rlgl (NULL for default internal) +func SetRenderBatchActive(batch *RenderBatch) { + rlSetRenderBatchActive(batch) +} + // DrawRenderBatchActive - Update and draw internal render batch func DrawRenderBatchActive() { rlDrawRenderBatchActive() From fdd3d616dae99a41e1fca746a771b7b5ee97d4c0 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:41:43 +0100 Subject: [PATCH 003/278] Update purego --- raylib/go.mod | 2 +- raylib/go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/raylib/go.mod b/raylib/go.mod index c5b70ff..25a1709 100644 --- a/raylib/go.mod +++ b/raylib/go.mod @@ -3,6 +3,6 @@ module github.com/gen2brain/raylib-go/raylib go 1.21 require ( - github.com/ebitengine/purego v0.5.0 + github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 golang.org/x/sys v0.14.0 ) diff --git a/raylib/go.sum b/raylib/go.sum index 949e8db..46b1d3e 100644 --- a/raylib/go.sum +++ b/raylib/go.sum @@ -1,4 +1,6 @@ github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo= github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 h1:yi8prWU9muoK5wqNcMX2dXxiIeflbKRs8NeVhX+cH0I= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= From 2be56088ed33685065d4b494527b69cf7c6135e8 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:50:49 +0100 Subject: [PATCH 004/278] Update modules --- examples/go.mod | 5 +++++ examples/go.sum | 4 ++++ raylib/go.sum | 2 -- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index 0271bbc..6a3f378 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -14,3 +14,8 @@ require ( github.com/jakecoffman/cp v1.2.1 github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b ) + +require ( + github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 // indirect + golang.org/x/sys v0.14.0 // indirect +) diff --git a/examples/go.sum b/examples/go.sum index 0b7361d..073f7e4 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,3 +1,5 @@ +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 h1:yi8prWU9muoK5wqNcMX2dXxiIeflbKRs8NeVhX+cH0I= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/gen2brain/raylib-go/easings v0.0.0-20231021203613-2d673bb5f4b3 h1:X96BFLT5c40DnZM8RKlyE6QC37IreaZbA/+ww6JCm4g= github.com/gen2brain/raylib-go/easings v0.0.0-20231021203613-2d673bb5f4b3/go.mod h1:UuXithI7f7GZ22PJtaZDXHzWzdXx0OCyuxaakj9gt9k= github.com/gen2brain/raylib-go/physics v0.0.0-20231021203613-2d673bb5f4b3 h1:TYu6QaR/DPgFgoluAUUj5Iftn76bjXCmCTYAlt5UHaU= @@ -6,3 +8,5 @@ github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI= github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b/go.mod h1:kvKwD9codtns5mvpA53V3vLnqFb/Ahcu8zgkGM0SIbI= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/raylib/go.sum b/raylib/go.sum index 46b1d3e..e90c25e 100644 --- a/raylib/go.sum +++ b/raylib/go.sum @@ -1,5 +1,3 @@ -github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo= -github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 h1:yi8prWU9muoK5wqNcMX2dXxiIeflbKRs8NeVhX+cH0I= github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= From db3e0be60e993157673bd68f04752cd72700343e Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:06:12 +0100 Subject: [PATCH 005/278] go mod tidy examples --- examples/go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/go.sum b/examples/go.sum index 073f7e4..df6280e 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,9 +1,5 @@ github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 h1:yi8prWU9muoK5wqNcMX2dXxiIeflbKRs8NeVhX+cH0I= github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= -github.com/gen2brain/raylib-go/easings v0.0.0-20231021203613-2d673bb5f4b3 h1:X96BFLT5c40DnZM8RKlyE6QC37IreaZbA/+ww6JCm4g= -github.com/gen2brain/raylib-go/easings v0.0.0-20231021203613-2d673bb5f4b3/go.mod h1:UuXithI7f7GZ22PJtaZDXHzWzdXx0OCyuxaakj9gt9k= -github.com/gen2brain/raylib-go/physics v0.0.0-20231021203613-2d673bb5f4b3 h1:TYu6QaR/DPgFgoluAUUj5Iftn76bjXCmCTYAlt5UHaU= -github.com/gen2brain/raylib-go/physics v0.0.0-20231021203613-2d673bb5f4b3/go.mod h1:ViQH1zqfv7oSbhxKUWDV5JgnYHHkf/DGQ9HrVNEPTd0= github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI= github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI= From f239fe2f679f3f198a23116e3f5e16c04424d197 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 22 Nov 2023 16:26:21 +0100 Subject: [PATCH 006/278] Updat purego to 192c5e846faa64025fb8a6a94532c7a77fbd8dce --- raylib/go.mod | 2 +- raylib/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/raylib/go.mod b/raylib/go.mod index 25a1709..c0c536c 100644 --- a/raylib/go.mod +++ b/raylib/go.mod @@ -3,6 +3,6 @@ module github.com/gen2brain/raylib-go/raylib go 1.21 require ( - github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 + github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa golang.org/x/sys v0.14.0 ) diff --git a/raylib/go.sum b/raylib/go.sum index e90c25e..96d4ea7 100644 --- a/raylib/go.sum +++ b/raylib/go.sum @@ -1,4 +1,4 @@ -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 h1:yi8prWU9muoK5wqNcMX2dXxiIeflbKRs8NeVhX+cH0I= -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa h1:Ik7QikRgeH+bFOfAcMpttCbs6XxWXxCLXMm4awxtOXk= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= From f537de6ed9ae3eea76bed5a37922fa4ea13d5148 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 22 Nov 2023 16:29:10 +0100 Subject: [PATCH 007/278] go mod tidy --- examples/go.mod | 2 +- examples/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index 0dd4c84..32ed05e 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -20,6 +20,6 @@ require ( ) require ( - github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 // indirect + github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa // indirect golang.org/x/sys v0.14.0 // indirect ) diff --git a/examples/go.sum b/examples/go.sum index df6280e..881382a 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,5 +1,5 @@ -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5 h1:yi8prWU9muoK5wqNcMX2dXxiIeflbKRs8NeVhX+cH0I= -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231118171415-63c6fec935c5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa h1:Ik7QikRgeH+bFOfAcMpttCbs6XxWXxCLXMm4awxtOXk= +github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI= github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI= From a5d2760b1620f783971b562049d5306e9a8947d9 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 22 Nov 2023 19:06:35 +0100 Subject: [PATCH 008/278] Remove obsolete comment --- raylib/raylib_purego.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index ad307fe..f49f4ae 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -1582,8 +1582,6 @@ func SetTraceLogCallback(fn TraceLogCallbackFun) { } // IsFileDropped - Check if a file has been dropped into window -// -// REVIEW NEEDED! 2023-11-12 JupiterRider: This funtions always returns true. func IsFileDropped() bool { return isFileDropped() } From 34ea0cc7f58a400b2c1de89375d2fcaff00832ff Mon Sep 17 00:00:00 2001 From: swazzles Date: Thu, 23 Nov 2023 22:51:47 +1100 Subject: [PATCH 009/278] Add flag for borderless windowed mode --- raylib/raylib.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/raylib/raylib.go b/raylib/raylib.go index abde8c6..1fa3d5c 100644 --- a/raylib/raylib.go +++ b/raylib/raylib.go @@ -234,6 +234,8 @@ const ( FlagWindowHighdpi = 0x00002000 // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED FlagWindowMousePassthrough = 0x00004000 + // Set to run program in borderless windowed mode + FlagBorderlessWindowedMode = 0x00008000 // Set to try enabling MSAA 4X FlagMsaa4xHint = 0x00000020 // Set to try enabling interlaced video format (for V3D) From 19dc46f86c85eece7a5ad780b953032752db12d0 Mon Sep 17 00:00:00 2001 From: jack gleeson Date: Wed, 6 Dec 2023 19:51:46 -0800 Subject: [PATCH 010/278] Add binding for DrawTriangle3D to rmodels.go --- raylib/rmodels.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/raylib/rmodels.go b/raylib/rmodels.go index 4ea205d..dc876de 100644 --- a/raylib/rmodels.go +++ b/raylib/rmodels.go @@ -93,6 +93,15 @@ func DrawCircle3D(center Vector3, radius float32, rotationAxis Vector3, rotation C.DrawCircle3D(*ccenter, cradius, *crotationAxis, crotationAngle, *ccolor) } +// DrawTriangle3D - Draw a color-filled triangle (vertex in counter-clockwise order!) +func DrawTriangle3D(v1 Vector3, v2 Vector3, v3 Vector3, col color.RGBA) { + cv1 := v1.cptr() + cv2 := v2.cptr() + cv3 := v3.cptr() + ccolor := colorCptr(col) + C.DrawTriangle3D(*cv1, *cv2, *cv3, *ccolor) +} + // DrawCube - Draw cube func DrawCube(position Vector3, width float32, height float32, length float32, col color.RGBA) { cposition := position.cptr() From 2bee857547dfaf13600eaa3a18c1d085bbc28d23 Mon Sep 17 00:00:00 2001 From: Yassen Tombokti Date: Mon, 18 Dec 2023 21:59:40 +0000 Subject: [PATCH 011/278] Update README.md --- physics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/README.md b/physics/README.md index b86c883..0005dff 100644 --- a/physics/README.md +++ b/physics/README.md @@ -2,4 +2,4 @@ 2D Physics library for videogames. -A port of Victor Fisac's [physac engine](https://github.com/raysan5/raylib/blob/master/src/physac.h). +A port of Victor Fisac's [physac engine](https://github.com/raysan5/physac/blob/master/src/physac.h). From cf285a20a18794619cd0a8b66e9ceb75423753bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Tue, 19 Dec 2023 14:38:36 +0000 Subject: [PATCH 012/278] Fix mouseCell pointer not updaing value --- raygui/raygui.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/raygui/raygui.go b/raygui/raygui.go index f2b40e8..1a3f8ef 100644 --- a/raygui/raygui.go +++ b/raygui/raygui.go @@ -621,6 +621,8 @@ func Grid(bounds rl.Rectangle, text string, spacing float32, subdivs int32, mous cmouseCell.x = C.float(mouseCell.X) cmouseCell.y = C.float(mouseCell.Y) res := C.GuiGrid(cbounds, ctext, cspacing, csubdivs, &cmouseCell) + mouseCell.X = float32(cmouseCell.x) + mouseCell.Y = float32(cmouseCell.y) return int32(res) } From 4bb9631420b2745938d99071be2ff7956ece4284 Mon Sep 17 00:00:00 2001 From: Snowminx Date: Sun, 24 Dec 2023 12:40:03 -0800 Subject: [PATCH 013/278] feat: update rtextures.go to have the func LoadTextureCubemap. --- raylib/rtextures.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 6945a83..afbc4c3 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -184,6 +184,13 @@ func LoadRenderTexture(width, height int32) RenderTexture2D { return v } +// LoadTextureCubemap - Loads a texture for a cubemap using given layout +func LoadTextureCubemap(image Image, layout int32) Texture2D { + ret := C.LoadTextureCubemap(image, layout) + v := newTexture2DFromPointer(unsafe.Pointer(&ret)) + return v +} + // UnloadImage - Unload image from CPU memory (RAM) func UnloadImage(image *Image) { cimage := image.cptr() From 656b4a4a8d0837df29d5785c60ec04e1d0ae3a4f Mon Sep 17 00:00:00 2001 From: Snowminx Date: Sun, 24 Dec 2023 18:36:56 -0800 Subject: [PATCH 014/278] fix: update to convert params to cgo --- raylib/rtextures.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/raylib/rtextures.go b/raylib/rtextures.go index afbc4c3..0bf775b 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -185,8 +185,10 @@ func LoadRenderTexture(width, height int32) RenderTexture2D { } // LoadTextureCubemap - Loads a texture for a cubemap using given layout -func LoadTextureCubemap(image Image, layout int32) Texture2D { - ret := C.LoadTextureCubemap(image, layout) +func LoadTextureCubemap(image *Image, layout int32) Texture2D { + cimage := image.cptr() + clayout := (C.int)(layout) + ret := C.LoadTextureCubemap(cimage, clayout) v := newTexture2DFromPointer(unsafe.Pointer(&ret)) return v } From 1cee1d0534ba25cc53f8e77e35c0f02e592d00a0 Mon Sep 17 00:00:00 2001 From: Snowminx Date: Sun, 24 Dec 2023 19:21:57 -0800 Subject: [PATCH 015/278] fix: pass by value to c function --- raylib/rtextures.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 0bf775b..0068c62 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -188,7 +188,7 @@ func LoadRenderTexture(width, height int32) RenderTexture2D { func LoadTextureCubemap(image *Image, layout int32) Texture2D { cimage := image.cptr() clayout := (C.int)(layout) - ret := C.LoadTextureCubemap(cimage, clayout) + ret := C.LoadTextureCubemap(*cimage, clayout) v := newTexture2DFromPointer(unsafe.Pointer(&ret)) return v } From 6656db4829a7d480b35c332f380d90296383e72c Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Thu, 28 Dec 2023 16:06:40 +0100 Subject: [PATCH 016/278] Change signature of LoadFontFromMemory in raylib/rtext.go to match with purego version --- raylib/rtext.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/raylib/rtext.go b/raylib/rtext.go index f791257..35deef8 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -74,14 +74,14 @@ func LoadFontFromImage(image Image, key color.RGBA, firstChar int32) Font { } // LoadFontFromMemory - Load font from memory buffer, fileType refers to extension: i.e. ".ttf" -func LoadFontFromMemory(fileType string, fileData []byte, dataSize int32, fontSize int32, fontChars *int32, charsCount int32) Font { +func LoadFontFromMemory(fileType string, fileData []byte, fontSize int32, codepoints []rune) Font { cfileType := C.CString(fileType) defer C.free(unsafe.Pointer(cfileType)) cfileData := (*C.uchar)(unsafe.Pointer(&fileData[0])) - cdataSize := (C.int)(dataSize) + cdataSize := (C.int)(len(fileData)) cfontSize := (C.int)(fontSize) - cfontChars := (*C.int)(unsafe.Pointer(fontChars)) - ccharsCount := (C.int)(charsCount) + cfontChars := (*C.int)(unsafe.SliceData(codepoints)) + ccharsCount := (C.int)(len(codepoints)) ret := C.LoadFontFromMemory(cfileType, cfileData, cdataSize, cfontSize, cfontChars, ccharsCount) v := newFontFromPointer(unsafe.Pointer(&ret)) return v From 48241c48d28cb4a58c95d6f5f0252685145cfc94 Mon Sep 17 00:00:00 2001 From: Snowminx Date: Fri, 29 Dec 2023 20:42:43 -0800 Subject: [PATCH 017/278] fix: update purego signature to match --- raylib/raylib_purego.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index f49f4ae..f70512e 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -2637,9 +2637,9 @@ func LoadTextureFromImage(image *Image) Texture2D { } // LoadTextureCubemap - Load cubemap from image, multiple image cubemap layouts supported -func LoadTextureCubemap(image Image, layout int32) Texture2D { +func LoadTextureCubemap(image *Image, layout int32) Texture2D { var texture Texture2D - loadTextureCubemap(uintptr(unsafe.Pointer(&texture)), uintptr(unsafe.Pointer(&image)), layout) + loadTextureCubemap(uintptr(unsafe.Pointer(&texture)), uintptr(unsafe.Pointer(image)), layout) return texture } From 381d68b2a360302f54e19e24fe31b586f42391a8 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:54:02 +0100 Subject: [PATCH 018/278] physics.GetBodies: return only non nil (active) bodies --- physics/physics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/physics.go b/physics/physics.go index 91cf03a..e98c675 100644 --- a/physics/physics.go +++ b/physics/physics.go @@ -526,7 +526,7 @@ func Shatter(body *Body, position rl.Vector2, force float32) { // GetBodies - Returns the slice of created physics bodies func GetBodies() []*Body { - return bodies[:] + return bodies[:bodiesCount] } // GetBodiesCount - Returns the current amount of created physics bodies From b63c9257c5d0b484ea9d26d3f0791a1c8476678a Mon Sep 17 00:00:00 2001 From: Pierre Curto Date: Wed, 10 Jan 2024 10:12:43 +0100 Subject: [PATCH 019/278] add ImageFromImage() --- raylib/rtextures.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 0068c62..4e008c0 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -282,6 +282,15 @@ func ImageCopy(image *Image) *Image { return v } +// Create an image from another image piece +func ImageFromImage(image Image, rec Rectangle) Image { + cimage := image.cptr() + crec := rec.cptr() + ret := C.ImageFromImage(*cimage, *crec) + v := newImageFromPointer(unsafe.Pointer(&ret)) + return *v +} + // ImageText - Create an image from text (default font) func ImageText(text string, fontSize int32, col color.RGBA) *Image { ctext := C.CString(text) From 509ad7da5c0f682abe06714ada99a1b0cbd13c7b Mon Sep 17 00:00:00 2001 From: Daniel 'ShellFu' Kendrick <3248200+shellfu@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:11:25 -0700 Subject: [PATCH 020/278] Align raylib-go ExportImage with C Library Behavior The original raylib C library's ExportImage function returns a boolean to indicate the success or failure of the export operation. This behavior was missing in the raylib-go implementation, which provided no return value, thereby limiting error handling capabilities. This commit updates the ExportImage function in raylib-go to return a boolean or an error, aligning it with its C counterpart and enabling idiomatic Go error handling. The change includes updates to the function and tests to reflect the new return type. This enhancement increases robustness and clarity in error handling for Go developers using raylib-go. The test suite has been updated and run to ensure the correct functioning of the modified ExportImage function, with results confirming the expected behavior in both successful and unsuccessful scenarios. - Daniel "ShellFu" Kendrick --- raylib/rtextures.go | 23 +++---------------- raylib/rtextures_test.go | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 raylib/rtextures_test.go diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 4e008c0..5459430 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -184,15 +184,6 @@ func LoadRenderTexture(width, height int32) RenderTexture2D { return v } -// LoadTextureCubemap - Loads a texture for a cubemap using given layout -func LoadTextureCubemap(image *Image, layout int32) Texture2D { - cimage := image.cptr() - clayout := (C.int)(layout) - ret := C.LoadTextureCubemap(*cimage, clayout) - v := newTexture2DFromPointer(unsafe.Pointer(&ret)) - return v -} - // UnloadImage - Unload image from CPU memory (RAM) func UnloadImage(image *Image) { cimage := image.cptr() @@ -255,11 +246,12 @@ func UpdateTextureRec(texture Texture2D, rec Rectangle, pixels []color.RGBA) { } // ExportImage - Export image as a PNG file -func ExportImage(image Image, fileName string) { +func ExportImage(image Image, fileName string) bool { cfileName := C.CString(fileName) defer C.free(unsafe.Pointer(cfileName)) cimage := image.cptr() - C.ExportImage(*cimage, cfileName) + + return bool(C.ExportImage(*cimage, cfileName)) } // ExportImageToMemory - Export image to memory buffer @@ -282,15 +274,6 @@ func ImageCopy(image *Image) *Image { return v } -// Create an image from another image piece -func ImageFromImage(image Image, rec Rectangle) Image { - cimage := image.cptr() - crec := rec.cptr() - ret := C.ImageFromImage(*cimage, *crec) - v := newImageFromPointer(unsafe.Pointer(&ret)) - return *v -} - // ImageText - Create an image from text (default font) func ImageText(text string, fontSize int32, col color.RGBA) *Image { ctext := C.CString(text) diff --git a/raylib/rtextures_test.go b/raylib/rtextures_test.go new file mode 100644 index 0000000..095084f --- /dev/null +++ b/raylib/rtextures_test.go @@ -0,0 +1,48 @@ +package rl_test + +import ( + "os" + "testing" + + "image/color" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +func TestExportImage(t *testing.T) { + var tests = []struct { + name string + image rl.Image + fileName string + want bool + }{ + { + name: "ValidImageExport", + image: *rl.GenImageColor(100, 100, color.RGBA{255, 0, 0, 255}), + fileName: "test_image.png", + want: true, + }, + { + name: "InvalidImageExport", + image: rl.Image{}, + fileName: "", + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + success := rl.ExportImage(tt.image, tt.fileName) + defer os.Remove(tt.fileName) + + if success != tt.want { + t.Errorf("ExportImage() result = %v, wantResult %v", success, tt.want) + return + } + + if _, err := os.Stat(tt.fileName); os.IsNotExist(err) && tt.want { + t.Errorf("ExportImage() failed to create file %s", tt.fileName) + } + }) + } +} From 1f80c1e4c2c0ec26a0617b24698c529e577d309f Mon Sep 17 00:00:00 2001 From: Daniel 'ShellFu' Kendrick <3248200+shellfu@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:20:45 -0700 Subject: [PATCH 021/278] Removed test per maintainer instruction, added back in ImageFromImage and LoadTextureCubemap --- raylib/rtextures.go | 19 +++++++++++++++- raylib/rtextures_test.go | 48 ---------------------------------------- 2 files changed, 18 insertions(+), 49 deletions(-) delete mode 100644 raylib/rtextures_test.go diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 5459430..23a1f37 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -184,6 +184,15 @@ func LoadRenderTexture(width, height int32) RenderTexture2D { return v } +// LoadTextureCubemap - Loads a texture for a cubemap using given layout +func LoadTextureCubemap(image *Image, layout int32) Texture2D { + cimage := image.cptr() + clayout := (C.int)(layout) + ret := C.LoadTextureCubemap(*cimage, clayout) + v := newTexture2DFromPointer(unsafe.Pointer(&ret)) + return v +} + // UnloadImage - Unload image from CPU memory (RAM) func UnloadImage(image *Image) { cimage := image.cptr() @@ -250,7 +259,6 @@ func ExportImage(image Image, fileName string) bool { cfileName := C.CString(fileName) defer C.free(unsafe.Pointer(cfileName)) cimage := image.cptr() - return bool(C.ExportImage(*cimage, cfileName)) } @@ -274,6 +282,15 @@ func ImageCopy(image *Image) *Image { return v } +// Create an image from another image piece +func ImageFromImage(image Image, rec Rectangle) Image { + cimage := image.cptr() + crec := rec.cptr() + ret := C.ImageFromImage(*cimage, *crec) + v := newImageFromPointer(unsafe.Pointer(&ret)) + return *v +} + // ImageText - Create an image from text (default font) func ImageText(text string, fontSize int32, col color.RGBA) *Image { ctext := C.CString(text) diff --git a/raylib/rtextures_test.go b/raylib/rtextures_test.go deleted file mode 100644 index 095084f..0000000 --- a/raylib/rtextures_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package rl_test - -import ( - "os" - "testing" - - "image/color" - - rl "github.com/gen2brain/raylib-go/raylib" -) - -func TestExportImage(t *testing.T) { - var tests = []struct { - name string - image rl.Image - fileName string - want bool - }{ - { - name: "ValidImageExport", - image: *rl.GenImageColor(100, 100, color.RGBA{255, 0, 0, 255}), - fileName: "test_image.png", - want: true, - }, - { - name: "InvalidImageExport", - image: rl.Image{}, - fileName: "", - want: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - success := rl.ExportImage(tt.image, tt.fileName) - defer os.Remove(tt.fileName) - - if success != tt.want { - t.Errorf("ExportImage() result = %v, wantResult %v", success, tt.want) - return - } - - if _, err := os.Stat(tt.fileName); os.IsNotExist(err) && tt.want { - t.Errorf("ExportImage() failed to create file %s", tt.fileName) - } - }) - } -} From 5c31cc3104a17281e53730fe23088ee31999bdeb Mon Sep 17 00:00:00 2001 From: Daniel 'ShellFu' Kendrick <3248200+shellfu@users.noreply.github.com> Date: Sun, 21 Jan 2024 11:08:17 -0700 Subject: [PATCH 022/278] Add Compute Shader and SSBO Functions to raylib-go This commit introduces functions related to compute shaders and Shader Buffer Storage Objects (SSBOs) in raylib-go. It adds bindings for loading, dispatching, and managing compute shaders and SSBOs, aligning raylib-go more closely with the raylib C library's capabilities. Specifically, the functions added are `LoadComputeShaderProgram`, `ComputeShaderDispatch`, `LoadShaderBuffer`, `UnloadShaderBuffer`, `UpdateShaderBuffer`, `BindShaderBuffer`, `ReadShaderBuffer`, and `CopyShaderBuffer`. These additions enhance raylib-go's utility for more advanced GPU operations. --- raylib/rlgl_cgo.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index defc8ef..af82f71 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -667,6 +667,12 @@ func SetUniformSampler(locIndex int32, textureId uint32) { C.rlSetUniformSampler(clocIndex, ctextureId) } +// LoadComputeShaderProgram - +func LoadComputeShaderProgram(shaderID uint) uint { + cshaderID := C.uint(shaderID) + return uint(C.rlLoadComputeShaderProgram(cshaderID)) +} + // ComputeShaderDispatch - Dispatch compute shader (equivalent to *draw* for graphics pilepine) func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { cgroupX := C.uint(groupX) @@ -675,6 +681,55 @@ func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { C.rlComputeShaderDispatch(cgroupX, cgroupY, cgroupZ) } +// LoadShaderBuffer - Load shader storage buffer object (SSBO) +func LoadShaderBuffer(size uint32, data unsafe.Pointer, usageHint int32) uint32 { + csize := C.uint(size) + cdata := data + cusageHint := C.int(usageHint) + return uint32(C.rlLoadShaderBuffer(csize, cdata, cusageHint)) +} + +// UnloadShaderBuffer - Unload shader storage buffer object (SSBO) +func UnloadShaderBuffer(id uint32) { + cid := C.uint(id) + C.rlUnloadShaderBuffer(cid) +} + +// UpdateShaderBuffer - Update SSBO buffer data +func UpdateShaderBuffer(id uint32, data unsafe.Pointer, dataSize uint32, offset uint32) { + cid := C.uint(id) + cdata := data + cdataSize := C.uint(dataSize) + coffset := C.uint(offset) + C.rlUpdateShaderBuffer(cid, cdata, cdataSize, coffset) +} + +// BindShaderBuffer - Bind SSBO buffer +func BindShaderBuffer(id uint32, index uint32) { + cid := C.uint(id) + cindex := C.uint(index) + C.rlBindShaderBuffer(cid, cindex) +} + +// ReadShaderBuffer - Read SSBO buffer data (GPU->CPU) +func ReadShaderBuffer(id uint32, dest unsafe.Pointer, count uint32, offset uint32) { + cid := C.uint(id) + cdest := dest + ccount := C.uint(count) + coffset := C.uint(offset) + C.rlReadShaderBuffer(cid, cdest, ccount, coffset) +} + +// CopyShaderBuffer - Copy SSBO data between buffers +func CopyShaderBuffer(destId uint32, srcId uint32, destOffset uint32, srcOffset uint32, count uint32) { + cdestId := C.uint(destId) + csrcId := C.uint(srcId) + cdestOffset := C.uint(destOffset) + csrcOffset := C.uint(srcOffset) + ccount := C.uint(count) + C.rlCopyShaderBuffer(cdestId, csrcId, cdestOffset, csrcOffset, ccount) +} + // GetShaderBufferSize - Get SSBO buffer size func GetShaderBufferSize(id uint32) uint32 { cid := C.uint(id) From 0b58bcbe1b5c19362618995df75ea6fd7c9d6401 Mon Sep 17 00:00:00 2001 From: Daniel 'ShellFu' Kendrick <3248200+shellfu@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:19:55 -0700 Subject: [PATCH 023/278] Add Compute Shader and SSBO Functions to raylib-go in `rlgl_purego.go` This commit introduces functions related to compute shaders and Shader Buffer Storage Objects (SSBOs) in raylib-go. It adds bindings for loading, dispatching, and managing compute shaders and SSBOs, aligning raylib-go more closely with the raylib C library's capabilities. Specifically, the functions added are `LoadComputeShaderProgram`, `ComputeShaderDispatch`, `LoadShaderBuffer`, `UnloadShaderBuffer`, `UpdateShaderBuffer`, `BindShaderBuffer`, `ReadShaderBuffer`, and `CopyShaderBuffer`. These additions enhance raylib-go's utility for more advanced GPU operations. --- raylib/rlgl_purego.go | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index d79c1d3..1c168d6 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -108,7 +108,14 @@ var rlUnloadShaderProgram func(id uint32) var rlGetLocationUniform func(shaderId uint32, uniformName string) int32 var rlGetLocationAttrib func(shaderId uint32, attribName string) int32 var rlSetUniformSampler func(locIndex int32, textureId uint32) +var rlLoadComputeShaderProgram func(shaderID uint) uint var rlComputeShaderDispatch func(groupX uint32, groupY uint32, groupZ uint32) +var rlLoadShaderBuffer func(size uint32, data unsafe.Pointer, usageHint int32) uint32 +var rlUnloadShaderBuffer func(id uint32) +var rlUpdateShaderBuffer func(id uint32, data unsafe.Pointer, dataSize uint32, offset uint32) +var rlBindShaderBuffer func(id uint32, index uint32) +var rlReadShaderBuffer func(id uint32, dest unsafe.Pointer, count uint32, offset uint32) +var rlCopyShaderBuffer func(destId uint32, srcId uint32, destOffset uint32, srcOffset uint32, count uint32) var rlGetShaderBufferSize func(id uint32) uint32 var rlBindImageTexture func(id uint32, index uint32, format int32, readonly bool) var rlGetMatrixModelview func(matrix uintptr) @@ -223,7 +230,14 @@ func initRlglPurego() { purego.RegisterLibFunc(&rlGetLocationUniform, raylibDll, "rlGetLocationUniform") purego.RegisterLibFunc(&rlGetLocationAttrib, raylibDll, "rlGetLocationAttrib") purego.RegisterLibFunc(&rlSetUniformSampler, raylibDll, "rlSetUniformSampler") + purego.RegisterLibFunc(&rlLoadComputeShaderProgram, raylibDll, "rlLoadComputeShaderProgram") purego.RegisterLibFunc(&rlComputeShaderDispatch, raylibDll, "rlComputeShaderDispatch") + purego.RegisterLibFunc(&rlLoadShaderBuffer, raylibDll, "rlLoadShaderBuffer") + purego.RegisterLibFunc(&rlUnloadShaderBuffer, "rlUnloadShaderBuffer") + purego.RegisterLibFunc(&rlUpdateShaderBuffer, raylibDll, "rlUpdateShaderBuffer") + purego.RegisterLibFunc(&rlBindShaderBuffer, raylibDll, "rlBindShaderBuffer") + purego.RegisterLibFunc(&rlReadShaderBuffer, raylibDll, "rlReadShaderBuffer") + purego.RegisterLibFunc(&rlCopyShaderBuffer, raylibDll, "rlCopyShaderBuffer") purego.RegisterLibFunc(&rlGetShaderBufferSize, raylibDll, "rlGetShaderBufferSize") purego.RegisterLibFunc(&rlBindImageTexture, raylibDll, "rlBindImageTexture") purego.RegisterLibFunc(&rlGetMatrixModelview, raylibDll, "rlGetMatrixModelview") @@ -746,11 +760,46 @@ func SetUniformSampler(locIndex int32, textureId uint32) { rlSetUniformSampler(locIndex, textureId) } +// LoadComputeShaderProgram - Load compute shader program +func LoadComputeShaderProgram(shaderID uint32) uint32 { + return rlLoadComputeShaderProgram(shaderID) +} + // ComputeShaderDispatch - Dispatch compute shader (equivalent to *draw* for graphics pilepine) func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { rlComputeShaderDispatch(groupX, groupY, groupZ) } +// LoadShaderBuffer loads a shader storage buffer object (SSBO) +func LoadShaderBuffer(size uint32, data unsafe.Pointer, usageHint int32) uint32 { + rlLoadShaderBuffer(size, data, usageHint) +} + +// UnloadShaderBuffer - Unload shader storage buffer object (SSBO) +func UnloadShaderBuffer(id uint32) { + rlUnloadShaderBuffer(id) +} + +// UpdateShaderBuffer - Update SSBO buffer data +func UpdateShaderBuffer(id uint32, data unsafe.Pointer, dataSize uint32, offset uint32) { + rlUpdateShaderBuffer(id, data, dataSize, offset) +} + +// BindShaderBuffer - Bind SSBO buffer +func BindShaderBuffer(id uint32, index uint32) { + rlBindShaderBuffer(id, index) +} + +// ReadShaderBuffer - Read SSBO buffer data (GPU->CPU) +func ReadShaderBuffer(id uint32, dest unsafe.Pointer, count uint32, offset uint32) { + rlReadShaderBuffer(id, dest, count, offset) +} + +// CopyShaderBuffer - Copy SSBO data between buffers +func CopyShaderBuffer(destId uint32, srcId uint32, destOffset uint32, srcOffset uint32, count uint32) { + rlCopyShaderBuffer(destId, srcId, destOffset, srcOffset, count) +} + // GetShaderBufferSize - Get SSBO buffer size func GetShaderBufferSize(id uint32) uint32 { return rlGetShaderBufferSize(id) From 2a08e83ca45789813879fd63b671c2b91c8f7084 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:56:50 +0100 Subject: [PATCH 024/278] Fix typo and data-types --- raylib/rlgl_cgo.go | 6 +++--- raylib/rlgl_purego.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index af82f71..c39a2eb 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -9,7 +9,7 @@ import "C" import ( "unsafe" ) - +rlLoadComputeShaderProgram // SetMatrixProjection - Set a custom projection matrix (replaces internal projection matrix) func SetMatrixProjection(proj Matrix) { cproj := proj.cptr() @@ -668,9 +668,9 @@ func SetUniformSampler(locIndex int32, textureId uint32) { } // LoadComputeShaderProgram - -func LoadComputeShaderProgram(shaderID uint) uint { +func LoadComputeShaderProgram(shaderID uint32) uint32 { cshaderID := C.uint(shaderID) - return uint(C.rlLoadComputeShaderProgram(cshaderID)) + return uint32(C.rlLoadComputeShaderProgram(cshaderID)) } // ComputeShaderDispatch - Dispatch compute shader (equivalent to *draw* for graphics pilepine) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index 1c168d6..ccb5029 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -108,7 +108,7 @@ var rlUnloadShaderProgram func(id uint32) var rlGetLocationUniform func(shaderId uint32, uniformName string) int32 var rlGetLocationAttrib func(shaderId uint32, attribName string) int32 var rlSetUniformSampler func(locIndex int32, textureId uint32) -var rlLoadComputeShaderProgram func(shaderID uint) uint +var rlLoadComputeShaderProgram func(shaderID uint32) uint32 var rlComputeShaderDispatch func(groupX uint32, groupY uint32, groupZ uint32) var rlLoadShaderBuffer func(size uint32, data unsafe.Pointer, usageHint int32) uint32 var rlUnloadShaderBuffer func(id uint32) @@ -233,7 +233,7 @@ func initRlglPurego() { purego.RegisterLibFunc(&rlLoadComputeShaderProgram, raylibDll, "rlLoadComputeShaderProgram") purego.RegisterLibFunc(&rlComputeShaderDispatch, raylibDll, "rlComputeShaderDispatch") purego.RegisterLibFunc(&rlLoadShaderBuffer, raylibDll, "rlLoadShaderBuffer") - purego.RegisterLibFunc(&rlUnloadShaderBuffer, "rlUnloadShaderBuffer") + purego.RegisterLibFunc(&rlUnloadShaderBuffer, raylibDll, "rlUnloadShaderBuffer") purego.RegisterLibFunc(&rlUpdateShaderBuffer, raylibDll, "rlUpdateShaderBuffer") purego.RegisterLibFunc(&rlBindShaderBuffer, raylibDll, "rlBindShaderBuffer") purego.RegisterLibFunc(&rlReadShaderBuffer, raylibDll, "rlReadShaderBuffer") @@ -772,7 +772,7 @@ func ComputeShaderDispatch(groupX uint32, groupY uint32, groupZ uint32) { // LoadShaderBuffer loads a shader storage buffer object (SSBO) func LoadShaderBuffer(size uint32, data unsafe.Pointer, usageHint int32) uint32 { - rlLoadShaderBuffer(size, data, usageHint) + return rlLoadShaderBuffer(size, data, usageHint) } // UnloadShaderBuffer - Unload shader storage buffer object (SSBO) From 3bc33ec8b7402f1de548de9767a5b4b199962ee0 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:58:33 +0100 Subject: [PATCH 025/278] Update rlgl_cgo.go --- raylib/rlgl_cgo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index c39a2eb..15f0067 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -9,7 +9,7 @@ import "C" import ( "unsafe" ) -rlLoadComputeShaderProgram + // SetMatrixProjection - Set a custom projection matrix (replaces internal projection matrix) func SetMatrixProjection(proj Matrix) { cproj := proj.cptr() From a5d0d71e503bd2d0de9223d95904c556cb9b457b Mon Sep 17 00:00:00 2001 From: unkl nik Date: Thu, 25 Jan 2024 12:55:45 +0200 Subject: [PATCH 026/278] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73f97d1..2f508e3 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ It is also possible build the dll yourself. You can find more infos at [raylib's ### Documentation -Documentation on [GoDoc](https://godoc.org/github.com/gen2brain/raylib-go/raylib). Also check raylib [cheatsheet](http://www.raylib.com/cheatsheet/cheatsheet.html). +Documentation on [GoDoc](https://godoc.org/github.com/gen2brain/raylib-go/raylib). Also check raylib [cheatsheet](http://www.raylib.com/cheatsheet/cheatsheet.html). If you have problems or need assistance there is an active community in the #raylib-go channel of the [Raylib Discord Server](https://discord.gg/raylib) that can help. ### Example From a490f10c86ada59b1fbd55cb008ff6358d674f39 Mon Sep 17 00:00:00 2001 From: Oleksandr Kryvonos Date: Sat, 24 Feb 2024 20:39:33 +0100 Subject: [PATCH 027/278] copied only changes --- raylib/rtext.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/raylib/rtext.go b/raylib/rtext.go index 35deef8..6a78bf8 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -63,6 +63,18 @@ func LoadFontEx(fileName string, fontSize int32, fontChars []rune) Font { return v } +// LoadFontEx - Load Font from file with extended parameter - number of runes to load +func LoadFontExByRunesNumber(fileName string, fontSize int32, runesNumber int32) Font { + ccharsCount := (C.int)(runesNumber) + cfileName := C.CString(fileName) + defer C.free(unsafe.Pointer(cfileName)) + cfontSize := (C.int)(fontSize) + + ret := C.LoadFontEx(cfileName, cfontSize, nil, ccharsCount) + v := newFontFromPointer(unsafe.Pointer(&ret)) + return v +} + // LoadFontFromImage - Loads an Image font file (XNA style) func LoadFontFromImage(image Image, key color.RGBA, firstChar int32) Font { cimage := image.cptr() From a870a098947c2724d4d8570edd8cfed55078aa43 Mon Sep 17 00:00:00 2001 From: Oleksandr Kryvonos Date: Sun, 25 Feb 2024 12:18:39 +0100 Subject: [PATCH 028/278] variadic parameter for runesNumber in LoadFontEx --- raylib/raylib_purego.go | 5 ++++- raylib/rtext.go | 19 ++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index f70512e..6651673 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -2829,9 +2829,12 @@ func LoadFont(fileName string) Font { } // LoadFontEx - Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character setFont -func LoadFontEx(fileName string, fontSize int32, codepoints []rune) Font { +func LoadFontEx(fileName string, fontSize int32, codepoints []rune, runesNumber ...int32) Font { var font Font codepointCount := int32(len(codepoints)) + if len(runesNumber) > 0 { + codepointCount = int32(runesNumber[0]) + } loadFontEx(uintptr(unsafe.Pointer(&font)), fileName, fontSize, codepoints, codepointCount) return font } diff --git a/raylib/rtext.go b/raylib/rtext.go index 6a78bf8..684c690 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -47,7 +47,7 @@ func LoadFont(fileName string) Font { } // LoadFontEx - Load Font from file with extended parameters -func LoadFontEx(fileName string, fontSize int32, fontChars []rune) Font { +func LoadFontEx(fileName string, fontSize int32, fontChars []rune, runesNumber ...int32) Font { var cfontChars *C.int var ccharsCount C.int @@ -58,23 +58,16 @@ func LoadFontEx(fileName string, fontSize int32, fontChars []rune) Font { cfontChars = (*C.int)(unsafe.Pointer(&fontChars[0])) ccharsCount = (C.int)(len(fontChars)) } + if fontChars == nil { + if len(runesNumber) > 0 { + ccharsCount = (C.int)(runesNumber[0]) + } + } ret := C.LoadFontEx(cfileName, cfontSize, cfontChars, ccharsCount) v := newFontFromPointer(unsafe.Pointer(&ret)) return v } -// LoadFontEx - Load Font from file with extended parameter - number of runes to load -func LoadFontExByRunesNumber(fileName string, fontSize int32, runesNumber int32) Font { - ccharsCount := (C.int)(runesNumber) - cfileName := C.CString(fileName) - defer C.free(unsafe.Pointer(cfileName)) - cfontSize := (C.int)(fontSize) - - ret := C.LoadFontEx(cfileName, cfontSize, nil, ccharsCount) - v := newFontFromPointer(unsafe.Pointer(&ret)) - return v -} - // LoadFontFromImage - Loads an Image font file (XNA style) func LoadFontFromImage(image Image, key color.RGBA, firstChar int32) Font { cimage := image.cptr() From 9a0e172ca7f41a2758da635adf6260ea60c11fbf Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:23:08 +0100 Subject: [PATCH 029/278] Update GLFW --- raylib/external/glfw/include/GLFW/glfw3.h | 348 +- .../external/glfw/include/GLFW/glfw3native.h | 97 +- raylib/external/glfw/src/cocoa_init.m | 151 +- raylib/external/glfw/src/cocoa_joystick.h | 2 - raylib/external/glfw/src/cocoa_joystick.m | 17 +- raylib/external/glfw/src/cocoa_monitor.m | 22 +- raylib/external/glfw/src/cocoa_platform.h | 4 +- raylib/external/glfw/src/cocoa_time.c | 6 +- raylib/external/glfw/src/cocoa_window.m | 49 +- raylib/external/glfw/src/context.c | 4 +- raylib/external/glfw/src/egl_context.c | 107 +- raylib/external/glfw/src/glx_context.c | 7 +- raylib/external/glfw/src/init.c | 49 +- raylib/external/glfw/src/input.c | 21 +- raylib/external/glfw/src/internal.h | 61 +- raylib/external/glfw/src/linux_joystick.c | 15 +- raylib/external/glfw/src/linux_joystick.h | 3 +- raylib/external/glfw/src/mappings.h | 1671 ++--- raylib/external/glfw/src/monitor.c | 8 +- raylib/external/glfw/src/nsgl_context.m | 26 +- raylib/external/glfw/src/null_init.c | 279 +- raylib/external/glfw/src/null_joystick.c | 2 - raylib/external/glfw/src/null_monitor.c | 7 +- raylib/external/glfw/src/null_platform.h | 128 +- raylib/external/glfw/src/null_window.c | 137 +- raylib/external/glfw/src/osmesa_context.c | 7 +- raylib/external/glfw/src/platform.c | 37 +- raylib/external/glfw/src/platform.h | 55 +- raylib/external/glfw/src/posix_module.c | 6 +- raylib/external/glfw/src/posix_poll.c | 6 +- raylib/external/glfw/src/posix_poll.h | 2 - raylib/external/glfw/src/posix_thread.c | 6 +- raylib/external/glfw/src/posix_time.c | 6 +- raylib/external/glfw/src/vulkan.c | 2 - .../glfw/src/wayland-client-protocol-code.h | 524 -- .../glfw/src/wayland-client-protocol.h | 6321 ----------------- ...inhibit-unstable-v1-client-protocol-code.h | 68 - ...idle-inhibit-unstable-v1-client-protocol.h | 232 - ...traints-unstable-v1-client-protocol-code.h | 108 - ...-constraints-unstable-v1-client-protocol.h | 667 -- ...pointer-unstable-v1-client-protocol-code.h | 79 - ...tive-pointer-unstable-v1-client-protocol.h | 297 - .../wayland-viewporter-client-protocol-code.h | 74 - .../src/wayland-viewporter-client-protocol.h | 398 -- ...land-xdg-decoration-client-protocol-code.h | 75 - .../wayland-xdg-decoration-client-protocol.h | 378 - .../wayland-xdg-shell-client-protocol-code.h | 183 - .../src/wayland-xdg-shell-client-protocol.h | 2290 ------ raylib/external/glfw/src/wgl_context.c | 24 +- raylib/external/glfw/src/win32_init.c | 156 +- raylib/external/glfw/src/win32_joystick.c | 13 +- raylib/external/glfw/src/win32_joystick.h | 2 - raylib/external/glfw/src/win32_module.c | 6 +- raylib/external/glfw/src/win32_monitor.c | 30 +- raylib/external/glfw/src/win32_platform.h | 5 +- raylib/external/glfw/src/win32_thread.c | 6 +- raylib/external/glfw/src/win32_thread.h | 5 + raylib/external/glfw/src/win32_time.c | 5 +- raylib/external/glfw/src/win32_time.h | 5 + raylib/external/glfw/src/win32_window.c | 227 +- raylib/external/glfw/src/window.c | 35 +- raylib/external/glfw/src/wl_init.c | 412 +- raylib/external/glfw/src/wl_monitor.c | 34 +- raylib/external/glfw/src/wl_platform.h | 220 +- raylib/external/glfw/src/wl_window.c | 1337 ++-- raylib/external/glfw/src/x11_init.c | 162 +- raylib/external/glfw/src/x11_monitor.c | 37 +- raylib/external/glfw/src/x11_platform.h | 2 +- raylib/external/glfw/src/x11_window.c | 40 +- raylib/external/glfw/src/xkb_unicode.c | 5 +- 70 files changed, 3551 insertions(+), 14259 deletions(-) delete mode 100644 raylib/external/glfw/src/wayland-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-client-protocol.h delete mode 100644 raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol.h delete mode 100644 raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol.h delete mode 100644 raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol.h delete mode 100644 raylib/external/glfw/src/wayland-viewporter-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-viewporter-client-protocol.h delete mode 100644 raylib/external/glfw/src/wayland-xdg-decoration-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-xdg-decoration-client-protocol.h delete mode 100644 raylib/external/glfw/src/wayland-xdg-shell-client-protocol-code.h delete mode 100644 raylib/external/glfw/src/wayland-xdg-shell-client-protocol.h diff --git a/raylib/external/glfw/include/GLFW/glfw3.h b/raylib/external/glfw/include/GLFW/glfw3.h index 2687546..9c55ac9 100644 --- a/raylib/external/glfw/include/GLFW/glfw3.h +++ b/raylib/external/glfw/include/GLFW/glfw3.h @@ -361,10 +361,15 @@ extern "C" { #define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) #define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) #define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN) + +/*! @ingroup input + */ +#define GLFW_KEY_UNKNOWN -1 + /*! @} */ -/*! @defgroup keys Keyboard keys - * @brief Keyboard key IDs. +/*! @defgroup keys Keyboard key tokens + * @brief Keyboard key tokens. * * See [key input](@ref input_key) for how these are used. * @@ -387,9 +392,6 @@ extern "C" { * @{ */ -/* The unknown key */ -#define GLFW_KEY_UNKNOWN -1 - /* Printable keys */ #define GLFW_KEY_SPACE 32 #define GLFW_KEY_APOSTROPHE 39 /* ' */ @@ -825,11 +827,11 @@ extern "C" { #define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D /*! @brief Platform unavailable or no matching platform was found. * - * If emitted during initialization, no matching platform was found. If @ref - * GLFW_PLATFORM is set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of the - * platforms supported by this library binary, except for the Null platform. If set to - * a specific platform, it is either not supported by this library binary or GLFW was not - * able to detect it. + * If emitted during initialization, no matching platform was found. If the @ref + * GLFW_PLATFORM init hint was set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of + * the platforms supported by this library binary, except for the Null platform. If the + * init hint was set to a specific platform, it is either not supported by this library + * binary or GLFW was not able to detect it. * * If emitted by a native access function, GLFW was initialized for a different platform * than the function is for. @@ -1096,8 +1098,15 @@ extern "C" { * [window hint](@ref GLFW_SCALE_TO_MONITOR). */ #define GLFW_SCALE_TO_MONITOR 0x0002200C -/*! @brief macOS specific - * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). +/*! @brief Window framebuffer scaling + * [window hint](@ref GLFW_SCALE_FRAMEBUFFER_hint). + */ +#define GLFW_SCALE_FRAMEBUFFER 0x0002200D +/*! @brief Legacy name for compatibility. + * + * This is an alias for the + * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for + * compatibility with earlier versions. */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 /*! @brief macOS specific @@ -1117,6 +1126,9 @@ extern "C" { */ #define GLFW_X11_INSTANCE_NAME 0x00024002 #define GLFW_WIN32_KEYBOARD_MENU 0x00025001 +/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint). + */ +#define GLFW_WIN32_SHOWDEFAULT 0x00025002 /*! @brief Wayland specific * [window hint](@ref GLFW_WAYLAND_APP_ID_hint). * @@ -1164,6 +1176,9 @@ extern "C" { #define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 #define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 +#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001 +#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002 + #define GLFW_ANY_POSITION 0x80000000 /*! @defgroup shapes Standard cursor shapes @@ -1215,11 +1230,11 @@ extern "C" { * @note @macos This shape is provided by a private system API and may fail * with @ref GLFW_CURSOR_UNAVAILABLE in the future. * - * @note @x11 This shape is provided by a newer standard not supported by all - * cursor themes. - * * @note @wayland This shape is provided by a newer standard not supported by * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. */ #define GLFW_RESIZE_NWSE_CURSOR 0x00036007 /*! @brief The top-right to bottom-left diagonal resize/move arrow shape. @@ -1230,11 +1245,11 @@ extern "C" { * @note @macos This shape is provided by a private system API and may fail * with @ref GLFW_CURSOR_UNAVAILABLE in the future. * - * @note @x11 This shape is provided by a newer standard not supported by all - * cursor themes. - * * @note @wayland This shape is provided by a newer standard not supported by * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. */ #define GLFW_RESIZE_NESW_CURSOR 0x00036008 /*! @brief The omni-directional resize/move cursor shape. @@ -1248,11 +1263,11 @@ extern "C" { * The operation-not-allowed shape. This is usually a circle with a diagonal * line through it. * - * @note @x11 This shape is provided by a newer standard not supported by all - * cursor themes. - * * @note @wayland This shape is provided by a newer standard not supported by * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. */ #define GLFW_NOT_ALLOWED_CURSOR 0x0003600A /*! @brief Legacy name for compatibility. @@ -1307,6 +1322,11 @@ extern "C" { * X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint). */ #define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001 +/*! @brief Wayland specific init hint. + * + * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint). + */ +#define GLFW_WAYLAND_LIBDECOR 0x00053001 /*! @} */ /*! @addtogroup init @@ -1406,16 +1426,25 @@ typedef struct GLFWcursor GLFWcursor; * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation * failures gracefully yet. * - * This function may be called during @ref glfwInit but before the library is - * flagged as initialized, as well as during @ref glfwTerminate after the - * library is no longer flagged as initialized. + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. * - * Any memory allocated by this function will be deallocated during library - * termination or earlier. + * Any memory allocated via this function will be deallocated via the same allocator + * during library termination or earlier. + * + * Any memory allocated via this function must be suitably aligned for any object type. + * If you are using C99 or earlier, this alignment is platform-dependent but will be the + * same as what `malloc` provides. If you are using C11 or later, this is the value of + * `alignof(max_align_t)`. * * The size will always be greater than zero. Allocations of size zero are filtered out * before reaching the custom allocator. * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * * @param[in] size The minimum size, in bytes, of the memory block. * @param[in] user The user-defined pointer from the allocator. * @return The address of the newly allocated memory block, or `NULL` if an @@ -1426,7 +1455,8 @@ typedef struct GLFWcursor GLFWcursor; * * @reentrancy This function should not call any GLFW function. * - * @thread_safety This function may be called from any thread that calls GLFW functions. + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. * * @sa @ref init_allocator * @sa @ref GLFWallocator @@ -1449,16 +1479,26 @@ typedef void* (* GLFWallocatefun)(size_t size, void* user); * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation * failures gracefully yet. * - * This function may be called during @ref glfwInit but before the library is - * flagged as initialized, as well as during @ref glfwTerminate after the - * library is no longer flagged as initialized. + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. * - * Any memory allocated by this function will be deallocated during library - * termination or earlier. + * Any memory allocated via this function will be deallocated via the same allocator + * during library termination or earlier. + * + * Any memory allocated via this function must be suitably aligned for any object type. + * If you are using C99 or earlier, this alignment is platform-dependent but will be the + * same as what `realloc` provides. If you are using C11 or later, this is the value of + * `alignof(max_align_t)`. * * The block address will never be `NULL` and the size will always be greater than zero. - * Reallocations of a block to size zero are converted into deallocations. Reallocations - * of `NULL` to a non-zero size are converted into regular allocations. + * Reallocations of a block to size zero are converted into deallocations before reaching + * the custom allocator. Reallocations of `NULL` to a non-zero size are converted into + * regular allocations before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. * * @param[in] block The address of the memory block to reallocate. * @param[in] size The new minimum size, in bytes, of the memory block. @@ -1471,7 +1511,8 @@ typedef void* (* GLFWallocatefun)(size_t size, void* user); * * @reentrancy This function should not call any GLFW function. * - * @thread_safety This function may be called from any thread that calls GLFW functions. + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. * * @sa @ref init_allocator * @sa @ref GLFWallocator @@ -1493,13 +1534,17 @@ typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user); * This function may deallocate the specified memory block. This memory block * will have been allocated with the same allocator. * - * This function may be called during @ref glfwInit but before the library is - * flagged as initialized, as well as during @ref glfwTerminate after the - * library is no longer flagged as initialized. + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. * * The block address will never be `NULL`. Deallocations of `NULL` are filtered out * before reaching the custom allocator. * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * * @param[in] block The address of the memory block to deallocate. * @param[in] user The user-defined pointer from the allocator. * @@ -1508,7 +1553,8 @@ typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user); * * @reentrancy This function should not call any GLFW function. * - * @thread_safety This function may be called from any thread that calls GLFW functions. + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. * * @sa @ref init_allocator * @sa @ref GLFWallocator @@ -2076,7 +2122,10 @@ typedef struct GLFWgamepadstate float axes[6]; } GLFWgamepadstate; -/*! @brief +/*! @brief Custom heap memory allocator. + * + * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it + * to @ref glfwInitAllocator before initializing the library. * * @sa @ref init_allocator * @sa @ref glfwInitAllocator @@ -2087,9 +2136,21 @@ typedef struct GLFWgamepadstate */ typedef struct GLFWallocator { + /*! The memory allocation function. See @ref GLFWallocatefun for details about + * allocation function. + */ GLFWallocatefun allocate; + /*! The memory reallocation function. See @ref GLFWreallocatefun for details about + * reallocation function. + */ GLFWreallocatefun reallocate; + /*! The memory deallocation function. See @ref GLFWdeallocatefun for details about + * deallocation function. + */ GLFWdeallocatefun deallocate; + /*! The user pointer for this custom allocator. This value will be passed to the + * allocator functions. + */ void* user; } GLFWallocator; @@ -2134,6 +2195,13 @@ typedef struct GLFWallocator * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init * hint. * + * @remark __Wayland, X11:__ If the library was compiled with support for both + * Wayland and X11, and the @ref GLFW_PLATFORM init hint is set to + * `GLFW_ANY_PLATFORM`, the `XDG_SESSION_TYPE` environment variable affects + * which platform is picked. If the environment variable is not set, or is set + * to something other than `wayland` or `x11`, the regular detection mechanism + * will be used instead. + * * @remark @x11 This function will set the `LC_CTYPE` category of the * application locale according to the current environment if that category is * still "C". This is because the "C" locale breaks Unicode text input. @@ -2222,8 +2290,12 @@ GLFWAPI void glfwInitHint(int hint, int value); * To use the default allocator, call this function with a `NULL` argument. * * If you specify an allocator struct, every member must be a valid function - * pointer. If any member is `NULL`, this function emits @ref - * GLFW_INVALID_VALUE and the init allocator is unchanged. + * pointer. If any member is `NULL`, this function will emit @ref + * GLFW_INVALID_VALUE and the init allocator will be unchanged. + * + * The functions in the allocator must fulfil a number of requirements. See the + * documentation for @ref GLFWallocatefun, @ref GLFWreallocatefun and @ref + * GLFWdeallocatefun for details. * * @param[in] allocator The allocator to use at the next initialization, or * `NULL` to use the default one. @@ -2590,9 +2662,10 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, * specified monitor. * * Some platforms do not provide accurate monitor size information, either - * because the monitor - * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) - * data is incorrect or because the driver does not report it accurately. + * because the monitor [EDID][] data is incorrect or because the driver does + * not report it accurately. + * + * [EDID]: https://en.wikipedia.org/wiki/Extended_display_identification_data * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. @@ -2639,6 +2712,9 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @wayland Fractional scaling information is not yet available for + * monitors, so this function only returns integer content scales. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_scale @@ -2835,11 +2911,11 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE, + * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -2859,11 +2935,11 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR + * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while * returning `NULL`. * * @pointer_lifetime The returned structure and its arrays are allocated and @@ -2898,8 +2974,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR + * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark The size of the specified gamma ramp should match the size of the * current ramp for that monitor. @@ -2907,7 +2983,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @remark @win32 The gamma ramp size must be 256. * * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * * @pointer_lifetime The specified gamma ramp is copied before this function * returns. @@ -3079,8 +3155,8 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref - * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref - * GLFW_PLATFORM_ERROR. + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark @win32 Window creation will fail if the Microsoft GDI software * OpenGL implementation is the only one available. @@ -3102,23 +3178,35 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * @remark @macos The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the - * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) - * in the Mac Developer Library. + * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. + * + * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * * @remark @macos On OS X 10.10 and later the window frame will not be rendered * at full resolution on Retina displays unless the - * [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint) + * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the * application bundle's `Info.plist`. For more information, see - * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) - * in the Mac Developer Library. The GLFW test and example programs use - * a custom `Info.plist` template for this, which can be found as - * `CMake/Info.plist.in` in the source tree. + * [High Resolution Guidelines for OS X][hidpi-guide] in the Mac Developer + * Library. The GLFW test and example programs use a custom `Info.plist` + * template for this, which can be found as `CMake/Info.plist.in` in the source + * tree. + * + * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html * * @remark @macos When activating frame autosaving with * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified * window size and position may be overridden by previously saved values. * + * @remark @wayland GLFW uses [libdecor][] where available to create its window + * decorations. This in turn uses server-side XDG decorations where available + * and provides high quality client-side decorations on compositors like GNOME. + * If both XDG decorations and libdecor are unavailable, GLFW falls back to + * a very simple set of window decorations that only support moving, resizing + * and the window manager's right-click menu. + * + * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor + * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. * @@ -3135,20 +3223,6 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to * override this. * - * @remark @wayland Compositors should implement the xdg-decoration protocol - * for GLFW to decorate the window properly. If this protocol isn't - * supported, or if the compositor prefers client-side decorations, a very - * simple fallback frame will be drawn using the wp_viewporter protocol. A - * compositor can still emit close, maximize or fullscreen events, using for - * instance a keybind mechanism. If neither of these protocols is supported, - * the window won't be decorated. - * - * @remark @wayland A full screen window will not attempt to change the mode, - * no matter what the requested size or refresh rate. - * - * @remark @wayland Screensaver inhibition requires the idle-inhibit protocol - * to be implemented in the user's compositor. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation @@ -3231,6 +3305,38 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); */ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); +/*! @brief Returns the title of the specified window. + * + * This function returns the window title, encoded as UTF-8, of the specified + * window. This is the title set previously by @ref glfwCreateWindow + * or @ref glfwSetWindowTitle. + * + * @param[in] window The window to query. + * @return The UTF-8 encoded window title, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark The returned title is currently a copy of the title last set by @ref + * glfwCreateWindow or @ref glfwSetWindowTitle. It does not include any + * additional text which may be appended by the platform or another program. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref + * glfwGetWindowTitle or @ref glfwSetWindowTitle, or until the library is + * terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_title + * @sa @ref glfwSetWindowTitle + * + * @since Added in version 3.4. + * + * @ingroup window + */ +GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window); + /*! @brief Sets the title of the specified window. * * This function sets the window title, encoded as UTF-8, of the specified @@ -3248,6 +3354,7 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); * @thread_safety This function must only be called from the main thread. * * @sa @ref window_title + * @sa @ref glfwGetWindowTitle * * @since Added in version 1.0. * @glfw3 Added window handle parameter. @@ -3287,8 +3394,9 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @remark @macos Regular windows do not have icons on macOS. This function * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as * the application bundle's icon. For more information on bundles, see the - * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) - * in the Mac Developer Library. + * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. + * + * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * * @remark @wayland There is no existing protocol to change an icon, the * window will thus inherit the one defined in the application's desktop file. @@ -3512,9 +3620,6 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland A full screen window will not attempt to change the mode, - * no matter what the requested size. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size @@ -3846,11 +3951,11 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * * @param[in] window The window to give input focus. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @remark @wayland It is not possible for an application to set the input - * focus. This function will emit @ref GLFW_FEATURE_UNAVAILABLE. + * @remark @wayland The compositor will likely ignore focus requests unless + * another window created by the same application already has input focus. * * @thread_safety This function must only be called from the main thread. * @@ -3955,9 +4060,6 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @remark @wayland The desired window position is ignored, as there is no way * for an application to set this property. * - * @remark @wayland Setting the window to full screen will not attempt to - * change the mode, no matter what the requested size or refresh rate. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor @@ -4030,11 +4132,15 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark Calling @ref glfwGetWindowAttrib will always return the latest * value, even if that value is ignored by the current mode of the window. * + * @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is + * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs @@ -4709,8 +4815,8 @@ GLFWAPI int glfwRawMouseMotionSupported(void); * @param[in] scancode The scancode of the key to query. * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @remark The contents of the returned string may change when a keyboard * layout change event is received. @@ -4732,15 +4838,18 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode); * * This function returns the platform-specific scancode of the specified key. * - * If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this - * method will return `-1`. + * If the specified [key token](@ref keys) corresponds to a physical key not + * supported on the current platform then this method will return `-1`. + * Calling this function with anything other than a key token will return `-1` + * and generate a @ref GLFW_INVALID_ENUM error. * - * @param[in] key Any [named key](@ref keys). - * @return The platform-specific scancode for the key, or `-1` if an - * [error](@ref error_handling) occurred. + * @param[in] key Any [key token](@ref keys). + * @return The platform-specific scancode for the key, or `-1` if the key is + * not supported on the current platform or an [error](@ref error_handling) + * occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. * * @thread_safety This function may be called from any thread. * @@ -4881,11 +4990,11 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * @param[in] ypos The desired y-coordinate, relative to the top edge of the * content area. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland This function will only work when the cursor mode is - * `GLFW_CURSOR_DISABLED`, otherwise it will do nothing. + * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -5049,9 +5158,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * [character callback](@ref glfwSetCharCallback) instead. * * When a window loses input focus, it will generate synthetic key release - * events for all pressed keys. You can tell these events from user-generated - * events by the fact that the synthetic ones are generated after the focus - * loss event has been processed, i.e. after the + * events for all pressed keys with associated key tokens. You can tell these + * events from user-generated events by the fact that the synthetic ones are + * generated after the focus loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * The scancode of a key is specific to that platform or sometimes even to that @@ -5332,8 +5441,6 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun ca * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @remark @wayland File drop is currently unimplemented. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop @@ -5800,6 +5907,11 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @win32 The clipboard on Windows has a single global lock for reading and + * writing. GLFW tries to acquire it a few times, which is almost always enough. If it + * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. + * It is safe to try this multiple times. + * * @pointer_lifetime The specified string is copied before this function * returns. * @@ -5828,6 +5940,11 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * + * @remark @win32 The clipboard on Windows has a single global lock for reading and + * writing. GLFW tries to acquire it a few times, which is almost always enough. If it + * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. + * It is safe to try this multiple times. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library @@ -5950,12 +6067,15 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void); * thread. * * This function makes the OpenGL or OpenGL ES context of the specified window - * current on the calling thread. A context must only be made current on - * a single thread at a time and each thread can have only a single current - * context at a time. + * current on the calling thread. It can also detach the current context from + * the calling thread without making a new one current by passing in `NULL`. * - * When moving a context between threads, you must make it non-current on the - * old thread before making it current on the new one. + * A context must only be made current on a single thread at a time and each + * thread can have only a single current context at a time. Making a context + * current detaches any previously current context on the calling thread. + * + * When moving a context between threads, you must detach it (make it + * non-current) on the old thread before making it current on the new one. * * By default, making a context non-current implicitly forces a pipeline flush. * On machines that support `GL_KHR_context_flush_control`, you can control @@ -5970,6 +6090,10 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void); * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * + * @remarks If the previously current context was created via a different + * context creation API than the one passed to this function, GLFW will still + * detach the previous one from its API before making the new one current. + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * diff --git a/raylib/external/glfw/include/GLFW/glfw3native.h b/raylib/external/glfw/include/GLFW/glfw3native.h index 171abe3..92f0d32 100644 --- a/raylib/external/glfw/include/GLFW/glfw3native.h +++ b/raylib/external/glfw/include/GLFW/glfw3native.h @@ -169,7 +169,8 @@ extern "C" { * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -186,7 +187,8 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -202,7 +204,8 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @remark The `HDC` associated with the window can be queried with the * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) @@ -228,8 +231,8 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. * * @remark The `HDC` associated with the window can be queried with the * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) @@ -255,7 +258,8 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -271,7 +275,8 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -281,6 +286,23 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @ingroup native */ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); + +/*! @brief Returns the `NSView` of the specified window. + * + * @return The `NSView` of the specified window, or `nil` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.4. + * + * @ingroup native + */ +GLFWAPI id glfwGetCocoaView(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_NSGL) @@ -289,8 +311,8 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -308,7 +330,8 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -324,7 +347,8 @@ GLFWAPI Display* glfwGetX11Display(void); * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -340,7 +364,8 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); * @return The `RROutput` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -356,7 +381,8 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -371,8 +397,8 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); * * @param[in] string A UTF-8 encoded string. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified string is copied before this function * returns. @@ -397,8 +423,8 @@ GLFWAPI void glfwSetX11SelectionString(const char* string); * @return The contents of the selection as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref @@ -424,8 +450,8 @@ GLFWAPI const char* glfwGetX11SelectionString(void); * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -441,8 +467,8 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); * @return The `GLXWindow` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -460,7 +486,8 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); * @return The `struct wl_display*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -476,7 +503,8 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); * @return The `struct wl_output*` of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -492,7 +520,8 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); * @return The main `struct wl_surface*` of the specified window, or `NULL` if * an [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -529,8 +558,8 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -546,8 +575,8 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -572,8 +601,8 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -596,8 +625,8 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -613,8 +642,8 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height * @return The `OSMesaContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized. diff --git a/raylib/external/glfw/src/cocoa_init.m b/raylib/external/glfw/src/cocoa_init.m index aa369f9..e75a551 100644 --- a/raylib/external/glfw/src/cocoa_init.m +++ b/raylib/external/glfw/src/cocoa_init.m @@ -23,10 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" + +#if defined(_GLFW_COCOA) + #include // For MAXPATHLEN // Needed for _NSGetProgname @@ -492,78 +493,78 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform) { const _GLFWplatform cocoa = { - GLFW_PLATFORM_COCOA, - _glfwInitCocoa, - _glfwTerminateCocoa, - _glfwGetCursorPosCocoa, - _glfwSetCursorPosCocoa, - _glfwSetCursorModeCocoa, - _glfwSetRawMouseMotionCocoa, - _glfwRawMouseMotionSupportedCocoa, - _glfwCreateCursorCocoa, - _glfwCreateStandardCursorCocoa, - _glfwDestroyCursorCocoa, - _glfwSetCursorCocoa, - _glfwGetScancodeNameCocoa, - _glfwGetKeyScancodeCocoa, - _glfwSetClipboardStringCocoa, - _glfwGetClipboardStringCocoa, - _glfwInitJoysticksCocoa, - _glfwTerminateJoysticksCocoa, - _glfwPollJoystickCocoa, - _glfwGetMappingNameCocoa, - _glfwUpdateGamepadGUIDCocoa, - _glfwFreeMonitorCocoa, - _glfwGetMonitorPosCocoa, - _glfwGetMonitorContentScaleCocoa, - _glfwGetMonitorWorkareaCocoa, - _glfwGetVideoModesCocoa, - _glfwGetVideoModeCocoa, - _glfwGetGammaRampCocoa, - _glfwSetGammaRampCocoa, - _glfwCreateWindowCocoa, - _glfwDestroyWindowCocoa, - _glfwSetWindowTitleCocoa, - _glfwSetWindowIconCocoa, - _glfwGetWindowPosCocoa, - _glfwSetWindowPosCocoa, - _glfwGetWindowSizeCocoa, - _glfwSetWindowSizeCocoa, - _glfwSetWindowSizeLimitsCocoa, - _glfwSetWindowAspectRatioCocoa, - _glfwGetFramebufferSizeCocoa, - _glfwGetWindowFrameSizeCocoa, - _glfwGetWindowContentScaleCocoa, - _glfwIconifyWindowCocoa, - _glfwRestoreWindowCocoa, - _glfwMaximizeWindowCocoa, - _glfwShowWindowCocoa, - _glfwHideWindowCocoa, - _glfwRequestWindowAttentionCocoa, - _glfwFocusWindowCocoa, - _glfwSetWindowMonitorCocoa, - _glfwWindowFocusedCocoa, - _glfwWindowIconifiedCocoa, - _glfwWindowVisibleCocoa, - _glfwWindowMaximizedCocoa, - _glfwWindowHoveredCocoa, - _glfwFramebufferTransparentCocoa, - _glfwGetWindowOpacityCocoa, - _glfwSetWindowResizableCocoa, - _glfwSetWindowDecoratedCocoa, - _glfwSetWindowFloatingCocoa, - _glfwSetWindowOpacityCocoa, - _glfwSetWindowMousePassthroughCocoa, - _glfwPollEventsCocoa, - _glfwWaitEventsCocoa, - _glfwWaitEventsTimeoutCocoa, - _glfwPostEmptyEventCocoa, - _glfwGetEGLPlatformCocoa, - _glfwGetEGLNativeDisplayCocoa, - _glfwGetEGLNativeWindowCocoa, - _glfwGetRequiredInstanceExtensionsCocoa, - _glfwGetPhysicalDevicePresentationSupportCocoa, - _glfwCreateWindowSurfaceCocoa, + .platformID = GLFW_PLATFORM_COCOA, + .init = _glfwInitCocoa, + .terminate = _glfwTerminateCocoa, + .getCursorPos = _glfwGetCursorPosCocoa, + .setCursorPos = _glfwSetCursorPosCocoa, + .setCursorMode = _glfwSetCursorModeCocoa, + .setRawMouseMotion = _glfwSetRawMouseMotionCocoa, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedCocoa, + .createCursor = _glfwCreateCursorCocoa, + .createStandardCursor = _glfwCreateStandardCursorCocoa, + .destroyCursor = _glfwDestroyCursorCocoa, + .setCursor = _glfwSetCursorCocoa, + .getScancodeName = _glfwGetScancodeNameCocoa, + .getKeyScancode = _glfwGetKeyScancodeCocoa, + .setClipboardString = _glfwSetClipboardStringCocoa, + .getClipboardString = _glfwGetClipboardStringCocoa, + .initJoysticks = _glfwInitJoysticksCocoa, + .terminateJoysticks = _glfwTerminateJoysticksCocoa, + .pollJoystick = _glfwPollJoystickCocoa, + .getMappingName = _glfwGetMappingNameCocoa, + .updateGamepadGUID = _glfwUpdateGamepadGUIDCocoa, + .freeMonitor = _glfwFreeMonitorCocoa, + .getMonitorPos = _glfwGetMonitorPosCocoa, + .getMonitorContentScale = _glfwGetMonitorContentScaleCocoa, + .getMonitorWorkarea = _glfwGetMonitorWorkareaCocoa, + .getVideoModes = _glfwGetVideoModesCocoa, + .getVideoMode = _glfwGetVideoModeCocoa, + .getGammaRamp = _glfwGetGammaRampCocoa, + .setGammaRamp = _glfwSetGammaRampCocoa, + .createWindow = _glfwCreateWindowCocoa, + .destroyWindow = _glfwDestroyWindowCocoa, + .setWindowTitle = _glfwSetWindowTitleCocoa, + .setWindowIcon = _glfwSetWindowIconCocoa, + .getWindowPos = _glfwGetWindowPosCocoa, + .setWindowPos = _glfwSetWindowPosCocoa, + .getWindowSize = _glfwGetWindowSizeCocoa, + .setWindowSize = _glfwSetWindowSizeCocoa, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsCocoa, + .setWindowAspectRatio = _glfwSetWindowAspectRatioCocoa, + .getFramebufferSize = _glfwGetFramebufferSizeCocoa, + .getWindowFrameSize = _glfwGetWindowFrameSizeCocoa, + .getWindowContentScale = _glfwGetWindowContentScaleCocoa, + .iconifyWindow = _glfwIconifyWindowCocoa, + .restoreWindow = _glfwRestoreWindowCocoa, + .maximizeWindow = _glfwMaximizeWindowCocoa, + .showWindow = _glfwShowWindowCocoa, + .hideWindow = _glfwHideWindowCocoa, + .requestWindowAttention = _glfwRequestWindowAttentionCocoa, + .focusWindow = _glfwFocusWindowCocoa, + .setWindowMonitor = _glfwSetWindowMonitorCocoa, + .windowFocused = _glfwWindowFocusedCocoa, + .windowIconified = _glfwWindowIconifiedCocoa, + .windowVisible = _glfwWindowVisibleCocoa, + .windowMaximized = _glfwWindowMaximizedCocoa, + .windowHovered = _glfwWindowHoveredCocoa, + .framebufferTransparent = _glfwFramebufferTransparentCocoa, + .getWindowOpacity = _glfwGetWindowOpacityCocoa, + .setWindowResizable = _glfwSetWindowResizableCocoa, + .setWindowDecorated = _glfwSetWindowDecoratedCocoa, + .setWindowFloating = _glfwSetWindowFloatingCocoa, + .setWindowOpacity = _glfwSetWindowOpacityCocoa, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughCocoa, + .pollEvents = _glfwPollEventsCocoa, + .waitEvents = _glfwWaitEventsCocoa, + .waitEventsTimeout = _glfwWaitEventsTimeoutCocoa, + .postEmptyEvent = _glfwPostEmptyEventCocoa, + .getEGLPlatform = _glfwGetEGLPlatformCocoa, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayCocoa, + .getEGLNativeWindow = _glfwGetEGLNativeWindowCocoa, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsCocoa, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportCocoa, + .createWindowSurface = _glfwCreateWindowSurfaceCocoa }; *platform = cocoa; @@ -690,3 +691,5 @@ void _glfwTerminateCocoa(void) } // autoreleasepool } +#endif // _GLFW_COCOA + diff --git a/raylib/external/glfw/src/cocoa_joystick.h b/raylib/external/glfw/src/cocoa_joystick.h index fc7ba7a..2f46dfc 100644 --- a/raylib/external/glfw/src/cocoa_joystick.h +++ b/raylib/external/glfw/src/cocoa_joystick.h @@ -31,8 +31,6 @@ #define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns; #define GLFW_COCOA_LIBRARY_JOYSTICK_STATE -#define GLFW_BUILD_COCOA_MAPPINGS - // Cocoa-specific per-joystick data // typedef struct _GLFWjoystickNS diff --git a/raylib/external/glfw/src/cocoa_joystick.m b/raylib/external/glfw/src/cocoa_joystick.m index ebcf5fd..d5de479 100644 --- a/raylib/external/glfw/src/cocoa_joystick.m +++ b/raylib/external/glfw/src/cocoa_joystick.m @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include #include @@ -134,6 +134,14 @@ static void matchCallback(void* context, return; } + CFArrayRef elements = + IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); + + // It is reportedly possible for this to fail on macOS 13 Ventura + // if the application does not have input monitoring permissions + if (!elements) + return; + axes = CFArrayCreateMutable(NULL, 0, NULL); buttons = CFArrayCreateMutable(NULL, 0, NULL); hats = CFArrayCreateMutable(NULL, 0, NULL); @@ -177,9 +185,6 @@ static void matchCallback(void* context, name[8], name[9], name[10]); } - CFArrayRef elements = - IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); - for (CFIndex i = 0; i < CFArrayGetCount(elements); i++) { IOHIDElementRef native = (IOHIDElementRef) @@ -476,3 +481,5 @@ void _glfwUpdateGamepadGUIDCocoa(char* guid) } } +#endif // _GLFW_COCOA + diff --git a/raylib/external/glfw/src/cocoa_monitor.m b/raylib/external/glfw/src/cocoa_monitor.m index 64d9eb2..641d5f0 100644 --- a/raylib/external/glfw/src/cocoa_monitor.m +++ b/raylib/external/glfw/src/cocoa_monitor.m @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include #include @@ -549,13 +549,20 @@ GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count) } // autoreleasepool } -void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode) +GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode) { @autoreleasepool { CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID); + if (!native) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to query display mode"); + return GLFW_FALSE; + } + *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate); CGDisplayModeRelease(native); + return GLFW_TRUE; } // autoreleasepool } @@ -622,6 +629,15 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); + + if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized"); + return kCGNullDirectDisplay; + } + return monitor->ns.displayID; } +#endif // _GLFW_COCOA + diff --git a/raylib/external/glfw/src/cocoa_platform.h b/raylib/external/glfw/src/cocoa_platform.h index 9f7d191..3991455 100644 --- a/raylib/external/glfw/src/cocoa_platform.h +++ b/raylib/external/glfw/src/cocoa_platform.h @@ -145,7 +145,7 @@ typedef struct _GLFWwindowNS GLFWbool maximized; GLFWbool occluded; - GLFWbool retina; + GLFWbool scaleFramebuffer; // Cached window properties to filter out duplicate events int width, height; @@ -281,7 +281,7 @@ void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos); void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count); -void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); diff --git a/raylib/external/glfw/src/cocoa_time.c b/raylib/external/glfw/src/cocoa_time.c index c2bf8ed..d56f145 100644 --- a/raylib/external/glfw/src/cocoa_time.c +++ b/raylib/external/glfw/src/cocoa_time.c @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_COCOA_TIMER) + #include @@ -53,3 +53,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void) return _glfw.timer.ns.frequency; } +#endif // GLFW_BUILD_COCOA_TIMER + diff --git a/raylib/external/glfw/src/cocoa_window.m b/raylib/external/glfw/src/cocoa_window.m index daac39b..0dcf0a3 100644 --- a/raylib/external/glfw/src/cocoa_window.m +++ b/raylib/external/glfw/src/cocoa_window.m @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include @@ -309,10 +309,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)windowDidChangeOcclusionState:(NSNotification* )notification { - if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) - window->ns.occluded = GLFW_FALSE; - else - window->ns.occluded = GLFW_TRUE; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 + if ([window->ns.object respondsToSelector:@selector(occlusionState)]) + { + if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) + window->ns.occluded = GLFW_FALSE; + else + window->ns.occluded = GLFW_TRUE; + } +#endif } @end @@ -508,7 +513,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; if (xscale != window->ns.xscale || yscale != window->ns.yscale) { - if (window->ns.retina && window->ns.layer) + if (window->ns.scaleFramebuffer && window->ns.layer) [window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]]; window->ns.xscale = xscale; @@ -867,7 +872,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, [window->ns.object setFrameAutosaveName:@(wndconfig->ns.frameName)]; window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; - window->ns.retina = wndconfig->ns.retina; + window->ns.scaleFramebuffer = wndconfig->scaleFramebuffer; if (fbconfig->transparent) { @@ -1277,7 +1282,7 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, if (window->monitor) { - styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable); styleMask |= NSWindowStyleMaskBorderless; } else @@ -1652,14 +1657,15 @@ const char* _glfwGetScancodeNameCocoa(int scancode) { @autoreleasepool { - if (scancode < 0 || scancode > 0xff || - _glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > 0xff) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } const int key = _glfw.ns.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; UInt32 deadKeyState = 0; UniChar characters[4]; @@ -1963,7 +1969,7 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, return VK_ERROR_EXTENSION_NOT_PRESENT; } - if (window->ns.retina) + if (window->ns.scaleFramebuffer) [window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]]; [window->ns.view setLayer:window->ns.layer]; @@ -2041,9 +2047,26 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) { _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized"); - return NULL; + return nil; } return window->ns.object; } +GLFWAPI id glfwGetCocoaView(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(nil); + + if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "Cocoa: Platform not initialized"); + return nil; + } + + return window->ns.view; +} + +#endif // _GLFW_COCOA + diff --git a/raylib/external/glfw/src/context.c b/raylib/external/glfw/src/context.c index 33b399c..cc1fac4 100644 --- a/raylib/external/glfw/src/context.c +++ b/raylib/external/glfw/src/context.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -363,6 +361,8 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window, previous = _glfwPlatformGetTls(&_glfw.contextSlot); glfwMakeContextCurrent((GLFWwindow*) window); + if (_glfwPlatformGetTls(&_glfw.contextSlot) != window) + return GLFW_FALSE; window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) window->context.getProcAddress("glGetIntegerv"); diff --git a/raylib/external/glfw/src/egl_context.c b/raylib/external/glfw/src/egl_context.c index bc5f3e6..ef65dd3 100644 --- a/raylib/external/glfw/src/egl_context.c +++ b/raylib/external/glfw/src/egl_context.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -88,13 +86,30 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib) // Return the EGLConfig most closely matching the specified hints // static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* desired, + const _GLFWfbconfig* fbconfig, EGLConfig* result) { EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; + int i, nativeCount, usableCount, apiBit; + GLFWbool wrongApiAvailable = GLFW_FALSE; + + if (ctxconfig->client == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major == 1) + apiBit = EGL_OPENGL_ES_BIT; + else + apiBit = EGL_OPENGL_ES2_BIT; + } + else + apiBit = EGL_OPENGL_BIT; + + if (fbconfig->stereo) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported"); + return GLFW_FALSE; + } eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); if (!nativeCount) @@ -132,7 +147,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, if (!vi.visualid) continue; - if (desired->transparent) + if (fbconfig->transparent) { int count; XVisualInfo* vis = @@ -146,23 +161,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, } #endif // _GLFW_X11 - if (ctxconfig->client == GLFW_OPENGL_ES_API) + if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit)) { - if (ctxconfig->major == 1) - { - if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) - continue; - } - else - { - if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) - continue; - } - } - else if (ctxconfig->client == GLFW_OPENGL_API) - { - if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) - continue; + wrongApiAvailable = GLFW_TRUE; + continue; } u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE); @@ -182,22 +184,51 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, // with an alpha channel to ensure the buffer is opaque if (!_glfw.egl.EXT_present_opaque) { - if (!desired->transparent && u->alphaBits > 0) + if (!fbconfig->transparent && u->alphaBits > 0) continue; } } #endif // _GLFW_WAYLAND u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); - u->doublebuffer = desired->doublebuffer; + u->doublebuffer = fbconfig->doublebuffer; u->handle = (uintptr_t) n; usableCount++; } - closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); + closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount); if (closest) *result = (EGLConfig) closest->handle; + else + { + if (wrongApiAvailable) + { + if (ctxconfig->client == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major == 1) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to find support for OpenGL ES 1.x"); + } + else + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to find support for OpenGL ES 2 or later"); + } + } + else + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to find support for OpenGL"); + } + } + else + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "EGL: Failed to find a suitable EGLConfig"); + } + } _glfw_free(nativeConfigs); _glfw_free(usableConfigs); @@ -278,6 +309,7 @@ static int extensionSupportedEGL(const char* extension) static GLFWglproc getProcAddressEGL(const char* procname) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); + assert(window != NULL); if (window->context.egl.client) { @@ -550,11 +582,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, share = ctxconfig->share->context.egl.handle; if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "EGL: Failed to find a suitable EGLConfig"); return GLFW_FALSE; - } if (ctxconfig->client == GLFW_OPENGL_ES_API) { @@ -611,18 +639,18 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; } - if (ctxconfig->noerror) - { - if (_glfw.egl.KHR_create_context_no_error) - SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); - } - if (ctxconfig->major != 1 || ctxconfig->minor != 0) { SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); } + if (ctxconfig->noerror) + { + if (_glfw.egl.KHR_create_context_no_error) + SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); + } + if (mask) SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); @@ -674,8 +702,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (!fbconfig->doublebuffer) SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); - if (_glfw.egl.EXT_present_opaque) - SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); + if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND) + { + if (_glfw.egl.EXT_present_opaque) + SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); + } SET_ATTRIB(EGL_NONE, EGL_NONE); @@ -815,11 +846,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, const long vimask = VisualScreenMask | VisualIDMask; if (!chooseEGLConfig(ctxconfig, fbconfig, &native)) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "EGL: Failed to find a suitable EGLConfig"); return GLFW_FALSE; - } eglGetConfigAttrib(_glfw.egl.display, native, EGL_NATIVE_VISUAL_ID, &visualID); diff --git a/raylib/external/glfw/src/glx_context.c b/raylib/external/glfw/src/glx_context.c index 3c38807..7082682 100644 --- a/raylib/external/glfw/src/glx_context.c +++ b/raylib/external/glfw/src/glx_context.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) + #include #include #include @@ -190,6 +190,7 @@ static void swapBuffersGLX(_GLFWwindow* window) static void swapIntervalGLX(int interval) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); + assert(window != NULL); if (_glfw.glx.EXT_swap_control) { @@ -714,3 +715,5 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) return window->context.glx.window; } +#endif // _GLFW_X11 + diff --git a/raylib/external/glfw/src/init.c b/raylib/external/glfw/src/init.c index d07a492..532264e 100644 --- a/raylib/external/glfw/src/init.c +++ b/raylib/external/glfw/src/init.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -51,16 +49,22 @@ static GLFWerrorfun _glfwErrorCallback; static GLFWallocator _glfwInitAllocator; static _GLFWinitconfig _glfwInitHints = { - GLFW_TRUE, // hat buttons - GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend - GLFW_ANY_PLATFORM, // preferred platform - NULL, // vkGetInstanceProcAddr function + .hatButtons = GLFW_TRUE, + .angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE, + .platformID = GLFW_ANY_PLATFORM, + .vulkanLoader = NULL, + .ns = { - GLFW_TRUE, // macOS menu bar - GLFW_TRUE // macOS bundle chdir + .menubar = GLFW_TRUE, + .chdir = GLFW_TRUE }, + .x11 = { - GLFW_TRUE, // X11 XCB Vulkan surface + .xcbVulkanSurface = GLFW_TRUE, + }, + .wl = + { + .libdecorMode = GLFW_WAYLAND_PREFER_LIBDECOR }, }; @@ -242,30 +246,6 @@ int _glfw_max(int a, int b) return a > b ? a : b; } -float _glfw_fminf(float a, float b) -{ - if (a != a) - return b; - else if (b != b) - return a; - else if (a < b) - return a; - else - return b; -} - -float _glfw_fmaxf(float a, float b) -{ - if (a != a) - return b; - else if (b != b) - return a; - else if (a > b) - return a; - else - return b; -} - void* _glfw_calloc(size_t count, size_t size) { if (count && size) @@ -479,6 +459,9 @@ GLFWAPI void glfwInitHint(int hint, int value) case GLFW_X11_XCB_VULKAN_SURFACE: _glfwInitHints.x11.xcbVulkanSurface = value; return; + case GLFW_WAYLAND_LIBDECOR: + _glfwInitHints.wl.libdecorMode = value; + return; } _glfwInputError(GLFW_INVALID_ENUM, diff --git a/raylib/external/glfw/src/input.c b/raylib/external/glfw/src/input.c index 36128e1..7b3b340 100644 --- a/raylib/external/glfw/src/input.c +++ b/raylib/external/glfw/src/input.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" #include "mappings.h" @@ -462,10 +460,11 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value) assert(hat >= 0); assert(hat < js->hatCount); - // Valid hat values only use the least significant nibble and have at most two bits - // set, which can be considered adjacent plus an arbitrary rotation within the nibble + // Valid hat values only use the least significant nibble assert((value & 0xf0) == 0); - assert((value & ((value << 2) | (value >> 2))) == 0); + // Valid hat values do not have both bits of an axis set + assert((value & GLFW_HAT_LEFT) == 0 || (value & GLFW_HAT_RIGHT) == 0); + assert((value & GLFW_HAT_UP) == 0 || (value & GLFW_HAT_DOWN) == 0); base = js->buttonCount + hat * 4; @@ -701,6 +700,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode) if (key != GLFW_KEY_UNKNOWN) { + if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); + return NULL; + } + if (key != GLFW_KEY_KP_EQUAL && (key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) && (key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2)) @@ -716,12 +721,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode) GLFWAPI int glfwGetKeyScancode(int key) { - _GLFW_REQUIRE_INIT_OR_RETURN(-1); + _GLFW_REQUIRE_INIT_OR_RETURN(0); if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) { _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); - return GLFW_RELEASE; + return -1; } return _glfw.platform.getKeyScancode(key); @@ -1433,7 +1438,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) if (e->type == _GLFW_JOYSTICK_AXIS) { const float value = js->axes[e->index] * e->axisScale + e->axisOffset; - state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f); + state->axes[i] = fminf(fmaxf(value, -1.f), 1.f); } else if (e->type == _GLFW_JOYSTICK_HATBIT) { diff --git a/raylib/external/glfw/src/internal.h b/raylib/external/glfw/src/internal.h index 5aa22f5..8873359 100644 --- a/raylib/external/glfw/src/internal.h +++ b/raylib/external/glfw/src/internal.h @@ -108,12 +108,6 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); -#if defined(_GLFW_WIN32) - #define EGLAPIENTRY __stdcall -#else - #define EGLAPIENTRY -#endif - #define EGL_SUCCESS 0x3000 #define EGL_NOT_INITIALIZED 0x3001 #define EGL_BAD_ACCESS 0x3002 @@ -200,22 +194,22 @@ typedef void* EGLNativeDisplayType; typedef void* EGLNativeWindowType; // EGL function pointer typedefs -typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*); -typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType); -typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum); -typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext); -typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); -typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); -typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); -typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); +typedef EGLBoolean (APIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*); +typedef EGLDisplay (APIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType); +typedef EGLint (APIENTRY * PFN_eglGetError)(void); +typedef EGLBoolean (APIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglTerminate)(EGLDisplay); +typedef EGLBoolean (APIENTRY * PFN_eglBindAPI)(EGLenum); +typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface); +typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext); +typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); +typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); +typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); +typedef const char* (APIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); +typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*); #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib #define eglGetConfigs _glfw.egl.GetConfigs #define eglGetDisplay _glfw.egl.GetDisplay @@ -233,8 +227,8 @@ typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); #define eglQueryString _glfw.egl.QueryString #define eglGetProcAddress _glfw.egl.GetProcAddress -typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*); -typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*); +typedef EGLDisplay (APIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*); +typedef EGLSurface (APIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*); #define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT #define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT @@ -330,12 +324,8 @@ typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const c #include "platform.h" -// Constructs a version number string from the public header macros -#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r -#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r) -#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \ - GLFW_VERSION_MINOR, \ - GLFW_VERSION_REVISION) +#define GLFW_NATIVE_INCLUDE_NONE +#include "../include/GLFW/glfw3native.h" // Checks for whether the library has been initialized #define _GLFW_REQUIRE_INIT() \ @@ -386,6 +376,9 @@ struct _GLFWinitconfig struct { GLFWbool xcbVulkanSurface; } x11; + struct { + int libdecorMode; + } wl; }; // Window configuration @@ -412,8 +405,8 @@ struct _GLFWwndconfig GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool scaleToMonitor; + GLFWbool scaleFramebuffer; struct { - GLFWbool retina; char frameName[256]; } ns; struct { @@ -422,6 +415,7 @@ struct _GLFWwndconfig } x11; struct { GLFWbool keymenu; + GLFWbool showDefault; } win32; struct { char appId[256]; @@ -541,6 +535,7 @@ struct _GLFWwindow GLFWvidmode videoMode; _GLFWmonitor* monitor; _GLFWcursor* cursor; + char* title; int minwidth, minheight; int maxwidth, maxheight; @@ -705,7 +700,7 @@ struct _GLFWplatform void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*); void (*getMonitorWorkarea)(_GLFWmonitor*,int*,int*,int*,int*); GLFWvidmode* (*getVideoModes)(_GLFWmonitor*,int*); - void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*); + GLFWbool (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*); GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*); void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*); // window @@ -1007,8 +1002,6 @@ char** _glfwParseUriList(char* text, int* count); char* _glfw_strdup(const char* source); int _glfw_min(int a, int b); int _glfw_max(int a, int b); -float _glfw_fminf(float a, float b); -float _glfw_fmaxf(float a, float b); void* _glfw_calloc(size_t count, size_t size); void* _glfw_realloc(void* pointer, size_t size); diff --git a/raylib/external/glfw/src/linux_joystick.c b/raylib/external/glfw/src/linux_joystick.c index 366bda2..07d41d3 100644 --- a/raylib/external/glfw/src/linux_joystick.c +++ b/raylib/external/glfw/src/linux_joystick.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + #include #include #include @@ -135,7 +135,7 @@ static GLFWbool openJoystickDevice(const char* path) } _GLFWjoystickLinux linjs = {0}; - linjs.fd = open(path, O_RDONLY | O_NONBLOCK); + linjs.fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (linjs.fd == -1) return GLFW_FALSE; @@ -324,7 +324,8 @@ GLFWbool _glfwInitJoysticksLinux(void) // Continue without device connection notifications if inotify fails - if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0) + _glfw.linjs.regexCompiled = (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) == 0); + if (!_glfw.linjs.regexCompiled) { _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); return GLFW_FALSE; @@ -376,8 +377,10 @@ void _glfwTerminateJoysticksLinux(void) inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch); close(_glfw.linjs.inotify); - regfree(&_glfw.linjs.regex); } + + if (_glfw.linjs.regexCompiled) + regfree(&_glfw.linjs.regex); } GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode) @@ -429,3 +432,5 @@ void _glfwUpdateGamepadGUIDLinux(char* guid) { } +#endif // GLFW_BUILD_LINUX_JOYSTICK + diff --git a/raylib/external/glfw/src/linux_joystick.h b/raylib/external/glfw/src/linux_joystick.h index f898b2b..64462b0 100644 --- a/raylib/external/glfw/src/linux_joystick.h +++ b/raylib/external/glfw/src/linux_joystick.h @@ -31,8 +31,6 @@ #define GLFW_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs; #define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs; -#define GLFW_BUILD_LINUX_MAPPINGS - // Linux-specific joystick data // typedef struct _GLFWjoystickLinux @@ -52,6 +50,7 @@ typedef struct _GLFWlibraryLinux int inotify; int watch; regex_t regex; + GLFWbool regexCompiled; GLFWbool dropped; } _GLFWlibraryLinux; diff --git a/raylib/external/glfw/src/mappings.h b/raylib/external/glfw/src/mappings.h index f3a778b..270fa4c 100644 --- a/raylib/external/glfw/src/mappings.h +++ b/raylib/external/glfw/src/mappings.h @@ -60,82 +60,54 @@ const char* _glfwDefaultMappings[] = { -#if defined(GLFW_BUILD_WIN32_MAPPINGS) -"03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,", -"03000000fa2d00000100000000000000,3dRudder Foot Motion Controller,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,", -"03000000d0160000040d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,", -"03000000d0160000050d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,", -"03000000d0160000060d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,", -"03000000d0160000070d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,", -"03000000d0160000600a000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,", -"03000000c82d00000031000000000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00000531000000000000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00000951000000000000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows,", -"03000000008000000210000000000000,8BitDo F30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"030000003512000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000c82d00001028000000000000,8BitDo F30 Arcade Joystick,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000801000000900000000000000,8BitDo F30 Arcade Stick,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", +#if defined(_GLFW_WIN32) +"03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,", +"03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00000951000000000000,8BitDo Dogbone Modkit,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,", +"03000000c82d000011ab000000000000,8BitDo F30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00001251000000000000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00001151000000000000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000150000000000000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000151000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00005106000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,guide:b2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00000151000000000000,8BitDo M30 ModKit,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,", "03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00000451000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows,", "03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d0000e002000000000000,8BitDo N30,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b6,platform:Windows,", +"03000000c82d00000451000000000000,8BitDo N30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,start:b11,platform:Windows,", "03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000290000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,", -"03000000c82d00003038000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,", -"030000003512000012ab000000000000,8BitDo NES30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Windows,", -"03000000c82d000012ab000000000000,8BitDo NES30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", -"03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00000851000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", +"03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", +"03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000131000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000231000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000331000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000431000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00002867000000000000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b10,x:b3,y:b4,platform:Windows,", +"03000000c82d00002867000000000000,8BitDo S30 Modkit,a:b0,b:b1,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,", "03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", -"03000000102800000900000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00003028000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", -"030000003512000020ab000000000000,8BitDo SN30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a2,rightshoulder:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", +"03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00003028000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00000021000000000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c82d00000351000000000000,8BitDo SN30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000121000000000000,8BitDo SN30 Pro for Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", "03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", -"03000000c82d00001330000000000000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", +"03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,", -"030000008f0e00001200000000000000,Acme GA02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", -"03000000c01100000355000000000000,Acrux,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000fa190000f0ff000000000000,Acteck AGJ 3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000d1180000402c000000000000,ADT1,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a3,rightx:a2,righty:a5,x:b3,y:b4,platform:Windows,", +"03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,", +"03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", +"03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", +"030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", +"03000000c01100000355000011010000,ACRUX USB GAME PAD,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000fa190000f0ff000000000000,Acteck AGJ-3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"030000006f0e00001413000000000000,Afterglow,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", @@ -143,670 +115,310 @@ const char* _glfwDefaultMappings[] = "030000006f0e00001402000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00001301000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e00001302000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e00001304000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e00001413000000000000,Afterglow Xbox Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00003901000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ab1200000103000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b000000f9000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000100000008200000000000000,Akishop Customs PS360,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000007c1800000006000000000000,Alienware Dual Compatible PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", +"03000000d62000001d57000000000000,Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,", "03000000710100001904000000000000,Amazon Luna Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b8,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b4,rightstick:b7,rightx:a3,righty:a4,start:b6,x:b3,y:b2,platform:Windows,", -"03000000830500000160000000000000,Arcade,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b4,platform:Windows,", -"03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000490b00004406000000000000,ASCII Seamic Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"03000000869800002500000000000000,Astro C40 TR PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000050b00000579000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000050b00000679000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000e4150000103f000000000000,Batarang,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000d6200000e557000000000000,Batarang PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000ef0500000300000000000000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,", +"03000000d6200000e557000000000000,Batarang,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,", "030000006f0e00003201000000000000,Battlefield 4 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ad1b000001f9000000000000,BB 070,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000bc2000005250000000000000,Beitong G3,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a3,righty:a4,start:b15,x:b3,y:b4,platform:Windows,", -"030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", "03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000bc2000000055000000000000,Betop BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000bc2000000055000000000000,Betop BFM Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", "03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000bc2000006321000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000bc2000006321000000000000,BETOP CONTROLLER,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000790000000700000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", "03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", -"030000006f0e00006401000000000000,BF One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000300f00000202000000000000,Bigben,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a5,righty:a2,start:b7,x:b2,y:b3,platform:Windows,", -"030000006b1400000209000000000000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006b1400000055000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,", -"03000000120c0000200e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000210e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f10e000000000000,Brook PS2 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,", -"030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,", -"030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,", -"030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"03000000120c0000210e000000000000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", +"03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,", "03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000b0400003365000000000000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,", -"030000004c050000c505000000000000,CronusMax Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000d814000007cd000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000d8140000cefa000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"030000005e040000a102000000000000,Controller (Xbox 360 Wireless Receiver for Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"030000005e040000ff02000000000000,Controller (Xbox One For Windows) - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"030000005e040000ea02000000000000,Controller (Xbox One For Windows) - Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,", -"030000003807000002cb000000000000,Cyborg,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000a306000022f6000000000000,Cyborg V.3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000f806000000a3000000000000,DA Leader,a:b7,b:b6,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b8,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:b3,rightx:a2,righty:a3,start:b12,x:b4,y:b5,platform:Windows,", -"030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", "03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000c0160000e105000000000000,Dual Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,", -"030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", -"030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", -"03000000bd12000002e0000000000000,Dual Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,", -"03000000ff1100003133000000000000,DualForce,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b1,platform:Windows,", +"030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,", +"03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,", "030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,", -"03000000317300000100000000000000,DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"030000006f0e00003001000000000000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000fc0400000250000000000000,Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"030000006e0500000a20000000000000,Elecom DUX60 MMO,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,", +"030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,", "03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,", -"030000006e0500000520000000000000,Elecom P301U PlayStation Controller Adapter,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", -"03000000411200004450000000000000,Elecom U1012,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", -"030000006e0500000320000000000000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", -"030000006e0500000e20000000000000,Elecom U3912T,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", -"030000006e0500000f20000000000000,Elecom U4013S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", -"030000006e0500001320000000000000,Elecom U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006e0500001020000000000000,Elecom U4113S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,", -"030000006e0500000720000000000000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,", -"030000007d0400000640000000000000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Windows,", "03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,", -"03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", "030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,", -"03000000341a00000108000000000000,EXEQ RF Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"030000006f0e00008401000000000000,Faceoff Deluxe Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00008001000000000000,Faceoff Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000021000000090000000000000,FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", -"0300000011040000c600000000000000,FC801,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000852100000201000000000000,FF GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ad1b000028f0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b00002ef0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b000038f0000000000000,Fightpad TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,", -"03000000f806000001a3000000000000,Firestorm,a:b9,b:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b10,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b12,x:b8,y:b4,platform:Windows,", -"03000000b50700000399000000000000,Firestorm 2,a:b2,b:b4,back:b10,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b9,start:b11,x:b3,y:b5,platform:Windows,", -"03000000b50700001302000000000000,Firestorm D3,a:b0,b:b2,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,x:b1,y:b3,platform:Windows,", -"03000000b40400001024000000000000,Flydigi Apex,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,platform:Windows,", -"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,", -"03000000b40400001224000000000000,Flydigi Vader 2 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,paddle3:b17,paddle4:b18,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,", -"030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,", +"03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,", +"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,", +"03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,", -"03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,", -"03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows,", -"03000000430b00000500000000000000,GameCube Controller,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows,", -"03000000790000004718000000000000,GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", -"03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", -"030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"0300000047530000616d000000000000,GameStop,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,", +"03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", +"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000ac0500004d04000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,", -"030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000c9110000f055000000000000,GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"030000009b2800003200000000000000,GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,", +"030000009b2800006000000000000000,GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,", "030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", -"03000000300f00000b01000000000000,GGE909 Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000f0250000c283000000000000,Gioteck PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", +"03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000f025000031c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000f0250000c383000000000000,Gioteck VX2 PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000f0250000c483000000000000,Gioteck VX2 PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"030000004f04000026b3000000000000,GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"0300000079000000d418000000000000,GPD Win,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c6240000025b000000000000,GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000007d0400000840000000000000,Gravis Destroyer Tilt,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,", -"030000007d0400000540000000000000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"03000000280400000140000000000000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a3,dpup:-a4,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows,", -"03000000ac0500006b05000000000000,GT2a,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", +"03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", "03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00004900000000000000,Hatsune Miku Sho PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,", -"030000000d0f00000c00000000000000,HEXT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000d81400000862000000000000,HitBox Edition Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,", -"03000000632500002605000000000000,HJD X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"030000000d0f00000a00000000000000,Hori DOA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f00008500000000000000,Hori Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00002500000000000000,Hori Fighting Commander 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,", +"03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,", +"03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", "030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00008400000000000000,Hori Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00005100000000000000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00008600000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f0000ba00000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f00008800000000000000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,", -"030000000d0f00008700000000000000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00001000000000000000,Hori Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00003200000000000000,Hori Fightstick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000c000000000000000,Hori Fightstick 4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f00000d00000000000000,Hori Fightstick EX2,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"030000000d0f00003701000000000000,Hori Fightstick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Windows,", -"030000000d0f00004000000000000000,Hori Fightstick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00002100000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00002700000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000a000000000000000,Hori Grip TAC4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b13,x:b0,y:b3,platform:Windows,", -"030000000d0f0000a500000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000a600000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00000101000000000000,Hori Mini Hatsune Miku FT,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,", "030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00003801000000000000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Windows,", -"030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00002301000000000000,Hori PS4 Controller Light,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"030000000d0f00001100000000000000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00002600000000000000,Hori Real Arcade Pro 3P,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00004b00000000000000,Hori Real Arcade Pro 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00008a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00008b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006f00000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00007000000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00003d00000000000000,Hori Real Arcade Pro N3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b4,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b6,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000ae00000000000000,Hori Real Arcade Pro N4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f00008c00000000000000,Hori Real Arcade Pro P4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f0000aa00000000000000,Hori Real Arcade Pro S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000d800000000000000,Hori Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,", -"030000000d0f00002200000000000000,Hori Real Arcade Pro V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00005b00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00005c00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000af00000000000000,Hori Real Arcade Pro VHS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00001b00000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b000002f5000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Windows,", +"030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00001600000000007803,HORI Real Arcade Pro EX-SE (Xbox 360),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,", "030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000c900000000000000,Hori Taiko Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006400000000000000,Horipad 3TP,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00001300000000000000,Horipad 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "030000000d0f00005500000000000000,Horipad 4 FPS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006e00000000000000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006600000000000000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00004200000000000000,Horipad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ad1b000001f5000000000000,Horipad EXT2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,", "030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,", -"03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,", -"03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,", -"03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"030000005c0a00000285000000000000,iDroidCon,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b6,platform:Windows,", -"03000000696400006964000000000000,iDroidCon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,", "03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", -"030000006f0e00002401000000000000,Injustice Fightstick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"03000000ef0500000300000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,", -"03000000fd0500000230000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,", -"03000000fd0500000030000000000000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,", -"03000000fd0500003902000000000000,InterAct Hammerhead,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,rightshoulder:b7,rightstick:b5,righttrigger:b9,start:b10,x:b0,y:b1,platform:Windows,", -"03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,", -"03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,", -"03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,", -"03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000491900000204000000000000,Ipega PG9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,", +"030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"03000000ac0500002c02000000000000,IPEGA,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000491900000304000000000000,Ipega PG-9087 - Bluetooth Gamepad,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,", +"030000006e0500000a20000000000000,JC-DUX60 ELECOM MMO Gamepad,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,", +"030000006e0500000520000000000000,JC-P301U,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", +"030000006e0500000320000000000000,JC-U3613M (DInput),a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,", +"030000006e0500000720000000000000,JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,", "030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,", +"030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,", "030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,", -"03000000250900000017000000000000,Joypad Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,", -"03000000bd12000003c0000000000000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ff1100004033000000000000,JPD FFB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a2,start:b15,x:b3,y:b0,platform:Windows,", -"03000000242f00002d00000000000000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"03000000242f00008a00000000000000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,", -"03000000c4100000c082000000000000,KADE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000828200000180000000000000,Keio,a:b4,b:b5,back:b8,leftshoulder:b2,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b1,platform:Windows,", +"030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,", +"03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000bd12000003c0000000000000,JY-P70UR,a:b1,b:b0,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b4,x:b3,y:b2,platform:Windows,", +"03000000242f00002d00000000000000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000242f00008a00000000000000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,", "03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", -"03000000bd12000001e0000000000000,Leadership,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"030000006f0e00000103000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e00000104000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000008f0e00001300000000000000,Logic3,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,", "030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006d0400001ec2000000000000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006d04000019c2000000000000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006d0400001ac2000000000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,", -"030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,", +"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", "030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,", -"03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700003888000000000000,Mad Catz Arcade Fightstick TE S Plus PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008532000000000000,Mad Catz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700006352000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700006652000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700005032000000000000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700005082000000000000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008031000000000000,Mad Catz FightStick Alpha PS3 ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000003807000038b7000000000000,Mad Catz Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700008433000000000000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008483000000000000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008134000000000000,Mad Catz Fightstick TE2 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008184000000000000,Mad Catz Fightstick TE2 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700006252000000000000,Mad Catz Micro CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008232000000000000,Mad Catz PlayStation Brawlpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700008731000000000000,Mad Catz PlayStation Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000003807000056a8000000000000,Mad Catz PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700001888000000000000,Mad Catz SFIV Fightstick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000380700008081000000000000,Mad Catz SFV Arcade Fightstick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700001847000000000000,Mad Catz Street Fighter 4 Xbox 360 FightStick,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,", +"03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700008433000000000000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700008483000000000000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700006252000000000000,Mad Catz Micro C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", "03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,", "030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", "03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,", -"03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", -"03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", +"03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", "03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,", "0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000008f0e00001030000000000000,Mayflash Sega Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,", -"0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,", -"03000000790000000318000000000000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,", -"03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000790000002418000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,", -"0300000079000000ae18000000000000,Mega Drive Controller,a:b0,b:b1,back:b7,dpdown:b14,dpleft:b15,dpright:b13,dpup:b2,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"03000000c0160000990a000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,righttrigger:b2,start:b3,platform:Windows,", -"030000005e0400002800000000000000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Windows,", -"030000005e0400000300000000000000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,", -"030000005e0400000700000000000000,Microsoft SideWinder,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"030000005e0400000e00000000000000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,", -"030000005e0400002700000000000000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Windows,", -"03000000280d00000202000000000000,Miller Lite Cantroller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b5,x:b2,y:b3,platform:Windows,", -"03000000ad1b000023f0000000000000,MLG,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a6,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"03000000ad1b00003ef0000000000000,MLG Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700006382000000000000,MLG PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ffff00000000000000000000,Mocute M053,a:b3,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b11,leftstick:b7,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b6,righttrigger:b4,rightx:a3,righty:a4,start:b8,x:b1,y:b0,platform:Windows,", -"03000000d6200000e589000000000000,Moga 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000d62000007162000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000d6200000ad0d000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c62400002a89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c62400002b89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c62400001a89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c62400001b89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,", +"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,", +"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000790000002418000000000000,Mega Drive,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,", +"03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", "03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", "03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,", -"03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,", -"030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000006b140000100d000000000000,Nacon Revolution Infinity PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006b140000080d000000000000,Nacon Revolution Unlimited Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000bd12000001c0000000000000,Nebular,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000eb0300000000000000000000,NeGcon Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows,", -"0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,", -"03000000921200004b46000000000000,NES 2 port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,", -"03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,", -"03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,", -"03000000790000004518000000000000,NEXILUX GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", +"030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"03000000921200004b46000000000000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,", +"03000000790000004518000000000000,NEXILUX GAMECUBE Controller Adapter,platform:Windows,a:b1,b:b0,x:b2,y:b3,start:b9,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,", "030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,", -"03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,", "03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", -"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,", +"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,", -"030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,", -"030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows,", -"03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,", -"03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,", -"030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"030000004b120000014d000000000000,Nyko Airflo,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,", -"03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,", -"030000000d0f00000401000000000000,Onyx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000008916000001fd000000000000,Onza CE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a3,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"03000000550900001472000000000000,NVIDIA Controller v01.04,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,", +"030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,", +"03000000d620000013a7000000000000,NSW wired controller,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", +"03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,", "03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,", -"03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,", -"03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,", -"03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b0,platform:Windows,", -"030000006f0e00000901000000000000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows,", -"03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", +"03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,", +"03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,", +"030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", "030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000632500002306000000000000,PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,", -"03000000f0250000c183000000000000,PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", "030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", "03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000d620000013a7000000000000,PowerA Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", "03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000c62400001a53000000000000,Pro Ex Mini,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "03000000d62000009f31000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000d6200000c757000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000110e000000000000,Pro5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,", +"03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", "03000000100800000100000000000000,PS1 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", "030000008f0e00007530000000000000,PS1 Controller,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000100800000300000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000250900000088000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"03000000250900006888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b6,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", "03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", "03000000666600006706000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,", "030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", "030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000151a00006222000000000000,PS2 Dual Plus Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f90e000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000250900000118000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"03000000250900000218000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", "03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,", "030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,", -"030000004f1f00000800000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", "03000000632500007505000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,", -"03000000888800000804000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b10,leftstick:b1,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,", -"030000008f0e00000300000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,", "030000008f0e00001431000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000ba2200002010000000000000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Windows,", -"03000000120c00000807000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000111e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000121e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000130e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000150e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000180e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000181e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000191e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c00001e0e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000a957000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000aa57000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f21c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f31c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f41c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f51c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120c0000f70e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000120e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000160e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000001a1e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000003807000056a8000000000000,PS3 RF pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", "030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,", +"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,", -"03000000830500005020000000000000,PSX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Windows,", -"03000000300f00000111000000000000,Qanba 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000300f00000211000000000000,Qanba 2P,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000300f00000011000000000000,Qanba Arcade Stick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,", -"03000000300f00001611000000000000,Qanba Arcade Stick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,", -"03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000222c00000020000000000000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000300f00001211000000000000,Qanba Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000300f00001210000000000000,Qanba Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,", -"03000000341a00000104000000000000,Qanba Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,", -"03000000222c00000223000000000000,Qanba Obsidian Arcade Stick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000222c00000023000000000000,Qanba Obsidian Arcade Stick PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000008a2400006682000000000000,R1 Mobile Controller,a:b3,b:b1,back:b7,leftx:a0,lefty:a1,start:b6,x:b4,y:b0,platform:Windows,", -"03000000086700006626000000000000,RadioShack,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000ff1100004733000000000000,Ramox FPS Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,", -"030000009b2800002300000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,", -"030000009b2800006900000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,", -"030000009b2800000800000000000000,Raphnet Dreamcast Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows,", -"030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,", -"030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,", -"030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,", -"030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,", -"030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,", -"030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,", -"030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,", -"030000009b2800000300000000000000,Raphnet SNES Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,", -"030000009b2800005600000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,", -"030000009b2800005700000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,", -"030000009b2800001e00000000000000,Raphnet Vectrex Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a1,lefty:a2,x:b2,y:b3,platform:Windows,", -"030000009b2800002b00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,", -"030000009b2800002c00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,", +"030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000ff000000cb01000000000000,PSP,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,", +"03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,", +"03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,", +"03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,", +"03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,", +"03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,", +"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000321500000204000000000000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000321500000104000000000000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000321500000010000000000000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", "03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000321500000710000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000321500000a10000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000321500000410000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,", -"03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,", -"03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,", -"03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,", -"0300000000f000000300000000000000,RetroUSB RetroPad,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,", -"0300000000f00000f100000000000000,RetroUSB Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,", -"03000000830500000960000000000000,Revenger,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b5,platform:Windows,", +"030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,", +"03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,", +"0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,", +"0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,", "030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000006b140000020d000000000000,Revolution Pro Controller 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000006b140000020d000000000000,Revolution Pro Controller 2(1/2),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00001f01000000000000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e00004601000000000000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c6240000fefa000000000000,Rock Candy Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00008701000000000000,Rock Candy Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,", -"03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,", -"03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,", -"03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,", -"03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,", -"03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,", -"030000004f04000001d0000000000000,Rumble Force,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", -"030000008916000000fe000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c6240000045d000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", +"030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000a306000023f6000000000000,Saitek Cyborg V.1 Game,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000300f00001201000000000000,Saitek Dual Analog,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", +"03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", +"03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", "03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows,", -"03000000a30600000cff000000000000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,", -"03000000a30600000d5f000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,", -"03000000a30600000dff000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b8,x:b0,y:b3,platform:Windows,", +"03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,", "03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", -"03000000a306000018f5000000000000,Saitek P3200,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000300f00001001000000000000,Saitek P480 Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", -"03000000a30600000901000000000000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b5,rightx:a3,righty:a2,x:b0,y:b1,platform:Windows,", +"03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", "03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,", -"03000000a30600002106000000000000,Saitek PS1000 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000a306000020f6000000000000,Saitek PS2700 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", -"03000000300f00001101000000000000,Saitek Rumble,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", -"03000000e804000000a0000000000000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000c01100000252000000000000,Sanwa Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"03000000c01100004350000000000000,Sanwa Micro Grip P3,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,x:b3,y:b2,platform:Windows,", -"03000000411200004550000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a1,righty:a2,start:b9,x:b1,y:b3,platform:Windows,", -"03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", -"03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b14,x:b3,y:b4,platform:Windows,", -"03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,", -"03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows,", -"03000000c01100000051000000000000,Satechi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000a30c00002500000000000000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows,", -"03000000a30c00002400000000000000,Sega Mega Drive Mini 6B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", -"0300000000050000289b000000000000,Sega Saturn Adapter,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,", -"0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows,", -"03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,", -"03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,", -"030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,", -"03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"0300000003040000c197000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,", -"0300000081170000960a000000000000,SNES Controller,a:b4,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b5,y:b1,platform:Windows,", -"03000000811700009d0a000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,", -"030000008b2800000300000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,", -"03000000921200004653000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,", -"03000000ff000000cb01000000000000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000341a00000208000000000000,Speedlink 6555,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,", -"03000000341a00000908000000000000,Speedlink 6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000380700001722000000000000,Speedlink Competition Pro,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,x:b2,y:b3,platform:Windows,", -"030000008f0e00000800000000000000,Speedlink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,", +"03000000a30600002106000000000000,Saitek PS1000,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", +"03000000a306000020f6000000000000,Saitek PS2700,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,", +"03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", +"03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,", +"0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,", +"030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000a30c00002500000000000000,Sega Genesis Mini 3B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows,", +"03000000a30c00002400000000000000,Sega Mega Drive Mini 6B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,", +"03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,", +"03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,", -"03000000de280000fc11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000120c0000160e000000000000,Steel Play Metaltech PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", "03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,", "03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,", -"03000000790000001c18000000000000,STK 7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000380700003847000000000000,Street Fighter Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,", -"030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000341200001300000000000000,Super Racer,a:b2,b:b3,back:b8,leftshoulder:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b7,x:b0,y:b1,platform:Windows,", -"03000000d620000011a7000000000000,Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000000d0f0000f600000000000000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,", -"030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000e40a00000207000000000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows,", -"03000000d814000001a0000000000000,TE Kitty,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000790000001c18000000000000,STK-7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,", +"03000000d620000011a7000000000000,Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000457500002211000000000000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000004f04000007d0000000000000,T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"030000004f0400000ab1000000000000,T.16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,", "03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", -"03000000ba2200000701000000000000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b2,platform:Windows,", -"03000000c61100001000000000000000,Tencent Xianyou Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,", -"03000000790000002601000000000000,TGZ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,", "030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", -"030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000004f04000008d0000000000000,ThrustMaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"030000004f0400000ed0000000000000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,", -"030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", -"030000004f04000003d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000004f04000009d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"03000000666600000288000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"030000004f04000007d0000000000000,TMini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000571d00002100000000000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Windows,", -"03000000571d00002000000000000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,", +"030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,", +"03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", "03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", -"03000000c01100000055000000000000,Tronsmart,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,", -"03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows,", -"03000000d90400000200000000000000,TwinShock PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000151900005678000000000000,Uniplay U6,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b10,x:b3,y:b4,platform:Windows,", +"03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", +"030000006e0500001320000000000000,U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", -"030000000b0400003065000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000242f00006e00000000000000,USB Controller,a:b1,b:b4,back:b10,leftshoulder:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b3,platform:Windows,", -"03000000300f00000701000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000341a00002308000000000000,USB Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000666600000188000000000000,USB Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,", -"030000006b1400000203000000000000,USB Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000790000000a00000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", -"03000000b404000081c6000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,", -"03000000b50700001503000000000000,USB Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b0,y:b1,platform:Windows,", -"03000000bd12000012d0000000000000,USB Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", +"03000000341a00002308000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"030000005509000000b4000000000000,USB gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,platform:Windows,", +"030000006b1400000203000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"03000000790000000a00000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,", +"03000000f0250000c183000000000000,USB gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", +"03000000ff1100004133000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", +"03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", "03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,", "03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00000302000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", -"030000006f0e00000702000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000006f0e00000302000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", +"030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,", "0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows,", -"03000000120c0000ab57000000000000,Warrior Joypad JS083,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"030000007e0500003003000000000000,Wii U Pro,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b6,leftstick:b11,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b12,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,", -"0300000032150000030a000000000000,Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"0300000032150000140a000000000000,Wolverine,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000002e160000efbe000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700001647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700002045000000000000,Xbox 360 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", -"03000000380700002644000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a5,start:b8,x:b2,y:b3,platform:Windows,", -"03000000380700002647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000003807000026b7000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700003647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a7,righty:a5,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e0400001907000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e0400009102000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b000000fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b000001fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b000016f0000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000ad1b00008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000a102000000000000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"03000000120c00001088000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2~,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5~,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000002a0600002000000000000000,Xbox Controller,a:b0,b:b1,back:b13,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b5,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b15,righttrigger:b7,rightx:a2,righty:a5,start:b12,x:b2,y:b3,platform:Windows,", -"03000000300f00008888000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:b13,dpleft:b10,dpright:b11,dpup:b12,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"03000000380700001645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"03000000380700002645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000380700003645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"03000000380700008645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e0400000202000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"030000005e0400008502000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e0400008702000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"030000005e0400008902000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b8,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b9,righttrigger:b4,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,", -"030000000d0f00006300000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e0400000c0b000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000fd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000005e040000ff02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e0000a802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000006f0e0000c802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"03000000c62400003a54000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", "03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"03000000450c00002043000000000000,Xeox SL6556BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", -"030000006f0e00000300000000000000,XGear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,", -"03000000172700004431000000000000,Xiaomi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", -"03000000172700003350000000000000,Xiaomi XMGP01YM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000bc2000005060000000000000,Xiaomi XMGP01YM,+lefty:+a2,+righty:+a5,-lefty:-a1,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,", +"03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,", +"03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,", +"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,", "03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,", -"030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,", -"03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", -"03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,", -"03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", +"03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,", +"03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,", "78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", @@ -814,281 +426,198 @@ const char* _glfwDefaultMappings[] = "78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", -#endif // GLFW_BUILD_WIN32_MAPPINGS +#endif // _GLFW_WIN32 -#if defined(GLFW_BUILD_COCOA_MAPPINGS) -"030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", -"03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00000531000000020000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X,", +#if defined(_GLFW_COCOA) +"030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00001251000000020000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00001151000000020000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000a30c00002400000006020000,8BitDo M30,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,guide:b9,leftshoulder:b6,lefttrigger:b5,rightshoulder:b4,righttrigger:b7,start:b8,x:b3,y:b0,platform:Mac OS X,", -"03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", "03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00005106000000010000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,lefttrigger:a5,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X,", +"03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"030000003512000012ab000001000000,8BitDo NES30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d000012ab000001000000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00002028000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000022000000090000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000190000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000431000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Mac OS X,", -"03000000102800000900000000000000,8BitDo SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", +"030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000c82d00004028000000010000,8Bitdo SN30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,platform:Mac OS X,", "03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000a00500003232000009010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,", -"03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,", -"03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,", -"03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", +"03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,", -"03000000050b00000579000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,", -"03000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,", +"03000000ef0500000300000000020000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,", +"03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,", +"03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,", "03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,", "03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", "03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000120c0000200e000000010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000120c0000210e000000010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,", -"03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000791d00000103000009010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", -"030000006e0500000720000010020000,Elecom JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Mac OS X,", -"030000006f0e00008401000003010000,Faceoff Premiere Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,", -"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Mac OS X,", +"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,", -"03000000ad1b000001f9000000000000,Gamestop BB070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,", "03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000006f0e00000102000000000000,GameStop Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000007d0400000540000001010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000280400000140000000020000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000008f0e00000300000007010000,GreenAsia Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,", +"030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000280400000140000000020000,Gravis Gamepad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000008f0e00000300000007010000,GreenAsia Inc. USB Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,", "030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00008400000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00008500000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00008800000000010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00008700000000010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00004d00000000000000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X,", -"030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00006e00000000010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00006600000000010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f00006600000000000000,Horipad FPS Plus 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000000d0f0000ee00000000010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000000d0f0000ee00000000010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,", -"03000000790000004e95000000010000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,", -"03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,", -"03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,", -"03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,", +"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,", +"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,", "030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,", "030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,", -"03000000242f00002d00000007010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", -"030000006d04000019c2000000000000,Logitech Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000242f00002d00000007010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", "030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000006d04000016c2000000000000,Logitech F310,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000006d04000018c2000000010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000380700005032000000010000,Mad Catz PS3 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000380700008433000000010000,Mad Catz PS3 Fightstick TE S+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000380700005082000000010000,Mad Catz PS4 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000380700008483000000010000,Mad Catz PS4 Fightstick TE S+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", -"03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,", +"030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000006d04000018c2000000010000,Logitech RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000380700008433000000010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000380700008483000000010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,", "03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,", "0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,", -"03000000790000000318000000010000,Mayflash Wii DolphinBar,a:b8,b:b12,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b44,leftshoulder:b16,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b4,platform:Mac OS X,", -"03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,", -"03000000790000000018000000010000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,", -"030000005e0400002800000002010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Mac OS X,", -"030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,", -"03000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,", -"03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,", +"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,", +"03000000790000000018000000010000,Mayflash Wii U Pro Controller Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,", +"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,", +"03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000005e0400002700000001010000,Microsoft SideWinder Plug & Play Game Pad,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,", +"03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,", +"03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000c62400002b89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,", "03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X,", "030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X,", -"03000000d620000011a7000000020000,Nintendo Switch Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000d620000011a7000010050000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000d620000011a7000000020000,Nintendo Switch Core (Plus) Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000d620000011a7000010050000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,", "030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,", -"030000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Mac OS X,", -"030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,", -"03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,", -"030000006f0e00000901000002010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,", -"030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", +"03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,", +"030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,", +"030000004c050000da0c000000010000,Playstation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", "030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", "030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,", "030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,", -"030000004c0500006802000072050000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,", "030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,", -"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,", -"03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000222c00000020000000010000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"03000000321500000204000000010000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000321500000104000000010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000321500000010000000010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000321500000011000000010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000321500000011000000010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,", "030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,", "0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"03000000632500008005000000010000,Redgear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", -"030000000d0f0000c100000072050000,Retro Bit Sega Genesis 6B Controller,a:b2,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b8,rightshoulder:b6,righttrigger:b7,start:b9,x:b3,y:b0,platform:Mac OS X,", -"03000000921200004547000000020000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b2,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,lefttrigger:b14,rightshoulder:b10,righttrigger:b4,start:b12,x:b6,y:b8,platform:Mac OS X,", -"03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,", +"03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", "030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000c6240000fefa000000000000,Rock Candy PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Mac OS X,", -"03000000a30c00002500000006020000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Mac OS X,", +"03000000c6240000fefa000000000000,Rock Candy Gamepad for PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X,", "03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,", -"03000000b40400000a01000000000000,Sega Saturn,a:b0,b:b1,back:b5,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,", -"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", +"03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,", +"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,", "0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,", -"030000004c050000a00b000000000000,Sony DualShock 4 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000004c050000e60c000000010000,Sony DualSense,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,", "030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,", +"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,", "03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,", "03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,", -"05000000484944204465766963650000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,", "050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,", -"050000004e696d6275732b008b000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,", -"05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,", -"03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", "03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,", "03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,", -"030000000d0f0000f600000000010000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,", -"03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000457500002211000000010000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,", -"030000004f0400000ed0000000020000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000004f0400000ed0000000020000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,", -"03000000571d00002100000021000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Mac OS X,", -"03000000bd12000015d0000000010000,Tomee Retro Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", -"03000000bd12000015d0000000000000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", -"03000000571d00002000000021000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,", -"030000005f140000c501000000020000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", +"03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", +"03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,", -"030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", -"030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000006f0e00000302000025040000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"030000006f0e00000702000003060000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", "050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,", "050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,", -"030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000006f0e00000104000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"03000000c6240000045d000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000006f0e00000104000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", "030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000005e040000050b000003090000,Xbox Elite Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"030000005e040000130b000011050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"030000005e040000200b000011050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,", -"030000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", -"030000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000c62400003a54000000000000,Xbox One PowerA Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000050b000003090000,Xbox Elite Wireless Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000c62400003a54000000000000,Xbox One PowerA Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", "030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", "030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"030000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"030000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,", -"03000000120c0000100e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -"03000000120c0000101e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -#endif // GLFW_BUILD_COCOA_MAPPINGS +"030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,", +"030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,", +"03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +"03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", +#endif // _GLFW_COCOA -#if defined(GLFW_BUILD_LINUX_MAPPINGS) -"030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,", -"03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", +#if defined(GLFW_BUILD_LINUX_JOYSTICK) "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux,", +"05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,", -"03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,", "03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", "03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,", "05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,", -"03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux,", +"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", +"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", +"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", +"03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,", -"030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", -"05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", -"05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", +"05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", +"03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", +"030000003512000012ab000010010000,8Bitdo SFC30 GamePad,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,", +"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", +"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", "03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,", "03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,", @@ -1097,272 +626,219 @@ const char* _glfwDefaultMappings[] = "05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", -"05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,", -"05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,", -"03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", -"050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,", +"05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", +"03000000c82d00000031000011010000,8BitDo Wireless Adapter (DInput),a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000005e0400008e02000020010000,8BitDo Wireless Adapter (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", -"03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"050000005e040000e002000030110000,8BitDo Zero 2 (XInput),a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,", +"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,", +"05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,", +"03000000c01100000355000011010000,ACRUX USB GAME PAD,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000006f0e00001302000000010000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006f0e00003901000020060000,Afterglow Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e00001302000000010000,Afterglow Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e00003901000020060000,Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000100000008200000011010000,Akishop Customs PS360,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000007c1800000006000010010000,Alienware Dual Compatible Game PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,", -"05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,", +"05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,", "05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", "03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", +"03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", "03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", "05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,", "05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,", -"03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,", -"03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,", -"05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,", -"05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,", -"05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,", -"03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux,", -"03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,", -"05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,", -"05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,", -"05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,", -"05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux,", -"03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,", +"05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,", +"03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,", +"05000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,", +"03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,", +"03000000ef0500000300000000010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,", +"03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000666600006706000000010000,Boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,", -"03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,", +"03000000120c0000200e000011010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000120c0000210e000011010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", "03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", "030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,", "03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,", -"03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", -"03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", +"03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,", +"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,", +"030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", "030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,", -"030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,", -"030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux,", -"03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", -"03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,", "03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", "030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,", -"030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", +"030000007d0400000540000000010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,", +"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", "0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", "03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,", -"03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,", -"030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,", -"030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,", +"03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"03000000632500002605000010010000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,", +"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f0000c100000011010000,HORI CO. LTD. HORIPAD S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00008500000010010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux,", -"030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,", -"030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", +"030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,", +"030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f0000ee00000011010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,", "03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,", -"050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,", -"03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,", -"03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,", -"03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,", -"03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux,", -"03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,", -"0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,", -"03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", -"03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", +"050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,", +"03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,", +"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,", +"0500000049190000020400001b010000,Ipega PG-9069 - Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"03000000632500007505000011010000,Ipega PG-9099 - Bluetooth Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,", +"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,", +"03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", +"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", "030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,", "050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,", "030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,", "050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,", "03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000242f00002d00000011010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000242f00008a00000011010000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,", +"03000000242f00002d00000011010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,", "030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006d0400001ec2000019200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006d0400001ec2000020200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006d0400001ec2000019200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,", "030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,", -"030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,", -"05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700005082000011010000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"050000004d4f435554452d3035305800,M54-PC,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,", -"03000000380700008034000011010000,Mad Catz Fightstick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700008084000011010000,Mad Catz Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700008433000011010000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700008483000011010000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700001888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700003888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700008433000011010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700008483000011010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", "03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000242f0000f700000001010000,Magic-S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", -"03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", "03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", +"03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,", "03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,", "0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,", -"03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,", -"03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,", -"03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", -"030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux,", +"0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,", +"03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", "030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,", -"030000005e0400000700000000010000,Microsoft SideWinder Gamepad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,", -"030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux,", -"030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", -"030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000120b00000b050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000dd02000003020000,Microsoft Xbox One 2015,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"030000005e040000ea02000008040000,Microsoft Xbox One S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", +"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"050000005e040000050b000003090000,Microsoft X-Box One Elite 2 pad,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000005e040000e302000003020000,Microsoft X-Box One Elite pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000dd02000003020000,Microsoft X-Box One pad (Firmware 2015),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", +"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", +"030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,", -"050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", +"05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", -"05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", -"03000000c62400002b89000011010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,", -"030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,", +"03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,", +"030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", "030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux,", -"03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", +"03000000790000004518000010010000,NEXILUX GAMECUBE Controller Adapter,a:b1,b:b0,x:b2,y:b3,start:b9,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,platform:Linux,", "030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,", "060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,", +"060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", "030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,", "03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,", -"060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", -"060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", -"050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux,", -"03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", -"050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", -"050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux,", -"05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,", -"030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,", -"050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,", -"050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", +"050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,back:b5,leftshoulder:b2,leftstick:b6,leftx:a1,lefty:a0~,rightshoulder:b4,start:b0,x:b7,y:b10,platform:Linux,", +"030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", +"050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,", +"050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0~,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux,", +"050000007e0500001720000001000000,Nintendo Switch SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,", +"050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,", +"05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,", "03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,", "03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,", "05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,", "03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,", -"19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,", +"19000000010000000100000001010000,odroidgo2_joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,", +"19000000010000000200000011000000,odroidgo2_joypad_v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,", +"030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", "03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux,", -"05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,", -"05000000362800000100000003010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,", -"05000000362800000100000004010000,OUYA Controller,a:b0,b:b3,back:b14,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b16,x:b1,y:b2,platform:Linux,", -"03000000830500005020000010010000,Padix Rockfire PlayStation Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,", -"03000000790000001c18000011010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000ff1100003133000010010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,", +"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,", +"03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,", +"03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000006f0e00008701000011010000,PDP Rock Nintendo Switch Candy Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"030000006f0e00000901000011010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", -"03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", +"030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"05000000491900000204000000000000,PG-9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", "030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", "03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,", -"03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000d62000000228000001010000,PowerA Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000c62400001a54000001010000,PowerA Xbox One Mini Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,", "03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", @@ -1370,7 +846,6 @@ const char* _glfwDefaultMappings[] = "030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,", "030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", -"030000005f1400003102000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", "030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", "030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", "050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,", @@ -1393,174 +868,134 @@ const char* _glfwDefaultMappings[] = "050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", "050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", -"030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,", -"030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", -"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,", -"050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", -"03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,", -"03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,", -"03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,", -"030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,", -"030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,", -"030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,", +"030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000ff000000cb01000010010000,PSP,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,", +"03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,", +"030000009b2800004200000001010000,Raphnet Technologies Dual NES to USB v2.0,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,", +"030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,", +"030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,", +"030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,", "030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000321500000810000011010000,Razer Panthera PS4 Evo Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000321500000010000011010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000321500000011000011010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,", "050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,", "0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,", "0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,", "0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,", -"00000000526574726f53746f6e653200,RetroStone 2 Controller,a:b1,b:b0,back:b10,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Linux,", "030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", +"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", "03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,", "03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,", -"03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,", -"03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,", -"03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", +"03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,", +"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,", "03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,", "03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,", -"03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,", -"03000000a306000020f6000011010000,Saitek PS2700 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", +"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,", +"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", +"03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,", "03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,", -"03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,", -"03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,", -"03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,", -"03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,", -"030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,", -"03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,", -"03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,", -"030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000bc2000000055000010010000,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000005f140000c501000010010000,SHANWAN Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000632500002305000010010000,ShanWan USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"03000000341a00000908000010010000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"030000004c050000e60c000011810000,Sony DualSense,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", +"050000004c050000e60c000000810000,Sony DualSense ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,", +"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,", +"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,", "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,", -"03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,", "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,", -"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,", +"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,", "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,", -"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,", +"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,", "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,", "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,", "05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,", -"03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux,", "03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux,", "03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,", +"03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,", "03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,", -"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,", -"030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,", -"030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", +"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,", +"03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000008f0e00001431000010010000,SZMY-POWER CO. LTD. PS3 gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", -"030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", -"030000004f04000023b3000000010000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000004f0400000ed0000011010000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,", "030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,", "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,", -"030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", -"030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", -"030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", -"03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,", -"03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,", -"03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,", +"030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000004f04000007d0000000010000,Thrustmaster T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,", +"030000004f04000012b3000010010000,Thrustmaster vibrating gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,", +"03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,", +"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,", "030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000680a00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,", -"03000000780300000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,", -"03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,", -"03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,", -"030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", -"03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", +"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", "03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,", "03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,", -"03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,", -"030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", -"05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", -"0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,", -"030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", -"030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,", -"0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,", -"030000005e040000120b000009050000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,", +"030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"030000006f0e00000702000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,", +"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,", +"03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"050000000d0f0000f600000001000000,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,", +"030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,", "030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"060000005e040000120b000007050000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e040000ea02000000000000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", +"030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", "030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", "050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"050000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"030000005e040000120b000007050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", -"050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"050000005e040000130b000007050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,", -"03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", -"05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,", -"03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,", -"03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -"03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -#endif // GLFW_BUILD_LINUX_MAPPINGS +"030000005e040000120b000005050000,XBox Series pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,", +"03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,", +"03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,", +"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,", +"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,", +"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", +#endif // GLFW_BUILD_LINUX_JOYSTICK }; diff --git a/raylib/external/glfw/src/monitor.c b/raylib/external/glfw/src/monitor.c index 6429493..efc286d 100644 --- a/raylib/external/glfw/src/monitor.c +++ b/raylib/external/glfw/src/monitor.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -452,7 +450,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _glfw.platform.getVideoMode(monitor, &monitor->currentMode); + if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode)) + return NULL; + return &monitor->currentMode; } @@ -489,7 +489,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; // Clamp to value range - value = _glfw_fminf(value, 65535.f); + value = fminf(value, 65535.f); values[i] = (unsigned short) value; } diff --git a/raylib/external/glfw/src/nsgl_context.m b/raylib/external/glfw/src/nsgl_context.m index fc1f752..daa8367 100644 --- a/raylib/external/glfw/src/nsgl_context.m +++ b/raylib/external/glfw/src/nsgl_context.m @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include @@ -81,11 +81,10 @@ static void swapIntervalNSGL(int interval) @autoreleasepool { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); - if (window) - { - [window->context.nsgl.object setValues:&interval - forParameter:NSOpenGLContextParameterSwapInterval]; - } + assert(window != NULL); + + [window->context.nsgl.object setValues:&interval + forParameter:NSOpenGLContextParameterSwapInterval]; } // autoreleasepool } @@ -162,7 +161,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, if (ctxconfig->client == GLFW_OPENGL_ES_API) { _glfwInputError(GLFW_API_UNAVAILABLE, - "NSGL: OpenGL ES is not available on macOS"); + "NSGL: OpenGL ES is not available via NSGL"); return GLFW_FALSE; } @@ -176,6 +175,13 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, } } + if (ctxconfig->major >= 3 && ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The compatibility profile is not available on macOS"); + return GLFW_FALSE; + } + // Context robustness modes (GL_KHR_robustness) are not yet supported by // macOS but are not a hard constraint, so ignore and continue @@ -334,7 +340,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, forParameter:NSOpenGLContextParameterSurfaceOpacity]; } - [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina]; + [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.scaleFramebuffer]; [window->context.nsgl.object setView:window->ns.view]; @@ -374,3 +380,5 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) return window->context.nsgl.object; } +#endif // _GLFW_COCOA + diff --git a/raylib/external/glfw/src/null_init.c b/raylib/external/glfw/src/null_init.c index de4b28f..88940fc 100644 --- a/raylib/external/glfw/src/null_init.c +++ b/raylib/external/glfw/src/null_init.c @@ -24,12 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" #include +#include ////////////////////////////////////////////////////////////////////////// @@ -40,78 +39,78 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { const _GLFWplatform null = { - GLFW_PLATFORM_NULL, - _glfwInitNull, - _glfwTerminateNull, - _glfwGetCursorPosNull, - _glfwSetCursorPosNull, - _glfwSetCursorModeNull, - _glfwSetRawMouseMotionNull, - _glfwRawMouseMotionSupportedNull, - _glfwCreateCursorNull, - _glfwCreateStandardCursorNull, - _glfwDestroyCursorNull, - _glfwSetCursorNull, - _glfwGetScancodeNameNull, - _glfwGetKeyScancodeNull, - _glfwSetClipboardStringNull, - _glfwGetClipboardStringNull, - _glfwInitJoysticksNull, - _glfwTerminateJoysticksNull, - _glfwPollJoystickNull, - _glfwGetMappingNameNull, - _glfwUpdateGamepadGUIDNull, - _glfwFreeMonitorNull, - _glfwGetMonitorPosNull, - _glfwGetMonitorContentScaleNull, - _glfwGetMonitorWorkareaNull, - _glfwGetVideoModesNull, - _glfwGetVideoModeNull, - _glfwGetGammaRampNull, - _glfwSetGammaRampNull, - _glfwCreateWindowNull, - _glfwDestroyWindowNull, - _glfwSetWindowTitleNull, - _glfwSetWindowIconNull, - _glfwGetWindowPosNull, - _glfwSetWindowPosNull, - _glfwGetWindowSizeNull, - _glfwSetWindowSizeNull, - _glfwSetWindowSizeLimitsNull, - _glfwSetWindowAspectRatioNull, - _glfwGetFramebufferSizeNull, - _glfwGetWindowFrameSizeNull, - _glfwGetWindowContentScaleNull, - _glfwIconifyWindowNull, - _glfwRestoreWindowNull, - _glfwMaximizeWindowNull, - _glfwShowWindowNull, - _glfwHideWindowNull, - _glfwRequestWindowAttentionNull, - _glfwFocusWindowNull, - _glfwSetWindowMonitorNull, - _glfwWindowFocusedNull, - _glfwWindowIconifiedNull, - _glfwWindowVisibleNull, - _glfwWindowMaximizedNull, - _glfwWindowHoveredNull, - _glfwFramebufferTransparentNull, - _glfwGetWindowOpacityNull, - _glfwSetWindowResizableNull, - _glfwSetWindowDecoratedNull, - _glfwSetWindowFloatingNull, - _glfwSetWindowOpacityNull, - _glfwSetWindowMousePassthroughNull, - _glfwPollEventsNull, - _glfwWaitEventsNull, - _glfwWaitEventsTimeoutNull, - _glfwPostEmptyEventNull, - _glfwGetEGLPlatformNull, - _glfwGetEGLNativeDisplayNull, - _glfwGetEGLNativeWindowNull, - _glfwGetRequiredInstanceExtensionsNull, - _glfwGetPhysicalDevicePresentationSupportNull, - _glfwCreateWindowSurfaceNull, + .platformID = GLFW_PLATFORM_NULL, + .init = _glfwInitNull, + .terminate = _glfwTerminateNull, + .getCursorPos = _glfwGetCursorPosNull, + .setCursorPos = _glfwSetCursorPosNull, + .setCursorMode = _glfwSetCursorModeNull, + .setRawMouseMotion = _glfwSetRawMouseMotionNull, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedNull, + .createCursor = _glfwCreateCursorNull, + .createStandardCursor = _glfwCreateStandardCursorNull, + .destroyCursor = _glfwDestroyCursorNull, + .setCursor = _glfwSetCursorNull, + .getScancodeName = _glfwGetScancodeNameNull, + .getKeyScancode = _glfwGetKeyScancodeNull, + .setClipboardString = _glfwSetClipboardStringNull, + .getClipboardString = _glfwGetClipboardStringNull, + .initJoysticks = _glfwInitJoysticksNull, + .terminateJoysticks = _glfwTerminateJoysticksNull, + .pollJoystick = _glfwPollJoystickNull, + .getMappingName = _glfwGetMappingNameNull, + .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, + .freeMonitor = _glfwFreeMonitorNull, + .getMonitorPos = _glfwGetMonitorPosNull, + .getMonitorContentScale = _glfwGetMonitorContentScaleNull, + .getMonitorWorkarea = _glfwGetMonitorWorkareaNull, + .getVideoModes = _glfwGetVideoModesNull, + .getVideoMode = _glfwGetVideoModeNull, + .getGammaRamp = _glfwGetGammaRampNull, + .setGammaRamp = _glfwSetGammaRampNull, + .createWindow = _glfwCreateWindowNull, + .destroyWindow = _glfwDestroyWindowNull, + .setWindowTitle = _glfwSetWindowTitleNull, + .setWindowIcon = _glfwSetWindowIconNull, + .getWindowPos = _glfwGetWindowPosNull, + .setWindowPos = _glfwSetWindowPosNull, + .getWindowSize = _glfwGetWindowSizeNull, + .setWindowSize = _glfwSetWindowSizeNull, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsNull, + .setWindowAspectRatio = _glfwSetWindowAspectRatioNull, + .getFramebufferSize = _glfwGetFramebufferSizeNull, + .getWindowFrameSize = _glfwGetWindowFrameSizeNull, + .getWindowContentScale = _glfwGetWindowContentScaleNull, + .iconifyWindow = _glfwIconifyWindowNull, + .restoreWindow = _glfwRestoreWindowNull, + .maximizeWindow = _glfwMaximizeWindowNull, + .showWindow = _glfwShowWindowNull, + .hideWindow = _glfwHideWindowNull, + .requestWindowAttention = _glfwRequestWindowAttentionNull, + .focusWindow = _glfwFocusWindowNull, + .setWindowMonitor = _glfwSetWindowMonitorNull, + .windowFocused = _glfwWindowFocusedNull, + .windowIconified = _glfwWindowIconifiedNull, + .windowVisible = _glfwWindowVisibleNull, + .windowMaximized = _glfwWindowMaximizedNull, + .windowHovered = _glfwWindowHoveredNull, + .framebufferTransparent = _glfwFramebufferTransparentNull, + .getWindowOpacity = _glfwGetWindowOpacityNull, + .setWindowResizable = _glfwSetWindowResizableNull, + .setWindowDecorated = _glfwSetWindowDecoratedNull, + .setWindowFloating = _glfwSetWindowFloatingNull, + .setWindowOpacity = _glfwSetWindowOpacityNull, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughNull, + .pollEvents = _glfwPollEventsNull, + .waitEvents = _glfwWaitEventsNull, + .waitEventsTimeout = _glfwWaitEventsTimeoutNull, + .postEmptyEvent = _glfwPostEmptyEventNull, + .getEGLPlatform = _glfwGetEGLPlatformNull, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayNull, + .getEGLNativeWindow = _glfwGetEGLNativeWindowNull, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsNull, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportNull, + .createWindowSurface = _glfwCreateWindowSurfaceNull }; *platform = null; @@ -120,6 +119,138 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) int _glfwInitNull(void) { + int scancode; + + memset(_glfw.null.keycodes, -1, sizeof(_glfw.null.keycodes)); + memset(_glfw.null.scancodes, -1, sizeof(_glfw.null.scancodes)); + + _glfw.null.keycodes[GLFW_NULL_SC_SPACE] = GLFW_KEY_SPACE; + _glfw.null.keycodes[GLFW_NULL_SC_APOSTROPHE] = GLFW_KEY_APOSTROPHE; + _glfw.null.keycodes[GLFW_NULL_SC_COMMA] = GLFW_KEY_COMMA; + _glfw.null.keycodes[GLFW_NULL_SC_MINUS] = GLFW_KEY_MINUS; + _glfw.null.keycodes[GLFW_NULL_SC_PERIOD] = GLFW_KEY_PERIOD; + _glfw.null.keycodes[GLFW_NULL_SC_SLASH] = GLFW_KEY_SLASH; + _glfw.null.keycodes[GLFW_NULL_SC_0] = GLFW_KEY_0; + _glfw.null.keycodes[GLFW_NULL_SC_1] = GLFW_KEY_1; + _glfw.null.keycodes[GLFW_NULL_SC_2] = GLFW_KEY_2; + _glfw.null.keycodes[GLFW_NULL_SC_3] = GLFW_KEY_3; + _glfw.null.keycodes[GLFW_NULL_SC_4] = GLFW_KEY_4; + _glfw.null.keycodes[GLFW_NULL_SC_5] = GLFW_KEY_5; + _glfw.null.keycodes[GLFW_NULL_SC_6] = GLFW_KEY_6; + _glfw.null.keycodes[GLFW_NULL_SC_7] = GLFW_KEY_7; + _glfw.null.keycodes[GLFW_NULL_SC_8] = GLFW_KEY_8; + _glfw.null.keycodes[GLFW_NULL_SC_9] = GLFW_KEY_9; + _glfw.null.keycodes[GLFW_NULL_SC_SEMICOLON] = GLFW_KEY_SEMICOLON; + _glfw.null.keycodes[GLFW_NULL_SC_EQUAL] = GLFW_KEY_EQUAL; + _glfw.null.keycodes[GLFW_NULL_SC_A] = GLFW_KEY_A; + _glfw.null.keycodes[GLFW_NULL_SC_B] = GLFW_KEY_B; + _glfw.null.keycodes[GLFW_NULL_SC_C] = GLFW_KEY_C; + _glfw.null.keycodes[GLFW_NULL_SC_D] = GLFW_KEY_D; + _glfw.null.keycodes[GLFW_NULL_SC_E] = GLFW_KEY_E; + _glfw.null.keycodes[GLFW_NULL_SC_F] = GLFW_KEY_F; + _glfw.null.keycodes[GLFW_NULL_SC_G] = GLFW_KEY_G; + _glfw.null.keycodes[GLFW_NULL_SC_H] = GLFW_KEY_H; + _glfw.null.keycodes[GLFW_NULL_SC_I] = GLFW_KEY_I; + _glfw.null.keycodes[GLFW_NULL_SC_J] = GLFW_KEY_J; + _glfw.null.keycodes[GLFW_NULL_SC_K] = GLFW_KEY_K; + _glfw.null.keycodes[GLFW_NULL_SC_L] = GLFW_KEY_L; + _glfw.null.keycodes[GLFW_NULL_SC_M] = GLFW_KEY_M; + _glfw.null.keycodes[GLFW_NULL_SC_N] = GLFW_KEY_N; + _glfw.null.keycodes[GLFW_NULL_SC_O] = GLFW_KEY_O; + _glfw.null.keycodes[GLFW_NULL_SC_P] = GLFW_KEY_P; + _glfw.null.keycodes[GLFW_NULL_SC_Q] = GLFW_KEY_Q; + _glfw.null.keycodes[GLFW_NULL_SC_R] = GLFW_KEY_R; + _glfw.null.keycodes[GLFW_NULL_SC_S] = GLFW_KEY_S; + _glfw.null.keycodes[GLFW_NULL_SC_T] = GLFW_KEY_T; + _glfw.null.keycodes[GLFW_NULL_SC_U] = GLFW_KEY_U; + _glfw.null.keycodes[GLFW_NULL_SC_V] = GLFW_KEY_V; + _glfw.null.keycodes[GLFW_NULL_SC_W] = GLFW_KEY_W; + _glfw.null.keycodes[GLFW_NULL_SC_X] = GLFW_KEY_X; + _glfw.null.keycodes[GLFW_NULL_SC_Y] = GLFW_KEY_Y; + _glfw.null.keycodes[GLFW_NULL_SC_Z] = GLFW_KEY_Z; + _glfw.null.keycodes[GLFW_NULL_SC_LEFT_BRACKET] = GLFW_KEY_LEFT_BRACKET; + _glfw.null.keycodes[GLFW_NULL_SC_BACKSLASH] = GLFW_KEY_BACKSLASH; + _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_BRACKET] = GLFW_KEY_RIGHT_BRACKET; + _glfw.null.keycodes[GLFW_NULL_SC_GRAVE_ACCENT] = GLFW_KEY_GRAVE_ACCENT; + _glfw.null.keycodes[GLFW_NULL_SC_WORLD_1] = GLFW_KEY_WORLD_1; + _glfw.null.keycodes[GLFW_NULL_SC_WORLD_2] = GLFW_KEY_WORLD_2; + _glfw.null.keycodes[GLFW_NULL_SC_ESCAPE] = GLFW_KEY_ESCAPE; + _glfw.null.keycodes[GLFW_NULL_SC_ENTER] = GLFW_KEY_ENTER; + _glfw.null.keycodes[GLFW_NULL_SC_TAB] = GLFW_KEY_TAB; + _glfw.null.keycodes[GLFW_NULL_SC_BACKSPACE] = GLFW_KEY_BACKSPACE; + _glfw.null.keycodes[GLFW_NULL_SC_INSERT] = GLFW_KEY_INSERT; + _glfw.null.keycodes[GLFW_NULL_SC_DELETE] = GLFW_KEY_DELETE; + _glfw.null.keycodes[GLFW_NULL_SC_RIGHT] = GLFW_KEY_RIGHT; + _glfw.null.keycodes[GLFW_NULL_SC_LEFT] = GLFW_KEY_LEFT; + _glfw.null.keycodes[GLFW_NULL_SC_DOWN] = GLFW_KEY_DOWN; + _glfw.null.keycodes[GLFW_NULL_SC_UP] = GLFW_KEY_UP; + _glfw.null.keycodes[GLFW_NULL_SC_PAGE_UP] = GLFW_KEY_PAGE_UP; + _glfw.null.keycodes[GLFW_NULL_SC_PAGE_DOWN] = GLFW_KEY_PAGE_DOWN; + _glfw.null.keycodes[GLFW_NULL_SC_HOME] = GLFW_KEY_HOME; + _glfw.null.keycodes[GLFW_NULL_SC_END] = GLFW_KEY_END; + _glfw.null.keycodes[GLFW_NULL_SC_CAPS_LOCK] = GLFW_KEY_CAPS_LOCK; + _glfw.null.keycodes[GLFW_NULL_SC_SCROLL_LOCK] = GLFW_KEY_SCROLL_LOCK; + _glfw.null.keycodes[GLFW_NULL_SC_NUM_LOCK] = GLFW_KEY_NUM_LOCK; + _glfw.null.keycodes[GLFW_NULL_SC_PRINT_SCREEN] = GLFW_KEY_PRINT_SCREEN; + _glfw.null.keycodes[GLFW_NULL_SC_PAUSE] = GLFW_KEY_PAUSE; + _glfw.null.keycodes[GLFW_NULL_SC_F1] = GLFW_KEY_F1; + _glfw.null.keycodes[GLFW_NULL_SC_F2] = GLFW_KEY_F2; + _glfw.null.keycodes[GLFW_NULL_SC_F3] = GLFW_KEY_F3; + _glfw.null.keycodes[GLFW_NULL_SC_F4] = GLFW_KEY_F4; + _glfw.null.keycodes[GLFW_NULL_SC_F5] = GLFW_KEY_F5; + _glfw.null.keycodes[GLFW_NULL_SC_F6] = GLFW_KEY_F6; + _glfw.null.keycodes[GLFW_NULL_SC_F7] = GLFW_KEY_F7; + _glfw.null.keycodes[GLFW_NULL_SC_F8] = GLFW_KEY_F8; + _glfw.null.keycodes[GLFW_NULL_SC_F9] = GLFW_KEY_F9; + _glfw.null.keycodes[GLFW_NULL_SC_F10] = GLFW_KEY_F10; + _glfw.null.keycodes[GLFW_NULL_SC_F11] = GLFW_KEY_F11; + _glfw.null.keycodes[GLFW_NULL_SC_F12] = GLFW_KEY_F12; + _glfw.null.keycodes[GLFW_NULL_SC_F13] = GLFW_KEY_F13; + _glfw.null.keycodes[GLFW_NULL_SC_F14] = GLFW_KEY_F14; + _glfw.null.keycodes[GLFW_NULL_SC_F15] = GLFW_KEY_F15; + _glfw.null.keycodes[GLFW_NULL_SC_F16] = GLFW_KEY_F16; + _glfw.null.keycodes[GLFW_NULL_SC_F17] = GLFW_KEY_F17; + _glfw.null.keycodes[GLFW_NULL_SC_F18] = GLFW_KEY_F18; + _glfw.null.keycodes[GLFW_NULL_SC_F19] = GLFW_KEY_F19; + _glfw.null.keycodes[GLFW_NULL_SC_F20] = GLFW_KEY_F20; + _glfw.null.keycodes[GLFW_NULL_SC_F21] = GLFW_KEY_F21; + _glfw.null.keycodes[GLFW_NULL_SC_F22] = GLFW_KEY_F22; + _glfw.null.keycodes[GLFW_NULL_SC_F23] = GLFW_KEY_F23; + _glfw.null.keycodes[GLFW_NULL_SC_F24] = GLFW_KEY_F24; + _glfw.null.keycodes[GLFW_NULL_SC_F25] = GLFW_KEY_F25; + _glfw.null.keycodes[GLFW_NULL_SC_KP_0] = GLFW_KEY_KP_0; + _glfw.null.keycodes[GLFW_NULL_SC_KP_1] = GLFW_KEY_KP_1; + _glfw.null.keycodes[GLFW_NULL_SC_KP_2] = GLFW_KEY_KP_2; + _glfw.null.keycodes[GLFW_NULL_SC_KP_3] = GLFW_KEY_KP_3; + _glfw.null.keycodes[GLFW_NULL_SC_KP_4] = GLFW_KEY_KP_4; + _glfw.null.keycodes[GLFW_NULL_SC_KP_5] = GLFW_KEY_KP_5; + _glfw.null.keycodes[GLFW_NULL_SC_KP_6] = GLFW_KEY_KP_6; + _glfw.null.keycodes[GLFW_NULL_SC_KP_7] = GLFW_KEY_KP_7; + _glfw.null.keycodes[GLFW_NULL_SC_KP_8] = GLFW_KEY_KP_8; + _glfw.null.keycodes[GLFW_NULL_SC_KP_9] = GLFW_KEY_KP_9; + _glfw.null.keycodes[GLFW_NULL_SC_KP_DECIMAL] = GLFW_KEY_KP_DECIMAL; + _glfw.null.keycodes[GLFW_NULL_SC_KP_DIVIDE] = GLFW_KEY_KP_DIVIDE; + _glfw.null.keycodes[GLFW_NULL_SC_KP_MULTIPLY] = GLFW_KEY_KP_MULTIPLY; + _glfw.null.keycodes[GLFW_NULL_SC_KP_SUBTRACT] = GLFW_KEY_KP_SUBTRACT; + _glfw.null.keycodes[GLFW_NULL_SC_KP_ADD] = GLFW_KEY_KP_ADD; + _glfw.null.keycodes[GLFW_NULL_SC_KP_ENTER] = GLFW_KEY_KP_ENTER; + _glfw.null.keycodes[GLFW_NULL_SC_KP_EQUAL] = GLFW_KEY_KP_EQUAL; + _glfw.null.keycodes[GLFW_NULL_SC_LEFT_SHIFT] = GLFW_KEY_LEFT_SHIFT; + _glfw.null.keycodes[GLFW_NULL_SC_LEFT_CONTROL] = GLFW_KEY_LEFT_CONTROL; + _glfw.null.keycodes[GLFW_NULL_SC_LEFT_ALT] = GLFW_KEY_LEFT_ALT; + _glfw.null.keycodes[GLFW_NULL_SC_LEFT_SUPER] = GLFW_KEY_LEFT_SUPER; + _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SHIFT] = GLFW_KEY_RIGHT_SHIFT; + _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_CONTROL] = GLFW_KEY_RIGHT_CONTROL; + _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_ALT] = GLFW_KEY_RIGHT_ALT; + _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SUPER] = GLFW_KEY_RIGHT_SUPER; + _glfw.null.keycodes[GLFW_NULL_SC_MENU] = GLFW_KEY_MENU; + + for (scancode = GLFW_NULL_SC_FIRST; scancode < GLFW_NULL_SC_LAST; scancode++) + { + if (_glfw.null.keycodes[scancode] > 0) + _glfw.null.scancodes[_glfw.null.keycodes[scancode]] = scancode; + } + _glfwPollMonitorsNull(); return GLFW_TRUE; } diff --git a/raylib/external/glfw/src/null_joystick.c b/raylib/external/glfw/src/null_joystick.c index 1fe5072..ec1f6b5 100644 --- a/raylib/external/glfw/src/null_joystick.c +++ b/raylib/external/glfw/src/null_joystick.c @@ -23,8 +23,6 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" diff --git a/raylib/external/glfw/src/null_monitor.c b/raylib/external/glfw/src/null_monitor.c index 63a1cd2..d818f45 100644 --- a/raylib/external/glfw/src/null_monitor.c +++ b/raylib/external/glfw/src/null_monitor.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" @@ -111,9 +109,10 @@ GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found) return mode; } -void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode) { *mode = getVideoMode(); + return GLFW_TRUE; } GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp) @@ -130,7 +129,7 @@ GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp) float value; value = i / (float) (monitor->null.ramp.size - 1); value = powf(value, 1.f / gamma) * 65535.f + 0.5f; - value = _glfw_fminf(value, 65535.f); + value = fminf(value, 65535.f); monitor->null.ramp.red[i] = (unsigned short) value; monitor->null.ramp.green[i] = (unsigned short) value; diff --git a/raylib/external/glfw/src/null_platform.h b/raylib/external/glfw/src/null_platform.h index b646acb..4843a76 100644 --- a/raylib/external/glfw/src/null_platform.h +++ b/raylib/external/glfw/src/null_platform.h @@ -33,6 +33,128 @@ #define GLFW_NULL_CURSOR_STATE #define GLFW_NULL_LIBRARY_CONTEXT_STATE +#define GLFW_NULL_SC_FIRST GLFW_NULL_SC_SPACE +#define GLFW_NULL_SC_SPACE 1 +#define GLFW_NULL_SC_APOSTROPHE 2 +#define GLFW_NULL_SC_COMMA 3 +#define GLFW_NULL_SC_MINUS 4 +#define GLFW_NULL_SC_PERIOD 5 +#define GLFW_NULL_SC_SLASH 6 +#define GLFW_NULL_SC_0 7 +#define GLFW_NULL_SC_1 8 +#define GLFW_NULL_SC_2 9 +#define GLFW_NULL_SC_3 10 +#define GLFW_NULL_SC_4 11 +#define GLFW_NULL_SC_5 12 +#define GLFW_NULL_SC_6 13 +#define GLFW_NULL_SC_7 14 +#define GLFW_NULL_SC_8 15 +#define GLFW_NULL_SC_9 16 +#define GLFW_NULL_SC_SEMICOLON 17 +#define GLFW_NULL_SC_EQUAL 18 +#define GLFW_NULL_SC_LEFT_BRACKET 19 +#define GLFW_NULL_SC_BACKSLASH 20 +#define GLFW_NULL_SC_RIGHT_BRACKET 21 +#define GLFW_NULL_SC_GRAVE_ACCENT 22 +#define GLFW_NULL_SC_WORLD_1 23 +#define GLFW_NULL_SC_WORLD_2 24 +#define GLFW_NULL_SC_ESCAPE 25 +#define GLFW_NULL_SC_ENTER 26 +#define GLFW_NULL_SC_TAB 27 +#define GLFW_NULL_SC_BACKSPACE 28 +#define GLFW_NULL_SC_INSERT 29 +#define GLFW_NULL_SC_DELETE 30 +#define GLFW_NULL_SC_RIGHT 31 +#define GLFW_NULL_SC_LEFT 32 +#define GLFW_NULL_SC_DOWN 33 +#define GLFW_NULL_SC_UP 34 +#define GLFW_NULL_SC_PAGE_UP 35 +#define GLFW_NULL_SC_PAGE_DOWN 36 +#define GLFW_NULL_SC_HOME 37 +#define GLFW_NULL_SC_END 38 +#define GLFW_NULL_SC_CAPS_LOCK 39 +#define GLFW_NULL_SC_SCROLL_LOCK 40 +#define GLFW_NULL_SC_NUM_LOCK 41 +#define GLFW_NULL_SC_PRINT_SCREEN 42 +#define GLFW_NULL_SC_PAUSE 43 +#define GLFW_NULL_SC_A 44 +#define GLFW_NULL_SC_B 45 +#define GLFW_NULL_SC_C 46 +#define GLFW_NULL_SC_D 47 +#define GLFW_NULL_SC_E 48 +#define GLFW_NULL_SC_F 49 +#define GLFW_NULL_SC_G 50 +#define GLFW_NULL_SC_H 51 +#define GLFW_NULL_SC_I 52 +#define GLFW_NULL_SC_J 53 +#define GLFW_NULL_SC_K 54 +#define GLFW_NULL_SC_L 55 +#define GLFW_NULL_SC_M 56 +#define GLFW_NULL_SC_N 57 +#define GLFW_NULL_SC_O 58 +#define GLFW_NULL_SC_P 59 +#define GLFW_NULL_SC_Q 60 +#define GLFW_NULL_SC_R 61 +#define GLFW_NULL_SC_S 62 +#define GLFW_NULL_SC_T 63 +#define GLFW_NULL_SC_U 64 +#define GLFW_NULL_SC_V 65 +#define GLFW_NULL_SC_W 66 +#define GLFW_NULL_SC_X 67 +#define GLFW_NULL_SC_Y 68 +#define GLFW_NULL_SC_Z 69 +#define GLFW_NULL_SC_F1 70 +#define GLFW_NULL_SC_F2 71 +#define GLFW_NULL_SC_F3 72 +#define GLFW_NULL_SC_F4 73 +#define GLFW_NULL_SC_F5 74 +#define GLFW_NULL_SC_F6 75 +#define GLFW_NULL_SC_F7 76 +#define GLFW_NULL_SC_F8 77 +#define GLFW_NULL_SC_F9 78 +#define GLFW_NULL_SC_F10 79 +#define GLFW_NULL_SC_F11 80 +#define GLFW_NULL_SC_F12 81 +#define GLFW_NULL_SC_F13 82 +#define GLFW_NULL_SC_F14 83 +#define GLFW_NULL_SC_F15 84 +#define GLFW_NULL_SC_F16 85 +#define GLFW_NULL_SC_F17 86 +#define GLFW_NULL_SC_F18 87 +#define GLFW_NULL_SC_F19 88 +#define GLFW_NULL_SC_F20 89 +#define GLFW_NULL_SC_F21 90 +#define GLFW_NULL_SC_F22 91 +#define GLFW_NULL_SC_F23 92 +#define GLFW_NULL_SC_F24 93 +#define GLFW_NULL_SC_F25 94 +#define GLFW_NULL_SC_KP_0 95 +#define GLFW_NULL_SC_KP_1 96 +#define GLFW_NULL_SC_KP_2 97 +#define GLFW_NULL_SC_KP_3 98 +#define GLFW_NULL_SC_KP_4 99 +#define GLFW_NULL_SC_KP_5 100 +#define GLFW_NULL_SC_KP_6 101 +#define GLFW_NULL_SC_KP_7 102 +#define GLFW_NULL_SC_KP_8 103 +#define GLFW_NULL_SC_KP_9 104 +#define GLFW_NULL_SC_KP_DECIMAL 105 +#define GLFW_NULL_SC_KP_DIVIDE 106 +#define GLFW_NULL_SC_KP_MULTIPLY 107 +#define GLFW_NULL_SC_KP_SUBTRACT 108 +#define GLFW_NULL_SC_KP_ADD 109 +#define GLFW_NULL_SC_KP_ENTER 110 +#define GLFW_NULL_SC_KP_EQUAL 111 +#define GLFW_NULL_SC_LEFT_SHIFT 112 +#define GLFW_NULL_SC_LEFT_CONTROL 113 +#define GLFW_NULL_SC_LEFT_ALT 114 +#define GLFW_NULL_SC_LEFT_SUPER 115 +#define GLFW_NULL_SC_RIGHT_SHIFT 116 +#define GLFW_NULL_SC_RIGHT_CONTROL 117 +#define GLFW_NULL_SC_RIGHT_ALT 118 +#define GLFW_NULL_SC_RIGHT_SUPER 119 +#define GLFW_NULL_SC_MENU 120 +#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU // Null-specific per-window data // @@ -42,7 +164,6 @@ typedef struct _GLFWwindowNull int ypos; int width; int height; - char* title; GLFWbool visible; GLFWbool iconified; GLFWbool maximized; @@ -68,6 +189,8 @@ typedef struct _GLFWlibraryNull int ycursor; char* clipboardString; _GLFWwindow* focusedWindow; + uint16_t keycodes[GLFW_NULL_SC_LAST + 1]; + uint8_t scancodes[GLFW_KEY_LAST + 1]; } _GLFWlibraryNull; void _glfwPollMonitorsNull(void); @@ -81,7 +204,7 @@ void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos); void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found); -void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); @@ -115,7 +238,6 @@ void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled); GLFWbool _glfwRawMouseMotionSupportedNull(void); void _glfwShowWindowNull(_GLFWwindow* window); void _glfwRequestWindowAttentionNull(_GLFWwindow* window); -void _glfwRequestWindowAttentionNull(_GLFWwindow* window); void _glfwHideWindowNull(_GLFWwindow* window); void _glfwFocusWindowNull(_GLFWwindow* window); GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window); diff --git a/raylib/external/glfw/src/null_window.c b/raylib/external/glfw/src/null_window.c index 5cdf3e2..1db0811 100644 --- a/raylib/external/glfw/src/null_window.c +++ b/raylib/external/glfw/src/null_window.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" @@ -260,8 +258,9 @@ void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height) { window->null.width = width; window->null.height = height; - _glfwInputWindowSize(window, width, height); _glfwInputFramebufferSize(window, width, height); + _glfwInputWindowDamage(window); + _glfwInputWindowSize(window, width, height); } } @@ -568,7 +567,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window) const char* _glfwGetScancodeNameNull(int scancode) { - if (scancode < GLFW_KEY_SPACE || scancode > GLFW_KEY_LAST) + if (scancode < GLFW_NULL_SC_FIRST || scancode > GLFW_NULL_SC_LAST) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; @@ -576,117 +575,117 @@ const char* _glfwGetScancodeNameNull(int scancode) switch (scancode) { - case GLFW_KEY_APOSTROPHE: + case GLFW_NULL_SC_APOSTROPHE: return "'"; - case GLFW_KEY_COMMA: + case GLFW_NULL_SC_COMMA: return ","; - case GLFW_KEY_MINUS: - case GLFW_KEY_KP_SUBTRACT: + case GLFW_NULL_SC_MINUS: + case GLFW_NULL_SC_KP_SUBTRACT: return "-"; - case GLFW_KEY_PERIOD: - case GLFW_KEY_KP_DECIMAL: + case GLFW_NULL_SC_PERIOD: + case GLFW_NULL_SC_KP_DECIMAL: return "."; - case GLFW_KEY_SLASH: - case GLFW_KEY_KP_DIVIDE: + case GLFW_NULL_SC_SLASH: + case GLFW_NULL_SC_KP_DIVIDE: return "/"; - case GLFW_KEY_SEMICOLON: + case GLFW_NULL_SC_SEMICOLON: return ";"; - case GLFW_KEY_EQUAL: - case GLFW_KEY_KP_EQUAL: + case GLFW_NULL_SC_EQUAL: + case GLFW_NULL_SC_KP_EQUAL: return "="; - case GLFW_KEY_LEFT_BRACKET: + case GLFW_NULL_SC_LEFT_BRACKET: return "["; - case GLFW_KEY_RIGHT_BRACKET: + case GLFW_NULL_SC_RIGHT_BRACKET: return "]"; - case GLFW_KEY_KP_MULTIPLY: + case GLFW_NULL_SC_KP_MULTIPLY: return "*"; - case GLFW_KEY_KP_ADD: + case GLFW_NULL_SC_KP_ADD: return "+"; - case GLFW_KEY_BACKSLASH: - case GLFW_KEY_WORLD_1: - case GLFW_KEY_WORLD_2: + case GLFW_NULL_SC_BACKSLASH: + case GLFW_NULL_SC_WORLD_1: + case GLFW_NULL_SC_WORLD_2: return "\\"; - case GLFW_KEY_0: - case GLFW_KEY_KP_0: + case GLFW_NULL_SC_0: + case GLFW_NULL_SC_KP_0: return "0"; - case GLFW_KEY_1: - case GLFW_KEY_KP_1: + case GLFW_NULL_SC_1: + case GLFW_NULL_SC_KP_1: return "1"; - case GLFW_KEY_2: - case GLFW_KEY_KP_2: + case GLFW_NULL_SC_2: + case GLFW_NULL_SC_KP_2: return "2"; - case GLFW_KEY_3: - case GLFW_KEY_KP_3: + case GLFW_NULL_SC_3: + case GLFW_NULL_SC_KP_3: return "3"; - case GLFW_KEY_4: - case GLFW_KEY_KP_4: + case GLFW_NULL_SC_4: + case GLFW_NULL_SC_KP_4: return "4"; - case GLFW_KEY_5: - case GLFW_KEY_KP_5: + case GLFW_NULL_SC_5: + case GLFW_NULL_SC_KP_5: return "5"; - case GLFW_KEY_6: - case GLFW_KEY_KP_6: + case GLFW_NULL_SC_6: + case GLFW_NULL_SC_KP_6: return "6"; - case GLFW_KEY_7: - case GLFW_KEY_KP_7: + case GLFW_NULL_SC_7: + case GLFW_NULL_SC_KP_7: return "7"; - case GLFW_KEY_8: - case GLFW_KEY_KP_8: + case GLFW_NULL_SC_8: + case GLFW_NULL_SC_KP_8: return "8"; - case GLFW_KEY_9: - case GLFW_KEY_KP_9: + case GLFW_NULL_SC_9: + case GLFW_NULL_SC_KP_9: return "9"; - case GLFW_KEY_A: + case GLFW_NULL_SC_A: return "a"; - case GLFW_KEY_B: + case GLFW_NULL_SC_B: return "b"; - case GLFW_KEY_C: + case GLFW_NULL_SC_C: return "c"; - case GLFW_KEY_D: + case GLFW_NULL_SC_D: return "d"; - case GLFW_KEY_E: + case GLFW_NULL_SC_E: return "e"; - case GLFW_KEY_F: + case GLFW_NULL_SC_F: return "f"; - case GLFW_KEY_G: + case GLFW_NULL_SC_G: return "g"; - case GLFW_KEY_H: + case GLFW_NULL_SC_H: return "h"; - case GLFW_KEY_I: + case GLFW_NULL_SC_I: return "i"; - case GLFW_KEY_J: + case GLFW_NULL_SC_J: return "j"; - case GLFW_KEY_K: + case GLFW_NULL_SC_K: return "k"; - case GLFW_KEY_L: + case GLFW_NULL_SC_L: return "l"; - case GLFW_KEY_M: + case GLFW_NULL_SC_M: return "m"; - case GLFW_KEY_N: + case GLFW_NULL_SC_N: return "n"; - case GLFW_KEY_O: + case GLFW_NULL_SC_O: return "o"; - case GLFW_KEY_P: + case GLFW_NULL_SC_P: return "p"; - case GLFW_KEY_Q: + case GLFW_NULL_SC_Q: return "q"; - case GLFW_KEY_R: + case GLFW_NULL_SC_R: return "r"; - case GLFW_KEY_S: + case GLFW_NULL_SC_S: return "s"; - case GLFW_KEY_T: + case GLFW_NULL_SC_T: return "t"; - case GLFW_KEY_U: + case GLFW_NULL_SC_U: return "u"; - case GLFW_KEY_V: + case GLFW_NULL_SC_V: return "v"; - case GLFW_KEY_W: + case GLFW_NULL_SC_W: return "w"; - case GLFW_KEY_X: + case GLFW_NULL_SC_X: return "x"; - case GLFW_KEY_Y: + case GLFW_NULL_SC_Y: return "y"; - case GLFW_KEY_Z: + case GLFW_NULL_SC_Z: return "z"; } @@ -695,7 +694,7 @@ const char* _glfwGetScancodeNameNull(int scancode) int _glfwGetKeyScancodeNull(int key) { - return key; + return _glfw.null.scancodes[key]; } void _glfwGetRequiredInstanceExtensionsNull(char** extensions) diff --git a/raylib/external/glfw/src/osmesa_context.c b/raylib/external/glfw/src/osmesa_context.c index 38adabb..2f12adf 100644 --- a/raylib/external/glfw/src/osmesa_context.c +++ b/raylib/external/glfw/src/osmesa_context.c @@ -24,16 +24,13 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== + +#include "internal.h" #include #include #include -#include "internal.h" - - static void makeContextCurrentOSMesa(_GLFWwindow* window) { if (window) diff --git a/raylib/external/glfw/src/platform.c b/raylib/external/glfw/src/platform.c index 24b6ac9..af1b0f4 100644 --- a/raylib/external/glfw/src/platform.c +++ b/raylib/external/glfw/src/platform.c @@ -24,11 +24,16 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#include +#include + +// These construct a string literal from individual numeric constants +#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r +#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r) + ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -45,12 +50,12 @@ static const struct #if defined(_GLFW_COCOA) { GLFW_PLATFORM_COCOA, _glfwConnectCocoa }, #endif -#if defined(_GLFW_X11) - { GLFW_PLATFORM_X11, _glfwConnectX11 }, -#endif #if defined(_GLFW_WAYLAND) { GLFW_PLATFORM_WAYLAND, _glfwConnectWayland }, #endif +#if defined(_GLFW_X11) + { GLFW_PLATFORM_X11, _glfwConnectX11 }, +#endif }; GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) @@ -71,13 +76,29 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) // Only allow the Null platform if specifically requested if (desiredID == GLFW_PLATFORM_NULL) - return GLFW_FALSE; //_glfwConnectNull(desiredID, platform); // @raysan5 + return _glfwConnectNull(desiredID, platform); else if (count == 0) { _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform"); return GLFW_FALSE; } +#if defined(_GLFW_WAYLAND) && defined(_GLFW_X11) + if (desiredID == GLFW_ANY_PLATFORM) + { + const char* const session = getenv("XDG_SESSION_TYPE"); + if (session) + { + // Only follow XDG_SESSION_TYPE if it is set correctly and the + // environment looks plausble; otherwise fall back to detection + if (strcmp(session, "wayland") == 0 && getenv("WAYLAND_DISPLAY")) + desiredID = GLFW_PLATFORM_WAYLAND; + else if (strcmp(session, "x11") == 0 && getenv("DISPLAY")) + desiredID = GLFW_PLATFORM_X11; + } + } +#endif + if (desiredID == GLFW_ANY_PLATFORM) { // If there is exactly one platform available for auto-selection, let it emit the @@ -146,7 +167,9 @@ GLFWAPI int glfwPlatformSupported(int platformID) GLFWAPI const char* glfwGetVersionString(void) { - return _GLFW_VERSION_NUMBER + return _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, + GLFW_VERSION_MINOR, + GLFW_VERSION_REVISION) #if defined(_GLFW_WIN32) " Win32 WGL" #endif diff --git a/raylib/external/glfw/src/platform.h b/raylib/external/glfw/src/platform.h index 0c59367..75652dc 100644 --- a/raylib/external/glfw/src/platform.h +++ b/raylib/external/glfw/src/platform.h @@ -25,10 +25,26 @@ // //======================================================================== +#if defined(GLFW_BUILD_WIN32_TIMER) || \ + defined(GLFW_BUILD_WIN32_MODULE) || \ + defined(GLFW_BUILD_WIN32_THREAD) || \ + defined(GLFW_BUILD_COCOA_TIMER) || \ + defined(GLFW_BUILD_POSIX_TIMER) || \ + defined(GLFW_BUILD_POSIX_MODULE) || \ + defined(GLFW_BUILD_POSIX_THREAD) || \ + defined(GLFW_BUILD_POSIX_POLL) || \ + defined(GLFW_BUILD_LINUX_JOYSTICK) + #error "You must not define these; define zero or more _GLFW_ macros instead" +#endif + #include "null_platform.h" +#define GLFW_EXPOSE_NATIVE_EGL +#define GLFW_EXPOSE_NATIVE_OSMESA #if defined(_GLFW_WIN32) #include "win32_platform.h" + #define GLFW_EXPOSE_NATIVE_WIN32 + #define GLFW_EXPOSE_NATIVE_WGL #else #define GLFW_WIN32_WINDOW_STATE #define GLFW_WIN32_MONITOR_STATE @@ -40,6 +56,8 @@ #if defined(_GLFW_COCOA) #include "cocoa_platform.h" + #define GLFW_EXPOSE_NATIVE_COCOA + #define GLFW_EXPOSE_NATIVE_NSGL #else #define GLFW_COCOA_WINDOW_STATE #define GLFW_COCOA_MONITOR_STATE @@ -51,6 +69,7 @@ #if defined(_GLFW_WAYLAND) #include "wl_platform.h" + #define GLFW_EXPOSE_NATIVE_WAYLAND #else #define GLFW_WAYLAND_WINDOW_STATE #define GLFW_WAYLAND_MONITOR_STATE @@ -60,6 +79,8 @@ #if defined(_GLFW_X11) #include "x11_platform.h" + #define GLFW_EXPOSE_NATIVE_X11 + #define GLFW_EXPOSE_NATIVE_GLX #else #define GLFW_X11_WINDOW_STATE #define GLFW_X11_MONITOR_STATE @@ -86,6 +107,10 @@ #endif #if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__) + #define GLFW_BUILD_LINUX_JOYSTICK +#endif + +#if defined(GLFW_BUILD_LINUX_JOYSTICK) #include "linux_joystick.h" #else #define GLFW_LINUX_JOYSTICK_STATE @@ -141,23 +166,47 @@ GLFW_GLX_LIBRARY_CONTEXT_STATE #if defined(_WIN32) + #define GLFW_BUILD_WIN32_THREAD +#else + #define GLFW_BUILD_POSIX_THREAD +#endif + +#if defined(GLFW_BUILD_WIN32_THREAD) #include "win32_thread.h" #define GLFW_PLATFORM_TLS_STATE GLFW_WIN32_TLS_STATE #define GLFW_PLATFORM_MUTEX_STATE GLFW_WIN32_MUTEX_STATE -#else +#elif defined(GLFW_BUILD_POSIX_THREAD) #include "posix_thread.h" #define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE #define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE #endif #if defined(_WIN32) + #define GLFW_BUILD_WIN32_TIMER +#elif defined(__APPLE__) + #define GLFW_BUILD_COCOA_TIMER +#else + #define GLFW_BUILD_POSIX_TIMER +#endif + +#if defined(GLFW_BUILD_WIN32_TIMER) #include "win32_time.h" #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE -#elif defined(__APPLE__) +#elif defined(GLFW_BUILD_COCOA_TIMER) #include "cocoa_time.h" #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE -#else +#elif defined(GLFW_BUILD_POSIX_TIMER) #include "posix_time.h" #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE #endif +#if defined(_WIN32) + #define GLFW_BUILD_WIN32_MODULE +#else + #define GLFW_BUILD_POSIX_MODULE +#endif + +#if defined(_GLFW_WAYLAND) || defined(_GLFW_X11) + #define GLFW_BUILD_POSIX_POLL +#endif + diff --git a/raylib/external/glfw/src/posix_module.c b/raylib/external/glfw/src/posix_module.c index 7079e5b..7d81c67 100644 --- a/raylib/external/glfw/src/posix_module.c +++ b/raylib/external/glfw/src/posix_module.c @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_MODULE) + #include ////////////////////////////////////////////////////////////////////////// @@ -49,3 +49,5 @@ GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name) return dlsym(module, name); } +#endif // GLFW_BUILD_POSIX_MODULE + diff --git a/raylib/external/glfw/src/posix_poll.c b/raylib/external/glfw/src/posix_poll.c index 676a8a5..b53e36e 100644 --- a/raylib/external/glfw/src/posix_poll.c +++ b/raylib/external/glfw/src/posix_poll.c @@ -23,13 +23,13 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #define _GNU_SOURCE #include "internal.h" +#if defined(GLFW_BUILD_POSIX_POLL) + #include #include #include @@ -79,3 +79,5 @@ GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout) } } +#endif // GLFW_BUILD_POSIX_POLL + diff --git a/raylib/external/glfw/src/posix_poll.h b/raylib/external/glfw/src/posix_poll.h index 1effd1c..4bdd244 100644 --- a/raylib/external/glfw/src/posix_poll.h +++ b/raylib/external/glfw/src/posix_poll.h @@ -23,8 +23,6 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include diff --git a/raylib/external/glfw/src/posix_thread.c b/raylib/external/glfw/src/posix_thread.c index 0236145..3c355a5 100644 --- a/raylib/external/glfw/src/posix_thread.c +++ b/raylib/external/glfw/src/posix_thread.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_THREAD) + #include #include @@ -103,3 +103,5 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex) pthread_mutex_unlock(&mutex->posix.handle); } +#endif // GLFW_BUILD_POSIX_THREAD + diff --git a/raylib/external/glfw/src/posix_time.c b/raylib/external/glfw/src/posix_time.c index f134be4..a172408 100644 --- a/raylib/external/glfw/src/posix_time.c +++ b/raylib/external/glfw/src/posix_time.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_TIMER) + #include #include @@ -61,3 +61,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void) return _glfw.timer.posix.frequency; } +#endif // GLFW_BUILD_POSIX_TIMER + diff --git a/raylib/external/glfw/src/vulkan.c b/raylib/external/glfw/src/vulkan.c index 64a4650..d9fabde 100644 --- a/raylib/external/glfw/src/vulkan.c +++ b/raylib/external/glfw/src/vulkan.c @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" diff --git a/raylib/external/glfw/src/wayland-client-protocol-code.h b/raylib/external/glfw/src/wayland-client-protocol-code.h deleted file mode 100644 index 5098871..0000000 --- a/raylib/external/glfw/src/wayland-client-protocol-code.h +++ /dev/null @@ -1,524 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2008-2011 Kristian Høgsberg - * Copyright © 2010-2011 Intel Corporation - * Copyright © 2012-2013 Collabora, Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_buffer_interface; -extern const struct wl_interface wl_callback_interface; -extern const struct wl_interface wl_data_device_interface; -extern const struct wl_interface wl_data_offer_interface; -extern const struct wl_interface wl_data_source_interface; -extern const struct wl_interface wl_keyboard_interface; -extern const struct wl_interface wl_output_interface; -extern const struct wl_interface wl_pointer_interface; -extern const struct wl_interface wl_region_interface; -extern const struct wl_interface wl_registry_interface; -extern const struct wl_interface wl_seat_interface; -extern const struct wl_interface wl_shell_surface_interface; -extern const struct wl_interface wl_shm_pool_interface; -extern const struct wl_interface wl_subsurface_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_touch_interface; - -static const struct wl_interface *wayland_types[] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - &wl_callback_interface, - &wl_registry_interface, - &wl_surface_interface, - &wl_region_interface, - &wl_buffer_interface, - NULL, - NULL, - NULL, - NULL, - NULL, - &wl_shm_pool_interface, - NULL, - NULL, - &wl_data_source_interface, - &wl_surface_interface, - &wl_surface_interface, - NULL, - &wl_data_source_interface, - NULL, - &wl_data_offer_interface, - NULL, - &wl_surface_interface, - NULL, - NULL, - &wl_data_offer_interface, - &wl_data_offer_interface, - &wl_data_source_interface, - &wl_data_device_interface, - &wl_seat_interface, - &wl_shell_surface_interface, - &wl_surface_interface, - &wl_seat_interface, - NULL, - &wl_seat_interface, - NULL, - NULL, - &wl_surface_interface, - NULL, - NULL, - NULL, - NULL, - NULL, - &wl_output_interface, - &wl_seat_interface, - NULL, - &wl_surface_interface, - NULL, - NULL, - NULL, - &wl_output_interface, - &wl_buffer_interface, - NULL, - NULL, - &wl_callback_interface, - &wl_region_interface, - &wl_region_interface, - &wl_output_interface, - &wl_output_interface, - &wl_pointer_interface, - &wl_keyboard_interface, - &wl_touch_interface, - NULL, - &wl_surface_interface, - NULL, - NULL, - NULL, - &wl_surface_interface, - NULL, - NULL, - NULL, - &wl_surface_interface, - NULL, - &wl_surface_interface, - NULL, - NULL, - &wl_surface_interface, - NULL, - NULL, - &wl_surface_interface, - NULL, - NULL, - NULL, - &wl_subsurface_interface, - &wl_surface_interface, - &wl_surface_interface, - &wl_surface_interface, - &wl_surface_interface, -}; - -static const struct wl_message wl_display_requests[] = { - { "sync", "n", wayland_types + 8 }, - { "get_registry", "n", wayland_types + 9 }, -}; - -static const struct wl_message wl_display_events[] = { - { "error", "ous", wayland_types + 0 }, - { "delete_id", "u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_display_interface = { - "wl_display", 1, - 2, wl_display_requests, - 2, wl_display_events, -}; - -static const struct wl_message wl_registry_requests[] = { - { "bind", "usun", wayland_types + 0 }, -}; - -static const struct wl_message wl_registry_events[] = { - { "global", "usu", wayland_types + 0 }, - { "global_remove", "u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_registry_interface = { - "wl_registry", 1, - 1, wl_registry_requests, - 2, wl_registry_events, -}; - -static const struct wl_message wl_callback_events[] = { - { "done", "u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_callback_interface = { - "wl_callback", 1, - 0, NULL, - 1, wl_callback_events, -}; - -static const struct wl_message wl_compositor_requests[] = { - { "create_surface", "n", wayland_types + 10 }, - { "create_region", "n", wayland_types + 11 }, -}; - -WL_PRIVATE const struct wl_interface wl_compositor_interface = { - "wl_compositor", 6, - 2, wl_compositor_requests, - 0, NULL, -}; - -static const struct wl_message wl_shm_pool_requests[] = { - { "create_buffer", "niiiiu", wayland_types + 12 }, - { "destroy", "", wayland_types + 0 }, - { "resize", "i", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_shm_pool_interface = { - "wl_shm_pool", 1, - 3, wl_shm_pool_requests, - 0, NULL, -}; - -static const struct wl_message wl_shm_requests[] = { - { "create_pool", "nhi", wayland_types + 18 }, -}; - -static const struct wl_message wl_shm_events[] = { - { "format", "u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_shm_interface = { - "wl_shm", 1, - 1, wl_shm_requests, - 1, wl_shm_events, -}; - -static const struct wl_message wl_buffer_requests[] = { - { "destroy", "", wayland_types + 0 }, -}; - -static const struct wl_message wl_buffer_events[] = { - { "release", "", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_buffer_interface = { - "wl_buffer", 1, - 1, wl_buffer_requests, - 1, wl_buffer_events, -}; - -static const struct wl_message wl_data_offer_requests[] = { - { "accept", "u?s", wayland_types + 0 }, - { "receive", "sh", wayland_types + 0 }, - { "destroy", "", wayland_types + 0 }, - { "finish", "3", wayland_types + 0 }, - { "set_actions", "3uu", wayland_types + 0 }, -}; - -static const struct wl_message wl_data_offer_events[] = { - { "offer", "s", wayland_types + 0 }, - { "source_actions", "3u", wayland_types + 0 }, - { "action", "3u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_data_offer_interface = { - "wl_data_offer", 3, - 5, wl_data_offer_requests, - 3, wl_data_offer_events, -}; - -static const struct wl_message wl_data_source_requests[] = { - { "offer", "s", wayland_types + 0 }, - { "destroy", "", wayland_types + 0 }, - { "set_actions", "3u", wayland_types + 0 }, -}; - -static const struct wl_message wl_data_source_events[] = { - { "target", "?s", wayland_types + 0 }, - { "send", "sh", wayland_types + 0 }, - { "cancelled", "", wayland_types + 0 }, - { "dnd_drop_performed", "3", wayland_types + 0 }, - { "dnd_finished", "3", wayland_types + 0 }, - { "action", "3u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_data_source_interface = { - "wl_data_source", 3, - 3, wl_data_source_requests, - 6, wl_data_source_events, -}; - -static const struct wl_message wl_data_device_requests[] = { - { "start_drag", "?oo?ou", wayland_types + 21 }, - { "set_selection", "?ou", wayland_types + 25 }, - { "release", "2", wayland_types + 0 }, -}; - -static const struct wl_message wl_data_device_events[] = { - { "data_offer", "n", wayland_types + 27 }, - { "enter", "uoff?o", wayland_types + 28 }, - { "leave", "", wayland_types + 0 }, - { "motion", "uff", wayland_types + 0 }, - { "drop", "", wayland_types + 0 }, - { "selection", "?o", wayland_types + 33 }, -}; - -WL_PRIVATE const struct wl_interface wl_data_device_interface = { - "wl_data_device", 3, - 3, wl_data_device_requests, - 6, wl_data_device_events, -}; - -static const struct wl_message wl_data_device_manager_requests[] = { - { "create_data_source", "n", wayland_types + 34 }, - { "get_data_device", "no", wayland_types + 35 }, -}; - -WL_PRIVATE const struct wl_interface wl_data_device_manager_interface = { - "wl_data_device_manager", 3, - 2, wl_data_device_manager_requests, - 0, NULL, -}; - -static const struct wl_message wl_shell_requests[] = { - { "get_shell_surface", "no", wayland_types + 37 }, -}; - -WL_PRIVATE const struct wl_interface wl_shell_interface = { - "wl_shell", 1, - 1, wl_shell_requests, - 0, NULL, -}; - -static const struct wl_message wl_shell_surface_requests[] = { - { "pong", "u", wayland_types + 0 }, - { "move", "ou", wayland_types + 39 }, - { "resize", "ouu", wayland_types + 41 }, - { "set_toplevel", "", wayland_types + 0 }, - { "set_transient", "oiiu", wayland_types + 44 }, - { "set_fullscreen", "uu?o", wayland_types + 48 }, - { "set_popup", "ouoiiu", wayland_types + 51 }, - { "set_maximized", "?o", wayland_types + 57 }, - { "set_title", "s", wayland_types + 0 }, - { "set_class", "s", wayland_types + 0 }, -}; - -static const struct wl_message wl_shell_surface_events[] = { - { "ping", "u", wayland_types + 0 }, - { "configure", "uii", wayland_types + 0 }, - { "popup_done", "", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_shell_surface_interface = { - "wl_shell_surface", 1, - 10, wl_shell_surface_requests, - 3, wl_shell_surface_events, -}; - -static const struct wl_message wl_surface_requests[] = { - { "destroy", "", wayland_types + 0 }, - { "attach", "?oii", wayland_types + 58 }, - { "damage", "iiii", wayland_types + 0 }, - { "frame", "n", wayland_types + 61 }, - { "set_opaque_region", "?o", wayland_types + 62 }, - { "set_input_region", "?o", wayland_types + 63 }, - { "commit", "", wayland_types + 0 }, - { "set_buffer_transform", "2i", wayland_types + 0 }, - { "set_buffer_scale", "3i", wayland_types + 0 }, - { "damage_buffer", "4iiii", wayland_types + 0 }, - { "offset", "5ii", wayland_types + 0 }, -}; - -static const struct wl_message wl_surface_events[] = { - { "enter", "o", wayland_types + 64 }, - { "leave", "o", wayland_types + 65 }, - { "preferred_buffer_scale", "6i", wayland_types + 0 }, - { "preferred_buffer_transform", "6u", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_surface_interface = { - "wl_surface", 6, - 11, wl_surface_requests, - 4, wl_surface_events, -}; - -static const struct wl_message wl_seat_requests[] = { - { "get_pointer", "n", wayland_types + 66 }, - { "get_keyboard", "n", wayland_types + 67 }, - { "get_touch", "n", wayland_types + 68 }, - { "release", "5", wayland_types + 0 }, -}; - -static const struct wl_message wl_seat_events[] = { - { "capabilities", "u", wayland_types + 0 }, - { "name", "2s", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_seat_interface = { - "wl_seat", 9, - 4, wl_seat_requests, - 2, wl_seat_events, -}; - -static const struct wl_message wl_pointer_requests[] = { - { "set_cursor", "u?oii", wayland_types + 69 }, - { "release", "3", wayland_types + 0 }, -}; - -static const struct wl_message wl_pointer_events[] = { - { "enter", "uoff", wayland_types + 73 }, - { "leave", "uo", wayland_types + 77 }, - { "motion", "uff", wayland_types + 0 }, - { "button", "uuuu", wayland_types + 0 }, - { "axis", "uuf", wayland_types + 0 }, - { "frame", "5", wayland_types + 0 }, - { "axis_source", "5u", wayland_types + 0 }, - { "axis_stop", "5uu", wayland_types + 0 }, - { "axis_discrete", "5ui", wayland_types + 0 }, - { "axis_value120", "8ui", wayland_types + 0 }, - { "axis_relative_direction", "9uu", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_pointer_interface = { - "wl_pointer", 9, - 2, wl_pointer_requests, - 11, wl_pointer_events, -}; - -static const struct wl_message wl_keyboard_requests[] = { - { "release", "3", wayland_types + 0 }, -}; - -static const struct wl_message wl_keyboard_events[] = { - { "keymap", "uhu", wayland_types + 0 }, - { "enter", "uoa", wayland_types + 79 }, - { "leave", "uo", wayland_types + 82 }, - { "key", "uuuu", wayland_types + 0 }, - { "modifiers", "uuuuu", wayland_types + 0 }, - { "repeat_info", "4ii", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_keyboard_interface = { - "wl_keyboard", 9, - 1, wl_keyboard_requests, - 6, wl_keyboard_events, -}; - -static const struct wl_message wl_touch_requests[] = { - { "release", "3", wayland_types + 0 }, -}; - -static const struct wl_message wl_touch_events[] = { - { "down", "uuoiff", wayland_types + 84 }, - { "up", "uui", wayland_types + 0 }, - { "motion", "uiff", wayland_types + 0 }, - { "frame", "", wayland_types + 0 }, - { "cancel", "", wayland_types + 0 }, - { "shape", "6iff", wayland_types + 0 }, - { "orientation", "6if", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_touch_interface = { - "wl_touch", 9, - 1, wl_touch_requests, - 7, wl_touch_events, -}; - -static const struct wl_message wl_output_requests[] = { - { "release", "3", wayland_types + 0 }, -}; - -static const struct wl_message wl_output_events[] = { - { "geometry", "iiiiissi", wayland_types + 0 }, - { "mode", "uiii", wayland_types + 0 }, - { "done", "2", wayland_types + 0 }, - { "scale", "2i", wayland_types + 0 }, - { "name", "4s", wayland_types + 0 }, - { "description", "4s", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_output_interface = { - "wl_output", 4, - 1, wl_output_requests, - 6, wl_output_events, -}; - -static const struct wl_message wl_region_requests[] = { - { "destroy", "", wayland_types + 0 }, - { "add", "iiii", wayland_types + 0 }, - { "subtract", "iiii", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_region_interface = { - "wl_region", 1, - 3, wl_region_requests, - 0, NULL, -}; - -static const struct wl_message wl_subcompositor_requests[] = { - { "destroy", "", wayland_types + 0 }, - { "get_subsurface", "noo", wayland_types + 90 }, -}; - -WL_PRIVATE const struct wl_interface wl_subcompositor_interface = { - "wl_subcompositor", 1, - 2, wl_subcompositor_requests, - 0, NULL, -}; - -static const struct wl_message wl_subsurface_requests[] = { - { "destroy", "", wayland_types + 0 }, - { "set_position", "ii", wayland_types + 0 }, - { "place_above", "o", wayland_types + 93 }, - { "place_below", "o", wayland_types + 94 }, - { "set_sync", "", wayland_types + 0 }, - { "set_desync", "", wayland_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wl_subsurface_interface = { - "wl_subsurface", 1, - 6, wl_subsurface_requests, - 0, NULL, -}; - diff --git a/raylib/external/glfw/src/wayland-client-protocol.h b/raylib/external/glfw/src/wayland-client-protocol.h deleted file mode 100644 index 0ae8ea1..0000000 --- a/raylib/external/glfw/src/wayland-client-protocol.h +++ /dev/null @@ -1,6321 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef WAYLAND_CLIENT_PROTOCOL_H -#define WAYLAND_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_wayland The wayland protocol - * @section page_ifaces_wayland Interfaces - * - @subpage page_iface_wl_display - core global object - * - @subpage page_iface_wl_registry - global registry object - * - @subpage page_iface_wl_callback - callback object - * - @subpage page_iface_wl_compositor - the compositor singleton - * - @subpage page_iface_wl_shm_pool - a shared memory pool - * - @subpage page_iface_wl_shm - shared memory support - * - @subpage page_iface_wl_buffer - content for a wl_surface - * - @subpage page_iface_wl_data_offer - offer to transfer data - * - @subpage page_iface_wl_data_source - offer to transfer data - * - @subpage page_iface_wl_data_device - data transfer device - * - @subpage page_iface_wl_data_device_manager - data transfer interface - * - @subpage page_iface_wl_shell - create desktop-style surfaces - * - @subpage page_iface_wl_shell_surface - desktop-style metadata interface - * - @subpage page_iface_wl_surface - an onscreen surface - * - @subpage page_iface_wl_seat - group of input devices - * - @subpage page_iface_wl_pointer - pointer input device - * - @subpage page_iface_wl_keyboard - keyboard input device - * - @subpage page_iface_wl_touch - touchscreen input device - * - @subpage page_iface_wl_output - compositor output region - * - @subpage page_iface_wl_region - region interface - * - @subpage page_iface_wl_subcompositor - sub-surface compositing - * - @subpage page_iface_wl_subsurface - sub-surface interface to a wl_surface - * @section page_copyright_wayland Copyright - *
- *
- * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2010-2011 Intel Corporation
- * Copyright © 2012-2013 Collabora, Ltd.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- * 
- */ -struct wl_buffer; -struct wl_callback; -struct wl_compositor; -struct wl_data_device; -struct wl_data_device_manager; -struct wl_data_offer; -struct wl_data_source; -struct wl_display; -struct wl_keyboard; -struct wl_output; -struct wl_pointer; -struct wl_region; -struct wl_registry; -struct wl_seat; -struct wl_shell; -struct wl_shell_surface; -struct wl_shm; -struct wl_shm_pool; -struct wl_subcompositor; -struct wl_subsurface; -struct wl_surface; -struct wl_touch; - -#ifndef WL_DISPLAY_INTERFACE -#define WL_DISPLAY_INTERFACE -/** - * @page page_iface_wl_display wl_display - * @section page_iface_wl_display_desc Description - * - * The core global object. This is a special singleton object. It - * is used for internal Wayland protocol features. - * @section page_iface_wl_display_api API - * See @ref iface_wl_display. - */ -/** - * @defgroup iface_wl_display The wl_display interface - * - * The core global object. This is a special singleton object. It - * is used for internal Wayland protocol features. - */ -extern const struct wl_interface wl_display_interface; -#endif -#ifndef WL_REGISTRY_INTERFACE -#define WL_REGISTRY_INTERFACE -/** - * @page page_iface_wl_registry wl_registry - * @section page_iface_wl_registry_desc Description - * - * The singleton global registry object. The server has a number of - * global objects that are available to all clients. These objects - * typically represent an actual object in the server (for example, - * an input device) or they are singleton objects that provide - * extension functionality. - * - * When a client creates a registry object, the registry object - * will emit a global event for each global currently in the - * registry. Globals come and go as a result of device or - * monitor hotplugs, reconfiguration or other events, and the - * registry will send out global and global_remove events to - * keep the client up to date with the changes. To mark the end - * of the initial burst of events, the client can use the - * wl_display.sync request immediately after calling - * wl_display.get_registry. - * - * A client can bind to a global object by using the bind - * request. This creates a client-side handle that lets the object - * emit events to the client and lets the client invoke requests on - * the object. - * @section page_iface_wl_registry_api API - * See @ref iface_wl_registry. - */ -/** - * @defgroup iface_wl_registry The wl_registry interface - * - * The singleton global registry object. The server has a number of - * global objects that are available to all clients. These objects - * typically represent an actual object in the server (for example, - * an input device) or they are singleton objects that provide - * extension functionality. - * - * When a client creates a registry object, the registry object - * will emit a global event for each global currently in the - * registry. Globals come and go as a result of device or - * monitor hotplugs, reconfiguration or other events, and the - * registry will send out global and global_remove events to - * keep the client up to date with the changes. To mark the end - * of the initial burst of events, the client can use the - * wl_display.sync request immediately after calling - * wl_display.get_registry. - * - * A client can bind to a global object by using the bind - * request. This creates a client-side handle that lets the object - * emit events to the client and lets the client invoke requests on - * the object. - */ -extern const struct wl_interface wl_registry_interface; -#endif -#ifndef WL_CALLBACK_INTERFACE -#define WL_CALLBACK_INTERFACE -/** - * @page page_iface_wl_callback wl_callback - * @section page_iface_wl_callback_desc Description - * - * Clients can handle the 'done' event to get notified when - * the related request is done. - * - * Note, because wl_callback objects are created from multiple independent - * factory interfaces, the wl_callback interface is frozen at version 1. - * @section page_iface_wl_callback_api API - * See @ref iface_wl_callback. - */ -/** - * @defgroup iface_wl_callback The wl_callback interface - * - * Clients can handle the 'done' event to get notified when - * the related request is done. - * - * Note, because wl_callback objects are created from multiple independent - * factory interfaces, the wl_callback interface is frozen at version 1. - */ -extern const struct wl_interface wl_callback_interface; -#endif -#ifndef WL_COMPOSITOR_INTERFACE -#define WL_COMPOSITOR_INTERFACE -/** - * @page page_iface_wl_compositor wl_compositor - * @section page_iface_wl_compositor_desc Description - * - * A compositor. This object is a singleton global. The - * compositor is in charge of combining the contents of multiple - * surfaces into one displayable output. - * @section page_iface_wl_compositor_api API - * See @ref iface_wl_compositor. - */ -/** - * @defgroup iface_wl_compositor The wl_compositor interface - * - * A compositor. This object is a singleton global. The - * compositor is in charge of combining the contents of multiple - * surfaces into one displayable output. - */ -extern const struct wl_interface wl_compositor_interface; -#endif -#ifndef WL_SHM_POOL_INTERFACE -#define WL_SHM_POOL_INTERFACE -/** - * @page page_iface_wl_shm_pool wl_shm_pool - * @section page_iface_wl_shm_pool_desc Description - * - * The wl_shm_pool object encapsulates a piece of memory shared - * between the compositor and client. Through the wl_shm_pool - * object, the client can allocate shared memory wl_buffer objects. - * All objects created through the same pool share the same - * underlying mapped memory. Reusing the mapped memory avoids the - * setup/teardown overhead and is useful when interactively resizing - * a surface or for many small buffers. - * @section page_iface_wl_shm_pool_api API - * See @ref iface_wl_shm_pool. - */ -/** - * @defgroup iface_wl_shm_pool The wl_shm_pool interface - * - * The wl_shm_pool object encapsulates a piece of memory shared - * between the compositor and client. Through the wl_shm_pool - * object, the client can allocate shared memory wl_buffer objects. - * All objects created through the same pool share the same - * underlying mapped memory. Reusing the mapped memory avoids the - * setup/teardown overhead and is useful when interactively resizing - * a surface or for many small buffers. - */ -extern const struct wl_interface wl_shm_pool_interface; -#endif -#ifndef WL_SHM_INTERFACE -#define WL_SHM_INTERFACE -/** - * @page page_iface_wl_shm wl_shm - * @section page_iface_wl_shm_desc Description - * - * A singleton global object that provides support for shared - * memory. - * - * Clients can create wl_shm_pool objects using the create_pool - * request. - * - * On binding the wl_shm object one or more format events - * are emitted to inform clients about the valid pixel formats - * that can be used for buffers. - * @section page_iface_wl_shm_api API - * See @ref iface_wl_shm. - */ -/** - * @defgroup iface_wl_shm The wl_shm interface - * - * A singleton global object that provides support for shared - * memory. - * - * Clients can create wl_shm_pool objects using the create_pool - * request. - * - * On binding the wl_shm object one or more format events - * are emitted to inform clients about the valid pixel formats - * that can be used for buffers. - */ -extern const struct wl_interface wl_shm_interface; -#endif -#ifndef WL_BUFFER_INTERFACE -#define WL_BUFFER_INTERFACE -/** - * @page page_iface_wl_buffer wl_buffer - * @section page_iface_wl_buffer_desc Description - * - * A buffer provides the content for a wl_surface. Buffers are - * created through factory interfaces such as wl_shm, wp_linux_buffer_params - * (from the linux-dmabuf protocol extension) or similar. It has a width and - * a height and can be attached to a wl_surface, but the mechanism by which a - * client provides and updates the contents is defined by the buffer factory - * interface. - * - * If the buffer uses a format that has an alpha channel, the alpha channel - * is assumed to be premultiplied in the electrical color channel values - * (after transfer function encoding) unless otherwise specified. - * - * Note, because wl_buffer objects are created from multiple independent - * factory interfaces, the wl_buffer interface is frozen at version 1. - * @section page_iface_wl_buffer_api API - * See @ref iface_wl_buffer. - */ -/** - * @defgroup iface_wl_buffer The wl_buffer interface - * - * A buffer provides the content for a wl_surface. Buffers are - * created through factory interfaces such as wl_shm, wp_linux_buffer_params - * (from the linux-dmabuf protocol extension) or similar. It has a width and - * a height and can be attached to a wl_surface, but the mechanism by which a - * client provides and updates the contents is defined by the buffer factory - * interface. - * - * If the buffer uses a format that has an alpha channel, the alpha channel - * is assumed to be premultiplied in the electrical color channel values - * (after transfer function encoding) unless otherwise specified. - * - * Note, because wl_buffer objects are created from multiple independent - * factory interfaces, the wl_buffer interface is frozen at version 1. - */ -extern const struct wl_interface wl_buffer_interface; -#endif -#ifndef WL_DATA_OFFER_INTERFACE -#define WL_DATA_OFFER_INTERFACE -/** - * @page page_iface_wl_data_offer wl_data_offer - * @section page_iface_wl_data_offer_desc Description - * - * A wl_data_offer represents a piece of data offered for transfer - * by another client (the source client). It is used by the - * copy-and-paste and drag-and-drop mechanisms. The offer - * describes the different mime types that the data can be - * converted to and provides the mechanism for transferring the - * data directly from the source client. - * @section page_iface_wl_data_offer_api API - * See @ref iface_wl_data_offer. - */ -/** - * @defgroup iface_wl_data_offer The wl_data_offer interface - * - * A wl_data_offer represents a piece of data offered for transfer - * by another client (the source client). It is used by the - * copy-and-paste and drag-and-drop mechanisms. The offer - * describes the different mime types that the data can be - * converted to and provides the mechanism for transferring the - * data directly from the source client. - */ -extern const struct wl_interface wl_data_offer_interface; -#endif -#ifndef WL_DATA_SOURCE_INTERFACE -#define WL_DATA_SOURCE_INTERFACE -/** - * @page page_iface_wl_data_source wl_data_source - * @section page_iface_wl_data_source_desc Description - * - * The wl_data_source object is the source side of a wl_data_offer. - * It is created by the source client in a data transfer and - * provides a way to describe the offered data and a way to respond - * to requests to transfer the data. - * @section page_iface_wl_data_source_api API - * See @ref iface_wl_data_source. - */ -/** - * @defgroup iface_wl_data_source The wl_data_source interface - * - * The wl_data_source object is the source side of a wl_data_offer. - * It is created by the source client in a data transfer and - * provides a way to describe the offered data and a way to respond - * to requests to transfer the data. - */ -extern const struct wl_interface wl_data_source_interface; -#endif -#ifndef WL_DATA_DEVICE_INTERFACE -#define WL_DATA_DEVICE_INTERFACE -/** - * @page page_iface_wl_data_device wl_data_device - * @section page_iface_wl_data_device_desc Description - * - * There is one wl_data_device per seat which can be obtained - * from the global wl_data_device_manager singleton. - * - * A wl_data_device provides access to inter-client data transfer - * mechanisms such as copy-and-paste and drag-and-drop. - * @section page_iface_wl_data_device_api API - * See @ref iface_wl_data_device. - */ -/** - * @defgroup iface_wl_data_device The wl_data_device interface - * - * There is one wl_data_device per seat which can be obtained - * from the global wl_data_device_manager singleton. - * - * A wl_data_device provides access to inter-client data transfer - * mechanisms such as copy-and-paste and drag-and-drop. - */ -extern const struct wl_interface wl_data_device_interface; -#endif -#ifndef WL_DATA_DEVICE_MANAGER_INTERFACE -#define WL_DATA_DEVICE_MANAGER_INTERFACE -/** - * @page page_iface_wl_data_device_manager wl_data_device_manager - * @section page_iface_wl_data_device_manager_desc Description - * - * The wl_data_device_manager is a singleton global object that - * provides access to inter-client data transfer mechanisms such as - * copy-and-paste and drag-and-drop. These mechanisms are tied to - * a wl_seat and this interface lets a client get a wl_data_device - * corresponding to a wl_seat. - * - * Depending on the version bound, the objects created from the bound - * wl_data_device_manager object will have different requirements for - * functioning properly. See wl_data_source.set_actions, - * wl_data_offer.accept and wl_data_offer.finish for details. - * @section page_iface_wl_data_device_manager_api API - * See @ref iface_wl_data_device_manager. - */ -/** - * @defgroup iface_wl_data_device_manager The wl_data_device_manager interface - * - * The wl_data_device_manager is a singleton global object that - * provides access to inter-client data transfer mechanisms such as - * copy-and-paste and drag-and-drop. These mechanisms are tied to - * a wl_seat and this interface lets a client get a wl_data_device - * corresponding to a wl_seat. - * - * Depending on the version bound, the objects created from the bound - * wl_data_device_manager object will have different requirements for - * functioning properly. See wl_data_source.set_actions, - * wl_data_offer.accept and wl_data_offer.finish for details. - */ -extern const struct wl_interface wl_data_device_manager_interface; -#endif -#ifndef WL_SHELL_INTERFACE -#define WL_SHELL_INTERFACE -/** - * @page page_iface_wl_shell wl_shell - * @section page_iface_wl_shell_desc Description - * - * This interface is implemented by servers that provide - * desktop-style user interfaces. - * - * It allows clients to associate a wl_shell_surface with - * a basic surface. - * - * Note! This protocol is deprecated and not intended for production use. - * For desktop-style user interfaces, use xdg_shell. Compositors and clients - * should not implement this interface. - * @section page_iface_wl_shell_api API - * See @ref iface_wl_shell. - */ -/** - * @defgroup iface_wl_shell The wl_shell interface - * - * This interface is implemented by servers that provide - * desktop-style user interfaces. - * - * It allows clients to associate a wl_shell_surface with - * a basic surface. - * - * Note! This protocol is deprecated and not intended for production use. - * For desktop-style user interfaces, use xdg_shell. Compositors and clients - * should not implement this interface. - */ -extern const struct wl_interface wl_shell_interface; -#endif -#ifndef WL_SHELL_SURFACE_INTERFACE -#define WL_SHELL_SURFACE_INTERFACE -/** - * @page page_iface_wl_shell_surface wl_shell_surface - * @section page_iface_wl_shell_surface_desc Description - * - * An interface that may be implemented by a wl_surface, for - * implementations that provide a desktop-style user interface. - * - * It provides requests to treat surfaces like toplevel, fullscreen - * or popup windows, move, resize or maximize them, associate - * metadata like title and class, etc. - * - * On the server side the object is automatically destroyed when - * the related wl_surface is destroyed. On the client side, - * wl_shell_surface_destroy() must be called before destroying - * the wl_surface object. - * @section page_iface_wl_shell_surface_api API - * See @ref iface_wl_shell_surface. - */ -/** - * @defgroup iface_wl_shell_surface The wl_shell_surface interface - * - * An interface that may be implemented by a wl_surface, for - * implementations that provide a desktop-style user interface. - * - * It provides requests to treat surfaces like toplevel, fullscreen - * or popup windows, move, resize or maximize them, associate - * metadata like title and class, etc. - * - * On the server side the object is automatically destroyed when - * the related wl_surface is destroyed. On the client side, - * wl_shell_surface_destroy() must be called before destroying - * the wl_surface object. - */ -extern const struct wl_interface wl_shell_surface_interface; -#endif -#ifndef WL_SURFACE_INTERFACE -#define WL_SURFACE_INTERFACE -/** - * @page page_iface_wl_surface wl_surface - * @section page_iface_wl_surface_desc Description - * - * A surface is a rectangular area that may be displayed on zero - * or more outputs, and shown any number of times at the compositor's - * discretion. They can present wl_buffers, receive user input, and - * define a local coordinate system. - * - * The size of a surface (and relative positions on it) is described - * in surface-local coordinates, which may differ from the buffer - * coordinates of the pixel content, in case a buffer_transform - * or a buffer_scale is used. - * - * A surface without a "role" is fairly useless: a compositor does - * not know where, when or how to present it. The role is the - * purpose of a wl_surface. Examples of roles are a cursor for a - * pointer (as set by wl_pointer.set_cursor), a drag icon - * (wl_data_device.start_drag), a sub-surface - * (wl_subcompositor.get_subsurface), and a window as defined by a - * shell protocol (e.g. wl_shell.get_shell_surface). - * - * A surface can have only one role at a time. Initially a - * wl_surface does not have a role. Once a wl_surface is given a - * role, it is set permanently for the whole lifetime of the - * wl_surface object. Giving the current role again is allowed, - * unless explicitly forbidden by the relevant interface - * specification. - * - * Surface roles are given by requests in other interfaces such as - * wl_pointer.set_cursor. The request should explicitly mention - * that this request gives a role to a wl_surface. Often, this - * request also creates a new protocol object that represents the - * role and adds additional functionality to wl_surface. When a - * client wants to destroy a wl_surface, they must destroy this role - * object before the wl_surface, otherwise a defunct_role_object error is - * sent. - * - * Destroying the role object does not remove the role from the - * wl_surface, but it may stop the wl_surface from "playing the role". - * For instance, if a wl_subsurface object is destroyed, the wl_surface - * it was created for will be unmapped and forget its position and - * z-order. It is allowed to create a wl_subsurface for the same - * wl_surface again, but it is not allowed to use the wl_surface as - * a cursor (cursor is a different role than sub-surface, and role - * switching is not allowed). - * @section page_iface_wl_surface_api API - * See @ref iface_wl_surface. - */ -/** - * @defgroup iface_wl_surface The wl_surface interface - * - * A surface is a rectangular area that may be displayed on zero - * or more outputs, and shown any number of times at the compositor's - * discretion. They can present wl_buffers, receive user input, and - * define a local coordinate system. - * - * The size of a surface (and relative positions on it) is described - * in surface-local coordinates, which may differ from the buffer - * coordinates of the pixel content, in case a buffer_transform - * or a buffer_scale is used. - * - * A surface without a "role" is fairly useless: a compositor does - * not know where, when or how to present it. The role is the - * purpose of a wl_surface. Examples of roles are a cursor for a - * pointer (as set by wl_pointer.set_cursor), a drag icon - * (wl_data_device.start_drag), a sub-surface - * (wl_subcompositor.get_subsurface), and a window as defined by a - * shell protocol (e.g. wl_shell.get_shell_surface). - * - * A surface can have only one role at a time. Initially a - * wl_surface does not have a role. Once a wl_surface is given a - * role, it is set permanently for the whole lifetime of the - * wl_surface object. Giving the current role again is allowed, - * unless explicitly forbidden by the relevant interface - * specification. - * - * Surface roles are given by requests in other interfaces such as - * wl_pointer.set_cursor. The request should explicitly mention - * that this request gives a role to a wl_surface. Often, this - * request also creates a new protocol object that represents the - * role and adds additional functionality to wl_surface. When a - * client wants to destroy a wl_surface, they must destroy this role - * object before the wl_surface, otherwise a defunct_role_object error is - * sent. - * - * Destroying the role object does not remove the role from the - * wl_surface, but it may stop the wl_surface from "playing the role". - * For instance, if a wl_subsurface object is destroyed, the wl_surface - * it was created for will be unmapped and forget its position and - * z-order. It is allowed to create a wl_subsurface for the same - * wl_surface again, but it is not allowed to use the wl_surface as - * a cursor (cursor is a different role than sub-surface, and role - * switching is not allowed). - */ -extern const struct wl_interface wl_surface_interface; -#endif -#ifndef WL_SEAT_INTERFACE -#define WL_SEAT_INTERFACE -/** - * @page page_iface_wl_seat wl_seat - * @section page_iface_wl_seat_desc Description - * - * A seat is a group of keyboards, pointer and touch devices. This - * object is published as a global during start up, or when such a - * device is hot plugged. A seat typically has a pointer and - * maintains a keyboard focus and a pointer focus. - * @section page_iface_wl_seat_api API - * See @ref iface_wl_seat. - */ -/** - * @defgroup iface_wl_seat The wl_seat interface - * - * A seat is a group of keyboards, pointer and touch devices. This - * object is published as a global during start up, or when such a - * device is hot plugged. A seat typically has a pointer and - * maintains a keyboard focus and a pointer focus. - */ -extern const struct wl_interface wl_seat_interface; -#endif -#ifndef WL_POINTER_INTERFACE -#define WL_POINTER_INTERFACE -/** - * @page page_iface_wl_pointer wl_pointer - * @section page_iface_wl_pointer_desc Description - * - * The wl_pointer interface represents one or more input devices, - * such as mice, which control the pointer location and pointer_focus - * of a seat. - * - * The wl_pointer interface generates motion, enter and leave - * events for the surfaces that the pointer is located over, - * and button and axis events for button presses, button releases - * and scrolling. - * @section page_iface_wl_pointer_api API - * See @ref iface_wl_pointer. - */ -/** - * @defgroup iface_wl_pointer The wl_pointer interface - * - * The wl_pointer interface represents one or more input devices, - * such as mice, which control the pointer location and pointer_focus - * of a seat. - * - * The wl_pointer interface generates motion, enter and leave - * events for the surfaces that the pointer is located over, - * and button and axis events for button presses, button releases - * and scrolling. - */ -extern const struct wl_interface wl_pointer_interface; -#endif -#ifndef WL_KEYBOARD_INTERFACE -#define WL_KEYBOARD_INTERFACE -/** - * @page page_iface_wl_keyboard wl_keyboard - * @section page_iface_wl_keyboard_desc Description - * - * The wl_keyboard interface represents one or more keyboards - * associated with a seat. - * @section page_iface_wl_keyboard_api API - * See @ref iface_wl_keyboard. - */ -/** - * @defgroup iface_wl_keyboard The wl_keyboard interface - * - * The wl_keyboard interface represents one or more keyboards - * associated with a seat. - */ -extern const struct wl_interface wl_keyboard_interface; -#endif -#ifndef WL_TOUCH_INTERFACE -#define WL_TOUCH_INTERFACE -/** - * @page page_iface_wl_touch wl_touch - * @section page_iface_wl_touch_desc Description - * - * The wl_touch interface represents a touchscreen - * associated with a seat. - * - * Touch interactions can consist of one or more contacts. - * For each contact, a series of events is generated, starting - * with a down event, followed by zero or more motion events, - * and ending with an up event. Events relating to the same - * contact point can be identified by the ID of the sequence. - * @section page_iface_wl_touch_api API - * See @ref iface_wl_touch. - */ -/** - * @defgroup iface_wl_touch The wl_touch interface - * - * The wl_touch interface represents a touchscreen - * associated with a seat. - * - * Touch interactions can consist of one or more contacts. - * For each contact, a series of events is generated, starting - * with a down event, followed by zero or more motion events, - * and ending with an up event. Events relating to the same - * contact point can be identified by the ID of the sequence. - */ -extern const struct wl_interface wl_touch_interface; -#endif -#ifndef WL_OUTPUT_INTERFACE -#define WL_OUTPUT_INTERFACE -/** - * @page page_iface_wl_output wl_output - * @section page_iface_wl_output_desc Description - * - * An output describes part of the compositor geometry. The - * compositor works in the 'compositor coordinate system' and an - * output corresponds to a rectangular area in that space that is - * actually visible. This typically corresponds to a monitor that - * displays part of the compositor space. This object is published - * as global during start up, or when a monitor is hotplugged. - * @section page_iface_wl_output_api API - * See @ref iface_wl_output. - */ -/** - * @defgroup iface_wl_output The wl_output interface - * - * An output describes part of the compositor geometry. The - * compositor works in the 'compositor coordinate system' and an - * output corresponds to a rectangular area in that space that is - * actually visible. This typically corresponds to a monitor that - * displays part of the compositor space. This object is published - * as global during start up, or when a monitor is hotplugged. - */ -extern const struct wl_interface wl_output_interface; -#endif -#ifndef WL_REGION_INTERFACE -#define WL_REGION_INTERFACE -/** - * @page page_iface_wl_region wl_region - * @section page_iface_wl_region_desc Description - * - * A region object describes an area. - * - * Region objects are used to describe the opaque and input - * regions of a surface. - * @section page_iface_wl_region_api API - * See @ref iface_wl_region. - */ -/** - * @defgroup iface_wl_region The wl_region interface - * - * A region object describes an area. - * - * Region objects are used to describe the opaque and input - * regions of a surface. - */ -extern const struct wl_interface wl_region_interface; -#endif -#ifndef WL_SUBCOMPOSITOR_INTERFACE -#define WL_SUBCOMPOSITOR_INTERFACE -/** - * @page page_iface_wl_subcompositor wl_subcompositor - * @section page_iface_wl_subcompositor_desc Description - * - * The global interface exposing sub-surface compositing capabilities. - * A wl_surface, that has sub-surfaces associated, is called the - * parent surface. Sub-surfaces can be arbitrarily nested and create - * a tree of sub-surfaces. - * - * The root surface in a tree of sub-surfaces is the main - * surface. The main surface cannot be a sub-surface, because - * sub-surfaces must always have a parent. - * - * A main surface with its sub-surfaces forms a (compound) window. - * For window management purposes, this set of wl_surface objects is - * to be considered as a single window, and it should also behave as - * such. - * - * The aim of sub-surfaces is to offload some of the compositing work - * within a window from clients to the compositor. A prime example is - * a video player with decorations and video in separate wl_surface - * objects. This should allow the compositor to pass YUV video buffer - * processing to dedicated overlay hardware when possible. - * @section page_iface_wl_subcompositor_api API - * See @ref iface_wl_subcompositor. - */ -/** - * @defgroup iface_wl_subcompositor The wl_subcompositor interface - * - * The global interface exposing sub-surface compositing capabilities. - * A wl_surface, that has sub-surfaces associated, is called the - * parent surface. Sub-surfaces can be arbitrarily nested and create - * a tree of sub-surfaces. - * - * The root surface in a tree of sub-surfaces is the main - * surface. The main surface cannot be a sub-surface, because - * sub-surfaces must always have a parent. - * - * A main surface with its sub-surfaces forms a (compound) window. - * For window management purposes, this set of wl_surface objects is - * to be considered as a single window, and it should also behave as - * such. - * - * The aim of sub-surfaces is to offload some of the compositing work - * within a window from clients to the compositor. A prime example is - * a video player with decorations and video in separate wl_surface - * objects. This should allow the compositor to pass YUV video buffer - * processing to dedicated overlay hardware when possible. - */ -extern const struct wl_interface wl_subcompositor_interface; -#endif -#ifndef WL_SUBSURFACE_INTERFACE -#define WL_SUBSURFACE_INTERFACE -/** - * @page page_iface_wl_subsurface wl_subsurface - * @section page_iface_wl_subsurface_desc Description - * - * An additional interface to a wl_surface object, which has been - * made a sub-surface. A sub-surface has one parent surface. A - * sub-surface's size and position are not limited to that of the parent. - * Particularly, a sub-surface is not automatically clipped to its - * parent's area. - * - * A sub-surface becomes mapped, when a non-NULL wl_buffer is applied - * and the parent surface is mapped. The order of which one happens - * first is irrelevant. A sub-surface is hidden if the parent becomes - * hidden, or if a NULL wl_buffer is applied. These rules apply - * recursively through the tree of surfaces. - * - * The behaviour of a wl_surface.commit request on a sub-surface - * depends on the sub-surface's mode. The possible modes are - * synchronized and desynchronized, see methods - * wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized - * mode caches the wl_surface state to be applied when the parent's - * state gets applied, and desynchronized mode applies the pending - * wl_surface state directly. A sub-surface is initially in the - * synchronized mode. - * - * Sub-surfaces also have another kind of state, which is managed by - * wl_subsurface requests, as opposed to wl_surface requests. This - * state includes the sub-surface position relative to the parent - * surface (wl_subsurface.set_position), and the stacking order of - * the parent and its sub-surfaces (wl_subsurface.place_above and - * .place_below). This state is applied when the parent surface's - * wl_surface state is applied, regardless of the sub-surface's mode. - * As the exception, set_sync and set_desync are effective immediately. - * - * The main surface can be thought to be always in desynchronized mode, - * since it does not have a parent in the sub-surfaces sense. - * - * Even if a sub-surface is in desynchronized mode, it will behave as - * in synchronized mode, if its parent surface behaves as in - * synchronized mode. This rule is applied recursively throughout the - * tree of surfaces. This means, that one can set a sub-surface into - * synchronized mode, and then assume that all its child and grand-child - * sub-surfaces are synchronized, too, without explicitly setting them. - * - * Destroying a sub-surface takes effect immediately. If you need to - * synchronize the removal of a sub-surface to the parent surface update, - * unmap the sub-surface first by attaching a NULL wl_buffer, update parent, - * and then destroy the sub-surface. - * - * If the parent wl_surface object is destroyed, the sub-surface is - * unmapped. - * @section page_iface_wl_subsurface_api API - * See @ref iface_wl_subsurface. - */ -/** - * @defgroup iface_wl_subsurface The wl_subsurface interface - * - * An additional interface to a wl_surface object, which has been - * made a sub-surface. A sub-surface has one parent surface. A - * sub-surface's size and position are not limited to that of the parent. - * Particularly, a sub-surface is not automatically clipped to its - * parent's area. - * - * A sub-surface becomes mapped, when a non-NULL wl_buffer is applied - * and the parent surface is mapped. The order of which one happens - * first is irrelevant. A sub-surface is hidden if the parent becomes - * hidden, or if a NULL wl_buffer is applied. These rules apply - * recursively through the tree of surfaces. - * - * The behaviour of a wl_surface.commit request on a sub-surface - * depends on the sub-surface's mode. The possible modes are - * synchronized and desynchronized, see methods - * wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized - * mode caches the wl_surface state to be applied when the parent's - * state gets applied, and desynchronized mode applies the pending - * wl_surface state directly. A sub-surface is initially in the - * synchronized mode. - * - * Sub-surfaces also have another kind of state, which is managed by - * wl_subsurface requests, as opposed to wl_surface requests. This - * state includes the sub-surface position relative to the parent - * surface (wl_subsurface.set_position), and the stacking order of - * the parent and its sub-surfaces (wl_subsurface.place_above and - * .place_below). This state is applied when the parent surface's - * wl_surface state is applied, regardless of the sub-surface's mode. - * As the exception, set_sync and set_desync are effective immediately. - * - * The main surface can be thought to be always in desynchronized mode, - * since it does not have a parent in the sub-surfaces sense. - * - * Even if a sub-surface is in desynchronized mode, it will behave as - * in synchronized mode, if its parent surface behaves as in - * synchronized mode. This rule is applied recursively throughout the - * tree of surfaces. This means, that one can set a sub-surface into - * synchronized mode, and then assume that all its child and grand-child - * sub-surfaces are synchronized, too, without explicitly setting them. - * - * Destroying a sub-surface takes effect immediately. If you need to - * synchronize the removal of a sub-surface to the parent surface update, - * unmap the sub-surface first by attaching a NULL wl_buffer, update parent, - * and then destroy the sub-surface. - * - * If the parent wl_surface object is destroyed, the sub-surface is - * unmapped. - */ -extern const struct wl_interface wl_subsurface_interface; -#endif - -#ifndef WL_DISPLAY_ERROR_ENUM -#define WL_DISPLAY_ERROR_ENUM -/** - * @ingroup iface_wl_display - * global error values - * - * These errors are global and can be emitted in response to any - * server request. - */ -enum wl_display_error { - /** - * server couldn't find object - */ - WL_DISPLAY_ERROR_INVALID_OBJECT = 0, - /** - * method doesn't exist on the specified interface or malformed request - */ - WL_DISPLAY_ERROR_INVALID_METHOD = 1, - /** - * server is out of memory - */ - WL_DISPLAY_ERROR_NO_MEMORY = 2, - /** - * implementation error in compositor - */ - WL_DISPLAY_ERROR_IMPLEMENTATION = 3, -}; -#endif /* WL_DISPLAY_ERROR_ENUM */ - -/** - * @ingroup iface_wl_display - * @struct wl_display_listener - */ -struct wl_display_listener { - /** - * fatal error event - * - * The error event is sent out when a fatal (non-recoverable) - * error has occurred. The object_id argument is the object where - * the error occurred, most often in response to a request to that - * object. The code identifies the error and is defined by the - * object interface. As such, each interface defines its own set of - * error codes. The message is a brief description of the error, - * for (debugging) convenience. - * @param object_id object where the error occurred - * @param code error code - * @param message error description - */ - void (*error)(void *data, - struct wl_display *wl_display, - void *object_id, - uint32_t code, - const char *message); - /** - * acknowledge object ID deletion - * - * This event is used internally by the object ID management - * logic. When a client deletes an object that it had created, the - * server will send this event to acknowledge that it has seen the - * delete request. When the client receives this event, it will - * know that it can safely reuse the object ID. - * @param id deleted object ID - */ - void (*delete_id)(void *data, - struct wl_display *wl_display, - uint32_t id); -}; - -/** - * @ingroup iface_wl_display - */ -static inline int -wl_display_add_listener(struct wl_display *wl_display, - const struct wl_display_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_display, - (void (**)(void)) listener, data); -} - -#define WL_DISPLAY_SYNC 0 -#define WL_DISPLAY_GET_REGISTRY 1 - -/** - * @ingroup iface_wl_display - */ -#define WL_DISPLAY_ERROR_SINCE_VERSION 1 -/** - * @ingroup iface_wl_display - */ -#define WL_DISPLAY_DELETE_ID_SINCE_VERSION 1 - -/** - * @ingroup iface_wl_display - */ -#define WL_DISPLAY_SYNC_SINCE_VERSION 1 -/** - * @ingroup iface_wl_display - */ -#define WL_DISPLAY_GET_REGISTRY_SINCE_VERSION 1 - -/** @ingroup iface_wl_display */ -static inline void -wl_display_set_user_data(struct wl_display *wl_display, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_display, user_data); -} - -/** @ingroup iface_wl_display */ -static inline void * -wl_display_get_user_data(struct wl_display *wl_display) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_display); -} - -static inline uint32_t -wl_display_get_version(struct wl_display *wl_display) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_display); -} - -/** - * @ingroup iface_wl_display - * - * The sync request asks the server to emit the 'done' event - * on the returned wl_callback object. Since requests are - * handled in-order and events are delivered in-order, this can - * be used as a barrier to ensure all previous requests and the - * resulting events have been handled. - * - * The object returned by this request will be destroyed by the - * compositor after the callback is fired and as such the client must not - * attempt to use it after that point. - * - * The callback_data passed in the callback is the event serial. - */ -static inline struct wl_callback * -wl_display_sync(struct wl_display *wl_display) -{ - struct wl_proxy *callback; - - callback = wl_proxy_marshal_flags((struct wl_proxy *) wl_display, - WL_DISPLAY_SYNC, &wl_callback_interface, wl_proxy_get_version((struct wl_proxy *) wl_display), 0, NULL); - - return (struct wl_callback *) callback; -} - -/** - * @ingroup iface_wl_display - * - * This request creates a registry object that allows the client - * to list and bind the global objects available from the - * compositor. - * - * It should be noted that the server side resources consumed in - * response to a get_registry request can only be released when the - * client disconnects, not when the client side proxy is destroyed. - * Therefore, clients should invoke get_registry as infrequently as - * possible to avoid wasting memory. - */ -static inline struct wl_registry * -wl_display_get_registry(struct wl_display *wl_display) -{ - struct wl_proxy *registry; - - registry = wl_proxy_marshal_flags((struct wl_proxy *) wl_display, - WL_DISPLAY_GET_REGISTRY, &wl_registry_interface, wl_proxy_get_version((struct wl_proxy *) wl_display), 0, NULL); - - return (struct wl_registry *) registry; -} - -/** - * @ingroup iface_wl_registry - * @struct wl_registry_listener - */ -struct wl_registry_listener { - /** - * announce global object - * - * Notify the client of global objects. - * - * The event notifies the client that a global object with the - * given name is now available, and it implements the given version - * of the given interface. - * @param name numeric name of the global object - * @param interface interface implemented by the object - * @param version interface version - */ - void (*global)(void *data, - struct wl_registry *wl_registry, - uint32_t name, - const char *interface, - uint32_t version); - /** - * announce removal of global object - * - * Notify the client of removed global objects. - * - * This event notifies the client that the global identified by - * name is no longer available. If the client bound to the global - * using the bind request, the client should now destroy that - * object. - * - * The object remains valid and requests to the object will be - * ignored until the client destroys it, to avoid races between the - * global going away and a client sending a request to it. - * @param name numeric name of the global object - */ - void (*global_remove)(void *data, - struct wl_registry *wl_registry, - uint32_t name); -}; - -/** - * @ingroup iface_wl_registry - */ -static inline int -wl_registry_add_listener(struct wl_registry *wl_registry, - const struct wl_registry_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_registry, - (void (**)(void)) listener, data); -} - -#define WL_REGISTRY_BIND 0 - -/** - * @ingroup iface_wl_registry - */ -#define WL_REGISTRY_GLOBAL_SINCE_VERSION 1 -/** - * @ingroup iface_wl_registry - */ -#define WL_REGISTRY_GLOBAL_REMOVE_SINCE_VERSION 1 - -/** - * @ingroup iface_wl_registry - */ -#define WL_REGISTRY_BIND_SINCE_VERSION 1 - -/** @ingroup iface_wl_registry */ -static inline void -wl_registry_set_user_data(struct wl_registry *wl_registry, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_registry, user_data); -} - -/** @ingroup iface_wl_registry */ -static inline void * -wl_registry_get_user_data(struct wl_registry *wl_registry) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_registry); -} - -static inline uint32_t -wl_registry_get_version(struct wl_registry *wl_registry) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_registry); -} - -/** @ingroup iface_wl_registry */ -static inline void -wl_registry_destroy(struct wl_registry *wl_registry) -{ - wl_proxy_destroy((struct wl_proxy *) wl_registry); -} - -/** - * @ingroup iface_wl_registry - * - * Binds a new, client-created object to the server using the - * specified name as the identifier. - */ -static inline void * -wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_registry, - WL_REGISTRY_BIND, interface, version, 0, name, interface->name, version, NULL); - - return (void *) id; -} - -/** - * @ingroup iface_wl_callback - * @struct wl_callback_listener - */ -struct wl_callback_listener { - /** - * done event - * - * Notify the client when the related request is done. - * @param callback_data request-specific data for the callback - */ - void (*done)(void *data, - struct wl_callback *wl_callback, - uint32_t callback_data); -}; - -/** - * @ingroup iface_wl_callback - */ -static inline int -wl_callback_add_listener(struct wl_callback *wl_callback, - const struct wl_callback_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_callback, - (void (**)(void)) listener, data); -} - -/** - * @ingroup iface_wl_callback - */ -#define WL_CALLBACK_DONE_SINCE_VERSION 1 - - -/** @ingroup iface_wl_callback */ -static inline void -wl_callback_set_user_data(struct wl_callback *wl_callback, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_callback, user_data); -} - -/** @ingroup iface_wl_callback */ -static inline void * -wl_callback_get_user_data(struct wl_callback *wl_callback) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_callback); -} - -static inline uint32_t -wl_callback_get_version(struct wl_callback *wl_callback) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_callback); -} - -/** @ingroup iface_wl_callback */ -static inline void -wl_callback_destroy(struct wl_callback *wl_callback) -{ - wl_proxy_destroy((struct wl_proxy *) wl_callback); -} - -#define WL_COMPOSITOR_CREATE_SURFACE 0 -#define WL_COMPOSITOR_CREATE_REGION 1 - - -/** - * @ingroup iface_wl_compositor - */ -#define WL_COMPOSITOR_CREATE_SURFACE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_compositor - */ -#define WL_COMPOSITOR_CREATE_REGION_SINCE_VERSION 1 - -/** @ingroup iface_wl_compositor */ -static inline void -wl_compositor_set_user_data(struct wl_compositor *wl_compositor, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_compositor, user_data); -} - -/** @ingroup iface_wl_compositor */ -static inline void * -wl_compositor_get_user_data(struct wl_compositor *wl_compositor) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_compositor); -} - -static inline uint32_t -wl_compositor_get_version(struct wl_compositor *wl_compositor) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_compositor); -} - -/** @ingroup iface_wl_compositor */ -static inline void -wl_compositor_destroy(struct wl_compositor *wl_compositor) -{ - wl_proxy_destroy((struct wl_proxy *) wl_compositor); -} - -/** - * @ingroup iface_wl_compositor - * - * Ask the compositor to create a new surface. - */ -static inline struct wl_surface * -wl_compositor_create_surface(struct wl_compositor *wl_compositor) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_compositor, - WL_COMPOSITOR_CREATE_SURFACE, &wl_surface_interface, wl_proxy_get_version((struct wl_proxy *) wl_compositor), 0, NULL); - - return (struct wl_surface *) id; -} - -/** - * @ingroup iface_wl_compositor - * - * Ask the compositor to create a new region. - */ -static inline struct wl_region * -wl_compositor_create_region(struct wl_compositor *wl_compositor) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_compositor, - WL_COMPOSITOR_CREATE_REGION, &wl_region_interface, wl_proxy_get_version((struct wl_proxy *) wl_compositor), 0, NULL); - - return (struct wl_region *) id; -} - -#define WL_SHM_POOL_CREATE_BUFFER 0 -#define WL_SHM_POOL_DESTROY 1 -#define WL_SHM_POOL_RESIZE 2 - - -/** - * @ingroup iface_wl_shm_pool - */ -#define WL_SHM_POOL_CREATE_BUFFER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shm_pool - */ -#define WL_SHM_POOL_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shm_pool - */ -#define WL_SHM_POOL_RESIZE_SINCE_VERSION 1 - -/** @ingroup iface_wl_shm_pool */ -static inline void -wl_shm_pool_set_user_data(struct wl_shm_pool *wl_shm_pool, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_shm_pool, user_data); -} - -/** @ingroup iface_wl_shm_pool */ -static inline void * -wl_shm_pool_get_user_data(struct wl_shm_pool *wl_shm_pool) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_shm_pool); -} - -static inline uint32_t -wl_shm_pool_get_version(struct wl_shm_pool *wl_shm_pool) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_shm_pool); -} - -/** - * @ingroup iface_wl_shm_pool - * - * Create a wl_buffer object from the pool. - * - * The buffer is created offset bytes into the pool and has - * width and height as specified. The stride argument specifies - * the number of bytes from the beginning of one row to the beginning - * of the next. The format is the pixel format of the buffer and - * must be one of those advertised through the wl_shm.format event. - * - * A buffer will keep a reference to the pool it was created from - * so it is valid to destroy the pool immediately after creating - * a buffer from it. - */ -static inline struct wl_buffer * -wl_shm_pool_create_buffer(struct wl_shm_pool *wl_shm_pool, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, - WL_SHM_POOL_CREATE_BUFFER, &wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), 0, NULL, offset, width, height, stride, format); - - return (struct wl_buffer *) id; -} - -/** - * @ingroup iface_wl_shm_pool - * - * Destroy the shared memory pool. - * - * The mmapped memory will be released when all - * buffers that have been created from this pool - * are gone. - */ -static inline void -wl_shm_pool_destroy(struct wl_shm_pool *wl_shm_pool) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, - WL_SHM_POOL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_shm_pool - * - * This request will cause the server to remap the backing memory - * for the pool from the file descriptor passed when the pool was - * created, but using the new size. This request can only be - * used to make the pool bigger. - * - * This request only changes the amount of bytes that are mmapped - * by the server and does not touch the file corresponding to the - * file descriptor passed at creation time. It is the client's - * responsibility to ensure that the file is at least as big as - * the new pool size. - */ -static inline void -wl_shm_pool_resize(struct wl_shm_pool *wl_shm_pool, int32_t size) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, - WL_SHM_POOL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), 0, size); -} - -#ifndef WL_SHM_ERROR_ENUM -#define WL_SHM_ERROR_ENUM -/** - * @ingroup iface_wl_shm - * wl_shm error values - * - * These errors can be emitted in response to wl_shm requests. - */ -enum wl_shm_error { - /** - * buffer format is not known - */ - WL_SHM_ERROR_INVALID_FORMAT = 0, - /** - * invalid size or stride during pool or buffer creation - */ - WL_SHM_ERROR_INVALID_STRIDE = 1, - /** - * mmapping the file descriptor failed - */ - WL_SHM_ERROR_INVALID_FD = 2, -}; -#endif /* WL_SHM_ERROR_ENUM */ - -#ifndef WL_SHM_FORMAT_ENUM -#define WL_SHM_FORMAT_ENUM -/** - * @ingroup iface_wl_shm - * pixel formats - * - * This describes the memory layout of an individual pixel. - * - * All renderers should support argb8888 and xrgb8888 but any other - * formats are optional and may not be supported by the particular - * renderer in use. - * - * The drm format codes match the macros defined in drm_fourcc.h, except - * argb8888 and xrgb8888. The formats actually supported by the compositor - * will be reported by the format event. - * - * For all wl_shm formats and unless specified in another protocol - * extension, pre-multiplied alpha is used for pixel values. - */ -enum wl_shm_format { - /** - * 32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian - */ - WL_SHM_FORMAT_ARGB8888 = 0, - /** - * 32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian - */ - WL_SHM_FORMAT_XRGB8888 = 1, - /** - * 8-bit color index format, [7:0] C - */ - WL_SHM_FORMAT_C8 = 0x20203843, - /** - * 8-bit RGB format, [7:0] R:G:B 3:3:2 - */ - WL_SHM_FORMAT_RGB332 = 0x38424752, - /** - * 8-bit BGR format, [7:0] B:G:R 2:3:3 - */ - WL_SHM_FORMAT_BGR233 = 0x38524742, - /** - * 16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian - */ - WL_SHM_FORMAT_XRGB4444 = 0x32315258, - /** - * 16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian - */ - WL_SHM_FORMAT_XBGR4444 = 0x32314258, - /** - * 16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian - */ - WL_SHM_FORMAT_RGBX4444 = 0x32315852, - /** - * 16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian - */ - WL_SHM_FORMAT_BGRX4444 = 0x32315842, - /** - * 16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian - */ - WL_SHM_FORMAT_ARGB4444 = 0x32315241, - /** - * 16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian - */ - WL_SHM_FORMAT_ABGR4444 = 0x32314241, - /** - * 16-bit RBGA format, [15:0] R:G:B:A 4:4:4:4 little endian - */ - WL_SHM_FORMAT_RGBA4444 = 0x32314152, - /** - * 16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian - */ - WL_SHM_FORMAT_BGRA4444 = 0x32314142, - /** - * 16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian - */ - WL_SHM_FORMAT_XRGB1555 = 0x35315258, - /** - * 16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian - */ - WL_SHM_FORMAT_XBGR1555 = 0x35314258, - /** - * 16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian - */ - WL_SHM_FORMAT_RGBX5551 = 0x35315852, - /** - * 16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian - */ - WL_SHM_FORMAT_BGRX5551 = 0x35315842, - /** - * 16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian - */ - WL_SHM_FORMAT_ARGB1555 = 0x35315241, - /** - * 16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian - */ - WL_SHM_FORMAT_ABGR1555 = 0x35314241, - /** - * 16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian - */ - WL_SHM_FORMAT_RGBA5551 = 0x35314152, - /** - * 16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian - */ - WL_SHM_FORMAT_BGRA5551 = 0x35314142, - /** - * 16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian - */ - WL_SHM_FORMAT_RGB565 = 0x36314752, - /** - * 16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian - */ - WL_SHM_FORMAT_BGR565 = 0x36314742, - /** - * 24-bit RGB format, [23:0] R:G:B little endian - */ - WL_SHM_FORMAT_RGB888 = 0x34324752, - /** - * 24-bit BGR format, [23:0] B:G:R little endian - */ - WL_SHM_FORMAT_BGR888 = 0x34324742, - /** - * 32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian - */ - WL_SHM_FORMAT_XBGR8888 = 0x34324258, - /** - * 32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian - */ - WL_SHM_FORMAT_RGBX8888 = 0x34325852, - /** - * 32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian - */ - WL_SHM_FORMAT_BGRX8888 = 0x34325842, - /** - * 32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian - */ - WL_SHM_FORMAT_ABGR8888 = 0x34324241, - /** - * 32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian - */ - WL_SHM_FORMAT_RGBA8888 = 0x34324152, - /** - * 32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian - */ - WL_SHM_FORMAT_BGRA8888 = 0x34324142, - /** - * 32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian - */ - WL_SHM_FORMAT_XRGB2101010 = 0x30335258, - /** - * 32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian - */ - WL_SHM_FORMAT_XBGR2101010 = 0x30334258, - /** - * 32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian - */ - WL_SHM_FORMAT_RGBX1010102 = 0x30335852, - /** - * 32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian - */ - WL_SHM_FORMAT_BGRX1010102 = 0x30335842, - /** - * 32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian - */ - WL_SHM_FORMAT_ARGB2101010 = 0x30335241, - /** - * 32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian - */ - WL_SHM_FORMAT_ABGR2101010 = 0x30334241, - /** - * 32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian - */ - WL_SHM_FORMAT_RGBA1010102 = 0x30334152, - /** - * 32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian - */ - WL_SHM_FORMAT_BGRA1010102 = 0x30334142, - /** - * packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian - */ - WL_SHM_FORMAT_YUYV = 0x56595559, - /** - * packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian - */ - WL_SHM_FORMAT_YVYU = 0x55595659, - /** - * packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian - */ - WL_SHM_FORMAT_UYVY = 0x59565955, - /** - * packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian - */ - WL_SHM_FORMAT_VYUY = 0x59555956, - /** - * packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian - */ - WL_SHM_FORMAT_AYUV = 0x56555941, - /** - * 2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane - */ - WL_SHM_FORMAT_NV12 = 0x3231564e, - /** - * 2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane - */ - WL_SHM_FORMAT_NV21 = 0x3132564e, - /** - * 2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane - */ - WL_SHM_FORMAT_NV16 = 0x3631564e, - /** - * 2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane - */ - WL_SHM_FORMAT_NV61 = 0x3136564e, - /** - * 3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes - */ - WL_SHM_FORMAT_YUV410 = 0x39565559, - /** - * 3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes - */ - WL_SHM_FORMAT_YVU410 = 0x39555659, - /** - * 3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes - */ - WL_SHM_FORMAT_YUV411 = 0x31315559, - /** - * 3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes - */ - WL_SHM_FORMAT_YVU411 = 0x31315659, - /** - * 3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes - */ - WL_SHM_FORMAT_YUV420 = 0x32315559, - /** - * 3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes - */ - WL_SHM_FORMAT_YVU420 = 0x32315659, - /** - * 3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes - */ - WL_SHM_FORMAT_YUV422 = 0x36315559, - /** - * 3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes - */ - WL_SHM_FORMAT_YVU422 = 0x36315659, - /** - * 3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes - */ - WL_SHM_FORMAT_YUV444 = 0x34325559, - /** - * 3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes - */ - WL_SHM_FORMAT_YVU444 = 0x34325659, - /** - * [7:0] R - */ - WL_SHM_FORMAT_R8 = 0x20203852, - /** - * [15:0] R little endian - */ - WL_SHM_FORMAT_R16 = 0x20363152, - /** - * [15:0] R:G 8:8 little endian - */ - WL_SHM_FORMAT_RG88 = 0x38384752, - /** - * [15:0] G:R 8:8 little endian - */ - WL_SHM_FORMAT_GR88 = 0x38385247, - /** - * [31:0] R:G 16:16 little endian - */ - WL_SHM_FORMAT_RG1616 = 0x32334752, - /** - * [31:0] G:R 16:16 little endian - */ - WL_SHM_FORMAT_GR1616 = 0x32335247, - /** - * [63:0] x:R:G:B 16:16:16:16 little endian - */ - WL_SHM_FORMAT_XRGB16161616F = 0x48345258, - /** - * [63:0] x:B:G:R 16:16:16:16 little endian - */ - WL_SHM_FORMAT_XBGR16161616F = 0x48344258, - /** - * [63:0] A:R:G:B 16:16:16:16 little endian - */ - WL_SHM_FORMAT_ARGB16161616F = 0x48345241, - /** - * [63:0] A:B:G:R 16:16:16:16 little endian - */ - WL_SHM_FORMAT_ABGR16161616F = 0x48344241, - /** - * [31:0] X:Y:Cb:Cr 8:8:8:8 little endian - */ - WL_SHM_FORMAT_XYUV8888 = 0x56555958, - /** - * [23:0] Cr:Cb:Y 8:8:8 little endian - */ - WL_SHM_FORMAT_VUY888 = 0x34325556, - /** - * Y followed by U then V, 10:10:10. Non-linear modifier only - */ - WL_SHM_FORMAT_VUY101010 = 0x30335556, - /** - * [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels - */ - WL_SHM_FORMAT_Y210 = 0x30313259, - /** - * [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels - */ - WL_SHM_FORMAT_Y212 = 0x32313259, - /** - * [63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels - */ - WL_SHM_FORMAT_Y216 = 0x36313259, - /** - * [31:0] A:Cr:Y:Cb 2:10:10:10 little endian - */ - WL_SHM_FORMAT_Y410 = 0x30313459, - /** - * [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian - */ - WL_SHM_FORMAT_Y412 = 0x32313459, - /** - * [63:0] A:Cr:Y:Cb 16:16:16:16 little endian - */ - WL_SHM_FORMAT_Y416 = 0x36313459, - /** - * [31:0] X:Cr:Y:Cb 2:10:10:10 little endian - */ - WL_SHM_FORMAT_XVYU2101010 = 0x30335658, - /** - * [63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian - */ - WL_SHM_FORMAT_XVYU12_16161616 = 0x36335658, - /** - * [63:0] X:Cr:Y:Cb 16:16:16:16 little endian - */ - WL_SHM_FORMAT_XVYU16161616 = 0x38345658, - /** - * [63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian - */ - WL_SHM_FORMAT_Y0L0 = 0x304c3059, - /** - * [63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian - */ - WL_SHM_FORMAT_X0L0 = 0x304c3058, - /** - * [63:0] A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian - */ - WL_SHM_FORMAT_Y0L2 = 0x324c3059, - /** - * [63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian - */ - WL_SHM_FORMAT_X0L2 = 0x324c3058, - WL_SHM_FORMAT_YUV420_8BIT = 0x38305559, - WL_SHM_FORMAT_YUV420_10BIT = 0x30315559, - WL_SHM_FORMAT_XRGB8888_A8 = 0x38415258, - WL_SHM_FORMAT_XBGR8888_A8 = 0x38414258, - WL_SHM_FORMAT_RGBX8888_A8 = 0x38415852, - WL_SHM_FORMAT_BGRX8888_A8 = 0x38415842, - WL_SHM_FORMAT_RGB888_A8 = 0x38413852, - WL_SHM_FORMAT_BGR888_A8 = 0x38413842, - WL_SHM_FORMAT_RGB565_A8 = 0x38413552, - WL_SHM_FORMAT_BGR565_A8 = 0x38413542, - /** - * non-subsampled Cr:Cb plane - */ - WL_SHM_FORMAT_NV24 = 0x3432564e, - /** - * non-subsampled Cb:Cr plane - */ - WL_SHM_FORMAT_NV42 = 0x3234564e, - /** - * 2x1 subsampled Cr:Cb plane, 10 bit per channel - */ - WL_SHM_FORMAT_P210 = 0x30313250, - /** - * 2x2 subsampled Cr:Cb plane 10 bits per channel - */ - WL_SHM_FORMAT_P010 = 0x30313050, - /** - * 2x2 subsampled Cr:Cb plane 12 bits per channel - */ - WL_SHM_FORMAT_P012 = 0x32313050, - /** - * 2x2 subsampled Cr:Cb plane 16 bits per channel - */ - WL_SHM_FORMAT_P016 = 0x36313050, - /** - * [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian - */ - WL_SHM_FORMAT_AXBXGXRX106106106106 = 0x30314241, - /** - * 2x2 subsampled Cr:Cb plane - */ - WL_SHM_FORMAT_NV15 = 0x3531564e, - WL_SHM_FORMAT_Q410 = 0x30313451, - WL_SHM_FORMAT_Q401 = 0x31303451, - /** - * [63:0] x:R:G:B 16:16:16:16 little endian - */ - WL_SHM_FORMAT_XRGB16161616 = 0x38345258, - /** - * [63:0] x:B:G:R 16:16:16:16 little endian - */ - WL_SHM_FORMAT_XBGR16161616 = 0x38344258, - /** - * [63:0] A:R:G:B 16:16:16:16 little endian - */ - WL_SHM_FORMAT_ARGB16161616 = 0x38345241, - /** - * [63:0] A:B:G:R 16:16:16:16 little endian - */ - WL_SHM_FORMAT_ABGR16161616 = 0x38344241, - /** - * [7:0] C0:C1:C2:C3:C4:C5:C6:C7 1:1:1:1:1:1:1:1 eight pixels/byte - */ - WL_SHM_FORMAT_C1 = 0x20203143, - /** - * [7:0] C0:C1:C2:C3 2:2:2:2 four pixels/byte - */ - WL_SHM_FORMAT_C2 = 0x20203243, - /** - * [7:0] C0:C1 4:4 two pixels/byte - */ - WL_SHM_FORMAT_C4 = 0x20203443, - /** - * [7:0] D0:D1:D2:D3:D4:D5:D6:D7 1:1:1:1:1:1:1:1 eight pixels/byte - */ - WL_SHM_FORMAT_D1 = 0x20203144, - /** - * [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte - */ - WL_SHM_FORMAT_D2 = 0x20203244, - /** - * [7:0] D0:D1 4:4 two pixels/byte - */ - WL_SHM_FORMAT_D4 = 0x20203444, - /** - * [7:0] D - */ - WL_SHM_FORMAT_D8 = 0x20203844, - /** - * [7:0] R0:R1:R2:R3:R4:R5:R6:R7 1:1:1:1:1:1:1:1 eight pixels/byte - */ - WL_SHM_FORMAT_R1 = 0x20203152, - /** - * [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte - */ - WL_SHM_FORMAT_R2 = 0x20203252, - /** - * [7:0] R0:R1 4:4 two pixels/byte - */ - WL_SHM_FORMAT_R4 = 0x20203452, - /** - * [15:0] x:R 6:10 little endian - */ - WL_SHM_FORMAT_R10 = 0x20303152, - /** - * [15:0] x:R 4:12 little endian - */ - WL_SHM_FORMAT_R12 = 0x20323152, - /** - * [31:0] A:Cr:Cb:Y 8:8:8:8 little endian - */ - WL_SHM_FORMAT_AVUY8888 = 0x59555641, - /** - * [31:0] X:Cr:Cb:Y 8:8:8:8 little endian - */ - WL_SHM_FORMAT_XVUY8888 = 0x59555658, - /** - * 2x2 subsampled Cr:Cb plane 10 bits per channel packed - */ - WL_SHM_FORMAT_P030 = 0x30333050, -}; -#endif /* WL_SHM_FORMAT_ENUM */ - -/** - * @ingroup iface_wl_shm - * @struct wl_shm_listener - */ -struct wl_shm_listener { - /** - * pixel format description - * - * Informs the client about a valid pixel format that can be used - * for buffers. Known formats include argb8888 and xrgb8888. - * @param format buffer pixel format - */ - void (*format)(void *data, - struct wl_shm *wl_shm, - uint32_t format); -}; - -/** - * @ingroup iface_wl_shm - */ -static inline int -wl_shm_add_listener(struct wl_shm *wl_shm, - const struct wl_shm_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_shm, - (void (**)(void)) listener, data); -} - -#define WL_SHM_CREATE_POOL 0 - -/** - * @ingroup iface_wl_shm - */ -#define WL_SHM_FORMAT_SINCE_VERSION 1 - -/** - * @ingroup iface_wl_shm - */ -#define WL_SHM_CREATE_POOL_SINCE_VERSION 1 - -/** @ingroup iface_wl_shm */ -static inline void -wl_shm_set_user_data(struct wl_shm *wl_shm, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_shm, user_data); -} - -/** @ingroup iface_wl_shm */ -static inline void * -wl_shm_get_user_data(struct wl_shm *wl_shm) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_shm); -} - -static inline uint32_t -wl_shm_get_version(struct wl_shm *wl_shm) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_shm); -} - -/** @ingroup iface_wl_shm */ -static inline void -wl_shm_destroy(struct wl_shm *wl_shm) -{ - wl_proxy_destroy((struct wl_proxy *) wl_shm); -} - -/** - * @ingroup iface_wl_shm - * - * Create a new wl_shm_pool object. - * - * The pool can be used to create shared memory based buffer - * objects. The server will mmap size bytes of the passed file - * descriptor, to use as backing memory for the pool. - */ -static inline struct wl_shm_pool * -wl_shm_create_pool(struct wl_shm *wl_shm, int32_t fd, int32_t size) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shm, - WL_SHM_CREATE_POOL, &wl_shm_pool_interface, wl_proxy_get_version((struct wl_proxy *) wl_shm), 0, NULL, fd, size); - - return (struct wl_shm_pool *) id; -} - -/** - * @ingroup iface_wl_buffer - * @struct wl_buffer_listener - */ -struct wl_buffer_listener { - /** - * compositor releases buffer - * - * Sent when this wl_buffer is no longer used by the compositor. - * The client is now free to reuse or destroy this buffer and its - * backing storage. - * - * If a client receives a release event before the frame callback - * requested in the same wl_surface.commit that attaches this - * wl_buffer to a surface, then the client is immediately free to - * reuse the buffer and its backing storage, and does not need a - * second buffer for the next surface content update. Typically - * this is possible, when the compositor maintains a copy of the - * wl_surface contents, e.g. as a GL texture. This is an important - * optimization for GL(ES) compositors with wl_shm clients. - */ - void (*release)(void *data, - struct wl_buffer *wl_buffer); -}; - -/** - * @ingroup iface_wl_buffer - */ -static inline int -wl_buffer_add_listener(struct wl_buffer *wl_buffer, - const struct wl_buffer_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_buffer, - (void (**)(void)) listener, data); -} - -#define WL_BUFFER_DESTROY 0 - -/** - * @ingroup iface_wl_buffer - */ -#define WL_BUFFER_RELEASE_SINCE_VERSION 1 - -/** - * @ingroup iface_wl_buffer - */ -#define WL_BUFFER_DESTROY_SINCE_VERSION 1 - -/** @ingroup iface_wl_buffer */ -static inline void -wl_buffer_set_user_data(struct wl_buffer *wl_buffer, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_buffer, user_data); -} - -/** @ingroup iface_wl_buffer */ -static inline void * -wl_buffer_get_user_data(struct wl_buffer *wl_buffer) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_buffer); -} - -static inline uint32_t -wl_buffer_get_version(struct wl_buffer *wl_buffer) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_buffer); -} - -/** - * @ingroup iface_wl_buffer - * - * Destroy a buffer. If and how you need to release the backing - * storage is defined by the buffer factory interface. - * - * For possible side-effects to a surface, see wl_surface.attach. - */ -static inline void -wl_buffer_destroy(struct wl_buffer *wl_buffer) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_buffer, - WL_BUFFER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_buffer), WL_MARSHAL_FLAG_DESTROY); -} - -#ifndef WL_DATA_OFFER_ERROR_ENUM -#define WL_DATA_OFFER_ERROR_ENUM -enum wl_data_offer_error { - /** - * finish request was called untimely - */ - WL_DATA_OFFER_ERROR_INVALID_FINISH = 0, - /** - * action mask contains invalid values - */ - WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK = 1, - /** - * action argument has an invalid value - */ - WL_DATA_OFFER_ERROR_INVALID_ACTION = 2, - /** - * offer doesn't accept this request - */ - WL_DATA_OFFER_ERROR_INVALID_OFFER = 3, -}; -#endif /* WL_DATA_OFFER_ERROR_ENUM */ - -/** - * @ingroup iface_wl_data_offer - * @struct wl_data_offer_listener - */ -struct wl_data_offer_listener { - /** - * advertise offered mime type - * - * Sent immediately after creating the wl_data_offer object. One - * event per offered mime type. - * @param mime_type offered mime type - */ - void (*offer)(void *data, - struct wl_data_offer *wl_data_offer, - const char *mime_type); - /** - * notify the source-side available actions - * - * This event indicates the actions offered by the data source. - * It will be sent immediately after creating the wl_data_offer - * object, or anytime the source side changes its offered actions - * through wl_data_source.set_actions. - * @param source_actions actions offered by the data source - * @since 3 - */ - void (*source_actions)(void *data, - struct wl_data_offer *wl_data_offer, - uint32_t source_actions); - /** - * notify the selected action - * - * This event indicates the action selected by the compositor - * after matching the source/destination side actions. Only one - * action (or none) will be offered here. - * - * This event can be emitted multiple times during the - * drag-and-drop operation in response to destination side action - * changes through wl_data_offer.set_actions. - * - * This event will no longer be emitted after wl_data_device.drop - * happened on the drag-and-drop destination, the client must honor - * the last action received, or the last preferred one set through - * wl_data_offer.set_actions when handling an "ask" action. - * - * Compositors may also change the selected action on the fly, - * mainly in response to keyboard modifier changes during the - * drag-and-drop operation. - * - * The most recent action received is always the valid one. Prior - * to receiving wl_data_device.drop, the chosen action may change - * (e.g. due to keyboard modifiers being pressed). At the time of - * receiving wl_data_device.drop the drag-and-drop destination must - * honor the last action received. - * - * Action changes may still happen after wl_data_device.drop, - * especially on "ask" actions, where the drag-and-drop destination - * may choose another action afterwards. Action changes happening - * at this stage are always the result of inter-client negotiation, - * the compositor shall no longer be able to induce a different - * action. - * - * Upon "ask" actions, it is expected that the drag-and-drop - * destination may potentially choose a different action and/or - * mime type, based on wl_data_offer.source_actions and finally - * chosen by the user (e.g. popping up a menu with the available - * options). The final wl_data_offer.set_actions and - * wl_data_offer.accept requests must happen before the call to - * wl_data_offer.finish. - * @param dnd_action action selected by the compositor - * @since 3 - */ - void (*action)(void *data, - struct wl_data_offer *wl_data_offer, - uint32_t dnd_action); -}; - -/** - * @ingroup iface_wl_data_offer - */ -static inline int -wl_data_offer_add_listener(struct wl_data_offer *wl_data_offer, - const struct wl_data_offer_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_data_offer, - (void (**)(void)) listener, data); -} - -#define WL_DATA_OFFER_ACCEPT 0 -#define WL_DATA_OFFER_RECEIVE 1 -#define WL_DATA_OFFER_DESTROY 2 -#define WL_DATA_OFFER_FINISH 3 -#define WL_DATA_OFFER_SET_ACTIONS 4 - -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_OFFER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION 3 -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_ACTION_SINCE_VERSION 3 - -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_ACCEPT_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_RECEIVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_FINISH_SINCE_VERSION 3 -/** - * @ingroup iface_wl_data_offer - */ -#define WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION 3 - -/** @ingroup iface_wl_data_offer */ -static inline void -wl_data_offer_set_user_data(struct wl_data_offer *wl_data_offer, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_data_offer, user_data); -} - -/** @ingroup iface_wl_data_offer */ -static inline void * -wl_data_offer_get_user_data(struct wl_data_offer *wl_data_offer) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_data_offer); -} - -static inline uint32_t -wl_data_offer_get_version(struct wl_data_offer *wl_data_offer) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_data_offer); -} - -/** - * @ingroup iface_wl_data_offer - * - * Indicate that the client can accept the given mime type, or - * NULL for not accepted. - * - * For objects of version 2 or older, this request is used by the - * client to give feedback whether the client can receive the given - * mime type, or NULL if none is accepted; the feedback does not - * determine whether the drag-and-drop operation succeeds or not. - * - * For objects of version 3 or newer, this request determines the - * final result of the drag-and-drop operation. If the end result - * is that no mime types were accepted, the drag-and-drop operation - * will be cancelled and the corresponding drag source will receive - * wl_data_source.cancelled. Clients may still use this event in - * conjunction with wl_data_source.action for feedback. - */ -static inline void -wl_data_offer_accept(struct wl_data_offer *wl_data_offer, uint32_t serial, const char *mime_type) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, - WL_DATA_OFFER_ACCEPT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, serial, mime_type); -} - -/** - * @ingroup iface_wl_data_offer - * - * To transfer the offered data, the client issues this request - * and indicates the mime type it wants to receive. The transfer - * happens through the passed file descriptor (typically created - * with the pipe system call). The source client writes the data - * in the mime type representation requested and then closes the - * file descriptor. - * - * The receiving client reads from the read end of the pipe until - * EOF and then closes its end, at which point the transfer is - * complete. - * - * This request may happen multiple times for different mime types, - * both before and after wl_data_device.drop. Drag-and-drop destination - * clients may preemptively fetch data or examine it more closely to - * determine acceptance. - */ -static inline void -wl_data_offer_receive(struct wl_data_offer *wl_data_offer, const char *mime_type, int32_t fd) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, - WL_DATA_OFFER_RECEIVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, mime_type, fd); -} - -/** - * @ingroup iface_wl_data_offer - * - * Destroy the data offer. - */ -static inline void -wl_data_offer_destroy(struct wl_data_offer *wl_data_offer) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, - WL_DATA_OFFER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_data_offer - * - * Notifies the compositor that the drag destination successfully - * finished the drag-and-drop operation. - * - * Upon receiving this request, the compositor will emit - * wl_data_source.dnd_finished on the drag source client. - * - * It is a client error to perform other requests than - * wl_data_offer.destroy after this one. It is also an error to perform - * this request after a NULL mime type has been set in - * wl_data_offer.accept or no action was received through - * wl_data_offer.action. - * - * If wl_data_offer.finish request is received for a non drag and drop - * operation, the invalid_finish protocol error is raised. - */ -static inline void -wl_data_offer_finish(struct wl_data_offer *wl_data_offer) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, - WL_DATA_OFFER_FINISH, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0); -} - -/** - * @ingroup iface_wl_data_offer - * - * Sets the actions that the destination side client supports for - * this operation. This request may trigger the emission of - * wl_data_source.action and wl_data_offer.action events if the compositor - * needs to change the selected action. - * - * This request can be called multiple times throughout the - * drag-and-drop operation, typically in response to wl_data_device.enter - * or wl_data_device.motion events. - * - * This request determines the final result of the drag-and-drop - * operation. If the end result is that no action is accepted, - * the drag source will receive wl_data_source.cancelled. - * - * The dnd_actions argument must contain only values expressed in the - * wl_data_device_manager.dnd_actions enum, and the preferred_action - * argument must only contain one of those values set, otherwise it - * will result in a protocol error. - * - * While managing an "ask" action, the destination drag-and-drop client - * may perform further wl_data_offer.receive requests, and is expected - * to perform one last wl_data_offer.set_actions request with a preferred - * action other than "ask" (and optionally wl_data_offer.accept) before - * requesting wl_data_offer.finish, in order to convey the action selected - * by the user. If the preferred action is not in the - * wl_data_offer.source_actions mask, an error will be raised. - * - * If the "ask" action is dismissed (e.g. user cancellation), the client - * is expected to perform wl_data_offer.destroy right away. - * - * This request can only be made on drag-and-drop offers, a protocol error - * will be raised otherwise. - */ -static inline void -wl_data_offer_set_actions(struct wl_data_offer *wl_data_offer, uint32_t dnd_actions, uint32_t preferred_action) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, - WL_DATA_OFFER_SET_ACTIONS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, dnd_actions, preferred_action); -} - -#ifndef WL_DATA_SOURCE_ERROR_ENUM -#define WL_DATA_SOURCE_ERROR_ENUM -enum wl_data_source_error { - /** - * action mask contains invalid values - */ - WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK = 0, - /** - * source doesn't accept this request - */ - WL_DATA_SOURCE_ERROR_INVALID_SOURCE = 1, -}; -#endif /* WL_DATA_SOURCE_ERROR_ENUM */ - -/** - * @ingroup iface_wl_data_source - * @struct wl_data_source_listener - */ -struct wl_data_source_listener { - /** - * a target accepts an offered mime type - * - * Sent when a target accepts pointer_focus or motion events. If - * a target does not accept any of the offered types, type is NULL. - * - * Used for feedback during drag-and-drop. - * @param mime_type mime type accepted by the target - */ - void (*target)(void *data, - struct wl_data_source *wl_data_source, - const char *mime_type); - /** - * send the data - * - * Request for data from the client. Send the data as the - * specified mime type over the passed file descriptor, then close - * it. - * @param mime_type mime type for the data - * @param fd file descriptor for the data - */ - void (*send)(void *data, - struct wl_data_source *wl_data_source, - const char *mime_type, - int32_t fd); - /** - * selection was cancelled - * - * This data source is no longer valid. There are several reasons - * why this could happen: - * - * - The data source has been replaced by another data source. - - * The drag-and-drop operation was performed, but the drop - * destination did not accept any of the mime types offered through - * wl_data_source.target. - The drag-and-drop operation was - * performed, but the drop destination did not select any of the - * actions present in the mask offered through - * wl_data_source.action. - The drag-and-drop operation was - * performed but didn't happen over a surface. - The compositor - * cancelled the drag-and-drop operation (e.g. compositor dependent - * timeouts to avoid stale drag-and-drop transfers). - * - * The client should clean up and destroy this data source. - * - * For objects of version 2 or older, wl_data_source.cancelled will - * only be emitted if the data source was replaced by another data - * source. - */ - void (*cancelled)(void *data, - struct wl_data_source *wl_data_source); - /** - * the drag-and-drop operation physically finished - * - * The user performed the drop action. This event does not - * indicate acceptance, wl_data_source.cancelled may still be - * emitted afterwards if the drop destination does not accept any - * mime type. - * - * However, this event might however not be received if the - * compositor cancelled the drag-and-drop operation before this - * event could happen. - * - * Note that the data_source may still be used in the future and - * should not be destroyed here. - * @since 3 - */ - void (*dnd_drop_performed)(void *data, - struct wl_data_source *wl_data_source); - /** - * the drag-and-drop operation concluded - * - * The drop destination finished interoperating with this data - * source, so the client is now free to destroy this data source - * and free all associated data. - * - * If the action used to perform the operation was "move", the - * source can now delete the transferred data. - * @since 3 - */ - void (*dnd_finished)(void *data, - struct wl_data_source *wl_data_source); - /** - * notify the selected action - * - * This event indicates the action selected by the compositor - * after matching the source/destination side actions. Only one - * action (or none) will be offered here. - * - * This event can be emitted multiple times during the - * drag-and-drop operation, mainly in response to destination side - * changes through wl_data_offer.set_actions, and as the data - * device enters/leaves surfaces. - * - * It is only possible to receive this event after - * wl_data_source.dnd_drop_performed if the drag-and-drop operation - * ended in an "ask" action, in which case the final - * wl_data_source.action event will happen immediately before - * wl_data_source.dnd_finished. - * - * Compositors may also change the selected action on the fly, - * mainly in response to keyboard modifier changes during the - * drag-and-drop operation. - * - * The most recent action received is always the valid one. The - * chosen action may change alongside negotiation (e.g. an "ask" - * action can turn into a "move" operation), so the effects of the - * final action must always be applied in - * wl_data_offer.dnd_finished. - * - * Clients can trigger cursor surface changes from this point, so - * they reflect the current action. - * @param dnd_action action selected by the compositor - * @since 3 - */ - void (*action)(void *data, - struct wl_data_source *wl_data_source, - uint32_t dnd_action); -}; - -/** - * @ingroup iface_wl_data_source - */ -static inline int -wl_data_source_add_listener(struct wl_data_source *wl_data_source, - const struct wl_data_source_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_data_source, - (void (**)(void)) listener, data); -} - -#define WL_DATA_SOURCE_OFFER 0 -#define WL_DATA_SOURCE_DESTROY 1 -#define WL_DATA_SOURCE_SET_ACTIONS 2 - -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_TARGET_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_SEND_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_CANCELLED_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION 3 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION 3 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_ACTION_SINCE_VERSION 3 - -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_OFFER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_source - */ -#define WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION 3 - -/** @ingroup iface_wl_data_source */ -static inline void -wl_data_source_set_user_data(struct wl_data_source *wl_data_source, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_data_source, user_data); -} - -/** @ingroup iface_wl_data_source */ -static inline void * -wl_data_source_get_user_data(struct wl_data_source *wl_data_source) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_data_source); -} - -static inline uint32_t -wl_data_source_get_version(struct wl_data_source *wl_data_source) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_data_source); -} - -/** - * @ingroup iface_wl_data_source - * - * This request adds a mime type to the set of mime types - * advertised to targets. Can be called several times to offer - * multiple types. - */ -static inline void -wl_data_source_offer(struct wl_data_source *wl_data_source, const char *mime_type) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, - WL_DATA_SOURCE_OFFER, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), 0, mime_type); -} - -/** - * @ingroup iface_wl_data_source - * - * Destroy the data source. - */ -static inline void -wl_data_source_destroy(struct wl_data_source *wl_data_source) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, - WL_DATA_SOURCE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_data_source - * - * Sets the actions that the source side client supports for this - * operation. This request may trigger wl_data_source.action and - * wl_data_offer.action events if the compositor needs to change the - * selected action. - * - * The dnd_actions argument must contain only values expressed in the - * wl_data_device_manager.dnd_actions enum, otherwise it will result - * in a protocol error. - * - * This request must be made once only, and can only be made on sources - * used in drag-and-drop, so it must be performed before - * wl_data_device.start_drag. Attempting to use the source other than - * for drag-and-drop will raise a protocol error. - */ -static inline void -wl_data_source_set_actions(struct wl_data_source *wl_data_source, uint32_t dnd_actions) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, - WL_DATA_SOURCE_SET_ACTIONS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), 0, dnd_actions); -} - -#ifndef WL_DATA_DEVICE_ERROR_ENUM -#define WL_DATA_DEVICE_ERROR_ENUM -enum wl_data_device_error { - /** - * given wl_surface has another role - */ - WL_DATA_DEVICE_ERROR_ROLE = 0, - /** - * source has already been used - */ - WL_DATA_DEVICE_ERROR_USED_SOURCE = 1, -}; -#endif /* WL_DATA_DEVICE_ERROR_ENUM */ - -/** - * @ingroup iface_wl_data_device - * @struct wl_data_device_listener - */ -struct wl_data_device_listener { - /** - * introduce a new wl_data_offer - * - * The data_offer event introduces a new wl_data_offer object, - * which will subsequently be used in either the data_device.enter - * event (for drag-and-drop) or the data_device.selection event - * (for selections). Immediately following the - * data_device.data_offer event, the new data_offer object will - * send out data_offer.offer events to describe the mime types it - * offers. - * @param id the new data_offer object - */ - void (*data_offer)(void *data, - struct wl_data_device *wl_data_device, - struct wl_data_offer *id); - /** - * initiate drag-and-drop session - * - * This event is sent when an active drag-and-drop pointer enters - * a surface owned by the client. The position of the pointer at - * enter time is provided by the x and y arguments, in - * surface-local coordinates. - * @param serial serial number of the enter event - * @param surface client surface entered - * @param x surface-local x coordinate - * @param y surface-local y coordinate - * @param id source data_offer object - */ - void (*enter)(void *data, - struct wl_data_device *wl_data_device, - uint32_t serial, - struct wl_surface *surface, - wl_fixed_t x, - wl_fixed_t y, - struct wl_data_offer *id); - /** - * end drag-and-drop session - * - * This event is sent when the drag-and-drop pointer leaves the - * surface and the session ends. The client must destroy the - * wl_data_offer introduced at enter time at this point. - */ - void (*leave)(void *data, - struct wl_data_device *wl_data_device); - /** - * drag-and-drop session motion - * - * This event is sent when the drag-and-drop pointer moves within - * the currently focused surface. The new position of the pointer - * is provided by the x and y arguments, in surface-local - * coordinates. - * @param time timestamp with millisecond granularity - * @param x surface-local x coordinate - * @param y surface-local y coordinate - */ - void (*motion)(void *data, - struct wl_data_device *wl_data_device, - uint32_t time, - wl_fixed_t x, - wl_fixed_t y); - /** - * end drag-and-drop session successfully - * - * The event is sent when a drag-and-drop operation is ended - * because the implicit grab is removed. - * - * The drag-and-drop destination is expected to honor the last - * action received through wl_data_offer.action, if the resulting - * action is "copy" or "move", the destination can still perform - * wl_data_offer.receive requests, and is expected to end all - * transfers with a wl_data_offer.finish request. - * - * If the resulting action is "ask", the action will not be - * considered final. The drag-and-drop destination is expected to - * perform one last wl_data_offer.set_actions request, or - * wl_data_offer.destroy in order to cancel the operation. - */ - void (*drop)(void *data, - struct wl_data_device *wl_data_device); - /** - * advertise new selection - * - * The selection event is sent out to notify the client of a new - * wl_data_offer for the selection for this device. The - * data_device.data_offer and the data_offer.offer events are sent - * out immediately before this event to introduce the data offer - * object. The selection event is sent to a client immediately - * before receiving keyboard focus and when a new selection is set - * while the client has keyboard focus. The data_offer is valid - * until a new data_offer or NULL is received or until the client - * loses keyboard focus. Switching surface with keyboard focus - * within the same client doesn't mean a new selection will be - * sent. The client must destroy the previous selection data_offer, - * if any, upon receiving this event. - * @param id selection data_offer object - */ - void (*selection)(void *data, - struct wl_data_device *wl_data_device, - struct wl_data_offer *id); -}; - -/** - * @ingroup iface_wl_data_device - */ -static inline int -wl_data_device_add_listener(struct wl_data_device *wl_data_device, - const struct wl_data_device_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_data_device, - (void (**)(void)) listener, data); -} - -#define WL_DATA_DEVICE_START_DRAG 0 -#define WL_DATA_DEVICE_SET_SELECTION 1 -#define WL_DATA_DEVICE_RELEASE 2 - -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_DATA_OFFER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_ENTER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_LEAVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_MOTION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_DROP_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_SELECTION_SINCE_VERSION 1 - -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_START_DRAG_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_SET_SELECTION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device - */ -#define WL_DATA_DEVICE_RELEASE_SINCE_VERSION 2 - -/** @ingroup iface_wl_data_device */ -static inline void -wl_data_device_set_user_data(struct wl_data_device *wl_data_device, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_data_device, user_data); -} - -/** @ingroup iface_wl_data_device */ -static inline void * -wl_data_device_get_user_data(struct wl_data_device *wl_data_device) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_data_device); -} - -static inline uint32_t -wl_data_device_get_version(struct wl_data_device *wl_data_device) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_data_device); -} - -/** @ingroup iface_wl_data_device */ -static inline void -wl_data_device_destroy(struct wl_data_device *wl_data_device) -{ - wl_proxy_destroy((struct wl_proxy *) wl_data_device); -} - -/** - * @ingroup iface_wl_data_device - * - * This request asks the compositor to start a drag-and-drop - * operation on behalf of the client. - * - * The source argument is the data source that provides the data - * for the eventual data transfer. If source is NULL, enter, leave - * and motion events are sent only to the client that initiated the - * drag and the client is expected to handle the data passing - * internally. If source is destroyed, the drag-and-drop session will be - * cancelled. - * - * The origin surface is the surface where the drag originates and - * the client must have an active implicit grab that matches the - * serial. - * - * The icon surface is an optional (can be NULL) surface that - * provides an icon to be moved around with the cursor. Initially, - * the top-left corner of the icon surface is placed at the cursor - * hotspot, but subsequent wl_surface.attach request can move the - * relative position. Attach requests must be confirmed with - * wl_surface.commit as usual. The icon surface is given the role of - * a drag-and-drop icon. If the icon surface already has another role, - * it raises a protocol error. - * - * The input region is ignored for wl_surfaces with the role of a - * drag-and-drop icon. - * - * The given source may not be used in any further set_selection or - * start_drag requests. Attempting to reuse a previously-used source - * may send a used_source error. - */ -static inline void -wl_data_device_start_drag(struct wl_data_device *wl_data_device, struct wl_data_source *source, struct wl_surface *origin, struct wl_surface *icon, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, - WL_DATA_DEVICE_START_DRAG, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), 0, source, origin, icon, serial); -} - -/** - * @ingroup iface_wl_data_device - * - * This request asks the compositor to set the selection - * to the data from the source on behalf of the client. - * - * To unset the selection, set the source to NULL. - * - * The given source may not be used in any further set_selection or - * start_drag requests. Attempting to reuse a previously-used source - * may send a used_source error. - */ -static inline void -wl_data_device_set_selection(struct wl_data_device *wl_data_device, struct wl_data_source *source, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, - WL_DATA_DEVICE_SET_SELECTION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), 0, source, serial); -} - -/** - * @ingroup iface_wl_data_device - * - * This request destroys the data device. - */ -static inline void -wl_data_device_release(struct wl_data_device *wl_data_device) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, - WL_DATA_DEVICE_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), WL_MARSHAL_FLAG_DESTROY); -} - -#ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM -#define WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM -/** - * @ingroup iface_wl_data_device_manager - * drag and drop actions - * - * This is a bitmask of the available/preferred actions in a - * drag-and-drop operation. - * - * In the compositor, the selected action is a result of matching the - * actions offered by the source and destination sides. "action" events - * with a "none" action will be sent to both source and destination if - * there is no match. All further checks will effectively happen on - * (source actions ∩ destination actions). - * - * In addition, compositors may also pick different actions in - * reaction to key modifiers being pressed. One common design that - * is used in major toolkits (and the behavior recommended for - * compositors) is: - * - * - If no modifiers are pressed, the first match (in bit order) - * will be used. - * - Pressing Shift selects "move", if enabled in the mask. - * - Pressing Control selects "copy", if enabled in the mask. - * - * Behavior beyond that is considered implementation-dependent. - * Compositors may for example bind other modifiers (like Alt/Meta) - * or drags initiated with other buttons than BTN_LEFT to specific - * actions (e.g. "ask"). - */ -enum wl_data_device_manager_dnd_action { - /** - * no action - */ - WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE = 0, - /** - * copy action - */ - WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY = 1, - /** - * move action - */ - WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE = 2, - /** - * ask action - */ - WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK = 4, -}; -#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */ - -#define WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE 0 -#define WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE 1 - - -/** - * @ingroup iface_wl_data_device_manager - */ -#define WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_data_device_manager - */ -#define WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE_SINCE_VERSION 1 - -/** @ingroup iface_wl_data_device_manager */ -static inline void -wl_data_device_manager_set_user_data(struct wl_data_device_manager *wl_data_device_manager, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_data_device_manager, user_data); -} - -/** @ingroup iface_wl_data_device_manager */ -static inline void * -wl_data_device_manager_get_user_data(struct wl_data_device_manager *wl_data_device_manager) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_data_device_manager); -} - -static inline uint32_t -wl_data_device_manager_get_version(struct wl_data_device_manager *wl_data_device_manager) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager); -} - -/** @ingroup iface_wl_data_device_manager */ -static inline void -wl_data_device_manager_destroy(struct wl_data_device_manager *wl_data_device_manager) -{ - wl_proxy_destroy((struct wl_proxy *) wl_data_device_manager); -} - -/** - * @ingroup iface_wl_data_device_manager - * - * Create a new data source. - */ -static inline struct wl_data_source * -wl_data_device_manager_create_data_source(struct wl_data_device_manager *wl_data_device_manager) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device_manager, - WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE, &wl_data_source_interface, wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager), 0, NULL); - - return (struct wl_data_source *) id; -} - -/** - * @ingroup iface_wl_data_device_manager - * - * Create a new data device for a given seat. - */ -static inline struct wl_data_device * -wl_data_device_manager_get_data_device(struct wl_data_device_manager *wl_data_device_manager, struct wl_seat *seat) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device_manager, - WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE, &wl_data_device_interface, wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager), 0, NULL, seat); - - return (struct wl_data_device *) id; -} - -#ifndef WL_SHELL_ERROR_ENUM -#define WL_SHELL_ERROR_ENUM -enum wl_shell_error { - /** - * given wl_surface has another role - */ - WL_SHELL_ERROR_ROLE = 0, -}; -#endif /* WL_SHELL_ERROR_ENUM */ - -#define WL_SHELL_GET_SHELL_SURFACE 0 - - -/** - * @ingroup iface_wl_shell - */ -#define WL_SHELL_GET_SHELL_SURFACE_SINCE_VERSION 1 - -/** @ingroup iface_wl_shell */ -static inline void -wl_shell_set_user_data(struct wl_shell *wl_shell, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_shell, user_data); -} - -/** @ingroup iface_wl_shell */ -static inline void * -wl_shell_get_user_data(struct wl_shell *wl_shell) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_shell); -} - -static inline uint32_t -wl_shell_get_version(struct wl_shell *wl_shell) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_shell); -} - -/** @ingroup iface_wl_shell */ -static inline void -wl_shell_destroy(struct wl_shell *wl_shell) -{ - wl_proxy_destroy((struct wl_proxy *) wl_shell); -} - -/** - * @ingroup iface_wl_shell - * - * Create a shell surface for an existing surface. This gives - * the wl_surface the role of a shell surface. If the wl_surface - * already has another role, it raises a protocol error. - * - * Only one shell surface can be associated with a given surface. - */ -static inline struct wl_shell_surface * -wl_shell_get_shell_surface(struct wl_shell *wl_shell, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shell, - WL_SHELL_GET_SHELL_SURFACE, &wl_shell_surface_interface, wl_proxy_get_version((struct wl_proxy *) wl_shell), 0, NULL, surface); - - return (struct wl_shell_surface *) id; -} - -#ifndef WL_SHELL_SURFACE_RESIZE_ENUM -#define WL_SHELL_SURFACE_RESIZE_ENUM -/** - * @ingroup iface_wl_shell_surface - * edge values for resizing - * - * These values are used to indicate which edge of a surface - * is being dragged in a resize operation. The server may - * use this information to adapt its behavior, e.g. choose - * an appropriate cursor image. - */ -enum wl_shell_surface_resize { - /** - * no edge - */ - WL_SHELL_SURFACE_RESIZE_NONE = 0, - /** - * top edge - */ - WL_SHELL_SURFACE_RESIZE_TOP = 1, - /** - * bottom edge - */ - WL_SHELL_SURFACE_RESIZE_BOTTOM = 2, - /** - * left edge - */ - WL_SHELL_SURFACE_RESIZE_LEFT = 4, - /** - * top and left edges - */ - WL_SHELL_SURFACE_RESIZE_TOP_LEFT = 5, - /** - * bottom and left edges - */ - WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT = 6, - /** - * right edge - */ - WL_SHELL_SURFACE_RESIZE_RIGHT = 8, - /** - * top and right edges - */ - WL_SHELL_SURFACE_RESIZE_TOP_RIGHT = 9, - /** - * bottom and right edges - */ - WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT = 10, -}; -#endif /* WL_SHELL_SURFACE_RESIZE_ENUM */ - -#ifndef WL_SHELL_SURFACE_TRANSIENT_ENUM -#define WL_SHELL_SURFACE_TRANSIENT_ENUM -/** - * @ingroup iface_wl_shell_surface - * details of transient behaviour - * - * These flags specify details of the expected behaviour - * of transient surfaces. Used in the set_transient request. - */ -enum wl_shell_surface_transient { - /** - * do not set keyboard focus - */ - WL_SHELL_SURFACE_TRANSIENT_INACTIVE = 0x1, -}; -#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */ - -#ifndef WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM -#define WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM -/** - * @ingroup iface_wl_shell_surface - * different method to set the surface fullscreen - * - * Hints to indicate to the compositor how to deal with a conflict - * between the dimensions of the surface and the dimensions of the - * output. The compositor is free to ignore this parameter. - */ -enum wl_shell_surface_fullscreen_method { - /** - * no preference, apply default policy - */ - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT = 0, - /** - * scale, preserve the surface's aspect ratio and center on output - */ - WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE = 1, - /** - * switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch - */ - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER = 2, - /** - * no upscaling, center on output and add black borders to compensate size mismatch - */ - WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL = 3, -}; -#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM */ - -/** - * @ingroup iface_wl_shell_surface - * @struct wl_shell_surface_listener - */ -struct wl_shell_surface_listener { - /** - * ping client - * - * Ping a client to check if it is receiving events and sending - * requests. A client is expected to reply with a pong request. - * @param serial serial number of the ping - */ - void (*ping)(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t serial); - /** - * suggest resize - * - * The configure event asks the client to resize its surface. - * - * The size is a hint, in the sense that the client is free to - * ignore it if it doesn't resize, pick a smaller size (to satisfy - * aspect ratio or resize in steps of NxM pixels). - * - * The edges parameter provides a hint about how the surface was - * resized. The client may use this information to decide how to - * adjust its content to the new size (e.g. a scrolling area might - * adjust its content position to leave the viewable content - * unmoved). - * - * The client is free to dismiss all but the last configure event - * it received. - * - * The width and height arguments specify the size of the window in - * surface-local coordinates. - * @param edges how the surface was resized - * @param width new width of the surface - * @param height new height of the surface - */ - void (*configure)(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t edges, - int32_t width, - int32_t height); - /** - * popup interaction is done - * - * The popup_done event is sent out when a popup grab is broken, - * that is, when the user clicks a surface that doesn't belong to - * the client owning the popup surface. - */ - void (*popup_done)(void *data, - struct wl_shell_surface *wl_shell_surface); -}; - -/** - * @ingroup iface_wl_shell_surface - */ -static inline int -wl_shell_surface_add_listener(struct wl_shell_surface *wl_shell_surface, - const struct wl_shell_surface_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_shell_surface, - (void (**)(void)) listener, data); -} - -#define WL_SHELL_SURFACE_PONG 0 -#define WL_SHELL_SURFACE_MOVE 1 -#define WL_SHELL_SURFACE_RESIZE 2 -#define WL_SHELL_SURFACE_SET_TOPLEVEL 3 -#define WL_SHELL_SURFACE_SET_TRANSIENT 4 -#define WL_SHELL_SURFACE_SET_FULLSCREEN 5 -#define WL_SHELL_SURFACE_SET_POPUP 6 -#define WL_SHELL_SURFACE_SET_MAXIMIZED 7 -#define WL_SHELL_SURFACE_SET_TITLE 8 -#define WL_SHELL_SURFACE_SET_CLASS 9 - -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_PING_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_CONFIGURE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_POPUP_DONE_SINCE_VERSION 1 - -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_PONG_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_MOVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_RESIZE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_TOPLEVEL_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_TRANSIENT_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_FULLSCREEN_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_POPUP_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_MAXIMIZED_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_TITLE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_shell_surface - */ -#define WL_SHELL_SURFACE_SET_CLASS_SINCE_VERSION 1 - -/** @ingroup iface_wl_shell_surface */ -static inline void -wl_shell_surface_set_user_data(struct wl_shell_surface *wl_shell_surface, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_shell_surface, user_data); -} - -/** @ingroup iface_wl_shell_surface */ -static inline void * -wl_shell_surface_get_user_data(struct wl_shell_surface *wl_shell_surface) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_shell_surface); -} - -static inline uint32_t -wl_shell_surface_get_version(struct wl_shell_surface *wl_shell_surface) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_shell_surface); -} - -/** @ingroup iface_wl_shell_surface */ -static inline void -wl_shell_surface_destroy(struct wl_shell_surface *wl_shell_surface) -{ - wl_proxy_destroy((struct wl_proxy *) wl_shell_surface); -} - -/** - * @ingroup iface_wl_shell_surface - * - * A client must respond to a ping event with a pong request or - * the client may be deemed unresponsive. - */ -static inline void -wl_shell_surface_pong(struct wl_shell_surface *wl_shell_surface, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, serial); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Start a pointer-driven move of the surface. - * - * This request must be used in response to a button press event. - * The server may ignore move requests depending on the state of - * the surface (e.g. fullscreen or maximized). - */ -static inline void -wl_shell_surface_move(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Start a pointer-driven resizing of the surface. - * - * This request must be used in response to a button press event. - * The server may ignore resize requests depending on the state of - * the surface (e.g. fullscreen or maximized). - */ -static inline void -wl_shell_surface_resize(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial, uint32_t edges) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial, edges); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Map the surface as a toplevel surface. - * - * A toplevel surface is not fullscreen, maximized or transient. - */ -static inline void -wl_shell_surface_set_toplevel(struct wl_shell_surface *wl_shell_surface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_TOPLEVEL, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Map the surface relative to an existing surface. - * - * The x and y arguments specify the location of the upper left - * corner of the surface relative to the upper left corner of the - * parent surface, in surface-local coordinates. - * - * The flags argument controls details of the transient behaviour. - */ -static inline void -wl_shell_surface_set_transient(struct wl_shell_surface *wl_shell_surface, struct wl_surface *parent, int32_t x, int32_t y, uint32_t flags) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_TRANSIENT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, parent, x, y, flags); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Map the surface as a fullscreen surface. - * - * If an output parameter is given then the surface will be made - * fullscreen on that output. If the client does not specify the - * output then the compositor will apply its policy - usually - * choosing the output on which the surface has the biggest surface - * area. - * - * The client may specify a method to resolve a size conflict - * between the output size and the surface size - this is provided - * through the method parameter. - * - * The framerate parameter is used only when the method is set - * to "driver", to indicate the preferred framerate. A value of 0 - * indicates that the client does not care about framerate. The - * framerate is specified in mHz, that is framerate of 60000 is 60Hz. - * - * A method of "scale" or "driver" implies a scaling operation of - * the surface, either via a direct scaling operation or a change of - * the output mode. This will override any kind of output scaling, so - * that mapping a surface with a buffer size equal to the mode can - * fill the screen independent of buffer_scale. - * - * A method of "fill" means we don't scale up the buffer, however - * any output scale is applied. This means that you may run into - * an edge case where the application maps a buffer with the same - * size of the output mode but buffer_scale 1 (thus making a - * surface larger than the output). In this case it is allowed to - * downscale the results to fit the screen. - * - * The compositor must reply to this request with a configure event - * with the dimensions for the output on which the surface will - * be made fullscreen. - */ -static inline void -wl_shell_surface_set_fullscreen(struct wl_shell_surface *wl_shell_surface, uint32_t method, uint32_t framerate, struct wl_output *output) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, method, framerate, output); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Map the surface as a popup. - * - * A popup surface is a transient surface with an added pointer - * grab. - * - * An existing implicit grab will be changed to owner-events mode, - * and the popup grab will continue after the implicit grab ends - * (i.e. releasing the mouse button does not cause the popup to - * be unmapped). - * - * The popup grab continues until the window is destroyed or a - * mouse button is pressed in any other client's window. A click - * in any of the client's surfaces is reported as normal, however, - * clicks in other clients' surfaces will be discarded and trigger - * the callback. - * - * The x and y arguments specify the location of the upper left - * corner of the surface relative to the upper left corner of the - * parent surface, in surface-local coordinates. - */ -static inline void -wl_shell_surface_set_popup(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial, struct wl_surface *parent, int32_t x, int32_t y, uint32_t flags) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_POPUP, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial, parent, x, y, flags); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Map the surface as a maximized surface. - * - * If an output parameter is given then the surface will be - * maximized on that output. If the client does not specify the - * output then the compositor will apply its policy - usually - * choosing the output on which the surface has the biggest surface - * area. - * - * The compositor will reply with a configure event telling - * the expected new surface size. The operation is completed - * on the next buffer attach to this surface. - * - * A maximized surface typically fills the entire output it is - * bound to, except for desktop elements such as panels. This is - * the main difference between a maximized shell surface and a - * fullscreen shell surface. - * - * The details depend on the compositor implementation. - */ -static inline void -wl_shell_surface_set_maximized(struct wl_shell_surface *wl_shell_surface, struct wl_output *output) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, output); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Set a short title for the surface. - * - * This string may be used to identify the surface in a task bar, - * window list, or other user interface elements provided by the - * compositor. - * - * The string must be encoded in UTF-8. - */ -static inline void -wl_shell_surface_set_title(struct wl_shell_surface *wl_shell_surface, const char *title) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, title); -} - -/** - * @ingroup iface_wl_shell_surface - * - * Set a class for the surface. - * - * The surface class identifies the general class of applications - * to which the surface belongs. A common convention is to use the - * file name (or the full path if it is a non-standard location) of - * the application's .desktop file as the class. - */ -static inline void -wl_shell_surface_set_class(struct wl_shell_surface *wl_shell_surface, const char *class_) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, - WL_SHELL_SURFACE_SET_CLASS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, class_); -} - -#ifndef WL_SURFACE_ERROR_ENUM -#define WL_SURFACE_ERROR_ENUM -/** - * @ingroup iface_wl_surface - * wl_surface error values - * - * These errors can be emitted in response to wl_surface requests. - */ -enum wl_surface_error { - /** - * buffer scale value is invalid - */ - WL_SURFACE_ERROR_INVALID_SCALE = 0, - /** - * buffer transform value is invalid - */ - WL_SURFACE_ERROR_INVALID_TRANSFORM = 1, - /** - * buffer size is invalid - */ - WL_SURFACE_ERROR_INVALID_SIZE = 2, - /** - * buffer offset is invalid - */ - WL_SURFACE_ERROR_INVALID_OFFSET = 3, - /** - * surface was destroyed before its role object - */ - WL_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 4, -}; -#endif /* WL_SURFACE_ERROR_ENUM */ - -/** - * @ingroup iface_wl_surface - * @struct wl_surface_listener - */ -struct wl_surface_listener { - /** - * surface enters an output - * - * This is emitted whenever a surface's creation, movement, or - * resizing results in some part of it being within the scanout - * region of an output. - * - * Note that a surface may be overlapping with zero or more - * outputs. - * @param output output entered by the surface - */ - void (*enter)(void *data, - struct wl_surface *wl_surface, - struct wl_output *output); - /** - * surface leaves an output - * - * This is emitted whenever a surface's creation, movement, or - * resizing results in it no longer having any part of it within - * the scanout region of an output. - * - * Clients should not use the number of outputs the surface is on - * for frame throttling purposes. The surface might be hidden even - * if no leave event has been sent, and the compositor might expect - * new surface content updates even if no enter event has been - * sent. The frame event should be used instead. - * @param output output left by the surface - */ - void (*leave)(void *data, - struct wl_surface *wl_surface, - struct wl_output *output); - /** - * preferred buffer scale for the surface - * - * This event indicates the preferred buffer scale for this - * surface. It is sent whenever the compositor's preference - * changes. - * - * It is intended that scaling aware clients use this event to - * scale their content and use wl_surface.set_buffer_scale to - * indicate the scale they have rendered with. This allows clients - * to supply a higher detail buffer. - * @param factor preferred scaling factor - * @since 6 - */ - void (*preferred_buffer_scale)(void *data, - struct wl_surface *wl_surface, - int32_t factor); - /** - * preferred buffer transform for the surface - * - * This event indicates the preferred buffer transform for this - * surface. It is sent whenever the compositor's preference - * changes. - * - * It is intended that transform aware clients use this event to - * apply the transform to their content and use - * wl_surface.set_buffer_transform to indicate the transform they - * have rendered with. - * @param transform preferred transform - * @since 6 - */ - void (*preferred_buffer_transform)(void *data, - struct wl_surface *wl_surface, - uint32_t transform); -}; - -/** - * @ingroup iface_wl_surface - */ -static inline int -wl_surface_add_listener(struct wl_surface *wl_surface, - const struct wl_surface_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_surface, - (void (**)(void)) listener, data); -} - -#define WL_SURFACE_DESTROY 0 -#define WL_SURFACE_ATTACH 1 -#define WL_SURFACE_DAMAGE 2 -#define WL_SURFACE_FRAME 3 -#define WL_SURFACE_SET_OPAQUE_REGION 4 -#define WL_SURFACE_SET_INPUT_REGION 5 -#define WL_SURFACE_COMMIT 6 -#define WL_SURFACE_SET_BUFFER_TRANSFORM 7 -#define WL_SURFACE_SET_BUFFER_SCALE 8 -#define WL_SURFACE_DAMAGE_BUFFER 9 -#define WL_SURFACE_OFFSET 10 - -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_ENTER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_LEAVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION 6 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION 6 - -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_ATTACH_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_DAMAGE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_FRAME_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_SET_OPAQUE_REGION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_SET_INPUT_REGION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_COMMIT_SINCE_VERSION 1 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_SET_BUFFER_TRANSFORM_SINCE_VERSION 2 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION 3 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION 4 -/** - * @ingroup iface_wl_surface - */ -#define WL_SURFACE_OFFSET_SINCE_VERSION 5 - -/** @ingroup iface_wl_surface */ -static inline void -wl_surface_set_user_data(struct wl_surface *wl_surface, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_surface, user_data); -} - -/** @ingroup iface_wl_surface */ -static inline void * -wl_surface_get_user_data(struct wl_surface *wl_surface) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_surface); -} - -static inline uint32_t -wl_surface_get_version(struct wl_surface *wl_surface) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_surface); -} - -/** - * @ingroup iface_wl_surface - * - * Deletes the surface and invalidates its object ID. - */ -static inline void -wl_surface_destroy(struct wl_surface *wl_surface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_surface - * - * Set a buffer as the content of this surface. - * - * The new size of the surface is calculated based on the buffer - * size transformed by the inverse buffer_transform and the - * inverse buffer_scale. This means that at commit time the supplied - * buffer size must be an integer multiple of the buffer_scale. If - * that's not the case, an invalid_size error is sent. - * - * The x and y arguments specify the location of the new pending - * buffer's upper left corner, relative to the current buffer's upper - * left corner, in surface-local coordinates. In other words, the - * x and y, combined with the new surface size define in which - * directions the surface's size changes. Setting anything other than 0 - * as x and y arguments is discouraged, and should instead be replaced - * with using the separate wl_surface.offset request. - * - * When the bound wl_surface version is 5 or higher, passing any - * non-zero x or y is a protocol violation, and will result in an - * 'invalid_offset' error being raised. The x and y arguments are ignored - * and do not change the pending state. To achieve equivalent semantics, - * use wl_surface.offset. - * - * Surface contents are double-buffered state, see wl_surface.commit. - * - * The initial surface contents are void; there is no content. - * wl_surface.attach assigns the given wl_buffer as the pending - * wl_buffer. wl_surface.commit makes the pending wl_buffer the new - * surface contents, and the size of the surface becomes the size - * calculated from the wl_buffer, as described above. After commit, - * there is no pending buffer until the next attach. - * - * Committing a pending wl_buffer allows the compositor to read the - * pixels in the wl_buffer. The compositor may access the pixels at - * any time after the wl_surface.commit request. When the compositor - * will not access the pixels anymore, it will send the - * wl_buffer.release event. Only after receiving wl_buffer.release, - * the client may reuse the wl_buffer. A wl_buffer that has been - * attached and then replaced by another attach instead of committed - * will not receive a release event, and is not used by the - * compositor. - * - * If a pending wl_buffer has been committed to more than one wl_surface, - * the delivery of wl_buffer.release events becomes undefined. A well - * behaved client should not rely on wl_buffer.release events in this - * case. Alternatively, a client could create multiple wl_buffer objects - * from the same backing storage or use wp_linux_buffer_release. - * - * Destroying the wl_buffer after wl_buffer.release does not change - * the surface contents. Destroying the wl_buffer before wl_buffer.release - * is allowed as long as the underlying buffer storage isn't re-used (this - * can happen e.g. on client process termination). However, if the client - * destroys the wl_buffer before receiving the wl_buffer.release event and - * mutates the underlying buffer storage, the surface contents become - * undefined immediately. - * - * If wl_surface.attach is sent with a NULL wl_buffer, the - * following wl_surface.commit will remove the surface content. - */ -static inline void -wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int32_t x, int32_t y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_ATTACH, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, buffer, x, y); -} - -/** - * @ingroup iface_wl_surface - * - * This request is used to describe the regions where the pending - * buffer is different from the current surface contents, and where - * the surface therefore needs to be repainted. The compositor - * ignores the parts of the damage that fall outside of the surface. - * - * Damage is double-buffered state, see wl_surface.commit. - * - * The damage rectangle is specified in surface-local coordinates, - * where x and y specify the upper left corner of the damage rectangle. - * - * The initial value for pending damage is empty: no damage. - * wl_surface.damage adds pending damage: the new pending damage - * is the union of old pending damage and the given rectangle. - * - * wl_surface.commit assigns pending damage as the current damage, - * and clears pending damage. The server will clear the current - * damage as it repaints the surface. - * - * Note! New clients should not use this request. Instead damage can be - * posted with wl_surface.damage_buffer which uses buffer coordinates - * instead of surface coordinates. - */ -static inline void -wl_surface_damage(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_DAMAGE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y, width, height); -} - -/** - * @ingroup iface_wl_surface - * - * Request a notification when it is a good time to start drawing a new - * frame, by creating a frame callback. This is useful for throttling - * redrawing operations, and driving animations. - * - * When a client is animating on a wl_surface, it can use the 'frame' - * request to get notified when it is a good time to draw and commit the - * next frame of animation. If the client commits an update earlier than - * that, it is likely that some updates will not make it to the display, - * and the client is wasting resources by drawing too often. - * - * The frame request will take effect on the next wl_surface.commit. - * The notification will only be posted for one frame unless - * requested again. For a wl_surface, the notifications are posted in - * the order the frame requests were committed. - * - * The server must send the notifications so that a client - * will not send excessive updates, while still allowing - * the highest possible update rate for clients that wait for the reply - * before drawing again. The server should give some time for the client - * to draw and commit after sending the frame callback events to let it - * hit the next output refresh. - * - * A server should avoid signaling the frame callbacks if the - * surface is not visible in any way, e.g. the surface is off-screen, - * or completely obscured by other opaque surfaces. - * - * The object returned by this request will be destroyed by the - * compositor after the callback is fired and as such the client must not - * attempt to use it after that point. - * - * The callback_data passed in the callback is the current time, in - * milliseconds, with an undefined base. - */ -static inline struct wl_callback * -wl_surface_frame(struct wl_surface *wl_surface) -{ - struct wl_proxy *callback; - - callback = wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_FRAME, &wl_callback_interface, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, NULL); - - return (struct wl_callback *) callback; -} - -/** - * @ingroup iface_wl_surface - * - * This request sets the region of the surface that contains - * opaque content. - * - * The opaque region is an optimization hint for the compositor - * that lets it optimize the redrawing of content behind opaque - * regions. Setting an opaque region is not required for correct - * behaviour, but marking transparent content as opaque will result - * in repaint artifacts. - * - * The opaque region is specified in surface-local coordinates. - * - * The compositor ignores the parts of the opaque region that fall - * outside of the surface. - * - * Opaque region is double-buffered state, see wl_surface.commit. - * - * wl_surface.set_opaque_region changes the pending opaque region. - * wl_surface.commit copies the pending region to the current region. - * Otherwise, the pending and current regions are never changed. - * - * The initial value for an opaque region is empty. Setting the pending - * opaque region has copy semantics, and the wl_region object can be - * destroyed immediately. A NULL wl_region causes the pending opaque - * region to be set to empty. - */ -static inline void -wl_surface_set_opaque_region(struct wl_surface *wl_surface, struct wl_region *region) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_SET_OPAQUE_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, region); -} - -/** - * @ingroup iface_wl_surface - * - * This request sets the region of the surface that can receive - * pointer and touch events. - * - * Input events happening outside of this region will try the next - * surface in the server surface stack. The compositor ignores the - * parts of the input region that fall outside of the surface. - * - * The input region is specified in surface-local coordinates. - * - * Input region is double-buffered state, see wl_surface.commit. - * - * wl_surface.set_input_region changes the pending input region. - * wl_surface.commit copies the pending region to the current region. - * Otherwise the pending and current regions are never changed, - * except cursor and icon surfaces are special cases, see - * wl_pointer.set_cursor and wl_data_device.start_drag. - * - * The initial value for an input region is infinite. That means the - * whole surface will accept input. Setting the pending input region - * has copy semantics, and the wl_region object can be destroyed - * immediately. A NULL wl_region causes the input region to be set - * to infinite. - */ -static inline void -wl_surface_set_input_region(struct wl_surface *wl_surface, struct wl_region *region) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_SET_INPUT_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, region); -} - -/** - * @ingroup iface_wl_surface - * - * Surface state (input, opaque, and damage regions, attached buffers, - * etc.) is double-buffered. Protocol requests modify the pending state, - * as opposed to the current state in use by the compositor. A commit - * request atomically applies all pending state, replacing the current - * state. After commit, the new pending state is as documented for each - * related request. - * - * On commit, a pending wl_buffer is applied first, and all other state - * second. This means that all coordinates in double-buffered state are - * relative to the new wl_buffer coming into use, except for - * wl_surface.attach itself. If there is no pending wl_buffer, the - * coordinates are relative to the current surface contents. - * - * All requests that need a commit to become effective are documented - * to affect double-buffered state. - * - * Other interfaces may add further double-buffered surface state. - */ -static inline void -wl_surface_commit(struct wl_surface *wl_surface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0); -} - -/** - * @ingroup iface_wl_surface - * - * This request sets an optional transformation on how the compositor - * interprets the contents of the buffer attached to the surface. The - * accepted values for the transform parameter are the values for - * wl_output.transform. - * - * Buffer transform is double-buffered state, see wl_surface.commit. - * - * A newly created surface has its buffer transformation set to normal. - * - * wl_surface.set_buffer_transform changes the pending buffer - * transformation. wl_surface.commit copies the pending buffer - * transformation to the current one. Otherwise, the pending and current - * values are never changed. - * - * The purpose of this request is to allow clients to render content - * according to the output transform, thus permitting the compositor to - * use certain optimizations even if the display is rotated. Using - * hardware overlays and scanning out a client buffer for fullscreen - * surfaces are examples of such optimizations. Those optimizations are - * highly dependent on the compositor implementation, so the use of this - * request should be considered on a case-by-case basis. - * - * Note that if the transform value includes 90 or 270 degree rotation, - * the width of the buffer will become the surface height and the height - * of the buffer will become the surface width. - * - * If transform is not one of the values from the - * wl_output.transform enum the invalid_transform protocol error - * is raised. - */ -static inline void -wl_surface_set_buffer_transform(struct wl_surface *wl_surface, int32_t transform) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_SET_BUFFER_TRANSFORM, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, transform); -} - -/** - * @ingroup iface_wl_surface - * - * This request sets an optional scaling factor on how the compositor - * interprets the contents of the buffer attached to the window. - * - * Buffer scale is double-buffered state, see wl_surface.commit. - * - * A newly created surface has its buffer scale set to 1. - * - * wl_surface.set_buffer_scale changes the pending buffer scale. - * wl_surface.commit copies the pending buffer scale to the current one. - * Otherwise, the pending and current values are never changed. - * - * The purpose of this request is to allow clients to supply higher - * resolution buffer data for use on high resolution outputs. It is - * intended that you pick the same buffer scale as the scale of the - * output that the surface is displayed on. This means the compositor - * can avoid scaling when rendering the surface on that output. - * - * Note that if the scale is larger than 1, then you have to attach - * a buffer that is larger (by a factor of scale in each dimension) - * than the desired surface size. - * - * If scale is not positive the invalid_scale protocol error is - * raised. - */ -static inline void -wl_surface_set_buffer_scale(struct wl_surface *wl_surface, int32_t scale) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_SET_BUFFER_SCALE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, scale); -} - -/** - * @ingroup iface_wl_surface - * - * This request is used to describe the regions where the pending - * buffer is different from the current surface contents, and where - * the surface therefore needs to be repainted. The compositor - * ignores the parts of the damage that fall outside of the surface. - * - * Damage is double-buffered state, see wl_surface.commit. - * - * The damage rectangle is specified in buffer coordinates, - * where x and y specify the upper left corner of the damage rectangle. - * - * The initial value for pending damage is empty: no damage. - * wl_surface.damage_buffer adds pending damage: the new pending - * damage is the union of old pending damage and the given rectangle. - * - * wl_surface.commit assigns pending damage as the current damage, - * and clears pending damage. The server will clear the current - * damage as it repaints the surface. - * - * This request differs from wl_surface.damage in only one way - it - * takes damage in buffer coordinates instead of surface-local - * coordinates. While this generally is more intuitive than surface - * coordinates, it is especially desirable when using wp_viewport - * or when a drawing library (like EGL) is unaware of buffer scale - * and buffer transform. - * - * Note: Because buffer transformation changes and damage requests may - * be interleaved in the protocol stream, it is impossible to determine - * the actual mapping between surface and buffer damage until - * wl_surface.commit time. Therefore, compositors wishing to take both - * kinds of damage into account will have to accumulate damage from the - * two requests separately and only transform from one to the other - * after receiving the wl_surface.commit. - */ -static inline void -wl_surface_damage_buffer(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_DAMAGE_BUFFER, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y, width, height); -} - -/** - * @ingroup iface_wl_surface - * - * The x and y arguments specify the location of the new pending - * buffer's upper left corner, relative to the current buffer's upper - * left corner, in surface-local coordinates. In other words, the - * x and y, combined with the new surface size define in which - * directions the surface's size changes. - * - * Surface location offset is double-buffered state, see - * wl_surface.commit. - * - * This request is semantically equivalent to and the replaces the x and y - * arguments in the wl_surface.attach request in wl_surface versions prior - * to 5. See wl_surface.attach for details. - */ -static inline void -wl_surface_offset(struct wl_surface *wl_surface, int32_t x, int32_t y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, - WL_SURFACE_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y); -} - -#ifndef WL_SEAT_CAPABILITY_ENUM -#define WL_SEAT_CAPABILITY_ENUM -/** - * @ingroup iface_wl_seat - * seat capability bitmask - * - * This is a bitmask of capabilities this seat has; if a member is - * set, then it is present on the seat. - */ -enum wl_seat_capability { - /** - * the seat has pointer devices - */ - WL_SEAT_CAPABILITY_POINTER = 1, - /** - * the seat has one or more keyboards - */ - WL_SEAT_CAPABILITY_KEYBOARD = 2, - /** - * the seat has touch devices - */ - WL_SEAT_CAPABILITY_TOUCH = 4, -}; -#endif /* WL_SEAT_CAPABILITY_ENUM */ - -#ifndef WL_SEAT_ERROR_ENUM -#define WL_SEAT_ERROR_ENUM -/** - * @ingroup iface_wl_seat - * wl_seat error values - * - * These errors can be emitted in response to wl_seat requests. - */ -enum wl_seat_error { - /** - * get_pointer, get_keyboard or get_touch called on seat without the matching capability - */ - WL_SEAT_ERROR_MISSING_CAPABILITY = 0, -}; -#endif /* WL_SEAT_ERROR_ENUM */ - -/** - * @ingroup iface_wl_seat - * @struct wl_seat_listener - */ -struct wl_seat_listener { - /** - * seat capabilities changed - * - * This is emitted whenever a seat gains or loses the pointer, - * keyboard or touch capabilities. The argument is a capability - * enum containing the complete set of capabilities this seat has. - * - * When the pointer capability is added, a client may create a - * wl_pointer object using the wl_seat.get_pointer request. This - * object will receive pointer events until the capability is - * removed in the future. - * - * When the pointer capability is removed, a client should destroy - * the wl_pointer objects associated with the seat where the - * capability was removed, using the wl_pointer.release request. No - * further pointer events will be received on these objects. - * - * In some compositors, if a seat regains the pointer capability - * and a client has a previously obtained wl_pointer object of - * version 4 or less, that object may start sending pointer events - * again. This behavior is considered a misinterpretation of the - * intended behavior and must not be relied upon by the client. - * wl_pointer objects of version 5 or later must not send events if - * created before the most recent event notifying the client of an - * added pointer capability. - * - * The above behavior also applies to wl_keyboard and wl_touch with - * the keyboard and touch capabilities, respectively. - * @param capabilities capabilities of the seat - */ - void (*capabilities)(void *data, - struct wl_seat *wl_seat, - uint32_t capabilities); - /** - * unique identifier for this seat - * - * In a multi-seat configuration the seat name can be used by - * clients to help identify which physical devices the seat - * represents. - * - * The seat name is a UTF-8 string with no convention defined for - * its contents. Each name is unique among all wl_seat globals. The - * name is only guaranteed to be unique for the current compositor - * instance. - * - * The same seat names are used for all clients. Thus, the name can - * be shared across processes to refer to a specific wl_seat - * global. - * - * The name event is sent after binding to the seat global. This - * event is only sent once per seat object, and the name does not - * change over the lifetime of the wl_seat global. - * - * Compositors may re-use the same seat name if the wl_seat global - * is destroyed and re-created later. - * @param name seat identifier - * @since 2 - */ - void (*name)(void *data, - struct wl_seat *wl_seat, - const char *name); -}; - -/** - * @ingroup iface_wl_seat - */ -static inline int -wl_seat_add_listener(struct wl_seat *wl_seat, - const struct wl_seat_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_seat, - (void (**)(void)) listener, data); -} - -#define WL_SEAT_GET_POINTER 0 -#define WL_SEAT_GET_KEYBOARD 1 -#define WL_SEAT_GET_TOUCH 2 -#define WL_SEAT_RELEASE 3 - -/** - * @ingroup iface_wl_seat - */ -#define WL_SEAT_CAPABILITIES_SINCE_VERSION 1 -/** - * @ingroup iface_wl_seat - */ -#define WL_SEAT_NAME_SINCE_VERSION 2 - -/** - * @ingroup iface_wl_seat - */ -#define WL_SEAT_GET_POINTER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_seat - */ -#define WL_SEAT_GET_KEYBOARD_SINCE_VERSION 1 -/** - * @ingroup iface_wl_seat - */ -#define WL_SEAT_GET_TOUCH_SINCE_VERSION 1 -/** - * @ingroup iface_wl_seat - */ -#define WL_SEAT_RELEASE_SINCE_VERSION 5 - -/** @ingroup iface_wl_seat */ -static inline void -wl_seat_set_user_data(struct wl_seat *wl_seat, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_seat, user_data); -} - -/** @ingroup iface_wl_seat */ -static inline void * -wl_seat_get_user_data(struct wl_seat *wl_seat) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_seat); -} - -static inline uint32_t -wl_seat_get_version(struct wl_seat *wl_seat) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_seat); -} - -/** @ingroup iface_wl_seat */ -static inline void -wl_seat_destroy(struct wl_seat *wl_seat) -{ - wl_proxy_destroy((struct wl_proxy *) wl_seat); -} - -/** - * @ingroup iface_wl_seat - * - * The ID provided will be initialized to the wl_pointer interface - * for this seat. - * - * This request only takes effect if the seat has the pointer - * capability, or has had the pointer capability in the past. - * It is a protocol violation to issue this request on a seat that has - * never had the pointer capability. The missing_capability error will - * be sent in this case. - */ -static inline struct wl_pointer * -wl_seat_get_pointer(struct wl_seat *wl_seat) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, - WL_SEAT_GET_POINTER, &wl_pointer_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); - - return (struct wl_pointer *) id; -} - -/** - * @ingroup iface_wl_seat - * - * The ID provided will be initialized to the wl_keyboard interface - * for this seat. - * - * This request only takes effect if the seat has the keyboard - * capability, or has had the keyboard capability in the past. - * It is a protocol violation to issue this request on a seat that has - * never had the keyboard capability. The missing_capability error will - * be sent in this case. - */ -static inline struct wl_keyboard * -wl_seat_get_keyboard(struct wl_seat *wl_seat) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, - WL_SEAT_GET_KEYBOARD, &wl_keyboard_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); - - return (struct wl_keyboard *) id; -} - -/** - * @ingroup iface_wl_seat - * - * The ID provided will be initialized to the wl_touch interface - * for this seat. - * - * This request only takes effect if the seat has the touch - * capability, or has had the touch capability in the past. - * It is a protocol violation to issue this request on a seat that has - * never had the touch capability. The missing_capability error will - * be sent in this case. - */ -static inline struct wl_touch * -wl_seat_get_touch(struct wl_seat *wl_seat) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, - WL_SEAT_GET_TOUCH, &wl_touch_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); - - return (struct wl_touch *) id; -} - -/** - * @ingroup iface_wl_seat - * - * Using this request a client can tell the server that it is not going to - * use the seat object anymore. - */ -static inline void -wl_seat_release(struct wl_seat *wl_seat) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, - WL_SEAT_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_seat), WL_MARSHAL_FLAG_DESTROY); -} - -#ifndef WL_POINTER_ERROR_ENUM -#define WL_POINTER_ERROR_ENUM -enum wl_pointer_error { - /** - * given wl_surface has another role - */ - WL_POINTER_ERROR_ROLE = 0, -}; -#endif /* WL_POINTER_ERROR_ENUM */ - -#ifndef WL_POINTER_BUTTON_STATE_ENUM -#define WL_POINTER_BUTTON_STATE_ENUM -/** - * @ingroup iface_wl_pointer - * physical button state - * - * Describes the physical state of a button that produced the button - * event. - */ -enum wl_pointer_button_state { - /** - * the button is not pressed - */ - WL_POINTER_BUTTON_STATE_RELEASED = 0, - /** - * the button is pressed - */ - WL_POINTER_BUTTON_STATE_PRESSED = 1, -}; -#endif /* WL_POINTER_BUTTON_STATE_ENUM */ - -#ifndef WL_POINTER_AXIS_ENUM -#define WL_POINTER_AXIS_ENUM -/** - * @ingroup iface_wl_pointer - * axis types - * - * Describes the axis types of scroll events. - */ -enum wl_pointer_axis { - /** - * vertical axis - */ - WL_POINTER_AXIS_VERTICAL_SCROLL = 0, - /** - * horizontal axis - */ - WL_POINTER_AXIS_HORIZONTAL_SCROLL = 1, -}; -#endif /* WL_POINTER_AXIS_ENUM */ - -#ifndef WL_POINTER_AXIS_SOURCE_ENUM -#define WL_POINTER_AXIS_SOURCE_ENUM -/** - * @ingroup iface_wl_pointer - * axis source types - * - * Describes the source types for axis events. This indicates to the - * client how an axis event was physically generated; a client may - * adjust the user interface accordingly. For example, scroll events - * from a "finger" source may be in a smooth coordinate space with - * kinetic scrolling whereas a "wheel" source may be in discrete steps - * of a number of lines. - * - * The "continuous" axis source is a device generating events in a - * continuous coordinate space, but using something other than a - * finger. One example for this source is button-based scrolling where - * the vertical motion of a device is converted to scroll events while - * a button is held down. - * - * The "wheel tilt" axis source indicates that the actual device is a - * wheel but the scroll event is not caused by a rotation but a - * (usually sideways) tilt of the wheel. - */ -enum wl_pointer_axis_source { - /** - * a physical wheel rotation - */ - WL_POINTER_AXIS_SOURCE_WHEEL = 0, - /** - * finger on a touch surface - */ - WL_POINTER_AXIS_SOURCE_FINGER = 1, - /** - * continuous coordinate space - */ - WL_POINTER_AXIS_SOURCE_CONTINUOUS = 2, - /** - * a physical wheel tilt - * @since 6 - */ - WL_POINTER_AXIS_SOURCE_WHEEL_TILT = 3, -}; -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION 6 -#endif /* WL_POINTER_AXIS_SOURCE_ENUM */ - -#ifndef WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM -#define WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM -/** - * @ingroup iface_wl_pointer - * axis relative direction - * - * This specifies the direction of the physical motion that caused a - * wl_pointer.axis event, relative to the wl_pointer.axis direction. - */ -enum wl_pointer_axis_relative_direction { - /** - * physical motion matches axis direction - */ - WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL = 0, - /** - * physical motion is the inverse of the axis direction - */ - WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED = 1, -}; -#endif /* WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM */ - -/** - * @ingroup iface_wl_pointer - * @struct wl_pointer_listener - */ -struct wl_pointer_listener { - /** - * enter event - * - * Notification that this seat's pointer is focused on a certain - * surface. - * - * When a seat's focus enters a surface, the pointer image is - * undefined and a client should respond to this event by setting - * an appropriate pointer image with the set_cursor request. - * @param serial serial number of the enter event - * @param surface surface entered by the pointer - * @param surface_x surface-local x coordinate - * @param surface_y surface-local y coordinate - */ - void (*enter)(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - struct wl_surface *surface, - wl_fixed_t surface_x, - wl_fixed_t surface_y); - /** - * leave event - * - * Notification that this seat's pointer is no longer focused on - * a certain surface. - * - * The leave notification is sent before the enter notification for - * the new focus. - * @param serial serial number of the leave event - * @param surface surface left by the pointer - */ - void (*leave)(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - struct wl_surface *surface); - /** - * pointer motion event - * - * Notification of pointer location change. The arguments - * surface_x and surface_y are the location relative to the focused - * surface. - * @param time timestamp with millisecond granularity - * @param surface_x surface-local x coordinate - * @param surface_y surface-local y coordinate - */ - void (*motion)(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - wl_fixed_t surface_x, - wl_fixed_t surface_y); - /** - * pointer button event - * - * Mouse button click and release notifications. - * - * The location of the click is given by the last motion or enter - * event. The time argument is a timestamp with millisecond - * granularity, with an undefined base. - * - * The button is a button code as defined in the Linux kernel's - * linux/input-event-codes.h header file, e.g. BTN_LEFT. - * - * Any 16-bit button code value is reserved for future additions to - * the kernel's event code list. All other button codes above - * 0xFFFF are currently undefined but may be used in future - * versions of this protocol. - * @param serial serial number of the button event - * @param time timestamp with millisecond granularity - * @param button button that produced the event - * @param state physical state of the button - */ - void (*button)(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - uint32_t time, - uint32_t button, - uint32_t state); - /** - * axis event - * - * Scroll and other axis notifications. - * - * For scroll events (vertical and horizontal scroll axes), the - * value parameter is the length of a vector along the specified - * axis in a coordinate space identical to those of motion events, - * representing a relative movement along the specified axis. - * - * For devices that support movements non-parallel to axes multiple - * axis events will be emitted. - * - * When applicable, for example for touch pads, the server can - * choose to emit scroll events where the motion vector is - * equivalent to a motion event vector. - * - * When applicable, a client can transform its content relative to - * the scroll distance. - * @param time timestamp with millisecond granularity - * @param axis axis type - * @param value length of vector in surface-local coordinate space - */ - void (*axis)(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value); - /** - * end of a pointer event sequence - * - * Indicates the end of a set of events that logically belong - * together. A client is expected to accumulate the data in all - * events within the frame before proceeding. - * - * All wl_pointer events before a wl_pointer.frame event belong - * logically together. For example, in a diagonal scroll motion the - * compositor will send an optional wl_pointer.axis_source event, - * two wl_pointer.axis events (horizontal and vertical) and finally - * a wl_pointer.frame event. The client may use this information to - * calculate a diagonal vector for scrolling. - * - * When multiple wl_pointer.axis events occur within the same - * frame, the motion vector is the combined motion of all events. - * When a wl_pointer.axis and a wl_pointer.axis_stop event occur - * within the same frame, this indicates that axis movement in one - * axis has stopped but continues in the other axis. When multiple - * wl_pointer.axis_stop events occur within the same frame, this - * indicates that these axes stopped in the same instance. - * - * A wl_pointer.frame event is sent for every logical event group, - * even if the group only contains a single wl_pointer event. - * Specifically, a client may get a sequence: motion, frame, - * button, frame, axis, frame, axis_stop, frame. - * - * The wl_pointer.enter and wl_pointer.leave events are logical - * events generated by the compositor and not the hardware. These - * events are also grouped by a wl_pointer.frame. When a pointer - * moves from one surface to another, a compositor should group the - * wl_pointer.leave event within the same wl_pointer.frame. - * However, a client must not rely on wl_pointer.leave and - * wl_pointer.enter being in the same wl_pointer.frame. - * Compositor-specific policies may require the wl_pointer.leave - * and wl_pointer.enter event being split across multiple - * wl_pointer.frame groups. - * @since 5 - */ - void (*frame)(void *data, - struct wl_pointer *wl_pointer); - /** - * axis source event - * - * Source information for scroll and other axes. - * - * This event does not occur on its own. It is sent before a - * wl_pointer.frame event and carries the source information for - * all events within that frame. - * - * The source specifies how this event was generated. If the source - * is wl_pointer.axis_source.finger, a wl_pointer.axis_stop event - * will be sent when the user lifts the finger off the device. - * - * If the source is wl_pointer.axis_source.wheel, - * wl_pointer.axis_source.wheel_tilt or - * wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event - * may or may not be sent. Whether a compositor sends an axis_stop - * event for these sources is hardware-specific and - * implementation-dependent; clients must not rely on receiving an - * axis_stop event for these scroll sources and should treat scroll - * sequences from these scroll sources as unterminated by default. - * - * This event is optional. If the source is unknown for a - * particular axis event sequence, no event is sent. Only one - * wl_pointer.axis_source event is permitted per frame. - * - * The order of wl_pointer.axis_discrete and wl_pointer.axis_source - * is not guaranteed. - * @param axis_source source of the axis event - * @since 5 - */ - void (*axis_source)(void *data, - struct wl_pointer *wl_pointer, - uint32_t axis_source); - /** - * axis stop event - * - * Stop notification for scroll and other axes. - * - * For some wl_pointer.axis_source types, a wl_pointer.axis_stop - * event is sent to notify a client that the axis sequence has - * terminated. This enables the client to implement kinetic - * scrolling. See the wl_pointer.axis_source documentation for - * information on when this event may be generated. - * - * Any wl_pointer.axis events with the same axis_source after this - * event should be considered as the start of a new axis motion. - * - * The timestamp is to be interpreted identical to the timestamp in - * the wl_pointer.axis event. The timestamp value may be the same - * as a preceding wl_pointer.axis event. - * @param time timestamp with millisecond granularity - * @param axis the axis stopped with this event - * @since 5 - */ - void (*axis_stop)(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - uint32_t axis); - /** - * axis click event - * - * Discrete step information for scroll and other axes. - * - * This event carries the axis value of the wl_pointer.axis event - * in discrete steps (e.g. mouse wheel clicks). - * - * This event is deprecated with wl_pointer version 8 - this event - * is not sent to clients supporting version 8 or later. - * - * This event does not occur on its own, it is coupled with a - * wl_pointer.axis event that represents this axis value on a - * continuous scale. The protocol guarantees that each - * axis_discrete event is always followed by exactly one axis event - * with the same axis number within the same wl_pointer.frame. Note - * that the protocol allows for other events to occur between the - * axis_discrete and its coupled axis event, including other - * axis_discrete or axis events. A wl_pointer.frame must not - * contain more than one axis_discrete event per axis type. - * - * This event is optional; continuous scrolling devices like - * two-finger scrolling on touchpads do not have discrete steps and - * do not generate this event. - * - * The discrete value carries the directional information. e.g. a - * value of -2 is two steps towards the negative direction of this - * axis. - * - * The axis number is identical to the axis number in the - * associated axis event. - * - * The order of wl_pointer.axis_discrete and wl_pointer.axis_source - * is not guaranteed. - * @param axis axis type - * @param discrete number of steps - * @since 5 - */ - void (*axis_discrete)(void *data, - struct wl_pointer *wl_pointer, - uint32_t axis, - int32_t discrete); - /** - * axis high-resolution scroll event - * - * Discrete high-resolution scroll information. - * - * This event carries high-resolution wheel scroll information, - * with each multiple of 120 representing one logical scroll step - * (a wheel detent). For example, an axis_value120 of 30 is one - * quarter of a logical scroll step in the positive direction, a - * value120 of -240 are two logical scroll steps in the negative - * direction within the same hardware event. Clients that rely on - * discrete scrolling should accumulate the value120 to multiples - * of 120 before processing the event. - * - * The value120 must not be zero. - * - * This event replaces the wl_pointer.axis_discrete event in - * clients supporting wl_pointer version 8 or later. - * - * Where a wl_pointer.axis_source event occurs in the same - * wl_pointer.frame, the axis source applies to this event. - * - * The order of wl_pointer.axis_value120 and wl_pointer.axis_source - * is not guaranteed. - * @param axis axis type - * @param value120 scroll distance as fraction of 120 - * @since 8 - */ - void (*axis_value120)(void *data, - struct wl_pointer *wl_pointer, - uint32_t axis, - int32_t value120); - /** - * axis relative physical direction event - * - * Relative directional information of the entity causing the - * axis motion. - * - * For a wl_pointer.axis event, the - * wl_pointer.axis_relative_direction event specifies the movement - * direction of the entity causing the wl_pointer.axis event. For - * example: - if a user's fingers on a touchpad move down and this - * causes a wl_pointer.axis vertical_scroll down event, the - * physical direction is 'identical' - if a user's fingers on a - * touchpad move down and this causes a wl_pointer.axis - * vertical_scroll up scroll up event ('natural scrolling'), the - * physical direction is 'inverted'. - * - * A client may use this information to adjust scroll motion of - * components. Specifically, enabling natural scrolling causes the - * content to change direction compared to traditional scrolling. - * Some widgets like volume control sliders should usually match - * the physical direction regardless of whether natural scrolling - * is active. This event enables clients to match the scroll - * direction of a widget to the physical direction. - * - * This event does not occur on its own, it is coupled with a - * wl_pointer.axis event that represents this axis value. The - * protocol guarantees that each axis_relative_direction event is - * always followed by exactly one axis event with the same axis - * number within the same wl_pointer.frame. Note that the protocol - * allows for other events to occur between the - * axis_relative_direction and its coupled axis event. - * - * The axis number is identical to the axis number in the - * associated axis event. - * - * The order of wl_pointer.axis_relative_direction, - * wl_pointer.axis_discrete and wl_pointer.axis_source is not - * guaranteed. - * @param axis axis type - * @param direction physical direction relative to axis motion - * @since 9 - */ - void (*axis_relative_direction)(void *data, - struct wl_pointer *wl_pointer, - uint32_t axis, - uint32_t direction); -}; - -/** - * @ingroup iface_wl_pointer - */ -static inline int -wl_pointer_add_listener(struct wl_pointer *wl_pointer, - const struct wl_pointer_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_pointer, - (void (**)(void)) listener, data); -} - -#define WL_POINTER_SET_CURSOR 0 -#define WL_POINTER_RELEASE 1 - -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_ENTER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_LEAVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_MOTION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_BUTTON_SINCE_VERSION 1 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_SINCE_VERSION 1 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_FRAME_SINCE_VERSION 5 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_SOURCE_SINCE_VERSION 5 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_STOP_SINCE_VERSION 5 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_DISCRETE_SINCE_VERSION 5 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_VALUE120_SINCE_VERSION 8 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_AXIS_RELATIVE_DIRECTION_SINCE_VERSION 9 - -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_SET_CURSOR_SINCE_VERSION 1 -/** - * @ingroup iface_wl_pointer - */ -#define WL_POINTER_RELEASE_SINCE_VERSION 3 - -/** @ingroup iface_wl_pointer */ -static inline void -wl_pointer_set_user_data(struct wl_pointer *wl_pointer, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_pointer, user_data); -} - -/** @ingroup iface_wl_pointer */ -static inline void * -wl_pointer_get_user_data(struct wl_pointer *wl_pointer) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_pointer); -} - -static inline uint32_t -wl_pointer_get_version(struct wl_pointer *wl_pointer) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_pointer); -} - -/** @ingroup iface_wl_pointer */ -static inline void -wl_pointer_destroy(struct wl_pointer *wl_pointer) -{ - wl_proxy_destroy((struct wl_proxy *) wl_pointer); -} - -/** - * @ingroup iface_wl_pointer - * - * Set the pointer surface, i.e., the surface that contains the - * pointer image (cursor). This request gives the surface the role - * of a cursor. If the surface already has another role, it raises - * a protocol error. - * - * The cursor actually changes only if the pointer - * focus for this device is one of the requesting client's surfaces - * or the surface parameter is the current pointer surface. If - * there was a previous surface set with this request it is - * replaced. If surface is NULL, the pointer image is hidden. - * - * The parameters hotspot_x and hotspot_y define the position of - * the pointer surface relative to the pointer location. Its - * top-left corner is always at (x, y) - (hotspot_x, hotspot_y), - * where (x, y) are the coordinates of the pointer location, in - * surface-local coordinates. - * - * On wl_surface.offset requests to the pointer surface, hotspot_x - * and hotspot_y are decremented by the x and y parameters - * passed to the request. The offset must be applied by - * wl_surface.commit as usual. - * - * The hotspot can also be updated by passing the currently set - * pointer surface to this request with new values for hotspot_x - * and hotspot_y. - * - * The input region is ignored for wl_surfaces with the role of - * a cursor. When the use as a cursor ends, the wl_surface is - * unmapped. - * - * The serial parameter must match the latest wl_pointer.enter - * serial number sent to the client. Otherwise the request will be - * ignored. - */ -static inline void -wl_pointer_set_cursor(struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, int32_t hotspot_x, int32_t hotspot_y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_pointer, - WL_POINTER_SET_CURSOR, NULL, wl_proxy_get_version((struct wl_proxy *) wl_pointer), 0, serial, surface, hotspot_x, hotspot_y); -} - -/** - * @ingroup iface_wl_pointer - * - * Using this request a client can tell the server that it is not going to - * use the pointer object anymore. - * - * This request destroys the pointer proxy object, so clients must not call - * wl_pointer_destroy() after using this request. - */ -static inline void -wl_pointer_release(struct wl_pointer *wl_pointer) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_pointer, - WL_POINTER_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_pointer), WL_MARSHAL_FLAG_DESTROY); -} - -#ifndef WL_KEYBOARD_KEYMAP_FORMAT_ENUM -#define WL_KEYBOARD_KEYMAP_FORMAT_ENUM -/** - * @ingroup iface_wl_keyboard - * keyboard mapping format - * - * This specifies the format of the keymap provided to the - * client with the wl_keyboard.keymap event. - */ -enum wl_keyboard_keymap_format { - /** - * no keymap; client must understand how to interpret the raw keycode - */ - WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP = 0, - /** - * libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode - */ - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 = 1, -}; -#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM */ - -#ifndef WL_KEYBOARD_KEY_STATE_ENUM -#define WL_KEYBOARD_KEY_STATE_ENUM -/** - * @ingroup iface_wl_keyboard - * physical key state - * - * Describes the physical state of a key that produced the key event. - */ -enum wl_keyboard_key_state { - /** - * key is not pressed - */ - WL_KEYBOARD_KEY_STATE_RELEASED = 0, - /** - * key is pressed - */ - WL_KEYBOARD_KEY_STATE_PRESSED = 1, -}; -#endif /* WL_KEYBOARD_KEY_STATE_ENUM */ - -/** - * @ingroup iface_wl_keyboard - * @struct wl_keyboard_listener - */ -struct wl_keyboard_listener { - /** - * keyboard mapping - * - * This event provides a file descriptor to the client which can - * be memory-mapped in read-only mode to provide a keyboard mapping - * description. - * - * From version 7 onwards, the fd must be mapped with MAP_PRIVATE - * by the recipient, as MAP_SHARED may fail. - * @param format keymap format - * @param fd keymap file descriptor - * @param size keymap size, in bytes - */ - void (*keymap)(void *data, - struct wl_keyboard *wl_keyboard, - uint32_t format, - int32_t fd, - uint32_t size); - /** - * enter event - * - * Notification that this seat's keyboard focus is on a certain - * surface. - * - * The compositor must send the wl_keyboard.modifiers event after - * this event. - * @param serial serial number of the enter event - * @param surface surface gaining keyboard focus - * @param keys the currently pressed keys - */ - void (*enter)(void *data, - struct wl_keyboard *wl_keyboard, - uint32_t serial, - struct wl_surface *surface, - struct wl_array *keys); - /** - * leave event - * - * Notification that this seat's keyboard focus is no longer on a - * certain surface. - * - * The leave notification is sent before the enter notification for - * the new focus. - * - * After this event client must assume that no keys are pressed, it - * must stop key repeating if there's some going on and until it - * receives the next wl_keyboard.modifiers event, the client must - * also assume no modifiers are active. - * @param serial serial number of the leave event - * @param surface surface that lost keyboard focus - */ - void (*leave)(void *data, - struct wl_keyboard *wl_keyboard, - uint32_t serial, - struct wl_surface *surface); - /** - * key event - * - * A key was pressed or released. The time argument is a - * timestamp with millisecond granularity, with an undefined base. - * - * The key is a platform-specific key code that can be interpreted - * by feeding it to the keyboard mapping (see the keymap event). - * - * If this event produces a change in modifiers, then the resulting - * wl_keyboard.modifiers event must be sent after this event. - * - * The compositor must not send this event without a surface of the - * client having keyboard focus. - * @param serial serial number of the key event - * @param time timestamp with millisecond granularity - * @param key key that produced the event - * @param state physical state of the key - */ - void (*key)(void *data, - struct wl_keyboard *wl_keyboard, - uint32_t serial, - uint32_t time, - uint32_t key, - uint32_t state); - /** - * modifier and group state - * - * Notifies clients that the modifier and/or group state has - * changed, and it should update its local state. - * - * The compositor may send this event without a surface of the - * client having keyboard focus, for example to tie modifier - * information to pointer focus instead. If a modifier event with - * pressed modifiers is sent without a prior enter event, the - * client can assume the modifier state is valid until it receives - * the next wl_keyboard.modifiers event. In order to reset the - * modifier state again, the compositor can send a - * wl_keyboard.modifiers event with no pressed modifiers. - * @param serial serial number of the modifiers event - * @param mods_depressed depressed modifiers - * @param mods_latched latched modifiers - * @param mods_locked locked modifiers - * @param group keyboard layout - */ - void (*modifiers)(void *data, - struct wl_keyboard *wl_keyboard, - uint32_t serial, - uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, - uint32_t group); - /** - * repeat rate and delay - * - * Informs the client about the keyboard's repeat rate and delay. - * - * This event is sent as soon as the wl_keyboard object has been - * created, and is guaranteed to be received by the client before - * any key press event. - * - * Negative values for either rate or delay are illegal. A rate of - * zero will disable any repeating (regardless of the value of - * delay). - * - * This event can be sent later on as well with a new value if - * necessary, so clients should continue listening for the event - * past the creation of wl_keyboard. - * @param rate the rate of repeating keys in characters per second - * @param delay delay in milliseconds since key down until repeating starts - * @since 4 - */ - void (*repeat_info)(void *data, - struct wl_keyboard *wl_keyboard, - int32_t rate, - int32_t delay); -}; - -/** - * @ingroup iface_wl_keyboard - */ -static inline int -wl_keyboard_add_listener(struct wl_keyboard *wl_keyboard, - const struct wl_keyboard_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_keyboard, - (void (**)(void)) listener, data); -} - -#define WL_KEYBOARD_RELEASE 0 - -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_KEYMAP_SINCE_VERSION 1 -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_ENTER_SINCE_VERSION 1 -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_LEAVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_KEY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_MODIFIERS_SINCE_VERSION 1 -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION 4 - -/** - * @ingroup iface_wl_keyboard - */ -#define WL_KEYBOARD_RELEASE_SINCE_VERSION 3 - -/** @ingroup iface_wl_keyboard */ -static inline void -wl_keyboard_set_user_data(struct wl_keyboard *wl_keyboard, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_keyboard, user_data); -} - -/** @ingroup iface_wl_keyboard */ -static inline void * -wl_keyboard_get_user_data(struct wl_keyboard *wl_keyboard) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_keyboard); -} - -static inline uint32_t -wl_keyboard_get_version(struct wl_keyboard *wl_keyboard) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_keyboard); -} - -/** @ingroup iface_wl_keyboard */ -static inline void -wl_keyboard_destroy(struct wl_keyboard *wl_keyboard) -{ - wl_proxy_destroy((struct wl_proxy *) wl_keyboard); -} - -/** - * @ingroup iface_wl_keyboard - */ -static inline void -wl_keyboard_release(struct wl_keyboard *wl_keyboard) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_keyboard, - WL_KEYBOARD_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_keyboard), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_touch - * @struct wl_touch_listener - */ -struct wl_touch_listener { - /** - * touch down event and beginning of a touch sequence - * - * A new touch point has appeared on the surface. This touch - * point is assigned a unique ID. Future events from this touch - * point reference this ID. The ID ceases to be valid after a touch - * up event and may be reused in the future. - * @param serial serial number of the touch down event - * @param time timestamp with millisecond granularity - * @param surface surface touched - * @param id the unique ID of this touch point - * @param x surface-local x coordinate - * @param y surface-local y coordinate - */ - void (*down)(void *data, - struct wl_touch *wl_touch, - uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - /** - * end of a touch event sequence - * - * The touch point has disappeared. No further events will be - * sent for this touch point and the touch point's ID is released - * and may be reused in a future touch down event. - * @param serial serial number of the touch up event - * @param time timestamp with millisecond granularity - * @param id the unique ID of this touch point - */ - void (*up)(void *data, - struct wl_touch *wl_touch, - uint32_t serial, - uint32_t time, - int32_t id); - /** - * update of touch point coordinates - * - * A touch point has changed coordinates. - * @param time timestamp with millisecond granularity - * @param id the unique ID of this touch point - * @param x surface-local x coordinate - * @param y surface-local y coordinate - */ - void (*motion)(void *data, - struct wl_touch *wl_touch, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - /** - * end of touch frame event - * - * Indicates the end of a set of events that logically belong - * together. A client is expected to accumulate the data in all - * events within the frame before proceeding. - * - * A wl_touch.frame terminates at least one event but otherwise no - * guarantee is provided about the set of events within a frame. A - * client must assume that any state not updated in a frame is - * unchanged from the previously known state. - */ - void (*frame)(void *data, - struct wl_touch *wl_touch); - /** - * touch session cancelled - * - * Sent if the compositor decides the touch stream is a global - * gesture. No further events are sent to the clients from that - * particular gesture. Touch cancellation applies to all touch - * points currently active on this client's surface. The client is - * responsible for finalizing the touch points, future touch points - * on this surface may reuse the touch point ID. - */ - void (*cancel)(void *data, - struct wl_touch *wl_touch); - /** - * update shape of touch point - * - * Sent when a touchpoint has changed its shape. - * - * This event does not occur on its own. It is sent before a - * wl_touch.frame event and carries the new shape information for - * any previously reported, or new touch points of that frame. - * - * Other events describing the touch point such as wl_touch.down, - * wl_touch.motion or wl_touch.orientation may be sent within the - * same wl_touch.frame. A client should treat these events as a - * single logical touch point update. The order of wl_touch.shape, - * wl_touch.orientation and wl_touch.motion is not guaranteed. A - * wl_touch.down event is guaranteed to occur before the first - * wl_touch.shape event for this touch ID but both events may occur - * within the same wl_touch.frame. - * - * A touchpoint shape is approximated by an ellipse through the - * major and minor axis length. The major axis length describes the - * longer diameter of the ellipse, while the minor axis length - * describes the shorter diameter. Major and minor are orthogonal - * and both are specified in surface-local coordinates. The center - * of the ellipse is always at the touchpoint location as reported - * by wl_touch.down or wl_touch.move. - * - * This event is only sent by the compositor if the touch device - * supports shape reports. The client has to make reasonable - * assumptions about the shape if it did not receive this event. - * @param id the unique ID of this touch point - * @param major length of the major axis in surface-local coordinates - * @param minor length of the minor axis in surface-local coordinates - * @since 6 - */ - void (*shape)(void *data, - struct wl_touch *wl_touch, - int32_t id, - wl_fixed_t major, - wl_fixed_t minor); - /** - * update orientation of touch point - * - * Sent when a touchpoint has changed its orientation. - * - * This event does not occur on its own. It is sent before a - * wl_touch.frame event and carries the new shape information for - * any previously reported, or new touch points of that frame. - * - * Other events describing the touch point such as wl_touch.down, - * wl_touch.motion or wl_touch.shape may be sent within the same - * wl_touch.frame. A client should treat these events as a single - * logical touch point update. The order of wl_touch.shape, - * wl_touch.orientation and wl_touch.motion is not guaranteed. A - * wl_touch.down event is guaranteed to occur before the first - * wl_touch.orientation event for this touch ID but both events may - * occur within the same wl_touch.frame. - * - * The orientation describes the clockwise angle of a touchpoint's - * major axis to the positive surface y-axis and is normalized to - * the -180 to +180 degree range. The granularity of orientation - * depends on the touch device, some devices only support binary - * rotation values between 0 and 90 degrees. - * - * This event is only sent by the compositor if the touch device - * supports orientation reports. - * @param id the unique ID of this touch point - * @param orientation angle between major axis and positive surface y-axis in degrees - * @since 6 - */ - void (*orientation)(void *data, - struct wl_touch *wl_touch, - int32_t id, - wl_fixed_t orientation); -}; - -/** - * @ingroup iface_wl_touch - */ -static inline int -wl_touch_add_listener(struct wl_touch *wl_touch, - const struct wl_touch_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_touch, - (void (**)(void)) listener, data); -} - -#define WL_TOUCH_RELEASE 0 - -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_DOWN_SINCE_VERSION 1 -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_UP_SINCE_VERSION 1 -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_MOTION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_FRAME_SINCE_VERSION 1 -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_CANCEL_SINCE_VERSION 1 -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_SHAPE_SINCE_VERSION 6 -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_ORIENTATION_SINCE_VERSION 6 - -/** - * @ingroup iface_wl_touch - */ -#define WL_TOUCH_RELEASE_SINCE_VERSION 3 - -/** @ingroup iface_wl_touch */ -static inline void -wl_touch_set_user_data(struct wl_touch *wl_touch, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_touch, user_data); -} - -/** @ingroup iface_wl_touch */ -static inline void * -wl_touch_get_user_data(struct wl_touch *wl_touch) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_touch); -} - -static inline uint32_t -wl_touch_get_version(struct wl_touch *wl_touch) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_touch); -} - -/** @ingroup iface_wl_touch */ -static inline void -wl_touch_destroy(struct wl_touch *wl_touch) -{ - wl_proxy_destroy((struct wl_proxy *) wl_touch); -} - -/** - * @ingroup iface_wl_touch - */ -static inline void -wl_touch_release(struct wl_touch *wl_touch) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_touch, - WL_TOUCH_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_touch), WL_MARSHAL_FLAG_DESTROY); -} - -#ifndef WL_OUTPUT_SUBPIXEL_ENUM -#define WL_OUTPUT_SUBPIXEL_ENUM -/** - * @ingroup iface_wl_output - * subpixel geometry information - * - * This enumeration describes how the physical - * pixels on an output are laid out. - */ -enum wl_output_subpixel { - /** - * unknown geometry - */ - WL_OUTPUT_SUBPIXEL_UNKNOWN = 0, - /** - * no geometry - */ - WL_OUTPUT_SUBPIXEL_NONE = 1, - /** - * horizontal RGB - */ - WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB = 2, - /** - * horizontal BGR - */ - WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR = 3, - /** - * vertical RGB - */ - WL_OUTPUT_SUBPIXEL_VERTICAL_RGB = 4, - /** - * vertical BGR - */ - WL_OUTPUT_SUBPIXEL_VERTICAL_BGR = 5, -}; -#endif /* WL_OUTPUT_SUBPIXEL_ENUM */ - -#ifndef WL_OUTPUT_TRANSFORM_ENUM -#define WL_OUTPUT_TRANSFORM_ENUM -/** - * @ingroup iface_wl_output - * transform from framebuffer to output - * - * This describes the transform that a compositor will apply to a - * surface to compensate for the rotation or mirroring of an - * output device. - * - * The flipped values correspond to an initial flip around a - * vertical axis followed by rotation. - * - * The purpose is mainly to allow clients to render accordingly and - * tell the compositor, so that for fullscreen surfaces, the - * compositor will still be able to scan out directly from client - * surfaces. - */ -enum wl_output_transform { - /** - * no transform - */ - WL_OUTPUT_TRANSFORM_NORMAL = 0, - /** - * 90 degrees counter-clockwise - */ - WL_OUTPUT_TRANSFORM_90 = 1, - /** - * 180 degrees counter-clockwise - */ - WL_OUTPUT_TRANSFORM_180 = 2, - /** - * 270 degrees counter-clockwise - */ - WL_OUTPUT_TRANSFORM_270 = 3, - /** - * 180 degree flip around a vertical axis - */ - WL_OUTPUT_TRANSFORM_FLIPPED = 4, - /** - * flip and rotate 90 degrees counter-clockwise - */ - WL_OUTPUT_TRANSFORM_FLIPPED_90 = 5, - /** - * flip and rotate 180 degrees counter-clockwise - */ - WL_OUTPUT_TRANSFORM_FLIPPED_180 = 6, - /** - * flip and rotate 270 degrees counter-clockwise - */ - WL_OUTPUT_TRANSFORM_FLIPPED_270 = 7, -}; -#endif /* WL_OUTPUT_TRANSFORM_ENUM */ - -#ifndef WL_OUTPUT_MODE_ENUM -#define WL_OUTPUT_MODE_ENUM -/** - * @ingroup iface_wl_output - * mode information - * - * These flags describe properties of an output mode. - * They are used in the flags bitfield of the mode event. - */ -enum wl_output_mode { - /** - * indicates this is the current mode - */ - WL_OUTPUT_MODE_CURRENT = 0x1, - /** - * indicates this is the preferred mode - */ - WL_OUTPUT_MODE_PREFERRED = 0x2, -}; -#endif /* WL_OUTPUT_MODE_ENUM */ - -/** - * @ingroup iface_wl_output - * @struct wl_output_listener - */ -struct wl_output_listener { - /** - * properties of the output - * - * The geometry event describes geometric properties of the - * output. The event is sent when binding to the output object and - * whenever any of the properties change. - * - * The physical size can be set to zero if it doesn't make sense - * for this output (e.g. for projectors or virtual outputs). - * - * The geometry event will be followed by a done event (starting - * from version 2). - * - * Note: wl_output only advertises partial information about the - * output position and identification. Some compositors, for - * instance those not implementing a desktop-style output layout or - * those exposing virtual outputs, might fake this information. - * Instead of using x and y, clients should use - * xdg_output.logical_position. Instead of using make and model, - * clients should use name and description. - * @param x x position within the global compositor space - * @param y y position within the global compositor space - * @param physical_width width in millimeters of the output - * @param physical_height height in millimeters of the output - * @param subpixel subpixel orientation of the output - * @param make textual description of the manufacturer - * @param model textual description of the model - * @param transform transform that maps framebuffer to output - */ - void (*geometry)(void *data, - struct wl_output *wl_output, - int32_t x, - int32_t y, - int32_t physical_width, - int32_t physical_height, - int32_t subpixel, - const char *make, - const char *model, - int32_t transform); - /** - * advertise available modes for the output - * - * The mode event describes an available mode for the output. - * - * The event is sent when binding to the output object and there - * will always be one mode, the current mode. The event is sent - * again if an output changes mode, for the mode that is now - * current. In other words, the current mode is always the last - * mode that was received with the current flag set. - * - * Non-current modes are deprecated. A compositor can decide to - * only advertise the current mode and never send other modes. - * Clients should not rely on non-current modes. - * - * The size of a mode is given in physical hardware units of the - * output device. This is not necessarily the same as the output - * size in the global compositor space. For instance, the output - * may be scaled, as described in wl_output.scale, or transformed, - * as described in wl_output.transform. Clients willing to retrieve - * the output size in the global compositor space should use - * xdg_output.logical_size instead. - * - * The vertical refresh rate can be set to zero if it doesn't make - * sense for this output (e.g. for virtual outputs). - * - * The mode event will be followed by a done event (starting from - * version 2). - * - * Clients should not use the refresh rate to schedule frames. - * Instead, they should use the wl_surface.frame event or the - * presentation-time protocol. - * - * Note: this information is not always meaningful for all outputs. - * Some compositors, such as those exposing virtual outputs, might - * fake the refresh rate or the size. - * @param flags bitfield of mode flags - * @param width width of the mode in hardware units - * @param height height of the mode in hardware units - * @param refresh vertical refresh rate in mHz - */ - void (*mode)(void *data, - struct wl_output *wl_output, - uint32_t flags, - int32_t width, - int32_t height, - int32_t refresh); - /** - * sent all information about output - * - * This event is sent after all other properties have been sent - * after binding to the output object and after any other property - * changes done after that. This allows changes to the output - * properties to be seen as atomic, even if they happen via - * multiple events. - * @since 2 - */ - void (*done)(void *data, - struct wl_output *wl_output); - /** - * output scaling properties - * - * This event contains scaling geometry information that is not - * in the geometry event. It may be sent after binding the output - * object or if the output scale changes later. If it is not sent, - * the client should assume a scale of 1. - * - * A scale larger than 1 means that the compositor will - * automatically scale surface buffers by this amount when - * rendering. This is used for very high resolution displays where - * applications rendering at the native resolution would be too - * small to be legible. - * - * It is intended that scaling aware clients track the current - * output of a surface, and if it is on a scaled output it should - * use wl_surface.set_buffer_scale with the scale of the output. - * That way the compositor can avoid scaling the surface, and the - * client can supply a higher detail image. - * - * The scale event will be followed by a done event. - * @param factor scaling factor of output - * @since 2 - */ - void (*scale)(void *data, - struct wl_output *wl_output, - int32_t factor); - /** - * name of this output - * - * Many compositors will assign user-friendly names to their - * outputs, show them to the user, allow the user to refer to an - * output, etc. The client may wish to know this name as well to - * offer the user similar behaviors. - * - * The name is a UTF-8 string with no convention defined for its - * contents. Each name is unique among all wl_output globals. The - * name is only guaranteed to be unique for the compositor - * instance. - * - * The same output name is used for all clients for a given - * wl_output global. Thus, the name can be shared across processes - * to refer to a specific wl_output global. - * - * The name is not guaranteed to be persistent across sessions, - * thus cannot be used to reliably identify an output in e.g. - * configuration files. - * - * Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. - * However, do not assume that the name is a reflection of an - * underlying DRM connector, X11 connection, etc. - * - * The name event is sent after binding the output object. This - * event is only sent once per output object, and the name does not - * change over the lifetime of the wl_output global. - * - * Compositors may re-use the same output name if the wl_output - * global is destroyed and re-created later. Compositors should - * avoid re-using the same name if possible. - * - * The name event will be followed by a done event. - * @param name output name - * @since 4 - */ - void (*name)(void *data, - struct wl_output *wl_output, - const char *name); - /** - * human-readable description of this output - * - * Many compositors can produce human-readable descriptions of - * their outputs. The client may wish to know this description as - * well, e.g. for output selection purposes. - * - * The description is a UTF-8 string with no convention defined for - * its contents. The description is not guaranteed to be unique - * among all wl_output globals. Examples might include 'Foocorp 11" - * Display' or 'Virtual X11 output via :1'. - * - * The description event is sent after binding the output object - * and whenever the description changes. The description is - * optional, and may not be sent at all. - * - * The description event will be followed by a done event. - * @param description output description - * @since 4 - */ - void (*description)(void *data, - struct wl_output *wl_output, - const char *description); -}; - -/** - * @ingroup iface_wl_output - */ -static inline int -wl_output_add_listener(struct wl_output *wl_output, - const struct wl_output_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) wl_output, - (void (**)(void)) listener, data); -} - -#define WL_OUTPUT_RELEASE 0 - -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_GEOMETRY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_MODE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_DONE_SINCE_VERSION 2 -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_SCALE_SINCE_VERSION 2 -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_NAME_SINCE_VERSION 4 -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_DESCRIPTION_SINCE_VERSION 4 - -/** - * @ingroup iface_wl_output - */ -#define WL_OUTPUT_RELEASE_SINCE_VERSION 3 - -/** @ingroup iface_wl_output */ -static inline void -wl_output_set_user_data(struct wl_output *wl_output, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_output, user_data); -} - -/** @ingroup iface_wl_output */ -static inline void * -wl_output_get_user_data(struct wl_output *wl_output) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_output); -} - -static inline uint32_t -wl_output_get_version(struct wl_output *wl_output) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_output); -} - -/** @ingroup iface_wl_output */ -static inline void -wl_output_destroy(struct wl_output *wl_output) -{ - wl_proxy_destroy((struct wl_proxy *) wl_output); -} - -/** - * @ingroup iface_wl_output - * - * Using this request a client can tell the server that it is not going to - * use the output object anymore. - */ -static inline void -wl_output_release(struct wl_output *wl_output) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_output, - WL_OUTPUT_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_output), WL_MARSHAL_FLAG_DESTROY); -} - -#define WL_REGION_DESTROY 0 -#define WL_REGION_ADD 1 -#define WL_REGION_SUBTRACT 2 - - -/** - * @ingroup iface_wl_region - */ -#define WL_REGION_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_region - */ -#define WL_REGION_ADD_SINCE_VERSION 1 -/** - * @ingroup iface_wl_region - */ -#define WL_REGION_SUBTRACT_SINCE_VERSION 1 - -/** @ingroup iface_wl_region */ -static inline void -wl_region_set_user_data(struct wl_region *wl_region, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_region, user_data); -} - -/** @ingroup iface_wl_region */ -static inline void * -wl_region_get_user_data(struct wl_region *wl_region) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_region); -} - -static inline uint32_t -wl_region_get_version(struct wl_region *wl_region) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_region); -} - -/** - * @ingroup iface_wl_region - * - * Destroy the region. This will invalidate the object ID. - */ -static inline void -wl_region_destroy(struct wl_region *wl_region) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_region, - WL_REGION_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_region - * - * Add the specified rectangle to the region. - */ -static inline void -wl_region_add(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_region, - WL_REGION_ADD, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), 0, x, y, width, height); -} - -/** - * @ingroup iface_wl_region - * - * Subtract the specified rectangle from the region. - */ -static inline void -wl_region_subtract(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_region, - WL_REGION_SUBTRACT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), 0, x, y, width, height); -} - -#ifndef WL_SUBCOMPOSITOR_ERROR_ENUM -#define WL_SUBCOMPOSITOR_ERROR_ENUM -enum wl_subcompositor_error { - /** - * the to-be sub-surface is invalid - */ - WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE = 0, - /** - * the to-be sub-surface parent is invalid - */ - WL_SUBCOMPOSITOR_ERROR_BAD_PARENT = 1, -}; -#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */ - -#define WL_SUBCOMPOSITOR_DESTROY 0 -#define WL_SUBCOMPOSITOR_GET_SUBSURFACE 1 - - -/** - * @ingroup iface_wl_subcompositor - */ -#define WL_SUBCOMPOSITOR_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_subcompositor - */ -#define WL_SUBCOMPOSITOR_GET_SUBSURFACE_SINCE_VERSION 1 - -/** @ingroup iface_wl_subcompositor */ -static inline void -wl_subcompositor_set_user_data(struct wl_subcompositor *wl_subcompositor, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_subcompositor, user_data); -} - -/** @ingroup iface_wl_subcompositor */ -static inline void * -wl_subcompositor_get_user_data(struct wl_subcompositor *wl_subcompositor) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_subcompositor); -} - -static inline uint32_t -wl_subcompositor_get_version(struct wl_subcompositor *wl_subcompositor) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_subcompositor); -} - -/** - * @ingroup iface_wl_subcompositor - * - * Informs the server that the client will not be using this - * protocol object anymore. This does not affect any other - * objects, wl_subsurface objects included. - */ -static inline void -wl_subcompositor_destroy(struct wl_subcompositor *wl_subcompositor) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subcompositor, - WL_SUBCOMPOSITOR_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subcompositor), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_subcompositor - * - * Create a sub-surface interface for the given surface, and - * associate it with the given parent surface. This turns a - * plain wl_surface into a sub-surface. - * - * The to-be sub-surface must not already have another role, and it - * must not have an existing wl_subsurface object. Otherwise the - * bad_surface protocol error is raised. - * - * Adding sub-surfaces to a parent is a double-buffered operation on the - * parent (see wl_surface.commit). The effect of adding a sub-surface - * becomes visible on the next time the state of the parent surface is - * applied. - * - * The parent surface must not be one of the child surface's descendants, - * and the parent must be different from the child surface, otherwise the - * bad_parent protocol error is raised. - * - * This request modifies the behaviour of wl_surface.commit request on - * the sub-surface, see the documentation on wl_subsurface interface. - */ -static inline struct wl_subsurface * -wl_subcompositor_get_subsurface(struct wl_subcompositor *wl_subcompositor, struct wl_surface *surface, struct wl_surface *parent) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wl_subcompositor, - WL_SUBCOMPOSITOR_GET_SUBSURFACE, &wl_subsurface_interface, wl_proxy_get_version((struct wl_proxy *) wl_subcompositor), 0, NULL, surface, parent); - - return (struct wl_subsurface *) id; -} - -#ifndef WL_SUBSURFACE_ERROR_ENUM -#define WL_SUBSURFACE_ERROR_ENUM -enum wl_subsurface_error { - /** - * wl_surface is not a sibling or the parent - */ - WL_SUBSURFACE_ERROR_BAD_SURFACE = 0, -}; -#endif /* WL_SUBSURFACE_ERROR_ENUM */ - -#define WL_SUBSURFACE_DESTROY 0 -#define WL_SUBSURFACE_SET_POSITION 1 -#define WL_SUBSURFACE_PLACE_ABOVE 2 -#define WL_SUBSURFACE_PLACE_BELOW 3 -#define WL_SUBSURFACE_SET_SYNC 4 -#define WL_SUBSURFACE_SET_DESYNC 5 - - -/** - * @ingroup iface_wl_subsurface - */ -#define WL_SUBSURFACE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wl_subsurface - */ -#define WL_SUBSURFACE_SET_POSITION_SINCE_VERSION 1 -/** - * @ingroup iface_wl_subsurface - */ -#define WL_SUBSURFACE_PLACE_ABOVE_SINCE_VERSION 1 -/** - * @ingroup iface_wl_subsurface - */ -#define WL_SUBSURFACE_PLACE_BELOW_SINCE_VERSION 1 -/** - * @ingroup iface_wl_subsurface - */ -#define WL_SUBSURFACE_SET_SYNC_SINCE_VERSION 1 -/** - * @ingroup iface_wl_subsurface - */ -#define WL_SUBSURFACE_SET_DESYNC_SINCE_VERSION 1 - -/** @ingroup iface_wl_subsurface */ -static inline void -wl_subsurface_set_user_data(struct wl_subsurface *wl_subsurface, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wl_subsurface, user_data); -} - -/** @ingroup iface_wl_subsurface */ -static inline void * -wl_subsurface_get_user_data(struct wl_subsurface *wl_subsurface) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wl_subsurface); -} - -static inline uint32_t -wl_subsurface_get_version(struct wl_subsurface *wl_subsurface) -{ - return wl_proxy_get_version((struct wl_proxy *) wl_subsurface); -} - -/** - * @ingroup iface_wl_subsurface - * - * The sub-surface interface is removed from the wl_surface object - * that was turned into a sub-surface with a - * wl_subcompositor.get_subsurface request. The wl_surface's association - * to the parent is deleted. The wl_surface is unmapped immediately. - */ -static inline void -wl_subsurface_destroy(struct wl_subsurface *wl_subsurface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, - WL_SUBSURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wl_subsurface - * - * This schedules a sub-surface position change. - * The sub-surface will be moved so that its origin (top left - * corner pixel) will be at the location x, y of the parent surface - * coordinate system. The coordinates are not restricted to the parent - * surface area. Negative values are allowed. - * - * The scheduled coordinates will take effect whenever the state of the - * parent surface is applied. When this happens depends on whether the - * parent surface is in synchronized mode or not. See - * wl_subsurface.set_sync and wl_subsurface.set_desync for details. - * - * If more than one set_position request is invoked by the client before - * the commit of the parent surface, the position of a new request always - * replaces the scheduled position from any previous request. - * - * The initial position is 0, 0. - */ -static inline void -wl_subsurface_set_position(struct wl_subsurface *wl_subsurface, int32_t x, int32_t y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, - WL_SUBSURFACE_SET_POSITION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, x, y); -} - -/** - * @ingroup iface_wl_subsurface - * - * This sub-surface is taken from the stack, and put back just - * above the reference surface, changing the z-order of the sub-surfaces. - * The reference surface must be one of the sibling surfaces, or the - * parent surface. Using any other surface, including this sub-surface, - * will cause a protocol error. - * - * The z-order is double-buffered. Requests are handled in order and - * applied immediately to a pending state. The final pending state is - * copied to the active state the next time the state of the parent - * surface is applied. When this happens depends on whether the parent - * surface is in synchronized mode or not. See wl_subsurface.set_sync and - * wl_subsurface.set_desync for details. - * - * A new sub-surface is initially added as the top-most in the stack - * of its siblings and parent. - */ -static inline void -wl_subsurface_place_above(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, - WL_SUBSURFACE_PLACE_ABOVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, sibling); -} - -/** - * @ingroup iface_wl_subsurface - * - * The sub-surface is placed just below the reference surface. - * See wl_subsurface.place_above. - */ -static inline void -wl_subsurface_place_below(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, - WL_SUBSURFACE_PLACE_BELOW, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, sibling); -} - -/** - * @ingroup iface_wl_subsurface - * - * Change the commit behaviour of the sub-surface to synchronized - * mode, also described as the parent dependent mode. - * - * In synchronized mode, wl_surface.commit on a sub-surface will - * accumulate the committed state in a cache, but the state will - * not be applied and hence will not change the compositor output. - * The cached state is applied to the sub-surface immediately after - * the parent surface's state is applied. This ensures atomic - * updates of the parent and all its synchronized sub-surfaces. - * Applying the cached state will invalidate the cache, so further - * parent surface commits do not (re-)apply old state. - * - * See wl_subsurface for the recursive effect of this mode. - */ -static inline void -wl_subsurface_set_sync(struct wl_subsurface *wl_subsurface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, - WL_SUBSURFACE_SET_SYNC, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0); -} - -/** - * @ingroup iface_wl_subsurface - * - * Change the commit behaviour of the sub-surface to desynchronized - * mode, also described as independent or freely running mode. - * - * In desynchronized mode, wl_surface.commit on a sub-surface will - * apply the pending state directly, without caching, as happens - * normally with a wl_surface. Calling wl_surface.commit on the - * parent surface has no effect on the sub-surface's wl_surface - * state. This mode allows a sub-surface to be updated on its own. - * - * If cached state exists when wl_surface.commit is called in - * desynchronized mode, the pending state is added to the cached - * state, and applied as a whole. This invalidates the cache. - * - * Note: even if a sub-surface is set to desynchronized, a parent - * sub-surface may override it to behave as synchronized. For details, - * see wl_subsurface. - * - * If a surface's parent surface behaves as desynchronized, then - * the cached state is applied on set_desync. - */ -static inline void -wl_subsurface_set_desync(struct wl_subsurface *wl_subsurface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, - WL_SUBSURFACE_SET_DESYNC, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol-code.h deleted file mode 100644 index 76ef732..0000000 --- a/raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol-code.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2015 Samsung Electronics Co., Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface zwp_idle_inhibitor_v1_interface; - -static const struct wl_interface *idle_inhibit_unstable_v1_types[] = { - &zwp_idle_inhibitor_v1_interface, - &wl_surface_interface, -}; - -static const struct wl_message zwp_idle_inhibit_manager_v1_requests[] = { - { "destroy", "", idle_inhibit_unstable_v1_types + 0 }, - { "create_inhibitor", "no", idle_inhibit_unstable_v1_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zwp_idle_inhibit_manager_v1_interface = { - "zwp_idle_inhibit_manager_v1", 1, - 2, zwp_idle_inhibit_manager_v1_requests, - 0, NULL, -}; - -static const struct wl_message zwp_idle_inhibitor_v1_requests[] = { - { "destroy", "", idle_inhibit_unstable_v1_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zwp_idle_inhibitor_v1_interface = { - "zwp_idle_inhibitor_v1", 1, - 1, zwp_idle_inhibitor_v1_requests, - 0, NULL, -}; - diff --git a/raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol.h b/raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol.h deleted file mode 100644 index a033a11..0000000 --- a/raylib/external/glfw/src/wayland-idle-inhibit-unstable-v1-client-protocol.h +++ /dev/null @@ -1,232 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef IDLE_INHIBIT_UNSTABLE_V1_CLIENT_PROTOCOL_H -#define IDLE_INHIBIT_UNSTABLE_V1_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_idle_inhibit_unstable_v1 The idle_inhibit_unstable_v1 protocol - * @section page_ifaces_idle_inhibit_unstable_v1 Interfaces - * - @subpage page_iface_zwp_idle_inhibit_manager_v1 - control behavior when display idles - * - @subpage page_iface_zwp_idle_inhibitor_v1 - context object for inhibiting idle behavior - * @section page_copyright_idle_inhibit_unstable_v1 Copyright - *
- *
- * Copyright © 2015 Samsung Electronics Co., Ltd
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */ -struct wl_surface; -struct zwp_idle_inhibit_manager_v1; -struct zwp_idle_inhibitor_v1; - -#ifndef ZWP_IDLE_INHIBIT_MANAGER_V1_INTERFACE -#define ZWP_IDLE_INHIBIT_MANAGER_V1_INTERFACE -/** - * @page page_iface_zwp_idle_inhibit_manager_v1 zwp_idle_inhibit_manager_v1 - * @section page_iface_zwp_idle_inhibit_manager_v1_desc Description - * - * This interface permits inhibiting the idle behavior such as screen - * blanking, locking, and screensaving. The client binds the idle manager - * globally, then creates idle-inhibitor objects for each surface. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - * @section page_iface_zwp_idle_inhibit_manager_v1_api API - * See @ref iface_zwp_idle_inhibit_manager_v1. - */ -/** - * @defgroup iface_zwp_idle_inhibit_manager_v1 The zwp_idle_inhibit_manager_v1 interface - * - * This interface permits inhibiting the idle behavior such as screen - * blanking, locking, and screensaving. The client binds the idle manager - * globally, then creates idle-inhibitor objects for each surface. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - */ -extern const struct wl_interface zwp_idle_inhibit_manager_v1_interface; -#endif -#ifndef ZWP_IDLE_INHIBITOR_V1_INTERFACE -#define ZWP_IDLE_INHIBITOR_V1_INTERFACE -/** - * @page page_iface_zwp_idle_inhibitor_v1 zwp_idle_inhibitor_v1 - * @section page_iface_zwp_idle_inhibitor_v1_desc Description - * - * An idle inhibitor prevents the output that the associated surface is - * visible on from being set to a state where it is not visually usable due - * to lack of user interaction (e.g. blanked, dimmed, locked, set to power - * save, etc.) Any screensaver processes are also blocked from displaying. - * - * If the surface is destroyed, unmapped, becomes occluded, loses - * visibility, or otherwise becomes not visually relevant for the user, the - * idle inhibitor will not be honored by the compositor; if the surface - * subsequently regains visibility the inhibitor takes effect once again. - * Likewise, the inhibitor isn't honored if the system was already idled at - * the time the inhibitor was established, although if the system later - * de-idles and re-idles the inhibitor will take effect. - * @section page_iface_zwp_idle_inhibitor_v1_api API - * See @ref iface_zwp_idle_inhibitor_v1. - */ -/** - * @defgroup iface_zwp_idle_inhibitor_v1 The zwp_idle_inhibitor_v1 interface - * - * An idle inhibitor prevents the output that the associated surface is - * visible on from being set to a state where it is not visually usable due - * to lack of user interaction (e.g. blanked, dimmed, locked, set to power - * save, etc.) Any screensaver processes are also blocked from displaying. - * - * If the surface is destroyed, unmapped, becomes occluded, loses - * visibility, or otherwise becomes not visually relevant for the user, the - * idle inhibitor will not be honored by the compositor; if the surface - * subsequently regains visibility the inhibitor takes effect once again. - * Likewise, the inhibitor isn't honored if the system was already idled at - * the time the inhibitor was established, although if the system later - * de-idles and re-idles the inhibitor will take effect. - */ -extern const struct wl_interface zwp_idle_inhibitor_v1_interface; -#endif - -#define ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY 0 -#define ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR 1 - - -/** - * @ingroup iface_zwp_idle_inhibit_manager_v1 - */ -#define ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_idle_inhibit_manager_v1 - */ -#define ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR_SINCE_VERSION 1 - -/** @ingroup iface_zwp_idle_inhibit_manager_v1 */ -static inline void -zwp_idle_inhibit_manager_v1_set_user_data(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_idle_inhibit_manager_v1, user_data); -} - -/** @ingroup iface_zwp_idle_inhibit_manager_v1 */ -static inline void * -zwp_idle_inhibit_manager_v1_get_user_data(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_idle_inhibit_manager_v1); -} - -static inline uint32_t -zwp_idle_inhibit_manager_v1_get_version(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1); -} - -/** - * @ingroup iface_zwp_idle_inhibit_manager_v1 - * - * Destroy the inhibit manager. - */ -static inline void -zwp_idle_inhibit_manager_v1_destroy(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibit_manager_v1, - ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zwp_idle_inhibit_manager_v1 - * - * Create a new inhibitor object associated with the given surface. - */ -static inline struct zwp_idle_inhibitor_v1 * -zwp_idle_inhibit_manager_v1_create_inhibitor(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibit_manager_v1, - ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR, &zwp_idle_inhibitor_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1), 0, NULL, surface); - - return (struct zwp_idle_inhibitor_v1 *) id; -} - -#define ZWP_IDLE_INHIBITOR_V1_DESTROY 0 - - -/** - * @ingroup iface_zwp_idle_inhibitor_v1 - */ -#define ZWP_IDLE_INHIBITOR_V1_DESTROY_SINCE_VERSION 1 - -/** @ingroup iface_zwp_idle_inhibitor_v1 */ -static inline void -zwp_idle_inhibitor_v1_set_user_data(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_idle_inhibitor_v1, user_data); -} - -/** @ingroup iface_zwp_idle_inhibitor_v1 */ -static inline void * -zwp_idle_inhibitor_v1_get_user_data(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_idle_inhibitor_v1); -} - -static inline uint32_t -zwp_idle_inhibitor_v1_get_version(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibitor_v1); -} - -/** - * @ingroup iface_zwp_idle_inhibitor_v1 - * - * Remove the inhibitor effect from the associated wl_surface. - */ -static inline void -zwp_idle_inhibitor_v1_destroy(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibitor_v1, - ZWP_IDLE_INHIBITOR_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibitor_v1), WL_MARSHAL_FLAG_DESTROY); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol-code.h deleted file mode 100644 index 5935c0b..0000000 --- a/raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol-code.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2014 Jonas Ådahl - * Copyright © 2015 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_pointer_interface; -extern const struct wl_interface wl_region_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface zwp_confined_pointer_v1_interface; -extern const struct wl_interface zwp_locked_pointer_v1_interface; - -static const struct wl_interface *pointer_constraints_unstable_v1_types[] = { - NULL, - NULL, - &zwp_locked_pointer_v1_interface, - &wl_surface_interface, - &wl_pointer_interface, - &wl_region_interface, - NULL, - &zwp_confined_pointer_v1_interface, - &wl_surface_interface, - &wl_pointer_interface, - &wl_region_interface, - NULL, - &wl_region_interface, - &wl_region_interface, -}; - -static const struct wl_message zwp_pointer_constraints_v1_requests[] = { - { "destroy", "", pointer_constraints_unstable_v1_types + 0 }, - { "lock_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 2 }, - { "confine_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 7 }, -}; - -WL_PRIVATE const struct wl_interface zwp_pointer_constraints_v1_interface = { - "zwp_pointer_constraints_v1", 1, - 3, zwp_pointer_constraints_v1_requests, - 0, NULL, -}; - -static const struct wl_message zwp_locked_pointer_v1_requests[] = { - { "destroy", "", pointer_constraints_unstable_v1_types + 0 }, - { "set_cursor_position_hint", "ff", pointer_constraints_unstable_v1_types + 0 }, - { "set_region", "?o", pointer_constraints_unstable_v1_types + 12 }, -}; - -static const struct wl_message zwp_locked_pointer_v1_events[] = { - { "locked", "", pointer_constraints_unstable_v1_types + 0 }, - { "unlocked", "", pointer_constraints_unstable_v1_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zwp_locked_pointer_v1_interface = { - "zwp_locked_pointer_v1", 1, - 3, zwp_locked_pointer_v1_requests, - 2, zwp_locked_pointer_v1_events, -}; - -static const struct wl_message zwp_confined_pointer_v1_requests[] = { - { "destroy", "", pointer_constraints_unstable_v1_types + 0 }, - { "set_region", "?o", pointer_constraints_unstable_v1_types + 13 }, -}; - -static const struct wl_message zwp_confined_pointer_v1_events[] = { - { "confined", "", pointer_constraints_unstable_v1_types + 0 }, - { "unconfined", "", pointer_constraints_unstable_v1_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zwp_confined_pointer_v1_interface = { - "zwp_confined_pointer_v1", 1, - 2, zwp_confined_pointer_v1_requests, - 2, zwp_confined_pointer_v1_events, -}; - diff --git a/raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol.h b/raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol.h deleted file mode 100644 index 5ff3867..0000000 --- a/raylib/external/glfw/src/wayland-pointer-constraints-unstable-v1-client-protocol.h +++ /dev/null @@ -1,667 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H -#define POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_pointer_constraints_unstable_v1 The pointer_constraints_unstable_v1 protocol - * protocol for constraining pointer motions - * - * @section page_desc_pointer_constraints_unstable_v1 Description - * - * This protocol specifies a set of interfaces used for adding constraints to - * the motion of a pointer. Possible constraints include confining pointer - * motions to a given region, or locking it to its current position. - * - * In order to constrain the pointer, a client must first bind the global - * interface "wp_pointer_constraints" which, if a compositor supports pointer - * constraints, is exposed by the registry. Using the bound global object, the - * client uses the request that corresponds to the type of constraint it wants - * to make. See wp_pointer_constraints for more details. - * - * Warning! The protocol described in this file is experimental and backward - * incompatible changes may be made. Backward compatible changes may be added - * together with the corresponding interface version bump. Backward - * incompatible changes are done by bumping the version number in the protocol - * and interface names and resetting the interface version. Once the protocol - * is to be declared stable, the 'z' prefix and the version number in the - * protocol and interface names are removed and the interface version number is - * reset. - * - * @section page_ifaces_pointer_constraints_unstable_v1 Interfaces - * - @subpage page_iface_zwp_pointer_constraints_v1 - constrain the movement of a pointer - * - @subpage page_iface_zwp_locked_pointer_v1 - receive relative pointer motion events - * - @subpage page_iface_zwp_confined_pointer_v1 - confined pointer object - * @section page_copyright_pointer_constraints_unstable_v1 Copyright - *
- *
- * Copyright © 2014      Jonas Ådahl
- * Copyright © 2015      Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */ -struct wl_pointer; -struct wl_region; -struct wl_surface; -struct zwp_confined_pointer_v1; -struct zwp_locked_pointer_v1; -struct zwp_pointer_constraints_v1; - -#ifndef ZWP_POINTER_CONSTRAINTS_V1_INTERFACE -#define ZWP_POINTER_CONSTRAINTS_V1_INTERFACE -/** - * @page page_iface_zwp_pointer_constraints_v1 zwp_pointer_constraints_v1 - * @section page_iface_zwp_pointer_constraints_v1_desc Description - * - * The global interface exposing pointer constraining functionality. It - * exposes two requests: lock_pointer for locking the pointer to its - * position, and confine_pointer for locking the pointer to a region. - * - * The lock_pointer and confine_pointer requests create the objects - * wp_locked_pointer and wp_confined_pointer respectively, and the client can - * use these objects to interact with the lock. - * - * For any surface, only one lock or confinement may be active across all - * wl_pointer objects of the same seat. If a lock or confinement is requested - * when another lock or confinement is active or requested on the same surface - * and with any of the wl_pointer objects of the same seat, an - * 'already_constrained' error will be raised. - * @section page_iface_zwp_pointer_constraints_v1_api API - * See @ref iface_zwp_pointer_constraints_v1. - */ -/** - * @defgroup iface_zwp_pointer_constraints_v1 The zwp_pointer_constraints_v1 interface - * - * The global interface exposing pointer constraining functionality. It - * exposes two requests: lock_pointer for locking the pointer to its - * position, and confine_pointer for locking the pointer to a region. - * - * The lock_pointer and confine_pointer requests create the objects - * wp_locked_pointer and wp_confined_pointer respectively, and the client can - * use these objects to interact with the lock. - * - * For any surface, only one lock or confinement may be active across all - * wl_pointer objects of the same seat. If a lock or confinement is requested - * when another lock or confinement is active or requested on the same surface - * and with any of the wl_pointer objects of the same seat, an - * 'already_constrained' error will be raised. - */ -extern const struct wl_interface zwp_pointer_constraints_v1_interface; -#endif -#ifndef ZWP_LOCKED_POINTER_V1_INTERFACE -#define ZWP_LOCKED_POINTER_V1_INTERFACE -/** - * @page page_iface_zwp_locked_pointer_v1 zwp_locked_pointer_v1 - * @section page_iface_zwp_locked_pointer_v1_desc Description - * - * The wp_locked_pointer interface represents a locked pointer state. - * - * While the lock of this object is active, the wl_pointer objects of the - * associated seat will not emit any wl_pointer.motion events. - * - * This object will send the event 'locked' when the lock is activated. - * Whenever the lock is activated, it is guaranteed that the locked surface - * will already have received pointer focus and that the pointer will be - * within the region passed to the request creating this object. - * - * To unlock the pointer, send the destroy request. This will also destroy - * the wp_locked_pointer object. - * - * If the compositor decides to unlock the pointer the unlocked event is - * sent. See wp_locked_pointer.unlock for details. - * - * When unlocking, the compositor may warp the cursor position to the set - * cursor position hint. If it does, it will not result in any relative - * motion events emitted via wp_relative_pointer. - * - * If the surface the lock was requested on is destroyed and the lock is not - * yet activated, the wp_locked_pointer object is now defunct and must be - * destroyed. - * @section page_iface_zwp_locked_pointer_v1_api API - * See @ref iface_zwp_locked_pointer_v1. - */ -/** - * @defgroup iface_zwp_locked_pointer_v1 The zwp_locked_pointer_v1 interface - * - * The wp_locked_pointer interface represents a locked pointer state. - * - * While the lock of this object is active, the wl_pointer objects of the - * associated seat will not emit any wl_pointer.motion events. - * - * This object will send the event 'locked' when the lock is activated. - * Whenever the lock is activated, it is guaranteed that the locked surface - * will already have received pointer focus and that the pointer will be - * within the region passed to the request creating this object. - * - * To unlock the pointer, send the destroy request. This will also destroy - * the wp_locked_pointer object. - * - * If the compositor decides to unlock the pointer the unlocked event is - * sent. See wp_locked_pointer.unlock for details. - * - * When unlocking, the compositor may warp the cursor position to the set - * cursor position hint. If it does, it will not result in any relative - * motion events emitted via wp_relative_pointer. - * - * If the surface the lock was requested on is destroyed and the lock is not - * yet activated, the wp_locked_pointer object is now defunct and must be - * destroyed. - */ -extern const struct wl_interface zwp_locked_pointer_v1_interface; -#endif -#ifndef ZWP_CONFINED_POINTER_V1_INTERFACE -#define ZWP_CONFINED_POINTER_V1_INTERFACE -/** - * @page page_iface_zwp_confined_pointer_v1 zwp_confined_pointer_v1 - * @section page_iface_zwp_confined_pointer_v1_desc Description - * - * The wp_confined_pointer interface represents a confined pointer state. - * - * This object will send the event 'confined' when the confinement is - * activated. Whenever the confinement is activated, it is guaranteed that - * the surface the pointer is confined to will already have received pointer - * focus and that the pointer will be within the region passed to the request - * creating this object. It is up to the compositor to decide whether this - * requires some user interaction and if the pointer will warp to within the - * passed region if outside. - * - * To unconfine the pointer, send the destroy request. This will also destroy - * the wp_confined_pointer object. - * - * If the compositor decides to unconfine the pointer the unconfined event is - * sent. The wp_confined_pointer object is at this point defunct and should - * be destroyed. - * @section page_iface_zwp_confined_pointer_v1_api API - * See @ref iface_zwp_confined_pointer_v1. - */ -/** - * @defgroup iface_zwp_confined_pointer_v1 The zwp_confined_pointer_v1 interface - * - * The wp_confined_pointer interface represents a confined pointer state. - * - * This object will send the event 'confined' when the confinement is - * activated. Whenever the confinement is activated, it is guaranteed that - * the surface the pointer is confined to will already have received pointer - * focus and that the pointer will be within the region passed to the request - * creating this object. It is up to the compositor to decide whether this - * requires some user interaction and if the pointer will warp to within the - * passed region if outside. - * - * To unconfine the pointer, send the destroy request. This will also destroy - * the wp_confined_pointer object. - * - * If the compositor decides to unconfine the pointer the unconfined event is - * sent. The wp_confined_pointer object is at this point defunct and should - * be destroyed. - */ -extern const struct wl_interface zwp_confined_pointer_v1_interface; -#endif - -#ifndef ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM -#define ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM -/** - * @ingroup iface_zwp_pointer_constraints_v1 - * wp_pointer_constraints error values - * - * These errors can be emitted in response to wp_pointer_constraints - * requests. - */ -enum zwp_pointer_constraints_v1_error { - /** - * pointer constraint already requested on that surface - */ - ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED = 1, -}; -#endif /* ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM */ - -#ifndef ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM -#define ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM -/** - * @ingroup iface_zwp_pointer_constraints_v1 - * constraint lifetime - * - * These values represent different lifetime semantics. They are passed - * as arguments to the factory requests to specify how the constraint - * lifetimes should be managed. - */ -enum zwp_pointer_constraints_v1_lifetime { - /** - * the pointer constraint is defunct once deactivated - * - * A oneshot pointer constraint will never reactivate once it has - * been deactivated. See the corresponding deactivation event - * (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) - * for details. - */ - ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT = 1, - /** - * the pointer constraint may reactivate - * - * A persistent pointer constraint may again reactivate once it - * has been deactivated. See the corresponding deactivation event - * (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) - * for details. - */ - ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT = 2, -}; -#endif /* ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM */ - -#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY 0 -#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER 1 -#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER 2 - - -/** - * @ingroup iface_zwp_pointer_constraints_v1 - */ -#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_pointer_constraints_v1 - */ -#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_pointer_constraints_v1 - */ -#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER_SINCE_VERSION 1 - -/** @ingroup iface_zwp_pointer_constraints_v1 */ -static inline void -zwp_pointer_constraints_v1_set_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_pointer_constraints_v1, user_data); -} - -/** @ingroup iface_zwp_pointer_constraints_v1 */ -static inline void * -zwp_pointer_constraints_v1_get_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_pointer_constraints_v1); -} - -static inline uint32_t -zwp_pointer_constraints_v1_get_version(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1); -} - -/** - * @ingroup iface_zwp_pointer_constraints_v1 - * - * Used by the client to notify the server that it will no longer use this - * pointer constraints object. - */ -static inline void -zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1, - ZWP_POINTER_CONSTRAINTS_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zwp_pointer_constraints_v1 - * - * The lock_pointer request lets the client request to disable movements of - * the virtual pointer (i.e. the cursor), effectively locking the pointer - * to a position. This request may not take effect immediately; in the - * future, when the compositor deems implementation-specific constraints - * are satisfied, the pointer lock will be activated and the compositor - * sends a locked event. - * - * The protocol provides no guarantee that the constraints are ever - * satisfied, and does not require the compositor to send an error if the - * constraints cannot ever be satisfied. It is thus possible to request a - * lock that will never activate. - * - * There may not be another pointer constraint of any kind requested or - * active on the surface for any of the wl_pointer objects of the seat of - * the passed pointer when requesting a lock. If there is, an error will be - * raised. See general pointer lock documentation for more details. - * - * The intersection of the region passed with this request and the input - * region of the surface is used to determine where the pointer must be - * in order for the lock to activate. It is up to the compositor whether to - * warp the pointer or require some kind of user interaction for the lock - * to activate. If the region is null the surface input region is used. - * - * A surface may receive pointer focus without the lock being activated. - * - * The request creates a new object wp_locked_pointer which is used to - * interact with the lock as well as receive updates about its state. See - * the the description of wp_locked_pointer for further information. - * - * Note that while a pointer is locked, the wl_pointer objects of the - * corresponding seat will not emit any wl_pointer.motion events, but - * relative motion events will still be emitted via wp_relative_pointer - * objects of the same seat. wl_pointer.axis and wl_pointer.button events - * are unaffected. - */ -static inline struct zwp_locked_pointer_v1 * -zwp_pointer_constraints_v1_lock_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1, - ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER, &zwp_locked_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime); - - return (struct zwp_locked_pointer_v1 *) id; -} - -/** - * @ingroup iface_zwp_pointer_constraints_v1 - * - * The confine_pointer request lets the client request to confine the - * pointer cursor to a given region. This request may not take effect - * immediately; in the future, when the compositor deems implementation- - * specific constraints are satisfied, the pointer confinement will be - * activated and the compositor sends a confined event. - * - * The intersection of the region passed with this request and the input - * region of the surface is used to determine where the pointer must be - * in order for the confinement to activate. It is up to the compositor - * whether to warp the pointer or require some kind of user interaction for - * the confinement to activate. If the region is null the surface input - * region is used. - * - * The request will create a new object wp_confined_pointer which is used - * to interact with the confinement as well as receive updates about its - * state. See the the description of wp_confined_pointer for further - * information. - */ -static inline struct zwp_confined_pointer_v1 * -zwp_pointer_constraints_v1_confine_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1, - ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER, &zwp_confined_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime); - - return (struct zwp_confined_pointer_v1 *) id; -} - -/** - * @ingroup iface_zwp_locked_pointer_v1 - * @struct zwp_locked_pointer_v1_listener - */ -struct zwp_locked_pointer_v1_listener { - /** - * lock activation event - * - * Notification that the pointer lock of the seat's pointer is - * activated. - */ - void (*locked)(void *data, - struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1); - /** - * lock deactivation event - * - * Notification that the pointer lock of the seat's pointer is no - * longer active. If this is a oneshot pointer lock (see - * wp_pointer_constraints.lifetime) this object is now defunct and - * should be destroyed. If this is a persistent pointer lock (see - * wp_pointer_constraints.lifetime) this pointer lock may again - * reactivate in the future. - */ - void (*unlocked)(void *data, - struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1); -}; - -/** - * @ingroup iface_zwp_locked_pointer_v1 - */ -static inline int -zwp_locked_pointer_v1_add_listener(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, - const struct zwp_locked_pointer_v1_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) zwp_locked_pointer_v1, - (void (**)(void)) listener, data); -} - -#define ZWP_LOCKED_POINTER_V1_DESTROY 0 -#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT 1 -#define ZWP_LOCKED_POINTER_V1_SET_REGION 2 - -/** - * @ingroup iface_zwp_locked_pointer_v1 - */ -#define ZWP_LOCKED_POINTER_V1_LOCKED_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_locked_pointer_v1 - */ -#define ZWP_LOCKED_POINTER_V1_UNLOCKED_SINCE_VERSION 1 - -/** - * @ingroup iface_zwp_locked_pointer_v1 - */ -#define ZWP_LOCKED_POINTER_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_locked_pointer_v1 - */ -#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_locked_pointer_v1 - */ -#define ZWP_LOCKED_POINTER_V1_SET_REGION_SINCE_VERSION 1 - -/** @ingroup iface_zwp_locked_pointer_v1 */ -static inline void -zwp_locked_pointer_v1_set_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_locked_pointer_v1, user_data); -} - -/** @ingroup iface_zwp_locked_pointer_v1 */ -static inline void * -zwp_locked_pointer_v1_get_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_locked_pointer_v1); -} - -static inline uint32_t -zwp_locked_pointer_v1_get_version(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1); -} - -/** - * @ingroup iface_zwp_locked_pointer_v1 - * - * Destroy the locked pointer object. If applicable, the compositor will - * unlock the pointer. - */ -static inline void -zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1, - ZWP_LOCKED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zwp_locked_pointer_v1 - * - * Set the cursor position hint relative to the top left corner of the - * surface. - * - * If the client is drawing its own cursor, it should update the position - * hint to the position of its own cursor. A compositor may use this - * information to warp the pointer upon unlock in order to avoid pointer - * jumps. - * - * The cursor position hint is double buffered. The new hint will only take - * effect when the associated surface gets it pending state applied. See - * wl_surface.commit for details. - */ -static inline void -zwp_locked_pointer_v1_set_cursor_position_hint(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1, - ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, surface_x, surface_y); -} - -/** - * @ingroup iface_zwp_locked_pointer_v1 - * - * Set a new region used to lock the pointer. - * - * The new lock region is double-buffered. The new lock region will - * only take effect when the associated surface gets its pending state - * applied. See wl_surface.commit for details. - * - * For details about the lock region, see wp_locked_pointer. - */ -static inline void -zwp_locked_pointer_v1_set_region(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, struct wl_region *region) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1, - ZWP_LOCKED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, region); -} - -/** - * @ingroup iface_zwp_confined_pointer_v1 - * @struct zwp_confined_pointer_v1_listener - */ -struct zwp_confined_pointer_v1_listener { - /** - * pointer confined - * - * Notification that the pointer confinement of the seat's - * pointer is activated. - */ - void (*confined)(void *data, - struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1); - /** - * pointer unconfined - * - * Notification that the pointer confinement of the seat's - * pointer is no longer active. If this is a oneshot pointer - * confinement (see wp_pointer_constraints.lifetime) this object is - * now defunct and should be destroyed. If this is a persistent - * pointer confinement (see wp_pointer_constraints.lifetime) this - * pointer confinement may again reactivate in the future. - */ - void (*unconfined)(void *data, - struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1); -}; - -/** - * @ingroup iface_zwp_confined_pointer_v1 - */ -static inline int -zwp_confined_pointer_v1_add_listener(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, - const struct zwp_confined_pointer_v1_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) zwp_confined_pointer_v1, - (void (**)(void)) listener, data); -} - -#define ZWP_CONFINED_POINTER_V1_DESTROY 0 -#define ZWP_CONFINED_POINTER_V1_SET_REGION 1 - -/** - * @ingroup iface_zwp_confined_pointer_v1 - */ -#define ZWP_CONFINED_POINTER_V1_CONFINED_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_confined_pointer_v1 - */ -#define ZWP_CONFINED_POINTER_V1_UNCONFINED_SINCE_VERSION 1 - -/** - * @ingroup iface_zwp_confined_pointer_v1 - */ -#define ZWP_CONFINED_POINTER_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_confined_pointer_v1 - */ -#define ZWP_CONFINED_POINTER_V1_SET_REGION_SINCE_VERSION 1 - -/** @ingroup iface_zwp_confined_pointer_v1 */ -static inline void -zwp_confined_pointer_v1_set_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_confined_pointer_v1, user_data); -} - -/** @ingroup iface_zwp_confined_pointer_v1 */ -static inline void * -zwp_confined_pointer_v1_get_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_confined_pointer_v1); -} - -static inline uint32_t -zwp_confined_pointer_v1_get_version(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1); -} - -/** - * @ingroup iface_zwp_confined_pointer_v1 - * - * Destroy the confined pointer object. If applicable, the compositor will - * unconfine the pointer. - */ -static inline void -zwp_confined_pointer_v1_destroy(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1, - ZWP_CONFINED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zwp_confined_pointer_v1 - * - * Set a new region used to confine the pointer. - * - * The new confine region is double-buffered. The new confine region will - * only take effect when the associated surface gets its pending state - * applied. See wl_surface.commit for details. - * - * If the confinement is active when the new confinement region is applied - * and the pointer ends up outside of newly applied region, the pointer may - * warped to a position within the new confinement region. If warped, a - * wl_pointer.motion event will be emitted, but no - * wp_relative_pointer.relative_motion event. - * - * The compositor may also, instead of using the new region, unconfine the - * pointer. - * - * For details about the confine region, see wp_confined_pointer. - */ -static inline void -zwp_confined_pointer_v1_set_region(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, struct wl_region *region) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1, - ZWP_CONFINED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), 0, region); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol-code.h deleted file mode 100644 index e650496..0000000 --- a/raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol-code.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2014 Jonas Ådahl - * Copyright © 2015 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_pointer_interface; -extern const struct wl_interface zwp_relative_pointer_v1_interface; - -static const struct wl_interface *relative_pointer_unstable_v1_types[] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - &zwp_relative_pointer_v1_interface, - &wl_pointer_interface, -}; - -static const struct wl_message zwp_relative_pointer_manager_v1_requests[] = { - { "destroy", "", relative_pointer_unstable_v1_types + 0 }, - { "get_relative_pointer", "no", relative_pointer_unstable_v1_types + 6 }, -}; - -WL_PRIVATE const struct wl_interface zwp_relative_pointer_manager_v1_interface = { - "zwp_relative_pointer_manager_v1", 1, - 2, zwp_relative_pointer_manager_v1_requests, - 0, NULL, -}; - -static const struct wl_message zwp_relative_pointer_v1_requests[] = { - { "destroy", "", relative_pointer_unstable_v1_types + 0 }, -}; - -static const struct wl_message zwp_relative_pointer_v1_events[] = { - { "relative_motion", "uuffff", relative_pointer_unstable_v1_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zwp_relative_pointer_v1_interface = { - "zwp_relative_pointer_v1", 1, - 1, zwp_relative_pointer_v1_requests, - 1, zwp_relative_pointer_v1_events, -}; - diff --git a/raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol.h b/raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol.h deleted file mode 100644 index 5aa213e..0000000 --- a/raylib/external/glfw/src/wayland-relative-pointer-unstable-v1-client-protocol.h +++ /dev/null @@ -1,297 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef RELATIVE_POINTER_UNSTABLE_V1_CLIENT_PROTOCOL_H -#define RELATIVE_POINTER_UNSTABLE_V1_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_relative_pointer_unstable_v1 The relative_pointer_unstable_v1 protocol - * protocol for relative pointer motion events - * - * @section page_desc_relative_pointer_unstable_v1 Description - * - * This protocol specifies a set of interfaces used for making clients able to - * receive relative pointer events not obstructed by barriers (such as the - * monitor edge or other pointer barriers). - * - * To start receiving relative pointer events, a client must first bind the - * global interface "wp_relative_pointer_manager" which, if a compositor - * supports relative pointer motion events, is exposed by the registry. After - * having created the relative pointer manager proxy object, the client uses - * it to create the actual relative pointer object using the - * "get_relative_pointer" request given a wl_pointer. The relative pointer - * motion events will then, when applicable, be transmitted via the proxy of - * the newly created relative pointer object. See the documentation of the - * relative pointer interface for more details. - * - * Warning! The protocol described in this file is experimental and backward - * incompatible changes may be made. Backward compatible changes may be added - * together with the corresponding interface version bump. Backward - * incompatible changes are done by bumping the version number in the protocol - * and interface names and resetting the interface version. Once the protocol - * is to be declared stable, the 'z' prefix and the version number in the - * protocol and interface names are removed and the interface version number is - * reset. - * - * @section page_ifaces_relative_pointer_unstable_v1 Interfaces - * - @subpage page_iface_zwp_relative_pointer_manager_v1 - get relative pointer objects - * - @subpage page_iface_zwp_relative_pointer_v1 - relative pointer object - * @section page_copyright_relative_pointer_unstable_v1 Copyright - *
- *
- * Copyright © 2014      Jonas Ådahl
- * Copyright © 2015      Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */ -struct wl_pointer; -struct zwp_relative_pointer_manager_v1; -struct zwp_relative_pointer_v1; - -#ifndef ZWP_RELATIVE_POINTER_MANAGER_V1_INTERFACE -#define ZWP_RELATIVE_POINTER_MANAGER_V1_INTERFACE -/** - * @page page_iface_zwp_relative_pointer_manager_v1 zwp_relative_pointer_manager_v1 - * @section page_iface_zwp_relative_pointer_manager_v1_desc Description - * - * A global interface used for getting the relative pointer object for a - * given pointer. - * @section page_iface_zwp_relative_pointer_manager_v1_api API - * See @ref iface_zwp_relative_pointer_manager_v1. - */ -/** - * @defgroup iface_zwp_relative_pointer_manager_v1 The zwp_relative_pointer_manager_v1 interface - * - * A global interface used for getting the relative pointer object for a - * given pointer. - */ -extern const struct wl_interface zwp_relative_pointer_manager_v1_interface; -#endif -#ifndef ZWP_RELATIVE_POINTER_V1_INTERFACE -#define ZWP_RELATIVE_POINTER_V1_INTERFACE -/** - * @page page_iface_zwp_relative_pointer_v1 zwp_relative_pointer_v1 - * @section page_iface_zwp_relative_pointer_v1_desc Description - * - * A wp_relative_pointer object is an extension to the wl_pointer interface - * used for emitting relative pointer events. It shares the same focus as - * wl_pointer objects of the same seat and will only emit events when it has - * focus. - * @section page_iface_zwp_relative_pointer_v1_api API - * See @ref iface_zwp_relative_pointer_v1. - */ -/** - * @defgroup iface_zwp_relative_pointer_v1 The zwp_relative_pointer_v1 interface - * - * A wp_relative_pointer object is an extension to the wl_pointer interface - * used for emitting relative pointer events. It shares the same focus as - * wl_pointer objects of the same seat and will only emit events when it has - * focus. - */ -extern const struct wl_interface zwp_relative_pointer_v1_interface; -#endif - -#define ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY 0 -#define ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER 1 - - -/** - * @ingroup iface_zwp_relative_pointer_manager_v1 - */ -#define ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_relative_pointer_manager_v1 - */ -#define ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER_SINCE_VERSION 1 - -/** @ingroup iface_zwp_relative_pointer_manager_v1 */ -static inline void -zwp_relative_pointer_manager_v1_set_user_data(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_relative_pointer_manager_v1, user_data); -} - -/** @ingroup iface_zwp_relative_pointer_manager_v1 */ -static inline void * -zwp_relative_pointer_manager_v1_get_user_data(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_relative_pointer_manager_v1); -} - -static inline uint32_t -zwp_relative_pointer_manager_v1_get_version(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1); -} - -/** - * @ingroup iface_zwp_relative_pointer_manager_v1 - * - * Used by the client to notify the server that it will no longer use this - * relative pointer manager object. - */ -static inline void -zwp_relative_pointer_manager_v1_destroy(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_manager_v1, - ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zwp_relative_pointer_manager_v1 - * - * Create a relative pointer interface given a wl_pointer object. See the - * wp_relative_pointer interface for more details. - */ -static inline struct zwp_relative_pointer_v1 * -zwp_relative_pointer_manager_v1_get_relative_pointer(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, struct wl_pointer *pointer) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_manager_v1, - ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER, &zwp_relative_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1), 0, NULL, pointer); - - return (struct zwp_relative_pointer_v1 *) id; -} - -/** - * @ingroup iface_zwp_relative_pointer_v1 - * @struct zwp_relative_pointer_v1_listener - */ -struct zwp_relative_pointer_v1_listener { - /** - * relative pointer motion - * - * Relative x/y pointer motion from the pointer of the seat - * associated with this object. - * - * A relative motion is in the same dimension as regular wl_pointer - * motion events, except they do not represent an absolute - * position. For example, moving a pointer from (x, y) to (x', y') - * would have the equivalent relative motion (x' - x, y' - y). If a - * pointer motion caused the absolute pointer position to be - * clipped by for example the edge of the monitor, the relative - * motion is unaffected by the clipping and will represent the - * unclipped motion. - * - * This event also contains non-accelerated motion deltas. The - * non-accelerated delta is, when applicable, the regular pointer - * motion delta as it was before having applied motion acceleration - * and other transformations such as normalization. - * - * Note that the non-accelerated delta does not represent 'raw' - * events as they were read from some device. Pointer motion - * acceleration is device- and configuration-specific and - * non-accelerated deltas and accelerated deltas may have the same - * value on some devices. - * - * Relative motions are not coupled to wl_pointer.motion events, - * and can be sent in combination with such events, but also - * independently. There may also be scenarios where - * wl_pointer.motion is sent, but there is no relative motion. The - * order of an absolute and relative motion event originating from - * the same physical motion is not guaranteed. - * - * If the client needs button events or focus state, it can receive - * them from a wl_pointer object of the same seat that the - * wp_relative_pointer object is associated with. - * @param utime_hi high 32 bits of a 64 bit timestamp with microsecond granularity - * @param utime_lo low 32 bits of a 64 bit timestamp with microsecond granularity - * @param dx the x component of the motion vector - * @param dy the y component of the motion vector - * @param dx_unaccel the x component of the unaccelerated motion vector - * @param dy_unaccel the y component of the unaccelerated motion vector - */ - void (*relative_motion)(void *data, - struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, - uint32_t utime_hi, - uint32_t utime_lo, - wl_fixed_t dx, - wl_fixed_t dy, - wl_fixed_t dx_unaccel, - wl_fixed_t dy_unaccel); -}; - -/** - * @ingroup iface_zwp_relative_pointer_v1 - */ -static inline int -zwp_relative_pointer_v1_add_listener(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, - const struct zwp_relative_pointer_v1_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) zwp_relative_pointer_v1, - (void (**)(void)) listener, data); -} - -#define ZWP_RELATIVE_POINTER_V1_DESTROY 0 - -/** - * @ingroup iface_zwp_relative_pointer_v1 - */ -#define ZWP_RELATIVE_POINTER_V1_RELATIVE_MOTION_SINCE_VERSION 1 - -/** - * @ingroup iface_zwp_relative_pointer_v1 - */ -#define ZWP_RELATIVE_POINTER_V1_DESTROY_SINCE_VERSION 1 - -/** @ingroup iface_zwp_relative_pointer_v1 */ -static inline void -zwp_relative_pointer_v1_set_user_data(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_relative_pointer_v1, user_data); -} - -/** @ingroup iface_zwp_relative_pointer_v1 */ -static inline void * -zwp_relative_pointer_v1_get_user_data(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_relative_pointer_v1); -} - -static inline uint32_t -zwp_relative_pointer_v1_get_version(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_v1); -} - -/** - * @ingroup iface_zwp_relative_pointer_v1 - */ -static inline void -zwp_relative_pointer_v1_destroy(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_v1, - ZWP_RELATIVE_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_v1), WL_MARSHAL_FLAG_DESTROY); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wayland-viewporter-client-protocol-code.h b/raylib/external/glfw/src/wayland-viewporter-client-protocol-code.h deleted file mode 100644 index fa70d5d..0000000 --- a/raylib/external/glfw/src/wayland-viewporter-client-protocol-code.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2013-2016 Collabora, Ltd. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wp_viewport_interface; - -static const struct wl_interface *viewporter_types[] = { - NULL, - NULL, - NULL, - NULL, - &wp_viewport_interface, - &wl_surface_interface, -}; - -static const struct wl_message wp_viewporter_requests[] = { - { "destroy", "", viewporter_types + 0 }, - { "get_viewport", "no", viewporter_types + 4 }, -}; - -WL_PRIVATE const struct wl_interface wp_viewporter_interface = { - "wp_viewporter", 1, - 2, wp_viewporter_requests, - 0, NULL, -}; - -static const struct wl_message wp_viewport_requests[] = { - { "destroy", "", viewporter_types + 0 }, - { "set_source", "ffff", viewporter_types + 0 }, - { "set_destination", "ii", viewporter_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface wp_viewport_interface = { - "wp_viewport", 1, - 3, wp_viewport_requests, - 0, NULL, -}; - diff --git a/raylib/external/glfw/src/wayland-viewporter-client-protocol.h b/raylib/external/glfw/src/wayland-viewporter-client-protocol.h deleted file mode 100644 index e1295d4..0000000 --- a/raylib/external/glfw/src/wayland-viewporter-client-protocol.h +++ /dev/null @@ -1,398 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef VIEWPORTER_CLIENT_PROTOCOL_H -#define VIEWPORTER_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_viewporter The viewporter protocol - * @section page_ifaces_viewporter Interfaces - * - @subpage page_iface_wp_viewporter - surface cropping and scaling - * - @subpage page_iface_wp_viewport - crop and scale interface to a wl_surface - * @section page_copyright_viewporter Copyright - *
- *
- * Copyright © 2013-2016 Collabora, Ltd.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */ -struct wl_surface; -struct wp_viewport; -struct wp_viewporter; - -#ifndef WP_VIEWPORTER_INTERFACE -#define WP_VIEWPORTER_INTERFACE -/** - * @page page_iface_wp_viewporter wp_viewporter - * @section page_iface_wp_viewporter_desc Description - * - * The global interface exposing surface cropping and scaling - * capabilities is used to instantiate an interface extension for a - * wl_surface object. This extended interface will then allow - * cropping and scaling the surface contents, effectively - * disconnecting the direct relationship between the buffer and the - * surface size. - * @section page_iface_wp_viewporter_api API - * See @ref iface_wp_viewporter. - */ -/** - * @defgroup iface_wp_viewporter The wp_viewporter interface - * - * The global interface exposing surface cropping and scaling - * capabilities is used to instantiate an interface extension for a - * wl_surface object. This extended interface will then allow - * cropping and scaling the surface contents, effectively - * disconnecting the direct relationship between the buffer and the - * surface size. - */ -extern const struct wl_interface wp_viewporter_interface; -#endif -#ifndef WP_VIEWPORT_INTERFACE -#define WP_VIEWPORT_INTERFACE -/** - * @page page_iface_wp_viewport wp_viewport - * @section page_iface_wp_viewport_desc Description - * - * An additional interface to a wl_surface object, which allows the - * client to specify the cropping and scaling of the surface - * contents. - * - * This interface works with two concepts: the source rectangle (src_x, - * src_y, src_width, src_height), and the destination size (dst_width, - * dst_height). The contents of the source rectangle are scaled to the - * destination size, and content outside the source rectangle is ignored. - * This state is double-buffered, and is applied on the next - * wl_surface.commit. - * - * The two parts of crop and scale state are independent: the source - * rectangle, and the destination size. Initially both are unset, that - * is, no scaling is applied. The whole of the current wl_buffer is - * used as the source, and the surface size is as defined in - * wl_surface.attach. - * - * If the destination size is set, it causes the surface size to become - * dst_width, dst_height. The source (rectangle) is scaled to exactly - * this size. This overrides whatever the attached wl_buffer size is, - * unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface - * has no content and therefore no size. Otherwise, the size is always - * at least 1x1 in surface local coordinates. - * - * If the source rectangle is set, it defines what area of the wl_buffer is - * taken as the source. If the source rectangle is set and the destination - * size is not set, then src_width and src_height must be integers, and the - * surface size becomes the source rectangle size. This results in cropping - * without scaling. If src_width or src_height are not integers and - * destination size is not set, the bad_size protocol error is raised when - * the surface state is applied. - * - * The coordinate transformations from buffer pixel coordinates up to - * the surface-local coordinates happen in the following order: - * 1. buffer_transform (wl_surface.set_buffer_transform) - * 2. buffer_scale (wl_surface.set_buffer_scale) - * 3. crop and scale (wp_viewport.set*) - * This means, that the source rectangle coordinates of crop and scale - * are given in the coordinates after the buffer transform and scale, - * i.e. in the coordinates that would be the surface-local coordinates - * if the crop and scale was not applied. - * - * If src_x or src_y are negative, the bad_value protocol error is raised. - * Otherwise, if the source rectangle is partially or completely outside of - * the non-NULL wl_buffer, then the out_of_buffer protocol error is raised - * when the surface state is applied. A NULL wl_buffer does not raise the - * out_of_buffer error. - * - * If the wl_surface associated with the wp_viewport is destroyed, - * all wp_viewport requests except 'destroy' raise the protocol error - * no_surface. - * - * If the wp_viewport object is destroyed, the crop and scale - * state is removed from the wl_surface. The change will be applied - * on the next wl_surface.commit. - * @section page_iface_wp_viewport_api API - * See @ref iface_wp_viewport. - */ -/** - * @defgroup iface_wp_viewport The wp_viewport interface - * - * An additional interface to a wl_surface object, which allows the - * client to specify the cropping and scaling of the surface - * contents. - * - * This interface works with two concepts: the source rectangle (src_x, - * src_y, src_width, src_height), and the destination size (dst_width, - * dst_height). The contents of the source rectangle are scaled to the - * destination size, and content outside the source rectangle is ignored. - * This state is double-buffered, and is applied on the next - * wl_surface.commit. - * - * The two parts of crop and scale state are independent: the source - * rectangle, and the destination size. Initially both are unset, that - * is, no scaling is applied. The whole of the current wl_buffer is - * used as the source, and the surface size is as defined in - * wl_surface.attach. - * - * If the destination size is set, it causes the surface size to become - * dst_width, dst_height. The source (rectangle) is scaled to exactly - * this size. This overrides whatever the attached wl_buffer size is, - * unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface - * has no content and therefore no size. Otherwise, the size is always - * at least 1x1 in surface local coordinates. - * - * If the source rectangle is set, it defines what area of the wl_buffer is - * taken as the source. If the source rectangle is set and the destination - * size is not set, then src_width and src_height must be integers, and the - * surface size becomes the source rectangle size. This results in cropping - * without scaling. If src_width or src_height are not integers and - * destination size is not set, the bad_size protocol error is raised when - * the surface state is applied. - * - * The coordinate transformations from buffer pixel coordinates up to - * the surface-local coordinates happen in the following order: - * 1. buffer_transform (wl_surface.set_buffer_transform) - * 2. buffer_scale (wl_surface.set_buffer_scale) - * 3. crop and scale (wp_viewport.set*) - * This means, that the source rectangle coordinates of crop and scale - * are given in the coordinates after the buffer transform and scale, - * i.e. in the coordinates that would be the surface-local coordinates - * if the crop and scale was not applied. - * - * If src_x or src_y are negative, the bad_value protocol error is raised. - * Otherwise, if the source rectangle is partially or completely outside of - * the non-NULL wl_buffer, then the out_of_buffer protocol error is raised - * when the surface state is applied. A NULL wl_buffer does not raise the - * out_of_buffer error. - * - * If the wl_surface associated with the wp_viewport is destroyed, - * all wp_viewport requests except 'destroy' raise the protocol error - * no_surface. - * - * If the wp_viewport object is destroyed, the crop and scale - * state is removed from the wl_surface. The change will be applied - * on the next wl_surface.commit. - */ -extern const struct wl_interface wp_viewport_interface; -#endif - -#ifndef WP_VIEWPORTER_ERROR_ENUM -#define WP_VIEWPORTER_ERROR_ENUM -enum wp_viewporter_error { - /** - * the surface already has a viewport object associated - */ - WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS = 0, -}; -#endif /* WP_VIEWPORTER_ERROR_ENUM */ - -#define WP_VIEWPORTER_DESTROY 0 -#define WP_VIEWPORTER_GET_VIEWPORT 1 - - -/** - * @ingroup iface_wp_viewporter - */ -#define WP_VIEWPORTER_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wp_viewporter - */ -#define WP_VIEWPORTER_GET_VIEWPORT_SINCE_VERSION 1 - -/** @ingroup iface_wp_viewporter */ -static inline void -wp_viewporter_set_user_data(struct wp_viewporter *wp_viewporter, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wp_viewporter, user_data); -} - -/** @ingroup iface_wp_viewporter */ -static inline void * -wp_viewporter_get_user_data(struct wp_viewporter *wp_viewporter) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wp_viewporter); -} - -static inline uint32_t -wp_viewporter_get_version(struct wp_viewporter *wp_viewporter) -{ - return wl_proxy_get_version((struct wl_proxy *) wp_viewporter); -} - -/** - * @ingroup iface_wp_viewporter - * - * Informs the server that the client will not be using this - * protocol object anymore. This does not affect any other objects, - * wp_viewport objects included. - */ -static inline void -wp_viewporter_destroy(struct wp_viewporter *wp_viewporter) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wp_viewporter, - WP_VIEWPORTER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewporter), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wp_viewporter - * - * Instantiate an interface extension for the given wl_surface to - * crop and scale its content. If the given wl_surface already has - * a wp_viewport object associated, the viewport_exists - * protocol error is raised. - */ -static inline struct wp_viewport * -wp_viewporter_get_viewport(struct wp_viewporter *wp_viewporter, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) wp_viewporter, - WP_VIEWPORTER_GET_VIEWPORT, &wp_viewport_interface, wl_proxy_get_version((struct wl_proxy *) wp_viewporter), 0, NULL, surface); - - return (struct wp_viewport *) id; -} - -#ifndef WP_VIEWPORT_ERROR_ENUM -#define WP_VIEWPORT_ERROR_ENUM -enum wp_viewport_error { - /** - * negative or zero values in width or height - */ - WP_VIEWPORT_ERROR_BAD_VALUE = 0, - /** - * destination size is not integer - */ - WP_VIEWPORT_ERROR_BAD_SIZE = 1, - /** - * source rectangle extends outside of the content area - */ - WP_VIEWPORT_ERROR_OUT_OF_BUFFER = 2, - /** - * the wl_surface was destroyed - */ - WP_VIEWPORT_ERROR_NO_SURFACE = 3, -}; -#endif /* WP_VIEWPORT_ERROR_ENUM */ - -#define WP_VIEWPORT_DESTROY 0 -#define WP_VIEWPORT_SET_SOURCE 1 -#define WP_VIEWPORT_SET_DESTINATION 2 - - -/** - * @ingroup iface_wp_viewport - */ -#define WP_VIEWPORT_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_wp_viewport - */ -#define WP_VIEWPORT_SET_SOURCE_SINCE_VERSION 1 -/** - * @ingroup iface_wp_viewport - */ -#define WP_VIEWPORT_SET_DESTINATION_SINCE_VERSION 1 - -/** @ingroup iface_wp_viewport */ -static inline void -wp_viewport_set_user_data(struct wp_viewport *wp_viewport, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) wp_viewport, user_data); -} - -/** @ingroup iface_wp_viewport */ -static inline void * -wp_viewport_get_user_data(struct wp_viewport *wp_viewport) -{ - return wl_proxy_get_user_data((struct wl_proxy *) wp_viewport); -} - -static inline uint32_t -wp_viewport_get_version(struct wp_viewport *wp_viewport) -{ - return wl_proxy_get_version((struct wl_proxy *) wp_viewport); -} - -/** - * @ingroup iface_wp_viewport - * - * The associated wl_surface's crop and scale state is removed. - * The change is applied on the next wl_surface.commit. - */ -static inline void -wp_viewport_destroy(struct wp_viewport *wp_viewport) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport, - WP_VIEWPORT_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_wp_viewport - * - * Set the source rectangle of the associated wl_surface. See - * wp_viewport for the description, and relation to the wl_buffer - * size. - * - * If all of x, y, width and height are -1.0, the source rectangle is - * unset instead. Any other set of values where width or height are zero - * or negative, or x or y are negative, raise the bad_value protocol - * error. - * - * The crop and scale state is double-buffered state, and will be - * applied on the next wl_surface.commit. - */ -static inline void -wp_viewport_set_source(struct wp_viewport *wp_viewport, wl_fixed_t x, wl_fixed_t y, wl_fixed_t width, wl_fixed_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport, - WP_VIEWPORT_SET_SOURCE, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), 0, x, y, width, height); -} - -/** - * @ingroup iface_wp_viewport - * - * Set the destination size of the associated wl_surface. See - * wp_viewport for the description, and relation to the wl_buffer - * size. - * - * If width is -1 and height is -1, the destination size is unset - * instead. Any other pair of values for width and height that - * contains zero or negative values raises the bad_value protocol - * error. - * - * The crop and scale state is double-buffered state, and will be - * applied on the next wl_surface.commit. - */ -static inline void -wp_viewport_set_destination(struct wp_viewport *wp_viewport, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport, - WP_VIEWPORT_SET_DESTINATION, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), 0, width, height); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wayland-xdg-decoration-client-protocol-code.h b/raylib/external/glfw/src/wayland-xdg-decoration-client-protocol-code.h deleted file mode 100644 index 9389145..0000000 --- a/raylib/external/glfw/src/wayland-xdg-decoration-client-protocol-code.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2018 Simon Ser - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface xdg_toplevel_interface; -extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; - -static const struct wl_interface *xdg_decoration_unstable_v1_types[] = { - NULL, - &zxdg_toplevel_decoration_v1_interface, - &xdg_toplevel_interface, -}; - -static const struct wl_message zxdg_decoration_manager_v1_requests[] = { - { "destroy", "", xdg_decoration_unstable_v1_types + 0 }, - { "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 }, -}; - -WL_PRIVATE const struct wl_interface zxdg_decoration_manager_v1_interface = { - "zxdg_decoration_manager_v1", 1, - 2, zxdg_decoration_manager_v1_requests, - 0, NULL, -}; - -static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = { - { "destroy", "", xdg_decoration_unstable_v1_types + 0 }, - { "set_mode", "u", xdg_decoration_unstable_v1_types + 0 }, - { "unset_mode", "", xdg_decoration_unstable_v1_types + 0 }, -}; - -static const struct wl_message zxdg_toplevel_decoration_v1_events[] = { - { "configure", "u", xdg_decoration_unstable_v1_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zxdg_toplevel_decoration_v1_interface = { - "zxdg_toplevel_decoration_v1", 1, - 3, zxdg_toplevel_decoration_v1_requests, - 1, zxdg_toplevel_decoration_v1_events, -}; - diff --git a/raylib/external/glfw/src/wayland-xdg-decoration-client-protocol.h b/raylib/external/glfw/src/wayland-xdg-decoration-client-protocol.h deleted file mode 100644 index 71cc22c..0000000 --- a/raylib/external/glfw/src/wayland-xdg-decoration-client-protocol.h +++ /dev/null @@ -1,378 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H -#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol - * @section page_ifaces_xdg_decoration_unstable_v1 Interfaces - * - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager - * - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface - * @section page_copyright_xdg_decoration_unstable_v1 Copyright - *
- *
- * Copyright © 2018 Simon Ser
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */ -struct xdg_toplevel; -struct zxdg_decoration_manager_v1; -struct zxdg_toplevel_decoration_v1; - -#ifndef ZXDG_DECORATION_MANAGER_V1_INTERFACE -#define ZXDG_DECORATION_MANAGER_V1_INTERFACE -/** - * @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1 - * @section page_iface_zxdg_decoration_manager_v1_desc Description - * - * This interface allows a compositor to announce support for server-side - * decorations. - * - * A window decoration is a set of window controls as deemed appropriate by - * the party managing them, such as user interface components used to move, - * resize and change a window's state. - * - * A client can use this protocol to request being decorated by a supporting - * compositor. - * - * If compositor and client do not negotiate the use of a server-side - * decoration using this protocol, clients continue to self-decorate as they - * see fit. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - * @section page_iface_zxdg_decoration_manager_v1_api API - * See @ref iface_zxdg_decoration_manager_v1. - */ -/** - * @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface - * - * This interface allows a compositor to announce support for server-side - * decorations. - * - * A window decoration is a set of window controls as deemed appropriate by - * the party managing them, such as user interface components used to move, - * resize and change a window's state. - * - * A client can use this protocol to request being decorated by a supporting - * compositor. - * - * If compositor and client do not negotiate the use of a server-side - * decoration using this protocol, clients continue to self-decorate as they - * see fit. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - */ -extern const struct wl_interface zxdg_decoration_manager_v1_interface; -#endif -#ifndef ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE -#define ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE -/** - * @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1 - * @section page_iface_zxdg_toplevel_decoration_v1_desc Description - * - * The decoration object allows the compositor to toggle server-side window - * decorations for a toplevel surface. The client can request to switch to - * another mode. - * - * The xdg_toplevel_decoration object must be destroyed before its - * xdg_toplevel. - * @section page_iface_zxdg_toplevel_decoration_v1_api API - * See @ref iface_zxdg_toplevel_decoration_v1. - */ -/** - * @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface - * - * The decoration object allows the compositor to toggle server-side window - * decorations for a toplevel surface. The client can request to switch to - * another mode. - * - * The xdg_toplevel_decoration object must be destroyed before its - * xdg_toplevel. - */ -extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; -#endif - -#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0 -#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1 - - -/** - * @ingroup iface_zxdg_decoration_manager_v1 - */ -#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zxdg_decoration_manager_v1 - */ -#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1 - -/** @ingroup iface_zxdg_decoration_manager_v1 */ -static inline void -zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data); -} - -/** @ingroup iface_zxdg_decoration_manager_v1 */ -static inline void * -zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1); -} - -static inline uint32_t -zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1); -} - -/** - * @ingroup iface_zxdg_decoration_manager_v1 - * - * Destroy the decoration manager. This doesn't destroy objects created - * with the manager. - */ -static inline void -zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1, - ZXDG_DECORATION_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zxdg_decoration_manager_v1 - * - * Create a new decoration object associated with the given toplevel. - * - * Creating an xdg_toplevel_decoration from an xdg_toplevel which has a - * buffer attached or committed is a client error, and any attempts by a - * client to attach or manipulate a buffer prior to the first - * xdg_toplevel_decoration.configure event must also be treated as - * errors. - */ -static inline struct zxdg_toplevel_decoration_v1 * -zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1, - ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), 0, NULL, toplevel); - - return (struct zxdg_toplevel_decoration_v1 *) id; -} - -#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM -#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM -enum zxdg_toplevel_decoration_v1_error { - /** - * xdg_toplevel has a buffer attached before configure - */ - ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0, - /** - * xdg_toplevel already has a decoration object - */ - ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1, - /** - * xdg_toplevel destroyed before the decoration object - */ - ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2, -}; -#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */ - -#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM -#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * window decoration modes - * - * These values describe window decoration modes. - */ -enum zxdg_toplevel_decoration_v1_mode { - /** - * no server-side window decoration - */ - ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1, - /** - * server-side window decoration - */ - ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2, -}; -#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */ - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * @struct zxdg_toplevel_decoration_v1_listener - */ -struct zxdg_toplevel_decoration_v1_listener { - /** - * suggest a surface change - * - * The configure event asks the client to change its decoration - * mode. The configured state should not be applied immediately. - * Clients must send an ack_configure in response to this event. - * See xdg_surface.configure and xdg_surface.ack_configure for - * details. - * - * A configure event can be sent at any time. The specified mode - * must be obeyed by the client. - * @param mode the decoration mode - */ - void (*configure)(void *data, - struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, - uint32_t mode); -}; - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -static inline int -zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, - const struct zxdg_toplevel_decoration_v1_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1, - (void (**)(void)) listener, data); -} - -#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0 -#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1 -#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2 - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1 - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1 -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1 - -/** @ingroup iface_zxdg_toplevel_decoration_v1 */ -static inline void -zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data); -} - -/** @ingroup iface_zxdg_toplevel_decoration_v1 */ -static inline void * -zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1); -} - -static inline uint32_t -zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1); -} - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * - * Switch back to a mode without any server-side decorations at the next - * commit. - */ -static inline void -zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1, - ZXDG_TOPLEVEL_DECORATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * - * Set the toplevel surface decoration mode. This informs the compositor - * that the client prefers the provided decoration mode. - * - * After requesting a decoration mode, the compositor will respond by - * emitting an xdg_surface.configure event. The client should then update - * its content, drawing it without decorations if the received mode is - * server-side decorations. The client must also acknowledge the configure - * when committing the new content (see xdg_surface.ack_configure). - * - * The compositor can decide not to use the client's mode and enforce a - * different mode instead. - * - * Clients whose decoration mode depend on the xdg_toplevel state may send - * a set_mode request in response to an xdg_surface.configure event and wait - * for the next xdg_surface.configure event to prevent unwanted state. - * Such clients are responsible for preventing configure loops and must - * make sure not to send multiple successive set_mode requests with the - * same decoration mode. - */ -static inline void -zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1, - ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0, mode); -} - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * - * Unset the toplevel surface decoration mode. This informs the compositor - * that the client doesn't prefer a particular decoration mode. - * - * This request has the same semantics as set_mode. - */ -static inline void -zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1, - ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wayland-xdg-shell-client-protocol-code.h b/raylib/external/glfw/src/wayland-xdg-shell-client-protocol-code.h deleted file mode 100644 index 8c460de..0000000 --- a/raylib/external/glfw/src/wayland-xdg-shell-client-protocol-code.h +++ /dev/null @@ -1,183 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -/* - * Copyright © 2008-2013 Kristian Høgsberg - * Copyright © 2013 Rafael Antognolli - * Copyright © 2013 Jasper St. Pierre - * Copyright © 2010-2013 Intel Corporation - * Copyright © 2015-2017 Samsung Electronics Co., Ltd - * Copyright © 2015-2017 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_output_interface; -extern const struct wl_interface wl_seat_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface xdg_popup_interface; -extern const struct wl_interface xdg_positioner_interface; -extern const struct wl_interface xdg_surface_interface; -extern const struct wl_interface xdg_toplevel_interface; - -static const struct wl_interface *xdg_shell_types[] = { - NULL, - NULL, - NULL, - NULL, - &xdg_positioner_interface, - &xdg_surface_interface, - &wl_surface_interface, - &xdg_toplevel_interface, - &xdg_popup_interface, - &xdg_surface_interface, - &xdg_positioner_interface, - &xdg_toplevel_interface, - &wl_seat_interface, - NULL, - NULL, - NULL, - &wl_seat_interface, - NULL, - &wl_seat_interface, - NULL, - NULL, - &wl_output_interface, - &wl_seat_interface, - NULL, - &xdg_positioner_interface, - NULL, -}; - -static const struct wl_message xdg_wm_base_requests[] = { - { "destroy", "", xdg_shell_types + 0 }, - { "create_positioner", "n", xdg_shell_types + 4 }, - { "get_xdg_surface", "no", xdg_shell_types + 5 }, - { "pong", "u", xdg_shell_types + 0 }, -}; - -static const struct wl_message xdg_wm_base_events[] = { - { "ping", "u", xdg_shell_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_wm_base_interface = { - "xdg_wm_base", 5, - 4, xdg_wm_base_requests, - 1, xdg_wm_base_events, -}; - -static const struct wl_message xdg_positioner_requests[] = { - { "destroy", "", xdg_shell_types + 0 }, - { "set_size", "ii", xdg_shell_types + 0 }, - { "set_anchor_rect", "iiii", xdg_shell_types + 0 }, - { "set_anchor", "u", xdg_shell_types + 0 }, - { "set_gravity", "u", xdg_shell_types + 0 }, - { "set_constraint_adjustment", "u", xdg_shell_types + 0 }, - { "set_offset", "ii", xdg_shell_types + 0 }, - { "set_reactive", "3", xdg_shell_types + 0 }, - { "set_parent_size", "3ii", xdg_shell_types + 0 }, - { "set_parent_configure", "3u", xdg_shell_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_positioner_interface = { - "xdg_positioner", 5, - 10, xdg_positioner_requests, - 0, NULL, -}; - -static const struct wl_message xdg_surface_requests[] = { - { "destroy", "", xdg_shell_types + 0 }, - { "get_toplevel", "n", xdg_shell_types + 7 }, - { "get_popup", "n?oo", xdg_shell_types + 8 }, - { "set_window_geometry", "iiii", xdg_shell_types + 0 }, - { "ack_configure", "u", xdg_shell_types + 0 }, -}; - -static const struct wl_message xdg_surface_events[] = { - { "configure", "u", xdg_shell_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_surface_interface = { - "xdg_surface", 5, - 5, xdg_surface_requests, - 1, xdg_surface_events, -}; - -static const struct wl_message xdg_toplevel_requests[] = { - { "destroy", "", xdg_shell_types + 0 }, - { "set_parent", "?o", xdg_shell_types + 11 }, - { "set_title", "s", xdg_shell_types + 0 }, - { "set_app_id", "s", xdg_shell_types + 0 }, - { "show_window_menu", "ouii", xdg_shell_types + 12 }, - { "move", "ou", xdg_shell_types + 16 }, - { "resize", "ouu", xdg_shell_types + 18 }, - { "set_max_size", "ii", xdg_shell_types + 0 }, - { "set_min_size", "ii", xdg_shell_types + 0 }, - { "set_maximized", "", xdg_shell_types + 0 }, - { "unset_maximized", "", xdg_shell_types + 0 }, - { "set_fullscreen", "?o", xdg_shell_types + 21 }, - { "unset_fullscreen", "", xdg_shell_types + 0 }, - { "set_minimized", "", xdg_shell_types + 0 }, -}; - -static const struct wl_message xdg_toplevel_events[] = { - { "configure", "iia", xdg_shell_types + 0 }, - { "close", "", xdg_shell_types + 0 }, - { "configure_bounds", "4ii", xdg_shell_types + 0 }, - { "wm_capabilities", "5a", xdg_shell_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_toplevel_interface = { - "xdg_toplevel", 5, - 14, xdg_toplevel_requests, - 4, xdg_toplevel_events, -}; - -static const struct wl_message xdg_popup_requests[] = { - { "destroy", "", xdg_shell_types + 0 }, - { "grab", "ou", xdg_shell_types + 22 }, - { "reposition", "3ou", xdg_shell_types + 24 }, -}; - -static const struct wl_message xdg_popup_events[] = { - { "configure", "iiii", xdg_shell_types + 0 }, - { "popup_done", "", xdg_shell_types + 0 }, - { "repositioned", "3u", xdg_shell_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_popup_interface = { - "xdg_popup", 5, - 3, xdg_popup_requests, - 3, xdg_popup_events, -}; - diff --git a/raylib/external/glfw/src/wayland-xdg-shell-client-protocol.h b/raylib/external/glfw/src/wayland-xdg-shell-client-protocol.h deleted file mode 100644 index fb2629a..0000000 --- a/raylib/external/glfw/src/wayland-xdg-shell-client-protocol.h +++ /dev/null @@ -1,2290 +0,0 @@ -/* Generated by wayland-scanner 1.22.0 */ - -#ifndef XDG_SHELL_CLIENT_PROTOCOL_H -#define XDG_SHELL_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_xdg_shell The xdg_shell protocol - * @section page_ifaces_xdg_shell Interfaces - * - @subpage page_iface_xdg_wm_base - create desktop-style surfaces - * - @subpage page_iface_xdg_positioner - child surface positioner - * - @subpage page_iface_xdg_surface - desktop user interface surface base interface - * - @subpage page_iface_xdg_toplevel - toplevel surface - * - @subpage page_iface_xdg_popup - short-lived, popup surfaces for menus - * @section page_copyright_xdg_shell Copyright - *
- *
- * Copyright © 2008-2013 Kristian Høgsberg
- * Copyright © 2013      Rafael Antognolli
- * Copyright © 2013      Jasper St. Pierre
- * Copyright © 2010-2013 Intel Corporation
- * Copyright © 2015-2017 Samsung Electronics Co., Ltd
- * Copyright © 2015-2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */ -struct wl_output; -struct wl_seat; -struct wl_surface; -struct xdg_popup; -struct xdg_positioner; -struct xdg_surface; -struct xdg_toplevel; -struct xdg_wm_base; - -#ifndef XDG_WM_BASE_INTERFACE -#define XDG_WM_BASE_INTERFACE -/** - * @page page_iface_xdg_wm_base xdg_wm_base - * @section page_iface_xdg_wm_base_desc Description - * - * The xdg_wm_base interface is exposed as a global object enabling clients - * to turn their wl_surfaces into windows in a desktop environment. It - * defines the basic functionality needed for clients and the compositor to - * create windows that can be dragged, resized, maximized, etc, as well as - * creating transient windows such as popup menus. - * @section page_iface_xdg_wm_base_api API - * See @ref iface_xdg_wm_base. - */ -/** - * @defgroup iface_xdg_wm_base The xdg_wm_base interface - * - * The xdg_wm_base interface is exposed as a global object enabling clients - * to turn their wl_surfaces into windows in a desktop environment. It - * defines the basic functionality needed for clients and the compositor to - * create windows that can be dragged, resized, maximized, etc, as well as - * creating transient windows such as popup menus. - */ -extern const struct wl_interface xdg_wm_base_interface; -#endif -#ifndef XDG_POSITIONER_INTERFACE -#define XDG_POSITIONER_INTERFACE -/** - * @page page_iface_xdg_positioner xdg_positioner - * @section page_iface_xdg_positioner_desc Description - * - * The xdg_positioner provides a collection of rules for the placement of a - * child surface relative to a parent surface. Rules can be defined to ensure - * the child surface remains within the visible area's borders, and to - * specify how the child surface changes its position, such as sliding along - * an axis, or flipping around a rectangle. These positioner-created rules are - * constrained by the requirement that a child surface must intersect with or - * be at least partially adjacent to its parent surface. - * - * See the various requests for details about possible rules. - * - * At the time of the request, the compositor makes a copy of the rules - * specified by the xdg_positioner. Thus, after the request is complete the - * xdg_positioner object can be destroyed or reused; further changes to the - * object will have no effect on previous usages. - * - * For an xdg_positioner object to be considered complete, it must have a - * non-zero size set by set_size, and a non-zero anchor rectangle set by - * set_anchor_rect. Passing an incomplete xdg_positioner object when - * positioning a surface raises an invalid_positioner error. - * @section page_iface_xdg_positioner_api API - * See @ref iface_xdg_positioner. - */ -/** - * @defgroup iface_xdg_positioner The xdg_positioner interface - * - * The xdg_positioner provides a collection of rules for the placement of a - * child surface relative to a parent surface. Rules can be defined to ensure - * the child surface remains within the visible area's borders, and to - * specify how the child surface changes its position, such as sliding along - * an axis, or flipping around a rectangle. These positioner-created rules are - * constrained by the requirement that a child surface must intersect with or - * be at least partially adjacent to its parent surface. - * - * See the various requests for details about possible rules. - * - * At the time of the request, the compositor makes a copy of the rules - * specified by the xdg_positioner. Thus, after the request is complete the - * xdg_positioner object can be destroyed or reused; further changes to the - * object will have no effect on previous usages. - * - * For an xdg_positioner object to be considered complete, it must have a - * non-zero size set by set_size, and a non-zero anchor rectangle set by - * set_anchor_rect. Passing an incomplete xdg_positioner object when - * positioning a surface raises an invalid_positioner error. - */ -extern const struct wl_interface xdg_positioner_interface; -#endif -#ifndef XDG_SURFACE_INTERFACE -#define XDG_SURFACE_INTERFACE -/** - * @page page_iface_xdg_surface xdg_surface - * @section page_iface_xdg_surface_desc Description - * - * An interface that may be implemented by a wl_surface, for - * implementations that provide a desktop-style user interface. - * - * It provides a base set of functionality required to construct user - * interface elements requiring management by the compositor, such as - * toplevel windows, menus, etc. The types of functionality are split into - * xdg_surface roles. - * - * Creating an xdg_surface does not set the role for a wl_surface. In order - * to map an xdg_surface, the client must create a role-specific object - * using, e.g., get_toplevel, get_popup. The wl_surface for any given - * xdg_surface can have at most one role, and may not be assigned any role - * not based on xdg_surface. - * - * A role must be assigned before any other requests are made to the - * xdg_surface object. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_surface state to take effect. - * - * Creating an xdg_surface from a wl_surface which has a buffer attached or - * committed is a client error, and any attempts by a client to attach or - * manipulate a buffer prior to the first xdg_surface.configure call must - * also be treated as errors. - * - * After creating a role-specific object and setting it up, the client must - * perform an initial commit without any buffer attached. The compositor - * will reply with an xdg_surface.configure event. The client must - * acknowledge it and is then allowed to attach a buffer to map the surface. - * - * Mapping an xdg_surface-based role surface is defined as making it - * possible for the surface to be shown by the compositor. Note that - * a mapped surface is not guaranteed to be visible once it is mapped. - * - * For an xdg_surface to be mapped by the compositor, the following - * conditions must be met: - * (1) the client has assigned an xdg_surface-based role to the surface - * (2) the client has set and committed the xdg_surface state and the - * role-dependent state to the surface - * (3) the client has committed a buffer to the surface - * - * A newly-unmapped surface is considered to have met condition (1) out - * of the 3 required conditions for mapping a surface if its role surface - * has not been destroyed, i.e. the client must perform the initial commit - * again before attaching a buffer. - * @section page_iface_xdg_surface_api API - * See @ref iface_xdg_surface. - */ -/** - * @defgroup iface_xdg_surface The xdg_surface interface - * - * An interface that may be implemented by a wl_surface, for - * implementations that provide a desktop-style user interface. - * - * It provides a base set of functionality required to construct user - * interface elements requiring management by the compositor, such as - * toplevel windows, menus, etc. The types of functionality are split into - * xdg_surface roles. - * - * Creating an xdg_surface does not set the role for a wl_surface. In order - * to map an xdg_surface, the client must create a role-specific object - * using, e.g., get_toplevel, get_popup. The wl_surface for any given - * xdg_surface can have at most one role, and may not be assigned any role - * not based on xdg_surface. - * - * A role must be assigned before any other requests are made to the - * xdg_surface object. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_surface state to take effect. - * - * Creating an xdg_surface from a wl_surface which has a buffer attached or - * committed is a client error, and any attempts by a client to attach or - * manipulate a buffer prior to the first xdg_surface.configure call must - * also be treated as errors. - * - * After creating a role-specific object and setting it up, the client must - * perform an initial commit without any buffer attached. The compositor - * will reply with an xdg_surface.configure event. The client must - * acknowledge it and is then allowed to attach a buffer to map the surface. - * - * Mapping an xdg_surface-based role surface is defined as making it - * possible for the surface to be shown by the compositor. Note that - * a mapped surface is not guaranteed to be visible once it is mapped. - * - * For an xdg_surface to be mapped by the compositor, the following - * conditions must be met: - * (1) the client has assigned an xdg_surface-based role to the surface - * (2) the client has set and committed the xdg_surface state and the - * role-dependent state to the surface - * (3) the client has committed a buffer to the surface - * - * A newly-unmapped surface is considered to have met condition (1) out - * of the 3 required conditions for mapping a surface if its role surface - * has not been destroyed, i.e. the client must perform the initial commit - * again before attaching a buffer. - */ -extern const struct wl_interface xdg_surface_interface; -#endif -#ifndef XDG_TOPLEVEL_INTERFACE -#define XDG_TOPLEVEL_INTERFACE -/** - * @page page_iface_xdg_toplevel xdg_toplevel - * @section page_iface_xdg_toplevel_desc Description - * - * This interface defines an xdg_surface role which allows a surface to, - * among other things, set window-like properties such as maximize, - * fullscreen, and minimize, set application-specific metadata like title and - * id, and well as trigger user interactive operations such as interactive - * resize and move. - * - * Unmapping an xdg_toplevel means that the surface cannot be shown - * by the compositor until it is explicitly mapped again. - * All active operations (e.g., move, resize) are canceled and all - * attributes (e.g. title, state, stacking, ...) are discarded for - * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to - * the state it had right after xdg_surface.get_toplevel. The client - * can re-map the toplevel by perfoming a commit without any buffer - * attached, waiting for a configure event and handling it as usual (see - * xdg_surface description). - * - * Attaching a null buffer to a toplevel unmaps the surface. - * @section page_iface_xdg_toplevel_api API - * See @ref iface_xdg_toplevel. - */ -/** - * @defgroup iface_xdg_toplevel The xdg_toplevel interface - * - * This interface defines an xdg_surface role which allows a surface to, - * among other things, set window-like properties such as maximize, - * fullscreen, and minimize, set application-specific metadata like title and - * id, and well as trigger user interactive operations such as interactive - * resize and move. - * - * Unmapping an xdg_toplevel means that the surface cannot be shown - * by the compositor until it is explicitly mapped again. - * All active operations (e.g., move, resize) are canceled and all - * attributes (e.g. title, state, stacking, ...) are discarded for - * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to - * the state it had right after xdg_surface.get_toplevel. The client - * can re-map the toplevel by perfoming a commit without any buffer - * attached, waiting for a configure event and handling it as usual (see - * xdg_surface description). - * - * Attaching a null buffer to a toplevel unmaps the surface. - */ -extern const struct wl_interface xdg_toplevel_interface; -#endif -#ifndef XDG_POPUP_INTERFACE -#define XDG_POPUP_INTERFACE -/** - * @page page_iface_xdg_popup xdg_popup - * @section page_iface_xdg_popup_desc Description - * - * A popup surface is a short-lived, temporary surface. It can be used to - * implement for example menus, popovers, tooltips and other similar user - * interface concepts. - * - * A popup can be made to take an explicit grab. See xdg_popup.grab for - * details. - * - * When the popup is dismissed, a popup_done event will be sent out, and at - * the same time the surface will be unmapped. See the xdg_popup.popup_done - * event for details. - * - * Explicitly destroying the xdg_popup object will also dismiss the popup and - * unmap the surface. Clients that want to dismiss the popup when another - * surface of their own is clicked should dismiss the popup using the destroy - * request. - * - * A newly created xdg_popup will be stacked on top of all previously created - * xdg_popup surfaces associated with the same xdg_toplevel. - * - * The parent of an xdg_popup must be mapped (see the xdg_surface - * description) before the xdg_popup itself. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_popup state to take effect. - * @section page_iface_xdg_popup_api API - * See @ref iface_xdg_popup. - */ -/** - * @defgroup iface_xdg_popup The xdg_popup interface - * - * A popup surface is a short-lived, temporary surface. It can be used to - * implement for example menus, popovers, tooltips and other similar user - * interface concepts. - * - * A popup can be made to take an explicit grab. See xdg_popup.grab for - * details. - * - * When the popup is dismissed, a popup_done event will be sent out, and at - * the same time the surface will be unmapped. See the xdg_popup.popup_done - * event for details. - * - * Explicitly destroying the xdg_popup object will also dismiss the popup and - * unmap the surface. Clients that want to dismiss the popup when another - * surface of their own is clicked should dismiss the popup using the destroy - * request. - * - * A newly created xdg_popup will be stacked on top of all previously created - * xdg_popup surfaces associated with the same xdg_toplevel. - * - * The parent of an xdg_popup must be mapped (see the xdg_surface - * description) before the xdg_popup itself. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_popup state to take effect. - */ -extern const struct wl_interface xdg_popup_interface; -#endif - -#ifndef XDG_WM_BASE_ERROR_ENUM -#define XDG_WM_BASE_ERROR_ENUM -enum xdg_wm_base_error { - /** - * given wl_surface has another role - */ - XDG_WM_BASE_ERROR_ROLE = 0, - /** - * xdg_wm_base was destroyed before children - */ - XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1, - /** - * the client tried to map or destroy a non-topmost popup - */ - XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2, - /** - * the client specified an invalid popup parent surface - */ - XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3, - /** - * the client provided an invalid surface state - */ - XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4, - /** - * the client provided an invalid positioner - */ - XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5, - /** - * the client didn’t respond to a ping event in time - */ - XDG_WM_BASE_ERROR_UNRESPONSIVE = 6, -}; -#endif /* XDG_WM_BASE_ERROR_ENUM */ - -/** - * @ingroup iface_xdg_wm_base - * @struct xdg_wm_base_listener - */ -struct xdg_wm_base_listener { - /** - * check if the client is alive - * - * The ping event asks the client if it's still alive. Pass the - * serial specified in the event back to the compositor by sending - * a "pong" request back with the specified serial. See - * xdg_wm_base.pong. - * - * Compositors can use this to determine if the client is still - * alive. It's unspecified what will happen if the client doesn't - * respond to the ping request, or in what timeframe. Clients - * should try to respond in a reasonable amount of time. The - * “unresponsive” error is provided for compositors that wish - * to disconnect unresponsive clients. - * - * A compositor is free to ping in any way it wants, but a client - * must always respond to any xdg_wm_base object it created. - * @param serial pass this to the pong request - */ - void (*ping)(void *data, - struct xdg_wm_base *xdg_wm_base, - uint32_t serial); -}; - -/** - * @ingroup iface_xdg_wm_base - */ -static inline int -xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base, - const struct xdg_wm_base_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_wm_base, - (void (**)(void)) listener, data); -} - -#define XDG_WM_BASE_DESTROY 0 -#define XDG_WM_BASE_CREATE_POSITIONER 1 -#define XDG_WM_BASE_GET_XDG_SURFACE 2 -#define XDG_WM_BASE_PONG 3 - -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_PING_SINCE_VERSION 1 - -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_CREATE_POSITIONER_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_GET_XDG_SURFACE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_PONG_SINCE_VERSION 1 - -/** @ingroup iface_xdg_wm_base */ -static inline void -xdg_wm_base_set_user_data(struct xdg_wm_base *xdg_wm_base, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_wm_base, user_data); -} - -/** @ingroup iface_xdg_wm_base */ -static inline void * -xdg_wm_base_get_user_data(struct xdg_wm_base *xdg_wm_base) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_wm_base); -} - -static inline uint32_t -xdg_wm_base_get_version(struct xdg_wm_base *xdg_wm_base) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_wm_base); -} - -/** - * @ingroup iface_xdg_wm_base - * - * Destroy this xdg_wm_base object. - * - * Destroying a bound xdg_wm_base object while there are surfaces - * still alive created by this xdg_wm_base object instance is illegal - * and will result in a defunct_surfaces error. - */ -static inline void -xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_xdg_wm_base - * - * Create a positioner object. A positioner object is used to position - * surfaces relative to some parent surface. See the interface description - * and xdg_surface.get_popup for details. - */ -static inline struct xdg_positioner * -xdg_wm_base_create_positioner(struct xdg_wm_base *xdg_wm_base) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_CREATE_POSITIONER, &xdg_positioner_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL); - - return (struct xdg_positioner *) id; -} - -/** - * @ingroup iface_xdg_wm_base - * - * This creates an xdg_surface for the given surface. While xdg_surface - * itself is not a role, the corresponding surface may only be assigned - * a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is - * illegal to create an xdg_surface for a wl_surface which already has an - * assigned role and this will result in a role error. - * - * This creates an xdg_surface for the given surface. An xdg_surface is - * used as basis to define a role to a given surface, such as xdg_toplevel - * or xdg_popup. It also manages functionality shared between xdg_surface - * based surface roles. - * - * See the documentation of xdg_surface for more details about what an - * xdg_surface is and how it is used. - */ -static inline struct xdg_surface * -xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_GET_XDG_SURFACE, &xdg_surface_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL, surface); - - return (struct xdg_surface *) id; -} - -/** - * @ingroup iface_xdg_wm_base - * - * A client must respond to a ping event with a pong request or - * the client may be deemed unresponsive. See xdg_wm_base.ping - * and xdg_wm_base.error.unresponsive. - */ -static inline void -xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, serial); -} - -#ifndef XDG_POSITIONER_ERROR_ENUM -#define XDG_POSITIONER_ERROR_ENUM -enum xdg_positioner_error { - /** - * invalid input provided - */ - XDG_POSITIONER_ERROR_INVALID_INPUT = 0, -}; -#endif /* XDG_POSITIONER_ERROR_ENUM */ - -#ifndef XDG_POSITIONER_ANCHOR_ENUM -#define XDG_POSITIONER_ANCHOR_ENUM -enum xdg_positioner_anchor { - XDG_POSITIONER_ANCHOR_NONE = 0, - XDG_POSITIONER_ANCHOR_TOP = 1, - XDG_POSITIONER_ANCHOR_BOTTOM = 2, - XDG_POSITIONER_ANCHOR_LEFT = 3, - XDG_POSITIONER_ANCHOR_RIGHT = 4, - XDG_POSITIONER_ANCHOR_TOP_LEFT = 5, - XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6, - XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7, - XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8, -}; -#endif /* XDG_POSITIONER_ANCHOR_ENUM */ - -#ifndef XDG_POSITIONER_GRAVITY_ENUM -#define XDG_POSITIONER_GRAVITY_ENUM -enum xdg_positioner_gravity { - XDG_POSITIONER_GRAVITY_NONE = 0, - XDG_POSITIONER_GRAVITY_TOP = 1, - XDG_POSITIONER_GRAVITY_BOTTOM = 2, - XDG_POSITIONER_GRAVITY_LEFT = 3, - XDG_POSITIONER_GRAVITY_RIGHT = 4, - XDG_POSITIONER_GRAVITY_TOP_LEFT = 5, - XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6, - XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7, - XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8, -}; -#endif /* XDG_POSITIONER_GRAVITY_ENUM */ - -#ifndef XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM -#define XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM -/** - * @ingroup iface_xdg_positioner - * constraint adjustments - * - * The constraint adjustment value define ways the compositor will adjust - * the position of the surface, if the unadjusted position would result - * in the surface being partly constrained. - * - * Whether a surface is considered 'constrained' is left to the compositor - * to determine. For example, the surface may be partly outside the - * compositor's defined 'work area', thus necessitating the child surface's - * position be adjusted until it is entirely inside the work area. - * - * The adjustments can be combined, according to a defined precedence: 1) - * Flip, 2) Slide, 3) Resize. - */ -enum xdg_positioner_constraint_adjustment { - /** - * don't move the child surface when constrained - * - * Don't alter the surface position even if it is constrained on - * some axis, for example partially outside the edge of an output. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0, - /** - * move along the x axis until unconstrained - * - * Slide the surface along the x axis until it is no longer - * constrained. - * - * First try to slide towards the direction of the gravity on the x - * axis until either the edge in the opposite direction of the - * gravity is unconstrained or the edge in the direction of the - * gravity is constrained. - * - * Then try to slide towards the opposite direction of the gravity - * on the x axis until either the edge in the direction of the - * gravity is unconstrained or the edge in the opposite direction - * of the gravity is constrained. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1, - /** - * move along the y axis until unconstrained - * - * Slide the surface along the y axis until it is no longer - * constrained. - * - * First try to slide towards the direction of the gravity on the y - * axis until either the edge in the opposite direction of the - * gravity is unconstrained or the edge in the direction of the - * gravity is constrained. - * - * Then try to slide towards the opposite direction of the gravity - * on the y axis until either the edge in the direction of the - * gravity is unconstrained or the edge in the opposite direction - * of the gravity is constrained. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2, - /** - * invert the anchor and gravity on the x axis - * - * Invert the anchor and gravity on the x axis if the surface is - * constrained on the x axis. For example, if the left edge of the - * surface is constrained, the gravity is 'left' and the anchor is - * 'left', change the gravity to 'right' and the anchor to 'right'. - * - * If the adjusted position also ends up being constrained, the - * resulting position of the flip_x adjustment will be the one - * before the adjustment. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4, - /** - * invert the anchor and gravity on the y axis - * - * Invert the anchor and gravity on the y axis if the surface is - * constrained on the y axis. For example, if the bottom edge of - * the surface is constrained, the gravity is 'bottom' and the - * anchor is 'bottom', change the gravity to 'top' and the anchor - * to 'top'. - * - * The adjusted position is calculated given the original anchor - * rectangle and offset, but with the new flipped anchor and - * gravity values. - * - * If the adjusted position also ends up being constrained, the - * resulting position of the flip_y adjustment will be the one - * before the adjustment. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8, - /** - * horizontally resize the surface - * - * Resize the surface horizontally so that it is completely - * unconstrained. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16, - /** - * vertically resize the surface - * - * Resize the surface vertically so that it is completely - * unconstrained. - */ - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, -}; -#endif /* XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM */ - -#define XDG_POSITIONER_DESTROY 0 -#define XDG_POSITIONER_SET_SIZE 1 -#define XDG_POSITIONER_SET_ANCHOR_RECT 2 -#define XDG_POSITIONER_SET_ANCHOR 3 -#define XDG_POSITIONER_SET_GRAVITY 4 -#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT 5 -#define XDG_POSITIONER_SET_OFFSET 6 -#define XDG_POSITIONER_SET_REACTIVE 7 -#define XDG_POSITIONER_SET_PARENT_SIZE 8 -#define XDG_POSITIONER_SET_PARENT_CONFIGURE 9 - - -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_SIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_ANCHOR_RECT_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_ANCHOR_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_GRAVITY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_OFFSET_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_REACTIVE_SINCE_VERSION 3 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_PARENT_SIZE_SINCE_VERSION 3 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION 3 - -/** @ingroup iface_xdg_positioner */ -static inline void -xdg_positioner_set_user_data(struct xdg_positioner *xdg_positioner, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_positioner, user_data); -} - -/** @ingroup iface_xdg_positioner */ -static inline void * -xdg_positioner_get_user_data(struct xdg_positioner *xdg_positioner) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_positioner); -} - -static inline uint32_t -xdg_positioner_get_version(struct xdg_positioner *xdg_positioner) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_positioner); -} - -/** - * @ingroup iface_xdg_positioner - * - * Notify the compositor that the xdg_positioner will no longer be used. - */ -static inline void -xdg_positioner_destroy(struct xdg_positioner *xdg_positioner) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_xdg_positioner - * - * Set the size of the surface that is to be positioned with the positioner - * object. The size is in surface-local coordinates and corresponds to the - * window geometry. See xdg_surface.set_window_geometry. - * - * If a zero or negative size is set the invalid_input error is raised. - */ -static inline void -xdg_positioner_set_size(struct xdg_positioner *xdg_positioner, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, width, height); -} - -/** - * @ingroup iface_xdg_positioner - * - * Specify the anchor rectangle within the parent surface that the child - * surface will be placed relative to. The rectangle is relative to the - * window geometry as defined by xdg_surface.set_window_geometry of the - * parent surface. - * - * When the xdg_positioner object is used to position a child surface, the - * anchor rectangle may not extend outside the window geometry of the - * positioned child's parent surface. - * - * If a negative size is set the invalid_input error is raised. - */ -static inline void -xdg_positioner_set_anchor_rect(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_ANCHOR_RECT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y, width, height); -} - -/** - * @ingroup iface_xdg_positioner - * - * Defines the anchor point for the anchor rectangle. The specified anchor - * is used derive an anchor point that the child surface will be - * positioned relative to. If a corner anchor is set (e.g. 'top_left' or - * 'bottom_right'), the anchor point will be at the specified corner; - * otherwise, the derived anchor point will be centered on the specified - * edge, or in the center of the anchor rectangle if no edge is specified. - */ -static inline void -xdg_positioner_set_anchor(struct xdg_positioner *xdg_positioner, uint32_t anchor) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, anchor); -} - -/** - * @ingroup iface_xdg_positioner - * - * Defines in what direction a surface should be positioned, relative to - * the anchor point of the parent surface. If a corner gravity is - * specified (e.g. 'bottom_right' or 'top_left'), then the child surface - * will be placed towards the specified gravity; otherwise, the child - * surface will be centered over the anchor point on any axis that had no - * gravity specified. If the gravity is not in the ‘gravity’ enum, an - * invalid_input error is raised. - */ -static inline void -xdg_positioner_set_gravity(struct xdg_positioner *xdg_positioner, uint32_t gravity) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_GRAVITY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, gravity); -} - -/** - * @ingroup iface_xdg_positioner - * - * Specify how the window should be positioned if the originally intended - * position caused the surface to be constrained, meaning at least - * partially outside positioning boundaries set by the compositor. The - * adjustment is set by constructing a bitmask describing the adjustment to - * be made when the surface is constrained on that axis. - * - * If no bit for one axis is set, the compositor will assume that the child - * surface should not change its position on that axis when constrained. - * - * If more than one bit for one axis is set, the order of how adjustments - * are applied is specified in the corresponding adjustment descriptions. - * - * The default adjustment is none. - */ -static inline void -xdg_positioner_set_constraint_adjustment(struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, constraint_adjustment); -} - -/** - * @ingroup iface_xdg_positioner - * - * Specify the surface position offset relative to the position of the - * anchor on the anchor rectangle and the anchor on the surface. For - * example if the anchor of the anchor rectangle is at (x, y), the surface - * has the gravity bottom|right, and the offset is (ox, oy), the calculated - * surface position will be (x + ox, y + oy). The offset position of the - * surface is the one used for constraint testing. See - * set_constraint_adjustment. - * - * An example use case is placing a popup menu on top of a user interface - * element, while aligning the user interface element of the parent surface - * with some user interface element placed somewhere in the popup surface. - */ -static inline void -xdg_positioner_set_offset(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y); -} - -/** - * @ingroup iface_xdg_positioner - * - * When set reactive, the surface is reconstrained if the conditions used - * for constraining changed, e.g. the parent window moved. - * - * If the conditions changed and the popup was reconstrained, an - * xdg_popup.configure event is sent with updated geometry, followed by an - * xdg_surface.configure event. - */ -static inline void -xdg_positioner_set_reactive(struct xdg_positioner *xdg_positioner) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_REACTIVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0); -} - -/** - * @ingroup iface_xdg_positioner - * - * Set the parent window geometry the compositor should use when - * positioning the popup. The compositor may use this information to - * determine the future state the popup should be constrained using. If - * this doesn't match the dimension of the parent the popup is eventually - * positioned against, the behavior is undefined. - * - * The arguments are given in the surface-local coordinate space. - */ -static inline void -xdg_positioner_set_parent_size(struct xdg_positioner *xdg_positioner, int32_t parent_width, int32_t parent_height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_PARENT_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, parent_width, parent_height); -} - -/** - * @ingroup iface_xdg_positioner - * - * Set the serial of an xdg_surface.configure event this positioner will be - * used in response to. The compositor may use this information together - * with set_parent_size to determine what future state the popup should be - * constrained using. - */ -static inline void -xdg_positioner_set_parent_configure(struct xdg_positioner *xdg_positioner, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_PARENT_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, serial); -} - -#ifndef XDG_SURFACE_ERROR_ENUM -#define XDG_SURFACE_ERROR_ENUM -enum xdg_surface_error { - /** - * Surface was not fully constructed - */ - XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1, - /** - * Surface was already constructed - */ - XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2, - /** - * Attaching a buffer to an unconfigured surface - */ - XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3, - /** - * Invalid serial number when acking a configure event - */ - XDG_SURFACE_ERROR_INVALID_SERIAL = 4, - /** - * Width or height was zero or negative - */ - XDG_SURFACE_ERROR_INVALID_SIZE = 5, - /** - * Surface was destroyed before its role object - */ - XDG_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 6, -}; -#endif /* XDG_SURFACE_ERROR_ENUM */ - -/** - * @ingroup iface_xdg_surface - * @struct xdg_surface_listener - */ -struct xdg_surface_listener { - /** - * suggest a surface change - * - * The configure event marks the end of a configure sequence. A - * configure sequence is a set of one or more events configuring - * the state of the xdg_surface, including the final - * xdg_surface.configure event. - * - * Where applicable, xdg_surface surface roles will during a - * configure sequence extend this event as a latched state sent as - * events before the xdg_surface.configure event. Such events - * should be considered to make up a set of atomically applied - * configuration states, where the xdg_surface.configure commits - * the accumulated state. - * - * Clients should arrange their surface for the new states, and - * then send an ack_configure request with the serial sent in this - * configure event at some point before committing the new surface. - * - * If the client receives multiple configure events before it can - * respond to one, it is free to discard all but the last event it - * received. - * @param serial serial of the configure event - */ - void (*configure)(void *data, - struct xdg_surface *xdg_surface, - uint32_t serial); -}; - -/** - * @ingroup iface_xdg_surface - */ -static inline int -xdg_surface_add_listener(struct xdg_surface *xdg_surface, - const struct xdg_surface_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_surface, - (void (**)(void)) listener, data); -} - -#define XDG_SURFACE_DESTROY 0 -#define XDG_SURFACE_GET_TOPLEVEL 1 -#define XDG_SURFACE_GET_POPUP 2 -#define XDG_SURFACE_SET_WINDOW_GEOMETRY 3 -#define XDG_SURFACE_ACK_CONFIGURE 4 - -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_CONFIGURE_SINCE_VERSION 1 - -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_GET_TOPLEVEL_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_GET_POPUP_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_SET_WINDOW_GEOMETRY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_ACK_CONFIGURE_SINCE_VERSION 1 - -/** @ingroup iface_xdg_surface */ -static inline void -xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data); -} - -/** @ingroup iface_xdg_surface */ -static inline void * -xdg_surface_get_user_data(struct xdg_surface *xdg_surface) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface); -} - -static inline uint32_t -xdg_surface_get_version(struct xdg_surface *xdg_surface) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_surface); -} - -/** - * @ingroup iface_xdg_surface - * - * Destroy the xdg_surface object. An xdg_surface must only be destroyed - * after its role object has been destroyed, otherwise - * a defunct_role_object error is raised. - */ -static inline void -xdg_surface_destroy(struct xdg_surface *xdg_surface) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, - XDG_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_xdg_surface - * - * This creates an xdg_toplevel object for the given xdg_surface and gives - * the associated wl_surface the xdg_toplevel role. - * - * See the documentation of xdg_toplevel for more details about what an - * xdg_toplevel is and how it is used. - */ -static inline struct xdg_toplevel * -xdg_surface_get_toplevel(struct xdg_surface *xdg_surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, - XDG_SURFACE_GET_TOPLEVEL, &xdg_toplevel_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL); - - return (struct xdg_toplevel *) id; -} - -/** - * @ingroup iface_xdg_surface - * - * This creates an xdg_popup object for the given xdg_surface and gives - * the associated wl_surface the xdg_popup role. - * - * If null is passed as a parent, a parent surface must be specified using - * some other protocol, before committing the initial state. - * - * See the documentation of xdg_popup for more details about what an - * xdg_popup is and how it is used. - */ -static inline struct xdg_popup * -xdg_surface_get_popup(struct xdg_surface *xdg_surface, struct xdg_surface *parent, struct xdg_positioner *positioner) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, - XDG_SURFACE_GET_POPUP, &xdg_popup_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL, parent, positioner); - - return (struct xdg_popup *) id; -} - -/** - * @ingroup iface_xdg_surface - * - * The window geometry of a surface is its "visible bounds" from the - * user's perspective. Client-side decorations often have invisible - * portions like drop-shadows which should be ignored for the - * purposes of aligning, placing and constraining windows. - * - * The window geometry is double buffered, and will be applied at the - * time wl_surface.commit of the corresponding wl_surface is called. - * - * When maintaining a position, the compositor should treat the (x, y) - * coordinate of the window geometry as the top left corner of the window. - * A client changing the (x, y) window geometry coordinate should in - * general not alter the position of the window. - * - * Once the window geometry of the surface is set, it is not possible to - * unset it, and it will remain the same until set_window_geometry is - * called again, even if a new subsurface or buffer is attached. - * - * If never set, the value is the full bounds of the surface, - * including any subsurfaces. This updates dynamically on every - * commit. This unset is meant for extremely simple clients. - * - * The arguments are given in the surface-local coordinate space of - * the wl_surface associated with this xdg_surface, and may extend outside - * of the wl_surface itself to mark parts of the subsurface tree as part of - * the window geometry. - * - * When applied, the effective window geometry will be the set window - * geometry clamped to the bounding rectangle of the combined - * geometry of the surface of the xdg_surface and the associated - * subsurfaces. - * - * The effective geometry will not be recalculated unless a new call to - * set_window_geometry is done and the new pending surface state is - * subsequently applied. - * - * The width and height of the effective window geometry must be - * greater than zero. Setting an invalid size will raise an - * invalid_size error. - */ -static inline void -xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, - XDG_SURFACE_SET_WINDOW_GEOMETRY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, x, y, width, height); -} - -/** - * @ingroup iface_xdg_surface - * - * When a configure event is received, if a client commits the - * surface in response to the configure event, then the client - * must make an ack_configure request sometime before the commit - * request, passing along the serial of the configure event. - * - * For instance, for toplevel surfaces the compositor might use this - * information to move a surface to the top left only when the client has - * drawn itself for the maximized or fullscreen state. - * - * If the client receives multiple configure events before it - * can respond to one, it only has to ack the last configure event. - * Acking a configure event that was never sent raises an invalid_serial - * error. - * - * A client is not required to commit immediately after sending - * an ack_configure request - it may even ack_configure several times - * before its next surface commit. - * - * A client may send multiple ack_configure requests before committing, but - * only the last request sent before a commit indicates which configure - * event the client really is responding to. - * - * Sending an ack_configure request consumes the serial number sent with - * the request, as well as serial numbers sent by all configure events - * sent on this xdg_surface prior to the configure event referenced by - * the committed serial. - * - * It is an error to issue multiple ack_configure requests referencing a - * serial from the same configure event, or to issue an ack_configure - * request referencing a serial from a configure event issued before the - * event identified by the last ack_configure request for the same - * xdg_surface. Doing so will raise an invalid_serial error. - */ -static inline void -xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, - XDG_SURFACE_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, serial); -} - -#ifndef XDG_TOPLEVEL_ERROR_ENUM -#define XDG_TOPLEVEL_ERROR_ENUM -enum xdg_toplevel_error { - /** - * provided value is not a valid variant of the resize_edge enum - */ - XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0, - /** - * invalid parent toplevel - */ - XDG_TOPLEVEL_ERROR_INVALID_PARENT = 1, - /** - * client provided an invalid min or max size - */ - XDG_TOPLEVEL_ERROR_INVALID_SIZE = 2, -}; -#endif /* XDG_TOPLEVEL_ERROR_ENUM */ - -#ifndef XDG_TOPLEVEL_RESIZE_EDGE_ENUM -#define XDG_TOPLEVEL_RESIZE_EDGE_ENUM -/** - * @ingroup iface_xdg_toplevel - * edge values for resizing - * - * These values are used to indicate which edge of a surface - * is being dragged in a resize operation. - */ -enum xdg_toplevel_resize_edge { - XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0, - XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1, - XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2, - XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4, - XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5, - XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6, - XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8, - XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9, - XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10, -}; -#endif /* XDG_TOPLEVEL_RESIZE_EDGE_ENUM */ - -#ifndef XDG_TOPLEVEL_STATE_ENUM -#define XDG_TOPLEVEL_STATE_ENUM -/** - * @ingroup iface_xdg_toplevel - * types of state on the surface - * - * The different state values used on the surface. This is designed for - * state values like maximized, fullscreen. It is paired with the - * configure event to ensure that both the client and the compositor - * setting the state can be synchronized. - * - * States set in this way are double-buffered. They will get applied on - * the next commit. - */ -enum xdg_toplevel_state { - /** - * the surface is maximized - * the surface is maximized - * - * The surface is maximized. The window geometry specified in the - * configure event must be obeyed by the client, or the - * xdg_wm_base.invalid_surface_state error is raised. - * - * The client should draw without shadow or other decoration - * outside of the window geometry. - */ - XDG_TOPLEVEL_STATE_MAXIMIZED = 1, - /** - * the surface is fullscreen - * the surface is fullscreen - * - * The surface is fullscreen. The window geometry specified in - * the configure event is a maximum; the client cannot resize - * beyond it. For a surface to cover the whole fullscreened area, - * the geometry dimensions must be obeyed by the client. For more - * details, see xdg_toplevel.set_fullscreen. - */ - XDG_TOPLEVEL_STATE_FULLSCREEN = 2, - /** - * the surface is being resized - * the surface is being resized - * - * The surface is being resized. The window geometry specified in - * the configure event is a maximum; the client cannot resize - * beyond it. Clients that have aspect ratio or cell sizing - * configuration can use a smaller size, however. - */ - XDG_TOPLEVEL_STATE_RESIZING = 3, - /** - * the surface is now activated - * the surface is now activated - * - * Client window decorations should be painted as if the window - * is active. Do not assume this means that the window actually has - * keyboard or pointer focus. - */ - XDG_TOPLEVEL_STATE_ACTIVATED = 4, - /** - * the surface’s left edge is tiled - * - * The window is currently in a tiled layout and the left edge is - * considered to be adjacent to another part of the tiling grid. - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_LEFT = 5, - /** - * the surface’s right edge is tiled - * - * The window is currently in a tiled layout and the right edge - * is considered to be adjacent to another part of the tiling grid. - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_RIGHT = 6, - /** - * the surface’s top edge is tiled - * - * The window is currently in a tiled layout and the top edge is - * considered to be adjacent to another part of the tiling grid. - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_TOP = 7, - /** - * the surface’s bottom edge is tiled - * - * The window is currently in a tiled layout and the bottom edge - * is considered to be adjacent to another part of the tiling grid. - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8, -}; -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION 2 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION 2 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_TOP_SINCE_VERSION 2 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2 -#endif /* XDG_TOPLEVEL_STATE_ENUM */ - -#ifndef XDG_TOPLEVEL_WM_CAPABILITIES_ENUM -#define XDG_TOPLEVEL_WM_CAPABILITIES_ENUM -enum xdg_toplevel_wm_capabilities { - /** - * show_window_menu is available - */ - XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU = 1, - /** - * set_maximized and unset_maximized are available - */ - XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE = 2, - /** - * set_fullscreen and unset_fullscreen are available - */ - XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN = 3, - /** - * set_minimized is available - */ - XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE = 4, -}; -#endif /* XDG_TOPLEVEL_WM_CAPABILITIES_ENUM */ - -/** - * @ingroup iface_xdg_toplevel - * @struct xdg_toplevel_listener - */ -struct xdg_toplevel_listener { - /** - * suggest a surface change - * - * This configure event asks the client to resize its toplevel - * surface or to change its state. The configured state should not - * be applied immediately. See xdg_surface.configure for details. - * - * The width and height arguments specify a hint to the window - * about how its surface should be resized in window geometry - * coordinates. See set_window_geometry. - * - * If the width or height arguments are zero, it means the client - * should decide its own window dimension. This may happen when the - * compositor needs to configure the state of the surface but - * doesn't have any information about any previous or expected - * dimension. - * - * The states listed in the event specify how the width/height - * arguments should be interpreted, and possibly how it should be - * drawn. - * - * Clients must send an ack_configure in response to this event. - * See xdg_surface.configure and xdg_surface.ack_configure for - * details. - */ - void (*configure)(void *data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states); - /** - * surface wants to be closed - * - * The close event is sent by the compositor when the user wants - * the surface to be closed. This should be equivalent to the user - * clicking the close button in client-side decorations, if your - * application has any. - * - * This is only a request that the user intends to close the - * window. The client may choose to ignore this request, or show a - * dialog to ask the user to save their data, etc. - */ - void (*close)(void *data, - struct xdg_toplevel *xdg_toplevel); - /** - * recommended window geometry bounds - * - * The configure_bounds event may be sent prior to a - * xdg_toplevel.configure event to communicate the bounds a window - * geometry size is recommended to constrain to. - * - * The passed width and height are in surface coordinate space. If - * width and height are 0, it means bounds is unknown and - * equivalent to as if no configure_bounds event was ever sent for - * this surface. - * - * The bounds can for example correspond to the size of a monitor - * excluding any panels or other shell components, so that a - * surface isn't created in a way that it cannot fit. - * - * The bounds may change at any point, and in such a case, a new - * xdg_toplevel.configure_bounds will be sent, followed by - * xdg_toplevel.configure and xdg_surface.configure. - * @since 4 - */ - void (*configure_bounds)(void *data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, - int32_t height); - /** - * compositor capabilities - * - * This event advertises the capabilities supported by the - * compositor. If a capability isn't supported, clients should hide - * or disable the UI elements that expose this functionality. For - * instance, if the compositor doesn't advertise support for - * minimized toplevels, a button triggering the set_minimized - * request should not be displayed. - * - * The compositor will ignore requests it doesn't support. For - * instance, a compositor which doesn't advertise support for - * minimized will ignore set_minimized requests. - * - * Compositors must send this event once before the first - * xdg_surface.configure event. When the capabilities change, - * compositors must send this event again and then send an - * xdg_surface.configure event. - * - * The configured state should not be applied immediately. See - * xdg_surface.configure for details. - * - * The capabilities are sent as an array of 32-bit unsigned - * integers in native endianness. - * @param capabilities array of 32-bit capabilities - * @since 5 - */ - void (*wm_capabilities)(void *data, - struct xdg_toplevel *xdg_toplevel, - struct wl_array *capabilities); -}; - -/** - * @ingroup iface_xdg_toplevel - */ -static inline int -xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel, - const struct xdg_toplevel_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel, - (void (**)(void)) listener, data); -} - -#define XDG_TOPLEVEL_DESTROY 0 -#define XDG_TOPLEVEL_SET_PARENT 1 -#define XDG_TOPLEVEL_SET_TITLE 2 -#define XDG_TOPLEVEL_SET_APP_ID 3 -#define XDG_TOPLEVEL_SHOW_WINDOW_MENU 4 -#define XDG_TOPLEVEL_MOVE 5 -#define XDG_TOPLEVEL_RESIZE 6 -#define XDG_TOPLEVEL_SET_MAX_SIZE 7 -#define XDG_TOPLEVEL_SET_MIN_SIZE 8 -#define XDG_TOPLEVEL_SET_MAXIMIZED 9 -#define XDG_TOPLEVEL_UNSET_MAXIMIZED 10 -#define XDG_TOPLEVEL_SET_FULLSCREEN 11 -#define XDG_TOPLEVEL_UNSET_FULLSCREEN 12 -#define XDG_TOPLEVEL_SET_MINIMIZED 13 - -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_CONFIGURE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_CLOSE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION 4 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION 5 - -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_PARENT_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_TITLE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_APP_ID_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SHOW_WINDOW_MENU_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_MOVE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_RESIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MAX_SIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MIN_SIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MAXIMIZED_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_UNSET_MAXIMIZED_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_FULLSCREEN_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_UNSET_FULLSCREEN_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MINIMIZED_SINCE_VERSION 1 - -/** @ingroup iface_xdg_toplevel */ -static inline void -xdg_toplevel_set_user_data(struct xdg_toplevel *xdg_toplevel, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_toplevel, user_data); -} - -/** @ingroup iface_xdg_toplevel */ -static inline void * -xdg_toplevel_get_user_data(struct xdg_toplevel *xdg_toplevel) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_toplevel); -} - -static inline uint32_t -xdg_toplevel_get_version(struct xdg_toplevel *xdg_toplevel) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_toplevel); -} - -/** - * @ingroup iface_xdg_toplevel - * - * This request destroys the role surface and unmaps the surface; - * see "Unmapping" behavior in interface section for details. - */ -static inline void -xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set the "parent" of this surface. This surface should be stacked - * above the parent surface and all other ancestor surfaces. - * - * Parent surfaces should be set on dialogs, toolboxes, or other - * "auxiliary" surfaces, so that the parent is raised when the dialog - * is raised. - * - * Setting a null parent for a child surface unsets its parent. Setting - * a null parent for a surface which currently has no parent is a no-op. - * - * Only mapped surfaces can have child surfaces. Setting a parent which - * is not mapped is equivalent to setting a null parent. If a surface - * becomes unmapped, its children's parent is set to the parent of - * the now-unmapped surface. If the now-unmapped surface has no parent, - * its children's parent is unset. If the now-unmapped surface becomes - * mapped again, its parent-child relationship is not restored. - * - * The parent toplevel must not be one of the child toplevel's - * descendants, and the parent must be different from the child toplevel, - * otherwise the invalid_parent protocol error is raised. - */ -static inline void -xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_PARENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, parent); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set a short title for the surface. - * - * This string may be used to identify the surface in a task bar, - * window list, or other user interface elements provided by the - * compositor. - * - * The string must be encoded in UTF-8. - */ -static inline void -xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, title); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set an application identifier for the surface. - * - * The app ID identifies the general class of applications to which - * the surface belongs. The compositor can use this to group multiple - * surfaces together, or to determine how to launch a new application. - * - * For D-Bus activatable applications, the app ID is used as the D-Bus - * service name. - * - * The compositor shell will try to group application surfaces together - * by their app ID. As a best practice, it is suggested to select app - * ID's that match the basename of the application's .desktop file. - * For example, "org.freedesktop.FooViewer" where the .desktop file is - * "org.freedesktop.FooViewer.desktop". - * - * Like other properties, a set_app_id request can be sent after the - * xdg_toplevel has been mapped to update the property. - * - * See the desktop-entry specification [0] for more details on - * application identifiers and how they relate to well-known D-Bus - * names and .desktop files. - * - * [0] https://standards.freedesktop.org/desktop-entry-spec/ - */ -static inline void -xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, app_id); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Clients implementing client-side decorations might want to show - * a context menu when right-clicking on the decorations, giving the - * user a menu that they can use to maximize or minimize the window. - * - * This request asks the compositor to pop up such a window menu at - * the given position, relative to the local surface coordinates of - * the parent surface. There are no guarantees as to what menu items - * the window menu contains, or even if a window menu will be drawn - * at all. - * - * This request must be used in response to some sort of user action - * like a button press, key press, or touch down event. - */ -static inline void -xdg_toplevel_show_window_menu(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SHOW_WINDOW_MENU, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, x, y); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Start an interactive, user-driven move of the surface. - * - * This request must be used in response to some sort of user action - * like a button press, key press, or touch down event. The passed - * serial is used to determine the type of interactive move (touch, - * pointer, etc). - * - * The server may ignore move requests depending on the state of - * the surface (e.g. fullscreen or maximized), or if the passed serial - * is no longer valid. - * - * If triggered, the surface will lose the focus of the device - * (wl_pointer, wl_touch, etc) used for the move. It is up to the - * compositor to visually indicate that the move is taking place, such as - * updating a pointer cursor, during the move. There is no guarantee - * that the device focus will return when the move is completed. - */ -static inline void -xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Start a user-driven, interactive resize of the surface. - * - * This request must be used in response to some sort of user action - * like a button press, key press, or touch down event. The passed - * serial is used to determine the type of interactive resize (touch, - * pointer, etc). - * - * The server may ignore resize requests depending on the state of - * the surface (e.g. fullscreen or maximized). - * - * If triggered, the client will receive configure events with the - * "resize" state enum value and the expected sizes. See the "resize" - * enum value for more details about what is required. The client - * must also acknowledge configure events using "ack_configure". After - * the resize is completed, the client will receive another "configure" - * event without the resize state. - * - * If triggered, the surface also will lose the focus of the device - * (wl_pointer, wl_touch, etc) used for the resize. It is up to the - * compositor to visually indicate that the resize is taking place, - * such as updating a pointer cursor, during the resize. There is no - * guarantee that the device focus will return when the resize is - * completed. - * - * The edges parameter specifies how the surface should be resized, and - * is one of the values of the resize_edge enum. Values not matching - * a variant of the enum will cause the invalid_resize_edge protocol error. - * The compositor may use this information to update the surface position - * for example when dragging the top left corner. The compositor may also - * use this information to adapt its behavior, e.g. choose an appropriate - * cursor image. - */ -static inline void -xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, edges); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set a maximum size for the window. - * - * The client can specify a maximum size so that the compositor does - * not try to configure the window beyond this size. - * - * The width and height arguments are in window geometry coordinates. - * See xdg_surface.set_window_geometry. - * - * Values set in this way are double-buffered. They will get applied - * on the next commit. - * - * The compositor can use this information to allow or disallow - * different states like maximize or fullscreen and draw accurate - * animations. - * - * Similarly, a tiling window manager may use this information to - * place and resize client windows in a more effective way. - * - * The client should not rely on the compositor to obey the maximum - * size. The compositor may decide to ignore the values set by the - * client and request a larger size. - * - * If never set, or a value of zero in the request, means that the - * client has no expected maximum size in the given dimension. - * As a result, a client wishing to reset the maximum size - * to an unspecified state can use zero for width and height in the - * request. - * - * Requesting a maximum size to be smaller than the minimum size of - * a surface is illegal and will result in an invalid_size error. - * - * The width and height must be greater than or equal to zero. Using - * strictly negative values for width or height will result in a - * invalid_size error. - */ -static inline void -xdg_toplevel_set_max_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MAX_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set a minimum size for the window. - * - * The client can specify a minimum size so that the compositor does - * not try to configure the window below this size. - * - * The width and height arguments are in window geometry coordinates. - * See xdg_surface.set_window_geometry. - * - * Values set in this way are double-buffered. They will get applied - * on the next commit. - * - * The compositor can use this information to allow or disallow - * different states like maximize or fullscreen and draw accurate - * animations. - * - * Similarly, a tiling window manager may use this information to - * place and resize client windows in a more effective way. - * - * The client should not rely on the compositor to obey the minimum - * size. The compositor may decide to ignore the values set by the - * client and request a smaller size. - * - * If never set, or a value of zero in the request, means that the - * client has no expected minimum size in the given dimension. - * As a result, a client wishing to reset the minimum size - * to an unspecified state can use zero for width and height in the - * request. - * - * Requesting a minimum size to be larger than the maximum size of - * a surface is illegal and will result in an invalid_size error. - * - * The width and height must be greater than or equal to zero. Using - * strictly negative values for width and height will result in a - * invalid_size error. - */ -static inline void -xdg_toplevel_set_min_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MIN_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Maximize the surface. - * - * After requesting that the surface should be maximized, the compositor - * will respond by emitting a configure event. Whether this configure - * actually sets the window maximized is subject to compositor policies. - * The client must then update its content, drawing in the configured - * state. The client must also acknowledge the configure when committing - * the new content (see ack_configure). - * - * It is up to the compositor to decide how and where to maximize the - * surface, for example which output and what region of the screen should - * be used. - * - * If the surface was already maximized, the compositor will still emit - * a configure event with the "maximized" state. - * - * If the surface is in a fullscreen state, this request has no direct - * effect. It may alter the state the surface is returned to when - * unmaximized unless overridden by the compositor. - */ -static inline void -xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Unmaximize the surface. - * - * After requesting that the surface should be unmaximized, the compositor - * will respond by emitting a configure event. Whether this actually - * un-maximizes the window is subject to compositor policies. - * If available and applicable, the compositor will include the window - * geometry dimensions the window had prior to being maximized in the - * configure event. The client must then update its content, drawing it in - * the configured state. The client must also acknowledge the configure - * when committing the new content (see ack_configure). - * - * It is up to the compositor to position the surface after it was - * unmaximized; usually the position the surface had before maximizing, if - * applicable. - * - * If the surface was already not maximized, the compositor will still - * emit a configure event without the "maximized" state. - * - * If the surface is in a fullscreen state, this request has no direct - * effect. It may alter the state the surface is returned to when - * unmaximized unless overridden by the compositor. - */ -static inline void -xdg_toplevel_unset_maximized(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_UNSET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Make the surface fullscreen. - * - * After requesting that the surface should be fullscreened, the - * compositor will respond by emitting a configure event. Whether the - * client is actually put into a fullscreen state is subject to compositor - * policies. The client must also acknowledge the configure when - * committing the new content (see ack_configure). - * - * The output passed by the request indicates the client's preference as - * to which display it should be set fullscreen on. If this value is NULL, - * it's up to the compositor to choose which display will be used to map - * this surface. - * - * If the surface doesn't cover the whole output, the compositor will - * position the surface in the center of the output and compensate with - * with border fill covering the rest of the output. The content of the - * border fill is undefined, but should be assumed to be in some way that - * attempts to blend into the surrounding area (e.g. solid black). - * - * If the fullscreened surface is not opaque, the compositor must make - * sure that other screen content not part of the same surface tree (made - * up of subsurfaces, popups or similarly coupled surfaces) are not - * visible below the fullscreened surface. - */ -static inline void -xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, output); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Make the surface no longer fullscreen. - * - * After requesting that the surface should be unfullscreened, the - * compositor will respond by emitting a configure event. - * Whether this actually removes the fullscreen state of the client is - * subject to compositor policies. - * - * Making a surface unfullscreen sets states for the surface based on the following: - * * the state(s) it may have had before becoming fullscreen - * * any state(s) decided by the compositor - * * any state(s) requested by the client while the surface was fullscreen - * - * The compositor may include the previous window geometry dimensions in - * the configure event, if applicable. - * - * The client must also acknowledge the configure when committing the new - * content (see ack_configure). - */ -static inline void -xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_UNSET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Request that the compositor minimize your surface. There is no - * way to know if the surface is currently minimized, nor is there - * any way to unset minimization on this surface. - * - * If you are looking to throttle redrawing when minimized, please - * instead use the wl_surface.frame event for this, as this will - * also work with live previews on windows in Alt-Tab, Expose or - * similar compositor features. - */ -static inline void -xdg_toplevel_set_minimized(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MINIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); -} - -#ifndef XDG_POPUP_ERROR_ENUM -#define XDG_POPUP_ERROR_ENUM -enum xdg_popup_error { - /** - * tried to grab after being mapped - */ - XDG_POPUP_ERROR_INVALID_GRAB = 0, -}; -#endif /* XDG_POPUP_ERROR_ENUM */ - -/** - * @ingroup iface_xdg_popup - * @struct xdg_popup_listener - */ -struct xdg_popup_listener { - /** - * configure the popup surface - * - * This event asks the popup surface to configure itself given - * the configuration. The configured state should not be applied - * immediately. See xdg_surface.configure for details. - * - * The x and y arguments represent the position the popup was - * placed at given the xdg_positioner rule, relative to the upper - * left corner of the window geometry of the parent surface. - * - * For version 2 or older, the configure event for an xdg_popup is - * only ever sent once for the initial configuration. Starting with - * version 3, it may be sent again if the popup is setup with an - * xdg_positioner with set_reactive requested, or in response to - * xdg_popup.reposition requests. - * @param x x position relative to parent surface window geometry - * @param y y position relative to parent surface window geometry - * @param width window geometry width - * @param height window geometry height - */ - void (*configure)(void *data, - struct xdg_popup *xdg_popup, - int32_t x, - int32_t y, - int32_t width, - int32_t height); - /** - * popup interaction is done - * - * The popup_done event is sent out when a popup is dismissed by - * the compositor. The client should destroy the xdg_popup object - * at this point. - */ - void (*popup_done)(void *data, - struct xdg_popup *xdg_popup); - /** - * signal the completion of a repositioned request - * - * The repositioned event is sent as part of a popup - * configuration sequence, together with xdg_popup.configure and - * lastly xdg_surface.configure to notify the completion of a - * reposition request. - * - * The repositioned event is to notify about the completion of a - * xdg_popup.reposition request. The token argument is the token - * passed in the xdg_popup.reposition request. - * - * Immediately after this event is emitted, xdg_popup.configure and - * xdg_surface.configure will be sent with the updated size and - * position, as well as a new configure serial. - * - * The client should optionally update the content of the popup, - * but must acknowledge the new popup configuration for the new - * position to take effect. See xdg_surface.ack_configure for - * details. - * @param token reposition request token - * @since 3 - */ - void (*repositioned)(void *data, - struct xdg_popup *xdg_popup, - uint32_t token); -}; - -/** - * @ingroup iface_xdg_popup - */ -static inline int -xdg_popup_add_listener(struct xdg_popup *xdg_popup, - const struct xdg_popup_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_popup, - (void (**)(void)) listener, data); -} - -#define XDG_POPUP_DESTROY 0 -#define XDG_POPUP_GRAB 1 -#define XDG_POPUP_REPOSITION 2 - -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_CONFIGURE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_POPUP_DONE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_REPOSITIONED_SINCE_VERSION 3 - -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_GRAB_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_REPOSITION_SINCE_VERSION 3 - -/** @ingroup iface_xdg_popup */ -static inline void -xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data); -} - -/** @ingroup iface_xdg_popup */ -static inline void * -xdg_popup_get_user_data(struct xdg_popup *xdg_popup) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup); -} - -static inline uint32_t -xdg_popup_get_version(struct xdg_popup *xdg_popup) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_popup); -} - -/** - * @ingroup iface_xdg_popup - * - * This destroys the popup. Explicitly destroying the xdg_popup - * object will also dismiss the popup, and unmap the surface. - * - * If this xdg_popup is not the "topmost" popup, the - * xdg_wm_base.not_the_topmost_popup protocol error will be sent. - */ -static inline void -xdg_popup_destroy(struct xdg_popup *xdg_popup) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, - XDG_POPUP_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), WL_MARSHAL_FLAG_DESTROY); -} - -/** - * @ingroup iface_xdg_popup - * - * This request makes the created popup take an explicit grab. An explicit - * grab will be dismissed when the user dismisses the popup, or when the - * client destroys the xdg_popup. This can be done by the user clicking - * outside the surface, using the keyboard, or even locking the screen - * through closing the lid or a timeout. - * - * If the compositor denies the grab, the popup will be immediately - * dismissed. - * - * This request must be used in response to some sort of user action like a - * button press, key press, or touch down event. The serial number of the - * event should be passed as 'serial'. - * - * The parent of a grabbing popup must either be an xdg_toplevel surface or - * another xdg_popup with an explicit grab. If the parent is another - * xdg_popup it means that the popups are nested, with this popup now being - * the topmost popup. - * - * Nested popups must be destroyed in the reverse order they were created - * in, e.g. the only popup you are allowed to destroy at all times is the - * topmost one. - * - * When compositors choose to dismiss a popup, they may dismiss every - * nested grabbing popup as well. When a compositor dismisses popups, it - * will follow the same dismissing order as required from the client. - * - * If the topmost grabbing popup is destroyed, the grab will be returned to - * the parent of the popup, if that parent previously had an explicit grab. - * - * If the parent is a grabbing popup which has already been dismissed, this - * popup will be immediately dismissed. If the parent is a popup that did - * not take an explicit grab, an error will be raised. - * - * During a popup grab, the client owning the grab will receive pointer - * and touch events for all their surfaces as normal (similar to an - * "owner-events" grab in X11 parlance), while the top most grabbing popup - * will always have keyboard focus. - */ -static inline void -xdg_popup_grab(struct xdg_popup *xdg_popup, struct wl_seat *seat, uint32_t serial) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, - XDG_POPUP_GRAB, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, seat, serial); -} - -/** - * @ingroup iface_xdg_popup - * - * Reposition an already-mapped popup. The popup will be placed given the - * details in the passed xdg_positioner object, and a - * xdg_popup.repositioned followed by xdg_popup.configure and - * xdg_surface.configure will be emitted in response. Any parameters set - * by the previous positioner will be discarded. - * - * The passed token will be sent in the corresponding - * xdg_popup.repositioned event. The new popup position will not take - * effect until the corresponding configure event is acknowledged by the - * client. See xdg_popup.repositioned for details. The token itself is - * opaque, and has no other special meaning. - * - * If multiple reposition requests are sent, the compositor may skip all - * but the last one. - * - * If the popup is repositioned in response to a configure event for its - * parent, the client should send an xdg_positioner.set_parent_configure - * and possibly an xdg_positioner.set_parent_size request to allow the - * compositor to properly constrain the popup. - * - * If the popup is repositioned together with a parent that is being - * resized, but not in response to a configure event, the client should - * send an xdg_positioner.set_parent_size request. - */ -static inline void -xdg_popup_reposition(struct xdg_popup *xdg_popup, struct xdg_positioner *positioner, uint32_t token) -{ - wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, - XDG_POPUP_REPOSITION, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, positioner, token); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/raylib/external/glfw/src/wgl_context.c b/raylib/external/glfw/src/wgl_context.c index 4a5e77a..8a23ffc 100644 --- a/raylib/external/glfw/src/wgl_context.c +++ b/raylib/external/glfw/src/wgl_context.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include @@ -115,6 +115,23 @@ static int choosePixelFormatWGL(_GLFWwindow* window, if (_glfw.wgl.EXT_colorspace) ADD_ATTRIB(WGL_COLORSPACE_EXT); } + + // NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than + // DescribePixelFormat, violating the guarantees of the extension spec + // HACK: Iterate through the minimum of both counts + + const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB; + int extensionCount; + + if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, + 1, 0, 1, &attrib, &extensionCount)) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve pixel format attribute"); + return 0; + } + + nativeCount = _glfw_min(nativeCount, extensionCount); } usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); @@ -330,6 +347,7 @@ static void swapBuffersWGL(_GLFWwindow* window) static void swapIntervalWGL(int interval) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); + assert(window != NULL); window->context.wgl.interval = interval; @@ -776,3 +794,5 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) return window->context.wgl.handle; } +#endif // _GLFW_WIN32 + diff --git a/raylib/external/glfw/src/win32_init.c b/raylib/external/glfw/src/win32_init.c index 8704150..824e383 100644 --- a/raylib/external/glfw/src/win32_init.c +++ b/raylib/external/glfw/src/win32_init.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include static const GUID _glfw_GUID_DEVINTERFACE_HID = @@ -382,7 +382,7 @@ static GLFWbool createHelperWindow(void) if (!_glfw.win32.helperWindowClass) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WIn32: Failed to register helper window class"); + "Win32: Failed to register helper window class"); return GLFW_FALSE; } @@ -430,7 +430,6 @@ static GLFWbool createHelperWindow(void) return GLFW_TRUE; } - ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -603,78 +602,78 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform) { const _GLFWplatform win32 = { - GLFW_PLATFORM_WIN32, - _glfwInitWin32, - _glfwTerminateWin32, - _glfwGetCursorPosWin32, - _glfwSetCursorPosWin32, - _glfwSetCursorModeWin32, - _glfwSetRawMouseMotionWin32, - _glfwRawMouseMotionSupportedWin32, - _glfwCreateCursorWin32, - _glfwCreateStandardCursorWin32, - _glfwDestroyCursorWin32, - _glfwSetCursorWin32, - _glfwGetScancodeNameWin32, - _glfwGetKeyScancodeWin32, - _glfwSetClipboardStringWin32, - _glfwGetClipboardStringWin32, - _glfwInitJoysticksWin32, - _glfwTerminateJoysticksWin32, - _glfwPollJoystickWin32, - _glfwGetMappingNameWin32, - _glfwUpdateGamepadGUIDWin32, - _glfwFreeMonitorWin32, - _glfwGetMonitorPosWin32, - _glfwGetMonitorContentScaleWin32, - _glfwGetMonitorWorkareaWin32, - _glfwGetVideoModesWin32, - _glfwGetVideoModeWin32, - _glfwGetGammaRampWin32, - _glfwSetGammaRampWin32, - _glfwCreateWindowWin32, - _glfwDestroyWindowWin32, - _glfwSetWindowTitleWin32, - _glfwSetWindowIconWin32, - _glfwGetWindowPosWin32, - _glfwSetWindowPosWin32, - _glfwGetWindowSizeWin32, - _glfwSetWindowSizeWin32, - _glfwSetWindowSizeLimitsWin32, - _glfwSetWindowAspectRatioWin32, - _glfwGetFramebufferSizeWin32, - _glfwGetWindowFrameSizeWin32, - _glfwGetWindowContentScaleWin32, - _glfwIconifyWindowWin32, - _glfwRestoreWindowWin32, - _glfwMaximizeWindowWin32, - _glfwShowWindowWin32, - _glfwHideWindowWin32, - _glfwRequestWindowAttentionWin32, - _glfwFocusWindowWin32, - _glfwSetWindowMonitorWin32, - _glfwWindowFocusedWin32, - _glfwWindowIconifiedWin32, - _glfwWindowVisibleWin32, - _glfwWindowMaximizedWin32, - _glfwWindowHoveredWin32, - _glfwFramebufferTransparentWin32, - _glfwGetWindowOpacityWin32, - _glfwSetWindowResizableWin32, - _glfwSetWindowDecoratedWin32, - _glfwSetWindowFloatingWin32, - _glfwSetWindowOpacityWin32, - _glfwSetWindowMousePassthroughWin32, - _glfwPollEventsWin32, - _glfwWaitEventsWin32, - _glfwWaitEventsTimeoutWin32, - _glfwPostEmptyEventWin32, - _glfwGetEGLPlatformWin32, - _glfwGetEGLNativeDisplayWin32, - _glfwGetEGLNativeWindowWin32, - _glfwGetRequiredInstanceExtensionsWin32, - _glfwGetPhysicalDevicePresentationSupportWin32, - _glfwCreateWindowSurfaceWin32, + .platformID = GLFW_PLATFORM_WIN32, + .init = _glfwInitWin32, + .terminate = _glfwTerminateWin32, + .getCursorPos = _glfwGetCursorPosWin32, + .setCursorPos = _glfwSetCursorPosWin32, + .setCursorMode = _glfwSetCursorModeWin32, + .setRawMouseMotion = _glfwSetRawMouseMotionWin32, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWin32, + .createCursor = _glfwCreateCursorWin32, + .createStandardCursor = _glfwCreateStandardCursorWin32, + .destroyCursor = _glfwDestroyCursorWin32, + .setCursor = _glfwSetCursorWin32, + .getScancodeName = _glfwGetScancodeNameWin32, + .getKeyScancode = _glfwGetKeyScancodeWin32, + .setClipboardString = _glfwSetClipboardStringWin32, + .getClipboardString = _glfwGetClipboardStringWin32, + .initJoysticks = _glfwInitJoysticksWin32, + .terminateJoysticks = _glfwTerminateJoysticksWin32, + .pollJoystick = _glfwPollJoystickWin32, + .getMappingName = _glfwGetMappingNameWin32, + .updateGamepadGUID = _glfwUpdateGamepadGUIDWin32, + .freeMonitor = _glfwFreeMonitorWin32, + .getMonitorPos = _glfwGetMonitorPosWin32, + .getMonitorContentScale = _glfwGetMonitorContentScaleWin32, + .getMonitorWorkarea = _glfwGetMonitorWorkareaWin32, + .getVideoModes = _glfwGetVideoModesWin32, + .getVideoMode = _glfwGetVideoModeWin32, + .getGammaRamp = _glfwGetGammaRampWin32, + .setGammaRamp = _glfwSetGammaRampWin32, + .createWindow = _glfwCreateWindowWin32, + .destroyWindow = _glfwDestroyWindowWin32, + .setWindowTitle = _glfwSetWindowTitleWin32, + .setWindowIcon = _glfwSetWindowIconWin32, + .getWindowPos = _glfwGetWindowPosWin32, + .setWindowPos = _glfwSetWindowPosWin32, + .getWindowSize = _glfwGetWindowSizeWin32, + .setWindowSize = _glfwSetWindowSizeWin32, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsWin32, + .setWindowAspectRatio = _glfwSetWindowAspectRatioWin32, + .getFramebufferSize = _glfwGetFramebufferSizeWin32, + .getWindowFrameSize = _glfwGetWindowFrameSizeWin32, + .getWindowContentScale = _glfwGetWindowContentScaleWin32, + .iconifyWindow = _glfwIconifyWindowWin32, + .restoreWindow = _glfwRestoreWindowWin32, + .maximizeWindow = _glfwMaximizeWindowWin32, + .showWindow = _glfwShowWindowWin32, + .hideWindow = _glfwHideWindowWin32, + .requestWindowAttention = _glfwRequestWindowAttentionWin32, + .focusWindow = _glfwFocusWindowWin32, + .setWindowMonitor = _glfwSetWindowMonitorWin32, + .windowFocused = _glfwWindowFocusedWin32, + .windowIconified = _glfwWindowIconifiedWin32, + .windowVisible = _glfwWindowVisibleWin32, + .windowMaximized = _glfwWindowMaximizedWin32, + .windowHovered = _glfwWindowHoveredWin32, + .framebufferTransparent = _glfwFramebufferTransparentWin32, + .getWindowOpacity = _glfwGetWindowOpacityWin32, + .setWindowResizable = _glfwSetWindowResizableWin32, + .setWindowDecorated = _glfwSetWindowDecoratedWin32, + .setWindowFloating = _glfwSetWindowFloatingWin32, + .setWindowOpacity = _glfwSetWindowOpacityWin32, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWin32, + .pollEvents = _glfwPollEventsWin32, + .waitEvents = _glfwWaitEventsWin32, + .waitEventsTimeout = _glfwWaitEventsTimeoutWin32, + .postEmptyEvent = _glfwPostEmptyEventWin32, + .getEGLPlatform = _glfwGetEGLPlatformWin32, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWin32, + .getEGLNativeWindow = _glfwGetEGLNativeWindowWin32, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWin32, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWin32, + .createWindowSurface = _glfwCreateWindowSurfaceWin32 }; *platform = win32; @@ -705,6 +704,9 @@ int _glfwInitWin32(void) void _glfwTerminateWin32(void) { + if (_glfw.win32.blankCursor) + DestroyIcon((HICON) _glfw.win32.blankCursor); + if (_glfw.win32.deviceNotificationHandle) UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); @@ -725,3 +727,5 @@ void _glfwTerminateWin32(void) freeLibraries(); } +#endif // _GLFW_WIN32 + diff --git a/raylib/external/glfw/src/win32_joystick.c b/raylib/external/glfw/src/win32_joystick.c index 3a28943..59389a9 100644 --- a/raylib/external/glfw/src/win32_joystick.c +++ b/raylib/external/glfw/src/win32_joystick.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include @@ -734,6 +734,13 @@ GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode) if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) dpad |= GLFW_HAT_LEFT; + // Treat invalid combinations as neither being pressed + // while preserving what data can be preserved + if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT)) + dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT); + if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN)) + dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN); + _glfwInputJoystickHat(js, 0, dpad); } @@ -756,3 +763,5 @@ void _glfwUpdateGamepadGUIDWin32(char* guid) } } +#endif // _GLFW_WIN32 + diff --git a/raylib/external/glfw/src/win32_joystick.h b/raylib/external/glfw/src/win32_joystick.h index d7c2bb6..9ab6438 100644 --- a/raylib/external/glfw/src/win32_joystick.h +++ b/raylib/external/glfw/src/win32_joystick.h @@ -27,8 +27,6 @@ #define GLFW_WIN32_JOYSTICK_STATE _GLFWjoystickWin32 win32; #define GLFW_WIN32_LIBRARY_JOYSTICK_STATE -#define GLFW_BUILD_WIN32_MAPPINGS - // Joystick element (axis, button or slider) // typedef struct _GLFWjoyobjectWin32 diff --git a/raylib/external/glfw/src/win32_module.c b/raylib/external/glfw/src/win32_module.c index 35bdd71..47c8dff 100644 --- a/raylib/external/glfw/src/win32_module.c +++ b/raylib/external/glfw/src/win32_module.c @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_MODULE) + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// @@ -47,3 +47,5 @@ GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name) return (GLFWproc) GetProcAddress((HMODULE) module, name); } +#endif // GLFW_BUILD_WIN32_MODULE + diff --git a/raylib/external/glfw/src/win32_monitor.c b/raylib/external/glfw/src/win32_monitor.c index 57b44af..87c85b9 100644 --- a/raylib/external/glfw/src/win32_monitor.c +++ b/raylib/external/glfw/src/win32_monitor.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include #include @@ -470,13 +470,17 @@ GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count) return result; } -void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode) { DEVMODEW dm; ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); - EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm); + if (!EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query display settings"); + return GLFW_FALSE; + } mode->width = dm.dmPelsWidth; mode->height = dm.dmPelsHeight; @@ -485,6 +489,8 @@ void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode) &mode->redBits, &mode->greenBits, &mode->blueBits); + + return GLFW_TRUE; } GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp) @@ -535,6 +541,13 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized"); + return NULL; + } + return monitor->win32.publicAdapterName; } @@ -542,6 +555,15 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized"); + return NULL; + } + return monitor->win32.publicDisplayName; } +#endif // _GLFW_WIN32 + diff --git a/raylib/external/glfw/src/win32_platform.h b/raylib/external/glfw/src/win32_platform.h index 82b34bb..7e3d884 100644 --- a/raylib/external/glfw/src/win32_platform.h +++ b/raylib/external/glfw/src/win32_platform.h @@ -424,6 +424,7 @@ typedef struct _GLFWwindowWin32 GLFWbool transparent; GLFWbool scaleToMonitor; GLFWbool keymenu; + GLFWbool showDefault; // Cached size used to filter out duplicate events int width, height; @@ -457,6 +458,8 @@ typedef struct _GLFWlibraryWin32 RAWINPUT* rawInput; int rawInputSize; UINT mouseTrailSize; + // The cursor handle to use to hide the cursor (NULL or a transparent cursor) + HCURSOR blankCursor; struct { HINSTANCE instance; @@ -606,7 +609,7 @@ void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos); void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count); -void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); diff --git a/raylib/external/glfw/src/win32_thread.c b/raylib/external/glfw/src/win32_thread.c index 35b8f99..212e666 100644 --- a/raylib/external/glfw/src/win32_thread.c +++ b/raylib/external/glfw/src/win32_thread.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_THREAD) + #include @@ -96,3 +96,5 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex) LeaveCriticalSection(&mutex->win32.section); } +#endif // GLFW_BUILD_WIN32_THREAD + diff --git a/raylib/external/glfw/src/win32_thread.h b/raylib/external/glfw/src/win32_thread.h index 4b5a696..dd5948f 100644 --- a/raylib/external/glfw/src/win32_thread.h +++ b/raylib/external/glfw/src/win32_thread.h @@ -25,6 +25,11 @@ // //======================================================================== +// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for +// example to allow applications to correctly declare a GL_KHR_debug callback) +// but windows.h assumes no one will define APIENTRY before it does +#undef APIENTRY + #include #define GLFW_WIN32_TLS_STATE _GLFWtlsWin32 win32; diff --git a/raylib/external/glfw/src/win32_time.c b/raylib/external/glfw/src/win32_time.c index a1c6414..a38e15d 100644 --- a/raylib/external/glfw/src/win32_time.c +++ b/raylib/external/glfw/src/win32_time.c @@ -24,11 +24,10 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_TIMER) ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -51,3 +50,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void) return _glfw.timer.win32.frequency; } +#endif // GLFW_BUILD_WIN32_TIMER + diff --git a/raylib/external/glfw/src/win32_time.h b/raylib/external/glfw/src/win32_time.h index da5afa4..ef57a5a 100644 --- a/raylib/external/glfw/src/win32_time.h +++ b/raylib/external/glfw/src/win32_time.h @@ -25,6 +25,11 @@ // //======================================================================== +// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for +// example to allow applications to correctly declare a GL_KHR_debug callback) +// but windows.h assumes no one will define APIENTRY before it does +#undef APIENTRY + #include #define GLFW_WIN32_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32; diff --git a/raylib/external/glfw/src/win32_window.c b/raylib/external/glfw/src/win32_window.c index 69fb642..e6a9496 100644 --- a/raylib/external/glfw/src/win32_window.c +++ b/raylib/external/glfw/src/win32_window.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include #include @@ -184,53 +184,38 @@ static HICON createIcon(const GLFWimage* image, int xhot, int yhot, GLFWbool ico return handle; } -// Translate content area size to full window size according to styles and DPI -// -static void getFullWindowSize(DWORD style, DWORD exStyle, - int contentWidth, int contentHeight, - int* fullWidth, int* fullHeight, - UINT dpi) -{ - RECT rect = { 0, 0, contentWidth, contentHeight }; - - if (_glfwIsWindows10Version1607OrGreaterWin32()) - AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi); - else - AdjustWindowRectEx(&rect, style, FALSE, exStyle); - - *fullWidth = rect.right - rect.left; - *fullHeight = rect.bottom - rect.top; -} - // Enforce the content area aspect ratio based on which edge is being dragged // static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) { - int xoff, yoff; - UINT dpi = USER_DEFAULT_SCREEN_DPI; + RECT frame = {0}; const float ratio = (float) window->numer / (float) window->denom; + const DWORD style = getWindowStyle(window); + const DWORD exStyle = getWindowExStyle(window); if (_glfwIsWindows10Version1607OrGreaterWin32()) - dpi = GetDpiForWindow(window->win32.handle); - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, dpi); + { + AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle, + GetDpiForWindow(window->win32.handle)); + } + else + AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) { - area->bottom = area->top + yoff + - (int) ((area->right - area->left - xoff) / ratio); + area->bottom = area->top + (frame.bottom - frame.top) + + (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) { - area->top = area->bottom - yoff - - (int) ((area->right - area->left - xoff) / ratio); + area->top = area->bottom - (frame.bottom - frame.top) - + (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) { - area->right = area->left + xoff + - (int) ((area->bottom - area->top - yoff) * ratio); + area->right = area->left + (frame.right - frame.left) + + (int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio); } } @@ -247,7 +232,12 @@ static void updateCursorImage(_GLFWwindow* window) SetCursor(LoadCursorW(NULL, IDC_ARROW)); } else - SetCursor(NULL); + { + // NOTE: Via Remote Desktop, setting the cursor to NULL does not hide it. + // HACK: When running locally, it is set to NULL, but when connected via Remote + // Desktop, this is a transparent cursor. + SetCursor(_glfw.win32.blankCursor); + } } // Sets the cursor clip rect to the window content area @@ -939,8 +929,28 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l data = _glfw.win32.rawInput; if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) { - dx = data->data.mouse.lLastX - window->win32.lastCursorPosX; - dy = data->data.mouse.lLastY - window->win32.lastCursorPosY; + POINT pos = {0}; + int width, height; + + if (data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) + { + pos.x += GetSystemMetrics(SM_XVIRTUALSCREEN); + pos.y += GetSystemMetrics(SM_YVIRTUALSCREEN); + width = GetSystemMetrics(SM_CXVIRTUALSCREEN); + height = GetSystemMetrics(SM_CYVIRTUALSCREEN); + } + else + { + width = GetSystemMetrics(SM_CXSCREEN); + height = GetSystemMetrics(SM_CYSCREEN); + } + + pos.x += (int) ((data->data.mouse.lLastX / 65535.f) * width); + pos.y += (int) ((data->data.mouse.lLastY / 65535.f) * height); + ScreenToClient(window->win32.handle, &pos); + + dx = pos.x - window->win32.lastCursorPosX; + dy = pos.y - window->win32.lastCursorPosY; } else { @@ -1080,31 +1090,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l case WM_GETMINMAXINFO: { - int xoff, yoff; - UINT dpi = USER_DEFAULT_SCREEN_DPI; + RECT frame = {0}; MINMAXINFO* mmi = (MINMAXINFO*) lParam; + const DWORD style = getWindowStyle(window); + const DWORD exStyle = getWindowExStyle(window); if (window->monitor) break; if (_glfwIsWindows10Version1607OrGreaterWin32()) - dpi = GetDpiForWindow(window->win32.handle); - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, dpi); + { + AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle, + GetDpiForWindow(window->win32.handle)); + } + else + AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) { - mmi->ptMinTrackSize.x = window->minwidth + xoff; - mmi->ptMinTrackSize.y = window->minheight + yoff; + mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left; + mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top; } if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) { - mmi->ptMaxTrackSize.x = window->maxwidth + xoff; - mmi->ptMaxTrackSize.y = window->maxheight + yoff; + mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left; + mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top; } if (!window->decorated) @@ -1263,7 +1276,7 @@ static int createNativeWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { - int xpos, ypos, fullWidth, fullHeight; + int frameX, frameY, frameWidth, frameHeight; WCHAR* wideTitle; DWORD style = getWindowStyle(window); DWORD exStyle = getWindowExStyle(window); @@ -1301,6 +1314,34 @@ static int createNativeWindow(_GLFWwindow* window, } } + if (GetSystemMetrics(SM_REMOTESESSION)) + { + // NOTE: On Remote Desktop, setting the cursor to NULL does not hide it + // HACK: Create a transparent cursor and always set that instead of NULL + // When not on Remote Desktop, this handle is NULL and normal hiding is used + if (!_glfw.win32.blankCursor) + { + const int cursorWidth = GetSystemMetrics(SM_CXCURSOR); + const int cursorHeight = GetSystemMetrics(SM_CYCURSOR); + + unsigned char* cursorPixels = _glfw_calloc(cursorWidth * cursorHeight, 4); + if (!cursorPixels) + return GLFW_FALSE; + + // NOTE: Windows checks whether the image is fully transparent and if so + // just ignores the alpha channel and makes the whole cursor opaque + // HACK: Make one pixel slightly less transparent + cursorPixels[3] = 1; + + const GLFWimage cursorImage = { cursorWidth, cursorHeight, cursorPixels }; + _glfw.win32.blankCursor = createIcon(&cursorImage, 0, 0, FALSE); + _glfw_free(cursorPixels); + + if (!_glfw.win32.blankCursor) + return GLFW_FALSE; + } + } + if (window->monitor) { MONITORINFO mi = { sizeof(mi) }; @@ -1309,10 +1350,10 @@ static int createNativeWindow(_GLFWwindow* window, // NOTE: This window placement is temporary and approximate, as the // correct position and size cannot be known until the monitor // video mode has been picked in _glfwSetVideoModeWin32 - xpos = mi.rcMonitor.left; - ypos = mi.rcMonitor.top; - fullWidth = mi.rcMonitor.right - mi.rcMonitor.left; - fullHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; + frameX = mi.rcMonitor.left; + frameY = mi.rcMonitor.top; + frameWidth = mi.rcMonitor.right - mi.rcMonitor.left; + frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else { @@ -1326,17 +1367,17 @@ static int createNativeWindow(_GLFWwindow* window, if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION) { - xpos = CW_USEDEFAULT; - ypos = CW_USEDEFAULT; + frameX = CW_USEDEFAULT; + frameY = CW_USEDEFAULT; } else { - xpos = wndconfig->xpos + rect.left; - ypos = wndconfig->ypos + rect.top; + frameX = wndconfig->xpos + rect.left; + frameY = wndconfig->ypos + rect.top; } - fullWidth = rect.right - rect.left; - fullHeight = rect.bottom - rect.top; + frameWidth = rect.right - rect.left; + frameHeight = rect.bottom - rect.top; } wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title); @@ -1347,8 +1388,8 @@ static int createNativeWindow(_GLFWwindow* window, MAKEINTATOM(_glfw.win32.mainWindowClass), wideTitle, style, - xpos, ypos, - fullWidth, fullHeight, + frameX, frameY, + frameWidth, frameHeight, NULL, // No parent window NULL, // No window menu _glfw.win32.instance, @@ -1377,6 +1418,7 @@ static int createNativeWindow(_GLFWwindow* window, window->win32.scaleToMonitor = wndconfig->scaleToMonitor; window->win32.keymenu = wndconfig->win32.keymenu; + window->win32.showDefault = wndconfig->win32.showDefault; if (!window->monitor) { @@ -1759,7 +1801,23 @@ void _glfwMaximizeWindowWin32(_GLFWwindow* window) void _glfwShowWindowWin32(_GLFWwindow* window) { - ShowWindow(window->win32.handle, SW_SHOWNA); + int showCommand = SW_SHOWNA; + + if (window->win32.showDefault) + { + // NOTE: GLFW windows currently do not seem to match the Windows 10 definition of + // a main window, so even SW_SHOWDEFAULT does nothing + // This definition is undocumented and can change (source: Raymond Chen) + // HACK: Apply the STARTUPINFO show command manually if available + STARTUPINFOW si = { sizeof(si) }; + GetStartupInfoW(&si); + if (si.dwFlags & STARTF_USESHOWWINDOW) + showCommand = si.wShowWindow; + + window->win32.showDefault = GLFW_FALSE; + } + + ShowWindow(window->win32.handle, showCommand); } void _glfwHideWindowWin32(_GLFWwindow* window) @@ -2114,6 +2172,7 @@ void _glfwPollEventsWin32(void) // NOTE: Re-center the cursor only if it has moved since the last call, // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE + // The re-center is required in order to prevent the mouse cursor stopping at the edges of the screen. if (window->win32.lastCursorPosX != width / 2 || window->win32.lastCursorPosY != height / 2) { @@ -2131,7 +2190,7 @@ void _glfwWaitEventsWin32(void) void _glfwWaitEventsTimeoutWin32(double timeout) { - MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS); + MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLINPUT); _glfwPollEventsWin32(); } @@ -2209,14 +2268,17 @@ void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode) const char* _glfwGetScancodeNameWin32(int scancode) { - if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) || - _glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > (KF_EXTENDED | 0xff)) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } - return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]]; + const int key = _glfw.win32.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; + + return _glfw.win32.keynames[key]; } int _glfwGetKeyScancodeWin32(int key) @@ -2303,7 +2365,7 @@ void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwSetClipboardStringWin32(const char* string) { - int characterCount; + int characterCount, tries = 0; HANDLE object; WCHAR* buffer; @@ -2331,12 +2393,20 @@ void _glfwSetClipboardStringWin32(const char* string) MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount); GlobalUnlock(object); - if (!OpenClipboard(_glfw.win32.helperWindowHandle)) + // NOTE: Retry clipboard opening a few times as some other application may have it + // open and also the Windows Clipboard History reads it after each update + while (!OpenClipboard(_glfw.win32.helperWindowHandle)) { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to open clipboard"); - GlobalFree(object); - return; + Sleep(1); + tries++; + + if (tries == 3) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to open clipboard"); + GlobalFree(object); + return; + } } EmptyClipboard(); @@ -2348,12 +2418,21 @@ const char* _glfwGetClipboardStringWin32(void) { HANDLE object; WCHAR* buffer; + int tries = 0; - if (!OpenClipboard(_glfw.win32.helperWindowHandle)) + // NOTE: Retry clipboard opening a few times as some other application may have it + // open and also the Windows Clipboard History reads it after each update + while (!OpenClipboard(_glfw.win32.helperWindowHandle)) { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to open clipboard"); - return NULL; + Sleep(1); + tries++; + + if (tries == 3) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to open clipboard"); + return NULL; + } } object = GetClipboardData(CF_UNICODETEXT); @@ -2510,3 +2589,5 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) return window->win32.handle; } +#endif // _GLFW_WIN32 + diff --git a/raylib/external/glfw/src/window.c b/raylib/external/glfw/src/window.c index 1c8519f..1463d16 100644 --- a/raylib/external/glfw/src/window.c +++ b/raylib/external/glfw/src/window.c @@ -25,8 +25,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -244,6 +242,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->maxheight = GLFW_DONT_CARE; window->numer = GLFW_DONT_CARE; window->denom = GLFW_DONT_CARE; + window->title = _glfw_strdup(title); if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig)) { @@ -276,6 +275,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.window.focusOnShow = GLFW_TRUE; _glfw.hints.window.xpos = GLFW_ANY_POSITION; _glfw.hints.window.ypos = GLFW_ANY_POSITION; + _glfw.hints.window.scaleFramebuffer = GLFW_TRUE; // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // double buffered @@ -290,9 +290,6 @@ void glfwDefaultWindowHints(void) // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; - - // The default is to use full Retina resolution framebuffers - _glfw.hints.window.ns.retina = GLFW_TRUE; } GLFWAPI void glfwWindowHint(int hint, int value) @@ -376,18 +373,22 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_POSITION_Y: _glfw.hints.window.ypos = value; return; - case GLFW_COCOA_RETINA_FRAMEBUFFER: - _glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE; - return; case GLFW_WIN32_KEYBOARD_MENU: _glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_WIN32_SHOWDEFAULT: + _glfw.hints.window.win32.showDefault = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_COCOA_GRAPHICS_SWITCHING: _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_SCALE_TO_MONITOR: _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_SCALE_FRAMEBUFFER: + case GLFW_COCOA_RETINA_FRAMEBUFFER: + _glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_CENTER_CURSOR: _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; return; @@ -494,6 +495,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) *prev = window->next; } + _glfw_free(window->title); _glfw_free(window); } @@ -515,6 +517,16 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) window->shouldClose = value; } +GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + return window->title; +} + GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) { _GLFWwindow* window = (_GLFWwindow*) handle; @@ -522,7 +534,12 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) assert(title != NULL); _GLFW_REQUIRE_INIT(); + + char* prev = window->title; + window->title = _glfw_strdup(title); + _glfw.platform.setWindowTitle(window, title); + _glfw_free(prev); } GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, @@ -742,7 +759,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(1.f); + _GLFW_REQUIRE_INIT_OR_RETURN(0.f); return _glfw.platform.getWindowOpacity(window); } diff --git a/raylib/external/glfw/src/wl_init.c b/raylib/external/glfw/src/wl_init.c index 8cbcc6e..3aff476 100644 --- a/raylib/external/glfw/src/wl_init.c +++ b/raylib/external/glfw/src/wl_init.c @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_WAYLAND) + #include #include #include @@ -38,14 +38,17 @@ #include #include #include +#include #include "wayland-client-protocol.h" -#include "wayland-xdg-shell-client-protocol.h" -#include "wayland-xdg-decoration-client-protocol.h" -#include "wayland-viewporter-client-protocol.h" -#include "wayland-relative-pointer-unstable-v1-client-protocol.h" -#include "wayland-pointer-constraints-unstable-v1-client-protocol.h" -#include "wayland-idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" +#include "pointer-constraints-unstable-v1-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" // NOTE: Versions of wayland-scanner prior to 1.17.91 named every global array of // wl_interface pointers 'types', making it impossible to combine several unmodified @@ -57,27 +60,35 @@ #undef types #define types _glfw_xdg_shell_types -#include "wayland-xdg-shell-client-protocol-code.h" +#include "xdg-shell-client-protocol-code.h" #undef types #define types _glfw_xdg_decoration_types -#include "wayland-xdg-decoration-client-protocol-code.h" +#include "xdg-decoration-unstable-v1-client-protocol-code.h" #undef types #define types _glfw_viewporter_types -#include "wayland-viewporter-client-protocol-code.h" +#include "viewporter-client-protocol-code.h" #undef types #define types _glfw_relative_pointer_types -#include "wayland-relative-pointer-unstable-v1-client-protocol-code.h" +#include "relative-pointer-unstable-v1-client-protocol-code.h" #undef types #define types _glfw_pointer_constraints_types -#include "wayland-pointer-constraints-unstable-v1-client-protocol-code.h" +#include "pointer-constraints-unstable-v1-client-protocol-code.h" +#undef types + +#define types _glfw_fractional_scale_types +#include "fractional-scale-v1-client-protocol-code.h" +#undef types + +#define types _glfw_xdg_activation_types +#include "xdg-activation-v1-client-protocol-code.h" #undef types #define types _glfw_idle_inhibit_types -#include "wayland-idle-inhibit-unstable-v1-client-protocol-code.h" +#include "idle-inhibit-unstable-v1-client-protocol-code.h" #undef types static void wmBaseHandlePing(void* userData, @@ -100,10 +111,9 @@ static void registryHandleGlobal(void* userData, { if (strcmp(interface, "wl_compositor") == 0) { - _glfw.wl.compositorVersion = _glfw_min(3, version); _glfw.wl.compositor = wl_registry_bind(registry, name, &wl_compositor_interface, - _glfw.wl.compositorVersion); + _glfw_min(3, version)); } else if (strcmp(interface, "wl_subcompositor") == 0) { @@ -123,10 +133,9 @@ static void registryHandleGlobal(void* userData, { if (!_glfw.wl.seat) { - _glfw.wl.seatVersion = _glfw_min(4, version); _glfw.wl.seat = wl_registry_bind(registry, name, &wl_seat_interface, - _glfw.wl.seatVersion); + _glfw_min(4, version)); _glfwAddSeatListenerWayland(_glfw.wl.seat); } } @@ -178,6 +187,20 @@ static void registryHandleGlobal(void* userData, &zwp_idle_inhibit_manager_v1_interface, 1); } + else if (strcmp(interface, "xdg_activation_v1") == 0) + { + _glfw.wl.activationManager = + wl_registry_bind(registry, name, + &xdg_activation_v1_interface, + 1); + } + else if (strcmp(interface, "wp_fractional_scale_manager_v1") == 0) + { + _glfw.wl.fractionalScaleManager = + wl_registry_bind(registry, name, + &wp_fractional_scale_manager_v1_interface, + 1); + } } static void registryHandleGlobalRemove(void* userData, @@ -202,6 +225,36 @@ static const struct wl_registry_listener registryListener = registryHandleGlobalRemove }; +void libdecorHandleError(struct libdecor* context, + enum libdecor_error error, + const char* message) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: libdecor error %u: %s", + error, message); +} + +static const struct libdecor_interface libdecorInterface = +{ + libdecorHandleError +}; + +static void libdecorReadyCallback(void* userData, + struct wl_callback* callback, + uint32_t time) +{ + _glfw.wl.libdecor.ready = GLFW_TRUE; + + assert(_glfw.wl.libdecor.callback == callback); + wl_callback_destroy(_glfw.wl.libdecor.callback); + _glfw.wl.libdecor.callback = NULL; +} + +static const struct wl_callback_listener libdecorReadyListener = +{ + libdecorReadyCallback +}; + // Create key code translation tables // static void createKeyTables(void) @@ -337,7 +390,7 @@ static void createKeyTables(void) static GLFWbool loadCursorTheme(void) { - int cursorSize = 32; + int cursorSize = 16; const char* sizeString = getenv("XCURSOR_SIZE"); if (sizeString) @@ -376,86 +429,86 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform) { const _GLFWplatform wayland = { - GLFW_PLATFORM_WAYLAND, - _glfwInitWayland, - _glfwTerminateWayland, - _glfwGetCursorPosWayland, - _glfwSetCursorPosWayland, - _glfwSetCursorModeWayland, - _glfwSetRawMouseMotionWayland, - _glfwRawMouseMotionSupportedWayland, - _glfwCreateCursorWayland, - _glfwCreateStandardCursorWayland, - _glfwDestroyCursorWayland, - _glfwSetCursorWayland, - _glfwGetScancodeNameWayland, - _glfwGetKeyScancodeWayland, - _glfwSetClipboardStringWayland, - _glfwGetClipboardStringWayland, -#if defined(__linux__) - _glfwInitJoysticksLinux, - _glfwTerminateJoysticksLinux, - _glfwPollJoystickLinux, - _glfwGetMappingNameLinux, - _glfwUpdateGamepadGUIDLinux, + .platformID = GLFW_PLATFORM_WAYLAND, + .init = _glfwInitWayland, + .terminate = _glfwTerminateWayland, + .getCursorPos = _glfwGetCursorPosWayland, + .setCursorPos = _glfwSetCursorPosWayland, + .setCursorMode = _glfwSetCursorModeWayland, + .setRawMouseMotion = _glfwSetRawMouseMotionWayland, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWayland, + .createCursor = _glfwCreateCursorWayland, + .createStandardCursor = _glfwCreateStandardCursorWayland, + .destroyCursor = _glfwDestroyCursorWayland, + .setCursor = _glfwSetCursorWayland, + .getScancodeName = _glfwGetScancodeNameWayland, + .getKeyScancode = _glfwGetKeyScancodeWayland, + .setClipboardString = _glfwSetClipboardStringWayland, + .getClipboardString = _glfwGetClipboardStringWayland, +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + .initJoysticks = _glfwInitJoysticksLinux, + .terminateJoysticks = _glfwTerminateJoysticksLinux, + .pollJoystick = _glfwPollJoystickLinux, + .getMappingName = _glfwGetMappingNameLinux, + .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, #else - _glfwInitJoysticksNull, - _glfwTerminateJoysticksNull, - _glfwPollJoystickNull, - _glfwGetMappingNameNull, - _glfwUpdateGamepadGUIDNull, + .initJoysticks = _glfwInitJoysticksNull, + .terminateJoysticks = _glfwTerminateJoysticksNull, + .pollJoystick = _glfwPollJoystickNull, + .getMappingName = _glfwGetMappingNameNull, + .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, #endif - _glfwFreeMonitorWayland, - _glfwGetMonitorPosWayland, - _glfwGetMonitorContentScaleWayland, - _glfwGetMonitorWorkareaWayland, - _glfwGetVideoModesWayland, - _glfwGetVideoModeWayland, - _glfwGetGammaRampWayland, - _glfwSetGammaRampWayland, - _glfwCreateWindowWayland, - _glfwDestroyWindowWayland, - _glfwSetWindowTitleWayland, - _glfwSetWindowIconWayland, - _glfwGetWindowPosWayland, - _glfwSetWindowPosWayland, - _glfwGetWindowSizeWayland, - _glfwSetWindowSizeWayland, - _glfwSetWindowSizeLimitsWayland, - _glfwSetWindowAspectRatioWayland, - _glfwGetFramebufferSizeWayland, - _glfwGetWindowFrameSizeWayland, - _glfwGetWindowContentScaleWayland, - _glfwIconifyWindowWayland, - _glfwRestoreWindowWayland, - _glfwMaximizeWindowWayland, - _glfwShowWindowWayland, - _glfwHideWindowWayland, - _glfwRequestWindowAttentionWayland, - _glfwFocusWindowWayland, - _glfwSetWindowMonitorWayland, - _glfwWindowFocusedWayland, - _glfwWindowIconifiedWayland, - _glfwWindowVisibleWayland, - _glfwWindowMaximizedWayland, - _glfwWindowHoveredWayland, - _glfwFramebufferTransparentWayland, - _glfwGetWindowOpacityWayland, - _glfwSetWindowResizableWayland, - _glfwSetWindowDecoratedWayland, - _glfwSetWindowFloatingWayland, - _glfwSetWindowOpacityWayland, - _glfwSetWindowMousePassthroughWayland, - _glfwPollEventsWayland, - _glfwWaitEventsWayland, - _glfwWaitEventsTimeoutWayland, - _glfwPostEmptyEventWayland, - _glfwGetEGLPlatformWayland, - _glfwGetEGLNativeDisplayWayland, - _glfwGetEGLNativeWindowWayland, - _glfwGetRequiredInstanceExtensionsWayland, - _glfwGetPhysicalDevicePresentationSupportWayland, - _glfwCreateWindowSurfaceWayland, + .freeMonitor = _glfwFreeMonitorWayland, + .getMonitorPos = _glfwGetMonitorPosWayland, + .getMonitorContentScale = _glfwGetMonitorContentScaleWayland, + .getMonitorWorkarea = _glfwGetMonitorWorkareaWayland, + .getVideoModes = _glfwGetVideoModesWayland, + .getVideoMode = _glfwGetVideoModeWayland, + .getGammaRamp = _glfwGetGammaRampWayland, + .setGammaRamp = _glfwSetGammaRampWayland, + .createWindow = _glfwCreateWindowWayland, + .destroyWindow = _glfwDestroyWindowWayland, + .setWindowTitle = _glfwSetWindowTitleWayland, + .setWindowIcon = _glfwSetWindowIconWayland, + .getWindowPos = _glfwGetWindowPosWayland, + .setWindowPos = _glfwSetWindowPosWayland, + .getWindowSize = _glfwGetWindowSizeWayland, + .setWindowSize = _glfwSetWindowSizeWayland, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsWayland, + .setWindowAspectRatio = _glfwSetWindowAspectRatioWayland, + .getFramebufferSize = _glfwGetFramebufferSizeWayland, + .getWindowFrameSize = _glfwGetWindowFrameSizeWayland, + .getWindowContentScale = _glfwGetWindowContentScaleWayland, + .iconifyWindow = _glfwIconifyWindowWayland, + .restoreWindow = _glfwRestoreWindowWayland, + .maximizeWindow = _glfwMaximizeWindowWayland, + .showWindow = _glfwShowWindowWayland, + .hideWindow = _glfwHideWindowWayland, + .requestWindowAttention = _glfwRequestWindowAttentionWayland, + .focusWindow = _glfwFocusWindowWayland, + .setWindowMonitor = _glfwSetWindowMonitorWayland, + .windowFocused = _glfwWindowFocusedWayland, + .windowIconified = _glfwWindowIconifiedWayland, + .windowVisible = _glfwWindowVisibleWayland, + .windowMaximized = _glfwWindowMaximizedWayland, + .windowHovered = _glfwWindowHoveredWayland, + .framebufferTransparent = _glfwFramebufferTransparentWayland, + .getWindowOpacity = _glfwGetWindowOpacityWayland, + .setWindowResizable = _glfwSetWindowResizableWayland, + .setWindowDecorated = _glfwSetWindowDecoratedWayland, + .setWindowFloating = _glfwSetWindowFloatingWayland, + .setWindowOpacity = _glfwSetWindowOpacityWayland, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWayland, + .pollEvents = _glfwPollEventsWayland, + .waitEvents = _glfwWaitEventsWayland, + .waitEventsTimeout = _glfwWaitEventsTimeoutWayland, + .postEmptyEvent = _glfwPostEmptyEventWayland, + .getEGLPlatform = _glfwGetEGLPlatformWayland, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWayland, + .getEGLNativeWindow = _glfwGetEGLNativeWindowWayland, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWayland, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWayland, + .createWindowSurface = _glfwCreateWindowSurfaceWayland }; void* module = _glfwPlatformLoadModule("libwayland-client.so.0"); @@ -507,6 +560,8 @@ int _glfwInitWayland(void) _glfw.wl.keyRepeatTimerfd = -1; _glfw.wl.cursorTimerfd = -1; + _glfw.wl.tag = glfwGetVersionString(); + _glfw.wl.client.display_flush = (PFN_wl_display_flush) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush"); _glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read) @@ -537,6 +592,10 @@ int _glfwInitWayland(void) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data"); _glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data"); + _glfw.wl.client.proxy_get_tag = (PFN_wl_proxy_get_tag) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_tag"); + _glfw.wl.client.proxy_set_tag = (PFN_wl_proxy_set_tag) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_tag"); _glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version"); _glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags) @@ -556,7 +615,9 @@ int _glfwInitWayland(void) !_glfw.wl.client.proxy_marshal_constructor || !_glfw.wl.client.proxy_marshal_constructor_versioned || !_glfw.wl.client.proxy_get_user_data || - !_glfw.wl.client.proxy_set_user_data) + !_glfw.wl.client.proxy_set_user_data || + !_glfw.wl.client.proxy_get_tag || + !_glfw.wl.client.proxy_set_tag) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to load libwayland-client entry point"); @@ -644,6 +705,119 @@ int _glfwInitWayland(void) _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym"); + if (!_glfw.wl.xkb.context_new || + !_glfw.wl.xkb.context_unref || + !_glfw.wl.xkb.keymap_new_from_string || + !_glfw.wl.xkb.keymap_unref || + !_glfw.wl.xkb.keymap_mod_get_index || + !_glfw.wl.xkb.keymap_key_repeats || + !_glfw.wl.xkb.keymap_key_get_syms_by_level || + !_glfw.wl.xkb.state_new || + !_glfw.wl.xkb.state_unref || + !_glfw.wl.xkb.state_key_get_syms || + !_glfw.wl.xkb.state_update_mask || + !_glfw.wl.xkb.state_key_get_layout || + !_glfw.wl.xkb.state_mod_index_is_active || + !_glfw.wl.xkb.compose_table_new_from_locale || + !_glfw.wl.xkb.compose_table_unref || + !_glfw.wl.xkb.compose_state_new || + !_glfw.wl.xkb.compose_state_unref || + !_glfw.wl.xkb.compose_state_feed || + !_glfw.wl.xkb.compose_state_get_status || + !_glfw.wl.xkb.compose_state_get_one_sym) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load all entry points from libxkbcommon"); + return GLFW_FALSE; + } + + if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR) + _glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0"); + + if (_glfw.wl.libdecor.handle) + { + _glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_new"); + _glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_unref"); + _glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_get_fd"); + _glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_dispatch"); + _glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_decorate"); + _glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unref"); + _glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id"); + _glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_title"); + _glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized"); + _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen"); + _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen"); + _glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_map"); + _glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_commit"); + _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size"); + _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size"); + _glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized"); + _glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized"); + _glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities"); + _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities"); + _glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility"); + _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel"); + _glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size"); + _glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state"); + _glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_new"); + _glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_free"); + + if (!_glfw.wl.libdecor.libdecor_new_ || + !_glfw.wl.libdecor.libdecor_unref_ || + !_glfw.wl.libdecor.libdecor_get_fd_ || + !_glfw.wl.libdecor.libdecor_dispatch_ || + !_glfw.wl.libdecor.libdecor_decorate_ || + !_glfw.wl.libdecor.libdecor_frame_unref_ || + !_glfw.wl.libdecor.libdecor_frame_set_app_id_ || + !_glfw.wl.libdecor.libdecor_frame_set_title_ || + !_glfw.wl.libdecor.libdecor_frame_set_minimized_ || + !_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ || + !_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ || + !_glfw.wl.libdecor.libdecor_frame_map_ || + !_glfw.wl.libdecor.libdecor_frame_commit_ || + !_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ || + !_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ || + !_glfw.wl.libdecor.libdecor_frame_set_maximized_ || + !_glfw.wl.libdecor.libdecor_frame_unset_maximized_ || + !_glfw.wl.libdecor.libdecor_frame_set_capabilities_ || + !_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ || + !_glfw.wl.libdecor.libdecor_frame_set_visibility_ || + !_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ || + !_glfw.wl.libdecor.libdecor_configuration_get_content_size_ || + !_glfw.wl.libdecor.libdecor_configuration_get_window_state_ || + !_glfw.wl.libdecor.libdecor_state_new_ || + !_glfw.wl.libdecor.libdecor_state_free_) + { + _glfwPlatformFreeModule(_glfw.wl.libdecor.handle); + memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor)); + } + } + _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); @@ -663,13 +837,27 @@ int _glfwInitWayland(void) // Sync so we got all initial output events wl_display_roundtrip(_glfw.wl.display); -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION - if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + if (_glfw.wl.libdecor.handle) + { + _glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface); + if (_glfw.wl.libdecor.context) + { + // Perform an initial dispatch and flush to get the init started + libdecor_dispatch(_glfw.wl.libdecor.context, 0); + + // Create sync point to "know" when libdecor is ready for use + _glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display); + wl_callback_add_listener(_glfw.wl.libdecor.callback, + &libdecorReadyListener, + NULL); + } + } + + if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { _glfw.wl.keyRepeatTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); } -#endif if (!_glfw.wl.wmBase) { @@ -704,6 +892,22 @@ void _glfwTerminateWayland(void) _glfwTerminateEGL(); _glfwTerminateOSMesa(); + if (_glfw.wl.libdecor.context) + { + // Allow libdecor to finish receiving all its requested globals + // and ensure the associated sync callback object is destroyed + while (!_glfw.wl.libdecor.ready) + _glfwWaitEventsWayland(); + + libdecor_unref(_glfw.wl.libdecor.context); + } + + if (_glfw.wl.libdecor.handle) + { + _glfwPlatformFreeModule(_glfw.wl.libdecor.handle); + _glfw.wl.libdecor.handle = NULL; + } + if (_glfw.wl.egl.handle) { _glfwPlatformFreeModule(_glfw.wl.egl.handle); @@ -775,6 +979,10 @@ void _glfwTerminateWayland(void) zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); if (_glfw.wl.idleInhibitManager) zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager); + if (_glfw.wl.activationManager) + xdg_activation_v1_destroy(_glfw.wl.activationManager); + if (_glfw.wl.fractionalScaleManager) + wp_fractional_scale_manager_v1_destroy(_glfw.wl.fractionalScaleManager); if (_glfw.wl.registry) wl_registry_destroy(_glfw.wl.registry); if (_glfw.wl.display) @@ -791,3 +999,5 @@ void _glfwTerminateWayland(void) _glfw_free(_glfw.wl.clipboardString); } +#endif // _GLFW_WAYLAND + diff --git a/raylib/external/glfw/src/wl_monitor.c b/raylib/external/glfw/src/wl_monitor.c index 336681f..df30313 100644 --- a/raylib/external/glfw/src/wl_monitor.c +++ b/raylib/external/glfw/src/wl_monitor.c @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_WAYLAND) + #include #include #include @@ -116,19 +116,18 @@ static void outputHandleScale(void* userData, for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) { - for (int i = 0; i < window->wl.monitorsCount; i++) + for (size_t i = 0; i < window->wl.outputScaleCount; i++) { - if (window->wl.monitors[i] == monitor) + if (window->wl.outputScales[i].output == monitor->wl.output) { - _glfwUpdateContentScaleWayland(window); + window->wl.outputScales[i].factor = monitor->wl.scale; + _glfwUpdateBufferScaleFromOutputsWayland(window); break; } } } } -#ifdef WL_OUTPUT_NAME_SINCE_VERSION - void outputHandleName(void* userData, struct wl_output* wl_output, const char* name) { struct _GLFWmonitor* monitor = userData; @@ -142,18 +141,14 @@ void outputHandleDescription(void* userData, { } -#endif // WL_OUTPUT_NAME_SINCE_VERSION - static const struct wl_output_listener outputListener = { outputHandleGeometry, outputHandleMode, outputHandleDone, outputHandleScale, -#ifdef WL_OUTPUT_NAME_SINCE_VERSION outputHandleName, outputHandleDescription, -#endif }; @@ -170,11 +165,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) return; } -#ifdef WL_OUTPUT_NAME_SINCE_VERSION version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION); -#else - version = 2; -#endif struct wl_output* output = wl_registry_bind(_glfw.wl.registry, name, @@ -189,6 +180,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) monitor->wl.output = output; monitor->wl.name = name; + wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag); wl_output_add_listener(output, &outputListener, monitor); } @@ -240,9 +232,10 @@ GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* found) return monitor->modes; } -void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode) { *mode = monitor->modes[monitor->wl.currentMode]; + return GLFW_TRUE; } GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp) @@ -267,6 +260,15 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Wayland: Platform not initialized"); + return NULL; + } + return monitor->wl.output; } +#endif // _GLFW_WAYLAND + diff --git a/raylib/external/glfw/src/wl_platform.h b/raylib/external/glfw/src/wl_platform.h index 238e1ed..149cd24 100644 --- a/raylib/external/glfw/src/wl_platform.h +++ b/raylib/external/glfw/src/wl_platform.h @@ -28,6 +28,8 @@ #include #include +#include + typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef struct VkWaylandSurfaceCreateInfoKHR @@ -61,6 +63,8 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor)(struct wl_proxy*,u typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...); typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*); typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*); +typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*); +typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*); typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*); typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...); #define wl_display_flush _glfw.wl.client.display_flush @@ -78,10 +82,13 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_ #define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned #define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data #define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data +#define wl_proxy_get_tag _glfw.wl.client.proxy_get_tag +#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag #define wl_proxy_get_version _glfw.wl.client.proxy_get_version #define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags struct wl_shm; +struct wl_output; #define wl_display_interface _glfw_wl_display_interface #define wl_subcompositor_interface _glfw_wl_subcompositor_interface @@ -122,6 +129,10 @@ struct wl_shm; #define xdg_surface_interface _glfw_xdg_surface_interface #define xdg_toplevel_interface _glfw_xdg_toplevel_interface #define xdg_wm_base_interface _glfw_xdg_wm_base_interface +#define xdg_activation_v1_interface _glfw_xdg_activation_v1_interface +#define xdg_activation_token_v1_interface _glfw_xdg_activation_token_v1_interface +#define wl_surface_interface _glfw_wl_surface_interface +#define wp_fractional_scale_v1_interface _glfw_wp_fractional_scale_v1_interface #define GLFW_WAYLAND_WINDOW_STATE _GLFWwindowWayland wl; #define GLFW_WAYLAND_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl; @@ -198,21 +209,128 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st #define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status #define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym -typedef enum _GLFWdecorationSideWayland -{ - mainWindow, - topDecoration, - leftDecoration, - rightDecoration, - bottomDecoration, -} _GLFWdecorationSideWayland; +struct libdecor; +struct libdecor_frame; +struct libdecor_state; +struct libdecor_configuration; -typedef struct _GLFWdecorationWayland +enum libdecor_error +{ + LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE, + LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION, +}; + +enum libdecor_window_state +{ + LIBDECOR_WINDOW_STATE_NONE = 0, + LIBDECOR_WINDOW_STATE_ACTIVE = 1, + LIBDECOR_WINDOW_STATE_MAXIMIZED = 2, + LIBDECOR_WINDOW_STATE_FULLSCREEN = 4, + LIBDECOR_WINDOW_STATE_TILED_LEFT = 8, + LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16, + LIBDECOR_WINDOW_STATE_TILED_TOP = 32, + LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64 +}; + +enum libdecor_capabilities +{ + LIBDECOR_ACTION_MOVE = 1, + LIBDECOR_ACTION_RESIZE = 2, + LIBDECOR_ACTION_MINIMIZE = 4, + LIBDECOR_ACTION_FULLSCREEN = 8, + LIBDECOR_ACTION_CLOSE = 16 +}; + +struct libdecor_interface +{ + void (* error)(struct libdecor*,enum libdecor_error,const char*); + void (* reserved0)(void); + void (* reserved1)(void); + void (* reserved2)(void); + void (* reserved3)(void); + void (* reserved4)(void); + void (* reserved5)(void); + void (* reserved6)(void); + void (* reserved7)(void); + void (* reserved8)(void); + void (* reserved9)(void); +}; + +struct libdecor_frame_interface +{ + void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*); + void (* close)(struct libdecor_frame*,void*); + void (* commit)(struct libdecor_frame*,void*); + void (* dismiss_popup)(struct libdecor_frame*,const char*,void*); + void (* reserved0)(void); + void (* reserved1)(void); + void (* reserved2)(void); + void (* reserved3)(void); + void (* reserved4)(void); + void (* reserved5)(void); + void (* reserved6)(void); + void (* reserved7)(void); + void (* reserved8)(void); + void (* reserved9)(void); +}; + +typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*); +typedef void (* PFN_libdecor_unref)(struct libdecor*); +typedef int (* PFN_libdecor_get_fd)(struct libdecor*); +typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int); +typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*); +typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*); +typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*); +typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*); +typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*); +typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int); +typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int); +typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); +typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); +typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible); +typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*); +typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*); +typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*); +typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int); +typedef void (* PFN_libdecor_state_free)(struct libdecor_state*); +#define libdecor_new _glfw.wl.libdecor.libdecor_new_ +#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_ +#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_ +#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_ +#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_ +#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_ +#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_ +#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_ +#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_ +#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ +#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ +#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_ +#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_ +#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ +#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ +#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_ +#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_ +#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_ +#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ +#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_ +#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ +#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_ +#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_ +#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_ +#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_ + +typedef struct _GLFWfallbackEdgeWayland { struct wl_surface* surface; struct wl_subsurface* subsurface; struct wp_viewport* viewport; -} _GLFWdecorationWayland; +} _GLFWfallbackEdgeWayland; typedef struct _GLFWofferWayland { @@ -221,17 +339,25 @@ typedef struct _GLFWofferWayland GLFWbool text_uri_list; } _GLFWofferWayland; +typedef struct _GLFWscaleWayland +{ + struct wl_output* output; + int32_t factor; +} _GLFWscaleWayland; + // Wayland-specific per-window data // typedef struct _GLFWwindowWayland { int width, height; + int fbWidth, fbHeight; GLFWbool visible; GLFWbool maximized; GLFWbool activated; GLFWbool fullscreen; GLFWbool hovered; GLFWbool transparent; + GLFWbool scaleFramebuffer; struct wl_surface* surface; struct wl_callback* callback; @@ -254,30 +380,39 @@ typedef struct _GLFWwindowWayland uint32_t decorationMode; } xdg; + struct { + struct libdecor_frame* frame; + } libdecor; + _GLFWcursor* currentCursor; double cursorPosX, cursorPosY; - char* title; char* appId; // We need to track the monitors the window spans on to calculate the // optimal scaling factor. - int scale; - _GLFWmonitor** monitors; - int monitorsCount; - int monitorsSize; + int32_t bufferScale; + _GLFWscaleWayland* outputScales; + size_t outputScaleCount; + size_t outputScaleSize; + + struct wp_viewport* scalingViewport; + uint32_t scalingNumerator; + struct wp_fractional_scale_v1* fractionalScale; struct zwp_relative_pointer_v1* relativePointer; struct zwp_locked_pointer_v1* lockedPointer; struct zwp_confined_pointer_v1* confinedPointer; - struct zwp_idle_inhibitor_v1* idleInhibitor; + struct zwp_idle_inhibitor_v1* idleInhibitor; + struct xdg_activation_token_v1* activationToken; struct { - struct wl_buffer* buffer; - _GLFWdecorationWayland top, left, right, bottom; - _GLFWdecorationSideWayland focus; - } decorations; + GLFWbool decorations; + struct wl_buffer* buffer; + _GLFWfallbackEdgeWayland top, left, right, bottom; + struct wl_surface* focus; + } fallback; } _GLFWwindowWayland; // Wayland-specific global data @@ -300,6 +435,8 @@ typedef struct _GLFWlibraryWayland struct zwp_relative_pointer_manager_v1* relativePointerManager; struct zwp_pointer_constraints_v1* pointerConstraints; struct zwp_idle_inhibit_manager_v1* idleInhibitManager; + struct xdg_activation_v1* activationManager; + struct wp_fractional_scale_manager_v1* fractionalScaleManager; _GLFWofferWayland* offers; unsigned int offerCount; @@ -311,8 +448,7 @@ typedef struct _GLFWlibraryWayland _GLFWwindow* dragFocus; uint32_t dragSerial; - int compositorVersion; - int seatVersion; + const char* tag; struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorThemeHiDPI; @@ -391,6 +527,8 @@ typedef struct _GLFWlibraryWayland PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned; PFN_wl_proxy_get_user_data proxy_get_user_data; PFN_wl_proxy_set_user_data proxy_set_user_data; + PFN_wl_proxy_get_tag proxy_get_tag; + PFN_wl_proxy_set_tag proxy_set_tag; PFN_wl_proxy_get_version proxy_get_version; PFN_wl_proxy_marshal_flags proxy_marshal_flags; } client; @@ -411,6 +549,38 @@ typedef struct _GLFWlibraryWayland PFN_wl_egl_window_destroy window_destroy; PFN_wl_egl_window_resize window_resize; } egl; + + struct { + void* handle; + struct libdecor* context; + struct wl_callback* callback; + GLFWbool ready; + PFN_libdecor_new libdecor_new_; + PFN_libdecor_unref libdecor_unref_; + PFN_libdecor_get_fd libdecor_get_fd_; + PFN_libdecor_dispatch libdecor_dispatch_; + PFN_libdecor_decorate libdecor_decorate_; + PFN_libdecor_frame_unref libdecor_frame_unref_; + PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_; + PFN_libdecor_frame_set_title libdecor_frame_set_title_; + PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_; + PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_; + PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_; + PFN_libdecor_frame_map libdecor_frame_map_; + PFN_libdecor_frame_commit libdecor_frame_commit_; + PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_; + PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_; + PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_; + PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_; + PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_; + PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_; + PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_; + PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_; + PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_; + PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_; + PFN_libdecor_state_new libdecor_state_new_; + PFN_libdecor_state_free libdecor_state_free_; + } libdecor; } _GLFWlibraryWayland; // Wayland-specific per-monitor data @@ -423,7 +593,7 @@ typedef struct _GLFWmonitorWayland int x; int y; - int scale; + int32_t scale; } _GLFWmonitorWayland; // Wayland-specific per-cursor data @@ -509,12 +679,12 @@ void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos); void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* count); -void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); void _glfwAddOutputWayland(uint32_t name, uint32_t version); -void _glfwUpdateContentScaleWayland(_GLFWwindow* window); +void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window); void _glfwAddSeatListenerWayland(struct wl_seat* seat); void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device); diff --git a/raylib/external/glfw/src/wl_window.c b/raylib/external/glfw/src/wl_window.c index 76d5f15..5b491ff 100644 --- a/raylib/external/glfw/src/wl_window.c +++ b/raylib/external/glfw/src/wl_window.c @@ -23,13 +23,13 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #define _GNU_SOURCE #include "internal.h" +#if defined(_GLFW_WAYLAND) + #include #include #include @@ -40,14 +40,17 @@ #include #include #include +#include #include "wayland-client-protocol.h" -#include "wayland-xdg-shell-client-protocol.h" -#include "wayland-xdg-decoration-client-protocol.h" -#include "wayland-viewporter-client-protocol.h" -#include "wayland-relative-pointer-unstable-v1-client-protocol.h" -#include "wayland-pointer-constraints-unstable-v1-client-protocol.h" -#include "wayland-idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" +#include "pointer-constraints-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" #define GLFW_BORDER_SIZE 4 #define GLFW_CAPTION_HEIGHT 24 @@ -190,26 +193,28 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) return buffer; } -static void createFallbackDecoration(_GLFWdecorationWayland* decoration, - struct wl_surface* parent, - struct wl_buffer* buffer, - int x, int y, - int width, int height) +static void createFallbackEdge(_GLFWwindow* window, + _GLFWfallbackEdgeWayland* edge, + struct wl_surface* parent, + struct wl_buffer* buffer, + int x, int y, + int width, int height) { - decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor); - decoration->subsurface = - wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, - decoration->surface, parent); - wl_subsurface_set_position(decoration->subsurface, x, y); - decoration->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter, - decoration->surface); - wp_viewport_set_destination(decoration->viewport, width, height); - wl_surface_attach(decoration->surface, buffer, 0, 0); + edge->surface = wl_compositor_create_surface(_glfw.wl.compositor); + wl_surface_set_user_data(edge->surface, window); + wl_proxy_set_tag((struct wl_proxy*) edge->surface, &_glfw.wl.tag); + edge->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, + edge->surface, parent); + wl_subsurface_set_position(edge->subsurface, x, y); + edge->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter, + edge->surface); + wp_viewport_set_destination(edge->viewport, width, height); + wl_surface_attach(edge->surface, buffer, 0, 0); struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor); wl_region_add(region, 0, 0, width, height); - wl_surface_set_opaque_region(decoration->surface, region); - wl_surface_commit(decoration->surface); + wl_surface_set_opaque_region(edge->surface, region); + wl_surface_commit(edge->surface); wl_region_destroy(region); } @@ -221,48 +226,53 @@ static void createFallbackDecorations(_GLFWwindow* window) if (!_glfw.wl.viewporter) return; - if (!window->wl.decorations.buffer) - window->wl.decorations.buffer = createShmBuffer(&image); - if (!window->wl.decorations.buffer) + if (!window->wl.fallback.buffer) + window->wl.fallback.buffer = createShmBuffer(&image); + if (!window->wl.fallback.buffer) return; - createFallbackDecoration(&window->wl.decorations.top, window->wl.surface, - window->wl.decorations.buffer, - 0, -GLFW_CAPTION_HEIGHT, - window->wl.width, GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.left, window->wl.surface, - window->wl.decorations.buffer, - -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.right, window->wl.surface, - window->wl.decorations.buffer, - window->wl.width, -GLFW_CAPTION_HEIGHT, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.bottom, window->wl.surface, - window->wl.decorations.buffer, - -GLFW_BORDER_SIZE, window->wl.height, - window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); + createFallbackEdge(window, &window->wl.fallback.top, window->wl.surface, + window->wl.fallback.buffer, + 0, -GLFW_CAPTION_HEIGHT, + window->wl.width, GLFW_CAPTION_HEIGHT); + createFallbackEdge(window, &window->wl.fallback.left, window->wl.surface, + window->wl.fallback.buffer, + -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); + createFallbackEdge(window, &window->wl.fallback.right, window->wl.surface, + window->wl.fallback.buffer, + window->wl.width, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); + createFallbackEdge(window, &window->wl.fallback.bottom, window->wl.surface, + window->wl.fallback.buffer, + -GLFW_BORDER_SIZE, window->wl.height, + window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); + + window->wl.fallback.decorations = GLFW_TRUE; } -static void destroyFallbackDecoration(_GLFWdecorationWayland* decoration) +static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge) { - if (decoration->subsurface) - wl_subsurface_destroy(decoration->subsurface); - if (decoration->surface) - wl_surface_destroy(decoration->surface); - if (decoration->viewport) - wp_viewport_destroy(decoration->viewport); - decoration->surface = NULL; - decoration->subsurface = NULL; - decoration->viewport = NULL; + if (edge->subsurface) + wl_subsurface_destroy(edge->subsurface); + if (edge->surface) + wl_surface_destroy(edge->surface); + if (edge->viewport) + wp_viewport_destroy(edge->viewport); + + edge->surface = NULL; + edge->subsurface = NULL; + edge->viewport = NULL; } static void destroyFallbackDecorations(_GLFWwindow* window) { - destroyFallbackDecoration(&window->wl.decorations.top); - destroyFallbackDecoration(&window->wl.decorations.left); - destroyFallbackDecoration(&window->wl.decorations.right); - destroyFallbackDecoration(&window->wl.decorations.bottom); + window->wl.fallback.decorations = GLFW_FALSE; + + destroyFallbackEdge(&window->wl.fallback.top); + destroyFallbackEdge(&window->wl.fallback.left); + destroyFallbackEdge(&window->wl.fallback.right); + destroyFallbackEdge(&window->wl.fallback.bottom); } static void xdgDecorationHandleConfigure(void* userData, @@ -301,61 +311,114 @@ static void setContentAreaOpaque(_GLFWwindow* window) wl_region_destroy(region); } - -static void resizeWindow(_GLFWwindow* window) +static void resizeFramebuffer(_GLFWwindow* window) { - int scale = window->wl.scale; - int scaledWidth = window->wl.width * scale; - int scaledHeight = window->wl.height * scale; + if (window->wl.fractionalScale) + { + window->wl.fbWidth = (window->wl.width * window->wl.scalingNumerator) / 120; + window->wl.fbHeight = (window->wl.height * window->wl.scalingNumerator) / 120; + } + else + { + window->wl.fbWidth = window->wl.width * window->wl.bufferScale; + window->wl.fbHeight = window->wl.height * window->wl.bufferScale; + } if (window->wl.egl.window) - wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0); + { + wl_egl_window_resize(window->wl.egl.window, + window->wl.fbWidth, + window->wl.fbHeight, + 0, 0); + } + if (!window->wl.transparent) setContentAreaOpaque(window); - _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); - if (!window->wl.decorations.top.surface) - return; - - wp_viewport_set_destination(window->wl.decorations.top.viewport, - window->wl.width, GLFW_CAPTION_HEIGHT); - wl_surface_commit(window->wl.decorations.top.surface); - - wp_viewport_set_destination(window->wl.decorations.left.viewport, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - wl_surface_commit(window->wl.decorations.left.surface); - - wl_subsurface_set_position(window->wl.decorations.right.subsurface, - window->wl.width, -GLFW_CAPTION_HEIGHT); - wp_viewport_set_destination(window->wl.decorations.right.viewport, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - wl_surface_commit(window->wl.decorations.right.surface); - - wl_subsurface_set_position(window->wl.decorations.bottom.subsurface, - -GLFW_BORDER_SIZE, window->wl.height); - wp_viewport_set_destination(window->wl.decorations.bottom.viewport, - window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); - wl_surface_commit(window->wl.decorations.bottom.surface); + _glfwInputFramebufferSize(window, window->wl.fbWidth, window->wl.fbHeight); } -void _glfwUpdateContentScaleWayland(_GLFWwindow* window) +static GLFWbool resizeWindow(_GLFWwindow* window, int width, int height) { - if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + width = _glfw_max(width, 1); + height = _glfw_max(height, 1); + + if (width == window->wl.width && height == window->wl.height) + return GLFW_FALSE; + + window->wl.width = width; + window->wl.height = height; + + resizeFramebuffer(window); + + if (window->wl.scalingViewport) + { + wp_viewport_set_destination(window->wl.scalingViewport, + window->wl.width, + window->wl.height); + } + + if (window->wl.fallback.decorations) + { + wp_viewport_set_destination(window->wl.fallback.top.viewport, + window->wl.width, + GLFW_CAPTION_HEIGHT); + wl_surface_commit(window->wl.fallback.top.surface); + + wp_viewport_set_destination(window->wl.fallback.left.viewport, + GLFW_BORDER_SIZE, + window->wl.height + GLFW_CAPTION_HEIGHT); + wl_surface_commit(window->wl.fallback.left.surface); + + wl_subsurface_set_position(window->wl.fallback.right.subsurface, + window->wl.width, -GLFW_CAPTION_HEIGHT); + wp_viewport_set_destination(window->wl.fallback.right.viewport, + GLFW_BORDER_SIZE, + window->wl.height + GLFW_CAPTION_HEIGHT); + wl_surface_commit(window->wl.fallback.right.surface); + + wl_subsurface_set_position(window->wl.fallback.bottom.subsurface, + -GLFW_BORDER_SIZE, window->wl.height); + wp_viewport_set_destination(window->wl.fallback.bottom.viewport, + window->wl.width + GLFW_BORDER_SIZE * 2, + GLFW_BORDER_SIZE); + wl_surface_commit(window->wl.fallback.bottom.surface); + } + + return GLFW_TRUE; +} + +void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window) +{ + if (wl_compositor_get_version(_glfw.wl.compositor) < + WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + { + return; + } + + if (!window->wl.scaleFramebuffer) + return; + + // When using fractional scaling, the buffer scale should remain at 1 + if (window->wl.fractionalScale) return; // Get the scale factor from the highest scale monitor. - int maxScale = 1; + int32_t maxScale = 1; - for (int i = 0; i < window->wl.monitorsCount; i++) - maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale); + for (size_t i = 0; i < window->wl.outputScaleCount; i++) + maxScale = _glfw_max(window->wl.outputScales[i].factor, maxScale); // Only change the framebuffer size if the scale changed. - if (window->wl.scale != maxScale) + if (window->wl.bufferScale != maxScale) { - window->wl.scale = maxScale; + window->wl.bufferScale = maxScale; wl_surface_set_buffer_scale(window->wl.surface, maxScale); _glfwInputWindowContentScale(window, maxScale, maxScale); - resizeWindow(window); + resizeFramebuffer(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } @@ -363,40 +426,50 @@ static void surfaceHandleEnter(void* userData, struct wl_surface* surface, struct wl_output* output) { + if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag) + return; + _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); + if (!window || !monitor) + return; - if (window->wl.monitorsCount + 1 > window->wl.monitorsSize) + if (window->wl.outputScaleCount + 1 > window->wl.outputScaleSize) { - ++window->wl.monitorsSize; - window->wl.monitors = - _glfw_realloc(window->wl.monitors, - window->wl.monitorsSize * sizeof(_GLFWmonitor*)); + window->wl.outputScaleSize++; + window->wl.outputScales = + _glfw_realloc(window->wl.outputScales, + window->wl.outputScaleSize * sizeof(_GLFWscaleWayland)); } - window->wl.monitors[window->wl.monitorsCount++] = monitor; + window->wl.outputScaleCount++; + window->wl.outputScales[window->wl.outputScaleCount - 1] = + (_GLFWscaleWayland) { output, monitor->wl.scale }; - _glfwUpdateContentScaleWayland(window); + _glfwUpdateBufferScaleFromOutputsWayland(window); } static void surfaceHandleLeave(void* userData, struct wl_surface* surface, struct wl_output* output) { + if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag) + return; + _GLFWwindow* window = userData; - _GLFWmonitor* monitor = wl_output_get_user_data(output); - GLFWbool found = GLFW_FALSE; - for (int i = 0; i < window->wl.monitorsCount - 1; ++i) + for (size_t i = 0; i < window->wl.outputScaleCount; i++) { - if (monitor == window->wl.monitors[i]) - found = GLFW_TRUE; - if (found) - window->wl.monitors[i] = window->wl.monitors[i + 1]; + if (window->wl.outputScales[i].output == output) + { + window->wl.outputScales[i] = + window->wl.outputScales[window->wl.outputScaleCount - 1]; + window->wl.outputScaleCount--; + break; + } } - window->wl.monitors[--window->wl.monitorsCount] = NULL; - _glfwUpdateContentScaleWayland(window); + _glfwUpdateBufferScaleFromOutputsWayland(window); } static const struct wl_surface_listener surfaceListener = @@ -427,7 +500,12 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) // static void acquireMonitor(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + { + libdecor_frame_set_fullscreen(window->wl.libdecor.frame, + window->monitor->wl.output); + } + else if (window->wl.xdg.toplevel) { xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, window->monitor->wl.output); @@ -435,7 +513,7 @@ static void acquireMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_TRUE); - if (window->wl.decorations.top.surface) + if (window->wl.fallback.decorations) destroyFallbackDecorations(window); } @@ -443,18 +521,40 @@ static void acquireMonitor(_GLFWwindow* window) // static void releaseMonitor(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_unset_fullscreen(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); - if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) + if (!window->wl.libdecor.frame && + window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) { if (window->decorated) createFallbackDecorations(window); } } +void fractionalScaleHandlePreferredScale(void* userData, + struct wp_fractional_scale_v1* fractionalScale, + uint32_t numerator) +{ + _GLFWwindow* window = userData; + + window->wl.scalingNumerator = numerator; + _glfwInputWindowContentScale(window, numerator / 120.f, numerator / 120.f); + resizeFramebuffer(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); +} + +const struct wp_fractional_scale_v1_listener fractionalScaleListener = +{ + fractionalScaleHandlePreferredScale, +}; + static void xdgToplevelHandleConfigure(void* userData, struct xdg_toplevel* toplevel, int32_t width, @@ -488,7 +588,7 @@ static void xdgToplevelHandleConfigure(void* userData, if (width && height) { - if (window->wl.decorations.top.surface) + if (window->wl.fallback.decorations) { window->wl.pending.width = _glfw_max(0, width - GLFW_BORDER_SIZE * 2); window->wl.pending.height = @@ -562,13 +662,9 @@ static void xdgSurfaceHandleConfigure(void* userData, } } - if (width != window->wl.width || height != window->wl.height) + if (resizeWindow(window, width, height)) { - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); - - _glfwInputWindowSize(window, width, height); + _glfwInputWindowSize(window, window->wl.width, window->wl.height); if (window->wl.visible) _glfwInputWindowDamage(window); @@ -591,7 +687,232 @@ static const struct xdg_surface_listener xdgSurfaceListener = xdgSurfaceHandleConfigure }; -static GLFWbool createShellObjects(_GLFWwindow* window) +void libdecorFrameHandleConfigure(struct libdecor_frame* frame, + struct libdecor_configuration* config, + void* userData) +{ + _GLFWwindow* window = userData; + int width, height; + + enum libdecor_window_state windowState; + GLFWbool fullscreen, activated, maximized; + + if (libdecor_configuration_get_window_state(config, &windowState)) + { + fullscreen = (windowState & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; + activated = (windowState & LIBDECOR_WINDOW_STATE_ACTIVE) != 0; + maximized = (windowState & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0; + } + else + { + fullscreen = window->wl.fullscreen; + activated = window->wl.activated; + maximized = window->wl.maximized; + } + + if (!libdecor_configuration_get_content_size(config, frame, &width, &height)) + { + width = window->wl.width; + height = window->wl.height; + } + + if (!maximized && !fullscreen) + { + if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) + { + const float aspectRatio = (float) width / (float) height; + const float targetRatio = (float) window->numer / (float) window->denom; + if (aspectRatio < targetRatio) + height = width / targetRatio; + else if (aspectRatio > targetRatio) + width = height * targetRatio; + } + } + + struct libdecor_state* frameState = libdecor_state_new(width, height); + libdecor_frame_commit(frame, frameState, config); + libdecor_state_free(frameState); + + if (window->wl.activated != activated) + { + window->wl.activated = activated; + if (!window->wl.activated) + { + if (window->monitor && window->autoIconify) + libdecor_frame_set_minimized(window->wl.libdecor.frame); + } + } + + if (window->wl.maximized != maximized) + { + window->wl.maximized = maximized; + _glfwInputWindowMaximize(window, window->wl.maximized); + } + + window->wl.fullscreen = fullscreen; + + GLFWbool damaged = GLFW_FALSE; + + if (!window->wl.visible) + { + window->wl.visible = GLFW_TRUE; + damaged = GLFW_TRUE; + } + + if (resizeWindow(window, width, height)) + { + _glfwInputWindowSize(window, window->wl.width, window->wl.height); + damaged = GLFW_TRUE; + } + + if (damaged) + _glfwInputWindowDamage(window); + else + wl_surface_commit(window->wl.surface); +} + +void libdecorFrameHandleClose(struct libdecor_frame* frame, void* userData) +{ + _GLFWwindow* window = userData; + _glfwInputWindowCloseRequest(window); +} + +void libdecorFrameHandleCommit(struct libdecor_frame* frame, void* userData) +{ + _GLFWwindow* window = userData; + wl_surface_commit(window->wl.surface); +} + +void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame, + const char* seatName, + void* userData) +{ +} + +static const struct libdecor_frame_interface libdecorFrameInterface = +{ + libdecorFrameHandleConfigure, + libdecorFrameHandleClose, + libdecorFrameHandleCommit, + libdecorFrameHandleDismissPopup +}; + +static GLFWbool createLibdecorFrame(_GLFWwindow* window) +{ + // Allow libdecor to finish initialization of itself and its plugin + while (!_glfw.wl.libdecor.ready) + _glfwWaitEventsWayland(); + + window->wl.libdecor.frame = libdecor_decorate(_glfw.wl.libdecor.context, + window->wl.surface, + &libdecorFrameInterface, + window); + if (!window->wl.libdecor.frame) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create libdecor frame"); + return GLFW_FALSE; + } + + struct libdecor_state* frameState = + libdecor_state_new(window->wl.width, window->wl.height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + + if (strlen(window->wl.appId)) + libdecor_frame_set_app_id(window->wl.libdecor.frame, window->wl.appId); + + libdecor_frame_set_title(window->wl.libdecor.frame, window->title); + + if (window->minwidth != GLFW_DONT_CARE && + window->minheight != GLFW_DONT_CARE) + { + libdecor_frame_set_min_content_size(window->wl.libdecor.frame, + window->minwidth, + window->minheight); + } + + if (window->maxwidth != GLFW_DONT_CARE && + window->maxheight != GLFW_DONT_CARE) + { + libdecor_frame_set_max_content_size(window->wl.libdecor.frame, + window->maxwidth, + window->maxheight); + } + + if (!window->resizable) + { + libdecor_frame_unset_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + + if (window->monitor) + { + libdecor_frame_set_fullscreen(window->wl.libdecor.frame, + window->monitor->wl.output); + setIdleInhibitor(window, GLFW_TRUE); + } + else + { + if (window->wl.maximized) + libdecor_frame_set_maximized(window->wl.libdecor.frame); + + if (!window->decorated) + libdecor_frame_set_visibility(window->wl.libdecor.frame, false); + + setIdleInhibitor(window, GLFW_FALSE); + } + + libdecor_frame_map(window->wl.libdecor.frame); + wl_display_roundtrip(_glfw.wl.display); + return GLFW_TRUE; +} + +static void updateXdgSizeLimits(_GLFWwindow* window) +{ + int minwidth, minheight, maxwidth, maxheight; + + if (window->resizable) + { + if (window->minwidth == GLFW_DONT_CARE || window->minheight == GLFW_DONT_CARE) + minwidth = minheight = 0; + else + { + minwidth = window->minwidth; + minheight = window->minheight; + + if (window->wl.fallback.decorations) + { + minwidth += GLFW_BORDER_SIZE * 2; + minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + } + + if (window->maxwidth == GLFW_DONT_CARE || window->maxheight == GLFW_DONT_CARE) + maxwidth = maxheight = 0; + else + { + maxwidth = window->maxwidth; + maxheight = window->maxheight; + + if (window->wl.fallback.decorations) + { + maxwidth += GLFW_BORDER_SIZE * 2; + maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + } + } + else + { + minwidth = maxwidth = window->wl.width; + minheight = maxheight = window->wl.height; + } + + xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); + xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); +} + +static GLFWbool createXdgShellObjects(_GLFWwindow* window) { window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase, window->wl.surface); @@ -617,8 +938,7 @@ static GLFWbool createShellObjects(_GLFWwindow* window) if (window->wl.appId) xdg_toplevel_set_app_id(window->wl.xdg.toplevel, window->wl.appId); - if (window->wl.title) - xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title); + xdg_toplevel_set_title(window->wl.xdg.toplevel, window->title); if (window->monitor) { @@ -631,70 +951,57 @@ static GLFWbool createShellObjects(_GLFWwindow* window) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); + } - if (_glfw.wl.decorationManager) - { - window->wl.xdg.decoration = - zxdg_decoration_manager_v1_get_toplevel_decoration( - _glfw.wl.decorationManager, window->wl.xdg.toplevel); - zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, - &xdgDecorationListener, - window); + if (_glfw.wl.decorationManager) + { + window->wl.xdg.decoration = + zxdg_decoration_manager_v1_get_toplevel_decoration( + _glfw.wl.decorationManager, window->wl.xdg.toplevel); + zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, + &xdgDecorationListener, + window); - uint32_t mode; + uint32_t mode; - if (window->decorated) - mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; - else - mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - - zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); - } + if (window->decorated) + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; else - { - if (window->decorated) - createFallbackDecorations(window); - } - } + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) + zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); + } + else { - int minwidth = window->minwidth; - int minheight = window->minheight; - - if (window->wl.decorations.top.surface) - { - minwidth += GLFW_BORDER_SIZE * 2; - minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - - xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); + if (window->decorated && !window->monitor) + createFallbackDecorations(window); } - if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) - { - int maxwidth = window->maxwidth; - int maxheight = window->maxheight; - - if (window->wl.decorations.top.surface) - { - maxwidth += GLFW_BORDER_SIZE * 2; - maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - - xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); - } + updateXdgSizeLimits(window); wl_surface_commit(window->wl.surface); wl_display_roundtrip(_glfw.wl.display); - return GLFW_TRUE; } +static GLFWbool createShellObjects(_GLFWwindow* window) +{ + if (_glfw.wl.libdecor.context) + { + if (createLibdecorFrame(window)) + return GLFW_TRUE; + } + + return createXdgShellObjects(window); +} + static void destroyShellObjects(_GLFWwindow* window) { destroyFallbackDecorations(window); + if (window->wl.libdecor.frame) + libdecor_frame_unref(window->wl.libdecor.frame); + if (window->wl.xdg.decoration) zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration); @@ -704,6 +1011,7 @@ static void destroyShellObjects(_GLFWwindow* window) if (window->wl.xdg.surface) xdg_surface_destroy(window->wl.xdg.surface); + window->wl.libdecor.frame = NULL; window->wl.xdg.decoration = NULL; window->wl.xdg.decorationMode = 0; window->wl.xdg.toplevel = NULL; @@ -721,24 +1029,49 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, return GLFW_FALSE; } + wl_proxy_set_tag((struct wl_proxy*) window->wl.surface, &_glfw.wl.tag); wl_surface_add_listener(window->wl.surface, &surfaceListener, window); - wl_surface_set_user_data(window->wl.surface, window); - window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; - window->wl.scale = 1; - window->wl.title = _glfw_strdup(wndconfig->title); + window->wl.fbWidth = wndconfig->width; + window->wl.fbHeight = wndconfig->height; window->wl.appId = _glfw_strdup(wndconfig->wl.appId); + window->wl.bufferScale = 1; + window->wl.scalingNumerator = 120; + window->wl.scaleFramebuffer = wndconfig->scaleFramebuffer; + window->wl.maximized = wndconfig->maximized; window->wl.transparent = fbconfig->transparent; if (!window->wl.transparent) setContentAreaOpaque(window); + if (_glfw.wl.fractionalScaleManager) + { + if (window->wl.scaleFramebuffer) + { + window->wl.scalingViewport = + wp_viewporter_get_viewport(_glfw.wl.viewporter, window->wl.surface); + + wp_viewport_set_destination(window->wl.scalingViewport, + window->wl.width, + window->wl.height); + + window->wl.fractionalScale = + wp_fractional_scale_manager_v1_get_fractional_scale( + _glfw.wl.fractionalScaleManager, + window->wl.surface); + + wp_fractional_scale_v1_add_listener(window->wl.fractionalScale, + &fractionalScaleListener, + window); + } + } + return GLFW_TRUE; } @@ -756,7 +1089,7 @@ static void setCursorImage(_GLFWwindow* window, buffer = cursorWayland->buffer; else { - if (window->wl.scale > 1 && cursorWayland->cursorHiDPI) + if (window->wl.bufferScale > 1 && cursorWayland->cursorHiDPI) { wlCursor = cursorWayland->cursorHiDPI; scale = 2; @@ -792,7 +1125,7 @@ static void incrementCursorImage(_GLFWwindow* window) { _GLFWcursor* cursor; - if (!window || window->wl.decorations.focus != mainWindow) + if (!window || !window->wl.hovered) return; cursor = window->wl.currentCursor; @@ -871,18 +1204,31 @@ static void inputText(_GLFWwindow* window, uint32_t scancode) static void handleEvents(double* timeout) { +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + if (_glfw.joysticksInitialized) + _glfwDetectJoystickConnectionLinux(); +#endif + GLFWbool event = GLFW_FALSE; + enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD, LIBDECOR_FD }; struct pollfd fds[] = { - { wl_display_get_fd(_glfw.wl.display), POLLIN }, - { _glfw.wl.keyRepeatTimerfd, POLLIN }, - { _glfw.wl.cursorTimerfd, POLLIN }, + [DISPLAY_FD] = { wl_display_get_fd(_glfw.wl.display), POLLIN }, + [KEYREPEAT_FD] = { _glfw.wl.keyRepeatTimerfd, POLLIN }, + [CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN }, + [LIBDECOR_FD] = { -1, POLLIN } }; + if (_glfw.wl.libdecor.context) + fds[LIBDECOR_FD].fd = libdecor_get_fd(_glfw.wl.libdecor.context); + while (!event) { while (wl_display_prepare_read(_glfw.wl.display) != 0) - wl_display_dispatch_pending(_glfw.wl.display); + { + if (wl_display_dispatch_pending(_glfw.wl.display) > 0) + return; + } // If an error other than EAGAIN happens, we have likely been disconnected // from the Wayland session; try to handle that the best we can. @@ -900,13 +1246,13 @@ static void handleEvents(double* timeout) return; } - if (!_glfwPollPOSIX(fds, 3, timeout)) + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) { wl_display_cancel_read(_glfw.wl.display); return; } - if (fds[0].revents & POLLIN) + if (fds[DISPLAY_FD].revents & POLLIN) { wl_display_read_events(_glfw.wl.display); if (wl_display_dispatch_pending(_glfw.wl.display) > 0) @@ -915,7 +1261,7 @@ static void handleEvents(double* timeout) else wl_display_cancel_read(_glfw.wl.display); - if (fds[1].revents & POLLIN) + if (fds[KEYREPEAT_FD].revents & POLLIN) { uint64_t repeats; @@ -935,15 +1281,18 @@ static void handleEvents(double* timeout) } } - if (fds[2].revents & POLLIN) + if (fds[CURSOR_FD].revents & POLLIN) { uint64_t repeats; if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8) - { incrementCursorImage(_glfw.wl.pointerFocus); + } + + if (fds[LIBDECOR_FD].revents & POLLIN) + { + if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0) event = GLFW_TRUE; - } } } } @@ -1012,40 +1361,6 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime return string; } -static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, - _GLFWdecorationSideWayland* which) -{ - _GLFWdecorationSideWayland focus; - _GLFWwindow* window = _glfw.windowListHead; - if (!which) - which = &focus; - while (window) - { - if (surface == window->wl.decorations.top.surface) - { - *which = topDecoration; - break; - } - if (surface == window->wl.decorations.left.surface) - { - *which = leftDecoration; - break; - } - if (surface == window->wl.decorations.right.surface) - { - *which = rightDecoration; - break; - } - if (surface == window->wl.decorations.bottom.surface) - { - *which = bottomDecoration; - break; - } - window = window->next; - } - return window; -} - static void pointerHandleEnter(void* userData, struct wl_pointer* pointer, uint32_t serial, @@ -1057,24 +1372,26 @@ static void pointerHandleEnter(void* userData, if (!surface) return; - _GLFWdecorationSideWayland focus = mainWindow; - _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, &focus); - if (!window) - return; - } + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + + _GLFWwindow* window = wl_surface_get_user_data(surface); - window->wl.decorations.focus = focus; _glfw.wl.serial = serial; _glfw.wl.pointerEnterSerial = serial; _glfw.wl.pointerFocus = window; - window->wl.hovered = GLFW_TRUE; - - _glfwSetCursorWayland(window, window->wl.currentCursor); - _glfwInputCursorEnter(window, GLFW_TRUE); + if (surface == window->wl.surface) + { + window->wl.hovered = GLFW_TRUE; + _glfwSetCursorWayland(window, window->wl.currentCursor); + _glfwInputCursorEnter(window, GLFW_TRUE); + } + else + { + if (window->wl.fallback.decorations) + window->wl.fallback.focus = surface; + } } static void pointerHandleLeave(void* userData, @@ -1082,62 +1399,30 @@ static void pointerHandleLeave(void* userData, uint32_t serial, struct wl_surface* surface) { - _GLFWwindow* window = _glfw.wl.pointerFocus; - - if (!window) + if (!surface) return; - window->wl.hovered = GLFW_FALSE; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + + _GLFWwindow* window = _glfw.wl.pointerFocus; + if (!window) + return; _glfw.wl.serial = serial; _glfw.wl.pointerFocus = NULL; _glfw.wl.cursorPreviousName = NULL; - _glfwInputCursorEnter(window, GLFW_FALSE); -} -static void setCursor(_GLFWwindow* window, const char* name) -{ - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; - struct wl_surface* surface = _glfw.wl.cursorSurface; - struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; - int scale = 1; - - if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI) + if (window->wl.hovered) { - // We only support up to scale=2 for now, since libwayland-cursor - // requires us to load a different theme for each size. - scale = 2; - theme = _glfw.wl.cursorThemeHiDPI; + window->wl.hovered = GLFW_FALSE; + _glfwInputCursorEnter(window, GLFW_FALSE); } - - cursor = wl_cursor_theme_get_cursor(theme, name); - if (!cursor) + else { - _glfwInputError(GLFW_CURSOR_UNAVAILABLE, - "Wayland: Standard cursor shape unavailable"); - return; + if (window->wl.fallback.decorations) + window->wl.fallback.focus = NULL; } - // TODO: handle animated cursors too. - image = cursor->images[0]; - - if (!image) - return; - - buffer = wl_cursor_image_get_buffer(image); - if (!buffer) - return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - surface, - image->hotspot_x / scale, - image->hotspot_y / scale); - wl_surface_set_buffer_scale(surface, scale); - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); - wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; } static void pointerHandleMotion(void* userData, @@ -1147,56 +1432,99 @@ static void pointerHandleMotion(void* userData, wl_fixed_t sy) { _GLFWwindow* window = _glfw.wl.pointerFocus; - const char* cursorName = NULL; - double x, y; - if (!window) return; if (window->cursorMode == GLFW_CURSOR_DISABLED) return; - x = wl_fixed_to_double(sx); - y = wl_fixed_to_double(sy); - window->wl.cursorPosX = x; - window->wl.cursorPosY = y; - switch (window->wl.decorations.focus) + const double xpos = wl_fixed_to_double(sx); + const double ypos = wl_fixed_to_double(sy); + window->wl.cursorPosX = xpos; + window->wl.cursorPosY = ypos; + + if (window->wl.hovered) { - case mainWindow: - _glfw.wl.cursorPreviousName = NULL; - _glfwInputCursorPos(window, x, y); - return; - case topDecoration: - if (y < GLFW_BORDER_SIZE) - cursorName = "n-resize"; - else - cursorName = "left_ptr"; - break; - case leftDecoration: - if (y < GLFW_BORDER_SIZE) - cursorName = "nw-resize"; - else - cursorName = "w-resize"; - break; - case rightDecoration: - if (y < GLFW_BORDER_SIZE) - cursorName = "ne-resize"; - else - cursorName = "e-resize"; - break; - case bottomDecoration: - if (x < GLFW_BORDER_SIZE) - cursorName = "sw-resize"; - else if (x > window->wl.width + GLFW_BORDER_SIZE) - cursorName = "se-resize"; - else - cursorName = "s-resize"; - break; - default: - assert(0); + _glfw.wl.cursorPreviousName = NULL; + _glfwInputCursorPos(window, xpos, ypos); + return; + } + + if (window->wl.fallback.decorations) + { + const char* cursorName = "left_ptr"; + + if (window->resizable) + { + if (window->wl.fallback.focus == window->wl.fallback.top.surface) + { + if (ypos < GLFW_BORDER_SIZE) + cursorName = "n-resize"; + } + else if (window->wl.fallback.focus == window->wl.fallback.left.surface) + { + if (ypos < GLFW_BORDER_SIZE) + cursorName = "nw-resize"; + else + cursorName = "w-resize"; + } + else if (window->wl.fallback.focus == window->wl.fallback.right.surface) + { + if (ypos < GLFW_BORDER_SIZE) + cursorName = "ne-resize"; + else + cursorName = "e-resize"; + } + else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface) + { + if (xpos < GLFW_BORDER_SIZE) + cursorName = "sw-resize"; + else if (xpos > window->wl.width + GLFW_BORDER_SIZE) + cursorName = "se-resize"; + else + cursorName = "s-resize"; + } + } + + if (_glfw.wl.cursorPreviousName != cursorName) + { + struct wl_surface* surface = _glfw.wl.cursorSurface; + struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; + int scale = 1; + + if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI) + { + // We only support up to scale=2 for now, since libwayland-cursor + // requires us to load a different theme for each size. + scale = 2; + theme = _glfw.wl.cursorThemeHiDPI; + } + + struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName); + if (!cursor) + return; + + // TODO: handle animated cursors too. + struct wl_cursor_image* image = cursor->images[0]; + if (!image) + return; + + struct wl_buffer* buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; + + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, + surface, + image->hotspot_x / scale, + image->hotspot_y / scale); + wl_surface_set_buffer_scale(surface, scale); + wl_surface_attach(surface, buffer, 0, 0); + wl_surface_damage(surface, 0, 0, image->width, image->height); + wl_surface_commit(surface); + + _glfw.wl.cursorPreviousName = cursorName; + } } - if (_glfw.wl.cursorPreviousName != cursorName) - setCursor(window, cursorName); } static void pointerHandleButton(void* userData, @@ -1207,81 +1535,74 @@ static void pointerHandleButton(void* userData, uint32_t state) { _GLFWwindow* window = _glfw.wl.pointerFocus; - int glfwButton; - uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE; - if (!window) return; - if (button == BTN_LEFT) + + if (window->wl.hovered) { - switch (window->wl.decorations.focus) + _glfw.wl.serial = serial; + + _glfwInputMouseClick(window, + button - BTN_LEFT, + state == WL_POINTER_BUTTON_STATE_PRESSED, + _glfw.wl.xkb.modifiers); + return; + } + + if (window->wl.fallback.decorations) + { + if (button == BTN_LEFT) { - case mainWindow: - break; - case topDecoration: + uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE; + + if (window->wl.fallback.focus == window->wl.fallback.top.surface) + { if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; else xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); - break; - case leftDecoration: + } + else if (window->wl.fallback.focus == window->wl.fallback.left.surface) + { if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; - break; - case rightDecoration: + } + else if (window->wl.fallback.focus == window->wl.fallback.right.surface) + { if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; - break; - case bottomDecoration: + } + else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface) + { if (window->wl.cursorPosX < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; - break; - default: - assert(0); + } + + if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE) + { + xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, + serial, edges); + } } - if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE) + else if (button == BTN_RIGHT) { - xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, - serial, edges); - return; + if (window->wl.xdg.toplevel) + { + xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, + _glfw.wl.seat, serial, + window->wl.cursorPosX, + window->wl.cursorPosY); + } } } - else if (button == BTN_RIGHT) - { - if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel) - { - xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, - _glfw.wl.seat, serial, - window->wl.cursorPosX, - window->wl.cursorPosY); - return; - } - } - - // Don’t pass the button to the user if it was related to a decoration. - if (window->wl.decorations.focus != mainWindow) - return; - - _glfw.wl.serial = serial; - - /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev - * codes. */ - glfwButton = button - BTN_LEFT; - - _glfwInputMouseClick(window, - glfwButton, - state == WL_POINTER_BUTTON_STATE_PRESSED - ? GLFW_PRESS - : GLFW_RELEASE, - _glfw.wl.xkb.modifiers); } static void pointerHandleAxis(void* userData, @@ -1291,24 +1612,14 @@ static void pointerHandleAxis(void* userData, wl_fixed_t value) { _GLFWwindow* window = _glfw.wl.pointerFocus; - double x = 0.0, y = 0.0; - // Wayland scroll events are in pointer motion coordinate space (think two - // finger scroll). The factor 10 is commonly used to convert to "scroll - // step means 1.0. - const double scrollFactor = 1.0 / 10.0; - if (!window) return; - assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL || - axis == WL_POINTER_AXIS_VERTICAL_SCROLL); - + // NOTE: 10 units of motion per mouse wheel step seems to be a common ratio if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) - x = -wl_fixed_to_double(value) * scrollFactor; + _glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0); else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) - y = -wl_fixed_to_double(value) * scrollFactor; - - _glfwInputScroll(window, x, y); + _glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0); } static const struct wl_pointer_listener pointerListener = @@ -1421,13 +1732,12 @@ static void keyboardHandleEnter(void* userData, if (!surface) return; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, NULL); - if (!window) - return; - } + if (surface != window->wl.surface) + return; _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = window; @@ -1545,7 +1855,6 @@ static void keyboardHandleModifiers(void* userData, } } -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION static void keyboardHandleRepeatInfo(void* userData, struct wl_keyboard* keyboard, int32_t rate, @@ -1557,7 +1866,6 @@ static void keyboardHandleRepeatInfo(void* userData, _glfw.wl.keyRepeatRate = rate; _glfw.wl.keyRepeatDelay = delay; } -#endif static const struct wl_keyboard_listener keyboardListener = { @@ -1566,9 +1874,7 @@ static const struct wl_keyboard_listener keyboardListener = keyboardHandleLeave, keyboardHandleKey, keyboardHandleModifiers, -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION keyboardHandleRepeatInfo, -#endif }; static void seatHandleCapabilities(void* userData, @@ -1638,7 +1944,8 @@ static void dataDeviceHandleDataOffer(void* userData, struct wl_data_offer* offer) { _GLFWofferWayland* offers = - _glfw_realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1); + _glfw_realloc(_glfw.wl.offers, + sizeof(_GLFWofferWayland) * (_glfw.wl.offerCount + 1)); if (!offers) { _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); @@ -1674,9 +1981,12 @@ static void dataDeviceHandleEnter(void* userData, _GLFWwindow* window = NULL; if (surface) - window = wl_surface_get_user_data(surface); + { + if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag) + window = wl_surface_get_user_data(surface); + } - if (window && _glfw.wl.offers[i].text_uri_list) + if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) { _glfw.wl.dragOffer = offer; _glfw.wl.dragFocus = window; @@ -1689,6 +1999,9 @@ static void dataDeviceHandleEnter(void* userData, } } + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + if (_glfw.wl.dragOffer) wl_data_offer_accept(offer, serial, "text/uri-list"); else @@ -1776,6 +2089,25 @@ const struct wl_data_device_listener dataDeviceListener = dataDeviceHandleSelection, }; +static void xdgActivationHandleDone(void* userData, + struct xdg_activation_token_v1* activationToken, + const char* token) +{ + _GLFWwindow* window = userData; + + if (activationToken != window->wl.activationToken) + return; + + xdg_activation_v1_activate(_glfw.wl.activationManager, token, window->wl.surface); + xdg_activation_token_v1_destroy(window->wl.activationToken); + window->wl.activationToken = NULL; +} + +static const struct xdg_activation_token_v1_listener xdgActivationListener = +{ + xdgActivationHandleDone +}; + void _glfwAddSeatListenerWayland(struct wl_seat* seat) { wl_seat_add_listener(seat, &seatListener, NULL); @@ -1805,8 +2137,8 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, ctxconfig->source == GLFW_NATIVE_CONTEXT_API) { window->wl.egl.window = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); + window->wl.fbWidth, + window->wl.fbHeight); if (!window->wl.egl.window) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -1851,6 +2183,9 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window) if (window == _glfw.wl.keyboardFocus) _glfw.wl.keyboardFocus = NULL; + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); + if (window->wl.idleInhibitor) zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor); @@ -1868,8 +2203,8 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window) destroyShellObjects(window); - if (window->wl.decorations.buffer) - wl_buffer_destroy(window->wl.decorations.buffer); + if (window->wl.fallback.buffer) + wl_buffer_destroy(window->wl.fallback.buffer); if (window->wl.egl.window) wl_egl_window_destroy(window->wl.egl.window); @@ -1877,18 +2212,15 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window) if (window->wl.surface) wl_surface_destroy(window->wl.surface); - _glfw_free(window->wl.title); _glfw_free(window->wl.appId); - _glfw_free(window->wl.monitors); + _glfw_free(window->wl.outputScales); } void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title) { - char* copy = _glfw_strdup(title); - _glfw_free(window->wl.title); - window->wl.title = copy; - - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_title(window->wl.libdecor.frame, title); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_title(window->wl.xdg.toplevel, title); } @@ -1932,9 +2264,19 @@ void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height) } else { - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); + if (!resizeWindow(window, width, height)) + return; + + if (window->wl.libdecor.frame) + { + struct libdecor_state* frameState = + libdecor_state_new(window->wl.width, window->wl.height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + } + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } @@ -1942,34 +2284,21 @@ void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) { if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) minwidth = minheight = 0; - else - { - if (window->wl.decorations.top.surface) - { - minwidth += GLFW_BORDER_SIZE * 2; - minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - } if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE) maxwidth = maxheight = 0; - else - { - if (window->wl.decorations.top.surface) - { - maxwidth += GLFW_BORDER_SIZE * 2; - maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - } - xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); - xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); - wl_surface_commit(window->wl.surface); + libdecor_frame_set_min_content_size(window->wl.libdecor.frame, + minwidth, minheight); + libdecor_frame_set_max_content_size(window->wl.libdecor.frame, + maxwidth, maxheight); } + else if (window->wl.xdg.toplevel) + updateXdgSizeLimits(window); } void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom) @@ -1977,33 +2306,48 @@ void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom) if (window->wl.maximized || window->wl.fullscreen) return; + int width = window->wl.width, height = window->wl.height; + if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) { - const float aspectRatio = (float) window->wl.width / (float) window->wl.height; + const float aspectRatio = (float) width / (float) height; const float targetRatio = (float) numer / (float) denom; if (aspectRatio < targetRatio) - window->wl.height = window->wl.width / targetRatio; + height /= targetRatio; else if (aspectRatio > targetRatio) - window->wl.width = window->wl.height * targetRatio; + width *= targetRatio; + } - resizeWindow(window); + if (resizeWindow(window, width, height)) + { + if (window->wl.libdecor.frame) + { + struct libdecor_state* frameState = + libdecor_state_new(window->wl.width, window->wl.height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + } + + _glfwInputWindowSize(window, window->wl.width, window->wl.height); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height) { - _glfwGetWindowSizeWayland(window, width, height); if (width) - *width *= window->wl.scale; + *width = window->wl.fbWidth; if (height) - *height *= window->wl.scale; + *height = window->wl.fbHeight; } void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window, int* left, int* top, int* right, int* bottom) { - if (window->decorated && !window->monitor && window->wl.decorations.top.surface) + if (window->wl.fallback.decorations) { if (top) *top = GLFW_CAPTION_HEIGHT; @@ -2019,15 +2363,27 @@ void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window, void _glfwGetWindowContentScaleWayland(_GLFWwindow* window, float* xscale, float* yscale) { - if (xscale) - *xscale = (float) window->wl.scale; - if (yscale) - *yscale = (float) window->wl.scale; + if (window->wl.fractionalScale) + { + if (xscale) + *xscale = (float) window->wl.scalingNumerator / 120.f; + if (yscale) + *yscale = (float) window->wl.scalingNumerator / 120.f; + } + else + { + if (xscale) + *xscale = (float) window->wl.bufferScale; + if (yscale) + *yscale = (float) window->wl.bufferScale; + } } void _glfwIconifyWindowWayland(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_minimized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_minimized(window->wl.xdg.toplevel); } @@ -2044,7 +2400,9 @@ void _glfwRestoreWindowWayland(_GLFWwindow* window) if (window->wl.maximized) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_unset_maximized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); else window->wl.maximized = GLFW_FALSE; @@ -2054,7 +2412,9 @@ void _glfwRestoreWindowWayland(_GLFWwindow* window) void _glfwMaximizeWindowWayland(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_maximized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); else window->wl.maximized = GLFW_TRUE; @@ -2062,7 +2422,7 @@ void _glfwMaximizeWindowWayland(_GLFWwindow* window) void _glfwShowWindowWayland(_GLFWwindow* window) { - if (!window->wl.xdg.toplevel) + if (!window->wl.libdecor.frame && !window->wl.xdg.toplevel) { // NOTE: The XDG surface and role are created here so command-line applications // with off-screen windows do not appear in for example the Unity dock @@ -2084,15 +2444,54 @@ void _glfwHideWindowWayland(_GLFWwindow* window) void _glfwRequestWindowAttentionWayland(_GLFWwindow* window) { - // TODO - _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, - "Wayland: Window attention request not implemented yet"); + if (!_glfw.wl.activationManager) + return; + + // We're about to overwrite this with a new request + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); + + window->wl.activationToken = + xdg_activation_v1_get_activation_token(_glfw.wl.activationManager); + xdg_activation_token_v1_add_listener(window->wl.activationToken, + &xdgActivationListener, + window); + + xdg_activation_token_v1_commit(window->wl.activationToken); } void _glfwFocusWindowWayland(_GLFWwindow* window) { - _glfwInputError(GLFW_FEATURE_UNAVAILABLE, - "Wayland: The platform does not support setting the input focus"); + if (!_glfw.wl.activationManager) + return; + + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); + + window->wl.activationToken = + xdg_activation_v1_get_activation_token(_glfw.wl.activationManager); + xdg_activation_token_v1_add_listener(window->wl.activationToken, + &xdgActivationListener, + window); + + xdg_activation_token_v1_set_serial(window->wl.activationToken, + _glfw.wl.serial, + _glfw.wl.seat); + + _GLFWwindow* requester = _glfw.wl.keyboardFocus; + if (requester) + { + xdg_activation_token_v1_set_surface(window->wl.activationToken, + requester->wl.surface); + + if (requester->wl.appId) + { + xdg_activation_token_v1_set_app_id(window->wl.activationToken, + requester->wl.appId); + } + } + + xdg_activation_token_v1_commit(window->wl.activationToken); } void _glfwSetWindowMonitorWayland(_GLFWwindow* window, @@ -2154,14 +2553,30 @@ GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window) void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled) { - // TODO - _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, - "Wayland: Window attribute setting not implemented yet"); + if (window->wl.libdecor.frame) + { + if (enabled) + { + libdecor_frame_set_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + else + { + libdecor_frame_unset_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + } + else if (window->wl.xdg.toplevel) + updateXdgSizeLimits(window); } void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled) { - if (window->wl.xdg.decoration) + if (window->wl.libdecor.frame) + { + libdecor_frame_set_visibility(window->wl.libdecor.frame, enabled); + } + else if (window->wl.xdg.decoration) { uint32_t mode; @@ -2172,7 +2587,7 @@ void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled) zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); } - else + else if (window->wl.xdg.toplevel) { if (enabled) createFallbackDecorations(window); @@ -2196,7 +2611,7 @@ void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled wl_region_destroy(region); } else - wl_surface_set_input_region(window->wl.surface, 0); + wl_surface_set_input_region(window->wl.surface, NULL); } float _glfwGetWindowOpacityWayland(_GLFWwindow* window) @@ -2263,8 +2678,7 @@ void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode) const char* _glfwGetScancodeNameWayland(int scancode) { - if (scancode < 0 || scancode > 255 || - _glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > 255) { _glfwInputError(GLFW_INVALID_VALUE, "Wayland: Invalid scancode %i", @@ -2273,6 +2687,9 @@ const char* _glfwGetScancodeNameWayland(int scancode) } const int key = _glfw.wl.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; + const xkb_keycode_t keycode = scancode + 8; const xkb_layout_index_t layout = xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode); @@ -2582,7 +2999,7 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor) // If we're not in the correct window just save the cursor // the next time the pointer enters the window the cursor will change - if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow) + if (!window->wl.hovered) return; // Update pointer lock to match cursor mode @@ -2887,3 +3304,5 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) return window->wl.surface; } +#endif // _GLFW_WAYLAND + diff --git a/raylib/external/glfw/src/x11_init.c b/raylib/external/glfw/src/x11_init.c index 11aeb9e..e992f44 100644 --- a/raylib/external/glfw/src/x11_init.c +++ b/raylib/external/glfw/src/x11_init.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) + #include #include #include @@ -1166,86 +1166,86 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) { const _GLFWplatform x11 = { - GLFW_PLATFORM_X11, - _glfwInitX11, - _glfwTerminateX11, - _glfwGetCursorPosX11, - _glfwSetCursorPosX11, - _glfwSetCursorModeX11, - _glfwSetRawMouseMotionX11, - _glfwRawMouseMotionSupportedX11, - _glfwCreateCursorX11, - _glfwCreateStandardCursorX11, - _glfwDestroyCursorX11, - _glfwSetCursorX11, - _glfwGetScancodeNameX11, - _glfwGetKeyScancodeX11, - _glfwSetClipboardStringX11, - _glfwGetClipboardStringX11, -#if defined(__linux__) - _glfwInitJoysticksLinux, - _glfwTerminateJoysticksLinux, - _glfwPollJoystickLinux, - _glfwGetMappingNameLinux, - _glfwUpdateGamepadGUIDLinux, + .platformID = GLFW_PLATFORM_X11, + .init = _glfwInitX11, + .terminate = _glfwTerminateX11, + .getCursorPos = _glfwGetCursorPosX11, + .setCursorPos = _glfwSetCursorPosX11, + .setCursorMode = _glfwSetCursorModeX11, + .setRawMouseMotion = _glfwSetRawMouseMotionX11, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedX11, + .createCursor = _glfwCreateCursorX11, + .createStandardCursor = _glfwCreateStandardCursorX11, + .destroyCursor = _glfwDestroyCursorX11, + .setCursor = _glfwSetCursorX11, + .getScancodeName = _glfwGetScancodeNameX11, + .getKeyScancode = _glfwGetKeyScancodeX11, + .setClipboardString = _glfwSetClipboardStringX11, + .getClipboardString = _glfwGetClipboardStringX11, +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + .initJoysticks = _glfwInitJoysticksLinux, + .terminateJoysticks = _glfwTerminateJoysticksLinux, + .pollJoystick = _glfwPollJoystickLinux, + .getMappingName = _glfwGetMappingNameLinux, + .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, #else - _glfwInitJoysticksNull, - _glfwTerminateJoysticksNull, - _glfwPollJoystickNull, - _glfwGetMappingNameNull, - _glfwUpdateGamepadGUIDNull, + .initJoysticks = _glfwInitJoysticksNull, + .terminateJoysticks = _glfwTerminateJoysticksNull, + .pollJoystick = _glfwPollJoystickNull, + .getMappingName = _glfwGetMappingNameNull, + .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, #endif - _glfwFreeMonitorX11, - _glfwGetMonitorPosX11, - _glfwGetMonitorContentScaleX11, - _glfwGetMonitorWorkareaX11, - _glfwGetVideoModesX11, - _glfwGetVideoModeX11, - _glfwGetGammaRampX11, - _glfwSetGammaRampX11, - _glfwCreateWindowX11, - _glfwDestroyWindowX11, - _glfwSetWindowTitleX11, - _glfwSetWindowIconX11, - _glfwGetWindowPosX11, - _glfwSetWindowPosX11, - _glfwGetWindowSizeX11, - _glfwSetWindowSizeX11, - _glfwSetWindowSizeLimitsX11, - _glfwSetWindowAspectRatioX11, - _glfwGetFramebufferSizeX11, - _glfwGetWindowFrameSizeX11, - _glfwGetWindowContentScaleX11, - _glfwIconifyWindowX11, - _glfwRestoreWindowX11, - _glfwMaximizeWindowX11, - _glfwShowWindowX11, - _glfwHideWindowX11, - _glfwRequestWindowAttentionX11, - _glfwFocusWindowX11, - _glfwSetWindowMonitorX11, - _glfwWindowFocusedX11, - _glfwWindowIconifiedX11, - _glfwWindowVisibleX11, - _glfwWindowMaximizedX11, - _glfwWindowHoveredX11, - _glfwFramebufferTransparentX11, - _glfwGetWindowOpacityX11, - _glfwSetWindowResizableX11, - _glfwSetWindowDecoratedX11, - _glfwSetWindowFloatingX11, - _glfwSetWindowOpacityX11, - _glfwSetWindowMousePassthroughX11, - _glfwPollEventsX11, - _glfwWaitEventsX11, - _glfwWaitEventsTimeoutX11, - _glfwPostEmptyEventX11, - _glfwGetEGLPlatformX11, - _glfwGetEGLNativeDisplayX11, - _glfwGetEGLNativeWindowX11, - _glfwGetRequiredInstanceExtensionsX11, - _glfwGetPhysicalDevicePresentationSupportX11, - _glfwCreateWindowSurfaceX11, + .freeMonitor = _glfwFreeMonitorX11, + .getMonitorPos = _glfwGetMonitorPosX11, + .getMonitorContentScale = _glfwGetMonitorContentScaleX11, + .getMonitorWorkarea = _glfwGetMonitorWorkareaX11, + .getVideoModes = _glfwGetVideoModesX11, + .getVideoMode = _glfwGetVideoModeX11, + .getGammaRamp = _glfwGetGammaRampX11, + .setGammaRamp = _glfwSetGammaRampX11, + .createWindow = _glfwCreateWindowX11, + .destroyWindow = _glfwDestroyWindowX11, + .setWindowTitle = _glfwSetWindowTitleX11, + .setWindowIcon = _glfwSetWindowIconX11, + .getWindowPos = _glfwGetWindowPosX11, + .setWindowPos = _glfwSetWindowPosX11, + .getWindowSize = _glfwGetWindowSizeX11, + .setWindowSize = _glfwSetWindowSizeX11, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsX11, + .setWindowAspectRatio = _glfwSetWindowAspectRatioX11, + .getFramebufferSize = _glfwGetFramebufferSizeX11, + .getWindowFrameSize = _glfwGetWindowFrameSizeX11, + .getWindowContentScale = _glfwGetWindowContentScaleX11, + .iconifyWindow = _glfwIconifyWindowX11, + .restoreWindow = _glfwRestoreWindowX11, + .maximizeWindow = _glfwMaximizeWindowX11, + .showWindow = _glfwShowWindowX11, + .hideWindow = _glfwHideWindowX11, + .requestWindowAttention = _glfwRequestWindowAttentionX11, + .focusWindow = _glfwFocusWindowX11, + .setWindowMonitor = _glfwSetWindowMonitorX11, + .windowFocused = _glfwWindowFocusedX11, + .windowIconified = _glfwWindowIconifiedX11, + .windowVisible = _glfwWindowVisibleX11, + .windowMaximized = _glfwWindowMaximizedX11, + .windowHovered = _glfwWindowHoveredX11, + .framebufferTransparent = _glfwFramebufferTransparentX11, + .getWindowOpacity = _glfwGetWindowOpacityX11, + .setWindowResizable = _glfwSetWindowResizableX11, + .setWindowDecorated = _glfwSetWindowDecoratedX11, + .setWindowFloating = _glfwSetWindowFloatingX11, + .setWindowOpacity = _glfwSetWindowOpacityX11, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughX11, + .pollEvents = _glfwPollEventsX11, + .waitEvents = _glfwWaitEventsX11, + .waitEventsTimeout = _glfwWaitEventsTimeoutX11, + .postEmptyEvent = _glfwPostEmptyEventX11, + .getEGLPlatform = _glfwGetEGLPlatformX11, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayX11, + .getEGLNativeWindow = _glfwGetEGLNativeWindowX11, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsX11, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportX11, + .createWindowSurface = _glfwCreateWindowSurfaceX11 }; // HACK: If the application has left the locale as "C" then both wide @@ -1652,3 +1652,5 @@ void _glfwTerminateX11(void) } } +#endif // _GLFW_X11 + diff --git a/raylib/external/glfw/src/x11_monitor.c b/raylib/external/glfw/src/x11_monitor.c index b031c83..38af7e0 100644 --- a/raylib/external/glfw/src/x11_monitor.c +++ b/raylib/external/glfw/src/x11_monitor.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) + #include #include #include @@ -491,24 +491,31 @@ GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count) return result; } -void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); - XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + const XRRModeInfo* mi = NULL; + XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); if (ci) { - const XRRModeInfo* mi = getModeInfo(sr, ci->mode); - if (mi) // mi can be NULL if the monitor has been disconnected + mi = getModeInfo(sr, ci->mode); + if (mi) *mode = vidmodeFromModeInfo(mi, ci); XRRFreeCrtcInfo(ci); } XRRFreeScreenResources(sr); + + if (!mi) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query video mode"); + return GLFW_FALSE; + } } else { @@ -519,6 +526,8 @@ void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode) _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), &mode->redBits, &mode->greenBits, &mode->blueBits); } + + return GLFW_TRUE; } GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp) @@ -604,6 +613,13 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return None; + } + return monitor->x11.crtc; } @@ -611,6 +627,15 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return None; + } + return monitor->x11.output; } +#endif // _GLFW_X11 + diff --git a/raylib/external/glfw/src/x11_platform.h b/raylib/external/glfw/src/x11_platform.h index cdea395..14e363d 100644 --- a/raylib/external/glfw/src/x11_platform.h +++ b/raylib/external/glfw/src/x11_platform.h @@ -968,7 +968,7 @@ void _glfwGetMonitorPosX11(_GLFWmonitor* monitor, int* xpos, int* ypos); void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count); -void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); diff --git a/raylib/external/glfw/src/x11_window.c b/raylib/external/glfw/src/x11_window.c index 8a689ed..e029546 100644 --- a/raylib/external/glfw/src/x11_window.c +++ b/raylib/external/glfw/src/x11_window.c @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) + #include #include @@ -79,24 +79,25 @@ static GLFWbool waitForX11Event(double* timeout) // static GLFWbool waitForAnyEvent(double* timeout) { - nfds_t count = 2; - struct pollfd fds[3] = + enum { XLIB_FD, PIPE_FD, INOTIFY_FD }; + struct pollfd fds[] = { - { ConnectionNumber(_glfw.x11.display), POLLIN }, - { _glfw.x11.emptyEventPipe[0], POLLIN } + [XLIB_FD] = { ConnectionNumber(_glfw.x11.display), POLLIN }, + [PIPE_FD] = { _glfw.x11.emptyEventPipe[0], POLLIN }, + [INOTIFY_FD] = { -1, POLLIN } }; -#if defined(__linux__) +#if defined(GLFW_BUILD_LINUX_JOYSTICK) if (_glfw.joysticksInitialized) - fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN }; + fds[INOTIFY_FD].fd = _glfw.linjs.inotify; #endif while (!XPending(_glfw.x11.display)) { - if (!_glfwPollPOSIX(fds, count, timeout)) + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) return GLFW_FALSE; - for (int i = 1; i < count; i++) + for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++) { if (fds[i].revents & POLLIN) return GLFW_TRUE; @@ -1487,6 +1488,9 @@ static void processEvent(XEvent *event) if (event->xconfigure.width != window->x11.width || event->xconfigure.height != window->x11.height) { + window->x11.width = event->xconfigure.width; + window->x11.height = event->xconfigure.height; + _glfwInputFramebufferSize(window, event->xconfigure.width, event->xconfigure.height); @@ -1494,9 +1498,6 @@ static void processEvent(XEvent *event) _glfwInputWindowSize(window, event->xconfigure.width, event->xconfigure.height); - - window->x11.width = event->xconfigure.width; - window->x11.height = event->xconfigure.height; } int xpos = event->xconfigure.x; @@ -1524,9 +1525,10 @@ static void processEvent(XEvent *event) if (xpos != window->x11.xpos || ypos != window->x11.ypos) { - _glfwInputWindowPos(window, xpos, ypos); window->x11.xpos = xpos; window->x11.ypos = ypos; + + _glfwInputWindowPos(window, xpos, ypos); } return; @@ -2781,7 +2783,7 @@ void _glfwPollEventsX11(void) { drainEmptyEvents(); -#if defined(__linux__) +#if defined(GLFW_BUILD_LINUX_JOYSTICK) if (_glfw.joysticksInitialized) _glfwDetectJoystickConnectionLinux(); #endif @@ -2901,14 +2903,16 @@ const char* _glfwGetScancodeNameX11(int scancode) if (!_glfw.x11.xkb.available) return NULL; - if (scancode < 0 || scancode > 0xff || - _glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > 0xff) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } const int key = _glfw.x11.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; + const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0); if (keysym == NoSymbol) @@ -3349,3 +3353,5 @@ GLFWAPI const char* glfwGetX11SelectionString(void) return getSelectionString(_glfw.x11.PRIMARY); } +#endif // _GLFW_X11 + diff --git a/raylib/external/glfw/src/xkb_unicode.c b/raylib/external/glfw/src/xkb_unicode.c index 1b2482c..6b8dfca 100644 --- a/raylib/external/glfw/src/xkb_unicode.c +++ b/raylib/external/glfw/src/xkb_unicode.c @@ -24,11 +24,10 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) /* * Marcus: This code was originally written by Markus G. Kuhn. @@ -940,3 +939,5 @@ uint32_t _glfwKeySym2Unicode(unsigned int keysym) return GLFW_INVALID_CODEPOINT; } +#endif // _GLFW_WAYLAND or _GLFW_X11 + From ce43cc1f103591edae4cac55a5bde55d1ff7fc37 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:24:04 +0100 Subject: [PATCH 030/278] Remove deps --- raylib/external/glfw/deps/getopt.c | 230 - raylib/external/glfw/deps/getopt.h | 57 - raylib/external/glfw/deps/glad/gl.h | 5996 ---------------- raylib/external/glfw/deps/glad/gles2.h | 1805 ----- raylib/external/glfw/deps/glad/vulkan.h | 6330 ----------------- .../glfw/deps/mingw/_mingw_dxhelper.h | 117 - raylib/external/glfw/deps/mingw/dinput.h | 2467 ------- raylib/external/glfw/deps/mingw/xinput.h | 239 - raylib/external/glfw/deps/vs2008/stdint.h | 247 - 9 files changed, 17488 deletions(-) delete mode 100644 raylib/external/glfw/deps/getopt.c delete mode 100644 raylib/external/glfw/deps/getopt.h delete mode 100644 raylib/external/glfw/deps/glad/gl.h delete mode 100644 raylib/external/glfw/deps/glad/gles2.h delete mode 100644 raylib/external/glfw/deps/glad/vulkan.h delete mode 100644 raylib/external/glfw/deps/mingw/_mingw_dxhelper.h delete mode 100644 raylib/external/glfw/deps/mingw/dinput.h delete mode 100644 raylib/external/glfw/deps/mingw/xinput.h delete mode 100644 raylib/external/glfw/deps/vs2008/stdint.h diff --git a/raylib/external/glfw/deps/getopt.c b/raylib/external/glfw/deps/getopt.c deleted file mode 100644 index 9743046..0000000 --- a/raylib/external/glfw/deps/getopt.c +++ /dev/null @@ -1,230 +0,0 @@ -/* Copyright (c) 2012, Kim Gräsman - * 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 Kim Gräsman nor the names of 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 KIM GRÄSMAN 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. - */ - -#include "getopt.h" - -#include -#include - -const int no_argument = 0; -const int required_argument = 1; -const int optional_argument = 2; - -char* optarg; -int optopt; -/* The variable optind [...] shall be initialized to 1 by the system. */ -int optind = 1; -int opterr; - -static char* optcursor = NULL; - -/* Implemented based on [1] and [2] for optional arguments. - optopt is handled FreeBSD-style, per [3]. - Other GNU and FreeBSD extensions are purely accidental. - -[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html -[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html -[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE -*/ -int getopt(int argc, char* const argv[], const char* optstring) { - int optchar = -1; - const char* optdecl = NULL; - - optarg = NULL; - opterr = 0; - optopt = 0; - - /* Unspecified, but we need it to avoid overrunning the argv bounds. */ - if (optind >= argc) - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] is a null pointer, getopt() - shall return -1 without changing optind. */ - if (argv[optind] == NULL) - goto no_more_optchars; - - /* If, when getopt() is called *argv[optind] is not the character '-', - getopt() shall return -1 without changing optind. */ - if (*argv[optind] != '-') - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] points to the string "-", - getopt() shall return -1 without changing optind. */ - if (strcmp(argv[optind], "-") == 0) - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] points to the string "--", - getopt() shall return -1 after incrementing optind. */ - if (strcmp(argv[optind], "--") == 0) { - ++optind; - goto no_more_optchars; - } - - if (optcursor == NULL || *optcursor == '\0') - optcursor = argv[optind] + 1; - - optchar = *optcursor; - - /* FreeBSD: The variable optopt saves the last known option character - returned by getopt(). */ - optopt = optchar; - - /* The getopt() function shall return the next option character (if one is - found) from argv that matches a character in optstring, if there is - one that matches. */ - optdecl = strchr(optstring, optchar); - if (optdecl) { - /* [I]f a character is followed by a colon, the option takes an - argument. */ - if (optdecl[1] == ':') { - optarg = ++optcursor; - if (*optarg == '\0') { - /* GNU extension: Two colons mean an option takes an - optional arg; if there is text in the current argv-element - (i.e., in the same word as the option name itself, for example, - "-oarg"), then it is returned in optarg, otherwise optarg is set - to zero. */ - if (optdecl[2] != ':') { - /* If the option was the last character in the string pointed to by - an element of argv, then optarg shall contain the next element - of argv, and optind shall be incremented by 2. If the resulting - value of optind is greater than argc, this indicates a missing - option-argument, and getopt() shall return an error indication. - - Otherwise, optarg shall point to the string following the - option character in that element of argv, and optind shall be - incremented by 1. - */ - if (++optind < argc) { - optarg = argv[optind]; - } else { - /* If it detects a missing option-argument, it shall return the - colon character ( ':' ) if the first character of optstring - was a colon, or a question-mark character ( '?' ) otherwise. - */ - optarg = NULL; - optchar = (optstring[0] == ':') ? ':' : '?'; - } - } else { - optarg = NULL; - } - } - - optcursor = NULL; - } - } else { - /* If getopt() encounters an option character that is not contained in - optstring, it shall return the question-mark ( '?' ) character. */ - optchar = '?'; - } - - if (optcursor == NULL || *++optcursor == '\0') - ++optind; - - return optchar; - -no_more_optchars: - optcursor = NULL; - return -1; -} - -/* Implementation based on [1]. - -[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html -*/ -int getopt_long(int argc, char* const argv[], const char* optstring, - const struct option* longopts, int* longindex) { - const struct option* o = longopts; - const struct option* match = NULL; - int num_matches = 0; - size_t argument_name_length = 0; - const char* current_argument = NULL; - int retval = -1; - - optarg = NULL; - optopt = 0; - - if (optind >= argc) - return -1; - - if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) - return getopt(argc, argv, optstring); - - /* It's an option; starts with -- and is longer than two chars. */ - current_argument = argv[optind] + 2; - argument_name_length = strcspn(current_argument, "="); - for (; o->name; ++o) { - if (strncmp(o->name, current_argument, argument_name_length) == 0) { - match = o; - ++num_matches; - } - } - - if (num_matches == 1) { - /* If longindex is not NULL, it points to a variable which is set to the - index of the long option relative to longopts. */ - if (longindex) - *longindex = (int) (match - longopts); - - /* If flag is NULL, then getopt_long() shall return val. - Otherwise, getopt_long() returns 0, and flag shall point to a variable - which shall be set to val if the option is found, but left unchanged if - the option is not found. */ - if (match->flag) - *(match->flag) = match->val; - - retval = match->flag ? 0 : match->val; - - if (match->has_arg != no_argument) { - optarg = strchr(argv[optind], '='); - if (optarg != NULL) - ++optarg; - - if (match->has_arg == required_argument) { - /* Only scan the next argv for required arguments. Behavior is not - specified, but has been observed with Ubuntu and Mac OSX. */ - if (optarg == NULL && ++optind < argc) { - optarg = argv[optind]; - } - - if (optarg == NULL) - retval = ':'; - } - } else if (strchr(argv[optind], '=')) { - /* An argument was provided to a non-argument option. - I haven't seen this specified explicitly, but both GNU and BSD-based - implementations show this behavior. - */ - retval = '?'; - } - } else { - /* Unknown option or ambiguous match. */ - retval = '?'; - } - - ++optind; - return retval; -} diff --git a/raylib/external/glfw/deps/getopt.h b/raylib/external/glfw/deps/getopt.h deleted file mode 100644 index e1eb540..0000000 --- a/raylib/external/glfw/deps/getopt.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2012, Kim Gräsman - * 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 Kim Gräsman nor the names of 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 KIM GRÄSMAN 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. - */ - -#ifndef INCLUDED_GETOPT_PORT_H -#define INCLUDED_GETOPT_PORT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -extern const int no_argument; -extern const int required_argument; -extern const int optional_argument; - -extern char* optarg; -extern int optind, opterr, optopt; - -struct option { - const char* name; - int has_arg; - int* flag; - int val; -}; - -int getopt(int argc, char* const argv[], const char* optstring); - -int getopt_long(int argc, char* const argv[], - const char* optstring, const struct option* longopts, int* longindex); - -#if defined(__cplusplus) -} -#endif - -#endif // INCLUDED_GETOPT_PORT_H diff --git a/raylib/external/glfw/deps/glad/gl.h b/raylib/external/glfw/deps/glad/gl.h deleted file mode 100644 index b421fe0..0000000 --- a/raylib/external/glfw/deps/glad/gl.h +++ /dev/null @@ -1,5996 +0,0 @@ -/** - * Loader generated by glad 2.0.0-beta on Tue Aug 24 22:51:07 2021 - * - * Generator: C/C++ - * Specification: gl - * Extensions: 3 - * - * APIs: - * - gl:compatibility=3.3 - * - * Options: - * - ALIAS = False - * - DEBUG = False - * - HEADER_ONLY = True - * - LOADER = False - * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False - * - * Commandline: - * --api='gl:compatibility=3.3' --extensions='GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug' c --header-only - * - * Online: - * http://glad.sh/#api=gl%3Acompatibility%3D3.3&extensions=GL_ARB_multisample%2CGL_ARB_robustness%2CGL_KHR_debug&generator=c&options=HEADER_ONLY - * - */ - -#ifndef GLAD_GL_H_ -#define GLAD_GL_H_ - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wreserved-id-macro" -#endif -#ifdef __gl_h_ - #error OpenGL (gl.h) header already included (API: gl), remove previous include! -#endif -#define __gl_h_ 1 -#ifdef __gl3_h_ - #error OpenGL (gl3.h) header already included (API: gl), remove previous include! -#endif -#define __gl3_h_ 1 -#ifdef __glext_h_ - #error OpenGL (glext.h) header already included (API: gl), remove previous include! -#endif -#define __glext_h_ 1 -#ifdef __gl3ext_h_ - #error OpenGL (gl3ext.h) header already included (API: gl), remove previous include! -#endif -#define __gl3ext_h_ 1 -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#define GLAD_GL -#define GLAD_OPTION_GL_HEADER_ONLY - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef GLAD_PLATFORM_H_ -#define GLAD_PLATFORM_H_ - -#ifndef GLAD_PLATFORM_WIN32 - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) - #define GLAD_PLATFORM_WIN32 1 - #else - #define GLAD_PLATFORM_WIN32 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_APPLE - #ifdef __APPLE__ - #define GLAD_PLATFORM_APPLE 1 - #else - #define GLAD_PLATFORM_APPLE 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_EMSCRIPTEN - #ifdef __EMSCRIPTEN__ - #define GLAD_PLATFORM_EMSCRIPTEN 1 - #else - #define GLAD_PLATFORM_EMSCRIPTEN 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_UWP - #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) - #ifdef __has_include - #if __has_include() - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #endif - - #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY - #include - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define GLAD_PLATFORM_UWP 1 - #endif - #endif - - #ifndef GLAD_PLATFORM_UWP - #define GLAD_PLATFORM_UWP 0 - #endif -#endif - -#ifdef __GNUC__ - #define GLAD_GNUC_EXTENSION __extension__ -#else - #define GLAD_GNUC_EXTENSION -#endif - -#ifndef GLAD_API_CALL - #if defined(GLAD_API_CALL_EXPORT) - #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) - #if defined(GLAD_API_CALL_EXPORT_BUILD) - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllexport)) extern - #else - #define GLAD_API_CALL __declspec(dllexport) extern - #endif - #else - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllimport)) extern - #else - #define GLAD_API_CALL __declspec(dllimport) extern - #endif - #endif - #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) - #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern - #else - #define GLAD_API_CALL extern - #endif - #else - #define GLAD_API_CALL extern - #endif -#endif - -#ifdef APIENTRY - #define GLAD_API_PTR APIENTRY -#elif GLAD_PLATFORM_WIN32 - #define GLAD_API_PTR __stdcall -#else - #define GLAD_API_PTR -#endif - -#ifndef GLAPI -#define GLAPI GLAD_API_CALL -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY GLAD_API_PTR -#endif - -#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) -#define GLAD_VERSION_MAJOR(version) (version / 10000) -#define GLAD_VERSION_MINOR(version) (version % 10000) - -#define GLAD_GENERATOR_VERSION "2.0.0-beta" - -typedef void (*GLADapiproc)(void); - -typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); - -typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); -typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); - -#endif /* GLAD_PLATFORM_H_ */ - -#define GL_2D 0x0600 -#define GL_2_BYTES 0x1407 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_3_BYTES 0x1408 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_4_BYTES 0x1409 -#define GL_ACCUM 0x0100 -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ADD 0x0104 -#define GL_ADD_SIGNED 0x8574 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_ALPHA 0x1906 -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_ALPHA_BITS 0x0D55 -#define GL_ALPHA_INTEGER 0x8D97 -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_ALWAYS 0x0207 -#define GL_AMBIENT 0x1200 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_AND 0x1501 -#define GL_AND_INVERTED 0x1504 -#define GL_AND_REVERSE 0x1502 -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_AUX_BUFFERS 0x0C00 -#define GL_BACK 0x0405 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_BGRA_INTEGER 0x8D9B -#define GL_BGR_INTEGER 0x8D9A -#define GL_BITMAP 0x1A00 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_BLEND 0x0BE2 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLUE 0x1905 -#define GL_BLUE_BIAS 0x0D1B -#define GL_BLUE_BITS 0x0D54 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_BUFFER 0x82E0 -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_BYTE 0x1400 -#define GL_C3F_V3F 0x2A24 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_CCW 0x0901 -#define GL_CLAMP 0x2900 -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLEAR 0x1500 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_COEFF 0x0A00 -#define GL_COLOR 0x1800 -#define GL_COLOR_ARRAY 0x8076 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_COLOR_ATTACHMENT16 0x8CF0 -#define GL_COLOR_ATTACHMENT17 0x8CF1 -#define GL_COLOR_ATTACHMENT18 0x8CF2 -#define GL_COLOR_ATTACHMENT19 0x8CF3 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT20 0x8CF4 -#define GL_COLOR_ATTACHMENT21 0x8CF5 -#define GL_COLOR_ATTACHMENT22 0x8CF6 -#define GL_COLOR_ATTACHMENT23 0x8CF7 -#define GL_COLOR_ATTACHMENT24 0x8CF8 -#define GL_COLOR_ATTACHMENT25 0x8CF9 -#define GL_COLOR_ATTACHMENT26 0x8CFA -#define GL_COLOR_ATTACHMENT27 0x8CFB -#define GL_COLOR_ATTACHMENT28 0x8CFC -#define GL_COLOR_ATTACHMENT29 0x8CFD -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT30 0x8CFE -#define GL_COLOR_ATTACHMENT31 0x8CFF -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_INDEX 0x1900 -#define GL_COLOR_INDEXES 0x1603 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_SUM 0x8458 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_COMBINE 0x8570 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_RG 0x8226 -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CONDITION_SATISFIED 0x911C -#define GL_CONSTANT 0x8576 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_FLAGS 0x821E -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_COORD_REPLACE 0x8862 -#define GL_COPY 0x1503 -#define GL_COPY_INVERTED 0x150C -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_CURRENT_BIT 0x00000001 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_CURRENT_QUERY 0x8865 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_CW 0x0900 -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DECAL 0x2101 -#define GL_DECR 0x1E03 -#define GL_DECR_WRAP 0x8508 -#define GL_DELETE_STATUS 0x8B80 -#define GL_DEPTH 0x1801 -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_DEPTH_BIAS 0x0D1F -#define GL_DEPTH_BITS 0x0D56 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_DEPTH_CLAMP 0x864F -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH_FUNC 0x0B74 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DIFFUSE 0x1201 -#define GL_DISPLAY_LIST 0x82E7 -#define GL_DITHER 0x0BD0 -#define GL_DOMAIN 0x0A02 -#define GL_DONT_CARE 0x1100 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#define GL_DOUBLE 0x140A -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_DST_ALPHA 0x0304 -#define GL_DST_COLOR 0x0306 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_EDGE_FLAG 0x0B43 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_EMISSION 0x1600 -#define GL_ENABLE_BIT 0x00002000 -#define GL_EQUAL 0x0202 -#define GL_EQUIV 0x1509 -#define GL_EVAL_BIT 0x00010000 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 -#define GL_EXTENSIONS 0x1F03 -#define GL_EYE_LINEAR 0x2400 -#define GL_EYE_PLANE 0x2502 -#define GL_FALSE 0 -#define GL_FASTEST 0x1101 -#define GL_FEEDBACK 0x1C01 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_FILL 0x1B02 -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_FIXED_ONLY 0x891D -#define GL_FLAT 0x1D00 -#define GL_FLOAT 0x1406 -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4 0x8B5C -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_FOG 0x0B60 -#define GL_FOG_BIT 0x00000080 -#define GL_FOG_COLOR 0x0B66 -#define GL_FOG_COORD 0x8451 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_END 0x0B64 -#define GL_FOG_HINT 0x0C54 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_START 0x0B63 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_FRAMEBUFFER 0x8D40 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_FRONT 0x0404 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_FRONT_FACE 0x0B46 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_FUNC_SUBTRACT 0x800A -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEQUAL 0x0206 -#define GL_GREATER 0x0204 -#define GL_GREEN 0x1904 -#define GL_GREEN_BIAS 0x0D19 -#define GL_GREEN_BITS 0x0D53 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#define GL_HALF_FLOAT 0x140B -#define GL_HINT_BIT 0x00008000 -#define GL_INCR 0x1E02 -#define GL_INCR_WRAP 0x8507 -#define GL_INDEX 0x8222 -#define GL_INDEX_ARRAY 0x8077 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_BITS 0x0D51 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_INDEX_MODE 0x0C30 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#define GL_INT 0x1404 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_INTERPOLATE 0x8575 -#define GL_INT_2_10_10_10_REV 0x8D9F -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_INVALID_INDEX 0xFFFFFFFF -#define GL_INVALID_OPERATION 0x0502 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVERT 0x150A -#define GL_KEEP 0x1E00 -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_LEFT 0x0406 -#define GL_LEQUAL 0x0203 -#define GL_LESS 0x0201 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LINE 0x1B01 -#define GL_LINEAR 0x2601 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_LINES 0x0001 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_BIT 0x00000004 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LINE_STRIP 0x0003 -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_LINE_TOKEN 0x0702 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINK_STATUS 0x8B82 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_BIT 0x00020000 -#define GL_LIST_INDEX 0x0B33 -#define GL_LIST_MODE 0x0B30 -#define GL_LOAD 0x0101 -#define GL_LOGIC_OP 0x0BF1 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_MAJOR_VERSION 0x821B -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_STENCIL 0x0D11 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_MAX 0x8008 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MIN 0x8007 -#define GL_MINOR_VERSION 0x821C -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MODELVIEW 0x1700 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_MODULATE 0x2100 -#define GL_MULT 0x0103 -#define GL_MULTISAMPLE 0x809D -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -#define GL_N3F_V3F 0x2A25 -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_NAND 0x150E -#define GL_NEAREST 0x2600 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_NEVER 0x0200 -#define GL_NICEST 0x1102 -#define GL_NONE 0 -#define GL_NOOP 0x1505 -#define GL_NOR 0x1508 -#define GL_NORMALIZE 0x0BA1 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_MAP 0x8511 -#define GL_NOTEQUAL 0x0205 -#define GL_NO_ERROR 0 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_NUM_EXTENSIONS 0x821D -#define GL_OBJECT_LINEAR 0x2401 -#define GL_OBJECT_PLANE 0x2501 -#define GL_OBJECT_TYPE 0x9112 -#define GL_ONE 1 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_OPERAND2_RGB 0x8592 -#define GL_OR 0x1507 -#define GL_ORDER 0x0A01 -#define GL_OR_INVERTED 0x150D -#define GL_OR_REVERSE 0x150B -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_POINT 0x1B00 -#define GL_POINTS 0x0000 -#define GL_POINT_BIT 0x00000002 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_POINT_SPRITE 0x8861 -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_POINT_TOKEN 0x0701 -#define GL_POLYGON 0x0009 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_POSITION 0x1203 -#define GL_PREVIOUS 0x8578 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_PROGRAM 0x82E2 -#define GL_PROGRAM_PIPELINE 0x82E4 -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_PROJECTION 0x1701 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_Q 0x2003 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_QUADS 0x0007 -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_QUAD_STRIP 0x0008 -#define GL_QUERY 0x82E3 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_QUERY_WAIT 0x8E13 -#define GL_R 0x2002 -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_R16 0x822A -#define GL_R16F 0x822D -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R16_SNORM 0x8F98 -#define GL_R32F 0x822E -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_R3_G3_B2 0x2A10 -#define GL_R8 0x8229 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R8_SNORM 0x8F94 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_READ_BUFFER 0x0C02 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_READ_ONLY 0x88B8 -#define GL_READ_WRITE 0x88BA -#define GL_RED 0x1903 -#define GL_RED_BIAS 0x0D15 -#define GL_RED_BITS 0x0D52 -#define GL_RED_INTEGER 0x8D94 -#define GL_RED_SCALE 0x0D14 -#define GL_REFLECTION_MAP 0x8512 -#define GL_RENDER 0x1C00 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERER 0x1F01 -#define GL_RENDER_MODE 0x0C40 -#define GL_REPEAT 0x2901 -#define GL_REPLACE 0x1E01 -#define GL_RESCALE_NORMAL 0x803A -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_RETURN 0x0102 -#define GL_RG 0x8227 -#define GL_RG16 0x822C -#define GL_RG16F 0x822F -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG16_SNORM 0x8F99 -#define GL_RG32F 0x8230 -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_RG8 0x822B -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB 0x1907 -#define GL_RGB10 0x8052 -#define GL_RGB10_A2 0x8059 -#define GL_RGB10_A2UI 0x906F -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGB16F 0x881B -#define GL_RGB16I 0x8D89 -#define GL_RGB16UI 0x8D77 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGB32F 0x8815 -#define GL_RGB32I 0x8D83 -#define GL_RGB32UI 0x8D71 -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB5_A1 0x8057 -#define GL_RGB8 0x8051 -#define GL_RGB8I 0x8D8F -#define GL_RGB8UI 0x8D7D -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGB9_E5 0x8C3D -#define GL_RGBA 0x1908 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_RGBA16F 0x881A -#define GL_RGBA16I 0x8D88 -#define GL_RGBA16UI 0x8D76 -#define GL_RGBA16_SNORM 0x8F9B -#define GL_RGBA2 0x8055 -#define GL_RGBA32F 0x8814 -#define GL_RGBA32I 0x8D82 -#define GL_RGBA32UI 0x8D70 -#define GL_RGBA4 0x8056 -#define GL_RGBA8 0x8058 -#define GL_RGBA8I 0x8D8E -#define GL_RGBA8UI 0x8D7C -#define GL_RGBA8_SNORM 0x8F97 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_RGBA_MODE 0x0C31 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGB_SCALE 0x8573 -#define GL_RG_INTEGER 0x8228 -#define GL_RIGHT 0x0407 -#define GL_S 0x2000 -#define GL_SAMPLER 0x82E6 -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_BINDING 0x8919 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLES_PASSED 0x8914 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SELECT 0x1C02 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_SET 0x150F -#define GL_SHADER 0x82E1 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_TYPE 0x8B4F -#define GL_SHADE_MODEL 0x0B54 -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_SHININESS 0x1601 -#define GL_SHORT 0x1402 -#define GL_SIGNALED 0x9119 -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SMOOTH 0x1D01 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_SOURCE2_RGB 0x8582 -#define GL_SPECULAR 0x1202 -#define GL_SPHERE_MAP 0x2402 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_ALPHA 0x8589 -#define GL_SRC1_COLOR 0x88F9 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_ALPHA 0x858A -#define GL_SRC2_RGB 0x8582 -#define GL_SRC_ALPHA 0x0302 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_SRC_COLOR 0x0300 -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_STATIC_COPY 0x88E6 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STENCIL 0x1802 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_STENCIL_BITS 0x0D57 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_INDEX 0x1901 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STEREO 0x0C33 -#define GL_STREAM_COPY 0x88E2 -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_SUBTRACT 0x84E7 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_SYNC_STATUS 0x9114 -#define GL_T 0x2001 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_C4F_N3F_V4F 0x2A2D -#define GL_T4F_V4F 0x2A28 -#define GL_TEXTURE 0x1702 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_TEXTURE_3D 0x806F -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPONENTS 0x1003 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_TEXTURE_ENV 0x2300 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF -#define GL_TIMESTAMP 0x8E28 -#define GL_TIME_ELAPSED 0x88BF -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_FAN 0x0006 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_TRUE 1 -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNSIGNALED 0x9118 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_INT 0x1405 -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_VENDOR 0x1F00 -#define GL_VERSION 0x1F02 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_VIEWPORT 0x0BA2 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_WAIT_FAILED 0x911D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_WRITE_ONLY 0x88B9 -#define GL_XOR 0x1506 -#define GL_ZERO 0 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 - - -#ifndef __khrplatform_h_ -#define __khrplatform_h_ - -/* -** Copyright (c) 2008-2018 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* Khronos platform-specific types and definitions. - * - * The master copy of khrplatform.h is maintained in the Khronos EGL - * Registry repository at https://github.com/KhronosGroup/EGL-Registry - * The last semantic modification to khrplatform.h was at commit ID: - * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 - * - * Adopters may modify this file to suit their platform. Adopters are - * encouraged to submit platform specific modifications to the Khronos - * group so that they can be included in future versions of this file. - * Please submit changes by filing pull requests or issues on - * the EGL Registry repository linked above. - * - * - * See the Implementer's Guidelines for information about where this file - * should be located on your system and for more details of its use: - * http://www.khronos.org/registry/implementers_guide.pdf - * - * This file should be included as - * #include - * by Khronos client API header files that use its types and defines. - * - * The types in khrplatform.h should only be used to define API-specific types. - * - * Types defined in khrplatform.h: - * khronos_int8_t signed 8 bit - * khronos_uint8_t unsigned 8 bit - * khronos_int16_t signed 16 bit - * khronos_uint16_t unsigned 16 bit - * khronos_int32_t signed 32 bit - * khronos_uint32_t unsigned 32 bit - * khronos_int64_t signed 64 bit - * khronos_uint64_t unsigned 64 bit - * khronos_intptr_t signed same number of bits as a pointer - * khronos_uintptr_t unsigned same number of bits as a pointer - * khronos_ssize_t signed size - * khronos_usize_t unsigned size - * khronos_float_t signed 32 bit floating point - * khronos_time_ns_t unsigned 64 bit time in nanoseconds - * khronos_utime_nanoseconds_t unsigned time interval or absolute time in - * nanoseconds - * khronos_stime_nanoseconds_t signed time interval in nanoseconds - * khronos_boolean_enum_t enumerated boolean type. This should - * only be used as a base type when a client API's boolean type is - * an enum. Client APIs which use an integer or other type for - * booleans cannot use this as the base type for their boolean. - * - * Tokens defined in khrplatform.h: - * - * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. - * - * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. - * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. - * - * Calling convention macros defined in this file: - * KHRONOS_APICALL - * KHRONOS_GLAD_API_PTR - * KHRONOS_APIATTRIBUTES - * - * These may be used in function prototypes as: - * - * KHRONOS_APICALL void KHRONOS_GLAD_API_PTR funcname( - * int arg1, - * int arg2) KHRONOS_APIATTRIBUTES; - */ - -#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) -# define KHRONOS_STATIC 1 -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APICALL - *------------------------------------------------------------------------- - * This precedes the return type of the function in the function prototype. - */ -#if defined(KHRONOS_STATIC) - /* If the preprocessor constant KHRONOS_STATIC is defined, make the - * header compatible with static linking. */ -# define KHRONOS_APICALL -#elif defined(_WIN32) -# define KHRONOS_APICALL __declspec(dllimport) -#elif defined (__SYMBIAN32__) -# define KHRONOS_APICALL IMPORT_C -#elif defined(__ANDROID__) -# define KHRONOS_APICALL __attribute__((visibility("default"))) -#else -# define KHRONOS_APICALL -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_GLAD_API_PTR - *------------------------------------------------------------------------- - * This follows the return type of the function and precedes the function - * name in the function prototype. - */ -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) - /* Win32 but not WinCE */ -# define KHRONOS_GLAD_API_PTR __stdcall -#else -# define KHRONOS_GLAD_API_PTR -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APIATTRIBUTES - *------------------------------------------------------------------------- - * This follows the closing parenthesis of the function prototype arguments. - */ -#if defined (__ARMCC_2__) -#define KHRONOS_APIATTRIBUTES __softfp -#else -#define KHRONOS_APIATTRIBUTES -#endif - -/*------------------------------------------------------------------------- - * basic type definitions - *-----------------------------------------------------------------------*/ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) - - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__VMS ) || defined(__sgi) - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) - -/* - * Win32 - */ -typedef __int32 khronos_int32_t; -typedef unsigned __int32 khronos_uint32_t; -typedef __int64 khronos_int64_t; -typedef unsigned __int64 khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__sun__) || defined(__digital__) - -/* - * Sun or Digital - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#if defined(__arch64__) || defined(_LP64) -typedef long int khronos_int64_t; -typedef unsigned long int khronos_uint64_t; -#else -typedef long long int khronos_int64_t; -typedef unsigned long long int khronos_uint64_t; -#endif /* __arch64__ */ -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif 0 - -/* - * Hypothetical platform with no float or int64 support - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#define KHRONOS_SUPPORT_INT64 0 -#define KHRONOS_SUPPORT_FLOAT 0 - -#else - -/* - * Generic fallback - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#endif - - -/* - * Types that are (so far) the same on all platforms - */ -typedef signed char khronos_int8_t; -typedef unsigned char khronos_uint8_t; -typedef signed short int khronos_int16_t; -typedef unsigned short int khronos_uint16_t; - -/* - * Types that differ between LLP64 and LP64 architectures - in LLP64, - * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears - * to be the only LLP64 architecture in current use. - */ -#ifdef _WIN64 -typedef signed long long int khronos_intptr_t; -typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; -#else -typedef signed long int khronos_intptr_t; -typedef unsigned long int khronos_uintptr_t; -typedef signed long int khronos_ssize_t; -typedef unsigned long int khronos_usize_t; -#endif - -#if KHRONOS_SUPPORT_FLOAT -/* - * Float type - */ -typedef float khronos_float_t; -#endif - -#if KHRONOS_SUPPORT_INT64 -/* Time types - * - * These types can be used to represent a time interval in nanoseconds or - * an absolute Unadjusted System Time. Unadjusted System Time is the number - * of nanoseconds since some arbitrary system event (e.g. since the last - * time the system booted). The Unadjusted System Time is an unsigned - * 64 bit value that wraps back to 0 every 584 years. Time intervals - * may be either signed or unsigned. - */ -typedef khronos_uint64_t khronos_utime_nanoseconds_t; -typedef khronos_int64_t khronos_stime_nanoseconds_t; -#endif - -/* - * Dummy value used to pad enum types to 32 bits. - */ -#ifndef KHRONOS_MAX_ENUM -#define KHRONOS_MAX_ENUM 0x7FFFFFFF -#endif - -/* - * Enumerated boolean type - * - * Values other than zero should be considered to be true. Therefore - * comparisons should not be made against KHRONOS_TRUE. - */ -typedef enum { - KHRONOS_FALSE = 0, - KHRONOS_TRUE = 1, - KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM -} khronos_boolean_enum_t; - -#endif /* __khrplatform_h_ */ - -typedef unsigned int GLenum; - -typedef unsigned char GLboolean; - -typedef unsigned int GLbitfield; - -typedef void GLvoid; - -typedef khronos_int8_t GLbyte; - -typedef khronos_uint8_t GLubyte; - -typedef khronos_int16_t GLshort; - -typedef khronos_uint16_t GLushort; - -typedef int GLint; - -typedef unsigned int GLuint; - -typedef khronos_int32_t GLclampx; - -typedef int GLsizei; - -typedef khronos_float_t GLfloat; - -typedef khronos_float_t GLclampf; - -typedef double GLdouble; - -typedef double GLclampd; - -typedef void *GLeglClientBufferEXT; - -typedef void *GLeglImageOES; - -typedef char GLchar; - -typedef char GLcharARB; - -#ifdef __APPLE__ -typedef void *GLhandleARB; -#else -typedef unsigned int GLhandleARB; -#endif - -typedef khronos_uint16_t GLhalf; - -typedef khronos_uint16_t GLhalfARB; - -typedef khronos_int32_t GLfixed; - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_intptr_t GLintptr; -#else -typedef khronos_intptr_t GLintptr; -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_intptr_t GLintptrARB; -#else -typedef khronos_intptr_t GLintptrARB; -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_ssize_t GLsizeiptr; -#else -typedef khronos_ssize_t GLsizeiptr; -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_ssize_t GLsizeiptrARB; -#else -typedef khronos_ssize_t GLsizeiptrARB; -#endif - -typedef khronos_int64_t GLint64; - -typedef khronos_int64_t GLint64EXT; - -typedef khronos_uint64_t GLuint64; - -typedef khronos_uint64_t GLuint64EXT; - -typedef struct __GLsync *GLsync; - -struct _cl_context; - -struct _cl_event; - -typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); - -typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); - -typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); - -typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); - -typedef unsigned short GLhalfNV; - -typedef GLintptr GLvdpauSurfaceNV; - -typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); - - - -#define GL_VERSION_1_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_0; -#define GL_VERSION_1_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_1; -#define GL_VERSION_1_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_2; -#define GL_VERSION_1_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_3; -#define GL_VERSION_1_4 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_4; -#define GL_VERSION_1_5 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_5; -#define GL_VERSION_2_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_2_0; -#define GL_VERSION_2_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_2_1; -#define GL_VERSION_3_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_0; -#define GL_VERSION_3_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_1; -#define GL_VERSION_3_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_2; -#define GL_VERSION_3_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_3; -#define GL_ARB_multisample 1 -GLAD_API_CALL int GLAD_GL_ARB_multisample; -#define GL_ARB_robustness 1 -GLAD_API_CALL int GLAD_GL_ARB_robustness; -#define GL_KHR_debug 1 -GLAD_API_CALL int GLAD_GL_KHR_debug; - - -typedef void (GLAD_API_PTR *PFNGLACCUMPROC)(GLenum op, GLfloat value); -typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); -typedef void (GLAD_API_PTR *PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); -typedef GLboolean (GLAD_API_PTR *PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint * textures, GLboolean * residences); -typedef void (GLAD_API_PTR *PFNGLARRAYELEMENTPROC)(GLint i); -typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); -typedef void (GLAD_API_PTR *PFNGLBEGINPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); -typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); -typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); -typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); -typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); -typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); -typedef void (GLAD_API_PTR *PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * bitmap); -typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); -typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); -typedef void (GLAD_API_PTR *PFNGLCALLLISTPROC)(GLuint list); -typedef void (GLAD_API_PTR *PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void * lists); -typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); -typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth); -typedef void (GLAD_API_PTR *PFNGLCLEARINDEXPROC)(GLfloat c); -typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); -typedef void (GLAD_API_PTR *PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); -typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (GLAD_API_PTR *PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble * equation); -typedef void (GLAD_API_PTR *PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UBVPROC)(const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UIVPROC)(const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -typedef void (GLAD_API_PTR *PFNGLCOLOR3USVPROC)(const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVPROC)(const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UIVPROC)(const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR4USVPROC)(const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (GLAD_API_PTR *PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); -typedef void (GLAD_API_PTR *PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint * color); -typedef void (GLAD_API_PTR *PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); -typedef void (GLAD_API_PTR *PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint * color); -typedef void (GLAD_API_PTR *PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); -typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); -typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void * userParam); -typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); -typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); -typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); -typedef void (GLAD_API_PTR *PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); -typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); -typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); -typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays); -typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); -typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); -typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); -typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); -typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLDISABLECLIENTSTATEPROC)(GLenum array); -typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); -typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); -typedef void (GLAD_API_PTR *PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); -typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); -typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPROC)(GLboolean flag); -typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLEDGEFLAGVPROC)(const GLboolean * flag); -typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLENABLECLIENTSTATEPROC)(GLenum array); -typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index); -typedef void (GLAD_API_PTR *PFNGLENDPROC)(void); -typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void); -typedef void (GLAD_API_PTR *PFNGLENDLISTPROC)(void); -typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DPROC)(GLdouble u); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DVPROC)(const GLdouble * u); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FPROC)(GLfloat u); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FVPROC)(const GLfloat * u); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DVPROC)(const GLdouble * u); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FVPROC)(const GLfloat * u); -typedef void (GLAD_API_PTR *PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); -typedef void (GLAD_API_PTR *PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); -typedef void (GLAD_API_PTR *PFNGLEVALPOINT1PROC)(GLint i); -typedef void (GLAD_API_PTR *PFNGLEVALPOINT2PROC)(GLint i, GLint j); -typedef void (GLAD_API_PTR *PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat * buffer); -typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); -typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); -typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); -typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDDPROC)(GLdouble coord); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDDVPROC)(const GLdouble * coord); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDFPROC)(GLfloat coord); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDFVPROC)(const GLfloat * coord); -typedef void (GLAD_API_PTR *PFNGLFOGFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLFOGFVPROC)(GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLFOGIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLFOGIVPROC)(GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); -typedef GLuint (GLAD_API_PTR *PFNGLGENLISTSPROC)(GLsizei range); -typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); -typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); -typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); -typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data); -typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data); -typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble * equation); -typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img); -typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); -typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data); -typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); -typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name); -typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); -typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSARBPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); -typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); -typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); -typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); -typedef void (GLAD_API_PTR *PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint * v); -typedef void (GLAD_API_PTR *PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val); -typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); -typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); -typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint * values); -typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort * values); -typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params); -typedef void (GLAD_API_PTR *PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte * mask); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); -typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); -typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); -typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); -typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); -typedef void (GLAD_API_PTR *PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); -typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); -typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); -typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETNCOLORTABLEARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * table); -typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)(GLenum target, GLint lod, GLsizei bufSize, void * img); -typedef void (GLAD_API_PTR *PFNGLGETNCONVOLUTIONFILTERARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * image); -typedef void (GLAD_API_PTR *PFNGLGETNHISTOGRAMARBPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); -typedef void (GLAD_API_PTR *PFNGLGETNMAPDVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLGETNMAPFVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLGETNMAPIVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLint * v); -typedef void (GLAD_API_PTR *PFNGLGETNMINMAXARBPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); -typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPFVARBPROC)(GLenum map, GLsizei bufSize, GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUIVARBPROC)(GLenum map, GLsizei bufSize, GLuint * values); -typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUSVARBPROC)(GLenum map, GLsizei bufSize, GLushort * values); -typedef void (GLAD_API_PTR *PFNGLGETNPOLYGONSTIPPLEARBPROC)(GLsizei bufSize, GLubyte * pattern); -typedef void (GLAD_API_PTR *PFNGLGETNSEPARABLEFILTERARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void * row, GLsizei columnBufSize, void * column, void * span); -typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEARBPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * img); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLINDEXMASKPROC)(GLuint mask); -typedef void (GLAD_API_PTR *PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLINDEXDPROC)(GLdouble c); -typedef void (GLAD_API_PTR *PFNGLINDEXDVPROC)(const GLdouble * c); -typedef void (GLAD_API_PTR *PFNGLINDEXFPROC)(GLfloat c); -typedef void (GLAD_API_PTR *PFNGLINDEXFVPROC)(const GLfloat * c); -typedef void (GLAD_API_PTR *PFNGLINDEXIPROC)(GLint c); -typedef void (GLAD_API_PTR *PFNGLINDEXIVPROC)(const GLint * c); -typedef void (GLAD_API_PTR *PFNGLINDEXSPROC)(GLshort c); -typedef void (GLAD_API_PTR *PFNGLINDEXSVPROC)(const GLshort * c); -typedef void (GLAD_API_PTR *PFNGLINDEXUBPROC)(GLubyte c); -typedef void (GLAD_API_PTR *PFNGLINDEXUBVPROC)(const GLubyte * c); -typedef void (GLAD_API_PTR *PFNGLINITNAMESPROC)(void); -typedef void (GLAD_API_PTR *PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void * pointer); -typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); -typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); -typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index); -typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); -typedef GLboolean (GLAD_API_PTR *PFNGLISLISTPROC)(GLuint list); -typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); -typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); -typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); -typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); -typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); -typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); -typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); -typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); -typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); -typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLLISTBASEPROC)(GLuint base); -typedef void (GLAD_API_PTR *PFNGLLOADIDENTITYPROC)(void); -typedef void (GLAD_API_PTR *PFNGLLOADMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLLOADMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLLOADNAMEPROC)(GLuint name); -typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode); -typedef void (GLAD_API_PTR *PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points); -typedef void (GLAD_API_PTR *PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points); -typedef void (GLAD_API_PTR *PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble * points); -typedef void (GLAD_API_PTR *PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat * points); -typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); -typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (GLAD_API_PTR *PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); -typedef void (GLAD_API_PTR *PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); -typedef void (GLAD_API_PTR *PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); -typedef void (GLAD_API_PTR *PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); -typedef void (GLAD_API_PTR *PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLMATRIXMODEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLMULTMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLMULTMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLNEWLISTPROC)(GLuint list, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (GLAD_API_PTR *PFNGLNORMAL3BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (GLAD_API_PTR *PFNGLNORMAL3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (GLAD_API_PTR *PFNGLNORMAL3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); -typedef void (GLAD_API_PTR *PFNGLNORMAL3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); -typedef void (GLAD_API_PTR *PFNGLNORMAL3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); -typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void * ptr, GLsizei length, const GLchar * label); -typedef void (GLAD_API_PTR *PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (GLAD_API_PTR *PFNGLPASSTHROUGHPROC)(GLfloat token); -typedef void (GLAD_API_PTR *PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint * values); -typedef void (GLAD_API_PTR *PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort * values); -typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size); -typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); -typedef void (GLAD_API_PTR *PFNGLPOLYGONSTIPPLEPROC)(const GLubyte * mask); -typedef void (GLAD_API_PTR *PFNGLPOPATTRIBPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPOPCLIENTATTRIBPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPOPMATRIXPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPOPNAMEPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint * textures, const GLfloat * priorities); -typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLPUSHATTRIBPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message); -typedef void (GLAD_API_PTR *PFNGLPUSHMATRIXPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPUSHNAMEPROC)(GLuint name); -typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IPROC)(GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); -typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); -typedef void (GLAD_API_PTR *PFNGLREADNPIXELSARBPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); -typedef void (GLAD_API_PTR *PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); -typedef void (GLAD_API_PTR *PFNGLRECTDVPROC)(const GLdouble * v1, const GLdouble * v2); -typedef void (GLAD_API_PTR *PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); -typedef void (GLAD_API_PTR *PFNGLRECTFVPROC)(const GLfloat * v1, const GLfloat * v2); -typedef void (GLAD_API_PTR *PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); -typedef void (GLAD_API_PTR *PFNGLRECTIVPROC)(const GLint * v1, const GLint * v2); -typedef void (GLAD_API_PTR *PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); -typedef void (GLAD_API_PTR *PFNGLRECTSVPROC)(const GLshort * v1, const GLshort * v2); -typedef GLint (GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); -typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEARBPROC)(GLfloat value, GLboolean invert); -typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); -typedef void (GLAD_API_PTR *PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USVPROC)(const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint * color); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint * buffer); -typedef void (GLAD_API_PTR *PFNGLSHADEMODELPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); -typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); -typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DPROC)(GLdouble s); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FPROC)(GLfloat s); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IPROC)(GLint s); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SPROC)(GLshort s); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IPROC)(GLint s, GLint t); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); -typedef void (GLAD_API_PTR *PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); -typedef void (GLAD_API_PTR *PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLVERTEX2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLVERTEX2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX2IPROC)(GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLVERTEX2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX2SPROC)(GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLVERTEX2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLVERTEX3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLVERTEX3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLVERTEX3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLVERTEX3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLVERTEX4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAD_API_PTR *PFNGLVERTEX4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); -typedef void (GLAD_API_PTR *PFNGLVERTEX4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAD_API_PTR *PFNGLVERTEX4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); -typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVPROC)(const GLshort * v); - -GLAD_API_CALL PFNGLACCUMPROC glad_glAccum; -#define glAccum glad_glAccum -GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -GLAD_API_CALL PFNGLALPHAFUNCPROC glad_glAlphaFunc; -#define glAlphaFunc glad_glAlphaFunc -GLAD_API_CALL PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; -#define glAreTexturesResident glad_glAreTexturesResident -GLAD_API_CALL PFNGLARRAYELEMENTPROC glad_glArrayElement; -#define glArrayElement glad_glArrayElement -GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; -#define glAttachShader glad_glAttachShader -GLAD_API_CALL PFNGLBEGINPROC glad_glBegin; -#define glBegin glad_glBegin -GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; -#define glBeginConditionalRender glad_glBeginConditionalRender -GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; -#define glBeginQuery glad_glBeginQuery -GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -#define glBeginTransformFeedback glad_glBeginTransformFeedback -GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -#define glBindBufferBase glad_glBindBufferBase -GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -#define glBindBufferRange glad_glBindBufferRange -GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; -#define glBindFragDataLocation glad_glBindFragDataLocation -GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; -#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed -GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; -#define glBindSampler glad_glBindSampler -GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -#define glBindVertexArray glad_glBindVertexArray -GLAD_API_CALL PFNGLBITMAPPROC glad_glBitmap; -#define glBitmap glad_glBitmap -GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -#define glBlitFramebuffer glad_glBlitFramebuffer -GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -GLAD_API_CALL PFNGLCALLLISTPROC glad_glCallList; -#define glCallList glad_glCallList -GLAD_API_CALL PFNGLCALLLISTSPROC glad_glCallLists; -#define glCallLists glad_glCallLists -GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -#define glCheckFramebufferStatus glad_glCheckFramebufferStatus -GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; -#define glClampColor glad_glClampColor -GLAD_API_CALL PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -GLAD_API_CALL PFNGLCLEARACCUMPROC glad_glClearAccum; -#define glClearAccum glad_glClearAccum -GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -#define glClearBufferfi glad_glClearBufferfi -GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -#define glClearBufferfv glad_glClearBufferfv -GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -#define glClearBufferiv glad_glClearBufferiv -GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -#define glClearBufferuiv glad_glClearBufferuiv -GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; -#define glClearColor glad_glClearColor -GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; -#define glClearDepth glad_glClearDepth -GLAD_API_CALL PFNGLCLEARINDEXPROC glad_glClearIndex; -#define glClearIndex glad_glClearIndex -GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; -#define glClearStencil glad_glClearStencil -GLAD_API_CALL PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; -#define glClientActiveTexture glad_glClientActiveTexture -GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -#define glClientWaitSync glad_glClientWaitSync -GLAD_API_CALL PFNGLCLIPPLANEPROC glad_glClipPlane; -#define glClipPlane glad_glClipPlane -GLAD_API_CALL PFNGLCOLOR3BPROC glad_glColor3b; -#define glColor3b glad_glColor3b -GLAD_API_CALL PFNGLCOLOR3BVPROC glad_glColor3bv; -#define glColor3bv glad_glColor3bv -GLAD_API_CALL PFNGLCOLOR3DPROC glad_glColor3d; -#define glColor3d glad_glColor3d -GLAD_API_CALL PFNGLCOLOR3DVPROC glad_glColor3dv; -#define glColor3dv glad_glColor3dv -GLAD_API_CALL PFNGLCOLOR3FPROC glad_glColor3f; -#define glColor3f glad_glColor3f -GLAD_API_CALL PFNGLCOLOR3FVPROC glad_glColor3fv; -#define glColor3fv glad_glColor3fv -GLAD_API_CALL PFNGLCOLOR3IPROC glad_glColor3i; -#define glColor3i glad_glColor3i -GLAD_API_CALL PFNGLCOLOR3IVPROC glad_glColor3iv; -#define glColor3iv glad_glColor3iv -GLAD_API_CALL PFNGLCOLOR3SPROC glad_glColor3s; -#define glColor3s glad_glColor3s -GLAD_API_CALL PFNGLCOLOR3SVPROC glad_glColor3sv; -#define glColor3sv glad_glColor3sv -GLAD_API_CALL PFNGLCOLOR3UBPROC glad_glColor3ub; -#define glColor3ub glad_glColor3ub -GLAD_API_CALL PFNGLCOLOR3UBVPROC glad_glColor3ubv; -#define glColor3ubv glad_glColor3ubv -GLAD_API_CALL PFNGLCOLOR3UIPROC glad_glColor3ui; -#define glColor3ui glad_glColor3ui -GLAD_API_CALL PFNGLCOLOR3UIVPROC glad_glColor3uiv; -#define glColor3uiv glad_glColor3uiv -GLAD_API_CALL PFNGLCOLOR3USPROC glad_glColor3us; -#define glColor3us glad_glColor3us -GLAD_API_CALL PFNGLCOLOR3USVPROC glad_glColor3usv; -#define glColor3usv glad_glColor3usv -GLAD_API_CALL PFNGLCOLOR4BPROC glad_glColor4b; -#define glColor4b glad_glColor4b -GLAD_API_CALL PFNGLCOLOR4BVPROC glad_glColor4bv; -#define glColor4bv glad_glColor4bv -GLAD_API_CALL PFNGLCOLOR4DPROC glad_glColor4d; -#define glColor4d glad_glColor4d -GLAD_API_CALL PFNGLCOLOR4DVPROC glad_glColor4dv; -#define glColor4dv glad_glColor4dv -GLAD_API_CALL PFNGLCOLOR4FPROC glad_glColor4f; -#define glColor4f glad_glColor4f -GLAD_API_CALL PFNGLCOLOR4FVPROC glad_glColor4fv; -#define glColor4fv glad_glColor4fv -GLAD_API_CALL PFNGLCOLOR4IPROC glad_glColor4i; -#define glColor4i glad_glColor4i -GLAD_API_CALL PFNGLCOLOR4IVPROC glad_glColor4iv; -#define glColor4iv glad_glColor4iv -GLAD_API_CALL PFNGLCOLOR4SPROC glad_glColor4s; -#define glColor4s glad_glColor4s -GLAD_API_CALL PFNGLCOLOR4SVPROC glad_glColor4sv; -#define glColor4sv glad_glColor4sv -GLAD_API_CALL PFNGLCOLOR4UBPROC glad_glColor4ub; -#define glColor4ub glad_glColor4ub -GLAD_API_CALL PFNGLCOLOR4UBVPROC glad_glColor4ubv; -#define glColor4ubv glad_glColor4ubv -GLAD_API_CALL PFNGLCOLOR4UIPROC glad_glColor4ui; -#define glColor4ui glad_glColor4ui -GLAD_API_CALL PFNGLCOLOR4UIVPROC glad_glColor4uiv; -#define glColor4uiv glad_glColor4uiv -GLAD_API_CALL PFNGLCOLOR4USPROC glad_glColor4us; -#define glColor4us glad_glColor4us -GLAD_API_CALL PFNGLCOLOR4USVPROC glad_glColor4usv; -#define glColor4usv glad_glColor4usv -GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; -#define glColorMaski glad_glColorMaski -GLAD_API_CALL PFNGLCOLORMATERIALPROC glad_glColorMaterial; -#define glColorMaterial glad_glColorMaterial -GLAD_API_CALL PFNGLCOLORP3UIPROC glad_glColorP3ui; -#define glColorP3ui glad_glColorP3ui -GLAD_API_CALL PFNGLCOLORP3UIVPROC glad_glColorP3uiv; -#define glColorP3uiv glad_glColorP3uiv -GLAD_API_CALL PFNGLCOLORP4UIPROC glad_glColorP4ui; -#define glColorP4ui glad_glColorP4ui -GLAD_API_CALL PFNGLCOLORP4UIVPROC glad_glColorP4uiv; -#define glColorP4uiv glad_glColorP4uiv -GLAD_API_CALL PFNGLCOLORPOINTERPROC glad_glColorPointer; -#define glColorPointer glad_glColorPointer -GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -#define glCompressedTexImage1D glad_glCompressedTexImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -#define glCompressedTexImage3D glad_glCompressedTexImage3D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -GLAD_API_CALL PFNGLCOPYPIXELSPROC glad_glCopyPixels; -#define glCopyPixels glad_glCopyPixels -GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -#define glCopyTexImage1D glad_glCopyTexImage1D -GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -#define glCopyTexSubImage1D glad_glCopyTexSubImage1D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -#define glCopyTexSubImage3D glad_glCopyTexSubImage3D -GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; -#define glCullFace glad_glCullFace -GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; -#define glDebugMessageCallback glad_glDebugMessageCallback -GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; -#define glDebugMessageControl glad_glDebugMessageControl -GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; -#define glDebugMessageInsert glad_glDebugMessageInsert -GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -GLAD_API_CALL PFNGLDELETELISTSPROC glad_glDeleteLists; -#define glDeleteLists glad_glDeleteLists -GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -#define glDeleteQueries glad_glDeleteQueries -GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -#define glDeleteSamplers glad_glDeleteSamplers -GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -#define glDeleteVertexArrays glad_glDeleteVertexArrays -GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; -#define glDepthFunc glad_glDepthFunc -GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; -#define glDepthMask glad_glDepthMask -GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; -#define glDepthRange glad_glDepthRange -GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -GLAD_API_CALL PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; -#define glDisableClientState glad_glDisableClientState -GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; -#define glDisablei glad_glDisablei -GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -#define glDrawBuffer glad_glDrawBuffer -GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -#define glDrawBuffers glad_glDrawBuffers -GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; -#define glDrawElements glad_glDrawElements -GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -#define glDrawElementsInstanced glad_glDrawElementsInstanced -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex -GLAD_API_CALL PFNGLDRAWPIXELSPROC glad_glDrawPixels; -#define glDrawPixels glad_glDrawPixels -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -#define glDrawRangeElements glad_glDrawRangeElements -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -GLAD_API_CALL PFNGLEDGEFLAGPROC glad_glEdgeFlag; -#define glEdgeFlag glad_glEdgeFlag -GLAD_API_CALL PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; -#define glEdgeFlagPointer glad_glEdgeFlagPointer -GLAD_API_CALL PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; -#define glEdgeFlagv glad_glEdgeFlagv -GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -GLAD_API_CALL PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; -#define glEnableClientState glad_glEnableClientState -GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; -#define glEnablei glad_glEnablei -GLAD_API_CALL PFNGLENDPROC glad_glEnd; -#define glEnd glad_glEnd -GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; -#define glEndConditionalRender glad_glEndConditionalRender -GLAD_API_CALL PFNGLENDLISTPROC glad_glEndList; -#define glEndList glad_glEndList -GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; -#define glEndQuery glad_glEndQuery -GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -#define glEndTransformFeedback glad_glEndTransformFeedback -GLAD_API_CALL PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; -#define glEvalCoord1d glad_glEvalCoord1d -GLAD_API_CALL PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; -#define glEvalCoord1dv glad_glEvalCoord1dv -GLAD_API_CALL PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; -#define glEvalCoord1f glad_glEvalCoord1f -GLAD_API_CALL PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; -#define glEvalCoord1fv glad_glEvalCoord1fv -GLAD_API_CALL PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; -#define glEvalCoord2d glad_glEvalCoord2d -GLAD_API_CALL PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; -#define glEvalCoord2dv glad_glEvalCoord2dv -GLAD_API_CALL PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; -#define glEvalCoord2f glad_glEvalCoord2f -GLAD_API_CALL PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; -#define glEvalCoord2fv glad_glEvalCoord2fv -GLAD_API_CALL PFNGLEVALMESH1PROC glad_glEvalMesh1; -#define glEvalMesh1 glad_glEvalMesh1 -GLAD_API_CALL PFNGLEVALMESH2PROC glad_glEvalMesh2; -#define glEvalMesh2 glad_glEvalMesh2 -GLAD_API_CALL PFNGLEVALPOINT1PROC glad_glEvalPoint1; -#define glEvalPoint1 glad_glEvalPoint1 -GLAD_API_CALL PFNGLEVALPOINT2PROC glad_glEvalPoint2; -#define glEvalPoint2 glad_glEvalPoint2 -GLAD_API_CALL PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; -#define glFeedbackBuffer glad_glFeedbackBuffer -GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -#define glFlushMappedBufferRange glad_glFlushMappedBufferRange -GLAD_API_CALL PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; -#define glFogCoordPointer glad_glFogCoordPointer -GLAD_API_CALL PFNGLFOGCOORDDPROC glad_glFogCoordd; -#define glFogCoordd glad_glFogCoordd -GLAD_API_CALL PFNGLFOGCOORDDVPROC glad_glFogCoorddv; -#define glFogCoorddv glad_glFogCoorddv -GLAD_API_CALL PFNGLFOGCOORDFPROC glad_glFogCoordf; -#define glFogCoordf glad_glFogCoordf -GLAD_API_CALL PFNGLFOGCOORDFVPROC glad_glFogCoordfv; -#define glFogCoordfv glad_glFogCoordfv -GLAD_API_CALL PFNGLFOGFPROC glad_glFogf; -#define glFogf glad_glFogf -GLAD_API_CALL PFNGLFOGFVPROC glad_glFogfv; -#define glFogfv glad_glFogfv -GLAD_API_CALL PFNGLFOGIPROC glad_glFogi; -#define glFogi glad_glFogi -GLAD_API_CALL PFNGLFOGIVPROC glad_glFogiv; -#define glFogiv glad_glFogiv -GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -#define glFramebufferTexture glad_glFramebufferTexture -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -#define glFramebufferTexture1D glad_glFramebufferTexture1D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -#define glFramebufferTexture3D glad_glFramebufferTexture3D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -#define glFramebufferTextureLayer glad_glFramebufferTextureLayer -GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -GLAD_API_CALL PFNGLFRUSTUMPROC glad_glFrustum; -#define glFrustum glad_glFrustum -GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -GLAD_API_CALL PFNGLGENLISTSPROC glad_glGenLists; -#define glGenLists glad_glGenLists -GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; -#define glGenQueries glad_glGenQueries -GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; -#define glGenSamplers glad_glGenSamplers -GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -#define glGenVertexArrays glad_glGenVertexArrays -GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -#define glGetActiveUniform glad_glGetActiveUniform -GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -#define glGetActiveUniformName glad_glGetActiveUniformName -GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -#define glGetActiveUniformsiv glad_glGetActiveUniformsiv -GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -#define glGetBooleani_v glad_glGetBooleani_v -GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -#define glGetBooleanv glad_glGetBooleanv -GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -#define glGetBufferParameteri64v glad_glGetBufferParameteri64v -GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -#define glGetBufferParameteriv glad_glGetBufferParameteriv -GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -#define glGetBufferPointerv glad_glGetBufferPointerv -GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -#define glGetBufferSubData glad_glGetBufferSubData -GLAD_API_CALL PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; -#define glGetClipPlane glad_glGetClipPlane -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -#define glGetCompressedTexImage glad_glGetCompressedTexImage -GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; -#define glGetDebugMessageLog glad_glGetDebugMessageLog -GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; -#define glGetDoublev glad_glGetDoublev -GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; -#define glGetFragDataIndex glad_glGetFragDataIndex -GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -#define glGetFragDataLocation glad_glGetFragDataLocation -GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; -#define glGetGraphicsResetStatusARB glad_glGetGraphicsResetStatusARB -GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -#define glGetInteger64i_v glad_glGetInteger64i_v -GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -#define glGetInteger64v glad_glGetInteger64v -GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -#define glGetIntegeri_v glad_glGetIntegeri_v -GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -GLAD_API_CALL PFNGLGETLIGHTFVPROC glad_glGetLightfv; -#define glGetLightfv glad_glGetLightfv -GLAD_API_CALL PFNGLGETLIGHTIVPROC glad_glGetLightiv; -#define glGetLightiv glad_glGetLightiv -GLAD_API_CALL PFNGLGETMAPDVPROC glad_glGetMapdv; -#define glGetMapdv glad_glGetMapdv -GLAD_API_CALL PFNGLGETMAPFVPROC glad_glGetMapfv; -#define glGetMapfv glad_glGetMapfv -GLAD_API_CALL PFNGLGETMAPIVPROC glad_glGetMapiv; -#define glGetMapiv glad_glGetMapiv -GLAD_API_CALL PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; -#define glGetMaterialfv glad_glGetMaterialfv -GLAD_API_CALL PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; -#define glGetMaterialiv glad_glGetMaterialiv -GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; -#define glGetObjectLabel glad_glGetObjectLabel -GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; -#define glGetObjectPtrLabel glad_glGetObjectPtrLabel -GLAD_API_CALL PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; -#define glGetPixelMapfv glad_glGetPixelMapfv -GLAD_API_CALL PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; -#define glGetPixelMapuiv glad_glGetPixelMapuiv -GLAD_API_CALL PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; -#define glGetPixelMapusv glad_glGetPixelMapusv -GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv; -#define glGetPointerv glad_glGetPointerv -GLAD_API_CALL PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; -#define glGetPolygonStipple glad_glGetPolygonStipple -GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; -#define glGetQueryObjecti64v glad_glGetQueryObjecti64v -GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -#define glGetQueryObjectiv glad_glGetQueryObjectiv -GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; -#define glGetQueryObjectui64v glad_glGetQueryObjectui64v -GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -#define glGetQueryObjectuiv glad_glGetQueryObjectuiv -GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; -#define glGetQueryiv glad_glGetQueryiv -GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; -#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; -#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; -#define glGetSamplerParameterfv glad_glGetSamplerParameterfv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; -#define glGetSamplerParameteriv glad_glGetSamplerParameteriv -GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -#define glGetShaderInfoLog glad_glGetShaderInfoLog -GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -#define glGetShaderSource glad_glGetShaderSource -GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; -#define glGetString glad_glGetString -GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; -#define glGetStringi glad_glGetStringi -GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; -#define glGetSynciv glad_glGetSynciv -GLAD_API_CALL PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; -#define glGetTexEnvfv glad_glGetTexEnvfv -GLAD_API_CALL PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; -#define glGetTexEnviv glad_glGetTexEnviv -GLAD_API_CALL PFNGLGETTEXGENDVPROC glad_glGetTexGendv; -#define glGetTexGendv glad_glGetTexGendv -GLAD_API_CALL PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; -#define glGetTexGenfv glad_glGetTexGenfv -GLAD_API_CALL PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; -#define glGetTexGeniv glad_glGetTexGeniv -GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; -#define glGetTexImage glad_glGetTexImage -GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv -GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv -GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -#define glGetTexParameterIiv glad_glGetTexParameterIiv -GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -#define glGetTexParameterIuiv glad_glGetTexParameterIuiv -GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -#define glGetUniformBlockIndex glad_glGetUniformBlockIndex -GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -#define glGetUniformfv glad_glGetUniformfv -GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -#define glGetUniformuiv glad_glGetUniformuiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -#define glGetVertexAttribIiv glad_glGetVertexAttribIiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -#define glGetVertexAttribdv glad_glGetVertexAttribdv -GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -GLAD_API_CALL PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; -#define glGetnColorTableARB glad_glGetnColorTableARB -GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; -#define glGetnCompressedTexImageARB glad_glGetnCompressedTexImageARB -GLAD_API_CALL PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; -#define glGetnConvolutionFilterARB glad_glGetnConvolutionFilterARB -GLAD_API_CALL PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; -#define glGetnHistogramARB glad_glGetnHistogramARB -GLAD_API_CALL PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; -#define glGetnMapdvARB glad_glGetnMapdvARB -GLAD_API_CALL PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; -#define glGetnMapfvARB glad_glGetnMapfvARB -GLAD_API_CALL PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; -#define glGetnMapivARB glad_glGetnMapivARB -GLAD_API_CALL PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; -#define glGetnMinmaxARB glad_glGetnMinmaxARB -GLAD_API_CALL PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; -#define glGetnPixelMapfvARB glad_glGetnPixelMapfvARB -GLAD_API_CALL PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; -#define glGetnPixelMapuivARB glad_glGetnPixelMapuivARB -GLAD_API_CALL PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; -#define glGetnPixelMapusvARB glad_glGetnPixelMapusvARB -GLAD_API_CALL PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; -#define glGetnPolygonStippleARB glad_glGetnPolygonStippleARB -GLAD_API_CALL PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; -#define glGetnSeparableFilterARB glad_glGetnSeparableFilterARB -GLAD_API_CALL PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; -#define glGetnTexImageARB glad_glGetnTexImageARB -GLAD_API_CALL PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; -#define glGetnUniformdvARB glad_glGetnUniformdvARB -GLAD_API_CALL PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; -#define glGetnUniformfvARB glad_glGetnUniformfvARB -GLAD_API_CALL PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; -#define glGetnUniformivARB glad_glGetnUniformivARB -GLAD_API_CALL PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; -#define glGetnUniformuivARB glad_glGetnUniformuivARB -GLAD_API_CALL PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -GLAD_API_CALL PFNGLINDEXMASKPROC glad_glIndexMask; -#define glIndexMask glad_glIndexMask -GLAD_API_CALL PFNGLINDEXPOINTERPROC glad_glIndexPointer; -#define glIndexPointer glad_glIndexPointer -GLAD_API_CALL PFNGLINDEXDPROC glad_glIndexd; -#define glIndexd glad_glIndexd -GLAD_API_CALL PFNGLINDEXDVPROC glad_glIndexdv; -#define glIndexdv glad_glIndexdv -GLAD_API_CALL PFNGLINDEXFPROC glad_glIndexf; -#define glIndexf glad_glIndexf -GLAD_API_CALL PFNGLINDEXFVPROC glad_glIndexfv; -#define glIndexfv glad_glIndexfv -GLAD_API_CALL PFNGLINDEXIPROC glad_glIndexi; -#define glIndexi glad_glIndexi -GLAD_API_CALL PFNGLINDEXIVPROC glad_glIndexiv; -#define glIndexiv glad_glIndexiv -GLAD_API_CALL PFNGLINDEXSPROC glad_glIndexs; -#define glIndexs glad_glIndexs -GLAD_API_CALL PFNGLINDEXSVPROC glad_glIndexsv; -#define glIndexsv glad_glIndexsv -GLAD_API_CALL PFNGLINDEXUBPROC glad_glIndexub; -#define glIndexub glad_glIndexub -GLAD_API_CALL PFNGLINDEXUBVPROC glad_glIndexubv; -#define glIndexubv glad_glIndexubv -GLAD_API_CALL PFNGLINITNAMESPROC glad_glInitNames; -#define glInitNames glad_glInitNames -GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; -#define glInterleavedArrays glad_glInterleavedArrays -GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; -#define glIsEnabledi glad_glIsEnabledi -GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -GLAD_API_CALL PFNGLISLISTPROC glad_glIsList; -#define glIsList glad_glIsList -GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; -#define glIsQuery glad_glIsQuery -GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; -#define glIsSampler glad_glIsSampler -GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -#define glIsVertexArray glad_glIsVertexArray -GLAD_API_CALL PFNGLLIGHTMODELFPROC glad_glLightModelf; -#define glLightModelf glad_glLightModelf -GLAD_API_CALL PFNGLLIGHTMODELFVPROC glad_glLightModelfv; -#define glLightModelfv glad_glLightModelfv -GLAD_API_CALL PFNGLLIGHTMODELIPROC glad_glLightModeli; -#define glLightModeli glad_glLightModeli -GLAD_API_CALL PFNGLLIGHTMODELIVPROC glad_glLightModeliv; -#define glLightModeliv glad_glLightModeliv -GLAD_API_CALL PFNGLLIGHTFPROC glad_glLightf; -#define glLightf glad_glLightf -GLAD_API_CALL PFNGLLIGHTFVPROC glad_glLightfv; -#define glLightfv glad_glLightfv -GLAD_API_CALL PFNGLLIGHTIPROC glad_glLighti; -#define glLighti glad_glLighti -GLAD_API_CALL PFNGLLIGHTIVPROC glad_glLightiv; -#define glLightiv glad_glLightiv -GLAD_API_CALL PFNGLLINESTIPPLEPROC glad_glLineStipple; -#define glLineStipple glad_glLineStipple -GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -GLAD_API_CALL PFNGLLISTBASEPROC glad_glListBase; -#define glListBase glad_glListBase -GLAD_API_CALL PFNGLLOADIDENTITYPROC glad_glLoadIdentity; -#define glLoadIdentity glad_glLoadIdentity -GLAD_API_CALL PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; -#define glLoadMatrixd glad_glLoadMatrixd -GLAD_API_CALL PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; -#define glLoadMatrixf glad_glLoadMatrixf -GLAD_API_CALL PFNGLLOADNAMEPROC glad_glLoadName; -#define glLoadName glad_glLoadName -GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; -#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd -GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; -#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf -GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; -#define glLogicOp glad_glLogicOp -GLAD_API_CALL PFNGLMAP1DPROC glad_glMap1d; -#define glMap1d glad_glMap1d -GLAD_API_CALL PFNGLMAP1FPROC glad_glMap1f; -#define glMap1f glad_glMap1f -GLAD_API_CALL PFNGLMAP2DPROC glad_glMap2d; -#define glMap2d glad_glMap2d -GLAD_API_CALL PFNGLMAP2FPROC glad_glMap2f; -#define glMap2f glad_glMap2f -GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; -#define glMapBuffer glad_glMapBuffer -GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -#define glMapBufferRange glad_glMapBufferRange -GLAD_API_CALL PFNGLMAPGRID1DPROC glad_glMapGrid1d; -#define glMapGrid1d glad_glMapGrid1d -GLAD_API_CALL PFNGLMAPGRID1FPROC glad_glMapGrid1f; -#define glMapGrid1f glad_glMapGrid1f -GLAD_API_CALL PFNGLMAPGRID2DPROC glad_glMapGrid2d; -#define glMapGrid2d glad_glMapGrid2d -GLAD_API_CALL PFNGLMAPGRID2FPROC glad_glMapGrid2f; -#define glMapGrid2f glad_glMapGrid2f -GLAD_API_CALL PFNGLMATERIALFPROC glad_glMaterialf; -#define glMaterialf glad_glMaterialf -GLAD_API_CALL PFNGLMATERIALFVPROC glad_glMaterialfv; -#define glMaterialfv glad_glMaterialfv -GLAD_API_CALL PFNGLMATERIALIPROC glad_glMateriali; -#define glMateriali glad_glMateriali -GLAD_API_CALL PFNGLMATERIALIVPROC glad_glMaterialiv; -#define glMaterialiv glad_glMaterialiv -GLAD_API_CALL PFNGLMATRIXMODEPROC glad_glMatrixMode; -#define glMatrixMode glad_glMatrixMode -GLAD_API_CALL PFNGLMULTMATRIXDPROC glad_glMultMatrixd; -#define glMultMatrixd glad_glMultMatrixd -GLAD_API_CALL PFNGLMULTMATRIXFPROC glad_glMultMatrixf; -#define glMultMatrixf glad_glMultMatrixf -GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; -#define glMultTransposeMatrixd glad_glMultTransposeMatrixd -GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; -#define glMultTransposeMatrixf glad_glMultTransposeMatrixf -GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -#define glMultiDrawArrays glad_glMultiDrawArrays -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -#define glMultiDrawElements glad_glMultiDrawElements -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -GLAD_API_CALL PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; -#define glMultiTexCoord1d glad_glMultiTexCoord1d -GLAD_API_CALL PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; -#define glMultiTexCoord1dv glad_glMultiTexCoord1dv -GLAD_API_CALL PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; -#define glMultiTexCoord1f glad_glMultiTexCoord1f -GLAD_API_CALL PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; -#define glMultiTexCoord1fv glad_glMultiTexCoord1fv -GLAD_API_CALL PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; -#define glMultiTexCoord1i glad_glMultiTexCoord1i -GLAD_API_CALL PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; -#define glMultiTexCoord1iv glad_glMultiTexCoord1iv -GLAD_API_CALL PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; -#define glMultiTexCoord1s glad_glMultiTexCoord1s -GLAD_API_CALL PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; -#define glMultiTexCoord1sv glad_glMultiTexCoord1sv -GLAD_API_CALL PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; -#define glMultiTexCoord2d glad_glMultiTexCoord2d -GLAD_API_CALL PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; -#define glMultiTexCoord2dv glad_glMultiTexCoord2dv -GLAD_API_CALL PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; -#define glMultiTexCoord2f glad_glMultiTexCoord2f -GLAD_API_CALL PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; -#define glMultiTexCoord2fv glad_glMultiTexCoord2fv -GLAD_API_CALL PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; -#define glMultiTexCoord2i glad_glMultiTexCoord2i -GLAD_API_CALL PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; -#define glMultiTexCoord2iv glad_glMultiTexCoord2iv -GLAD_API_CALL PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; -#define glMultiTexCoord2s glad_glMultiTexCoord2s -GLAD_API_CALL PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; -#define glMultiTexCoord2sv glad_glMultiTexCoord2sv -GLAD_API_CALL PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; -#define glMultiTexCoord3d glad_glMultiTexCoord3d -GLAD_API_CALL PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; -#define glMultiTexCoord3dv glad_glMultiTexCoord3dv -GLAD_API_CALL PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; -#define glMultiTexCoord3f glad_glMultiTexCoord3f -GLAD_API_CALL PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; -#define glMultiTexCoord3fv glad_glMultiTexCoord3fv -GLAD_API_CALL PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; -#define glMultiTexCoord3i glad_glMultiTexCoord3i -GLAD_API_CALL PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; -#define glMultiTexCoord3iv glad_glMultiTexCoord3iv -GLAD_API_CALL PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; -#define glMultiTexCoord3s glad_glMultiTexCoord3s -GLAD_API_CALL PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; -#define glMultiTexCoord3sv glad_glMultiTexCoord3sv -GLAD_API_CALL PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; -#define glMultiTexCoord4d glad_glMultiTexCoord4d -GLAD_API_CALL PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; -#define glMultiTexCoord4dv glad_glMultiTexCoord4dv -GLAD_API_CALL PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; -#define glMultiTexCoord4f glad_glMultiTexCoord4f -GLAD_API_CALL PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; -#define glMultiTexCoord4fv glad_glMultiTexCoord4fv -GLAD_API_CALL PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; -#define glMultiTexCoord4i glad_glMultiTexCoord4i -GLAD_API_CALL PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; -#define glMultiTexCoord4iv glad_glMultiTexCoord4iv -GLAD_API_CALL PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; -#define glMultiTexCoord4s glad_glMultiTexCoord4s -GLAD_API_CALL PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; -#define glMultiTexCoord4sv glad_glMultiTexCoord4sv -GLAD_API_CALL PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; -#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui -GLAD_API_CALL PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; -#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv -GLAD_API_CALL PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; -#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui -GLAD_API_CALL PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; -#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv -GLAD_API_CALL PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; -#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui -GLAD_API_CALL PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; -#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv -GLAD_API_CALL PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; -#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui -GLAD_API_CALL PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; -#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv -GLAD_API_CALL PFNGLNEWLISTPROC glad_glNewList; -#define glNewList glad_glNewList -GLAD_API_CALL PFNGLNORMAL3BPROC glad_glNormal3b; -#define glNormal3b glad_glNormal3b -GLAD_API_CALL PFNGLNORMAL3BVPROC glad_glNormal3bv; -#define glNormal3bv glad_glNormal3bv -GLAD_API_CALL PFNGLNORMAL3DPROC glad_glNormal3d; -#define glNormal3d glad_glNormal3d -GLAD_API_CALL PFNGLNORMAL3DVPROC glad_glNormal3dv; -#define glNormal3dv glad_glNormal3dv -GLAD_API_CALL PFNGLNORMAL3FPROC glad_glNormal3f; -#define glNormal3f glad_glNormal3f -GLAD_API_CALL PFNGLNORMAL3FVPROC glad_glNormal3fv; -#define glNormal3fv glad_glNormal3fv -GLAD_API_CALL PFNGLNORMAL3IPROC glad_glNormal3i; -#define glNormal3i glad_glNormal3i -GLAD_API_CALL PFNGLNORMAL3IVPROC glad_glNormal3iv; -#define glNormal3iv glad_glNormal3iv -GLAD_API_CALL PFNGLNORMAL3SPROC glad_glNormal3s; -#define glNormal3s glad_glNormal3s -GLAD_API_CALL PFNGLNORMAL3SVPROC glad_glNormal3sv; -#define glNormal3sv glad_glNormal3sv -GLAD_API_CALL PFNGLNORMALP3UIPROC glad_glNormalP3ui; -#define glNormalP3ui glad_glNormalP3ui -GLAD_API_CALL PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; -#define glNormalP3uiv glad_glNormalP3uiv -GLAD_API_CALL PFNGLNORMALPOINTERPROC glad_glNormalPointer; -#define glNormalPointer glad_glNormalPointer -GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel; -#define glObjectLabel glad_glObjectLabel -GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; -#define glObjectPtrLabel glad_glObjectPtrLabel -GLAD_API_CALL PFNGLORTHOPROC glad_glOrtho; -#define glOrtho glad_glOrtho -GLAD_API_CALL PFNGLPASSTHROUGHPROC glad_glPassThrough; -#define glPassThrough glad_glPassThrough -GLAD_API_CALL PFNGLPIXELMAPFVPROC glad_glPixelMapfv; -#define glPixelMapfv glad_glPixelMapfv -GLAD_API_CALL PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; -#define glPixelMapuiv glad_glPixelMapuiv -GLAD_API_CALL PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; -#define glPixelMapusv glad_glPixelMapusv -GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; -#define glPixelStoref glad_glPixelStoref -GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -GLAD_API_CALL PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; -#define glPixelTransferf glad_glPixelTransferf -GLAD_API_CALL PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; -#define glPixelTransferi glad_glPixelTransferi -GLAD_API_CALL PFNGLPIXELZOOMPROC glad_glPixelZoom; -#define glPixelZoom glad_glPixelZoom -GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -#define glPointParameterf glad_glPointParameterf -GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -#define glPointParameterfv glad_glPointParameterfv -GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -#define glPointParameteri glad_glPointParameteri -GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -#define glPointParameteriv glad_glPointParameteriv -GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; -#define glPointSize glad_glPointSize -GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; -#define glPolygonMode glad_glPolygonMode -GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -#define glPolygonOffset glad_glPolygonOffset -GLAD_API_CALL PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; -#define glPolygonStipple glad_glPolygonStipple -GLAD_API_CALL PFNGLPOPATTRIBPROC glad_glPopAttrib; -#define glPopAttrib glad_glPopAttrib -GLAD_API_CALL PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; -#define glPopClientAttrib glad_glPopClientAttrib -GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; -#define glPopDebugGroup glad_glPopDebugGroup -GLAD_API_CALL PFNGLPOPMATRIXPROC glad_glPopMatrix; -#define glPopMatrix glad_glPopMatrix -GLAD_API_CALL PFNGLPOPNAMEPROC glad_glPopName; -#define glPopName glad_glPopName -GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -GLAD_API_CALL PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; -#define glPrioritizeTextures glad_glPrioritizeTextures -GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -#define glProvokingVertex glad_glProvokingVertex -GLAD_API_CALL PFNGLPUSHATTRIBPROC glad_glPushAttrib; -#define glPushAttrib glad_glPushAttrib -GLAD_API_CALL PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; -#define glPushClientAttrib glad_glPushClientAttrib -GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; -#define glPushDebugGroup glad_glPushDebugGroup -GLAD_API_CALL PFNGLPUSHMATRIXPROC glad_glPushMatrix; -#define glPushMatrix glad_glPushMatrix -GLAD_API_CALL PFNGLPUSHNAMEPROC glad_glPushName; -#define glPushName glad_glPushName -GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; -#define glQueryCounter glad_glQueryCounter -GLAD_API_CALL PFNGLRASTERPOS2DPROC glad_glRasterPos2d; -#define glRasterPos2d glad_glRasterPos2d -GLAD_API_CALL PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; -#define glRasterPos2dv glad_glRasterPos2dv -GLAD_API_CALL PFNGLRASTERPOS2FPROC glad_glRasterPos2f; -#define glRasterPos2f glad_glRasterPos2f -GLAD_API_CALL PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; -#define glRasterPos2fv glad_glRasterPos2fv -GLAD_API_CALL PFNGLRASTERPOS2IPROC glad_glRasterPos2i; -#define glRasterPos2i glad_glRasterPos2i -GLAD_API_CALL PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; -#define glRasterPos2iv glad_glRasterPos2iv -GLAD_API_CALL PFNGLRASTERPOS2SPROC glad_glRasterPos2s; -#define glRasterPos2s glad_glRasterPos2s -GLAD_API_CALL PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; -#define glRasterPos2sv glad_glRasterPos2sv -GLAD_API_CALL PFNGLRASTERPOS3DPROC glad_glRasterPos3d; -#define glRasterPos3d glad_glRasterPos3d -GLAD_API_CALL PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; -#define glRasterPos3dv glad_glRasterPos3dv -GLAD_API_CALL PFNGLRASTERPOS3FPROC glad_glRasterPos3f; -#define glRasterPos3f glad_glRasterPos3f -GLAD_API_CALL PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; -#define glRasterPos3fv glad_glRasterPos3fv -GLAD_API_CALL PFNGLRASTERPOS3IPROC glad_glRasterPos3i; -#define glRasterPos3i glad_glRasterPos3i -GLAD_API_CALL PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; -#define glRasterPos3iv glad_glRasterPos3iv -GLAD_API_CALL PFNGLRASTERPOS3SPROC glad_glRasterPos3s; -#define glRasterPos3s glad_glRasterPos3s -GLAD_API_CALL PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; -#define glRasterPos3sv glad_glRasterPos3sv -GLAD_API_CALL PFNGLRASTERPOS4DPROC glad_glRasterPos4d; -#define glRasterPos4d glad_glRasterPos4d -GLAD_API_CALL PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; -#define glRasterPos4dv glad_glRasterPos4dv -GLAD_API_CALL PFNGLRASTERPOS4FPROC glad_glRasterPos4f; -#define glRasterPos4f glad_glRasterPos4f -GLAD_API_CALL PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; -#define glRasterPos4fv glad_glRasterPos4fv -GLAD_API_CALL PFNGLRASTERPOS4IPROC glad_glRasterPos4i; -#define glRasterPos4i glad_glRasterPos4i -GLAD_API_CALL PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; -#define glRasterPos4iv glad_glRasterPos4iv -GLAD_API_CALL PFNGLRASTERPOS4SPROC glad_glRasterPos4s; -#define glRasterPos4s glad_glRasterPos4s -GLAD_API_CALL PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; -#define glRasterPos4sv glad_glRasterPos4sv -GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; -#define glReadBuffer glad_glReadBuffer -GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -GLAD_API_CALL PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; -#define glReadnPixelsARB glad_glReadnPixelsARB -GLAD_API_CALL PFNGLRECTDPROC glad_glRectd; -#define glRectd glad_glRectd -GLAD_API_CALL PFNGLRECTDVPROC glad_glRectdv; -#define glRectdv glad_glRectdv -GLAD_API_CALL PFNGLRECTFPROC glad_glRectf; -#define glRectf glad_glRectf -GLAD_API_CALL PFNGLRECTFVPROC glad_glRectfv; -#define glRectfv glad_glRectfv -GLAD_API_CALL PFNGLRECTIPROC glad_glRecti; -#define glRecti glad_glRecti -GLAD_API_CALL PFNGLRECTIVPROC glad_glRectiv; -#define glRectiv glad_glRectiv -GLAD_API_CALL PFNGLRECTSPROC glad_glRects; -#define glRects glad_glRects -GLAD_API_CALL PFNGLRECTSVPROC glad_glRectsv; -#define glRectsv glad_glRectsv -GLAD_API_CALL PFNGLRENDERMODEPROC glad_glRenderMode; -#define glRenderMode glad_glRenderMode -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated; -#define glRotated glad_glRotated -GLAD_API_CALL PFNGLROTATEFPROC glad_glRotatef; -#define glRotatef glad_glRotatef -GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -GLAD_API_CALL PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; -#define glSampleCoverageARB glad_glSampleCoverageARB -GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; -#define glSamplerParameterIiv glad_glSamplerParameterIiv -GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; -#define glSamplerParameterIuiv glad_glSamplerParameterIuiv -GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; -#define glSamplerParameterf glad_glSamplerParameterf -GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; -#define glSamplerParameterfv glad_glSamplerParameterfv -GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; -#define glSamplerParameteri glad_glSamplerParameteri -GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; -#define glSamplerParameteriv glad_glSamplerParameteriv -GLAD_API_CALL PFNGLSCALEDPROC glad_glScaled; -#define glScaled glad_glScaled -GLAD_API_CALL PFNGLSCALEFPROC glad_glScalef; -#define glScalef glad_glScalef -GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -GLAD_API_CALL PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; -#define glSecondaryColor3b glad_glSecondaryColor3b -GLAD_API_CALL PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; -#define glSecondaryColor3bv glad_glSecondaryColor3bv -GLAD_API_CALL PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; -#define glSecondaryColor3d glad_glSecondaryColor3d -GLAD_API_CALL PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; -#define glSecondaryColor3dv glad_glSecondaryColor3dv -GLAD_API_CALL PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; -#define glSecondaryColor3f glad_glSecondaryColor3f -GLAD_API_CALL PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; -#define glSecondaryColor3fv glad_glSecondaryColor3fv -GLAD_API_CALL PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; -#define glSecondaryColor3i glad_glSecondaryColor3i -GLAD_API_CALL PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; -#define glSecondaryColor3iv glad_glSecondaryColor3iv -GLAD_API_CALL PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; -#define glSecondaryColor3s glad_glSecondaryColor3s -GLAD_API_CALL PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; -#define glSecondaryColor3sv glad_glSecondaryColor3sv -GLAD_API_CALL PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; -#define glSecondaryColor3ub glad_glSecondaryColor3ub -GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; -#define glSecondaryColor3ubv glad_glSecondaryColor3ubv -GLAD_API_CALL PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; -#define glSecondaryColor3ui glad_glSecondaryColor3ui -GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; -#define glSecondaryColor3uiv glad_glSecondaryColor3uiv -GLAD_API_CALL PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; -#define glSecondaryColor3us glad_glSecondaryColor3us -GLAD_API_CALL PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; -#define glSecondaryColor3usv glad_glSecondaryColor3usv -GLAD_API_CALL PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; -#define glSecondaryColorP3ui glad_glSecondaryColorP3ui -GLAD_API_CALL PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; -#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv -GLAD_API_CALL PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; -#define glSecondaryColorPointer glad_glSecondaryColorPointer -GLAD_API_CALL PFNGLSELECTBUFFERPROC glad_glSelectBuffer; -#define glSelectBuffer glad_glSelectBuffer -GLAD_API_CALL PFNGLSHADEMODELPROC glad_glShadeModel; -#define glShadeModel glad_glShadeModel -GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; -#define glStencilMask glad_glStencilMask -GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -#define glStencilMaskSeparate glad_glStencilMaskSeparate -GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; -#define glStencilOp glad_glStencilOp -GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -#define glStencilOpSeparate glad_glStencilOpSeparate -GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; -#define glTexBuffer glad_glTexBuffer -GLAD_API_CALL PFNGLTEXCOORD1DPROC glad_glTexCoord1d; -#define glTexCoord1d glad_glTexCoord1d -GLAD_API_CALL PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; -#define glTexCoord1dv glad_glTexCoord1dv -GLAD_API_CALL PFNGLTEXCOORD1FPROC glad_glTexCoord1f; -#define glTexCoord1f glad_glTexCoord1f -GLAD_API_CALL PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; -#define glTexCoord1fv glad_glTexCoord1fv -GLAD_API_CALL PFNGLTEXCOORD1IPROC glad_glTexCoord1i; -#define glTexCoord1i glad_glTexCoord1i -GLAD_API_CALL PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; -#define glTexCoord1iv glad_glTexCoord1iv -GLAD_API_CALL PFNGLTEXCOORD1SPROC glad_glTexCoord1s; -#define glTexCoord1s glad_glTexCoord1s -GLAD_API_CALL PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; -#define glTexCoord1sv glad_glTexCoord1sv -GLAD_API_CALL PFNGLTEXCOORD2DPROC glad_glTexCoord2d; -#define glTexCoord2d glad_glTexCoord2d -GLAD_API_CALL PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; -#define glTexCoord2dv glad_glTexCoord2dv -GLAD_API_CALL PFNGLTEXCOORD2FPROC glad_glTexCoord2f; -#define glTexCoord2f glad_glTexCoord2f -GLAD_API_CALL PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; -#define glTexCoord2fv glad_glTexCoord2fv -GLAD_API_CALL PFNGLTEXCOORD2IPROC glad_glTexCoord2i; -#define glTexCoord2i glad_glTexCoord2i -GLAD_API_CALL PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; -#define glTexCoord2iv glad_glTexCoord2iv -GLAD_API_CALL PFNGLTEXCOORD2SPROC glad_glTexCoord2s; -#define glTexCoord2s glad_glTexCoord2s -GLAD_API_CALL PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; -#define glTexCoord2sv glad_glTexCoord2sv -GLAD_API_CALL PFNGLTEXCOORD3DPROC glad_glTexCoord3d; -#define glTexCoord3d glad_glTexCoord3d -GLAD_API_CALL PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; -#define glTexCoord3dv glad_glTexCoord3dv -GLAD_API_CALL PFNGLTEXCOORD3FPROC glad_glTexCoord3f; -#define glTexCoord3f glad_glTexCoord3f -GLAD_API_CALL PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; -#define glTexCoord3fv glad_glTexCoord3fv -GLAD_API_CALL PFNGLTEXCOORD3IPROC glad_glTexCoord3i; -#define glTexCoord3i glad_glTexCoord3i -GLAD_API_CALL PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; -#define glTexCoord3iv glad_glTexCoord3iv -GLAD_API_CALL PFNGLTEXCOORD3SPROC glad_glTexCoord3s; -#define glTexCoord3s glad_glTexCoord3s -GLAD_API_CALL PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; -#define glTexCoord3sv glad_glTexCoord3sv -GLAD_API_CALL PFNGLTEXCOORD4DPROC glad_glTexCoord4d; -#define glTexCoord4d glad_glTexCoord4d -GLAD_API_CALL PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; -#define glTexCoord4dv glad_glTexCoord4dv -GLAD_API_CALL PFNGLTEXCOORD4FPROC glad_glTexCoord4f; -#define glTexCoord4f glad_glTexCoord4f -GLAD_API_CALL PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; -#define glTexCoord4fv glad_glTexCoord4fv -GLAD_API_CALL PFNGLTEXCOORD4IPROC glad_glTexCoord4i; -#define glTexCoord4i glad_glTexCoord4i -GLAD_API_CALL PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; -#define glTexCoord4iv glad_glTexCoord4iv -GLAD_API_CALL PFNGLTEXCOORD4SPROC glad_glTexCoord4s; -#define glTexCoord4s glad_glTexCoord4s -GLAD_API_CALL PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; -#define glTexCoord4sv glad_glTexCoord4sv -GLAD_API_CALL PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; -#define glTexCoordP1ui glad_glTexCoordP1ui -GLAD_API_CALL PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; -#define glTexCoordP1uiv glad_glTexCoordP1uiv -GLAD_API_CALL PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; -#define glTexCoordP2ui glad_glTexCoordP2ui -GLAD_API_CALL PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; -#define glTexCoordP2uiv glad_glTexCoordP2uiv -GLAD_API_CALL PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; -#define glTexCoordP3ui glad_glTexCoordP3ui -GLAD_API_CALL PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; -#define glTexCoordP3uiv glad_glTexCoordP3uiv -GLAD_API_CALL PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; -#define glTexCoordP4ui glad_glTexCoordP4ui -GLAD_API_CALL PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; -#define glTexCoordP4uiv glad_glTexCoordP4uiv -GLAD_API_CALL PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; -#define glTexCoordPointer glad_glTexCoordPointer -GLAD_API_CALL PFNGLTEXENVFPROC glad_glTexEnvf; -#define glTexEnvf glad_glTexEnvf -GLAD_API_CALL PFNGLTEXENVFVPROC glad_glTexEnvfv; -#define glTexEnvfv glad_glTexEnvfv -GLAD_API_CALL PFNGLTEXENVIPROC glad_glTexEnvi; -#define glTexEnvi glad_glTexEnvi -GLAD_API_CALL PFNGLTEXENVIVPROC glad_glTexEnviv; -#define glTexEnviv glad_glTexEnviv -GLAD_API_CALL PFNGLTEXGENDPROC glad_glTexGend; -#define glTexGend glad_glTexGend -GLAD_API_CALL PFNGLTEXGENDVPROC glad_glTexGendv; -#define glTexGendv glad_glTexGendv -GLAD_API_CALL PFNGLTEXGENFPROC glad_glTexGenf; -#define glTexGenf glad_glTexGenf -GLAD_API_CALL PFNGLTEXGENFVPROC glad_glTexGenfv; -#define glTexGenfv glad_glTexGenfv -GLAD_API_CALL PFNGLTEXGENIPROC glad_glTexGeni; -#define glTexGeni glad_glTexGeni -GLAD_API_CALL PFNGLTEXGENIVPROC glad_glTexGeniv; -#define glTexGeniv glad_glTexGeniv -GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; -#define glTexImage1D glad_glTexImage1D -GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -#define glTexImage2D glad_glTexImage2D -GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -#define glTexImage2DMultisample glad_glTexImage2DMultisample -GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -#define glTexImage3D glad_glTexImage3D -GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -#define glTexImage3DMultisample glad_glTexImage3DMultisample -GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -#define glTexParameterIiv glad_glTexParameterIiv -GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -#define glTexParameterIuiv glad_glTexParameterIuiv -GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -#define glTexParameterf glad_glTexParameterf -GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -#define glTexParameterfv glad_glTexParameterfv -GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -#define glTexParameteri glad_glTexParameteri -GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -#define glTexParameteriv glad_glTexParameteriv -GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -#define glTexSubImage1D glad_glTexSubImage1D -GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -#define glTexSubImage3D glad_glTexSubImage3D -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -GLAD_API_CALL PFNGLTRANSLATEDPROC glad_glTranslated; -#define glTranslated glad_glTranslated -GLAD_API_CALL PFNGLTRANSLATEFPROC glad_glTranslatef; -#define glTranslatef glad_glTranslatef -GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; -#define glUniform1f glad_glUniform1f -GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; -#define glUniform1ui glad_glUniform1ui -GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -#define glUniform1uiv glad_glUniform1uiv -GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; -#define glUniform2f glad_glUniform2f -GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; -#define glUniform2ui glad_glUniform2ui -GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -#define glUniform2uiv glad_glUniform2uiv -GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; -#define glUniform3f glad_glUniform3f -GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; -#define glUniform3ui glad_glUniform3ui -GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -#define glUniform3uiv glad_glUniform3uiv -GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; -#define glUniform4f glad_glUniform4f -GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; -#define glUniform4ui glad_glUniform4ui -GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -#define glUniform4uiv glad_glUniform4uiv -GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv -GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -#define glUniformMatrix3fv glad_glUniformMatrix3fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -#define glUniformMatrix4fv glad_glUniformMatrix4fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv -GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -#define glUnmapBuffer glad_glUnmapBuffer -GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -GLAD_API_CALL PFNGLVERTEX2DPROC glad_glVertex2d; -#define glVertex2d glad_glVertex2d -GLAD_API_CALL PFNGLVERTEX2DVPROC glad_glVertex2dv; -#define glVertex2dv glad_glVertex2dv -GLAD_API_CALL PFNGLVERTEX2FPROC glad_glVertex2f; -#define glVertex2f glad_glVertex2f -GLAD_API_CALL PFNGLVERTEX2FVPROC glad_glVertex2fv; -#define glVertex2fv glad_glVertex2fv -GLAD_API_CALL PFNGLVERTEX2IPROC glad_glVertex2i; -#define glVertex2i glad_glVertex2i -GLAD_API_CALL PFNGLVERTEX2IVPROC glad_glVertex2iv; -#define glVertex2iv glad_glVertex2iv -GLAD_API_CALL PFNGLVERTEX2SPROC glad_glVertex2s; -#define glVertex2s glad_glVertex2s -GLAD_API_CALL PFNGLVERTEX2SVPROC glad_glVertex2sv; -#define glVertex2sv glad_glVertex2sv -GLAD_API_CALL PFNGLVERTEX3DPROC glad_glVertex3d; -#define glVertex3d glad_glVertex3d -GLAD_API_CALL PFNGLVERTEX3DVPROC glad_glVertex3dv; -#define glVertex3dv glad_glVertex3dv -GLAD_API_CALL PFNGLVERTEX3FPROC glad_glVertex3f; -#define glVertex3f glad_glVertex3f -GLAD_API_CALL PFNGLVERTEX3FVPROC glad_glVertex3fv; -#define glVertex3fv glad_glVertex3fv -GLAD_API_CALL PFNGLVERTEX3IPROC glad_glVertex3i; -#define glVertex3i glad_glVertex3i -GLAD_API_CALL PFNGLVERTEX3IVPROC glad_glVertex3iv; -#define glVertex3iv glad_glVertex3iv -GLAD_API_CALL PFNGLVERTEX3SPROC glad_glVertex3s; -#define glVertex3s glad_glVertex3s -GLAD_API_CALL PFNGLVERTEX3SVPROC glad_glVertex3sv; -#define glVertex3sv glad_glVertex3sv -GLAD_API_CALL PFNGLVERTEX4DPROC glad_glVertex4d; -#define glVertex4d glad_glVertex4d -GLAD_API_CALL PFNGLVERTEX4DVPROC glad_glVertex4dv; -#define glVertex4dv glad_glVertex4dv -GLAD_API_CALL PFNGLVERTEX4FPROC glad_glVertex4f; -#define glVertex4f glad_glVertex4f -GLAD_API_CALL PFNGLVERTEX4FVPROC glad_glVertex4fv; -#define glVertex4fv glad_glVertex4fv -GLAD_API_CALL PFNGLVERTEX4IPROC glad_glVertex4i; -#define glVertex4i glad_glVertex4i -GLAD_API_CALL PFNGLVERTEX4IVPROC glad_glVertex4iv; -#define glVertex4iv glad_glVertex4iv -GLAD_API_CALL PFNGLVERTEX4SPROC glad_glVertex4s; -#define glVertex4s glad_glVertex4s -GLAD_API_CALL PFNGLVERTEX4SVPROC glad_glVertex4sv; -#define glVertex4sv glad_glVertex4sv -GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -#define glVertexAttrib1d glad_glVertexAttrib1d -GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -#define glVertexAttrib1dv glad_glVertexAttrib1dv -GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -#define glVertexAttrib1s glad_glVertexAttrib1s -GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -#define glVertexAttrib1sv glad_glVertexAttrib1sv -GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -#define glVertexAttrib2d glad_glVertexAttrib2d -GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -#define glVertexAttrib2dv glad_glVertexAttrib2dv -GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -#define glVertexAttrib2s glad_glVertexAttrib2s -GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -#define glVertexAttrib2sv glad_glVertexAttrib2sv -GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -#define glVertexAttrib3d glad_glVertexAttrib3d -GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -#define glVertexAttrib3dv glad_glVertexAttrib3dv -GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -#define glVertexAttrib3s glad_glVertexAttrib3s -GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -#define glVertexAttrib3sv glad_glVertexAttrib3sv -GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv -GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -#define glVertexAttrib4Niv glad_glVertexAttrib4Niv -GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -#define glVertexAttrib4Nub glad_glVertexAttrib4Nub -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv -GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -#define glVertexAttrib4bv glad_glVertexAttrib4bv -GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -#define glVertexAttrib4d glad_glVertexAttrib4d -GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -#define glVertexAttrib4dv glad_glVertexAttrib4dv -GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -#define glVertexAttrib4iv glad_glVertexAttrib4iv -GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -#define glVertexAttrib4s glad_glVertexAttrib4s -GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -#define glVertexAttrib4sv glad_glVertexAttrib4sv -GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -#define glVertexAttrib4ubv glad_glVertexAttrib4ubv -GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -#define glVertexAttrib4uiv glad_glVertexAttrib4uiv -GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -#define glVertexAttrib4usv glad_glVertexAttrib4usv -GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -#define glVertexAttribDivisor glad_glVertexAttribDivisor -GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -#define glVertexAttribI1i glad_glVertexAttribI1i -GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -#define glVertexAttribI1iv glad_glVertexAttribI1iv -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -#define glVertexAttribI1ui glad_glVertexAttribI1ui -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -#define glVertexAttribI1uiv glad_glVertexAttribI1uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -#define glVertexAttribI2i glad_glVertexAttribI2i -GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -#define glVertexAttribI2iv glad_glVertexAttribI2iv -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -#define glVertexAttribI2ui glad_glVertexAttribI2ui -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -#define glVertexAttribI2uiv glad_glVertexAttribI2uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -#define glVertexAttribI3i glad_glVertexAttribI3i -GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -#define glVertexAttribI3iv glad_glVertexAttribI3iv -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -#define glVertexAttribI3ui glad_glVertexAttribI3ui -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -#define glVertexAttribI3uiv glad_glVertexAttribI3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -#define glVertexAttribI4bv glad_glVertexAttribI4bv -GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -#define glVertexAttribI4i glad_glVertexAttribI4i -GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -#define glVertexAttribI4iv glad_glVertexAttribI4iv -GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -#define glVertexAttribI4sv glad_glVertexAttribI4sv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -#define glVertexAttribI4ubv glad_glVertexAttribI4ubv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -#define glVertexAttribI4ui glad_glVertexAttribI4ui -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -#define glVertexAttribI4uiv glad_glVertexAttribI4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -#define glVertexAttribI4usv glad_glVertexAttribI4usv -GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -#define glVertexAttribIPointer glad_glVertexAttribIPointer -GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; -#define glVertexAttribP1ui glad_glVertexAttribP1ui -GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; -#define glVertexAttribP1uiv glad_glVertexAttribP1uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; -#define glVertexAttribP2ui glad_glVertexAttribP2ui -GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; -#define glVertexAttribP2uiv glad_glVertexAttribP2uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; -#define glVertexAttribP3ui glad_glVertexAttribP3ui -GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; -#define glVertexAttribP3uiv glad_glVertexAttribP3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; -#define glVertexAttribP4ui glad_glVertexAttribP4ui -GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; -#define glVertexAttribP4uiv glad_glVertexAttribP4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -GLAD_API_CALL PFNGLVERTEXP2UIPROC glad_glVertexP2ui; -#define glVertexP2ui glad_glVertexP2ui -GLAD_API_CALL PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; -#define glVertexP2uiv glad_glVertexP2uiv -GLAD_API_CALL PFNGLVERTEXP3UIPROC glad_glVertexP3ui; -#define glVertexP3ui glad_glVertexP3ui -GLAD_API_CALL PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; -#define glVertexP3uiv glad_glVertexP3uiv -GLAD_API_CALL PFNGLVERTEXP4UIPROC glad_glVertexP4ui; -#define glVertexP4ui glad_glVertexP4ui -GLAD_API_CALL PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; -#define glVertexP4uiv glad_glVertexP4uiv -GLAD_API_CALL PFNGLVERTEXPOINTERPROC glad_glVertexPointer; -#define glVertexPointer glad_glVertexPointer -GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; -#define glViewport glad_glViewport -GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync -GLAD_API_CALL PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; -#define glWindowPos2d glad_glWindowPos2d -GLAD_API_CALL PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; -#define glWindowPos2dv glad_glWindowPos2dv -GLAD_API_CALL PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; -#define glWindowPos2f glad_glWindowPos2f -GLAD_API_CALL PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; -#define glWindowPos2fv glad_glWindowPos2fv -GLAD_API_CALL PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; -#define glWindowPos2i glad_glWindowPos2i -GLAD_API_CALL PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; -#define glWindowPos2iv glad_glWindowPos2iv -GLAD_API_CALL PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; -#define glWindowPos2s glad_glWindowPos2s -GLAD_API_CALL PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; -#define glWindowPos2sv glad_glWindowPos2sv -GLAD_API_CALL PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; -#define glWindowPos3d glad_glWindowPos3d -GLAD_API_CALL PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; -#define glWindowPos3dv glad_glWindowPos3dv -GLAD_API_CALL PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; -#define glWindowPos3f glad_glWindowPos3f -GLAD_API_CALL PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; -#define glWindowPos3fv glad_glWindowPos3fv -GLAD_API_CALL PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; -#define glWindowPos3i glad_glWindowPos3i -GLAD_API_CALL PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; -#define glWindowPos3iv glad_glWindowPos3iv -GLAD_API_CALL PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; -#define glWindowPos3s glad_glWindowPos3s -GLAD_API_CALL PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; -#define glWindowPos3sv glad_glWindowPos3sv - - - - - -GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadGL( GLADloadfunc load); - - - -#ifdef __cplusplus -} -#endif -#endif - -/* Source */ -#ifdef GLAD_GL_IMPLEMENTATION -#include -#include -#include - -#ifndef GLAD_IMPL_UTIL_C_ -#define GLAD_IMPL_UTIL_C_ - -#ifdef _MSC_VER -#define GLAD_IMPL_UTIL_SSCANF sscanf_s -#else -#define GLAD_IMPL_UTIL_SSCANF sscanf -#endif - -#endif /* GLAD_IMPL_UTIL_C_ */ - -#ifdef __cplusplus -extern "C" { -#endif - - - -int GLAD_GL_VERSION_1_0 = 0; -int GLAD_GL_VERSION_1_1 = 0; -int GLAD_GL_VERSION_1_2 = 0; -int GLAD_GL_VERSION_1_3 = 0; -int GLAD_GL_VERSION_1_4 = 0; -int GLAD_GL_VERSION_1_5 = 0; -int GLAD_GL_VERSION_2_0 = 0; -int GLAD_GL_VERSION_2_1 = 0; -int GLAD_GL_VERSION_3_0 = 0; -int GLAD_GL_VERSION_3_1 = 0; -int GLAD_GL_VERSION_3_2 = 0; -int GLAD_GL_VERSION_3_3 = 0; -int GLAD_GL_ARB_multisample = 0; -int GLAD_GL_ARB_robustness = 0; -int GLAD_GL_KHR_debug = 0; - - - -PFNGLACCUMPROC glad_glAccum = NULL; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; -PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; -PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINPROC glad_glBegin = NULL; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBITMAPPROC glad_glBitmap = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCALLLISTPROC glad_glCallList = NULL; -PFNGLCALLLISTSPROC glad_glCallLists = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARACCUMPROC glad_glClearAccum = NULL; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; -PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; -PFNGLCOLOR3BPROC glad_glColor3b = NULL; -PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; -PFNGLCOLOR3DPROC glad_glColor3d = NULL; -PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; -PFNGLCOLOR3FPROC glad_glColor3f = NULL; -PFNGLCOLOR3FVPROC glad_glColor3fv = NULL; -PFNGLCOLOR3IPROC glad_glColor3i = NULL; -PFNGLCOLOR3IVPROC glad_glColor3iv = NULL; -PFNGLCOLOR3SPROC glad_glColor3s = NULL; -PFNGLCOLOR3SVPROC glad_glColor3sv = NULL; -PFNGLCOLOR3UBPROC glad_glColor3ub = NULL; -PFNGLCOLOR3UBVPROC glad_glColor3ubv = NULL; -PFNGLCOLOR3UIPROC glad_glColor3ui = NULL; -PFNGLCOLOR3UIVPROC glad_glColor3uiv = NULL; -PFNGLCOLOR3USPROC glad_glColor3us = NULL; -PFNGLCOLOR3USVPROC glad_glColor3usv = NULL; -PFNGLCOLOR4BPROC glad_glColor4b = NULL; -PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; -PFNGLCOLOR4DPROC glad_glColor4d = NULL; -PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; -PFNGLCOLOR4FPROC glad_glColor4f = NULL; -PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; -PFNGLCOLOR4IPROC glad_glColor4i = NULL; -PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; -PFNGLCOLOR4SPROC glad_glColor4s = NULL; -PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; -PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; -PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; -PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; -PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; -PFNGLCOLOR4USPROC glad_glColor4us = NULL; -PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOLORMATERIALPROC glad_glColorMaterial = NULL; -PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; -PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; -PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; -PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; -PFNGLCOLORPOINTERPROC glad_glColorPointer = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; -PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; -PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; -PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDISABLEIPROC glad_glDisablei = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; -PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; -PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; -PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; -PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDPROC glad_glEnd = NULL; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDLISTPROC glad_glEndList = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; -PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; -PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; -PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; -PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; -PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; -PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; -PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; -PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; -PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; -PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; -PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; -PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; -PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; -PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; -PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; -PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; -PFNGLFOGFPROC glad_glFogf = NULL; -PFNGLFOGFVPROC glad_glFogfv = NULL; -PFNGLFOGIPROC glad_glFogi = NULL; -PFNGLFOGIVPROC glad_glFogiv = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLFRUSTUMPROC glad_glFrustum = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENLISTSPROC glad_glGenLists = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; -PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; -PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB = NULL; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; -PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; -PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; -PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; -PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; -PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; -PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; -PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; -PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; -PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; -PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; -PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; -PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; -PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; -PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; -PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; -PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; -PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; -PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB = NULL; -PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB = NULL; -PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB = NULL; -PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB = NULL; -PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB = NULL; -PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB = NULL; -PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB = NULL; -PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB = NULL; -PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB = NULL; -PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB = NULL; -PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB = NULL; -PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB = NULL; -PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB = NULL; -PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB = NULL; -PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB = NULL; -PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB = NULL; -PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB = NULL; -PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLINDEXMASKPROC glad_glIndexMask = NULL; -PFNGLINDEXPOINTERPROC glad_glIndexPointer = NULL; -PFNGLINDEXDPROC glad_glIndexd = NULL; -PFNGLINDEXDVPROC glad_glIndexdv = NULL; -PFNGLINDEXFPROC glad_glIndexf = NULL; -PFNGLINDEXFVPROC glad_glIndexfv = NULL; -PFNGLINDEXIPROC glad_glIndexi = NULL; -PFNGLINDEXIVPROC glad_glIndexiv = NULL; -PFNGLINDEXSPROC glad_glIndexs = NULL; -PFNGLINDEXSVPROC glad_glIndexsv = NULL; -PFNGLINDEXUBPROC glad_glIndexub = NULL; -PFNGLINDEXUBVPROC glad_glIndexubv = NULL; -PFNGLINITNAMESPROC glad_glInitNames = NULL; -PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISLISTPROC glad_glIsList = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSAMPLERPROC glad_glIsSampler = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; -PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; -PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; -PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; -PFNGLLIGHTFPROC glad_glLightf = NULL; -PFNGLLIGHTFVPROC glad_glLightfv = NULL; -PFNGLLIGHTIPROC glad_glLighti = NULL; -PFNGLLIGHTIVPROC glad_glLightiv = NULL; -PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLISTBASEPROC glad_glListBase = NULL; -PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; -PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; -PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; -PFNGLLOADNAMEPROC glad_glLoadName = NULL; -PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; -PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; -PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAP1DPROC glad_glMap1d = NULL; -PFNGLMAP1FPROC glad_glMap1f = NULL; -PFNGLMAP2DPROC glad_glMap2d = NULL; -PFNGLMAP2FPROC glad_glMap2f = NULL; -PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; -PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; -PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; -PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; -PFNGLMATERIALFPROC glad_glMaterialf = NULL; -PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; -PFNGLMATERIALIPROC glad_glMateriali = NULL; -PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; -PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; -PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; -PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; -PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; -PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; -PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; -PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; -PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; -PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; -PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; -PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; -PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; -PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; -PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; -PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; -PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; -PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; -PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; -PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; -PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; -PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; -PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; -PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; -PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; -PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; -PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; -PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; -PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; -PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; -PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; -PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; -PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; -PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; -PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; -PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; -PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; -PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = NULL; -PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; -PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; -PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; -PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; -PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; -PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; -PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; -PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; -PFNGLNEWLISTPROC glad_glNewList = NULL; -PFNGLNORMAL3BPROC glad_glNormal3b = NULL; -PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; -PFNGLNORMAL3DPROC glad_glNormal3d = NULL; -PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; -PFNGLNORMAL3FPROC glad_glNormal3f = NULL; -PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; -PFNGLNORMAL3IPROC glad_glNormal3i = NULL; -PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; -PFNGLNORMAL3SPROC glad_glNormal3s = NULL; -PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; -PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; -PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; -PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; -PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; -PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; -PFNGLORTHOPROC glad_glOrtho = NULL; -PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; -PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; -PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; -PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; -PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; -PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; -PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; -PFNGLPOINTSIZEPROC glad_glPointSize = NULL; -PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; -PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; -PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; -PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; -PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; -PFNGLPOPNAMEPROC glad_glPopName = NULL; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; -PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; -PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; -PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; -PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; -PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; -PFNGLPUSHNAMEPROC glad_glPushName = NULL; -PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; -PFNGLRASTERPOS2DPROC glad_glRasterPos2d = NULL; -PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv = NULL; -PFNGLRASTERPOS2FPROC glad_glRasterPos2f = NULL; -PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv = NULL; -PFNGLRASTERPOS2IPROC glad_glRasterPos2i = NULL; -PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv = NULL; -PFNGLRASTERPOS2SPROC glad_glRasterPos2s = NULL; -PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv = NULL; -PFNGLRASTERPOS3DPROC glad_glRasterPos3d = NULL; -PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv = NULL; -PFNGLRASTERPOS3FPROC glad_glRasterPos3f = NULL; -PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv = NULL; -PFNGLRASTERPOS3IPROC glad_glRasterPos3i = NULL; -PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv = NULL; -PFNGLRASTERPOS3SPROC glad_glRasterPos3s = NULL; -PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv = NULL; -PFNGLRASTERPOS4DPROC glad_glRasterPos4d = NULL; -PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv = NULL; -PFNGLRASTERPOS4FPROC glad_glRasterPos4f = NULL; -PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv = NULL; -PFNGLRASTERPOS4IPROC glad_glRasterPos4i = NULL; -PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv = NULL; -PFNGLRASTERPOS4SPROC glad_glRasterPos4s = NULL; -PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv = NULL; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB = NULL; -PFNGLRECTDPROC glad_glRectd = NULL; -PFNGLRECTDVPROC glad_glRectdv = NULL; -PFNGLRECTFPROC glad_glRectf = NULL; -PFNGLRECTFVPROC glad_glRectfv = NULL; -PFNGLRECTIPROC glad_glRecti = NULL; -PFNGLRECTIVPROC glad_glRectiv = NULL; -PFNGLRECTSPROC glad_glRects = NULL; -PFNGLRECTSVPROC glad_glRectsv = NULL; -PFNGLRENDERMODEPROC glad_glRenderMode = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLROTATEDPROC glad_glRotated = NULL; -PFNGLROTATEFPROC glad_glRotatef = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB = NULL; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; -PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; -PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; -PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; -PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; -PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; -PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; -PFNGLSCALEDPROC glad_glScaled = NULL; -PFNGLSCALEFPROC glad_glScalef = NULL; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; -PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; -PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; -PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; -PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; -PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; -PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; -PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; -PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; -PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; -PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; -PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; -PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; -PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; -PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; -PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; -PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; -PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; -PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; -PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; -PFNGLSHADEMODELPROC glad_glShadeModel = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; -PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; -PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; -PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; -PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; -PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; -PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; -PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; -PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; -PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; -PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; -PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; -PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; -PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; -PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; -PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; -PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; -PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; -PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; -PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; -PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; -PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; -PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; -PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; -PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; -PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; -PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; -PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; -PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; -PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; -PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; -PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; -PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = NULL; -PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; -PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; -PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; -PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; -PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; -PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; -PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; -PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; -PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer = NULL; -PFNGLTEXENVFPROC glad_glTexEnvf = NULL; -PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; -PFNGLTEXENVIPROC glad_glTexEnvi = NULL; -PFNGLTEXENVIVPROC glad_glTexEnviv = NULL; -PFNGLTEXGENDPROC glad_glTexGend = NULL; -PFNGLTEXGENDVPROC glad_glTexGendv = NULL; -PFNGLTEXGENFPROC glad_glTexGenf = NULL; -PFNGLTEXGENFVPROC glad_glTexGenfv = NULL; -PFNGLTEXGENIPROC glad_glTexGeni = NULL; -PFNGLTEXGENIVPROC glad_glTexGeniv = NULL; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLTRANSLATEDPROC glad_glTranslated = NULL; -PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVERTEX2DPROC glad_glVertex2d = NULL; -PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; -PFNGLVERTEX2FPROC glad_glVertex2f = NULL; -PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; -PFNGLVERTEX2IPROC glad_glVertex2i = NULL; -PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; -PFNGLVERTEX2SPROC glad_glVertex2s = NULL; -PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; -PFNGLVERTEX3DPROC glad_glVertex3d = NULL; -PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; -PFNGLVERTEX3FPROC glad_glVertex3f = NULL; -PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; -PFNGLVERTEX3IPROC glad_glVertex3i = NULL; -PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; -PFNGLVERTEX3SPROC glad_glVertex3s = NULL; -PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; -PFNGLVERTEX4DPROC glad_glVertex4d = NULL; -PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; -PFNGLVERTEX4FPROC glad_glVertex4f = NULL; -PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; -PFNGLVERTEX4IPROC glad_glVertex4i = NULL; -PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; -PFNGLVERTEX4SPROC glad_glVertex4s = NULL; -PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; -PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; -PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; -PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; -PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; -PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; -PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; -PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; -PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; -PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; -PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; -PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; -PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; -PFNGLVERTEXPOINTERPROC glad_glVertexPointer = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; -PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; -PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; -PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; -PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; -PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; -PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; -PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; -PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; -PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; -PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; -PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; -PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; -PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; -PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; -PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL; - - -static void glad_gl_load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_0) return; - glad_glAccum = (PFNGLACCUMPROC) load(userptr, "glAccum"); - glad_glAlphaFunc = (PFNGLALPHAFUNCPROC) load(userptr, "glAlphaFunc"); - glad_glBegin = (PFNGLBEGINPROC) load(userptr, "glBegin"); - glad_glBitmap = (PFNGLBITMAPPROC) load(userptr, "glBitmap"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); - glad_glCallList = (PFNGLCALLLISTPROC) load(userptr, "glCallList"); - glad_glCallLists = (PFNGLCALLLISTSPROC) load(userptr, "glCallLists"); - glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); - glad_glClearAccum = (PFNGLCLEARACCUMPROC) load(userptr, "glClearAccum"); - glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); - glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); - glad_glClearIndex = (PFNGLCLEARINDEXPROC) load(userptr, "glClearIndex"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); - glad_glClipPlane = (PFNGLCLIPPLANEPROC) load(userptr, "glClipPlane"); - glad_glColor3b = (PFNGLCOLOR3BPROC) load(userptr, "glColor3b"); - glad_glColor3bv = (PFNGLCOLOR3BVPROC) load(userptr, "glColor3bv"); - glad_glColor3d = (PFNGLCOLOR3DPROC) load(userptr, "glColor3d"); - glad_glColor3dv = (PFNGLCOLOR3DVPROC) load(userptr, "glColor3dv"); - glad_glColor3f = (PFNGLCOLOR3FPROC) load(userptr, "glColor3f"); - glad_glColor3fv = (PFNGLCOLOR3FVPROC) load(userptr, "glColor3fv"); - glad_glColor3i = (PFNGLCOLOR3IPROC) load(userptr, "glColor3i"); - glad_glColor3iv = (PFNGLCOLOR3IVPROC) load(userptr, "glColor3iv"); - glad_glColor3s = (PFNGLCOLOR3SPROC) load(userptr, "glColor3s"); - glad_glColor3sv = (PFNGLCOLOR3SVPROC) load(userptr, "glColor3sv"); - glad_glColor3ub = (PFNGLCOLOR3UBPROC) load(userptr, "glColor3ub"); - glad_glColor3ubv = (PFNGLCOLOR3UBVPROC) load(userptr, "glColor3ubv"); - glad_glColor3ui = (PFNGLCOLOR3UIPROC) load(userptr, "glColor3ui"); - glad_glColor3uiv = (PFNGLCOLOR3UIVPROC) load(userptr, "glColor3uiv"); - glad_glColor3us = (PFNGLCOLOR3USPROC) load(userptr, "glColor3us"); - glad_glColor3usv = (PFNGLCOLOR3USVPROC) load(userptr, "glColor3usv"); - glad_glColor4b = (PFNGLCOLOR4BPROC) load(userptr, "glColor4b"); - glad_glColor4bv = (PFNGLCOLOR4BVPROC) load(userptr, "glColor4bv"); - glad_glColor4d = (PFNGLCOLOR4DPROC) load(userptr, "glColor4d"); - glad_glColor4dv = (PFNGLCOLOR4DVPROC) load(userptr, "glColor4dv"); - glad_glColor4f = (PFNGLCOLOR4FPROC) load(userptr, "glColor4f"); - glad_glColor4fv = (PFNGLCOLOR4FVPROC) load(userptr, "glColor4fv"); - glad_glColor4i = (PFNGLCOLOR4IPROC) load(userptr, "glColor4i"); - glad_glColor4iv = (PFNGLCOLOR4IVPROC) load(userptr, "glColor4iv"); - glad_glColor4s = (PFNGLCOLOR4SPROC) load(userptr, "glColor4s"); - glad_glColor4sv = (PFNGLCOLOR4SVPROC) load(userptr, "glColor4sv"); - glad_glColor4ub = (PFNGLCOLOR4UBPROC) load(userptr, "glColor4ub"); - glad_glColor4ubv = (PFNGLCOLOR4UBVPROC) load(userptr, "glColor4ubv"); - glad_glColor4ui = (PFNGLCOLOR4UIPROC) load(userptr, "glColor4ui"); - glad_glColor4uiv = (PFNGLCOLOR4UIVPROC) load(userptr, "glColor4uiv"); - glad_glColor4us = (PFNGLCOLOR4USPROC) load(userptr, "glColor4us"); - glad_glColor4usv = (PFNGLCOLOR4USVPROC) load(userptr, "glColor4usv"); - glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); - glad_glColorMaterial = (PFNGLCOLORMATERIALPROC) load(userptr, "glColorMaterial"); - glad_glCopyPixels = (PFNGLCOPYPIXELSPROC) load(userptr, "glCopyPixels"); - glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); - glad_glDeleteLists = (PFNGLDELETELISTSPROC) load(userptr, "glDeleteLists"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); - glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); - glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); - glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); - glad_glDrawPixels = (PFNGLDRAWPIXELSPROC) load(userptr, "glDrawPixels"); - glad_glEdgeFlag = (PFNGLEDGEFLAGPROC) load(userptr, "glEdgeFlag"); - glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC) load(userptr, "glEdgeFlagv"); - glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); - glad_glEnd = (PFNGLENDPROC) load(userptr, "glEnd"); - glad_glEndList = (PFNGLENDLISTPROC) load(userptr, "glEndList"); - glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC) load(userptr, "glEvalCoord1d"); - glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC) load(userptr, "glEvalCoord1dv"); - glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC) load(userptr, "glEvalCoord1f"); - glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC) load(userptr, "glEvalCoord1fv"); - glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC) load(userptr, "glEvalCoord2d"); - glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC) load(userptr, "glEvalCoord2dv"); - glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC) load(userptr, "glEvalCoord2f"); - glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC) load(userptr, "glEvalCoord2fv"); - glad_glEvalMesh1 = (PFNGLEVALMESH1PROC) load(userptr, "glEvalMesh1"); - glad_glEvalMesh2 = (PFNGLEVALMESH2PROC) load(userptr, "glEvalMesh2"); - glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC) load(userptr, "glEvalPoint1"); - glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC) load(userptr, "glEvalPoint2"); - glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) load(userptr, "glFeedbackBuffer"); - glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); - glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); - glad_glFogf = (PFNGLFOGFPROC) load(userptr, "glFogf"); - glad_glFogfv = (PFNGLFOGFVPROC) load(userptr, "glFogfv"); - glad_glFogi = (PFNGLFOGIPROC) load(userptr, "glFogi"); - glad_glFogiv = (PFNGLFOGIVPROC) load(userptr, "glFogiv"); - glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); - glad_glFrustum = (PFNGLFRUSTUMPROC) load(userptr, "glFrustum"); - glad_glGenLists = (PFNGLGENLISTSPROC) load(userptr, "glGenLists"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); - glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC) load(userptr, "glGetClipPlane"); - glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); - glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); - glad_glGetLightfv = (PFNGLGETLIGHTFVPROC) load(userptr, "glGetLightfv"); - glad_glGetLightiv = (PFNGLGETLIGHTIVPROC) load(userptr, "glGetLightiv"); - glad_glGetMapdv = (PFNGLGETMAPDVPROC) load(userptr, "glGetMapdv"); - glad_glGetMapfv = (PFNGLGETMAPFVPROC) load(userptr, "glGetMapfv"); - glad_glGetMapiv = (PFNGLGETMAPIVPROC) load(userptr, "glGetMapiv"); - glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC) load(userptr, "glGetMaterialfv"); - glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC) load(userptr, "glGetMaterialiv"); - glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC) load(userptr, "glGetPixelMapfv"); - glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC) load(userptr, "glGetPixelMapuiv"); - glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC) load(userptr, "glGetPixelMapusv"); - glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC) load(userptr, "glGetPolygonStipple"); - glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); - glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC) load(userptr, "glGetTexEnvfv"); - glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC) load(userptr, "glGetTexEnviv"); - glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC) load(userptr, "glGetTexGendv"); - glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC) load(userptr, "glGetTexGenfv"); - glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC) load(userptr, "glGetTexGeniv"); - glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); - glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); - glad_glIndexMask = (PFNGLINDEXMASKPROC) load(userptr, "glIndexMask"); - glad_glIndexd = (PFNGLINDEXDPROC) load(userptr, "glIndexd"); - glad_glIndexdv = (PFNGLINDEXDVPROC) load(userptr, "glIndexdv"); - glad_glIndexf = (PFNGLINDEXFPROC) load(userptr, "glIndexf"); - glad_glIndexfv = (PFNGLINDEXFVPROC) load(userptr, "glIndexfv"); - glad_glIndexi = (PFNGLINDEXIPROC) load(userptr, "glIndexi"); - glad_glIndexiv = (PFNGLINDEXIVPROC) load(userptr, "glIndexiv"); - glad_glIndexs = (PFNGLINDEXSPROC) load(userptr, "glIndexs"); - glad_glIndexsv = (PFNGLINDEXSVPROC) load(userptr, "glIndexsv"); - glad_glInitNames = (PFNGLINITNAMESPROC) load(userptr, "glInitNames"); - glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); - glad_glIsList = (PFNGLISLISTPROC) load(userptr, "glIsList"); - glad_glLightModelf = (PFNGLLIGHTMODELFPROC) load(userptr, "glLightModelf"); - glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC) load(userptr, "glLightModelfv"); - glad_glLightModeli = (PFNGLLIGHTMODELIPROC) load(userptr, "glLightModeli"); - glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC) load(userptr, "glLightModeliv"); - glad_glLightf = (PFNGLLIGHTFPROC) load(userptr, "glLightf"); - glad_glLightfv = (PFNGLLIGHTFVPROC) load(userptr, "glLightfv"); - glad_glLighti = (PFNGLLIGHTIPROC) load(userptr, "glLighti"); - glad_glLightiv = (PFNGLLIGHTIVPROC) load(userptr, "glLightiv"); - glad_glLineStipple = (PFNGLLINESTIPPLEPROC) load(userptr, "glLineStipple"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); - glad_glListBase = (PFNGLLISTBASEPROC) load(userptr, "glListBase"); - glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC) load(userptr, "glLoadIdentity"); - glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC) load(userptr, "glLoadMatrixd"); - glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC) load(userptr, "glLoadMatrixf"); - glad_glLoadName = (PFNGLLOADNAMEPROC) load(userptr, "glLoadName"); - glad_glLogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); - glad_glMap1d = (PFNGLMAP1DPROC) load(userptr, "glMap1d"); - glad_glMap1f = (PFNGLMAP1FPROC) load(userptr, "glMap1f"); - glad_glMap2d = (PFNGLMAP2DPROC) load(userptr, "glMap2d"); - glad_glMap2f = (PFNGLMAP2FPROC) load(userptr, "glMap2f"); - glad_glMapGrid1d = (PFNGLMAPGRID1DPROC) load(userptr, "glMapGrid1d"); - glad_glMapGrid1f = (PFNGLMAPGRID1FPROC) load(userptr, "glMapGrid1f"); - glad_glMapGrid2d = (PFNGLMAPGRID2DPROC) load(userptr, "glMapGrid2d"); - glad_glMapGrid2f = (PFNGLMAPGRID2FPROC) load(userptr, "glMapGrid2f"); - glad_glMaterialf = (PFNGLMATERIALFPROC) load(userptr, "glMaterialf"); - glad_glMaterialfv = (PFNGLMATERIALFVPROC) load(userptr, "glMaterialfv"); - glad_glMateriali = (PFNGLMATERIALIPROC) load(userptr, "glMateriali"); - glad_glMaterialiv = (PFNGLMATERIALIVPROC) load(userptr, "glMaterialiv"); - glad_glMatrixMode = (PFNGLMATRIXMODEPROC) load(userptr, "glMatrixMode"); - glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC) load(userptr, "glMultMatrixd"); - glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC) load(userptr, "glMultMatrixf"); - glad_glNewList = (PFNGLNEWLISTPROC) load(userptr, "glNewList"); - glad_glNormal3b = (PFNGLNORMAL3BPROC) load(userptr, "glNormal3b"); - glad_glNormal3bv = (PFNGLNORMAL3BVPROC) load(userptr, "glNormal3bv"); - glad_glNormal3d = (PFNGLNORMAL3DPROC) load(userptr, "glNormal3d"); - glad_glNormal3dv = (PFNGLNORMAL3DVPROC) load(userptr, "glNormal3dv"); - glad_glNormal3f = (PFNGLNORMAL3FPROC) load(userptr, "glNormal3f"); - glad_glNormal3fv = (PFNGLNORMAL3FVPROC) load(userptr, "glNormal3fv"); - glad_glNormal3i = (PFNGLNORMAL3IPROC) load(userptr, "glNormal3i"); - glad_glNormal3iv = (PFNGLNORMAL3IVPROC) load(userptr, "glNormal3iv"); - glad_glNormal3s = (PFNGLNORMAL3SPROC) load(userptr, "glNormal3s"); - glad_glNormal3sv = (PFNGLNORMAL3SVPROC) load(userptr, "glNormal3sv"); - glad_glOrtho = (PFNGLORTHOPROC) load(userptr, "glOrtho"); - glad_glPassThrough = (PFNGLPASSTHROUGHPROC) load(userptr, "glPassThrough"); - glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC) load(userptr, "glPixelMapfv"); - glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC) load(userptr, "glPixelMapuiv"); - glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC) load(userptr, "glPixelMapusv"); - glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); - glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC) load(userptr, "glPixelTransferf"); - glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC) load(userptr, "glPixelTransferi"); - glad_glPixelZoom = (PFNGLPIXELZOOMPROC) load(userptr, "glPixelZoom"); - glad_glPointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); - glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); - glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC) load(userptr, "glPolygonStipple"); - glad_glPopAttrib = (PFNGLPOPATTRIBPROC) load(userptr, "glPopAttrib"); - glad_glPopMatrix = (PFNGLPOPMATRIXPROC) load(userptr, "glPopMatrix"); - glad_glPopName = (PFNGLPOPNAMEPROC) load(userptr, "glPopName"); - glad_glPushAttrib = (PFNGLPUSHATTRIBPROC) load(userptr, "glPushAttrib"); - glad_glPushMatrix = (PFNGLPUSHMATRIXPROC) load(userptr, "glPushMatrix"); - glad_glPushName = (PFNGLPUSHNAMEPROC) load(userptr, "glPushName"); - glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC) load(userptr, "glRasterPos2d"); - glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC) load(userptr, "glRasterPos2dv"); - glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC) load(userptr, "glRasterPos2f"); - glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC) load(userptr, "glRasterPos2fv"); - glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC) load(userptr, "glRasterPos2i"); - glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC) load(userptr, "glRasterPos2iv"); - glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC) load(userptr, "glRasterPos2s"); - glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC) load(userptr, "glRasterPos2sv"); - glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC) load(userptr, "glRasterPos3d"); - glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC) load(userptr, "glRasterPos3dv"); - glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC) load(userptr, "glRasterPos3f"); - glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC) load(userptr, "glRasterPos3fv"); - glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC) load(userptr, "glRasterPos3i"); - glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC) load(userptr, "glRasterPos3iv"); - glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC) load(userptr, "glRasterPos3s"); - glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC) load(userptr, "glRasterPos3sv"); - glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC) load(userptr, "glRasterPos4d"); - glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC) load(userptr, "glRasterPos4dv"); - glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC) load(userptr, "glRasterPos4f"); - glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC) load(userptr, "glRasterPos4fv"); - glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC) load(userptr, "glRasterPos4i"); - glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC) load(userptr, "glRasterPos4iv"); - glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC) load(userptr, "glRasterPos4s"); - glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC) load(userptr, "glRasterPos4sv"); - glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); - glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); - glad_glRectd = (PFNGLRECTDPROC) load(userptr, "glRectd"); - glad_glRectdv = (PFNGLRECTDVPROC) load(userptr, "glRectdv"); - glad_glRectf = (PFNGLRECTFPROC) load(userptr, "glRectf"); - glad_glRectfv = (PFNGLRECTFVPROC) load(userptr, "glRectfv"); - glad_glRecti = (PFNGLRECTIPROC) load(userptr, "glRecti"); - glad_glRectiv = (PFNGLRECTIVPROC) load(userptr, "glRectiv"); - glad_glRects = (PFNGLRECTSPROC) load(userptr, "glRects"); - glad_glRectsv = (PFNGLRECTSVPROC) load(userptr, "glRectsv"); - glad_glRenderMode = (PFNGLRENDERMODEPROC) load(userptr, "glRenderMode"); - glad_glRotated = (PFNGLROTATEDPROC) load(userptr, "glRotated"); - glad_glRotatef = (PFNGLROTATEFPROC) load(userptr, "glRotatef"); - glad_glScaled = (PFNGLSCALEDPROC) load(userptr, "glScaled"); - glad_glScalef = (PFNGLSCALEFPROC) load(userptr, "glScalef"); - glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); - glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC) load(userptr, "glSelectBuffer"); - glad_glShadeModel = (PFNGLSHADEMODELPROC) load(userptr, "glShadeModel"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); - glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); - glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC) load(userptr, "glTexCoord1d"); - glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC) load(userptr, "glTexCoord1dv"); - glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC) load(userptr, "glTexCoord1f"); - glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC) load(userptr, "glTexCoord1fv"); - glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC) load(userptr, "glTexCoord1i"); - glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC) load(userptr, "glTexCoord1iv"); - glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC) load(userptr, "glTexCoord1s"); - glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC) load(userptr, "glTexCoord1sv"); - glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC) load(userptr, "glTexCoord2d"); - glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC) load(userptr, "glTexCoord2dv"); - glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC) load(userptr, "glTexCoord2f"); - glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC) load(userptr, "glTexCoord2fv"); - glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC) load(userptr, "glTexCoord2i"); - glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC) load(userptr, "glTexCoord2iv"); - glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC) load(userptr, "glTexCoord2s"); - glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC) load(userptr, "glTexCoord2sv"); - glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC) load(userptr, "glTexCoord3d"); - glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC) load(userptr, "glTexCoord3dv"); - glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC) load(userptr, "glTexCoord3f"); - glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC) load(userptr, "glTexCoord3fv"); - glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC) load(userptr, "glTexCoord3i"); - glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC) load(userptr, "glTexCoord3iv"); - glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC) load(userptr, "glTexCoord3s"); - glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC) load(userptr, "glTexCoord3sv"); - glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC) load(userptr, "glTexCoord4d"); - glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC) load(userptr, "glTexCoord4dv"); - glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC) load(userptr, "glTexCoord4f"); - glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC) load(userptr, "glTexCoord4fv"); - glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC) load(userptr, "glTexCoord4i"); - glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC) load(userptr, "glTexCoord4iv"); - glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC) load(userptr, "glTexCoord4s"); - glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC) load(userptr, "glTexCoord4sv"); - glad_glTexEnvf = (PFNGLTEXENVFPROC) load(userptr, "glTexEnvf"); - glad_glTexEnvfv = (PFNGLTEXENVFVPROC) load(userptr, "glTexEnvfv"); - glad_glTexEnvi = (PFNGLTEXENVIPROC) load(userptr, "glTexEnvi"); - glad_glTexEnviv = (PFNGLTEXENVIVPROC) load(userptr, "glTexEnviv"); - glad_glTexGend = (PFNGLTEXGENDPROC) load(userptr, "glTexGend"); - glad_glTexGendv = (PFNGLTEXGENDVPROC) load(userptr, "glTexGendv"); - glad_glTexGenf = (PFNGLTEXGENFPROC) load(userptr, "glTexGenf"); - glad_glTexGenfv = (PFNGLTEXGENFVPROC) load(userptr, "glTexGenfv"); - glad_glTexGeni = (PFNGLTEXGENIPROC) load(userptr, "glTexGeni"); - glad_glTexGeniv = (PFNGLTEXGENIVPROC) load(userptr, "glTexGeniv"); - glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); - glad_glTranslated = (PFNGLTRANSLATEDPROC) load(userptr, "glTranslated"); - glad_glTranslatef = (PFNGLTRANSLATEFPROC) load(userptr, "glTranslatef"); - glad_glVertex2d = (PFNGLVERTEX2DPROC) load(userptr, "glVertex2d"); - glad_glVertex2dv = (PFNGLVERTEX2DVPROC) load(userptr, "glVertex2dv"); - glad_glVertex2f = (PFNGLVERTEX2FPROC) load(userptr, "glVertex2f"); - glad_glVertex2fv = (PFNGLVERTEX2FVPROC) load(userptr, "glVertex2fv"); - glad_glVertex2i = (PFNGLVERTEX2IPROC) load(userptr, "glVertex2i"); - glad_glVertex2iv = (PFNGLVERTEX2IVPROC) load(userptr, "glVertex2iv"); - glad_glVertex2s = (PFNGLVERTEX2SPROC) load(userptr, "glVertex2s"); - glad_glVertex2sv = (PFNGLVERTEX2SVPROC) load(userptr, "glVertex2sv"); - glad_glVertex3d = (PFNGLVERTEX3DPROC) load(userptr, "glVertex3d"); - glad_glVertex3dv = (PFNGLVERTEX3DVPROC) load(userptr, "glVertex3dv"); - glad_glVertex3f = (PFNGLVERTEX3FPROC) load(userptr, "glVertex3f"); - glad_glVertex3fv = (PFNGLVERTEX3FVPROC) load(userptr, "glVertex3fv"); - glad_glVertex3i = (PFNGLVERTEX3IPROC) load(userptr, "glVertex3i"); - glad_glVertex3iv = (PFNGLVERTEX3IVPROC) load(userptr, "glVertex3iv"); - glad_glVertex3s = (PFNGLVERTEX3SPROC) load(userptr, "glVertex3s"); - glad_glVertex3sv = (PFNGLVERTEX3SVPROC) load(userptr, "glVertex3sv"); - glad_glVertex4d = (PFNGLVERTEX4DPROC) load(userptr, "glVertex4d"); - glad_glVertex4dv = (PFNGLVERTEX4DVPROC) load(userptr, "glVertex4dv"); - glad_glVertex4f = (PFNGLVERTEX4FPROC) load(userptr, "glVertex4f"); - glad_glVertex4fv = (PFNGLVERTEX4FVPROC) load(userptr, "glVertex4fv"); - glad_glVertex4i = (PFNGLVERTEX4IPROC) load(userptr, "glVertex4i"); - glad_glVertex4iv = (PFNGLVERTEX4IVPROC) load(userptr, "glVertex4iv"); - glad_glVertex4s = (PFNGLVERTEX4SPROC) load(userptr, "glVertex4s"); - glad_glVertex4sv = (PFNGLVERTEX4SVPROC) load(userptr, "glVertex4sv"); - glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); -} -static void glad_gl_load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_1) return; - glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC) load(userptr, "glAreTexturesResident"); - glad_glArrayElement = (PFNGLARRAYELEMENTPROC) load(userptr, "glArrayElement"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); - glad_glColorPointer = (PFNGLCOLORPOINTERPROC) load(userptr, "glColorPointer"); - glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); - glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); - glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC) load(userptr, "glDisableClientState"); - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); - glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC) load(userptr, "glEdgeFlagPointer"); - glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC) load(userptr, "glEnableClientState"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); - glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); - glad_glIndexPointer = (PFNGLINDEXPOINTERPROC) load(userptr, "glIndexPointer"); - glad_glIndexub = (PFNGLINDEXUBPROC) load(userptr, "glIndexub"); - glad_glIndexubv = (PFNGLINDEXUBVPROC) load(userptr, "glIndexubv"); - glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC) load(userptr, "glInterleavedArrays"); - glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); - glad_glNormalPointer = (PFNGLNORMALPOINTERPROC) load(userptr, "glNormalPointer"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); - glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC) load(userptr, "glPopClientAttrib"); - glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC) load(userptr, "glPrioritizeTextures"); - glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC) load(userptr, "glPushClientAttrib"); - glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC) load(userptr, "glTexCoordPointer"); - glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); - glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC) load(userptr, "glVertexPointer"); -} -static void glad_gl_load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_2) return; - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); -} -static void glad_gl_load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_3) return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); - glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) load(userptr, "glClientActiveTexture"); - glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); - glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); - glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); - glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC) load(userptr, "glLoadTransposeMatrixd"); - glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC) load(userptr, "glLoadTransposeMatrixf"); - glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC) load(userptr, "glMultTransposeMatrixd"); - glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC) load(userptr, "glMultTransposeMatrixf"); - glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC) load(userptr, "glMultiTexCoord1d"); - glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC) load(userptr, "glMultiTexCoord1dv"); - glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC) load(userptr, "glMultiTexCoord1f"); - glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC) load(userptr, "glMultiTexCoord1fv"); - glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC) load(userptr, "glMultiTexCoord1i"); - glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC) load(userptr, "glMultiTexCoord1iv"); - glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC) load(userptr, "glMultiTexCoord1s"); - glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC) load(userptr, "glMultiTexCoord1sv"); - glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC) load(userptr, "glMultiTexCoord2d"); - glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC) load(userptr, "glMultiTexCoord2dv"); - glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) load(userptr, "glMultiTexCoord2f"); - glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC) load(userptr, "glMultiTexCoord2fv"); - glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC) load(userptr, "glMultiTexCoord2i"); - glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC) load(userptr, "glMultiTexCoord2iv"); - glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC) load(userptr, "glMultiTexCoord2s"); - glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC) load(userptr, "glMultiTexCoord2sv"); - glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC) load(userptr, "glMultiTexCoord3d"); - glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC) load(userptr, "glMultiTexCoord3dv"); - glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC) load(userptr, "glMultiTexCoord3f"); - glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC) load(userptr, "glMultiTexCoord3fv"); - glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC) load(userptr, "glMultiTexCoord3i"); - glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC) load(userptr, "glMultiTexCoord3iv"); - glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC) load(userptr, "glMultiTexCoord3s"); - glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC) load(userptr, "glMultiTexCoord3sv"); - glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC) load(userptr, "glMultiTexCoord4d"); - glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC) load(userptr, "glMultiTexCoord4dv"); - glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC) load(userptr, "glMultiTexCoord4f"); - glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC) load(userptr, "glMultiTexCoord4fv"); - glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC) load(userptr, "glMultiTexCoord4i"); - glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC) load(userptr, "glMultiTexCoord4iv"); - glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC) load(userptr, "glMultiTexCoord4s"); - glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC) load(userptr, "glMultiTexCoord4sv"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); -} -static void glad_gl_load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_4) return; - glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); - glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC) load(userptr, "glFogCoordPointer"); - glad_glFogCoordd = (PFNGLFOGCOORDDPROC) load(userptr, "glFogCoordd"); - glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC) load(userptr, "glFogCoorddv"); - glad_glFogCoordf = (PFNGLFOGCOORDFPROC) load(userptr, "glFogCoordf"); - glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC) load(userptr, "glFogCoordfv"); - glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); - glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); - glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); - glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); - glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); - glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); - glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC) load(userptr, "glSecondaryColor3b"); - glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC) load(userptr, "glSecondaryColor3bv"); - glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC) load(userptr, "glSecondaryColor3d"); - glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC) load(userptr, "glSecondaryColor3dv"); - glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC) load(userptr, "glSecondaryColor3f"); - glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC) load(userptr, "glSecondaryColor3fv"); - glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC) load(userptr, "glSecondaryColor3i"); - glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC) load(userptr, "glSecondaryColor3iv"); - glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC) load(userptr, "glSecondaryColor3s"); - glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC) load(userptr, "glSecondaryColor3sv"); - glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC) load(userptr, "glSecondaryColor3ub"); - glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC) load(userptr, "glSecondaryColor3ubv"); - glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC) load(userptr, "glSecondaryColor3ui"); - glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC) load(userptr, "glSecondaryColor3uiv"); - glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC) load(userptr, "glSecondaryColor3us"); - glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC) load(userptr, "glSecondaryColor3usv"); - glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC) load(userptr, "glSecondaryColorPointer"); - glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC) load(userptr, "glWindowPos2d"); - glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC) load(userptr, "glWindowPos2dv"); - glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC) load(userptr, "glWindowPos2f"); - glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC) load(userptr, "glWindowPos2fv"); - glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC) load(userptr, "glWindowPos2i"); - glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC) load(userptr, "glWindowPos2iv"); - glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC) load(userptr, "glWindowPos2s"); - glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC) load(userptr, "glWindowPos2sv"); - glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC) load(userptr, "glWindowPos3d"); - glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC) load(userptr, "glWindowPos3dv"); - glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC) load(userptr, "glWindowPos3f"); - glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC) load(userptr, "glWindowPos3fv"); - glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC) load(userptr, "glWindowPos3i"); - glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC) load(userptr, "glWindowPos3iv"); - glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC) load(userptr, "glWindowPos3s"); - glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC) load(userptr, "glWindowPos3sv"); -} -static void glad_gl_load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_5) return; - glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); - glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); - glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); - glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); - glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); - glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); - glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); - glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); - glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); -} -static void glad_gl_load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_2_0) return; - glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); - glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); - glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); - glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); - glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); - glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); - glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); - glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); - glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); - glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); - glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); - glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); - glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); - glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); - glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); - glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); - glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); - glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); - glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); - glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); - glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); - glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); - glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); - glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); - glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); - glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); - glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); - glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); - glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); - glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); - glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); - glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); -} -static void glad_gl_load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_2_1) return; - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); -} -static void glad_gl_load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_0) return; - glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); - glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); - glad_glClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); - glad_glColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); - glad_glDisablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); - glad_glEnablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); - glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); - glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); - glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); - glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); - glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); - glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); - glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); - glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); - glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); - glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); - glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); - glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); - glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); - glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); - glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); - glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); - glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); - glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); - glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); - glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); - glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); - glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); -} -static void glad_gl_load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_1) return; - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); - glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); - glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); - glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); - glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); - glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); - glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); - glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); - glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); - glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); - glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); - glad_glTexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); - glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); -} -static void glad_gl_load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_2) return; - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); - glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); - glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); - glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); - glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); - glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); - glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); - glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); - glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); - glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); - glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); - glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); - glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); - glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); - glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); - glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); -} -static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_3) return; - glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); - glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); - glad_glColorP3ui = (PFNGLCOLORP3UIPROC) load(userptr, "glColorP3ui"); - glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC) load(userptr, "glColorP3uiv"); - glad_glColorP4ui = (PFNGLCOLORP4UIPROC) load(userptr, "glColorP4ui"); - glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC) load(userptr, "glColorP4uiv"); - glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); - glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); - glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); - glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); - glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); - glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); - glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); - glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); - glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); - glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); - glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) load(userptr, "glMultiTexCoordP1ui"); - glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) load(userptr, "glMultiTexCoordP1uiv"); - glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) load(userptr, "glMultiTexCoordP2ui"); - glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) load(userptr, "glMultiTexCoordP2uiv"); - glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) load(userptr, "glMultiTexCoordP3ui"); - glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) load(userptr, "glMultiTexCoordP3uiv"); - glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) load(userptr, "glMultiTexCoordP4ui"); - glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) load(userptr, "glMultiTexCoordP4uiv"); - glad_glNormalP3ui = (PFNGLNORMALP3UIPROC) load(userptr, "glNormalP3ui"); - glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC) load(userptr, "glNormalP3uiv"); - glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); - glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); - glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); - glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); - glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); - glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); - glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); - glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) load(userptr, "glSecondaryColorP3ui"); - glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) load(userptr, "glSecondaryColorP3uiv"); - glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) load(userptr, "glTexCoordP1ui"); - glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) load(userptr, "glTexCoordP1uiv"); - glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) load(userptr, "glTexCoordP2ui"); - glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) load(userptr, "glTexCoordP2uiv"); - glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) load(userptr, "glTexCoordP3ui"); - glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) load(userptr, "glTexCoordP3uiv"); - glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) load(userptr, "glTexCoordP4ui"); - glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) load(userptr, "glTexCoordP4uiv"); - glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); - glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); - glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); - glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); - glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); - glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); - glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); - glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); - glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); - glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC) load(userptr, "glVertexP2ui"); - glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC) load(userptr, "glVertexP2uiv"); - glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC) load(userptr, "glVertexP3ui"); - glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC) load(userptr, "glVertexP3uiv"); - glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC) load(userptr, "glVertexP4ui"); - glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC) load(userptr, "glVertexP4uiv"); -} -static void glad_gl_load_GL_ARB_multisample( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_ARB_multisample) return; - glad_glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC) load(userptr, "glSampleCoverageARB"); -} -static void glad_gl_load_GL_ARB_robustness( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_ARB_robustness) return; - glad_glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC) load(userptr, "glGetGraphicsResetStatusARB"); - glad_glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC) load(userptr, "glGetnColorTableARB"); - glad_glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) load(userptr, "glGetnCompressedTexImageARB"); - glad_glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC) load(userptr, "glGetnConvolutionFilterARB"); - glad_glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC) load(userptr, "glGetnHistogramARB"); - glad_glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC) load(userptr, "glGetnMapdvARB"); - glad_glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC) load(userptr, "glGetnMapfvARB"); - glad_glGetnMapivARB = (PFNGLGETNMAPIVARBPROC) load(userptr, "glGetnMapivARB"); - glad_glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC) load(userptr, "glGetnMinmaxARB"); - glad_glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC) load(userptr, "glGetnPixelMapfvARB"); - glad_glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC) load(userptr, "glGetnPixelMapuivARB"); - glad_glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC) load(userptr, "glGetnPixelMapusvARB"); - glad_glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC) load(userptr, "glGetnPolygonStippleARB"); - glad_glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC) load(userptr, "glGetnSeparableFilterARB"); - glad_glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC) load(userptr, "glGetnTexImageARB"); - glad_glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC) load(userptr, "glGetnUniformdvARB"); - glad_glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC) load(userptr, "glGetnUniformfvARB"); - glad_glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC) load(userptr, "glGetnUniformivARB"); - glad_glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC) load(userptr, "glGetnUniformuivARB"); - glad_glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC) load(userptr, "glReadnPixelsARB"); -} -static void glad_gl_load_GL_KHR_debug( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_KHR_debug) return; - glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback"); - glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl"); - glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert"); - glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog"); - glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel"); - glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel"); - glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); - glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel"); - glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel"); - glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup"); - glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup"); -} - - - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -#define GLAD_GL_IS_SOME_NEW_VERSION 1 -#else -#define GLAD_GL_IS_SOME_NEW_VERSION 0 -#endif - -static int glad_gl_get_extensions( int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) { -#if GLAD_GL_IS_SOME_NEW_VERSION - if(GLAD_VERSION_MAJOR(version) < 3) { -#else - (void) version; - (void) out_num_exts_i; - (void) out_exts_i; -#endif - if (glad_glGetString == NULL) { - return 0; - } - *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); -#if GLAD_GL_IS_SOME_NEW_VERSION - } else { - unsigned int index = 0; - unsigned int num_exts_i = 0; - char **exts_i = NULL; - if (glad_glGetStringi == NULL || glad_glGetIntegerv == NULL) { - return 0; - } - glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i)); - } - if (exts_i == NULL) { - return 0; - } - for(index = 0; index < num_exts_i; index++) { - const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp) + 1; - - char *local_str = (char*) malloc(len * sizeof(char)); - if(local_str != NULL) { - memcpy(local_str, gl_str_tmp, len * sizeof(char)); - } - - exts_i[index] = local_str; - } - - *out_num_exts_i = num_exts_i; - *out_exts_i = exts_i; - } -#endif - return 1; -} -static void glad_gl_free_extensions(char **exts_i, unsigned int num_exts_i) { - if (exts_i != NULL) { - unsigned int index; - for(index = 0; index < num_exts_i; index++) { - free((void *) (exts_i[index])); - } - free((void *)exts_i); - exts_i = NULL; - } -} -static int glad_gl_has_extension(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) { - if(GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) { - const char *extensions; - const char *loc; - const char *terminator; - extensions = exts; - if(extensions == NULL || ext == NULL) { - return 0; - } - while(1) { - loc = strstr(extensions, ext); - if(loc == NULL) { - return 0; - } - terminator = loc + strlen(ext); - if((loc == extensions || *(loc - 1) == ' ') && - (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } - } else { - unsigned int index; - for(index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - if(strcmp(e, ext) == 0) { - return 1; - } - } - } - return 0; -} - -static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { - return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); -} - -static int glad_gl_find_extensions_gl( int version) { - const char *exts = NULL; - unsigned int num_exts_i = 0; - char **exts_i = NULL; - if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0; - - GLAD_GL_ARB_multisample = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_multisample"); - GLAD_GL_ARB_robustness = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_robustness"); - GLAD_GL_KHR_debug = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_KHR_debug"); - - glad_gl_free_extensions(exts_i, num_exts_i); - - return 1; -} - -static int glad_gl_find_core_gl(void) { - int i; - const char* version; - const char* prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - "OpenGL SC ", - NULL - }; - int major = 0; - int minor = 0; - version = (const char*) glad_glGetString(GL_VERSION); - if (!version) return 0; - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } - - GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); - - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; - GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; - - return GLAD_MAKE_VERSION(major, minor); -} - -int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { - int version; - - glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); - if(glad_glGetString == NULL) return 0; - if(glad_glGetString(GL_VERSION) == NULL) return 0; - version = glad_gl_find_core_gl(); - - glad_gl_load_GL_VERSION_1_0(load, userptr); - glad_gl_load_GL_VERSION_1_1(load, userptr); - glad_gl_load_GL_VERSION_1_2(load, userptr); - glad_gl_load_GL_VERSION_1_3(load, userptr); - glad_gl_load_GL_VERSION_1_4(load, userptr); - glad_gl_load_GL_VERSION_1_5(load, userptr); - glad_gl_load_GL_VERSION_2_0(load, userptr); - glad_gl_load_GL_VERSION_2_1(load, userptr); - glad_gl_load_GL_VERSION_3_0(load, userptr); - glad_gl_load_GL_VERSION_3_1(load, userptr); - glad_gl_load_GL_VERSION_3_2(load, userptr); - glad_gl_load_GL_VERSION_3_3(load, userptr); - - if (!glad_gl_find_extensions_gl(version)) return 0; - glad_gl_load_GL_ARB_multisample(load, userptr); - glad_gl_load_GL_ARB_robustness(load, userptr); - glad_gl_load_GL_KHR_debug(load, userptr); - - - - return version; -} - - -int gladLoadGL( GLADloadfunc load) { - return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); -} - - - - - - -#ifdef __cplusplus -} -#endif - -#endif /* GLAD_GL_IMPLEMENTATION */ - diff --git a/raylib/external/glfw/deps/glad/gles2.h b/raylib/external/glfw/deps/glad/gles2.h deleted file mode 100644 index d67f110..0000000 --- a/raylib/external/glfw/deps/glad/gles2.h +++ /dev/null @@ -1,1805 +0,0 @@ -/** - * Loader generated by glad 2.0.0-beta on Tue Aug 24 22:51:42 2021 - * - * Generator: C/C++ - * Specification: gl - * Extensions: 0 - * - * APIs: - * - gles2=2.0 - * - * Options: - * - ALIAS = False - * - DEBUG = False - * - HEADER_ONLY = True - * - LOADER = False - * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False - * - * Commandline: - * --api='gles2=2.0' --extensions='' c --header-only - * - * Online: - * http://glad.sh/#api=gles2%3D2.0&extensions=&generator=c&options=HEADER_ONLY - * - */ - -#ifndef GLAD_GLES2_H_ -#define GLAD_GLES2_H_ - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wreserved-id-macro" -#endif -#ifdef __gl2_h_ - #error OpenGL ES 2 header already included (API: gles2), remove previous include! -#endif -#define __gl2_h_ 1 -#ifdef __gl3_h_ - #error OpenGL ES 3 header already included (API: gles2), remove previous include! -#endif -#define __gl3_h_ 1 -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#define GLAD_GLES2 -#define GLAD_OPTION_GLES2_HEADER_ONLY - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef GLAD_PLATFORM_H_ -#define GLAD_PLATFORM_H_ - -#ifndef GLAD_PLATFORM_WIN32 - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) - #define GLAD_PLATFORM_WIN32 1 - #else - #define GLAD_PLATFORM_WIN32 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_APPLE - #ifdef __APPLE__ - #define GLAD_PLATFORM_APPLE 1 - #else - #define GLAD_PLATFORM_APPLE 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_EMSCRIPTEN - #ifdef __EMSCRIPTEN__ - #define GLAD_PLATFORM_EMSCRIPTEN 1 - #else - #define GLAD_PLATFORM_EMSCRIPTEN 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_UWP - #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) - #ifdef __has_include - #if __has_include() - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #endif - - #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY - #include - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define GLAD_PLATFORM_UWP 1 - #endif - #endif - - #ifndef GLAD_PLATFORM_UWP - #define GLAD_PLATFORM_UWP 0 - #endif -#endif - -#ifdef __GNUC__ - #define GLAD_GNUC_EXTENSION __extension__ -#else - #define GLAD_GNUC_EXTENSION -#endif - -#ifndef GLAD_API_CALL - #if defined(GLAD_API_CALL_EXPORT) - #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) - #if defined(GLAD_API_CALL_EXPORT_BUILD) - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllexport)) extern - #else - #define GLAD_API_CALL __declspec(dllexport) extern - #endif - #else - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllimport)) extern - #else - #define GLAD_API_CALL __declspec(dllimport) extern - #endif - #endif - #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) - #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern - #else - #define GLAD_API_CALL extern - #endif - #else - #define GLAD_API_CALL extern - #endif -#endif - -#ifdef APIENTRY - #define GLAD_API_PTR APIENTRY -#elif GLAD_PLATFORM_WIN32 - #define GLAD_API_PTR __stdcall -#else - #define GLAD_API_PTR -#endif - -#ifndef GLAPI -#define GLAPI GLAD_API_CALL -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY GLAD_API_PTR -#endif - -#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) -#define GLAD_VERSION_MAJOR(version) (version / 10000) -#define GLAD_VERSION_MINOR(version) (version % 10000) - -#define GLAD_GENERATOR_VERSION "2.0.0-beta" - -typedef void (*GLADapiproc)(void); - -typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); - -typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); -typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); - -#endif /* GLAD_PLATFORM_H_ */ - -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALPHA 0x1906 -#define GL_ALPHA_BITS 0x0D55 -#define GL_ALWAYS 0x0207 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_BACK 0x0405 -#define GL_BLEND 0x0BE2 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLUE_BITS 0x0D54 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_BYTE 0x1400 -#define GL_CCW 0x0901 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_CW 0x0900 -#define GL_DECR 0x1E03 -#define GL_DECR_WRAP 0x8508 -#define GL_DELETE_STATUS 0x8B80 -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_DEPTH_BITS 0x0D56 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DITHER 0x0BD0 -#define GL_DONT_CARE 0x1100 -#define GL_DST_ALPHA 0x0304 -#define GL_DST_COLOR 0x0306 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_EQUAL 0x0202 -#define GL_EXTENSIONS 0x1F03 -#define GL_FALSE 0 -#define GL_FASTEST 0x1101 -#define GL_FIXED 0x140C -#define GL_FLOAT 0x1406 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_FRONT 0x0404 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_FRONT_FACE 0x0B46 -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_FUNC_SUBTRACT 0x800A -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_GEQUAL 0x0206 -#define GL_GREATER 0x0204 -#define GL_GREEN_BITS 0x0D53 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_HIGH_INT 0x8DF5 -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_INCR 0x1E02 -#define GL_INCR_WRAP 0x8507 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_INT 0x1404 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_INVALID_OPERATION 0x0502 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVERT 0x150A -#define GL_KEEP 0x1E00 -#define GL_LEQUAL 0x0203 -#define GL_LESS 0x0201 -#define GL_LINEAR 0x2601 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINK_STATUS 0x8B82 -#define GL_LOW_FLOAT 0x8DF0 -#define GL_LOW_INT 0x8DF3 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_NEAREST 0x2600 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_NEVER 0x0200 -#define GL_NICEST 0x1102 -#define GL_NONE 0 -#define GL_NOTEQUAL 0x0205 -#define GL_NO_ERROR 0 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_ONE 1 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_POINTS 0x0000 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_RED_BITS 0x0D52 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERER 0x1F01 -#define GL_REPEAT 0x2901 -#define GL_REPLACE 0x1E01 -#define GL_RGB 0x1907 -#define GL_RGB565 0x8D62 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA 0x1908 -#define GL_RGBA4 0x8056 -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_TYPE 0x8B4F -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_SHORT 0x1402 -#define GL_SRC_ALPHA 0x0302 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_SRC_COLOR 0x0300 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_STENCIL_BITS 0x0D57 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STREAM_DRAW 0x88E0 -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_TEXTURE 0x1702 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRUE 1 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_UNSIGNED_INT 0x1405 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_VENDOR 0x1F00 -#define GL_VERSION 0x1F02 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_VIEWPORT 0x0BA2 -#define GL_ZERO 0 - - -#ifndef __khrplatform_h_ -#define __khrplatform_h_ - -/* -** Copyright (c) 2008-2018 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* Khronos platform-specific types and definitions. - * - * The master copy of khrplatform.h is maintained in the Khronos EGL - * Registry repository at https://github.com/KhronosGroup/EGL-Registry - * The last semantic modification to khrplatform.h was at commit ID: - * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 - * - * Adopters may modify this file to suit their platform. Adopters are - * encouraged to submit platform specific modifications to the Khronos - * group so that they can be included in future versions of this file. - * Please submit changes by filing pull requests or issues on - * the EGL Registry repository linked above. - * - * - * See the Implementer's Guidelines for information about where this file - * should be located on your system and for more details of its use: - * http://www.khronos.org/registry/implementers_guide.pdf - * - * This file should be included as - * #include - * by Khronos client API header files that use its types and defines. - * - * The types in khrplatform.h should only be used to define API-specific types. - * - * Types defined in khrplatform.h: - * khronos_int8_t signed 8 bit - * khronos_uint8_t unsigned 8 bit - * khronos_int16_t signed 16 bit - * khronos_uint16_t unsigned 16 bit - * khronos_int32_t signed 32 bit - * khronos_uint32_t unsigned 32 bit - * khronos_int64_t signed 64 bit - * khronos_uint64_t unsigned 64 bit - * khronos_intptr_t signed same number of bits as a pointer - * khronos_uintptr_t unsigned same number of bits as a pointer - * khronos_ssize_t signed size - * khronos_usize_t unsigned size - * khronos_float_t signed 32 bit floating point - * khronos_time_ns_t unsigned 64 bit time in nanoseconds - * khronos_utime_nanoseconds_t unsigned time interval or absolute time in - * nanoseconds - * khronos_stime_nanoseconds_t signed time interval in nanoseconds - * khronos_boolean_enum_t enumerated boolean type. This should - * only be used as a base type when a client API's boolean type is - * an enum. Client APIs which use an integer or other type for - * booleans cannot use this as the base type for their boolean. - * - * Tokens defined in khrplatform.h: - * - * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. - * - * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. - * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. - * - * Calling convention macros defined in this file: - * KHRONOS_APICALL - * KHRONOS_GLAD_API_PTR - * KHRONOS_APIATTRIBUTES - * - * These may be used in function prototypes as: - * - * KHRONOS_APICALL void KHRONOS_GLAD_API_PTR funcname( - * int arg1, - * int arg2) KHRONOS_APIATTRIBUTES; - */ - -#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) -# define KHRONOS_STATIC 1 -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APICALL - *------------------------------------------------------------------------- - * This precedes the return type of the function in the function prototype. - */ -#if defined(KHRONOS_STATIC) - /* If the preprocessor constant KHRONOS_STATIC is defined, make the - * header compatible with static linking. */ -# define KHRONOS_APICALL -#elif defined(_WIN32) -# define KHRONOS_APICALL __declspec(dllimport) -#elif defined (__SYMBIAN32__) -# define KHRONOS_APICALL IMPORT_C -#elif defined(__ANDROID__) -# define KHRONOS_APICALL __attribute__((visibility("default"))) -#else -# define KHRONOS_APICALL -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_GLAD_API_PTR - *------------------------------------------------------------------------- - * This follows the return type of the function and precedes the function - * name in the function prototype. - */ -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) - /* Win32 but not WinCE */ -# define KHRONOS_GLAD_API_PTR __stdcall -#else -# define KHRONOS_GLAD_API_PTR -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APIATTRIBUTES - *------------------------------------------------------------------------- - * This follows the closing parenthesis of the function prototype arguments. - */ -#if defined (__ARMCC_2__) -#define KHRONOS_APIATTRIBUTES __softfp -#else -#define KHRONOS_APIATTRIBUTES -#endif - -/*------------------------------------------------------------------------- - * basic type definitions - *-----------------------------------------------------------------------*/ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) - - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__VMS ) || defined(__sgi) - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) - -/* - * Win32 - */ -typedef __int32 khronos_int32_t; -typedef unsigned __int32 khronos_uint32_t; -typedef __int64 khronos_int64_t; -typedef unsigned __int64 khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__sun__) || defined(__digital__) - -/* - * Sun or Digital - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#if defined(__arch64__) || defined(_LP64) -typedef long int khronos_int64_t; -typedef unsigned long int khronos_uint64_t; -#else -typedef long long int khronos_int64_t; -typedef unsigned long long int khronos_uint64_t; -#endif /* __arch64__ */ -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif 0 - -/* - * Hypothetical platform with no float or int64 support - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#define KHRONOS_SUPPORT_INT64 0 -#define KHRONOS_SUPPORT_FLOAT 0 - -#else - -/* - * Generic fallback - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#endif - - -/* - * Types that are (so far) the same on all platforms - */ -typedef signed char khronos_int8_t; -typedef unsigned char khronos_uint8_t; -typedef signed short int khronos_int16_t; -typedef unsigned short int khronos_uint16_t; - -/* - * Types that differ between LLP64 and LP64 architectures - in LLP64, - * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears - * to be the only LLP64 architecture in current use. - */ -#ifdef _WIN64 -typedef signed long long int khronos_intptr_t; -typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; -#else -typedef signed long int khronos_intptr_t; -typedef unsigned long int khronos_uintptr_t; -typedef signed long int khronos_ssize_t; -typedef unsigned long int khronos_usize_t; -#endif - -#if KHRONOS_SUPPORT_FLOAT -/* - * Float type - */ -typedef float khronos_float_t; -#endif - -#if KHRONOS_SUPPORT_INT64 -/* Time types - * - * These types can be used to represent a time interval in nanoseconds or - * an absolute Unadjusted System Time. Unadjusted System Time is the number - * of nanoseconds since some arbitrary system event (e.g. since the last - * time the system booted). The Unadjusted System Time is an unsigned - * 64 bit value that wraps back to 0 every 584 years. Time intervals - * may be either signed or unsigned. - */ -typedef khronos_uint64_t khronos_utime_nanoseconds_t; -typedef khronos_int64_t khronos_stime_nanoseconds_t; -#endif - -/* - * Dummy value used to pad enum types to 32 bits. - */ -#ifndef KHRONOS_MAX_ENUM -#define KHRONOS_MAX_ENUM 0x7FFFFFFF -#endif - -/* - * Enumerated boolean type - * - * Values other than zero should be considered to be true. Therefore - * comparisons should not be made against KHRONOS_TRUE. - */ -typedef enum { - KHRONOS_FALSE = 0, - KHRONOS_TRUE = 1, - KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM -} khronos_boolean_enum_t; - -#endif /* __khrplatform_h_ */ - -typedef unsigned int GLenum; - -typedef unsigned char GLboolean; - -typedef unsigned int GLbitfield; - -typedef void GLvoid; - -typedef khronos_int8_t GLbyte; - -typedef khronos_uint8_t GLubyte; - -typedef khronos_int16_t GLshort; - -typedef khronos_uint16_t GLushort; - -typedef int GLint; - -typedef unsigned int GLuint; - -typedef khronos_int32_t GLclampx; - -typedef int GLsizei; - -typedef khronos_float_t GLfloat; - -typedef khronos_float_t GLclampf; - -typedef double GLdouble; - -typedef double GLclampd; - -typedef void *GLeglClientBufferEXT; - -typedef void *GLeglImageOES; - -typedef char GLchar; - -typedef char GLcharARB; - -#ifdef __APPLE__ -typedef void *GLhandleARB; -#else -typedef unsigned int GLhandleARB; -#endif - -typedef khronos_uint16_t GLhalf; - -typedef khronos_uint16_t GLhalfARB; - -typedef khronos_int32_t GLfixed; - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_intptr_t GLintptr; -#else -typedef khronos_intptr_t GLintptr; -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_intptr_t GLintptrARB; -#else -typedef khronos_intptr_t GLintptrARB; -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_ssize_t GLsizeiptr; -#else -typedef khronos_ssize_t GLsizeiptr; -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_ssize_t GLsizeiptrARB; -#else -typedef khronos_ssize_t GLsizeiptrARB; -#endif - -typedef khronos_int64_t GLint64; - -typedef khronos_int64_t GLint64EXT; - -typedef khronos_uint64_t GLuint64; - -typedef khronos_uint64_t GLuint64EXT; - -typedef struct __GLsync *GLsync; - -struct _cl_context; - -struct _cl_event; - -typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); - -typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); - -typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); - -typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); - -typedef unsigned short GLhalfNV; - -typedef GLintptr GLvdpauSurfaceNV; - -typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); - - - -#define GL_ES_VERSION_2_0 1 -GLAD_API_CALL int GLAD_GL_ES_VERSION_2_0; - - -typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); -typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); -typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); -typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); -typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); -typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); -typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); -typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); -typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); -typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); -typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); -typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); -typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); -typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); -typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); -typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); -typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); -typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); -typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); -typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); -typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); -typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); -typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); -typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); -typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); -typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); -typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); -typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); -typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); -typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); -typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); -typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); -typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); -typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); -typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); -typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); -typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length); -typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); -typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); -typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); - -GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; -#define glAttachShader glad_glAttachShader -GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -#define glCheckFramebufferStatus glad_glCheckFramebufferStatus -GLAD_API_CALL PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; -#define glClearColor glad_glClearColor -GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; -#define glClearDepthf glad_glClearDepthf -GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; -#define glClearStencil glad_glClearStencil -GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; -#define glCullFace glad_glCullFace -GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; -#define glDepthFunc glad_glDepthFunc -GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; -#define glDepthMask glad_glDepthMask -GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; -#define glDepthRangef glad_glDepthRangef -GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; -#define glDrawElements glad_glDrawElements -GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -#define glGetActiveUniform glad_glGetActiveUniform -GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -#define glGetBooleanv glad_glGetBooleanv -GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -#define glGetBufferParameteriv glad_glGetBufferParameteriv -GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -#define glGetShaderInfoLog glad_glGetShaderInfoLog -GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; -#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat -GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -#define glGetShaderSource glad_glGetShaderSource -GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; -#define glGetString glad_glGetString -GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -#define glGetUniformfv glad_glGetUniformfv -GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -GLAD_API_CALL PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -#define glPolygonOffset glad_glPolygonOffset -GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; -#define glReleaseShaderCompiler glad_glReleaseShaderCompiler -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; -#define glShaderBinary glad_glShaderBinary -GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; -#define glStencilMask glad_glStencilMask -GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -#define glStencilMaskSeparate glad_glStencilMaskSeparate -GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; -#define glStencilOp glad_glStencilOp -GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -#define glStencilOpSeparate glad_glStencilOpSeparate -GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -#define glTexImage2D glad_glTexImage2D -GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -#define glTexParameterf glad_glTexParameterf -GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -#define glTexParameterfv glad_glTexParameterfv -GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -#define glTexParameteri glad_glTexParameteri -GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -#define glTexParameteriv glad_glTexParameteriv -GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; -#define glUniform1f glad_glUniform1f -GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; -#define glUniform2f glad_glUniform2f -GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; -#define glUniform3f glad_glUniform3f -GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; -#define glUniform4f glad_glUniform4f -GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -#define glUniformMatrix3fv glad_glUniformMatrix3fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -#define glUniformMatrix4fv glad_glUniformMatrix4fv -GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; -#define glViewport glad_glViewport - - - - - -GLAD_API_CALL int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadGLES2( GLADloadfunc load); - - - -#ifdef __cplusplus -} -#endif -#endif - -/* Source */ -#ifdef GLAD_GLES2_IMPLEMENTATION -#include -#include -#include - -#ifndef GLAD_IMPL_UTIL_C_ -#define GLAD_IMPL_UTIL_C_ - -#ifdef _MSC_VER -#define GLAD_IMPL_UTIL_SSCANF sscanf_s -#else -#define GLAD_IMPL_UTIL_SSCANF sscanf -#endif - -#endif /* GLAD_IMPL_UTIL_C_ */ - -#ifdef __cplusplus -extern "C" { -#endif - - - -int GLAD_GL_ES_VERSION_2_0 = 0; - - - -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; - - -static void glad_gl_load_GL_ES_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_ES_VERSION_2_0) return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); - glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); - glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); - glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); - glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); - glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); - glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); - glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); - glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); - glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); - glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); - glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); - glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); - glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); - glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); - glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); - glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); - glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); - glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); - glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); - glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); - glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); - glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); - glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); - glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); - glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); - glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); - glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); - glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); -} - - - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -#define GLAD_GL_IS_SOME_NEW_VERSION 1 -#else -#define GLAD_GL_IS_SOME_NEW_VERSION 0 -#endif - -static int glad_gl_get_extensions( int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) { -#if GLAD_GL_IS_SOME_NEW_VERSION - if(GLAD_VERSION_MAJOR(version) < 3) { -#else - (void) version; - (void) out_num_exts_i; - (void) out_exts_i; -#endif - if (glad_glGetString == NULL) { - return 0; - } - *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); -#if GLAD_GL_IS_SOME_NEW_VERSION - } else { - unsigned int index = 0; - unsigned int num_exts_i = 0; - char **exts_i = NULL; - if (glad_glGetStringi == NULL || glad_glGetIntegerv == NULL) { - return 0; - } - glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i)); - } - if (exts_i == NULL) { - return 0; - } - for(index = 0; index < num_exts_i; index++) { - const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp) + 1; - - char *local_str = (char*) malloc(len * sizeof(char)); - if(local_str != NULL) { - memcpy(local_str, gl_str_tmp, len * sizeof(char)); - } - - exts_i[index] = local_str; - } - - *out_num_exts_i = num_exts_i; - *out_exts_i = exts_i; - } -#endif - return 1; -} -static void glad_gl_free_extensions(char **exts_i, unsigned int num_exts_i) { - if (exts_i != NULL) { - unsigned int index; - for(index = 0; index < num_exts_i; index++) { - free((void *) (exts_i[index])); - } - free((void *)exts_i); - exts_i = NULL; - } -} -static int glad_gl_has_extension(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) { - if(GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) { - const char *extensions; - const char *loc; - const char *terminator; - extensions = exts; - if(extensions == NULL || ext == NULL) { - return 0; - } - while(1) { - loc = strstr(extensions, ext); - if(loc == NULL) { - return 0; - } - terminator = loc + strlen(ext); - if((loc == extensions || *(loc - 1) == ' ') && - (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } - } else { - unsigned int index; - for(index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - if(strcmp(e, ext) == 0) { - return 1; - } - } - } - return 0; -} - -static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { - return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); -} - -static int glad_gl_find_extensions_gles2( int version) { - const char *exts = NULL; - unsigned int num_exts_i = 0; - char **exts_i = NULL; - if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0; - - (void) glad_gl_has_extension; - - glad_gl_free_extensions(exts_i, num_exts_i); - - return 1; -} - -static int glad_gl_find_core_gles2(void) { - int i; - const char* version; - const char* prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - "OpenGL SC ", - NULL - }; - int major = 0; - int minor = 0; - version = (const char*) glad_glGetString(GL_VERSION); - if (!version) return 0; - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } - - GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); - - GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - - return GLAD_MAKE_VERSION(major, minor); -} - -int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr) { - int version; - - glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); - if(glad_glGetString == NULL) return 0; - if(glad_glGetString(GL_VERSION) == NULL) return 0; - version = glad_gl_find_core_gles2(); - - glad_gl_load_GL_ES_VERSION_2_0(load, userptr); - - if (!glad_gl_find_extensions_gles2(version)) return 0; - - - - return version; -} - - -int gladLoadGLES2( GLADloadfunc load) { - return gladLoadGLES2UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); -} - - - - - - -#ifdef __cplusplus -} -#endif - -#endif /* GLAD_GLES2_IMPLEMENTATION */ - diff --git a/raylib/external/glfw/deps/glad/vulkan.h b/raylib/external/glfw/deps/glad/vulkan.h deleted file mode 100644 index 469ffe5..0000000 --- a/raylib/external/glfw/deps/glad/vulkan.h +++ /dev/null @@ -1,6330 +0,0 @@ -/** - * Loader generated by glad 2.0.0-beta on Thu Jul 7 20:52:04 2022 - * - * Generator: C/C++ - * Specification: vk - * Extensions: 4 - * - * APIs: - * - vulkan=1.3 - * - * Options: - * - ALIAS = False - * - DEBUG = False - * - HEADER_ONLY = True - * - LOADER = False - * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False - * - * Commandline: - * --api='vulkan=1.3' --extensions='VK_EXT_debug_report,VK_KHR_portability_enumeration,VK_KHR_surface,VK_KHR_swapchain' c --header-only - * - * Online: - * http://glad.sh/#api=vulkan%3D1.3&extensions=VK_EXT_debug_report%2CVK_KHR_portability_enumeration%2CVK_KHR_surface%2CVK_KHR_swapchain&generator=c&options=HEADER_ONLY - * - */ - -#ifndef GLAD_VULKAN_H_ -#define GLAD_VULKAN_H_ - -#ifdef VULKAN_H_ - #error header already included (API: vulkan), remove previous include! -#endif -#define VULKAN_H_ 1 - -#ifdef VULKAN_CORE_H_ - #error header already included (API: vulkan), remove previous include! -#endif -#define VULKAN_CORE_H_ 1 - - -#define GLAD_VULKAN -#define GLAD_OPTION_VULKAN_HEADER_ONLY - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef GLAD_PLATFORM_H_ -#define GLAD_PLATFORM_H_ - -#ifndef GLAD_PLATFORM_WIN32 - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) - #define GLAD_PLATFORM_WIN32 1 - #else - #define GLAD_PLATFORM_WIN32 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_APPLE - #ifdef __APPLE__ - #define GLAD_PLATFORM_APPLE 1 - #else - #define GLAD_PLATFORM_APPLE 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_EMSCRIPTEN - #ifdef __EMSCRIPTEN__ - #define GLAD_PLATFORM_EMSCRIPTEN 1 - #else - #define GLAD_PLATFORM_EMSCRIPTEN 0 - #endif -#endif - -#ifndef GLAD_PLATFORM_UWP - #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) - #ifdef __has_include - #if __has_include() - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #endif - - #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY - #include - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define GLAD_PLATFORM_UWP 1 - #endif - #endif - - #ifndef GLAD_PLATFORM_UWP - #define GLAD_PLATFORM_UWP 0 - #endif -#endif - -#ifdef __GNUC__ - #define GLAD_GNUC_EXTENSION __extension__ -#else - #define GLAD_GNUC_EXTENSION -#endif - -#ifndef GLAD_API_CALL - #if defined(GLAD_API_CALL_EXPORT) - #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) - #if defined(GLAD_API_CALL_EXPORT_BUILD) - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllexport)) extern - #else - #define GLAD_API_CALL __declspec(dllexport) extern - #endif - #else - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllimport)) extern - #else - #define GLAD_API_CALL __declspec(dllimport) extern - #endif - #endif - #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) - #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern - #else - #define GLAD_API_CALL extern - #endif - #else - #define GLAD_API_CALL extern - #endif -#endif - -#ifdef APIENTRY - #define GLAD_API_PTR APIENTRY -#elif GLAD_PLATFORM_WIN32 - #define GLAD_API_PTR __stdcall -#else - #define GLAD_API_PTR -#endif - -#ifndef GLAPI -#define GLAPI GLAD_API_CALL -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY GLAD_API_PTR -#endif - -#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) -#define GLAD_VERSION_MAJOR(version) (version / 10000) -#define GLAD_VERSION_MINOR(version) (version % 10000) - -#define GLAD_GENERATOR_VERSION "2.0.0-beta" - -typedef void (*GLADapiproc)(void); - -typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); - -typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); -typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); - -#endif /* GLAD_PLATFORM_H_ */ - -#define VK_ATTACHMENT_UNUSED (~0U) -#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" -#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 10 -#define VK_FALSE 0 -#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" -#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 -#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" -#define VK_KHR_SURFACE_SPEC_VERSION 25 -#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" -#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70 -#define VK_LOD_CLAMP_NONE 1000.0F -#define VK_LUID_SIZE 8 -#define VK_MAX_DESCRIPTION_SIZE 256 -#define VK_MAX_DEVICE_GROUP_SIZE 32 -#define VK_MAX_DRIVER_INFO_SIZE 256 -#define VK_MAX_DRIVER_NAME_SIZE 256 -#define VK_MAX_EXTENSION_NAME_SIZE 256 -#define VK_MAX_MEMORY_HEAPS 16 -#define VK_MAX_MEMORY_TYPES 32 -#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 -#define VK_QUEUE_FAMILY_EXTERNAL (~1U) -#define VK_QUEUE_FAMILY_IGNORED (~0U) -#define VK_REMAINING_ARRAY_LAYERS (~0U) -#define VK_REMAINING_MIP_LEVELS (~0U) -#define VK_SUBPASS_EXTERNAL (~0U) -#define VK_TRUE 1 -#define VK_UUID_SIZE 16 -#define VK_WHOLE_SIZE (~0ULL) - - -/* */ -/* File: vk_platform.h */ -/* */ -/* -** Copyright 2014-2022 The Khronos Group Inc. -** -** SPDX-License-Identifier: Apache-2.0 -*/ - - -#ifndef VK_PLATFORM_H_ -#define VK_PLATFORM_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* -*************************************************************************************************** -* Platform-specific directives and type declarations -*************************************************************************************************** -*/ - -/* Platform-specific calling convention macros. - * - * Platforms should define these so that Vulkan clients call Vulkan commands - * with the same calling conventions that the Vulkan implementation expects. - * - * VKAPI_ATTR - Placed before the return type in function declarations. - * Useful for C++11 and GCC/Clang-style function attribute syntax. - * VKAPI_CALL - Placed after the return type in function declarations. - * Useful for MSVC-style calling convention syntax. - * VKAPI_PTR - Placed between the '(' and '*' in function pointer types. - * - * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); - * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); - */ -#if defined(_WIN32) - /* On Windows, Vulkan commands use the stdcall convention */ - #define VKAPI_ATTR - #define VKAPI_CALL __stdcall - #define VKAPI_PTR VKAPI_CALL -#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan is not supported for the 'armeabi' NDK ABI" -#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) - /* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */ - /* calling convention, i.e. float parameters are passed in registers. This */ - /* is true even if the rest of the application passes floats on the stack, */ - /* as it does by default when compiling for the armeabi-v7a NDK ABI. */ - #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp"))) - #define VKAPI_CALL - #define VKAPI_PTR VKAPI_ATTR -#else - /* On other platforms, use the default calling convention */ - #define VKAPI_ATTR - #define VKAPI_CALL - #define VKAPI_PTR -#endif - -#if !defined(VK_NO_STDDEF_H) - #include -#endif /* !defined(VK_NO_STDDEF_H) */ - -#if !defined(VK_NO_STDINT_H) - #if defined(_MSC_VER) && (_MSC_VER < 1600) - typedef signed __int8 int8_t; - typedef unsigned __int8 uint8_t; - typedef signed __int16 int16_t; - typedef unsigned __int16 uint16_t; - typedef signed __int32 int32_t; - typedef unsigned __int32 uint32_t; - typedef signed __int64 int64_t; - typedef unsigned __int64 uint64_t; - #else - #include - #endif -#endif /* !defined(VK_NO_STDINT_H) */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif -/* DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead. */ -#define VK_MAKE_VERSION(major, minor, patch) \ - ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) -/* DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. */ -#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) -/* DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead. */ -#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) -/* DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead. */ -#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) -#define VK_MAKE_API_VERSION(variant, major, minor, patch) \ - ((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) -#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29) -#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU) -#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) -#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) -/* DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. */ -/*#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 */ -/* Vulkan 1.0 version number */ -#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)/* Patch version should always be set to 0 */ -/* Vulkan 1.1 version number */ -#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)/* Patch version should always be set to 0 */ -/* Vulkan 1.2 version number */ -#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)/* Patch version should always be set to 0 */ -/* Vulkan 1.3 version number */ -#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)/* Patch version should always be set to 0 */ -/* Version of this file */ -#define VK_HEADER_VERSION 220 -/* Complete version of this file */ -#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) -#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; -#ifndef VK_USE_64_BIT_PTR_DEFINES - #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) - #define VK_USE_64_BIT_PTR_DEFINES 1 - #else - #define VK_USE_64_BIT_PTR_DEFINES 0 - #endif -#endif -#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE - #if (VK_USE_64_BIT_PTR_DEFINES==1) - #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) - #define VK_NULL_HANDLE nullptr - #else - #define VK_NULL_HANDLE ((void*)0) - #endif - #else - #define VK_NULL_HANDLE 0ULL - #endif -#endif -#ifndef VK_NULL_HANDLE - #define VK_NULL_HANDLE 0 -#endif -#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE - #if (VK_USE_64_BIT_PTR_DEFINES==1) - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; - #else - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; - #endif -#endif - - - - - - - - -VK_DEFINE_HANDLE(VkInstance) -VK_DEFINE_HANDLE(VkPhysicalDevice) -VK_DEFINE_HANDLE(VkDevice) -VK_DEFINE_HANDLE(VkQueue) -VK_DEFINE_HANDLE(VkCommandBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) -typedef enum VkAttachmentLoadOp { - VK_ATTACHMENT_LOAD_OP_LOAD = 0, - VK_ATTACHMENT_LOAD_OP_CLEAR = 1, - VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, - VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentLoadOp; -typedef enum VkAttachmentStoreOp { - VK_ATTACHMENT_STORE_OP_STORE = 0, - VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_NONE = 1000301000, - VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentStoreOp; -typedef enum VkBlendFactor { - VK_BLEND_FACTOR_ZERO = 0, - VK_BLEND_FACTOR_ONE = 1, - VK_BLEND_FACTOR_SRC_COLOR = 2, - VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, - VK_BLEND_FACTOR_DST_COLOR = 4, - VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, - VK_BLEND_FACTOR_SRC_ALPHA = 6, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, - VK_BLEND_FACTOR_DST_ALPHA = 8, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, - VK_BLEND_FACTOR_CONSTANT_COLOR = 10, - VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, - VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, - VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, - VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, - VK_BLEND_FACTOR_SRC1_COLOR = 15, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, - VK_BLEND_FACTOR_SRC1_ALPHA = 17, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, - VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF -} VkBlendFactor; -typedef enum VkBlendOp { - VK_BLEND_OP_ADD = 0, - VK_BLEND_OP_SUBTRACT = 1, - VK_BLEND_OP_REVERSE_SUBTRACT = 2, - VK_BLEND_OP_MIN = 3, - VK_BLEND_OP_MAX = 4, - VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF -} VkBlendOp; -typedef enum VkBorderColor { - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, - VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, - VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, - VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, - VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, - VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, - VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF -} VkBorderColor; -typedef enum VkFramebufferCreateFlagBits { - VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 1, - VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFramebufferCreateFlagBits; -typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheHeaderVersion; -typedef enum VkPipelineCacheCreateFlagBits { - VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 1, - VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheCreateFlagBits; -typedef enum VkPipelineShaderStageCreateFlagBits { - VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 1, - VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 2, - VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineShaderStageCreateFlagBits; -typedef enum VkDescriptorSetLayoutCreateFlagBits { - VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 2, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorSetLayoutCreateFlagBits; -typedef enum VkInstanceCreateFlagBits { - VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 1, - VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkInstanceCreateFlagBits; -typedef enum VkDeviceQueueCreateFlagBits { - VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 1, - VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDeviceQueueCreateFlagBits; -typedef enum VkBufferCreateFlagBits { - VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 1, - VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 2, - VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 4, - VK_BUFFER_CREATE_PROTECTED_BIT = 8, - VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 16, - VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkBufferCreateFlagBits; -typedef enum VkBufferUsageFlagBits { - VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 1, - VK_BUFFER_USAGE_TRANSFER_DST_BIT = 2, - VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 4, - VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 8, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 16, - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 32, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 64, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 128, - VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 256, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 131072, - VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkBufferUsageFlagBits; -typedef enum VkColorComponentFlagBits { - VK_COLOR_COMPONENT_R_BIT = 1, - VK_COLOR_COMPONENT_G_BIT = 2, - VK_COLOR_COMPONENT_B_BIT = 4, - VK_COLOR_COMPONENT_A_BIT = 8, - VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkColorComponentFlagBits; -typedef enum VkComponentSwizzle { - VK_COMPONENT_SWIZZLE_IDENTITY = 0, - VK_COMPONENT_SWIZZLE_ZERO = 1, - VK_COMPONENT_SWIZZLE_ONE = 2, - VK_COMPONENT_SWIZZLE_R = 3, - VK_COMPONENT_SWIZZLE_G = 4, - VK_COMPONENT_SWIZZLE_B = 5, - VK_COMPONENT_SWIZZLE_A = 6, - VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF -} VkComponentSwizzle; -typedef enum VkCommandPoolCreateFlagBits { - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 1, - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 2, - VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 4, - VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolCreateFlagBits; -typedef enum VkCommandPoolResetFlagBits { - VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 1, - VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolResetFlagBits; -typedef enum VkCommandBufferResetFlagBits { - VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 1, - VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferResetFlagBits; -typedef enum VkCommandBufferLevel { - VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, - VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, - VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferLevel; -typedef enum VkCommandBufferUsageFlagBits { - VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 1, - VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 2, - VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 4, - VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferUsageFlagBits; -typedef enum VkCompareOp { - VK_COMPARE_OP_NEVER = 0, - VK_COMPARE_OP_LESS = 1, - VK_COMPARE_OP_EQUAL = 2, - VK_COMPARE_OP_LESS_OR_EQUAL = 3, - VK_COMPARE_OP_GREATER = 4, - VK_COMPARE_OP_NOT_EQUAL = 5, - VK_COMPARE_OP_GREATER_OR_EQUAL = 6, - VK_COMPARE_OP_ALWAYS = 7, - VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF -} VkCompareOp; -typedef enum VkCullModeFlagBits { - VK_CULL_MODE_NONE = 0, - VK_CULL_MODE_FRONT_BIT = 1, - VK_CULL_MODE_BACK_BIT = 2, - VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, - VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCullModeFlagBits; -typedef enum VkDescriptorType { - VK_DESCRIPTOR_TYPE_SAMPLER = 0, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, - VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, - VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorType; -typedef enum VkDynamicState { - VK_DYNAMIC_STATE_VIEWPORT = 0, - VK_DYNAMIC_STATE_SCISSOR = 1, - VK_DYNAMIC_STATE_LINE_WIDTH = 2, - VK_DYNAMIC_STATE_DEPTH_BIAS = 3, - VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, - VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, - VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, - VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, - VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, - VK_DYNAMIC_STATE_CULL_MODE = 1000267000, - VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, - VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, - VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, - VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, - VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, - VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, - VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, - VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, - VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, - VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, - VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, - VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF -} VkDynamicState; -typedef enum VkFenceCreateFlagBits { - VK_FENCE_CREATE_SIGNALED_BIT = 1, - VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFenceCreateFlagBits; -typedef enum VkPolygonMode { - VK_POLYGON_MODE_FILL = 0, - VK_POLYGON_MODE_LINE = 1, - VK_POLYGON_MODE_POINT = 2, - VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF -} VkPolygonMode; -typedef enum VkFormat { - VK_FORMAT_UNDEFINED = 0, - VK_FORMAT_R4G4_UNORM_PACK8 = 1, - VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, - VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, - VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, - VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, - VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, - VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, - VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, - VK_FORMAT_R8_UNORM = 9, - VK_FORMAT_R8_SNORM = 10, - VK_FORMAT_R8_USCALED = 11, - VK_FORMAT_R8_SSCALED = 12, - VK_FORMAT_R8_UINT = 13, - VK_FORMAT_R8_SINT = 14, - VK_FORMAT_R8_SRGB = 15, - VK_FORMAT_R8G8_UNORM = 16, - VK_FORMAT_R8G8_SNORM = 17, - VK_FORMAT_R8G8_USCALED = 18, - VK_FORMAT_R8G8_SSCALED = 19, - VK_FORMAT_R8G8_UINT = 20, - VK_FORMAT_R8G8_SINT = 21, - VK_FORMAT_R8G8_SRGB = 22, - VK_FORMAT_R8G8B8_UNORM = 23, - VK_FORMAT_R8G8B8_SNORM = 24, - VK_FORMAT_R8G8B8_USCALED = 25, - VK_FORMAT_R8G8B8_SSCALED = 26, - VK_FORMAT_R8G8B8_UINT = 27, - VK_FORMAT_R8G8B8_SINT = 28, - VK_FORMAT_R8G8B8_SRGB = 29, - VK_FORMAT_B8G8R8_UNORM = 30, - VK_FORMAT_B8G8R8_SNORM = 31, - VK_FORMAT_B8G8R8_USCALED = 32, - VK_FORMAT_B8G8R8_SSCALED = 33, - VK_FORMAT_B8G8R8_UINT = 34, - VK_FORMAT_B8G8R8_SINT = 35, - VK_FORMAT_B8G8R8_SRGB = 36, - VK_FORMAT_R8G8B8A8_UNORM = 37, - VK_FORMAT_R8G8B8A8_SNORM = 38, - VK_FORMAT_R8G8B8A8_USCALED = 39, - VK_FORMAT_R8G8B8A8_SSCALED = 40, - VK_FORMAT_R8G8B8A8_UINT = 41, - VK_FORMAT_R8G8B8A8_SINT = 42, - VK_FORMAT_R8G8B8A8_SRGB = 43, - VK_FORMAT_B8G8R8A8_UNORM = 44, - VK_FORMAT_B8G8R8A8_SNORM = 45, - VK_FORMAT_B8G8R8A8_USCALED = 46, - VK_FORMAT_B8G8R8A8_SSCALED = 47, - VK_FORMAT_B8G8R8A8_UINT = 48, - VK_FORMAT_B8G8R8A8_SINT = 49, - VK_FORMAT_B8G8R8A8_SRGB = 50, - VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, - VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, - VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, - VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, - VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, - VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, - VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, - VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, - VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, - VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, - VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, - VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, - VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, - VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, - VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, - VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, - VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, - VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, - VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, - VK_FORMAT_R16_UNORM = 70, - VK_FORMAT_R16_SNORM = 71, - VK_FORMAT_R16_USCALED = 72, - VK_FORMAT_R16_SSCALED = 73, - VK_FORMAT_R16_UINT = 74, - VK_FORMAT_R16_SINT = 75, - VK_FORMAT_R16_SFLOAT = 76, - VK_FORMAT_R16G16_UNORM = 77, - VK_FORMAT_R16G16_SNORM = 78, - VK_FORMAT_R16G16_USCALED = 79, - VK_FORMAT_R16G16_SSCALED = 80, - VK_FORMAT_R16G16_UINT = 81, - VK_FORMAT_R16G16_SINT = 82, - VK_FORMAT_R16G16_SFLOAT = 83, - VK_FORMAT_R16G16B16_UNORM = 84, - VK_FORMAT_R16G16B16_SNORM = 85, - VK_FORMAT_R16G16B16_USCALED = 86, - VK_FORMAT_R16G16B16_SSCALED = 87, - VK_FORMAT_R16G16B16_UINT = 88, - VK_FORMAT_R16G16B16_SINT = 89, - VK_FORMAT_R16G16B16_SFLOAT = 90, - VK_FORMAT_R16G16B16A16_UNORM = 91, - VK_FORMAT_R16G16B16A16_SNORM = 92, - VK_FORMAT_R16G16B16A16_USCALED = 93, - VK_FORMAT_R16G16B16A16_SSCALED = 94, - VK_FORMAT_R16G16B16A16_UINT = 95, - VK_FORMAT_R16G16B16A16_SINT = 96, - VK_FORMAT_R16G16B16A16_SFLOAT = 97, - VK_FORMAT_R32_UINT = 98, - VK_FORMAT_R32_SINT = 99, - VK_FORMAT_R32_SFLOAT = 100, - VK_FORMAT_R32G32_UINT = 101, - VK_FORMAT_R32G32_SINT = 102, - VK_FORMAT_R32G32_SFLOAT = 103, - VK_FORMAT_R32G32B32_UINT = 104, - VK_FORMAT_R32G32B32_SINT = 105, - VK_FORMAT_R32G32B32_SFLOAT = 106, - VK_FORMAT_R32G32B32A32_UINT = 107, - VK_FORMAT_R32G32B32A32_SINT = 108, - VK_FORMAT_R32G32B32A32_SFLOAT = 109, - VK_FORMAT_R64_UINT = 110, - VK_FORMAT_R64_SINT = 111, - VK_FORMAT_R64_SFLOAT = 112, - VK_FORMAT_R64G64_UINT = 113, - VK_FORMAT_R64G64_SINT = 114, - VK_FORMAT_R64G64_SFLOAT = 115, - VK_FORMAT_R64G64B64_UINT = 116, - VK_FORMAT_R64G64B64_SINT = 117, - VK_FORMAT_R64G64B64_SFLOAT = 118, - VK_FORMAT_R64G64B64A64_UINT = 119, - VK_FORMAT_R64G64B64A64_SINT = 120, - VK_FORMAT_R64G64B64A64_SFLOAT = 121, - VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, - VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, - VK_FORMAT_D16_UNORM = 124, - VK_FORMAT_X8_D24_UNORM_PACK32 = 125, - VK_FORMAT_D32_SFLOAT = 126, - VK_FORMAT_S8_UINT = 127, - VK_FORMAT_D16_UNORM_S8_UINT = 128, - VK_FORMAT_D24_UNORM_S8_UINT = 129, - VK_FORMAT_D32_SFLOAT_S8_UINT = 130, - VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, - VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, - VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, - VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, - VK_FORMAT_BC2_UNORM_BLOCK = 135, - VK_FORMAT_BC2_SRGB_BLOCK = 136, - VK_FORMAT_BC3_UNORM_BLOCK = 137, - VK_FORMAT_BC3_SRGB_BLOCK = 138, - VK_FORMAT_BC4_UNORM_BLOCK = 139, - VK_FORMAT_BC4_SNORM_BLOCK = 140, - VK_FORMAT_BC5_UNORM_BLOCK = 141, - VK_FORMAT_BC5_SNORM_BLOCK = 142, - VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, - VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, - VK_FORMAT_BC7_UNORM_BLOCK = 145, - VK_FORMAT_BC7_SRGB_BLOCK = 146, - VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, - VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, - VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, - VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, - VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, - VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, - VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, - VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, - VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, - VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, - VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, - VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, - VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, - VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, - VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, - VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, - VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, - VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, - VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, - VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, - VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, - VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, - VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, - VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, - VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, - VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, - VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, - VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, - VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, - VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, - VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, - VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, - VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, - VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, - VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, - VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, - VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, - VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, - VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000, - VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001, - VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002, - VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003, - VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004, - VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005, - VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006, - VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007, - VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008, - VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009, - VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010, - VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016, - VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017, - VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018, - VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019, - VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020, - VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026, - VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027, - VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028, - VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029, - VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, - VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, - VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, - VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, - VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, - VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, - VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, - VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, - VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, - VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, - VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, - VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, - VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, - VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, - VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, - VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, - VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, - VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, - VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, - VK_FORMAT_MAX_ENUM = 0x7FFFFFFF -} VkFormat; -typedef enum VkFormatFeatureFlagBits { - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 1, - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 2, - VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 4, - VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 8, - VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 16, - VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 32, - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 64, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 128, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 256, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 512, - VK_FORMAT_FEATURE_BLIT_SRC_BIT = 1024, - VK_FORMAT_FEATURE_BLIT_DST_BIT = 2048, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 4096, - VK_FORMAT_FEATURE_TRANSFER_SRC_BIT = 16384, - VK_FORMAT_FEATURE_TRANSFER_DST_BIT = 32768, - VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT = 131072, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 262144, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 524288, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 1048576, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 2097152, - VK_FORMAT_FEATURE_DISJOINT_BIT = 4194304, - VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 8388608, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 65536, - VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFormatFeatureFlagBits; -typedef enum VkFrontFace { - VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, - VK_FRONT_FACE_CLOCKWISE = 1, - VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF -} VkFrontFace; -typedef enum VkImageAspectFlagBits { - VK_IMAGE_ASPECT_COLOR_BIT = 1, - VK_IMAGE_ASPECT_DEPTH_BIT = 2, - VK_IMAGE_ASPECT_STENCIL_BIT = 4, - VK_IMAGE_ASPECT_METADATA_BIT = 8, - VK_IMAGE_ASPECT_PLANE_0_BIT = 16, - VK_IMAGE_ASPECT_PLANE_1_BIT = 32, - VK_IMAGE_ASPECT_PLANE_2_BIT = 64, - VK_IMAGE_ASPECT_NONE = 0, - VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageAspectFlagBits; -typedef enum VkImageCreateFlagBits { - VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 1, - VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 2, - VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 4, - VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 8, - VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 16, - VK_IMAGE_CREATE_ALIAS_BIT = 1024, - VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 64, - VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 32, - VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 128, - VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 256, - VK_IMAGE_CREATE_PROTECTED_BIT = 2048, - VK_IMAGE_CREATE_DISJOINT_BIT = 512, - VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageCreateFlagBits; -typedef enum VkImageLayout { - VK_IMAGE_LAYOUT_UNDEFINED = 0, - VK_IMAGE_LAYOUT_GENERAL = 1, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, - VK_IMAGE_LAYOUT_PREINITIALIZED = 8, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, - VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, - VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF -} VkImageLayout; -typedef enum VkImageTiling { - VK_IMAGE_TILING_OPTIMAL = 0, - VK_IMAGE_TILING_LINEAR = 1, - VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF -} VkImageTiling; -typedef enum VkImageType { - VK_IMAGE_TYPE_1D = 0, - VK_IMAGE_TYPE_2D = 1, - VK_IMAGE_TYPE_3D = 2, - VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageType; -typedef enum VkImageUsageFlagBits { - VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 1, - VK_IMAGE_USAGE_TRANSFER_DST_BIT = 2, - VK_IMAGE_USAGE_SAMPLED_BIT = 4, - VK_IMAGE_USAGE_STORAGE_BIT = 8, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 16, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 32, - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 64, - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 128, - VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageUsageFlagBits; -typedef enum VkImageViewType { - VK_IMAGE_VIEW_TYPE_1D = 0, - VK_IMAGE_VIEW_TYPE_2D = 1, - VK_IMAGE_VIEW_TYPE_3D = 2, - VK_IMAGE_VIEW_TYPE_CUBE = 3, - VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, - VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, - VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, - VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageViewType; -typedef enum VkSharingMode { - VK_SHARING_MODE_EXCLUSIVE = 0, - VK_SHARING_MODE_CONCURRENT = 1, - VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSharingMode; -typedef enum VkIndexType { - VK_INDEX_TYPE_UINT16 = 0, - VK_INDEX_TYPE_UINT32 = 1, - VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkIndexType; -typedef enum VkLogicOp { - VK_LOGIC_OP_CLEAR = 0, - VK_LOGIC_OP_AND = 1, - VK_LOGIC_OP_AND_REVERSE = 2, - VK_LOGIC_OP_COPY = 3, - VK_LOGIC_OP_AND_INVERTED = 4, - VK_LOGIC_OP_NO_OP = 5, - VK_LOGIC_OP_XOR = 6, - VK_LOGIC_OP_OR = 7, - VK_LOGIC_OP_NOR = 8, - VK_LOGIC_OP_EQUIVALENT = 9, - VK_LOGIC_OP_INVERT = 10, - VK_LOGIC_OP_OR_REVERSE = 11, - VK_LOGIC_OP_COPY_INVERTED = 12, - VK_LOGIC_OP_OR_INVERTED = 13, - VK_LOGIC_OP_NAND = 14, - VK_LOGIC_OP_SET = 15, - VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF -} VkLogicOp; -typedef enum VkMemoryHeapFlagBits { - VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 1, - VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 2, - VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryHeapFlagBits; -typedef enum VkAccessFlagBits { - VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 1, - VK_ACCESS_INDEX_READ_BIT = 2, - VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 4, - VK_ACCESS_UNIFORM_READ_BIT = 8, - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 16, - VK_ACCESS_SHADER_READ_BIT = 32, - VK_ACCESS_SHADER_WRITE_BIT = 64, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 128, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 256, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 512, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 1024, - VK_ACCESS_TRANSFER_READ_BIT = 2048, - VK_ACCESS_TRANSFER_WRITE_BIT = 4096, - VK_ACCESS_HOST_READ_BIT = 8192, - VK_ACCESS_HOST_WRITE_BIT = 16384, - VK_ACCESS_MEMORY_READ_BIT = 32768, - VK_ACCESS_MEMORY_WRITE_BIT = 65536, - VK_ACCESS_NONE = 0, - VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAccessFlagBits; -typedef enum VkMemoryPropertyFlagBits { - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 1, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 2, - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 4, - VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 8, - VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 16, - VK_MEMORY_PROPERTY_PROTECTED_BIT = 32, - VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryPropertyFlagBits; -typedef enum VkPhysicalDeviceType { - VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, - VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, - VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, - VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, - VK_PHYSICAL_DEVICE_TYPE_CPU = 4, - VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkPhysicalDeviceType; -typedef enum VkPipelineBindPoint { - VK_PIPELINE_BIND_POINT_GRAPHICS = 0, - VK_PIPELINE_BIND_POINT_COMPUTE = 1, - VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF -} VkPipelineBindPoint; -typedef enum VkPipelineCreateFlagBits { - VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 1, - VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 2, - VK_PIPELINE_CREATE_DERIVATIVE_BIT = 4, - VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 8, - VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 16, - VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 256, - VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 512, - VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCreateFlagBits; -typedef enum VkPrimitiveTopology { - VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, - VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, - VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF -} VkPrimitiveTopology; -typedef enum VkQueryControlFlagBits { - VK_QUERY_CONTROL_PRECISE_BIT = 1, - VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryControlFlagBits; -typedef enum VkQueryPipelineStatisticFlagBits { - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 1, - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 2, - VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 4, - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 8, - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 16, - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 32, - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 64, - VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 128, - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 256, - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 512, - VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 1024, - VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryPipelineStatisticFlagBits; -typedef enum VkQueryResultFlagBits { - VK_QUERY_RESULT_64_BIT = 1, - VK_QUERY_RESULT_WAIT_BIT = 2, - VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 4, - VK_QUERY_RESULT_PARTIAL_BIT = 8, - VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryResultFlagBits; -typedef enum VkQueryType { - VK_QUERY_TYPE_OCCLUSION = 0, - VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, - VK_QUERY_TYPE_TIMESTAMP = 2, - VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkQueryType; -typedef enum VkQueueFlagBits { - VK_QUEUE_GRAPHICS_BIT = 1, - VK_QUEUE_COMPUTE_BIT = 2, - VK_QUEUE_TRANSFER_BIT = 4, - VK_QUEUE_SPARSE_BINDING_BIT = 8, - VK_QUEUE_PROTECTED_BIT = 16, - VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueueFlagBits; -typedef enum VkSubpassContents { - VK_SUBPASS_CONTENTS_INLINE = 0, - VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, - VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF -} VkSubpassContents; -typedef enum VkResult { - VK_SUCCESS = 0, - VK_NOT_READY = 1, - VK_TIMEOUT = 2, - VK_EVENT_SET = 3, - VK_EVENT_RESET = 4, - VK_INCOMPLETE = 5, - VK_ERROR_OUT_OF_HOST_MEMORY = -1, - VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, - VK_ERROR_INITIALIZATION_FAILED = -3, - VK_ERROR_DEVICE_LOST = -4, - VK_ERROR_MEMORY_MAP_FAILED = -5, - VK_ERROR_LAYER_NOT_PRESENT = -6, - VK_ERROR_EXTENSION_NOT_PRESENT = -7, - VK_ERROR_FEATURE_NOT_PRESENT = -8, - VK_ERROR_INCOMPATIBLE_DRIVER = -9, - VK_ERROR_TOO_MANY_OBJECTS = -10, - VK_ERROR_FORMAT_NOT_SUPPORTED = -11, - VK_ERROR_FRAGMENTED_POOL = -12, - VK_ERROR_UNKNOWN = -13, - VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, - VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, - VK_ERROR_FRAGMENTATION = -1000161000, - VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, - VK_PIPELINE_COMPILE_REQUIRED = 1000297000, - VK_ERROR_SURFACE_LOST_KHR = -1000000000, - VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, - VK_SUBOPTIMAL_KHR = 1000001003, - VK_ERROR_OUT_OF_DATE_KHR = -1000001004, - VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, - VK_RESULT_MAX_ENUM = 0x7FFFFFFF -} VkResult; -typedef enum VkShaderStageFlagBits { - VK_SHADER_STAGE_VERTEX_BIT = 1, - VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 2, - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 4, - VK_SHADER_STAGE_GEOMETRY_BIT = 8, - VK_SHADER_STAGE_FRAGMENT_BIT = 16, - VK_SHADER_STAGE_COMPUTE_BIT = 32, - VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, - VK_SHADER_STAGE_ALL = 0x7FFFFFFF, - VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkShaderStageFlagBits; -typedef enum VkSparseMemoryBindFlagBits { - VK_SPARSE_MEMORY_BIND_METADATA_BIT = 1, - VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseMemoryBindFlagBits; -typedef enum VkStencilFaceFlagBits { - VK_STENCIL_FACE_FRONT_BIT = 1, - VK_STENCIL_FACE_BACK_BIT = 2, - VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003, - VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK, - VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkStencilFaceFlagBits; -typedef enum VkStencilOp { - VK_STENCIL_OP_KEEP = 0, - VK_STENCIL_OP_ZERO = 1, - VK_STENCIL_OP_REPLACE = 2, - VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, - VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, - VK_STENCIL_OP_INVERT = 5, - VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, - VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, - VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF -} VkStencilOp; -typedef enum VkStructureType { - VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, - VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, - VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, - VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, - VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, - VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, - VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, - VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, - VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, - VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, - VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, - VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, - VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, - VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, - VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, - VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, - VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005, - VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, - VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, - VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, - VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, - VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, - VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, - VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, - VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, - VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, - VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, - VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001, - VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000, - VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, - VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, - VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, - VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, - VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, - VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, - VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, - VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002, - VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, - VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004, - VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001, - VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, - VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, - VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, - VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, - VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, - VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, - VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, - VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, - VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, - VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, - VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, - VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, - VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, - VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, - VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, - VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, - VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, - VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, - VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, - VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, - VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, - VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, - VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, - VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, - VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, - VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, - VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, - VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkStructureType; -typedef enum VkSystemAllocationScope { - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, - VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, - VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF -} VkSystemAllocationScope; -typedef enum VkInternalAllocationType { - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, - VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkInternalAllocationType; -typedef enum VkSamplerAddressMode { - VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, - VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, - VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, - VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerAddressMode; -typedef enum VkFilter { - VK_FILTER_NEAREST = 0, - VK_FILTER_LINEAR = 1, - VK_FILTER_MAX_ENUM = 0x7FFFFFFF -} VkFilter; -typedef enum VkSamplerMipmapMode { - VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, - VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, - VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerMipmapMode; -typedef enum VkVertexInputRate { - VK_VERTEX_INPUT_RATE_VERTEX = 0, - VK_VERTEX_INPUT_RATE_INSTANCE = 1, - VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF -} VkVertexInputRate; -typedef enum VkPipelineStageFlagBits { - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 1, - VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 2, - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 4, - VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 8, - VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 16, - VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 32, - VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 64, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 128, - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 256, - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 512, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 1024, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 2048, - VK_PIPELINE_STAGE_TRANSFER_BIT = 4096, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 8192, - VK_PIPELINE_STAGE_HOST_BIT = 16384, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 32768, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 65536, - VK_PIPELINE_STAGE_NONE = 0, - VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineStageFlagBits; -typedef enum VkSparseImageFormatFlagBits { - VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 1, - VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 2, - VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 4, - VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseImageFormatFlagBits; -typedef enum VkSampleCountFlagBits { - VK_SAMPLE_COUNT_1_BIT = 1, - VK_SAMPLE_COUNT_2_BIT = 2, - VK_SAMPLE_COUNT_4_BIT = 4, - VK_SAMPLE_COUNT_8_BIT = 8, - VK_SAMPLE_COUNT_16_BIT = 16, - VK_SAMPLE_COUNT_32_BIT = 32, - VK_SAMPLE_COUNT_64_BIT = 64, - VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSampleCountFlagBits; -typedef enum VkAttachmentDescriptionFlagBits { - VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 1, - VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentDescriptionFlagBits; -typedef enum VkDescriptorPoolCreateFlagBits { - VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 1, - VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 2, - VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorPoolCreateFlagBits; -typedef enum VkDependencyFlagBits { - VK_DEPENDENCY_BY_REGION_BIT = 1, - VK_DEPENDENCY_DEVICE_GROUP_BIT = 4, - VK_DEPENDENCY_VIEW_LOCAL_BIT = 2, - VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDependencyFlagBits; -typedef enum VkObjectType { - VK_OBJECT_TYPE_UNKNOWN = 0, - VK_OBJECT_TYPE_INSTANCE = 1, - VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, - VK_OBJECT_TYPE_DEVICE = 3, - VK_OBJECT_TYPE_QUEUE = 4, - VK_OBJECT_TYPE_SEMAPHORE = 5, - VK_OBJECT_TYPE_COMMAND_BUFFER = 6, - VK_OBJECT_TYPE_FENCE = 7, - VK_OBJECT_TYPE_DEVICE_MEMORY = 8, - VK_OBJECT_TYPE_BUFFER = 9, - VK_OBJECT_TYPE_IMAGE = 10, - VK_OBJECT_TYPE_EVENT = 11, - VK_OBJECT_TYPE_QUERY_POOL = 12, - VK_OBJECT_TYPE_BUFFER_VIEW = 13, - VK_OBJECT_TYPE_IMAGE_VIEW = 14, - VK_OBJECT_TYPE_SHADER_MODULE = 15, - VK_OBJECT_TYPE_PIPELINE_CACHE = 16, - VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, - VK_OBJECT_TYPE_RENDER_PASS = 18, - VK_OBJECT_TYPE_PIPELINE = 19, - VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, - VK_OBJECT_TYPE_SAMPLER = 21, - VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, - VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, - VK_OBJECT_TYPE_FRAMEBUFFER = 24, - VK_OBJECT_TYPE_COMMAND_POOL = 25, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, - VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, - VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, - VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, - VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, - VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, - VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkObjectType; -typedef enum VkEventCreateFlagBits { - VK_EVENT_CREATE_DEVICE_ONLY_BIT = 1, - VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkEventCreateFlagBits; -typedef enum VkDescriptorUpdateTemplateType { - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorUpdateTemplateType; -typedef enum VkPointClippingBehavior { - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, - VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, - VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF -} VkPointClippingBehavior; -typedef enum VkResolveModeFlagBits { - VK_RESOLVE_MODE_NONE = 0, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 1, - VK_RESOLVE_MODE_AVERAGE_BIT = 2, - VK_RESOLVE_MODE_MIN_BIT = 4, - VK_RESOLVE_MODE_MAX_BIT = 8, - VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkResolveModeFlagBits; -typedef enum VkDescriptorBindingFlagBits { - VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 1, - VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 2, - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 4, - VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 8, - VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorBindingFlagBits; -typedef enum VkSemaphoreType { - VK_SEMAPHORE_TYPE_BINARY = 0, - VK_SEMAPHORE_TYPE_TIMELINE = 1, - VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreType; -typedef enum VkPipelineCreationFeedbackFlagBits { - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 1, - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 2, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 4, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, - VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCreationFeedbackFlagBits; -typedef enum VkSemaphoreWaitFlagBits { - VK_SEMAPHORE_WAIT_ANY_BIT = 1, - VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreWaitFlagBits; -typedef enum VkToolPurposeFlagBits { - VK_TOOL_PURPOSE_VALIDATION_BIT = 1, - VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, - VK_TOOL_PURPOSE_PROFILING_BIT = 2, - VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, - VK_TOOL_PURPOSE_TRACING_BIT = 4, - VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 8, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 16, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, - VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkToolPurposeFlagBits; -typedef uint64_t VkAccessFlagBits2; -static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0; -static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0; -static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 1; -static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 1; -static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 2; -static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 2; -static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 4; -static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 4; -static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 8; -static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 8; -static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 16; -static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 16; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 32; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 32; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 64; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 64; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 128; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 128; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 256; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 256; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 512; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 512; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 1024; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 1024; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 2048; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 2048; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 4096; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 4096; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 8192; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 8192; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 16384; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 16384; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 32768; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 32768; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 65536; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 65536; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 4294967296; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 4294967296; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 8589934592; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 8589934592; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 17179869184; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 17179869184; - -typedef uint64_t VkPipelineStageFlagBits2; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 1; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 1; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 2; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 2; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 4; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 4; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 8; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 8; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 16; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 16; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 32; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 32; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 64; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 64; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 128; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 128; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 256; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 256; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 512; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 512; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 1024; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 1024; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 2048; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 2048; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 4096; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 4096; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 4096; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 4096; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 8192; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 8192; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 16384; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 16384; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 32768; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 32768; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 65536; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 65536; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 4294967296; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 4294967296; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 8589934592; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 8589934592; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 17179869184; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 17179869184; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 34359738368; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 34359738368; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 68719476736; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 68719476736; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 137438953472; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 137438953472; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 274877906944; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 274877906944; - -typedef uint64_t VkFormatFeatureFlagBits2; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 1; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 1; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 2; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 2; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 4; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 4; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 8; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 8; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 16; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 16; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 32; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 32; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 64; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 64; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 128; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 128; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 256; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 256; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 512; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 512; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 1024; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 1024; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 2048; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 2048; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 4096; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 4096; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 8192; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 8192; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 16384; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 16384; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 32768; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 32768; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 65536; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 65536; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 131072; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 131072; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 262144; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 262144; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 524288; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 524288; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 1048576; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 1048576; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 2097152; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 2097152; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 4194304; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 4194304; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 8388608; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 8388608; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 2147483648; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 2147483648; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 4294967296; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 4294967296; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 8589934592; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 8589934592; - -typedef enum VkRenderingFlagBits { - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 1, - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, - VK_RENDERING_SUSPENDING_BIT = 2, - VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, - VK_RENDERING_RESUMING_BIT = 4, - VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, - VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkRenderingFlagBits; -typedef enum VkColorSpaceKHR { - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, - VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkColorSpaceKHR; -typedef enum VkCompositeAlphaFlagBitsKHR { - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 1, - VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 2, - VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 4, - VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 8, - VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkCompositeAlphaFlagBitsKHR; -typedef enum VkPresentModeKHR { - VK_PRESENT_MODE_IMMEDIATE_KHR = 0, - VK_PRESENT_MODE_MAILBOX_KHR = 1, - VK_PRESENT_MODE_FIFO_KHR = 2, - VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, - VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPresentModeKHR; -typedef enum VkSurfaceTransformFlagBitsKHR { - VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 1, - VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 2, - VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 4, - VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 8, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 16, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 32, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 64, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 128, - VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 256, - VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSurfaceTransformFlagBitsKHR; -typedef enum VkDebugReportFlagBitsEXT { - VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 1, - VK_DEBUG_REPORT_WARNING_BIT_EXT = 2, - VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 4, - VK_DEBUG_REPORT_ERROR_BIT_EXT = 8, - VK_DEBUG_REPORT_DEBUG_BIT_EXT = 16, - VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugReportFlagBitsEXT; -typedef enum VkDebugReportObjectTypeEXT { - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, - VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, - VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, - VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, - VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, - VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, - VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, - VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, - VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, - VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, - VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, - VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, - VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, - VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, - VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, - VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, - VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, - VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, - VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, - VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, - VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugReportObjectTypeEXT; -typedef enum VkExternalMemoryHandleTypeFlagBits { - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 1, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 2, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 4, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 8, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 16, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 32, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 64, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalMemoryHandleTypeFlagBits; -typedef enum VkExternalMemoryFeatureFlagBits { - VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 1, - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 2, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 4, - VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalMemoryFeatureFlagBits; -typedef enum VkExternalSemaphoreHandleTypeFlagBits { - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 1, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 2, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 4, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 8, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 16, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalSemaphoreHandleTypeFlagBits; -typedef enum VkExternalSemaphoreFeatureFlagBits { - VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 1, - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 2, - VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalSemaphoreFeatureFlagBits; -typedef enum VkSemaphoreImportFlagBits { - VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 1, - VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreImportFlagBits; -typedef enum VkExternalFenceHandleTypeFlagBits { - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 1, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 2, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 4, - VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 8, - VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalFenceHandleTypeFlagBits; -typedef enum VkExternalFenceFeatureFlagBits { - VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 1, - VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 2, - VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalFenceFeatureFlagBits; -typedef enum VkFenceImportFlagBits { - VK_FENCE_IMPORT_TEMPORARY_BIT = 1, - VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFenceImportFlagBits; -typedef enum VkPeerMemoryFeatureFlagBits { - VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 1, - VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 2, - VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 4, - VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 8, - VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPeerMemoryFeatureFlagBits; -typedef enum VkMemoryAllocateFlagBits { - VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 1, - VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 2, - VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 4, - VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryAllocateFlagBits; -typedef enum VkDeviceGroupPresentModeFlagBitsKHR { - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 1, - VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 2, - VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 4, - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 8, - VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDeviceGroupPresentModeFlagBitsKHR; -typedef enum VkSwapchainCreateFlagBitsKHR { - VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 1, - VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 2, - VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSwapchainCreateFlagBitsKHR; -typedef enum VkSubgroupFeatureFlagBits { - VK_SUBGROUP_FEATURE_BASIC_BIT = 1, - VK_SUBGROUP_FEATURE_VOTE_BIT = 2, - VK_SUBGROUP_FEATURE_ARITHMETIC_BIT = 4, - VK_SUBGROUP_FEATURE_BALLOT_BIT = 8, - VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 16, - VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 32, - VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 64, - VK_SUBGROUP_FEATURE_QUAD_BIT = 128, - VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubgroupFeatureFlagBits; -typedef enum VkTessellationDomainOrigin { - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, - VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF -} VkTessellationDomainOrigin; -typedef enum VkSamplerYcbcrModelConversion { - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF -} VkSamplerYcbcrModelConversion; -typedef enum VkSamplerYcbcrRange { - VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, - VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, - VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerYcbcrRange; -typedef enum VkChromaLocation { - VK_CHROMA_LOCATION_COSITED_EVEN = 0, - VK_CHROMA_LOCATION_MIDPOINT = 1, - VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF -} VkChromaLocation; -typedef enum VkSamplerReductionMode { - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, - VK_SAMPLER_REDUCTION_MODE_MIN = 1, - VK_SAMPLER_REDUCTION_MODE_MAX = 2, - VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerReductionMode; -typedef enum VkShaderFloatControlsIndependence { - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF -} VkShaderFloatControlsIndependence; -typedef enum VkSubmitFlagBits { - VK_SUBMIT_PROTECTED_BIT = 1, - VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, - VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubmitFlagBits; -typedef enum VkVendorId { - VK_VENDOR_ID_VIV = 0x10001, - VK_VENDOR_ID_VSI = 0x10002, - VK_VENDOR_ID_KAZAN = 0x10003, - VK_VENDOR_ID_CODEPLAY = 0x10004, - VK_VENDOR_ID_MESA = 0x10005, - VK_VENDOR_ID_POCL = 0x10006, - VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF -} VkVendorId; -typedef enum VkDriverId { - VK_DRIVER_ID_AMD_PROPRIETARY = 1, - VK_DRIVER_ID_AMD_OPEN_SOURCE = 2, - VK_DRIVER_ID_MESA_RADV = 3, - VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4, - VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5, - VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6, - VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7, - VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8, - VK_DRIVER_ID_ARM_PROPRIETARY = 9, - VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10, - VK_DRIVER_ID_GGP_PROPRIETARY = 11, - VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12, - VK_DRIVER_ID_MESA_LLVMPIPE = 13, - VK_DRIVER_ID_MOLTENVK = 14, - VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, - VK_DRIVER_ID_JUICE_PROPRIETARY = 16, - VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, - VK_DRIVER_ID_MESA_TURNIP = 18, - VK_DRIVER_ID_MESA_V3DV = 19, - VK_DRIVER_ID_MESA_PANVK = 20, - VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, - VK_DRIVER_ID_MESA_VENUS = 22, - VK_DRIVER_ID_MESA_DOZEN = 23, - VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF -} VkDriverId; -typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( - void* pUserData, - size_t size, - VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope); -typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( - void* pUserData, - size_t size, - VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope); -typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( - void* pUserData, - void* pOriginal, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); -typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( - void* pUserData, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); -typedef void (VKAPI_PTR *PFN_vkFreeFunction)( - void* pUserData, - void* pMemory); -typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); -typedef struct VkBaseOutStructure { - VkStructureType sType; - struct VkBaseOutStructure * pNext; -} VkBaseOutStructure; - -typedef struct VkBaseInStructure { - VkStructureType sType; - const struct VkBaseInStructure * pNext; -} VkBaseInStructure; - -typedef struct VkOffset2D { - int32_t x; - int32_t y; -} VkOffset2D; - -typedef struct VkOffset3D { - int32_t x; - int32_t y; - int32_t z; -} VkOffset3D; - -typedef struct VkExtent2D { - uint32_t width; - uint32_t height; -} VkExtent2D; - -typedef struct VkExtent3D { - uint32_t width; - uint32_t height; - uint32_t depth; -} VkExtent3D; - -typedef struct VkViewport { - float x; - float y; - float width; - float height; - float minDepth; - float maxDepth; -} VkViewport; - -typedef struct VkRect2D { - VkOffset2D offset; - VkExtent2D extent; -} VkRect2D; - -typedef struct VkClearRect { - VkRect2D rect; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkClearRect; - -typedef struct VkComponentMapping { - VkComponentSwizzle r; - VkComponentSwizzle g; - VkComponentSwizzle b; - VkComponentSwizzle a; -} VkComponentMapping; - -typedef struct VkExtensionProperties { - char extensionName [ VK_MAX_EXTENSION_NAME_SIZE ]; - uint32_t specVersion; -} VkExtensionProperties; - -typedef struct VkLayerProperties { - char layerName [ VK_MAX_EXTENSION_NAME_SIZE ]; - uint32_t specVersion; - uint32_t implementationVersion; - char description [ VK_MAX_DESCRIPTION_SIZE ]; -} VkLayerProperties; - -typedef struct VkApplicationInfo { - VkStructureType sType; - const void * pNext; - const char * pApplicationName; - uint32_t applicationVersion; - const char * pEngineName; - uint32_t engineVersion; - uint32_t apiVersion; -} VkApplicationInfo; - -typedef struct VkAllocationCallbacks { - void * pUserData; - PFN_vkAllocationFunction pfnAllocation; - PFN_vkReallocationFunction pfnReallocation; - PFN_vkFreeFunction pfnFree; - PFN_vkInternalAllocationNotification pfnInternalAllocation; - PFN_vkInternalFreeNotification pfnInternalFree; -} VkAllocationCallbacks; - -typedef struct VkDescriptorImageInfo { - VkSampler sampler; - VkImageView imageView; - VkImageLayout imageLayout; -} VkDescriptorImageInfo; - -typedef struct VkCopyDescriptorSet { - VkStructureType sType; - const void * pNext; - VkDescriptorSet srcSet; - uint32_t srcBinding; - uint32_t srcArrayElement; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; -} VkCopyDescriptorSet; - -typedef struct VkDescriptorPoolSize { - VkDescriptorType type; - uint32_t descriptorCount; -} VkDescriptorPoolSize; - -typedef struct VkDescriptorSetAllocateInfo { - VkStructureType sType; - const void * pNext; - VkDescriptorPool descriptorPool; - uint32_t descriptorSetCount; - const VkDescriptorSetLayout * pSetLayouts; -} VkDescriptorSetAllocateInfo; - -typedef struct VkSpecializationMapEntry { - uint32_t constantID; - uint32_t offset; - size_t size; -} VkSpecializationMapEntry; - -typedef struct VkSpecializationInfo { - uint32_t mapEntryCount; - const VkSpecializationMapEntry * pMapEntries; - size_t dataSize; - const void * pData; -} VkSpecializationInfo; - -typedef struct VkVertexInputBindingDescription { - uint32_t binding; - uint32_t stride; - VkVertexInputRate inputRate; -} VkVertexInputBindingDescription; - -typedef struct VkVertexInputAttributeDescription { - uint32_t location; - uint32_t binding; - VkFormat format; - uint32_t offset; -} VkVertexInputAttributeDescription; - -typedef struct VkStencilOpState { - VkStencilOp failOp; - VkStencilOp passOp; - VkStencilOp depthFailOp; - VkCompareOp compareOp; - uint32_t compareMask; - uint32_t writeMask; - uint32_t reference; -} VkStencilOpState; - -typedef struct VkPipelineCacheHeaderVersionOne { - uint32_t headerSize; - VkPipelineCacheHeaderVersion headerVersion; - uint32_t vendorID; - uint32_t deviceID; - uint8_t pipelineCacheUUID [ VK_UUID_SIZE ]; -} VkPipelineCacheHeaderVersionOne; - -typedef struct VkCommandBufferAllocateInfo { - VkStructureType sType; - const void * pNext; - VkCommandPool commandPool; - VkCommandBufferLevel level; - uint32_t commandBufferCount; -} VkCommandBufferAllocateInfo; - -typedef union VkClearColorValue { - float float32 [4]; - int32_t int32 [4]; - uint32_t uint32 [4]; -} VkClearColorValue; - -typedef struct VkClearDepthStencilValue { - float depth; - uint32_t stencil; -} VkClearDepthStencilValue; - -typedef union VkClearValue { - VkClearColorValue color; - VkClearDepthStencilValue depthStencil; -} VkClearValue; - -typedef struct VkAttachmentReference { - uint32_t attachment; - VkImageLayout layout; -} VkAttachmentReference; - -typedef struct VkDrawIndirectCommand { - uint32_t vertexCount; - uint32_t instanceCount; - uint32_t firstVertex; - uint32_t firstInstance; -} VkDrawIndirectCommand; - -typedef struct VkDrawIndexedIndirectCommand { - uint32_t indexCount; - uint32_t instanceCount; - uint32_t firstIndex; - int32_t vertexOffset; - uint32_t firstInstance; -} VkDrawIndexedIndirectCommand; - -typedef struct VkDispatchIndirectCommand { - uint32_t x; - uint32_t y; - uint32_t z; -} VkDispatchIndirectCommand; - -typedef struct VkSurfaceFormatKHR { - VkFormat format; - VkColorSpaceKHR colorSpace; -} VkSurfaceFormatKHR; - -typedef struct VkPresentInfoKHR { - VkStructureType sType; - const void * pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore * pWaitSemaphores; - uint32_t swapchainCount; - const VkSwapchainKHR * pSwapchains; - const uint32_t * pImageIndices; - VkResult * pResults; -} VkPresentInfoKHR; - -typedef struct VkDevicePrivateDataCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t privateDataSlotRequestCount; -} VkDevicePrivateDataCreateInfo; - -typedef struct VkConformanceVersion { - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t patch; -} VkConformanceVersion; - -typedef struct VkPhysicalDeviceDriverProperties { - VkStructureType sType; - void * pNext; - VkDriverId driverID; - char driverName [ VK_MAX_DRIVER_NAME_SIZE ]; - char driverInfo [ VK_MAX_DRIVER_INFO_SIZE ]; - VkConformanceVersion conformanceVersion; -} VkPhysicalDeviceDriverProperties; - -typedef struct VkPhysicalDeviceExternalImageFormatInfo { - VkStructureType sType; - const void * pNext; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalImageFormatInfo; - -typedef struct VkPhysicalDeviceExternalSemaphoreInfo { - VkStructureType sType; - const void * pNext; - VkExternalSemaphoreHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalSemaphoreInfo; - -typedef struct VkPhysicalDeviceExternalFenceInfo { - VkStructureType sType; - const void * pNext; - VkExternalFenceHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalFenceInfo; - -typedef struct VkPhysicalDeviceMultiviewProperties { - VkStructureType sType; - void * pNext; - uint32_t maxMultiviewViewCount; - uint32_t maxMultiviewInstanceIndex; -} VkPhysicalDeviceMultiviewProperties; - -typedef struct VkRenderPassMultiviewCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t subpassCount; - const uint32_t * pViewMasks; - uint32_t dependencyCount; - const int32_t * pViewOffsets; - uint32_t correlationMaskCount; - const uint32_t * pCorrelationMasks; -} VkRenderPassMultiviewCreateInfo; - -typedef struct VkBindBufferMemoryDeviceGroupInfo { - VkStructureType sType; - const void * pNext; - uint32_t deviceIndexCount; - const uint32_t * pDeviceIndices; -} VkBindBufferMemoryDeviceGroupInfo; - -typedef struct VkBindImageMemoryDeviceGroupInfo { - VkStructureType sType; - const void * pNext; - uint32_t deviceIndexCount; - const uint32_t * pDeviceIndices; - uint32_t splitInstanceBindRegionCount; - const VkRect2D * pSplitInstanceBindRegions; -} VkBindImageMemoryDeviceGroupInfo; - -typedef struct VkDeviceGroupRenderPassBeginInfo { - VkStructureType sType; - const void * pNext; - uint32_t deviceMask; - uint32_t deviceRenderAreaCount; - const VkRect2D * pDeviceRenderAreas; -} VkDeviceGroupRenderPassBeginInfo; - -typedef struct VkDeviceGroupCommandBufferBeginInfo { - VkStructureType sType; - const void * pNext; - uint32_t deviceMask; -} VkDeviceGroupCommandBufferBeginInfo; - -typedef struct VkDeviceGroupSubmitInfo { - VkStructureType sType; - const void * pNext; - uint32_t waitSemaphoreCount; - const uint32_t * pWaitSemaphoreDeviceIndices; - uint32_t commandBufferCount; - const uint32_t * pCommandBufferDeviceMasks; - uint32_t signalSemaphoreCount; - const uint32_t * pSignalSemaphoreDeviceIndices; -} VkDeviceGroupSubmitInfo; - -typedef struct VkDeviceGroupBindSparseInfo { - VkStructureType sType; - const void * pNext; - uint32_t resourceDeviceIndex; - uint32_t memoryDeviceIndex; -} VkDeviceGroupBindSparseInfo; - -typedef struct VkImageSwapchainCreateInfoKHR { - VkStructureType sType; - const void * pNext; - VkSwapchainKHR swapchain; -} VkImageSwapchainCreateInfoKHR; - -typedef struct VkBindImageMemorySwapchainInfoKHR { - VkStructureType sType; - const void * pNext; - VkSwapchainKHR swapchain; - uint32_t imageIndex; -} VkBindImageMemorySwapchainInfoKHR; - -typedef struct VkAcquireNextImageInfoKHR { - VkStructureType sType; - const void * pNext; - VkSwapchainKHR swapchain; - uint64_t timeout; - VkSemaphore semaphore; - VkFence fence; - uint32_t deviceMask; -} VkAcquireNextImageInfoKHR; - -typedef struct VkDeviceGroupPresentInfoKHR { - VkStructureType sType; - const void * pNext; - uint32_t swapchainCount; - const uint32_t * pDeviceMasks; - VkDeviceGroupPresentModeFlagBitsKHR mode; -} VkDeviceGroupPresentInfoKHR; - -typedef struct VkDeviceGroupDeviceCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t physicalDeviceCount; - const VkPhysicalDevice * pPhysicalDevices; -} VkDeviceGroupDeviceCreateInfo; - -typedef struct VkDescriptorUpdateTemplateEntry { - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - size_t offset; - size_t stride; -} VkDescriptorUpdateTemplateEntry; - -typedef struct VkBufferMemoryRequirementsInfo2 { - VkStructureType sType; - const void * pNext; - VkBuffer buffer; -} VkBufferMemoryRequirementsInfo2; - -typedef struct VkImageMemoryRequirementsInfo2 { - VkStructureType sType; - const void * pNext; - VkImage image; -} VkImageMemoryRequirementsInfo2; - -typedef struct VkImageSparseMemoryRequirementsInfo2 { - VkStructureType sType; - const void * pNext; - VkImage image; -} VkImageSparseMemoryRequirementsInfo2; - -typedef struct VkPhysicalDevicePointClippingProperties { - VkStructureType sType; - void * pNext; - VkPointClippingBehavior pointClippingBehavior; -} VkPhysicalDevicePointClippingProperties; - -typedef struct VkMemoryDedicatedAllocateInfo { - VkStructureType sType; - const void * pNext; - VkImage image; - VkBuffer buffer; -} VkMemoryDedicatedAllocateInfo; - -typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkTessellationDomainOrigin domainOrigin; -} VkPipelineTessellationDomainOriginStateCreateInfo; - -typedef struct VkSamplerYcbcrConversionInfo { - VkStructureType sType; - const void * pNext; - VkSamplerYcbcrConversion conversion; -} VkSamplerYcbcrConversionInfo; - -typedef struct VkBindImagePlaneMemoryInfo { - VkStructureType sType; - const void * pNext; - VkImageAspectFlagBits planeAspect; -} VkBindImagePlaneMemoryInfo; - -typedef struct VkImagePlaneMemoryRequirementsInfo { - VkStructureType sType; - const void * pNext; - VkImageAspectFlagBits planeAspect; -} VkImagePlaneMemoryRequirementsInfo; - -typedef struct VkSamplerYcbcrConversionImageFormatProperties { - VkStructureType sType; - void * pNext; - uint32_t combinedImageSamplerDescriptorCount; -} VkSamplerYcbcrConversionImageFormatProperties; - -typedef struct VkSamplerReductionModeCreateInfo { - VkStructureType sType; - const void * pNext; - VkSamplerReductionMode reductionMode; -} VkSamplerReductionModeCreateInfo; - -typedef struct VkPhysicalDeviceInlineUniformBlockProperties { - VkStructureType sType; - void * pNext; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; -} VkPhysicalDeviceInlineUniformBlockProperties; - -typedef struct VkWriteDescriptorSetInlineUniformBlock { - VkStructureType sType; - const void * pNext; - uint32_t dataSize; - const void * pData; -} VkWriteDescriptorSetInlineUniformBlock; - -typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t maxInlineUniformBlockBindings; -} VkDescriptorPoolInlineUniformBlockCreateInfo; - -typedef struct VkImageFormatListCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t viewFormatCount; - const VkFormat * pViewFormats; -} VkImageFormatListCreateInfo; - -typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo { - VkStructureType sType; - const void * pNext; - uint32_t descriptorSetCount; - const uint32_t * pDescriptorCounts; -} VkDescriptorSetVariableDescriptorCountAllocateInfo; - -typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { - VkStructureType sType; - void * pNext; - uint32_t maxVariableDescriptorCount; -} VkDescriptorSetVariableDescriptorCountLayoutSupport; - -typedef struct VkSubpassBeginInfo { - VkStructureType sType; - const void * pNext; - VkSubpassContents contents; -} VkSubpassBeginInfo; - -typedef struct VkSubpassEndInfo { - VkStructureType sType; - const void * pNext; -} VkSubpassEndInfo; - -typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { - VkStructureType sType; - void * pNext; - uint64_t maxTimelineSemaphoreValueDifference; -} VkPhysicalDeviceTimelineSemaphoreProperties; - -typedef struct VkSemaphoreTypeCreateInfo { - VkStructureType sType; - const void * pNext; - VkSemaphoreType semaphoreType; - uint64_t initialValue; -} VkSemaphoreTypeCreateInfo; - -typedef struct VkTimelineSemaphoreSubmitInfo { - VkStructureType sType; - const void * pNext; - uint32_t waitSemaphoreValueCount; - const uint64_t * pWaitSemaphoreValues; - uint32_t signalSemaphoreValueCount; - const uint64_t * pSignalSemaphoreValues; -} VkTimelineSemaphoreSubmitInfo; - -typedef struct VkSemaphoreSignalInfo { - VkStructureType sType; - const void * pNext; - VkSemaphore semaphore; - uint64_t value; -} VkSemaphoreSignalInfo; - -typedef struct VkBufferDeviceAddressInfo { - VkStructureType sType; - const void * pNext; - VkBuffer buffer; -} VkBufferDeviceAddressInfo; - -typedef struct VkBufferOpaqueCaptureAddressCreateInfo { - VkStructureType sType; - const void * pNext; - uint64_t opaqueCaptureAddress; -} VkBufferOpaqueCaptureAddressCreateInfo; - -typedef struct VkRenderPassAttachmentBeginInfo { - VkStructureType sType; - const void * pNext; - uint32_t attachmentCount; - const VkImageView * pAttachments; -} VkRenderPassAttachmentBeginInfo; - -typedef struct VkAttachmentReferenceStencilLayout { - VkStructureType sType; - void * pNext; - VkImageLayout stencilLayout; -} VkAttachmentReferenceStencilLayout; - -typedef struct VkAttachmentDescriptionStencilLayout { - VkStructureType sType; - void * pNext; - VkImageLayout stencilInitialLayout; - VkImageLayout stencilFinalLayout; -} VkAttachmentDescriptionStencilLayout; - -typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { - VkStructureType sType; - void * pNext; - uint32_t requiredSubgroupSize; -} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; - -typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { - VkStructureType sType; - const void * pNext; - uint64_t opaqueCaptureAddress; -} VkMemoryOpaqueCaptureAddressAllocateInfo; - -typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { - VkStructureType sType; - const void * pNext; - VkDeviceMemory memory; -} VkDeviceMemoryOpaqueCaptureAddressInfo; - -typedef struct VkCommandBufferSubmitInfo { - VkStructureType sType; - const void * pNext; - VkCommandBuffer commandBuffer; - uint32_t deviceMask; -} VkCommandBufferSubmitInfo; - -typedef struct VkPipelineRenderingCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat * pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; -} VkPipelineRenderingCreateInfo; - -typedef struct VkRenderingAttachmentInfo { - VkStructureType sType; - const void * pNext; - VkImageView imageView; - VkImageLayout imageLayout; - VkResolveModeFlagBits resolveMode; - VkImageView resolveImageView; - VkImageLayout resolveImageLayout; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkClearValue clearValue; -} VkRenderingAttachmentInfo; - -typedef uint32_t VkSampleMask; -typedef uint32_t VkBool32; -typedef uint32_t VkFlags; -typedef uint64_t VkFlags64; -typedef uint64_t VkDeviceSize; -typedef uint64_t VkDeviceAddress; -typedef VkFlags VkFramebufferCreateFlags; -typedef VkFlags VkQueryPoolCreateFlags; -typedef VkFlags VkRenderPassCreateFlags; -typedef VkFlags VkSamplerCreateFlags; -typedef VkFlags VkPipelineLayoutCreateFlags; -typedef VkFlags VkPipelineCacheCreateFlags; -typedef VkFlags VkPipelineDepthStencilStateCreateFlags; -typedef VkFlags VkPipelineDynamicStateCreateFlags; -typedef VkFlags VkPipelineColorBlendStateCreateFlags; -typedef VkFlags VkPipelineMultisampleStateCreateFlags; -typedef VkFlags VkPipelineRasterizationStateCreateFlags; -typedef VkFlags VkPipelineViewportStateCreateFlags; -typedef VkFlags VkPipelineTessellationStateCreateFlags; -typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; -typedef VkFlags VkPipelineVertexInputStateCreateFlags; -typedef VkFlags VkPipelineShaderStageCreateFlags; -typedef VkFlags VkDescriptorSetLayoutCreateFlags; -typedef VkFlags VkBufferViewCreateFlags; -typedef VkFlags VkInstanceCreateFlags; -typedef VkFlags VkDeviceCreateFlags; -typedef VkFlags VkDeviceQueueCreateFlags; -typedef VkFlags VkQueueFlags; -typedef VkFlags VkMemoryPropertyFlags; -typedef VkFlags VkMemoryHeapFlags; -typedef VkFlags VkAccessFlags; -typedef VkFlags VkBufferUsageFlags; -typedef VkFlags VkBufferCreateFlags; -typedef VkFlags VkShaderStageFlags; -typedef VkFlags VkImageUsageFlags; -typedef VkFlags VkImageCreateFlags; -typedef VkFlags VkImageViewCreateFlags; -typedef VkFlags VkPipelineCreateFlags; -typedef VkFlags VkColorComponentFlags; -typedef VkFlags VkFenceCreateFlags; -typedef VkFlags VkSemaphoreCreateFlags; -typedef VkFlags VkFormatFeatureFlags; -typedef VkFlags VkQueryControlFlags; -typedef VkFlags VkQueryResultFlags; -typedef VkFlags VkShaderModuleCreateFlags; -typedef VkFlags VkEventCreateFlags; -typedef VkFlags VkCommandPoolCreateFlags; -typedef VkFlags VkCommandPoolResetFlags; -typedef VkFlags VkCommandBufferResetFlags; -typedef VkFlags VkCommandBufferUsageFlags; -typedef VkFlags VkQueryPipelineStatisticFlags; -typedef VkFlags VkMemoryMapFlags; -typedef VkFlags VkImageAspectFlags; -typedef VkFlags VkSparseMemoryBindFlags; -typedef VkFlags VkSparseImageFormatFlags; -typedef VkFlags VkSubpassDescriptionFlags; -typedef VkFlags VkPipelineStageFlags; -typedef VkFlags VkSampleCountFlags; -typedef VkFlags VkAttachmentDescriptionFlags; -typedef VkFlags VkStencilFaceFlags; -typedef VkFlags VkCullModeFlags; -typedef VkFlags VkDescriptorPoolCreateFlags; -typedef VkFlags VkDescriptorPoolResetFlags; -typedef VkFlags VkDependencyFlags; -typedef VkFlags VkSubgroupFeatureFlags; -typedef VkFlags VkPrivateDataSlotCreateFlags; -typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; -typedef VkFlags VkPipelineCreationFeedbackFlags; -typedef VkFlags VkSemaphoreWaitFlags; -typedef VkFlags64 VkAccessFlags2; -typedef VkFlags64 VkPipelineStageFlags2; -typedef VkFlags64 VkFormatFeatureFlags2; -typedef VkFlags VkRenderingFlags; -typedef VkFlags VkCompositeAlphaFlagsKHR; -typedef VkFlags VkSurfaceTransformFlagsKHR; -typedef VkFlags VkSwapchainCreateFlagsKHR; -typedef VkFlags VkPeerMemoryFeatureFlags; -typedef VkFlags VkMemoryAllocateFlags; -typedef VkFlags VkDeviceGroupPresentModeFlagsKHR; -typedef VkFlags VkDebugReportFlagsEXT; -typedef VkFlags VkCommandPoolTrimFlags; -typedef VkFlags VkExternalMemoryHandleTypeFlags; -typedef VkFlags VkExternalMemoryFeatureFlags; -typedef VkFlags VkExternalSemaphoreHandleTypeFlags; -typedef VkFlags VkExternalSemaphoreFeatureFlags; -typedef VkFlags VkSemaphoreImportFlags; -typedef VkFlags VkExternalFenceHandleTypeFlags; -typedef VkFlags VkExternalFenceFeatureFlags; -typedef VkFlags VkFenceImportFlags; -typedef VkFlags VkDescriptorBindingFlags; -typedef VkFlags VkResolveModeFlags; -typedef VkFlags VkToolPurposeFlags; -typedef VkFlags VkSubmitFlags; -typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage, - void* pUserData); -typedef struct VkDeviceQueueCreateInfo { - VkStructureType sType; - const void * pNext; - VkDeviceQueueCreateFlags flags; - uint32_t queueFamilyIndex; - uint32_t queueCount; - const float * pQueuePriorities; -} VkDeviceQueueCreateInfo; - -typedef struct VkInstanceCreateInfo { - VkStructureType sType; - const void * pNext; - VkInstanceCreateFlags flags; - const VkApplicationInfo * pApplicationInfo; - uint32_t enabledLayerCount; - const char * const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char * const* ppEnabledExtensionNames; -} VkInstanceCreateInfo; - -typedef struct VkQueueFamilyProperties { - VkQueueFlags queueFlags; - uint32_t queueCount; - uint32_t timestampValidBits; - VkExtent3D minImageTransferGranularity; -} VkQueueFamilyProperties; - -typedef struct VkMemoryAllocateInfo { - VkStructureType sType; - const void * pNext; - VkDeviceSize allocationSize; - uint32_t memoryTypeIndex; -} VkMemoryAllocateInfo; - -typedef struct VkMemoryRequirements { - VkDeviceSize size; - VkDeviceSize alignment; - uint32_t memoryTypeBits; -} VkMemoryRequirements; - -typedef struct VkSparseImageFormatProperties { - VkImageAspectFlags aspectMask; - VkExtent3D imageGranularity; - VkSparseImageFormatFlags flags; -} VkSparseImageFormatProperties; - -typedef struct VkSparseImageMemoryRequirements { - VkSparseImageFormatProperties formatProperties; - uint32_t imageMipTailFirstLod; - VkDeviceSize imageMipTailSize; - VkDeviceSize imageMipTailOffset; - VkDeviceSize imageMipTailStride; -} VkSparseImageMemoryRequirements; - -typedef struct VkMemoryType { - VkMemoryPropertyFlags propertyFlags; - uint32_t heapIndex; -} VkMemoryType; - -typedef struct VkMemoryHeap { - VkDeviceSize size; - VkMemoryHeapFlags flags; -} VkMemoryHeap; - -typedef struct VkMappedMemoryRange { - VkStructureType sType; - const void * pNext; - VkDeviceMemory memory; - VkDeviceSize offset; - VkDeviceSize size; -} VkMappedMemoryRange; - -typedef struct VkFormatProperties { - VkFormatFeatureFlags linearTilingFeatures; - VkFormatFeatureFlags optimalTilingFeatures; - VkFormatFeatureFlags bufferFeatures; -} VkFormatProperties; - -typedef struct VkImageFormatProperties { - VkExtent3D maxExtent; - uint32_t maxMipLevels; - uint32_t maxArrayLayers; - VkSampleCountFlags sampleCounts; - VkDeviceSize maxResourceSize; -} VkImageFormatProperties; - -typedef struct VkDescriptorBufferInfo { - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize range; -} VkDescriptorBufferInfo; - -typedef struct VkWriteDescriptorSet { - VkStructureType sType; - const void * pNext; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - const VkDescriptorImageInfo * pImageInfo; - const VkDescriptorBufferInfo * pBufferInfo; - const VkBufferView * pTexelBufferView; -} VkWriteDescriptorSet; - -typedef struct VkBufferCreateInfo { - VkStructureType sType; - const void * pNext; - VkBufferCreateFlags flags; - VkDeviceSize size; - VkBufferUsageFlags usage; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t * pQueueFamilyIndices; -} VkBufferCreateInfo; - -typedef struct VkBufferViewCreateInfo { - VkStructureType sType; - const void * pNext; - VkBufferViewCreateFlags flags; - VkBuffer buffer; - VkFormat format; - VkDeviceSize offset; - VkDeviceSize range; -} VkBufferViewCreateInfo; - -typedef struct VkImageSubresource { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t arrayLayer; -} VkImageSubresource; - -typedef struct VkImageSubresourceLayers { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceLayers; - -typedef struct VkImageSubresourceRange { - VkImageAspectFlags aspectMask; - uint32_t baseMipLevel; - uint32_t levelCount; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceRange; - -typedef struct VkMemoryBarrier { - VkStructureType sType; - const void * pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; -} VkMemoryBarrier; - -typedef struct VkBufferMemoryBarrier { - VkStructureType sType; - const void * pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier; - -typedef struct VkImageMemoryBarrier { - VkStructureType sType; - const void * pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier; - -typedef struct VkImageCreateInfo { - VkStructureType sType; - const void * pNext; - VkImageCreateFlags flags; - VkImageType imageType; - VkFormat format; - VkExtent3D extent; - uint32_t mipLevels; - uint32_t arrayLayers; - VkSampleCountFlagBits samples; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t * pQueueFamilyIndices; - VkImageLayout initialLayout; -} VkImageCreateInfo; - -typedef struct VkSubresourceLayout { - VkDeviceSize offset; - VkDeviceSize size; - VkDeviceSize rowPitch; - VkDeviceSize arrayPitch; - VkDeviceSize depthPitch; -} VkSubresourceLayout; - -typedef struct VkImageViewCreateInfo { - VkStructureType sType; - const void * pNext; - VkImageViewCreateFlags flags; - VkImage image; - VkImageViewType viewType; - VkFormat format; - VkComponentMapping components; - VkImageSubresourceRange subresourceRange; -} VkImageViewCreateInfo; - -typedef struct VkBufferCopy { - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy; - -typedef struct VkSparseMemoryBind { - VkDeviceSize resourceOffset; - VkDeviceSize size; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - VkSparseMemoryBindFlags flags; -} VkSparseMemoryBind; - -typedef struct VkSparseImageMemoryBind { - VkImageSubresource subresource; - VkOffset3D offset; - VkExtent3D extent; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - VkSparseMemoryBindFlags flags; -} VkSparseImageMemoryBind; - -typedef struct VkSparseBufferMemoryBindInfo { - VkBuffer buffer; - uint32_t bindCount; - const VkSparseMemoryBind * pBinds; -} VkSparseBufferMemoryBindInfo; - -typedef struct VkSparseImageOpaqueMemoryBindInfo { - VkImage image; - uint32_t bindCount; - const VkSparseMemoryBind * pBinds; -} VkSparseImageOpaqueMemoryBindInfo; - -typedef struct VkSparseImageMemoryBindInfo { - VkImage image; - uint32_t bindCount; - const VkSparseImageMemoryBind * pBinds; -} VkSparseImageMemoryBindInfo; - -typedef struct VkBindSparseInfo { - VkStructureType sType; - const void * pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore * pWaitSemaphores; - uint32_t bufferBindCount; - const VkSparseBufferMemoryBindInfo * pBufferBinds; - uint32_t imageOpaqueBindCount; - const VkSparseImageOpaqueMemoryBindInfo * pImageOpaqueBinds; - uint32_t imageBindCount; - const VkSparseImageMemoryBindInfo * pImageBinds; - uint32_t signalSemaphoreCount; - const VkSemaphore * pSignalSemaphores; -} VkBindSparseInfo; - -typedef struct VkImageCopy { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy; - -typedef struct VkImageBlit { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets [2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets [2]; -} VkImageBlit; - -typedef struct VkBufferImageCopy { - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy; - -typedef struct VkImageResolve { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve; - -typedef struct VkShaderModuleCreateInfo { - VkStructureType sType; - const void * pNext; - VkShaderModuleCreateFlags flags; - size_t codeSize; - const uint32_t * pCode; -} VkShaderModuleCreateInfo; - -typedef struct VkDescriptorSetLayoutBinding { - uint32_t binding; - VkDescriptorType descriptorType; - uint32_t descriptorCount; - VkShaderStageFlags stageFlags; - const VkSampler * pImmutableSamplers; -} VkDescriptorSetLayoutBinding; - -typedef struct VkDescriptorSetLayoutCreateInfo { - VkStructureType sType; - const void * pNext; - VkDescriptorSetLayoutCreateFlags flags; - uint32_t bindingCount; - const VkDescriptorSetLayoutBinding * pBindings; -} VkDescriptorSetLayoutCreateInfo; - -typedef struct VkDescriptorPoolCreateInfo { - VkStructureType sType; - const void * pNext; - VkDescriptorPoolCreateFlags flags; - uint32_t maxSets; - uint32_t poolSizeCount; - const VkDescriptorPoolSize * pPoolSizes; -} VkDescriptorPoolCreateInfo; - -typedef struct VkPipelineShaderStageCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineShaderStageCreateFlags flags; - VkShaderStageFlagBits stage; - VkShaderModule module; - const char * pName; - const VkSpecializationInfo * pSpecializationInfo; -} VkPipelineShaderStageCreateInfo; - -typedef struct VkComputePipelineCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineCreateFlags flags; - VkPipelineShaderStageCreateInfo stage; - VkPipelineLayout layout; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkComputePipelineCreateInfo; - -typedef struct VkPipelineVertexInputStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineVertexInputStateCreateFlags flags; - uint32_t vertexBindingDescriptionCount; - const VkVertexInputBindingDescription * pVertexBindingDescriptions; - uint32_t vertexAttributeDescriptionCount; - const VkVertexInputAttributeDescription * pVertexAttributeDescriptions; -} VkPipelineVertexInputStateCreateInfo; - -typedef struct VkPipelineInputAssemblyStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineInputAssemblyStateCreateFlags flags; - VkPrimitiveTopology topology; - VkBool32 primitiveRestartEnable; -} VkPipelineInputAssemblyStateCreateInfo; - -typedef struct VkPipelineTessellationStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineTessellationStateCreateFlags flags; - uint32_t patchControlPoints; -} VkPipelineTessellationStateCreateInfo; - -typedef struct VkPipelineViewportStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineViewportStateCreateFlags flags; - uint32_t viewportCount; - const VkViewport * pViewports; - uint32_t scissorCount; - const VkRect2D * pScissors; -} VkPipelineViewportStateCreateInfo; - -typedef struct VkPipelineRasterizationStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineRasterizationStateCreateFlags flags; - VkBool32 depthClampEnable; - VkBool32 rasterizerDiscardEnable; - VkPolygonMode polygonMode; - VkCullModeFlags cullMode; - VkFrontFace frontFace; - VkBool32 depthBiasEnable; - float depthBiasConstantFactor; - float depthBiasClamp; - float depthBiasSlopeFactor; - float lineWidth; -} VkPipelineRasterizationStateCreateInfo; - -typedef struct VkPipelineMultisampleStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineMultisampleStateCreateFlags flags; - VkSampleCountFlagBits rasterizationSamples; - VkBool32 sampleShadingEnable; - float minSampleShading; - const VkSampleMask * pSampleMask; - VkBool32 alphaToCoverageEnable; - VkBool32 alphaToOneEnable; -} VkPipelineMultisampleStateCreateInfo; - -typedef struct VkPipelineColorBlendAttachmentState { - VkBool32 blendEnable; - VkBlendFactor srcColorBlendFactor; - VkBlendFactor dstColorBlendFactor; - VkBlendOp colorBlendOp; - VkBlendFactor srcAlphaBlendFactor; - VkBlendFactor dstAlphaBlendFactor; - VkBlendOp alphaBlendOp; - VkColorComponentFlags colorWriteMask; -} VkPipelineColorBlendAttachmentState; - -typedef struct VkPipelineColorBlendStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineColorBlendStateCreateFlags flags; - VkBool32 logicOpEnable; - VkLogicOp logicOp; - uint32_t attachmentCount; - const VkPipelineColorBlendAttachmentState * pAttachments; - float blendConstants [4]; -} VkPipelineColorBlendStateCreateInfo; - -typedef struct VkPipelineDynamicStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineDynamicStateCreateFlags flags; - uint32_t dynamicStateCount; - const VkDynamicState * pDynamicStates; -} VkPipelineDynamicStateCreateInfo; - -typedef struct VkPipelineDepthStencilStateCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineDepthStencilStateCreateFlags flags; - VkBool32 depthTestEnable; - VkBool32 depthWriteEnable; - VkCompareOp depthCompareOp; - VkBool32 depthBoundsTestEnable; - VkBool32 stencilTestEnable; - VkStencilOpState front; - VkStencilOpState back; - float minDepthBounds; - float maxDepthBounds; -} VkPipelineDepthStencilStateCreateInfo; - -typedef struct VkGraphicsPipelineCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineCreateFlags flags; - uint32_t stageCount; - const VkPipelineShaderStageCreateInfo * pStages; - const VkPipelineVertexInputStateCreateInfo * pVertexInputState; - const VkPipelineInputAssemblyStateCreateInfo * pInputAssemblyState; - const VkPipelineTessellationStateCreateInfo * pTessellationState; - const VkPipelineViewportStateCreateInfo * pViewportState; - const VkPipelineRasterizationStateCreateInfo * pRasterizationState; - const VkPipelineMultisampleStateCreateInfo * pMultisampleState; - const VkPipelineDepthStencilStateCreateInfo * pDepthStencilState; - const VkPipelineColorBlendStateCreateInfo * pColorBlendState; - const VkPipelineDynamicStateCreateInfo * pDynamicState; - VkPipelineLayout layout; - VkRenderPass renderPass; - uint32_t subpass; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkGraphicsPipelineCreateInfo; - -typedef struct VkPipelineCacheCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineCacheCreateFlags flags; - size_t initialDataSize; - const void * pInitialData; -} VkPipelineCacheCreateInfo; - -typedef struct VkPushConstantRange { - VkShaderStageFlags stageFlags; - uint32_t offset; - uint32_t size; -} VkPushConstantRange; - -typedef struct VkPipelineLayoutCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineLayoutCreateFlags flags; - uint32_t setLayoutCount; - const VkDescriptorSetLayout * pSetLayouts; - uint32_t pushConstantRangeCount; - const VkPushConstantRange * pPushConstantRanges; -} VkPipelineLayoutCreateInfo; - -typedef struct VkSamplerCreateInfo { - VkStructureType sType; - const void * pNext; - VkSamplerCreateFlags flags; - VkFilter magFilter; - VkFilter minFilter; - VkSamplerMipmapMode mipmapMode; - VkSamplerAddressMode addressModeU; - VkSamplerAddressMode addressModeV; - VkSamplerAddressMode addressModeW; - float mipLodBias; - VkBool32 anisotropyEnable; - float maxAnisotropy; - VkBool32 compareEnable; - VkCompareOp compareOp; - float minLod; - float maxLod; - VkBorderColor borderColor; - VkBool32 unnormalizedCoordinates; -} VkSamplerCreateInfo; - -typedef struct VkCommandPoolCreateInfo { - VkStructureType sType; - const void * pNext; - VkCommandPoolCreateFlags flags; - uint32_t queueFamilyIndex; -} VkCommandPoolCreateInfo; - -typedef struct VkCommandBufferInheritanceInfo { - VkStructureType sType; - const void * pNext; - VkRenderPass renderPass; - uint32_t subpass; - VkFramebuffer framebuffer; - VkBool32 occlusionQueryEnable; - VkQueryControlFlags queryFlags; - VkQueryPipelineStatisticFlags pipelineStatistics; -} VkCommandBufferInheritanceInfo; - -typedef struct VkCommandBufferBeginInfo { - VkStructureType sType; - const void * pNext; - VkCommandBufferUsageFlags flags; - const VkCommandBufferInheritanceInfo * pInheritanceInfo; -} VkCommandBufferBeginInfo; - -typedef struct VkRenderPassBeginInfo { - VkStructureType sType; - const void * pNext; - VkRenderPass renderPass; - VkFramebuffer framebuffer; - VkRect2D renderArea; - uint32_t clearValueCount; - const VkClearValue * pClearValues; -} VkRenderPassBeginInfo; - -typedef struct VkClearAttachment { - VkImageAspectFlags aspectMask; - uint32_t colorAttachment; - VkClearValue clearValue; -} VkClearAttachment; - -typedef struct VkAttachmentDescription { - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription; - -typedef struct VkSubpassDescription { - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t inputAttachmentCount; - const VkAttachmentReference * pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference * pColorAttachments; - const VkAttachmentReference * pResolveAttachments; - const VkAttachmentReference * pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t * pPreserveAttachments; -} VkSubpassDescription; - -typedef struct VkSubpassDependency { - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; -} VkSubpassDependency; - -typedef struct VkRenderPassCreateInfo { - VkStructureType sType; - const void * pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription * pAttachments; - uint32_t subpassCount; - const VkSubpassDescription * pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency * pDependencies; -} VkRenderPassCreateInfo; - -typedef struct VkEventCreateInfo { - VkStructureType sType; - const void * pNext; - VkEventCreateFlags flags; -} VkEventCreateInfo; - -typedef struct VkFenceCreateInfo { - VkStructureType sType; - const void * pNext; - VkFenceCreateFlags flags; -} VkFenceCreateInfo; - -typedef struct VkPhysicalDeviceFeatures { - VkBool32 robustBufferAccess; - VkBool32 fullDrawIndexUint32; - VkBool32 imageCubeArray; - VkBool32 independentBlend; - VkBool32 geometryShader; - VkBool32 tessellationShader; - VkBool32 sampleRateShading; - VkBool32 dualSrcBlend; - VkBool32 logicOp; - VkBool32 multiDrawIndirect; - VkBool32 drawIndirectFirstInstance; - VkBool32 depthClamp; - VkBool32 depthBiasClamp; - VkBool32 fillModeNonSolid; - VkBool32 depthBounds; - VkBool32 wideLines; - VkBool32 largePoints; - VkBool32 alphaToOne; - VkBool32 multiViewport; - VkBool32 samplerAnisotropy; - VkBool32 textureCompressionETC2; - VkBool32 textureCompressionASTC_LDR; - VkBool32 textureCompressionBC; - VkBool32 occlusionQueryPrecise; - VkBool32 pipelineStatisticsQuery; - VkBool32 vertexPipelineStoresAndAtomics; - VkBool32 fragmentStoresAndAtomics; - VkBool32 shaderTessellationAndGeometryPointSize; - VkBool32 shaderImageGatherExtended; - VkBool32 shaderStorageImageExtendedFormats; - VkBool32 shaderStorageImageMultisample; - VkBool32 shaderStorageImageReadWithoutFormat; - VkBool32 shaderStorageImageWriteWithoutFormat; - VkBool32 shaderUniformBufferArrayDynamicIndexing; - VkBool32 shaderSampledImageArrayDynamicIndexing; - VkBool32 shaderStorageBufferArrayDynamicIndexing; - VkBool32 shaderStorageImageArrayDynamicIndexing; - VkBool32 shaderClipDistance; - VkBool32 shaderCullDistance; - VkBool32 shaderFloat64; - VkBool32 shaderInt64; - VkBool32 shaderInt16; - VkBool32 shaderResourceResidency; - VkBool32 shaderResourceMinLod; - VkBool32 sparseBinding; - VkBool32 sparseResidencyBuffer; - VkBool32 sparseResidencyImage2D; - VkBool32 sparseResidencyImage3D; - VkBool32 sparseResidency2Samples; - VkBool32 sparseResidency4Samples; - VkBool32 sparseResidency8Samples; - VkBool32 sparseResidency16Samples; - VkBool32 sparseResidencyAliased; - VkBool32 variableMultisampleRate; - VkBool32 inheritedQueries; -} VkPhysicalDeviceFeatures; - -typedef struct VkPhysicalDeviceSparseProperties { - VkBool32 residencyStandard2DBlockShape; - VkBool32 residencyStandard2DMultisampleBlockShape; - VkBool32 residencyStandard3DBlockShape; - VkBool32 residencyAlignedMipSize; - VkBool32 residencyNonResidentStrict; -} VkPhysicalDeviceSparseProperties; - -typedef struct VkPhysicalDeviceLimits { - uint32_t maxImageDimension1D; - uint32_t maxImageDimension2D; - uint32_t maxImageDimension3D; - uint32_t maxImageDimensionCube; - uint32_t maxImageArrayLayers; - uint32_t maxTexelBufferElements; - uint32_t maxUniformBufferRange; - uint32_t maxStorageBufferRange; - uint32_t maxPushConstantsSize; - uint32_t maxMemoryAllocationCount; - uint32_t maxSamplerAllocationCount; - VkDeviceSize bufferImageGranularity; - VkDeviceSize sparseAddressSpaceSize; - uint32_t maxBoundDescriptorSets; - uint32_t maxPerStageDescriptorSamplers; - uint32_t maxPerStageDescriptorUniformBuffers; - uint32_t maxPerStageDescriptorStorageBuffers; - uint32_t maxPerStageDescriptorSampledImages; - uint32_t maxPerStageDescriptorStorageImages; - uint32_t maxPerStageDescriptorInputAttachments; - uint32_t maxPerStageResources; - uint32_t maxDescriptorSetSamplers; - uint32_t maxDescriptorSetUniformBuffers; - uint32_t maxDescriptorSetUniformBuffersDynamic; - uint32_t maxDescriptorSetStorageBuffers; - uint32_t maxDescriptorSetStorageBuffersDynamic; - uint32_t maxDescriptorSetSampledImages; - uint32_t maxDescriptorSetStorageImages; - uint32_t maxDescriptorSetInputAttachments; - uint32_t maxVertexInputAttributes; - uint32_t maxVertexInputBindings; - uint32_t maxVertexInputAttributeOffset; - uint32_t maxVertexInputBindingStride; - uint32_t maxVertexOutputComponents; - uint32_t maxTessellationGenerationLevel; - uint32_t maxTessellationPatchSize; - uint32_t maxTessellationControlPerVertexInputComponents; - uint32_t maxTessellationControlPerVertexOutputComponents; - uint32_t maxTessellationControlPerPatchOutputComponents; - uint32_t maxTessellationControlTotalOutputComponents; - uint32_t maxTessellationEvaluationInputComponents; - uint32_t maxTessellationEvaluationOutputComponents; - uint32_t maxGeometryShaderInvocations; - uint32_t maxGeometryInputComponents; - uint32_t maxGeometryOutputComponents; - uint32_t maxGeometryOutputVertices; - uint32_t maxGeometryTotalOutputComponents; - uint32_t maxFragmentInputComponents; - uint32_t maxFragmentOutputAttachments; - uint32_t maxFragmentDualSrcAttachments; - uint32_t maxFragmentCombinedOutputResources; - uint32_t maxComputeSharedMemorySize; - uint32_t maxComputeWorkGroupCount [3]; - uint32_t maxComputeWorkGroupInvocations; - uint32_t maxComputeWorkGroupSize [3]; - uint32_t subPixelPrecisionBits; - uint32_t subTexelPrecisionBits; - uint32_t mipmapPrecisionBits; - uint32_t maxDrawIndexedIndexValue; - uint32_t maxDrawIndirectCount; - float maxSamplerLodBias; - float maxSamplerAnisotropy; - uint32_t maxViewports; - uint32_t maxViewportDimensions [2]; - float viewportBoundsRange [2]; - uint32_t viewportSubPixelBits; - size_t minMemoryMapAlignment; - VkDeviceSize minTexelBufferOffsetAlignment; - VkDeviceSize minUniformBufferOffsetAlignment; - VkDeviceSize minStorageBufferOffsetAlignment; - int32_t minTexelOffset; - uint32_t maxTexelOffset; - int32_t minTexelGatherOffset; - uint32_t maxTexelGatherOffset; - float minInterpolationOffset; - float maxInterpolationOffset; - uint32_t subPixelInterpolationOffsetBits; - uint32_t maxFramebufferWidth; - uint32_t maxFramebufferHeight; - uint32_t maxFramebufferLayers; - VkSampleCountFlags framebufferColorSampleCounts; - VkSampleCountFlags framebufferDepthSampleCounts; - VkSampleCountFlags framebufferStencilSampleCounts; - VkSampleCountFlags framebufferNoAttachmentsSampleCounts; - uint32_t maxColorAttachments; - VkSampleCountFlags sampledImageColorSampleCounts; - VkSampleCountFlags sampledImageIntegerSampleCounts; - VkSampleCountFlags sampledImageDepthSampleCounts; - VkSampleCountFlags sampledImageStencilSampleCounts; - VkSampleCountFlags storageImageSampleCounts; - uint32_t maxSampleMaskWords; - VkBool32 timestampComputeAndGraphics; - float timestampPeriod; - uint32_t maxClipDistances; - uint32_t maxCullDistances; - uint32_t maxCombinedClipAndCullDistances; - uint32_t discreteQueuePriorities; - float pointSizeRange [2]; - float lineWidthRange [2]; - float pointSizeGranularity; - float lineWidthGranularity; - VkBool32 strictLines; - VkBool32 standardSampleLocations; - VkDeviceSize optimalBufferCopyOffsetAlignment; - VkDeviceSize optimalBufferCopyRowPitchAlignment; - VkDeviceSize nonCoherentAtomSize; -} VkPhysicalDeviceLimits; - -typedef struct VkSemaphoreCreateInfo { - VkStructureType sType; - const void * pNext; - VkSemaphoreCreateFlags flags; -} VkSemaphoreCreateInfo; - -typedef struct VkQueryPoolCreateInfo { - VkStructureType sType; - const void * pNext; - VkQueryPoolCreateFlags flags; - VkQueryType queryType; - uint32_t queryCount; - VkQueryPipelineStatisticFlags pipelineStatistics; -} VkQueryPoolCreateInfo; - -typedef struct VkFramebufferCreateInfo { - VkStructureType sType; - const void * pNext; - VkFramebufferCreateFlags flags; - VkRenderPass renderPass; - uint32_t attachmentCount; - const VkImageView * pAttachments; - uint32_t width; - uint32_t height; - uint32_t layers; -} VkFramebufferCreateInfo; - -typedef struct VkSubmitInfo { - VkStructureType sType; - const void * pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore * pWaitSemaphores; - const VkPipelineStageFlags * pWaitDstStageMask; - uint32_t commandBufferCount; - const VkCommandBuffer * pCommandBuffers; - uint32_t signalSemaphoreCount; - const VkSemaphore * pSignalSemaphores; -} VkSubmitInfo; - -typedef struct VkSurfaceCapabilitiesKHR { - uint32_t minImageCount; - uint32_t maxImageCount; - VkExtent2D currentExtent; - VkExtent2D minImageExtent; - VkExtent2D maxImageExtent; - uint32_t maxImageArrayLayers; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkSurfaceTransformFlagBitsKHR currentTransform; - VkCompositeAlphaFlagsKHR supportedCompositeAlpha; - VkImageUsageFlags supportedUsageFlags; -} VkSurfaceCapabilitiesKHR; - -typedef struct VkSwapchainCreateInfoKHR { - VkStructureType sType; - const void * pNext; - VkSwapchainCreateFlagsKHR flags; - VkSurfaceKHR surface; - uint32_t minImageCount; - VkFormat imageFormat; - VkColorSpaceKHR imageColorSpace; - VkExtent2D imageExtent; - uint32_t imageArrayLayers; - VkImageUsageFlags imageUsage; - VkSharingMode imageSharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t * pQueueFamilyIndices; - VkSurfaceTransformFlagBitsKHR preTransform; - VkCompositeAlphaFlagBitsKHR compositeAlpha; - VkPresentModeKHR presentMode; - VkBool32 clipped; - VkSwapchainKHR oldSwapchain; -} VkSwapchainCreateInfoKHR; - -typedef struct VkDebugReportCallbackCreateInfoEXT { - VkStructureType sType; - const void * pNext; - VkDebugReportFlagsEXT flags; - PFN_vkDebugReportCallbackEXT pfnCallback; - void * pUserData; -} VkDebugReportCallbackCreateInfoEXT; - -typedef struct VkPrivateDataSlotCreateInfo { - VkStructureType sType; - const void * pNext; - VkPrivateDataSlotCreateFlags flags; -} VkPrivateDataSlotCreateInfo; - -typedef struct VkPhysicalDevicePrivateDataFeatures { - VkStructureType sType; - void * pNext; - VkBool32 privateData; -} VkPhysicalDevicePrivateDataFeatures; - -typedef struct VkPhysicalDeviceFeatures2 { - VkStructureType sType; - void * pNext; - VkPhysicalDeviceFeatures features; -} VkPhysicalDeviceFeatures2; - -typedef struct VkFormatProperties2 { - VkStructureType sType; - void * pNext; - VkFormatProperties formatProperties; -} VkFormatProperties2; - -typedef struct VkImageFormatProperties2 { - VkStructureType sType; - void * pNext; - VkImageFormatProperties imageFormatProperties; -} VkImageFormatProperties2; - -typedef struct VkPhysicalDeviceImageFormatInfo2 { - VkStructureType sType; - const void * pNext; - VkFormat format; - VkImageType type; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkImageCreateFlags flags; -} VkPhysicalDeviceImageFormatInfo2; - -typedef struct VkQueueFamilyProperties2 { - VkStructureType sType; - void * pNext; - VkQueueFamilyProperties queueFamilyProperties; -} VkQueueFamilyProperties2; - -typedef struct VkSparseImageFormatProperties2 { - VkStructureType sType; - void * pNext; - VkSparseImageFormatProperties properties; -} VkSparseImageFormatProperties2; - -typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { - VkStructureType sType; - const void * pNext; - VkFormat format; - VkImageType type; - VkSampleCountFlagBits samples; - VkImageUsageFlags usage; - VkImageTiling tiling; -} VkPhysicalDeviceSparseImageFormatInfo2; - -typedef struct VkPhysicalDeviceVariablePointersFeatures { - VkStructureType sType; - void * pNext; - VkBool32 variablePointersStorageBuffer; - VkBool32 variablePointers; -} VkPhysicalDeviceVariablePointersFeatures; - -typedef struct VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures; - -typedef struct VkExternalMemoryProperties { - VkExternalMemoryFeatureFlags externalMemoryFeatures; - VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; - VkExternalMemoryHandleTypeFlags compatibleHandleTypes; -} VkExternalMemoryProperties; - -typedef struct VkExternalImageFormatProperties { - VkStructureType sType; - void * pNext; - VkExternalMemoryProperties externalMemoryProperties; -} VkExternalImageFormatProperties; - -typedef struct VkPhysicalDeviceExternalBufferInfo { - VkStructureType sType; - const void * pNext; - VkBufferCreateFlags flags; - VkBufferUsageFlags usage; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalBufferInfo; - -typedef struct VkExternalBufferProperties { - VkStructureType sType; - void * pNext; - VkExternalMemoryProperties externalMemoryProperties; -} VkExternalBufferProperties; - -typedef struct VkPhysicalDeviceIDProperties { - VkStructureType sType; - void * pNext; - uint8_t deviceUUID [ VK_UUID_SIZE ]; - uint8_t driverUUID [ VK_UUID_SIZE ]; - uint8_t deviceLUID [ VK_LUID_SIZE ]; - uint32_t deviceNodeMask; - VkBool32 deviceLUIDValid; -} VkPhysicalDeviceIDProperties; - -typedef struct VkExternalMemoryImageCreateInfo { - VkStructureType sType; - const void * pNext; - VkExternalMemoryHandleTypeFlags handleTypes; -} VkExternalMemoryImageCreateInfo; - -typedef struct VkExternalMemoryBufferCreateInfo { - VkStructureType sType; - const void * pNext; - VkExternalMemoryHandleTypeFlags handleTypes; -} VkExternalMemoryBufferCreateInfo; - -typedef struct VkExportMemoryAllocateInfo { - VkStructureType sType; - const void * pNext; - VkExternalMemoryHandleTypeFlags handleTypes; -} VkExportMemoryAllocateInfo; - -typedef struct VkExternalSemaphoreProperties { - VkStructureType sType; - void * pNext; - VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes; - VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes; - VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; -} VkExternalSemaphoreProperties; - -typedef struct VkExportSemaphoreCreateInfo { - VkStructureType sType; - const void * pNext; - VkExternalSemaphoreHandleTypeFlags handleTypes; -} VkExportSemaphoreCreateInfo; - -typedef struct VkExternalFenceProperties { - VkStructureType sType; - void * pNext; - VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes; - VkExternalFenceHandleTypeFlags compatibleHandleTypes; - VkExternalFenceFeatureFlags externalFenceFeatures; -} VkExternalFenceProperties; - -typedef struct VkExportFenceCreateInfo { - VkStructureType sType; - const void * pNext; - VkExternalFenceHandleTypeFlags handleTypes; -} VkExportFenceCreateInfo; - -typedef struct VkPhysicalDeviceMultiviewFeatures { - VkStructureType sType; - void * pNext; - VkBool32 multiview; - VkBool32 multiviewGeometryShader; - VkBool32 multiviewTessellationShader; -} VkPhysicalDeviceMultiviewFeatures; - -typedef struct VkPhysicalDeviceGroupProperties { - VkStructureType sType; - void * pNext; - uint32_t physicalDeviceCount; - VkPhysicalDevice physicalDevices [ VK_MAX_DEVICE_GROUP_SIZE ]; - VkBool32 subsetAllocation; -} VkPhysicalDeviceGroupProperties; - -typedef struct VkMemoryAllocateFlagsInfo { - VkStructureType sType; - const void * pNext; - VkMemoryAllocateFlags flags; - uint32_t deviceMask; -} VkMemoryAllocateFlagsInfo; - -typedef struct VkBindBufferMemoryInfo { - VkStructureType sType; - const void * pNext; - VkBuffer buffer; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; -} VkBindBufferMemoryInfo; - -typedef struct VkBindImageMemoryInfo { - VkStructureType sType; - const void * pNext; - VkImage image; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; -} VkBindImageMemoryInfo; - -typedef struct VkDeviceGroupPresentCapabilitiesKHR { - VkStructureType sType; - void * pNext; - uint32_t presentMask [ VK_MAX_DEVICE_GROUP_SIZE ]; - VkDeviceGroupPresentModeFlagsKHR modes; -} VkDeviceGroupPresentCapabilitiesKHR; - -typedef struct VkDeviceGroupSwapchainCreateInfoKHR { - VkStructureType sType; - const void * pNext; - VkDeviceGroupPresentModeFlagsKHR modes; -} VkDeviceGroupSwapchainCreateInfoKHR; - -typedef struct VkDescriptorUpdateTemplateCreateInfo { - VkStructureType sType; - const void * pNext; - VkDescriptorUpdateTemplateCreateFlags flags; - uint32_t descriptorUpdateEntryCount; - const VkDescriptorUpdateTemplateEntry * pDescriptorUpdateEntries; - VkDescriptorUpdateTemplateType templateType; - VkDescriptorSetLayout descriptorSetLayout; - VkPipelineBindPoint pipelineBindPoint; - VkPipelineLayout pipelineLayout; - uint32_t set; -} VkDescriptorUpdateTemplateCreateInfo; - -typedef struct VkInputAttachmentAspectReference { - uint32_t subpass; - uint32_t inputAttachmentIndex; - VkImageAspectFlags aspectMask; -} VkInputAttachmentAspectReference; - -typedef struct VkRenderPassInputAttachmentAspectCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t aspectReferenceCount; - const VkInputAttachmentAspectReference * pAspectReferences; -} VkRenderPassInputAttachmentAspectCreateInfo; - -typedef struct VkPhysicalDevice16BitStorageFeatures { - VkStructureType sType; - void * pNext; - VkBool32 storageBuffer16BitAccess; - VkBool32 uniformAndStorageBuffer16BitAccess; - VkBool32 storagePushConstant16; - VkBool32 storageInputOutput16; -} VkPhysicalDevice16BitStorageFeatures; - -typedef struct VkPhysicalDeviceSubgroupProperties { - VkStructureType sType; - void * pNext; - uint32_t subgroupSize; - VkShaderStageFlags supportedStages; - VkSubgroupFeatureFlags supportedOperations; - VkBool32 quadOperationsInAllStages; -} VkPhysicalDeviceSubgroupProperties; - -typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderSubgroupExtendedTypes; -} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; - -typedef struct VkDeviceBufferMemoryRequirements { - VkStructureType sType; - const void * pNext; - const VkBufferCreateInfo * pCreateInfo; -} VkDeviceBufferMemoryRequirements; - -typedef struct VkDeviceImageMemoryRequirements { - VkStructureType sType; - const void * pNext; - const VkImageCreateInfo * pCreateInfo; - VkImageAspectFlagBits planeAspect; -} VkDeviceImageMemoryRequirements; - -typedef struct VkMemoryRequirements2 { - VkStructureType sType; - void * pNext; - VkMemoryRequirements memoryRequirements; -} VkMemoryRequirements2; - -typedef struct VkSparseImageMemoryRequirements2 { - VkStructureType sType; - void * pNext; - VkSparseImageMemoryRequirements memoryRequirements; -} VkSparseImageMemoryRequirements2; - -typedef struct VkMemoryDedicatedRequirements { - VkStructureType sType; - void * pNext; - VkBool32 prefersDedicatedAllocation; - VkBool32 requiresDedicatedAllocation; -} VkMemoryDedicatedRequirements; - -typedef struct VkImageViewUsageCreateInfo { - VkStructureType sType; - const void * pNext; - VkImageUsageFlags usage; -} VkImageViewUsageCreateInfo; - -typedef struct VkSamplerYcbcrConversionCreateInfo { - VkStructureType sType; - const void * pNext; - VkFormat format; - VkSamplerYcbcrModelConversion ycbcrModel; - VkSamplerYcbcrRange ycbcrRange; - VkComponentMapping components; - VkChromaLocation xChromaOffset; - VkChromaLocation yChromaOffset; - VkFilter chromaFilter; - VkBool32 forceExplicitReconstruction; -} VkSamplerYcbcrConversionCreateInfo; - -typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { - VkStructureType sType; - void * pNext; - VkBool32 samplerYcbcrConversion; -} VkPhysicalDeviceSamplerYcbcrConversionFeatures; - -typedef struct VkProtectedSubmitInfo { - VkStructureType sType; - const void * pNext; - VkBool32 protectedSubmit; -} VkProtectedSubmitInfo; - -typedef struct VkPhysicalDeviceProtectedMemoryFeatures { - VkStructureType sType; - void * pNext; - VkBool32 protectedMemory; -} VkPhysicalDeviceProtectedMemoryFeatures; - -typedef struct VkPhysicalDeviceProtectedMemoryProperties { - VkStructureType sType; - void * pNext; - VkBool32 protectedNoFault; -} VkPhysicalDeviceProtectedMemoryProperties; - -typedef struct VkDeviceQueueInfo2 { - VkStructureType sType; - const void * pNext; - VkDeviceQueueCreateFlags flags; - uint32_t queueFamilyIndex; - uint32_t queueIndex; -} VkDeviceQueueInfo2; - -typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { - VkStructureType sType; - void * pNext; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; -} VkPhysicalDeviceSamplerFilterMinmaxProperties; - -typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { - VkStructureType sType; - void * pNext; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; -} VkPhysicalDeviceInlineUniformBlockFeatures; - -typedef struct VkPhysicalDeviceMaintenance3Properties { - VkStructureType sType; - void * pNext; - uint32_t maxPerSetDescriptors; - VkDeviceSize maxMemoryAllocationSize; -} VkPhysicalDeviceMaintenance3Properties; - -typedef struct VkPhysicalDeviceMaintenance4Features { - VkStructureType sType; - void * pNext; - VkBool32 maintenance4; -} VkPhysicalDeviceMaintenance4Features; - -typedef struct VkPhysicalDeviceMaintenance4Properties { - VkStructureType sType; - void * pNext; - VkDeviceSize maxBufferSize; -} VkPhysicalDeviceMaintenance4Properties; - -typedef struct VkDescriptorSetLayoutSupport { - VkStructureType sType; - void * pNext; - VkBool32 supported; -} VkDescriptorSetLayoutSupport; - -typedef struct VkPhysicalDeviceShaderDrawParametersFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderDrawParameters; -} VkPhysicalDeviceShaderDrawParametersFeatures; - -typedef struct VkPhysicalDeviceShaderDrawParametersFeatures VkPhysicalDeviceShaderDrawParameterFeatures; - -typedef struct VkPhysicalDeviceShaderFloat16Int8Features { - VkStructureType sType; - void * pNext; - VkBool32 shaderFloat16; - VkBool32 shaderInt8; -} VkPhysicalDeviceShaderFloat16Int8Features; - -typedef struct VkPhysicalDeviceFloatControlsProperties { - VkStructureType sType; - void * pNext; - VkShaderFloatControlsIndependence denormBehaviorIndependence; - VkShaderFloatControlsIndependence roundingModeIndependence; - VkBool32 shaderSignedZeroInfNanPreserveFloat16; - VkBool32 shaderSignedZeroInfNanPreserveFloat32; - VkBool32 shaderSignedZeroInfNanPreserveFloat64; - VkBool32 shaderDenormPreserveFloat16; - VkBool32 shaderDenormPreserveFloat32; - VkBool32 shaderDenormPreserveFloat64; - VkBool32 shaderDenormFlushToZeroFloat16; - VkBool32 shaderDenormFlushToZeroFloat32; - VkBool32 shaderDenormFlushToZeroFloat64; - VkBool32 shaderRoundingModeRTEFloat16; - VkBool32 shaderRoundingModeRTEFloat32; - VkBool32 shaderRoundingModeRTEFloat64; - VkBool32 shaderRoundingModeRTZFloat16; - VkBool32 shaderRoundingModeRTZFloat32; - VkBool32 shaderRoundingModeRTZFloat64; -} VkPhysicalDeviceFloatControlsProperties; - -typedef struct VkPhysicalDeviceHostQueryResetFeatures { - VkStructureType sType; - void * pNext; - VkBool32 hostQueryReset; -} VkPhysicalDeviceHostQueryResetFeatures; - -typedef struct VkPhysicalDeviceDescriptorIndexingFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderInputAttachmentArrayDynamicIndexing; - VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; - VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; - VkBool32 shaderUniformBufferArrayNonUniformIndexing; - VkBool32 shaderSampledImageArrayNonUniformIndexing; - VkBool32 shaderStorageBufferArrayNonUniformIndexing; - VkBool32 shaderStorageImageArrayNonUniformIndexing; - VkBool32 shaderInputAttachmentArrayNonUniformIndexing; - VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; - VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; - VkBool32 descriptorBindingUniformBufferUpdateAfterBind; - VkBool32 descriptorBindingSampledImageUpdateAfterBind; - VkBool32 descriptorBindingStorageImageUpdateAfterBind; - VkBool32 descriptorBindingStorageBufferUpdateAfterBind; - VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingUpdateUnusedWhilePending; - VkBool32 descriptorBindingPartiallyBound; - VkBool32 descriptorBindingVariableDescriptorCount; - VkBool32 runtimeDescriptorArray; -} VkPhysicalDeviceDescriptorIndexingFeatures; - -typedef struct VkPhysicalDeviceDescriptorIndexingProperties { - VkStructureType sType; - void * pNext; - uint32_t maxUpdateAfterBindDescriptorsInAllPools; - VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; - VkBool32 shaderSampledImageArrayNonUniformIndexingNative; - VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; - VkBool32 shaderStorageImageArrayNonUniformIndexingNative; - VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; - VkBool32 robustBufferAccessUpdateAfterBind; - VkBool32 quadDivergentImplicitLod; - uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; - uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; - uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; - uint32_t maxPerStageUpdateAfterBindResources; - uint32_t maxDescriptorSetUpdateAfterBindSamplers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindSampledImages; - uint32_t maxDescriptorSetUpdateAfterBindStorageImages; - uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; -} VkPhysicalDeviceDescriptorIndexingProperties; - -typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t bindingCount; - const VkDescriptorBindingFlags * pBindingFlags; -} VkDescriptorSetLayoutBindingFlagsCreateInfo; - -typedef struct VkAttachmentDescription2 { - VkStructureType sType; - const void * pNext; - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription2; - -typedef struct VkAttachmentReference2 { - VkStructureType sType; - const void * pNext; - uint32_t attachment; - VkImageLayout layout; - VkImageAspectFlags aspectMask; -} VkAttachmentReference2; - -typedef struct VkSubpassDescription2 { - VkStructureType sType; - const void * pNext; - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t viewMask; - uint32_t inputAttachmentCount; - const VkAttachmentReference2 * pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference2 * pColorAttachments; - const VkAttachmentReference2 * pResolveAttachments; - const VkAttachmentReference2 * pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t * pPreserveAttachments; -} VkSubpassDescription2; - -typedef struct VkSubpassDependency2 { - VkStructureType sType; - const void * pNext; - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; - int32_t viewOffset; -} VkSubpassDependency2; - -typedef struct VkRenderPassCreateInfo2 { - VkStructureType sType; - const void * pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription2 * pAttachments; - uint32_t subpassCount; - const VkSubpassDescription2 * pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency2 * pDependencies; - uint32_t correlatedViewMaskCount; - const uint32_t * pCorrelatedViewMasks; -} VkRenderPassCreateInfo2; - -typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { - VkStructureType sType; - void * pNext; - VkBool32 timelineSemaphore; -} VkPhysicalDeviceTimelineSemaphoreFeatures; - -typedef struct VkSemaphoreWaitInfo { - VkStructureType sType; - const void * pNext; - VkSemaphoreWaitFlags flags; - uint32_t semaphoreCount; - const VkSemaphore * pSemaphores; - const uint64_t * pValues; -} VkSemaphoreWaitInfo; - -typedef struct VkPhysicalDevice8BitStorageFeatures { - VkStructureType sType; - void * pNext; - VkBool32 storageBuffer8BitAccess; - VkBool32 uniformAndStorageBuffer8BitAccess; - VkBool32 storagePushConstant8; -} VkPhysicalDevice8BitStorageFeatures; - -typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { - VkStructureType sType; - void * pNext; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; -} VkPhysicalDeviceVulkanMemoryModelFeatures; - -typedef struct VkPhysicalDeviceShaderAtomicInt64Features { - VkStructureType sType; - void * pNext; - VkBool32 shaderBufferInt64Atomics; - VkBool32 shaderSharedInt64Atomics; -} VkPhysicalDeviceShaderAtomicInt64Features; - -typedef struct VkPhysicalDeviceDepthStencilResolveProperties { - VkStructureType sType; - void * pNext; - VkResolveModeFlags supportedDepthResolveModes; - VkResolveModeFlags supportedStencilResolveModes; - VkBool32 independentResolveNone; - VkBool32 independentResolve; -} VkPhysicalDeviceDepthStencilResolveProperties; - -typedef struct VkSubpassDescriptionDepthStencilResolve { - VkStructureType sType; - const void * pNext; - VkResolveModeFlagBits depthResolveMode; - VkResolveModeFlagBits stencilResolveMode; - const VkAttachmentReference2 * pDepthStencilResolveAttachment; -} VkSubpassDescriptionDepthStencilResolve; - -typedef struct VkImageStencilUsageCreateInfo { - VkStructureType sType; - const void * pNext; - VkImageUsageFlags stencilUsage; -} VkImageStencilUsageCreateInfo; - -typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { - VkStructureType sType; - void * pNext; - VkBool32 scalarBlockLayout; -} VkPhysicalDeviceScalarBlockLayoutFeatures; - -typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { - VkStructureType sType; - void * pNext; - VkBool32 uniformBufferStandardLayout; -} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; - -typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { - VkStructureType sType; - void * pNext; - VkBool32 bufferDeviceAddress; - VkBool32 bufferDeviceAddressCaptureReplay; - VkBool32 bufferDeviceAddressMultiDevice; -} VkPhysicalDeviceBufferDeviceAddressFeatures; - -typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { - VkStructureType sType; - void * pNext; - VkBool32 imagelessFramebuffer; -} VkPhysicalDeviceImagelessFramebufferFeatures; - -typedef struct VkFramebufferAttachmentImageInfo { - VkStructureType sType; - const void * pNext; - VkImageCreateFlags flags; - VkImageUsageFlags usage; - uint32_t width; - uint32_t height; - uint32_t layerCount; - uint32_t viewFormatCount; - const VkFormat * pViewFormats; -} VkFramebufferAttachmentImageInfo; - -typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { - VkStructureType sType; - void * pNext; - VkBool32 textureCompressionASTC_HDR; -} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; - -typedef struct VkPipelineCreationFeedback { - VkPipelineCreationFeedbackFlags flags; - uint64_t duration; -} VkPipelineCreationFeedback; - -typedef struct VkPipelineCreationFeedbackCreateInfo { - VkStructureType sType; - const void * pNext; - VkPipelineCreationFeedback * pPipelineCreationFeedback; - uint32_t pipelineStageCreationFeedbackCount; - VkPipelineCreationFeedback * pPipelineStageCreationFeedbacks; -} VkPipelineCreationFeedbackCreateInfo; - -typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { - VkStructureType sType; - void * pNext; - VkBool32 separateDepthStencilLayouts; -} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; - -typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderDemoteToHelperInvocation; -} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; - -typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { - VkStructureType sType; - void * pNext; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; -} VkPhysicalDeviceTexelBufferAlignmentProperties; - -typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { - VkStructureType sType; - void * pNext; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; -} VkPhysicalDeviceSubgroupSizeControlFeatures; - -typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { - VkStructureType sType; - void * pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; -} VkPhysicalDeviceSubgroupSizeControlProperties; - -typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { - VkStructureType sType; - void * pNext; - VkBool32 pipelineCreationCacheControl; -} VkPhysicalDevicePipelineCreationCacheControlFeatures; - -typedef struct VkPhysicalDeviceVulkan11Features { - VkStructureType sType; - void * pNext; - VkBool32 storageBuffer16BitAccess; - VkBool32 uniformAndStorageBuffer16BitAccess; - VkBool32 storagePushConstant16; - VkBool32 storageInputOutput16; - VkBool32 multiview; - VkBool32 multiviewGeometryShader; - VkBool32 multiviewTessellationShader; - VkBool32 variablePointersStorageBuffer; - VkBool32 variablePointers; - VkBool32 protectedMemory; - VkBool32 samplerYcbcrConversion; - VkBool32 shaderDrawParameters; -} VkPhysicalDeviceVulkan11Features; - -typedef struct VkPhysicalDeviceVulkan11Properties { - VkStructureType sType; - void * pNext; - uint8_t deviceUUID [ VK_UUID_SIZE ]; - uint8_t driverUUID [ VK_UUID_SIZE ]; - uint8_t deviceLUID [ VK_LUID_SIZE ]; - uint32_t deviceNodeMask; - VkBool32 deviceLUIDValid; - uint32_t subgroupSize; - VkShaderStageFlags subgroupSupportedStages; - VkSubgroupFeatureFlags subgroupSupportedOperations; - VkBool32 subgroupQuadOperationsInAllStages; - VkPointClippingBehavior pointClippingBehavior; - uint32_t maxMultiviewViewCount; - uint32_t maxMultiviewInstanceIndex; - VkBool32 protectedNoFault; - uint32_t maxPerSetDescriptors; - VkDeviceSize maxMemoryAllocationSize; -} VkPhysicalDeviceVulkan11Properties; - -typedef struct VkPhysicalDeviceVulkan12Features { - VkStructureType sType; - void * pNext; - VkBool32 samplerMirrorClampToEdge; - VkBool32 drawIndirectCount; - VkBool32 storageBuffer8BitAccess; - VkBool32 uniformAndStorageBuffer8BitAccess; - VkBool32 storagePushConstant8; - VkBool32 shaderBufferInt64Atomics; - VkBool32 shaderSharedInt64Atomics; - VkBool32 shaderFloat16; - VkBool32 shaderInt8; - VkBool32 descriptorIndexing; - VkBool32 shaderInputAttachmentArrayDynamicIndexing; - VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; - VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; - VkBool32 shaderUniformBufferArrayNonUniformIndexing; - VkBool32 shaderSampledImageArrayNonUniformIndexing; - VkBool32 shaderStorageBufferArrayNonUniformIndexing; - VkBool32 shaderStorageImageArrayNonUniformIndexing; - VkBool32 shaderInputAttachmentArrayNonUniformIndexing; - VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; - VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; - VkBool32 descriptorBindingUniformBufferUpdateAfterBind; - VkBool32 descriptorBindingSampledImageUpdateAfterBind; - VkBool32 descriptorBindingStorageImageUpdateAfterBind; - VkBool32 descriptorBindingStorageBufferUpdateAfterBind; - VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingUpdateUnusedWhilePending; - VkBool32 descriptorBindingPartiallyBound; - VkBool32 descriptorBindingVariableDescriptorCount; - VkBool32 runtimeDescriptorArray; - VkBool32 samplerFilterMinmax; - VkBool32 scalarBlockLayout; - VkBool32 imagelessFramebuffer; - VkBool32 uniformBufferStandardLayout; - VkBool32 shaderSubgroupExtendedTypes; - VkBool32 separateDepthStencilLayouts; - VkBool32 hostQueryReset; - VkBool32 timelineSemaphore; - VkBool32 bufferDeviceAddress; - VkBool32 bufferDeviceAddressCaptureReplay; - VkBool32 bufferDeviceAddressMultiDevice; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; - VkBool32 shaderOutputViewportIndex; - VkBool32 shaderOutputLayer; - VkBool32 subgroupBroadcastDynamicId; -} VkPhysicalDeviceVulkan12Features; - -typedef struct VkPhysicalDeviceVulkan12Properties { - VkStructureType sType; - void * pNext; - VkDriverId driverID; - char driverName [ VK_MAX_DRIVER_NAME_SIZE ]; - char driverInfo [ VK_MAX_DRIVER_INFO_SIZE ]; - VkConformanceVersion conformanceVersion; - VkShaderFloatControlsIndependence denormBehaviorIndependence; - VkShaderFloatControlsIndependence roundingModeIndependence; - VkBool32 shaderSignedZeroInfNanPreserveFloat16; - VkBool32 shaderSignedZeroInfNanPreserveFloat32; - VkBool32 shaderSignedZeroInfNanPreserveFloat64; - VkBool32 shaderDenormPreserveFloat16; - VkBool32 shaderDenormPreserveFloat32; - VkBool32 shaderDenormPreserveFloat64; - VkBool32 shaderDenormFlushToZeroFloat16; - VkBool32 shaderDenormFlushToZeroFloat32; - VkBool32 shaderDenormFlushToZeroFloat64; - VkBool32 shaderRoundingModeRTEFloat16; - VkBool32 shaderRoundingModeRTEFloat32; - VkBool32 shaderRoundingModeRTEFloat64; - VkBool32 shaderRoundingModeRTZFloat16; - VkBool32 shaderRoundingModeRTZFloat32; - VkBool32 shaderRoundingModeRTZFloat64; - uint32_t maxUpdateAfterBindDescriptorsInAllPools; - VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; - VkBool32 shaderSampledImageArrayNonUniformIndexingNative; - VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; - VkBool32 shaderStorageImageArrayNonUniformIndexingNative; - VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; - VkBool32 robustBufferAccessUpdateAfterBind; - VkBool32 quadDivergentImplicitLod; - uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; - uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; - uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; - uint32_t maxPerStageUpdateAfterBindResources; - uint32_t maxDescriptorSetUpdateAfterBindSamplers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindSampledImages; - uint32_t maxDescriptorSetUpdateAfterBindStorageImages; - uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; - VkResolveModeFlags supportedDepthResolveModes; - VkResolveModeFlags supportedStencilResolveModes; - VkBool32 independentResolveNone; - VkBool32 independentResolve; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; - uint64_t maxTimelineSemaphoreValueDifference; - VkSampleCountFlags framebufferIntegerColorSampleCounts; -} VkPhysicalDeviceVulkan12Properties; - -typedef struct VkPhysicalDeviceVulkan13Features { - VkStructureType sType; - void * pNext; - VkBool32 robustImageAccess; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; - VkBool32 pipelineCreationCacheControl; - VkBool32 privateData; - VkBool32 shaderDemoteToHelperInvocation; - VkBool32 shaderTerminateInvocation; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; - VkBool32 synchronization2; - VkBool32 textureCompressionASTC_HDR; - VkBool32 shaderZeroInitializeWorkgroupMemory; - VkBool32 dynamicRendering; - VkBool32 shaderIntegerDotProduct; - VkBool32 maintenance4; -} VkPhysicalDeviceVulkan13Features; - -typedef struct VkPhysicalDeviceVulkan13Properties { - VkStructureType sType; - void * pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; - uint32_t maxInlineUniformTotalSize; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize maxBufferSize; -} VkPhysicalDeviceVulkan13Properties; - -typedef struct VkPhysicalDeviceToolProperties { - VkStructureType sType; - void * pNext; - char name [ VK_MAX_EXTENSION_NAME_SIZE ]; - char version [ VK_MAX_EXTENSION_NAME_SIZE ]; - VkToolPurposeFlags purposes; - char description [ VK_MAX_DESCRIPTION_SIZE ]; - char layer [ VK_MAX_EXTENSION_NAME_SIZE ]; -} VkPhysicalDeviceToolProperties; - -typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderZeroInitializeWorkgroupMemory; -} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; - -typedef struct VkPhysicalDeviceImageRobustnessFeatures { - VkStructureType sType; - void * pNext; - VkBool32 robustImageAccess; -} VkPhysicalDeviceImageRobustnessFeatures; - -typedef struct VkBufferCopy2 { - VkStructureType sType; - const void * pNext; - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy2; - -typedef struct VkImageCopy2 { - VkStructureType sType; - const void * pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy2; - -typedef struct VkImageBlit2 { - VkStructureType sType; - const void * pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets [2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets [2]; -} VkImageBlit2; - -typedef struct VkBufferImageCopy2 { - VkStructureType sType; - const void * pNext; - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy2; - -typedef struct VkImageResolve2 { - VkStructureType sType; - const void * pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve2; - -typedef struct VkCopyBufferInfo2 { - VkStructureType sType; - const void * pNext; - VkBuffer srcBuffer; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferCopy2 * pRegions; -} VkCopyBufferInfo2; - -typedef struct VkCopyImageInfo2 { - VkStructureType sType; - const void * pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageCopy2 * pRegions; -} VkCopyImageInfo2; - -typedef struct VkBlitImageInfo2 { - VkStructureType sType; - const void * pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageBlit2 * pRegions; - VkFilter filter; -} VkBlitImageInfo2; - -typedef struct VkCopyBufferToImageInfo2 { - VkStructureType sType; - const void * pNext; - VkBuffer srcBuffer; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkBufferImageCopy2 * pRegions; -} VkCopyBufferToImageInfo2; - -typedef struct VkCopyImageToBufferInfo2 { - VkStructureType sType; - const void * pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferImageCopy2 * pRegions; -} VkCopyImageToBufferInfo2; - -typedef struct VkResolveImageInfo2 { - VkStructureType sType; - const void * pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageResolve2 * pRegions; -} VkResolveImageInfo2; - -typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderTerminateInvocation; -} VkPhysicalDeviceShaderTerminateInvocationFeatures; - -typedef struct VkMemoryBarrier2 { - VkStructureType sType; - const void * pNext; - VkPipelineStageFlags2 srcStageMask; - VkAccessFlags2 srcAccessMask; - VkPipelineStageFlags2 dstStageMask; - VkAccessFlags2 dstAccessMask; -} VkMemoryBarrier2; - -typedef struct VkImageMemoryBarrier2 { - VkStructureType sType; - const void * pNext; - VkPipelineStageFlags2 srcStageMask; - VkAccessFlags2 srcAccessMask; - VkPipelineStageFlags2 dstStageMask; - VkAccessFlags2 dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier2; - -typedef struct VkBufferMemoryBarrier2 { - VkStructureType sType; - const void * pNext; - VkPipelineStageFlags2 srcStageMask; - VkAccessFlags2 srcAccessMask; - VkPipelineStageFlags2 dstStageMask; - VkAccessFlags2 dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier2; - -typedef struct VkDependencyInfo { - VkStructureType sType; - const void * pNext; - VkDependencyFlags dependencyFlags; - uint32_t memoryBarrierCount; - const VkMemoryBarrier2 * pMemoryBarriers; - uint32_t bufferMemoryBarrierCount; - const VkBufferMemoryBarrier2 * pBufferMemoryBarriers; - uint32_t imageMemoryBarrierCount; - const VkImageMemoryBarrier2 * pImageMemoryBarriers; -} VkDependencyInfo; - -typedef struct VkSemaphoreSubmitInfo { - VkStructureType sType; - const void * pNext; - VkSemaphore semaphore; - uint64_t value; - VkPipelineStageFlags2 stageMask; - uint32_t deviceIndex; -} VkSemaphoreSubmitInfo; - -typedef struct VkSubmitInfo2 { - VkStructureType sType; - const void * pNext; - VkSubmitFlags flags; - uint32_t waitSemaphoreInfoCount; - const VkSemaphoreSubmitInfo * pWaitSemaphoreInfos; - uint32_t commandBufferInfoCount; - const VkCommandBufferSubmitInfo * pCommandBufferInfos; - uint32_t signalSemaphoreInfoCount; - const VkSemaphoreSubmitInfo * pSignalSemaphoreInfos; -} VkSubmitInfo2; - -typedef struct VkPhysicalDeviceSynchronization2Features { - VkStructureType sType; - void * pNext; - VkBool32 synchronization2; -} VkPhysicalDeviceSynchronization2Features; - -typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { - VkStructureType sType; - void * pNext; - VkBool32 shaderIntegerDotProduct; -} VkPhysicalDeviceShaderIntegerDotProductFeatures; - -typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { - VkStructureType sType; - void * pNext; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; -} VkPhysicalDeviceShaderIntegerDotProductProperties; - -typedef struct VkFormatProperties3 { - VkStructureType sType; - void * pNext; - VkFormatFeatureFlags2 linearTilingFeatures; - VkFormatFeatureFlags2 optimalTilingFeatures; - VkFormatFeatureFlags2 bufferFeatures; -} VkFormatProperties3; - -typedef struct VkRenderingInfo { - VkStructureType sType; - const void * pNext; - VkRenderingFlags flags; - VkRect2D renderArea; - uint32_t layerCount; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkRenderingAttachmentInfo * pColorAttachments; - const VkRenderingAttachmentInfo * pDepthAttachment; - const VkRenderingAttachmentInfo * pStencilAttachment; -} VkRenderingInfo; - -typedef struct VkPhysicalDeviceDynamicRenderingFeatures { - VkStructureType sType; - void * pNext; - VkBool32 dynamicRendering; -} VkPhysicalDeviceDynamicRenderingFeatures; - -typedef struct VkCommandBufferInheritanceRenderingInfo { - VkStructureType sType; - const void * pNext; - VkRenderingFlags flags; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat * pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; - VkSampleCountFlagBits rasterizationSamples; -} VkCommandBufferInheritanceRenderingInfo; - -typedef struct VkPhysicalDeviceProperties { - uint32_t apiVersion; - uint32_t driverVersion; - uint32_t vendorID; - uint32_t deviceID; - VkPhysicalDeviceType deviceType; - char deviceName [ VK_MAX_PHYSICAL_DEVICE_NAME_SIZE ]; - uint8_t pipelineCacheUUID [ VK_UUID_SIZE ]; - VkPhysicalDeviceLimits limits; - VkPhysicalDeviceSparseProperties sparseProperties; -} VkPhysicalDeviceProperties; - -typedef struct VkDeviceCreateInfo { - VkStructureType sType; - const void * pNext; - VkDeviceCreateFlags flags; - uint32_t queueCreateInfoCount; - const VkDeviceQueueCreateInfo * pQueueCreateInfos; - uint32_t enabledLayerCount; - const char * const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char * const* ppEnabledExtensionNames; - const VkPhysicalDeviceFeatures * pEnabledFeatures; -} VkDeviceCreateInfo; - -typedef struct VkPhysicalDeviceMemoryProperties { - uint32_t memoryTypeCount; - VkMemoryType memoryTypes [ VK_MAX_MEMORY_TYPES ]; - uint32_t memoryHeapCount; - VkMemoryHeap memoryHeaps [ VK_MAX_MEMORY_HEAPS ]; -} VkPhysicalDeviceMemoryProperties; - -typedef struct VkPhysicalDeviceProperties2 { - VkStructureType sType; - void * pNext; - VkPhysicalDeviceProperties properties; -} VkPhysicalDeviceProperties2; - -typedef struct VkPhysicalDeviceMemoryProperties2 { - VkStructureType sType; - void * pNext; - VkPhysicalDeviceMemoryProperties memoryProperties; -} VkPhysicalDeviceMemoryProperties2; - -typedef struct VkFramebufferAttachmentsCreateInfo { - VkStructureType sType; - const void * pNext; - uint32_t attachmentImageInfoCount; - const VkFramebufferAttachmentImageInfo * pAttachmentImageInfos; -} VkFramebufferAttachmentsCreateInfo; - - - -#define VK_VERSION_1_0 1 -GLAD_API_CALL int GLAD_VK_VERSION_1_0; -#define VK_VERSION_1_1 1 -GLAD_API_CALL int GLAD_VK_VERSION_1_1; -#define VK_VERSION_1_2 1 -GLAD_API_CALL int GLAD_VK_VERSION_1_2; -#define VK_VERSION_1_3 1 -GLAD_API_CALL int GLAD_VK_VERSION_1_3; -#define VK_EXT_debug_report 1 -GLAD_API_CALL int GLAD_VK_EXT_debug_report; -#define VK_KHR_portability_enumeration 1 -GLAD_API_CALL int GLAD_VK_KHR_portability_enumeration; -#define VK_KHR_surface 1 -GLAD_API_CALL int GLAD_VK_KHR_surface; -#define VK_KHR_swapchain 1 -GLAD_API_CALL int GLAD_VK_KHR_swapchain; - - -typedef VkResult (GLAD_API_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR * pAcquireInfo, uint32_t * pImageIndex); -typedef VkResult (GLAD_API_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t * pImageIndex); -typedef VkResult (GLAD_API_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo * pAllocateInfo, VkCommandBuffer * pCommandBuffers); -typedef VkResult (GLAD_API_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo * pAllocateInfo, VkDescriptorSet * pDescriptorSets); -typedef VkResult (GLAD_API_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo * pAllocateInfo, const VkAllocationCallbacks * pAllocator, VkDeviceMemory * pMemory); -typedef VkResult (GLAD_API_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo * pBeginInfo); -typedef VkResult (GLAD_API_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef VkResult (GLAD_API_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo * pBindInfos); -typedef VkResult (GLAD_API_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef VkResult (GLAD_API_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo * pBindInfos); -typedef void (GLAD_API_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); -typedef void (GLAD_API_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo * pRenderPassBegin, VkSubpassContents contents); -typedef void (GLAD_API_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo * pRenderPassBegin, const VkSubpassBeginInfo * pSubpassBeginInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo * pRenderingInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t * pDynamicOffsets); -typedef void (GLAD_API_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); -typedef void (GLAD_API_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); -typedef void (GLAD_API_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer * pBuffers, const VkDeviceSize * pOffsets); -typedef void (GLAD_API_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer * pBuffers, const VkDeviceSize * pOffsets, const VkDeviceSize * pSizes, const VkDeviceSize * pStrides); -typedef void (GLAD_API_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit * pRegions, VkFilter filter); -typedef void (GLAD_API_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2 * pBlitImageInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment * pAttachments, uint32_t rectCount, const VkClearRect * pRects); -typedef void (GLAD_API_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue * pColor, uint32_t rangeCount, const VkImageSubresourceRange * pRanges); -typedef void (GLAD_API_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue * pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange * pRanges); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 * pCopyBufferInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2 * pCopyImageInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); -typedef void (GLAD_API_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef void (GLAD_API_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef void (GLAD_API_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); -typedef void (GLAD_API_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (GLAD_API_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); -typedef void (GLAD_API_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); -typedef void (GLAD_API_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo * pSubpassEndInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); -typedef void (GLAD_API_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers); -typedef void (GLAD_API_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); -typedef void (GLAD_API_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); -typedef void (GLAD_API_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo * pSubpassBeginInfo, const VkSubpassEndInfo * pSubpassEndInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers); -typedef void (GLAD_API_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo * pDependencyInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void * pValues); -typedef void (GLAD_API_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (GLAD_API_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); -typedef void (GLAD_API_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); -typedef void (GLAD_API_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * pResolveImageInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants [4]); -typedef void (GLAD_API_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo * pDependencyInfo); -typedef void (GLAD_API_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); -typedef void (GLAD_API_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); -typedef void (GLAD_API_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); -typedef void (GLAD_API_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D * pScissors); -typedef void (GLAD_API_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D * pScissors); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport * pViewports); -typedef void (GLAD_API_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport * pViewports); -typedef void (GLAD_API_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void * pData); -typedef void (GLAD_API_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent * pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers); -typedef void (GLAD_API_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent * pEvents, const VkDependencyInfo * pDependencyInfos); -typedef void (GLAD_API_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); -typedef void (GLAD_API_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBuffer * pBuffer); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBufferView * pView); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkCommandPool * pCommandPool); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDebugReportCallbackEXT * pCallback); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorPool * pDescriptorPool); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorSetLayout * pSetLayout); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDevice * pDevice); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkEvent * pEvent); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFence * pFence); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFramebuffer * pFramebuffer); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImage * pImage); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImageView * pView); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkInstance * pInstance); -typedef VkResult (GLAD_API_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineCache * pPipelineCache); -typedef VkResult (GLAD_API_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineLayout * pPipelineLayout); -typedef VkResult (GLAD_API_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPrivateDataSlot * pPrivateDataSlot); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkQueryPool * pQueryPool); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkRenderPass * pRenderPass); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2 * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkRenderPass * pRenderPass); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSampler * pSampler); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSamplerYcbcrConversion * pYcbcrConversion); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSemaphore * pSemaphore); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule * pShaderModule); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSwapchainKHR * pSwapchain); -typedef void (GLAD_API_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char * pLayerPrefix, const char * pMessage); -typedef void (GLAD_API_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks * pAllocator); -typedef VkResult (GLAD_API_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); -typedef VkResult (GLAD_API_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char * pLayerName, uint32_t * pPropertyCount, VkExtensionProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t * pPropertyCount, VkLayerProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char * pLayerName, uint32_t * pPropertyCount, VkExtensionProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t * pPropertyCount, VkLayerProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t * pApiVersion); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t * pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t * pPhysicalDeviceCount, VkPhysicalDevice * pPhysicalDevices); -typedef VkResult (GLAD_API_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges); -typedef void (GLAD_API_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers); -typedef VkResult (GLAD_API_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets); -typedef void (GLAD_API_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks * pAllocator); -typedef VkDeviceAddress (GLAD_API_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo * pInfo); -typedef void (GLAD_API_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2 * pInfo, VkMemoryRequirements2 * pMemoryRequirements); -typedef uint64_t (GLAD_API_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo * pInfo); -typedef void (GLAD_API_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, VkDescriptorSetLayoutSupport * pSupport); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements * pInfo, VkMemoryRequirements2 * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags * pPeerMemoryFeatures); -typedef VkResult (GLAD_API_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities); -typedef VkResult (GLAD_API_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR * pModes); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements * pInfo, VkMemoryRequirements2 * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements * pInfo, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize * pCommittedMemoryInBytes); -typedef uint64_t (GLAD_API_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo * pInfo); -typedef PFN_vkVoidFunction (GLAD_API_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char * pName); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue * pQueue); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2 * pQueueInfo, VkQueue * pQueue); -typedef VkResult (GLAD_API_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); -typedef VkResult (GLAD_API_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); -typedef void (GLAD_API_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2 * pInfo, VkMemoryRequirements2 * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements * pSparseMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2 * pInfo, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource * pSubresource, VkSubresourceLayout * pLayout); -typedef PFN_vkVoidFunction (GLAD_API_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char * pName); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo, VkExternalBufferProperties * pExternalBufferProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo, VkExternalFenceProperties * pExternalFenceProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo, VkExternalSemaphoreProperties * pExternalSemaphoreProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures * pFeatures); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 * pFeatures); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties * pFormatProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2 * pFormatProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties * pImageFormatProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo, VkImageFormatProperties2 * pImageFormatProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties * pMemoryProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 * pMemoryProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pRectCount, VkRect2D * pRects); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties * pProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 * pProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t * pQueueFamilyPropertyCount, VkQueueFamilyProperties * pQueueFamilyProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t * pQueueFamilyPropertyCount, VkQueueFamilyProperties2 * pQueueFamilyProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t * pPropertyCount, VkSparseImageFormatProperties * pProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo, uint32_t * pPropertyCount, VkSparseImageFormatProperties2 * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR * pSurfaceCapabilities); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pSurfaceFormatCount, VkSurfaceFormatKHR * pSurfaceFormats); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pPresentModeCount, VkPresentModeKHR * pPresentModes); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 * pSupported); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t * pToolCount, VkPhysicalDeviceToolProperties * pToolProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t * pDataSize, void * pData); -typedef void (GLAD_API_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t * pData); -typedef VkResult (GLAD_API_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void * pData, VkDeviceSize stride, VkQueryResultFlags flags); -typedef void (GLAD_API_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D * pGranularity); -typedef VkResult (GLAD_API_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t * pValue); -typedef VkResult (GLAD_API_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t * pSwapchainImageCount, VkImage * pSwapchainImages); -typedef VkResult (GLAD_API_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges); -typedef VkResult (GLAD_API_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void ** ppData); -typedef VkResult (GLAD_API_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache * pSrcCaches); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo * pBindInfo, VkFence fence); -typedef VkResult (GLAD_API_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR * pPresentInfo); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo * pSubmits, VkFence fence); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 * pSubmits, VkFence fence); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); -typedef VkResult (GLAD_API_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); -typedef VkResult (GLAD_API_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); -typedef VkResult (GLAD_API_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); -typedef VkResult (GLAD_API_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); -typedef VkResult (GLAD_API_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence * pFences); -typedef void (GLAD_API_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); -typedef VkResult (GLAD_API_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); -typedef VkResult (GLAD_API_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); -typedef VkResult (GLAD_API_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo * pSignalInfo); -typedef void (GLAD_API_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); -typedef void (GLAD_API_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); -typedef void (GLAD_API_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void * pData); -typedef void (GLAD_API_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet * pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet * pDescriptorCopies); -typedef VkResult (GLAD_API_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence * pFences, VkBool32 waitAll, uint64_t timeout); -typedef VkResult (GLAD_API_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo * pWaitInfo, uint64_t timeout); - -GLAD_API_CALL PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR; -#define vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR -GLAD_API_CALL PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR; -#define vkAcquireNextImageKHR glad_vkAcquireNextImageKHR -GLAD_API_CALL PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers; -#define vkAllocateCommandBuffers glad_vkAllocateCommandBuffers -GLAD_API_CALL PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets; -#define vkAllocateDescriptorSets glad_vkAllocateDescriptorSets -GLAD_API_CALL PFN_vkAllocateMemory glad_vkAllocateMemory; -#define vkAllocateMemory glad_vkAllocateMemory -GLAD_API_CALL PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer; -#define vkBeginCommandBuffer glad_vkBeginCommandBuffer -GLAD_API_CALL PFN_vkBindBufferMemory glad_vkBindBufferMemory; -#define vkBindBufferMemory glad_vkBindBufferMemory -GLAD_API_CALL PFN_vkBindBufferMemory2 glad_vkBindBufferMemory2; -#define vkBindBufferMemory2 glad_vkBindBufferMemory2 -GLAD_API_CALL PFN_vkBindImageMemory glad_vkBindImageMemory; -#define vkBindImageMemory glad_vkBindImageMemory -GLAD_API_CALL PFN_vkBindImageMemory2 glad_vkBindImageMemory2; -#define vkBindImageMemory2 glad_vkBindImageMemory2 -GLAD_API_CALL PFN_vkCmdBeginQuery glad_vkCmdBeginQuery; -#define vkCmdBeginQuery glad_vkCmdBeginQuery -GLAD_API_CALL PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass; -#define vkCmdBeginRenderPass glad_vkCmdBeginRenderPass -GLAD_API_CALL PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2; -#define vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 -GLAD_API_CALL PFN_vkCmdBeginRendering glad_vkCmdBeginRendering; -#define vkCmdBeginRendering glad_vkCmdBeginRendering -GLAD_API_CALL PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets; -#define vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets -GLAD_API_CALL PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer; -#define vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer -GLAD_API_CALL PFN_vkCmdBindPipeline glad_vkCmdBindPipeline; -#define vkCmdBindPipeline glad_vkCmdBindPipeline -GLAD_API_CALL PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers; -#define vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers -GLAD_API_CALL PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2; -#define vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 -GLAD_API_CALL PFN_vkCmdBlitImage glad_vkCmdBlitImage; -#define vkCmdBlitImage glad_vkCmdBlitImage -GLAD_API_CALL PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2; -#define vkCmdBlitImage2 glad_vkCmdBlitImage2 -GLAD_API_CALL PFN_vkCmdClearAttachments glad_vkCmdClearAttachments; -#define vkCmdClearAttachments glad_vkCmdClearAttachments -GLAD_API_CALL PFN_vkCmdClearColorImage glad_vkCmdClearColorImage; -#define vkCmdClearColorImage glad_vkCmdClearColorImage -GLAD_API_CALL PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage; -#define vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage -GLAD_API_CALL PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer; -#define vkCmdCopyBuffer glad_vkCmdCopyBuffer -GLAD_API_CALL PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2; -#define vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 -GLAD_API_CALL PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage; -#define vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage -GLAD_API_CALL PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2; -#define vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 -GLAD_API_CALL PFN_vkCmdCopyImage glad_vkCmdCopyImage; -#define vkCmdCopyImage glad_vkCmdCopyImage -GLAD_API_CALL PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2; -#define vkCmdCopyImage2 glad_vkCmdCopyImage2 -GLAD_API_CALL PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer; -#define vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer -GLAD_API_CALL PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2; -#define vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 -GLAD_API_CALL PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults; -#define vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults -GLAD_API_CALL PFN_vkCmdDispatch glad_vkCmdDispatch; -#define vkCmdDispatch glad_vkCmdDispatch -GLAD_API_CALL PFN_vkCmdDispatchBase glad_vkCmdDispatchBase; -#define vkCmdDispatchBase glad_vkCmdDispatchBase -GLAD_API_CALL PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect; -#define vkCmdDispatchIndirect glad_vkCmdDispatchIndirect -GLAD_API_CALL PFN_vkCmdDraw glad_vkCmdDraw; -#define vkCmdDraw glad_vkCmdDraw -GLAD_API_CALL PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed; -#define vkCmdDrawIndexed glad_vkCmdDrawIndexed -GLAD_API_CALL PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect; -#define vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect -GLAD_API_CALL PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount; -#define vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount -GLAD_API_CALL PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect; -#define vkCmdDrawIndirect glad_vkCmdDrawIndirect -GLAD_API_CALL PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount; -#define vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount -GLAD_API_CALL PFN_vkCmdEndQuery glad_vkCmdEndQuery; -#define vkCmdEndQuery glad_vkCmdEndQuery -GLAD_API_CALL PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass; -#define vkCmdEndRenderPass glad_vkCmdEndRenderPass -GLAD_API_CALL PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2; -#define vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 -GLAD_API_CALL PFN_vkCmdEndRendering glad_vkCmdEndRendering; -#define vkCmdEndRendering glad_vkCmdEndRendering -GLAD_API_CALL PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands; -#define vkCmdExecuteCommands glad_vkCmdExecuteCommands -GLAD_API_CALL PFN_vkCmdFillBuffer glad_vkCmdFillBuffer; -#define vkCmdFillBuffer glad_vkCmdFillBuffer -GLAD_API_CALL PFN_vkCmdNextSubpass glad_vkCmdNextSubpass; -#define vkCmdNextSubpass glad_vkCmdNextSubpass -GLAD_API_CALL PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2; -#define vkCmdNextSubpass2 glad_vkCmdNextSubpass2 -GLAD_API_CALL PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier; -#define vkCmdPipelineBarrier glad_vkCmdPipelineBarrier -GLAD_API_CALL PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2; -#define vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 -GLAD_API_CALL PFN_vkCmdPushConstants glad_vkCmdPushConstants; -#define vkCmdPushConstants glad_vkCmdPushConstants -GLAD_API_CALL PFN_vkCmdResetEvent glad_vkCmdResetEvent; -#define vkCmdResetEvent glad_vkCmdResetEvent -GLAD_API_CALL PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2; -#define vkCmdResetEvent2 glad_vkCmdResetEvent2 -GLAD_API_CALL PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool; -#define vkCmdResetQueryPool glad_vkCmdResetQueryPool -GLAD_API_CALL PFN_vkCmdResolveImage glad_vkCmdResolveImage; -#define vkCmdResolveImage glad_vkCmdResolveImage -GLAD_API_CALL PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2; -#define vkCmdResolveImage2 glad_vkCmdResolveImage2 -GLAD_API_CALL PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants; -#define vkCmdSetBlendConstants glad_vkCmdSetBlendConstants -GLAD_API_CALL PFN_vkCmdSetCullMode glad_vkCmdSetCullMode; -#define vkCmdSetCullMode glad_vkCmdSetCullMode -GLAD_API_CALL PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias; -#define vkCmdSetDepthBias glad_vkCmdSetDepthBias -GLAD_API_CALL PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable; -#define vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable -GLAD_API_CALL PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds; -#define vkCmdSetDepthBounds glad_vkCmdSetDepthBounds -GLAD_API_CALL PFN_vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable; -#define vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable -GLAD_API_CALL PFN_vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp; -#define vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp -GLAD_API_CALL PFN_vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable; -#define vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable -GLAD_API_CALL PFN_vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable; -#define vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable -GLAD_API_CALL PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask; -#define vkCmdSetDeviceMask glad_vkCmdSetDeviceMask -GLAD_API_CALL PFN_vkCmdSetEvent glad_vkCmdSetEvent; -#define vkCmdSetEvent glad_vkCmdSetEvent -GLAD_API_CALL PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2; -#define vkCmdSetEvent2 glad_vkCmdSetEvent2 -GLAD_API_CALL PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace; -#define vkCmdSetFrontFace glad_vkCmdSetFrontFace -GLAD_API_CALL PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth; -#define vkCmdSetLineWidth glad_vkCmdSetLineWidth -GLAD_API_CALL PFN_vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable; -#define vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable -GLAD_API_CALL PFN_vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology; -#define vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology -GLAD_API_CALL PFN_vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable; -#define vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable -GLAD_API_CALL PFN_vkCmdSetScissor glad_vkCmdSetScissor; -#define vkCmdSetScissor glad_vkCmdSetScissor -GLAD_API_CALL PFN_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount; -#define vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount -GLAD_API_CALL PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask; -#define vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask -GLAD_API_CALL PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp; -#define vkCmdSetStencilOp glad_vkCmdSetStencilOp -GLAD_API_CALL PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference; -#define vkCmdSetStencilReference glad_vkCmdSetStencilReference -GLAD_API_CALL PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable; -#define vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable -GLAD_API_CALL PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask; -#define vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask -GLAD_API_CALL PFN_vkCmdSetViewport glad_vkCmdSetViewport; -#define vkCmdSetViewport glad_vkCmdSetViewport -GLAD_API_CALL PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount; -#define vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount -GLAD_API_CALL PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer; -#define vkCmdUpdateBuffer glad_vkCmdUpdateBuffer -GLAD_API_CALL PFN_vkCmdWaitEvents glad_vkCmdWaitEvents; -#define vkCmdWaitEvents glad_vkCmdWaitEvents -GLAD_API_CALL PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2; -#define vkCmdWaitEvents2 glad_vkCmdWaitEvents2 -GLAD_API_CALL PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp; -#define vkCmdWriteTimestamp glad_vkCmdWriteTimestamp -GLAD_API_CALL PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2; -#define vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 -GLAD_API_CALL PFN_vkCreateBuffer glad_vkCreateBuffer; -#define vkCreateBuffer glad_vkCreateBuffer -GLAD_API_CALL PFN_vkCreateBufferView glad_vkCreateBufferView; -#define vkCreateBufferView glad_vkCreateBufferView -GLAD_API_CALL PFN_vkCreateCommandPool glad_vkCreateCommandPool; -#define vkCreateCommandPool glad_vkCreateCommandPool -GLAD_API_CALL PFN_vkCreateComputePipelines glad_vkCreateComputePipelines; -#define vkCreateComputePipelines glad_vkCreateComputePipelines -GLAD_API_CALL PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT; -#define vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT -GLAD_API_CALL PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool; -#define vkCreateDescriptorPool glad_vkCreateDescriptorPool -GLAD_API_CALL PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout; -#define vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout -GLAD_API_CALL PFN_vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate; -#define vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate -GLAD_API_CALL PFN_vkCreateDevice glad_vkCreateDevice; -#define vkCreateDevice glad_vkCreateDevice -GLAD_API_CALL PFN_vkCreateEvent glad_vkCreateEvent; -#define vkCreateEvent glad_vkCreateEvent -GLAD_API_CALL PFN_vkCreateFence glad_vkCreateFence; -#define vkCreateFence glad_vkCreateFence -GLAD_API_CALL PFN_vkCreateFramebuffer glad_vkCreateFramebuffer; -#define vkCreateFramebuffer glad_vkCreateFramebuffer -GLAD_API_CALL PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines; -#define vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines -GLAD_API_CALL PFN_vkCreateImage glad_vkCreateImage; -#define vkCreateImage glad_vkCreateImage -GLAD_API_CALL PFN_vkCreateImageView glad_vkCreateImageView; -#define vkCreateImageView glad_vkCreateImageView -GLAD_API_CALL PFN_vkCreateInstance glad_vkCreateInstance; -#define vkCreateInstance glad_vkCreateInstance -GLAD_API_CALL PFN_vkCreatePipelineCache glad_vkCreatePipelineCache; -#define vkCreatePipelineCache glad_vkCreatePipelineCache -GLAD_API_CALL PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout; -#define vkCreatePipelineLayout glad_vkCreatePipelineLayout -GLAD_API_CALL PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot; -#define vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot -GLAD_API_CALL PFN_vkCreateQueryPool glad_vkCreateQueryPool; -#define vkCreateQueryPool glad_vkCreateQueryPool -GLAD_API_CALL PFN_vkCreateRenderPass glad_vkCreateRenderPass; -#define vkCreateRenderPass glad_vkCreateRenderPass -GLAD_API_CALL PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2; -#define vkCreateRenderPass2 glad_vkCreateRenderPass2 -GLAD_API_CALL PFN_vkCreateSampler glad_vkCreateSampler; -#define vkCreateSampler glad_vkCreateSampler -GLAD_API_CALL PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion; -#define vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion -GLAD_API_CALL PFN_vkCreateSemaphore glad_vkCreateSemaphore; -#define vkCreateSemaphore glad_vkCreateSemaphore -GLAD_API_CALL PFN_vkCreateShaderModule glad_vkCreateShaderModule; -#define vkCreateShaderModule glad_vkCreateShaderModule -GLAD_API_CALL PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR; -#define vkCreateSwapchainKHR glad_vkCreateSwapchainKHR -GLAD_API_CALL PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT; -#define vkDebugReportMessageEXT glad_vkDebugReportMessageEXT -GLAD_API_CALL PFN_vkDestroyBuffer glad_vkDestroyBuffer; -#define vkDestroyBuffer glad_vkDestroyBuffer -GLAD_API_CALL PFN_vkDestroyBufferView glad_vkDestroyBufferView; -#define vkDestroyBufferView glad_vkDestroyBufferView -GLAD_API_CALL PFN_vkDestroyCommandPool glad_vkDestroyCommandPool; -#define vkDestroyCommandPool glad_vkDestroyCommandPool -GLAD_API_CALL PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT; -#define vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT -GLAD_API_CALL PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool; -#define vkDestroyDescriptorPool glad_vkDestroyDescriptorPool -GLAD_API_CALL PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout; -#define vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout -GLAD_API_CALL PFN_vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate; -#define vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate -GLAD_API_CALL PFN_vkDestroyDevice glad_vkDestroyDevice; -#define vkDestroyDevice glad_vkDestroyDevice -GLAD_API_CALL PFN_vkDestroyEvent glad_vkDestroyEvent; -#define vkDestroyEvent glad_vkDestroyEvent -GLAD_API_CALL PFN_vkDestroyFence glad_vkDestroyFence; -#define vkDestroyFence glad_vkDestroyFence -GLAD_API_CALL PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer; -#define vkDestroyFramebuffer glad_vkDestroyFramebuffer -GLAD_API_CALL PFN_vkDestroyImage glad_vkDestroyImage; -#define vkDestroyImage glad_vkDestroyImage -GLAD_API_CALL PFN_vkDestroyImageView glad_vkDestroyImageView; -#define vkDestroyImageView glad_vkDestroyImageView -GLAD_API_CALL PFN_vkDestroyInstance glad_vkDestroyInstance; -#define vkDestroyInstance glad_vkDestroyInstance -GLAD_API_CALL PFN_vkDestroyPipeline glad_vkDestroyPipeline; -#define vkDestroyPipeline glad_vkDestroyPipeline -GLAD_API_CALL PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache; -#define vkDestroyPipelineCache glad_vkDestroyPipelineCache -GLAD_API_CALL PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout; -#define vkDestroyPipelineLayout glad_vkDestroyPipelineLayout -GLAD_API_CALL PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot; -#define vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot -GLAD_API_CALL PFN_vkDestroyQueryPool glad_vkDestroyQueryPool; -#define vkDestroyQueryPool glad_vkDestroyQueryPool -GLAD_API_CALL PFN_vkDestroyRenderPass glad_vkDestroyRenderPass; -#define vkDestroyRenderPass glad_vkDestroyRenderPass -GLAD_API_CALL PFN_vkDestroySampler glad_vkDestroySampler; -#define vkDestroySampler glad_vkDestroySampler -GLAD_API_CALL PFN_vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion; -#define vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion -GLAD_API_CALL PFN_vkDestroySemaphore glad_vkDestroySemaphore; -#define vkDestroySemaphore glad_vkDestroySemaphore -GLAD_API_CALL PFN_vkDestroyShaderModule glad_vkDestroyShaderModule; -#define vkDestroyShaderModule glad_vkDestroyShaderModule -GLAD_API_CALL PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR; -#define vkDestroySurfaceKHR glad_vkDestroySurfaceKHR -GLAD_API_CALL PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR; -#define vkDestroySwapchainKHR glad_vkDestroySwapchainKHR -GLAD_API_CALL PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle; -#define vkDeviceWaitIdle glad_vkDeviceWaitIdle -GLAD_API_CALL PFN_vkEndCommandBuffer glad_vkEndCommandBuffer; -#define vkEndCommandBuffer glad_vkEndCommandBuffer -GLAD_API_CALL PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties; -#define vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties -GLAD_API_CALL PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties; -#define vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties -GLAD_API_CALL PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties; -#define vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties -GLAD_API_CALL PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties; -#define vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties -GLAD_API_CALL PFN_vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion; -#define vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion -GLAD_API_CALL PFN_vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups; -#define vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups -GLAD_API_CALL PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices; -#define vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices -GLAD_API_CALL PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges; -#define vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges -GLAD_API_CALL PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers; -#define vkFreeCommandBuffers glad_vkFreeCommandBuffers -GLAD_API_CALL PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets; -#define vkFreeDescriptorSets glad_vkFreeDescriptorSets -GLAD_API_CALL PFN_vkFreeMemory glad_vkFreeMemory; -#define vkFreeMemory glad_vkFreeMemory -GLAD_API_CALL PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress; -#define vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress -GLAD_API_CALL PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements; -#define vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements -GLAD_API_CALL PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2; -#define vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 -GLAD_API_CALL PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress; -#define vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress -GLAD_API_CALL PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport; -#define vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport -GLAD_API_CALL PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements; -#define vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements -GLAD_API_CALL PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures; -#define vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures -GLAD_API_CALL PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR; -#define vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR -GLAD_API_CALL PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR; -#define vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR -GLAD_API_CALL PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements; -#define vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements -GLAD_API_CALL PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements; -#define vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements -GLAD_API_CALL PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment; -#define vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment -GLAD_API_CALL PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress; -#define vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress -GLAD_API_CALL PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr; -#define vkGetDeviceProcAddr glad_vkGetDeviceProcAddr -GLAD_API_CALL PFN_vkGetDeviceQueue glad_vkGetDeviceQueue; -#define vkGetDeviceQueue glad_vkGetDeviceQueue -GLAD_API_CALL PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2; -#define vkGetDeviceQueue2 glad_vkGetDeviceQueue2 -GLAD_API_CALL PFN_vkGetEventStatus glad_vkGetEventStatus; -#define vkGetEventStatus glad_vkGetEventStatus -GLAD_API_CALL PFN_vkGetFenceStatus glad_vkGetFenceStatus; -#define vkGetFenceStatus glad_vkGetFenceStatus -GLAD_API_CALL PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements; -#define vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements -GLAD_API_CALL PFN_vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2; -#define vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2 -GLAD_API_CALL PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements; -#define vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements -GLAD_API_CALL PFN_vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2; -#define vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2 -GLAD_API_CALL PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout; -#define vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout -GLAD_API_CALL PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr; -#define vkGetInstanceProcAddr glad_vkGetInstanceProcAddr -GLAD_API_CALL PFN_vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties; -#define vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties; -#define vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties; -#define vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures; -#define vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures -GLAD_API_CALL PFN_vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2; -#define vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2 -GLAD_API_CALL PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties; -#define vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2; -#define vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2 -GLAD_API_CALL PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties; -#define vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2; -#define vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2 -GLAD_API_CALL PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties; -#define vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2; -#define vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2 -GLAD_API_CALL PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR; -#define vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR -GLAD_API_CALL PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties; -#define vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2; -#define vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2 -GLAD_API_CALL PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties; -#define vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2; -#define vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2 -GLAD_API_CALL PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties; -#define vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties -GLAD_API_CALL PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2; -#define vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2 -GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR; -#define vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR -GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR; -#define vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR -GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR; -#define vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR -GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR; -#define vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR -GLAD_API_CALL PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties; -#define vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties -GLAD_API_CALL PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData; -#define vkGetPipelineCacheData glad_vkGetPipelineCacheData -GLAD_API_CALL PFN_vkGetPrivateData glad_vkGetPrivateData; -#define vkGetPrivateData glad_vkGetPrivateData -GLAD_API_CALL PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults; -#define vkGetQueryPoolResults glad_vkGetQueryPoolResults -GLAD_API_CALL PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity; -#define vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity -GLAD_API_CALL PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue; -#define vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue -GLAD_API_CALL PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR; -#define vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR -GLAD_API_CALL PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges; -#define vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges -GLAD_API_CALL PFN_vkMapMemory glad_vkMapMemory; -#define vkMapMemory glad_vkMapMemory -GLAD_API_CALL PFN_vkMergePipelineCaches glad_vkMergePipelineCaches; -#define vkMergePipelineCaches glad_vkMergePipelineCaches -GLAD_API_CALL PFN_vkQueueBindSparse glad_vkQueueBindSparse; -#define vkQueueBindSparse glad_vkQueueBindSparse -GLAD_API_CALL PFN_vkQueuePresentKHR glad_vkQueuePresentKHR; -#define vkQueuePresentKHR glad_vkQueuePresentKHR -GLAD_API_CALL PFN_vkQueueSubmit glad_vkQueueSubmit; -#define vkQueueSubmit glad_vkQueueSubmit -GLAD_API_CALL PFN_vkQueueSubmit2 glad_vkQueueSubmit2; -#define vkQueueSubmit2 glad_vkQueueSubmit2 -GLAD_API_CALL PFN_vkQueueWaitIdle glad_vkQueueWaitIdle; -#define vkQueueWaitIdle glad_vkQueueWaitIdle -GLAD_API_CALL PFN_vkResetCommandBuffer glad_vkResetCommandBuffer; -#define vkResetCommandBuffer glad_vkResetCommandBuffer -GLAD_API_CALL PFN_vkResetCommandPool glad_vkResetCommandPool; -#define vkResetCommandPool glad_vkResetCommandPool -GLAD_API_CALL PFN_vkResetDescriptorPool glad_vkResetDescriptorPool; -#define vkResetDescriptorPool glad_vkResetDescriptorPool -GLAD_API_CALL PFN_vkResetEvent glad_vkResetEvent; -#define vkResetEvent glad_vkResetEvent -GLAD_API_CALL PFN_vkResetFences glad_vkResetFences; -#define vkResetFences glad_vkResetFences -GLAD_API_CALL PFN_vkResetQueryPool glad_vkResetQueryPool; -#define vkResetQueryPool glad_vkResetQueryPool -GLAD_API_CALL PFN_vkSetEvent glad_vkSetEvent; -#define vkSetEvent glad_vkSetEvent -GLAD_API_CALL PFN_vkSetPrivateData glad_vkSetPrivateData; -#define vkSetPrivateData glad_vkSetPrivateData -GLAD_API_CALL PFN_vkSignalSemaphore glad_vkSignalSemaphore; -#define vkSignalSemaphore glad_vkSignalSemaphore -GLAD_API_CALL PFN_vkTrimCommandPool glad_vkTrimCommandPool; -#define vkTrimCommandPool glad_vkTrimCommandPool -GLAD_API_CALL PFN_vkUnmapMemory glad_vkUnmapMemory; -#define vkUnmapMemory glad_vkUnmapMemory -GLAD_API_CALL PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate; -#define vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate -GLAD_API_CALL PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets; -#define vkUpdateDescriptorSets glad_vkUpdateDescriptorSets -GLAD_API_CALL PFN_vkWaitForFences glad_vkWaitForFences; -#define vkWaitForFences glad_vkWaitForFences -GLAD_API_CALL PFN_vkWaitSemaphores glad_vkWaitSemaphores; -#define vkWaitSemaphores glad_vkWaitSemaphores - - - - - -GLAD_API_CALL int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load); - - - -#ifdef __cplusplus -} -#endif -#endif - -/* Source */ -#ifdef GLAD_VULKAN_IMPLEMENTATION -#include -#include -#include - -#ifndef GLAD_IMPL_UTIL_C_ -#define GLAD_IMPL_UTIL_C_ - -#ifdef _MSC_VER -#define GLAD_IMPL_UTIL_SSCANF sscanf_s -#else -#define GLAD_IMPL_UTIL_SSCANF sscanf -#endif - -#endif /* GLAD_IMPL_UTIL_C_ */ - -#ifdef __cplusplus -extern "C" { -#endif - - - -int GLAD_VK_VERSION_1_0 = 0; -int GLAD_VK_VERSION_1_1 = 0; -int GLAD_VK_VERSION_1_2 = 0; -int GLAD_VK_VERSION_1_3 = 0; -int GLAD_VK_EXT_debug_report = 0; -int GLAD_VK_KHR_portability_enumeration = 0; -int GLAD_VK_KHR_surface = 0; -int GLAD_VK_KHR_swapchain = 0; - - - -PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR = NULL; -PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR = NULL; -PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers = NULL; -PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets = NULL; -PFN_vkAllocateMemory glad_vkAllocateMemory = NULL; -PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer = NULL; -PFN_vkBindBufferMemory glad_vkBindBufferMemory = NULL; -PFN_vkBindBufferMemory2 glad_vkBindBufferMemory2 = NULL; -PFN_vkBindImageMemory glad_vkBindImageMemory = NULL; -PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL; -PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL; -PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL; -PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 = NULL; -PFN_vkCmdBeginRendering glad_vkCmdBeginRendering = NULL; -PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL; -PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL; -PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL; -PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL; -PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 = NULL; -PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL; -PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2 = NULL; -PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL; -PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL; -PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL; -PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL; -PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 = NULL; -PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL; -PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 = NULL; -PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL; -PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2 = NULL; -PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL; -PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 = NULL; -PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL; -PFN_vkCmdDispatch glad_vkCmdDispatch = NULL; -PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL; -PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL; -PFN_vkCmdDraw glad_vkCmdDraw = NULL; -PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL; -PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL; -PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount = NULL; -PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL; -PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount = NULL; -PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL; -PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL; -PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 = NULL; -PFN_vkCmdEndRendering glad_vkCmdEndRendering = NULL; -PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL; -PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL; -PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL; -PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2 = NULL; -PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL; -PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 = NULL; -PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL; -PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL; -PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2 = NULL; -PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL; -PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL; -PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2 = NULL; -PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL; -PFN_vkCmdSetCullMode glad_vkCmdSetCullMode = NULL; -PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL; -PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable = NULL; -PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL; -PFN_vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable = NULL; -PFN_vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp = NULL; -PFN_vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable = NULL; -PFN_vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable = NULL; -PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL; -PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL; -PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2 = NULL; -PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace = NULL; -PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL; -PFN_vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable = NULL; -PFN_vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology = NULL; -PFN_vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable = NULL; -PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL; -PFN_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount = NULL; -PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL; -PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp = NULL; -PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL; -PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable = NULL; -PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL; -PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL; -PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount = NULL; -PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL; -PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL; -PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2 = NULL; -PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL; -PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 = NULL; -PFN_vkCreateBuffer glad_vkCreateBuffer = NULL; -PFN_vkCreateBufferView glad_vkCreateBufferView = NULL; -PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL; -PFN_vkCreateComputePipelines glad_vkCreateComputePipelines = NULL; -PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT = NULL; -PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool = NULL; -PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout = NULL; -PFN_vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate = NULL; -PFN_vkCreateDevice glad_vkCreateDevice = NULL; -PFN_vkCreateEvent glad_vkCreateEvent = NULL; -PFN_vkCreateFence glad_vkCreateFence = NULL; -PFN_vkCreateFramebuffer glad_vkCreateFramebuffer = NULL; -PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines = NULL; -PFN_vkCreateImage glad_vkCreateImage = NULL; -PFN_vkCreateImageView glad_vkCreateImageView = NULL; -PFN_vkCreateInstance glad_vkCreateInstance = NULL; -PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL; -PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL; -PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot = NULL; -PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL; -PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL; -PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2 = NULL; -PFN_vkCreateSampler glad_vkCreateSampler = NULL; -PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL; -PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL; -PFN_vkCreateShaderModule glad_vkCreateShaderModule = NULL; -PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR = NULL; -PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT = NULL; -PFN_vkDestroyBuffer glad_vkDestroyBuffer = NULL; -PFN_vkDestroyBufferView glad_vkDestroyBufferView = NULL; -PFN_vkDestroyCommandPool glad_vkDestroyCommandPool = NULL; -PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT = NULL; -PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool = NULL; -PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout = NULL; -PFN_vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate = NULL; -PFN_vkDestroyDevice glad_vkDestroyDevice = NULL; -PFN_vkDestroyEvent glad_vkDestroyEvent = NULL; -PFN_vkDestroyFence glad_vkDestroyFence = NULL; -PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer = NULL; -PFN_vkDestroyImage glad_vkDestroyImage = NULL; -PFN_vkDestroyImageView glad_vkDestroyImageView = NULL; -PFN_vkDestroyInstance glad_vkDestroyInstance = NULL; -PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL; -PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL; -PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL; -PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot = NULL; -PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL; -PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL; -PFN_vkDestroySampler glad_vkDestroySampler = NULL; -PFN_vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion = NULL; -PFN_vkDestroySemaphore glad_vkDestroySemaphore = NULL; -PFN_vkDestroyShaderModule glad_vkDestroyShaderModule = NULL; -PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR = NULL; -PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR = NULL; -PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle = NULL; -PFN_vkEndCommandBuffer glad_vkEndCommandBuffer = NULL; -PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties = NULL; -PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties = NULL; -PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties = NULL; -PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties = NULL; -PFN_vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion = NULL; -PFN_vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups = NULL; -PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices = NULL; -PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL; -PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL; -PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL; -PFN_vkFreeMemory glad_vkFreeMemory = NULL; -PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress = NULL; -PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL; -PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL; -PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress = NULL; -PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL; -PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements = NULL; -PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL; -PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL; -PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL; -PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements = NULL; -PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements = NULL; -PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL; -PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress = NULL; -PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL; -PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL; -PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL; -PFN_vkGetEventStatus glad_vkGetEventStatus = NULL; -PFN_vkGetFenceStatus glad_vkGetFenceStatus = NULL; -PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements = NULL; -PFN_vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2 = NULL; -PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements = NULL; -PFN_vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2 = NULL; -PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout = NULL; -PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr = NULL; -PFN_vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties = NULL; -PFN_vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties = NULL; -PFN_vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties = NULL; -PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures = NULL; -PFN_vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2 = NULL; -PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties = NULL; -PFN_vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2 = NULL; -PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties = NULL; -PFN_vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2 = NULL; -PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties = NULL; -PFN_vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2 = NULL; -PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR = NULL; -PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties = NULL; -PFN_vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2 = NULL; -PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties = NULL; -PFN_vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2 = NULL; -PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties = NULL; -PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = NULL; -PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = NULL; -PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL; -PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL; -PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL; -PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties = NULL; -PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL; -PFN_vkGetPrivateData glad_vkGetPrivateData = NULL; -PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL; -PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL; -PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue = NULL; -PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL; -PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL; -PFN_vkMapMemory glad_vkMapMemory = NULL; -PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL; -PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL; -PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL; -PFN_vkQueueSubmit glad_vkQueueSubmit = NULL; -PFN_vkQueueSubmit2 glad_vkQueueSubmit2 = NULL; -PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL; -PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL; -PFN_vkResetCommandPool glad_vkResetCommandPool = NULL; -PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL; -PFN_vkResetEvent glad_vkResetEvent = NULL; -PFN_vkResetFences glad_vkResetFences = NULL; -PFN_vkResetQueryPool glad_vkResetQueryPool = NULL; -PFN_vkSetEvent glad_vkSetEvent = NULL; -PFN_vkSetPrivateData glad_vkSetPrivateData = NULL; -PFN_vkSignalSemaphore glad_vkSignalSemaphore = NULL; -PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL; -PFN_vkUnmapMemory glad_vkUnmapMemory = NULL; -PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL; -PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL; -PFN_vkWaitForFences glad_vkWaitForFences = NULL; -PFN_vkWaitSemaphores glad_vkWaitSemaphores = NULL; - - -static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_VERSION_1_0) return; - glad_vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load(userptr, "vkAllocateCommandBuffers"); - glad_vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load(userptr, "vkAllocateDescriptorSets"); - glad_vkAllocateMemory = (PFN_vkAllocateMemory) load(userptr, "vkAllocateMemory"); - glad_vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load(userptr, "vkBeginCommandBuffer"); - glad_vkBindBufferMemory = (PFN_vkBindBufferMemory) load(userptr, "vkBindBufferMemory"); - glad_vkBindImageMemory = (PFN_vkBindImageMemory) load(userptr, "vkBindImageMemory"); - glad_vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load(userptr, "vkCmdBeginQuery"); - glad_vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load(userptr, "vkCmdBeginRenderPass"); - glad_vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load(userptr, "vkCmdBindDescriptorSets"); - glad_vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load(userptr, "vkCmdBindIndexBuffer"); - glad_vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load(userptr, "vkCmdBindPipeline"); - glad_vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load(userptr, "vkCmdBindVertexBuffers"); - glad_vkCmdBlitImage = (PFN_vkCmdBlitImage) load(userptr, "vkCmdBlitImage"); - glad_vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load(userptr, "vkCmdClearAttachments"); - glad_vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load(userptr, "vkCmdClearColorImage"); - glad_vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load(userptr, "vkCmdClearDepthStencilImage"); - glad_vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load(userptr, "vkCmdCopyBuffer"); - glad_vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load(userptr, "vkCmdCopyBufferToImage"); - glad_vkCmdCopyImage = (PFN_vkCmdCopyImage) load(userptr, "vkCmdCopyImage"); - glad_vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load(userptr, "vkCmdCopyImageToBuffer"); - glad_vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load(userptr, "vkCmdCopyQueryPoolResults"); - glad_vkCmdDispatch = (PFN_vkCmdDispatch) load(userptr, "vkCmdDispatch"); - glad_vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load(userptr, "vkCmdDispatchIndirect"); - glad_vkCmdDraw = (PFN_vkCmdDraw) load(userptr, "vkCmdDraw"); - glad_vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load(userptr, "vkCmdDrawIndexed"); - glad_vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load(userptr, "vkCmdDrawIndexedIndirect"); - glad_vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load(userptr, "vkCmdDrawIndirect"); - glad_vkCmdEndQuery = (PFN_vkCmdEndQuery) load(userptr, "vkCmdEndQuery"); - glad_vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load(userptr, "vkCmdEndRenderPass"); - glad_vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load(userptr, "vkCmdExecuteCommands"); - glad_vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load(userptr, "vkCmdFillBuffer"); - glad_vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load(userptr, "vkCmdNextSubpass"); - glad_vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load(userptr, "vkCmdPipelineBarrier"); - glad_vkCmdPushConstants = (PFN_vkCmdPushConstants) load(userptr, "vkCmdPushConstants"); - glad_vkCmdResetEvent = (PFN_vkCmdResetEvent) load(userptr, "vkCmdResetEvent"); - glad_vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load(userptr, "vkCmdResetQueryPool"); - glad_vkCmdResolveImage = (PFN_vkCmdResolveImage) load(userptr, "vkCmdResolveImage"); - glad_vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load(userptr, "vkCmdSetBlendConstants"); - glad_vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load(userptr, "vkCmdSetDepthBias"); - glad_vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load(userptr, "vkCmdSetDepthBounds"); - glad_vkCmdSetEvent = (PFN_vkCmdSetEvent) load(userptr, "vkCmdSetEvent"); - glad_vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load(userptr, "vkCmdSetLineWidth"); - glad_vkCmdSetScissor = (PFN_vkCmdSetScissor) load(userptr, "vkCmdSetScissor"); - glad_vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load(userptr, "vkCmdSetStencilCompareMask"); - glad_vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load(userptr, "vkCmdSetStencilReference"); - glad_vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load(userptr, "vkCmdSetStencilWriteMask"); - glad_vkCmdSetViewport = (PFN_vkCmdSetViewport) load(userptr, "vkCmdSetViewport"); - glad_vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load(userptr, "vkCmdUpdateBuffer"); - glad_vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load(userptr, "vkCmdWaitEvents"); - glad_vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load(userptr, "vkCmdWriteTimestamp"); - glad_vkCreateBuffer = (PFN_vkCreateBuffer) load(userptr, "vkCreateBuffer"); - glad_vkCreateBufferView = (PFN_vkCreateBufferView) load(userptr, "vkCreateBufferView"); - glad_vkCreateCommandPool = (PFN_vkCreateCommandPool) load(userptr, "vkCreateCommandPool"); - glad_vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load(userptr, "vkCreateComputePipelines"); - glad_vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load(userptr, "vkCreateDescriptorPool"); - glad_vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load(userptr, "vkCreateDescriptorSetLayout"); - glad_vkCreateDevice = (PFN_vkCreateDevice) load(userptr, "vkCreateDevice"); - glad_vkCreateEvent = (PFN_vkCreateEvent) load(userptr, "vkCreateEvent"); - glad_vkCreateFence = (PFN_vkCreateFence) load(userptr, "vkCreateFence"); - glad_vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load(userptr, "vkCreateFramebuffer"); - glad_vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load(userptr, "vkCreateGraphicsPipelines"); - glad_vkCreateImage = (PFN_vkCreateImage) load(userptr, "vkCreateImage"); - glad_vkCreateImageView = (PFN_vkCreateImageView) load(userptr, "vkCreateImageView"); - glad_vkCreateInstance = (PFN_vkCreateInstance) load(userptr, "vkCreateInstance"); - glad_vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load(userptr, "vkCreatePipelineCache"); - glad_vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load(userptr, "vkCreatePipelineLayout"); - glad_vkCreateQueryPool = (PFN_vkCreateQueryPool) load(userptr, "vkCreateQueryPool"); - glad_vkCreateRenderPass = (PFN_vkCreateRenderPass) load(userptr, "vkCreateRenderPass"); - glad_vkCreateSampler = (PFN_vkCreateSampler) load(userptr, "vkCreateSampler"); - glad_vkCreateSemaphore = (PFN_vkCreateSemaphore) load(userptr, "vkCreateSemaphore"); - glad_vkCreateShaderModule = (PFN_vkCreateShaderModule) load(userptr, "vkCreateShaderModule"); - glad_vkDestroyBuffer = (PFN_vkDestroyBuffer) load(userptr, "vkDestroyBuffer"); - glad_vkDestroyBufferView = (PFN_vkDestroyBufferView) load(userptr, "vkDestroyBufferView"); - glad_vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load(userptr, "vkDestroyCommandPool"); - glad_vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load(userptr, "vkDestroyDescriptorPool"); - glad_vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load(userptr, "vkDestroyDescriptorSetLayout"); - glad_vkDestroyDevice = (PFN_vkDestroyDevice) load(userptr, "vkDestroyDevice"); - glad_vkDestroyEvent = (PFN_vkDestroyEvent) load(userptr, "vkDestroyEvent"); - glad_vkDestroyFence = (PFN_vkDestroyFence) load(userptr, "vkDestroyFence"); - glad_vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load(userptr, "vkDestroyFramebuffer"); - glad_vkDestroyImage = (PFN_vkDestroyImage) load(userptr, "vkDestroyImage"); - glad_vkDestroyImageView = (PFN_vkDestroyImageView) load(userptr, "vkDestroyImageView"); - glad_vkDestroyInstance = (PFN_vkDestroyInstance) load(userptr, "vkDestroyInstance"); - glad_vkDestroyPipeline = (PFN_vkDestroyPipeline) load(userptr, "vkDestroyPipeline"); - glad_vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load(userptr, "vkDestroyPipelineCache"); - glad_vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load(userptr, "vkDestroyPipelineLayout"); - glad_vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load(userptr, "vkDestroyQueryPool"); - glad_vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load(userptr, "vkDestroyRenderPass"); - glad_vkDestroySampler = (PFN_vkDestroySampler) load(userptr, "vkDestroySampler"); - glad_vkDestroySemaphore = (PFN_vkDestroySemaphore) load(userptr, "vkDestroySemaphore"); - glad_vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load(userptr, "vkDestroyShaderModule"); - glad_vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load(userptr, "vkDeviceWaitIdle"); - glad_vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load(userptr, "vkEndCommandBuffer"); - glad_vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load(userptr, "vkEnumerateDeviceExtensionProperties"); - glad_vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load(userptr, "vkEnumerateDeviceLayerProperties"); - glad_vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load(userptr, "vkEnumerateInstanceExtensionProperties"); - glad_vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load(userptr, "vkEnumerateInstanceLayerProperties"); - glad_vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load(userptr, "vkEnumeratePhysicalDevices"); - glad_vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load(userptr, "vkFlushMappedMemoryRanges"); - glad_vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load(userptr, "vkFreeCommandBuffers"); - glad_vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load(userptr, "vkFreeDescriptorSets"); - glad_vkFreeMemory = (PFN_vkFreeMemory) load(userptr, "vkFreeMemory"); - glad_vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load(userptr, "vkGetBufferMemoryRequirements"); - glad_vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load(userptr, "vkGetDeviceMemoryCommitment"); - glad_vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load(userptr, "vkGetDeviceProcAddr"); - glad_vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load(userptr, "vkGetDeviceQueue"); - glad_vkGetEventStatus = (PFN_vkGetEventStatus) load(userptr, "vkGetEventStatus"); - glad_vkGetFenceStatus = (PFN_vkGetFenceStatus) load(userptr, "vkGetFenceStatus"); - glad_vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load(userptr, "vkGetImageMemoryRequirements"); - glad_vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load(userptr, "vkGetImageSparseMemoryRequirements"); - glad_vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load(userptr, "vkGetImageSubresourceLayout"); - glad_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load(userptr, "vkGetInstanceProcAddr"); - glad_vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load(userptr, "vkGetPhysicalDeviceFeatures"); - glad_vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load(userptr, "vkGetPhysicalDeviceFormatProperties"); - glad_vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load(userptr, "vkGetPhysicalDeviceImageFormatProperties"); - glad_vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load(userptr, "vkGetPhysicalDeviceMemoryProperties"); - glad_vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load(userptr, "vkGetPhysicalDeviceProperties"); - glad_vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties"); - glad_vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties"); - glad_vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load(userptr, "vkGetPipelineCacheData"); - glad_vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load(userptr, "vkGetQueryPoolResults"); - glad_vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load(userptr, "vkGetRenderAreaGranularity"); - glad_vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load(userptr, "vkInvalidateMappedMemoryRanges"); - glad_vkMapMemory = (PFN_vkMapMemory) load(userptr, "vkMapMemory"); - glad_vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load(userptr, "vkMergePipelineCaches"); - glad_vkQueueBindSparse = (PFN_vkQueueBindSparse) load(userptr, "vkQueueBindSparse"); - glad_vkQueueSubmit = (PFN_vkQueueSubmit) load(userptr, "vkQueueSubmit"); - glad_vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load(userptr, "vkQueueWaitIdle"); - glad_vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load(userptr, "vkResetCommandBuffer"); - glad_vkResetCommandPool = (PFN_vkResetCommandPool) load(userptr, "vkResetCommandPool"); - glad_vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load(userptr, "vkResetDescriptorPool"); - glad_vkResetEvent = (PFN_vkResetEvent) load(userptr, "vkResetEvent"); - glad_vkResetFences = (PFN_vkResetFences) load(userptr, "vkResetFences"); - glad_vkSetEvent = (PFN_vkSetEvent) load(userptr, "vkSetEvent"); - glad_vkUnmapMemory = (PFN_vkUnmapMemory) load(userptr, "vkUnmapMemory"); - glad_vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load(userptr, "vkUpdateDescriptorSets"); - glad_vkWaitForFences = (PFN_vkWaitForFences) load(userptr, "vkWaitForFences"); -} -static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_VERSION_1_1) return; - glad_vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load(userptr, "vkBindBufferMemory2"); - glad_vkBindImageMemory2 = (PFN_vkBindImageMemory2) load(userptr, "vkBindImageMemory2"); - glad_vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load(userptr, "vkCmdDispatchBase"); - glad_vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load(userptr, "vkCmdSetDeviceMask"); - glad_vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load(userptr, "vkCreateDescriptorUpdateTemplate"); - glad_vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load(userptr, "vkCreateSamplerYcbcrConversion"); - glad_vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load(userptr, "vkDestroyDescriptorUpdateTemplate"); - glad_vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load(userptr, "vkDestroySamplerYcbcrConversion"); - glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion"); - glad_vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load(userptr, "vkEnumeratePhysicalDeviceGroups"); - glad_vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load(userptr, "vkGetBufferMemoryRequirements2"); - glad_vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load(userptr, "vkGetDescriptorSetLayoutSupport"); - glad_vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load(userptr, "vkGetDeviceGroupPeerMemoryFeatures"); - glad_vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load(userptr, "vkGetDeviceQueue2"); - glad_vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load(userptr, "vkGetImageMemoryRequirements2"); - glad_vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load(userptr, "vkGetImageSparseMemoryRequirements2"); - glad_vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load(userptr, "vkGetPhysicalDeviceExternalBufferProperties"); - glad_vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load(userptr, "vkGetPhysicalDeviceExternalFenceProperties"); - glad_vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load(userptr, "vkGetPhysicalDeviceExternalSemaphoreProperties"); - glad_vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load(userptr, "vkGetPhysicalDeviceFeatures2"); - glad_vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load(userptr, "vkGetPhysicalDeviceFormatProperties2"); - glad_vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceImageFormatProperties2"); - glad_vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load(userptr, "vkGetPhysicalDeviceMemoryProperties2"); - glad_vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load(userptr, "vkGetPhysicalDeviceProperties2"); - glad_vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties2"); - glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties2"); - glad_vkTrimCommandPool = (PFN_vkTrimCommandPool) load(userptr, "vkTrimCommandPool"); - glad_vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load(userptr, "vkUpdateDescriptorSetWithTemplate"); -} -static void glad_vk_load_VK_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_VERSION_1_2) return; - glad_vkCmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2) load(userptr, "vkCmdBeginRenderPass2"); - glad_vkCmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount) load(userptr, "vkCmdDrawIndexedIndirectCount"); - glad_vkCmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount) load(userptr, "vkCmdDrawIndirectCount"); - glad_vkCmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2) load(userptr, "vkCmdEndRenderPass2"); - glad_vkCmdNextSubpass2 = (PFN_vkCmdNextSubpass2) load(userptr, "vkCmdNextSubpass2"); - glad_vkCreateRenderPass2 = (PFN_vkCreateRenderPass2) load(userptr, "vkCreateRenderPass2"); - glad_vkGetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress) load(userptr, "vkGetBufferDeviceAddress"); - glad_vkGetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress) load(userptr, "vkGetBufferOpaqueCaptureAddress"); - glad_vkGetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress) load(userptr, "vkGetDeviceMemoryOpaqueCaptureAddress"); - glad_vkGetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue) load(userptr, "vkGetSemaphoreCounterValue"); - glad_vkResetQueryPool = (PFN_vkResetQueryPool) load(userptr, "vkResetQueryPool"); - glad_vkSignalSemaphore = (PFN_vkSignalSemaphore) load(userptr, "vkSignalSemaphore"); - glad_vkWaitSemaphores = (PFN_vkWaitSemaphores) load(userptr, "vkWaitSemaphores"); -} -static void glad_vk_load_VK_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_VERSION_1_3) return; - glad_vkCmdBeginRendering = (PFN_vkCmdBeginRendering) load(userptr, "vkCmdBeginRendering"); - glad_vkCmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2) load(userptr, "vkCmdBindVertexBuffers2"); - glad_vkCmdBlitImage2 = (PFN_vkCmdBlitImage2) load(userptr, "vkCmdBlitImage2"); - glad_vkCmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2) load(userptr, "vkCmdCopyBuffer2"); - glad_vkCmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2) load(userptr, "vkCmdCopyBufferToImage2"); - glad_vkCmdCopyImage2 = (PFN_vkCmdCopyImage2) load(userptr, "vkCmdCopyImage2"); - glad_vkCmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2) load(userptr, "vkCmdCopyImageToBuffer2"); - glad_vkCmdEndRendering = (PFN_vkCmdEndRendering) load(userptr, "vkCmdEndRendering"); - glad_vkCmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2) load(userptr, "vkCmdPipelineBarrier2"); - glad_vkCmdResetEvent2 = (PFN_vkCmdResetEvent2) load(userptr, "vkCmdResetEvent2"); - glad_vkCmdResolveImage2 = (PFN_vkCmdResolveImage2) load(userptr, "vkCmdResolveImage2"); - glad_vkCmdSetCullMode = (PFN_vkCmdSetCullMode) load(userptr, "vkCmdSetCullMode"); - glad_vkCmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable) load(userptr, "vkCmdSetDepthBiasEnable"); - glad_vkCmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable) load(userptr, "vkCmdSetDepthBoundsTestEnable"); - glad_vkCmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp) load(userptr, "vkCmdSetDepthCompareOp"); - glad_vkCmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable) load(userptr, "vkCmdSetDepthTestEnable"); - glad_vkCmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable) load(userptr, "vkCmdSetDepthWriteEnable"); - glad_vkCmdSetEvent2 = (PFN_vkCmdSetEvent2) load(userptr, "vkCmdSetEvent2"); - glad_vkCmdSetFrontFace = (PFN_vkCmdSetFrontFace) load(userptr, "vkCmdSetFrontFace"); - glad_vkCmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable) load(userptr, "vkCmdSetPrimitiveRestartEnable"); - glad_vkCmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology) load(userptr, "vkCmdSetPrimitiveTopology"); - glad_vkCmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable) load(userptr, "vkCmdSetRasterizerDiscardEnable"); - glad_vkCmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount) load(userptr, "vkCmdSetScissorWithCount"); - glad_vkCmdSetStencilOp = (PFN_vkCmdSetStencilOp) load(userptr, "vkCmdSetStencilOp"); - glad_vkCmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable) load(userptr, "vkCmdSetStencilTestEnable"); - glad_vkCmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount) load(userptr, "vkCmdSetViewportWithCount"); - glad_vkCmdWaitEvents2 = (PFN_vkCmdWaitEvents2) load(userptr, "vkCmdWaitEvents2"); - glad_vkCmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2) load(userptr, "vkCmdWriteTimestamp2"); - glad_vkCreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot) load(userptr, "vkCreatePrivateDataSlot"); - glad_vkDestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot) load(userptr, "vkDestroyPrivateDataSlot"); - glad_vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements) load(userptr, "vkGetDeviceBufferMemoryRequirements"); - glad_vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements) load(userptr, "vkGetDeviceImageMemoryRequirements"); - glad_vkGetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements) load(userptr, "vkGetDeviceImageSparseMemoryRequirements"); - glad_vkGetPhysicalDeviceToolProperties = (PFN_vkGetPhysicalDeviceToolProperties) load(userptr, "vkGetPhysicalDeviceToolProperties"); - glad_vkGetPrivateData = (PFN_vkGetPrivateData) load(userptr, "vkGetPrivateData"); - glad_vkQueueSubmit2 = (PFN_vkQueueSubmit2) load(userptr, "vkQueueSubmit2"); - glad_vkSetPrivateData = (PFN_vkSetPrivateData) load(userptr, "vkSetPrivateData"); -} -static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_EXT_debug_report) return; - glad_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load(userptr, "vkCreateDebugReportCallbackEXT"); - glad_vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load(userptr, "vkDebugReportMessageEXT"); - glad_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load(userptr, "vkDestroyDebugReportCallbackEXT"); -} -static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_KHR_surface) return; - glad_vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load(userptr, "vkDestroySurfaceKHR"); - glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load(userptr, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); - glad_vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load(userptr, "vkGetPhysicalDeviceSurfaceFormatsKHR"); - glad_vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load(userptr, "vkGetPhysicalDeviceSurfacePresentModesKHR"); - glad_vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load(userptr, "vkGetPhysicalDeviceSurfaceSupportKHR"); -} -static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_VK_KHR_swapchain) return; - glad_vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load(userptr, "vkAcquireNextImage2KHR"); - glad_vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load(userptr, "vkAcquireNextImageKHR"); - glad_vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load(userptr, "vkCreateSwapchainKHR"); - glad_vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load(userptr, "vkDestroySwapchainKHR"); - glad_vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load(userptr, "vkGetDeviceGroupPresentCapabilitiesKHR"); - glad_vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load(userptr, "vkGetDeviceGroupSurfacePresentModesKHR"); - glad_vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load(userptr, "vkGetPhysicalDevicePresentRectanglesKHR"); - glad_vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load(userptr, "vkGetSwapchainImagesKHR"); - glad_vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load(userptr, "vkQueuePresentKHR"); -} - - - -static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *out_extension_count, char ***out_extensions) { - uint32_t i; - uint32_t instance_extension_count = 0; - uint32_t device_extension_count = 0; - uint32_t max_extension_count = 0; - uint32_t total_extension_count = 0; - char **extensions = NULL; - VkExtensionProperties *ext_properties = NULL; - VkResult result; - - if (glad_vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && glad_vkEnumerateDeviceExtensionProperties == NULL)) { - return 0; - } - - result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); - if (result != VK_SUCCESS) { - return 0; - } - - if (physical_device != NULL) { - result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL); - if (result != VK_SUCCESS) { - return 0; - } - } - - total_extension_count = instance_extension_count + device_extension_count; - if (total_extension_count <= 0) { - return 0; - } - - max_extension_count = instance_extension_count > device_extension_count - ? instance_extension_count : device_extension_count; - - ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties)); - if (ext_properties == NULL) { - goto glad_vk_get_extensions_error; - } - - result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties); - if (result != VK_SUCCESS) { - goto glad_vk_get_extensions_error; - } - - extensions = (char**) calloc(total_extension_count, sizeof(char*)); - if (extensions == NULL) { - goto glad_vk_get_extensions_error; - } - - for (i = 0; i < instance_extension_count; ++i) { - VkExtensionProperties ext = ext_properties[i]; - - size_t extension_name_length = strlen(ext.extensionName) + 1; - extensions[i] = (char*) malloc(extension_name_length * sizeof(char)); - if (extensions[i] == NULL) { - goto glad_vk_get_extensions_error; - } - memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char)); - } - - if (physical_device != NULL) { - result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties); - if (result != VK_SUCCESS) { - goto glad_vk_get_extensions_error; - } - - for (i = 0; i < device_extension_count; ++i) { - VkExtensionProperties ext = ext_properties[i]; - - size_t extension_name_length = strlen(ext.extensionName) + 1; - extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char)); - if (extensions[instance_extension_count + i] == NULL) { - goto glad_vk_get_extensions_error; - } - memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char)); - } - } - - free((void*) ext_properties); - - *out_extension_count = total_extension_count; - *out_extensions = extensions; - - return 1; - -glad_vk_get_extensions_error: - free((void*) ext_properties); - if (extensions != NULL) { - for (i = 0; i < total_extension_count; ++i) { - free((void*) extensions[i]); - } - free(extensions); - } - return 0; -} - -static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) { - uint32_t i; - - for(i = 0; i < extension_count ; ++i) { - free((void*) (extensions[i])); - } - - free((void*) extensions); -} - -static int glad_vk_has_extension(const char *name, uint32_t extension_count, char **extensions) { - uint32_t i; - - for (i = 0; i < extension_count; ++i) { - if(extensions[i] != NULL && strcmp(name, extensions[i]) == 0) { - return 1; - } - } - - return 0; -} - -static GLADapiproc glad_vk_get_proc_from_userptr(void *userptr, const char* name) { - return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); -} - -static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) { - uint32_t extension_count = 0; - char **extensions = NULL; - if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0; - - GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions); - GLAD_VK_KHR_portability_enumeration = glad_vk_has_extension("VK_KHR_portability_enumeration", extension_count, extensions); - GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions); - GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions); - - (void) glad_vk_has_extension; - - glad_vk_free_extensions(extension_count, extensions); - - return 1; -} - -static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) { - int major = 1; - int minor = 0; - -#ifdef VK_VERSION_1_1 - if (glad_vkEnumerateInstanceVersion != NULL) { - uint32_t version; - VkResult result; - - result = glad_vkEnumerateInstanceVersion(&version); - if (result == VK_SUCCESS) { - major = (int) VK_VERSION_MAJOR(version); - minor = (int) VK_VERSION_MINOR(version); - } - } -#endif - - if (physical_device != NULL && glad_vkGetPhysicalDeviceProperties != NULL) { - VkPhysicalDeviceProperties properties; - glad_vkGetPhysicalDeviceProperties(physical_device, &properties); - - major = (int) VK_VERSION_MAJOR(properties.apiVersion); - minor = (int) VK_VERSION_MINOR(properties.apiVersion); - } - - GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_VK_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_VK_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - - return GLAD_MAKE_VERSION(major, minor); -} - -int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr) { - int version; - -#ifdef VK_VERSION_1_1 - glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion"); -#endif - version = glad_vk_find_core_vulkan( physical_device); - if (!version) { - return 0; - } - - glad_vk_load_VK_VERSION_1_0(load, userptr); - glad_vk_load_VK_VERSION_1_1(load, userptr); - glad_vk_load_VK_VERSION_1_2(load, userptr); - glad_vk_load_VK_VERSION_1_3(load, userptr); - - if (!glad_vk_find_extensions_vulkan( physical_device)) return 0; - glad_vk_load_VK_EXT_debug_report(load, userptr); - glad_vk_load_VK_KHR_surface(load, userptr); - glad_vk_load_VK_KHR_swapchain(load, userptr); - - - return version; -} - - -int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) { - return gladLoadVulkanUserPtr( physical_device, glad_vk_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); -} - - - - - - -#ifdef __cplusplus -} -#endif - -#endif /* GLAD_VULKAN_IMPLEMENTATION */ - diff --git a/raylib/external/glfw/deps/mingw/_mingw_dxhelper.h b/raylib/external/glfw/deps/mingw/_mingw_dxhelper.h deleted file mode 100644 index 849e291..0000000 --- a/raylib/external/glfw/deps/mingw/_mingw_dxhelper.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER within this package. - */ - -#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS) -#define NONAMELESSUNION 1 -#endif -#if defined(NONAMELESSSTRUCT) && \ - !defined(NONAMELESSUNION) -#define NONAMELESSUNION 1 -#endif -#if defined(NONAMELESSUNION) && \ - !defined(NONAMELESSSTRUCT) -#define NONAMELESSSTRUCT 1 -#endif -#if !defined(__GNU_EXTENSION) -#if defined(__GNUC__) || defined(__GNUG__) -#define __GNU_EXTENSION __extension__ -#else -#define __GNU_EXTENSION -#endif -#endif /* __extension__ */ - -#ifndef __ANONYMOUS_DEFINED -#define __ANONYMOUS_DEFINED -#if defined(__GNUC__) || defined(__GNUG__) -#define _ANONYMOUS_UNION __extension__ -#define _ANONYMOUS_STRUCT __extension__ -#else -#define _ANONYMOUS_UNION -#define _ANONYMOUS_STRUCT -#endif -#ifndef NONAMELESSUNION -#define _UNION_NAME(x) -#define _STRUCT_NAME(x) -#else /* NONAMELESSUNION */ -#define _UNION_NAME(x) x -#define _STRUCT_NAME(x) x -#endif -#endif /* __ANONYMOUS_DEFINED */ - -#ifndef DUMMYUNIONNAME -# ifdef NONAMELESSUNION -# define DUMMYUNIONNAME u -# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */ -# define DUMMYUNIONNAME2 u2 -# define DUMMYUNIONNAME3 u3 -# define DUMMYUNIONNAME4 u4 -# define DUMMYUNIONNAME5 u5 -# define DUMMYUNIONNAME6 u6 -# define DUMMYUNIONNAME7 u7 -# define DUMMYUNIONNAME8 u8 -# define DUMMYUNIONNAME9 u9 -# else /* NONAMELESSUNION */ -# define DUMMYUNIONNAME -# define DUMMYUNIONNAME1 /* Wine uses this variant */ -# define DUMMYUNIONNAME2 -# define DUMMYUNIONNAME3 -# define DUMMYUNIONNAME4 -# define DUMMYUNIONNAME5 -# define DUMMYUNIONNAME6 -# define DUMMYUNIONNAME7 -# define DUMMYUNIONNAME8 -# define DUMMYUNIONNAME9 -# endif -#endif /* DUMMYUNIONNAME */ - -#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */ -# ifdef NONAMELESSUNION -# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */ -# else -# define DUMMYUNIONNAME1 /* Wine uses this variant */ -# endif -#endif /* DUMMYUNIONNAME1 */ - -#ifndef DUMMYSTRUCTNAME -# ifdef NONAMELESSUNION -# define DUMMYSTRUCTNAME s -# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */ -# define DUMMYSTRUCTNAME2 s2 -# define DUMMYSTRUCTNAME3 s3 -# define DUMMYSTRUCTNAME4 s4 -# define DUMMYSTRUCTNAME5 s5 -# else -# define DUMMYSTRUCTNAME -# define DUMMYSTRUCTNAME1 /* Wine uses this variant */ -# define DUMMYSTRUCTNAME2 -# define DUMMYSTRUCTNAME3 -# define DUMMYSTRUCTNAME4 -# define DUMMYSTRUCTNAME5 -# endif -#endif /* DUMMYSTRUCTNAME */ - -/* These are for compatibility with the Wine source tree */ - -#ifndef WINELIB_NAME_AW -# ifdef __MINGW_NAME_AW -# define WINELIB_NAME_AW __MINGW_NAME_AW -# else -# ifdef UNICODE -# define WINELIB_NAME_AW(func) func##W -# else -# define WINELIB_NAME_AW(func) func##A -# endif -# endif -#endif /* WINELIB_NAME_AW */ - -#ifndef DECL_WINELIB_TYPE_AW -# ifdef __MINGW_TYPEDEF_AW -# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW -# else -# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; -# endif -#endif /* DECL_WINELIB_TYPE_AW */ - diff --git a/raylib/external/glfw/deps/mingw/dinput.h b/raylib/external/glfw/deps/mingw/dinput.h deleted file mode 100644 index b575480..0000000 --- a/raylib/external/glfw/deps/mingw/dinput.h +++ /dev/null @@ -1,2467 +0,0 @@ -/* - * Copyright (C) the Wine project - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __DINPUT_INCLUDED__ -#define __DINPUT_INCLUDED__ - -#define COM_NO_WINDOWS_H -#include -#include <_mingw_dxhelper.h> - -#ifndef DIRECTINPUT_VERSION -#define DIRECTINPUT_VERSION 0x0800 -#endif - -/* Classes */ -DEFINE_GUID(CLSID_DirectInput, 0x25E609E0,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(CLSID_DirectInputDevice, 0x25E609E1,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); - -DEFINE_GUID(CLSID_DirectInput8, 0x25E609E4,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(CLSID_DirectInputDevice8, 0x25E609E5,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); - -/* Interfaces */ -DEFINE_GUID(IID_IDirectInputA, 0x89521360,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInputW, 0x89521361,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInput2A, 0x5944E662,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInput2W, 0x5944E663,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInput7A, 0x9A4CB684,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); -DEFINE_GUID(IID_IDirectInput7W, 0x9A4CB685,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); -DEFINE_GUID(IID_IDirectInput8A, 0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); -DEFINE_GUID(IID_IDirectInput8W, 0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); -DEFINE_GUID(IID_IDirectInputDeviceA, 0x5944E680,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInputDeviceW, 0x5944E681,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInputDevice2A, 0x5944E682,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInputDevice2W, 0x5944E683,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(IID_IDirectInputDevice7A, 0x57D7C6BC,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); -DEFINE_GUID(IID_IDirectInputDevice7W, 0x57D7C6BD,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); -DEFINE_GUID(IID_IDirectInputDevice8A, 0x54D41080,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); -DEFINE_GUID(IID_IDirectInputDevice8W, 0x54D41081,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); -DEFINE_GUID(IID_IDirectInputEffect, 0xE7E1F7C0,0x88D2,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); - -/* Predefined object types */ -DEFINE_GUID(GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_RxAxis,0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_RyAxis,0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_RzAxis,0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Slider,0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Button,0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Key, 0x55728220,0xD33C,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_POV, 0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Unknown,0xA36D02F3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); - -/* Predefined product GUIDs */ -DEFINE_GUID(GUID_SysMouse, 0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_SysKeyboard, 0x6F1D2B61,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Joystick, 0x6F1D2B70,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_SysMouseEm, 0x6F1D2B80,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_SysMouseEm2, 0x6F1D2B81,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_SysKeyboardEm, 0x6F1D2B82,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_SysKeyboardEm2,0x6F1D2B83,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); - -/* predefined forcefeedback effects */ -DEFINE_GUID(GUID_ConstantForce, 0x13541C20,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_RampForce, 0x13541C21,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Square, 0x13541C22,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Sine, 0x13541C23,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Triangle, 0x13541C24,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_SawtoothUp, 0x13541C25,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_SawtoothDown, 0x13541C26,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Spring, 0x13541C27,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Damper, 0x13541C28,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Inertia, 0x13541C29,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_Friction, 0x13541C2A,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); -DEFINE_GUID(GUID_CustomForce, 0x13541C2B,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); - -typedef struct IDirectInputA *LPDIRECTINPUTA; -typedef struct IDirectInputW *LPDIRECTINPUTW; -typedef struct IDirectInput2A *LPDIRECTINPUT2A; -typedef struct IDirectInput2W *LPDIRECTINPUT2W; -typedef struct IDirectInput7A *LPDIRECTINPUT7A; -typedef struct IDirectInput7W *LPDIRECTINPUT7W; -#if DIRECTINPUT_VERSION >= 0x0800 -typedef struct IDirectInput8A *LPDIRECTINPUT8A; -typedef struct IDirectInput8W *LPDIRECTINPUT8W; -#endif /* DI8 */ -typedef struct IDirectInputDeviceA *LPDIRECTINPUTDEVICEA; -typedef struct IDirectInputDeviceW *LPDIRECTINPUTDEVICEW; -#if DIRECTINPUT_VERSION >= 0x0500 -typedef struct IDirectInputDevice2A *LPDIRECTINPUTDEVICE2A; -typedef struct IDirectInputDevice2W *LPDIRECTINPUTDEVICE2W; -#endif /* DI5 */ -#if DIRECTINPUT_VERSION >= 0x0700 -typedef struct IDirectInputDevice7A *LPDIRECTINPUTDEVICE7A; -typedef struct IDirectInputDevice7W *LPDIRECTINPUTDEVICE7W; -#endif /* DI7 */ -#if DIRECTINPUT_VERSION >= 0x0800 -typedef struct IDirectInputDevice8A *LPDIRECTINPUTDEVICE8A; -typedef struct IDirectInputDevice8W *LPDIRECTINPUTDEVICE8W; -#endif /* DI8 */ -#if DIRECTINPUT_VERSION >= 0x0500 -typedef struct IDirectInputEffect *LPDIRECTINPUTEFFECT; -#endif /* DI5 */ -typedef struct SysKeyboardA *LPSYSKEYBOARDA; -typedef struct SysMouseA *LPSYSMOUSEA; - -#define IID_IDirectInput WINELIB_NAME_AW(IID_IDirectInput) -#define IDirectInput WINELIB_NAME_AW(IDirectInput) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUT) -#define IID_IDirectInput2 WINELIB_NAME_AW(IID_IDirectInput2) -#define IDirectInput2 WINELIB_NAME_AW(IDirectInput2) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUT2) -#define IID_IDirectInput7 WINELIB_NAME_AW(IID_IDirectInput7) -#define IDirectInput7 WINELIB_NAME_AW(IDirectInput7) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUT7) -#if DIRECTINPUT_VERSION >= 0x0800 -#define IID_IDirectInput8 WINELIB_NAME_AW(IID_IDirectInput8) -#define IDirectInput8 WINELIB_NAME_AW(IDirectInput8) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUT8) -#endif /* DI8 */ -#define IID_IDirectInputDevice WINELIB_NAME_AW(IID_IDirectInputDevice) -#define IDirectInputDevice WINELIB_NAME_AW(IDirectInputDevice) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE) -#if DIRECTINPUT_VERSION >= 0x0500 -#define IID_IDirectInputDevice2 WINELIB_NAME_AW(IID_IDirectInputDevice2) -#define IDirectInputDevice2 WINELIB_NAME_AW(IDirectInputDevice2) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE2) -#endif /* DI5 */ -#if DIRECTINPUT_VERSION >= 0x0700 -#define IID_IDirectInputDevice7 WINELIB_NAME_AW(IID_IDirectInputDevice7) -#define IDirectInputDevice7 WINELIB_NAME_AW(IDirectInputDevice7) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE7) -#endif /* DI7 */ -#if DIRECTINPUT_VERSION >= 0x0800 -#define IID_IDirectInputDevice8 WINELIB_NAME_AW(IID_IDirectInputDevice8) -#define IDirectInputDevice8 WINELIB_NAME_AW(IDirectInputDevice8) -DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE8) -#endif /* DI8 */ - -#define DI_OK S_OK -#define DI_NOTATTACHED S_FALSE -#define DI_BUFFEROVERFLOW S_FALSE -#define DI_PROPNOEFFECT S_FALSE -#define DI_NOEFFECT S_FALSE -#define DI_POLLEDDEVICE ((HRESULT)0x00000002L) -#define DI_DOWNLOADSKIPPED ((HRESULT)0x00000003L) -#define DI_EFFECTRESTARTED ((HRESULT)0x00000004L) -#define DI_TRUNCATED ((HRESULT)0x00000008L) -#define DI_SETTINGSNOTSAVED ((HRESULT)0x0000000BL) -#define DI_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL) -#define DI_WRITEPROTECT ((HRESULT)0x00000013L) - -#define DIERR_OLDDIRECTINPUTVERSION \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_OLD_WIN_VERSION) -#define DIERR_BETADIRECTINPUTVERSION \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_RMODE_APP) -#define DIERR_BADDRIVERVER \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BAD_DRIVER_LEVEL) -#define DIERR_DEVICENOTREG REGDB_E_CLASSNOTREG -#define DIERR_NOTFOUND \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND) -#define DIERR_OBJECTNOTFOUND \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND) -#define DIERR_INVALIDPARAM E_INVALIDARG -#define DIERR_NOINTERFACE E_NOINTERFACE -#define DIERR_GENERIC E_FAIL -#define DIERR_OUTOFMEMORY E_OUTOFMEMORY -#define DIERR_UNSUPPORTED E_NOTIMPL -#define DIERR_NOTINITIALIZED \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_READY) -#define DIERR_ALREADYINITIALIZED \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED) -#define DIERR_NOAGGREGATION CLASS_E_NOAGGREGATION -#define DIERR_OTHERAPPHASPRIO E_ACCESSDENIED -#define DIERR_INPUTLOST \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_READ_FAULT) -#define DIERR_ACQUIRED \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BUSY) -#define DIERR_NOTACQUIRED \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INVALID_ACCESS) -#define DIERR_READONLY E_ACCESSDENIED -#define DIERR_HANDLEEXISTS E_ACCESSDENIED -#ifndef E_PENDING -#define E_PENDING 0x8000000AL -#endif -#define DIERR_INSUFFICIENTPRIVS 0x80040200L -#define DIERR_DEVICEFULL 0x80040201L -#define DIERR_MOREDATA 0x80040202L -#define DIERR_NOTDOWNLOADED 0x80040203L -#define DIERR_HASEFFECTS 0x80040204L -#define DIERR_NOTEXCLUSIVEACQUIRED 0x80040205L -#define DIERR_INCOMPLETEEFFECT 0x80040206L -#define DIERR_NOTBUFFERED 0x80040207L -#define DIERR_EFFECTPLAYING 0x80040208L -#define DIERR_UNPLUGGED 0x80040209L -#define DIERR_REPORTFULL 0x8004020AL -#define DIERR_MAPFILEFAIL 0x8004020BL - -#define DIENUM_STOP 0 -#define DIENUM_CONTINUE 1 - -#define DIEDFL_ALLDEVICES 0x00000000 -#define DIEDFL_ATTACHEDONLY 0x00000001 -#define DIEDFL_FORCEFEEDBACK 0x00000100 -#define DIEDFL_INCLUDEALIASES 0x00010000 -#define DIEDFL_INCLUDEPHANTOMS 0x00020000 -#define DIEDFL_INCLUDEHIDDEN 0x00040000 - -#define DIDEVTYPE_DEVICE 1 -#define DIDEVTYPE_MOUSE 2 -#define DIDEVTYPE_KEYBOARD 3 -#define DIDEVTYPE_JOYSTICK 4 -#define DIDEVTYPE_HID 0x00010000 - -#define DI8DEVCLASS_ALL 0 -#define DI8DEVCLASS_DEVICE 1 -#define DI8DEVCLASS_POINTER 2 -#define DI8DEVCLASS_KEYBOARD 3 -#define DI8DEVCLASS_GAMECTRL 4 - -#define DI8DEVTYPE_DEVICE 0x11 -#define DI8DEVTYPE_MOUSE 0x12 -#define DI8DEVTYPE_KEYBOARD 0x13 -#define DI8DEVTYPE_JOYSTICK 0x14 -#define DI8DEVTYPE_GAMEPAD 0x15 -#define DI8DEVTYPE_DRIVING 0x16 -#define DI8DEVTYPE_FLIGHT 0x17 -#define DI8DEVTYPE_1STPERSON 0x18 -#define DI8DEVTYPE_DEVICECTRL 0x19 -#define DI8DEVTYPE_SCREENPOINTER 0x1A -#define DI8DEVTYPE_REMOTE 0x1B -#define DI8DEVTYPE_SUPPLEMENTAL 0x1C - -#define DIDEVTYPEMOUSE_UNKNOWN 1 -#define DIDEVTYPEMOUSE_TRADITIONAL 2 -#define DIDEVTYPEMOUSE_FINGERSTICK 3 -#define DIDEVTYPEMOUSE_TOUCHPAD 4 -#define DIDEVTYPEMOUSE_TRACKBALL 5 - -#define DIDEVTYPEKEYBOARD_UNKNOWN 0 -#define DIDEVTYPEKEYBOARD_PCXT 1 -#define DIDEVTYPEKEYBOARD_OLIVETTI 2 -#define DIDEVTYPEKEYBOARD_PCAT 3 -#define DIDEVTYPEKEYBOARD_PCENH 4 -#define DIDEVTYPEKEYBOARD_NOKIA1050 5 -#define DIDEVTYPEKEYBOARD_NOKIA9140 6 -#define DIDEVTYPEKEYBOARD_NEC98 7 -#define DIDEVTYPEKEYBOARD_NEC98LAPTOP 8 -#define DIDEVTYPEKEYBOARD_NEC98106 9 -#define DIDEVTYPEKEYBOARD_JAPAN106 10 -#define DIDEVTYPEKEYBOARD_JAPANAX 11 -#define DIDEVTYPEKEYBOARD_J3100 12 - -#define DIDEVTYPEJOYSTICK_UNKNOWN 1 -#define DIDEVTYPEJOYSTICK_TRADITIONAL 2 -#define DIDEVTYPEJOYSTICK_FLIGHTSTICK 3 -#define DIDEVTYPEJOYSTICK_GAMEPAD 4 -#define DIDEVTYPEJOYSTICK_RUDDER 5 -#define DIDEVTYPEJOYSTICK_WHEEL 6 -#define DIDEVTYPEJOYSTICK_HEADTRACKER 7 - -#define DI8DEVTYPEMOUSE_UNKNOWN 1 -#define DI8DEVTYPEMOUSE_TRADITIONAL 2 -#define DI8DEVTYPEMOUSE_FINGERSTICK 3 -#define DI8DEVTYPEMOUSE_TOUCHPAD 4 -#define DI8DEVTYPEMOUSE_TRACKBALL 5 -#define DI8DEVTYPEMOUSE_ABSOLUTE 6 - -#define DI8DEVTYPEKEYBOARD_UNKNOWN 0 -#define DI8DEVTYPEKEYBOARD_PCXT 1 -#define DI8DEVTYPEKEYBOARD_OLIVETTI 2 -#define DI8DEVTYPEKEYBOARD_PCAT 3 -#define DI8DEVTYPEKEYBOARD_PCENH 4 -#define DI8DEVTYPEKEYBOARD_NOKIA1050 5 -#define DI8DEVTYPEKEYBOARD_NOKIA9140 6 -#define DI8DEVTYPEKEYBOARD_NEC98 7 -#define DI8DEVTYPEKEYBOARD_NEC98LAPTOP 8 -#define DI8DEVTYPEKEYBOARD_NEC98106 9 -#define DI8DEVTYPEKEYBOARD_JAPAN106 10 -#define DI8DEVTYPEKEYBOARD_JAPANAX 11 -#define DI8DEVTYPEKEYBOARD_J3100 12 - -#define DI8DEVTYPE_LIMITEDGAMESUBTYPE 1 - -#define DI8DEVTYPEJOYSTICK_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE -#define DI8DEVTYPEJOYSTICK_STANDARD 2 - -#define DI8DEVTYPEGAMEPAD_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE -#define DI8DEVTYPEGAMEPAD_STANDARD 2 -#define DI8DEVTYPEGAMEPAD_TILT 3 - -#define DI8DEVTYPEDRIVING_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE -#define DI8DEVTYPEDRIVING_COMBINEDPEDALS 2 -#define DI8DEVTYPEDRIVING_DUALPEDALS 3 -#define DI8DEVTYPEDRIVING_THREEPEDALS 4 -#define DI8DEVTYPEDRIVING_HANDHELD 5 - -#define DI8DEVTYPEFLIGHT_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE -#define DI8DEVTYPEFLIGHT_STICK 2 -#define DI8DEVTYPEFLIGHT_YOKE 3 -#define DI8DEVTYPEFLIGHT_RC 4 - -#define DI8DEVTYPE1STPERSON_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE -#define DI8DEVTYPE1STPERSON_UNKNOWN 2 -#define DI8DEVTYPE1STPERSON_SIXDOF 3 -#define DI8DEVTYPE1STPERSON_SHOOTER 4 - -#define DI8DEVTYPESCREENPTR_UNKNOWN 2 -#define DI8DEVTYPESCREENPTR_LIGHTGUN 3 -#define DI8DEVTYPESCREENPTR_LIGHTPEN 4 -#define DI8DEVTYPESCREENPTR_TOUCH 5 - -#define DI8DEVTYPEREMOTE_UNKNOWN 2 - -#define DI8DEVTYPEDEVICECTRL_UNKNOWN 2 -#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION 3 -#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED 4 - -#define DI8DEVTYPESUPPLEMENTAL_UNKNOWN 2 -#define DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER 3 -#define DI8DEVTYPESUPPLEMENTAL_HEADTRACKER 4 -#define DI8DEVTYPESUPPLEMENTAL_HANDTRACKER 5 -#define DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE 6 -#define DI8DEVTYPESUPPLEMENTAL_SHIFTER 7 -#define DI8DEVTYPESUPPLEMENTAL_THROTTLE 8 -#define DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE 9 -#define DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS 10 -#define DI8DEVTYPESUPPLEMENTAL_DUALPEDALS 11 -#define DI8DEVTYPESUPPLEMENTAL_THREEPEDALS 12 -#define DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS 13 - -#define GET_DIDEVICE_TYPE(dwDevType) LOBYTE(dwDevType) -#define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType) - -typedef struct DIDEVICEOBJECTINSTANCE_DX3A { - DWORD dwSize; - GUID guidType; - DWORD dwOfs; - DWORD dwType; - DWORD dwFlags; - CHAR tszName[MAX_PATH]; -} DIDEVICEOBJECTINSTANCE_DX3A, *LPDIDEVICEOBJECTINSTANCE_DX3A; -typedef const DIDEVICEOBJECTINSTANCE_DX3A *LPCDIDEVICEOBJECTINSTANCE_DX3A; -typedef struct DIDEVICEOBJECTINSTANCE_DX3W { - DWORD dwSize; - GUID guidType; - DWORD dwOfs; - DWORD dwType; - DWORD dwFlags; - WCHAR tszName[MAX_PATH]; -} DIDEVICEOBJECTINSTANCE_DX3W, *LPDIDEVICEOBJECTINSTANCE_DX3W; -typedef const DIDEVICEOBJECTINSTANCE_DX3W *LPCDIDEVICEOBJECTINSTANCE_DX3W; - -DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE_DX3) -DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE_DX3) -DECL_WINELIB_TYPE_AW(LPCDIDEVICEOBJECTINSTANCE_DX3) - -typedef struct DIDEVICEOBJECTINSTANCEA { - DWORD dwSize; - GUID guidType; - DWORD dwOfs; - DWORD dwType; - DWORD dwFlags; - CHAR tszName[MAX_PATH]; -#if(DIRECTINPUT_VERSION >= 0x0500) - DWORD dwFFMaxForce; - DWORD dwFFForceResolution; - WORD wCollectionNumber; - WORD wDesignatorIndex; - WORD wUsagePage; - WORD wUsage; - DWORD dwDimension; - WORD wExponent; - WORD wReserved; -#endif /* DIRECTINPUT_VERSION >= 0x0500 */ -} DIDEVICEOBJECTINSTANCEA, *LPDIDEVICEOBJECTINSTANCEA; -typedef const DIDEVICEOBJECTINSTANCEA *LPCDIDEVICEOBJECTINSTANCEA; - -typedef struct DIDEVICEOBJECTINSTANCEW { - DWORD dwSize; - GUID guidType; - DWORD dwOfs; - DWORD dwType; - DWORD dwFlags; - WCHAR tszName[MAX_PATH]; -#if(DIRECTINPUT_VERSION >= 0x0500) - DWORD dwFFMaxForce; - DWORD dwFFForceResolution; - WORD wCollectionNumber; - WORD wDesignatorIndex; - WORD wUsagePage; - WORD wUsage; - DWORD dwDimension; - WORD wExponent; - WORD wReserved; -#endif /* DIRECTINPUT_VERSION >= 0x0500 */ -} DIDEVICEOBJECTINSTANCEW, *LPDIDEVICEOBJECTINSTANCEW; -typedef const DIDEVICEOBJECTINSTANCEW *LPCDIDEVICEOBJECTINSTANCEW; - -DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE) -DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE) -DECL_WINELIB_TYPE_AW(LPCDIDEVICEOBJECTINSTANCE) - -typedef struct DIDEVICEINSTANCE_DX3A { - DWORD dwSize; - GUID guidInstance; - GUID guidProduct; - DWORD dwDevType; - CHAR tszInstanceName[MAX_PATH]; - CHAR tszProductName[MAX_PATH]; -} DIDEVICEINSTANCE_DX3A, *LPDIDEVICEINSTANCE_DX3A; -typedef const DIDEVICEINSTANCE_DX3A *LPCDIDEVICEINSTANCE_DX3A; -typedef struct DIDEVICEINSTANCE_DX3W { - DWORD dwSize; - GUID guidInstance; - GUID guidProduct; - DWORD dwDevType; - WCHAR tszInstanceName[MAX_PATH]; - WCHAR tszProductName[MAX_PATH]; -} DIDEVICEINSTANCE_DX3W, *LPDIDEVICEINSTANCE_DX3W; -typedef const DIDEVICEINSTANCE_DX3W *LPCDIDEVICEINSTANCE_DX3W; - -DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE_DX3) -DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE_DX3) -DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE_DX3) - -typedef struct DIDEVICEINSTANCEA { - DWORD dwSize; - GUID guidInstance; - GUID guidProduct; - DWORD dwDevType; - CHAR tszInstanceName[MAX_PATH]; - CHAR tszProductName[MAX_PATH]; -#if(DIRECTINPUT_VERSION >= 0x0500) - GUID guidFFDriver; - WORD wUsagePage; - WORD wUsage; -#endif /* DIRECTINPUT_VERSION >= 0x0500 */ -} DIDEVICEINSTANCEA, *LPDIDEVICEINSTANCEA; -typedef const DIDEVICEINSTANCEA *LPCDIDEVICEINSTANCEA; - -typedef struct DIDEVICEINSTANCEW { - DWORD dwSize; - GUID guidInstance; - GUID guidProduct; - DWORD dwDevType; - WCHAR tszInstanceName[MAX_PATH]; - WCHAR tszProductName[MAX_PATH]; -#if(DIRECTINPUT_VERSION >= 0x0500) - GUID guidFFDriver; - WORD wUsagePage; - WORD wUsage; -#endif /* DIRECTINPUT_VERSION >= 0x0500 */ -} DIDEVICEINSTANCEW, *LPDIDEVICEINSTANCEW; -typedef const DIDEVICEINSTANCEW *LPCDIDEVICEINSTANCEW; - -DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE) -DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE) -DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE) - -typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKA)(LPCDIDEVICEINSTANCEA,LPVOID); -typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKW)(LPCDIDEVICEINSTANCEW,LPVOID); -DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESCALLBACK) - -#define DIEDBS_MAPPEDPRI1 0x00000001 -#define DIEDBS_MAPPEDPRI2 0x00000002 -#define DIEDBS_RECENTDEVICE 0x00000010 -#define DIEDBS_NEWDEVICE 0x00000020 - -#define DIEDBSFL_ATTACHEDONLY 0x00000000 -#define DIEDBSFL_THISUSER 0x00000010 -#define DIEDBSFL_FORCEFEEDBACK DIEDFL_FORCEFEEDBACK -#define DIEDBSFL_AVAILABLEDEVICES 0x00001000 -#define DIEDBSFL_MULTIMICEKEYBOARDS 0x00002000 -#define DIEDBSFL_NONGAMINGDEVICES 0x00004000 -#define DIEDBSFL_VALID 0x00007110 - -#if DIRECTINPUT_VERSION >= 0x0800 -typedef BOOL (CALLBACK *LPDIENUMDEVICESBYSEMANTICSCBA)(LPCDIDEVICEINSTANCEA,LPDIRECTINPUTDEVICE8A,DWORD,DWORD,LPVOID); -typedef BOOL (CALLBACK *LPDIENUMDEVICESBYSEMANTICSCBW)(LPCDIDEVICEINSTANCEW,LPDIRECTINPUTDEVICE8W,DWORD,DWORD,LPVOID); -DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESBYSEMANTICSCB) -#endif - -typedef BOOL (CALLBACK *LPDICONFIGUREDEVICESCALLBACK)(LPUNKNOWN,LPVOID); - -typedef BOOL (CALLBACK *LPDIENUMDEVICEOBJECTSCALLBACKA)(LPCDIDEVICEOBJECTINSTANCEA,LPVOID); -typedef BOOL (CALLBACK *LPDIENUMDEVICEOBJECTSCALLBACKW)(LPCDIDEVICEOBJECTINSTANCEW,LPVOID); -DECL_WINELIB_TYPE_AW(LPDIENUMDEVICEOBJECTSCALLBACK) - -#if DIRECTINPUT_VERSION >= 0x0500 -typedef BOOL (CALLBACK *LPDIENUMCREATEDEFFECTOBJECTSCALLBACK)(LPDIRECTINPUTEFFECT, LPVOID); -#endif - -#define DIK_ESCAPE 0x01 -#define DIK_1 0x02 -#define DIK_2 0x03 -#define DIK_3 0x04 -#define DIK_4 0x05 -#define DIK_5 0x06 -#define DIK_6 0x07 -#define DIK_7 0x08 -#define DIK_8 0x09 -#define DIK_9 0x0A -#define DIK_0 0x0B -#define DIK_MINUS 0x0C /* - on main keyboard */ -#define DIK_EQUALS 0x0D -#define DIK_BACK 0x0E /* backspace */ -#define DIK_TAB 0x0F -#define DIK_Q 0x10 -#define DIK_W 0x11 -#define DIK_E 0x12 -#define DIK_R 0x13 -#define DIK_T 0x14 -#define DIK_Y 0x15 -#define DIK_U 0x16 -#define DIK_I 0x17 -#define DIK_O 0x18 -#define DIK_P 0x19 -#define DIK_LBRACKET 0x1A -#define DIK_RBRACKET 0x1B -#define DIK_RETURN 0x1C /* Enter on main keyboard */ -#define DIK_LCONTROL 0x1D -#define DIK_A 0x1E -#define DIK_S 0x1F -#define DIK_D 0x20 -#define DIK_F 0x21 -#define DIK_G 0x22 -#define DIK_H 0x23 -#define DIK_J 0x24 -#define DIK_K 0x25 -#define DIK_L 0x26 -#define DIK_SEMICOLON 0x27 -#define DIK_APOSTROPHE 0x28 -#define DIK_GRAVE 0x29 /* accent grave */ -#define DIK_LSHIFT 0x2A -#define DIK_BACKSLASH 0x2B -#define DIK_Z 0x2C -#define DIK_X 0x2D -#define DIK_C 0x2E -#define DIK_V 0x2F -#define DIK_B 0x30 -#define DIK_N 0x31 -#define DIK_M 0x32 -#define DIK_COMMA 0x33 -#define DIK_PERIOD 0x34 /* . on main keyboard */ -#define DIK_SLASH 0x35 /* / on main keyboard */ -#define DIK_RSHIFT 0x36 -#define DIK_MULTIPLY 0x37 /* * on numeric keypad */ -#define DIK_LMENU 0x38 /* left Alt */ -#define DIK_SPACE 0x39 -#define DIK_CAPITAL 0x3A -#define DIK_F1 0x3B -#define DIK_F2 0x3C -#define DIK_F3 0x3D -#define DIK_F4 0x3E -#define DIK_F5 0x3F -#define DIK_F6 0x40 -#define DIK_F7 0x41 -#define DIK_F8 0x42 -#define DIK_F9 0x43 -#define DIK_F10 0x44 -#define DIK_NUMLOCK 0x45 -#define DIK_SCROLL 0x46 /* Scroll Lock */ -#define DIK_NUMPAD7 0x47 -#define DIK_NUMPAD8 0x48 -#define DIK_NUMPAD9 0x49 -#define DIK_SUBTRACT 0x4A /* - on numeric keypad */ -#define DIK_NUMPAD4 0x4B -#define DIK_NUMPAD5 0x4C -#define DIK_NUMPAD6 0x4D -#define DIK_ADD 0x4E /* + on numeric keypad */ -#define DIK_NUMPAD1 0x4F -#define DIK_NUMPAD2 0x50 -#define DIK_NUMPAD3 0x51 -#define DIK_NUMPAD0 0x52 -#define DIK_DECIMAL 0x53 /* . on numeric keypad */ -#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */ -#define DIK_F11 0x57 -#define DIK_F12 0x58 -#define DIK_F13 0x64 /* (NEC PC98) */ -#define DIK_F14 0x65 /* (NEC PC98) */ -#define DIK_F15 0x66 /* (NEC PC98) */ -#define DIK_KANA 0x70 /* (Japanese keyboard) */ -#define DIK_ABNT_C1 0x73 /* / ? on Portugese (Brazilian) keyboards */ -#define DIK_CONVERT 0x79 /* (Japanese keyboard) */ -#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */ -#define DIK_YEN 0x7D /* (Japanese keyboard) */ -#define DIK_ABNT_C2 0x7E /* Numpad . on Portugese (Brazilian) keyboards */ -#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */ -#define DIK_CIRCUMFLEX 0x90 /* (Japanese keyboard) */ -#define DIK_AT 0x91 /* (NEC PC98) */ -#define DIK_COLON 0x92 /* (NEC PC98) */ -#define DIK_UNDERLINE 0x93 /* (NEC PC98) */ -#define DIK_KANJI 0x94 /* (Japanese keyboard) */ -#define DIK_STOP 0x95 /* (NEC PC98) */ -#define DIK_AX 0x96 /* (Japan AX) */ -#define DIK_UNLABELED 0x97 /* (J3100) */ -#define DIK_NEXTTRACK 0x99 /* Next Track */ -#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */ -#define DIK_RCONTROL 0x9D -#define DIK_MUTE 0xA0 /* Mute */ -#define DIK_CALCULATOR 0xA1 /* Calculator */ -#define DIK_PLAYPAUSE 0xA2 /* Play / Pause */ -#define DIK_MEDIASTOP 0xA4 /* Media Stop */ -#define DIK_VOLUMEDOWN 0xAE /* Volume - */ -#define DIK_VOLUMEUP 0xB0 /* Volume + */ -#define DIK_WEBHOME 0xB2 /* Web home */ -#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */ -#define DIK_DIVIDE 0xB5 /* / on numeric keypad */ -#define DIK_SYSRQ 0xB7 -#define DIK_RMENU 0xB8 /* right Alt */ -#define DIK_PAUSE 0xC5 /* Pause */ -#define DIK_HOME 0xC7 /* Home on arrow keypad */ -#define DIK_UP 0xC8 /* UpArrow on arrow keypad */ -#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */ -#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */ -#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */ -#define DIK_END 0xCF /* End on arrow keypad */ -#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */ -#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */ -#define DIK_INSERT 0xD2 /* Insert on arrow keypad */ -#define DIK_DELETE 0xD3 /* Delete on arrow keypad */ -#define DIK_LWIN 0xDB /* Left Windows key */ -#define DIK_RWIN 0xDC /* Right Windows key */ -#define DIK_APPS 0xDD /* AppMenu key */ -#define DIK_POWER 0xDE -#define DIK_SLEEP 0xDF -#define DIK_WAKE 0xE3 /* System Wake */ -#define DIK_WEBSEARCH 0xE5 /* Web Search */ -#define DIK_WEBFAVORITES 0xE6 /* Web Favorites */ -#define DIK_WEBREFRESH 0xE7 /* Web Refresh */ -#define DIK_WEBSTOP 0xE8 /* Web Stop */ -#define DIK_WEBFORWARD 0xE9 /* Web Forward */ -#define DIK_WEBBACK 0xEA /* Web Back */ -#define DIK_MYCOMPUTER 0xEB /* My Computer */ -#define DIK_MAIL 0xEC /* Mail */ -#define DIK_MEDIASELECT 0xED /* Media Select */ - -#define DIK_BACKSPACE DIK_BACK /* backspace */ -#define DIK_NUMPADSTAR DIK_MULTIPLY /* * on numeric keypad */ -#define DIK_LALT DIK_LMENU /* left Alt */ -#define DIK_CAPSLOCK DIK_CAPITAL /* CapsLock */ -#define DIK_NUMPADMINUS DIK_SUBTRACT /* - on numeric keypad */ -#define DIK_NUMPADPLUS DIK_ADD /* + on numeric keypad */ -#define DIK_NUMPADPERIOD DIK_DECIMAL /* . on numeric keypad */ -#define DIK_NUMPADSLASH DIK_DIVIDE /* / on numeric keypad */ -#define DIK_RALT DIK_RMENU /* right Alt */ -#define DIK_UPARROW DIK_UP /* UpArrow on arrow keypad */ -#define DIK_PGUP DIK_PRIOR /* PgUp on arrow keypad */ -#define DIK_LEFTARROW DIK_LEFT /* LeftArrow on arrow keypad */ -#define DIK_RIGHTARROW DIK_RIGHT /* RightArrow on arrow keypad */ -#define DIK_DOWNARROW DIK_DOWN /* DownArrow on arrow keypad */ -#define DIK_PGDN DIK_NEXT /* PgDn on arrow keypad */ - -#define DIDFT_ALL 0x00000000 -#define DIDFT_RELAXIS 0x00000001 -#define DIDFT_ABSAXIS 0x00000002 -#define DIDFT_AXIS 0x00000003 -#define DIDFT_PSHBUTTON 0x00000004 -#define DIDFT_TGLBUTTON 0x00000008 -#define DIDFT_BUTTON 0x0000000C -#define DIDFT_POV 0x00000010 -#define DIDFT_COLLECTION 0x00000040 -#define DIDFT_NODATA 0x00000080 -#define DIDFT_ANYINSTANCE 0x00FFFF00 -#define DIDFT_INSTANCEMASK DIDFT_ANYINSTANCE -#define DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8) -#define DIDFT_GETTYPE(n) LOBYTE(n) -#define DIDFT_GETINSTANCE(n) LOWORD((n) >> 8) -#define DIDFT_FFACTUATOR 0x01000000 -#define DIDFT_FFEFFECTTRIGGER 0x02000000 -#if DIRECTINPUT_VERSION >= 0x050a -#define DIDFT_OUTPUT 0x10000000 -#define DIDFT_VENDORDEFINED 0x04000000 -#define DIDFT_ALIAS 0x08000000 -#endif /* DI5a */ -#ifndef DIDFT_OPTIONAL -#define DIDFT_OPTIONAL 0x80000000 -#endif -#define DIDFT_ENUMCOLLECTION(n) ((WORD)(n) << 8) -#define DIDFT_NOCOLLECTION 0x00FFFF00 - -#define DIDF_ABSAXIS 0x00000001 -#define DIDF_RELAXIS 0x00000002 - -#define DIGDD_PEEK 0x00000001 - -#define DISEQUENCE_COMPARE(dwSq1,cmp,dwSq2) ((int)((dwSq1) - (dwSq2)) cmp 0) - -typedef struct DIDEVICEOBJECTDATA_DX3 { - DWORD dwOfs; - DWORD dwData; - DWORD dwTimeStamp; - DWORD dwSequence; -} DIDEVICEOBJECTDATA_DX3,*LPDIDEVICEOBJECTDATA_DX3; -typedef const DIDEVICEOBJECTDATA_DX3 *LPCDIDEVICEOBJECTDATA_DX3; - -typedef struct DIDEVICEOBJECTDATA { - DWORD dwOfs; - DWORD dwData; - DWORD dwTimeStamp; - DWORD dwSequence; -#if(DIRECTINPUT_VERSION >= 0x0800) - UINT_PTR uAppData; -#endif /* DIRECTINPUT_VERSION >= 0x0800 */ -} DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA; -typedef const DIDEVICEOBJECTDATA *LPCDIDEVICEOBJECTDATA; - -typedef struct _DIOBJECTDATAFORMAT { - const GUID *pguid; - DWORD dwOfs; - DWORD dwType; - DWORD dwFlags; -} DIOBJECTDATAFORMAT, *LPDIOBJECTDATAFORMAT; -typedef const DIOBJECTDATAFORMAT *LPCDIOBJECTDATAFORMAT; - -typedef struct _DIDATAFORMAT { - DWORD dwSize; - DWORD dwObjSize; - DWORD dwFlags; - DWORD dwDataSize; - DWORD dwNumObjs; - LPDIOBJECTDATAFORMAT rgodf; -} DIDATAFORMAT, *LPDIDATAFORMAT; -typedef const DIDATAFORMAT *LPCDIDATAFORMAT; - -#if DIRECTINPUT_VERSION >= 0x0500 -#define DIDOI_FFACTUATOR 0x00000001 -#define DIDOI_FFEFFECTTRIGGER 0x00000002 -#define DIDOI_POLLED 0x00008000 -#define DIDOI_ASPECTPOSITION 0x00000100 -#define DIDOI_ASPECTVELOCITY 0x00000200 -#define DIDOI_ASPECTACCEL 0x00000300 -#define DIDOI_ASPECTFORCE 0x00000400 -#define DIDOI_ASPECTMASK 0x00000F00 -#endif /* DI5 */ -#if DIRECTINPUT_VERSION >= 0x050a -#define DIDOI_GUIDISUSAGE 0x00010000 -#endif /* DI5a */ - -typedef struct DIPROPHEADER { - DWORD dwSize; - DWORD dwHeaderSize; - DWORD dwObj; - DWORD dwHow; -} DIPROPHEADER,*LPDIPROPHEADER; -typedef const DIPROPHEADER *LPCDIPROPHEADER; - -#define DIPH_DEVICE 0 -#define DIPH_BYOFFSET 1 -#define DIPH_BYID 2 -#if DIRECTINPUT_VERSION >= 0x050a -#define DIPH_BYUSAGE 3 - -#define DIMAKEUSAGEDWORD(UsagePage, Usage) (DWORD)MAKELONG(Usage, UsagePage) -#endif /* DI5a */ - -typedef struct DIPROPDWORD { - DIPROPHEADER diph; - DWORD dwData; -} DIPROPDWORD, *LPDIPROPDWORD; -typedef const DIPROPDWORD *LPCDIPROPDWORD; - -typedef struct DIPROPRANGE { - DIPROPHEADER diph; - LONG lMin; - LONG lMax; -} DIPROPRANGE, *LPDIPROPRANGE; -typedef const DIPROPRANGE *LPCDIPROPRANGE; - -#define DIPROPRANGE_NOMIN ((LONG)0x80000000) -#define DIPROPRANGE_NOMAX ((LONG)0x7FFFFFFF) - -#if DIRECTINPUT_VERSION >= 0x050a -typedef struct DIPROPCAL { - DIPROPHEADER diph; - LONG lMin; - LONG lCenter; - LONG lMax; -} DIPROPCAL, *LPDIPROPCAL; -typedef const DIPROPCAL *LPCDIPROPCAL; - -typedef struct DIPROPCALPOV { - DIPROPHEADER diph; - LONG lMin[5]; - LONG lMax[5]; -} DIPROPCALPOV, *LPDIPROPCALPOV; -typedef const DIPROPCALPOV *LPCDIPROPCALPOV; - -typedef struct DIPROPGUIDANDPATH { - DIPROPHEADER diph; - GUID guidClass; - WCHAR wszPath[MAX_PATH]; -} DIPROPGUIDANDPATH, *LPDIPROPGUIDANDPATH; -typedef const DIPROPGUIDANDPATH *LPCDIPROPGUIDANDPATH; - -typedef struct DIPROPSTRING { - DIPROPHEADER diph; - WCHAR wsz[MAX_PATH]; -} DIPROPSTRING, *LPDIPROPSTRING; -typedef const DIPROPSTRING *LPCDIPROPSTRING; -#endif /* DI5a */ - -#if DIRECTINPUT_VERSION >= 0x0800 -typedef struct DIPROPPOINTER { - DIPROPHEADER diph; - UINT_PTR uData; -} DIPROPPOINTER, *LPDIPROPPOINTER; -typedef const DIPROPPOINTER *LPCDIPROPPOINTER; -#endif /* DI8 */ - -/* special property GUIDs */ -#ifdef __cplusplus -#define MAKEDIPROP(prop) (*(const GUID *)(prop)) -#else -#define MAKEDIPROP(prop) ((REFGUID)(prop)) -#endif -#define DIPROP_BUFFERSIZE MAKEDIPROP(1) -#define DIPROP_AXISMODE MAKEDIPROP(2) - -#define DIPROPAXISMODE_ABS 0 -#define DIPROPAXISMODE_REL 1 - -#define DIPROP_GRANULARITY MAKEDIPROP(3) -#define DIPROP_RANGE MAKEDIPROP(4) -#define DIPROP_DEADZONE MAKEDIPROP(5) -#define DIPROP_SATURATION MAKEDIPROP(6) -#define DIPROP_FFGAIN MAKEDIPROP(7) -#define DIPROP_FFLOAD MAKEDIPROP(8) -#define DIPROP_AUTOCENTER MAKEDIPROP(9) - -#define DIPROPAUTOCENTER_OFF 0 -#define DIPROPAUTOCENTER_ON 1 - -#define DIPROP_CALIBRATIONMODE MAKEDIPROP(10) - -#define DIPROPCALIBRATIONMODE_COOKED 0 -#define DIPROPCALIBRATIONMODE_RAW 1 - -#if DIRECTINPUT_VERSION >= 0x050a -#define DIPROP_CALIBRATION MAKEDIPROP(11) -#define DIPROP_GUIDANDPATH MAKEDIPROP(12) -#define DIPROP_INSTANCENAME MAKEDIPROP(13) -#define DIPROP_PRODUCTNAME MAKEDIPROP(14) -#endif - -#if DIRECTINPUT_VERSION >= 0x5B2 -#define DIPROP_JOYSTICKID MAKEDIPROP(15) -#define DIPROP_GETPORTDISPLAYNAME MAKEDIPROP(16) -#endif - -#if DIRECTINPUT_VERSION >= 0x0700 -#define DIPROP_PHYSICALRANGE MAKEDIPROP(18) -#define DIPROP_LOGICALRANGE MAKEDIPROP(19) -#endif - -#if(DIRECTINPUT_VERSION >= 0x0800) -#define DIPROP_KEYNAME MAKEDIPROP(20) -#define DIPROP_CPOINTS MAKEDIPROP(21) -#define DIPROP_APPDATA MAKEDIPROP(22) -#define DIPROP_SCANCODE MAKEDIPROP(23) -#define DIPROP_VIDPID MAKEDIPROP(24) -#define DIPROP_USERNAME MAKEDIPROP(25) -#define DIPROP_TYPENAME MAKEDIPROP(26) - -#define MAXCPOINTSNUM 8 - -typedef struct _CPOINT { - LONG lP; - DWORD dwLog; -} CPOINT, *PCPOINT; - -typedef struct DIPROPCPOINTS { - DIPROPHEADER diph; - DWORD dwCPointsNum; - CPOINT cp[MAXCPOINTSNUM]; -} DIPROPCPOINTS, *LPDIPROPCPOINTS; -typedef const DIPROPCPOINTS *LPCDIPROPCPOINTS; -#endif /* DI8 */ - - -typedef struct DIDEVCAPS_DX3 { - DWORD dwSize; - DWORD dwFlags; - DWORD dwDevType; - DWORD dwAxes; - DWORD dwButtons; - DWORD dwPOVs; -} DIDEVCAPS_DX3, *LPDIDEVCAPS_DX3; - -typedef struct DIDEVCAPS { - DWORD dwSize; - DWORD dwFlags; - DWORD dwDevType; - DWORD dwAxes; - DWORD dwButtons; - DWORD dwPOVs; -#if(DIRECTINPUT_VERSION >= 0x0500) - DWORD dwFFSamplePeriod; - DWORD dwFFMinTimeResolution; - DWORD dwFirmwareRevision; - DWORD dwHardwareRevision; - DWORD dwFFDriverVersion; -#endif /* DIRECTINPUT_VERSION >= 0x0500 */ -} DIDEVCAPS,*LPDIDEVCAPS; - -#define DIDC_ATTACHED 0x00000001 -#define DIDC_POLLEDDEVICE 0x00000002 -#define DIDC_EMULATED 0x00000004 -#define DIDC_POLLEDDATAFORMAT 0x00000008 -#define DIDC_FORCEFEEDBACK 0x00000100 -#define DIDC_FFATTACK 0x00000200 -#define DIDC_FFFADE 0x00000400 -#define DIDC_SATURATION 0x00000800 -#define DIDC_POSNEGCOEFFICIENTS 0x00001000 -#define DIDC_POSNEGSATURATION 0x00002000 -#define DIDC_DEADBAND 0x00004000 -#define DIDC_STARTDELAY 0x00008000 -#define DIDC_ALIAS 0x00010000 -#define DIDC_PHANTOM 0x00020000 -#define DIDC_HIDDEN 0x00040000 - - -/* SetCooperativeLevel dwFlags */ -#define DISCL_EXCLUSIVE 0x00000001 -#define DISCL_NONEXCLUSIVE 0x00000002 -#define DISCL_FOREGROUND 0x00000004 -#define DISCL_BACKGROUND 0x00000008 -#define DISCL_NOWINKEY 0x00000010 - -#if (DIRECTINPUT_VERSION >= 0x0500) -/* Device FF flags */ -#define DISFFC_RESET 0x00000001 -#define DISFFC_STOPALL 0x00000002 -#define DISFFC_PAUSE 0x00000004 -#define DISFFC_CONTINUE 0x00000008 -#define DISFFC_SETACTUATORSON 0x00000010 -#define DISFFC_SETACTUATORSOFF 0x00000020 - -#define DIGFFS_EMPTY 0x00000001 -#define DIGFFS_STOPPED 0x00000002 -#define DIGFFS_PAUSED 0x00000004 -#define DIGFFS_ACTUATORSON 0x00000010 -#define DIGFFS_ACTUATORSOFF 0x00000020 -#define DIGFFS_POWERON 0x00000040 -#define DIGFFS_POWEROFF 0x00000080 -#define DIGFFS_SAFETYSWITCHON 0x00000100 -#define DIGFFS_SAFETYSWITCHOFF 0x00000200 -#define DIGFFS_USERFFSWITCHON 0x00000400 -#define DIGFFS_USERFFSWITCHOFF 0x00000800 -#define DIGFFS_DEVICELOST 0x80000000 - -/* Effect flags */ -#define DIEFT_ALL 0x00000000 - -#define DIEFT_CONSTANTFORCE 0x00000001 -#define DIEFT_RAMPFORCE 0x00000002 -#define DIEFT_PERIODIC 0x00000003 -#define DIEFT_CONDITION 0x00000004 -#define DIEFT_CUSTOMFORCE 0x00000005 -#define DIEFT_HARDWARE 0x000000FF -#define DIEFT_FFATTACK 0x00000200 -#define DIEFT_FFFADE 0x00000400 -#define DIEFT_SATURATION 0x00000800 -#define DIEFT_POSNEGCOEFFICIENTS 0x00001000 -#define DIEFT_POSNEGSATURATION 0x00002000 -#define DIEFT_DEADBAND 0x00004000 -#define DIEFT_STARTDELAY 0x00008000 -#define DIEFT_GETTYPE(n) LOBYTE(n) - -#define DIEFF_OBJECTIDS 0x00000001 -#define DIEFF_OBJECTOFFSETS 0x00000002 -#define DIEFF_CARTESIAN 0x00000010 -#define DIEFF_POLAR 0x00000020 -#define DIEFF_SPHERICAL 0x00000040 - -#define DIEP_DURATION 0x00000001 -#define DIEP_SAMPLEPERIOD 0x00000002 -#define DIEP_GAIN 0x00000004 -#define DIEP_TRIGGERBUTTON 0x00000008 -#define DIEP_TRIGGERREPEATINTERVAL 0x00000010 -#define DIEP_AXES 0x00000020 -#define DIEP_DIRECTION 0x00000040 -#define DIEP_ENVELOPE 0x00000080 -#define DIEP_TYPESPECIFICPARAMS 0x00000100 -#if(DIRECTINPUT_VERSION >= 0x0600) -#define DIEP_STARTDELAY 0x00000200 -#define DIEP_ALLPARAMS_DX5 0x000001FF -#define DIEP_ALLPARAMS 0x000003FF -#else -#define DIEP_ALLPARAMS 0x000001FF -#endif /* DIRECTINPUT_VERSION >= 0x0600 */ -#define DIEP_START 0x20000000 -#define DIEP_NORESTART 0x40000000 -#define DIEP_NODOWNLOAD 0x80000000 -#define DIEB_NOTRIGGER 0xFFFFFFFF - -#define DIES_SOLO 0x00000001 -#define DIES_NODOWNLOAD 0x80000000 - -#define DIEGES_PLAYING 0x00000001 -#define DIEGES_EMULATED 0x00000002 - -#define DI_DEGREES 100 -#define DI_FFNOMINALMAX 10000 -#define DI_SECONDS 1000000 - -typedef struct DICONSTANTFORCE { - LONG lMagnitude; -} DICONSTANTFORCE, *LPDICONSTANTFORCE; -typedef const DICONSTANTFORCE *LPCDICONSTANTFORCE; - -typedef struct DIRAMPFORCE { - LONG lStart; - LONG lEnd; -} DIRAMPFORCE, *LPDIRAMPFORCE; -typedef const DIRAMPFORCE *LPCDIRAMPFORCE; - -typedef struct DIPERIODIC { - DWORD dwMagnitude; - LONG lOffset; - DWORD dwPhase; - DWORD dwPeriod; -} DIPERIODIC, *LPDIPERIODIC; -typedef const DIPERIODIC *LPCDIPERIODIC; - -typedef struct DICONDITION { - LONG lOffset; - LONG lPositiveCoefficient; - LONG lNegativeCoefficient; - DWORD dwPositiveSaturation; - DWORD dwNegativeSaturation; - LONG lDeadBand; -} DICONDITION, *LPDICONDITION; -typedef const DICONDITION *LPCDICONDITION; - -typedef struct DICUSTOMFORCE { - DWORD cChannels; - DWORD dwSamplePeriod; - DWORD cSamples; - LPLONG rglForceData; -} DICUSTOMFORCE, *LPDICUSTOMFORCE; -typedef const DICUSTOMFORCE *LPCDICUSTOMFORCE; - -typedef struct DIENVELOPE { - DWORD dwSize; - DWORD dwAttackLevel; - DWORD dwAttackTime; - DWORD dwFadeLevel; - DWORD dwFadeTime; -} DIENVELOPE, *LPDIENVELOPE; -typedef const DIENVELOPE *LPCDIENVELOPE; - -typedef struct DIEFFECT_DX5 { - DWORD dwSize; - DWORD dwFlags; - DWORD dwDuration; - DWORD dwSamplePeriod; - DWORD dwGain; - DWORD dwTriggerButton; - DWORD dwTriggerRepeatInterval; - DWORD cAxes; - LPDWORD rgdwAxes; - LPLONG rglDirection; - LPDIENVELOPE lpEnvelope; - DWORD cbTypeSpecificParams; - LPVOID lpvTypeSpecificParams; -} DIEFFECT_DX5, *LPDIEFFECT_DX5; -typedef const DIEFFECT_DX5 *LPCDIEFFECT_DX5; - -typedef struct DIEFFECT { - DWORD dwSize; - DWORD dwFlags; - DWORD dwDuration; - DWORD dwSamplePeriod; - DWORD dwGain; - DWORD dwTriggerButton; - DWORD dwTriggerRepeatInterval; - DWORD cAxes; - LPDWORD rgdwAxes; - LPLONG rglDirection; - LPDIENVELOPE lpEnvelope; - DWORD cbTypeSpecificParams; - LPVOID lpvTypeSpecificParams; -#if(DIRECTINPUT_VERSION >= 0x0600) - DWORD dwStartDelay; -#endif /* DIRECTINPUT_VERSION >= 0x0600 */ -} DIEFFECT, *LPDIEFFECT; -typedef const DIEFFECT *LPCDIEFFECT; -typedef DIEFFECT DIEFFECT_DX6; -typedef LPDIEFFECT LPDIEFFECT_DX6; - -typedef struct DIEFFECTINFOA { - DWORD dwSize; - GUID guid; - DWORD dwEffType; - DWORD dwStaticParams; - DWORD dwDynamicParams; - CHAR tszName[MAX_PATH]; -} DIEFFECTINFOA, *LPDIEFFECTINFOA; -typedef const DIEFFECTINFOA *LPCDIEFFECTINFOA; - -typedef struct DIEFFECTINFOW { - DWORD dwSize; - GUID guid; - DWORD dwEffType; - DWORD dwStaticParams; - DWORD dwDynamicParams; - WCHAR tszName[MAX_PATH]; -} DIEFFECTINFOW, *LPDIEFFECTINFOW; -typedef const DIEFFECTINFOW *LPCDIEFFECTINFOW; - -DECL_WINELIB_TYPE_AW(DIEFFECTINFO) -DECL_WINELIB_TYPE_AW(LPDIEFFECTINFO) -DECL_WINELIB_TYPE_AW(LPCDIEFFECTINFO) - -typedef BOOL (CALLBACK *LPDIENUMEFFECTSCALLBACKA)(LPCDIEFFECTINFOA, LPVOID); -typedef BOOL (CALLBACK *LPDIENUMEFFECTSCALLBACKW)(LPCDIEFFECTINFOW, LPVOID); - -typedef struct DIEFFESCAPE { - DWORD dwSize; - DWORD dwCommand; - LPVOID lpvInBuffer; - DWORD cbInBuffer; - LPVOID lpvOutBuffer; - DWORD cbOutBuffer; -} DIEFFESCAPE, *LPDIEFFESCAPE; - -typedef struct DIJOYSTATE { - LONG lX; - LONG lY; - LONG lZ; - LONG lRx; - LONG lRy; - LONG lRz; - LONG rglSlider[2]; - DWORD rgdwPOV[4]; - BYTE rgbButtons[32]; -} DIJOYSTATE, *LPDIJOYSTATE; - -typedef struct DIJOYSTATE2 { - LONG lX; - LONG lY; - LONG lZ; - LONG lRx; - LONG lRy; - LONG lRz; - LONG rglSlider[2]; - DWORD rgdwPOV[4]; - BYTE rgbButtons[128]; - LONG lVX; /* 'v' as in velocity */ - LONG lVY; - LONG lVZ; - LONG lVRx; - LONG lVRy; - LONG lVRz; - LONG rglVSlider[2]; - LONG lAX; /* 'a' as in acceleration */ - LONG lAY; - LONG lAZ; - LONG lARx; - LONG lARy; - LONG lARz; - LONG rglASlider[2]; - LONG lFX; /* 'f' as in force */ - LONG lFY; - LONG lFZ; - LONG lFRx; /* 'fr' as in rotational force aka torque */ - LONG lFRy; - LONG lFRz; - LONG rglFSlider[2]; -} DIJOYSTATE2, *LPDIJOYSTATE2; - -#define DIJOFS_X FIELD_OFFSET(DIJOYSTATE, lX) -#define DIJOFS_Y FIELD_OFFSET(DIJOYSTATE, lY) -#define DIJOFS_Z FIELD_OFFSET(DIJOYSTATE, lZ) -#define DIJOFS_RX FIELD_OFFSET(DIJOYSTATE, lRx) -#define DIJOFS_RY FIELD_OFFSET(DIJOYSTATE, lRy) -#define DIJOFS_RZ FIELD_OFFSET(DIJOYSTATE, lRz) -#define DIJOFS_SLIDER(n) (FIELD_OFFSET(DIJOYSTATE, rglSlider) + \ - (n) * sizeof(LONG)) -#define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE, rgdwPOV) + \ - (n) * sizeof(DWORD)) -#define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE, rgbButtons) + (n)) -#define DIJOFS_BUTTON0 DIJOFS_BUTTON(0) -#define DIJOFS_BUTTON1 DIJOFS_BUTTON(1) -#define DIJOFS_BUTTON2 DIJOFS_BUTTON(2) -#define DIJOFS_BUTTON3 DIJOFS_BUTTON(3) -#define DIJOFS_BUTTON4 DIJOFS_BUTTON(4) -#define DIJOFS_BUTTON5 DIJOFS_BUTTON(5) -#define DIJOFS_BUTTON6 DIJOFS_BUTTON(6) -#define DIJOFS_BUTTON7 DIJOFS_BUTTON(7) -#define DIJOFS_BUTTON8 DIJOFS_BUTTON(8) -#define DIJOFS_BUTTON9 DIJOFS_BUTTON(9) -#define DIJOFS_BUTTON10 DIJOFS_BUTTON(10) -#define DIJOFS_BUTTON11 DIJOFS_BUTTON(11) -#define DIJOFS_BUTTON12 DIJOFS_BUTTON(12) -#define DIJOFS_BUTTON13 DIJOFS_BUTTON(13) -#define DIJOFS_BUTTON14 DIJOFS_BUTTON(14) -#define DIJOFS_BUTTON15 DIJOFS_BUTTON(15) -#define DIJOFS_BUTTON16 DIJOFS_BUTTON(16) -#define DIJOFS_BUTTON17 DIJOFS_BUTTON(17) -#define DIJOFS_BUTTON18 DIJOFS_BUTTON(18) -#define DIJOFS_BUTTON19 DIJOFS_BUTTON(19) -#define DIJOFS_BUTTON20 DIJOFS_BUTTON(20) -#define DIJOFS_BUTTON21 DIJOFS_BUTTON(21) -#define DIJOFS_BUTTON22 DIJOFS_BUTTON(22) -#define DIJOFS_BUTTON23 DIJOFS_BUTTON(23) -#define DIJOFS_BUTTON24 DIJOFS_BUTTON(24) -#define DIJOFS_BUTTON25 DIJOFS_BUTTON(25) -#define DIJOFS_BUTTON26 DIJOFS_BUTTON(26) -#define DIJOFS_BUTTON27 DIJOFS_BUTTON(27) -#define DIJOFS_BUTTON28 DIJOFS_BUTTON(28) -#define DIJOFS_BUTTON29 DIJOFS_BUTTON(29) -#define DIJOFS_BUTTON30 DIJOFS_BUTTON(30) -#define DIJOFS_BUTTON31 DIJOFS_BUTTON(31) -#endif /* DIRECTINPUT_VERSION >= 0x0500 */ - -/* DInput 7 structures, types */ -#if(DIRECTINPUT_VERSION >= 0x0700) -typedef struct DIFILEEFFECT { - DWORD dwSize; - GUID GuidEffect; - LPCDIEFFECT lpDiEffect; - CHAR szFriendlyName[MAX_PATH]; -} DIFILEEFFECT, *LPDIFILEEFFECT; - -typedef const DIFILEEFFECT *LPCDIFILEEFFECT; -typedef BOOL (CALLBACK *LPDIENUMEFFECTSINFILECALLBACK)(LPCDIFILEEFFECT , LPVOID); -#endif /* DIRECTINPUT_VERSION >= 0x0700 */ - -/* DInput 8 structures and types */ -#if DIRECTINPUT_VERSION >= 0x0800 -typedef struct _DIACTIONA { - UINT_PTR uAppData; - DWORD dwSemantic; - DWORD dwFlags; - __GNU_EXTENSION union { - LPCSTR lptszActionName; - UINT uResIdString; - } DUMMYUNIONNAME; - GUID guidInstance; - DWORD dwObjID; - DWORD dwHow; -} DIACTIONA, *LPDIACTIONA; -typedef const DIACTIONA *LPCDIACTIONA; - -typedef struct _DIACTIONW { - UINT_PTR uAppData; - DWORD dwSemantic; - DWORD dwFlags; - __GNU_EXTENSION union { - LPCWSTR lptszActionName; - UINT uResIdString; - } DUMMYUNIONNAME; - GUID guidInstance; - DWORD dwObjID; - DWORD dwHow; -} DIACTIONW, *LPDIACTIONW; -typedef const DIACTIONW *LPCDIACTIONW; - -DECL_WINELIB_TYPE_AW(DIACTION) -DECL_WINELIB_TYPE_AW(LPDIACTION) -DECL_WINELIB_TYPE_AW(LPCDIACTION) - -#define DIA_FORCEFEEDBACK 0x00000001 -#define DIA_APPMAPPED 0x00000002 -#define DIA_APPNOMAP 0x00000004 -#define DIA_NORANGE 0x00000008 -#define DIA_APPFIXED 0x00000010 - -#define DIAH_UNMAPPED 0x00000000 -#define DIAH_USERCONFIG 0x00000001 -#define DIAH_APPREQUESTED 0x00000002 -#define DIAH_HWAPP 0x00000004 -#define DIAH_HWDEFAULT 0x00000008 -#define DIAH_DEFAULT 0x00000020 -#define DIAH_ERROR 0x80000000 - -typedef struct _DIACTIONFORMATA { - DWORD dwSize; - DWORD dwActionSize; - DWORD dwDataSize; - DWORD dwNumActions; - LPDIACTIONA rgoAction; - GUID guidActionMap; - DWORD dwGenre; - DWORD dwBufferSize; - LONG lAxisMin; - LONG lAxisMax; - HINSTANCE hInstString; - FILETIME ftTimeStamp; - DWORD dwCRC; - CHAR tszActionMap[MAX_PATH]; -} DIACTIONFORMATA, *LPDIACTIONFORMATA; -typedef const DIACTIONFORMATA *LPCDIACTIONFORMATA; - -typedef struct _DIACTIONFORMATW { - DWORD dwSize; - DWORD dwActionSize; - DWORD dwDataSize; - DWORD dwNumActions; - LPDIACTIONW rgoAction; - GUID guidActionMap; - DWORD dwGenre; - DWORD dwBufferSize; - LONG lAxisMin; - LONG lAxisMax; - HINSTANCE hInstString; - FILETIME ftTimeStamp; - DWORD dwCRC; - WCHAR tszActionMap[MAX_PATH]; -} DIACTIONFORMATW, *LPDIACTIONFORMATW; -typedef const DIACTIONFORMATW *LPCDIACTIONFORMATW; - -DECL_WINELIB_TYPE_AW(DIACTIONFORMAT) -DECL_WINELIB_TYPE_AW(LPDIACTIONFORMAT) -DECL_WINELIB_TYPE_AW(LPCDIACTIONFORMAT) - -#define DIAFTS_NEWDEVICELOW 0xFFFFFFFF -#define DIAFTS_NEWDEVICEHIGH 0xFFFFFFFF -#define DIAFTS_UNUSEDDEVICELOW 0x00000000 -#define DIAFTS_UNUSEDDEVICEHIGH 0x00000000 - -#define DIDBAM_DEFAULT 0x00000000 -#define DIDBAM_PRESERVE 0x00000001 -#define DIDBAM_INITIALIZE 0x00000002 -#define DIDBAM_HWDEFAULTS 0x00000004 - -#define DIDSAM_DEFAULT 0x00000000 -#define DIDSAM_NOUSER 0x00000001 -#define DIDSAM_FORCESAVE 0x00000002 - -#define DICD_DEFAULT 0x00000000 -#define DICD_EDIT 0x00000001 - -#ifndef D3DCOLOR_DEFINED -typedef DWORD D3DCOLOR; -#define D3DCOLOR_DEFINED -#endif - -typedef struct _DICOLORSET { - DWORD dwSize; - D3DCOLOR cTextFore; - D3DCOLOR cTextHighlight; - D3DCOLOR cCalloutLine; - D3DCOLOR cCalloutHighlight; - D3DCOLOR cBorder; - D3DCOLOR cControlFill; - D3DCOLOR cHighlightFill; - D3DCOLOR cAreaFill; -} DICOLORSET, *LPDICOLORSET; -typedef const DICOLORSET *LPCDICOLORSET; - -typedef struct _DICONFIGUREDEVICESPARAMSA { - DWORD dwSize; - DWORD dwcUsers; - LPSTR lptszUserNames; - DWORD dwcFormats; - LPDIACTIONFORMATA lprgFormats; - HWND hwnd; - DICOLORSET dics; - LPUNKNOWN lpUnkDDSTarget; -} DICONFIGUREDEVICESPARAMSA, *LPDICONFIGUREDEVICESPARAMSA; -typedef const DICONFIGUREDEVICESPARAMSA *LPCDICONFIGUREDEVICESPARAMSA; - -typedef struct _DICONFIGUREDEVICESPARAMSW { - DWORD dwSize; - DWORD dwcUsers; - LPWSTR lptszUserNames; - DWORD dwcFormats; - LPDIACTIONFORMATW lprgFormats; - HWND hwnd; - DICOLORSET dics; - LPUNKNOWN lpUnkDDSTarget; -} DICONFIGUREDEVICESPARAMSW, *LPDICONFIGUREDEVICESPARAMSW; -typedef const DICONFIGUREDEVICESPARAMSW *LPCDICONFIGUREDEVICESPARAMSW; - -DECL_WINELIB_TYPE_AW(DICONFIGUREDEVICESPARAMS) -DECL_WINELIB_TYPE_AW(LPDICONFIGUREDEVICESPARAMS) -DECL_WINELIB_TYPE_AW(LPCDICONFIGUREDEVICESPARAMS) - -#define DIDIFT_CONFIGURATION 0x00000001 -#define DIDIFT_OVERLAY 0x00000002 - -#define DIDAL_CENTERED 0x00000000 -#define DIDAL_LEFTALIGNED 0x00000001 -#define DIDAL_RIGHTALIGNED 0x00000002 -#define DIDAL_MIDDLE 0x00000000 -#define DIDAL_TOPALIGNED 0x00000004 -#define DIDAL_BOTTOMALIGNED 0x00000008 - -typedef struct _DIDEVICEIMAGEINFOA { - CHAR tszImagePath[MAX_PATH]; - DWORD dwFlags; - DWORD dwViewID; - RECT rcOverlay; - DWORD dwObjID; - DWORD dwcValidPts; - POINT rgptCalloutLine[5]; - RECT rcCalloutRect; - DWORD dwTextAlign; -} DIDEVICEIMAGEINFOA, *LPDIDEVICEIMAGEINFOA; -typedef const DIDEVICEIMAGEINFOA *LPCDIDEVICEIMAGEINFOA; - -typedef struct _DIDEVICEIMAGEINFOW { - WCHAR tszImagePath[MAX_PATH]; - DWORD dwFlags; - DWORD dwViewID; - RECT rcOverlay; - DWORD dwObjID; - DWORD dwcValidPts; - POINT rgptCalloutLine[5]; - RECT rcCalloutRect; - DWORD dwTextAlign; -} DIDEVICEIMAGEINFOW, *LPDIDEVICEIMAGEINFOW; -typedef const DIDEVICEIMAGEINFOW *LPCDIDEVICEIMAGEINFOW; - -DECL_WINELIB_TYPE_AW(DIDEVICEIMAGEINFO) -DECL_WINELIB_TYPE_AW(LPDIDEVICEIMAGEINFO) -DECL_WINELIB_TYPE_AW(LPCDIDEVICEIMAGEINFO) - -typedef struct _DIDEVICEIMAGEINFOHEADERA { - DWORD dwSize; - DWORD dwSizeImageInfo; - DWORD dwcViews; - DWORD dwcButtons; - DWORD dwcAxes; - DWORD dwcPOVs; - DWORD dwBufferSize; - DWORD dwBufferUsed; - LPDIDEVICEIMAGEINFOA lprgImageInfoArray; -} DIDEVICEIMAGEINFOHEADERA, *LPDIDEVICEIMAGEINFOHEADERA; -typedef const DIDEVICEIMAGEINFOHEADERA *LPCDIDEVICEIMAGEINFOHEADERA; - -typedef struct _DIDEVICEIMAGEINFOHEADERW { - DWORD dwSize; - DWORD dwSizeImageInfo; - DWORD dwcViews; - DWORD dwcButtons; - DWORD dwcAxes; - DWORD dwcPOVs; - DWORD dwBufferSize; - DWORD dwBufferUsed; - LPDIDEVICEIMAGEINFOW lprgImageInfoArray; -} DIDEVICEIMAGEINFOHEADERW, *LPDIDEVICEIMAGEINFOHEADERW; -typedef const DIDEVICEIMAGEINFOHEADERW *LPCDIDEVICEIMAGEINFOHEADERW; - -DECL_WINELIB_TYPE_AW(DIDEVICEIMAGEINFOHEADER) -DECL_WINELIB_TYPE_AW(LPDIDEVICEIMAGEINFOHEADER) -DECL_WINELIB_TYPE_AW(LPCDIDEVICEIMAGEINFOHEADER) - -#endif /* DI8 */ - - -/***************************************************************************** - * IDirectInputEffect interface - */ -#if (DIRECTINPUT_VERSION >= 0x0500) -#undef INTERFACE -#define INTERFACE IDirectInputEffect -DECLARE_INTERFACE_(IDirectInputEffect,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputEffect methods ***/ - STDMETHOD(Initialize)(THIS_ HINSTANCE, DWORD, REFGUID) PURE; - STDMETHOD(GetEffectGuid)(THIS_ LPGUID) PURE; - STDMETHOD(GetParameters)(THIS_ LPDIEFFECT, DWORD) PURE; - STDMETHOD(SetParameters)(THIS_ LPCDIEFFECT, DWORD) PURE; - STDMETHOD(Start)(THIS_ DWORD, DWORD) PURE; - STDMETHOD(Stop)(THIS) PURE; - STDMETHOD(GetEffectStatus)(THIS_ LPDWORD) PURE; - STDMETHOD(Download)(THIS) PURE; - STDMETHOD(Unload)(THIS) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInputEffect_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInputEffect_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInputEffect_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInputEffect methods ***/ -#define IDirectInputEffect_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) -#define IDirectInputEffect_GetEffectGuid(p,a) (p)->lpVtbl->GetEffectGuid(p,a) -#define IDirectInputEffect_GetParameters(p,a,b) (p)->lpVtbl->GetParameters(p,a,b) -#define IDirectInputEffect_SetParameters(p,a,b) (p)->lpVtbl->SetParameters(p,a,b) -#define IDirectInputEffect_Start(p,a,b) (p)->lpVtbl->Start(p,a,b) -#define IDirectInputEffect_Stop(p) (p)->lpVtbl->Stop(p) -#define IDirectInputEffect_GetEffectStatus(p,a) (p)->lpVtbl->GetEffectStatus(p,a) -#define IDirectInputEffect_Download(p) (p)->lpVtbl->Download(p) -#define IDirectInputEffect_Unload(p) (p)->lpVtbl->Unload(p) -#define IDirectInputEffect_Escape(p,a) (p)->lpVtbl->Escape(p,a) -#else -/*** IUnknown methods ***/ -#define IDirectInputEffect_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInputEffect_AddRef(p) (p)->AddRef() -#define IDirectInputEffect_Release(p) (p)->Release() -/*** IDirectInputEffect methods ***/ -#define IDirectInputEffect_Initialize(p,a,b,c) (p)->Initialize(a,b,c) -#define IDirectInputEffect_GetEffectGuid(p,a) (p)->GetEffectGuid(a) -#define IDirectInputEffect_GetParameters(p,a,b) (p)->GetParameters(a,b) -#define IDirectInputEffect_SetParameters(p,a,b) (p)->SetParameters(a,b) -#define IDirectInputEffect_Start(p,a,b) (p)->Start(a,b) -#define IDirectInputEffect_Stop(p) (p)->Stop() -#define IDirectInputEffect_GetEffectStatus(p,a) (p)->GetEffectStatus(a) -#define IDirectInputEffect_Download(p) (p)->Download() -#define IDirectInputEffect_Unload(p) (p)->Unload() -#define IDirectInputEffect_Escape(p,a) (p)->Escape(a) -#endif - -#endif /* DI5 */ - - -/***************************************************************************** - * IDirectInputDeviceA interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDeviceA -DECLARE_INTERFACE_(IDirectInputDeviceA,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceA methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; -}; - -/***************************************************************************** - * IDirectInputDeviceW interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDeviceW -DECLARE_INTERFACE_(IDirectInputDeviceW,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceW methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInputDevice_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInputDevice_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInputDevice_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) -#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) -#define IDirectInputDevice_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) -#define IDirectInputDevice_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) -#define IDirectInputDevice_Acquire(p) (p)->lpVtbl->Acquire(p) -#define IDirectInputDevice_Unacquire(p) (p)->lpVtbl->Unacquire(p) -#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) -#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) -#define IDirectInputDevice_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) -#define IDirectInputDevice_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) -#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) -#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) -#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) -#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInputDevice_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) -#else -/*** IUnknown methods ***/ -#define IDirectInputDevice_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInputDevice_AddRef(p) (p)->AddRef() -#define IDirectInputDevice_Release(p) (p)->Release() -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice_GetCapabilities(p,a) (p)->GetCapabilities(a) -#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) -#define IDirectInputDevice_GetProperty(p,a,b) (p)->GetProperty(a,b) -#define IDirectInputDevice_SetProperty(p,a,b) (p)->SetProperty(a,b) -#define IDirectInputDevice_Acquire(p) (p)->Acquire() -#define IDirectInputDevice_Unacquire(p) (p)->Unacquire() -#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) -#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) -#define IDirectInputDevice_SetDataFormat(p,a) (p)->SetDataFormat(a) -#define IDirectInputDevice_SetEventNotification(p,a) (p)->SetEventNotification(a) -#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) -#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) -#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) -#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInputDevice_Initialize(p,a,b,c) (p)->Initialize(a,b,c) -#endif - - -#if (DIRECTINPUT_VERSION >= 0x0500) -/***************************************************************************** - * IDirectInputDevice2A interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDevice2A -DECLARE_INTERFACE_(IDirectInputDevice2A,IDirectInputDeviceA) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceA methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; - /*** IDirectInputDevice2A methods ***/ - STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE; - STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE; - STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE; - STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE; - STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE; - STDMETHOD(Poll)(THIS) PURE; - STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE; -}; - -/***************************************************************************** - * IDirectInputDevice2W interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDevice2W -DECLARE_INTERFACE_(IDirectInputDevice2W,IDirectInputDeviceW) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceW methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; - /*** IDirectInputDevice2W methods ***/ - STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE; - STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE; - STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE; - STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE; - STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE; - STDMETHOD(Poll)(THIS) PURE; - STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInputDevice2_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInputDevice2_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice2_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) -#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) -#define IDirectInputDevice2_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) -#define IDirectInputDevice2_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) -#define IDirectInputDevice2_Acquire(p) (p)->lpVtbl->Acquire(p) -#define IDirectInputDevice2_Unacquire(p) (p)->lpVtbl->Unacquire(p) -#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) -#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) -#define IDirectInputDevice2_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) -#define IDirectInputDevice2_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) -#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) -#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) -#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) -#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) -/*** IDirectInputDevice2 methods ***/ -#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d) -#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c) -#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b) -#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a) -#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a) -#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c) -#define IDirectInputDevice2_Escape(p,a) (p)->lpVtbl->Escape(p,a) -#define IDirectInputDevice2_Poll(p) (p)->lpVtbl->Poll(p) -#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d) -#else -/*** IUnknown methods ***/ -#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInputDevice2_AddRef(p) (p)->AddRef() -#define IDirectInputDevice2_Release(p) (p)->Release() -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice2_GetCapabilities(p,a) (p)->GetCapabilities(a) -#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) -#define IDirectInputDevice2_GetProperty(p,a,b) (p)->GetProperty(a,b) -#define IDirectInputDevice2_SetProperty(p,a,b) (p)->SetProperty(a,b) -#define IDirectInputDevice2_Acquire(p) (p)->Acquire() -#define IDirectInputDevice2_Unacquire(p) (p)->Unacquire() -#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) -#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) -#define IDirectInputDevice2_SetDataFormat(p,a) (p)->SetDataFormat(a) -#define IDirectInputDevice2_SetEventNotification(p,a) (p)->SetEventNotification(a) -#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) -#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) -#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) -#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->Initialize(a,b,c) -/*** IDirectInputDevice2 methods ***/ -#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d) -#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c) -#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b) -#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a) -#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a) -#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c) -#define IDirectInputDevice2_Escape(p,a) (p)->Escape(a) -#define IDirectInputDevice2_Poll(p) (p)->Poll() -#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d) -#endif -#endif /* DI5 */ - -#if DIRECTINPUT_VERSION >= 0x0700 -/***************************************************************************** - * IDirectInputDevice7A interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDevice7A -DECLARE_INTERFACE_(IDirectInputDevice7A,IDirectInputDevice2A) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceA methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; - /*** IDirectInputDevice2A methods ***/ - STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE; - STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE; - STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE; - STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE; - STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE; - STDMETHOD(Poll)(THIS) PURE; - STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE; - /*** IDirectInputDevice7A methods ***/ - STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE; - STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE; -}; - -/***************************************************************************** - * IDirectInputDevice7W interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDevice7W -DECLARE_INTERFACE_(IDirectInputDevice7W,IDirectInputDevice2W) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceW methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; - /*** IDirectInputDevice2W methods ***/ - STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE; - STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE; - STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE; - STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE; - STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE; - STDMETHOD(Poll)(THIS) PURE; - STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE; - /*** IDirectInputDevice7W methods ***/ - STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE; - STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInputDevice7_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInputDevice7_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice7_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) -#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) -#define IDirectInputDevice7_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) -#define IDirectInputDevice7_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) -#define IDirectInputDevice7_Acquire(p) (p)->lpVtbl->Acquire(p) -#define IDirectInputDevice7_Unacquire(p) (p)->lpVtbl->Unacquire(p) -#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) -#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) -#define IDirectInputDevice7_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) -#define IDirectInputDevice7_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) -#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) -#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) -#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) -#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) -/*** IDirectInputDevice2 methods ***/ -#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d) -#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c) -#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b) -#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a) -#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a) -#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c) -#define IDirectInputDevice7_Escape(p,a) (p)->lpVtbl->Escape(p,a) -#define IDirectInputDevice7_Poll(p) (p)->lpVtbl->Poll(p) -#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d) -/*** IDirectInputDevice7 methods ***/ -#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d) -#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d) -#else -/*** IUnknown methods ***/ -#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInputDevice7_AddRef(p) (p)->AddRef() -#define IDirectInputDevice7_Release(p) (p)->Release() -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice7_GetCapabilities(p,a) (p)->GetCapabilities(a) -#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) -#define IDirectInputDevice7_GetProperty(p,a,b) (p)->GetProperty(a,b) -#define IDirectInputDevice7_SetProperty(p,a,b) (p)->SetProperty(a,b) -#define IDirectInputDevice7_Acquire(p) (p)->Acquire() -#define IDirectInputDevice7_Unacquire(p) (p)->Unacquire() -#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) -#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) -#define IDirectInputDevice7_SetDataFormat(p,a) (p)->SetDataFormat(a) -#define IDirectInputDevice7_SetEventNotification(p,a) (p)->SetEventNotification(a) -#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) -#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) -#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) -#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->Initialize(a,b,c) -/*** IDirectInputDevice2 methods ***/ -#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d) -#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c) -#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b) -#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a) -#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a) -#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c) -#define IDirectInputDevice7_Escape(p,a) (p)->Escape(a) -#define IDirectInputDevice7_Poll(p) (p)->Poll() -#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d) -/*** IDirectInputDevice7 methods ***/ -#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d) -#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d) -#endif - -#endif /* DI7 */ - -#if DIRECTINPUT_VERSION >= 0x0800 -/***************************************************************************** - * IDirectInputDevice8A interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDevice8A -DECLARE_INTERFACE_(IDirectInputDevice8A,IDirectInputDevice7A) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceA methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; - /*** IDirectInputDevice2A methods ***/ - STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE; - STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE; - STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE; - STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE; - STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE; - STDMETHOD(Poll)(THIS) PURE; - STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE; - /*** IDirectInputDevice7A methods ***/ - STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE; - STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE; - /*** IDirectInputDevice8A methods ***/ - STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) PURE; - STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) PURE; - STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader) PURE; -}; - -/***************************************************************************** - * IDirectInputDevice8W interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputDevice8W -DECLARE_INTERFACE_(IDirectInputDevice8W,IDirectInputDevice7W) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputDeviceW methods ***/ - STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE; - STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE; - STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE; - STDMETHOD(Acquire)(THIS) PURE; - STDMETHOD(Unacquire)(THIS) PURE; - STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE; - STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE; - STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE; - STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE; - STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE; - STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE; - /*** IDirectInputDevice2W methods ***/ - STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE; - STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE; - STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE; - STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE; - STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE; - STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE; - STDMETHOD(Poll)(THIS) PURE; - STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE; - /*** IDirectInputDevice7W methods ***/ - STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE; - STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE; - /*** IDirectInputDevice8W methods ***/ - STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) PURE; - STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) PURE; - STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInputDevice8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInputDevice8_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice8_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) -#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) -#define IDirectInputDevice8_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) -#define IDirectInputDevice8_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) -#define IDirectInputDevice8_Acquire(p) (p)->lpVtbl->Acquire(p) -#define IDirectInputDevice8_Unacquire(p) (p)->lpVtbl->Unacquire(p) -#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) -#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) -#define IDirectInputDevice8_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) -#define IDirectInputDevice8_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) -#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) -#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) -#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) -#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) -/*** IDirectInputDevice2 methods ***/ -#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d) -#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c) -#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b) -#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a) -#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a) -#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c) -#define IDirectInputDevice8_Escape(p,a) (p)->lpVtbl->Escape(p,a) -#define IDirectInputDevice8_Poll(p) (p)->lpVtbl->Poll(p) -#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d) -/*** IDirectInputDevice7 methods ***/ -#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d) -#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d) -/*** IDirectInputDevice8 methods ***/ -#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->lpVtbl->BuildActionMap(p,a,b,c) -#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->lpVtbl->SetActionMap(p,a,b,c) -#define IDirectInputDevice8_GetImageInfo(p,a) (p)->lpVtbl->GetImageInfo(p,a) -#else -/*** IUnknown methods ***/ -#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInputDevice8_AddRef(p) (p)->AddRef() -#define IDirectInputDevice8_Release(p) (p)->Release() -/*** IDirectInputDevice methods ***/ -#define IDirectInputDevice8_GetCapabilities(p,a) (p)->GetCapabilities(a) -#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) -#define IDirectInputDevice8_GetProperty(p,a,b) (p)->GetProperty(a,b) -#define IDirectInputDevice8_SetProperty(p,a,b) (p)->SetProperty(a,b) -#define IDirectInputDevice8_Acquire(p) (p)->Acquire() -#define IDirectInputDevice8_Unacquire(p) (p)->Unacquire() -#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) -#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) -#define IDirectInputDevice8_SetDataFormat(p,a) (p)->SetDataFormat(a) -#define IDirectInputDevice8_SetEventNotification(p,a) (p)->SetEventNotification(a) -#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) -#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) -#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) -#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->Initialize(a,b,c) -/*** IDirectInputDevice2 methods ***/ -#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d) -#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c) -#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b) -#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a) -#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a) -#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c) -#define IDirectInputDevice8_Escape(p,a) (p)->Escape(a) -#define IDirectInputDevice8_Poll(p) (p)->Poll() -#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d) -/*** IDirectInputDevice7 methods ***/ -#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d) -#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d) -/*** IDirectInputDevice8 methods ***/ -#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->BuildActionMap(a,b,c) -#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->SetActionMap(a,b,c) -#define IDirectInputDevice8_GetImageInfo(p,a) (p)->GetImageInfo(a) -#endif - -#endif /* DI8 */ - -/* "Standard" Mouse report... */ -typedef struct DIMOUSESTATE { - LONG lX; - LONG lY; - LONG lZ; - BYTE rgbButtons[4]; -} DIMOUSESTATE; - -#if DIRECTINPUT_VERSION >= 0x0700 -/* "Standard" Mouse report for DInput 7... */ -typedef struct DIMOUSESTATE2 { - LONG lX; - LONG lY; - LONG lZ; - BYTE rgbButtons[8]; -} DIMOUSESTATE2; -#endif /* DI7 */ - -#define DIMOFS_X FIELD_OFFSET(DIMOUSESTATE, lX) -#define DIMOFS_Y FIELD_OFFSET(DIMOUSESTATE, lY) -#define DIMOFS_Z FIELD_OFFSET(DIMOUSESTATE, lZ) -#define DIMOFS_BUTTON0 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 0) -#define DIMOFS_BUTTON1 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 1) -#define DIMOFS_BUTTON2 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 2) -#define DIMOFS_BUTTON3 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 3) -#if DIRECTINPUT_VERSION >= 0x0700 -#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4) -#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5) -#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6) -#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7) -#endif /* DI7 */ - -#ifdef __cplusplus -extern "C" { -#endif -extern const DIDATAFORMAT c_dfDIMouse; -#if DIRECTINPUT_VERSION >= 0x0700 -extern const DIDATAFORMAT c_dfDIMouse2; /* DX 7 */ -#endif /* DI7 */ -extern const DIDATAFORMAT c_dfDIKeyboard; -#if DIRECTINPUT_VERSION >= 0x0500 -extern const DIDATAFORMAT c_dfDIJoystick; -extern const DIDATAFORMAT c_dfDIJoystick2; -#endif /* DI5 */ -#ifdef __cplusplus -}; -#endif - -/***************************************************************************** - * IDirectInputA interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputA -DECLARE_INTERFACE_(IDirectInputA,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputA methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; -}; - -/***************************************************************************** - * IDirectInputW interface - */ -#undef INTERFACE -#define INTERFACE IDirectInputW -DECLARE_INTERFACE_(IDirectInputW,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputW methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInput_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInput methods ***/ -#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) -#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) -#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) -#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -#else -/*** IUnknown methods ***/ -#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInput_AddRef(p) (p)->AddRef() -#define IDirectInput_Release(p) (p)->Release() -/*** IDirectInput methods ***/ -#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) -#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) -#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) -#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b) -#endif - -/***************************************************************************** - * IDirectInput2A interface - */ -#undef INTERFACE -#define INTERFACE IDirectInput2A -DECLARE_INTERFACE_(IDirectInput2A,IDirectInputA) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputA methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; - /*** IDirectInput2A methods ***/ - STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE; -}; - -/***************************************************************************** - * IDirectInput2W interface - */ -#undef INTERFACE -#define INTERFACE IDirectInput2W -DECLARE_INTERFACE_(IDirectInput2W,IDirectInputW) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputW methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; - /*** IDirectInput2W methods ***/ - STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInput2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInput2_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInput2_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInput methods ***/ -#define IDirectInput2_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) -#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) -#define IDirectInput2_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) -#define IDirectInput2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInput2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -/*** IDirectInput2 methods ***/ -#define IDirectInput2_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c) -#else -/*** IUnknown methods ***/ -#define IDirectInput2_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInput2_AddRef(p) (p)->AddRef() -#define IDirectInput2_Release(p) (p)->Release() -/*** IDirectInput methods ***/ -#define IDirectInput2_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) -#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) -#define IDirectInput2_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) -#define IDirectInput2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInput2_Initialize(p,a,b) (p)->Initialize(a,b) -/*** IDirectInput2 methods ***/ -#define IDirectInput2_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c) -#endif - -/***************************************************************************** - * IDirectInput7A interface - */ -#undef INTERFACE -#define INTERFACE IDirectInput7A -DECLARE_INTERFACE_(IDirectInput7A,IDirectInput2A) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputA methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; - /*** IDirectInput2A methods ***/ - STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE; - /*** IDirectInput7A methods ***/ - STDMETHOD(CreateDeviceEx)(THIS_ REFGUID rguid, REFIID riid, LPVOID *pvOut, LPUNKNOWN lpUnknownOuter) PURE; -}; - -/***************************************************************************** - * IDirectInput7W interface - */ -#undef INTERFACE -#define INTERFACE IDirectInput7W -DECLARE_INTERFACE_(IDirectInput7W,IDirectInput2W) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInputW methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; - /*** IDirectInput2W methods ***/ - STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE; - /*** IDirectInput7W methods ***/ - STDMETHOD(CreateDeviceEx)(THIS_ REFGUID rguid, REFIID riid, LPVOID *pvOut, LPUNKNOWN lpUnknownOuter) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInput7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInput7_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInput7_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInput methods ***/ -#define IDirectInput7_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) -#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) -#define IDirectInput7_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) -#define IDirectInput7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInput7_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -/*** IDirectInput2 methods ***/ -#define IDirectInput7_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c) -/*** IDirectInput7 methods ***/ -#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d) -#else -/*** IUnknown methods ***/ -#define IDirectInput7_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInput7_AddRef(p) (p)->AddRef() -#define IDirectInput7_Release(p) (p)->Release() -/*** IDirectInput methods ***/ -#define IDirectInput7_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) -#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) -#define IDirectInput7_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) -#define IDirectInput7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInput7_Initialize(p,a,b) (p)->Initialize(a,b) -/*** IDirectInput2 methods ***/ -#define IDirectInput7_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c) -/*** IDirectInput7 methods ***/ -#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->CreateDeviceEx(a,b,c,d) -#endif - - -#if DIRECTINPUT_VERSION >= 0x0800 -/***************************************************************************** - * IDirectInput8A interface - */ -#undef INTERFACE -#define INTERFACE IDirectInput8A -DECLARE_INTERFACE_(IDirectInput8A,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInput8A methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8A *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; - STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE; - STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE; -}; - -/***************************************************************************** - * IDirectInput8W interface - */ -#undef INTERFACE -#define INTERFACE IDirectInput8W -DECLARE_INTERFACE_(IDirectInput8W,IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectInput8W methods ***/ - STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8W *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE; - STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE; - STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE; - STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; - STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE; - STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE; - STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE; -}; -#undef INTERFACE - -#if !defined(__cplusplus) || defined(CINTERFACE) -/*** IUnknown methods ***/ -#define IDirectInput8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectInput8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectInput8_Release(p) (p)->lpVtbl->Release(p) -/*** IDirectInput8 methods ***/ -#define IDirectInput8_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) -#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) -#define IDirectInput8_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) -#define IDirectInput8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) -#define IDirectInput8_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -#define IDirectInput8_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c) -#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->lpVtbl->EnumDevicesBySemantics(p,a,b,c,d,e) -#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->lpVtbl->ConfigureDevices(p,a,b,c,d) -#else -/*** IUnknown methods ***/ -#define IDirectInput8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirectInput8_AddRef(p) (p)->AddRef() -#define IDirectInput8_Release(p) (p)->Release() -/*** IDirectInput8 methods ***/ -#define IDirectInput8_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) -#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) -#define IDirectInput8_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) -#define IDirectInput8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) -#define IDirectInput8_Initialize(p,a,b) (p)->Initialize(a,b) -#define IDirectInput8_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c) -#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->EnumDevicesBySemantics(a,b,c,d,e) -#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->ConfigureDevices(a,b,c,d) -#endif - -#endif /* DI8 */ - -/* Export functions */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if DIRECTINPUT_VERSION >= 0x0800 -HRESULT WINAPI DirectInput8Create(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN); -#else /* DI < 8 */ -HRESULT WINAPI DirectInputCreateA(HINSTANCE,DWORD,LPDIRECTINPUTA *,LPUNKNOWN); -HRESULT WINAPI DirectInputCreateW(HINSTANCE,DWORD,LPDIRECTINPUTW *,LPUNKNOWN); -#define DirectInputCreate WINELIB_NAME_AW(DirectInputCreate) - -HRESULT WINAPI DirectInputCreateEx(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN); -#endif /* DI8 */ - -#ifdef __cplusplus -}; -#endif - -#endif /* __DINPUT_INCLUDED__ */ diff --git a/raylib/external/glfw/deps/mingw/xinput.h b/raylib/external/glfw/deps/mingw/xinput.h deleted file mode 100644 index d3ca726..0000000 --- a/raylib/external/glfw/deps/mingw/xinput.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * The Wine project - Xinput Joystick Library - * Copyright 2008 Andrew Fenn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __WINE_XINPUT_H -#define __WINE_XINPUT_H - -#include - -/* - * Bitmasks for the joysticks buttons, determines what has - * been pressed on the joystick, these need to be mapped - * to whatever device you're using instead of an xbox 360 - * joystick - */ - -#define XINPUT_GAMEPAD_DPAD_UP 0x0001 -#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 -#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 -#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 -#define XINPUT_GAMEPAD_START 0x0010 -#define XINPUT_GAMEPAD_BACK 0x0020 -#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 -#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 -#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 -#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 -#define XINPUT_GAMEPAD_A 0x1000 -#define XINPUT_GAMEPAD_B 0x2000 -#define XINPUT_GAMEPAD_X 0x4000 -#define XINPUT_GAMEPAD_Y 0x8000 - -/* - * Defines the flags used to determine if the user is pushing - * down on a button, not holding a button, etc - */ - -#define XINPUT_KEYSTROKE_KEYDOWN 0x0001 -#define XINPUT_KEYSTROKE_KEYUP 0x0002 -#define XINPUT_KEYSTROKE_REPEAT 0x0004 - -/* - * Defines the codes which are returned by XInputGetKeystroke - */ - -#define VK_PAD_A 0x5800 -#define VK_PAD_B 0x5801 -#define VK_PAD_X 0x5802 -#define VK_PAD_Y 0x5803 -#define VK_PAD_RSHOULDER 0x5804 -#define VK_PAD_LSHOULDER 0x5805 -#define VK_PAD_LTRIGGER 0x5806 -#define VK_PAD_RTRIGGER 0x5807 -#define VK_PAD_DPAD_UP 0x5810 -#define VK_PAD_DPAD_DOWN 0x5811 -#define VK_PAD_DPAD_LEFT 0x5812 -#define VK_PAD_DPAD_RIGHT 0x5813 -#define VK_PAD_START 0x5814 -#define VK_PAD_BACK 0x5815 -#define VK_PAD_LTHUMB_PRESS 0x5816 -#define VK_PAD_RTHUMB_PRESS 0x5817 -#define VK_PAD_LTHUMB_UP 0x5820 -#define VK_PAD_LTHUMB_DOWN 0x5821 -#define VK_PAD_LTHUMB_RIGHT 0x5822 -#define VK_PAD_LTHUMB_LEFT 0x5823 -#define VK_PAD_LTHUMB_UPLEFT 0x5824 -#define VK_PAD_LTHUMB_UPRIGHT 0x5825 -#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826 -#define VK_PAD_LTHUMB_DOWNLEFT 0x5827 -#define VK_PAD_RTHUMB_UP 0x5830 -#define VK_PAD_RTHUMB_DOWN 0x5831 -#define VK_PAD_RTHUMB_RIGHT 0x5832 -#define VK_PAD_RTHUMB_LEFT 0x5833 -#define VK_PAD_RTHUMB_UPLEFT 0x5834 -#define VK_PAD_RTHUMB_UPRIGHT 0x5835 -#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836 -#define VK_PAD_RTHUMB_DOWNLEFT 0x5837 - -/* - * Deadzones are for analogue joystick controls on the joypad - * which determine when input should be assumed to be in the - * middle of the pad. This is a threshold to stop a joypad - * controlling the game when the player isn't touching the - * controls. - */ - -#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 -#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 -#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30 - - -/* - * Defines what type of abilities the type of joystick has - * DEVTYPE_GAMEPAD is available for all joysticks, however - * there may be more specific identifiers for other joysticks - * which are being used. - */ - -#define XINPUT_DEVTYPE_GAMEPAD 0x01 -#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01 -#define XINPUT_DEVSUBTYPE_WHEEL 0x02 -#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03 -#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04 -#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05 -#define XINPUT_DEVSUBTYPE_GUITAR 0x06 -#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08 - -/* - * These are used with the XInputGetCapabilities function to - * determine the abilities to the joystick which has been - * plugged in. - */ - -#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004 -#define XINPUT_FLAG_GAMEPAD 0x00000001 - -/* - * Defines the status of the battery if one is used in the - * attached joystick. The first two define if the joystick - * supports a battery. Disconnected means that the joystick - * isn't connected. Wired shows that the joystick is a wired - * joystick. - */ - -#define BATTERY_DEVTYPE_GAMEPAD 0x00 -#define BATTERY_DEVTYPE_HEADSET 0x01 -#define BATTERY_TYPE_DISCONNECTED 0x00 -#define BATTERY_TYPE_WIRED 0x01 -#define BATTERY_TYPE_ALKALINE 0x02 -#define BATTERY_TYPE_NIMH 0x03 -#define BATTERY_TYPE_UNKNOWN 0xFF -#define BATTERY_LEVEL_EMPTY 0x00 -#define BATTERY_LEVEL_LOW 0x01 -#define BATTERY_LEVEL_MEDIUM 0x02 -#define BATTERY_LEVEL_FULL 0x03 - -/* - * How many joysticks can be used with this library. Games that - * use the xinput library will not go over this number. - */ - -#define XUSER_MAX_COUNT 4 -#define XUSER_INDEX_ANY 0x000000FF - -/* - * Defines the structure of an xbox 360 joystick. - */ - -typedef struct _XINPUT_GAMEPAD { - WORD wButtons; - BYTE bLeftTrigger; - BYTE bRightTrigger; - SHORT sThumbLX; - SHORT sThumbLY; - SHORT sThumbRX; - SHORT sThumbRY; -} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD; - -typedef struct _XINPUT_STATE { - DWORD dwPacketNumber; - XINPUT_GAMEPAD Gamepad; -} XINPUT_STATE, *PXINPUT_STATE; - -/* - * Defines the structure of how much vibration is set on both the - * right and left motors in a joystick. If you're not using a 360 - * joystick you will have to map these to your device. - */ - -typedef struct _XINPUT_VIBRATION { - WORD wLeftMotorSpeed; - WORD wRightMotorSpeed; -} XINPUT_VIBRATION, *PXINPUT_VIBRATION; - -/* - * Defines the structure for what kind of abilities the joystick has - * such abilities are things such as if the joystick has the ability - * to send and receive audio, if the joystick is in fact a driving - * wheel or perhaps if the joystick is some kind of dance pad or - * guitar. - */ - -typedef struct _XINPUT_CAPABILITIES { - BYTE Type; - BYTE SubType; - WORD Flags; - XINPUT_GAMEPAD Gamepad; - XINPUT_VIBRATION Vibration; -} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES; - -/* - * Defines the structure for a joystick input event which is - * retrieved using the function XInputGetKeystroke - */ -typedef struct _XINPUT_KEYSTROKE { - WORD VirtualKey; - WCHAR Unicode; - WORD Flags; - BYTE UserIndex; - BYTE HidCode; -} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE; - -typedef struct _XINPUT_BATTERY_INFORMATION -{ - BYTE BatteryType; - BYTE BatteryLevel; -} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION; - -#ifdef __cplusplus -extern "C" { -#endif - -void WINAPI XInputEnable(WINBOOL); -DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*); -DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*); -DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE); -DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*); -DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*); -DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*); - -#ifdef __cplusplus -} -#endif - -#endif /* __WINE_XINPUT_H */ diff --git a/raylib/external/glfw/deps/vs2008/stdint.h b/raylib/external/glfw/deps/vs2008/stdint.h deleted file mode 100644 index d02608a..0000000 --- a/raylib/external/glfw/deps/vs2008/stdint.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. 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. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] From 8596a5db729eea07b31804d0421fd5536cbefcd3 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:25:40 +0100 Subject: [PATCH 031/278] Rename wayland functions --- raylib/external/glfw/src/wl_init.c | 4 ++-- raylib/external/glfw/src/wl_window.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/raylib/external/glfw/src/wl_init.c b/raylib/external/glfw/src/wl_init.c index 3aff476..c017322 100644 --- a/raylib/external/glfw/src/wl_init.c +++ b/raylib/external/glfw/src/wl_init.c @@ -257,7 +257,7 @@ static const struct wl_callback_listener libdecorReadyListener = // Create key code translation tables // -static void createKeyTables(void) +static void createKeyTablesWL(void) { memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes)); memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes)); @@ -821,7 +821,7 @@ int _glfwInitWayland(void) _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); - createKeyTables(); + createKeyTablesWL(); _glfw.wl.xkb.context = xkb_context_new(0); if (!_glfw.wl.xkb.context) diff --git a/raylib/external/glfw/src/wl_window.c b/raylib/external/glfw/src/wl_window.c index 5b491ff..8721992 100644 --- a/raylib/external/glfw/src/wl_window.c +++ b/raylib/external/glfw/src/wl_window.c @@ -498,7 +498,7 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) // Make the specified window and its video mode active on its monitor // -static void acquireMonitor(_GLFWwindow* window) +static void acquireMonitorWL(_GLFWwindow* window) { if (window->wl.libdecor.frame) { @@ -519,7 +519,7 @@ static void acquireMonitor(_GLFWwindow* window) // Remove the window and restore the original video mode // -static void releaseMonitor(_GLFWwindow* window) +static void releaseMonitorWL(_GLFWwindow* window) { if (window->wl.libdecor.frame) libdecor_frame_unset_fullscreen(window->wl.libdecor.frame); @@ -1156,7 +1156,7 @@ static GLFWbool flushDisplay(void) return GLFW_TRUE; } -static int translateKey(uint32_t scancode) +static int translateKeyWL(uint32_t scancode) { if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) return _glfw.wl.keycodes[scancode]; @@ -1270,7 +1270,7 @@ static void handleEvents(double* timeout) for (uint64_t i = 0; i < repeats; i++) { _glfwInputKey(_glfw.wl.keyboardFocus, - translateKey(_glfw.wl.keyRepeatScancode), + translateKeyWL(_glfw.wl.keyRepeatScancode), _glfw.wl.keyRepeatScancode, GLFW_PRESS, _glfw.wl.xkb.modifiers); @@ -1773,7 +1773,7 @@ static void keyboardHandleKey(void* userData, if (!window) return; - const int key = translateKey(scancode); + const int key = translateKeyWL(scancode); const int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; @@ -2509,12 +2509,12 @@ void _glfwSetWindowMonitorWayland(_GLFWwindow* window, } if (window->monitor) - releaseMonitor(window); + releaseMonitorWL(window); _glfwInputWindowMonitor(window, monitor); if (window->monitor) - acquireMonitor(window); + acquireMonitorWL(window); else _glfwSetWindowSizeWayland(window, width, height); } From 5abcc8b79ce4184ebac57f111dfbf40391fa7d64 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:26:12 +0100 Subject: [PATCH 032/278] Update wayland script --- .../external/scripts/glfw-generate-wayland.sh | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/raylib/external/scripts/glfw-generate-wayland.sh b/raylib/external/scripts/glfw-generate-wayland.sh index 931fd9b..0619c4c 100755 --- a/raylib/external/scripts/glfw-generate-wayland.sh +++ b/raylib/external/scripts/glfw-generate-wayland.sh @@ -19,33 +19,43 @@ wayland-scanner client-header ./protocol/wayland.xml "$GLGLFW_PATH"/wayland-clie cd $TMPDIR cd wayland-protocols -rm -f "$GLGLFW_PATH"/wayland-xdg-shell-client-protocol.h -rm -f "$GLGLFW_PATH"/wayland-xdg-shell-client-protocol-code.h -rm -f "$GLGLFW_PATH"/wayland-xdg-decoration-client-protocol.h -rm -f "$GLGLFW_PATH"/wayland-xdg-decoration-client-protocol-code.h -rm -f "$GLGLFW_PATH"/wayland-viewporter-client-protocol.h -rm -f "$GLGLFW_PATH"/wayland-viewporter-client-protocol-code.h -rm -f "$GLGLFW_PATH"/wayland-relative-pointer-unstable-v1-client-protocol.h -rm -f "$GLGLFW_PATH"/wayland-relative-pointer-unstable-v1-client-protocol-code.h -rm -f "$GLGLFW_PATH"/wayland-pointer-constraints-unstable-v1-client-protocol.h -rm -f "$GLGLFW_PATH"/wayland-pointer-constraints-unstable-v1-client-protocol-code.h -rm -f "$GLGLFW_PATH"/wayland-idle-inhibit-unstable-v1-client-protocol.h -rm -f "$GLGLFW_PATH"/wayland-idle-inhibit-unstable-v1-client-protocol-code.h +rm -f "$GLGLFW_PATH"/xdg-shell-client-protocol.h +rm -f "$GLGLFW_PATH"/xdg-shell-client-protocol-code.h +rm -f "$GLGLFW_PATH"/fractional-scale-v1-client-protocol.h +rm -f "$GLGLFW_PATH"/fractional-scale-v1-client-protocol-code.h +rm -f "$GLGLFW_PATH"/xdg-activation-v1-client-protocol.h +rm -f "$GLGLFW_PATH"/xdg-activation-v1-client-protocol-code.h +rm -f "$GLGLFW_PATH"/xdg-decoration-client-protocol.h +rm -f "$GLGLFW_PATH"/xdg-decoration-client-protocol-code.h +rm -f "$GLGLFW_PATH"/viewporter-client-protocol.h +rm -f "$GLGLFW_PATH"/viewporter-client-protocol-code.h +rm -f "$GLGLFW_PATH"/relative-pointer-unstable-v1-client-protocol.h +rm -f "$GLGLFW_PATH"/relative-pointer-unstable-v1-client-protocol-code.h +rm -f "$GLGLFW_PATH"/pointer-constraints-unstable-v1-client-protocol.h +rm -f "$GLGLFW_PATH"/pointer-constraints-unstable-v1-client-protocol-code.h +rm -f "$GLGLFW_PATH"/idle-inhibit-unstable-v1-client-protocol.h +rm -f "$GLGLFW_PATH"/idle-inhibit-unstable-v1-client-protocol-code.h -wayland-scanner private-code ./stable/xdg-shell/xdg-shell.xml "$GLGLFW_PATH"/wayland-xdg-shell-client-protocol-code.h -wayland-scanner client-header ./stable/xdg-shell/xdg-shell.xml "$GLGLFW_PATH"/wayland-xdg-shell-client-protocol.h +wayland-scanner private-code ./stable/xdg-shell/xdg-shell.xml "$GLGLFW_PATH"/xdg-shell-client-protocol-code.h +wayland-scanner client-header ./stable/xdg-shell/xdg-shell.xml "$GLGLFW_PATH"/xdg-shell-client-protocol.h -wayland-scanner private-code ./unstable/xdg-decoration/xdg-decoration-unstable-v1.xml "$GLGLFW_PATH"/wayland-xdg-decoration-client-protocol-code.h -wayland-scanner client-header ./unstable/xdg-decoration/xdg-decoration-unstable-v1.xml "$GLGLFW_PATH"/wayland-xdg-decoration-client-protocol.h +wayland-scanner private-code ./staging/fractional-scale/fractional-scale-v1.xml "$GLGLFW_PATH"/fractional-scale-v1-client-protocol-code.h +wayland-scanner client-header ./staging/fractional-scale/fractional-scale-v1.xml "$GLGLFW_PATH"/fractional-scale-v1-client-protocol.h -wayland-scanner private-code ./stable/viewporter/viewporter.xml "$GLGLFW_PATH"/wayland-viewporter-client-protocol-code.h -wayland-scanner client-header ./stable/viewporter/viewporter.xml "$GLGLFW_PATH"/wayland-viewporter-client-protocol.h +wayland-scanner private-code ./staging/xdg-activation/xdg-activation-v1.xml "$GLGLFW_PATH"/xdg-activation-v1-client-protocol-code.h +wayland-scanner client-header ./staging/xdg-activation/xdg-activation-v1.xml "$GLGLFW_PATH"/xdg-activation-v1-client-protocol.h -wayland-scanner private-code ./unstable/relative-pointer/relative-pointer-unstable-v1.xml "$GLGLFW_PATH"/wayland-relative-pointer-unstable-v1-client-protocol-code.h -wayland-scanner client-header ./unstable/relative-pointer/relative-pointer-unstable-v1.xml "$GLGLFW_PATH"/wayland-relative-pointer-unstable-v1-client-protocol.h +wayland-scanner private-code ./unstable/xdg-decoration/xdg-decoration-unstable-v1.xml "$GLGLFW_PATH"/xdg-decoration-unstable-v1-client-protocol-code.h +wayland-scanner client-header ./unstable/xdg-decoration/xdg-decoration-unstable-v1.xml "$GLGLFW_PATH"/xdg-decoration-unstable-v1-client-protocol.h -wayland-scanner private-code ./unstable/pointer-constraints/pointer-constraints-unstable-v1.xml "$GLGLFW_PATH"/wayland-pointer-constraints-unstable-v1-client-protocol-code.h -wayland-scanner client-header ./unstable/pointer-constraints/pointer-constraints-unstable-v1.xml "$GLGLFW_PATH"/wayland-pointer-constraints-unstable-v1-client-protocol.h +wayland-scanner private-code ./stable/viewporter/viewporter.xml "$GLGLFW_PATH"/viewporter-client-protocol-code.h +wayland-scanner client-header ./stable/viewporter/viewporter.xml "$GLGLFW_PATH"/viewporter-client-protocol.h -wayland-scanner private-code ./unstable/idle-inhibit/idle-inhibit-unstable-v1.xml "$GLGLFW_PATH"/wayland-idle-inhibit-unstable-v1-client-protocol-code.h -wayland-scanner client-header ./unstable/idle-inhibit/idle-inhibit-unstable-v1.xml "$GLGLFW_PATH"/wayland-idle-inhibit-unstable-v1-client-protocol.h +wayland-scanner private-code ./unstable/relative-pointer/relative-pointer-unstable-v1.xml "$GLGLFW_PATH"/relative-pointer-unstable-v1-client-protocol-code.h +wayland-scanner client-header ./unstable/relative-pointer/relative-pointer-unstable-v1.xml "$GLGLFW_PATH"/relative-pointer-unstable-v1-client-protocol.h + +wayland-scanner private-code ./unstable/pointer-constraints/pointer-constraints-unstable-v1.xml "$GLGLFW_PATH"/pointer-constraints-unstable-v1-client-protocol-code.h +wayland-scanner client-header ./unstable/pointer-constraints/pointer-constraints-unstable-v1.xml "$GLGLFW_PATH"/pointer-constraints-unstable-v1-client-protocol.h + +wayland-scanner private-code ./unstable/idle-inhibit/idle-inhibit-unstable-v1.xml "$GLGLFW_PATH"/idle-inhibit-unstable-v1-client-protocol-code.h +wayland-scanner client-header ./unstable/idle-inhibit/idle-inhibit-unstable-v1.xml "$GLGLFW_PATH"/idle-inhibit-unstable-v1-client-protocol.h From 83c4beb421d0eb2113f949ff453fa2ac77dc5dd3 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:26:41 +0100 Subject: [PATCH 033/278] Add wayland files --- ...fractional-scale-v1-client-protocol-code.h | 73 + .../src/fractional-scale-v1-client-protocol.h | 264 + ...inhibit-unstable-v1-client-protocol-code.h | 68 + ...idle-inhibit-unstable-v1-client-protocol.h | 232 + ...traints-unstable-v1-client-protocol-code.h | 108 + ...-constraints-unstable-v1-client-protocol.h | 667 ++ ...pointer-unstable-v1-client-protocol-code.h | 79 + ...tive-pointer-unstable-v1-client-protocol.h | 297 + .../src/viewporter-client-protocol-code.h | 74 + .../glfw/src/viewporter-client-protocol.h | 398 ++ .../glfw/src/wayland-client-protocol-code.h | 525 ++ .../glfw/src/wayland-client-protocol.h | 6359 +++++++++++++++++ .../xdg-activation-v1-client-protocol-code.h | 84 + .../src/xdg-activation-v1-client-protocol.h | 415 ++ ...oration-unstable-v1-client-protocol-code.h | 75 + ...g-decoration-unstable-v1-client-protocol.h | 377 + .../glfw/src/xdg-shell-client-protocol-code.h | 183 + .../glfw/src/xdg-shell-client-protocol.h | 2315 ++++++ 18 files changed, 12593 insertions(+) create mode 100644 raylib/external/glfw/src/fractional-scale-v1-client-protocol-code.h create mode 100644 raylib/external/glfw/src/fractional-scale-v1-client-protocol.h create mode 100644 raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol-code.h create mode 100644 raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol.h create mode 100644 raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol-code.h create mode 100644 raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol.h create mode 100644 raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol-code.h create mode 100644 raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol.h create mode 100644 raylib/external/glfw/src/viewporter-client-protocol-code.h create mode 100644 raylib/external/glfw/src/viewporter-client-protocol.h create mode 100644 raylib/external/glfw/src/wayland-client-protocol-code.h create mode 100644 raylib/external/glfw/src/wayland-client-protocol.h create mode 100644 raylib/external/glfw/src/xdg-activation-v1-client-protocol-code.h create mode 100644 raylib/external/glfw/src/xdg-activation-v1-client-protocol.h create mode 100644 raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol-code.h create mode 100644 raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol.h create mode 100644 raylib/external/glfw/src/xdg-shell-client-protocol-code.h create mode 100644 raylib/external/glfw/src/xdg-shell-client-protocol.h diff --git a/raylib/external/glfw/src/fractional-scale-v1-client-protocol-code.h b/raylib/external/glfw/src/fractional-scale-v1-client-protocol-code.h new file mode 100644 index 0000000..090166b --- /dev/null +++ b/raylib/external/glfw/src/fractional-scale-v1-client-protocol-code.h @@ -0,0 +1,73 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2022 Kenny Levinsen + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface wp_fractional_scale_v1_interface; + +static const struct wl_interface *fractional_scale_v1_types[] = { + NULL, + &wp_fractional_scale_v1_interface, + &wl_surface_interface, +}; + +static const struct wl_message wp_fractional_scale_manager_v1_requests[] = { + { "destroy", "", fractional_scale_v1_types + 0 }, + { "get_fractional_scale", "no", fractional_scale_v1_types + 1 }, +}; + +WL_PRIVATE const struct wl_interface wp_fractional_scale_manager_v1_interface = { + "wp_fractional_scale_manager_v1", 1, + 2, wp_fractional_scale_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message wp_fractional_scale_v1_requests[] = { + { "destroy", "", fractional_scale_v1_types + 0 }, +}; + +static const struct wl_message wp_fractional_scale_v1_events[] = { + { "preferred_scale", "u", fractional_scale_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wp_fractional_scale_v1_interface = { + "wp_fractional_scale_v1", 1, + 1, wp_fractional_scale_v1_requests, + 1, wp_fractional_scale_v1_events, +}; + diff --git a/raylib/external/glfw/src/fractional-scale-v1-client-protocol.h b/raylib/external/glfw/src/fractional-scale-v1-client-protocol.h new file mode 100644 index 0000000..7f0dec4 --- /dev/null +++ b/raylib/external/glfw/src/fractional-scale-v1-client-protocol.h @@ -0,0 +1,264 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H +#define FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_fractional_scale_v1 The fractional_scale_v1 protocol + * Protocol for requesting fractional surface scales + * + * @section page_desc_fractional_scale_v1 Description + * + * This protocol allows a compositor to suggest for surfaces to render at + * fractional scales. + * + * A client can submit scaled content by utilizing wp_viewport. This is done by + * creating a wp_viewport object for the surface and setting the destination + * rectangle to the surface size before the scale factor is applied. + * + * The buffer size is calculated by multiplying the surface size by the + * intended scale. + * + * The wl_surface buffer scale should remain set to 1. + * + * If a surface has a surface-local size of 100 px by 50 px and wishes to + * submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should + * be used and the wp_viewport destination rectangle should be 100 px by 50 px. + * + * For toplevel surfaces, the size is rounded halfway away from zero. The + * rounding algorithm for subsurface position and size is not defined. + * + * @section page_ifaces_fractional_scale_v1 Interfaces + * - @subpage page_iface_wp_fractional_scale_manager_v1 - fractional surface scale information + * - @subpage page_iface_wp_fractional_scale_v1 - fractional scale interface to a wl_surface + * @section page_copyright_fractional_scale_v1 Copyright + *
+ *
+ * Copyright © 2022 Kenny Levinsen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_surface; +struct wp_fractional_scale_manager_v1; +struct wp_fractional_scale_v1; + +#ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE +#define WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE +/** + * @page page_iface_wp_fractional_scale_manager_v1 wp_fractional_scale_manager_v1 + * @section page_iface_wp_fractional_scale_manager_v1_desc Description + * + * A global interface for requesting surfaces to use fractional scales. + * @section page_iface_wp_fractional_scale_manager_v1_api API + * See @ref iface_wp_fractional_scale_manager_v1. + */ +/** + * @defgroup iface_wp_fractional_scale_manager_v1 The wp_fractional_scale_manager_v1 interface + * + * A global interface for requesting surfaces to use fractional scales. + */ +extern const struct wl_interface wp_fractional_scale_manager_v1_interface; +#endif +#ifndef WP_FRACTIONAL_SCALE_V1_INTERFACE +#define WP_FRACTIONAL_SCALE_V1_INTERFACE +/** + * @page page_iface_wp_fractional_scale_v1 wp_fractional_scale_v1 + * @section page_iface_wp_fractional_scale_v1_desc Description + * + * An additional interface to a wl_surface object which allows the compositor + * to inform the client of the preferred scale. + * @section page_iface_wp_fractional_scale_v1_api API + * See @ref iface_wp_fractional_scale_v1. + */ +/** + * @defgroup iface_wp_fractional_scale_v1 The wp_fractional_scale_v1 interface + * + * An additional interface to a wl_surface object which allows the compositor + * to inform the client of the preferred scale. + */ +extern const struct wl_interface wp_fractional_scale_v1_interface; +#endif + +#ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM +#define WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM +enum wp_fractional_scale_manager_v1_error { + /** + * the surface already has a fractional_scale object associated + */ + WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS = 0, +}; +#endif /* WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM */ + +#define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY 0 +#define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE 1 + + +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + */ +#define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + */ +#define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE_SINCE_VERSION 1 + +/** @ingroup iface_wp_fractional_scale_manager_v1 */ +static inline void +wp_fractional_scale_manager_v1_set_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1, user_data); +} + +/** @ingroup iface_wp_fractional_scale_manager_v1 */ +static inline void * +wp_fractional_scale_manager_v1_get_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1); +} + +static inline uint32_t +wp_fractional_scale_manager_v1_get_version(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1); +} + +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + * + * Informs the server that the client will not be using this protocol + * object anymore. This does not affect any other objects, + * wp_fractional_scale_v1 objects included. + */ +static inline void +wp_fractional_scale_manager_v1_destroy(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_manager_v1, + WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + * + * Create an add-on object for the the wl_surface to let the compositor + * request fractional scales. If the given wl_surface already has a + * wp_fractional_scale_v1 object associated, the fractional_scale_exists + * protocol error is raised. + */ +static inline struct wp_fractional_scale_v1 * +wp_fractional_scale_manager_v1_get_fractional_scale(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_manager_v1, + WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE, &wp_fractional_scale_v1_interface, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1), 0, NULL, surface); + + return (struct wp_fractional_scale_v1 *) id; +} + +/** + * @ingroup iface_wp_fractional_scale_v1 + * @struct wp_fractional_scale_v1_listener + */ +struct wp_fractional_scale_v1_listener { + /** + * notify of new preferred scale + * + * Notification of a new preferred scale for this surface that + * the compositor suggests that the client should use. + * + * The sent scale is the numerator of a fraction with a denominator + * of 120. + * @param scale the new preferred scale + */ + void (*preferred_scale)(void *data, + struct wp_fractional_scale_v1 *wp_fractional_scale_v1, + uint32_t scale); +}; + +/** + * @ingroup iface_wp_fractional_scale_v1 + */ +static inline int +wp_fractional_scale_v1_add_listener(struct wp_fractional_scale_v1 *wp_fractional_scale_v1, + const struct wp_fractional_scale_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wp_fractional_scale_v1, + (void (**)(void)) listener, data); +} + +#define WP_FRACTIONAL_SCALE_V1_DESTROY 0 + +/** + * @ingroup iface_wp_fractional_scale_v1 + */ +#define WP_FRACTIONAL_SCALE_V1_PREFERRED_SCALE_SINCE_VERSION 1 + +/** + * @ingroup iface_wp_fractional_scale_v1 + */ +#define WP_FRACTIONAL_SCALE_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_wp_fractional_scale_v1 */ +static inline void +wp_fractional_scale_v1_set_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_v1, user_data); +} + +/** @ingroup iface_wp_fractional_scale_v1 */ +static inline void * +wp_fractional_scale_v1_get_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_v1); +} + +static inline uint32_t +wp_fractional_scale_v1_get_version(struct wp_fractional_scale_v1 *wp_fractional_scale_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1); +} + +/** + * @ingroup iface_wp_fractional_scale_v1 + * + * Destroy the fractional scale object. When this object is destroyed, + * preferred_scale events will no longer be sent. + */ +static inline void +wp_fractional_scale_v1_destroy(struct wp_fractional_scale_v1 *wp_fractional_scale_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_v1, + WP_FRACTIONAL_SCALE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol-code.h new file mode 100644 index 0000000..76ef732 --- /dev/null +++ b/raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol-code.h @@ -0,0 +1,68 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2015 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface zwp_idle_inhibitor_v1_interface; + +static const struct wl_interface *idle_inhibit_unstable_v1_types[] = { + &zwp_idle_inhibitor_v1_interface, + &wl_surface_interface, +}; + +static const struct wl_message zwp_idle_inhibit_manager_v1_requests[] = { + { "destroy", "", idle_inhibit_unstable_v1_types + 0 }, + { "create_inhibitor", "no", idle_inhibit_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_idle_inhibit_manager_v1_interface = { + "zwp_idle_inhibit_manager_v1", 1, + 2, zwp_idle_inhibit_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message zwp_idle_inhibitor_v1_requests[] = { + { "destroy", "", idle_inhibit_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_idle_inhibitor_v1_interface = { + "zwp_idle_inhibitor_v1", 1, + 1, zwp_idle_inhibitor_v1_requests, + 0, NULL, +}; + diff --git a/raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol.h b/raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol.h new file mode 100644 index 0000000..a033a11 --- /dev/null +++ b/raylib/external/glfw/src/idle-inhibit-unstable-v1-client-protocol.h @@ -0,0 +1,232 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef IDLE_INHIBIT_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define IDLE_INHIBIT_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_idle_inhibit_unstable_v1 The idle_inhibit_unstable_v1 protocol + * @section page_ifaces_idle_inhibit_unstable_v1 Interfaces + * - @subpage page_iface_zwp_idle_inhibit_manager_v1 - control behavior when display idles + * - @subpage page_iface_zwp_idle_inhibitor_v1 - context object for inhibiting idle behavior + * @section page_copyright_idle_inhibit_unstable_v1 Copyright + *
+ *
+ * Copyright © 2015 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_surface; +struct zwp_idle_inhibit_manager_v1; +struct zwp_idle_inhibitor_v1; + +#ifndef ZWP_IDLE_INHIBIT_MANAGER_V1_INTERFACE +#define ZWP_IDLE_INHIBIT_MANAGER_V1_INTERFACE +/** + * @page page_iface_zwp_idle_inhibit_manager_v1 zwp_idle_inhibit_manager_v1 + * @section page_iface_zwp_idle_inhibit_manager_v1_desc Description + * + * This interface permits inhibiting the idle behavior such as screen + * blanking, locking, and screensaving. The client binds the idle manager + * globally, then creates idle-inhibitor objects for each surface. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + * @section page_iface_zwp_idle_inhibit_manager_v1_api API + * See @ref iface_zwp_idle_inhibit_manager_v1. + */ +/** + * @defgroup iface_zwp_idle_inhibit_manager_v1 The zwp_idle_inhibit_manager_v1 interface + * + * This interface permits inhibiting the idle behavior such as screen + * blanking, locking, and screensaving. The client binds the idle manager + * globally, then creates idle-inhibitor objects for each surface. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + */ +extern const struct wl_interface zwp_idle_inhibit_manager_v1_interface; +#endif +#ifndef ZWP_IDLE_INHIBITOR_V1_INTERFACE +#define ZWP_IDLE_INHIBITOR_V1_INTERFACE +/** + * @page page_iface_zwp_idle_inhibitor_v1 zwp_idle_inhibitor_v1 + * @section page_iface_zwp_idle_inhibitor_v1_desc Description + * + * An idle inhibitor prevents the output that the associated surface is + * visible on from being set to a state where it is not visually usable due + * to lack of user interaction (e.g. blanked, dimmed, locked, set to power + * save, etc.) Any screensaver processes are also blocked from displaying. + * + * If the surface is destroyed, unmapped, becomes occluded, loses + * visibility, or otherwise becomes not visually relevant for the user, the + * idle inhibitor will not be honored by the compositor; if the surface + * subsequently regains visibility the inhibitor takes effect once again. + * Likewise, the inhibitor isn't honored if the system was already idled at + * the time the inhibitor was established, although if the system later + * de-idles and re-idles the inhibitor will take effect. + * @section page_iface_zwp_idle_inhibitor_v1_api API + * See @ref iface_zwp_idle_inhibitor_v1. + */ +/** + * @defgroup iface_zwp_idle_inhibitor_v1 The zwp_idle_inhibitor_v1 interface + * + * An idle inhibitor prevents the output that the associated surface is + * visible on from being set to a state where it is not visually usable due + * to lack of user interaction (e.g. blanked, dimmed, locked, set to power + * save, etc.) Any screensaver processes are also blocked from displaying. + * + * If the surface is destroyed, unmapped, becomes occluded, loses + * visibility, or otherwise becomes not visually relevant for the user, the + * idle inhibitor will not be honored by the compositor; if the surface + * subsequently regains visibility the inhibitor takes effect once again. + * Likewise, the inhibitor isn't honored if the system was already idled at + * the time the inhibitor was established, although if the system later + * de-idles and re-idles the inhibitor will take effect. + */ +extern const struct wl_interface zwp_idle_inhibitor_v1_interface; +#endif + +#define ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY 0 +#define ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR 1 + + +/** + * @ingroup iface_zwp_idle_inhibit_manager_v1 + */ +#define ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_idle_inhibit_manager_v1 + */ +#define ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR_SINCE_VERSION 1 + +/** @ingroup iface_zwp_idle_inhibit_manager_v1 */ +static inline void +zwp_idle_inhibit_manager_v1_set_user_data(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_idle_inhibit_manager_v1, user_data); +} + +/** @ingroup iface_zwp_idle_inhibit_manager_v1 */ +static inline void * +zwp_idle_inhibit_manager_v1_get_user_data(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_idle_inhibit_manager_v1); +} + +static inline uint32_t +zwp_idle_inhibit_manager_v1_get_version(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1); +} + +/** + * @ingroup iface_zwp_idle_inhibit_manager_v1 + * + * Destroy the inhibit manager. + */ +static inline void +zwp_idle_inhibit_manager_v1_destroy(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibit_manager_v1, + ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_idle_inhibit_manager_v1 + * + * Create a new inhibitor object associated with the given surface. + */ +static inline struct zwp_idle_inhibitor_v1 * +zwp_idle_inhibit_manager_v1_create_inhibitor(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibit_manager_v1, + ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR, &zwp_idle_inhibitor_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1), 0, NULL, surface); + + return (struct zwp_idle_inhibitor_v1 *) id; +} + +#define ZWP_IDLE_INHIBITOR_V1_DESTROY 0 + + +/** + * @ingroup iface_zwp_idle_inhibitor_v1 + */ +#define ZWP_IDLE_INHIBITOR_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zwp_idle_inhibitor_v1 */ +static inline void +zwp_idle_inhibitor_v1_set_user_data(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_idle_inhibitor_v1, user_data); +} + +/** @ingroup iface_zwp_idle_inhibitor_v1 */ +static inline void * +zwp_idle_inhibitor_v1_get_user_data(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_idle_inhibitor_v1); +} + +static inline uint32_t +zwp_idle_inhibitor_v1_get_version(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibitor_v1); +} + +/** + * @ingroup iface_zwp_idle_inhibitor_v1 + * + * Remove the inhibitor effect from the associated wl_surface. + */ +static inline void +zwp_idle_inhibitor_v1_destroy(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibitor_v1, + ZWP_IDLE_INHIBITOR_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibitor_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol-code.h new file mode 100644 index 0000000..5935c0b --- /dev/null +++ b/raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol-code.h @@ -0,0 +1,108 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2014 Jonas Ådahl + * Copyright © 2015 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_pointer_interface; +extern const struct wl_interface wl_region_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface zwp_confined_pointer_v1_interface; +extern const struct wl_interface zwp_locked_pointer_v1_interface; + +static const struct wl_interface *pointer_constraints_unstable_v1_types[] = { + NULL, + NULL, + &zwp_locked_pointer_v1_interface, + &wl_surface_interface, + &wl_pointer_interface, + &wl_region_interface, + NULL, + &zwp_confined_pointer_v1_interface, + &wl_surface_interface, + &wl_pointer_interface, + &wl_region_interface, + NULL, + &wl_region_interface, + &wl_region_interface, +}; + +static const struct wl_message zwp_pointer_constraints_v1_requests[] = { + { "destroy", "", pointer_constraints_unstable_v1_types + 0 }, + { "lock_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 2 }, + { "confine_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 7 }, +}; + +WL_PRIVATE const struct wl_interface zwp_pointer_constraints_v1_interface = { + "zwp_pointer_constraints_v1", 1, + 3, zwp_pointer_constraints_v1_requests, + 0, NULL, +}; + +static const struct wl_message zwp_locked_pointer_v1_requests[] = { + { "destroy", "", pointer_constraints_unstable_v1_types + 0 }, + { "set_cursor_position_hint", "ff", pointer_constraints_unstable_v1_types + 0 }, + { "set_region", "?o", pointer_constraints_unstable_v1_types + 12 }, +}; + +static const struct wl_message zwp_locked_pointer_v1_events[] = { + { "locked", "", pointer_constraints_unstable_v1_types + 0 }, + { "unlocked", "", pointer_constraints_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_locked_pointer_v1_interface = { + "zwp_locked_pointer_v1", 1, + 3, zwp_locked_pointer_v1_requests, + 2, zwp_locked_pointer_v1_events, +}; + +static const struct wl_message zwp_confined_pointer_v1_requests[] = { + { "destroy", "", pointer_constraints_unstable_v1_types + 0 }, + { "set_region", "?o", pointer_constraints_unstable_v1_types + 13 }, +}; + +static const struct wl_message zwp_confined_pointer_v1_events[] = { + { "confined", "", pointer_constraints_unstable_v1_types + 0 }, + { "unconfined", "", pointer_constraints_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_confined_pointer_v1_interface = { + "zwp_confined_pointer_v1", 1, + 2, zwp_confined_pointer_v1_requests, + 2, zwp_confined_pointer_v1_events, +}; + diff --git a/raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol.h b/raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol.h new file mode 100644 index 0000000..5ff3867 --- /dev/null +++ b/raylib/external/glfw/src/pointer-constraints-unstable-v1-client-protocol.h @@ -0,0 +1,667 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_pointer_constraints_unstable_v1 The pointer_constraints_unstable_v1 protocol + * protocol for constraining pointer motions + * + * @section page_desc_pointer_constraints_unstable_v1 Description + * + * This protocol specifies a set of interfaces used for adding constraints to + * the motion of a pointer. Possible constraints include confining pointer + * motions to a given region, or locking it to its current position. + * + * In order to constrain the pointer, a client must first bind the global + * interface "wp_pointer_constraints" which, if a compositor supports pointer + * constraints, is exposed by the registry. Using the bound global object, the + * client uses the request that corresponds to the type of constraint it wants + * to make. See wp_pointer_constraints for more details. + * + * Warning! The protocol described in this file is experimental and backward + * incompatible changes may be made. Backward compatible changes may be added + * together with the corresponding interface version bump. Backward + * incompatible changes are done by bumping the version number in the protocol + * and interface names and resetting the interface version. Once the protocol + * is to be declared stable, the 'z' prefix and the version number in the + * protocol and interface names are removed and the interface version number is + * reset. + * + * @section page_ifaces_pointer_constraints_unstable_v1 Interfaces + * - @subpage page_iface_zwp_pointer_constraints_v1 - constrain the movement of a pointer + * - @subpage page_iface_zwp_locked_pointer_v1 - receive relative pointer motion events + * - @subpage page_iface_zwp_confined_pointer_v1 - confined pointer object + * @section page_copyright_pointer_constraints_unstable_v1 Copyright + *
+ *
+ * Copyright © 2014      Jonas Ådahl
+ * Copyright © 2015      Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_pointer; +struct wl_region; +struct wl_surface; +struct zwp_confined_pointer_v1; +struct zwp_locked_pointer_v1; +struct zwp_pointer_constraints_v1; + +#ifndef ZWP_POINTER_CONSTRAINTS_V1_INTERFACE +#define ZWP_POINTER_CONSTRAINTS_V1_INTERFACE +/** + * @page page_iface_zwp_pointer_constraints_v1 zwp_pointer_constraints_v1 + * @section page_iface_zwp_pointer_constraints_v1_desc Description + * + * The global interface exposing pointer constraining functionality. It + * exposes two requests: lock_pointer for locking the pointer to its + * position, and confine_pointer for locking the pointer to a region. + * + * The lock_pointer and confine_pointer requests create the objects + * wp_locked_pointer and wp_confined_pointer respectively, and the client can + * use these objects to interact with the lock. + * + * For any surface, only one lock or confinement may be active across all + * wl_pointer objects of the same seat. If a lock or confinement is requested + * when another lock or confinement is active or requested on the same surface + * and with any of the wl_pointer objects of the same seat, an + * 'already_constrained' error will be raised. + * @section page_iface_zwp_pointer_constraints_v1_api API + * See @ref iface_zwp_pointer_constraints_v1. + */ +/** + * @defgroup iface_zwp_pointer_constraints_v1 The zwp_pointer_constraints_v1 interface + * + * The global interface exposing pointer constraining functionality. It + * exposes two requests: lock_pointer for locking the pointer to its + * position, and confine_pointer for locking the pointer to a region. + * + * The lock_pointer and confine_pointer requests create the objects + * wp_locked_pointer and wp_confined_pointer respectively, and the client can + * use these objects to interact with the lock. + * + * For any surface, only one lock or confinement may be active across all + * wl_pointer objects of the same seat. If a lock or confinement is requested + * when another lock or confinement is active or requested on the same surface + * and with any of the wl_pointer objects of the same seat, an + * 'already_constrained' error will be raised. + */ +extern const struct wl_interface zwp_pointer_constraints_v1_interface; +#endif +#ifndef ZWP_LOCKED_POINTER_V1_INTERFACE +#define ZWP_LOCKED_POINTER_V1_INTERFACE +/** + * @page page_iface_zwp_locked_pointer_v1 zwp_locked_pointer_v1 + * @section page_iface_zwp_locked_pointer_v1_desc Description + * + * The wp_locked_pointer interface represents a locked pointer state. + * + * While the lock of this object is active, the wl_pointer objects of the + * associated seat will not emit any wl_pointer.motion events. + * + * This object will send the event 'locked' when the lock is activated. + * Whenever the lock is activated, it is guaranteed that the locked surface + * will already have received pointer focus and that the pointer will be + * within the region passed to the request creating this object. + * + * To unlock the pointer, send the destroy request. This will also destroy + * the wp_locked_pointer object. + * + * If the compositor decides to unlock the pointer the unlocked event is + * sent. See wp_locked_pointer.unlock for details. + * + * When unlocking, the compositor may warp the cursor position to the set + * cursor position hint. If it does, it will not result in any relative + * motion events emitted via wp_relative_pointer. + * + * If the surface the lock was requested on is destroyed and the lock is not + * yet activated, the wp_locked_pointer object is now defunct and must be + * destroyed. + * @section page_iface_zwp_locked_pointer_v1_api API + * See @ref iface_zwp_locked_pointer_v1. + */ +/** + * @defgroup iface_zwp_locked_pointer_v1 The zwp_locked_pointer_v1 interface + * + * The wp_locked_pointer interface represents a locked pointer state. + * + * While the lock of this object is active, the wl_pointer objects of the + * associated seat will not emit any wl_pointer.motion events. + * + * This object will send the event 'locked' when the lock is activated. + * Whenever the lock is activated, it is guaranteed that the locked surface + * will already have received pointer focus and that the pointer will be + * within the region passed to the request creating this object. + * + * To unlock the pointer, send the destroy request. This will also destroy + * the wp_locked_pointer object. + * + * If the compositor decides to unlock the pointer the unlocked event is + * sent. See wp_locked_pointer.unlock for details. + * + * When unlocking, the compositor may warp the cursor position to the set + * cursor position hint. If it does, it will not result in any relative + * motion events emitted via wp_relative_pointer. + * + * If the surface the lock was requested on is destroyed and the lock is not + * yet activated, the wp_locked_pointer object is now defunct and must be + * destroyed. + */ +extern const struct wl_interface zwp_locked_pointer_v1_interface; +#endif +#ifndef ZWP_CONFINED_POINTER_V1_INTERFACE +#define ZWP_CONFINED_POINTER_V1_INTERFACE +/** + * @page page_iface_zwp_confined_pointer_v1 zwp_confined_pointer_v1 + * @section page_iface_zwp_confined_pointer_v1_desc Description + * + * The wp_confined_pointer interface represents a confined pointer state. + * + * This object will send the event 'confined' when the confinement is + * activated. Whenever the confinement is activated, it is guaranteed that + * the surface the pointer is confined to will already have received pointer + * focus and that the pointer will be within the region passed to the request + * creating this object. It is up to the compositor to decide whether this + * requires some user interaction and if the pointer will warp to within the + * passed region if outside. + * + * To unconfine the pointer, send the destroy request. This will also destroy + * the wp_confined_pointer object. + * + * If the compositor decides to unconfine the pointer the unconfined event is + * sent. The wp_confined_pointer object is at this point defunct and should + * be destroyed. + * @section page_iface_zwp_confined_pointer_v1_api API + * See @ref iface_zwp_confined_pointer_v1. + */ +/** + * @defgroup iface_zwp_confined_pointer_v1 The zwp_confined_pointer_v1 interface + * + * The wp_confined_pointer interface represents a confined pointer state. + * + * This object will send the event 'confined' when the confinement is + * activated. Whenever the confinement is activated, it is guaranteed that + * the surface the pointer is confined to will already have received pointer + * focus and that the pointer will be within the region passed to the request + * creating this object. It is up to the compositor to decide whether this + * requires some user interaction and if the pointer will warp to within the + * passed region if outside. + * + * To unconfine the pointer, send the destroy request. This will also destroy + * the wp_confined_pointer object. + * + * If the compositor decides to unconfine the pointer the unconfined event is + * sent. The wp_confined_pointer object is at this point defunct and should + * be destroyed. + */ +extern const struct wl_interface zwp_confined_pointer_v1_interface; +#endif + +#ifndef ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM +#define ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM +/** + * @ingroup iface_zwp_pointer_constraints_v1 + * wp_pointer_constraints error values + * + * These errors can be emitted in response to wp_pointer_constraints + * requests. + */ +enum zwp_pointer_constraints_v1_error { + /** + * pointer constraint already requested on that surface + */ + ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED = 1, +}; +#endif /* ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM */ + +#ifndef ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM +#define ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM +/** + * @ingroup iface_zwp_pointer_constraints_v1 + * constraint lifetime + * + * These values represent different lifetime semantics. They are passed + * as arguments to the factory requests to specify how the constraint + * lifetimes should be managed. + */ +enum zwp_pointer_constraints_v1_lifetime { + /** + * the pointer constraint is defunct once deactivated + * + * A oneshot pointer constraint will never reactivate once it has + * been deactivated. See the corresponding deactivation event + * (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) + * for details. + */ + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT = 1, + /** + * the pointer constraint may reactivate + * + * A persistent pointer constraint may again reactivate once it + * has been deactivated. See the corresponding deactivation event + * (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) + * for details. + */ + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT = 2, +}; +#endif /* ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM */ + +#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY 0 +#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER 1 +#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER 2 + + +/** + * @ingroup iface_zwp_pointer_constraints_v1 + */ +#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_pointer_constraints_v1 + */ +#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_pointer_constraints_v1 + */ +#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER_SINCE_VERSION 1 + +/** @ingroup iface_zwp_pointer_constraints_v1 */ +static inline void +zwp_pointer_constraints_v1_set_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_pointer_constraints_v1, user_data); +} + +/** @ingroup iface_zwp_pointer_constraints_v1 */ +static inline void * +zwp_pointer_constraints_v1_get_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_pointer_constraints_v1); +} + +static inline uint32_t +zwp_pointer_constraints_v1_get_version(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1); +} + +/** + * @ingroup iface_zwp_pointer_constraints_v1 + * + * Used by the client to notify the server that it will no longer use this + * pointer constraints object. + */ +static inline void +zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1, + ZWP_POINTER_CONSTRAINTS_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_pointer_constraints_v1 + * + * The lock_pointer request lets the client request to disable movements of + * the virtual pointer (i.e. the cursor), effectively locking the pointer + * to a position. This request may not take effect immediately; in the + * future, when the compositor deems implementation-specific constraints + * are satisfied, the pointer lock will be activated and the compositor + * sends a locked event. + * + * The protocol provides no guarantee that the constraints are ever + * satisfied, and does not require the compositor to send an error if the + * constraints cannot ever be satisfied. It is thus possible to request a + * lock that will never activate. + * + * There may not be another pointer constraint of any kind requested or + * active on the surface for any of the wl_pointer objects of the seat of + * the passed pointer when requesting a lock. If there is, an error will be + * raised. See general pointer lock documentation for more details. + * + * The intersection of the region passed with this request and the input + * region of the surface is used to determine where the pointer must be + * in order for the lock to activate. It is up to the compositor whether to + * warp the pointer or require some kind of user interaction for the lock + * to activate. If the region is null the surface input region is used. + * + * A surface may receive pointer focus without the lock being activated. + * + * The request creates a new object wp_locked_pointer which is used to + * interact with the lock as well as receive updates about its state. See + * the the description of wp_locked_pointer for further information. + * + * Note that while a pointer is locked, the wl_pointer objects of the + * corresponding seat will not emit any wl_pointer.motion events, but + * relative motion events will still be emitted via wp_relative_pointer + * objects of the same seat. wl_pointer.axis and wl_pointer.button events + * are unaffected. + */ +static inline struct zwp_locked_pointer_v1 * +zwp_pointer_constraints_v1_lock_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1, + ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER, &zwp_locked_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime); + + return (struct zwp_locked_pointer_v1 *) id; +} + +/** + * @ingroup iface_zwp_pointer_constraints_v1 + * + * The confine_pointer request lets the client request to confine the + * pointer cursor to a given region. This request may not take effect + * immediately; in the future, when the compositor deems implementation- + * specific constraints are satisfied, the pointer confinement will be + * activated and the compositor sends a confined event. + * + * The intersection of the region passed with this request and the input + * region of the surface is used to determine where the pointer must be + * in order for the confinement to activate. It is up to the compositor + * whether to warp the pointer or require some kind of user interaction for + * the confinement to activate. If the region is null the surface input + * region is used. + * + * The request will create a new object wp_confined_pointer which is used + * to interact with the confinement as well as receive updates about its + * state. See the the description of wp_confined_pointer for further + * information. + */ +static inline struct zwp_confined_pointer_v1 * +zwp_pointer_constraints_v1_confine_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1, + ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER, &zwp_confined_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime); + + return (struct zwp_confined_pointer_v1 *) id; +} + +/** + * @ingroup iface_zwp_locked_pointer_v1 + * @struct zwp_locked_pointer_v1_listener + */ +struct zwp_locked_pointer_v1_listener { + /** + * lock activation event + * + * Notification that the pointer lock of the seat's pointer is + * activated. + */ + void (*locked)(void *data, + struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1); + /** + * lock deactivation event + * + * Notification that the pointer lock of the seat's pointer is no + * longer active. If this is a oneshot pointer lock (see + * wp_pointer_constraints.lifetime) this object is now defunct and + * should be destroyed. If this is a persistent pointer lock (see + * wp_pointer_constraints.lifetime) this pointer lock may again + * reactivate in the future. + */ + void (*unlocked)(void *data, + struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1); +}; + +/** + * @ingroup iface_zwp_locked_pointer_v1 + */ +static inline int +zwp_locked_pointer_v1_add_listener(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, + const struct zwp_locked_pointer_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_locked_pointer_v1, + (void (**)(void)) listener, data); +} + +#define ZWP_LOCKED_POINTER_V1_DESTROY 0 +#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT 1 +#define ZWP_LOCKED_POINTER_V1_SET_REGION 2 + +/** + * @ingroup iface_zwp_locked_pointer_v1 + */ +#define ZWP_LOCKED_POINTER_V1_LOCKED_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_locked_pointer_v1 + */ +#define ZWP_LOCKED_POINTER_V1_UNLOCKED_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_locked_pointer_v1 + */ +#define ZWP_LOCKED_POINTER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_locked_pointer_v1 + */ +#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_locked_pointer_v1 + */ +#define ZWP_LOCKED_POINTER_V1_SET_REGION_SINCE_VERSION 1 + +/** @ingroup iface_zwp_locked_pointer_v1 */ +static inline void +zwp_locked_pointer_v1_set_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_locked_pointer_v1, user_data); +} + +/** @ingroup iface_zwp_locked_pointer_v1 */ +static inline void * +zwp_locked_pointer_v1_get_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_locked_pointer_v1); +} + +static inline uint32_t +zwp_locked_pointer_v1_get_version(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1); +} + +/** + * @ingroup iface_zwp_locked_pointer_v1 + * + * Destroy the locked pointer object. If applicable, the compositor will + * unlock the pointer. + */ +static inline void +zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1, + ZWP_LOCKED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_locked_pointer_v1 + * + * Set the cursor position hint relative to the top left corner of the + * surface. + * + * If the client is drawing its own cursor, it should update the position + * hint to the position of its own cursor. A compositor may use this + * information to warp the pointer upon unlock in order to avoid pointer + * jumps. + * + * The cursor position hint is double buffered. The new hint will only take + * effect when the associated surface gets it pending state applied. See + * wl_surface.commit for details. + */ +static inline void +zwp_locked_pointer_v1_set_cursor_position_hint(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1, + ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, surface_x, surface_y); +} + +/** + * @ingroup iface_zwp_locked_pointer_v1 + * + * Set a new region used to lock the pointer. + * + * The new lock region is double-buffered. The new lock region will + * only take effect when the associated surface gets its pending state + * applied. See wl_surface.commit for details. + * + * For details about the lock region, see wp_locked_pointer. + */ +static inline void +zwp_locked_pointer_v1_set_region(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, struct wl_region *region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1, + ZWP_LOCKED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, region); +} + +/** + * @ingroup iface_zwp_confined_pointer_v1 + * @struct zwp_confined_pointer_v1_listener + */ +struct zwp_confined_pointer_v1_listener { + /** + * pointer confined + * + * Notification that the pointer confinement of the seat's + * pointer is activated. + */ + void (*confined)(void *data, + struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1); + /** + * pointer unconfined + * + * Notification that the pointer confinement of the seat's + * pointer is no longer active. If this is a oneshot pointer + * confinement (see wp_pointer_constraints.lifetime) this object is + * now defunct and should be destroyed. If this is a persistent + * pointer confinement (see wp_pointer_constraints.lifetime) this + * pointer confinement may again reactivate in the future. + */ + void (*unconfined)(void *data, + struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1); +}; + +/** + * @ingroup iface_zwp_confined_pointer_v1 + */ +static inline int +zwp_confined_pointer_v1_add_listener(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, + const struct zwp_confined_pointer_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_confined_pointer_v1, + (void (**)(void)) listener, data); +} + +#define ZWP_CONFINED_POINTER_V1_DESTROY 0 +#define ZWP_CONFINED_POINTER_V1_SET_REGION 1 + +/** + * @ingroup iface_zwp_confined_pointer_v1 + */ +#define ZWP_CONFINED_POINTER_V1_CONFINED_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_confined_pointer_v1 + */ +#define ZWP_CONFINED_POINTER_V1_UNCONFINED_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_confined_pointer_v1 + */ +#define ZWP_CONFINED_POINTER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_confined_pointer_v1 + */ +#define ZWP_CONFINED_POINTER_V1_SET_REGION_SINCE_VERSION 1 + +/** @ingroup iface_zwp_confined_pointer_v1 */ +static inline void +zwp_confined_pointer_v1_set_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_confined_pointer_v1, user_data); +} + +/** @ingroup iface_zwp_confined_pointer_v1 */ +static inline void * +zwp_confined_pointer_v1_get_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_confined_pointer_v1); +} + +static inline uint32_t +zwp_confined_pointer_v1_get_version(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1); +} + +/** + * @ingroup iface_zwp_confined_pointer_v1 + * + * Destroy the confined pointer object. If applicable, the compositor will + * unconfine the pointer. + */ +static inline void +zwp_confined_pointer_v1_destroy(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1, + ZWP_CONFINED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_confined_pointer_v1 + * + * Set a new region used to confine the pointer. + * + * The new confine region is double-buffered. The new confine region will + * only take effect when the associated surface gets its pending state + * applied. See wl_surface.commit for details. + * + * If the confinement is active when the new confinement region is applied + * and the pointer ends up outside of newly applied region, the pointer may + * warped to a position within the new confinement region. If warped, a + * wl_pointer.motion event will be emitted, but no + * wp_relative_pointer.relative_motion event. + * + * The compositor may also, instead of using the new region, unconfine the + * pointer. + * + * For details about the confine region, see wp_confined_pointer. + */ +static inline void +zwp_confined_pointer_v1_set_region(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, struct wl_region *region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1, + ZWP_CONFINED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), 0, region); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol-code.h new file mode 100644 index 0000000..e650496 --- /dev/null +++ b/raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol-code.h @@ -0,0 +1,79 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2014 Jonas Ådahl + * Copyright © 2015 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_pointer_interface; +extern const struct wl_interface zwp_relative_pointer_v1_interface; + +static const struct wl_interface *relative_pointer_unstable_v1_types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &zwp_relative_pointer_v1_interface, + &wl_pointer_interface, +}; + +static const struct wl_message zwp_relative_pointer_manager_v1_requests[] = { + { "destroy", "", relative_pointer_unstable_v1_types + 0 }, + { "get_relative_pointer", "no", relative_pointer_unstable_v1_types + 6 }, +}; + +WL_PRIVATE const struct wl_interface zwp_relative_pointer_manager_v1_interface = { + "zwp_relative_pointer_manager_v1", 1, + 2, zwp_relative_pointer_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message zwp_relative_pointer_v1_requests[] = { + { "destroy", "", relative_pointer_unstable_v1_types + 0 }, +}; + +static const struct wl_message zwp_relative_pointer_v1_events[] = { + { "relative_motion", "uuffff", relative_pointer_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_relative_pointer_v1_interface = { + "zwp_relative_pointer_v1", 1, + 1, zwp_relative_pointer_v1_requests, + 1, zwp_relative_pointer_v1_events, +}; + diff --git a/raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol.h b/raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol.h new file mode 100644 index 0000000..5aa213e --- /dev/null +++ b/raylib/external/glfw/src/relative-pointer-unstable-v1-client-protocol.h @@ -0,0 +1,297 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef RELATIVE_POINTER_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define RELATIVE_POINTER_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_relative_pointer_unstable_v1 The relative_pointer_unstable_v1 protocol + * protocol for relative pointer motion events + * + * @section page_desc_relative_pointer_unstable_v1 Description + * + * This protocol specifies a set of interfaces used for making clients able to + * receive relative pointer events not obstructed by barriers (such as the + * monitor edge or other pointer barriers). + * + * To start receiving relative pointer events, a client must first bind the + * global interface "wp_relative_pointer_manager" which, if a compositor + * supports relative pointer motion events, is exposed by the registry. After + * having created the relative pointer manager proxy object, the client uses + * it to create the actual relative pointer object using the + * "get_relative_pointer" request given a wl_pointer. The relative pointer + * motion events will then, when applicable, be transmitted via the proxy of + * the newly created relative pointer object. See the documentation of the + * relative pointer interface for more details. + * + * Warning! The protocol described in this file is experimental and backward + * incompatible changes may be made. Backward compatible changes may be added + * together with the corresponding interface version bump. Backward + * incompatible changes are done by bumping the version number in the protocol + * and interface names and resetting the interface version. Once the protocol + * is to be declared stable, the 'z' prefix and the version number in the + * protocol and interface names are removed and the interface version number is + * reset. + * + * @section page_ifaces_relative_pointer_unstable_v1 Interfaces + * - @subpage page_iface_zwp_relative_pointer_manager_v1 - get relative pointer objects + * - @subpage page_iface_zwp_relative_pointer_v1 - relative pointer object + * @section page_copyright_relative_pointer_unstable_v1 Copyright + *
+ *
+ * Copyright © 2014      Jonas Ådahl
+ * Copyright © 2015      Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_pointer; +struct zwp_relative_pointer_manager_v1; +struct zwp_relative_pointer_v1; + +#ifndef ZWP_RELATIVE_POINTER_MANAGER_V1_INTERFACE +#define ZWP_RELATIVE_POINTER_MANAGER_V1_INTERFACE +/** + * @page page_iface_zwp_relative_pointer_manager_v1 zwp_relative_pointer_manager_v1 + * @section page_iface_zwp_relative_pointer_manager_v1_desc Description + * + * A global interface used for getting the relative pointer object for a + * given pointer. + * @section page_iface_zwp_relative_pointer_manager_v1_api API + * See @ref iface_zwp_relative_pointer_manager_v1. + */ +/** + * @defgroup iface_zwp_relative_pointer_manager_v1 The zwp_relative_pointer_manager_v1 interface + * + * A global interface used for getting the relative pointer object for a + * given pointer. + */ +extern const struct wl_interface zwp_relative_pointer_manager_v1_interface; +#endif +#ifndef ZWP_RELATIVE_POINTER_V1_INTERFACE +#define ZWP_RELATIVE_POINTER_V1_INTERFACE +/** + * @page page_iface_zwp_relative_pointer_v1 zwp_relative_pointer_v1 + * @section page_iface_zwp_relative_pointer_v1_desc Description + * + * A wp_relative_pointer object is an extension to the wl_pointer interface + * used for emitting relative pointer events. It shares the same focus as + * wl_pointer objects of the same seat and will only emit events when it has + * focus. + * @section page_iface_zwp_relative_pointer_v1_api API + * See @ref iface_zwp_relative_pointer_v1. + */ +/** + * @defgroup iface_zwp_relative_pointer_v1 The zwp_relative_pointer_v1 interface + * + * A wp_relative_pointer object is an extension to the wl_pointer interface + * used for emitting relative pointer events. It shares the same focus as + * wl_pointer objects of the same seat and will only emit events when it has + * focus. + */ +extern const struct wl_interface zwp_relative_pointer_v1_interface; +#endif + +#define ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY 0 +#define ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER 1 + + +/** + * @ingroup iface_zwp_relative_pointer_manager_v1 + */ +#define ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_relative_pointer_manager_v1 + */ +#define ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER_SINCE_VERSION 1 + +/** @ingroup iface_zwp_relative_pointer_manager_v1 */ +static inline void +zwp_relative_pointer_manager_v1_set_user_data(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_relative_pointer_manager_v1, user_data); +} + +/** @ingroup iface_zwp_relative_pointer_manager_v1 */ +static inline void * +zwp_relative_pointer_manager_v1_get_user_data(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_relative_pointer_manager_v1); +} + +static inline uint32_t +zwp_relative_pointer_manager_v1_get_version(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1); +} + +/** + * @ingroup iface_zwp_relative_pointer_manager_v1 + * + * Used by the client to notify the server that it will no longer use this + * relative pointer manager object. + */ +static inline void +zwp_relative_pointer_manager_v1_destroy(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_manager_v1, + ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_relative_pointer_manager_v1 + * + * Create a relative pointer interface given a wl_pointer object. See the + * wp_relative_pointer interface for more details. + */ +static inline struct zwp_relative_pointer_v1 * +zwp_relative_pointer_manager_v1_get_relative_pointer(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, struct wl_pointer *pointer) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_manager_v1, + ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER, &zwp_relative_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1), 0, NULL, pointer); + + return (struct zwp_relative_pointer_v1 *) id; +} + +/** + * @ingroup iface_zwp_relative_pointer_v1 + * @struct zwp_relative_pointer_v1_listener + */ +struct zwp_relative_pointer_v1_listener { + /** + * relative pointer motion + * + * Relative x/y pointer motion from the pointer of the seat + * associated with this object. + * + * A relative motion is in the same dimension as regular wl_pointer + * motion events, except they do not represent an absolute + * position. For example, moving a pointer from (x, y) to (x', y') + * would have the equivalent relative motion (x' - x, y' - y). If a + * pointer motion caused the absolute pointer position to be + * clipped by for example the edge of the monitor, the relative + * motion is unaffected by the clipping and will represent the + * unclipped motion. + * + * This event also contains non-accelerated motion deltas. The + * non-accelerated delta is, when applicable, the regular pointer + * motion delta as it was before having applied motion acceleration + * and other transformations such as normalization. + * + * Note that the non-accelerated delta does not represent 'raw' + * events as they were read from some device. Pointer motion + * acceleration is device- and configuration-specific and + * non-accelerated deltas and accelerated deltas may have the same + * value on some devices. + * + * Relative motions are not coupled to wl_pointer.motion events, + * and can be sent in combination with such events, but also + * independently. There may also be scenarios where + * wl_pointer.motion is sent, but there is no relative motion. The + * order of an absolute and relative motion event originating from + * the same physical motion is not guaranteed. + * + * If the client needs button events or focus state, it can receive + * them from a wl_pointer object of the same seat that the + * wp_relative_pointer object is associated with. + * @param utime_hi high 32 bits of a 64 bit timestamp with microsecond granularity + * @param utime_lo low 32 bits of a 64 bit timestamp with microsecond granularity + * @param dx the x component of the motion vector + * @param dy the y component of the motion vector + * @param dx_unaccel the x component of the unaccelerated motion vector + * @param dy_unaccel the y component of the unaccelerated motion vector + */ + void (*relative_motion)(void *data, + struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, + uint32_t utime_hi, + uint32_t utime_lo, + wl_fixed_t dx, + wl_fixed_t dy, + wl_fixed_t dx_unaccel, + wl_fixed_t dy_unaccel); +}; + +/** + * @ingroup iface_zwp_relative_pointer_v1 + */ +static inline int +zwp_relative_pointer_v1_add_listener(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, + const struct zwp_relative_pointer_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_relative_pointer_v1, + (void (**)(void)) listener, data); +} + +#define ZWP_RELATIVE_POINTER_V1_DESTROY 0 + +/** + * @ingroup iface_zwp_relative_pointer_v1 + */ +#define ZWP_RELATIVE_POINTER_V1_RELATIVE_MOTION_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_relative_pointer_v1 + */ +#define ZWP_RELATIVE_POINTER_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zwp_relative_pointer_v1 */ +static inline void +zwp_relative_pointer_v1_set_user_data(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_relative_pointer_v1, user_data); +} + +/** @ingroup iface_zwp_relative_pointer_v1 */ +static inline void * +zwp_relative_pointer_v1_get_user_data(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_relative_pointer_v1); +} + +static inline uint32_t +zwp_relative_pointer_v1_get_version(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_v1); +} + +/** + * @ingroup iface_zwp_relative_pointer_v1 + */ +static inline void +zwp_relative_pointer_v1_destroy(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_v1, + ZWP_RELATIVE_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/viewporter-client-protocol-code.h b/raylib/external/glfw/src/viewporter-client-protocol-code.h new file mode 100644 index 0000000..fa70d5d --- /dev/null +++ b/raylib/external/glfw/src/viewporter-client-protocol-code.h @@ -0,0 +1,74 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2013-2016 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface wp_viewport_interface; + +static const struct wl_interface *viewporter_types[] = { + NULL, + NULL, + NULL, + NULL, + &wp_viewport_interface, + &wl_surface_interface, +}; + +static const struct wl_message wp_viewporter_requests[] = { + { "destroy", "", viewporter_types + 0 }, + { "get_viewport", "no", viewporter_types + 4 }, +}; + +WL_PRIVATE const struct wl_interface wp_viewporter_interface = { + "wp_viewporter", 1, + 2, wp_viewporter_requests, + 0, NULL, +}; + +static const struct wl_message wp_viewport_requests[] = { + { "destroy", "", viewporter_types + 0 }, + { "set_source", "ffff", viewporter_types + 0 }, + { "set_destination", "ii", viewporter_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wp_viewport_interface = { + "wp_viewport", 1, + 3, wp_viewport_requests, + 0, NULL, +}; + diff --git a/raylib/external/glfw/src/viewporter-client-protocol.h b/raylib/external/glfw/src/viewporter-client-protocol.h new file mode 100644 index 0000000..e1295d4 --- /dev/null +++ b/raylib/external/glfw/src/viewporter-client-protocol.h @@ -0,0 +1,398 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef VIEWPORTER_CLIENT_PROTOCOL_H +#define VIEWPORTER_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_viewporter The viewporter protocol + * @section page_ifaces_viewporter Interfaces + * - @subpage page_iface_wp_viewporter - surface cropping and scaling + * - @subpage page_iface_wp_viewport - crop and scale interface to a wl_surface + * @section page_copyright_viewporter Copyright + *
+ *
+ * Copyright © 2013-2016 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_surface; +struct wp_viewport; +struct wp_viewporter; + +#ifndef WP_VIEWPORTER_INTERFACE +#define WP_VIEWPORTER_INTERFACE +/** + * @page page_iface_wp_viewporter wp_viewporter + * @section page_iface_wp_viewporter_desc Description + * + * The global interface exposing surface cropping and scaling + * capabilities is used to instantiate an interface extension for a + * wl_surface object. This extended interface will then allow + * cropping and scaling the surface contents, effectively + * disconnecting the direct relationship between the buffer and the + * surface size. + * @section page_iface_wp_viewporter_api API + * See @ref iface_wp_viewporter. + */ +/** + * @defgroup iface_wp_viewporter The wp_viewporter interface + * + * The global interface exposing surface cropping and scaling + * capabilities is used to instantiate an interface extension for a + * wl_surface object. This extended interface will then allow + * cropping and scaling the surface contents, effectively + * disconnecting the direct relationship between the buffer and the + * surface size. + */ +extern const struct wl_interface wp_viewporter_interface; +#endif +#ifndef WP_VIEWPORT_INTERFACE +#define WP_VIEWPORT_INTERFACE +/** + * @page page_iface_wp_viewport wp_viewport + * @section page_iface_wp_viewport_desc Description + * + * An additional interface to a wl_surface object, which allows the + * client to specify the cropping and scaling of the surface + * contents. + * + * This interface works with two concepts: the source rectangle (src_x, + * src_y, src_width, src_height), and the destination size (dst_width, + * dst_height). The contents of the source rectangle are scaled to the + * destination size, and content outside the source rectangle is ignored. + * This state is double-buffered, and is applied on the next + * wl_surface.commit. + * + * The two parts of crop and scale state are independent: the source + * rectangle, and the destination size. Initially both are unset, that + * is, no scaling is applied. The whole of the current wl_buffer is + * used as the source, and the surface size is as defined in + * wl_surface.attach. + * + * If the destination size is set, it causes the surface size to become + * dst_width, dst_height. The source (rectangle) is scaled to exactly + * this size. This overrides whatever the attached wl_buffer size is, + * unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface + * has no content and therefore no size. Otherwise, the size is always + * at least 1x1 in surface local coordinates. + * + * If the source rectangle is set, it defines what area of the wl_buffer is + * taken as the source. If the source rectangle is set and the destination + * size is not set, then src_width and src_height must be integers, and the + * surface size becomes the source rectangle size. This results in cropping + * without scaling. If src_width or src_height are not integers and + * destination size is not set, the bad_size protocol error is raised when + * the surface state is applied. + * + * The coordinate transformations from buffer pixel coordinates up to + * the surface-local coordinates happen in the following order: + * 1. buffer_transform (wl_surface.set_buffer_transform) + * 2. buffer_scale (wl_surface.set_buffer_scale) + * 3. crop and scale (wp_viewport.set*) + * This means, that the source rectangle coordinates of crop and scale + * are given in the coordinates after the buffer transform and scale, + * i.e. in the coordinates that would be the surface-local coordinates + * if the crop and scale was not applied. + * + * If src_x or src_y are negative, the bad_value protocol error is raised. + * Otherwise, if the source rectangle is partially or completely outside of + * the non-NULL wl_buffer, then the out_of_buffer protocol error is raised + * when the surface state is applied. A NULL wl_buffer does not raise the + * out_of_buffer error. + * + * If the wl_surface associated with the wp_viewport is destroyed, + * all wp_viewport requests except 'destroy' raise the protocol error + * no_surface. + * + * If the wp_viewport object is destroyed, the crop and scale + * state is removed from the wl_surface. The change will be applied + * on the next wl_surface.commit. + * @section page_iface_wp_viewport_api API + * See @ref iface_wp_viewport. + */ +/** + * @defgroup iface_wp_viewport The wp_viewport interface + * + * An additional interface to a wl_surface object, which allows the + * client to specify the cropping and scaling of the surface + * contents. + * + * This interface works with two concepts: the source rectangle (src_x, + * src_y, src_width, src_height), and the destination size (dst_width, + * dst_height). The contents of the source rectangle are scaled to the + * destination size, and content outside the source rectangle is ignored. + * This state is double-buffered, and is applied on the next + * wl_surface.commit. + * + * The two parts of crop and scale state are independent: the source + * rectangle, and the destination size. Initially both are unset, that + * is, no scaling is applied. The whole of the current wl_buffer is + * used as the source, and the surface size is as defined in + * wl_surface.attach. + * + * If the destination size is set, it causes the surface size to become + * dst_width, dst_height. The source (rectangle) is scaled to exactly + * this size. This overrides whatever the attached wl_buffer size is, + * unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface + * has no content and therefore no size. Otherwise, the size is always + * at least 1x1 in surface local coordinates. + * + * If the source rectangle is set, it defines what area of the wl_buffer is + * taken as the source. If the source rectangle is set and the destination + * size is not set, then src_width and src_height must be integers, and the + * surface size becomes the source rectangle size. This results in cropping + * without scaling. If src_width or src_height are not integers and + * destination size is not set, the bad_size protocol error is raised when + * the surface state is applied. + * + * The coordinate transformations from buffer pixel coordinates up to + * the surface-local coordinates happen in the following order: + * 1. buffer_transform (wl_surface.set_buffer_transform) + * 2. buffer_scale (wl_surface.set_buffer_scale) + * 3. crop and scale (wp_viewport.set*) + * This means, that the source rectangle coordinates of crop and scale + * are given in the coordinates after the buffer transform and scale, + * i.e. in the coordinates that would be the surface-local coordinates + * if the crop and scale was not applied. + * + * If src_x or src_y are negative, the bad_value protocol error is raised. + * Otherwise, if the source rectangle is partially or completely outside of + * the non-NULL wl_buffer, then the out_of_buffer protocol error is raised + * when the surface state is applied. A NULL wl_buffer does not raise the + * out_of_buffer error. + * + * If the wl_surface associated with the wp_viewport is destroyed, + * all wp_viewport requests except 'destroy' raise the protocol error + * no_surface. + * + * If the wp_viewport object is destroyed, the crop and scale + * state is removed from the wl_surface. The change will be applied + * on the next wl_surface.commit. + */ +extern const struct wl_interface wp_viewport_interface; +#endif + +#ifndef WP_VIEWPORTER_ERROR_ENUM +#define WP_VIEWPORTER_ERROR_ENUM +enum wp_viewporter_error { + /** + * the surface already has a viewport object associated + */ + WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS = 0, +}; +#endif /* WP_VIEWPORTER_ERROR_ENUM */ + +#define WP_VIEWPORTER_DESTROY 0 +#define WP_VIEWPORTER_GET_VIEWPORT 1 + + +/** + * @ingroup iface_wp_viewporter + */ +#define WP_VIEWPORTER_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wp_viewporter + */ +#define WP_VIEWPORTER_GET_VIEWPORT_SINCE_VERSION 1 + +/** @ingroup iface_wp_viewporter */ +static inline void +wp_viewporter_set_user_data(struct wp_viewporter *wp_viewporter, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wp_viewporter, user_data); +} + +/** @ingroup iface_wp_viewporter */ +static inline void * +wp_viewporter_get_user_data(struct wp_viewporter *wp_viewporter) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wp_viewporter); +} + +static inline uint32_t +wp_viewporter_get_version(struct wp_viewporter *wp_viewporter) +{ + return wl_proxy_get_version((struct wl_proxy *) wp_viewporter); +} + +/** + * @ingroup iface_wp_viewporter + * + * Informs the server that the client will not be using this + * protocol object anymore. This does not affect any other objects, + * wp_viewport objects included. + */ +static inline void +wp_viewporter_destroy(struct wp_viewporter *wp_viewporter) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_viewporter, + WP_VIEWPORTER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewporter), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wp_viewporter + * + * Instantiate an interface extension for the given wl_surface to + * crop and scale its content. If the given wl_surface already has + * a wp_viewport object associated, the viewport_exists + * protocol error is raised. + */ +static inline struct wp_viewport * +wp_viewporter_get_viewport(struct wp_viewporter *wp_viewporter, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wp_viewporter, + WP_VIEWPORTER_GET_VIEWPORT, &wp_viewport_interface, wl_proxy_get_version((struct wl_proxy *) wp_viewporter), 0, NULL, surface); + + return (struct wp_viewport *) id; +} + +#ifndef WP_VIEWPORT_ERROR_ENUM +#define WP_VIEWPORT_ERROR_ENUM +enum wp_viewport_error { + /** + * negative or zero values in width or height + */ + WP_VIEWPORT_ERROR_BAD_VALUE = 0, + /** + * destination size is not integer + */ + WP_VIEWPORT_ERROR_BAD_SIZE = 1, + /** + * source rectangle extends outside of the content area + */ + WP_VIEWPORT_ERROR_OUT_OF_BUFFER = 2, + /** + * the wl_surface was destroyed + */ + WP_VIEWPORT_ERROR_NO_SURFACE = 3, +}; +#endif /* WP_VIEWPORT_ERROR_ENUM */ + +#define WP_VIEWPORT_DESTROY 0 +#define WP_VIEWPORT_SET_SOURCE 1 +#define WP_VIEWPORT_SET_DESTINATION 2 + + +/** + * @ingroup iface_wp_viewport + */ +#define WP_VIEWPORT_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wp_viewport + */ +#define WP_VIEWPORT_SET_SOURCE_SINCE_VERSION 1 +/** + * @ingroup iface_wp_viewport + */ +#define WP_VIEWPORT_SET_DESTINATION_SINCE_VERSION 1 + +/** @ingroup iface_wp_viewport */ +static inline void +wp_viewport_set_user_data(struct wp_viewport *wp_viewport, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wp_viewport, user_data); +} + +/** @ingroup iface_wp_viewport */ +static inline void * +wp_viewport_get_user_data(struct wp_viewport *wp_viewport) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wp_viewport); +} + +static inline uint32_t +wp_viewport_get_version(struct wp_viewport *wp_viewport) +{ + return wl_proxy_get_version((struct wl_proxy *) wp_viewport); +} + +/** + * @ingroup iface_wp_viewport + * + * The associated wl_surface's crop and scale state is removed. + * The change is applied on the next wl_surface.commit. + */ +static inline void +wp_viewport_destroy(struct wp_viewport *wp_viewport) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport, + WP_VIEWPORT_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wp_viewport + * + * Set the source rectangle of the associated wl_surface. See + * wp_viewport for the description, and relation to the wl_buffer + * size. + * + * If all of x, y, width and height are -1.0, the source rectangle is + * unset instead. Any other set of values where width or height are zero + * or negative, or x or y are negative, raise the bad_value protocol + * error. + * + * The crop and scale state is double-buffered state, and will be + * applied on the next wl_surface.commit. + */ +static inline void +wp_viewport_set_source(struct wp_viewport *wp_viewport, wl_fixed_t x, wl_fixed_t y, wl_fixed_t width, wl_fixed_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport, + WP_VIEWPORT_SET_SOURCE, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), 0, x, y, width, height); +} + +/** + * @ingroup iface_wp_viewport + * + * Set the destination size of the associated wl_surface. See + * wp_viewport for the description, and relation to the wl_buffer + * size. + * + * If width is -1 and height is -1, the destination size is unset + * instead. Any other pair of values for width and height that + * contains zero or negative values raises the bad_value protocol + * error. + * + * The crop and scale state is double-buffered state, and will be + * applied on the next wl_surface.commit. + */ +static inline void +wp_viewport_set_destination(struct wp_viewport *wp_viewport, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport, + WP_VIEWPORT_SET_DESTINATION, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), 0, width, height); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/wayland-client-protocol-code.h b/raylib/external/glfw/src/wayland-client-protocol-code.h new file mode 100644 index 0000000..cd1a838 --- /dev/null +++ b/raylib/external/glfw/src/wayland-client-protocol-code.h @@ -0,0 +1,525 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2010-2011 Intel Corporation + * Copyright © 2012-2013 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_buffer_interface; +extern const struct wl_interface wl_callback_interface; +extern const struct wl_interface wl_data_device_interface; +extern const struct wl_interface wl_data_offer_interface; +extern const struct wl_interface wl_data_source_interface; +extern const struct wl_interface wl_keyboard_interface; +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface wl_pointer_interface; +extern const struct wl_interface wl_region_interface; +extern const struct wl_interface wl_registry_interface; +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface wl_shell_surface_interface; +extern const struct wl_interface wl_shm_pool_interface; +extern const struct wl_interface wl_subsurface_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface wl_touch_interface; + +static const struct wl_interface *wayland_types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &wl_callback_interface, + &wl_registry_interface, + &wl_surface_interface, + &wl_region_interface, + &wl_buffer_interface, + NULL, + NULL, + NULL, + NULL, + NULL, + &wl_shm_pool_interface, + NULL, + NULL, + &wl_data_source_interface, + &wl_surface_interface, + &wl_surface_interface, + NULL, + &wl_data_source_interface, + NULL, + &wl_data_offer_interface, + NULL, + &wl_surface_interface, + NULL, + NULL, + &wl_data_offer_interface, + &wl_data_offer_interface, + &wl_data_source_interface, + &wl_data_device_interface, + &wl_seat_interface, + &wl_shell_surface_interface, + &wl_surface_interface, + &wl_seat_interface, + NULL, + &wl_seat_interface, + NULL, + NULL, + &wl_surface_interface, + NULL, + NULL, + NULL, + NULL, + NULL, + &wl_output_interface, + &wl_seat_interface, + NULL, + &wl_surface_interface, + NULL, + NULL, + NULL, + &wl_output_interface, + &wl_buffer_interface, + NULL, + NULL, + &wl_callback_interface, + &wl_region_interface, + &wl_region_interface, + &wl_output_interface, + &wl_output_interface, + &wl_pointer_interface, + &wl_keyboard_interface, + &wl_touch_interface, + NULL, + &wl_surface_interface, + NULL, + NULL, + NULL, + &wl_surface_interface, + NULL, + NULL, + NULL, + &wl_surface_interface, + NULL, + &wl_surface_interface, + NULL, + NULL, + &wl_surface_interface, + NULL, + NULL, + &wl_surface_interface, + NULL, + NULL, + NULL, + &wl_subsurface_interface, + &wl_surface_interface, + &wl_surface_interface, + &wl_surface_interface, + &wl_surface_interface, +}; + +static const struct wl_message wl_display_requests[] = { + { "sync", "n", wayland_types + 8 }, + { "get_registry", "n", wayland_types + 9 }, +}; + +static const struct wl_message wl_display_events[] = { + { "error", "ous", wayland_types + 0 }, + { "delete_id", "u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_display_interface = { + "wl_display", 1, + 2, wl_display_requests, + 2, wl_display_events, +}; + +static const struct wl_message wl_registry_requests[] = { + { "bind", "usun", wayland_types + 0 }, +}; + +static const struct wl_message wl_registry_events[] = { + { "global", "usu", wayland_types + 0 }, + { "global_remove", "u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_registry_interface = { + "wl_registry", 1, + 1, wl_registry_requests, + 2, wl_registry_events, +}; + +static const struct wl_message wl_callback_events[] = { + { "done", "u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_callback_interface = { + "wl_callback", 1, + 0, NULL, + 1, wl_callback_events, +}; + +static const struct wl_message wl_compositor_requests[] = { + { "create_surface", "n", wayland_types + 10 }, + { "create_region", "n", wayland_types + 11 }, +}; + +WL_PRIVATE const struct wl_interface wl_compositor_interface = { + "wl_compositor", 6, + 2, wl_compositor_requests, + 0, NULL, +}; + +static const struct wl_message wl_shm_pool_requests[] = { + { "create_buffer", "niiiiu", wayland_types + 12 }, + { "destroy", "", wayland_types + 0 }, + { "resize", "i", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_shm_pool_interface = { + "wl_shm_pool", 2, + 3, wl_shm_pool_requests, + 0, NULL, +}; + +static const struct wl_message wl_shm_requests[] = { + { "create_pool", "nhi", wayland_types + 18 }, + { "release", "2", wayland_types + 0 }, +}; + +static const struct wl_message wl_shm_events[] = { + { "format", "u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_shm_interface = { + "wl_shm", 2, + 2, wl_shm_requests, + 1, wl_shm_events, +}; + +static const struct wl_message wl_buffer_requests[] = { + { "destroy", "", wayland_types + 0 }, +}; + +static const struct wl_message wl_buffer_events[] = { + { "release", "", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_buffer_interface = { + "wl_buffer", 1, + 1, wl_buffer_requests, + 1, wl_buffer_events, +}; + +static const struct wl_message wl_data_offer_requests[] = { + { "accept", "u?s", wayland_types + 0 }, + { "receive", "sh", wayland_types + 0 }, + { "destroy", "", wayland_types + 0 }, + { "finish", "3", wayland_types + 0 }, + { "set_actions", "3uu", wayland_types + 0 }, +}; + +static const struct wl_message wl_data_offer_events[] = { + { "offer", "s", wayland_types + 0 }, + { "source_actions", "3u", wayland_types + 0 }, + { "action", "3u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_data_offer_interface = { + "wl_data_offer", 3, + 5, wl_data_offer_requests, + 3, wl_data_offer_events, +}; + +static const struct wl_message wl_data_source_requests[] = { + { "offer", "s", wayland_types + 0 }, + { "destroy", "", wayland_types + 0 }, + { "set_actions", "3u", wayland_types + 0 }, +}; + +static const struct wl_message wl_data_source_events[] = { + { "target", "?s", wayland_types + 0 }, + { "send", "sh", wayland_types + 0 }, + { "cancelled", "", wayland_types + 0 }, + { "dnd_drop_performed", "3", wayland_types + 0 }, + { "dnd_finished", "3", wayland_types + 0 }, + { "action", "3u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_data_source_interface = { + "wl_data_source", 3, + 3, wl_data_source_requests, + 6, wl_data_source_events, +}; + +static const struct wl_message wl_data_device_requests[] = { + { "start_drag", "?oo?ou", wayland_types + 21 }, + { "set_selection", "?ou", wayland_types + 25 }, + { "release", "2", wayland_types + 0 }, +}; + +static const struct wl_message wl_data_device_events[] = { + { "data_offer", "n", wayland_types + 27 }, + { "enter", "uoff?o", wayland_types + 28 }, + { "leave", "", wayland_types + 0 }, + { "motion", "uff", wayland_types + 0 }, + { "drop", "", wayland_types + 0 }, + { "selection", "?o", wayland_types + 33 }, +}; + +WL_PRIVATE const struct wl_interface wl_data_device_interface = { + "wl_data_device", 3, + 3, wl_data_device_requests, + 6, wl_data_device_events, +}; + +static const struct wl_message wl_data_device_manager_requests[] = { + { "create_data_source", "n", wayland_types + 34 }, + { "get_data_device", "no", wayland_types + 35 }, +}; + +WL_PRIVATE const struct wl_interface wl_data_device_manager_interface = { + "wl_data_device_manager", 3, + 2, wl_data_device_manager_requests, + 0, NULL, +}; + +static const struct wl_message wl_shell_requests[] = { + { "get_shell_surface", "no", wayland_types + 37 }, +}; + +WL_PRIVATE const struct wl_interface wl_shell_interface = { + "wl_shell", 1, + 1, wl_shell_requests, + 0, NULL, +}; + +static const struct wl_message wl_shell_surface_requests[] = { + { "pong", "u", wayland_types + 0 }, + { "move", "ou", wayland_types + 39 }, + { "resize", "ouu", wayland_types + 41 }, + { "set_toplevel", "", wayland_types + 0 }, + { "set_transient", "oiiu", wayland_types + 44 }, + { "set_fullscreen", "uu?o", wayland_types + 48 }, + { "set_popup", "ouoiiu", wayland_types + 51 }, + { "set_maximized", "?o", wayland_types + 57 }, + { "set_title", "s", wayland_types + 0 }, + { "set_class", "s", wayland_types + 0 }, +}; + +static const struct wl_message wl_shell_surface_events[] = { + { "ping", "u", wayland_types + 0 }, + { "configure", "uii", wayland_types + 0 }, + { "popup_done", "", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_shell_surface_interface = { + "wl_shell_surface", 1, + 10, wl_shell_surface_requests, + 3, wl_shell_surface_events, +}; + +static const struct wl_message wl_surface_requests[] = { + { "destroy", "", wayland_types + 0 }, + { "attach", "?oii", wayland_types + 58 }, + { "damage", "iiii", wayland_types + 0 }, + { "frame", "n", wayland_types + 61 }, + { "set_opaque_region", "?o", wayland_types + 62 }, + { "set_input_region", "?o", wayland_types + 63 }, + { "commit", "", wayland_types + 0 }, + { "set_buffer_transform", "2i", wayland_types + 0 }, + { "set_buffer_scale", "3i", wayland_types + 0 }, + { "damage_buffer", "4iiii", wayland_types + 0 }, + { "offset", "5ii", wayland_types + 0 }, +}; + +static const struct wl_message wl_surface_events[] = { + { "enter", "o", wayland_types + 64 }, + { "leave", "o", wayland_types + 65 }, + { "preferred_buffer_scale", "6i", wayland_types + 0 }, + { "preferred_buffer_transform", "6u", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_surface_interface = { + "wl_surface", 6, + 11, wl_surface_requests, + 4, wl_surface_events, +}; + +static const struct wl_message wl_seat_requests[] = { + { "get_pointer", "n", wayland_types + 66 }, + { "get_keyboard", "n", wayland_types + 67 }, + { "get_touch", "n", wayland_types + 68 }, + { "release", "5", wayland_types + 0 }, +}; + +static const struct wl_message wl_seat_events[] = { + { "capabilities", "u", wayland_types + 0 }, + { "name", "2s", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_seat_interface = { + "wl_seat", 9, + 4, wl_seat_requests, + 2, wl_seat_events, +}; + +static const struct wl_message wl_pointer_requests[] = { + { "set_cursor", "u?oii", wayland_types + 69 }, + { "release", "3", wayland_types + 0 }, +}; + +static const struct wl_message wl_pointer_events[] = { + { "enter", "uoff", wayland_types + 73 }, + { "leave", "uo", wayland_types + 77 }, + { "motion", "uff", wayland_types + 0 }, + { "button", "uuuu", wayland_types + 0 }, + { "axis", "uuf", wayland_types + 0 }, + { "frame", "5", wayland_types + 0 }, + { "axis_source", "5u", wayland_types + 0 }, + { "axis_stop", "5uu", wayland_types + 0 }, + { "axis_discrete", "5ui", wayland_types + 0 }, + { "axis_value120", "8ui", wayland_types + 0 }, + { "axis_relative_direction", "9uu", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_pointer_interface = { + "wl_pointer", 9, + 2, wl_pointer_requests, + 11, wl_pointer_events, +}; + +static const struct wl_message wl_keyboard_requests[] = { + { "release", "3", wayland_types + 0 }, +}; + +static const struct wl_message wl_keyboard_events[] = { + { "keymap", "uhu", wayland_types + 0 }, + { "enter", "uoa", wayland_types + 79 }, + { "leave", "uo", wayland_types + 82 }, + { "key", "uuuu", wayland_types + 0 }, + { "modifiers", "uuuuu", wayland_types + 0 }, + { "repeat_info", "4ii", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_keyboard_interface = { + "wl_keyboard", 9, + 1, wl_keyboard_requests, + 6, wl_keyboard_events, +}; + +static const struct wl_message wl_touch_requests[] = { + { "release", "3", wayland_types + 0 }, +}; + +static const struct wl_message wl_touch_events[] = { + { "down", "uuoiff", wayland_types + 84 }, + { "up", "uui", wayland_types + 0 }, + { "motion", "uiff", wayland_types + 0 }, + { "frame", "", wayland_types + 0 }, + { "cancel", "", wayland_types + 0 }, + { "shape", "6iff", wayland_types + 0 }, + { "orientation", "6if", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_touch_interface = { + "wl_touch", 9, + 1, wl_touch_requests, + 7, wl_touch_events, +}; + +static const struct wl_message wl_output_requests[] = { + { "release", "3", wayland_types + 0 }, +}; + +static const struct wl_message wl_output_events[] = { + { "geometry", "iiiiissi", wayland_types + 0 }, + { "mode", "uiii", wayland_types + 0 }, + { "done", "2", wayland_types + 0 }, + { "scale", "2i", wayland_types + 0 }, + { "name", "4s", wayland_types + 0 }, + { "description", "4s", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_output_interface = { + "wl_output", 4, + 1, wl_output_requests, + 6, wl_output_events, +}; + +static const struct wl_message wl_region_requests[] = { + { "destroy", "", wayland_types + 0 }, + { "add", "iiii", wayland_types + 0 }, + { "subtract", "iiii", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_region_interface = { + "wl_region", 1, + 3, wl_region_requests, + 0, NULL, +}; + +static const struct wl_message wl_subcompositor_requests[] = { + { "destroy", "", wayland_types + 0 }, + { "get_subsurface", "noo", wayland_types + 90 }, +}; + +WL_PRIVATE const struct wl_interface wl_subcompositor_interface = { + "wl_subcompositor", 1, + 2, wl_subcompositor_requests, + 0, NULL, +}; + +static const struct wl_message wl_subsurface_requests[] = { + { "destroy", "", wayland_types + 0 }, + { "set_position", "ii", wayland_types + 0 }, + { "place_above", "o", wayland_types + 93 }, + { "place_below", "o", wayland_types + 94 }, + { "set_sync", "", wayland_types + 0 }, + { "set_desync", "", wayland_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wl_subsurface_interface = { + "wl_subsurface", 1, + 6, wl_subsurface_requests, + 0, NULL, +}; + diff --git a/raylib/external/glfw/src/wayland-client-protocol.h b/raylib/external/glfw/src/wayland-client-protocol.h new file mode 100644 index 0000000..d200c79 --- /dev/null +++ b/raylib/external/glfw/src/wayland-client-protocol.h @@ -0,0 +1,6359 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef WAYLAND_CLIENT_PROTOCOL_H +#define WAYLAND_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_wayland The wayland protocol + * @section page_ifaces_wayland Interfaces + * - @subpage page_iface_wl_display - core global object + * - @subpage page_iface_wl_registry - global registry object + * - @subpage page_iface_wl_callback - callback object + * - @subpage page_iface_wl_compositor - the compositor singleton + * - @subpage page_iface_wl_shm_pool - a shared memory pool + * - @subpage page_iface_wl_shm - shared memory support + * - @subpage page_iface_wl_buffer - content for a wl_surface + * - @subpage page_iface_wl_data_offer - offer to transfer data + * - @subpage page_iface_wl_data_source - offer to transfer data + * - @subpage page_iface_wl_data_device - data transfer device + * - @subpage page_iface_wl_data_device_manager - data transfer interface + * - @subpage page_iface_wl_shell - create desktop-style surfaces + * - @subpage page_iface_wl_shell_surface - desktop-style metadata interface + * - @subpage page_iface_wl_surface - an onscreen surface + * - @subpage page_iface_wl_seat - group of input devices + * - @subpage page_iface_wl_pointer - pointer input device + * - @subpage page_iface_wl_keyboard - keyboard input device + * - @subpage page_iface_wl_touch - touchscreen input device + * - @subpage page_iface_wl_output - compositor output region + * - @subpage page_iface_wl_region - region interface + * - @subpage page_iface_wl_subcompositor - sub-surface compositing + * - @subpage page_iface_wl_subsurface - sub-surface interface to a wl_surface + * @section page_copyright_wayland Copyright + *
+ *
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ * Copyright © 2012-2013 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * 
+ */ +struct wl_buffer; +struct wl_callback; +struct wl_compositor; +struct wl_data_device; +struct wl_data_device_manager; +struct wl_data_offer; +struct wl_data_source; +struct wl_display; +struct wl_keyboard; +struct wl_output; +struct wl_pointer; +struct wl_region; +struct wl_registry; +struct wl_seat; +struct wl_shell; +struct wl_shell_surface; +struct wl_shm; +struct wl_shm_pool; +struct wl_subcompositor; +struct wl_subsurface; +struct wl_surface; +struct wl_touch; + +#ifndef WL_DISPLAY_INTERFACE +#define WL_DISPLAY_INTERFACE +/** + * @page page_iface_wl_display wl_display + * @section page_iface_wl_display_desc Description + * + * The core global object. This is a special singleton object. It + * is used for internal Wayland protocol features. + * @section page_iface_wl_display_api API + * See @ref iface_wl_display. + */ +/** + * @defgroup iface_wl_display The wl_display interface + * + * The core global object. This is a special singleton object. It + * is used for internal Wayland protocol features. + */ +extern const struct wl_interface wl_display_interface; +#endif +#ifndef WL_REGISTRY_INTERFACE +#define WL_REGISTRY_INTERFACE +/** + * @page page_iface_wl_registry wl_registry + * @section page_iface_wl_registry_desc Description + * + * The singleton global registry object. The server has a number of + * global objects that are available to all clients. These objects + * typically represent an actual object in the server (for example, + * an input device) or they are singleton objects that provide + * extension functionality. + * + * When a client creates a registry object, the registry object + * will emit a global event for each global currently in the + * registry. Globals come and go as a result of device or + * monitor hotplugs, reconfiguration or other events, and the + * registry will send out global and global_remove events to + * keep the client up to date with the changes. To mark the end + * of the initial burst of events, the client can use the + * wl_display.sync request immediately after calling + * wl_display.get_registry. + * + * A client can bind to a global object by using the bind + * request. This creates a client-side handle that lets the object + * emit events to the client and lets the client invoke requests on + * the object. + * @section page_iface_wl_registry_api API + * See @ref iface_wl_registry. + */ +/** + * @defgroup iface_wl_registry The wl_registry interface + * + * The singleton global registry object. The server has a number of + * global objects that are available to all clients. These objects + * typically represent an actual object in the server (for example, + * an input device) or they are singleton objects that provide + * extension functionality. + * + * When a client creates a registry object, the registry object + * will emit a global event for each global currently in the + * registry. Globals come and go as a result of device or + * monitor hotplugs, reconfiguration or other events, and the + * registry will send out global and global_remove events to + * keep the client up to date with the changes. To mark the end + * of the initial burst of events, the client can use the + * wl_display.sync request immediately after calling + * wl_display.get_registry. + * + * A client can bind to a global object by using the bind + * request. This creates a client-side handle that lets the object + * emit events to the client and lets the client invoke requests on + * the object. + */ +extern const struct wl_interface wl_registry_interface; +#endif +#ifndef WL_CALLBACK_INTERFACE +#define WL_CALLBACK_INTERFACE +/** + * @page page_iface_wl_callback wl_callback + * @section page_iface_wl_callback_desc Description + * + * Clients can handle the 'done' event to get notified when + * the related request is done. + * + * Note, because wl_callback objects are created from multiple independent + * factory interfaces, the wl_callback interface is frozen at version 1. + * @section page_iface_wl_callback_api API + * See @ref iface_wl_callback. + */ +/** + * @defgroup iface_wl_callback The wl_callback interface + * + * Clients can handle the 'done' event to get notified when + * the related request is done. + * + * Note, because wl_callback objects are created from multiple independent + * factory interfaces, the wl_callback interface is frozen at version 1. + */ +extern const struct wl_interface wl_callback_interface; +#endif +#ifndef WL_COMPOSITOR_INTERFACE +#define WL_COMPOSITOR_INTERFACE +/** + * @page page_iface_wl_compositor wl_compositor + * @section page_iface_wl_compositor_desc Description + * + * A compositor. This object is a singleton global. The + * compositor is in charge of combining the contents of multiple + * surfaces into one displayable output. + * @section page_iface_wl_compositor_api API + * See @ref iface_wl_compositor. + */ +/** + * @defgroup iface_wl_compositor The wl_compositor interface + * + * A compositor. This object is a singleton global. The + * compositor is in charge of combining the contents of multiple + * surfaces into one displayable output. + */ +extern const struct wl_interface wl_compositor_interface; +#endif +#ifndef WL_SHM_POOL_INTERFACE +#define WL_SHM_POOL_INTERFACE +/** + * @page page_iface_wl_shm_pool wl_shm_pool + * @section page_iface_wl_shm_pool_desc Description + * + * The wl_shm_pool object encapsulates a piece of memory shared + * between the compositor and client. Through the wl_shm_pool + * object, the client can allocate shared memory wl_buffer objects. + * All objects created through the same pool share the same + * underlying mapped memory. Reusing the mapped memory avoids the + * setup/teardown overhead and is useful when interactively resizing + * a surface or for many small buffers. + * @section page_iface_wl_shm_pool_api API + * See @ref iface_wl_shm_pool. + */ +/** + * @defgroup iface_wl_shm_pool The wl_shm_pool interface + * + * The wl_shm_pool object encapsulates a piece of memory shared + * between the compositor and client. Through the wl_shm_pool + * object, the client can allocate shared memory wl_buffer objects. + * All objects created through the same pool share the same + * underlying mapped memory. Reusing the mapped memory avoids the + * setup/teardown overhead and is useful when interactively resizing + * a surface or for many small buffers. + */ +extern const struct wl_interface wl_shm_pool_interface; +#endif +#ifndef WL_SHM_INTERFACE +#define WL_SHM_INTERFACE +/** + * @page page_iface_wl_shm wl_shm + * @section page_iface_wl_shm_desc Description + * + * A singleton global object that provides support for shared + * memory. + * + * Clients can create wl_shm_pool objects using the create_pool + * request. + * + * On binding the wl_shm object one or more format events + * are emitted to inform clients about the valid pixel formats + * that can be used for buffers. + * @section page_iface_wl_shm_api API + * See @ref iface_wl_shm. + */ +/** + * @defgroup iface_wl_shm The wl_shm interface + * + * A singleton global object that provides support for shared + * memory. + * + * Clients can create wl_shm_pool objects using the create_pool + * request. + * + * On binding the wl_shm object one or more format events + * are emitted to inform clients about the valid pixel formats + * that can be used for buffers. + */ +extern const struct wl_interface wl_shm_interface; +#endif +#ifndef WL_BUFFER_INTERFACE +#define WL_BUFFER_INTERFACE +/** + * @page page_iface_wl_buffer wl_buffer + * @section page_iface_wl_buffer_desc Description + * + * A buffer provides the content for a wl_surface. Buffers are + * created through factory interfaces such as wl_shm, wp_linux_buffer_params + * (from the linux-dmabuf protocol extension) or similar. It has a width and + * a height and can be attached to a wl_surface, but the mechanism by which a + * client provides and updates the contents is defined by the buffer factory + * interface. + * + * If the buffer uses a format that has an alpha channel, the alpha channel + * is assumed to be premultiplied in the electrical color channel values + * (after transfer function encoding) unless otherwise specified. + * + * Note, because wl_buffer objects are created from multiple independent + * factory interfaces, the wl_buffer interface is frozen at version 1. + * @section page_iface_wl_buffer_api API + * See @ref iface_wl_buffer. + */ +/** + * @defgroup iface_wl_buffer The wl_buffer interface + * + * A buffer provides the content for a wl_surface. Buffers are + * created through factory interfaces such as wl_shm, wp_linux_buffer_params + * (from the linux-dmabuf protocol extension) or similar. It has a width and + * a height and can be attached to a wl_surface, but the mechanism by which a + * client provides and updates the contents is defined by the buffer factory + * interface. + * + * If the buffer uses a format that has an alpha channel, the alpha channel + * is assumed to be premultiplied in the electrical color channel values + * (after transfer function encoding) unless otherwise specified. + * + * Note, because wl_buffer objects are created from multiple independent + * factory interfaces, the wl_buffer interface is frozen at version 1. + */ +extern const struct wl_interface wl_buffer_interface; +#endif +#ifndef WL_DATA_OFFER_INTERFACE +#define WL_DATA_OFFER_INTERFACE +/** + * @page page_iface_wl_data_offer wl_data_offer + * @section page_iface_wl_data_offer_desc Description + * + * A wl_data_offer represents a piece of data offered for transfer + * by another client (the source client). It is used by the + * copy-and-paste and drag-and-drop mechanisms. The offer + * describes the different mime types that the data can be + * converted to and provides the mechanism for transferring the + * data directly from the source client. + * @section page_iface_wl_data_offer_api API + * See @ref iface_wl_data_offer. + */ +/** + * @defgroup iface_wl_data_offer The wl_data_offer interface + * + * A wl_data_offer represents a piece of data offered for transfer + * by another client (the source client). It is used by the + * copy-and-paste and drag-and-drop mechanisms. The offer + * describes the different mime types that the data can be + * converted to and provides the mechanism for transferring the + * data directly from the source client. + */ +extern const struct wl_interface wl_data_offer_interface; +#endif +#ifndef WL_DATA_SOURCE_INTERFACE +#define WL_DATA_SOURCE_INTERFACE +/** + * @page page_iface_wl_data_source wl_data_source + * @section page_iface_wl_data_source_desc Description + * + * The wl_data_source object is the source side of a wl_data_offer. + * It is created by the source client in a data transfer and + * provides a way to describe the offered data and a way to respond + * to requests to transfer the data. + * @section page_iface_wl_data_source_api API + * See @ref iface_wl_data_source. + */ +/** + * @defgroup iface_wl_data_source The wl_data_source interface + * + * The wl_data_source object is the source side of a wl_data_offer. + * It is created by the source client in a data transfer and + * provides a way to describe the offered data and a way to respond + * to requests to transfer the data. + */ +extern const struct wl_interface wl_data_source_interface; +#endif +#ifndef WL_DATA_DEVICE_INTERFACE +#define WL_DATA_DEVICE_INTERFACE +/** + * @page page_iface_wl_data_device wl_data_device + * @section page_iface_wl_data_device_desc Description + * + * There is one wl_data_device per seat which can be obtained + * from the global wl_data_device_manager singleton. + * + * A wl_data_device provides access to inter-client data transfer + * mechanisms such as copy-and-paste and drag-and-drop. + * @section page_iface_wl_data_device_api API + * See @ref iface_wl_data_device. + */ +/** + * @defgroup iface_wl_data_device The wl_data_device interface + * + * There is one wl_data_device per seat which can be obtained + * from the global wl_data_device_manager singleton. + * + * A wl_data_device provides access to inter-client data transfer + * mechanisms such as copy-and-paste and drag-and-drop. + */ +extern const struct wl_interface wl_data_device_interface; +#endif +#ifndef WL_DATA_DEVICE_MANAGER_INTERFACE +#define WL_DATA_DEVICE_MANAGER_INTERFACE +/** + * @page page_iface_wl_data_device_manager wl_data_device_manager + * @section page_iface_wl_data_device_manager_desc Description + * + * The wl_data_device_manager is a singleton global object that + * provides access to inter-client data transfer mechanisms such as + * copy-and-paste and drag-and-drop. These mechanisms are tied to + * a wl_seat and this interface lets a client get a wl_data_device + * corresponding to a wl_seat. + * + * Depending on the version bound, the objects created from the bound + * wl_data_device_manager object will have different requirements for + * functioning properly. See wl_data_source.set_actions, + * wl_data_offer.accept and wl_data_offer.finish for details. + * @section page_iface_wl_data_device_manager_api API + * See @ref iface_wl_data_device_manager. + */ +/** + * @defgroup iface_wl_data_device_manager The wl_data_device_manager interface + * + * The wl_data_device_manager is a singleton global object that + * provides access to inter-client data transfer mechanisms such as + * copy-and-paste and drag-and-drop. These mechanisms are tied to + * a wl_seat and this interface lets a client get a wl_data_device + * corresponding to a wl_seat. + * + * Depending on the version bound, the objects created from the bound + * wl_data_device_manager object will have different requirements for + * functioning properly. See wl_data_source.set_actions, + * wl_data_offer.accept and wl_data_offer.finish for details. + */ +extern const struct wl_interface wl_data_device_manager_interface; +#endif +#ifndef WL_SHELL_INTERFACE +#define WL_SHELL_INTERFACE +/** + * @page page_iface_wl_shell wl_shell + * @section page_iface_wl_shell_desc Description + * + * This interface is implemented by servers that provide + * desktop-style user interfaces. + * + * It allows clients to associate a wl_shell_surface with + * a basic surface. + * + * Note! This protocol is deprecated and not intended for production use. + * For desktop-style user interfaces, use xdg_shell. Compositors and clients + * should not implement this interface. + * @section page_iface_wl_shell_api API + * See @ref iface_wl_shell. + */ +/** + * @defgroup iface_wl_shell The wl_shell interface + * + * This interface is implemented by servers that provide + * desktop-style user interfaces. + * + * It allows clients to associate a wl_shell_surface with + * a basic surface. + * + * Note! This protocol is deprecated and not intended for production use. + * For desktop-style user interfaces, use xdg_shell. Compositors and clients + * should not implement this interface. + */ +extern const struct wl_interface wl_shell_interface; +#endif +#ifndef WL_SHELL_SURFACE_INTERFACE +#define WL_SHELL_SURFACE_INTERFACE +/** + * @page page_iface_wl_shell_surface wl_shell_surface + * @section page_iface_wl_shell_surface_desc Description + * + * An interface that may be implemented by a wl_surface, for + * implementations that provide a desktop-style user interface. + * + * It provides requests to treat surfaces like toplevel, fullscreen + * or popup windows, move, resize or maximize them, associate + * metadata like title and class, etc. + * + * On the server side the object is automatically destroyed when + * the related wl_surface is destroyed. On the client side, + * wl_shell_surface_destroy() must be called before destroying + * the wl_surface object. + * @section page_iface_wl_shell_surface_api API + * See @ref iface_wl_shell_surface. + */ +/** + * @defgroup iface_wl_shell_surface The wl_shell_surface interface + * + * An interface that may be implemented by a wl_surface, for + * implementations that provide a desktop-style user interface. + * + * It provides requests to treat surfaces like toplevel, fullscreen + * or popup windows, move, resize or maximize them, associate + * metadata like title and class, etc. + * + * On the server side the object is automatically destroyed when + * the related wl_surface is destroyed. On the client side, + * wl_shell_surface_destroy() must be called before destroying + * the wl_surface object. + */ +extern const struct wl_interface wl_shell_surface_interface; +#endif +#ifndef WL_SURFACE_INTERFACE +#define WL_SURFACE_INTERFACE +/** + * @page page_iface_wl_surface wl_surface + * @section page_iface_wl_surface_desc Description + * + * A surface is a rectangular area that may be displayed on zero + * or more outputs, and shown any number of times at the compositor's + * discretion. They can present wl_buffers, receive user input, and + * define a local coordinate system. + * + * The size of a surface (and relative positions on it) is described + * in surface-local coordinates, which may differ from the buffer + * coordinates of the pixel content, in case a buffer_transform + * or a buffer_scale is used. + * + * A surface without a "role" is fairly useless: a compositor does + * not know where, when or how to present it. The role is the + * purpose of a wl_surface. Examples of roles are a cursor for a + * pointer (as set by wl_pointer.set_cursor), a drag icon + * (wl_data_device.start_drag), a sub-surface + * (wl_subcompositor.get_subsurface), and a window as defined by a + * shell protocol (e.g. wl_shell.get_shell_surface). + * + * A surface can have only one role at a time. Initially a + * wl_surface does not have a role. Once a wl_surface is given a + * role, it is set permanently for the whole lifetime of the + * wl_surface object. Giving the current role again is allowed, + * unless explicitly forbidden by the relevant interface + * specification. + * + * Surface roles are given by requests in other interfaces such as + * wl_pointer.set_cursor. The request should explicitly mention + * that this request gives a role to a wl_surface. Often, this + * request also creates a new protocol object that represents the + * role and adds additional functionality to wl_surface. When a + * client wants to destroy a wl_surface, they must destroy this role + * object before the wl_surface, otherwise a defunct_role_object error is + * sent. + * + * Destroying the role object does not remove the role from the + * wl_surface, but it may stop the wl_surface from "playing the role". + * For instance, if a wl_subsurface object is destroyed, the wl_surface + * it was created for will be unmapped and forget its position and + * z-order. It is allowed to create a wl_subsurface for the same + * wl_surface again, but it is not allowed to use the wl_surface as + * a cursor (cursor is a different role than sub-surface, and role + * switching is not allowed). + * @section page_iface_wl_surface_api API + * See @ref iface_wl_surface. + */ +/** + * @defgroup iface_wl_surface The wl_surface interface + * + * A surface is a rectangular area that may be displayed on zero + * or more outputs, and shown any number of times at the compositor's + * discretion. They can present wl_buffers, receive user input, and + * define a local coordinate system. + * + * The size of a surface (and relative positions on it) is described + * in surface-local coordinates, which may differ from the buffer + * coordinates of the pixel content, in case a buffer_transform + * or a buffer_scale is used. + * + * A surface without a "role" is fairly useless: a compositor does + * not know where, when or how to present it. The role is the + * purpose of a wl_surface. Examples of roles are a cursor for a + * pointer (as set by wl_pointer.set_cursor), a drag icon + * (wl_data_device.start_drag), a sub-surface + * (wl_subcompositor.get_subsurface), and a window as defined by a + * shell protocol (e.g. wl_shell.get_shell_surface). + * + * A surface can have only one role at a time. Initially a + * wl_surface does not have a role. Once a wl_surface is given a + * role, it is set permanently for the whole lifetime of the + * wl_surface object. Giving the current role again is allowed, + * unless explicitly forbidden by the relevant interface + * specification. + * + * Surface roles are given by requests in other interfaces such as + * wl_pointer.set_cursor. The request should explicitly mention + * that this request gives a role to a wl_surface. Often, this + * request also creates a new protocol object that represents the + * role and adds additional functionality to wl_surface. When a + * client wants to destroy a wl_surface, they must destroy this role + * object before the wl_surface, otherwise a defunct_role_object error is + * sent. + * + * Destroying the role object does not remove the role from the + * wl_surface, but it may stop the wl_surface from "playing the role". + * For instance, if a wl_subsurface object is destroyed, the wl_surface + * it was created for will be unmapped and forget its position and + * z-order. It is allowed to create a wl_subsurface for the same + * wl_surface again, but it is not allowed to use the wl_surface as + * a cursor (cursor is a different role than sub-surface, and role + * switching is not allowed). + */ +extern const struct wl_interface wl_surface_interface; +#endif +#ifndef WL_SEAT_INTERFACE +#define WL_SEAT_INTERFACE +/** + * @page page_iface_wl_seat wl_seat + * @section page_iface_wl_seat_desc Description + * + * A seat is a group of keyboards, pointer and touch devices. This + * object is published as a global during start up, or when such a + * device is hot plugged. A seat typically has a pointer and + * maintains a keyboard focus and a pointer focus. + * @section page_iface_wl_seat_api API + * See @ref iface_wl_seat. + */ +/** + * @defgroup iface_wl_seat The wl_seat interface + * + * A seat is a group of keyboards, pointer and touch devices. This + * object is published as a global during start up, or when such a + * device is hot plugged. A seat typically has a pointer and + * maintains a keyboard focus and a pointer focus. + */ +extern const struct wl_interface wl_seat_interface; +#endif +#ifndef WL_POINTER_INTERFACE +#define WL_POINTER_INTERFACE +/** + * @page page_iface_wl_pointer wl_pointer + * @section page_iface_wl_pointer_desc Description + * + * The wl_pointer interface represents one or more input devices, + * such as mice, which control the pointer location and pointer_focus + * of a seat. + * + * The wl_pointer interface generates motion, enter and leave + * events for the surfaces that the pointer is located over, + * and button and axis events for button presses, button releases + * and scrolling. + * @section page_iface_wl_pointer_api API + * See @ref iface_wl_pointer. + */ +/** + * @defgroup iface_wl_pointer The wl_pointer interface + * + * The wl_pointer interface represents one or more input devices, + * such as mice, which control the pointer location and pointer_focus + * of a seat. + * + * The wl_pointer interface generates motion, enter and leave + * events for the surfaces that the pointer is located over, + * and button and axis events for button presses, button releases + * and scrolling. + */ +extern const struct wl_interface wl_pointer_interface; +#endif +#ifndef WL_KEYBOARD_INTERFACE +#define WL_KEYBOARD_INTERFACE +/** + * @page page_iface_wl_keyboard wl_keyboard + * @section page_iface_wl_keyboard_desc Description + * + * The wl_keyboard interface represents one or more keyboards + * associated with a seat. + * @section page_iface_wl_keyboard_api API + * See @ref iface_wl_keyboard. + */ +/** + * @defgroup iface_wl_keyboard The wl_keyboard interface + * + * The wl_keyboard interface represents one or more keyboards + * associated with a seat. + */ +extern const struct wl_interface wl_keyboard_interface; +#endif +#ifndef WL_TOUCH_INTERFACE +#define WL_TOUCH_INTERFACE +/** + * @page page_iface_wl_touch wl_touch + * @section page_iface_wl_touch_desc Description + * + * The wl_touch interface represents a touchscreen + * associated with a seat. + * + * Touch interactions can consist of one or more contacts. + * For each contact, a series of events is generated, starting + * with a down event, followed by zero or more motion events, + * and ending with an up event. Events relating to the same + * contact point can be identified by the ID of the sequence. + * @section page_iface_wl_touch_api API + * See @ref iface_wl_touch. + */ +/** + * @defgroup iface_wl_touch The wl_touch interface + * + * The wl_touch interface represents a touchscreen + * associated with a seat. + * + * Touch interactions can consist of one or more contacts. + * For each contact, a series of events is generated, starting + * with a down event, followed by zero or more motion events, + * and ending with an up event. Events relating to the same + * contact point can be identified by the ID of the sequence. + */ +extern const struct wl_interface wl_touch_interface; +#endif +#ifndef WL_OUTPUT_INTERFACE +#define WL_OUTPUT_INTERFACE +/** + * @page page_iface_wl_output wl_output + * @section page_iface_wl_output_desc Description + * + * An output describes part of the compositor geometry. The + * compositor works in the 'compositor coordinate system' and an + * output corresponds to a rectangular area in that space that is + * actually visible. This typically corresponds to a monitor that + * displays part of the compositor space. This object is published + * as global during start up, or when a monitor is hotplugged. + * @section page_iface_wl_output_api API + * See @ref iface_wl_output. + */ +/** + * @defgroup iface_wl_output The wl_output interface + * + * An output describes part of the compositor geometry. The + * compositor works in the 'compositor coordinate system' and an + * output corresponds to a rectangular area in that space that is + * actually visible. This typically corresponds to a monitor that + * displays part of the compositor space. This object is published + * as global during start up, or when a monitor is hotplugged. + */ +extern const struct wl_interface wl_output_interface; +#endif +#ifndef WL_REGION_INTERFACE +#define WL_REGION_INTERFACE +/** + * @page page_iface_wl_region wl_region + * @section page_iface_wl_region_desc Description + * + * A region object describes an area. + * + * Region objects are used to describe the opaque and input + * regions of a surface. + * @section page_iface_wl_region_api API + * See @ref iface_wl_region. + */ +/** + * @defgroup iface_wl_region The wl_region interface + * + * A region object describes an area. + * + * Region objects are used to describe the opaque and input + * regions of a surface. + */ +extern const struct wl_interface wl_region_interface; +#endif +#ifndef WL_SUBCOMPOSITOR_INTERFACE +#define WL_SUBCOMPOSITOR_INTERFACE +/** + * @page page_iface_wl_subcompositor wl_subcompositor + * @section page_iface_wl_subcompositor_desc Description + * + * The global interface exposing sub-surface compositing capabilities. + * A wl_surface, that has sub-surfaces associated, is called the + * parent surface. Sub-surfaces can be arbitrarily nested and create + * a tree of sub-surfaces. + * + * The root surface in a tree of sub-surfaces is the main + * surface. The main surface cannot be a sub-surface, because + * sub-surfaces must always have a parent. + * + * A main surface with its sub-surfaces forms a (compound) window. + * For window management purposes, this set of wl_surface objects is + * to be considered as a single window, and it should also behave as + * such. + * + * The aim of sub-surfaces is to offload some of the compositing work + * within a window from clients to the compositor. A prime example is + * a video player with decorations and video in separate wl_surface + * objects. This should allow the compositor to pass YUV video buffer + * processing to dedicated overlay hardware when possible. + * @section page_iface_wl_subcompositor_api API + * See @ref iface_wl_subcompositor. + */ +/** + * @defgroup iface_wl_subcompositor The wl_subcompositor interface + * + * The global interface exposing sub-surface compositing capabilities. + * A wl_surface, that has sub-surfaces associated, is called the + * parent surface. Sub-surfaces can be arbitrarily nested and create + * a tree of sub-surfaces. + * + * The root surface in a tree of sub-surfaces is the main + * surface. The main surface cannot be a sub-surface, because + * sub-surfaces must always have a parent. + * + * A main surface with its sub-surfaces forms a (compound) window. + * For window management purposes, this set of wl_surface objects is + * to be considered as a single window, and it should also behave as + * such. + * + * The aim of sub-surfaces is to offload some of the compositing work + * within a window from clients to the compositor. A prime example is + * a video player with decorations and video in separate wl_surface + * objects. This should allow the compositor to pass YUV video buffer + * processing to dedicated overlay hardware when possible. + */ +extern const struct wl_interface wl_subcompositor_interface; +#endif +#ifndef WL_SUBSURFACE_INTERFACE +#define WL_SUBSURFACE_INTERFACE +/** + * @page page_iface_wl_subsurface wl_subsurface + * @section page_iface_wl_subsurface_desc Description + * + * An additional interface to a wl_surface object, which has been + * made a sub-surface. A sub-surface has one parent surface. A + * sub-surface's size and position are not limited to that of the parent. + * Particularly, a sub-surface is not automatically clipped to its + * parent's area. + * + * A sub-surface becomes mapped, when a non-NULL wl_buffer is applied + * and the parent surface is mapped. The order of which one happens + * first is irrelevant. A sub-surface is hidden if the parent becomes + * hidden, or if a NULL wl_buffer is applied. These rules apply + * recursively through the tree of surfaces. + * + * The behaviour of a wl_surface.commit request on a sub-surface + * depends on the sub-surface's mode. The possible modes are + * synchronized and desynchronized, see methods + * wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized + * mode caches the wl_surface state to be applied when the parent's + * state gets applied, and desynchronized mode applies the pending + * wl_surface state directly. A sub-surface is initially in the + * synchronized mode. + * + * Sub-surfaces also have another kind of state, which is managed by + * wl_subsurface requests, as opposed to wl_surface requests. This + * state includes the sub-surface position relative to the parent + * surface (wl_subsurface.set_position), and the stacking order of + * the parent and its sub-surfaces (wl_subsurface.place_above and + * .place_below). This state is applied when the parent surface's + * wl_surface state is applied, regardless of the sub-surface's mode. + * As the exception, set_sync and set_desync are effective immediately. + * + * The main surface can be thought to be always in desynchronized mode, + * since it does not have a parent in the sub-surfaces sense. + * + * Even if a sub-surface is in desynchronized mode, it will behave as + * in synchronized mode, if its parent surface behaves as in + * synchronized mode. This rule is applied recursively throughout the + * tree of surfaces. This means, that one can set a sub-surface into + * synchronized mode, and then assume that all its child and grand-child + * sub-surfaces are synchronized, too, without explicitly setting them. + * + * Destroying a sub-surface takes effect immediately. If you need to + * synchronize the removal of a sub-surface to the parent surface update, + * unmap the sub-surface first by attaching a NULL wl_buffer, update parent, + * and then destroy the sub-surface. + * + * If the parent wl_surface object is destroyed, the sub-surface is + * unmapped. + * + * A sub-surface never has the keyboard focus of any seat. + * + * The wl_surface.offset request is ignored: clients must use set_position + * instead to move the sub-surface. + * @section page_iface_wl_subsurface_api API + * See @ref iface_wl_subsurface. + */ +/** + * @defgroup iface_wl_subsurface The wl_subsurface interface + * + * An additional interface to a wl_surface object, which has been + * made a sub-surface. A sub-surface has one parent surface. A + * sub-surface's size and position are not limited to that of the parent. + * Particularly, a sub-surface is not automatically clipped to its + * parent's area. + * + * A sub-surface becomes mapped, when a non-NULL wl_buffer is applied + * and the parent surface is mapped. The order of which one happens + * first is irrelevant. A sub-surface is hidden if the parent becomes + * hidden, or if a NULL wl_buffer is applied. These rules apply + * recursively through the tree of surfaces. + * + * The behaviour of a wl_surface.commit request on a sub-surface + * depends on the sub-surface's mode. The possible modes are + * synchronized and desynchronized, see methods + * wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized + * mode caches the wl_surface state to be applied when the parent's + * state gets applied, and desynchronized mode applies the pending + * wl_surface state directly. A sub-surface is initially in the + * synchronized mode. + * + * Sub-surfaces also have another kind of state, which is managed by + * wl_subsurface requests, as opposed to wl_surface requests. This + * state includes the sub-surface position relative to the parent + * surface (wl_subsurface.set_position), and the stacking order of + * the parent and its sub-surfaces (wl_subsurface.place_above and + * .place_below). This state is applied when the parent surface's + * wl_surface state is applied, regardless of the sub-surface's mode. + * As the exception, set_sync and set_desync are effective immediately. + * + * The main surface can be thought to be always in desynchronized mode, + * since it does not have a parent in the sub-surfaces sense. + * + * Even if a sub-surface is in desynchronized mode, it will behave as + * in synchronized mode, if its parent surface behaves as in + * synchronized mode. This rule is applied recursively throughout the + * tree of surfaces. This means, that one can set a sub-surface into + * synchronized mode, and then assume that all its child and grand-child + * sub-surfaces are synchronized, too, without explicitly setting them. + * + * Destroying a sub-surface takes effect immediately. If you need to + * synchronize the removal of a sub-surface to the parent surface update, + * unmap the sub-surface first by attaching a NULL wl_buffer, update parent, + * and then destroy the sub-surface. + * + * If the parent wl_surface object is destroyed, the sub-surface is + * unmapped. + * + * A sub-surface never has the keyboard focus of any seat. + * + * The wl_surface.offset request is ignored: clients must use set_position + * instead to move the sub-surface. + */ +extern const struct wl_interface wl_subsurface_interface; +#endif + +#ifndef WL_DISPLAY_ERROR_ENUM +#define WL_DISPLAY_ERROR_ENUM +/** + * @ingroup iface_wl_display + * global error values + * + * These errors are global and can be emitted in response to any + * server request. + */ +enum wl_display_error { + /** + * server couldn't find object + */ + WL_DISPLAY_ERROR_INVALID_OBJECT = 0, + /** + * method doesn't exist on the specified interface or malformed request + */ + WL_DISPLAY_ERROR_INVALID_METHOD = 1, + /** + * server is out of memory + */ + WL_DISPLAY_ERROR_NO_MEMORY = 2, + /** + * implementation error in compositor + */ + WL_DISPLAY_ERROR_IMPLEMENTATION = 3, +}; +#endif /* WL_DISPLAY_ERROR_ENUM */ + +/** + * @ingroup iface_wl_display + * @struct wl_display_listener + */ +struct wl_display_listener { + /** + * fatal error event + * + * The error event is sent out when a fatal (non-recoverable) + * error has occurred. The object_id argument is the object where + * the error occurred, most often in response to a request to that + * object. The code identifies the error and is defined by the + * object interface. As such, each interface defines its own set of + * error codes. The message is a brief description of the error, + * for (debugging) convenience. + * @param object_id object where the error occurred + * @param code error code + * @param message error description + */ + void (*error)(void *data, + struct wl_display *wl_display, + void *object_id, + uint32_t code, + const char *message); + /** + * acknowledge object ID deletion + * + * This event is used internally by the object ID management + * logic. When a client deletes an object that it had created, the + * server will send this event to acknowledge that it has seen the + * delete request. When the client receives this event, it will + * know that it can safely reuse the object ID. + * @param id deleted object ID + */ + void (*delete_id)(void *data, + struct wl_display *wl_display, + uint32_t id); +}; + +/** + * @ingroup iface_wl_display + */ +static inline int +wl_display_add_listener(struct wl_display *wl_display, + const struct wl_display_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_display, + (void (**)(void)) listener, data); +} + +#define WL_DISPLAY_SYNC 0 +#define WL_DISPLAY_GET_REGISTRY 1 + +/** + * @ingroup iface_wl_display + */ +#define WL_DISPLAY_ERROR_SINCE_VERSION 1 +/** + * @ingroup iface_wl_display + */ +#define WL_DISPLAY_DELETE_ID_SINCE_VERSION 1 + +/** + * @ingroup iface_wl_display + */ +#define WL_DISPLAY_SYNC_SINCE_VERSION 1 +/** + * @ingroup iface_wl_display + */ +#define WL_DISPLAY_GET_REGISTRY_SINCE_VERSION 1 + +/** @ingroup iface_wl_display */ +static inline void +wl_display_set_user_data(struct wl_display *wl_display, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_display, user_data); +} + +/** @ingroup iface_wl_display */ +static inline void * +wl_display_get_user_data(struct wl_display *wl_display) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_display); +} + +static inline uint32_t +wl_display_get_version(struct wl_display *wl_display) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_display); +} + +/** + * @ingroup iface_wl_display + * + * The sync request asks the server to emit the 'done' event + * on the returned wl_callback object. Since requests are + * handled in-order and events are delivered in-order, this can + * be used as a barrier to ensure all previous requests and the + * resulting events have been handled. + * + * The object returned by this request will be destroyed by the + * compositor after the callback is fired and as such the client must not + * attempt to use it after that point. + * + * The callback_data passed in the callback is the event serial. + */ +static inline struct wl_callback * +wl_display_sync(struct wl_display *wl_display) +{ + struct wl_proxy *callback; + + callback = wl_proxy_marshal_flags((struct wl_proxy *) wl_display, + WL_DISPLAY_SYNC, &wl_callback_interface, wl_proxy_get_version((struct wl_proxy *) wl_display), 0, NULL); + + return (struct wl_callback *) callback; +} + +/** + * @ingroup iface_wl_display + * + * This request creates a registry object that allows the client + * to list and bind the global objects available from the + * compositor. + * + * It should be noted that the server side resources consumed in + * response to a get_registry request can only be released when the + * client disconnects, not when the client side proxy is destroyed. + * Therefore, clients should invoke get_registry as infrequently as + * possible to avoid wasting memory. + */ +static inline struct wl_registry * +wl_display_get_registry(struct wl_display *wl_display) +{ + struct wl_proxy *registry; + + registry = wl_proxy_marshal_flags((struct wl_proxy *) wl_display, + WL_DISPLAY_GET_REGISTRY, &wl_registry_interface, wl_proxy_get_version((struct wl_proxy *) wl_display), 0, NULL); + + return (struct wl_registry *) registry; +} + +/** + * @ingroup iface_wl_registry + * @struct wl_registry_listener + */ +struct wl_registry_listener { + /** + * announce global object + * + * Notify the client of global objects. + * + * The event notifies the client that a global object with the + * given name is now available, and it implements the given version + * of the given interface. + * @param name numeric name of the global object + * @param interface interface implemented by the object + * @param version interface version + */ + void (*global)(void *data, + struct wl_registry *wl_registry, + uint32_t name, + const char *interface, + uint32_t version); + /** + * announce removal of global object + * + * Notify the client of removed global objects. + * + * This event notifies the client that the global identified by + * name is no longer available. If the client bound to the global + * using the bind request, the client should now destroy that + * object. + * + * The object remains valid and requests to the object will be + * ignored until the client destroys it, to avoid races between the + * global going away and a client sending a request to it. + * @param name numeric name of the global object + */ + void (*global_remove)(void *data, + struct wl_registry *wl_registry, + uint32_t name); +}; + +/** + * @ingroup iface_wl_registry + */ +static inline int +wl_registry_add_listener(struct wl_registry *wl_registry, + const struct wl_registry_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_registry, + (void (**)(void)) listener, data); +} + +#define WL_REGISTRY_BIND 0 + +/** + * @ingroup iface_wl_registry + */ +#define WL_REGISTRY_GLOBAL_SINCE_VERSION 1 +/** + * @ingroup iface_wl_registry + */ +#define WL_REGISTRY_GLOBAL_REMOVE_SINCE_VERSION 1 + +/** + * @ingroup iface_wl_registry + */ +#define WL_REGISTRY_BIND_SINCE_VERSION 1 + +/** @ingroup iface_wl_registry */ +static inline void +wl_registry_set_user_data(struct wl_registry *wl_registry, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_registry, user_data); +} + +/** @ingroup iface_wl_registry */ +static inline void * +wl_registry_get_user_data(struct wl_registry *wl_registry) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_registry); +} + +static inline uint32_t +wl_registry_get_version(struct wl_registry *wl_registry) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_registry); +} + +/** @ingroup iface_wl_registry */ +static inline void +wl_registry_destroy(struct wl_registry *wl_registry) +{ + wl_proxy_destroy((struct wl_proxy *) wl_registry); +} + +/** + * @ingroup iface_wl_registry + * + * Binds a new, client-created object to the server using the + * specified name as the identifier. + */ +static inline void * +wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_registry, + WL_REGISTRY_BIND, interface, version, 0, name, interface->name, version, NULL); + + return (void *) id; +} + +/** + * @ingroup iface_wl_callback + * @struct wl_callback_listener + */ +struct wl_callback_listener { + /** + * done event + * + * Notify the client when the related request is done. + * @param callback_data request-specific data for the callback + */ + void (*done)(void *data, + struct wl_callback *wl_callback, + uint32_t callback_data); +}; + +/** + * @ingroup iface_wl_callback + */ +static inline int +wl_callback_add_listener(struct wl_callback *wl_callback, + const struct wl_callback_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_callback, + (void (**)(void)) listener, data); +} + +/** + * @ingroup iface_wl_callback + */ +#define WL_CALLBACK_DONE_SINCE_VERSION 1 + + +/** @ingroup iface_wl_callback */ +static inline void +wl_callback_set_user_data(struct wl_callback *wl_callback, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_callback, user_data); +} + +/** @ingroup iface_wl_callback */ +static inline void * +wl_callback_get_user_data(struct wl_callback *wl_callback) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_callback); +} + +static inline uint32_t +wl_callback_get_version(struct wl_callback *wl_callback) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_callback); +} + +/** @ingroup iface_wl_callback */ +static inline void +wl_callback_destroy(struct wl_callback *wl_callback) +{ + wl_proxy_destroy((struct wl_proxy *) wl_callback); +} + +#define WL_COMPOSITOR_CREATE_SURFACE 0 +#define WL_COMPOSITOR_CREATE_REGION 1 + + +/** + * @ingroup iface_wl_compositor + */ +#define WL_COMPOSITOR_CREATE_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_compositor + */ +#define WL_COMPOSITOR_CREATE_REGION_SINCE_VERSION 1 + +/** @ingroup iface_wl_compositor */ +static inline void +wl_compositor_set_user_data(struct wl_compositor *wl_compositor, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_compositor, user_data); +} + +/** @ingroup iface_wl_compositor */ +static inline void * +wl_compositor_get_user_data(struct wl_compositor *wl_compositor) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_compositor); +} + +static inline uint32_t +wl_compositor_get_version(struct wl_compositor *wl_compositor) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_compositor); +} + +/** @ingroup iface_wl_compositor */ +static inline void +wl_compositor_destroy(struct wl_compositor *wl_compositor) +{ + wl_proxy_destroy((struct wl_proxy *) wl_compositor); +} + +/** + * @ingroup iface_wl_compositor + * + * Ask the compositor to create a new surface. + */ +static inline struct wl_surface * +wl_compositor_create_surface(struct wl_compositor *wl_compositor) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_compositor, + WL_COMPOSITOR_CREATE_SURFACE, &wl_surface_interface, wl_proxy_get_version((struct wl_proxy *) wl_compositor), 0, NULL); + + return (struct wl_surface *) id; +} + +/** + * @ingroup iface_wl_compositor + * + * Ask the compositor to create a new region. + */ +static inline struct wl_region * +wl_compositor_create_region(struct wl_compositor *wl_compositor) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_compositor, + WL_COMPOSITOR_CREATE_REGION, &wl_region_interface, wl_proxy_get_version((struct wl_proxy *) wl_compositor), 0, NULL); + + return (struct wl_region *) id; +} + +#define WL_SHM_POOL_CREATE_BUFFER 0 +#define WL_SHM_POOL_DESTROY 1 +#define WL_SHM_POOL_RESIZE 2 + + +/** + * @ingroup iface_wl_shm_pool + */ +#define WL_SHM_POOL_CREATE_BUFFER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shm_pool + */ +#define WL_SHM_POOL_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shm_pool + */ +#define WL_SHM_POOL_RESIZE_SINCE_VERSION 1 + +/** @ingroup iface_wl_shm_pool */ +static inline void +wl_shm_pool_set_user_data(struct wl_shm_pool *wl_shm_pool, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shm_pool, user_data); +} + +/** @ingroup iface_wl_shm_pool */ +static inline void * +wl_shm_pool_get_user_data(struct wl_shm_pool *wl_shm_pool) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shm_pool); +} + +static inline uint32_t +wl_shm_pool_get_version(struct wl_shm_pool *wl_shm_pool) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shm_pool); +} + +/** + * @ingroup iface_wl_shm_pool + * + * Create a wl_buffer object from the pool. + * + * The buffer is created offset bytes into the pool and has + * width and height as specified. The stride argument specifies + * the number of bytes from the beginning of one row to the beginning + * of the next. The format is the pixel format of the buffer and + * must be one of those advertised through the wl_shm.format event. + * + * A buffer will keep a reference to the pool it was created from + * so it is valid to destroy the pool immediately after creating + * a buffer from it. + */ +static inline struct wl_buffer * +wl_shm_pool_create_buffer(struct wl_shm_pool *wl_shm_pool, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, + WL_SHM_POOL_CREATE_BUFFER, &wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), 0, NULL, offset, width, height, stride, format); + + return (struct wl_buffer *) id; +} + +/** + * @ingroup iface_wl_shm_pool + * + * Destroy the shared memory pool. + * + * The mmapped memory will be released when all + * buffers that have been created from this pool + * are gone. + */ +static inline void +wl_shm_pool_destroy(struct wl_shm_pool *wl_shm_pool) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, + WL_SHM_POOL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_shm_pool + * + * This request will cause the server to remap the backing memory + * for the pool from the file descriptor passed when the pool was + * created, but using the new size. This request can only be + * used to make the pool bigger. + * + * This request only changes the amount of bytes that are mmapped + * by the server and does not touch the file corresponding to the + * file descriptor passed at creation time. It is the client's + * responsibility to ensure that the file is at least as big as + * the new pool size. + */ +static inline void +wl_shm_pool_resize(struct wl_shm_pool *wl_shm_pool, int32_t size) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shm_pool, + WL_SHM_POOL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm_pool), 0, size); +} + +#ifndef WL_SHM_ERROR_ENUM +#define WL_SHM_ERROR_ENUM +/** + * @ingroup iface_wl_shm + * wl_shm error values + * + * These errors can be emitted in response to wl_shm requests. + */ +enum wl_shm_error { + /** + * buffer format is not known + */ + WL_SHM_ERROR_INVALID_FORMAT = 0, + /** + * invalid size or stride during pool or buffer creation + */ + WL_SHM_ERROR_INVALID_STRIDE = 1, + /** + * mmapping the file descriptor failed + */ + WL_SHM_ERROR_INVALID_FD = 2, +}; +#endif /* WL_SHM_ERROR_ENUM */ + +#ifndef WL_SHM_FORMAT_ENUM +#define WL_SHM_FORMAT_ENUM +/** + * @ingroup iface_wl_shm + * pixel formats + * + * This describes the memory layout of an individual pixel. + * + * All renderers should support argb8888 and xrgb8888 but any other + * formats are optional and may not be supported by the particular + * renderer in use. + * + * The drm format codes match the macros defined in drm_fourcc.h, except + * argb8888 and xrgb8888. The formats actually supported by the compositor + * will be reported by the format event. + * + * For all wl_shm formats and unless specified in another protocol + * extension, pre-multiplied alpha is used for pixel values. + */ +enum wl_shm_format { + /** + * 32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian + */ + WL_SHM_FORMAT_ARGB8888 = 0, + /** + * 32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian + */ + WL_SHM_FORMAT_XRGB8888 = 1, + /** + * 8-bit color index format, [7:0] C + */ + WL_SHM_FORMAT_C8 = 0x20203843, + /** + * 8-bit RGB format, [7:0] R:G:B 3:3:2 + */ + WL_SHM_FORMAT_RGB332 = 0x38424752, + /** + * 8-bit BGR format, [7:0] B:G:R 2:3:3 + */ + WL_SHM_FORMAT_BGR233 = 0x38524742, + /** + * 16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian + */ + WL_SHM_FORMAT_XRGB4444 = 0x32315258, + /** + * 16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian + */ + WL_SHM_FORMAT_XBGR4444 = 0x32314258, + /** + * 16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian + */ + WL_SHM_FORMAT_RGBX4444 = 0x32315852, + /** + * 16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian + */ + WL_SHM_FORMAT_BGRX4444 = 0x32315842, + /** + * 16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian + */ + WL_SHM_FORMAT_ARGB4444 = 0x32315241, + /** + * 16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian + */ + WL_SHM_FORMAT_ABGR4444 = 0x32314241, + /** + * 16-bit RBGA format, [15:0] R:G:B:A 4:4:4:4 little endian + */ + WL_SHM_FORMAT_RGBA4444 = 0x32314152, + /** + * 16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian + */ + WL_SHM_FORMAT_BGRA4444 = 0x32314142, + /** + * 16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian + */ + WL_SHM_FORMAT_XRGB1555 = 0x35315258, + /** + * 16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian + */ + WL_SHM_FORMAT_XBGR1555 = 0x35314258, + /** + * 16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian + */ + WL_SHM_FORMAT_RGBX5551 = 0x35315852, + /** + * 16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian + */ + WL_SHM_FORMAT_BGRX5551 = 0x35315842, + /** + * 16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian + */ + WL_SHM_FORMAT_ARGB1555 = 0x35315241, + /** + * 16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian + */ + WL_SHM_FORMAT_ABGR1555 = 0x35314241, + /** + * 16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian + */ + WL_SHM_FORMAT_RGBA5551 = 0x35314152, + /** + * 16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian + */ + WL_SHM_FORMAT_BGRA5551 = 0x35314142, + /** + * 16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian + */ + WL_SHM_FORMAT_RGB565 = 0x36314752, + /** + * 16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian + */ + WL_SHM_FORMAT_BGR565 = 0x36314742, + /** + * 24-bit RGB format, [23:0] R:G:B little endian + */ + WL_SHM_FORMAT_RGB888 = 0x34324752, + /** + * 24-bit BGR format, [23:0] B:G:R little endian + */ + WL_SHM_FORMAT_BGR888 = 0x34324742, + /** + * 32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian + */ + WL_SHM_FORMAT_XBGR8888 = 0x34324258, + /** + * 32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian + */ + WL_SHM_FORMAT_RGBX8888 = 0x34325852, + /** + * 32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian + */ + WL_SHM_FORMAT_BGRX8888 = 0x34325842, + /** + * 32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian + */ + WL_SHM_FORMAT_ABGR8888 = 0x34324241, + /** + * 32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian + */ + WL_SHM_FORMAT_RGBA8888 = 0x34324152, + /** + * 32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian + */ + WL_SHM_FORMAT_BGRA8888 = 0x34324142, + /** + * 32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian + */ + WL_SHM_FORMAT_XRGB2101010 = 0x30335258, + /** + * 32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian + */ + WL_SHM_FORMAT_XBGR2101010 = 0x30334258, + /** + * 32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian + */ + WL_SHM_FORMAT_RGBX1010102 = 0x30335852, + /** + * 32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian + */ + WL_SHM_FORMAT_BGRX1010102 = 0x30335842, + /** + * 32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian + */ + WL_SHM_FORMAT_ARGB2101010 = 0x30335241, + /** + * 32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian + */ + WL_SHM_FORMAT_ABGR2101010 = 0x30334241, + /** + * 32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian + */ + WL_SHM_FORMAT_RGBA1010102 = 0x30334152, + /** + * 32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian + */ + WL_SHM_FORMAT_BGRA1010102 = 0x30334142, + /** + * packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian + */ + WL_SHM_FORMAT_YUYV = 0x56595559, + /** + * packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian + */ + WL_SHM_FORMAT_YVYU = 0x55595659, + /** + * packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian + */ + WL_SHM_FORMAT_UYVY = 0x59565955, + /** + * packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian + */ + WL_SHM_FORMAT_VYUY = 0x59555956, + /** + * packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian + */ + WL_SHM_FORMAT_AYUV = 0x56555941, + /** + * 2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane + */ + WL_SHM_FORMAT_NV12 = 0x3231564e, + /** + * 2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane + */ + WL_SHM_FORMAT_NV21 = 0x3132564e, + /** + * 2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane + */ + WL_SHM_FORMAT_NV16 = 0x3631564e, + /** + * 2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane + */ + WL_SHM_FORMAT_NV61 = 0x3136564e, + /** + * 3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes + */ + WL_SHM_FORMAT_YUV410 = 0x39565559, + /** + * 3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes + */ + WL_SHM_FORMAT_YVU410 = 0x39555659, + /** + * 3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes + */ + WL_SHM_FORMAT_YUV411 = 0x31315559, + /** + * 3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes + */ + WL_SHM_FORMAT_YVU411 = 0x31315659, + /** + * 3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes + */ + WL_SHM_FORMAT_YUV420 = 0x32315559, + /** + * 3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes + */ + WL_SHM_FORMAT_YVU420 = 0x32315659, + /** + * 3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes + */ + WL_SHM_FORMAT_YUV422 = 0x36315559, + /** + * 3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes + */ + WL_SHM_FORMAT_YVU422 = 0x36315659, + /** + * 3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes + */ + WL_SHM_FORMAT_YUV444 = 0x34325559, + /** + * 3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes + */ + WL_SHM_FORMAT_YVU444 = 0x34325659, + /** + * [7:0] R + */ + WL_SHM_FORMAT_R8 = 0x20203852, + /** + * [15:0] R little endian + */ + WL_SHM_FORMAT_R16 = 0x20363152, + /** + * [15:0] R:G 8:8 little endian + */ + WL_SHM_FORMAT_RG88 = 0x38384752, + /** + * [15:0] G:R 8:8 little endian + */ + WL_SHM_FORMAT_GR88 = 0x38385247, + /** + * [31:0] R:G 16:16 little endian + */ + WL_SHM_FORMAT_RG1616 = 0x32334752, + /** + * [31:0] G:R 16:16 little endian + */ + WL_SHM_FORMAT_GR1616 = 0x32335247, + /** + * [63:0] x:R:G:B 16:16:16:16 little endian + */ + WL_SHM_FORMAT_XRGB16161616F = 0x48345258, + /** + * [63:0] x:B:G:R 16:16:16:16 little endian + */ + WL_SHM_FORMAT_XBGR16161616F = 0x48344258, + /** + * [63:0] A:R:G:B 16:16:16:16 little endian + */ + WL_SHM_FORMAT_ARGB16161616F = 0x48345241, + /** + * [63:0] A:B:G:R 16:16:16:16 little endian + */ + WL_SHM_FORMAT_ABGR16161616F = 0x48344241, + /** + * [31:0] X:Y:Cb:Cr 8:8:8:8 little endian + */ + WL_SHM_FORMAT_XYUV8888 = 0x56555958, + /** + * [23:0] Cr:Cb:Y 8:8:8 little endian + */ + WL_SHM_FORMAT_VUY888 = 0x34325556, + /** + * Y followed by U then V, 10:10:10. Non-linear modifier only + */ + WL_SHM_FORMAT_VUY101010 = 0x30335556, + /** + * [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels + */ + WL_SHM_FORMAT_Y210 = 0x30313259, + /** + * [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels + */ + WL_SHM_FORMAT_Y212 = 0x32313259, + /** + * [63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels + */ + WL_SHM_FORMAT_Y216 = 0x36313259, + /** + * [31:0] A:Cr:Y:Cb 2:10:10:10 little endian + */ + WL_SHM_FORMAT_Y410 = 0x30313459, + /** + * [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian + */ + WL_SHM_FORMAT_Y412 = 0x32313459, + /** + * [63:0] A:Cr:Y:Cb 16:16:16:16 little endian + */ + WL_SHM_FORMAT_Y416 = 0x36313459, + /** + * [31:0] X:Cr:Y:Cb 2:10:10:10 little endian + */ + WL_SHM_FORMAT_XVYU2101010 = 0x30335658, + /** + * [63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian + */ + WL_SHM_FORMAT_XVYU12_16161616 = 0x36335658, + /** + * [63:0] X:Cr:Y:Cb 16:16:16:16 little endian + */ + WL_SHM_FORMAT_XVYU16161616 = 0x38345658, + /** + * [63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian + */ + WL_SHM_FORMAT_Y0L0 = 0x304c3059, + /** + * [63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian + */ + WL_SHM_FORMAT_X0L0 = 0x304c3058, + /** + * [63:0] A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian + */ + WL_SHM_FORMAT_Y0L2 = 0x324c3059, + /** + * [63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian + */ + WL_SHM_FORMAT_X0L2 = 0x324c3058, + WL_SHM_FORMAT_YUV420_8BIT = 0x38305559, + WL_SHM_FORMAT_YUV420_10BIT = 0x30315559, + WL_SHM_FORMAT_XRGB8888_A8 = 0x38415258, + WL_SHM_FORMAT_XBGR8888_A8 = 0x38414258, + WL_SHM_FORMAT_RGBX8888_A8 = 0x38415852, + WL_SHM_FORMAT_BGRX8888_A8 = 0x38415842, + WL_SHM_FORMAT_RGB888_A8 = 0x38413852, + WL_SHM_FORMAT_BGR888_A8 = 0x38413842, + WL_SHM_FORMAT_RGB565_A8 = 0x38413552, + WL_SHM_FORMAT_BGR565_A8 = 0x38413542, + /** + * non-subsampled Cr:Cb plane + */ + WL_SHM_FORMAT_NV24 = 0x3432564e, + /** + * non-subsampled Cb:Cr plane + */ + WL_SHM_FORMAT_NV42 = 0x3234564e, + /** + * 2x1 subsampled Cr:Cb plane, 10 bit per channel + */ + WL_SHM_FORMAT_P210 = 0x30313250, + /** + * 2x2 subsampled Cr:Cb plane 10 bits per channel + */ + WL_SHM_FORMAT_P010 = 0x30313050, + /** + * 2x2 subsampled Cr:Cb plane 12 bits per channel + */ + WL_SHM_FORMAT_P012 = 0x32313050, + /** + * 2x2 subsampled Cr:Cb plane 16 bits per channel + */ + WL_SHM_FORMAT_P016 = 0x36313050, + /** + * [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian + */ + WL_SHM_FORMAT_AXBXGXRX106106106106 = 0x30314241, + /** + * 2x2 subsampled Cr:Cb plane + */ + WL_SHM_FORMAT_NV15 = 0x3531564e, + WL_SHM_FORMAT_Q410 = 0x30313451, + WL_SHM_FORMAT_Q401 = 0x31303451, + /** + * [63:0] x:R:G:B 16:16:16:16 little endian + */ + WL_SHM_FORMAT_XRGB16161616 = 0x38345258, + /** + * [63:0] x:B:G:R 16:16:16:16 little endian + */ + WL_SHM_FORMAT_XBGR16161616 = 0x38344258, + /** + * [63:0] A:R:G:B 16:16:16:16 little endian + */ + WL_SHM_FORMAT_ARGB16161616 = 0x38345241, + /** + * [63:0] A:B:G:R 16:16:16:16 little endian + */ + WL_SHM_FORMAT_ABGR16161616 = 0x38344241, + /** + * [7:0] C0:C1:C2:C3:C4:C5:C6:C7 1:1:1:1:1:1:1:1 eight pixels/byte + */ + WL_SHM_FORMAT_C1 = 0x20203143, + /** + * [7:0] C0:C1:C2:C3 2:2:2:2 four pixels/byte + */ + WL_SHM_FORMAT_C2 = 0x20203243, + /** + * [7:0] C0:C1 4:4 two pixels/byte + */ + WL_SHM_FORMAT_C4 = 0x20203443, + /** + * [7:0] D0:D1:D2:D3:D4:D5:D6:D7 1:1:1:1:1:1:1:1 eight pixels/byte + */ + WL_SHM_FORMAT_D1 = 0x20203144, + /** + * [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte + */ + WL_SHM_FORMAT_D2 = 0x20203244, + /** + * [7:0] D0:D1 4:4 two pixels/byte + */ + WL_SHM_FORMAT_D4 = 0x20203444, + /** + * [7:0] D + */ + WL_SHM_FORMAT_D8 = 0x20203844, + /** + * [7:0] R0:R1:R2:R3:R4:R5:R6:R7 1:1:1:1:1:1:1:1 eight pixels/byte + */ + WL_SHM_FORMAT_R1 = 0x20203152, + /** + * [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte + */ + WL_SHM_FORMAT_R2 = 0x20203252, + /** + * [7:0] R0:R1 4:4 two pixels/byte + */ + WL_SHM_FORMAT_R4 = 0x20203452, + /** + * [15:0] x:R 6:10 little endian + */ + WL_SHM_FORMAT_R10 = 0x20303152, + /** + * [15:0] x:R 4:12 little endian + */ + WL_SHM_FORMAT_R12 = 0x20323152, + /** + * [31:0] A:Cr:Cb:Y 8:8:8:8 little endian + */ + WL_SHM_FORMAT_AVUY8888 = 0x59555641, + /** + * [31:0] X:Cr:Cb:Y 8:8:8:8 little endian + */ + WL_SHM_FORMAT_XVUY8888 = 0x59555658, + /** + * 2x2 subsampled Cr:Cb plane 10 bits per channel packed + */ + WL_SHM_FORMAT_P030 = 0x30333050, +}; +#endif /* WL_SHM_FORMAT_ENUM */ + +/** + * @ingroup iface_wl_shm + * @struct wl_shm_listener + */ +struct wl_shm_listener { + /** + * pixel format description + * + * Informs the client about a valid pixel format that can be used + * for buffers. Known formats include argb8888 and xrgb8888. + * @param format buffer pixel format + */ + void (*format)(void *data, + struct wl_shm *wl_shm, + uint32_t format); +}; + +/** + * @ingroup iface_wl_shm + */ +static inline int +wl_shm_add_listener(struct wl_shm *wl_shm, + const struct wl_shm_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_shm, + (void (**)(void)) listener, data); +} + +#define WL_SHM_CREATE_POOL 0 +#define WL_SHM_RELEASE 1 + +/** + * @ingroup iface_wl_shm + */ +#define WL_SHM_FORMAT_SINCE_VERSION 1 + +/** + * @ingroup iface_wl_shm + */ +#define WL_SHM_CREATE_POOL_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shm + */ +#define WL_SHM_RELEASE_SINCE_VERSION 2 + +/** @ingroup iface_wl_shm */ +static inline void +wl_shm_set_user_data(struct wl_shm *wl_shm, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shm, user_data); +} + +/** @ingroup iface_wl_shm */ +static inline void * +wl_shm_get_user_data(struct wl_shm *wl_shm) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shm); +} + +static inline uint32_t +wl_shm_get_version(struct wl_shm *wl_shm) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shm); +} + +/** @ingroup iface_wl_shm */ +static inline void +wl_shm_destroy(struct wl_shm *wl_shm) +{ + wl_proxy_destroy((struct wl_proxy *) wl_shm); +} + +/** + * @ingroup iface_wl_shm + * + * Create a new wl_shm_pool object. + * + * The pool can be used to create shared memory based buffer + * objects. The server will mmap size bytes of the passed file + * descriptor, to use as backing memory for the pool. + */ +static inline struct wl_shm_pool * +wl_shm_create_pool(struct wl_shm *wl_shm, int32_t fd, int32_t size) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shm, + WL_SHM_CREATE_POOL, &wl_shm_pool_interface, wl_proxy_get_version((struct wl_proxy *) wl_shm), 0, NULL, fd, size); + + return (struct wl_shm_pool *) id; +} + +/** + * @ingroup iface_wl_shm + * + * Using this request a client can tell the server that it is not going to + * use the shm object anymore. + * + * Objects created via this interface remain unaffected. + */ +static inline void +wl_shm_release(struct wl_shm *wl_shm) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shm, + WL_SHM_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shm), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_buffer + * @struct wl_buffer_listener + */ +struct wl_buffer_listener { + /** + * compositor releases buffer + * + * Sent when this wl_buffer is no longer used by the compositor. + * The client is now free to reuse or destroy this buffer and its + * backing storage. + * + * If a client receives a release event before the frame callback + * requested in the same wl_surface.commit that attaches this + * wl_buffer to a surface, then the client is immediately free to + * reuse the buffer and its backing storage, and does not need a + * second buffer for the next surface content update. Typically + * this is possible, when the compositor maintains a copy of the + * wl_surface contents, e.g. as a GL texture. This is an important + * optimization for GL(ES) compositors with wl_shm clients. + */ + void (*release)(void *data, + struct wl_buffer *wl_buffer); +}; + +/** + * @ingroup iface_wl_buffer + */ +static inline int +wl_buffer_add_listener(struct wl_buffer *wl_buffer, + const struct wl_buffer_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_buffer, + (void (**)(void)) listener, data); +} + +#define WL_BUFFER_DESTROY 0 + +/** + * @ingroup iface_wl_buffer + */ +#define WL_BUFFER_RELEASE_SINCE_VERSION 1 + +/** + * @ingroup iface_wl_buffer + */ +#define WL_BUFFER_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_wl_buffer */ +static inline void +wl_buffer_set_user_data(struct wl_buffer *wl_buffer, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_buffer, user_data); +} + +/** @ingroup iface_wl_buffer */ +static inline void * +wl_buffer_get_user_data(struct wl_buffer *wl_buffer) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_buffer); +} + +static inline uint32_t +wl_buffer_get_version(struct wl_buffer *wl_buffer) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_buffer); +} + +/** + * @ingroup iface_wl_buffer + * + * Destroy a buffer. If and how you need to release the backing + * storage is defined by the buffer factory interface. + * + * For possible side-effects to a surface, see wl_surface.attach. + */ +static inline void +wl_buffer_destroy(struct wl_buffer *wl_buffer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_buffer, + WL_BUFFER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_buffer), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_DATA_OFFER_ERROR_ENUM +#define WL_DATA_OFFER_ERROR_ENUM +enum wl_data_offer_error { + /** + * finish request was called untimely + */ + WL_DATA_OFFER_ERROR_INVALID_FINISH = 0, + /** + * action mask contains invalid values + */ + WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK = 1, + /** + * action argument has an invalid value + */ + WL_DATA_OFFER_ERROR_INVALID_ACTION = 2, + /** + * offer doesn't accept this request + */ + WL_DATA_OFFER_ERROR_INVALID_OFFER = 3, +}; +#endif /* WL_DATA_OFFER_ERROR_ENUM */ + +/** + * @ingroup iface_wl_data_offer + * @struct wl_data_offer_listener + */ +struct wl_data_offer_listener { + /** + * advertise offered mime type + * + * Sent immediately after creating the wl_data_offer object. One + * event per offered mime type. + * @param mime_type offered mime type + */ + void (*offer)(void *data, + struct wl_data_offer *wl_data_offer, + const char *mime_type); + /** + * notify the source-side available actions + * + * This event indicates the actions offered by the data source. + * It will be sent immediately after creating the wl_data_offer + * object, or anytime the source side changes its offered actions + * through wl_data_source.set_actions. + * @param source_actions actions offered by the data source + * @since 3 + */ + void (*source_actions)(void *data, + struct wl_data_offer *wl_data_offer, + uint32_t source_actions); + /** + * notify the selected action + * + * This event indicates the action selected by the compositor + * after matching the source/destination side actions. Only one + * action (or none) will be offered here. + * + * This event can be emitted multiple times during the + * drag-and-drop operation in response to destination side action + * changes through wl_data_offer.set_actions. + * + * This event will no longer be emitted after wl_data_device.drop + * happened on the drag-and-drop destination, the client must honor + * the last action received, or the last preferred one set through + * wl_data_offer.set_actions when handling an "ask" action. + * + * Compositors may also change the selected action on the fly, + * mainly in response to keyboard modifier changes during the + * drag-and-drop operation. + * + * The most recent action received is always the valid one. Prior + * to receiving wl_data_device.drop, the chosen action may change + * (e.g. due to keyboard modifiers being pressed). At the time of + * receiving wl_data_device.drop the drag-and-drop destination must + * honor the last action received. + * + * Action changes may still happen after wl_data_device.drop, + * especially on "ask" actions, where the drag-and-drop destination + * may choose another action afterwards. Action changes happening + * at this stage are always the result of inter-client negotiation, + * the compositor shall no longer be able to induce a different + * action. + * + * Upon "ask" actions, it is expected that the drag-and-drop + * destination may potentially choose a different action and/or + * mime type, based on wl_data_offer.source_actions and finally + * chosen by the user (e.g. popping up a menu with the available + * options). The final wl_data_offer.set_actions and + * wl_data_offer.accept requests must happen before the call to + * wl_data_offer.finish. + * @param dnd_action action selected by the compositor + * @since 3 + */ + void (*action)(void *data, + struct wl_data_offer *wl_data_offer, + uint32_t dnd_action); +}; + +/** + * @ingroup iface_wl_data_offer + */ +static inline int +wl_data_offer_add_listener(struct wl_data_offer *wl_data_offer, + const struct wl_data_offer_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_data_offer, + (void (**)(void)) listener, data); +} + +#define WL_DATA_OFFER_ACCEPT 0 +#define WL_DATA_OFFER_RECEIVE 1 +#define WL_DATA_OFFER_DESTROY 2 +#define WL_DATA_OFFER_FINISH 3 +#define WL_DATA_OFFER_SET_ACTIONS 4 + +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_OFFER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION 3 +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_ACTION_SINCE_VERSION 3 + +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_ACCEPT_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_RECEIVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_FINISH_SINCE_VERSION 3 +/** + * @ingroup iface_wl_data_offer + */ +#define WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION 3 + +/** @ingroup iface_wl_data_offer */ +static inline void +wl_data_offer_set_user_data(struct wl_data_offer *wl_data_offer, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_offer, user_data); +} + +/** @ingroup iface_wl_data_offer */ +static inline void * +wl_data_offer_get_user_data(struct wl_data_offer *wl_data_offer) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_offer); +} + +static inline uint32_t +wl_data_offer_get_version(struct wl_data_offer *wl_data_offer) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_offer); +} + +/** + * @ingroup iface_wl_data_offer + * + * Indicate that the client can accept the given mime type, or + * NULL for not accepted. + * + * For objects of version 2 or older, this request is used by the + * client to give feedback whether the client can receive the given + * mime type, or NULL if none is accepted; the feedback does not + * determine whether the drag-and-drop operation succeeds or not. + * + * For objects of version 3 or newer, this request determines the + * final result of the drag-and-drop operation. If the end result + * is that no mime types were accepted, the drag-and-drop operation + * will be cancelled and the corresponding drag source will receive + * wl_data_source.cancelled. Clients may still use this event in + * conjunction with wl_data_source.action for feedback. + */ +static inline void +wl_data_offer_accept(struct wl_data_offer *wl_data_offer, uint32_t serial, const char *mime_type) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_ACCEPT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, serial, mime_type); +} + +/** + * @ingroup iface_wl_data_offer + * + * To transfer the offered data, the client issues this request + * and indicates the mime type it wants to receive. The transfer + * happens through the passed file descriptor (typically created + * with the pipe system call). The source client writes the data + * in the mime type representation requested and then closes the + * file descriptor. + * + * The receiving client reads from the read end of the pipe until + * EOF and then closes its end, at which point the transfer is + * complete. + * + * This request may happen multiple times for different mime types, + * both before and after wl_data_device.drop. Drag-and-drop destination + * clients may preemptively fetch data or examine it more closely to + * determine acceptance. + */ +static inline void +wl_data_offer_receive(struct wl_data_offer *wl_data_offer, const char *mime_type, int32_t fd) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_RECEIVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, mime_type, fd); +} + +/** + * @ingroup iface_wl_data_offer + * + * Destroy the data offer. + */ +static inline void +wl_data_offer_destroy(struct wl_data_offer *wl_data_offer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_data_offer + * + * Notifies the compositor that the drag destination successfully + * finished the drag-and-drop operation. + * + * Upon receiving this request, the compositor will emit + * wl_data_source.dnd_finished on the drag source client. + * + * It is a client error to perform other requests than + * wl_data_offer.destroy after this one. It is also an error to perform + * this request after a NULL mime type has been set in + * wl_data_offer.accept or no action was received through + * wl_data_offer.action. + * + * If wl_data_offer.finish request is received for a non drag and drop + * operation, the invalid_finish protocol error is raised. + */ +static inline void +wl_data_offer_finish(struct wl_data_offer *wl_data_offer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_FINISH, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0); +} + +/** + * @ingroup iface_wl_data_offer + * + * Sets the actions that the destination side client supports for + * this operation. This request may trigger the emission of + * wl_data_source.action and wl_data_offer.action events if the compositor + * needs to change the selected action. + * + * This request can be called multiple times throughout the + * drag-and-drop operation, typically in response to wl_data_device.enter + * or wl_data_device.motion events. + * + * This request determines the final result of the drag-and-drop + * operation. If the end result is that no action is accepted, + * the drag source will receive wl_data_source.cancelled. + * + * The dnd_actions argument must contain only values expressed in the + * wl_data_device_manager.dnd_actions enum, and the preferred_action + * argument must only contain one of those values set, otherwise it + * will result in a protocol error. + * + * While managing an "ask" action, the destination drag-and-drop client + * may perform further wl_data_offer.receive requests, and is expected + * to perform one last wl_data_offer.set_actions request with a preferred + * action other than "ask" (and optionally wl_data_offer.accept) before + * requesting wl_data_offer.finish, in order to convey the action selected + * by the user. If the preferred action is not in the + * wl_data_offer.source_actions mask, an error will be raised. + * + * If the "ask" action is dismissed (e.g. user cancellation), the client + * is expected to perform wl_data_offer.destroy right away. + * + * This request can only be made on drag-and-drop offers, a protocol error + * will be raised otherwise. + */ +static inline void +wl_data_offer_set_actions(struct wl_data_offer *wl_data_offer, uint32_t dnd_actions, uint32_t preferred_action) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_offer, + WL_DATA_OFFER_SET_ACTIONS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_offer), 0, dnd_actions, preferred_action); +} + +#ifndef WL_DATA_SOURCE_ERROR_ENUM +#define WL_DATA_SOURCE_ERROR_ENUM +enum wl_data_source_error { + /** + * action mask contains invalid values + */ + WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK = 0, + /** + * source doesn't accept this request + */ + WL_DATA_SOURCE_ERROR_INVALID_SOURCE = 1, +}; +#endif /* WL_DATA_SOURCE_ERROR_ENUM */ + +/** + * @ingroup iface_wl_data_source + * @struct wl_data_source_listener + */ +struct wl_data_source_listener { + /** + * a target accepts an offered mime type + * + * Sent when a target accepts pointer_focus or motion events. If + * a target does not accept any of the offered types, type is NULL. + * + * Used for feedback during drag-and-drop. + * @param mime_type mime type accepted by the target + */ + void (*target)(void *data, + struct wl_data_source *wl_data_source, + const char *mime_type); + /** + * send the data + * + * Request for data from the client. Send the data as the + * specified mime type over the passed file descriptor, then close + * it. + * @param mime_type mime type for the data + * @param fd file descriptor for the data + */ + void (*send)(void *data, + struct wl_data_source *wl_data_source, + const char *mime_type, + int32_t fd); + /** + * selection was cancelled + * + * This data source is no longer valid. There are several reasons + * why this could happen: + * + * - The data source has been replaced by another data source. - + * The drag-and-drop operation was performed, but the drop + * destination did not accept any of the mime types offered through + * wl_data_source.target. - The drag-and-drop operation was + * performed, but the drop destination did not select any of the + * actions present in the mask offered through + * wl_data_source.action. - The drag-and-drop operation was + * performed but didn't happen over a surface. - The compositor + * cancelled the drag-and-drop operation (e.g. compositor dependent + * timeouts to avoid stale drag-and-drop transfers). + * + * The client should clean up and destroy this data source. + * + * For objects of version 2 or older, wl_data_source.cancelled will + * only be emitted if the data source was replaced by another data + * source. + */ + void (*cancelled)(void *data, + struct wl_data_source *wl_data_source); + /** + * the drag-and-drop operation physically finished + * + * The user performed the drop action. This event does not + * indicate acceptance, wl_data_source.cancelled may still be + * emitted afterwards if the drop destination does not accept any + * mime type. + * + * However, this event might however not be received if the + * compositor cancelled the drag-and-drop operation before this + * event could happen. + * + * Note that the data_source may still be used in the future and + * should not be destroyed here. + * @since 3 + */ + void (*dnd_drop_performed)(void *data, + struct wl_data_source *wl_data_source); + /** + * the drag-and-drop operation concluded + * + * The drop destination finished interoperating with this data + * source, so the client is now free to destroy this data source + * and free all associated data. + * + * If the action used to perform the operation was "move", the + * source can now delete the transferred data. + * @since 3 + */ + void (*dnd_finished)(void *data, + struct wl_data_source *wl_data_source); + /** + * notify the selected action + * + * This event indicates the action selected by the compositor + * after matching the source/destination side actions. Only one + * action (or none) will be offered here. + * + * This event can be emitted multiple times during the + * drag-and-drop operation, mainly in response to destination side + * changes through wl_data_offer.set_actions, and as the data + * device enters/leaves surfaces. + * + * It is only possible to receive this event after + * wl_data_source.dnd_drop_performed if the drag-and-drop operation + * ended in an "ask" action, in which case the final + * wl_data_source.action event will happen immediately before + * wl_data_source.dnd_finished. + * + * Compositors may also change the selected action on the fly, + * mainly in response to keyboard modifier changes during the + * drag-and-drop operation. + * + * The most recent action received is always the valid one. The + * chosen action may change alongside negotiation (e.g. an "ask" + * action can turn into a "move" operation), so the effects of the + * final action must always be applied in + * wl_data_offer.dnd_finished. + * + * Clients can trigger cursor surface changes from this point, so + * they reflect the current action. + * @param dnd_action action selected by the compositor + * @since 3 + */ + void (*action)(void *data, + struct wl_data_source *wl_data_source, + uint32_t dnd_action); +}; + +/** + * @ingroup iface_wl_data_source + */ +static inline int +wl_data_source_add_listener(struct wl_data_source *wl_data_source, + const struct wl_data_source_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_data_source, + (void (**)(void)) listener, data); +} + +#define WL_DATA_SOURCE_OFFER 0 +#define WL_DATA_SOURCE_DESTROY 1 +#define WL_DATA_SOURCE_SET_ACTIONS 2 + +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_TARGET_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_SEND_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_CANCELLED_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION 3 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION 3 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_ACTION_SINCE_VERSION 3 + +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_OFFER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_source + */ +#define WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION 3 + +/** @ingroup iface_wl_data_source */ +static inline void +wl_data_source_set_user_data(struct wl_data_source *wl_data_source, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_source, user_data); +} + +/** @ingroup iface_wl_data_source */ +static inline void * +wl_data_source_get_user_data(struct wl_data_source *wl_data_source) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_source); +} + +static inline uint32_t +wl_data_source_get_version(struct wl_data_source *wl_data_source) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_source); +} + +/** + * @ingroup iface_wl_data_source + * + * This request adds a mime type to the set of mime types + * advertised to targets. Can be called several times to offer + * multiple types. + */ +static inline void +wl_data_source_offer(struct wl_data_source *wl_data_source, const char *mime_type) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, + WL_DATA_SOURCE_OFFER, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), 0, mime_type); +} + +/** + * @ingroup iface_wl_data_source + * + * Destroy the data source. + */ +static inline void +wl_data_source_destroy(struct wl_data_source *wl_data_source) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, + WL_DATA_SOURCE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_data_source + * + * Sets the actions that the source side client supports for this + * operation. This request may trigger wl_data_source.action and + * wl_data_offer.action events if the compositor needs to change the + * selected action. + * + * The dnd_actions argument must contain only values expressed in the + * wl_data_device_manager.dnd_actions enum, otherwise it will result + * in a protocol error. + * + * This request must be made once only, and can only be made on sources + * used in drag-and-drop, so it must be performed before + * wl_data_device.start_drag. Attempting to use the source other than + * for drag-and-drop will raise a protocol error. + */ +static inline void +wl_data_source_set_actions(struct wl_data_source *wl_data_source, uint32_t dnd_actions) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_source, + WL_DATA_SOURCE_SET_ACTIONS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_source), 0, dnd_actions); +} + +#ifndef WL_DATA_DEVICE_ERROR_ENUM +#define WL_DATA_DEVICE_ERROR_ENUM +enum wl_data_device_error { + /** + * given wl_surface has another role + */ + WL_DATA_DEVICE_ERROR_ROLE = 0, + /** + * source has already been used + */ + WL_DATA_DEVICE_ERROR_USED_SOURCE = 1, +}; +#endif /* WL_DATA_DEVICE_ERROR_ENUM */ + +/** + * @ingroup iface_wl_data_device + * @struct wl_data_device_listener + */ +struct wl_data_device_listener { + /** + * introduce a new wl_data_offer + * + * The data_offer event introduces a new wl_data_offer object, + * which will subsequently be used in either the data_device.enter + * event (for drag-and-drop) or the data_device.selection event + * (for selections). Immediately following the + * data_device.data_offer event, the new data_offer object will + * send out data_offer.offer events to describe the mime types it + * offers. + * @param id the new data_offer object + */ + void (*data_offer)(void *data, + struct wl_data_device *wl_data_device, + struct wl_data_offer *id); + /** + * initiate drag-and-drop session + * + * This event is sent when an active drag-and-drop pointer enters + * a surface owned by the client. The position of the pointer at + * enter time is provided by the x and y arguments, in + * surface-local coordinates. + * @param serial serial number of the enter event + * @param surface client surface entered + * @param x surface-local x coordinate + * @param y surface-local y coordinate + * @param id source data_offer object + */ + void (*enter)(void *data, + struct wl_data_device *wl_data_device, + uint32_t serial, + struct wl_surface *surface, + wl_fixed_t x, + wl_fixed_t y, + struct wl_data_offer *id); + /** + * end drag-and-drop session + * + * This event is sent when the drag-and-drop pointer leaves the + * surface and the session ends. The client must destroy the + * wl_data_offer introduced at enter time at this point. + */ + void (*leave)(void *data, + struct wl_data_device *wl_data_device); + /** + * drag-and-drop session motion + * + * This event is sent when the drag-and-drop pointer moves within + * the currently focused surface. The new position of the pointer + * is provided by the x and y arguments, in surface-local + * coordinates. + * @param time timestamp with millisecond granularity + * @param x surface-local x coordinate + * @param y surface-local y coordinate + */ + void (*motion)(void *data, + struct wl_data_device *wl_data_device, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y); + /** + * end drag-and-drop session successfully + * + * The event is sent when a drag-and-drop operation is ended + * because the implicit grab is removed. + * + * The drag-and-drop destination is expected to honor the last + * action received through wl_data_offer.action, if the resulting + * action is "copy" or "move", the destination can still perform + * wl_data_offer.receive requests, and is expected to end all + * transfers with a wl_data_offer.finish request. + * + * If the resulting action is "ask", the action will not be + * considered final. The drag-and-drop destination is expected to + * perform one last wl_data_offer.set_actions request, or + * wl_data_offer.destroy in order to cancel the operation. + */ + void (*drop)(void *data, + struct wl_data_device *wl_data_device); + /** + * advertise new selection + * + * The selection event is sent out to notify the client of a new + * wl_data_offer for the selection for this device. The + * data_device.data_offer and the data_offer.offer events are sent + * out immediately before this event to introduce the data offer + * object. The selection event is sent to a client immediately + * before receiving keyboard focus and when a new selection is set + * while the client has keyboard focus. The data_offer is valid + * until a new data_offer or NULL is received or until the client + * loses keyboard focus. Switching surface with keyboard focus + * within the same client doesn't mean a new selection will be + * sent. The client must destroy the previous selection data_offer, + * if any, upon receiving this event. + * @param id selection data_offer object + */ + void (*selection)(void *data, + struct wl_data_device *wl_data_device, + struct wl_data_offer *id); +}; + +/** + * @ingroup iface_wl_data_device + */ +static inline int +wl_data_device_add_listener(struct wl_data_device *wl_data_device, + const struct wl_data_device_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_data_device, + (void (**)(void)) listener, data); +} + +#define WL_DATA_DEVICE_START_DRAG 0 +#define WL_DATA_DEVICE_SET_SELECTION 1 +#define WL_DATA_DEVICE_RELEASE 2 + +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_DATA_OFFER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_ENTER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_LEAVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_MOTION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_DROP_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_SELECTION_SINCE_VERSION 1 + +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_START_DRAG_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_SET_SELECTION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device + */ +#define WL_DATA_DEVICE_RELEASE_SINCE_VERSION 2 + +/** @ingroup iface_wl_data_device */ +static inline void +wl_data_device_set_user_data(struct wl_data_device *wl_data_device, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_device, user_data); +} + +/** @ingroup iface_wl_data_device */ +static inline void * +wl_data_device_get_user_data(struct wl_data_device *wl_data_device) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_device); +} + +static inline uint32_t +wl_data_device_get_version(struct wl_data_device *wl_data_device) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_device); +} + +/** @ingroup iface_wl_data_device */ +static inline void +wl_data_device_destroy(struct wl_data_device *wl_data_device) +{ + wl_proxy_destroy((struct wl_proxy *) wl_data_device); +} + +/** + * @ingroup iface_wl_data_device + * + * This request asks the compositor to start a drag-and-drop + * operation on behalf of the client. + * + * The source argument is the data source that provides the data + * for the eventual data transfer. If source is NULL, enter, leave + * and motion events are sent only to the client that initiated the + * drag and the client is expected to handle the data passing + * internally. If source is destroyed, the drag-and-drop session will be + * cancelled. + * + * The origin surface is the surface where the drag originates and + * the client must have an active implicit grab that matches the + * serial. + * + * The icon surface is an optional (can be NULL) surface that + * provides an icon to be moved around with the cursor. Initially, + * the top-left corner of the icon surface is placed at the cursor + * hotspot, but subsequent wl_surface.offset requests can move the + * relative position. Attach requests must be confirmed with + * wl_surface.commit as usual. The icon surface is given the role of + * a drag-and-drop icon. If the icon surface already has another role, + * it raises a protocol error. + * + * The input region is ignored for wl_surfaces with the role of a + * drag-and-drop icon. + * + * The given source may not be used in any further set_selection or + * start_drag requests. Attempting to reuse a previously-used source + * may send a used_source error. + */ +static inline void +wl_data_device_start_drag(struct wl_data_device *wl_data_device, struct wl_data_source *source, struct wl_surface *origin, struct wl_surface *icon, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, + WL_DATA_DEVICE_START_DRAG, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), 0, source, origin, icon, serial); +} + +/** + * @ingroup iface_wl_data_device + * + * This request asks the compositor to set the selection + * to the data from the source on behalf of the client. + * + * To unset the selection, set the source to NULL. + * + * The given source may not be used in any further set_selection or + * start_drag requests. Attempting to reuse a previously-used source + * may send a used_source error. + */ +static inline void +wl_data_device_set_selection(struct wl_data_device *wl_data_device, struct wl_data_source *source, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, + WL_DATA_DEVICE_SET_SELECTION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), 0, source, serial); +} + +/** + * @ingroup iface_wl_data_device + * + * This request destroys the data device. + */ +static inline void +wl_data_device_release(struct wl_data_device *wl_data_device) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device, + WL_DATA_DEVICE_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_data_device), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM +#define WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM +/** + * @ingroup iface_wl_data_device_manager + * drag and drop actions + * + * This is a bitmask of the available/preferred actions in a + * drag-and-drop operation. + * + * In the compositor, the selected action is a result of matching the + * actions offered by the source and destination sides. "action" events + * with a "none" action will be sent to both source and destination if + * there is no match. All further checks will effectively happen on + * (source actions ∩ destination actions). + * + * In addition, compositors may also pick different actions in + * reaction to key modifiers being pressed. One common design that + * is used in major toolkits (and the behavior recommended for + * compositors) is: + * + * - If no modifiers are pressed, the first match (in bit order) + * will be used. + * - Pressing Shift selects "move", if enabled in the mask. + * - Pressing Control selects "copy", if enabled in the mask. + * + * Behavior beyond that is considered implementation-dependent. + * Compositors may for example bind other modifiers (like Alt/Meta) + * or drags initiated with other buttons than BTN_LEFT to specific + * actions (e.g. "ask"). + */ +enum wl_data_device_manager_dnd_action { + /** + * no action + */ + WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE = 0, + /** + * copy action + */ + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY = 1, + /** + * move action + */ + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE = 2, + /** + * ask action + */ + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK = 4, +}; +#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */ + +#define WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE 0 +#define WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE 1 + + +/** + * @ingroup iface_wl_data_device_manager + */ +#define WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_data_device_manager + */ +#define WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE_SINCE_VERSION 1 + +/** @ingroup iface_wl_data_device_manager */ +static inline void +wl_data_device_manager_set_user_data(struct wl_data_device_manager *wl_data_device_manager, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_data_device_manager, user_data); +} + +/** @ingroup iface_wl_data_device_manager */ +static inline void * +wl_data_device_manager_get_user_data(struct wl_data_device_manager *wl_data_device_manager) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_data_device_manager); +} + +static inline uint32_t +wl_data_device_manager_get_version(struct wl_data_device_manager *wl_data_device_manager) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager); +} + +/** @ingroup iface_wl_data_device_manager */ +static inline void +wl_data_device_manager_destroy(struct wl_data_device_manager *wl_data_device_manager) +{ + wl_proxy_destroy((struct wl_proxy *) wl_data_device_manager); +} + +/** + * @ingroup iface_wl_data_device_manager + * + * Create a new data source. + */ +static inline struct wl_data_source * +wl_data_device_manager_create_data_source(struct wl_data_device_manager *wl_data_device_manager) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device_manager, + WL_DATA_DEVICE_MANAGER_CREATE_DATA_SOURCE, &wl_data_source_interface, wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager), 0, NULL); + + return (struct wl_data_source *) id; +} + +/** + * @ingroup iface_wl_data_device_manager + * + * Create a new data device for a given seat. + */ +static inline struct wl_data_device * +wl_data_device_manager_get_data_device(struct wl_data_device_manager *wl_data_device_manager, struct wl_seat *seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_data_device_manager, + WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE, &wl_data_device_interface, wl_proxy_get_version((struct wl_proxy *) wl_data_device_manager), 0, NULL, seat); + + return (struct wl_data_device *) id; +} + +#ifndef WL_SHELL_ERROR_ENUM +#define WL_SHELL_ERROR_ENUM +enum wl_shell_error { + /** + * given wl_surface has another role + */ + WL_SHELL_ERROR_ROLE = 0, +}; +#endif /* WL_SHELL_ERROR_ENUM */ + +#define WL_SHELL_GET_SHELL_SURFACE 0 + + +/** + * @ingroup iface_wl_shell + */ +#define WL_SHELL_GET_SHELL_SURFACE_SINCE_VERSION 1 + +/** @ingroup iface_wl_shell */ +static inline void +wl_shell_set_user_data(struct wl_shell *wl_shell, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shell, user_data); +} + +/** @ingroup iface_wl_shell */ +static inline void * +wl_shell_get_user_data(struct wl_shell *wl_shell) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shell); +} + +static inline uint32_t +wl_shell_get_version(struct wl_shell *wl_shell) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shell); +} + +/** @ingroup iface_wl_shell */ +static inline void +wl_shell_destroy(struct wl_shell *wl_shell) +{ + wl_proxy_destroy((struct wl_proxy *) wl_shell); +} + +/** + * @ingroup iface_wl_shell + * + * Create a shell surface for an existing surface. This gives + * the wl_surface the role of a shell surface. If the wl_surface + * already has another role, it raises a protocol error. + * + * Only one shell surface can be associated with a given surface. + */ +static inline struct wl_shell_surface * +wl_shell_get_shell_surface(struct wl_shell *wl_shell, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_shell, + WL_SHELL_GET_SHELL_SURFACE, &wl_shell_surface_interface, wl_proxy_get_version((struct wl_proxy *) wl_shell), 0, NULL, surface); + + return (struct wl_shell_surface *) id; +} + +#ifndef WL_SHELL_SURFACE_RESIZE_ENUM +#define WL_SHELL_SURFACE_RESIZE_ENUM +/** + * @ingroup iface_wl_shell_surface + * edge values for resizing + * + * These values are used to indicate which edge of a surface + * is being dragged in a resize operation. The server may + * use this information to adapt its behavior, e.g. choose + * an appropriate cursor image. + */ +enum wl_shell_surface_resize { + /** + * no edge + */ + WL_SHELL_SURFACE_RESIZE_NONE = 0, + /** + * top edge + */ + WL_SHELL_SURFACE_RESIZE_TOP = 1, + /** + * bottom edge + */ + WL_SHELL_SURFACE_RESIZE_BOTTOM = 2, + /** + * left edge + */ + WL_SHELL_SURFACE_RESIZE_LEFT = 4, + /** + * top and left edges + */ + WL_SHELL_SURFACE_RESIZE_TOP_LEFT = 5, + /** + * bottom and left edges + */ + WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT = 6, + /** + * right edge + */ + WL_SHELL_SURFACE_RESIZE_RIGHT = 8, + /** + * top and right edges + */ + WL_SHELL_SURFACE_RESIZE_TOP_RIGHT = 9, + /** + * bottom and right edges + */ + WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT = 10, +}; +#endif /* WL_SHELL_SURFACE_RESIZE_ENUM */ + +#ifndef WL_SHELL_SURFACE_TRANSIENT_ENUM +#define WL_SHELL_SURFACE_TRANSIENT_ENUM +/** + * @ingroup iface_wl_shell_surface + * details of transient behaviour + * + * These flags specify details of the expected behaviour + * of transient surfaces. Used in the set_transient request. + */ +enum wl_shell_surface_transient { + /** + * do not set keyboard focus + */ + WL_SHELL_SURFACE_TRANSIENT_INACTIVE = 0x1, +}; +#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */ + +#ifndef WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM +#define WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM +/** + * @ingroup iface_wl_shell_surface + * different method to set the surface fullscreen + * + * Hints to indicate to the compositor how to deal with a conflict + * between the dimensions of the surface and the dimensions of the + * output. The compositor is free to ignore this parameter. + */ +enum wl_shell_surface_fullscreen_method { + /** + * no preference, apply default policy + */ + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT = 0, + /** + * scale, preserve the surface's aspect ratio and center on output + */ + WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE = 1, + /** + * switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch + */ + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER = 2, + /** + * no upscaling, center on output and add black borders to compensate size mismatch + */ + WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL = 3, +}; +#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM */ + +/** + * @ingroup iface_wl_shell_surface + * @struct wl_shell_surface_listener + */ +struct wl_shell_surface_listener { + /** + * ping client + * + * Ping a client to check if it is receiving events and sending + * requests. A client is expected to reply with a pong request. + * @param serial serial number of the ping + */ + void (*ping)(void *data, + struct wl_shell_surface *wl_shell_surface, + uint32_t serial); + /** + * suggest resize + * + * The configure event asks the client to resize its surface. + * + * The size is a hint, in the sense that the client is free to + * ignore it if it doesn't resize, pick a smaller size (to satisfy + * aspect ratio or resize in steps of NxM pixels). + * + * The edges parameter provides a hint about how the surface was + * resized. The client may use this information to decide how to + * adjust its content to the new size (e.g. a scrolling area might + * adjust its content position to leave the viewable content + * unmoved). + * + * The client is free to dismiss all but the last configure event + * it received. + * + * The width and height arguments specify the size of the window in + * surface-local coordinates. + * @param edges how the surface was resized + * @param width new width of the surface + * @param height new height of the surface + */ + void (*configure)(void *data, + struct wl_shell_surface *wl_shell_surface, + uint32_t edges, + int32_t width, + int32_t height); + /** + * popup interaction is done + * + * The popup_done event is sent out when a popup grab is broken, + * that is, when the user clicks a surface that doesn't belong to + * the client owning the popup surface. + */ + void (*popup_done)(void *data, + struct wl_shell_surface *wl_shell_surface); +}; + +/** + * @ingroup iface_wl_shell_surface + */ +static inline int +wl_shell_surface_add_listener(struct wl_shell_surface *wl_shell_surface, + const struct wl_shell_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_shell_surface, + (void (**)(void)) listener, data); +} + +#define WL_SHELL_SURFACE_PONG 0 +#define WL_SHELL_SURFACE_MOVE 1 +#define WL_SHELL_SURFACE_RESIZE 2 +#define WL_SHELL_SURFACE_SET_TOPLEVEL 3 +#define WL_SHELL_SURFACE_SET_TRANSIENT 4 +#define WL_SHELL_SURFACE_SET_FULLSCREEN 5 +#define WL_SHELL_SURFACE_SET_POPUP 6 +#define WL_SHELL_SURFACE_SET_MAXIMIZED 7 +#define WL_SHELL_SURFACE_SET_TITLE 8 +#define WL_SHELL_SURFACE_SET_CLASS 9 + +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_PING_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_POPUP_DONE_SINCE_VERSION 1 + +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_PONG_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_MOVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_RESIZE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_TOPLEVEL_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_TRANSIENT_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_FULLSCREEN_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_POPUP_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_MAXIMIZED_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_TITLE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_shell_surface + */ +#define WL_SHELL_SURFACE_SET_CLASS_SINCE_VERSION 1 + +/** @ingroup iface_wl_shell_surface */ +static inline void +wl_shell_surface_set_user_data(struct wl_shell_surface *wl_shell_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_shell_surface, user_data); +} + +/** @ingroup iface_wl_shell_surface */ +static inline void * +wl_shell_surface_get_user_data(struct wl_shell_surface *wl_shell_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_shell_surface); +} + +static inline uint32_t +wl_shell_surface_get_version(struct wl_shell_surface *wl_shell_surface) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_shell_surface); +} + +/** @ingroup iface_wl_shell_surface */ +static inline void +wl_shell_surface_destroy(struct wl_shell_surface *wl_shell_surface) +{ + wl_proxy_destroy((struct wl_proxy *) wl_shell_surface); +} + +/** + * @ingroup iface_wl_shell_surface + * + * A client must respond to a ping event with a pong request or + * the client may be deemed unresponsive. + */ +static inline void +wl_shell_surface_pong(struct wl_shell_surface *wl_shell_surface, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, serial); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Start a pointer-driven move of the surface. + * + * This request must be used in response to a button press event. + * The server may ignore move requests depending on the state of + * the surface (e.g. fullscreen or maximized). + */ +static inline void +wl_shell_surface_move(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Start a pointer-driven resizing of the surface. + * + * This request must be used in response to a button press event. + * The server may ignore resize requests depending on the state of + * the surface (e.g. fullscreen or maximized). + */ +static inline void +wl_shell_surface_resize(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial, uint32_t edges) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial, edges); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Map the surface as a toplevel surface. + * + * A toplevel surface is not fullscreen, maximized or transient. + */ +static inline void +wl_shell_surface_set_toplevel(struct wl_shell_surface *wl_shell_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_TOPLEVEL, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Map the surface relative to an existing surface. + * + * The x and y arguments specify the location of the upper left + * corner of the surface relative to the upper left corner of the + * parent surface, in surface-local coordinates. + * + * The flags argument controls details of the transient behaviour. + */ +static inline void +wl_shell_surface_set_transient(struct wl_shell_surface *wl_shell_surface, struct wl_surface *parent, int32_t x, int32_t y, uint32_t flags) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_TRANSIENT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, parent, x, y, flags); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Map the surface as a fullscreen surface. + * + * If an output parameter is given then the surface will be made + * fullscreen on that output. If the client does not specify the + * output then the compositor will apply its policy - usually + * choosing the output on which the surface has the biggest surface + * area. + * + * The client may specify a method to resolve a size conflict + * between the output size and the surface size - this is provided + * through the method parameter. + * + * The framerate parameter is used only when the method is set + * to "driver", to indicate the preferred framerate. A value of 0 + * indicates that the client does not care about framerate. The + * framerate is specified in mHz, that is framerate of 60000 is 60Hz. + * + * A method of "scale" or "driver" implies a scaling operation of + * the surface, either via a direct scaling operation or a change of + * the output mode. This will override any kind of output scaling, so + * that mapping a surface with a buffer size equal to the mode can + * fill the screen independent of buffer_scale. + * + * A method of "fill" means we don't scale up the buffer, however + * any output scale is applied. This means that you may run into + * an edge case where the application maps a buffer with the same + * size of the output mode but buffer_scale 1 (thus making a + * surface larger than the output). In this case it is allowed to + * downscale the results to fit the screen. + * + * The compositor must reply to this request with a configure event + * with the dimensions for the output on which the surface will + * be made fullscreen. + */ +static inline void +wl_shell_surface_set_fullscreen(struct wl_shell_surface *wl_shell_surface, uint32_t method, uint32_t framerate, struct wl_output *output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, method, framerate, output); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Map the surface as a popup. + * + * A popup surface is a transient surface with an added pointer + * grab. + * + * An existing implicit grab will be changed to owner-events mode, + * and the popup grab will continue after the implicit grab ends + * (i.e. releasing the mouse button does not cause the popup to + * be unmapped). + * + * The popup grab continues until the window is destroyed or a + * mouse button is pressed in any other client's window. A click + * in any of the client's surfaces is reported as normal, however, + * clicks in other clients' surfaces will be discarded and trigger + * the callback. + * + * The x and y arguments specify the location of the upper left + * corner of the surface relative to the upper left corner of the + * parent surface, in surface-local coordinates. + */ +static inline void +wl_shell_surface_set_popup(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial, struct wl_surface *parent, int32_t x, int32_t y, uint32_t flags) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_POPUP, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, seat, serial, parent, x, y, flags); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Map the surface as a maximized surface. + * + * If an output parameter is given then the surface will be + * maximized on that output. If the client does not specify the + * output then the compositor will apply its policy - usually + * choosing the output on which the surface has the biggest surface + * area. + * + * The compositor will reply with a configure event telling + * the expected new surface size. The operation is completed + * on the next buffer attach to this surface. + * + * A maximized surface typically fills the entire output it is + * bound to, except for desktop elements such as panels. This is + * the main difference between a maximized shell surface and a + * fullscreen shell surface. + * + * The details depend on the compositor implementation. + */ +static inline void +wl_shell_surface_set_maximized(struct wl_shell_surface *wl_shell_surface, struct wl_output *output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, output); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Set a short title for the surface. + * + * This string may be used to identify the surface in a task bar, + * window list, or other user interface elements provided by the + * compositor. + * + * The string must be encoded in UTF-8. + */ +static inline void +wl_shell_surface_set_title(struct wl_shell_surface *wl_shell_surface, const char *title) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, title); +} + +/** + * @ingroup iface_wl_shell_surface + * + * Set a class for the surface. + * + * The surface class identifies the general class of applications + * to which the surface belongs. A common convention is to use the + * file name (or the full path if it is a non-standard location) of + * the application's .desktop file as the class. + */ +static inline void +wl_shell_surface_set_class(struct wl_shell_surface *wl_shell_surface, const char *class_) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_shell_surface, + WL_SHELL_SURFACE_SET_CLASS, NULL, wl_proxy_get_version((struct wl_proxy *) wl_shell_surface), 0, class_); +} + +#ifndef WL_SURFACE_ERROR_ENUM +#define WL_SURFACE_ERROR_ENUM +/** + * @ingroup iface_wl_surface + * wl_surface error values + * + * These errors can be emitted in response to wl_surface requests. + */ +enum wl_surface_error { + /** + * buffer scale value is invalid + */ + WL_SURFACE_ERROR_INVALID_SCALE = 0, + /** + * buffer transform value is invalid + */ + WL_SURFACE_ERROR_INVALID_TRANSFORM = 1, + /** + * buffer size is invalid + */ + WL_SURFACE_ERROR_INVALID_SIZE = 2, + /** + * buffer offset is invalid + */ + WL_SURFACE_ERROR_INVALID_OFFSET = 3, + /** + * surface was destroyed before its role object + */ + WL_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 4, +}; +#endif /* WL_SURFACE_ERROR_ENUM */ + +/** + * @ingroup iface_wl_surface + * @struct wl_surface_listener + */ +struct wl_surface_listener { + /** + * surface enters an output + * + * This is emitted whenever a surface's creation, movement, or + * resizing results in some part of it being within the scanout + * region of an output. + * + * Note that a surface may be overlapping with zero or more + * outputs. + * @param output output entered by the surface + */ + void (*enter)(void *data, + struct wl_surface *wl_surface, + struct wl_output *output); + /** + * surface leaves an output + * + * This is emitted whenever a surface's creation, movement, or + * resizing results in it no longer having any part of it within + * the scanout region of an output. + * + * Clients should not use the number of outputs the surface is on + * for frame throttling purposes. The surface might be hidden even + * if no leave event has been sent, and the compositor might expect + * new surface content updates even if no enter event has been + * sent. The frame event should be used instead. + * @param output output left by the surface + */ + void (*leave)(void *data, + struct wl_surface *wl_surface, + struct wl_output *output); + /** + * preferred buffer scale for the surface + * + * This event indicates the preferred buffer scale for this + * surface. It is sent whenever the compositor's preference + * changes. + * + * Before receiving this event the preferred buffer scale for this + * surface is 1. + * + * It is intended that scaling aware clients use this event to + * scale their content and use wl_surface.set_buffer_scale to + * indicate the scale they have rendered with. This allows clients + * to supply a higher detail buffer. + * + * The compositor shall emit a scale value greater than 0. + * @param factor preferred scaling factor + * @since 6 + */ + void (*preferred_buffer_scale)(void *data, + struct wl_surface *wl_surface, + int32_t factor); + /** + * preferred buffer transform for the surface + * + * This event indicates the preferred buffer transform for this + * surface. It is sent whenever the compositor's preference + * changes. + * + * Before receiving this event the preferred buffer transform for + * this surface is normal. + * + * It is intended that transform aware clients use this event to + * apply the transform to their content and use + * wl_surface.set_buffer_transform to indicate the transform they + * have rendered with. + * @param transform preferred transform + * @since 6 + */ + void (*preferred_buffer_transform)(void *data, + struct wl_surface *wl_surface, + uint32_t transform); +}; + +/** + * @ingroup iface_wl_surface + */ +static inline int +wl_surface_add_listener(struct wl_surface *wl_surface, + const struct wl_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_surface, + (void (**)(void)) listener, data); +} + +#define WL_SURFACE_DESTROY 0 +#define WL_SURFACE_ATTACH 1 +#define WL_SURFACE_DAMAGE 2 +#define WL_SURFACE_FRAME 3 +#define WL_SURFACE_SET_OPAQUE_REGION 4 +#define WL_SURFACE_SET_INPUT_REGION 5 +#define WL_SURFACE_COMMIT 6 +#define WL_SURFACE_SET_BUFFER_TRANSFORM 7 +#define WL_SURFACE_SET_BUFFER_SCALE 8 +#define WL_SURFACE_DAMAGE_BUFFER 9 +#define WL_SURFACE_OFFSET 10 + +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_ENTER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_LEAVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION 6 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION 6 + +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_ATTACH_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_DAMAGE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_FRAME_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_SET_OPAQUE_REGION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_SET_INPUT_REGION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_COMMIT_SINCE_VERSION 1 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_SET_BUFFER_TRANSFORM_SINCE_VERSION 2 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION 3 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION 4 +/** + * @ingroup iface_wl_surface + */ +#define WL_SURFACE_OFFSET_SINCE_VERSION 5 + +/** @ingroup iface_wl_surface */ +static inline void +wl_surface_set_user_data(struct wl_surface *wl_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_surface, user_data); +} + +/** @ingroup iface_wl_surface */ +static inline void * +wl_surface_get_user_data(struct wl_surface *wl_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_surface); +} + +static inline uint32_t +wl_surface_get_version(struct wl_surface *wl_surface) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_surface); +} + +/** + * @ingroup iface_wl_surface + * + * Deletes the surface and invalidates its object ID. + */ +static inline void +wl_surface_destroy(struct wl_surface *wl_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_surface + * + * Set a buffer as the content of this surface. + * + * The new size of the surface is calculated based on the buffer + * size transformed by the inverse buffer_transform and the + * inverse buffer_scale. This means that at commit time the supplied + * buffer size must be an integer multiple of the buffer_scale. If + * that's not the case, an invalid_size error is sent. + * + * The x and y arguments specify the location of the new pending + * buffer's upper left corner, relative to the current buffer's upper + * left corner, in surface-local coordinates. In other words, the + * x and y, combined with the new surface size define in which + * directions the surface's size changes. Setting anything other than 0 + * as x and y arguments is discouraged, and should instead be replaced + * with using the separate wl_surface.offset request. + * + * When the bound wl_surface version is 5 or higher, passing any + * non-zero x or y is a protocol violation, and will result in an + * 'invalid_offset' error being raised. The x and y arguments are ignored + * and do not change the pending state. To achieve equivalent semantics, + * use wl_surface.offset. + * + * Surface contents are double-buffered state, see wl_surface.commit. + * + * The initial surface contents are void; there is no content. + * wl_surface.attach assigns the given wl_buffer as the pending + * wl_buffer. wl_surface.commit makes the pending wl_buffer the new + * surface contents, and the size of the surface becomes the size + * calculated from the wl_buffer, as described above. After commit, + * there is no pending buffer until the next attach. + * + * Committing a pending wl_buffer allows the compositor to read the + * pixels in the wl_buffer. The compositor may access the pixels at + * any time after the wl_surface.commit request. When the compositor + * will not access the pixels anymore, it will send the + * wl_buffer.release event. Only after receiving wl_buffer.release, + * the client may reuse the wl_buffer. A wl_buffer that has been + * attached and then replaced by another attach instead of committed + * will not receive a release event, and is not used by the + * compositor. + * + * If a pending wl_buffer has been committed to more than one wl_surface, + * the delivery of wl_buffer.release events becomes undefined. A well + * behaved client should not rely on wl_buffer.release events in this + * case. Alternatively, a client could create multiple wl_buffer objects + * from the same backing storage or use wp_linux_buffer_release. + * + * Destroying the wl_buffer after wl_buffer.release does not change + * the surface contents. Destroying the wl_buffer before wl_buffer.release + * is allowed as long as the underlying buffer storage isn't re-used (this + * can happen e.g. on client process termination). However, if the client + * destroys the wl_buffer before receiving the wl_buffer.release event and + * mutates the underlying buffer storage, the surface contents become + * undefined immediately. + * + * If wl_surface.attach is sent with a NULL wl_buffer, or the pending + * wl_buffer has been destroyed, the following wl_surface.commit will + * remove the surface content. + */ +static inline void +wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_ATTACH, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, buffer, x, y); +} + +/** + * @ingroup iface_wl_surface + * + * This request is used to describe the regions where the pending + * buffer is different from the current surface contents, and where + * the surface therefore needs to be repainted. The compositor + * ignores the parts of the damage that fall outside of the surface. + * + * Damage is double-buffered state, see wl_surface.commit. + * + * The damage rectangle is specified in surface-local coordinates, + * where x and y specify the upper left corner of the damage rectangle. + * + * The initial value for pending damage is empty: no damage. + * wl_surface.damage adds pending damage: the new pending damage + * is the union of old pending damage and the given rectangle. + * + * wl_surface.commit assigns pending damage as the current damage, + * and clears pending damage. The server will clear the current + * damage as it repaints the surface. + * + * Note! New clients should not use this request. Instead damage can be + * posted with wl_surface.damage_buffer which uses buffer coordinates + * instead of surface coordinates. + */ +static inline void +wl_surface_damage(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_DAMAGE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y, width, height); +} + +/** + * @ingroup iface_wl_surface + * + * Request a notification when it is a good time to start drawing a new + * frame, by creating a frame callback. This is useful for throttling + * redrawing operations, and driving animations. + * + * When a client is animating on a wl_surface, it can use the 'frame' + * request to get notified when it is a good time to draw and commit the + * next frame of animation. If the client commits an update earlier than + * that, it is likely that some updates will not make it to the display, + * and the client is wasting resources by drawing too often. + * + * The frame request will take effect on the next wl_surface.commit. + * The notification will only be posted for one frame unless + * requested again. For a wl_surface, the notifications are posted in + * the order the frame requests were committed. + * + * The server must send the notifications so that a client + * will not send excessive updates, while still allowing + * the highest possible update rate for clients that wait for the reply + * before drawing again. The server should give some time for the client + * to draw and commit after sending the frame callback events to let it + * hit the next output refresh. + * + * A server should avoid signaling the frame callbacks if the + * surface is not visible in any way, e.g. the surface is off-screen, + * or completely obscured by other opaque surfaces. + * + * The object returned by this request will be destroyed by the + * compositor after the callback is fired and as such the client must not + * attempt to use it after that point. + * + * The callback_data passed in the callback is the current time, in + * milliseconds, with an undefined base. + */ +static inline struct wl_callback * +wl_surface_frame(struct wl_surface *wl_surface) +{ + struct wl_proxy *callback; + + callback = wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_FRAME, &wl_callback_interface, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, NULL); + + return (struct wl_callback *) callback; +} + +/** + * @ingroup iface_wl_surface + * + * This request sets the region of the surface that contains + * opaque content. + * + * The opaque region is an optimization hint for the compositor + * that lets it optimize the redrawing of content behind opaque + * regions. Setting an opaque region is not required for correct + * behaviour, but marking transparent content as opaque will result + * in repaint artifacts. + * + * The opaque region is specified in surface-local coordinates. + * + * The compositor ignores the parts of the opaque region that fall + * outside of the surface. + * + * Opaque region is double-buffered state, see wl_surface.commit. + * + * wl_surface.set_opaque_region changes the pending opaque region. + * wl_surface.commit copies the pending region to the current region. + * Otherwise, the pending and current regions are never changed. + * + * The initial value for an opaque region is empty. Setting the pending + * opaque region has copy semantics, and the wl_region object can be + * destroyed immediately. A NULL wl_region causes the pending opaque + * region to be set to empty. + */ +static inline void +wl_surface_set_opaque_region(struct wl_surface *wl_surface, struct wl_region *region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_OPAQUE_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, region); +} + +/** + * @ingroup iface_wl_surface + * + * This request sets the region of the surface that can receive + * pointer and touch events. + * + * Input events happening outside of this region will try the next + * surface in the server surface stack. The compositor ignores the + * parts of the input region that fall outside of the surface. + * + * The input region is specified in surface-local coordinates. + * + * Input region is double-buffered state, see wl_surface.commit. + * + * wl_surface.set_input_region changes the pending input region. + * wl_surface.commit copies the pending region to the current region. + * Otherwise the pending and current regions are never changed, + * except cursor and icon surfaces are special cases, see + * wl_pointer.set_cursor and wl_data_device.start_drag. + * + * The initial value for an input region is infinite. That means the + * whole surface will accept input. Setting the pending input region + * has copy semantics, and the wl_region object can be destroyed + * immediately. A NULL wl_region causes the input region to be set + * to infinite. + */ +static inline void +wl_surface_set_input_region(struct wl_surface *wl_surface, struct wl_region *region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_INPUT_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, region); +} + +/** + * @ingroup iface_wl_surface + * + * Surface state (input, opaque, and damage regions, attached buffers, + * etc.) is double-buffered. Protocol requests modify the pending state, + * as opposed to the current state in use by the compositor. A commit + * request atomically applies all pending state, replacing the current + * state. After commit, the new pending state is as documented for each + * related request. + * + * On commit, a pending wl_buffer is applied first, and all other state + * second. This means that all coordinates in double-buffered state are + * relative to the new wl_buffer coming into use, except for + * wl_surface.attach itself. If there is no pending wl_buffer, the + * coordinates are relative to the current surface contents. + * + * All requests that need a commit to become effective are documented + * to affect double-buffered state. + * + * Other interfaces may add further double-buffered surface state. + */ +static inline void +wl_surface_commit(struct wl_surface *wl_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0); +} + +/** + * @ingroup iface_wl_surface + * + * This request sets an optional transformation on how the compositor + * interprets the contents of the buffer attached to the surface. The + * accepted values for the transform parameter are the values for + * wl_output.transform. + * + * Buffer transform is double-buffered state, see wl_surface.commit. + * + * A newly created surface has its buffer transformation set to normal. + * + * wl_surface.set_buffer_transform changes the pending buffer + * transformation. wl_surface.commit copies the pending buffer + * transformation to the current one. Otherwise, the pending and current + * values are never changed. + * + * The purpose of this request is to allow clients to render content + * according to the output transform, thus permitting the compositor to + * use certain optimizations even if the display is rotated. Using + * hardware overlays and scanning out a client buffer for fullscreen + * surfaces are examples of such optimizations. Those optimizations are + * highly dependent on the compositor implementation, so the use of this + * request should be considered on a case-by-case basis. + * + * Note that if the transform value includes 90 or 270 degree rotation, + * the width of the buffer will become the surface height and the height + * of the buffer will become the surface width. + * + * If transform is not one of the values from the + * wl_output.transform enum the invalid_transform protocol error + * is raised. + */ +static inline void +wl_surface_set_buffer_transform(struct wl_surface *wl_surface, int32_t transform) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_BUFFER_TRANSFORM, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, transform); +} + +/** + * @ingroup iface_wl_surface + * + * This request sets an optional scaling factor on how the compositor + * interprets the contents of the buffer attached to the window. + * + * Buffer scale is double-buffered state, see wl_surface.commit. + * + * A newly created surface has its buffer scale set to 1. + * + * wl_surface.set_buffer_scale changes the pending buffer scale. + * wl_surface.commit copies the pending buffer scale to the current one. + * Otherwise, the pending and current values are never changed. + * + * The purpose of this request is to allow clients to supply higher + * resolution buffer data for use on high resolution outputs. It is + * intended that you pick the same buffer scale as the scale of the + * output that the surface is displayed on. This means the compositor + * can avoid scaling when rendering the surface on that output. + * + * Note that if the scale is larger than 1, then you have to attach + * a buffer that is larger (by a factor of scale in each dimension) + * than the desired surface size. + * + * If scale is not greater than 0 the invalid_scale protocol error is + * raised. + */ +static inline void +wl_surface_set_buffer_scale(struct wl_surface *wl_surface, int32_t scale) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_SET_BUFFER_SCALE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, scale); +} + +/** + * @ingroup iface_wl_surface + * + * This request is used to describe the regions where the pending + * buffer is different from the current surface contents, and where + * the surface therefore needs to be repainted. The compositor + * ignores the parts of the damage that fall outside of the surface. + * + * Damage is double-buffered state, see wl_surface.commit. + * + * The damage rectangle is specified in buffer coordinates, + * where x and y specify the upper left corner of the damage rectangle. + * + * The initial value for pending damage is empty: no damage. + * wl_surface.damage_buffer adds pending damage: the new pending + * damage is the union of old pending damage and the given rectangle. + * + * wl_surface.commit assigns pending damage as the current damage, + * and clears pending damage. The server will clear the current + * damage as it repaints the surface. + * + * This request differs from wl_surface.damage in only one way - it + * takes damage in buffer coordinates instead of surface-local + * coordinates. While this generally is more intuitive than surface + * coordinates, it is especially desirable when using wp_viewport + * or when a drawing library (like EGL) is unaware of buffer scale + * and buffer transform. + * + * Note: Because buffer transformation changes and damage requests may + * be interleaved in the protocol stream, it is impossible to determine + * the actual mapping between surface and buffer damage until + * wl_surface.commit time. Therefore, compositors wishing to take both + * kinds of damage into account will have to accumulate damage from the + * two requests separately and only transform from one to the other + * after receiving the wl_surface.commit. + */ +static inline void +wl_surface_damage_buffer(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_DAMAGE_BUFFER, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y, width, height); +} + +/** + * @ingroup iface_wl_surface + * + * The x and y arguments specify the location of the new pending + * buffer's upper left corner, relative to the current buffer's upper + * left corner, in surface-local coordinates. In other words, the + * x and y, combined with the new surface size define in which + * directions the surface's size changes. + * + * Surface location offset is double-buffered state, see + * wl_surface.commit. + * + * This request is semantically equivalent to and the replaces the x and y + * arguments in the wl_surface.attach request in wl_surface versions prior + * to 5. See wl_surface.attach for details. + */ +static inline void +wl_surface_offset(struct wl_surface *wl_surface, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_surface, + WL_SURFACE_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) wl_surface), 0, x, y); +} + +#ifndef WL_SEAT_CAPABILITY_ENUM +#define WL_SEAT_CAPABILITY_ENUM +/** + * @ingroup iface_wl_seat + * seat capability bitmask + * + * This is a bitmask of capabilities this seat has; if a member is + * set, then it is present on the seat. + */ +enum wl_seat_capability { + /** + * the seat has pointer devices + */ + WL_SEAT_CAPABILITY_POINTER = 1, + /** + * the seat has one or more keyboards + */ + WL_SEAT_CAPABILITY_KEYBOARD = 2, + /** + * the seat has touch devices + */ + WL_SEAT_CAPABILITY_TOUCH = 4, +}; +#endif /* WL_SEAT_CAPABILITY_ENUM */ + +#ifndef WL_SEAT_ERROR_ENUM +#define WL_SEAT_ERROR_ENUM +/** + * @ingroup iface_wl_seat + * wl_seat error values + * + * These errors can be emitted in response to wl_seat requests. + */ +enum wl_seat_error { + /** + * get_pointer, get_keyboard or get_touch called on seat without the matching capability + */ + WL_SEAT_ERROR_MISSING_CAPABILITY = 0, +}; +#endif /* WL_SEAT_ERROR_ENUM */ + +/** + * @ingroup iface_wl_seat + * @struct wl_seat_listener + */ +struct wl_seat_listener { + /** + * seat capabilities changed + * + * This is emitted whenever a seat gains or loses the pointer, + * keyboard or touch capabilities. The argument is a capability + * enum containing the complete set of capabilities this seat has. + * + * When the pointer capability is added, a client may create a + * wl_pointer object using the wl_seat.get_pointer request. This + * object will receive pointer events until the capability is + * removed in the future. + * + * When the pointer capability is removed, a client should destroy + * the wl_pointer objects associated with the seat where the + * capability was removed, using the wl_pointer.release request. No + * further pointer events will be received on these objects. + * + * In some compositors, if a seat regains the pointer capability + * and a client has a previously obtained wl_pointer object of + * version 4 or less, that object may start sending pointer events + * again. This behavior is considered a misinterpretation of the + * intended behavior and must not be relied upon by the client. + * wl_pointer objects of version 5 or later must not send events if + * created before the most recent event notifying the client of an + * added pointer capability. + * + * The above behavior also applies to wl_keyboard and wl_touch with + * the keyboard and touch capabilities, respectively. + * @param capabilities capabilities of the seat + */ + void (*capabilities)(void *data, + struct wl_seat *wl_seat, + uint32_t capabilities); + /** + * unique identifier for this seat + * + * In a multi-seat configuration the seat name can be used by + * clients to help identify which physical devices the seat + * represents. + * + * The seat name is a UTF-8 string with no convention defined for + * its contents. Each name is unique among all wl_seat globals. The + * name is only guaranteed to be unique for the current compositor + * instance. + * + * The same seat names are used for all clients. Thus, the name can + * be shared across processes to refer to a specific wl_seat + * global. + * + * The name event is sent after binding to the seat global. This + * event is only sent once per seat object, and the name does not + * change over the lifetime of the wl_seat global. + * + * Compositors may re-use the same seat name if the wl_seat global + * is destroyed and re-created later. + * @param name seat identifier + * @since 2 + */ + void (*name)(void *data, + struct wl_seat *wl_seat, + const char *name); +}; + +/** + * @ingroup iface_wl_seat + */ +static inline int +wl_seat_add_listener(struct wl_seat *wl_seat, + const struct wl_seat_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_seat, + (void (**)(void)) listener, data); +} + +#define WL_SEAT_GET_POINTER 0 +#define WL_SEAT_GET_KEYBOARD 1 +#define WL_SEAT_GET_TOUCH 2 +#define WL_SEAT_RELEASE 3 + +/** + * @ingroup iface_wl_seat + */ +#define WL_SEAT_CAPABILITIES_SINCE_VERSION 1 +/** + * @ingroup iface_wl_seat + */ +#define WL_SEAT_NAME_SINCE_VERSION 2 + +/** + * @ingroup iface_wl_seat + */ +#define WL_SEAT_GET_POINTER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_seat + */ +#define WL_SEAT_GET_KEYBOARD_SINCE_VERSION 1 +/** + * @ingroup iface_wl_seat + */ +#define WL_SEAT_GET_TOUCH_SINCE_VERSION 1 +/** + * @ingroup iface_wl_seat + */ +#define WL_SEAT_RELEASE_SINCE_VERSION 5 + +/** @ingroup iface_wl_seat */ +static inline void +wl_seat_set_user_data(struct wl_seat *wl_seat, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_seat, user_data); +} + +/** @ingroup iface_wl_seat */ +static inline void * +wl_seat_get_user_data(struct wl_seat *wl_seat) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_seat); +} + +static inline uint32_t +wl_seat_get_version(struct wl_seat *wl_seat) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_seat); +} + +/** @ingroup iface_wl_seat */ +static inline void +wl_seat_destroy(struct wl_seat *wl_seat) +{ + wl_proxy_destroy((struct wl_proxy *) wl_seat); +} + +/** + * @ingroup iface_wl_seat + * + * The ID provided will be initialized to the wl_pointer interface + * for this seat. + * + * This request only takes effect if the seat has the pointer + * capability, or has had the pointer capability in the past. + * It is a protocol violation to issue this request on a seat that has + * never had the pointer capability. The missing_capability error will + * be sent in this case. + */ +static inline struct wl_pointer * +wl_seat_get_pointer(struct wl_seat *wl_seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_GET_POINTER, &wl_pointer_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); + + return (struct wl_pointer *) id; +} + +/** + * @ingroup iface_wl_seat + * + * The ID provided will be initialized to the wl_keyboard interface + * for this seat. + * + * This request only takes effect if the seat has the keyboard + * capability, or has had the keyboard capability in the past. + * It is a protocol violation to issue this request on a seat that has + * never had the keyboard capability. The missing_capability error will + * be sent in this case. + */ +static inline struct wl_keyboard * +wl_seat_get_keyboard(struct wl_seat *wl_seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_GET_KEYBOARD, &wl_keyboard_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); + + return (struct wl_keyboard *) id; +} + +/** + * @ingroup iface_wl_seat + * + * The ID provided will be initialized to the wl_touch interface + * for this seat. + * + * This request only takes effect if the seat has the touch + * capability, or has had the touch capability in the past. + * It is a protocol violation to issue this request on a seat that has + * never had the touch capability. The missing_capability error will + * be sent in this case. + */ +static inline struct wl_touch * +wl_seat_get_touch(struct wl_seat *wl_seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_GET_TOUCH, &wl_touch_interface, wl_proxy_get_version((struct wl_proxy *) wl_seat), 0, NULL); + + return (struct wl_touch *) id; +} + +/** + * @ingroup iface_wl_seat + * + * Using this request a client can tell the server that it is not going to + * use the seat object anymore. + */ +static inline void +wl_seat_release(struct wl_seat *wl_seat) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_seat, + WL_SEAT_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_seat), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_POINTER_ERROR_ENUM +#define WL_POINTER_ERROR_ENUM +enum wl_pointer_error { + /** + * given wl_surface has another role + */ + WL_POINTER_ERROR_ROLE = 0, +}; +#endif /* WL_POINTER_ERROR_ENUM */ + +#ifndef WL_POINTER_BUTTON_STATE_ENUM +#define WL_POINTER_BUTTON_STATE_ENUM +/** + * @ingroup iface_wl_pointer + * physical button state + * + * Describes the physical state of a button that produced the button + * event. + */ +enum wl_pointer_button_state { + /** + * the button is not pressed + */ + WL_POINTER_BUTTON_STATE_RELEASED = 0, + /** + * the button is pressed + */ + WL_POINTER_BUTTON_STATE_PRESSED = 1, +}; +#endif /* WL_POINTER_BUTTON_STATE_ENUM */ + +#ifndef WL_POINTER_AXIS_ENUM +#define WL_POINTER_AXIS_ENUM +/** + * @ingroup iface_wl_pointer + * axis types + * + * Describes the axis types of scroll events. + */ +enum wl_pointer_axis { + /** + * vertical axis + */ + WL_POINTER_AXIS_VERTICAL_SCROLL = 0, + /** + * horizontal axis + */ + WL_POINTER_AXIS_HORIZONTAL_SCROLL = 1, +}; +#endif /* WL_POINTER_AXIS_ENUM */ + +#ifndef WL_POINTER_AXIS_SOURCE_ENUM +#define WL_POINTER_AXIS_SOURCE_ENUM +/** + * @ingroup iface_wl_pointer + * axis source types + * + * Describes the source types for axis events. This indicates to the + * client how an axis event was physically generated; a client may + * adjust the user interface accordingly. For example, scroll events + * from a "finger" source may be in a smooth coordinate space with + * kinetic scrolling whereas a "wheel" source may be in discrete steps + * of a number of lines. + * + * The "continuous" axis source is a device generating events in a + * continuous coordinate space, but using something other than a + * finger. One example for this source is button-based scrolling where + * the vertical motion of a device is converted to scroll events while + * a button is held down. + * + * The "wheel tilt" axis source indicates that the actual device is a + * wheel but the scroll event is not caused by a rotation but a + * (usually sideways) tilt of the wheel. + */ +enum wl_pointer_axis_source { + /** + * a physical wheel rotation + */ + WL_POINTER_AXIS_SOURCE_WHEEL = 0, + /** + * finger on a touch surface + */ + WL_POINTER_AXIS_SOURCE_FINGER = 1, + /** + * continuous coordinate space + */ + WL_POINTER_AXIS_SOURCE_CONTINUOUS = 2, + /** + * a physical wheel tilt + * @since 6 + */ + WL_POINTER_AXIS_SOURCE_WHEEL_TILT = 3, +}; +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION 6 +#endif /* WL_POINTER_AXIS_SOURCE_ENUM */ + +#ifndef WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM +#define WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM +/** + * @ingroup iface_wl_pointer + * axis relative direction + * + * This specifies the direction of the physical motion that caused a + * wl_pointer.axis event, relative to the wl_pointer.axis direction. + */ +enum wl_pointer_axis_relative_direction { + /** + * physical motion matches axis direction + */ + WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL = 0, + /** + * physical motion is the inverse of the axis direction + */ + WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED = 1, +}; +#endif /* WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM */ + +/** + * @ingroup iface_wl_pointer + * @struct wl_pointer_listener + */ +struct wl_pointer_listener { + /** + * enter event + * + * Notification that this seat's pointer is focused on a certain + * surface. + * + * When a seat's focus enters a surface, the pointer image is + * undefined and a client should respond to this event by setting + * an appropriate pointer image with the set_cursor request. + * @param serial serial number of the enter event + * @param surface surface entered by the pointer + * @param surface_x surface-local x coordinate + * @param surface_y surface-local y coordinate + */ + void (*enter)(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + struct wl_surface *surface, + wl_fixed_t surface_x, + wl_fixed_t surface_y); + /** + * leave event + * + * Notification that this seat's pointer is no longer focused on + * a certain surface. + * + * The leave notification is sent before the enter notification for + * the new focus. + * @param serial serial number of the leave event + * @param surface surface left by the pointer + */ + void (*leave)(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + struct wl_surface *surface); + /** + * pointer motion event + * + * Notification of pointer location change. The arguments + * surface_x and surface_y are the location relative to the focused + * surface. + * @param time timestamp with millisecond granularity + * @param surface_x surface-local x coordinate + * @param surface_y surface-local y coordinate + */ + void (*motion)(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + wl_fixed_t surface_x, + wl_fixed_t surface_y); + /** + * pointer button event + * + * Mouse button click and release notifications. + * + * The location of the click is given by the last motion or enter + * event. The time argument is a timestamp with millisecond + * granularity, with an undefined base. + * + * The button is a button code as defined in the Linux kernel's + * linux/input-event-codes.h header file, e.g. BTN_LEFT. + * + * Any 16-bit button code value is reserved for future additions to + * the kernel's event code list. All other button codes above + * 0xFFFF are currently undefined but may be used in future + * versions of this protocol. + * @param serial serial number of the button event + * @param time timestamp with millisecond granularity + * @param button button that produced the event + * @param state physical state of the button + */ + void (*button)(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + uint32_t time, + uint32_t button, + uint32_t state); + /** + * axis event + * + * Scroll and other axis notifications. + * + * For scroll events (vertical and horizontal scroll axes), the + * value parameter is the length of a vector along the specified + * axis in a coordinate space identical to those of motion events, + * representing a relative movement along the specified axis. + * + * For devices that support movements non-parallel to axes multiple + * axis events will be emitted. + * + * When applicable, for example for touch pads, the server can + * choose to emit scroll events where the motion vector is + * equivalent to a motion event vector. + * + * When applicable, a client can transform its content relative to + * the scroll distance. + * @param time timestamp with millisecond granularity + * @param axis axis type + * @param value length of vector in surface-local coordinate space + */ + void (*axis)(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + uint32_t axis, + wl_fixed_t value); + /** + * end of a pointer event sequence + * + * Indicates the end of a set of events that logically belong + * together. A client is expected to accumulate the data in all + * events within the frame before proceeding. + * + * All wl_pointer events before a wl_pointer.frame event belong + * logically together. For example, in a diagonal scroll motion the + * compositor will send an optional wl_pointer.axis_source event, + * two wl_pointer.axis events (horizontal and vertical) and finally + * a wl_pointer.frame event. The client may use this information to + * calculate a diagonal vector for scrolling. + * + * When multiple wl_pointer.axis events occur within the same + * frame, the motion vector is the combined motion of all events. + * When a wl_pointer.axis and a wl_pointer.axis_stop event occur + * within the same frame, this indicates that axis movement in one + * axis has stopped but continues in the other axis. When multiple + * wl_pointer.axis_stop events occur within the same frame, this + * indicates that these axes stopped in the same instance. + * + * A wl_pointer.frame event is sent for every logical event group, + * even if the group only contains a single wl_pointer event. + * Specifically, a client may get a sequence: motion, frame, + * button, frame, axis, frame, axis_stop, frame. + * + * The wl_pointer.enter and wl_pointer.leave events are logical + * events generated by the compositor and not the hardware. These + * events are also grouped by a wl_pointer.frame. When a pointer + * moves from one surface to another, a compositor should group the + * wl_pointer.leave event within the same wl_pointer.frame. + * However, a client must not rely on wl_pointer.leave and + * wl_pointer.enter being in the same wl_pointer.frame. + * Compositor-specific policies may require the wl_pointer.leave + * and wl_pointer.enter event being split across multiple + * wl_pointer.frame groups. + * @since 5 + */ + void (*frame)(void *data, + struct wl_pointer *wl_pointer); + /** + * axis source event + * + * Source information for scroll and other axes. + * + * This event does not occur on its own. It is sent before a + * wl_pointer.frame event and carries the source information for + * all events within that frame. + * + * The source specifies how this event was generated. If the source + * is wl_pointer.axis_source.finger, a wl_pointer.axis_stop event + * will be sent when the user lifts the finger off the device. + * + * If the source is wl_pointer.axis_source.wheel, + * wl_pointer.axis_source.wheel_tilt or + * wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event + * may or may not be sent. Whether a compositor sends an axis_stop + * event for these sources is hardware-specific and + * implementation-dependent; clients must not rely on receiving an + * axis_stop event for these scroll sources and should treat scroll + * sequences from these scroll sources as unterminated by default. + * + * This event is optional. If the source is unknown for a + * particular axis event sequence, no event is sent. Only one + * wl_pointer.axis_source event is permitted per frame. + * + * The order of wl_pointer.axis_discrete and wl_pointer.axis_source + * is not guaranteed. + * @param axis_source source of the axis event + * @since 5 + */ + void (*axis_source)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis_source); + /** + * axis stop event + * + * Stop notification for scroll and other axes. + * + * For some wl_pointer.axis_source types, a wl_pointer.axis_stop + * event is sent to notify a client that the axis sequence has + * terminated. This enables the client to implement kinetic + * scrolling. See the wl_pointer.axis_source documentation for + * information on when this event may be generated. + * + * Any wl_pointer.axis events with the same axis_source after this + * event should be considered as the start of a new axis motion. + * + * The timestamp is to be interpreted identical to the timestamp in + * the wl_pointer.axis event. The timestamp value may be the same + * as a preceding wl_pointer.axis event. + * @param time timestamp with millisecond granularity + * @param axis the axis stopped with this event + * @since 5 + */ + void (*axis_stop)(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + uint32_t axis); + /** + * axis click event + * + * Discrete step information for scroll and other axes. + * + * This event carries the axis value of the wl_pointer.axis event + * in discrete steps (e.g. mouse wheel clicks). + * + * This event is deprecated with wl_pointer version 8 - this event + * is not sent to clients supporting version 8 or later. + * + * This event does not occur on its own, it is coupled with a + * wl_pointer.axis event that represents this axis value on a + * continuous scale. The protocol guarantees that each + * axis_discrete event is always followed by exactly one axis event + * with the same axis number within the same wl_pointer.frame. Note + * that the protocol allows for other events to occur between the + * axis_discrete and its coupled axis event, including other + * axis_discrete or axis events. A wl_pointer.frame must not + * contain more than one axis_discrete event per axis type. + * + * This event is optional; continuous scrolling devices like + * two-finger scrolling on touchpads do not have discrete steps and + * do not generate this event. + * + * The discrete value carries the directional information. e.g. a + * value of -2 is two steps towards the negative direction of this + * axis. + * + * The axis number is identical to the axis number in the + * associated axis event. + * + * The order of wl_pointer.axis_discrete and wl_pointer.axis_source + * is not guaranteed. + * @param axis axis type + * @param discrete number of steps + * @since 5 + */ + void (*axis_discrete)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + int32_t discrete); + /** + * axis high-resolution scroll event + * + * Discrete high-resolution scroll information. + * + * This event carries high-resolution wheel scroll information, + * with each multiple of 120 representing one logical scroll step + * (a wheel detent). For example, an axis_value120 of 30 is one + * quarter of a logical scroll step in the positive direction, a + * value120 of -240 are two logical scroll steps in the negative + * direction within the same hardware event. Clients that rely on + * discrete scrolling should accumulate the value120 to multiples + * of 120 before processing the event. + * + * The value120 must not be zero. + * + * This event replaces the wl_pointer.axis_discrete event in + * clients supporting wl_pointer version 8 or later. + * + * Where a wl_pointer.axis_source event occurs in the same + * wl_pointer.frame, the axis source applies to this event. + * + * The order of wl_pointer.axis_value120 and wl_pointer.axis_source + * is not guaranteed. + * @param axis axis type + * @param value120 scroll distance as fraction of 120 + * @since 8 + */ + void (*axis_value120)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + int32_t value120); + /** + * axis relative physical direction event + * + * Relative directional information of the entity causing the + * axis motion. + * + * For a wl_pointer.axis event, the + * wl_pointer.axis_relative_direction event specifies the movement + * direction of the entity causing the wl_pointer.axis event. For + * example: - if a user's fingers on a touchpad move down and this + * causes a wl_pointer.axis vertical_scroll down event, the + * physical direction is 'identical' - if a user's fingers on a + * touchpad move down and this causes a wl_pointer.axis + * vertical_scroll up scroll up event ('natural scrolling'), the + * physical direction is 'inverted'. + * + * A client may use this information to adjust scroll motion of + * components. Specifically, enabling natural scrolling causes the + * content to change direction compared to traditional scrolling. + * Some widgets like volume control sliders should usually match + * the physical direction regardless of whether natural scrolling + * is active. This event enables clients to match the scroll + * direction of a widget to the physical direction. + * + * This event does not occur on its own, it is coupled with a + * wl_pointer.axis event that represents this axis value. The + * protocol guarantees that each axis_relative_direction event is + * always followed by exactly one axis event with the same axis + * number within the same wl_pointer.frame. Note that the protocol + * allows for other events to occur between the + * axis_relative_direction and its coupled axis event. + * + * The axis number is identical to the axis number in the + * associated axis event. + * + * The order of wl_pointer.axis_relative_direction, + * wl_pointer.axis_discrete and wl_pointer.axis_source is not + * guaranteed. + * @param axis axis type + * @param direction physical direction relative to axis motion + * @since 9 + */ + void (*axis_relative_direction)(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + uint32_t direction); +}; + +/** + * @ingroup iface_wl_pointer + */ +static inline int +wl_pointer_add_listener(struct wl_pointer *wl_pointer, + const struct wl_pointer_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_pointer, + (void (**)(void)) listener, data); +} + +#define WL_POINTER_SET_CURSOR 0 +#define WL_POINTER_RELEASE 1 + +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_ENTER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_LEAVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_MOTION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_BUTTON_SINCE_VERSION 1 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_SINCE_VERSION 1 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_FRAME_SINCE_VERSION 5 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_SOURCE_SINCE_VERSION 5 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_STOP_SINCE_VERSION 5 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_DISCRETE_SINCE_VERSION 5 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_VALUE120_SINCE_VERSION 8 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_AXIS_RELATIVE_DIRECTION_SINCE_VERSION 9 + +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_SET_CURSOR_SINCE_VERSION 1 +/** + * @ingroup iface_wl_pointer + */ +#define WL_POINTER_RELEASE_SINCE_VERSION 3 + +/** @ingroup iface_wl_pointer */ +static inline void +wl_pointer_set_user_data(struct wl_pointer *wl_pointer, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_pointer, user_data); +} + +/** @ingroup iface_wl_pointer */ +static inline void * +wl_pointer_get_user_data(struct wl_pointer *wl_pointer) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_pointer); +} + +static inline uint32_t +wl_pointer_get_version(struct wl_pointer *wl_pointer) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_pointer); +} + +/** @ingroup iface_wl_pointer */ +static inline void +wl_pointer_destroy(struct wl_pointer *wl_pointer) +{ + wl_proxy_destroy((struct wl_proxy *) wl_pointer); +} + +/** + * @ingroup iface_wl_pointer + * + * Set the pointer surface, i.e., the surface that contains the + * pointer image (cursor). This request gives the surface the role + * of a cursor. If the surface already has another role, it raises + * a protocol error. + * + * The cursor actually changes only if the pointer + * focus for this device is one of the requesting client's surfaces + * or the surface parameter is the current pointer surface. If + * there was a previous surface set with this request it is + * replaced. If surface is NULL, the pointer image is hidden. + * + * The parameters hotspot_x and hotspot_y define the position of + * the pointer surface relative to the pointer location. Its + * top-left corner is always at (x, y) - (hotspot_x, hotspot_y), + * where (x, y) are the coordinates of the pointer location, in + * surface-local coordinates. + * + * On wl_surface.offset requests to the pointer surface, hotspot_x + * and hotspot_y are decremented by the x and y parameters + * passed to the request. The offset must be applied by + * wl_surface.commit as usual. + * + * The hotspot can also be updated by passing the currently set + * pointer surface to this request with new values for hotspot_x + * and hotspot_y. + * + * The input region is ignored for wl_surfaces with the role of + * a cursor. When the use as a cursor ends, the wl_surface is + * unmapped. + * + * The serial parameter must match the latest wl_pointer.enter + * serial number sent to the client. Otherwise the request will be + * ignored. + */ +static inline void +wl_pointer_set_cursor(struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, int32_t hotspot_x, int32_t hotspot_y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_pointer, + WL_POINTER_SET_CURSOR, NULL, wl_proxy_get_version((struct wl_proxy *) wl_pointer), 0, serial, surface, hotspot_x, hotspot_y); +} + +/** + * @ingroup iface_wl_pointer + * + * Using this request a client can tell the server that it is not going to + * use the pointer object anymore. + * + * This request destroys the pointer proxy object, so clients must not call + * wl_pointer_destroy() after using this request. + */ +static inline void +wl_pointer_release(struct wl_pointer *wl_pointer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_pointer, + WL_POINTER_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_pointer), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_KEYBOARD_KEYMAP_FORMAT_ENUM +#define WL_KEYBOARD_KEYMAP_FORMAT_ENUM +/** + * @ingroup iface_wl_keyboard + * keyboard mapping format + * + * This specifies the format of the keymap provided to the + * client with the wl_keyboard.keymap event. + */ +enum wl_keyboard_keymap_format { + /** + * no keymap; client must understand how to interpret the raw keycode + */ + WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP = 0, + /** + * libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode + */ + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 = 1, +}; +#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM */ + +#ifndef WL_KEYBOARD_KEY_STATE_ENUM +#define WL_KEYBOARD_KEY_STATE_ENUM +/** + * @ingroup iface_wl_keyboard + * physical key state + * + * Describes the physical state of a key that produced the key event. + */ +enum wl_keyboard_key_state { + /** + * key is not pressed + */ + WL_KEYBOARD_KEY_STATE_RELEASED = 0, + /** + * key is pressed + */ + WL_KEYBOARD_KEY_STATE_PRESSED = 1, +}; +#endif /* WL_KEYBOARD_KEY_STATE_ENUM */ + +/** + * @ingroup iface_wl_keyboard + * @struct wl_keyboard_listener + */ +struct wl_keyboard_listener { + /** + * keyboard mapping + * + * This event provides a file descriptor to the client which can + * be memory-mapped in read-only mode to provide a keyboard mapping + * description. + * + * From version 7 onwards, the fd must be mapped with MAP_PRIVATE + * by the recipient, as MAP_SHARED may fail. + * @param format keymap format + * @param fd keymap file descriptor + * @param size keymap size, in bytes + */ + void (*keymap)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t format, + int32_t fd, + uint32_t size); + /** + * enter event + * + * Notification that this seat's keyboard focus is on a certain + * surface. + * + * The compositor must send the wl_keyboard.modifiers event after + * this event. + * @param serial serial number of the enter event + * @param surface surface gaining keyboard focus + * @param keys the currently pressed keys + */ + void (*enter)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + struct wl_surface *surface, + struct wl_array *keys); + /** + * leave event + * + * Notification that this seat's keyboard focus is no longer on a + * certain surface. + * + * The leave notification is sent before the enter notification for + * the new focus. + * + * After this event client must assume that no keys are pressed, it + * must stop key repeating if there's some going on and until it + * receives the next wl_keyboard.modifiers event, the client must + * also assume no modifiers are active. + * @param serial serial number of the leave event + * @param surface surface that lost keyboard focus + */ + void (*leave)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + struct wl_surface *surface); + /** + * key event + * + * A key was pressed or released. The time argument is a + * timestamp with millisecond granularity, with an undefined base. + * + * The key is a platform-specific key code that can be interpreted + * by feeding it to the keyboard mapping (see the keymap event). + * + * If this event produces a change in modifiers, then the resulting + * wl_keyboard.modifiers event must be sent after this event. + * + * The compositor must not send this event without a surface of the + * client having keyboard focus. + * @param serial serial number of the key event + * @param time timestamp with millisecond granularity + * @param key key that produced the event + * @param state physical state of the key + */ + void (*key)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state); + /** + * modifier and group state + * + * Notifies clients that the modifier and/or group state has + * changed, and it should update its local state. + * + * The compositor may send this event without a surface of the + * client having keyboard focus, for example to tie modifier + * information to pointer focus instead. If a modifier event with + * pressed modifiers is sent without a prior enter event, the + * client can assume the modifier state is valid until it receives + * the next wl_keyboard.modifiers event. In order to reset the + * modifier state again, the compositor can send a + * wl_keyboard.modifiers event with no pressed modifiers. + * @param serial serial number of the modifiers event + * @param mods_depressed depressed modifiers + * @param mods_latched latched modifiers + * @param mods_locked locked modifiers + * @param group keyboard layout + */ + void (*modifiers)(void *data, + struct wl_keyboard *wl_keyboard, + uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group); + /** + * repeat rate and delay + * + * Informs the client about the keyboard's repeat rate and delay. + * + * This event is sent as soon as the wl_keyboard object has been + * created, and is guaranteed to be received by the client before + * any key press event. + * + * Negative values for either rate or delay are illegal. A rate of + * zero will disable any repeating (regardless of the value of + * delay). + * + * This event can be sent later on as well with a new value if + * necessary, so clients should continue listening for the event + * past the creation of wl_keyboard. + * @param rate the rate of repeating keys in characters per second + * @param delay delay in milliseconds since key down until repeating starts + * @since 4 + */ + void (*repeat_info)(void *data, + struct wl_keyboard *wl_keyboard, + int32_t rate, + int32_t delay); +}; + +/** + * @ingroup iface_wl_keyboard + */ +static inline int +wl_keyboard_add_listener(struct wl_keyboard *wl_keyboard, + const struct wl_keyboard_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_keyboard, + (void (**)(void)) listener, data); +} + +#define WL_KEYBOARD_RELEASE 0 + +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_KEYMAP_SINCE_VERSION 1 +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_ENTER_SINCE_VERSION 1 +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_LEAVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_KEY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_MODIFIERS_SINCE_VERSION 1 +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION 4 + +/** + * @ingroup iface_wl_keyboard + */ +#define WL_KEYBOARD_RELEASE_SINCE_VERSION 3 + +/** @ingroup iface_wl_keyboard */ +static inline void +wl_keyboard_set_user_data(struct wl_keyboard *wl_keyboard, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_keyboard, user_data); +} + +/** @ingroup iface_wl_keyboard */ +static inline void * +wl_keyboard_get_user_data(struct wl_keyboard *wl_keyboard) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_keyboard); +} + +static inline uint32_t +wl_keyboard_get_version(struct wl_keyboard *wl_keyboard) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_keyboard); +} + +/** @ingroup iface_wl_keyboard */ +static inline void +wl_keyboard_destroy(struct wl_keyboard *wl_keyboard) +{ + wl_proxy_destroy((struct wl_proxy *) wl_keyboard); +} + +/** + * @ingroup iface_wl_keyboard + */ +static inline void +wl_keyboard_release(struct wl_keyboard *wl_keyboard) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_keyboard, + WL_KEYBOARD_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_keyboard), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_touch + * @struct wl_touch_listener + */ +struct wl_touch_listener { + /** + * touch down event and beginning of a touch sequence + * + * A new touch point has appeared on the surface. This touch + * point is assigned a unique ID. Future events from this touch + * point reference this ID. The ID ceases to be valid after a touch + * up event and may be reused in the future. + * @param serial serial number of the touch down event + * @param time timestamp with millisecond granularity + * @param surface surface touched + * @param id the unique ID of this touch point + * @param x surface-local x coordinate + * @param y surface-local y coordinate + */ + void (*down)(void *data, + struct wl_touch *wl_touch, + uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y); + /** + * end of a touch event sequence + * + * The touch point has disappeared. No further events will be + * sent for this touch point and the touch point's ID is released + * and may be reused in a future touch down event. + * @param serial serial number of the touch up event + * @param time timestamp with millisecond granularity + * @param id the unique ID of this touch point + */ + void (*up)(void *data, + struct wl_touch *wl_touch, + uint32_t serial, + uint32_t time, + int32_t id); + /** + * update of touch point coordinates + * + * A touch point has changed coordinates. + * @param time timestamp with millisecond granularity + * @param id the unique ID of this touch point + * @param x surface-local x coordinate + * @param y surface-local y coordinate + */ + void (*motion)(void *data, + struct wl_touch *wl_touch, + uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y); + /** + * end of touch frame event + * + * Indicates the end of a set of events that logically belong + * together. A client is expected to accumulate the data in all + * events within the frame before proceeding. + * + * A wl_touch.frame terminates at least one event but otherwise no + * guarantee is provided about the set of events within a frame. A + * client must assume that any state not updated in a frame is + * unchanged from the previously known state. + */ + void (*frame)(void *data, + struct wl_touch *wl_touch); + /** + * touch session cancelled + * + * Sent if the compositor decides the touch stream is a global + * gesture. No further events are sent to the clients from that + * particular gesture. Touch cancellation applies to all touch + * points currently active on this client's surface. The client is + * responsible for finalizing the touch points, future touch points + * on this surface may reuse the touch point ID. + */ + void (*cancel)(void *data, + struct wl_touch *wl_touch); + /** + * update shape of touch point + * + * Sent when a touchpoint has changed its shape. + * + * This event does not occur on its own. It is sent before a + * wl_touch.frame event and carries the new shape information for + * any previously reported, or new touch points of that frame. + * + * Other events describing the touch point such as wl_touch.down, + * wl_touch.motion or wl_touch.orientation may be sent within the + * same wl_touch.frame. A client should treat these events as a + * single logical touch point update. The order of wl_touch.shape, + * wl_touch.orientation and wl_touch.motion is not guaranteed. A + * wl_touch.down event is guaranteed to occur before the first + * wl_touch.shape event for this touch ID but both events may occur + * within the same wl_touch.frame. + * + * A touchpoint shape is approximated by an ellipse through the + * major and minor axis length. The major axis length describes the + * longer diameter of the ellipse, while the minor axis length + * describes the shorter diameter. Major and minor are orthogonal + * and both are specified in surface-local coordinates. The center + * of the ellipse is always at the touchpoint location as reported + * by wl_touch.down or wl_touch.move. + * + * This event is only sent by the compositor if the touch device + * supports shape reports. The client has to make reasonable + * assumptions about the shape if it did not receive this event. + * @param id the unique ID of this touch point + * @param major length of the major axis in surface-local coordinates + * @param minor length of the minor axis in surface-local coordinates + * @since 6 + */ + void (*shape)(void *data, + struct wl_touch *wl_touch, + int32_t id, + wl_fixed_t major, + wl_fixed_t minor); + /** + * update orientation of touch point + * + * Sent when a touchpoint has changed its orientation. + * + * This event does not occur on its own. It is sent before a + * wl_touch.frame event and carries the new shape information for + * any previously reported, or new touch points of that frame. + * + * Other events describing the touch point such as wl_touch.down, + * wl_touch.motion or wl_touch.shape may be sent within the same + * wl_touch.frame. A client should treat these events as a single + * logical touch point update. The order of wl_touch.shape, + * wl_touch.orientation and wl_touch.motion is not guaranteed. A + * wl_touch.down event is guaranteed to occur before the first + * wl_touch.orientation event for this touch ID but both events may + * occur within the same wl_touch.frame. + * + * The orientation describes the clockwise angle of a touchpoint's + * major axis to the positive surface y-axis and is normalized to + * the -180 to +180 degree range. The granularity of orientation + * depends on the touch device, some devices only support binary + * rotation values between 0 and 90 degrees. + * + * This event is only sent by the compositor if the touch device + * supports orientation reports. + * @param id the unique ID of this touch point + * @param orientation angle between major axis and positive surface y-axis in degrees + * @since 6 + */ + void (*orientation)(void *data, + struct wl_touch *wl_touch, + int32_t id, + wl_fixed_t orientation); +}; + +/** + * @ingroup iface_wl_touch + */ +static inline int +wl_touch_add_listener(struct wl_touch *wl_touch, + const struct wl_touch_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_touch, + (void (**)(void)) listener, data); +} + +#define WL_TOUCH_RELEASE 0 + +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_DOWN_SINCE_VERSION 1 +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_UP_SINCE_VERSION 1 +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_MOTION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_FRAME_SINCE_VERSION 1 +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_CANCEL_SINCE_VERSION 1 +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_SHAPE_SINCE_VERSION 6 +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_ORIENTATION_SINCE_VERSION 6 + +/** + * @ingroup iface_wl_touch + */ +#define WL_TOUCH_RELEASE_SINCE_VERSION 3 + +/** @ingroup iface_wl_touch */ +static inline void +wl_touch_set_user_data(struct wl_touch *wl_touch, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_touch, user_data); +} + +/** @ingroup iface_wl_touch */ +static inline void * +wl_touch_get_user_data(struct wl_touch *wl_touch) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_touch); +} + +static inline uint32_t +wl_touch_get_version(struct wl_touch *wl_touch) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_touch); +} + +/** @ingroup iface_wl_touch */ +static inline void +wl_touch_destroy(struct wl_touch *wl_touch) +{ + wl_proxy_destroy((struct wl_proxy *) wl_touch); +} + +/** + * @ingroup iface_wl_touch + */ +static inline void +wl_touch_release(struct wl_touch *wl_touch) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_touch, + WL_TOUCH_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_touch), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef WL_OUTPUT_SUBPIXEL_ENUM +#define WL_OUTPUT_SUBPIXEL_ENUM +/** + * @ingroup iface_wl_output + * subpixel geometry information + * + * This enumeration describes how the physical + * pixels on an output are laid out. + */ +enum wl_output_subpixel { + /** + * unknown geometry + */ + WL_OUTPUT_SUBPIXEL_UNKNOWN = 0, + /** + * no geometry + */ + WL_OUTPUT_SUBPIXEL_NONE = 1, + /** + * horizontal RGB + */ + WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB = 2, + /** + * horizontal BGR + */ + WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR = 3, + /** + * vertical RGB + */ + WL_OUTPUT_SUBPIXEL_VERTICAL_RGB = 4, + /** + * vertical BGR + */ + WL_OUTPUT_SUBPIXEL_VERTICAL_BGR = 5, +}; +#endif /* WL_OUTPUT_SUBPIXEL_ENUM */ + +#ifndef WL_OUTPUT_TRANSFORM_ENUM +#define WL_OUTPUT_TRANSFORM_ENUM +/** + * @ingroup iface_wl_output + * transform from framebuffer to output + * + * This describes the transform that a compositor will apply to a + * surface to compensate for the rotation or mirroring of an + * output device. + * + * The flipped values correspond to an initial flip around a + * vertical axis followed by rotation. + * + * The purpose is mainly to allow clients to render accordingly and + * tell the compositor, so that for fullscreen surfaces, the + * compositor will still be able to scan out directly from client + * surfaces. + */ +enum wl_output_transform { + /** + * no transform + */ + WL_OUTPUT_TRANSFORM_NORMAL = 0, + /** + * 90 degrees counter-clockwise + */ + WL_OUTPUT_TRANSFORM_90 = 1, + /** + * 180 degrees counter-clockwise + */ + WL_OUTPUT_TRANSFORM_180 = 2, + /** + * 270 degrees counter-clockwise + */ + WL_OUTPUT_TRANSFORM_270 = 3, + /** + * 180 degree flip around a vertical axis + */ + WL_OUTPUT_TRANSFORM_FLIPPED = 4, + /** + * flip and rotate 90 degrees counter-clockwise + */ + WL_OUTPUT_TRANSFORM_FLIPPED_90 = 5, + /** + * flip and rotate 180 degrees counter-clockwise + */ + WL_OUTPUT_TRANSFORM_FLIPPED_180 = 6, + /** + * flip and rotate 270 degrees counter-clockwise + */ + WL_OUTPUT_TRANSFORM_FLIPPED_270 = 7, +}; +#endif /* WL_OUTPUT_TRANSFORM_ENUM */ + +#ifndef WL_OUTPUT_MODE_ENUM +#define WL_OUTPUT_MODE_ENUM +/** + * @ingroup iface_wl_output + * mode information + * + * These flags describe properties of an output mode. + * They are used in the flags bitfield of the mode event. + */ +enum wl_output_mode { + /** + * indicates this is the current mode + */ + WL_OUTPUT_MODE_CURRENT = 0x1, + /** + * indicates this is the preferred mode + */ + WL_OUTPUT_MODE_PREFERRED = 0x2, +}; +#endif /* WL_OUTPUT_MODE_ENUM */ + +/** + * @ingroup iface_wl_output + * @struct wl_output_listener + */ +struct wl_output_listener { + /** + * properties of the output + * + * The geometry event describes geometric properties of the + * output. The event is sent when binding to the output object and + * whenever any of the properties change. + * + * The physical size can be set to zero if it doesn't make sense + * for this output (e.g. for projectors or virtual outputs). + * + * The geometry event will be followed by a done event (starting + * from version 2). + * + * Clients should use wl_surface.preferred_buffer_transform instead + * of the transform advertised by this event to find the preferred + * buffer transform to use for a surface. + * + * Note: wl_output only advertises partial information about the + * output position and identification. Some compositors, for + * instance those not implementing a desktop-style output layout or + * those exposing virtual outputs, might fake this information. + * Instead of using x and y, clients should use + * xdg_output.logical_position. Instead of using make and model, + * clients should use name and description. + * @param x x position within the global compositor space + * @param y y position within the global compositor space + * @param physical_width width in millimeters of the output + * @param physical_height height in millimeters of the output + * @param subpixel subpixel orientation of the output + * @param make textual description of the manufacturer + * @param model textual description of the model + * @param transform transform that maps framebuffer to output + */ + void (*geometry)(void *data, + struct wl_output *wl_output, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char *make, + const char *model, + int32_t transform); + /** + * advertise available modes for the output + * + * The mode event describes an available mode for the output. + * + * The event is sent when binding to the output object and there + * will always be one mode, the current mode. The event is sent + * again if an output changes mode, for the mode that is now + * current. In other words, the current mode is always the last + * mode that was received with the current flag set. + * + * Non-current modes are deprecated. A compositor can decide to + * only advertise the current mode and never send other modes. + * Clients should not rely on non-current modes. + * + * The size of a mode is given in physical hardware units of the + * output device. This is not necessarily the same as the output + * size in the global compositor space. For instance, the output + * may be scaled, as described in wl_output.scale, or transformed, + * as described in wl_output.transform. Clients willing to retrieve + * the output size in the global compositor space should use + * xdg_output.logical_size instead. + * + * The vertical refresh rate can be set to zero if it doesn't make + * sense for this output (e.g. for virtual outputs). + * + * The mode event will be followed by a done event (starting from + * version 2). + * + * Clients should not use the refresh rate to schedule frames. + * Instead, they should use the wl_surface.frame event or the + * presentation-time protocol. + * + * Note: this information is not always meaningful for all outputs. + * Some compositors, such as those exposing virtual outputs, might + * fake the refresh rate or the size. + * @param flags bitfield of mode flags + * @param width width of the mode in hardware units + * @param height height of the mode in hardware units + * @param refresh vertical refresh rate in mHz + */ + void (*mode)(void *data, + struct wl_output *wl_output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh); + /** + * sent all information about output + * + * This event is sent after all other properties have been sent + * after binding to the output object and after any other property + * changes done after that. This allows changes to the output + * properties to be seen as atomic, even if they happen via + * multiple events. + * @since 2 + */ + void (*done)(void *data, + struct wl_output *wl_output); + /** + * output scaling properties + * + * This event contains scaling geometry information that is not + * in the geometry event. It may be sent after binding the output + * object or if the output scale changes later. The compositor will + * emit a non-zero, positive value for scale. If it is not sent, + * the client should assume a scale of 1. + * + * A scale larger than 1 means that the compositor will + * automatically scale surface buffers by this amount when + * rendering. This is used for very high resolution displays where + * applications rendering at the native resolution would be too + * small to be legible. + * + * Clients should use wl_surface.preferred_buffer_scale instead of + * this event to find the preferred buffer scale to use for a + * surface. + * + * The scale event will be followed by a done event. + * @param factor scaling factor of output + * @since 2 + */ + void (*scale)(void *data, + struct wl_output *wl_output, + int32_t factor); + /** + * name of this output + * + * Many compositors will assign user-friendly names to their + * outputs, show them to the user, allow the user to refer to an + * output, etc. The client may wish to know this name as well to + * offer the user similar behaviors. + * + * The name is a UTF-8 string with no convention defined for its + * contents. Each name is unique among all wl_output globals. The + * name is only guaranteed to be unique for the compositor + * instance. + * + * The same output name is used for all clients for a given + * wl_output global. Thus, the name can be shared across processes + * to refer to a specific wl_output global. + * + * The name is not guaranteed to be persistent across sessions, + * thus cannot be used to reliably identify an output in e.g. + * configuration files. + * + * Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. + * However, do not assume that the name is a reflection of an + * underlying DRM connector, X11 connection, etc. + * + * The name event is sent after binding the output object. This + * event is only sent once per output object, and the name does not + * change over the lifetime of the wl_output global. + * + * Compositors may re-use the same output name if the wl_output + * global is destroyed and re-created later. Compositors should + * avoid re-using the same name if possible. + * + * The name event will be followed by a done event. + * @param name output name + * @since 4 + */ + void (*name)(void *data, + struct wl_output *wl_output, + const char *name); + /** + * human-readable description of this output + * + * Many compositors can produce human-readable descriptions of + * their outputs. The client may wish to know this description as + * well, e.g. for output selection purposes. + * + * The description is a UTF-8 string with no convention defined for + * its contents. The description is not guaranteed to be unique + * among all wl_output globals. Examples might include 'Foocorp 11" + * Display' or 'Virtual X11 output via :1'. + * + * The description event is sent after binding the output object + * and whenever the description changes. The description is + * optional, and may not be sent at all. + * + * The description event will be followed by a done event. + * @param description output description + * @since 4 + */ + void (*description)(void *data, + struct wl_output *wl_output, + const char *description); +}; + +/** + * @ingroup iface_wl_output + */ +static inline int +wl_output_add_listener(struct wl_output *wl_output, + const struct wl_output_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_output, + (void (**)(void)) listener, data); +} + +#define WL_OUTPUT_RELEASE 0 + +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_GEOMETRY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_MODE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_DONE_SINCE_VERSION 2 +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_SCALE_SINCE_VERSION 2 +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_NAME_SINCE_VERSION 4 +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_DESCRIPTION_SINCE_VERSION 4 + +/** + * @ingroup iface_wl_output + */ +#define WL_OUTPUT_RELEASE_SINCE_VERSION 3 + +/** @ingroup iface_wl_output */ +static inline void +wl_output_set_user_data(struct wl_output *wl_output, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_output, user_data); +} + +/** @ingroup iface_wl_output */ +static inline void * +wl_output_get_user_data(struct wl_output *wl_output) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_output); +} + +static inline uint32_t +wl_output_get_version(struct wl_output *wl_output) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_output); +} + +/** @ingroup iface_wl_output */ +static inline void +wl_output_destroy(struct wl_output *wl_output) +{ + wl_proxy_destroy((struct wl_proxy *) wl_output); +} + +/** + * @ingroup iface_wl_output + * + * Using this request a client can tell the server that it is not going to + * use the output object anymore. + */ +static inline void +wl_output_release(struct wl_output *wl_output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_output, + WL_OUTPUT_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_output), WL_MARSHAL_FLAG_DESTROY); +} + +#define WL_REGION_DESTROY 0 +#define WL_REGION_ADD 1 +#define WL_REGION_SUBTRACT 2 + + +/** + * @ingroup iface_wl_region + */ +#define WL_REGION_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_region + */ +#define WL_REGION_ADD_SINCE_VERSION 1 +/** + * @ingroup iface_wl_region + */ +#define WL_REGION_SUBTRACT_SINCE_VERSION 1 + +/** @ingroup iface_wl_region */ +static inline void +wl_region_set_user_data(struct wl_region *wl_region, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_region, user_data); +} + +/** @ingroup iface_wl_region */ +static inline void * +wl_region_get_user_data(struct wl_region *wl_region) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_region); +} + +static inline uint32_t +wl_region_get_version(struct wl_region *wl_region) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_region); +} + +/** + * @ingroup iface_wl_region + * + * Destroy the region. This will invalidate the object ID. + */ +static inline void +wl_region_destroy(struct wl_region *wl_region) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_region, + WL_REGION_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_region + * + * Add the specified rectangle to the region. + */ +static inline void +wl_region_add(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_region, + WL_REGION_ADD, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), 0, x, y, width, height); +} + +/** + * @ingroup iface_wl_region + * + * Subtract the specified rectangle from the region. + */ +static inline void +wl_region_subtract(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_region, + WL_REGION_SUBTRACT, NULL, wl_proxy_get_version((struct wl_proxy *) wl_region), 0, x, y, width, height); +} + +#ifndef WL_SUBCOMPOSITOR_ERROR_ENUM +#define WL_SUBCOMPOSITOR_ERROR_ENUM +enum wl_subcompositor_error { + /** + * the to-be sub-surface is invalid + */ + WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE = 0, + /** + * the to-be sub-surface parent is invalid + */ + WL_SUBCOMPOSITOR_ERROR_BAD_PARENT = 1, +}; +#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */ + +#define WL_SUBCOMPOSITOR_DESTROY 0 +#define WL_SUBCOMPOSITOR_GET_SUBSURFACE 1 + + +/** + * @ingroup iface_wl_subcompositor + */ +#define WL_SUBCOMPOSITOR_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_subcompositor + */ +#define WL_SUBCOMPOSITOR_GET_SUBSURFACE_SINCE_VERSION 1 + +/** @ingroup iface_wl_subcompositor */ +static inline void +wl_subcompositor_set_user_data(struct wl_subcompositor *wl_subcompositor, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_subcompositor, user_data); +} + +/** @ingroup iface_wl_subcompositor */ +static inline void * +wl_subcompositor_get_user_data(struct wl_subcompositor *wl_subcompositor) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_subcompositor); +} + +static inline uint32_t +wl_subcompositor_get_version(struct wl_subcompositor *wl_subcompositor) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_subcompositor); +} + +/** + * @ingroup iface_wl_subcompositor + * + * Informs the server that the client will not be using this + * protocol object anymore. This does not affect any other + * objects, wl_subsurface objects included. + */ +static inline void +wl_subcompositor_destroy(struct wl_subcompositor *wl_subcompositor) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subcompositor, + WL_SUBCOMPOSITOR_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subcompositor), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_subcompositor + * + * Create a sub-surface interface for the given surface, and + * associate it with the given parent surface. This turns a + * plain wl_surface into a sub-surface. + * + * The to-be sub-surface must not already have another role, and it + * must not have an existing wl_subsurface object. Otherwise the + * bad_surface protocol error is raised. + * + * Adding sub-surfaces to a parent is a double-buffered operation on the + * parent (see wl_surface.commit). The effect of adding a sub-surface + * becomes visible on the next time the state of the parent surface is + * applied. + * + * The parent surface must not be one of the child surface's descendants, + * and the parent must be different from the child surface, otherwise the + * bad_parent protocol error is raised. + * + * This request modifies the behaviour of wl_surface.commit request on + * the sub-surface, see the documentation on wl_subsurface interface. + */ +static inline struct wl_subsurface * +wl_subcompositor_get_subsurface(struct wl_subcompositor *wl_subcompositor, struct wl_surface *surface, struct wl_surface *parent) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wl_subcompositor, + WL_SUBCOMPOSITOR_GET_SUBSURFACE, &wl_subsurface_interface, wl_proxy_get_version((struct wl_proxy *) wl_subcompositor), 0, NULL, surface, parent); + + return (struct wl_subsurface *) id; +} + +#ifndef WL_SUBSURFACE_ERROR_ENUM +#define WL_SUBSURFACE_ERROR_ENUM +enum wl_subsurface_error { + /** + * wl_surface is not a sibling or the parent + */ + WL_SUBSURFACE_ERROR_BAD_SURFACE = 0, +}; +#endif /* WL_SUBSURFACE_ERROR_ENUM */ + +#define WL_SUBSURFACE_DESTROY 0 +#define WL_SUBSURFACE_SET_POSITION 1 +#define WL_SUBSURFACE_PLACE_ABOVE 2 +#define WL_SUBSURFACE_PLACE_BELOW 3 +#define WL_SUBSURFACE_SET_SYNC 4 +#define WL_SUBSURFACE_SET_DESYNC 5 + + +/** + * @ingroup iface_wl_subsurface + */ +#define WL_SUBSURFACE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wl_subsurface + */ +#define WL_SUBSURFACE_SET_POSITION_SINCE_VERSION 1 +/** + * @ingroup iface_wl_subsurface + */ +#define WL_SUBSURFACE_PLACE_ABOVE_SINCE_VERSION 1 +/** + * @ingroup iface_wl_subsurface + */ +#define WL_SUBSURFACE_PLACE_BELOW_SINCE_VERSION 1 +/** + * @ingroup iface_wl_subsurface + */ +#define WL_SUBSURFACE_SET_SYNC_SINCE_VERSION 1 +/** + * @ingroup iface_wl_subsurface + */ +#define WL_SUBSURFACE_SET_DESYNC_SINCE_VERSION 1 + +/** @ingroup iface_wl_subsurface */ +static inline void +wl_subsurface_set_user_data(struct wl_subsurface *wl_subsurface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_subsurface, user_data); +} + +/** @ingroup iface_wl_subsurface */ +static inline void * +wl_subsurface_get_user_data(struct wl_subsurface *wl_subsurface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_subsurface); +} + +static inline uint32_t +wl_subsurface_get_version(struct wl_subsurface *wl_subsurface) +{ + return wl_proxy_get_version((struct wl_proxy *) wl_subsurface); +} + +/** + * @ingroup iface_wl_subsurface + * + * The sub-surface interface is removed from the wl_surface object + * that was turned into a sub-surface with a + * wl_subcompositor.get_subsurface request. The wl_surface's association + * to the parent is deleted. The wl_surface is unmapped immediately. + */ +static inline void +wl_subsurface_destroy(struct wl_subsurface *wl_subsurface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wl_subsurface + * + * This schedules a sub-surface position change. + * The sub-surface will be moved so that its origin (top left + * corner pixel) will be at the location x, y of the parent surface + * coordinate system. The coordinates are not restricted to the parent + * surface area. Negative values are allowed. + * + * The scheduled coordinates will take effect whenever the state of the + * parent surface is applied. + * + * If more than one set_position request is invoked by the client before + * the commit of the parent surface, the position of a new request always + * replaces the scheduled position from any previous request. + * + * The initial position is 0, 0. + */ +static inline void +wl_subsurface_set_position(struct wl_subsurface *wl_subsurface, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_SET_POSITION, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, x, y); +} + +/** + * @ingroup iface_wl_subsurface + * + * This sub-surface is taken from the stack, and put back just + * above the reference surface, changing the z-order of the sub-surfaces. + * The reference surface must be one of the sibling surfaces, or the + * parent surface. Using any other surface, including this sub-surface, + * will cause a protocol error. + * + * The z-order is double-buffered. Requests are handled in order and + * applied immediately to a pending state. The final pending state is + * copied to the active state the next time the state of the parent + * surface is applied. + * + * A new sub-surface is initially added as the top-most in the stack + * of its siblings and parent. + */ +static inline void +wl_subsurface_place_above(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_PLACE_ABOVE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, sibling); +} + +/** + * @ingroup iface_wl_subsurface + * + * The sub-surface is placed just below the reference surface. + * See wl_subsurface.place_above. + */ +static inline void +wl_subsurface_place_below(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_PLACE_BELOW, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0, sibling); +} + +/** + * @ingroup iface_wl_subsurface + * + * Change the commit behaviour of the sub-surface to synchronized + * mode, also described as the parent dependent mode. + * + * In synchronized mode, wl_surface.commit on a sub-surface will + * accumulate the committed state in a cache, but the state will + * not be applied and hence will not change the compositor output. + * The cached state is applied to the sub-surface immediately after + * the parent surface's state is applied. This ensures atomic + * updates of the parent and all its synchronized sub-surfaces. + * Applying the cached state will invalidate the cache, so further + * parent surface commits do not (re-)apply old state. + * + * See wl_subsurface for the recursive effect of this mode. + */ +static inline void +wl_subsurface_set_sync(struct wl_subsurface *wl_subsurface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_SET_SYNC, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0); +} + +/** + * @ingroup iface_wl_subsurface + * + * Change the commit behaviour of the sub-surface to desynchronized + * mode, also described as independent or freely running mode. + * + * In desynchronized mode, wl_surface.commit on a sub-surface will + * apply the pending state directly, without caching, as happens + * normally with a wl_surface. Calling wl_surface.commit on the + * parent surface has no effect on the sub-surface's wl_surface + * state. This mode allows a sub-surface to be updated on its own. + * + * If cached state exists when wl_surface.commit is called in + * desynchronized mode, the pending state is added to the cached + * state, and applied as a whole. This invalidates the cache. + * + * Note: even if a sub-surface is set to desynchronized, a parent + * sub-surface may override it to behave as synchronized. For details, + * see wl_subsurface. + * + * If a surface's parent surface behaves as desynchronized, then + * the cached state is applied on set_desync. + */ +static inline void +wl_subsurface_set_desync(struct wl_subsurface *wl_subsurface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wl_subsurface, + WL_SUBSURFACE_SET_DESYNC, NULL, wl_proxy_get_version((struct wl_proxy *) wl_subsurface), 0); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/xdg-activation-v1-client-protocol-code.h b/raylib/external/glfw/src/xdg-activation-v1-client-protocol-code.h new file mode 100644 index 0000000..9e6cfc5 --- /dev/null +++ b/raylib/external/glfw/src/xdg-activation-v1-client-protocol-code.h @@ -0,0 +1,84 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2020 Aleix Pol Gonzalez + * Copyright © 2020 Carlos Garnacho + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface xdg_activation_token_v1_interface; + +static const struct wl_interface *xdg_activation_v1_types[] = { + NULL, + &xdg_activation_token_v1_interface, + NULL, + &wl_surface_interface, + NULL, + &wl_seat_interface, + &wl_surface_interface, +}; + +static const struct wl_message xdg_activation_v1_requests[] = { + { "destroy", "", xdg_activation_v1_types + 0 }, + { "get_activation_token", "n", xdg_activation_v1_types + 1 }, + { "activate", "so", xdg_activation_v1_types + 2 }, +}; + +WL_PRIVATE const struct wl_interface xdg_activation_v1_interface = { + "xdg_activation_v1", 1, + 3, xdg_activation_v1_requests, + 0, NULL, +}; + +static const struct wl_message xdg_activation_token_v1_requests[] = { + { "set_serial", "uo", xdg_activation_v1_types + 4 }, + { "set_app_id", "s", xdg_activation_v1_types + 0 }, + { "set_surface", "o", xdg_activation_v1_types + 6 }, + { "commit", "", xdg_activation_v1_types + 0 }, + { "destroy", "", xdg_activation_v1_types + 0 }, +}; + +static const struct wl_message xdg_activation_token_v1_events[] = { + { "done", "s", xdg_activation_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_activation_token_v1_interface = { + "xdg_activation_token_v1", 1, + 5, xdg_activation_token_v1_requests, + 1, xdg_activation_token_v1_events, +}; + diff --git a/raylib/external/glfw/src/xdg-activation-v1-client-protocol.h b/raylib/external/glfw/src/xdg-activation-v1-client-protocol.h new file mode 100644 index 0000000..7e8cd29 --- /dev/null +++ b/raylib/external/glfw/src/xdg-activation-v1-client-protocol.h @@ -0,0 +1,415 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef XDG_ACTIVATION_V1_CLIENT_PROTOCOL_H +#define XDG_ACTIVATION_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_xdg_activation_v1 The xdg_activation_v1 protocol + * Protocol for requesting activation of surfaces + * + * @section page_desc_xdg_activation_v1 Description + * + * The way for a client to pass focus to another toplevel is as follows. + * + * The client that intends to activate another toplevel uses the + * xdg_activation_v1.get_activation_token request to get an activation token. + * This token is then forwarded to the client, which is supposed to activate + * one of its surfaces, through a separate band of communication. + * + * One established way of doing this is through the XDG_ACTIVATION_TOKEN + * environment variable of a newly launched child process. The child process + * should unset the environment variable again right after reading it out in + * order to avoid propagating it to other child processes. + * + * Another established way exists for Applications implementing the D-Bus + * interface org.freedesktop.Application, which should get their token under + * activation-token on their platform_data. + * + * In general activation tokens may be transferred across clients through + * means not described in this protocol. + * + * The client to be activated will then pass the token + * it received to the xdg_activation_v1.activate request. The compositor can + * then use this token to decide how to react to the activation request. + * + * The token the activating client gets may be ineffective either already at + * the time it receives it, for example if it was not focused, for focus + * stealing prevention. The activating client will have no way to discover + * the validity of the token, and may still forward it to the to be activated + * client. + * + * The created activation token may optionally get information attached to it + * that can be used by the compositor to identify the application that we + * intend to activate. This can for example be used to display a visual hint + * about what application is being started. + * + * Warning! The protocol described in this file is currently in the testing + * phase. Backward compatible changes may be added together with the + * corresponding interface version bump. Backward incompatible changes can + * only be done by creating a new major version of the extension. + * + * @section page_ifaces_xdg_activation_v1 Interfaces + * - @subpage page_iface_xdg_activation_v1 - interface for activating surfaces + * - @subpage page_iface_xdg_activation_token_v1 - an exported activation handle + * @section page_copyright_xdg_activation_v1 Copyright + *
+ *
+ * Copyright © 2020 Aleix Pol Gonzalez 
+ * Copyright © 2020 Carlos Garnacho 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_seat; +struct wl_surface; +struct xdg_activation_token_v1; +struct xdg_activation_v1; + +#ifndef XDG_ACTIVATION_V1_INTERFACE +#define XDG_ACTIVATION_V1_INTERFACE +/** + * @page page_iface_xdg_activation_v1 xdg_activation_v1 + * @section page_iface_xdg_activation_v1_desc Description + * + * A global interface used for informing the compositor about applications + * being activated or started, or for applications to request to be + * activated. + * @section page_iface_xdg_activation_v1_api API + * See @ref iface_xdg_activation_v1. + */ +/** + * @defgroup iface_xdg_activation_v1 The xdg_activation_v1 interface + * + * A global interface used for informing the compositor about applications + * being activated or started, or for applications to request to be + * activated. + */ +extern const struct wl_interface xdg_activation_v1_interface; +#endif +#ifndef XDG_ACTIVATION_TOKEN_V1_INTERFACE +#define XDG_ACTIVATION_TOKEN_V1_INTERFACE +/** + * @page page_iface_xdg_activation_token_v1 xdg_activation_token_v1 + * @section page_iface_xdg_activation_token_v1_desc Description + * + * An object for setting up a token and receiving a token handle that can + * be passed as an activation token to another client. + * + * The object is created using the xdg_activation_v1.get_activation_token + * request. This object should then be populated with the app_id, surface + * and serial information and committed. The compositor shall then issue a + * done event with the token. In case the request's parameters are invalid, + * the compositor will provide an invalid token. + * @section page_iface_xdg_activation_token_v1_api API + * See @ref iface_xdg_activation_token_v1. + */ +/** + * @defgroup iface_xdg_activation_token_v1 The xdg_activation_token_v1 interface + * + * An object for setting up a token and receiving a token handle that can + * be passed as an activation token to another client. + * + * The object is created using the xdg_activation_v1.get_activation_token + * request. This object should then be populated with the app_id, surface + * and serial information and committed. The compositor shall then issue a + * done event with the token. In case the request's parameters are invalid, + * the compositor will provide an invalid token. + */ +extern const struct wl_interface xdg_activation_token_v1_interface; +#endif + +#define XDG_ACTIVATION_V1_DESTROY 0 +#define XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN 1 +#define XDG_ACTIVATION_V1_ACTIVATE 2 + + +/** + * @ingroup iface_xdg_activation_v1 + */ +#define XDG_ACTIVATION_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_activation_v1 + */ +#define XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_activation_v1 + */ +#define XDG_ACTIVATION_V1_ACTIVATE_SINCE_VERSION 1 + +/** @ingroup iface_xdg_activation_v1 */ +static inline void +xdg_activation_v1_set_user_data(struct xdg_activation_v1 *xdg_activation_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_activation_v1, user_data); +} + +/** @ingroup iface_xdg_activation_v1 */ +static inline void * +xdg_activation_v1_get_user_data(struct xdg_activation_v1 *xdg_activation_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_activation_v1); +} + +static inline uint32_t +xdg_activation_v1_get_version(struct xdg_activation_v1 *xdg_activation_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1); +} + +/** + * @ingroup iface_xdg_activation_v1 + * + * Notify the compositor that the xdg_activation object will no longer be + * used. + * + * The child objects created via this interface are unaffected and should + * be destroyed separately. + */ +static inline void +xdg_activation_v1_destroy(struct xdg_activation_v1 *xdg_activation_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_v1, + XDG_ACTIVATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_activation_v1 + * + * Creates an xdg_activation_token_v1 object that will provide + * the initiating client with a unique token for this activation. This + * token should be offered to the clients to be activated. + */ +static inline struct xdg_activation_token_v1 * +xdg_activation_v1_get_activation_token(struct xdg_activation_v1 *xdg_activation_v1) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_v1, + XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN, &xdg_activation_token_v1_interface, wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1), 0, NULL); + + return (struct xdg_activation_token_v1 *) id; +} + +/** + * @ingroup iface_xdg_activation_v1 + * + * Requests surface activation. It's up to the compositor to display + * this information as desired, for example by placing the surface above + * the rest. + * + * The compositor may know who requested this by checking the activation + * token and might decide not to follow through with the activation if it's + * considered unwanted. + * + * Compositors can ignore unknown activation tokens when an invalid + * token is passed. + */ +static inline void +xdg_activation_v1_activate(struct xdg_activation_v1 *xdg_activation_v1, const char *token, struct wl_surface *surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_v1, + XDG_ACTIVATION_V1_ACTIVATE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1), 0, token, surface); +} + +#ifndef XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM +#define XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM +enum xdg_activation_token_v1_error { + /** + * The token has already been used previously + */ + XDG_ACTIVATION_TOKEN_V1_ERROR_ALREADY_USED = 0, +}; +#endif /* XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_activation_token_v1 + * @struct xdg_activation_token_v1_listener + */ +struct xdg_activation_token_v1_listener { + /** + * the exported activation token + * + * The 'done' event contains the unique token of this activation + * request and notifies that the provider is done. + * @param token the exported activation token + */ + void (*done)(void *data, + struct xdg_activation_token_v1 *xdg_activation_token_v1, + const char *token); +}; + +/** + * @ingroup iface_xdg_activation_token_v1 + */ +static inline int +xdg_activation_token_v1_add_listener(struct xdg_activation_token_v1 *xdg_activation_token_v1, + const struct xdg_activation_token_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_activation_token_v1, + (void (**)(void)) listener, data); +} + +#define XDG_ACTIVATION_TOKEN_V1_SET_SERIAL 0 +#define XDG_ACTIVATION_TOKEN_V1_SET_APP_ID 1 +#define XDG_ACTIVATION_TOKEN_V1_SET_SURFACE 2 +#define XDG_ACTIVATION_TOKEN_V1_COMMIT 3 +#define XDG_ACTIVATION_TOKEN_V1_DESTROY 4 + +/** + * @ingroup iface_xdg_activation_token_v1 + */ +#define XDG_ACTIVATION_TOKEN_V1_DONE_SINCE_VERSION 1 + +/** + * @ingroup iface_xdg_activation_token_v1 + */ +#define XDG_ACTIVATION_TOKEN_V1_SET_SERIAL_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_activation_token_v1 + */ +#define XDG_ACTIVATION_TOKEN_V1_SET_APP_ID_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_activation_token_v1 + */ +#define XDG_ACTIVATION_TOKEN_V1_SET_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_activation_token_v1 + */ +#define XDG_ACTIVATION_TOKEN_V1_COMMIT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_activation_token_v1 + */ +#define XDG_ACTIVATION_TOKEN_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_xdg_activation_token_v1 */ +static inline void +xdg_activation_token_v1_set_user_data(struct xdg_activation_token_v1 *xdg_activation_token_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_activation_token_v1, user_data); +} + +/** @ingroup iface_xdg_activation_token_v1 */ +static inline void * +xdg_activation_token_v1_get_user_data(struct xdg_activation_token_v1 *xdg_activation_token_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_activation_token_v1); +} + +static inline uint32_t +xdg_activation_token_v1_get_version(struct xdg_activation_token_v1 *xdg_activation_token_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1); +} + +/** + * @ingroup iface_xdg_activation_token_v1 + * + * Provides information about the seat and serial event that requested the + * token. + * + * The serial can come from an input or focus event. For instance, if a + * click triggers the launch of a third-party client, the launcher client + * should send a set_serial request with the serial and seat from the + * wl_pointer.button event. + * + * Some compositors might refuse to activate toplevels when the token + * doesn't have a valid and recent enough event serial. + * + * Must be sent before commit. This information is optional. + */ +static inline void +xdg_activation_token_v1_set_serial(struct xdg_activation_token_v1 *xdg_activation_token_v1, uint32_t serial, struct wl_seat *seat) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1, + XDG_ACTIVATION_TOKEN_V1_SET_SERIAL, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0, serial, seat); +} + +/** + * @ingroup iface_xdg_activation_token_v1 + * + * The requesting client can specify an app_id to associate the token + * being created with it. + * + * Must be sent before commit. This information is optional. + */ +static inline void +xdg_activation_token_v1_set_app_id(struct xdg_activation_token_v1 *xdg_activation_token_v1, const char *app_id) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1, + XDG_ACTIVATION_TOKEN_V1_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0, app_id); +} + +/** + * @ingroup iface_xdg_activation_token_v1 + * + * This request sets the surface requesting the activation. Note, this is + * different from the surface that will be activated. + * + * Some compositors might refuse to activate toplevels when the token + * doesn't have a requesting surface. + * + * Must be sent before commit. This information is optional. + */ +static inline void +xdg_activation_token_v1_set_surface(struct xdg_activation_token_v1 *xdg_activation_token_v1, struct wl_surface *surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1, + XDG_ACTIVATION_TOKEN_V1_SET_SURFACE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0, surface); +} + +/** + * @ingroup iface_xdg_activation_token_v1 + * + * Requests an activation token based on the different parameters that + * have been offered through set_serial, set_surface and set_app_id. + */ +static inline void +xdg_activation_token_v1_commit(struct xdg_activation_token_v1 *xdg_activation_token_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1, + XDG_ACTIVATION_TOKEN_V1_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0); +} + +/** + * @ingroup iface_xdg_activation_token_v1 + * + * Notify the compositor that the xdg_activation_token_v1 object will no + * longer be used. The received token stays valid. + */ +static inline void +xdg_activation_token_v1_destroy(struct xdg_activation_token_v1 *xdg_activation_token_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1, + XDG_ACTIVATION_TOKEN_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol-code.h b/raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol-code.h new file mode 100644 index 0000000..9389145 --- /dev/null +++ b/raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol-code.h @@ -0,0 +1,75 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2018 Simon Ser + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface xdg_toplevel_interface; +extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; + +static const struct wl_interface *xdg_decoration_unstable_v1_types[] = { + NULL, + &zxdg_toplevel_decoration_v1_interface, + &xdg_toplevel_interface, +}; + +static const struct wl_message zxdg_decoration_manager_v1_requests[] = { + { "destroy", "", xdg_decoration_unstable_v1_types + 0 }, + { "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 }, +}; + +WL_PRIVATE const struct wl_interface zxdg_decoration_manager_v1_interface = { + "zxdg_decoration_manager_v1", 1, + 2, zxdg_decoration_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = { + { "destroy", "", xdg_decoration_unstable_v1_types + 0 }, + { "set_mode", "u", xdg_decoration_unstable_v1_types + 0 }, + { "unset_mode", "", xdg_decoration_unstable_v1_types + 0 }, +}; + +static const struct wl_message zxdg_toplevel_decoration_v1_events[] = { + { "configure", "u", xdg_decoration_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zxdg_toplevel_decoration_v1_interface = { + "zxdg_toplevel_decoration_v1", 1, + 3, zxdg_toplevel_decoration_v1_requests, + 1, zxdg_toplevel_decoration_v1_events, +}; + diff --git a/raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol.h b/raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol.h new file mode 100644 index 0000000..308c297 --- /dev/null +++ b/raylib/external/glfw/src/xdg-decoration-unstable-v1-client-protocol.h @@ -0,0 +1,377 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol + * @section page_ifaces_xdg_decoration_unstable_v1 Interfaces + * - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager + * - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface + * @section page_copyright_xdg_decoration_unstable_v1 Copyright + *
+ *
+ * Copyright © 2018 Simon Ser
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct xdg_toplevel; +struct zxdg_decoration_manager_v1; +struct zxdg_toplevel_decoration_v1; + +#ifndef ZXDG_DECORATION_MANAGER_V1_INTERFACE +#define ZXDG_DECORATION_MANAGER_V1_INTERFACE +/** + * @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1 + * @section page_iface_zxdg_decoration_manager_v1_desc Description + * + * This interface allows a compositor to announce support for server-side + * decorations. + * + * A window decoration is a set of window controls as deemed appropriate by + * the party managing them, such as user interface components used to move, + * resize and change a window's state. + * + * A client can use this protocol to request being decorated by a supporting + * compositor. + * + * If compositor and client do not negotiate the use of a server-side + * decoration using this protocol, clients continue to self-decorate as they + * see fit. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + * @section page_iface_zxdg_decoration_manager_v1_api API + * See @ref iface_zxdg_decoration_manager_v1. + */ +/** + * @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface + * + * This interface allows a compositor to announce support for server-side + * decorations. + * + * A window decoration is a set of window controls as deemed appropriate by + * the party managing them, such as user interface components used to move, + * resize and change a window's state. + * + * A client can use this protocol to request being decorated by a supporting + * compositor. + * + * If compositor and client do not negotiate the use of a server-side + * decoration using this protocol, clients continue to self-decorate as they + * see fit. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + */ +extern const struct wl_interface zxdg_decoration_manager_v1_interface; +#endif +#ifndef ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE +#define ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE +/** + * @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1 + * @section page_iface_zxdg_toplevel_decoration_v1_desc Description + * + * The decoration object allows the compositor to toggle server-side window + * decorations for a toplevel surface. The client can request to switch to + * another mode. + * + * The xdg_toplevel_decoration object must be destroyed before its + * xdg_toplevel. + * @section page_iface_zxdg_toplevel_decoration_v1_api API + * See @ref iface_zxdg_toplevel_decoration_v1. + */ +/** + * @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface + * + * The decoration object allows the compositor to toggle server-side window + * decorations for a toplevel surface. The client can request to switch to + * another mode. + * + * The xdg_toplevel_decoration object must be destroyed before its + * xdg_toplevel. + */ +extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; +#endif + +#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0 +#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1 + + +/** + * @ingroup iface_zxdg_decoration_manager_v1 + */ +#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_decoration_manager_v1 + */ +#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1 + +/** @ingroup iface_zxdg_decoration_manager_v1 */ +static inline void +zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data); +} + +/** @ingroup iface_zxdg_decoration_manager_v1 */ +static inline void * +zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1); +} + +static inline uint32_t +zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1); +} + +/** + * @ingroup iface_zxdg_decoration_manager_v1 + * + * Destroy the decoration manager. This doesn't destroy objects created + * with the manager. + */ +static inline void +zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1, + ZXDG_DECORATION_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zxdg_decoration_manager_v1 + * + * Create a new decoration object associated with the given toplevel. + * + * Creating an xdg_toplevel_decoration from an xdg_toplevel which has a + * buffer attached or committed is a client error, and any attempts by a + * client to attach or manipulate a buffer prior to the first + * xdg_toplevel_decoration.configure event must also be treated as + * errors. + */ +static inline struct zxdg_toplevel_decoration_v1 * +zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1, + ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), 0, NULL, toplevel); + + return (struct zxdg_toplevel_decoration_v1 *) id; +} + +#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM +#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM +enum zxdg_toplevel_decoration_v1_error { + /** + * xdg_toplevel has a buffer attached before configure + */ + ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0, + /** + * xdg_toplevel already has a decoration object + */ + ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1, + /** + * xdg_toplevel destroyed before the decoration object + */ + ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2, +}; +#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */ + +#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM +#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + * window decoration modes + * + * These values describe window decoration modes. + */ +enum zxdg_toplevel_decoration_v1_mode { + /** + * no server-side window decoration + */ + ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1, + /** + * server-side window decoration + */ + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2, +}; +#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */ + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + * @struct zxdg_toplevel_decoration_v1_listener + */ +struct zxdg_toplevel_decoration_v1_listener { + /** + * notify a decoration mode change + * + * The configure event configures the effective decoration mode. + * The configured state should not be applied immediately. Clients + * must send an ack_configure in response to this event. See + * xdg_surface.configure and xdg_surface.ack_configure for details. + * + * A configure event can be sent at any time. The specified mode + * must be obeyed by the client. + * @param mode the decoration mode + */ + void (*configure)(void *data, + struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, + uint32_t mode); +}; + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + */ +static inline int +zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, + const struct zxdg_toplevel_decoration_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1, + (void (**)(void)) listener, data); +} + +#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0 +#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1 +#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2 + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + */ +#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1 + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + */ +#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + */ +#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + */ +#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1 + +/** @ingroup iface_zxdg_toplevel_decoration_v1 */ +static inline void +zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data); +} + +/** @ingroup iface_zxdg_toplevel_decoration_v1 */ +static inline void * +zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1); +} + +static inline uint32_t +zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1); +} + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + * + * Switch back to a mode without any server-side decorations at the next + * commit. + */ +static inline void +zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1, + ZXDG_TOPLEVEL_DECORATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + * + * Set the toplevel surface decoration mode. This informs the compositor + * that the client prefers the provided decoration mode. + * + * After requesting a decoration mode, the compositor will respond by + * emitting an xdg_surface.configure event. The client should then update + * its content, drawing it without decorations if the received mode is + * server-side decorations. The client must also acknowledge the configure + * when committing the new content (see xdg_surface.ack_configure). + * + * The compositor can decide not to use the client's mode and enforce a + * different mode instead. + * + * Clients whose decoration mode depend on the xdg_toplevel state may send + * a set_mode request in response to an xdg_surface.configure event and wait + * for the next xdg_surface.configure event to prevent unwanted state. + * Such clients are responsible for preventing configure loops and must + * make sure not to send multiple successive set_mode requests with the + * same decoration mode. + */ +static inline void +zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1, + ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0, mode); +} + +/** + * @ingroup iface_zxdg_toplevel_decoration_v1 + * + * Unset the toplevel surface decoration mode. This informs the compositor + * that the client doesn't prefer a particular decoration mode. + * + * This request has the same semantics as set_mode. + */ +static inline void +zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1, + ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/raylib/external/glfw/src/xdg-shell-client-protocol-code.h b/raylib/external/glfw/src/xdg-shell-client-protocol-code.h new file mode 100644 index 0000000..03826cd --- /dev/null +++ b/raylib/external/glfw/src/xdg-shell-client-protocol-code.h @@ -0,0 +1,183 @@ +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2008-2013 Kristian Høgsberg + * Copyright © 2013 Rafael Antognolli + * Copyright © 2013 Jasper St. Pierre + * Copyright © 2010-2013 Intel Corporation + * Copyright © 2015-2017 Samsung Electronics Co., Ltd + * Copyright © 2015-2017 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface xdg_popup_interface; +extern const struct wl_interface xdg_positioner_interface; +extern const struct wl_interface xdg_surface_interface; +extern const struct wl_interface xdg_toplevel_interface; + +static const struct wl_interface *xdg_shell_types[] = { + NULL, + NULL, + NULL, + NULL, + &xdg_positioner_interface, + &xdg_surface_interface, + &wl_surface_interface, + &xdg_toplevel_interface, + &xdg_popup_interface, + &xdg_surface_interface, + &xdg_positioner_interface, + &xdg_toplevel_interface, + &wl_seat_interface, + NULL, + NULL, + NULL, + &wl_seat_interface, + NULL, + &wl_seat_interface, + NULL, + NULL, + &wl_output_interface, + &wl_seat_interface, + NULL, + &xdg_positioner_interface, + NULL, +}; + +static const struct wl_message xdg_wm_base_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "create_positioner", "n", xdg_shell_types + 4 }, + { "get_xdg_surface", "no", xdg_shell_types + 5 }, + { "pong", "u", xdg_shell_types + 0 }, +}; + +static const struct wl_message xdg_wm_base_events[] = { + { "ping", "u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_wm_base_interface = { + "xdg_wm_base", 6, + 4, xdg_wm_base_requests, + 1, xdg_wm_base_events, +}; + +static const struct wl_message xdg_positioner_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "set_size", "ii", xdg_shell_types + 0 }, + { "set_anchor_rect", "iiii", xdg_shell_types + 0 }, + { "set_anchor", "u", xdg_shell_types + 0 }, + { "set_gravity", "u", xdg_shell_types + 0 }, + { "set_constraint_adjustment", "u", xdg_shell_types + 0 }, + { "set_offset", "ii", xdg_shell_types + 0 }, + { "set_reactive", "3", xdg_shell_types + 0 }, + { "set_parent_size", "3ii", xdg_shell_types + 0 }, + { "set_parent_configure", "3u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_positioner_interface = { + "xdg_positioner", 6, + 10, xdg_positioner_requests, + 0, NULL, +}; + +static const struct wl_message xdg_surface_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "get_toplevel", "n", xdg_shell_types + 7 }, + { "get_popup", "n?oo", xdg_shell_types + 8 }, + { "set_window_geometry", "iiii", xdg_shell_types + 0 }, + { "ack_configure", "u", xdg_shell_types + 0 }, +}; + +static const struct wl_message xdg_surface_events[] = { + { "configure", "u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_surface_interface = { + "xdg_surface", 6, + 5, xdg_surface_requests, + 1, xdg_surface_events, +}; + +static const struct wl_message xdg_toplevel_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "set_parent", "?o", xdg_shell_types + 11 }, + { "set_title", "s", xdg_shell_types + 0 }, + { "set_app_id", "s", xdg_shell_types + 0 }, + { "show_window_menu", "ouii", xdg_shell_types + 12 }, + { "move", "ou", xdg_shell_types + 16 }, + { "resize", "ouu", xdg_shell_types + 18 }, + { "set_max_size", "ii", xdg_shell_types + 0 }, + { "set_min_size", "ii", xdg_shell_types + 0 }, + { "set_maximized", "", xdg_shell_types + 0 }, + { "unset_maximized", "", xdg_shell_types + 0 }, + { "set_fullscreen", "?o", xdg_shell_types + 21 }, + { "unset_fullscreen", "", xdg_shell_types + 0 }, + { "set_minimized", "", xdg_shell_types + 0 }, +}; + +static const struct wl_message xdg_toplevel_events[] = { + { "configure", "iia", xdg_shell_types + 0 }, + { "close", "", xdg_shell_types + 0 }, + { "configure_bounds", "4ii", xdg_shell_types + 0 }, + { "wm_capabilities", "5a", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_toplevel_interface = { + "xdg_toplevel", 6, + 14, xdg_toplevel_requests, + 4, xdg_toplevel_events, +}; + +static const struct wl_message xdg_popup_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "grab", "ou", xdg_shell_types + 22 }, + { "reposition", "3ou", xdg_shell_types + 24 }, +}; + +static const struct wl_message xdg_popup_events[] = { + { "configure", "iiii", xdg_shell_types + 0 }, + { "popup_done", "", xdg_shell_types + 0 }, + { "repositioned", "3u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_popup_interface = { + "xdg_popup", 6, + 3, xdg_popup_requests, + 3, xdg_popup_events, +}; + diff --git a/raylib/external/glfw/src/xdg-shell-client-protocol.h b/raylib/external/glfw/src/xdg-shell-client-protocol.h new file mode 100644 index 0000000..8b24f09 --- /dev/null +++ b/raylib/external/glfw/src/xdg-shell-client-protocol.h @@ -0,0 +1,2315 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef XDG_SHELL_CLIENT_PROTOCOL_H +#define XDG_SHELL_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_xdg_shell The xdg_shell protocol + * @section page_ifaces_xdg_shell Interfaces + * - @subpage page_iface_xdg_wm_base - create desktop-style surfaces + * - @subpage page_iface_xdg_positioner - child surface positioner + * - @subpage page_iface_xdg_surface - desktop user interface surface base interface + * - @subpage page_iface_xdg_toplevel - toplevel surface + * - @subpage page_iface_xdg_popup - short-lived, popup surfaces for menus + * @section page_copyright_xdg_shell Copyright + *
+ *
+ * Copyright © 2008-2013 Kristian Høgsberg
+ * Copyright © 2013      Rafael Antognolli
+ * Copyright © 2013      Jasper St. Pierre
+ * Copyright © 2010-2013 Intel Corporation
+ * Copyright © 2015-2017 Samsung Electronics Co., Ltd
+ * Copyright © 2015-2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_output; +struct wl_seat; +struct wl_surface; +struct xdg_popup; +struct xdg_positioner; +struct xdg_surface; +struct xdg_toplevel; +struct xdg_wm_base; + +#ifndef XDG_WM_BASE_INTERFACE +#define XDG_WM_BASE_INTERFACE +/** + * @page page_iface_xdg_wm_base xdg_wm_base + * @section page_iface_xdg_wm_base_desc Description + * + * The xdg_wm_base interface is exposed as a global object enabling clients + * to turn their wl_surfaces into windows in a desktop environment. It + * defines the basic functionality needed for clients and the compositor to + * create windows that can be dragged, resized, maximized, etc, as well as + * creating transient windows such as popup menus. + * @section page_iface_xdg_wm_base_api API + * See @ref iface_xdg_wm_base. + */ +/** + * @defgroup iface_xdg_wm_base The xdg_wm_base interface + * + * The xdg_wm_base interface is exposed as a global object enabling clients + * to turn their wl_surfaces into windows in a desktop environment. It + * defines the basic functionality needed for clients and the compositor to + * create windows that can be dragged, resized, maximized, etc, as well as + * creating transient windows such as popup menus. + */ +extern const struct wl_interface xdg_wm_base_interface; +#endif +#ifndef XDG_POSITIONER_INTERFACE +#define XDG_POSITIONER_INTERFACE +/** + * @page page_iface_xdg_positioner xdg_positioner + * @section page_iface_xdg_positioner_desc Description + * + * The xdg_positioner provides a collection of rules for the placement of a + * child surface relative to a parent surface. Rules can be defined to ensure + * the child surface remains within the visible area's borders, and to + * specify how the child surface changes its position, such as sliding along + * an axis, or flipping around a rectangle. These positioner-created rules are + * constrained by the requirement that a child surface must intersect with or + * be at least partially adjacent to its parent surface. + * + * See the various requests for details about possible rules. + * + * At the time of the request, the compositor makes a copy of the rules + * specified by the xdg_positioner. Thus, after the request is complete the + * xdg_positioner object can be destroyed or reused; further changes to the + * object will have no effect on previous usages. + * + * For an xdg_positioner object to be considered complete, it must have a + * non-zero size set by set_size, and a non-zero anchor rectangle set by + * set_anchor_rect. Passing an incomplete xdg_positioner object when + * positioning a surface raises an invalid_positioner error. + * @section page_iface_xdg_positioner_api API + * See @ref iface_xdg_positioner. + */ +/** + * @defgroup iface_xdg_positioner The xdg_positioner interface + * + * The xdg_positioner provides a collection of rules for the placement of a + * child surface relative to a parent surface. Rules can be defined to ensure + * the child surface remains within the visible area's borders, and to + * specify how the child surface changes its position, such as sliding along + * an axis, or flipping around a rectangle. These positioner-created rules are + * constrained by the requirement that a child surface must intersect with or + * be at least partially adjacent to its parent surface. + * + * See the various requests for details about possible rules. + * + * At the time of the request, the compositor makes a copy of the rules + * specified by the xdg_positioner. Thus, after the request is complete the + * xdg_positioner object can be destroyed or reused; further changes to the + * object will have no effect on previous usages. + * + * For an xdg_positioner object to be considered complete, it must have a + * non-zero size set by set_size, and a non-zero anchor rectangle set by + * set_anchor_rect. Passing an incomplete xdg_positioner object when + * positioning a surface raises an invalid_positioner error. + */ +extern const struct wl_interface xdg_positioner_interface; +#endif +#ifndef XDG_SURFACE_INTERFACE +#define XDG_SURFACE_INTERFACE +/** + * @page page_iface_xdg_surface xdg_surface + * @section page_iface_xdg_surface_desc Description + * + * An interface that may be implemented by a wl_surface, for + * implementations that provide a desktop-style user interface. + * + * It provides a base set of functionality required to construct user + * interface elements requiring management by the compositor, such as + * toplevel windows, menus, etc. The types of functionality are split into + * xdg_surface roles. + * + * Creating an xdg_surface does not set the role for a wl_surface. In order + * to map an xdg_surface, the client must create a role-specific object + * using, e.g., get_toplevel, get_popup. The wl_surface for any given + * xdg_surface can have at most one role, and may not be assigned any role + * not based on xdg_surface. + * + * A role must be assigned before any other requests are made to the + * xdg_surface object. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_surface state to take effect. + * + * Creating an xdg_surface from a wl_surface which has a buffer attached or + * committed is a client error, and any attempts by a client to attach or + * manipulate a buffer prior to the first xdg_surface.configure call must + * also be treated as errors. + * + * After creating a role-specific object and setting it up, the client must + * perform an initial commit without any buffer attached. The compositor + * will reply with initial wl_surface state such as + * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure + * event. The client must acknowledge it and is then allowed to attach a + * buffer to map the surface. + * + * Mapping an xdg_surface-based role surface is defined as making it + * possible for the surface to be shown by the compositor. Note that + * a mapped surface is not guaranteed to be visible once it is mapped. + * + * For an xdg_surface to be mapped by the compositor, the following + * conditions must be met: + * (1) the client has assigned an xdg_surface-based role to the surface + * (2) the client has set and committed the xdg_surface state and the + * role-dependent state to the surface + * (3) the client has committed a buffer to the surface + * + * A newly-unmapped surface is considered to have met condition (1) out + * of the 3 required conditions for mapping a surface if its role surface + * has not been destroyed, i.e. the client must perform the initial commit + * again before attaching a buffer. + * @section page_iface_xdg_surface_api API + * See @ref iface_xdg_surface. + */ +/** + * @defgroup iface_xdg_surface The xdg_surface interface + * + * An interface that may be implemented by a wl_surface, for + * implementations that provide a desktop-style user interface. + * + * It provides a base set of functionality required to construct user + * interface elements requiring management by the compositor, such as + * toplevel windows, menus, etc. The types of functionality are split into + * xdg_surface roles. + * + * Creating an xdg_surface does not set the role for a wl_surface. In order + * to map an xdg_surface, the client must create a role-specific object + * using, e.g., get_toplevel, get_popup. The wl_surface for any given + * xdg_surface can have at most one role, and may not be assigned any role + * not based on xdg_surface. + * + * A role must be assigned before any other requests are made to the + * xdg_surface object. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_surface state to take effect. + * + * Creating an xdg_surface from a wl_surface which has a buffer attached or + * committed is a client error, and any attempts by a client to attach or + * manipulate a buffer prior to the first xdg_surface.configure call must + * also be treated as errors. + * + * After creating a role-specific object and setting it up, the client must + * perform an initial commit without any buffer attached. The compositor + * will reply with initial wl_surface state such as + * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure + * event. The client must acknowledge it and is then allowed to attach a + * buffer to map the surface. + * + * Mapping an xdg_surface-based role surface is defined as making it + * possible for the surface to be shown by the compositor. Note that + * a mapped surface is not guaranteed to be visible once it is mapped. + * + * For an xdg_surface to be mapped by the compositor, the following + * conditions must be met: + * (1) the client has assigned an xdg_surface-based role to the surface + * (2) the client has set and committed the xdg_surface state and the + * role-dependent state to the surface + * (3) the client has committed a buffer to the surface + * + * A newly-unmapped surface is considered to have met condition (1) out + * of the 3 required conditions for mapping a surface if its role surface + * has not been destroyed, i.e. the client must perform the initial commit + * again before attaching a buffer. + */ +extern const struct wl_interface xdg_surface_interface; +#endif +#ifndef XDG_TOPLEVEL_INTERFACE +#define XDG_TOPLEVEL_INTERFACE +/** + * @page page_iface_xdg_toplevel xdg_toplevel + * @section page_iface_xdg_toplevel_desc Description + * + * This interface defines an xdg_surface role which allows a surface to, + * among other things, set window-like properties such as maximize, + * fullscreen, and minimize, set application-specific metadata like title and + * id, and well as trigger user interactive operations such as interactive + * resize and move. + * + * A xdg_toplevel by default is responsible for providing the full intended + * visual representation of the toplevel, which depending on the window + * state, may mean things like a title bar, window controls and drop shadow. + * + * Unmapping an xdg_toplevel means that the surface cannot be shown + * by the compositor until it is explicitly mapped again. + * All active operations (e.g., move, resize) are canceled and all + * attributes (e.g. title, state, stacking, ...) are discarded for + * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to + * the state it had right after xdg_surface.get_toplevel. The client + * can re-map the toplevel by perfoming a commit without any buffer + * attached, waiting for a configure event and handling it as usual (see + * xdg_surface description). + * + * Attaching a null buffer to a toplevel unmaps the surface. + * @section page_iface_xdg_toplevel_api API + * See @ref iface_xdg_toplevel. + */ +/** + * @defgroup iface_xdg_toplevel The xdg_toplevel interface + * + * This interface defines an xdg_surface role which allows a surface to, + * among other things, set window-like properties such as maximize, + * fullscreen, and minimize, set application-specific metadata like title and + * id, and well as trigger user interactive operations such as interactive + * resize and move. + * + * A xdg_toplevel by default is responsible for providing the full intended + * visual representation of the toplevel, which depending on the window + * state, may mean things like a title bar, window controls and drop shadow. + * + * Unmapping an xdg_toplevel means that the surface cannot be shown + * by the compositor until it is explicitly mapped again. + * All active operations (e.g., move, resize) are canceled and all + * attributes (e.g. title, state, stacking, ...) are discarded for + * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to + * the state it had right after xdg_surface.get_toplevel. The client + * can re-map the toplevel by perfoming a commit without any buffer + * attached, waiting for a configure event and handling it as usual (see + * xdg_surface description). + * + * Attaching a null buffer to a toplevel unmaps the surface. + */ +extern const struct wl_interface xdg_toplevel_interface; +#endif +#ifndef XDG_POPUP_INTERFACE +#define XDG_POPUP_INTERFACE +/** + * @page page_iface_xdg_popup xdg_popup + * @section page_iface_xdg_popup_desc Description + * + * A popup surface is a short-lived, temporary surface. It can be used to + * implement for example menus, popovers, tooltips and other similar user + * interface concepts. + * + * A popup can be made to take an explicit grab. See xdg_popup.grab for + * details. + * + * When the popup is dismissed, a popup_done event will be sent out, and at + * the same time the surface will be unmapped. See the xdg_popup.popup_done + * event for details. + * + * Explicitly destroying the xdg_popup object will also dismiss the popup and + * unmap the surface. Clients that want to dismiss the popup when another + * surface of their own is clicked should dismiss the popup using the destroy + * request. + * + * A newly created xdg_popup will be stacked on top of all previously created + * xdg_popup surfaces associated with the same xdg_toplevel. + * + * The parent of an xdg_popup must be mapped (see the xdg_surface + * description) before the xdg_popup itself. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_popup state to take effect. + * @section page_iface_xdg_popup_api API + * See @ref iface_xdg_popup. + */ +/** + * @defgroup iface_xdg_popup The xdg_popup interface + * + * A popup surface is a short-lived, temporary surface. It can be used to + * implement for example menus, popovers, tooltips and other similar user + * interface concepts. + * + * A popup can be made to take an explicit grab. See xdg_popup.grab for + * details. + * + * When the popup is dismissed, a popup_done event will be sent out, and at + * the same time the surface will be unmapped. See the xdg_popup.popup_done + * event for details. + * + * Explicitly destroying the xdg_popup object will also dismiss the popup and + * unmap the surface. Clients that want to dismiss the popup when another + * surface of their own is clicked should dismiss the popup using the destroy + * request. + * + * A newly created xdg_popup will be stacked on top of all previously created + * xdg_popup surfaces associated with the same xdg_toplevel. + * + * The parent of an xdg_popup must be mapped (see the xdg_surface + * description) before the xdg_popup itself. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_popup state to take effect. + */ +extern const struct wl_interface xdg_popup_interface; +#endif + +#ifndef XDG_WM_BASE_ERROR_ENUM +#define XDG_WM_BASE_ERROR_ENUM +enum xdg_wm_base_error { + /** + * given wl_surface has another role + */ + XDG_WM_BASE_ERROR_ROLE = 0, + /** + * xdg_wm_base was destroyed before children + */ + XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1, + /** + * the client tried to map or destroy a non-topmost popup + */ + XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2, + /** + * the client specified an invalid popup parent surface + */ + XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3, + /** + * the client provided an invalid surface state + */ + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4, + /** + * the client provided an invalid positioner + */ + XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5, + /** + * the client didn’t respond to a ping event in time + */ + XDG_WM_BASE_ERROR_UNRESPONSIVE = 6, +}; +#endif /* XDG_WM_BASE_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_wm_base + * @struct xdg_wm_base_listener + */ +struct xdg_wm_base_listener { + /** + * check if the client is alive + * + * The ping event asks the client if it's still alive. Pass the + * serial specified in the event back to the compositor by sending + * a "pong" request back with the specified serial. See + * xdg_wm_base.pong. + * + * Compositors can use this to determine if the client is still + * alive. It's unspecified what will happen if the client doesn't + * respond to the ping request, or in what timeframe. Clients + * should try to respond in a reasonable amount of time. The + * “unresponsive” error is provided for compositors that wish + * to disconnect unresponsive clients. + * + * A compositor is free to ping in any way it wants, but a client + * must always respond to any xdg_wm_base object it created. + * @param serial pass this to the pong request + */ + void (*ping)(void *data, + struct xdg_wm_base *xdg_wm_base, + uint32_t serial); +}; + +/** + * @ingroup iface_xdg_wm_base + */ +static inline int +xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base, + const struct xdg_wm_base_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_wm_base, + (void (**)(void)) listener, data); +} + +#define XDG_WM_BASE_DESTROY 0 +#define XDG_WM_BASE_CREATE_POSITIONER 1 +#define XDG_WM_BASE_GET_XDG_SURFACE 2 +#define XDG_WM_BASE_PONG 3 + +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_PING_SINCE_VERSION 1 + +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_CREATE_POSITIONER_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_GET_XDG_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_PONG_SINCE_VERSION 1 + +/** @ingroup iface_xdg_wm_base */ +static inline void +xdg_wm_base_set_user_data(struct xdg_wm_base *xdg_wm_base, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_wm_base, user_data); +} + +/** @ingroup iface_xdg_wm_base */ +static inline void * +xdg_wm_base_get_user_data(struct xdg_wm_base *xdg_wm_base) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_wm_base); +} + +static inline uint32_t +xdg_wm_base_get_version(struct xdg_wm_base *xdg_wm_base) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_wm_base); +} + +/** + * @ingroup iface_xdg_wm_base + * + * Destroy this xdg_wm_base object. + * + * Destroying a bound xdg_wm_base object while there are surfaces + * still alive created by this xdg_wm_base object instance is illegal + * and will result in a defunct_surfaces error. + */ +static inline void +xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_wm_base + * + * Create a positioner object. A positioner object is used to position + * surfaces relative to some parent surface. See the interface description + * and xdg_surface.get_popup for details. + */ +static inline struct xdg_positioner * +xdg_wm_base_create_positioner(struct xdg_wm_base *xdg_wm_base) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_CREATE_POSITIONER, &xdg_positioner_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL); + + return (struct xdg_positioner *) id; +} + +/** + * @ingroup iface_xdg_wm_base + * + * This creates an xdg_surface for the given surface. While xdg_surface + * itself is not a role, the corresponding surface may only be assigned + * a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is + * illegal to create an xdg_surface for a wl_surface which already has an + * assigned role and this will result in a role error. + * + * This creates an xdg_surface for the given surface. An xdg_surface is + * used as basis to define a role to a given surface, such as xdg_toplevel + * or xdg_popup. It also manages functionality shared between xdg_surface + * based surface roles. + * + * See the documentation of xdg_surface for more details about what an + * xdg_surface is and how it is used. + */ +static inline struct xdg_surface * +xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_GET_XDG_SURFACE, &xdg_surface_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL, surface); + + return (struct xdg_surface *) id; +} + +/** + * @ingroup iface_xdg_wm_base + * + * A client must respond to a ping event with a pong request or + * the client may be deemed unresponsive. See xdg_wm_base.ping + * and xdg_wm_base.error.unresponsive. + */ +static inline void +xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, serial); +} + +#ifndef XDG_POSITIONER_ERROR_ENUM +#define XDG_POSITIONER_ERROR_ENUM +enum xdg_positioner_error { + /** + * invalid input provided + */ + XDG_POSITIONER_ERROR_INVALID_INPUT = 0, +}; +#endif /* XDG_POSITIONER_ERROR_ENUM */ + +#ifndef XDG_POSITIONER_ANCHOR_ENUM +#define XDG_POSITIONER_ANCHOR_ENUM +enum xdg_positioner_anchor { + XDG_POSITIONER_ANCHOR_NONE = 0, + XDG_POSITIONER_ANCHOR_TOP = 1, + XDG_POSITIONER_ANCHOR_BOTTOM = 2, + XDG_POSITIONER_ANCHOR_LEFT = 3, + XDG_POSITIONER_ANCHOR_RIGHT = 4, + XDG_POSITIONER_ANCHOR_TOP_LEFT = 5, + XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6, + XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7, + XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8, +}; +#endif /* XDG_POSITIONER_ANCHOR_ENUM */ + +#ifndef XDG_POSITIONER_GRAVITY_ENUM +#define XDG_POSITIONER_GRAVITY_ENUM +enum xdg_positioner_gravity { + XDG_POSITIONER_GRAVITY_NONE = 0, + XDG_POSITIONER_GRAVITY_TOP = 1, + XDG_POSITIONER_GRAVITY_BOTTOM = 2, + XDG_POSITIONER_GRAVITY_LEFT = 3, + XDG_POSITIONER_GRAVITY_RIGHT = 4, + XDG_POSITIONER_GRAVITY_TOP_LEFT = 5, + XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6, + XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7, + XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8, +}; +#endif /* XDG_POSITIONER_GRAVITY_ENUM */ + +#ifndef XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM +#define XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM +/** + * @ingroup iface_xdg_positioner + * constraint adjustments + * + * The constraint adjustment value define ways the compositor will adjust + * the position of the surface, if the unadjusted position would result + * in the surface being partly constrained. + * + * Whether a surface is considered 'constrained' is left to the compositor + * to determine. For example, the surface may be partly outside the + * compositor's defined 'work area', thus necessitating the child surface's + * position be adjusted until it is entirely inside the work area. + * + * The adjustments can be combined, according to a defined precedence: 1) + * Flip, 2) Slide, 3) Resize. + */ +enum xdg_positioner_constraint_adjustment { + /** + * don't move the child surface when constrained + * + * Don't alter the surface position even if it is constrained on + * some axis, for example partially outside the edge of an output. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0, + /** + * move along the x axis until unconstrained + * + * Slide the surface along the x axis until it is no longer + * constrained. + * + * First try to slide towards the direction of the gravity on the x + * axis until either the edge in the opposite direction of the + * gravity is unconstrained or the edge in the direction of the + * gravity is constrained. + * + * Then try to slide towards the opposite direction of the gravity + * on the x axis until either the edge in the direction of the + * gravity is unconstrained or the edge in the opposite direction + * of the gravity is constrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1, + /** + * move along the y axis until unconstrained + * + * Slide the surface along the y axis until it is no longer + * constrained. + * + * First try to slide towards the direction of the gravity on the y + * axis until either the edge in the opposite direction of the + * gravity is unconstrained or the edge in the direction of the + * gravity is constrained. + * + * Then try to slide towards the opposite direction of the gravity + * on the y axis until either the edge in the direction of the + * gravity is unconstrained or the edge in the opposite direction + * of the gravity is constrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2, + /** + * invert the anchor and gravity on the x axis + * + * Invert the anchor and gravity on the x axis if the surface is + * constrained on the x axis. For example, if the left edge of the + * surface is constrained, the gravity is 'left' and the anchor is + * 'left', change the gravity to 'right' and the anchor to 'right'. + * + * If the adjusted position also ends up being constrained, the + * resulting position of the flip_x adjustment will be the one + * before the adjustment. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4, + /** + * invert the anchor and gravity on the y axis + * + * Invert the anchor and gravity on the y axis if the surface is + * constrained on the y axis. For example, if the bottom edge of + * the surface is constrained, the gravity is 'bottom' and the + * anchor is 'bottom', change the gravity to 'top' and the anchor + * to 'top'. + * + * The adjusted position is calculated given the original anchor + * rectangle and offset, but with the new flipped anchor and + * gravity values. + * + * If the adjusted position also ends up being constrained, the + * resulting position of the flip_y adjustment will be the one + * before the adjustment. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8, + /** + * horizontally resize the surface + * + * Resize the surface horizontally so that it is completely + * unconstrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16, + /** + * vertically resize the surface + * + * Resize the surface vertically so that it is completely + * unconstrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, +}; +#endif /* XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM */ + +#define XDG_POSITIONER_DESTROY 0 +#define XDG_POSITIONER_SET_SIZE 1 +#define XDG_POSITIONER_SET_ANCHOR_RECT 2 +#define XDG_POSITIONER_SET_ANCHOR 3 +#define XDG_POSITIONER_SET_GRAVITY 4 +#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT 5 +#define XDG_POSITIONER_SET_OFFSET 6 +#define XDG_POSITIONER_SET_REACTIVE 7 +#define XDG_POSITIONER_SET_PARENT_SIZE 8 +#define XDG_POSITIONER_SET_PARENT_CONFIGURE 9 + + +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_ANCHOR_RECT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_ANCHOR_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_GRAVITY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_OFFSET_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_REACTIVE_SINCE_VERSION 3 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_PARENT_SIZE_SINCE_VERSION 3 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION 3 + +/** @ingroup iface_xdg_positioner */ +static inline void +xdg_positioner_set_user_data(struct xdg_positioner *xdg_positioner, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_positioner, user_data); +} + +/** @ingroup iface_xdg_positioner */ +static inline void * +xdg_positioner_get_user_data(struct xdg_positioner *xdg_positioner) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_positioner); +} + +static inline uint32_t +xdg_positioner_get_version(struct xdg_positioner *xdg_positioner) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_positioner); +} + +/** + * @ingroup iface_xdg_positioner + * + * Notify the compositor that the xdg_positioner will no longer be used. + */ +static inline void +xdg_positioner_destroy(struct xdg_positioner *xdg_positioner) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_positioner + * + * Set the size of the surface that is to be positioned with the positioner + * object. The size is in surface-local coordinates and corresponds to the + * window geometry. See xdg_surface.set_window_geometry. + * + * If a zero or negative size is set the invalid_input error is raised. + */ +static inline void +xdg_positioner_set_size(struct xdg_positioner *xdg_positioner, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, width, height); +} + +/** + * @ingroup iface_xdg_positioner + * + * Specify the anchor rectangle within the parent surface that the child + * surface will be placed relative to. The rectangle is relative to the + * window geometry as defined by xdg_surface.set_window_geometry of the + * parent surface. + * + * When the xdg_positioner object is used to position a child surface, the + * anchor rectangle may not extend outside the window geometry of the + * positioned child's parent surface. + * + * If a negative size is set the invalid_input error is raised. + */ +static inline void +xdg_positioner_set_anchor_rect(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_ANCHOR_RECT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y, width, height); +} + +/** + * @ingroup iface_xdg_positioner + * + * Defines the anchor point for the anchor rectangle. The specified anchor + * is used derive an anchor point that the child surface will be + * positioned relative to. If a corner anchor is set (e.g. 'top_left' or + * 'bottom_right'), the anchor point will be at the specified corner; + * otherwise, the derived anchor point will be centered on the specified + * edge, or in the center of the anchor rectangle if no edge is specified. + */ +static inline void +xdg_positioner_set_anchor(struct xdg_positioner *xdg_positioner, uint32_t anchor) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, anchor); +} + +/** + * @ingroup iface_xdg_positioner + * + * Defines in what direction a surface should be positioned, relative to + * the anchor point of the parent surface. If a corner gravity is + * specified (e.g. 'bottom_right' or 'top_left'), then the child surface + * will be placed towards the specified gravity; otherwise, the child + * surface will be centered over the anchor point on any axis that had no + * gravity specified. If the gravity is not in the ‘gravity’ enum, an + * invalid_input error is raised. + */ +static inline void +xdg_positioner_set_gravity(struct xdg_positioner *xdg_positioner, uint32_t gravity) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_GRAVITY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, gravity); +} + +/** + * @ingroup iface_xdg_positioner + * + * Specify how the window should be positioned if the originally intended + * position caused the surface to be constrained, meaning at least + * partially outside positioning boundaries set by the compositor. The + * adjustment is set by constructing a bitmask describing the adjustment to + * be made when the surface is constrained on that axis. + * + * If no bit for one axis is set, the compositor will assume that the child + * surface should not change its position on that axis when constrained. + * + * If more than one bit for one axis is set, the order of how adjustments + * are applied is specified in the corresponding adjustment descriptions. + * + * The default adjustment is none. + */ +static inline void +xdg_positioner_set_constraint_adjustment(struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, constraint_adjustment); +} + +/** + * @ingroup iface_xdg_positioner + * + * Specify the surface position offset relative to the position of the + * anchor on the anchor rectangle and the anchor on the surface. For + * example if the anchor of the anchor rectangle is at (x, y), the surface + * has the gravity bottom|right, and the offset is (ox, oy), the calculated + * surface position will be (x + ox, y + oy). The offset position of the + * surface is the one used for constraint testing. See + * set_constraint_adjustment. + * + * An example use case is placing a popup menu on top of a user interface + * element, while aligning the user interface element of the parent surface + * with some user interface element placed somewhere in the popup surface. + */ +static inline void +xdg_positioner_set_offset(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y); +} + +/** + * @ingroup iface_xdg_positioner + * + * When set reactive, the surface is reconstrained if the conditions used + * for constraining changed, e.g. the parent window moved. + * + * If the conditions changed and the popup was reconstrained, an + * xdg_popup.configure event is sent with updated geometry, followed by an + * xdg_surface.configure event. + */ +static inline void +xdg_positioner_set_reactive(struct xdg_positioner *xdg_positioner) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_REACTIVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0); +} + +/** + * @ingroup iface_xdg_positioner + * + * Set the parent window geometry the compositor should use when + * positioning the popup. The compositor may use this information to + * determine the future state the popup should be constrained using. If + * this doesn't match the dimension of the parent the popup is eventually + * positioned against, the behavior is undefined. + * + * The arguments are given in the surface-local coordinate space. + */ +static inline void +xdg_positioner_set_parent_size(struct xdg_positioner *xdg_positioner, int32_t parent_width, int32_t parent_height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_PARENT_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, parent_width, parent_height); +} + +/** + * @ingroup iface_xdg_positioner + * + * Set the serial of an xdg_surface.configure event this positioner will be + * used in response to. The compositor may use this information together + * with set_parent_size to determine what future state the popup should be + * constrained using. + */ +static inline void +xdg_positioner_set_parent_configure(struct xdg_positioner *xdg_positioner, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_PARENT_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, serial); +} + +#ifndef XDG_SURFACE_ERROR_ENUM +#define XDG_SURFACE_ERROR_ENUM +enum xdg_surface_error { + /** + * Surface was not fully constructed + */ + XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1, + /** + * Surface was already constructed + */ + XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2, + /** + * Attaching a buffer to an unconfigured surface + */ + XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3, + /** + * Invalid serial number when acking a configure event + */ + XDG_SURFACE_ERROR_INVALID_SERIAL = 4, + /** + * Width or height was zero or negative + */ + XDG_SURFACE_ERROR_INVALID_SIZE = 5, + /** + * Surface was destroyed before its role object + */ + XDG_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 6, +}; +#endif /* XDG_SURFACE_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_surface + * @struct xdg_surface_listener + */ +struct xdg_surface_listener { + /** + * suggest a surface change + * + * The configure event marks the end of a configure sequence. A + * configure sequence is a set of one or more events configuring + * the state of the xdg_surface, including the final + * xdg_surface.configure event. + * + * Where applicable, xdg_surface surface roles will during a + * configure sequence extend this event as a latched state sent as + * events before the xdg_surface.configure event. Such events + * should be considered to make up a set of atomically applied + * configuration states, where the xdg_surface.configure commits + * the accumulated state. + * + * Clients should arrange their surface for the new states, and + * then send an ack_configure request with the serial sent in this + * configure event at some point before committing the new surface. + * + * If the client receives multiple configure events before it can + * respond to one, it is free to discard all but the last event it + * received. + * @param serial serial of the configure event + */ + void (*configure)(void *data, + struct xdg_surface *xdg_surface, + uint32_t serial); +}; + +/** + * @ingroup iface_xdg_surface + */ +static inline int +xdg_surface_add_listener(struct xdg_surface *xdg_surface, + const struct xdg_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_surface, + (void (**)(void)) listener, data); +} + +#define XDG_SURFACE_DESTROY 0 +#define XDG_SURFACE_GET_TOPLEVEL 1 +#define XDG_SURFACE_GET_POPUP 2 +#define XDG_SURFACE_SET_WINDOW_GEOMETRY 3 +#define XDG_SURFACE_ACK_CONFIGURE 4 + +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_CONFIGURE_SINCE_VERSION 1 + +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_GET_TOPLEVEL_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_GET_POPUP_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_SET_WINDOW_GEOMETRY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_ACK_CONFIGURE_SINCE_VERSION 1 + +/** @ingroup iface_xdg_surface */ +static inline void +xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data); +} + +/** @ingroup iface_xdg_surface */ +static inline void * +xdg_surface_get_user_data(struct xdg_surface *xdg_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface); +} + +static inline uint32_t +xdg_surface_get_version(struct xdg_surface *xdg_surface) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_surface); +} + +/** + * @ingroup iface_xdg_surface + * + * Destroy the xdg_surface object. An xdg_surface must only be destroyed + * after its role object has been destroyed, otherwise + * a defunct_role_object error is raised. + */ +static inline void +xdg_surface_destroy(struct xdg_surface *xdg_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_surface + * + * This creates an xdg_toplevel object for the given xdg_surface and gives + * the associated wl_surface the xdg_toplevel role. + * + * See the documentation of xdg_toplevel for more details about what an + * xdg_toplevel is and how it is used. + */ +static inline struct xdg_toplevel * +xdg_surface_get_toplevel(struct xdg_surface *xdg_surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_GET_TOPLEVEL, &xdg_toplevel_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL); + + return (struct xdg_toplevel *) id; +} + +/** + * @ingroup iface_xdg_surface + * + * This creates an xdg_popup object for the given xdg_surface and gives + * the associated wl_surface the xdg_popup role. + * + * If null is passed as a parent, a parent surface must be specified using + * some other protocol, before committing the initial state. + * + * See the documentation of xdg_popup for more details about what an + * xdg_popup is and how it is used. + */ +static inline struct xdg_popup * +xdg_surface_get_popup(struct xdg_surface *xdg_surface, struct xdg_surface *parent, struct xdg_positioner *positioner) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_GET_POPUP, &xdg_popup_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL, parent, positioner); + + return (struct xdg_popup *) id; +} + +/** + * @ingroup iface_xdg_surface + * + * The window geometry of a surface is its "visible bounds" from the + * user's perspective. Client-side decorations often have invisible + * portions like drop-shadows which should be ignored for the + * purposes of aligning, placing and constraining windows. + * + * The window geometry is double buffered, and will be applied at the + * time wl_surface.commit of the corresponding wl_surface is called. + * + * When maintaining a position, the compositor should treat the (x, y) + * coordinate of the window geometry as the top left corner of the window. + * A client changing the (x, y) window geometry coordinate should in + * general not alter the position of the window. + * + * Once the window geometry of the surface is set, it is not possible to + * unset it, and it will remain the same until set_window_geometry is + * called again, even if a new subsurface or buffer is attached. + * + * If never set, the value is the full bounds of the surface, + * including any subsurfaces. This updates dynamically on every + * commit. This unset is meant for extremely simple clients. + * + * The arguments are given in the surface-local coordinate space of + * the wl_surface associated with this xdg_surface, and may extend outside + * of the wl_surface itself to mark parts of the subsurface tree as part of + * the window geometry. + * + * When applied, the effective window geometry will be the set window + * geometry clamped to the bounding rectangle of the combined + * geometry of the surface of the xdg_surface and the associated + * subsurfaces. + * + * The effective geometry will not be recalculated unless a new call to + * set_window_geometry is done and the new pending surface state is + * subsequently applied. + * + * The width and height of the effective window geometry must be + * greater than zero. Setting an invalid size will raise an + * invalid_size error. + */ +static inline void +xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_SET_WINDOW_GEOMETRY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, x, y, width, height); +} + +/** + * @ingroup iface_xdg_surface + * + * When a configure event is received, if a client commits the + * surface in response to the configure event, then the client + * must make an ack_configure request sometime before the commit + * request, passing along the serial of the configure event. + * + * For instance, for toplevel surfaces the compositor might use this + * information to move a surface to the top left only when the client has + * drawn itself for the maximized or fullscreen state. + * + * If the client receives multiple configure events before it + * can respond to one, it only has to ack the last configure event. + * Acking a configure event that was never sent raises an invalid_serial + * error. + * + * A client is not required to commit immediately after sending + * an ack_configure request - it may even ack_configure several times + * before its next surface commit. + * + * A client may send multiple ack_configure requests before committing, but + * only the last request sent before a commit indicates which configure + * event the client really is responding to. + * + * Sending an ack_configure request consumes the serial number sent with + * the request, as well as serial numbers sent by all configure events + * sent on this xdg_surface prior to the configure event referenced by + * the committed serial. + * + * It is an error to issue multiple ack_configure requests referencing a + * serial from the same configure event, or to issue an ack_configure + * request referencing a serial from a configure event issued before the + * event identified by the last ack_configure request for the same + * xdg_surface. Doing so will raise an invalid_serial error. + */ +static inline void +xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, serial); +} + +#ifndef XDG_TOPLEVEL_ERROR_ENUM +#define XDG_TOPLEVEL_ERROR_ENUM +enum xdg_toplevel_error { + /** + * provided value is not a valid variant of the resize_edge enum + */ + XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0, + /** + * invalid parent toplevel + */ + XDG_TOPLEVEL_ERROR_INVALID_PARENT = 1, + /** + * client provided an invalid min or max size + */ + XDG_TOPLEVEL_ERROR_INVALID_SIZE = 2, +}; +#endif /* XDG_TOPLEVEL_ERROR_ENUM */ + +#ifndef XDG_TOPLEVEL_RESIZE_EDGE_ENUM +#define XDG_TOPLEVEL_RESIZE_EDGE_ENUM +/** + * @ingroup iface_xdg_toplevel + * edge values for resizing + * + * These values are used to indicate which edge of a surface + * is being dragged in a resize operation. + */ +enum xdg_toplevel_resize_edge { + XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0, + XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2, + XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4, + XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6, + XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8, + XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10, +}; +#endif /* XDG_TOPLEVEL_RESIZE_EDGE_ENUM */ + +#ifndef XDG_TOPLEVEL_STATE_ENUM +#define XDG_TOPLEVEL_STATE_ENUM +/** + * @ingroup iface_xdg_toplevel + * types of state on the surface + * + * The different state values used on the surface. This is designed for + * state values like maximized, fullscreen. It is paired with the + * configure event to ensure that both the client and the compositor + * setting the state can be synchronized. + * + * States set in this way are double-buffered. They will get applied on + * the next commit. + */ +enum xdg_toplevel_state { + /** + * the surface is maximized + * the surface is maximized + * + * The surface is maximized. The window geometry specified in the + * configure event must be obeyed by the client, or the + * xdg_wm_base.invalid_surface_state error is raised. + * + * The client should draw without shadow or other decoration + * outside of the window geometry. + */ + XDG_TOPLEVEL_STATE_MAXIMIZED = 1, + /** + * the surface is fullscreen + * the surface is fullscreen + * + * The surface is fullscreen. The window geometry specified in + * the configure event is a maximum; the client cannot resize + * beyond it. For a surface to cover the whole fullscreened area, + * the geometry dimensions must be obeyed by the client. For more + * details, see xdg_toplevel.set_fullscreen. + */ + XDG_TOPLEVEL_STATE_FULLSCREEN = 2, + /** + * the surface is being resized + * the surface is being resized + * + * The surface is being resized. The window geometry specified in + * the configure event is a maximum; the client cannot resize + * beyond it. Clients that have aspect ratio or cell sizing + * configuration can use a smaller size, however. + */ + XDG_TOPLEVEL_STATE_RESIZING = 3, + /** + * the surface is now activated + * the surface is now activated + * + * Client window decorations should be painted as if the window + * is active. Do not assume this means that the window actually has + * keyboard or pointer focus. + */ + XDG_TOPLEVEL_STATE_ACTIVATED = 4, + /** + * the surface’s left edge is tiled + * + * The window is currently in a tiled layout and the left edge is + * considered to be adjacent to another part of the tiling grid. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_LEFT = 5, + /** + * the surface’s right edge is tiled + * + * The window is currently in a tiled layout and the right edge + * is considered to be adjacent to another part of the tiling grid. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_RIGHT = 6, + /** + * the surface’s top edge is tiled + * + * The window is currently in a tiled layout and the top edge is + * considered to be adjacent to another part of the tiling grid. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_TOP = 7, + /** + * the surface’s bottom edge is tiled + * + * The window is currently in a tiled layout and the bottom edge + * is considered to be adjacent to another part of the tiling grid. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8, + /** + * surface repaint is suspended + * + * The surface is currently not ordinarily being repainted; for + * example because its content is occluded by another window, or + * its outputs are switched off due to screen locking. + * @since 6 + */ + XDG_TOPLEVEL_STATE_SUSPENDED = 9, +}; +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_TOP_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION 6 +#endif /* XDG_TOPLEVEL_STATE_ENUM */ + +#ifndef XDG_TOPLEVEL_WM_CAPABILITIES_ENUM +#define XDG_TOPLEVEL_WM_CAPABILITIES_ENUM +enum xdg_toplevel_wm_capabilities { + /** + * show_window_menu is available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU = 1, + /** + * set_maximized and unset_maximized are available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE = 2, + /** + * set_fullscreen and unset_fullscreen are available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN = 3, + /** + * set_minimized is available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE = 4, +}; +#endif /* XDG_TOPLEVEL_WM_CAPABILITIES_ENUM */ + +/** + * @ingroup iface_xdg_toplevel + * @struct xdg_toplevel_listener + */ +struct xdg_toplevel_listener { + /** + * suggest a surface change + * + * This configure event asks the client to resize its toplevel + * surface or to change its state. The configured state should not + * be applied immediately. See xdg_surface.configure for details. + * + * The width and height arguments specify a hint to the window + * about how its surface should be resized in window geometry + * coordinates. See set_window_geometry. + * + * If the width or height arguments are zero, it means the client + * should decide its own window dimension. This may happen when the + * compositor needs to configure the state of the surface but + * doesn't have any information about any previous or expected + * dimension. + * + * The states listed in the event specify how the width/height + * arguments should be interpreted, and possibly how it should be + * drawn. + * + * Clients must send an ack_configure in response to this event. + * See xdg_surface.configure and xdg_surface.ack_configure for + * details. + */ + void (*configure)(void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states); + /** + * surface wants to be closed + * + * The close event is sent by the compositor when the user wants + * the surface to be closed. This should be equivalent to the user + * clicking the close button in client-side decorations, if your + * application has any. + * + * This is only a request that the user intends to close the + * window. The client may choose to ignore this request, or show a + * dialog to ask the user to save their data, etc. + */ + void (*close)(void *data, + struct xdg_toplevel *xdg_toplevel); + /** + * recommended window geometry bounds + * + * The configure_bounds event may be sent prior to a + * xdg_toplevel.configure event to communicate the bounds a window + * geometry size is recommended to constrain to. + * + * The passed width and height are in surface coordinate space. If + * width and height are 0, it means bounds is unknown and + * equivalent to as if no configure_bounds event was ever sent for + * this surface. + * + * The bounds can for example correspond to the size of a monitor + * excluding any panels or other shell components, so that a + * surface isn't created in a way that it cannot fit. + * + * The bounds may change at any point, and in such a case, a new + * xdg_toplevel.configure_bounds will be sent, followed by + * xdg_toplevel.configure and xdg_surface.configure. + * @since 4 + */ + void (*configure_bounds)(void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height); + /** + * compositor capabilities + * + * This event advertises the capabilities supported by the + * compositor. If a capability isn't supported, clients should hide + * or disable the UI elements that expose this functionality. For + * instance, if the compositor doesn't advertise support for + * minimized toplevels, a button triggering the set_minimized + * request should not be displayed. + * + * The compositor will ignore requests it doesn't support. For + * instance, a compositor which doesn't advertise support for + * minimized will ignore set_minimized requests. + * + * Compositors must send this event once before the first + * xdg_surface.configure event. When the capabilities change, + * compositors must send this event again and then send an + * xdg_surface.configure event. + * + * The configured state should not be applied immediately. See + * xdg_surface.configure for details. + * + * The capabilities are sent as an array of 32-bit unsigned + * integers in native endianness. + * @param capabilities array of 32-bit capabilities + * @since 5 + */ + void (*wm_capabilities)(void *data, + struct xdg_toplevel *xdg_toplevel, + struct wl_array *capabilities); +}; + +/** + * @ingroup iface_xdg_toplevel + */ +static inline int +xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel, + const struct xdg_toplevel_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel, + (void (**)(void)) listener, data); +} + +#define XDG_TOPLEVEL_DESTROY 0 +#define XDG_TOPLEVEL_SET_PARENT 1 +#define XDG_TOPLEVEL_SET_TITLE 2 +#define XDG_TOPLEVEL_SET_APP_ID 3 +#define XDG_TOPLEVEL_SHOW_WINDOW_MENU 4 +#define XDG_TOPLEVEL_MOVE 5 +#define XDG_TOPLEVEL_RESIZE 6 +#define XDG_TOPLEVEL_SET_MAX_SIZE 7 +#define XDG_TOPLEVEL_SET_MIN_SIZE 8 +#define XDG_TOPLEVEL_SET_MAXIMIZED 9 +#define XDG_TOPLEVEL_UNSET_MAXIMIZED 10 +#define XDG_TOPLEVEL_SET_FULLSCREEN 11 +#define XDG_TOPLEVEL_UNSET_FULLSCREEN 12 +#define XDG_TOPLEVEL_SET_MINIMIZED 13 + +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_CLOSE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION 4 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION 5 + +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_PARENT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_TITLE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_APP_ID_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SHOW_WINDOW_MENU_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_MOVE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_RESIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MAX_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MIN_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MAXIMIZED_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_UNSET_MAXIMIZED_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_FULLSCREEN_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_UNSET_FULLSCREEN_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MINIMIZED_SINCE_VERSION 1 + +/** @ingroup iface_xdg_toplevel */ +static inline void +xdg_toplevel_set_user_data(struct xdg_toplevel *xdg_toplevel, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_toplevel, user_data); +} + +/** @ingroup iface_xdg_toplevel */ +static inline void * +xdg_toplevel_get_user_data(struct xdg_toplevel *xdg_toplevel) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_toplevel); +} + +static inline uint32_t +xdg_toplevel_get_version(struct xdg_toplevel *xdg_toplevel) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_toplevel); +} + +/** + * @ingroup iface_xdg_toplevel + * + * This request destroys the role surface and unmaps the surface; + * see "Unmapping" behavior in interface section for details. + */ +static inline void +xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set the "parent" of this surface. This surface should be stacked + * above the parent surface and all other ancestor surfaces. + * + * Parent surfaces should be set on dialogs, toolboxes, or other + * "auxiliary" surfaces, so that the parent is raised when the dialog + * is raised. + * + * Setting a null parent for a child surface unsets its parent. Setting + * a null parent for a surface which currently has no parent is a no-op. + * + * Only mapped surfaces can have child surfaces. Setting a parent which + * is not mapped is equivalent to setting a null parent. If a surface + * becomes unmapped, its children's parent is set to the parent of + * the now-unmapped surface. If the now-unmapped surface has no parent, + * its children's parent is unset. If the now-unmapped surface becomes + * mapped again, its parent-child relationship is not restored. + * + * The parent toplevel must not be one of the child toplevel's + * descendants, and the parent must be different from the child toplevel, + * otherwise the invalid_parent protocol error is raised. + */ +static inline void +xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_PARENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, parent); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set a short title for the surface. + * + * This string may be used to identify the surface in a task bar, + * window list, or other user interface elements provided by the + * compositor. + * + * The string must be encoded in UTF-8. + */ +static inline void +xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, title); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set an application identifier for the surface. + * + * The app ID identifies the general class of applications to which + * the surface belongs. The compositor can use this to group multiple + * surfaces together, or to determine how to launch a new application. + * + * For D-Bus activatable applications, the app ID is used as the D-Bus + * service name. + * + * The compositor shell will try to group application surfaces together + * by their app ID. As a best practice, it is suggested to select app + * ID's that match the basename of the application's .desktop file. + * For example, "org.freedesktop.FooViewer" where the .desktop file is + * "org.freedesktop.FooViewer.desktop". + * + * Like other properties, a set_app_id request can be sent after the + * xdg_toplevel has been mapped to update the property. + * + * See the desktop-entry specification [0] for more details on + * application identifiers and how they relate to well-known D-Bus + * names and .desktop files. + * + * [0] https://standards.freedesktop.org/desktop-entry-spec/ + */ +static inline void +xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, app_id); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Clients implementing client-side decorations might want to show + * a context menu when right-clicking on the decorations, giving the + * user a menu that they can use to maximize or minimize the window. + * + * This request asks the compositor to pop up such a window menu at + * the given position, relative to the local surface coordinates of + * the parent surface. There are no guarantees as to what menu items + * the window menu contains, or even if a window menu will be drawn + * at all. + * + * This request must be used in response to some sort of user action + * like a button press, key press, or touch down event. + */ +static inline void +xdg_toplevel_show_window_menu(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SHOW_WINDOW_MENU, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, x, y); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Start an interactive, user-driven move of the surface. + * + * This request must be used in response to some sort of user action + * like a button press, key press, or touch down event. The passed + * serial is used to determine the type of interactive move (touch, + * pointer, etc). + * + * The server may ignore move requests depending on the state of + * the surface (e.g. fullscreen or maximized), or if the passed serial + * is no longer valid. + * + * If triggered, the surface will lose the focus of the device + * (wl_pointer, wl_touch, etc) used for the move. It is up to the + * compositor to visually indicate that the move is taking place, such as + * updating a pointer cursor, during the move. There is no guarantee + * that the device focus will return when the move is completed. + */ +static inline void +xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Start a user-driven, interactive resize of the surface. + * + * This request must be used in response to some sort of user action + * like a button press, key press, or touch down event. The passed + * serial is used to determine the type of interactive resize (touch, + * pointer, etc). + * + * The server may ignore resize requests depending on the state of + * the surface (e.g. fullscreen or maximized). + * + * If triggered, the client will receive configure events with the + * "resize" state enum value and the expected sizes. See the "resize" + * enum value for more details about what is required. The client + * must also acknowledge configure events using "ack_configure". After + * the resize is completed, the client will receive another "configure" + * event without the resize state. + * + * If triggered, the surface also will lose the focus of the device + * (wl_pointer, wl_touch, etc) used for the resize. It is up to the + * compositor to visually indicate that the resize is taking place, + * such as updating a pointer cursor, during the resize. There is no + * guarantee that the device focus will return when the resize is + * completed. + * + * The edges parameter specifies how the surface should be resized, and + * is one of the values of the resize_edge enum. Values not matching + * a variant of the enum will cause the invalid_resize_edge protocol error. + * The compositor may use this information to update the surface position + * for example when dragging the top left corner. The compositor may also + * use this information to adapt its behavior, e.g. choose an appropriate + * cursor image. + */ +static inline void +xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, edges); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set a maximum size for the window. + * + * The client can specify a maximum size so that the compositor does + * not try to configure the window beyond this size. + * + * The width and height arguments are in window geometry coordinates. + * See xdg_surface.set_window_geometry. + * + * Values set in this way are double-buffered. They will get applied + * on the next commit. + * + * The compositor can use this information to allow or disallow + * different states like maximize or fullscreen and draw accurate + * animations. + * + * Similarly, a tiling window manager may use this information to + * place and resize client windows in a more effective way. + * + * The client should not rely on the compositor to obey the maximum + * size. The compositor may decide to ignore the values set by the + * client and request a larger size. + * + * If never set, or a value of zero in the request, means that the + * client has no expected maximum size in the given dimension. + * As a result, a client wishing to reset the maximum size + * to an unspecified state can use zero for width and height in the + * request. + * + * Requesting a maximum size to be smaller than the minimum size of + * a surface is illegal and will result in an invalid_size error. + * + * The width and height must be greater than or equal to zero. Using + * strictly negative values for width or height will result in a + * invalid_size error. + */ +static inline void +xdg_toplevel_set_max_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MAX_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set a minimum size for the window. + * + * The client can specify a minimum size so that the compositor does + * not try to configure the window below this size. + * + * The width and height arguments are in window geometry coordinates. + * See xdg_surface.set_window_geometry. + * + * Values set in this way are double-buffered. They will get applied + * on the next commit. + * + * The compositor can use this information to allow or disallow + * different states like maximize or fullscreen and draw accurate + * animations. + * + * Similarly, a tiling window manager may use this information to + * place and resize client windows in a more effective way. + * + * The client should not rely on the compositor to obey the minimum + * size. The compositor may decide to ignore the values set by the + * client and request a smaller size. + * + * If never set, or a value of zero in the request, means that the + * client has no expected minimum size in the given dimension. + * As a result, a client wishing to reset the minimum size + * to an unspecified state can use zero for width and height in the + * request. + * + * Requesting a minimum size to be larger than the maximum size of + * a surface is illegal and will result in an invalid_size error. + * + * The width and height must be greater than or equal to zero. Using + * strictly negative values for width and height will result in a + * invalid_size error. + */ +static inline void +xdg_toplevel_set_min_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MIN_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Maximize the surface. + * + * After requesting that the surface should be maximized, the compositor + * will respond by emitting a configure event. Whether this configure + * actually sets the window maximized is subject to compositor policies. + * The client must then update its content, drawing in the configured + * state. The client must also acknowledge the configure when committing + * the new content (see ack_configure). + * + * It is up to the compositor to decide how and where to maximize the + * surface, for example which output and what region of the screen should + * be used. + * + * If the surface was already maximized, the compositor will still emit + * a configure event with the "maximized" state. + * + * If the surface is in a fullscreen state, this request has no direct + * effect. It may alter the state the surface is returned to when + * unmaximized unless overridden by the compositor. + */ +static inline void +xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Unmaximize the surface. + * + * After requesting that the surface should be unmaximized, the compositor + * will respond by emitting a configure event. Whether this actually + * un-maximizes the window is subject to compositor policies. + * If available and applicable, the compositor will include the window + * geometry dimensions the window had prior to being maximized in the + * configure event. The client must then update its content, drawing it in + * the configured state. The client must also acknowledge the configure + * when committing the new content (see ack_configure). + * + * It is up to the compositor to position the surface after it was + * unmaximized; usually the position the surface had before maximizing, if + * applicable. + * + * If the surface was already not maximized, the compositor will still + * emit a configure event without the "maximized" state. + * + * If the surface is in a fullscreen state, this request has no direct + * effect. It may alter the state the surface is returned to when + * unmaximized unless overridden by the compositor. + */ +static inline void +xdg_toplevel_unset_maximized(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_UNSET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Make the surface fullscreen. + * + * After requesting that the surface should be fullscreened, the + * compositor will respond by emitting a configure event. Whether the + * client is actually put into a fullscreen state is subject to compositor + * policies. The client must also acknowledge the configure when + * committing the new content (see ack_configure). + * + * The output passed by the request indicates the client's preference as + * to which display it should be set fullscreen on. If this value is NULL, + * it's up to the compositor to choose which display will be used to map + * this surface. + * + * If the surface doesn't cover the whole output, the compositor will + * position the surface in the center of the output and compensate with + * with border fill covering the rest of the output. The content of the + * border fill is undefined, but should be assumed to be in some way that + * attempts to blend into the surrounding area (e.g. solid black). + * + * If the fullscreened surface is not opaque, the compositor must make + * sure that other screen content not part of the same surface tree (made + * up of subsurfaces, popups or similarly coupled surfaces) are not + * visible below the fullscreened surface. + */ +static inline void +xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, output); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Make the surface no longer fullscreen. + * + * After requesting that the surface should be unfullscreened, the + * compositor will respond by emitting a configure event. + * Whether this actually removes the fullscreen state of the client is + * subject to compositor policies. + * + * Making a surface unfullscreen sets states for the surface based on the following: + * * the state(s) it may have had before becoming fullscreen + * * any state(s) decided by the compositor + * * any state(s) requested by the client while the surface was fullscreen + * + * The compositor may include the previous window geometry dimensions in + * the configure event, if applicable. + * + * The client must also acknowledge the configure when committing the new + * content (see ack_configure). + */ +static inline void +xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_UNSET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Request that the compositor minimize your surface. There is no + * way to know if the surface is currently minimized, nor is there + * any way to unset minimization on this surface. + * + * If you are looking to throttle redrawing when minimized, please + * instead use the wl_surface.frame event for this, as this will + * also work with live previews on windows in Alt-Tab, Expose or + * similar compositor features. + */ +static inline void +xdg_toplevel_set_minimized(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MINIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +#ifndef XDG_POPUP_ERROR_ENUM +#define XDG_POPUP_ERROR_ENUM +enum xdg_popup_error { + /** + * tried to grab after being mapped + */ + XDG_POPUP_ERROR_INVALID_GRAB = 0, +}; +#endif /* XDG_POPUP_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_popup + * @struct xdg_popup_listener + */ +struct xdg_popup_listener { + /** + * configure the popup surface + * + * This event asks the popup surface to configure itself given + * the configuration. The configured state should not be applied + * immediately. See xdg_surface.configure for details. + * + * The x and y arguments represent the position the popup was + * placed at given the xdg_positioner rule, relative to the upper + * left corner of the window geometry of the parent surface. + * + * For version 2 or older, the configure event for an xdg_popup is + * only ever sent once for the initial configuration. Starting with + * version 3, it may be sent again if the popup is setup with an + * xdg_positioner with set_reactive requested, or in response to + * xdg_popup.reposition requests. + * @param x x position relative to parent surface window geometry + * @param y y position relative to parent surface window geometry + * @param width window geometry width + * @param height window geometry height + */ + void (*configure)(void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height); + /** + * popup interaction is done + * + * The popup_done event is sent out when a popup is dismissed by + * the compositor. The client should destroy the xdg_popup object + * at this point. + */ + void (*popup_done)(void *data, + struct xdg_popup *xdg_popup); + /** + * signal the completion of a repositioned request + * + * The repositioned event is sent as part of a popup + * configuration sequence, together with xdg_popup.configure and + * lastly xdg_surface.configure to notify the completion of a + * reposition request. + * + * The repositioned event is to notify about the completion of a + * xdg_popup.reposition request. The token argument is the token + * passed in the xdg_popup.reposition request. + * + * Immediately after this event is emitted, xdg_popup.configure and + * xdg_surface.configure will be sent with the updated size and + * position, as well as a new configure serial. + * + * The client should optionally update the content of the popup, + * but must acknowledge the new popup configuration for the new + * position to take effect. See xdg_surface.ack_configure for + * details. + * @param token reposition request token + * @since 3 + */ + void (*repositioned)(void *data, + struct xdg_popup *xdg_popup, + uint32_t token); +}; + +/** + * @ingroup iface_xdg_popup + */ +static inline int +xdg_popup_add_listener(struct xdg_popup *xdg_popup, + const struct xdg_popup_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_popup, + (void (**)(void)) listener, data); +} + +#define XDG_POPUP_DESTROY 0 +#define XDG_POPUP_GRAB 1 +#define XDG_POPUP_REPOSITION 2 + +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_POPUP_DONE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_REPOSITIONED_SINCE_VERSION 3 + +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_GRAB_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_REPOSITION_SINCE_VERSION 3 + +/** @ingroup iface_xdg_popup */ +static inline void +xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data); +} + +/** @ingroup iface_xdg_popup */ +static inline void * +xdg_popup_get_user_data(struct xdg_popup *xdg_popup) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup); +} + +static inline uint32_t +xdg_popup_get_version(struct xdg_popup *xdg_popup) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_popup); +} + +/** + * @ingroup iface_xdg_popup + * + * This destroys the popup. Explicitly destroying the xdg_popup + * object will also dismiss the popup, and unmap the surface. + * + * If this xdg_popup is not the "topmost" popup, the + * xdg_wm_base.not_the_topmost_popup protocol error will be sent. + */ +static inline void +xdg_popup_destroy(struct xdg_popup *xdg_popup) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, + XDG_POPUP_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_popup + * + * This request makes the created popup take an explicit grab. An explicit + * grab will be dismissed when the user dismisses the popup, or when the + * client destroys the xdg_popup. This can be done by the user clicking + * outside the surface, using the keyboard, or even locking the screen + * through closing the lid or a timeout. + * + * If the compositor denies the grab, the popup will be immediately + * dismissed. + * + * This request must be used in response to some sort of user action like a + * button press, key press, or touch down event. The serial number of the + * event should be passed as 'serial'. + * + * The parent of a grabbing popup must either be an xdg_toplevel surface or + * another xdg_popup with an explicit grab. If the parent is another + * xdg_popup it means that the popups are nested, with this popup now being + * the topmost popup. + * + * Nested popups must be destroyed in the reverse order they were created + * in, e.g. the only popup you are allowed to destroy at all times is the + * topmost one. + * + * When compositors choose to dismiss a popup, they may dismiss every + * nested grabbing popup as well. When a compositor dismisses popups, it + * will follow the same dismissing order as required from the client. + * + * If the topmost grabbing popup is destroyed, the grab will be returned to + * the parent of the popup, if that parent previously had an explicit grab. + * + * If the parent is a grabbing popup which has already been dismissed, this + * popup will be immediately dismissed. If the parent is a popup that did + * not take an explicit grab, an error will be raised. + * + * During a popup grab, the client owning the grab will receive pointer + * and touch events for all their surfaces as normal (similar to an + * "owner-events" grab in X11 parlance), while the top most grabbing popup + * will always have keyboard focus. + */ +static inline void +xdg_popup_grab(struct xdg_popup *xdg_popup, struct wl_seat *seat, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, + XDG_POPUP_GRAB, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, seat, serial); +} + +/** + * @ingroup iface_xdg_popup + * + * Reposition an already-mapped popup. The popup will be placed given the + * details in the passed xdg_positioner object, and a + * xdg_popup.repositioned followed by xdg_popup.configure and + * xdg_surface.configure will be emitted in response. Any parameters set + * by the previous positioner will be discarded. + * + * The passed token will be sent in the corresponding + * xdg_popup.repositioned event. The new popup position will not take + * effect until the corresponding configure event is acknowledged by the + * client. See xdg_popup.repositioned for details. The token itself is + * opaque, and has no other special meaning. + * + * If multiple reposition requests are sent, the compositor may skip all + * but the last one. + * + * If the popup is repositioned in response to a configure event for its + * parent, the client should send an xdg_positioner.set_parent_configure + * and possibly an xdg_positioner.set_parent_size request to allow the + * compositor to properly constrain the popup. + * + * If the popup is repositioned together with a parent that is being + * resized, but not in response to a configure event, the client should + * send an xdg_positioner.set_parent_size request. + */ +static inline void +xdg_popup_reposition(struct xdg_popup *xdg_popup, struct xdg_positioner *positioner, uint32_t token) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, + XDG_POPUP_REPOSITION, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, positioner, token); +} + +#ifdef __cplusplus +} +#endif + +#endif From caf96ad1c0b1a7848a0d83c8c6335c6661012a62 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:29:23 +0100 Subject: [PATCH 034/278] Update cgo --- raylib/cgo_darwin.go | 4 ++++ raylib/cgo_freebsd.go | 19 +++++-------------- raylib/cgo_linux.go | 16 ++++++---------- raylib/cgo_openbsd.go | 19 +++++-------------- raylib/cgo_windows.go | 6 +++++- 5 files changed, 25 insertions(+), 39 deletions(-) diff --git a/raylib/cgo_darwin.go b/raylib/cgo_darwin.go index 111df77..ce68341 100644 --- a/raylib/cgo_darwin.go +++ b/raylib/cgo_darwin.go @@ -23,6 +23,10 @@ package rl #include "external/glfw/src/egl_context.c" #include "external/glfw/src/osmesa_context.c" +GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { + return GLFW_TRUE; +} + #cgo darwin LDFLAGS: -framework Cocoa -framework IOKit -framework CoreVideo -framework CoreFoundation #cgo darwin CFLAGS: -x objective-c -Iexternal/glfw/include -D_GLFW_COCOA -D_GLFW_USE_CHDIR -D_GLFW_USE_MENUBAR -D_GLFW_USE_RETINA -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -DPLATFORM_DESKTOP diff --git a/raylib/cgo_freebsd.go b/raylib/cgo_freebsd.go index 72f5b45..8b71e4d 100644 --- a/raylib/cgo_freebsd.go +++ b/raylib/cgo_freebsd.go @@ -12,17 +12,10 @@ package rl #include "external/glfw/src/vulkan.c" #include "external/glfw/src/window.c" -#ifdef _GLFW_WAYLAND -#include "external/glfw/src/wl_init.c" -#include "external/glfw/src/wl_monitor.c" -#include "external/glfw/src/wl_window.c" -#endif -#ifdef _GLFW_X11 #include "external/glfw/src/x11_init.c" #include "external/glfw/src/x11_monitor.c" #include "external/glfw/src/x11_window.c" #include "external/glfw/src/glx_context.c" -#endif #include "external/glfw/src/null_joystick.c" #include "external/glfw/src/posix_module.c" @@ -33,17 +26,15 @@ package rl #include "external/glfw/src/egl_context.c" #include "external/glfw/src/osmesa_context.c" -#cgo freebsd CFLAGS: -I. -I/usr/local/include -Iexternal/glfw/include -DPLATFORM_DESKTOP -#cgo freebsd LDFLAGS: -L/usr/local/lib +GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { + return GLFW_TRUE; +} -#cgo freebsd,!wayland LDFLAGS: -lm -pthread -ldl -lrt -lX11 -#cgo freebsd,wayland LDFLAGS: -lm -pthread -ldl -lrt -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon +#cgo freebsd CFLAGS: -I. -I/usr/local/include -Iexternal/glfw/include -DPLATFORM_DESKTOP -D_GLFW_X11 +#cgo freebsd LDFLAGS: -L/usr/local/lib -lm -pthread -ldl -lrt -lX11 #cgo freebsd,!es2,!es3 LDFLAGS: -lGL -#cgo freebsd,!wayland CFLAGS: -D_GLFW_X11 -#cgo freebsd,wayland CFLAGS: -D_GLFW_WAYLAND - #cgo freebsd,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 #cgo freebsd,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 #cgo freebsd,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 diff --git a/raylib/cgo_linux.go b/raylib/cgo_linux.go index 237a77a..cfaabaf 100644 --- a/raylib/cgo_linux.go +++ b/raylib/cgo_linux.go @@ -12,17 +12,14 @@ package rl #include "external/glfw/src/vulkan.c" #include "external/glfw/src/window.c" -#ifdef _GLFW_WAYLAND #include "external/glfw/src/wl_init.c" #include "external/glfw/src/wl_monitor.c" #include "external/glfw/src/wl_window.c" -#endif -#ifdef _GLFW_X11 + #include "external/glfw/src/x11_init.c" #include "external/glfw/src/x11_monitor.c" #include "external/glfw/src/x11_window.c" #include "external/glfw/src/glx_context.c" -#endif #include "external/glfw/src/linux_joystick.c" #include "external/glfw/src/posix_module.c" @@ -33,16 +30,15 @@ package rl #include "external/glfw/src/egl_context.c" #include "external/glfw/src/osmesa_context.c" -#cgo linux CFLAGS: -Iexternal/glfw/include -DPLATFORM_DESKTOP -Wno-stringop-overflow +GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { + return GLFW_TRUE; +} -#cgo linux,!wayland LDFLAGS: -lm -pthread -ldl -lrt -lX11 -#cgo linux,wayland LDFLAGS: -lm -pthread -ldl -lrt -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon +#cgo linux CFLAGS: -Iexternal/glfw/include -DPLATFORM_DESKTOP -D_GLFW_WAYLAND -D_GLFW_X11 -Wno-stringop-overflow +#cgo linux LDFLAGS: -lm -pthread -ldl -lrt -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon #cgo linux,!es2,!es3 LDFLAGS: -lGL -#cgo linux,!wayland CFLAGS: -D_GLFW_X11 -#cgo linux,wayland CFLAGS: -D_GLFW_WAYLAND - #cgo linux,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 #cgo linux,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 #cgo linux,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 diff --git a/raylib/cgo_openbsd.go b/raylib/cgo_openbsd.go index 970d09b..ce5244d 100644 --- a/raylib/cgo_openbsd.go +++ b/raylib/cgo_openbsd.go @@ -12,17 +12,10 @@ package rl #include "external/glfw/src/vulkan.c" #include "external/glfw/src/window.c" -#ifdef _GLFW_WAYLAND -#include "external/glfw/src/wl_init.c" -#include "external/glfw/src/wl_monitor.c" -#include "external/glfw/src/wl_window.c" -#endif -#ifdef _GLFW_X11 #include "external/glfw/src/x11_init.c" #include "external/glfw/src/x11_monitor.c" #include "external/glfw/src/x11_window.c" #include "external/glfw/src/glx_context.c" -#endif #include "external/glfw/src/null_joystick.c" #include "external/glfw/src/posix_module.c" @@ -33,17 +26,15 @@ package rl #include "external/glfw/src/egl_context.c" #include "external/glfw/src/osmesa_context.c" -#cgo openbsd CFLAGS: -I. -I/usr/X11R6/include -Iexternal/glfw/include -DPLATFORM_DESKTOP -#cgo openbsd LDFLAGS: -L/usr/X11R6/lib +GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { + return GLFW_TRUE; +} -#cgo openbsd,!wayland LDFLAGS: -lm -pthread -lX11 -#cgo openbsd,wayland LDFLAGS: -lm -pthread -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon +#cgo openbsd CFLAGS: -I. -I/usr/X11R6/include -Iexternal/glfw/include -DPLATFORM_DESKTOP -D_GLFW_X11 +#cgo openbsd LDFLAGS: -L/usr/X11R6/lib -lm -pthread -lX11 #cgo openbsd,!es2,!es3 LDFLAGS: -lGL -#cgo openbsd,!wayland CFLAGS: -D_GLFW_X11 -#cgo openbsd,wayland CFLAGS: -D_GLFW_WAYLAND - #cgo openbsd,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 #cgo openbsd,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 #cgo openbsd,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 diff --git a/raylib/cgo_windows.go b/raylib/cgo_windows.go index 3c71c31..41d1761 100644 --- a/raylib/cgo_windows.go +++ b/raylib/cgo_windows.go @@ -23,8 +23,12 @@ package rl #include "external/glfw/src/egl_context.c" #include "external/glfw/src/osmesa_context.c" +GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { + return GLFW_TRUE; +} + #cgo windows LDFLAGS: -lgdi32 -lwinmm -lole32 -#cgo windows CFLAGS: -D_GLFW_WIN32 -Iexternal -Iexternal/glfw/include -Iexternal/glfw/deps/mingw -DPLATFORM_DESKTOP -Wno-stringop-overflow +#cgo windows CFLAGS: -Iexternal -Iexternal/glfw/include -DPLATFORM_DESKTOP -D_GLFW_WIN32 -Wno-stringop-overflow #cgo windows,!es2,!es3 LDFLAGS: -lopengl32 From cc776abd3b97b7ee608a287c9b33a7030f3ec6a7 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:35:31 +0100 Subject: [PATCH 035/278] Update actions --- .github/workflows/build.yml | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e2f4f6a..ce2ff0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v3 - name: Install package run: | - sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev + sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev libwayland-dev libxkbcommon-dev if: runner.os == 'Linux' - name: Build run: go build ./... @@ -80,26 +80,6 @@ jobs: run: go build -tags sdl working-directory: raylib - test-wayland: - strategy: - matrix: - go-version: [1.21.x] - os: [ubuntu-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Install Go - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.go-version }} - - name: Checkout code - uses: actions/checkout@v3 - - name: Install package - run: | - sudo apt-get update -y; sudo apt-get -y install libgl1-mesa-dev libwayland-dev libxkbcommon-dev - - name: Build - run: go build -tags wayland - working-directory: raylib - test-examples: strategy: matrix: From 3889376dd31675cafa4d16d0c2045b9c1acb1c06 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:38:46 +0100 Subject: [PATCH 036/278] Update actions --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce2ff0f..f2fd4f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,7 +95,7 @@ jobs: uses: actions/checkout@v3 - name: Install package run: | - sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev + sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev libwayland-dev libxkbcommon-dev - name: Build run: go build ./... working-directory: examples From 468523fda45c4d666482a560f6ae4ec9c19768cc Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Mon, 26 Feb 2024 09:45:57 +0100 Subject: [PATCH 037/278] Update README.md --- README.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 2f508e3..5dfaafd 100644 --- a/README.md +++ b/README.md @@ -15,23 +15,11 @@ It is also possible to use raylib-go without cgo (Windows only; see requirements ##### Ubuntu -###### X11 - - apt-get install libgl1-mesa-dev libxi-dev libxcursor-dev libxrandr-dev libxinerama-dev - -###### Wayland - - apt-get install libgl1-mesa-dev libwayland-dev libxkbcommon-dev + apt-get install libgl1-mesa-dev libxi-dev libxcursor-dev libxrandr-dev libxinerama-dev libwayland-dev libxkbcommon-dev ##### Fedora -###### X11 - - dnf install mesa-libGL-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel - -###### Wayland - - dnf install mesa-libGL-devel wayland-devel libxkbcommon-devel + dnf install mesa-libGL-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel wayland-devel libxkbcommon-devel ##### macOS @@ -67,7 +55,6 @@ It is also possible build the dll yourself. You can find more infos at [raylib's * `drm` - build for Linux native DRM mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM) * `sdl` - build for SDL backend instead of internal GLFW (PLATFORM_DESKTOP_SDL) -* `wayland` - build against Wayland libraries (internal GLFW) * `noaudio` - disables audio functions * `opengl43` - uses OpenGL 4.3 backend * `opengl21` - uses OpenGL 2.1 backend (default is 3.3 on desktop) From 069b39e6886e869cb2b1f1a8a4a7c61ceba5176f Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Tue, 27 Feb 2024 07:48:19 +0100 Subject: [PATCH 038/278] Fix android build --- raylib/platform_android.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/raylib/platform_android.go b/raylib/platform_android.go index 3d6d3f8..e80c8bc 100644 --- a/raylib/platform_android.go +++ b/raylib/platform_android.go @@ -11,8 +11,8 @@ package rl extern void android_init(); -extern AAssetManager* asset_manager; -extern const char* internal_storage_path; +static AAssetManager* asset_manager; +static const char* internal_storage_path; */ import "C" From 00f5f785e6ecc7d0826d0bb5c79792956d57ae60 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Tue, 27 Feb 2024 07:54:10 +0100 Subject: [PATCH 039/278] Update android example --- examples/others/android/example/README.md | 9 +- .../example/android/AndroidManifest.xml | 4 +- .../android/example/android/build.gradle | 7 +- .../others/android/example/android/build.xml | 92 ------------------- .../example/android/project.properties | 2 - examples/others/android/example/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 7 files changed, 10 insertions(+), 108 deletions(-) delete mode 100644 examples/others/android/example/android/build.xml delete mode 100644 examples/others/android/example/android/project.properties diff --git a/examples/others/android/example/README.md b/examples/others/android/example/README.md index 98468ce..6ef631d 100644 --- a/examples/others/android/example/README.md +++ b/examples/others/android/example/README.md @@ -33,16 +33,11 @@ To build apk export path to Android SDK, point to location where you unpacked ar export ANDROID_HOME=/opt/android-sdk -And build apk with ant: - - cd android - ant clean debug - -Or with gradle: +And build apk: ./gradlew assembleDebug -If everything is successfully built apk can be found in bin/ directory or in the android/build/outputs in case `gradle` is used. +If everything is successfully built apk can be found in the android/build/outputs. For aarch64/arm64 replace `arm-linux-androideabi` with `aarch64-linux-android`, set GOARCH to arm64 and use minimum `ANDROID_API=21`. diff --git a/examples/others/android/example/android/AndroidManifest.xml b/examples/others/android/example/android/AndroidManifest.xml index 20cc5cf..19b1694 100644 --- a/examples/others/android/example/android/AndroidManifest.xml +++ b/examples/others/android/example/android/AndroidManifest.xml @@ -1,10 +1,9 @@ - + @@ -15,6 +14,7 @@ diff --git a/examples/others/android/example/android/build.gradle b/examples/others/android/example/android/build.gradle index 3bb73a0..b819fb4 100644 --- a/examples/others/android/example/android/build.gradle +++ b/examples/others/android/example/android/build.gradle @@ -1,13 +1,14 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 27 - buildToolsVersion '27.0.3' + namespace = "com.example.android" + compileSdkVersion 34 + buildToolsVersion '34.0.0' defaultConfig { applicationId "com.example.android" minSdkVersion 16 - targetSdkVersion 27 + targetSdkVersion 34 versionCode 1 versionName '1.0' } diff --git a/examples/others/android/example/android/build.xml b/examples/others/android/example/android/build.xml deleted file mode 100644 index 3e7a699..0000000 --- a/examples/others/android/example/android/build.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/others/android/example/android/project.properties b/examples/others/android/example/android/project.properties deleted file mode 100644 index 36b004b..0000000 --- a/examples/others/android/example/android/project.properties +++ /dev/null @@ -1,2 +0,0 @@ -# Project target. -target=android-27 diff --git a/examples/others/android/example/build.gradle b/examples/others/android/example/build.gradle index e9f7a57..301e2dd 100644 --- a/examples/others/android/example/build.gradle +++ b/examples/others/android/example/build.gradle @@ -4,7 +4,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:8.2.2' } } diff --git a/examples/others/android/example/gradle/wrapper/gradle-wrapper.properties b/examples/others/android/example/gradle/wrapper/gradle-wrapper.properties index 9f7ad18..b05c5cc 100644 --- a/examples/others/android/example/gradle/wrapper/gradle-wrapper.properties +++ b/examples/others/android/example/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip From c3665eb9abf8a426feb76c5e4d02c1b63fc7e482 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Tue, 27 Feb 2024 12:46:48 +0100 Subject: [PATCH 040/278] Add x11 build tag --- README.md | 1 + raylib/cgo_linux.go | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dfaafd..d391fcd 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ It is also possible build the dll yourself. You can find more infos at [raylib's * `opengl11` - uses OpenGL 1.1 backend (pseudo OpenGL 1.1 style) * `es2` - uses OpenGL ES 2.0 backend (can be used to link against [Google's ANGLE](https://github.com/google/angle)) * `es3` - experimental support for OpenGL ES 3.0 +* `x11` - force X11 compatibility mode on Wayland ### Documentation diff --git a/raylib/cgo_linux.go b/raylib/cgo_linux.go index cfaabaf..9c8a507 100644 --- a/raylib/cgo_linux.go +++ b/raylib/cgo_linux.go @@ -34,9 +34,12 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) { return GLFW_TRUE; } -#cgo linux CFLAGS: -Iexternal/glfw/include -DPLATFORM_DESKTOP -D_GLFW_WAYLAND -D_GLFW_X11 -Wno-stringop-overflow +#cgo linux CFLAGS: -Iexternal/glfw/include -DPLATFORM_DESKTOP -Wno-stringop-overflow #cgo linux LDFLAGS: -lm -pthread -ldl -lrt -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon +#cgo linux,x11 CFLAGS: -D_GLFW_X11 +#cgo linux,!x11 CFLAGS: -D_GLFW_X11 -D_GLFW_WAYLAND + #cgo linux,!es2,!es3 LDFLAGS: -lGL #cgo linux,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 From 0b4f8b1cc09fd86efd233c62a5992c91f759f837 Mon Sep 17 00:00:00 2001 From: John Bannister Date: Sun, 7 Apr 2024 14:12:03 +0100 Subject: [PATCH 041/278] Fix ScrollPanel view binding The values on the view parameter of ScrollPanel() should be updated with the values set by the C method. --- raygui/raygui.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/raygui/raygui.go b/raygui/raygui.go index 1a3f8ef..2e7a6ed 100644 --- a/raygui/raygui.go +++ b/raygui/raygui.go @@ -375,6 +375,12 @@ func ScrollPanel(bounds rl.Rectangle, text string, content rl.Rectangle, scroll cview.y = C.float(view.Y) cview.width = C.float(view.Width) cview.height = C.float(view.Height) + defer func() { + view.X = float32(cview.x) + view.Y = float32(cview.y) + view.Width = float32(cview.width) + view.Height = float32(cview.height) + }() res := C.GuiScrollPanel(cbounds, ctext, ccontent, &cscroll, &cview) From 39b56ef013af878ed283849a0beced539948d2e4 Mon Sep 17 00:00:00 2001 From: Alessandro Cuppari Date: Tue, 16 Apr 2024 21:55:35 +0100 Subject: [PATCH 042/278] feat: add DrawTextPro --- raylib/rtext.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/raylib/rtext.go b/raylib/rtext.go index 684c690..27a1150 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -155,6 +155,20 @@ func DrawTextEx(font Font, text string, position Vector2, fontSize float32, spac C.DrawTextEx(*cfont, ctext, *cposition, cfontSize, cspacing, *ctint) } +// DrawTextPro - Draw text using Font and pro parameters (rotation) +func DrawTextPro(font Font, text string, position Vector2, origin Vector2, rotation, fontSize float32, spacing float32, tint color.RGBA) { + cfont := font.cptr() + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + cposition := position.cptr() + crotation := (C.float)(rotation) + corigin := origin.cptr() + cfontSize := (C.float)(fontSize) + cspacing := (C.float)(spacing) + ctint := colorCptr(tint) + C.DrawTextPro(cfont, ctext, cposition, corigin, crotation, cfontSize, cspacing, ctint) +} + // SetTextLineSpacing - Set vertical line spacing when drawing with line-breaks func SetTextLineSpacing(spacing int) { cspacing := (C.int)(spacing) From e717485867f53dc15ecfdddcee931275e4563f0e Mon Sep 17 00:00:00 2001 From: Alessandro Cuppari Date: Thu, 18 Apr 2024 13:59:55 +0100 Subject: [PATCH 043/278] fix: args should be pointers --- raylib/rtext.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/rtext.go b/raylib/rtext.go index 27a1150..25f980d 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -166,7 +166,7 @@ func DrawTextPro(font Font, text string, position Vector2, origin Vector2, rotat cfontSize := (C.float)(fontSize) cspacing := (C.float)(spacing) ctint := colorCptr(tint) - C.DrawTextPro(cfont, ctext, cposition, corigin, crotation, cfontSize, cspacing, ctint) + C.DrawTextPro(*cfont, ctext, *cposition, *corigin, crotation, cfontSize, cspacing, *ctint) } // SetTextLineSpacing - Set vertical line spacing when drawing with line-breaks From 8545220e18f428e5c37445c3ad8eaff07b5a1a56 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:27:15 +0200 Subject: [PATCH 044/278] Don't use struct return values This fixes https://github.com/gen2brain/raylib-go/issues/376 --- raylib/raylib_purego.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 6651673..7f99845 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -230,11 +230,11 @@ var drawSplineSegmentBasis func(p1 uintptr, p2 uintptr, p3 uintptr, p4 uintptr, var drawSplineSegmentCatmullRom func(p1 uintptr, p2 uintptr, p3 uintptr, p4 uintptr, thick float32, col uintptr) var drawSplineSegmentBezierQuadratic func(p1 uintptr, c2 uintptr, p3 uintptr, thick float32, col uintptr) var drawSplineSegmentBezierCubic func(p1 uintptr, c2 uintptr, c3 uintptr, p4 uintptr, thick float32, col uintptr) -var getSplinePointLinear func(startPos uintptr, endPos uintptr, t float32) Vector2 -var getSplinePointBasis func(p1 uintptr, p2 uintptr, p3 uintptr, p4 uintptr, t float32) Vector2 -var getSplinePointCatmullRom func(p1 uintptr, p2 uintptr, p3 uintptr, p4 uintptr, t float32) Vector2 -var getSplinePointBezierQuad func(p1 uintptr, c2 uintptr, p3 uintptr, t float32) Vector2 -var getSplinePointBezierCubic func(p1 uintptr, c2 uintptr, c3 uintptr, p4 uintptr, t float32) Vector2 +var getSplinePointLinear func(startPos uintptr, endPos uintptr, t float32) uintptr +var getSplinePointBasis func(p1 uintptr, p2 uintptr, p3 uintptr, p4 uintptr, t float32) uintptr +var getSplinePointCatmullRom func(p1 uintptr, p2 uintptr, p3 uintptr, p4 uintptr, t float32) uintptr +var getSplinePointBezierQuad func(p1 uintptr, c2 uintptr, p3 uintptr, t float32) uintptr +var getSplinePointBezierCubic func(p1 uintptr, c2 uintptr, c3 uintptr, p4 uintptr, t float32) uintptr var checkCollisionRecs func(rec1 uintptr, rec2 uintptr) bool var checkCollisionCircles func(center1 uintptr, radius1 float32, center2 uintptr, radius2 float32) bool var checkCollisionCircleRec func(center uintptr, radius float32, rec uintptr) bool From 4523bcd71db15f5df5353bddd1fc0419a583de8e Mon Sep 17 00:00:00 2001 From: Gabriel Da Silva Marques Date: Wed, 24 Apr 2024 17:12:01 +0200 Subject: [PATCH 045/278] Added custom frame control functions to rcore.go Added SwapScreenBuffer() and PollInputEvents into rcore.go with corresponding comments To use them it's necessary to build with CGO_CFLAGS="-DSUPPORT_CUSTOM_FRAME_CONTROL=1" Also added more info in the raylib_purego.go file for theses two functions in order to inform that the dll must be recompiled --- raylib/raylib_purego.go | 5 +++++ raylib/rcore.go | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 7f99845..ef58489 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -1492,6 +1492,11 @@ func GetFPS() int32 { return getFPS() } +// Custom frame control functions +// NOTE: SwapScreenBuffer and PollInputEvents are intended for advanced users that want full control over the frame processing +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +// To avoid that behaviour and control frame processes manually you must recompile raylib with SUPPORT_CUSTOM_FRAME_CONTROL enabled in config.h + // SwapScreenBuffer - Swap back buffer with front buffer (screen drawing) func SwapScreenBuffer() { swapScreenBuffer() diff --git a/raylib/rcore.go b/raylib/rcore.go index 12a3f84..d184a34 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -702,6 +702,22 @@ func GetTime() float64 { return v } +// Custom frame control functions +// NOTE: SwapScreenBuffer and PollInputEvents are intended for advanced users that want full control over the frame processing +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +// To avoid that behaviour and control frame processes manually you can either enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL +// or add CGO_CFLAGS="-DSUPPORT_CUSTOM_FRAME_CONTROL=1" to your build + +// SwapScreenBuffer - Swap back buffer to front buffer +func SwapScreenBuffer() { + C.SwapScreenBuffer() +} + +// Register all input events +func PollInputEvents() { + C.PollInputEvents() +} + // Fade - Returns color with alpha applied, alpha goes from 0.0f to 1.0f func Fade(col color.RGBA, alpha float32) color.RGBA { ccolor := colorCptr(col) From 1c9f65903d1b490901b00f90773ed30fdea1cb4a Mon Sep 17 00:00:00 2001 From: ajsosa Date: Sun, 28 Apr 2024 18:30:46 -0500 Subject: [PATCH 046/278] Expose ToggleBorderlessWindowed() to golang. --- raylib/rcore.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/raylib/rcore.go b/raylib/rcore.go index d184a34..c3b3a7e 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -217,6 +217,11 @@ func ToggleFullscreen() { C.ToggleFullscreen() } +// ToggleBorderlessWindowed - Borderless fullscreen toggle (only PLATFORM_DESKTOP) +func ToggleBorderlessWindowed() { + C.ToggleBorderlessWindowed() +} + // MaximizeWindow - Set window state: maximized, if resizable func MaximizeWindow() { C.MaximizeWindow() From 19429cd00d104f0ab984cadcb418692bec1ac5c4 Mon Sep 17 00:00:00 2001 From: JFAexe Date: Sun, 5 May 2024 10:21:22 +0300 Subject: [PATCH 047/278] Add missing WaitTime --- raylib/rcore.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/raylib/rcore.go b/raylib/rcore.go index d184a34..8cef656 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -718,6 +718,12 @@ func PollInputEvents() { C.PollInputEvents() } +// WaitTime - Wait for some time (halt program execution) +func WaitTime(seconds float64) { + cseconds := (C.double)(seconds) + C.WaitTime(cseconds) +} + // Fade - Returns color with alpha applied, alpha goes from 0.0f to 1.0f func Fade(col color.RGBA, alpha float32) color.RGBA { ccolor := colorCptr(col) From 18685208495936dcbdc637373810f80c2fa98949 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Tue, 7 May 2024 21:54:39 +0200 Subject: [PATCH 048/278] Update C sources --- raylib/cgo.go | 2 +- raylib/config.h | 30 +- raylib/external/cgltf.h | 230 +++-- raylib/external/rl_gputex.h | 4 +- raylib/external/rprand.h | 16 +- raylib/external/sinfl.h | 8 +- raylib/external/vox_loader.h | 17 + raylib/platforms/rcore_android.c | 207 +++- raylib/platforms/rcore_desktop.c | 193 ++-- raylib/platforms/rcore_desktop_sdl.c | 329 ++++++- raylib/platforms/rcore_drm.c | 1307 +++++++++++--------------- raylib/raudio.c | 612 +++++++----- raylib/raylib.h | 97 +- raylib/raymath.h | 389 +++++++- raylib/rcamera.h | 62 +- raylib/rcore.c | 247 +++-- raylib/rcore.go | 2 +- raylib/rgestures.h | 2 +- raylib/rlgl.h | 516 +++++++--- raylib/rlgl_cgo.go | 4 +- raylib/rmodels.c | 827 ++++++++++++---- raylib/rshapes.c | 433 +++++---- raylib/rshapes.go | 3 +- raylib/rtext.c | 662 ++++++++++--- raylib/rtextures.c | 595 ++++++++---- raylib/utils.c | 20 +- raylib/utils.h | 2 +- 27 files changed, 4582 insertions(+), 2234 deletions(-) diff --git a/raylib/cgo.go b/raylib/cgo.go index 60e7130..88562e0 100644 --- a/raylib/cgo.go +++ b/raylib/cgo.go @@ -1,6 +1,6 @@ package rl /* -#cgo CFLAGS: -std=gnu99 -Wno-missing-braces -Wno-unused-result -Wno-implicit-function-declaration +#cgo CFLAGS: -std=gnu99 -Wno-missing-braces -Wno-unused-result -Wno-implicit-function-declaration -Wno-int-to-pointer-cast */ import "C" diff --git a/raylib/config.h b/raylib/config.h index 4017e62..4edaa59 100644 --- a/raylib/config.h +++ b/raylib/config.h @@ -6,7 +6,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5) +* Copyright (c) 2018-2024 Ahmad Fatoum & Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -81,6 +81,7 @@ #define MAX_GAMEPADS 4 // Maximum number of gamepads supported #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue @@ -111,14 +112,22 @@ #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance +// Default shader vertex attribute locations +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0 +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1 +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2 +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3 +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4 +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 + // Default shader vertex attribute names to set location points // NOTE: When a new shader is loaded, the following locations are tried to be set for convenience -#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD +#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL +#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix @@ -138,6 +147,10 @@ // Some lines-based shapes could still use lines #define SUPPORT_QUADS_DRAW_MODE 1 +// rshapes: Configuration values +//------------------------------------------------------------------------------------ +#define SPLINE_SEGMENT_DIVISIONS 24 // Spline segments subdivisions + //------------------------------------------------------------------------------------ // Module: rtextures - Configuration Flags @@ -175,8 +188,9 @@ // NOTE: If enabled, uses external module functions to load default raylib font #define SUPPORT_DEFAULT_FONT 1 // Selected desired font fileformats to be supported for loading -#define SUPPORT_FILEFORMAT_FNT 1 #define SUPPORT_FILEFORMAT_TTF 1 +#define SUPPORT_FILEFORMAT_FNT 1 +#define SUPPORT_FILEFORMAT_BDF 1 // Support text management functions // If not defined, still some functions are supported: TextLength(), TextFormat() diff --git a/raylib/external/cgltf.h b/raylib/external/cgltf.h index ddec501..3231201 100644 --- a/raylib/external/cgltf.h +++ b/raylib/external/cgltf.h @@ -63,9 +63,14 @@ * By passing null for the output pointer, users can find out how many floats are required in the * output buffer. * + * `cgltf_accessor_unpack_indices` reads in the index data from an accessor. Assumes that + * `cgltf_load_buffers` has already been called. By passing null for the output pointer, users can + * find out how many indices are required in the output buffer. Returns 0 if the accessor is + * sparse or if the output component size is less than the accessor's component size. + * * `cgltf_num_components` is a tiny utility that tells you the dimensionality of * a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate - * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for + * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for * similar purposes. * * `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to @@ -75,7 +80,7 @@ * * `cgltf_accessor_read_uint` is similar to its floating-point counterpart, but limited to reading * vector types and does not support matrix types. The passed-in element size is the number of uints - * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in + * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in * element_size is too small, or if the accessor is sparse. * * `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t @@ -197,6 +202,7 @@ typedef enum cgltf_type typedef enum cgltf_primitive_type { + cgltf_primitive_type_invalid, cgltf_primitive_type_points, cgltf_primitive_type_lines, cgltf_primitive_type_line_loop, @@ -499,6 +505,11 @@ typedef struct cgltf_anisotropy cgltf_texture_view anisotropy_texture; } cgltf_anisotropy; +typedef struct cgltf_dispersion +{ + cgltf_float dispersion; +} cgltf_dispersion; + typedef struct cgltf_material { char* name; @@ -513,6 +524,7 @@ typedef struct cgltf_material cgltf_bool has_emissive_strength; cgltf_bool has_iridescence; cgltf_bool has_anisotropy; + cgltf_bool has_dispersion; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; cgltf_clearcoat clearcoat; @@ -524,6 +536,7 @@ typedef struct cgltf_material cgltf_emissive_strength emissive_strength; cgltf_iridescence iridescence; cgltf_anisotropy anisotropy; + cgltf_dispersion dispersion; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture; @@ -838,7 +851,7 @@ cgltf_size cgltf_component_size(cgltf_component_type component_type); cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type); cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count); -cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count); +cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count); /* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size); @@ -938,8 +951,8 @@ static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t #ifndef CGLTF_CONSTS -static const cgltf_size GlbHeaderSize = 12; -static const cgltf_size GlbChunkHeaderSize = 8; +#define GlbHeaderSize 12 +#define GlbChunkHeaderSize 8 static const uint32_t GlbVersion = 2; static const uint32_t GlbMagic = 0x46546C67; static const uint32_t GlbMagicJsonChunk = 0x4E4F534A; @@ -1033,7 +1046,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m fclose(file); return cgltf_result_out_of_memory; } - + cgltf_size read_size = fread(file_data, 1, file_size, file); fclose(file); @@ -1141,7 +1154,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s // JSON chunk: length uint32_t json_length; memcpy(&json_length, json_chunk, 4); - if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size) + if (json_length > size - GlbHeaderSize - GlbChunkHeaderSize) { return cgltf_result_data_too_short; } @@ -1158,7 +1171,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s const void* bin = NULL; cgltf_size bin_size = 0; - if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size) + if (GlbChunkHeaderSize <= size - GlbHeaderSize - GlbChunkHeaderSize - json_length) { // We can read another chunk const uint8_t* bin_chunk = json_chunk + json_length; @@ -1166,7 +1179,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s // Bin chunk: length uint32_t bin_length; memcpy(&bin_length, bin_chunk, 4); - if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size) + if (bin_length > size - GlbHeaderSize - GlbChunkHeaderSize - json_length - GlbChunkHeaderSize) { return cgltf_result_data_too_short; } @@ -1552,6 +1565,9 @@ cgltf_result cgltf_validate(cgltf_data* data) { cgltf_accessor* accessor = &data->accessors[i]; + CGLTF_ASSERT_IF(data->accessors[i].component_type == cgltf_component_type_invalid, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(data->accessors[i].type == cgltf_type_invalid, cgltf_result_invalid_gltf); + cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type); if (accessor->buffer_view) @@ -1565,7 +1581,7 @@ cgltf_result cgltf_validate(cgltf_data* data) { cgltf_accessor_sparse* sparse = &accessor->sparse; - cgltf_size indices_component_size = cgltf_calc_size(cgltf_type_scalar, sparse->indices_component_type); + cgltf_size indices_component_size = cgltf_component_size(sparse->indices_component_type); cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count; cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count; @@ -1631,43 +1647,48 @@ cgltf_result cgltf_validate(cgltf_data* data) for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j) { + CGLTF_ASSERT_IF(data->meshes[i].primitives[j].type == cgltf_primitive_type_invalid, cgltf_result_invalid_gltf); CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf); - if (data->meshes[i].primitives[j].attributes_count) + CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes_count == 0, cgltf_result_invalid_gltf); + + cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data; + + CGLTF_ASSERT_IF(first->count == 0, cgltf_result_invalid_gltf); + + for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k) { - cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data; + CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf); + } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k) + for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k) + { + for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m) { - CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf); } + } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k) - { - for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m) - { - CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf); - } - } + cgltf_accessor* indices = data->meshes[i].primitives[j].indices; - cgltf_accessor* indices = data->meshes[i].primitives[j].indices; + CGLTF_ASSERT_IF(indices && + indices->component_type != cgltf_component_type_r_8u && + indices->component_type != cgltf_component_type_r_16u && + indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf); - CGLTF_ASSERT_IF(indices && - indices->component_type != cgltf_component_type_r_8u && - indices->component_type != cgltf_component_type_r_16u && - indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(indices && indices->type != cgltf_type_scalar, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(indices && indices->stride != cgltf_component_size(indices->component_type), cgltf_result_invalid_gltf); - if (indices && indices->buffer_view && indices->buffer_view->buffer->data) - { - cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count); + if (indices && indices->buffer_view && indices->buffer_view->buffer->data) + { + cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count); - CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short); - } + CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short); + } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k) - { - CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf); - } + for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k) + { + CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf); } } } @@ -1724,10 +1745,15 @@ cgltf_result cgltf_validate(cgltf_data* data) cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1; - CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short); + CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_invalid_gltf); } } + for (cgltf_size i = 0; i < data->variants_count; ++i) + { + CGLTF_ASSERT_IF(!data->variants[i].name, cgltf_result_invalid_gltf); + } + return cgltf_result_success; } @@ -1902,7 +1928,7 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->materials); - for (cgltf_size i = 0; i < data->images_count; ++i) + for (cgltf_size i = 0; i < data->images_count; ++i) { data->memory.free_func(data->memory.user_data, data->images[i].name); data->memory.free_func(data->memory.user_data, data->images[i].uri); @@ -2550,7 +2576,7 @@ cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const return (cgltf_size)(object - animation->channels); } -cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count) +cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count) { if (out == NULL) { @@ -2558,6 +2584,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u } index_count = accessor->count < index_count ? accessor->count : index_count; + cgltf_size index_component_size = cgltf_component_size(accessor->component_type); if (accessor->is_sparse) { @@ -2567,6 +2594,10 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u { return 0; } + if (index_component_size > out_component_size) + { + return 0; + } const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); if (element == NULL) { @@ -2574,18 +2605,29 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u } element += accessor->offset; - if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint)) + if (index_component_size == out_component_size && accessor->stride == out_component_size) { - memcpy(out, element, index_count * sizeof(cgltf_uint)); + memcpy(out, element, index_count * index_component_size); + return index_count; } - else - { - cgltf_uint* dest = out; - for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride) + // The component size of the output array is larger than the component size of the index data, so index data will be padded. + switch (out_component_size) + { + case 2: + for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride) { - *dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type); + ((uint16_t*)out)[index] = (uint16_t)cgltf_component_read_index(element, accessor->component_type); } + break; + case 4: + for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride) + { + ((uint32_t*)out)[index] = (uint32_t)cgltf_component_read_index(element, accessor->component_type); + } + break; + default: + break; } return index_count; @@ -2596,7 +2638,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u #define CGLTF_ERROR_LEGACY -3 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; } -#define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; } +#define CGLTF_CHECK_TOKTYPE_RET(tok_, type_, ret_) if ((tok_).type != (type_)) { return ret_; } #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; } /* checking size for 0 verifies that a value follows the key */ #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1) @@ -2623,12 +2665,13 @@ static int cgltf_json_to_int(jsmntok_t const* tok, const uint8_t* json_chunk) static cgltf_size cgltf_json_to_size(jsmntok_t const* tok, const uint8_t* json_chunk) { - CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size); + CGLTF_CHECK_TOKTYPE_RET(*tok, JSMN_PRIMITIVE, 0); char tmp[128]; int size = (size_t)(tok->end - tok->start) < sizeof(tmp) ? (int)(tok->end - tok->start) : (int)(sizeof(tmp) - 1); strncpy(tmp, (const char*)json_chunk + tok->start, size); tmp[size] = 0; - return (cgltf_size)CGLTF_ATOLL(tmp); + long long res = CGLTF_ATOLL(tmp); + return res < 0 ? 0 : (cgltf_size)res; } static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk) @@ -2810,6 +2853,11 @@ static void cgltf_parse_attribute_type(const char* name, cgltf_attribute_type* o if (us && *out_type != cgltf_attribute_type_invalid) { *out_index = CGLTF_ATOI(us + 1); + if (*out_index < 0) + { + *out_type = cgltf_attribute_type_invalid; + *out_index = 0; + } } } @@ -3142,6 +3190,31 @@ static int cgltf_parse_json_material_mappings(cgltf_options* options, jsmntok_t return i; } +static cgltf_primitive_type cgltf_json_to_primitive_type(jsmntok_t const* tok, const uint8_t* json_chunk) +{ + int type = cgltf_json_to_int(tok, json_chunk); + + switch (type) + { + case 0: + return cgltf_primitive_type_points; + case 1: + return cgltf_primitive_type_lines; + case 2: + return cgltf_primitive_type_line_loop; + case 3: + return cgltf_primitive_type_line_strip; + case 4: + return cgltf_primitive_type_triangles; + case 5: + return cgltf_primitive_type_triangle_strip; + case 6: + return cgltf_primitive_type_triangle_fan; + default: + return cgltf_primitive_type_invalid; + } +} + static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -3158,9 +3231,7 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0) { ++i; - out_prim->type - = (cgltf_primitive_type) - cgltf_json_to_int(tokens+i, json_chunk); + out_prim->type = cgltf_json_to_primitive_type(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0) @@ -3410,7 +3481,7 @@ static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, cons if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) { ++i; - out_sparse->count = cgltf_json_to_int(tokens + i, json_chunk); + out_sparse->count = cgltf_json_to_size(tokens + i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0) @@ -3546,8 +3617,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) { ++i; - out_accessor->count = - cgltf_json_to_int(tokens+i, json_chunk); + out_accessor->count = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0) @@ -3700,7 +3770,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) { ++i; out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk); @@ -3769,11 +3839,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0) { ++i; - out_pbr->metallic_factor = + out_pbr->metallic_factor = cgltf_json_to_float(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) + else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) { ++i; out_pbr->roughness_factor = @@ -4234,6 +4304,37 @@ static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* return i; } +static int cgltf_parse_json_dispersion(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_dispersion* out_dispersion) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "dispersion") == 0) + { + ++i; + out_dispersion->dispersion = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else + { + i = cgltf_skip_json(tokens, i + 1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -4241,11 +4342,11 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token int size = tokens[i].size; ++i; - for (int j = 0; j < size; ++j) + for (int j = 0; j < size; ++j) { CGLTF_CHECK_KEY(tokens[i]); - if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) + if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) { i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri); } @@ -4325,7 +4426,7 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok = cgltf_json_to_int(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) { ++i; out_sampler->wrap_t @@ -4375,7 +4476,7 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk)); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) { ++i; out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk)); @@ -4627,6 +4728,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_anisotropy = 1; i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_dispersion") == 0) + { + out_material->has_dispersion = 1; + i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->dispersion); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); @@ -4786,7 +4892,7 @@ static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_ else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) { ++i; - out_meshopt_compression->count = cgltf_json_to_int(tokens+i, json_chunk); + out_meshopt_compression->count = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0) diff --git a/raylib/external/rl_gputex.h b/raylib/external/rl_gputex.h index 2cbe596..c577305 100644 --- a/raylib/external/rl_gputex.h +++ b/raylib/external/rl_gputex.h @@ -229,7 +229,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_ } } } - else if (header->ddspf.flags == 0x40 && header->ddspf.rgb_bit_count == 24) // DDS_RGB, no compressed + else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed { int data_size = image_pixel_size*3*sizeof(unsigned char); image_data = RL_MALLOC(data_size); @@ -238,7 +238,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_ *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8; } - else if (header->ddspf.flags == 0x41 && header->ddspf.rgb_bit_count == 32) // DDS_RGBA, no compressed + else if ((header->ddspf.flags == 0x41) && (header->ddspf.rgb_bit_count == 32)) // DDS_RGBA, no compressed { int data_size = image_pixel_size*4*sizeof(unsigned char); image_data = RL_MALLOC(data_size); diff --git a/raylib/external/rprand.h b/raylib/external/rprand.h index c9b460c..ded6708 100644 --- a/raylib/external/rprand.h +++ b/raylib/external/rprand.h @@ -147,8 +147,13 @@ RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static uint64_t rprand_seed = 0; // SplitMix64 actual seed -static uint32_t rprand_state[4] = { 0 }; // Xoshiro128** state, nitialized by SplitMix64 +static uint64_t rprand_seed = 0xAABBCCDD; // SplitMix64 default seed (aligned to rprand_state) +static uint32_t rprand_state[4] = { // Xoshiro128** state, initialized by SplitMix64 + 0x96ea83c1, + 0x218b21e5, + 0xaa91febd, + 0x976414d4 +}; //---------------------------------------------------------------------------------- // Module internal functions declaration @@ -200,10 +205,9 @@ int *rprand_load_sequence(unsigned int count, int min, int max) for (unsigned int i = 0; i < count;) { - value = ((int)rprand_xoshiro()%(abs(max - min) + 1)) + min; - value_is_dup = false; + value = ((unsigned int)rprand_xoshiro()%(abs(max - min) + 1)) + min; - for (int j = 0; j < i; j++) + for (unsigned int j = 0; j < i; j++) { if (sequence[j] == value) { @@ -217,6 +221,8 @@ int *rprand_load_sequence(unsigned int count, int min, int max) sequence[i] = value; i++; } + + value_is_dup = false; } return sequence; diff --git a/raylib/external/sinfl.h b/raylib/external/sinfl.h index 16589c1..3c71737 100644 --- a/raylib/external/sinfl.h +++ b/raylib/external/sinfl.h @@ -171,7 +171,7 @@ extern int zsinflate(void *out, int cap, const void *in, int size); static int sinfl_bsr(unsigned n) { -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) _BitScanReverse(&n, n); return n; #elif defined(__GNUC__) || defined(__clang__) @@ -231,13 +231,13 @@ sinfl_refill(struct sinfl *s) { } static int sinfl_peek(struct sinfl *s, int cnt) { - assert(cnt >= 0 && cnt <= 56); - assert(cnt <= s->bitcnt); + //assert(cnt >= 0 && cnt <= 56); // @raysan5: commented to avoid crash on decompression + //assert(cnt <= s->bitcnt); return s->bitbuf & ((1ull << cnt) - 1); } static void sinfl_eat(struct sinfl *s, int cnt) { - assert(cnt <= s->bitcnt); + //assert(cnt <= s->bitcnt); // @raysan5: commented s->bitbuf >>= cnt; s->bitcnt -= cnt; } diff --git a/raylib/external/vox_loader.h b/raylib/external/vox_loader.h index 6df10b5..0d328c0 100644 --- a/raylib/external/vox_loader.h +++ b/raylib/external/vox_loader.h @@ -123,6 +123,7 @@ typedef struct { // Arrays for mesh build ArrayVector3 vertices; + ArrayVector3 normals; ArrayUShort indices; ArrayColor colors; @@ -292,6 +293,16 @@ const VoxVector3 SolidVertex[] = { {1, 1, 1} //7 }; +const VoxVector3 FacesPerSideNormal[] = { + { -1, 0, 0 }, //-X + {1, 0, 0 }, //+X + {0,-1, 0}, //-Y + {0, 1, 0}, //+Y + {0, 0, -1}, //-Z + {0, 0, 1}, //+Z +}; + + // Allocated VoxArray3D size static void Vox_AllocArray(VoxArray3D* pvoxarray, int _sx, int _sy, int _sz) { @@ -508,6 +519,11 @@ static void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matI insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]); insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]); + insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]); + insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]); + insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]); + insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]); + VoxColor col = pvoxArray->palette[matID]; insertArrayColor(&pvoxArray->colors, col); @@ -653,6 +669,7 @@ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArr // Init Arrays initArrayVector3(&pvoxarray->vertices, 3 * 1024); + initArrayVector3(&pvoxarray->normals, 3 * 1024); initArrayUShort(&pvoxarray->indices, 3 * 1024); initArrayColor(&pvoxarray->colors, 3 * 1024); diff --git a/raylib/platforms/rcore_android.c b/raylib/platforms/rcore_android.c index e0b7fd2..f7b304e 100644 --- a/raylib/platforms/rcore_android.c +++ b/raylib/platforms/rcore_android.c @@ -27,7 +27,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -77,6 +77,175 @@ extern CoreData CORE; // Global CORE state context static PlatformData platform = { 0 }; // Platform specific data +//---------------------------------------------------------------------------------- +// Local Variables Definition +//---------------------------------------------------------------------------------- +#define KEYCODE_MAP_SIZE 162 +static const KeyboardKey KeycodeMap[KEYCODE_MAP_SIZE] = { + KEY_NULL, // AKEYCODE_UNKNOWN + 0, // AKEYCODE_SOFT_LEFT + 0, // AKEYCODE_SOFT_RIGHT + 0, // AKEYCODE_HOME + KEY_BACK, // AKEYCODE_BACK + 0, // AKEYCODE_CALL + 0, // AKEYCODE_ENDCALL + KEY_ZERO, // AKEYCODE_0 + KEY_ONE, // AKEYCODE_1 + KEY_TWO, // AKEYCODE_2 + KEY_THREE, // AKEYCODE_3 + KEY_FOUR, // AKEYCODE_4 + KEY_FIVE, // AKEYCODE_5 + KEY_SIX, // AKEYCODE_6 + KEY_SEVEN, // AKEYCODE_7 + KEY_EIGHT, // AKEYCODE_8 + KEY_NINE, // AKEYCODE_9 + 0, // AKEYCODE_STAR + 0, // AKEYCODE_POUND + KEY_UP, // AKEYCODE_DPAD_UP + KEY_DOWN, // AKEYCODE_DPAD_DOWN + KEY_LEFT, // AKEYCODE_DPAD_LEFT + KEY_RIGHT, // AKEYCODE_DPAD_RIGHT + 0, // AKEYCODE_DPAD_CENTER + KEY_VOLUME_UP, // AKEYCODE_VOLUME_UP + KEY_VOLUME_DOWN, // AKEYCODE_VOLUME_DOWN + 0, // AKEYCODE_POWER + 0, // AKEYCODE_CAMERA + 0, // AKEYCODE_CLEAR + KEY_A, // AKEYCODE_A + KEY_B, // AKEYCODE_B + KEY_C, // AKEYCODE_C + KEY_D, // AKEYCODE_D + KEY_E, // AKEYCODE_E + KEY_F, // AKEYCODE_F + KEY_G, // AKEYCODE_G + KEY_H, // AKEYCODE_H + KEY_I, // AKEYCODE_I + KEY_J, // AKEYCODE_J + KEY_K, // AKEYCODE_K + KEY_L, // AKEYCODE_L + KEY_M, // AKEYCODE_M + KEY_N, // AKEYCODE_N + KEY_O, // AKEYCODE_O + KEY_P, // AKEYCODE_P + KEY_Q, // AKEYCODE_Q + KEY_R, // AKEYCODE_R + KEY_S, // AKEYCODE_S + KEY_T, // AKEYCODE_T + KEY_U, // AKEYCODE_U + KEY_V, // AKEYCODE_V + KEY_W, // AKEYCODE_W + KEY_X, // AKEYCODE_X + KEY_Y, // AKEYCODE_Y + KEY_Z, // AKEYCODE_Z + KEY_COMMA, // AKEYCODE_COMMA + KEY_PERIOD, // AKEYCODE_PERIOD + KEY_LEFT_ALT, // AKEYCODE_ALT_LEFT + KEY_RIGHT_ALT, // AKEYCODE_ALT_RIGHT + KEY_LEFT_SHIFT, // AKEYCODE_SHIFT_LEFT + KEY_RIGHT_SHIFT, // AKEYCODE_SHIFT_RIGHT + KEY_TAB, // AKEYCODE_TAB + KEY_SPACE, // AKEYCODE_SPACE + 0, // AKEYCODE_SYM + 0, // AKEYCODE_EXPLORER + 0, // AKEYCODE_ENVELOPE + KEY_ENTER, // AKEYCODE_ENTER + KEY_BACKSPACE, // AKEYCODE_DEL + KEY_GRAVE, // AKEYCODE_GRAVE + KEY_MINUS, // AKEYCODE_MINUS + KEY_EQUAL, // AKEYCODE_EQUALS + KEY_LEFT_BRACKET, // AKEYCODE_LEFT_BRACKET + KEY_RIGHT_BRACKET, // AKEYCODE_RIGHT_BRACKET + KEY_BACKSLASH, // AKEYCODE_BACKSLASH + KEY_SEMICOLON, // AKEYCODE_SEMICOLON + KEY_APOSTROPHE, // AKEYCODE_APOSTROPHE + KEY_SLASH, // AKEYCODE_SLASH + 0, // AKEYCODE_AT + 0, // AKEYCODE_NUM + 0, // AKEYCODE_HEADSETHOOK + 0, // AKEYCODE_FOCUS + 0, // AKEYCODE_PLUS + KEY_MENU, // AKEYCODE_MENU + 0, // AKEYCODE_NOTIFICATION + 0, // AKEYCODE_SEARCH + 0, // AKEYCODE_MEDIA_PLAY_PAUSE + 0, // AKEYCODE_MEDIA_STOP + 0, // AKEYCODE_MEDIA_NEXT + 0, // AKEYCODE_MEDIA_PREVIOUS + 0, // AKEYCODE_MEDIA_REWIND + 0, // AKEYCODE_MEDIA_FAST_FORWARD + 0, // AKEYCODE_MUTE + KEY_PAGE_UP, // AKEYCODE_PAGE_UP + KEY_PAGE_DOWN, // AKEYCODE_PAGE_DOWN + 0, // AKEYCODE_PICTSYMBOLS + 0, // AKEYCODE_SWITCH_CHARSET + 0, // AKEYCODE_BUTTON_A + 0, // AKEYCODE_BUTTON_B + 0, // AKEYCODE_BUTTON_C + 0, // AKEYCODE_BUTTON_X + 0, // AKEYCODE_BUTTON_Y + 0, // AKEYCODE_BUTTON_Z + 0, // AKEYCODE_BUTTON_L1 + 0, // AKEYCODE_BUTTON_R1 + 0, // AKEYCODE_BUTTON_L2 + 0, // AKEYCODE_BUTTON_R2 + 0, // AKEYCODE_BUTTON_THUMBL + 0, // AKEYCODE_BUTTON_THUMBR + 0, // AKEYCODE_BUTTON_START + 0, // AKEYCODE_BUTTON_SELECT + 0, // AKEYCODE_BUTTON_MODE + KEY_ESCAPE, // AKEYCODE_ESCAPE + KEY_DELETE, // AKEYCODE_FORWARD_DELL + KEY_LEFT_CONTROL, // AKEYCODE_CTRL_LEFT + KEY_RIGHT_CONTROL, // AKEYCODE_CTRL_RIGHT + KEY_CAPS_LOCK, // AKEYCODE_CAPS_LOCK + KEY_SCROLL_LOCK, // AKEYCODE_SCROLL_LOCK + KEY_LEFT_SUPER, // AKEYCODE_META_LEFT + KEY_RIGHT_SUPER, // AKEYCODE_META_RIGHT + 0, // AKEYCODE_FUNCTION + KEY_PRINT_SCREEN, // AKEYCODE_SYSRQ + KEY_PAUSE, // AKEYCODE_BREAK + KEY_HOME, // AKEYCODE_MOVE_HOME + KEY_END, // AKEYCODE_MOVE_END + KEY_INSERT, // AKEYCODE_INSERT + 0, // AKEYCODE_FORWARD + 0, // AKEYCODE_MEDIA_PLAY + 0, // AKEYCODE_MEDIA_PAUSE + 0, // AKEYCODE_MEDIA_CLOSE + 0, // AKEYCODE_MEDIA_EJECT + 0, // AKEYCODE_MEDIA_RECORD + KEY_F1, // AKEYCODE_F1 + KEY_F2, // AKEYCODE_F2 + KEY_F3, // AKEYCODE_F3 + KEY_F4, // AKEYCODE_F4 + KEY_F5, // AKEYCODE_F5 + KEY_F6, // AKEYCODE_F6 + KEY_F7, // AKEYCODE_F7 + KEY_F8, // AKEYCODE_F8 + KEY_F9, // AKEYCODE_F9 + KEY_F10, // AKEYCODE_F10 + KEY_F11, // AKEYCODE_F11 + KEY_F12, // AKEYCODE_F12 + KEY_NUM_LOCK, // AKEYCODE_NUM_LOCK + KEY_KP_0, // AKEYCODE_NUMPAD_0 + KEY_KP_1, // AKEYCODE_NUMPAD_1 + KEY_KP_2, // AKEYCODE_NUMPAD_2 + KEY_KP_3, // AKEYCODE_NUMPAD_3 + KEY_KP_4, // AKEYCODE_NUMPAD_4 + KEY_KP_5, // AKEYCODE_NUMPAD_5 + KEY_KP_6, // AKEYCODE_NUMPAD_6 + KEY_KP_7, // AKEYCODE_NUMPAD_7 + KEY_KP_8, // AKEYCODE_NUMPAD_8 + KEY_KP_9, // AKEYCODE_NUMPAD_9 + KEY_KP_DIVIDE, // AKEYCODE_NUMPAD_DIVIDE + KEY_KP_MULTIPLY, // AKEYCODE_NUMPAD_MULTIPLY + KEY_KP_SUBTRACT, // AKEYCODE_NUMPAD_SUBTRACT + KEY_KP_ADD, // AKEYCODE_NUMPAD_ADD + KEY_KP_DECIMAL, // AKEYCODE_NUMPAD_DOT + 0, // AKEYCODE_NUMPAD_COMMA + KEY_KP_ENTER, // AKEYCODE_NUMPAD_ENTER + KEY_KP_EQUAL // AKEYCODE_NUMPAD_EQUALS +}; + //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- @@ -446,6 +615,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { @@ -478,6 +653,16 @@ void PollInputEvents(void) CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN //CORE.Input.Gamepad.axisCount = 0; + for (int i = 0; i < MAX_GAMEPADS; i++) + { + if (CORE.Input.Gamepad.ready[i]) // Check if gamepad is available + { + // Register previous gamepad states + for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) + CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; + } + } + // Register previous touch states for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; @@ -1018,17 +1203,21 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) return 1; // Handled gamepad button } - // Save current button and its state - // NOTE: Android key action is 0 for down and 1 for up - if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) + KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE) ? KeycodeMap[keycode] : KEY_NULL; + if (key != KEY_NULL) { - CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down + // Save current key and its state + // NOTE: Android key action is 0 for down and 1 for up + if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) + { + CORE.Input.Keyboard.currentKeyState[key] = 1; // Key down - CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; - CORE.Input.Keyboard.keyPressedQueueCount++; + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + else if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_MULTIPLE) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1; + else CORE.Input.Keyboard.currentKeyState[key] = 0; // Key up } - else if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_MULTIPLE) CORE.Input.Keyboard.keyRepeatInFrame[keycode] = 1; - else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up if (keycode == AKEYCODE_POWER) { diff --git a/raylib/platforms/rcore_desktop.c b/raylib/platforms/rcore_desktop.c index 05c390f..f087741 100644 --- a/raylib/platforms/rcore_desktop.c +++ b/raylib/platforms/rcore_desktop.c @@ -30,7 +30,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -74,7 +74,6 @@ //#define GLFW_EXPOSE_NATIVE_X11 // WARNING: Exposing Xlib.h > X.h results in dup symbols for Font type //#define GLFW_EXPOSE_NATIVE_WAYLAND - //#define GLFW_EXPOSE_NATIVE_MIR #include "GLFW/glfw3native.h" // Required for: glfwGetX11Window() #endif #if defined(__APPLE__) @@ -85,15 +84,6 @@ #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow() #endif -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -// TODO: HACK: Added flag if not provided by GLFW when using external library -// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev -#if !defined(GLFW_MOUSE_PASSTHROUGH) - #define GLFW_MOUSE_PASSTHROUGH 0x0002000D -#endif - //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -123,13 +113,14 @@ static void WindowIconifyCallback(GLFWwindow *window, int iconified); static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window +static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale // Input callbacks events static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed -static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value) +static void CharCallback(GLFWwindow *window, unsigned int codepoint); // GLFW3 Char Callback, runs on key pressed (get codepoint value) static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move -static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel +static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Scrolling Callback, runs on mouse wheel static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area static void JoystickCallback(int jid, int event); // GLFW3 Joystick Connected/Disconnected Callback @@ -941,31 +932,8 @@ Vector2 GetWindowPosition(void) // Get window scale DPI factor for current monitor Vector2 GetWindowScaleDPI(void) { - float xdpi = 1.0; - float ydpi = 1.0; - Vector2 scale = { 1.0f, 1.0f }; - Vector2 windowPos = GetWindowPosition(); - - int monitorCount = 0; - GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); - - // Check window monitor - for (int i = 0; i < monitorCount; i++) - { - glfwGetMonitorContentScale(monitors[i], &xdpi, &ydpi); - - int xpos, ypos, width, height; - glfwGetMonitorWorkarea(monitors[i], &xpos, &ypos, &width, &height); - - if ((windowPos.x >= xpos) && (windowPos.x < xpos + width) && - (windowPos.y >= ypos) && (windowPos.y < ypos + height)) - { - scale.x = xdpi; - scale.y = ydpi; - break; - } - } - + Vector2 scale = {0}; + glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); return scale; } @@ -1004,6 +972,8 @@ void EnableCursor(void) // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); + CORE.Input.Mouse.cursorHidden = false; } @@ -1015,6 +985,8 @@ void DisableCursor(void) // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); + CORE.Input.Mouse.cursorHidden = true; } @@ -1072,6 +1044,12 @@ int SetGamepadMappings(const char *mappings) return glfwUpdateGamepadMappings(mappings); } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { @@ -1137,7 +1115,7 @@ void PollInputEvents(void) //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 }; // Map touch position to mouse position for convenience - // WARNING: If the target desktop device supports touch screen, this behavious should be reviewed! + // WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed! // TODO: GLFW does not support multi-touch input just yet // https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch // https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages @@ -1240,6 +1218,19 @@ void PollInputEvents(void) // Module Internal Functions Definition //---------------------------------------------------------------------------------- +static void SetDimensionsFromMonitor(GLFWmonitor *monitor) +{ + const GLFWvidmode *mode = glfwGetVideoMode(monitor); + + // Default display resolution to that of the current mode + CORE.Window.display.width = mode->width; + CORE.Window.display.height = mode->height; + + // Set screen width/height to the display width/height if they are 0 + if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; + if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; +} + // Initialize platform: graphics, inputs and more int InitPlatform(void) { @@ -1380,26 +1371,22 @@ int InitPlatform(void) // REF: https://github.com/raysan5/raylib/issues/1554 glfwSetJoystickCallback(NULL); - // Find monitor resolution - GLFWmonitor *monitor = glfwGetPrimaryMonitor(); - if (!monitor) - { - TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); - return -1; - } - - const GLFWvidmode *mode = glfwGetVideoMode(monitor); - - CORE.Window.display.width = mode->width; - CORE.Window.display.height = mode->height; - - // Set screen width/height to the display width/height if they are 0 - if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; - if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; - + GLFWmonitor *monitor = NULL; if (CORE.Window.fullscreen) { - // remember center for switchinging from fullscreen to window + // According to glfwCreateWindow(), if the user does not have a choice, fullscreen applications + // should default to the primary monitor. + + monitor = glfwGetPrimaryMonitor(); + if (!monitor) + { + TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); + return -1; + } + + SetDimensionsFromMonitor(monitor); + + // Remember center for switching from fullscreen to window if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) { // If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed. @@ -1418,7 +1405,7 @@ int InitPlatform(void) // Obtain recommended CORE.Window.display.width/CORE.Window.display.height from a valid videomode for the monitor int count = 0; - const GLFWvidmode *modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); + const GLFWvidmode *modes = glfwGetVideoModes(monitor, &count); // Get closest video mode to desired CORE.Window.screen.width/CORE.Window.screen.height for (int i = 0; i < count; i++) @@ -1448,21 +1435,55 @@ int InitPlatform(void) // HighDPI monitors are properly considered in a following similar function: SetupViewport() SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL); + platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL); // NOTE: Full-screen change, not working properly... //glfwSetWindowMonitor(platform.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } else { - // If we are windowed fullscreen, ensures that window does not minimize when focus is lost - if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) + // No-fullscreen window creation + bool wantWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0); + + // If we are windowed fullscreen, ensures that window does not minimize when focus is lost. + // This hinting code will not work if the user already specified the correct monitor dimensions; + // at this point we don't know the monitor's dimensions. (Though, how did the user then?) + if (wantWindowedFullscreen) { glfwWindowHint(GLFW_AUTO_ICONIFY, 0); } - // No-fullscreen window creation - platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); + // Default to at least one pixel in size, as creation with a zero dimension is not allowed. + int creationWidth = CORE.Window.screen.width != 0 ? CORE.Window.screen.width : 1; + int creationHeight = CORE.Window.screen.height != 0 ? CORE.Window.screen.height : 1; + + platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); + + // After the window was created, determine the monitor that the window manager assigned. + // Derive display sizes, and, if possible, window size in case it was zero at beginning. + + int monitorCount = 0; + int monitorIndex = GetCurrentMonitor(); + GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); + + if (monitorIndex < monitorCount) + { + monitor = monitors[monitorIndex]; + SetDimensionsFromMonitor(monitor); + + TRACELOG(LOG_INFO, "wantWindowed: %d, size: %dx%d", wantWindowedFullscreen, CORE.Window.screen.width, CORE.Window.screen.height); + if (wantWindowedFullscreen) + { + glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height); + } + } + else + { + // The monitor for the window-manager-created window can not be determined, so it can not be centered. + glfwTerminate(); + TRACELOG(LOG_WARNING, "GLFW: Failed to determine Monitor to center Window"); + return -1; + } if (platform.handle) { @@ -1537,7 +1558,21 @@ int InitPlatform(void) // If graphic device is no properly initialized, we end program if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } - else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2); + else + { + // Try to center window on screen but avoiding window-bar outside of screen + int monitorX = 0; + int monitorY = 0; + int monitorWidth = 0; + int monitorHeight = 0; + glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight); + + int posX = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2; + int posY = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2; + if (posX < monitorX) posX = monitorX; + if (posY < monitorY) posY = monitorY; + SetWindowPosition(posX, posY); + } // Load OpenGL extensions // NOTE: GL procedures address loader is required to load extensions @@ -1553,6 +1588,11 @@ int InitPlatform(void) glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback); glfwSetDropCallback(platform.handle, WindowDropCallback); + if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + { + glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback); + } + // Set input callback events glfwSetKeyCallback(platform.handle, KeyCallback); glfwSetCharCallback(platform.handle, CharCallback); @@ -1581,6 +1621,17 @@ int InitPlatform(void) CORE.Storage.basePath = GetWorkingDirectory(); //---------------------------------------------------------------------------- + char* glfwPlatform = ""; + switch (glfwGetPlatform()) + { + case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break; + case GLFW_PLATFORM_COCOA: glfwPlatform = "Cocoa"; break; + case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break; + case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break; + case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break; + } + + TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully"); return 0; @@ -1638,6 +1689,11 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height) // NOTE: Postprocessing texture is not scaled to new size } +static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley) +{ + CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f); +} + // GLFW3 WindowIconify Callback, runs when window is minimized/restored static void WindowIconifyCallback(GLFWwindow *window, int iconified) { @@ -1714,10 +1770,10 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE); } -// GLFW3 Char Key Callback, runs on key down (gets equivalent unicode char value) -static void CharCallback(GLFWwindow *window, unsigned int key) +// GLFW3 Char Callback, get unicode codepoint value +static void CharCallback(GLFWwindow *window, unsigned int codepoint) { - //TRACELOG(LOG_DEBUG, "Char Callback: KEY:%i(%c)", key, key); + //TRACELOG(LOG_DEBUG, "Char Callback: Codepoint: %i", codepoint); // NOTE: Registers any key down considering OS keyboard layout but // does not detect action events, those should be managed by user... @@ -1728,7 +1784,7 @@ static void CharCallback(GLFWwindow *window, unsigned int key) if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) { // Add character to the queue - CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = key; + CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = codepoint; CORE.Input.Keyboard.charPressedQueueCount++; } } @@ -1739,6 +1795,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int // WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now, // but future releases may add more actions (i.e. GLFW_REPEAT) CORE.Input.Mouse.currentButtonState[button] = action; + CORE.Input.Touch.currentTouchState[button] = action; #if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES) // Process mouse events as touches to be able to use mouse-gestures diff --git a/raylib/platforms/rcore_desktop_sdl.c b/raylib/platforms/rcore_desktop_sdl.c index 96e5570..9dfdd53 100644 --- a/raylib/platforms/rcore_desktop_sdl.c +++ b/raylib/platforms/rcore_desktop_sdl.c @@ -29,7 +29,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -48,8 +48,14 @@ * **********************************************************************************************/ -#include "SDL.h" // SDL base library (window/rendered, input, timming... functionality) -#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer) +#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality) + +#if defined(GRAPHICS_API_OPENGL_ES2) + // It seems it does not need to be included to work + //#include "SDL_opengles2.h" +#else + #include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer) +#endif //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -58,7 +64,7 @@ typedef struct { SDL_Window *window; SDL_GLContext glContext; - SDL_Joystick *gamepad; + SDL_Joystick *gamepad[MAX_GAMEPADS]; SDL_Cursor *cursor; bool cursorRelative; } PlatformData; @@ -493,9 +499,9 @@ void SetWindowIcon(Image image) bmask = 0x001F, amask = 0; depth = 16, pitch = image.width * 2; break; - case PIXELFORMAT_UNCOMPRESSED_R8G8B8: - rmask = 0xFF0000, gmask = 0x00FF00; - bmask = 0x0000FF, amask = 0; + case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // Uses BGR for 24-bit + rmask = 0x0000FF, gmask = 0x00FF00; + bmask = 0xFF0000, amask = 0; depth = 24, pitch = image.width * 3; break; case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: @@ -592,7 +598,7 @@ void SetWindowMonitor(int monitor) // NOTE: // 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3, // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba - // 2. A workround for SDL2 is leaving fullscreen, moving the window, then entering full screen again. + // 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again. const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) ? true : false; const int screenWidth = CORE.Window.screen.width; @@ -611,7 +617,7 @@ void SetWindowMonitor(int monitor) // ending up positioned partly outside the target display. // 2. The workaround for that is, previously to moving the window, // setting the window size to the target display size, so they match. - // 3. It was't done here because we can't assume changing the window size automatically + // 3. It wasn't done here because we can't assume changing the window size automatically // is acceptable behavior by the user. SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y); CORE.Window.position.x = usableBounds.x; @@ -932,9 +938,26 @@ int SetGamepadMappings(const char *mappings) return SDL_GameControllerAddMapping(mappings); } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + //Limit input values to between 0.0f and 1.0f + leftMotor = (0.0f > leftMotor) ? 0.0f : leftMotor; + rightMotor = (0.0f > rightMotor) ? 0.0f : rightMotor; + leftMotor = (1.0f < leftMotor) ? 1.0f : leftMotor; + rightMotor = (1.0f < rightMotor) ? 1.0f : rightMotor; + + if (IsGamepadAvailable(gamepad)) + { + SDL_JoystickRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f)); + } +} + // Set mouse position XY void SetMousePosition(int x, int y) { + SDL_WarpMouseInWindow(platform.window, x, y); + CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; } @@ -948,6 +971,22 @@ void SetMouseCursor(int cursor) CORE.Input.Mouse.cursor = cursor; } +static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event) +{ + CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId); + + for (int i = 0; i < CORE.Input.Touch.pointCount; i++) + { + SDL_Finger *finger = SDL_GetTouchFinger(event.touchId, i); + CORE.Input.Touch.pointId[i] = finger->id; + CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width; + CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height; + CORE.Input.Touch.currentTouchState[i] = 1; + } + + for (int i = CORE.Input.Touch.pointCount; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.currentTouchState[i] = 0; +} + // Register all input events void PollInputEvents(void) { @@ -961,9 +1000,6 @@ void PollInputEvents(void) CORE.Input.Keyboard.keyPressedQueueCount = 0; CORE.Input.Keyboard.charPressedQueueCount = 0; - // Reset key repeats - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; - // Reset mouse wheel CORE.Input.Mouse.currentWheelMove.x = 0; CORE.Input.Mouse.currentWheelMove.y = 0; @@ -973,25 +1009,27 @@ void PollInputEvents(void) else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; // Reset last gamepad button/axis registered state - CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; - for (int i = 0; i < MAX_GAMEPADS; i++) CORE.Input.Gamepad.axisCount[i] = 0; + for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++) + { + // Check if gamepad is available + if (CORE.Input.Gamepad.ready[i]) + { + // Register previous gamepad button states + for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) + { + CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; + } + } + } // Register previous touch states for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; - // Reset touch positions - // TODO: It resets on target platform the mouse position and not filled again until a move-event, - // so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed! - //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 }; - // Map touch position to mouse position for convenience - // WARNING: If the target desktop device supports touch screen, this behavious should be reviewed! - // https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch - // https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE - bool gestureUpdate = false; // Flag to note gestures require to update + bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones // Register previous keys states // NOTE: Android supports up to 260 keys @@ -1004,7 +1042,7 @@ void PollInputEvents(void) // Register previous mouse states for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; - // Poll input events for current plaform + // Poll input events for current platform //----------------------------------------------------------------------------- /* // WARNING: Indexes into this array are obtained by using SDL_Scancode values, not SDL_Keycode values @@ -1070,11 +1108,17 @@ void PollInputEvents(void) CORE.Window.currentFbo.height = height; CORE.Window.resizedLastFrame = true; } break; + case SDL_WINDOWEVENT_ENTER: + { + CORE.Input.Mouse.cursorOnScreen = true; + } break; case SDL_WINDOWEVENT_LEAVE: + { + CORE.Input.Mouse.cursorOnScreen = false; + } break; case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_FOCUS_LOST: - case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_MAXIMIZED: @@ -1087,7 +1131,19 @@ void PollInputEvents(void) case SDL_KEYDOWN: { KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode); - if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 1; + + if (key != KEY_NULL) { + // If key was up, add it to the key pressed queue + if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) + { + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + + CORE.Input.Keyboard.currentKeyState[key] = 1; + } + + if (event.key.repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1; // TODO: Put exitKey verification outside the switch? if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) @@ -1102,6 +1158,21 @@ void PollInputEvents(void) if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0; } break; + case SDL_TEXTINPUT: + { + // NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int) + + int codepointSize = 0; + + // Check if there is space available in the queue + if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) + { + // Add character (codepoint) to the queue + CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = GetCodepointNext(event.text.text, &codepointSize); + CORE.Input.Keyboard.charPressedQueueCount++; + } + } break; + // Check mouse events case SDL_MOUSEBUTTONDOWN: { @@ -1112,9 +1183,9 @@ void PollInputEvents(void) else if (btn == 1) btn = 2; CORE.Input.Mouse.currentButtonState[btn] = 1; + CORE.Input.Touch.currentTouchState[btn] = 1; touchAction = 1; - gestureUpdate = true; } break; case SDL_MOUSEBUTTONUP: { @@ -1125,9 +1196,9 @@ void PollInputEvents(void) else if (btn == 1) btn = 2; CORE.Input.Mouse.currentButtonState[btn] = 0; + CORE.Input.Touch.currentTouchState[btn] = 0; touchAction = 0; - gestureUpdate = true; } break; case SDL_MOUSEWHEEL: { @@ -1150,24 +1221,160 @@ void PollInputEvents(void) CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; touchAction = 2; - gestureUpdate = true; + } break; + + case SDL_FINGERDOWN: + { + UpdateTouchPointsSDL(event.tfinger); + touchAction = 1; + realTouch = true; + } break; + case SDL_FINGERUP: + { + UpdateTouchPointsSDL(event.tfinger); + touchAction = 0; + realTouch = true; + } break; + case SDL_FINGERMOTION: + { + UpdateTouchPointsSDL(event.tfinger); + touchAction = 2; + realTouch = true; } break; // Check gamepad events + case SDL_JOYDEVICEADDED: + { + int jid = event.jdevice.which; + + if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) + { + platform.gamepad[jid] = SDL_JoystickOpen(jid); + + if (platform.gamepad[jid]) + { + CORE.Input.Gamepad.ready[jid] = true; + CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(platform.gamepad[jid]); + CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + strncpy(CORE.Input.Gamepad.name[jid], SDL_JoystickName(platform.gamepad[jid]), 63); + CORE.Input.Gamepad.name[jid][63] = '\0'; + } + else + { + TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); + } + } + } break; + case SDL_JOYDEVICEREMOVED: + { + int jid = event.jdevice.which; + + if (jid == SDL_JoystickInstanceID(platform.gamepad[jid])) + { + SDL_JoystickClose(platform.gamepad[jid]); + platform.gamepad[jid] = SDL_JoystickOpen(0); + CORE.Input.Gamepad.ready[jid] = false; + memset(CORE.Input.Gamepad.name[jid], 0, 64); + } + } break; + case SDL_JOYBUTTONDOWN: + { + int button = -1; + + switch (event.jbutton.button) + { + case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; + case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; + case SDL_CONTROLLER_BUTTON_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; + case SDL_CONTROLLER_BUTTON_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; + + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; + + case SDL_CONTROLLER_BUTTON_BACK: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; + case SDL_CONTROLLER_BUTTON_GUIDE: button = GAMEPAD_BUTTON_MIDDLE; break; + case SDL_CONTROLLER_BUTTON_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; + + case SDL_CONTROLLER_BUTTON_DPAD_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; + + case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = GAMEPAD_BUTTON_LEFT_THUMB; break; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = GAMEPAD_BUTTON_RIGHT_THUMB; break; + default: break; + } + + if (button >= 0) + { + CORE.Input.Gamepad.currentButtonState[event.jbutton.which][button] = 1; + CORE.Input.Gamepad.lastButtonPressed = button; + } + } break; + case SDL_JOYBUTTONUP: + { + int button = -1; + + switch (event.jbutton.button) + { + case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; + case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; + case SDL_CONTROLLER_BUTTON_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; + case SDL_CONTROLLER_BUTTON_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; + + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; + + case SDL_CONTROLLER_BUTTON_BACK: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; + case SDL_CONTROLLER_BUTTON_GUIDE: button = GAMEPAD_BUTTON_MIDDLE; break; + case SDL_CONTROLLER_BUTTON_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; + + case SDL_CONTROLLER_BUTTON_DPAD_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; + + case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = GAMEPAD_BUTTON_LEFT_THUMB; break; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = GAMEPAD_BUTTON_RIGHT_THUMB; break; + default: break; + } + + if (button >= 0) + { + CORE.Input.Gamepad.currentButtonState[event.jbutton.which][button] = 0; + if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; + } + } break; case SDL_JOYAXISMOTION: { - // Motion on gamepad 0 - if (event.jaxis.which == 0) + int axis = -1; + + switch (event.jaxis.axis) { - // X axis motion - if (event.jaxis.axis == 0) + case SDL_CONTROLLER_AXIS_LEFTX: axis = GAMEPAD_AXIS_LEFT_X; break; + case SDL_CONTROLLER_AXIS_LEFTY: axis = GAMEPAD_AXIS_LEFT_Y; break; + case SDL_CONTROLLER_AXIS_RIGHTX: axis = GAMEPAD_AXIS_RIGHT_X; break; + case SDL_CONTROLLER_AXIS_RIGHTY: axis = GAMEPAD_AXIS_RIGHT_Y; break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break; + default: break; + } + + if (axis >= 0) + { + // SDL axis value range is -32768 to 32767, we normalize it to RayLib's -1.0 to 1.0f range + float value = event.jaxis.value / (float) 32767; + CORE.Input.Gamepad.axisState[event.jaxis.which][axis] = value; + + // Register button state for triggers in addition to their axes + if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER)) { - //... - } - // Y axis motion - else if (event.jaxis.axis == 1) - { - //... + int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER) ? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2; + int pressed = (value > 0.1f); + CORE.Input.Gamepad.currentButtonState[event.jaxis.which][button] = pressed; + if (pressed) CORE.Input.Gamepad.lastButtonPressed = button; + else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; } } } break; @@ -1175,7 +1382,7 @@ void PollInputEvents(void) } #if defined(SUPPORT_GESTURES_SYSTEM) - if (gestureUpdate) + if (touchAction > -1) { // Process mouse events as touches to be able to use mouse-gestures GestureEvent gestureEvent = { 0 }; @@ -1190,7 +1397,7 @@ void PollInputEvents(void) gestureEvent.pointCount = 1; // Register touch points position, only one point registered - if (touchAction == 2) gestureEvent.position[0] = CORE.Input.Touch.position[0]; + if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0]; else gestureEvent.position[0] = GetMousePosition(); // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height @@ -1199,6 +1406,8 @@ void PollInputEvents(void) // Gesture data is sent to gestures-system for processing ProcessGestureEvent(gestureEvent); + + touchAction = -1; } #endif } @@ -1212,8 +1421,9 @@ void PollInputEvents(void) // Initialize platform: graphics, inputs and more int InitPlatform(void) { - // Initialize SDL internal global state - int result = SDL_Init(SDL_INIT_EVERYTHING); + // Initialize SDL internal global state, only required systems + // NOTE: Not all systems need to be initialized, SDL_INIT_AUDIO is not required, managed by miniaudio + int result = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER); if (result < 0) { TRACELOG(LOG_WARNING, "SDL: Failed to initialize SDL"); return -1; } // Initialize graphic device: display/window and graphic context @@ -1265,11 +1475,7 @@ int InitPlatform(void) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); -#if defined(__APPLE__) - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // OSX Requires forward compatibility -#else SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); -#endif } else if (rlGetVersion() == RL_OPENGL_43) { @@ -1310,7 +1516,7 @@ int InitPlatform(void) // Init OpenGL context platform.glContext = SDL_GL_CreateContext(platform.window); - // Check window and glContext have been initialized succesfully + // Check window and glContext have been initialized successfully if ((platform.window != NULL) && (platform.glContext != NULL)) { CORE.Window.ready = true; @@ -1345,19 +1551,38 @@ int InitPlatform(void) // Initialize input events system //---------------------------------------------------------------------------- - if (SDL_NumJoysticks() >= 1) + // Initialize gamepads + for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++) { - platform.gamepad = SDL_JoystickOpen(0); - //if (platform.gamepadgamepad == NULL) TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); + platform.gamepad[i] = SDL_JoystickOpen(i); + if (platform.gamepad[i]) + { + CORE.Input.Gamepad.ready[i] = true; + CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(platform.gamepad[i]); + CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + strncpy(CORE.Input.Gamepad.name[i], SDL_JoystickName(platform.gamepad[i]), 63); + CORE.Input.Gamepad.name[i][63] = '\0'; + } + else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); } + // Disable mouse events being interpreted as touch events + // NOTE: This is wanted because there are SDL_FINGER* events available which provide unique data + // Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES + SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); + SDL_EventState(SDL_DROPFILE, SDL_ENABLE); //---------------------------------------------------------------------------- - // Initialize timming system + // Initialize timing system //---------------------------------------------------------------------------- // NOTE: No need to call InitTimer(), let SDL manage it internally CORE.Time.previous = GetTime(); // Get time as double + + #if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP) + SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); // SDL equivalent of timeBeginPeriod() and timeEndPeriod() + #endif //---------------------------------------------------------------------------- // Initialize storage system diff --git a/raylib/platforms/rcore_drm.c b/raylib/platforms/rcore_drm.c index bdfc9e0..ba60714 100644 --- a/raylib/platforms/rcore_drm.c +++ b/raylib/platforms/rcore_drm.c @@ -29,7 +29,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -59,39 +59,37 @@ #include // Linux: Keycodes constants definition (KEY_A, ...) #include // Linux: Joystick support library -#include // Generic Buffer Management (native platform for EGL on DRM) -#include // Direct Rendering Manager user-level library interface -#include // Direct Rendering Manager mode setting (KMS) interface +// WARNING: Both 'linux/input.h' and 'raylib.h' define KEY_F12 +// To avoid conflict with the capturing code in rcore.c we undefine the macro KEY_F12, +// so the enum KEY_F12 from raylib is used +#undef KEY_F12 -#include "EGL/egl.h" // Native platform windowing system interface -#include "EGL/eglext.h" // EGL extensions +#include // Generic Buffer Management (native platform for EGL on DRM) +#include // Direct Rendering Manager user-level library interface +#include // Direct Rendering Manager mode setting (KMS) interface + +#include "EGL/egl.h" // Native platform windowing system interface +#include "EGL/eglext.h" // EGL extensions + +#ifndef EGL_OPENGL_ES3_BIT + #define EGL_OPENGL_ES3_BIT 0x40 +#endif //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event number -#define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...) #define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events +// So actually the biggest key is KEY_CNT but we only really map the keys up to +// KEY_ALS_TOGGLE +#define KEYMAP_SIZE KEY_ALS_TOGGLE + //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef struct { - pthread_t threadId; // Event reading thread id - - int fd; // File descriptor to the device it is assigned to - int eventNum; // Number of 'event' device - Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) - int touchSlot; // Hold the touch slot number of the currently being sent multitouch block - bool isMouse; // True if device supports relative X Y movements - bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH - bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH - bool isKeyboard; // True if device has letter keycodes - bool isGamepad; // True if device has gamepad buttons -} InputEventWorker; - typedef struct { // Display data int fd; // File descriptor for /dev/dri/... @@ -108,9 +106,6 @@ typedef struct { EGLContext context; // Graphic context, mode in which drawing can be done EGLConfig config; // Graphic config - // Input data - InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event" - // Keyboard data int defaultKeyboardMode; // Default keyboard mode bool eventKeyboardMode; // Keyboard in event mode @@ -128,9 +123,10 @@ typedef struct { int touchSlot; // Hold the touch slot number of the currently being sent multitouch block // Gamepad data - pthread_t gamepadThreadId; // Gamepad reading thread id int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor - + int gamepadAbsAxisRange[MAX_GAMEPADS][MAX_GAMEPAD_AXIS][2]; // [0] = min, [1] = range value of the axis + int gamepadAbsAxisMap[MAX_GAMEPADS][ABS_CNT]; // Maps the axes gamepads from the evdev api to a sequential one + int gamepadCount; // The number of gamepads registered } PlatformData; //---------------------------------------------------------------------------------- @@ -143,55 +139,98 @@ static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- // Local Variables Definition //---------------------------------------------------------------------------------- -// Scancode to keycode mapping for US keyboards -// TODO: Replace this with a keymap from the X11 to get the correct regional map for the keyboard: -// Currently non US keyboards will have the wrong mapping for some keys -static const int keymapUS[] = { - 0, 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 258, 81, 87, 69, 82, 84, - 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 96, - 340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, 332, 342, 32, 280, 290, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 282, 281, 327, 328, 329, 333, 324, 325, - 326, 334, 321, 322, 323, 320, 330, 0, 85, 86, 300, 301, 89, 90, 91, 92, 93, 94, 95, - 335, 345, 331, 283, 346, 101, 268, 265, 266, 263, 262, 269, 264, 267, 260, 261, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 347, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 0, 0, 0, 0, 0, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0 -}; // NOTE: The complete evdev EV_KEY list can be found at /usr/include/linux/input-event-codes.h // TODO: Complete the LUT with all unicode decimal values -static const int EvkeyToUnicodeLUT[] = { +// TODO: Replace this with a keymap from the X11 to get the correct regional map for the keyboard: +// Currently non US keyboards will have the wrong mapping for some keys +// NOTE: Replacing this with the keymap from X11 would probably be useless, as people use the drm +// backend to *avoid* X11 +static const int evkeyToUnicodeLUT[] = { 0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8, 0, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 0, 0, 13, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 96, 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 32 // LUT currently incomplete, just mapped the most essential keys }; +// This is the map used to map any keycode returned from linux to a raylib code from 'raylib.h' +// NOTE: Use short here to save a little memory +static const short linuxToRaylibMap[KEYMAP_SIZE] = { + // We don't map those with designated initialization, because we would getting + // into loads of naming conflicts + 0, 256, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 48, 45, 61, 259, 258, + 81, 87, 69, 82, 84, 89, 85, 73, + 79, 80, 91, 93, 257, 341, 65, 83, + 68, 70, 71, 72, 74, 75, 76, 59, + 39, 96, 340, 92, 90, 88, 67, 86, + 66, 78, 77, 44, 46, 47, 344, 332, + 342, 32, 280, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 282, 281, 327, + 328, 329, 333, 324, 325, 326, 334, 321, + 322, 323, 320, 330, 0, 85, 86, 300, + 301, 89, 90, 91, 92, 93, 94, 95, + 335, 345, 331, 283, 346, 101, 268, 265, + 266, 263, 262, 269, 264, 267, 260, 261, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 347, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 0, 0, 0, 0, 0, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 0, 0, 0, 0, 0, 0, 0, + + // Gamepads are mapped according to: + // https://www.kernel.org/doc/html/next/input/gamepad.html + // Those mappings are standardized, but that doesn't mean people follow + // the standards, so this is more of an approximation + [BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP, + [BTN_DPAD_RIGHT] = GAMEPAD_BUTTON_LEFT_FACE_RIGHT, + [BTN_DPAD_DOWN] = GAMEPAD_BUTTON_LEFT_FACE_DOWN, + [BTN_DPAD_LEFT] = GAMEPAD_BUTTON_LEFT_FACE_LEFT, + [BTN_Y] = GAMEPAD_BUTTON_RIGHT_FACE_UP, + [BTN_B] = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, + [BTN_A] = GAMEPAD_BUTTON_RIGHT_FACE_DOWN, + [BTN_X] = GAMEPAD_BUTTON_RIGHT_FACE_LEFT, + [BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1, + [BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2, + [BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1, + [BTN_TR2] GAMEPAD_BUTTON_RIGHT_TRIGGER_2, + [BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT, + [BTN_MODE] = GAMEPAD_BUTTON_MIDDLE, + [BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT, + [BTN_THUMBL] = GAMEPAD_BUTTON_LEFT_THUMB, + [BTN_THUMBR] = GAMEPAD_BUTTON_RIGHT_THUMB, +}; + //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- int InitPlatform(void); // Initialize platform (graphics, inputs and more) void ClosePlatform(void); // Close platform +#if defined(SUPPORT_SSH_KEYBOARD_RPI) static void InitKeyboard(void); // Initialize raw keyboard system static void RestoreKeyboard(void); // Restore keyboard system -#if defined(SUPPORT_SSH_KEYBOARD_RPI) static void ProcessKeyboard(void); // Process keyboard events #endif static void InitEvdevInput(void); // Initialize evdev inputs static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate static void PollKeyboardEvents(void); // Process evdev keyboard events -static void *EventThread(void *arg); // Input device events reading thread - -static void InitGamepad(void); // Initialize raw gamepad input -static void *GamepadThread(void *arg); // Mouse reading thread +static void PollGamepadEvents(void); // Process evdev gamepad events +static void PollMouseEvents(void); // Process evdev mouse events static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list @@ -349,29 +388,69 @@ Vector2 GetMonitorPosition(int monitor) // Get selected monitor width (currently used by monitor) int GetMonitorWidth(int monitor) { - TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform"); - return 0; + int width = 0; + + if (monitor != 0) + { + TRACELOG(LOG_WARNING, "GetMonitorWidth() implemented for first monitor only"); + } + else if ((platform.connector) && (platform.modeIndex >= 0)) + { + width = platform.connector->modes[platform.modeIndex].hdisplay; + } + + return width; } // Get selected monitor height (currently used by monitor) int GetMonitorHeight(int monitor) { - TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform"); - return 0; + int height = 0; + + if (monitor != 0) + { + TRACELOG(LOG_WARNING, "GetMonitorHeight() implemented for first monitor only"); + } + else if ((platform.connector) && (platform.modeIndex >= 0)) + { + height = platform.connector->modes[platform.modeIndex].vdisplay; + } + + return height; } // Get selected monitor physical width in millimetres int GetMonitorPhysicalWidth(int monitor) { - TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform"); - return 0; + int physicalWidth = 0; + + if (monitor != 0) + { + TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() implemented for first monitor only"); + } + else if ((platform.connector) && (platform.modeIndex >= 0)) + { + physicalWidth = platform.connector->mmWidth; + } + + return physicalWidth; } // Get selected monitor physical height in millimetres int GetMonitorPhysicalHeight(int monitor) { - TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform"); - return 0; + int physicalHeight = 0; + + if (monitor != 0) + { + TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() implemented for first monitor only"); + } + else if ((platform.connector) && (platform.modeIndex >= 0)) + { + physicalHeight = platform.connector->mmHeight; + } + + return physicalHeight; } // Get selected monitor refresh rate @@ -390,8 +469,18 @@ int GetMonitorRefreshRate(int monitor) // Get the human-readable, UTF-8 encoded name of the selected monitor const char *GetMonitorName(int monitor) { - TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform"); - return ""; + const char *name = ""; + + if (monitor != 0) + { + TRACELOG(LOG_WARNING, "GetMonitorName() implemented for first monitor only"); + } + else if ((platform.connector) && (platform.modeIndex >= 0)) + { + name = platform.connector->modes[platform.modeIndex].name; + } + + return name; } // Get window position XY on monitor @@ -520,6 +609,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { @@ -546,9 +641,6 @@ void PollInputEvents(void) CORE.Input.Keyboard.keyPressedQueueCount = 0; CORE.Input.Keyboard.charPressedQueueCount = 0; - // Reset key repeats - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; - // Reset last gamepad button/axis registered state CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN //CORE.Input.Gamepad.axisCount = 0; @@ -562,6 +654,15 @@ void PollInputEvents(void) PollKeyboardEvents(); +#if defined(SUPPORT_SSH_KEYBOARD_RPI) + // NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here. + // stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console + if (!platform.eventKeyboardMode) ProcessKeyboard(); +#endif + + // Check exit key + if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true; + // Register previous mouse position if (platform.cursorRelative) CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f }; else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; @@ -570,21 +671,16 @@ void PollInputEvents(void) CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove; CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove; platform.eventWheelMove = (Vector2){ 0.0f, 0.0f }; + for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) { CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; CORE.Input.Mouse.currentButtonState[i] = platform.currentButtonStateEvdev[i]; + CORE.Input.Touch.currentTouchState[i] = platform.currentButtonStateEvdev[i]; } // Register gamepads buttons events - for (int i = 0; i < MAX_GAMEPADS; i++) - { - if (CORE.Input.Gamepad.ready[i]) - { - // Register previous gamepad states - for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; - } - } + PollGamepadEvents(); // Register previous touch states for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; @@ -595,192 +691,8 @@ void PollInputEvents(void) // Map touch position to mouse position for convenience CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; -#if defined(SUPPORT_SSH_KEYBOARD_RPI) - // NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here. - // stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console - - if (!platform.eventKeyboardMode) ProcessKeyboard(); - - // NOTE: Mouse input events polling is done asynchronously in another pthread - EventThread() - // NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread() -#endif - // Handle the mouse/touch/gestures events: - // NOTE: Replaces the EventThread handling that is now commented. - { - int fd = platform.mouseFd; - if (fd == -1) return; - - struct input_event event = { 0 }; - - int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE - bool gestureUpdate = false; // Flag to note gestures require to update - - // Try to read data from the mouse/touch/gesture and only continue if successful - while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) - { - // Relative movement parsing - if (event.type == EV_REL) - { - if (event.code == REL_X) - { - if (platform.cursorRelative) - { - CORE.Input.Mouse.currentPosition.x = event.value; - CORE.Input.Mouse.previousPosition.x = 0.0f; - } - else CORE.Input.Mouse.currentPosition.x += event.value; - CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x; - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - if (event.code == REL_Y) - { - if (platform.cursorRelative) - { - CORE.Input.Mouse.currentPosition.y = event.value; - CORE.Input.Mouse.previousPosition.y = 0.0f; - } - else CORE.Input.Mouse.currentPosition.y += event.value; - CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y; - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value; - } - - // Absolute movement parsing - if (event.type == EV_ABS) - { - // Basic movement - if (event.code == ABS_X) - { - CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange - CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - if (event.code == ABS_Y) - { - CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - // Multitouch movement - if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events - - if (event.code == ABS_MT_POSITION_X) - { - if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange - } - - if (event.code == ABS_MT_POSITION_Y) - { - if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - } - - if (event.code == ABS_MT_TRACKING_ID) - { - if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS)) - { - // Touch has ended for this point - CORE.Input.Touch.position[platform.touchSlot].x = -1; - CORE.Input.Touch.position[platform.touchSlot].y = -1; - } - } - - // Touchscreen tap - if (event.code == ABS_PRESSURE) - { - int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT]; - - if (!event.value && previousMouseLeftButtonState) - { - platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; - - touchAction = 0; // TOUCH_ACTION_UP - gestureUpdate = true; - } - - if (event.value && !previousMouseLeftButtonState) - { - platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; - - touchAction = 1; // TOUCH_ACTION_DOWN - gestureUpdate = true; - } - } - - } - - // Button parsing - if (event.type == EV_KEY) - { - // Mouse button parsing - if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT)) - { - platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value; - - if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN - else touchAction = 0; // TOUCH_ACTION_UP - gestureUpdate = true; - } - - if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; - if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value; - if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value; - if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value; - if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value; - if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value; - } - - // Screen confinement - if (!CORE.Input.Mouse.cursorHidden) - { - if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; - if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; - - if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; - if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; - } - - // Update touch point count - CORE.Input.Touch.pointCount = 0; - for (int i = 0; i < MAX_TOUCH_POINTS; i++) - { - if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++; - } - -#if defined(SUPPORT_GESTURES_SYSTEM) - if (gestureUpdate) - { - GestureEvent gestureEvent = { 0 }; - - gestureEvent.touchAction = touchAction; - gestureEvent.pointCount = CORE.Input.Touch.pointCount; - - for (int i = 0; i < MAX_TOUCH_POINTS; i++) - { - gestureEvent.pointId[i] = i; - gestureEvent.position[i] = CORE.Input.Touch.position[i]; - } - - ProcessGestureEvent(gestureEvent); - - gestureUpdate = false; - } -#endif - } - } + PollMouseEvents(); } //---------------------------------------------------------------------------------- @@ -1138,8 +1050,10 @@ int InitPlatform(void) // Initialize input events system //---------------------------------------------------------------------------- InitEvdevInput(); // Evdev inputs initialization - InitGamepad(); // Gamepad init + +#if defined(SUPPORT_SSH_KEYBOARD_RPI) InitKeyboard(); // Keyboard init (stdin) +#endif //---------------------------------------------------------------------------- // Initialize storage system @@ -1218,30 +1132,29 @@ void ClosePlatform(void) platform.device = EGL_NO_DISPLAY; } - // Wait for mouse and gamepad threads to finish before closing - // NOTE: Those threads should already have finished at this point - // because they are controlled by CORE.Window.shouldClose variable - CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called - // Close the evdev keyboard + // Close the evdev devices + + if (platform.mouseFd != -1) { + close(platform.mouseFd); + platform.mouseFd = -1; + } + + for (int i = 0; i < platform.gamepadCount; i++) + { + close(platform.gamepadStreamFd[i]); + platform.gamepadStreamFd[i] = -1; + } + if (platform.keyboardFd != -1) { close(platform.keyboardFd); platform.keyboardFd = -1; } - - for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i) - { - if (platform.eventWorker[i].threadId) - { - pthread_join(platform.eventWorker[i].threadId, NULL); - } - } - - if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL); } +#if defined(SUPPORT_SSH_KEYBOARD_RPI) // Initialize Keyboard system (using standard input) static void InitKeyboard(void) { @@ -1273,7 +1186,7 @@ static void InitKeyboard(void) int result = ioctl(STDIN_FILENO, KDGKBMODE, &platform.defaultKeyboardMode); // In case of failure, it could mean a remote keyboard is used (SSH) - if (result < 0) TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode, an SSH keyboard is probably used"); + if (result < 0) TRACELOG(LOG_WARNING, "DRM: Failed to change keyboard mode, an SSH keyboard is probably used"); else { // Reconfigure keyboard mode to get: @@ -1299,7 +1212,6 @@ static void RestoreKeyboard(void) ioctl(STDIN_FILENO, KDSKBMODE, platform.defaultKeyboardMode); } -#if defined(SUPPORT_SSH_KEYBOARD_RPI) // Process keyboard inputs static void ProcessKeyboard(void) { @@ -1400,18 +1312,6 @@ static void ProcessKeyboard(void) CORE.Input.Keyboard.keyPressedQueueCount++; } } - - // Check exit key (same functionality as GLFW3 KeyCallback()) - if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true; - -#if defined(SUPPORT_SCREEN_CAPTURE) - // Check screen capture key (raylib key: KEY_F12) - if (CORE.Input.Keyboard.currentKeyState[301] == 1) - { - TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); - screenshotCounter++; - } -#endif } #endif // SUPPORT_SSH_KEYBOARD_RPI @@ -1425,6 +1325,7 @@ static void InitEvdevInput(void) // Initialise keyboard file descriptor platform.keyboardFd = -1; + platform.mouseFd = -1; // Reset variables for (int i = 0; i < MAX_TOUCH_POINTS; ++i) @@ -1457,7 +1358,7 @@ static void InitEvdevInput(void) closedir(directory); } - else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH); + else TRACELOG(LOG_WARNING, "INPUT: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH); } // Identifies a input device and configures it for use if appropriate @@ -1470,62 +1371,18 @@ static void ConfigureEvdevDevice(char *device) #define LONG(x) ((x)/BITS_PER_LONG) #define TEST_BIT(array, bit) ((array[LONG(bit)] >> OFF(bit)) & 1) - struct input_absinfo absinfo = { 0 }; unsigned long evBits[NBITS(EV_MAX)] = { 0 }; unsigned long absBits[NBITS(ABS_MAX)] = { 0 }; unsigned long relBits[NBITS(REL_MAX)] = { 0 }; unsigned long keyBits[NBITS(KEY_MAX)] = { 0 }; - bool hasAbs = false; - bool hasRel = false; - bool hasAbsMulti = false; - int freeWorkerId = -1; - int fd = -1; - - InputEventWorker *worker = NULL; - - // Open the device and allocate worker - //------------------------------------------------------------------------------------------------------- - // Find a free spot in the workers array - for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i) - { - if (platform.eventWorker[i].threadId == 0) - { - freeWorkerId = i; - break; - } - } - - // Select the free worker from array - if (freeWorkerId >= 0) - { - worker = &(platform.eventWorker[freeWorkerId]); // Grab a pointer to the worker - memset(worker, 0, sizeof(InputEventWorker)); // Clear the worker - } - else - { - TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread for %s, out of worker slots", device); - return; - } // Open the device - fd = open(device, O_RDONLY | O_NONBLOCK); + int fd = open(device, O_RDONLY | O_NONBLOCK); if (fd < 0) { - TRACELOG(LOG_WARNING, "RPI: Failed to open input device: %s", device); + TRACELOG(LOG_WARNING, "DRM: Failed to open input device: %s", device); return; } - worker->fd = fd; - - // Grab number on the end of the devices name "event" - int devNum = 0; - char *ptrDevName = strrchr(device, 't'); - worker->eventNum = -1; - - if (ptrDevName != NULL) - { - if (sscanf(ptrDevName, "t%d", &devNum) == 1) worker->eventNum = devNum; - } - else worker->eventNum = 0; // TODO: HACK: Grab number for mouse0 device! // At this point we have a connection to the device, but we don't yet know what the device is. // It could be many things, even as simple as a power button... @@ -1533,149 +1390,173 @@ static void ConfigureEvdevDevice(char *device) // Identify the device //------------------------------------------------------------------------------------------------------- - ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the available device properties + struct { + bool exist; + struct input_absinfo info; + } absinfo[ABS_CNT] = { 0 }; + + // These flags aren't really a one of + // Some devices could have properties we assosciate with keyboards as well as properties + // we assosciate with mice + bool isKeyboard = false; + bool isMouse = false; + bool isTouch = false; + bool isGamepad = false; + + int absAxisCount = 0; + + ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); + ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits); - // Check for absolute input devices if (TEST_BIT(evBits, EV_ABS)) { ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits); - // Check for absolute movement support (usually touchscreens, but also joysticks) - if (TEST_BIT(absBits, ABS_X) && TEST_BIT(absBits, ABS_Y)) + // If the device has an X an Y axis it's either a touch device, a special mouse or a gamepad + bool hasAbsXY = TEST_BIT(absBits, ABS_X) && TEST_BIT(absBits, ABS_Y); + + if (hasAbsXY) { - hasAbs = true; + absAxisCount += 2; - // Get the scaling values - ioctl(fd, EVIOCGABS(ABS_X), &absinfo); - worker->absRange.x = absinfo.minimum; - worker->absRange.width = absinfo.maximum - absinfo.minimum; - platform.absRange.x = absinfo.minimum; - platform.absRange.width = absinfo.maximum - absinfo.minimum; + absinfo[ABS_X].exist = true; + absinfo[ABS_Y].exist = true; - ioctl(fd, EVIOCGABS(ABS_Y), &absinfo); - worker->absRange.y = absinfo.minimum; - worker->absRange.height = absinfo.maximum - absinfo.minimum; - platform.absRange.y = absinfo.minimum; - platform.absRange.height = absinfo.maximum - absinfo.minimum; + ioctl(fd, EVIOCGABS(ABS_X), &absinfo[ABS_X].info); + ioctl(fd, EVIOCGABS(ABS_Y), &absinfo[ABS_Y].info); } - // Check for multiple absolute movement support (usually multitouch touchscreens) - if (TEST_BIT(absBits, ABS_MT_POSITION_X) && TEST_BIT(absBits, ABS_MT_POSITION_Y)) + // If it has any of these buttons it's a touch device + if (hasAbsXY && + (TEST_BIT(keyBits, BTN_STYLUS) || + TEST_BIT(keyBits, BTN_TOOL_PEN) || + TEST_BIT(keyBits, BTN_TOOL_FINGER) || + TEST_BIT(keyBits, BTN_TOUCH))) isTouch = true; + + // Absolute mice should really only exist with VMWare, but it shouldn't + // matter if we support them + else if (hasAbsXY && TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true; + + // If any of the common joystick axis is present, we assume it's a gamepad + else { - hasAbsMulti = true; + for (int axis = (hasAbsXY? ABS_Z : ABS_X); axis < ABS_PRESSURE; axis++) + { + if (TEST_BIT(absBits, axis)) + { + absinfo[axis].exist = true; + isGamepad = true; + absAxisCount++; - // Get the scaling values - ioctl(fd, EVIOCGABS(ABS_X), &absinfo); - worker->absRange.x = absinfo.minimum; - worker->absRange.width = absinfo.maximum - absinfo.minimum; - platform.absRange.x = absinfo.minimum; - platform.absRange.width = absinfo.maximum - absinfo.minimum; - - ioctl(fd, EVIOCGABS(ABS_Y), &absinfo); - worker->absRange.y = absinfo.minimum; - worker->absRange.height = absinfo.maximum - absinfo.minimum; - platform.absRange.y = absinfo.minimum; - platform.absRange.height = absinfo.maximum - absinfo.minimum; + ioctl(fd, EVIOCGABS(axis), &absinfo[axis].info); + } + } } + + // If the device has multitouch axes, it's a touch device + if (TEST_BIT(absBits, ABS_MT_POSITION_X) && + TEST_BIT(absBits, ABS_MT_POSITION_Y)) isTouch = true; } - // Check for relative movement support (usually mouse) if (TEST_BIT(evBits, EV_REL)) { ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits); - if (TEST_BIT(relBits, REL_X) && TEST_BIT(relBits, REL_Y)) hasRel = true; + // If it has any of the gamepad or touch features we tested so far, it's not a mouse + if (!isTouch && + !isGamepad && + TEST_BIT(relBits, REL_X) && + TEST_BIT(relBits, REL_Y) && + TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true; } - // Check for button support to determine the device type(usually on all input devices) + if (TEST_BIT(evBits, EV_KEY)) { - ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits); + // The first 32 keys as defined in input-event-codes.h are pretty much + // exclusive to keyboards, so we can test them using a mask + // Leave out the first bit to not test KEY_RESERVED + const unsigned long mask = 0xFFFFFFFE; + if ((keyBits[0] & mask) == mask) isKeyboard = true; - if (hasAbs || hasAbsMulti) + // If we find any of the common gamepad buttons we assume it's a gamepad + else { - if (TEST_BIT(keyBits, BTN_TOUCH)) worker->isTouch = true; // This is a touchscreen - if (TEST_BIT(keyBits, BTN_TOOL_FINGER)) worker->isTouch = true; // This is a drawing tablet - if (TEST_BIT(keyBits, BTN_TOOL_PEN)) worker->isTouch = true; // This is a drawing tablet - if (TEST_BIT(keyBits, BTN_STYLUS)) worker->isTouch = true; // This is a drawing tablet - if (worker->isTouch || hasAbsMulti) worker->isMultitouch = true; // This is a multitouch capable device - } - - if (hasRel) - { - if (TEST_BIT(keyBits, BTN_LEFT)) worker->isMouse = true; // This is a mouse - if (TEST_BIT(keyBits, BTN_RIGHT)) worker->isMouse = true; // This is a mouse - } - - if (TEST_BIT(keyBits, BTN_A)) worker->isGamepad = true; // This is a gamepad - if (TEST_BIT(keyBits, BTN_TRIGGER)) worker->isGamepad = true; // This is a gamepad - if (TEST_BIT(keyBits, BTN_START)) worker->isGamepad = true; // This is a gamepad - if (TEST_BIT(keyBits, BTN_TL)) worker->isGamepad = true; // This is a gamepad - if (TEST_BIT(keyBits, BTN_TL)) worker->isGamepad = true; // This is a gamepad - - if (TEST_BIT(keyBits, KEY_SPACE)) worker->isKeyboard = true; // This is a keyboard - } - //------------------------------------------------------------------------------------------------------- - - // Decide what to do with the device - //------------------------------------------------------------------------------------------------------- - if (worker->isKeyboard && (platform.keyboardFd == -1)) - { - // Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a - // keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate - // threads so that they don't drop events when the frame rate is slow. - TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device); - platform.keyboardFd = worker->fd; - } - else if (worker->isTouch || worker->isMouse) - { - // Looks like an interesting device - TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s)", device, - worker->isMouse? "mouse " : "", - worker->isMultitouch? "multitouch " : "", - worker->isTouch? "touchscreen " : "", - worker->isGamepad? "gamepad " : ""); - platform.mouseFd = worker->fd; - - // NOTE: moved the mouse/touch/gesture input to PollInputEvents()/ - // so added the "platform.mouseFd = worker->fd;" line above - // and commented the thread code below: - - // Create a thread for this device - //int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker); - //if (error != 0) - //{ - // TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread: %s (error: %d)", device, error); - // worker->threadId = 0; - // close(fd); - //} - -#if defined(USE_LAST_TOUCH_DEVICE) - // Find touchscreen with the highest index - int maxTouchNumber = -1; - - for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i) - { - if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = platform.eventWorker[i].eventNum; - } - - // Find touchscreens with lower indexes - for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i) - { - if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum < maxTouchNumber)) + for (int button = BTN_JOYSTICK; button < BTN_DIGI; ++button) { - if (platform.eventWorker[i].threadId != 0) + if (TEST_BIT(keyBits, button)) isGamepad = true; + } + + for (int button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40; button++) + { + if (TEST_BIT(keyBits, button)) isGamepad = true; + } + } + } + + const char *deviceKindStr = "unknown"; + if (isMouse || isTouch) + { + deviceKindStr = "mouse"; + if (platform.mouseFd != -1) close(platform.mouseFd); + platform.mouseFd = fd; + + if (absAxisCount > 0) + { + platform.absRange.x = absinfo[ABS_X].info.minimum; + platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum; + + platform.absRange.y = absinfo[ABS_Y].info.minimum; + platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; + } + } + else if (isGamepad && !isMouse && !isKeyboard && platform.gamepadCount < MAX_GAMEPADS) + { + deviceKindStr = "gamepad"; + int index = platform.gamepadCount++; + + platform.gamepadStreamFd[index] = fd; + CORE.Input.Gamepad.ready[index] = true; + + ioctl(platform.gamepadStreamFd[index], EVIOCGNAME(64), &CORE.Input.Gamepad.name[index]); + CORE.Input.Gamepad.axisCount[index] = absAxisCount; + + if (absAxisCount > 0) + { + // TODO / NOTE + // So gamepad axis (as in the actual linux joydev.c) are just simply enumerated + // and (at least for some input drivers like xpat) it's convention to use + // ABS_X, ABX_Y for one joystick ABS_RX, ABS_RY for the other and the Z axes for the + // shoulder buttons + // If these are now enumerated you get LJOY_X, LJOY_Y, LEFT_SHOULDERB, RJOY_X, ... + // That means they don't match the GamepadAxis enum + // This could be fixed + int axisIndex = 0; + for (int axis = ABS_X; axis < ABS_PRESSURE; axis++) + { + if (absinfo[axis].exist) { - TRACELOG(LOG_WARNING, "RPI: Found duplicate touchscreen, killing touchscreen on event: %d", i); - pthread_cancel(platform.eventWorker[i].threadId); - close(platform.eventWorker[i].fd); + platform.gamepadAbsAxisRange[index][axisIndex][0] = absinfo[axisIndex].info.minimum; + platform.gamepadAbsAxisRange[index][axisIndex][1] = absinfo[axisIndex].info.maximum - absinfo[axisIndex].info.minimum; + + platform.gamepadAbsAxisMap[index][axis] = axisIndex; + axisIndex++; } } } -#endif } - else close(fd); // We are not interested in this device - //------------------------------------------------------------------------------------------------------- + else if (isKeyboard && (platform.keyboardFd == -1)) + { + deviceKindStr = "keyboard"; + platform.keyboardFd = fd; + } + else + { + close(fd); + return; + } + + TRACELOG(LOG_INFO, "INPUT: Initialized input device %s as %s", device, deviceKindStr); } // Poll and process evdev keyboard events @@ -1690,338 +1571,272 @@ static void PollKeyboardEvents(void) // Try to read data from the keyboard and only continue if successful while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) { - // Button parsing - if (event.type == EV_KEY) - { -#if defined(SUPPORT_SSH_KEYBOARD_RPI) - // Change keyboard mode to events - platform.eventKeyboardMode = true; -#endif - // Keyboard button parsing - if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255 - { - keycode = keymapUS[event.code & 0xFF]; // The code we get is a scancode so we look up the appropriate keycode + // Check if the event is a key event + if (event.type != EV_KEY) continue; - // Make sure we got a valid keycode - if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState))) +#if defined(SUPPORT_SSH_KEYBOARD_RPI) + // If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard + platform.eventKeyboardMode = true; +#endif + + // Keyboard keys appear for codes 1 to 255, ignore everthing else + if ((event.code >= 1) && (event.code <= 255)) + { + + // Lookup the scancode in the keymap to get a keycode + keycode = linuxToRaylibMap[event.code]; + + // Make sure we got a valid keycode + if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS)) + { + + // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt + // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL, + // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat + CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1); + CORE.Input.Keyboard.keyRepeatInFrame[keycode] = (event.value == 2); + + // If the key is pressed add it to the queues + if (event.value == 1) { - // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt - // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL, - // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat - CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0; - if (event.value >= 1) + if (CORE.Input.Keyboard.keyPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) { - CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; CORE.Input.Keyboard.keyPressedQueueCount++; } - #if defined(SUPPORT_SCREEN_CAPTURE) - // Check screen capture key (raylib key: KEY_F12) - if (CORE.Input.Keyboard.currentKeyState[301] == 1) + if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) { - TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); - screenshotCounter++; + // TODO/FIXME: This is not actually converting to unicode properly because it's not taking things like shift into account + CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = evkeyToUnicodeLUT[event.code]; + CORE.Input.Keyboard.charPressedQueueCount++; } - #endif - - // Detect char presses (unicode) - if (event.value == 1) - { - // Check if there is space available in the queue - if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) - { - // Add character to the queue - CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = EvkeyToUnicodeLUT[event.code]; - CORE.Input.Keyboard.charPressedQueueCount++; - } - } - - if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true; - - TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", (event.value == 0)? "UP" : "DOWN", event.code, keycode); } + + TRACELOG(LOG_DEBUG, "INPUT: KEY_%s Keycode(linux): %4i KeyCode(raylib): %4i", (event.value == 0) ? "UP " : "DOWN", event.code, keycode); } } } } -// Input device events reading thread -static void *EventThread(void *arg) +// Poll gamepad input events +static void PollGamepadEvents(void) { -/* + // Read gamepad event struct input_event event = { 0 }; - InputEventWorker *worker = (InputEventWorker *)arg; - int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE - bool gestureUpdate = false; // Flag to note gestures require to update - - while (!CORE.Window.shouldClose) + for (int i = 0; i < platform.gamepadCount; i++) { - // Try to read data from the device and only continue if successful - while (read(worker->fd, &event, sizeof(event)) == (int)sizeof(event)) + if (!CORE.Input.Gamepad.ready[i]) continue; + + // Register previous gamepad states + for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; + + while (read(platform.gamepadStreamFd[i], &event, sizeof(event)) == (int)sizeof(event)) { - // Relative movement parsing - if (event.type == EV_REL) - { - if (event.code == REL_X) - { - if (platform.cursorRelative) - { - CORE.Input.Mouse.currentPosition.x -= event.value; - CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x; - } - else - { - CORE.Input.Mouse.currentPosition.x += event.value; - CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x; - } - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - if (event.code == REL_Y) - { - if (platform.cursorRelative) - { - CORE.Input.Mouse.currentPosition.y -= event.value; - CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y; - } - else - { - CORE.Input.Mouse.currentPosition.y += event.value; - CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y; - } - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value; - } - - // Absolute movement parsing - if (event.type == EV_ABS) - { - // Basic movement - if (event.code == ABS_X) - { - CORE.Input.Mouse.currentPosition.x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale according to absRange - CORE.Input.Touch.position[0].x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale according to absRange - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - if (event.code == ABS_Y) - { - CORE.Input.Mouse.currentPosition.y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale according to absRange - CORE.Input.Touch.position[0].y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale according to absRange - - touchAction = 2; // TOUCH_ACTION_MOVE - gestureUpdate = true; - } - - // Multitouch movement - if (event.code == ABS_MT_SLOT) worker->touchSlot = event.value; // Remember the slot number for the folowing events - - if (event.code == ABS_MT_POSITION_X) - { - if (worker->touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[worker->touchSlot].x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale according to absRange - } - - if (event.code == ABS_MT_POSITION_Y) - { - if (worker->touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[worker->touchSlot].y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale according to absRange - } - - if (event.code == ABS_MT_TRACKING_ID) - { - if ((event.value < 0) && (worker->touchSlot < MAX_TOUCH_POINTS)) - { - // Touch has ended for this point - CORE.Input.Touch.position[worker->touchSlot].x = -1; - CORE.Input.Touch.position[worker->touchSlot].y = -1; - } - } - - // Touchscreen tap - if (event.code == ABS_PRESSURE) - { - int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT]; - - if (!event.value && previousMouseLeftButtonState) - { - platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; - - touchAction = 0; // TOUCH_ACTION_UP - gestureUpdate = true; - } - - if (event.value && !previousMouseLeftButtonState) - { - platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; - - touchAction = 1; // TOUCH_ACTION_DOWN - gestureUpdate = true; - } - } - - } - - // Button parsing if (event.type == EV_KEY) { - // Mouse button parsing - if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT)) + if (event.code < KEYMAP_SIZE) { - platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value; + short keycodeRaylib = linuxToRaylibMap[event.code]; - if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN - else touchAction = 0; // TOUCH_ACTION_UP - gestureUpdate = true; - } + TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0) ? "UP " : "DOWN", event.code, keycodeRaylib); - if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; - if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value; - if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value; - if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value; - if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value; - if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value; - } - - // Screen confinement - if (!CORE.Input.Mouse.cursorHidden) - { - if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; - if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; - - if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; - if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; - } - - // Update touch point count - CORE.Input.Touch.pointCount = 0; - for (int i = 0; i < MAX_TOUCH_POINTS; i++) - { - if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++; - } - -#if defined(SUPPORT_GESTURES_SYSTEM) - if (gestureUpdate) - { - GestureEvent gestureEvent = { 0 }; - - gestureEvent.touchAction = touchAction; - gestureEvent.pointCount = CORE.Input.Touch.pointCount; - - for (int i = 0; i < MAX_TOUCH_POINTS; i++) - { - gestureEvent.pointId[i] = i; - gestureEvent.position[i] = CORE.Input.Touch.position[i]; - } - - ProcessGestureEvent(gestureEvent); - } -#endif - } - - WaitTime(0.005); // Sleep for 5ms to avoid hogging CPU time - } - - close(worker->fd); -*/ - return NULL; -} - -// Initialize gamepad system -static void InitGamepad(void) -{ - char gamepadDev[128] = { 0 }; - - for (int i = 0; i < MAX_GAMEPADS; i++) - { - sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i); - - if ((platform.gamepadStreamFd[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0) - { - // NOTE: Only show message for first gamepad - if (i == 0) TRACELOG(LOG_WARNING, "RPI: Failed to open Gamepad device, no gamepad available"); - } - else - { - CORE.Input.Gamepad.ready[i] = true; - - // NOTE: Only create one thread - if (i == 0) - { - int error = pthread_create(&platform.gamepadThreadId, NULL, &GamepadThread, NULL); - - if (error != 0) TRACELOG(LOG_WARNING, "RPI: Failed to create gamepad input event thread"); - else TRACELOG(LOG_INFO, "RPI: Gamepad device initialized successfully"); - } - - ioctl(platform.gamepadStreamFd[i], JSIOCGNAME(64), &CORE.Input.Gamepad.name[i]); - ioctl(platform.gamepadStreamFd[i], JSIOCGAXES, &CORE.Input.Gamepad.axisCount[i]); - } - } -} - -// Process Gamepad (/dev/input/js0) -static void *GamepadThread(void *arg) -{ - #define JS_EVENT_BUTTON 0x01 // Button pressed/released - #define JS_EVENT_AXIS 0x02 // Joystick axis moved - #define JS_EVENT_INIT 0x80 // Initial state of device - - struct js_event { - unsigned int time; // event timestamp in milliseconds - short value; // event value - unsigned char type; // event type - unsigned char number; // event axis/button number - }; - - // Read gamepad event - struct js_event gamepadEvent = { 0 }; - - while (!CORE.Window.shouldClose) - { - for (int i = 0; i < MAX_GAMEPADS; i++) - { - if (read(platform.gamepadStreamFd[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event)) - { - gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events - - // Process gamepad events by type - if (gamepadEvent.type == JS_EVENT_BUTTON) - { - //TRACELOG(LOG_WARNING, "RPI: Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value); - - if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) + if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS)) { // 1 - button pressed, 0 - button released - CORE.Input.Gamepad.currentButtonState[i][gamepadEvent.number] = (int)gamepadEvent.value; + CORE.Input.Gamepad.currentButtonState[i][keycodeRaylib] = event.value; - if ((int)gamepadEvent.value == 1) CORE.Input.Gamepad.lastButtonPressed = gamepadEvent.number; - else CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN - } - } - else if (gamepadEvent.type == JS_EVENT_AXIS) - { - //TRACELOG(LOG_WARNING, "RPI: Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value); - - if (gamepadEvent.number < MAX_GAMEPAD_AXIS) - { - // NOTE: Scaling of gamepadEvent.value to get values between -1..1 - CORE.Input.Gamepad.axisState[i][gamepadEvent.number] = (float)gamepadEvent.value/32768; + CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycodeRaylib : GAMEPAD_BUTTON_UNKNOWN; + } + } + } + else if (event.type == EV_ABS) + { + if (event.code < ABS_CNT) + { + int axisRaylib = platform.gamepadAbsAxisMap[i][event.code]; + + TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: Axis: %2i Value: %i", i, axisRaylib, event.value); + + if (axisRaylib < MAX_GAMEPAD_AXIS) + { + int min = platform.gamepadAbsAxisRange[i][event.code][0]; + int range = platform.gamepadAbsAxisRange[i][event.code][1]; + + // NOTE: Scaling of event.value to get values between -1..1 + CORE.Input.Gamepad.axisState[i][axisRaylib] = (2 * (float)(event.value - min) / range) - 1; } } } - else WaitTime(0.001); // Sleep for 1 ms to avoid hogging CPU time } } +} - return NULL; +// Poll mouse input events +static void PollMouseEvents(void) +{ + int fd = platform.mouseFd; + if (fd == -1) return; + + struct input_event event = { 0 }; + int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE + + // Try to read data from the mouse/touch/gesture and only continue if successful + while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) + { + // Relative movement parsing + if (event.type == EV_REL) + { + if (event.code == REL_X) + { + if (platform.cursorRelative) + { + CORE.Input.Mouse.currentPosition.x = event.value; + CORE.Input.Mouse.previousPosition.x = 0.0f; + } + else CORE.Input.Mouse.currentPosition.x += event.value; + + CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x; + touchAction = 2; // TOUCH_ACTION_MOVE + } + + if (event.code == REL_Y) + { + if (platform.cursorRelative) + { + CORE.Input.Mouse.currentPosition.y = event.value; + CORE.Input.Mouse.previousPosition.y = 0.0f; + } + else CORE.Input.Mouse.currentPosition.y += event.value; + + CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y; + touchAction = 2; // TOUCH_ACTION_MOVE + } + + if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value; + } + + // Absolute movement parsing + if (event.type == EV_ABS) + { + // Basic movement + if (event.code == ABS_X) + { + CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange + CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange + + touchAction = 2; // TOUCH_ACTION_MOVE + } + + if (event.code == ABS_Y) + { + CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange + CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange + + touchAction = 2; // TOUCH_ACTION_MOVE + } + + // Multitouch movement + if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events + + if (event.code == ABS_MT_POSITION_X) + { + if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange + } + + if (event.code == ABS_MT_POSITION_Y) + { + if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange + } + + if (event.code == ABS_MT_TRACKING_ID) + { + if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS)) + { + // Touch has ended for this point + CORE.Input.Touch.position[platform.touchSlot].x = -1; + CORE.Input.Touch.position[platform.touchSlot].y = -1; + } + } + + // Touchscreen tap + if (event.code == ABS_PRESSURE) + { + int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT]; + + if (!event.value && previousMouseLeftButtonState) + { + platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; + touchAction = 0; // TOUCH_ACTION_UP + } + + if (event.value && !previousMouseLeftButtonState) + { + platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; + touchAction = 1; // TOUCH_ACTION_DOWN + } + } + + } + + // Button parsing + if (event.type == EV_KEY) + { + // Mouse button parsing + if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT)) + { + platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value; + + if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN + else touchAction = 0; // TOUCH_ACTION_UP + } + + if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; + if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value; + if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value; + if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value; + if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value; + if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value; + } + + // Screen confinement + if (!CORE.Input.Mouse.cursorHidden) + { + if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; + if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; + + if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; + if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; + } + + // Update touch point count + CORE.Input.Touch.pointCount = 0; + for (int i = 0; i < MAX_TOUCH_POINTS; i++) + { + if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++; + } + +#if defined(SUPPORT_GESTURES_SYSTEM) + if (touchAction > -1) + { + GestureEvent gestureEvent = { 0 }; + + gestureEvent.touchAction = touchAction; + gestureEvent.pointCount = CORE.Input.Touch.pointCount; + + for (int i = 0; i < MAX_TOUCH_POINTS; i++) + { + gestureEvent.pointId[i] = i; + gestureEvent.position[i] = CORE.Input.Touch.position[i]; + } + + ProcessGestureEvent(gestureEvent); + + touchAction = -1; + } +#endif + } } // Search matching DRM mode in connector's mode list diff --git a/raylib/raudio.c b/raylib/raudio.c index 101b72e..4a140c5 100644 --- a/raylib/raudio.c +++ b/raylib/raudio.c @@ -53,7 +53,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -170,6 +170,10 @@ typedef struct tagBITMAPINFOHEADER { #define MA_NO_WAV #define MA_NO_FLAC #define MA_NO_MP3 +#define MA_NO_RESOURCE_MANAGER +#define MA_NO_NODE_GRAPH +#define MA_NO_ENGINE +#define MA_NO_GENERATION // Threading model: Default: [0] COINIT_MULTITHREADED: COM calls objects on any thread (free threading) #define MA_COINIT_VALUE 2 // [2] COINIT_APARTMENTTHREADED: Each object has its own thread (apartment model) @@ -409,12 +413,23 @@ static AudioData AUDIO = { // Global AUDIO context // Module specific Functions Declaration //---------------------------------------------------------------------------------- static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage); + +// Reads audio data from an AudioBuffer object in internal/device formats +static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount); +static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount); + static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount); static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer); +static bool IsAudioBufferPlayingInLockedState(AudioBuffer *buffer); +static void StopAudioBufferInLockedState(AudioBuffer *buffer); +static void UpdateAudioStreamInLockedState(AudioStream stream, const void *data, int frameCount); + #if defined(RAUDIO_STANDALONE) static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension static const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes the dot: .png) +static const char *GetFileName(const char *filePath); // Get pointer to filename for a path string +static const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) static unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) static bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write) @@ -439,6 +454,7 @@ void SetAudioBufferPan(AudioBuffer *buffer, float pan); void TrackAudioBuffer(AudioBuffer *buffer); void UntrackAudioBuffer(AudioBuffer *buffer); + //---------------------------------------------------------------------------------- // Module Functions Definition - Audio Device initialization and Closing //---------------------------------------------------------------------------------- @@ -457,12 +473,12 @@ void InitAudioDevice(void) } // Init audio device - // NOTE: Using the default device. Format is floating point because it simplifies mixing. + // NOTE: Using the default device. Format is floating point because it simplifies mixing ma_device_config config = ma_device_config_init(ma_device_type_playback); - config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device. + config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device config.playback.format = AUDIO_DEVICE_FORMAT; config.playback.channels = AUDIO_DEVICE_CHANNELS; - config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device. + config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device config.capture.format = ma_format_s16; config.capture.channels = 1; config.sampleRate = AUDIO_DEVICE_SAMPLE_RATE; @@ -478,7 +494,7 @@ void InitAudioDevice(void) } // Mixing happens on a separate thread which means we need to synchronize. I'm using a mutex here to make things simple, but may - // want to look at something a bit smarter later on to keep everything real-time, if that's necessary. + // want to look at something a bit smarter later on to keep everything real-time, if that's necessary if (ma_mutex_init(&AUDIO.System.lock) != MA_SUCCESS) { TRACELOG(LOG_WARNING, "AUDIO: Failed to create mutex for mixing"); @@ -488,7 +504,7 @@ void InitAudioDevice(void) } // Keep the device running the whole time. May want to consider doing something a bit smarter and only have the device running - // while there's at least one sound being played. + // while there's at least one sound being played result = ma_device_start(&AUDIO.System.device); if (result != MA_SUCCESS) { @@ -499,7 +515,7 @@ void InitAudioDevice(void) } TRACELOG(LOG_INFO, "AUDIO: Device initialized successfully"); - TRACELOG(LOG_INFO, " > Backend: miniaudio / %s", ma_get_backend_name(AUDIO.System.context.backend)); + TRACELOG(LOG_INFO, " > Backend: miniaudio | %s", ma_get_backend_name(AUDIO.System.context.backend)); TRACELOG(LOG_INFO, " > Format: %s -> %s", ma_get_format_name(AUDIO.System.device.playback.format), ma_get_format_name(AUDIO.System.device.playback.internalFormat)); TRACELOG(LOG_INFO, " > Channels: %d -> %d", AUDIO.System.device.playback.channels, AUDIO.System.device.playback.internalChannels); TRACELOG(LOG_INFO, " > Sample rate: %d -> %d", AUDIO.System.device.sampleRate, AUDIO.System.device.playback.internalSampleRate); @@ -609,69 +625,77 @@ void UnloadAudioBuffer(AudioBuffer *buffer) { if (buffer != NULL) { - ma_data_converter_uninit(&buffer->converter, NULL); UntrackAudioBuffer(buffer); + ma_data_converter_uninit(&buffer->converter, NULL); RL_FREE(buffer->data); RL_FREE(buffer); } } -// Check if an audio buffer is playing +// Check if an audio buffer is playing from a program state without lock bool IsAudioBufferPlaying(AudioBuffer *buffer) { bool result = false; - - if (buffer != NULL) result = (buffer->playing && !buffer->paused); - + ma_mutex_lock(&AUDIO.System.lock); + result = IsAudioBufferPlayingInLockedState(buffer); + ma_mutex_unlock(&AUDIO.System.lock); return result; } // Play an audio buffer -// NOTE: Buffer is restarted to the start. -// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained. +// NOTE: Buffer is restarted to the start +// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained void PlayAudioBuffer(AudioBuffer *buffer) { if (buffer != NULL) { + ma_mutex_lock(&AUDIO.System.lock); buffer->playing = true; buffer->paused = false; buffer->frameCursorPos = 0; + ma_mutex_unlock(&AUDIO.System.lock); } } -// Stop an audio buffer +// Stop an audio buffer from a program state without lock void StopAudioBuffer(AudioBuffer *buffer) { - if (buffer != NULL) - { - if (IsAudioBufferPlaying(buffer)) - { - buffer->playing = false; - buffer->paused = false; - buffer->frameCursorPos = 0; - buffer->framesProcessed = 0; - buffer->isSubBufferProcessed[0] = true; - buffer->isSubBufferProcessed[1] = true; - } - } + ma_mutex_lock(&AUDIO.System.lock); + StopAudioBufferInLockedState(buffer); + ma_mutex_unlock(&AUDIO.System.lock); } // Pause an audio buffer void PauseAudioBuffer(AudioBuffer *buffer) { - if (buffer != NULL) buffer->paused = true; + if (buffer != NULL) + { + ma_mutex_lock(&AUDIO.System.lock); + buffer->paused = true; + ma_mutex_unlock(&AUDIO.System.lock); + } } // Resume an audio buffer void ResumeAudioBuffer(AudioBuffer *buffer) { - if (buffer != NULL) buffer->paused = false; + if (buffer != NULL) + { + ma_mutex_lock(&AUDIO.System.lock); + buffer->paused = false; + ma_mutex_unlock(&AUDIO.System.lock); + } } // Set volume for an audio buffer void SetAudioBufferVolume(AudioBuffer *buffer, float volume) { - if (buffer != NULL) buffer->volume = volume; + if (buffer != NULL) + { + ma_mutex_lock(&AUDIO.System.lock); + buffer->volume = volume; + ma_mutex_unlock(&AUDIO.System.lock); + } } // Set pitch for an audio buffer @@ -679,7 +703,8 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch) { if ((buffer != NULL) && (pitch > 0.0f)) { - // Pitching is just an adjustment of the sample rate. + ma_mutex_lock(&AUDIO.System.lock); + // Pitching is just an adjustment of the sample rate // Note that this changes the duration of the sound: // - higher pitches will make the sound faster // - lower pitches make it slower @@ -687,6 +712,7 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch) ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate); buffer->pitch = pitch; + ma_mutex_unlock(&AUDIO.System.lock); } } @@ -696,7 +722,12 @@ void SetAudioBufferPan(AudioBuffer *buffer, float pan) if (pan < 0.0f) pan = 0.0f; else if (pan > 1.0f) pan = 1.0f; - if (buffer != NULL) buffer->pan = pan; + if (buffer != NULL) + { + ma_mutex_lock(&AUDIO.System.lock); + buffer->pan = pan; + ma_mutex_unlock(&AUDIO.System.lock); + } } // Track audio buffer to linked list next position @@ -749,7 +780,7 @@ Wave LoadWave(const char *fileName) // Loading wave from memory data if (fileData != NULL) wave = LoadWaveFromMemory(GetFileExtension(fileName), fileData, dataSize); - RL_FREE(fileData); + UnloadFileData(fileData); return wave; } @@ -867,11 +898,15 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int // Checks if wave data is ready bool IsWaveReady(Wave wave) { - return ((wave.data != NULL) && // Validate wave data available - (wave.frameCount > 0) && // Validate frame count - (wave.sampleRate > 0) && // Validate sample rate is supported - (wave.sampleSize > 0) && // Validate sample size is supported - (wave.channels > 0)); // Validate number of channels supported + bool result = false; + + if ((wave.data != NULL) && // Validate wave data available + (wave.frameCount > 0) && // Validate frame count + (wave.sampleRate > 0) && // Validate sample rate is supported + (wave.sampleSize > 0) && // Validate sample size is supported + (wave.channels > 0)) result = true; // Validate number of channels supported + + return result; } // Load sound from file @@ -895,15 +930,15 @@ Sound LoadSoundFromWave(Wave wave) if (wave.data != NULL) { - // When using miniaudio we need to do our own mixing. + // When using miniaudio we need to do our own mixing // To simplify this we need convert the format of each sound to be consistent with // the format used to open the playback AUDIO.System.device. We can do this two ways: // - // 1) Convert the whole sound in one go at load time (here). - // 2) Convert the audio data in chunks at mixing time. + // 1) Convert the whole sound in one go at load time (here) + // 2) Convert the audio data in chunks at mixing time // - // First option has been selected, format conversion is done on the loading stage. - // The downside is that it uses more memory if the original sound is u8 or s16. + // First option has been selected, format conversion is done on the loading stage + // The downside is that it uses more memory if the original sound is u8 or s16 ma_format formatIn = ((wave.sampleSize == 8)? ma_format_u8 : ((wave.sampleSize == 16)? ma_format_s16 : ma_format_f32)); ma_uint32 frameCountIn = wave.frameCount; @@ -938,12 +973,14 @@ Sound LoadSoundAlias(Sound source) if (source.stream.buffer->data != NULL) { - AudioBuffer* audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC); + AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC); + if (audioBuffer == NULL) { TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer"); - return sound; // early return to avoid dereferencing the audioBuffer null pointer + return sound; // Early return to avoid dereferencing the audioBuffer null pointer } + audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames; audioBuffer->volume = source.stream.buffer->volume; audioBuffer->data = source.stream.buffer->data; @@ -962,11 +999,15 @@ Sound LoadSoundAlias(Sound source) // Checks if a sound is ready bool IsSoundReady(Sound sound) { - return ((sound.frameCount > 0) && // Validate frame count - (sound.stream.buffer != NULL) && // Validate stream buffer - (sound.stream.sampleRate > 0) && // Validate sample rate is supported - (sound.stream.sampleSize > 0) && // Validate sample size is supported - (sound.stream.channels > 0)); // Validate number of channels supported + bool result = false; + + if ((sound.frameCount > 0) && // Validate frame count + (sound.stream.buffer != NULL) && // Validate stream buffer + (sound.stream.sampleRate > 0) && // Validate sample rate is supported + (sound.stream.sampleSize > 0) && // Validate sample size is supported + (sound.stream.channels > 0)) result = true; // Validate number of channels supported + + return result; } // Unload wave data @@ -985,11 +1026,11 @@ void UnloadSound(Sound sound) void UnloadSoundAlias(Sound alias) { - // untrack and unload just the sound buffer, not the sample data, it is shared with the source for the alias + // Untrack and unload just the sound buffer, not the sample data, it is shared with the source for the alias if (alias.stream.buffer != NULL) { - ma_data_converter_uninit(&alias.stream.buffer->converter, NULL); UntrackAudioBuffer(alias.stream.buffer); + ma_data_converter_uninit(&alias.stream.buffer->converter, NULL); RL_FREE(alias.stream.buffer); } } @@ -1001,7 +1042,6 @@ void UpdateSound(Sound sound, const void *data, int frameCount) { StopAudioBuffer(sound.stream.buffer); - // TODO: May want to lock/unlock this since this data buffer is read at mixing time memcpy(sound.stream.buffer->data, data, frameCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.formatIn, sound.stream.buffer->converter.channelsIn)); } } @@ -1076,8 +1116,9 @@ bool ExportWaveAsCode(Wave wave, const char *fileName) int waveDataSize = wave.frameCount*wave.channels*wave.sampleSize/8; // NOTE: Text data buffer size is estimated considering wave data size in bytes - // and requiring 6 char bytes for every byte: "0x00, " - char *txtData = (char *)RL_CALLOC(waveDataSize*6 + 2000, sizeof(char)); + // and requiring 12 char bytes for every byte; the actual size varies, but + // the longest possible char being appended is "%.4ff,\n ", which is 12 bytes. + char *txtData = (char *)RL_CALLOC(waveDataSize*12 + 2000, sizeof(char)); int byteCount = 0; byteCount += sprintf(txtData + byteCount, "\n//////////////////////////////////////////////////////////////////////////////////\n"); @@ -1087,7 +1128,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName) byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2023 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2024 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n"); @@ -1096,7 +1137,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName) strcpy(varFileName, GetFileNameWithoutExt(fileName)); for (int i = 0; varFileName[i] != '\0'; i++) if (varFileName[i] >= 'a' && varFileName[i] <= 'z') { varFileName[i] = varFileName[i] - 32; } - //Add wave information + // Add wave information byteCount += sprintf(txtData + byteCount, "// Wave data information\n"); byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount); byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_RATE %u\n", varFileName, wave.sampleRate); @@ -1157,7 +1198,11 @@ void StopSound(Sound sound) // Check if a sound is playing bool IsSoundPlaying(Sound sound) { - return IsAudioBufferPlaying(sound.stream.buffer); + bool result = false; + + if (IsAudioBufferPlaying(sound.stream.buffer)) result = true; + + return result; } // Set volume for a sound @@ -1292,11 +1337,10 @@ Music LoadMusicStream(const char *fileName) drwav *ctxWav = RL_CALLOC(1, sizeof(drwav)); bool success = drwav_init_file(ctxWav, fileName, NULL); - music.ctxType = MUSIC_AUDIO_WAV; - music.ctxData = ctxWav; - if (success) { + music.ctxType = MUSIC_AUDIO_WAV; + music.ctxData = ctxWav; int sampleSize = ctxWav->bitsPerSample; if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream() @@ -1305,17 +1349,23 @@ Music LoadMusicStream(const char *fileName) music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + drwav_uninit(ctxWav); + RL_FREE(ctxWav); + } } #endif #if defined(SUPPORT_FILEFORMAT_OGG) else if (IsFileExtension(fileName, ".ogg")) { // Open ogg audio stream - music.ctxType = MUSIC_AUDIO_OGG; - music.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL); + stb_vorbis *ctxOgg = stb_vorbis_open_filename(fileName, NULL, NULL); - if (music.ctxData != NULL) + if (ctxOgg != NULL) { + music.ctxType = MUSIC_AUDIO_OGG; + music.ctxData = ctxOgg; stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)music.ctxData); // Get Ogg file info // OGG bit rate defaults to 16 bit, it's enough for compressed format @@ -1326,6 +1376,10 @@ Music LoadMusicStream(const char *fileName) music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + stb_vorbis_close(ctxOgg); + } } #endif #if defined(SUPPORT_FILEFORMAT_MP3) @@ -1334,27 +1388,30 @@ Music LoadMusicStream(const char *fileName) drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3)); int result = drmp3_init_file(ctxMp3, fileName, NULL); - music.ctxType = MUSIC_AUDIO_MP3; - music.ctxData = ctxMp3; - if (result > 0) { + music.ctxType = MUSIC_AUDIO_MP3; + music.ctxData = ctxMp3; music.stream = LoadAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels); music.frameCount = (unsigned int)drmp3_get_pcm_frame_count(ctxMp3); music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + RL_FREE(ctxMp3); + } } #endif #if defined(SUPPORT_FILEFORMAT_QOA) else if (IsFileExtension(fileName, ".qoa")) { qoaplay_desc *ctxQoa = qoaplay_open(fileName); - music.ctxType = MUSIC_AUDIO_QOA; - music.ctxData = ctxQoa; - if (ctxQoa->file != NULL) + if (ctxQoa != NULL) { + music.ctxType = MUSIC_AUDIO_QOA; + music.ctxData = ctxQoa; // NOTE: We are loading samples are 32bit float normalized data, so, // we configure the output audio stream to also use float 32bit music.stream = LoadAudioStream(ctxQoa->info.samplerate, 32, ctxQoa->info.channels); @@ -1362,23 +1419,27 @@ Music LoadMusicStream(const char *fileName) music.looping = true; // Looping enabled by default musicLoaded = true; } + else{} //No uninit required } #endif #if defined(SUPPORT_FILEFORMAT_FLAC) else if (IsFileExtension(fileName, ".flac")) { - music.ctxType = MUSIC_AUDIO_FLAC; - music.ctxData = drflac_open_file(fileName, NULL); + drflac *ctxFlac = drflac_open_file(fileName, NULL); - if (music.ctxData != NULL) + if (ctxFlac != NULL) { - drflac *ctxFlac = (drflac *)music.ctxData; - + music.ctxType = MUSIC_AUDIO_FLAC; + music.ctxData = ctxFlac; music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount; music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + drflac_free(ctxFlac, NULL); + } } #endif #if defined(SUPPORT_FILEFORMAT_XM) @@ -1387,11 +1448,10 @@ Music LoadMusicStream(const char *fileName) jar_xm_context_t *ctxXm = NULL; int result = jar_xm_create_context_from_file(&ctxXm, AUDIO.System.device.sampleRate, fileName); - music.ctxType = MUSIC_MODULE_XM; - music.ctxData = ctxXm; - if (result == 0) // XM AUDIO.System.context created successfully { + music.ctxType = MUSIC_MODULE_XM; + music.ctxData = ctxXm; jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops unsigned int bits = 32; @@ -1402,9 +1462,13 @@ Music LoadMusicStream(const char *fileName) music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, AUDIO_DEVICE_CHANNELS); music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo) music.looping = true; // Looping enabled by default - jar_xm_reset(ctxXm); // make sure we start at the beginning of the song + jar_xm_reset(ctxXm); // Make sure we start at the beginning of the song musicLoaded = true; } + else + { + jar_xm_free_context(ctxXm); + } } #endif #if defined(SUPPORT_FILEFORMAT_MOD) @@ -1414,47 +1478,27 @@ Music LoadMusicStream(const char *fileName) jar_mod_init(ctxMod); int result = jar_mod_load_file(ctxMod, fileName); - music.ctxType = MUSIC_MODULE_MOD; - music.ctxData = ctxMod; - if (result > 0) { + music.ctxType = MUSIC_MODULE_MOD; + music.ctxData = ctxMod; // NOTE: Only stereo is supported for MOD music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, 16, AUDIO_DEVICE_CHANNELS); music.frameCount = (unsigned int)jar_mod_max_samples(ctxMod); // NOTE: Always 2 channels (stereo) music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + jar_mod_unload(ctxMod); + RL_FREE(ctxMod); + } } #endif else TRACELOG(LOG_WARNING, "STREAM: [%s] File format not supported", fileName); if (!musicLoaded) { - if (false) { } - #if defined(SUPPORT_FILEFORMAT_WAV) - else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_OGG) - else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_MP3) - else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); } - #endif - #if defined(SUPPORT_FILEFORMAT_QOA) - else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_FLAC) - else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL); - #endif - #if defined(SUPPORT_FILEFORMAT_XM) - else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_MOD) - else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); } - #endif - - music.ctxData = NULL; TRACELOG(LOG_WARNING, "FILEIO: [%s] Music file could not be opened", fileName); } else @@ -1485,11 +1529,10 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, bool success = drwav_init_memory(ctxWav, (const void *)data, dataSize, NULL); - music.ctxType = MUSIC_AUDIO_WAV; - music.ctxData = ctxWav; - if (success) { + music.ctxType = MUSIC_AUDIO_WAV; + music.ctxData = ctxWav; int sampleSize = ctxWav->bitsPerSample; if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream() @@ -1498,18 +1541,22 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, music.looping = true; // Looping enabled by default musicLoaded = true; } + else { + drwav_uninit(ctxWav); + RL_FREE(ctxWav); + } } #endif #if defined(SUPPORT_FILEFORMAT_OGG) else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0)) { // Open ogg audio stream - music.ctxType = MUSIC_AUDIO_OGG; - //music.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL); - music.ctxData = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL); + stb_vorbis* ctxOgg = stb_vorbis_open_memory((const unsigned char*)data, dataSize, NULL, NULL); - if (music.ctxData != NULL) + if (ctxOgg != NULL) { + music.ctxType = MUSIC_AUDIO_OGG; + music.ctxData = ctxOgg; stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)music.ctxData); // Get Ogg file info // OGG bit rate defaults to 16 bit, it's enough for compressed format @@ -1520,6 +1567,10 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + stb_vorbis_close(ctxOgg); + } } #endif #if defined(SUPPORT_FILEFORMAT_MP3) @@ -1528,27 +1579,35 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3)); int success = drmp3_init_memory(ctxMp3, (const void*)data, dataSize, NULL); - music.ctxType = MUSIC_AUDIO_MP3; - music.ctxData = ctxMp3; - if (success) { + music.ctxType = MUSIC_AUDIO_MP3; + music.ctxData = ctxMp3; music.stream = LoadAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels); music.frameCount = (unsigned int)drmp3_get_pcm_frame_count(ctxMp3); music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + drmp3_uninit(ctxMp3); + RL_FREE(ctxMp3); + } } #endif #if defined(SUPPORT_FILEFORMAT_QOA) else if ((strcmp(fileType, ".qoa") == 0) || (strcmp(fileType, ".QOA") == 0)) { - qoaplay_desc *ctxQoa = qoaplay_open_memory(data, dataSize); - music.ctxType = MUSIC_AUDIO_QOA; - music.ctxData = ctxQoa; - - if ((ctxQoa->file_data != NULL) && (ctxQoa->file_data_size != 0)) + qoaplay_desc *ctxQoa = NULL; + if ((data != NULL) && (dataSize > 0)) { + ctxQoa = qoaplay_open_memory(data, dataSize); + } + + if (ctxQoa != NULL) + { + music.ctxType = MUSIC_AUDIO_QOA; + music.ctxData = ctxQoa; // NOTE: We are loading samples are 32bit float normalized data, so, // we configure the output audio stream to also use float 32bit music.stream = LoadAudioStream(ctxQoa->info.samplerate, 32, ctxQoa->info.channels); @@ -1556,23 +1615,27 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, music.looping = true; // Looping enabled by default musicLoaded = true; } + else{} //No uninit required } #endif #if defined(SUPPORT_FILEFORMAT_FLAC) else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0)) { - music.ctxType = MUSIC_AUDIO_FLAC; - music.ctxData = drflac_open_memory((const void*)data, dataSize, NULL); + drflac *ctxFlac = drflac_open_memory((const void*)data, dataSize, NULL); - if (music.ctxData != NULL) + if (ctxFlac != NULL) { - drflac *ctxFlac = (drflac *)music.ctxData; - + music.ctxType = MUSIC_AUDIO_FLAC; + music.ctxData = ctxFlac; music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount; music.looping = true; // Looping enabled by default musicLoaded = true; } + else + { + drflac_free(ctxFlac, NULL); + } } #endif #if defined(SUPPORT_FILEFORMAT_XM) @@ -1583,6 +1646,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, if (result == 0) // XM AUDIO.System.context created successfully { music.ctxType = MUSIC_MODULE_XM; + music.ctxData = ctxXm; jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops unsigned int bits = 32; @@ -1593,11 +1657,14 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2); music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo) music.looping = true; // Looping enabled by default - jar_xm_reset(ctxXm); // make sure we start at the beginning of the song + jar_xm_reset(ctxXm); // Make sure we start at the beginning of the song - music.ctxData = ctxXm; musicLoaded = true; } + else + { + jar_xm_free_context(ctxXm); + } } #endif #if defined(SUPPORT_FILEFORMAT_MOD) @@ -1624,15 +1691,18 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, if (result > 0) { music.ctxType = MUSIC_MODULE_MOD; + music.ctxData = ctxMod; // NOTE: Only stereo is supported for MOD music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, 16, 2); music.frameCount = (unsigned int)jar_mod_max_samples(ctxMod); // NOTE: Always 2 channels (stereo) music.looping = true; // Looping enabled by default musicLoaded = true; - - music.ctxData = ctxMod; - musicLoaded = true; + } + else + { + jar_mod_unload(ctxMod); + RL_FREE(ctxMod); } } #endif @@ -1640,30 +1710,6 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, if (!musicLoaded) { - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL); -#endif -#if defined(SUPPORT_FILEFORMAT_XM) - else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_MOD) - else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); } -#endif - - music.ctxData = NULL; TRACELOG(LOG_WARNING, "FILEIO: Music data could not be loaded"); } else @@ -1721,19 +1767,10 @@ void UnloadMusicStream(Music music) } } -// Start music playing (open stream) +// Start music playing (open stream) from beginning void PlayMusicStream(Music music) { - if (music.stream.buffer != NULL) - { - // For music streams, we need to make sure we maintain the frame cursor position - // This is a hack for this section of code in UpdateMusicStream() - // NOTE: In case window is minimized, music stream is stopped, just make sure to - // play again on window restore: if (IsMusicStreamPlaying(music)) PlayMusicStream(music); - ma_uint32 frameCursorPos = music.stream.buffer->frameCursorPos; - PlayAudioStream(music.stream); // WARNING: This resets the cursor position. - music.stream.buffer->frameCursorPos = frameCursorPos; - } + PlayAudioStream(music.stream); } // Pause music playing @@ -1815,7 +1852,9 @@ void SeekMusicStream(Music music, float position) default: break; } + ma_mutex_lock(&AUDIO.System.lock); music.stream.buffer->framesProcessed = positionInFrames; + ma_mutex_unlock(&AUDIO.System.lock); } // Update (re-fill) music buffers if data already processed @@ -1823,6 +1862,8 @@ void UpdateMusicStream(Music music) { if (music.stream.buffer == NULL) return; + ma_mutex_lock(&AUDIO.System.lock); + unsigned int subBufferSizeInFrames = music.stream.buffer->sizeInFrames/2; // On first call of this function we lazily pre-allocated a temp buffer to read audio files/memory data in @@ -1839,7 +1880,7 @@ void UpdateMusicStream(Music music) // Check both sub-buffers to check if they require refilling for (int i = 0; i < 2; i++) { - if ((music.stream.buffer != NULL) && !music.stream.buffer->isSubBufferProcessed[i]) continue; // No refilling required, move to next sub-buffer + if (!music.stream.buffer->isSubBufferProcessed[i]) continue; // No refilling required, move to next sub-buffer unsigned int framesLeft = music.frameCount - music.stream.buffer->framesProcessed; // Frames left to be processed unsigned int framesToStream = 0; // Total frames to be streamed @@ -1958,7 +1999,7 @@ void UpdateMusicStream(Music music) default: break; } - UpdateAudioStream(music.stream, AUDIO.System.pcmBuffer, framesToStream); + UpdateAudioStreamInLockedState(music.stream, AUDIO.System.pcmBuffer, framesToStream); music.stream.buffer->framesProcessed = music.stream.buffer->framesProcessed%music.frameCount; @@ -1966,6 +2007,7 @@ void UpdateMusicStream(Music music) { if (!music.looping) { + ma_mutex_unlock(&AUDIO.System.lock); // Streaming is ending, we filled latest frames from input StopMusicStream(music); return; @@ -1973,9 +2015,7 @@ void UpdateMusicStream(Music music) } } - // NOTE: In case window is minimized, music stream is stopped, - // just make sure to play again on window restore - if (IsMusicStreamPlaying(music)) PlayMusicStream(music); + ma_mutex_unlock(&AUDIO.System.lock); } // Check if any music is playing @@ -2029,6 +2069,7 @@ float GetMusicTimePlayed(Music music) else #endif { + ma_mutex_lock(&AUDIO.System.lock); //ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels; int framesProcessed = (int)music.stream.buffer->framesProcessed; int subBufferSize = (int)music.stream.buffer->sizeInFrames/2; @@ -2038,6 +2079,7 @@ float GetMusicTimePlayed(Music music) int framesPlayed = (framesProcessed - framesInFirstBuffer - framesInSecondBuffer + framesSentToMix)%(int)music.frameCount; if (framesPlayed < 0) framesPlayed += music.frameCount; secondsPlayed = (float)framesPlayed/music.stream.sampleRate; + ma_mutex_unlock(&AUDIO.System.lock); } } @@ -2098,51 +2140,9 @@ void UnloadAudioStream(AudioStream stream) // NOTE 2: To dequeue a buffer it needs to be processed: IsAudioStreamProcessed() void UpdateAudioStream(AudioStream stream, const void *data, int frameCount) { - if (stream.buffer != NULL) - { - if (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]) - { - ma_uint32 subBufferToUpdate = 0; - - if (stream.buffer->isSubBufferProcessed[0] && stream.buffer->isSubBufferProcessed[1]) - { - // Both buffers are available for updating. - // Update the first one and make sure the cursor is moved back to the front. - subBufferToUpdate = 0; - stream.buffer->frameCursorPos = 0; - } - else - { - // Just update whichever sub-buffer is processed. - subBufferToUpdate = (stream.buffer->isSubBufferProcessed[0])? 0 : 1; - } - - ma_uint32 subBufferSizeInFrames = stream.buffer->sizeInFrames/2; - unsigned char *subBuffer = stream.buffer->data + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate); - - // Total frames processed in buffer is always the complete size, filled with 0 if required - stream.buffer->framesProcessed += subBufferSizeInFrames; - - // Does this API expect a whole buffer to be updated in one go? - // Assuming so, but if not will need to change this logic. - if (subBufferSizeInFrames >= (ma_uint32)frameCount) - { - ma_uint32 framesToWrite = (ma_uint32)frameCount; - - ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8); - memcpy(subBuffer, data, bytesToWrite); - - // Any leftover frames should be filled with zeros. - ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite; - - if (leftoverFrameCount > 0) memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8)); - - stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false; - } - else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer"); - } - else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating"); - } + ma_mutex_lock(&AUDIO.System.lock); + UpdateAudioStreamInLockedState(stream, data, frameCount); + ma_mutex_unlock(&AUDIO.System.lock); } // Check if any audio stream buffers requires refill @@ -2150,7 +2150,11 @@ bool IsAudioStreamProcessed(AudioStream stream) { if (stream.buffer == NULL) return false; - return (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]); + bool result = false; + ma_mutex_lock(&AUDIO.System.lock); + result = stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]; + ma_mutex_unlock(&AUDIO.System.lock); + return result; } // Play audio stream @@ -2171,7 +2175,7 @@ void ResumeAudioStream(AudioStream stream) ResumeAudioBuffer(stream.buffer); } -// Check if audio stream is playing. +// Check if audio stream is playing bool IsAudioStreamPlaying(AudioStream stream) { return IsAudioBufferPlaying(stream.buffer); @@ -2210,12 +2214,17 @@ void SetAudioStreamBufferSizeDefault(int size) // Audio thread callback to request new data void SetAudioStreamCallback(AudioStream stream, AudioCallback callback) { - if (stream.buffer != NULL) stream.buffer->callback = callback; + if (stream.buffer != NULL) + { + ma_mutex_lock(&AUDIO.System.lock); + stream.buffer->callback = callback; + ma_mutex_unlock(&AUDIO.System.lock); + } } -// Add processor to audio stream. Contrary to buffers, the order of processors is important. +// Add processor to audio stream. Contrary to buffers, the order of processors is important // The new processor must be added at the end. As there aren't supposed to be a lot of processors attached to -// a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element. +// a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element void AttachAudioStreamProcessor(AudioStream stream, AudioCallback process) { ma_mutex_lock(&AUDIO.System.lock); @@ -2330,7 +2339,7 @@ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage) TRACELOG(LOG_WARNING, "miniaudio: %s", pMessage); // All log messages from miniaudio are errors } -// Reads audio data from an AudioBuffer object in internal format. +// Reads audio data from an AudioBuffer object in internal format static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount) { // Using audio buffer callback @@ -2404,7 +2413,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, // We need to break from this loop if we're not looping if (!audioBuffer->looping) { - StopAudioBuffer(audioBuffer); + StopAudioBufferInLockedState(audioBuffer); break; } } @@ -2418,20 +2427,20 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, // For static buffers we can fill the remaining frames with silence for safety, but we don't want // to report those frames as "read". The reason for this is that the caller uses the return value - // to know whether a non-looping sound has finished playback. + // to know whether a non-looping sound has finished playback if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining; } return framesRead; } -// Reads audio data from an AudioBuffer object in device format. Returned data will be in a format appropriate for mixing. +// Reads audio data from an AudioBuffer object in device format, returned data will be in a format appropriate for mixing static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount) { // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important // detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output - // frames. This can be achieved with ma_data_converter_get_required_input_frame_count(). + // frames. This can be achieved with ma_data_converter_get_required_input_frame_count() ma_uint8 inputBuffer[4096] = { 0 }; ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); @@ -2540,7 +2549,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const { if (!audioBuffer->looping) { - StopAudioBuffer(audioBuffer); + StopAudioBufferInLockedState(audioBuffer); break; } else @@ -2613,6 +2622,83 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr } } +// Check if an audio buffer is playing, assuming the audio system mutex has been locked +static bool IsAudioBufferPlayingInLockedState(AudioBuffer *buffer) +{ + bool result = false; + + if (buffer != NULL) result = (buffer->playing && !buffer->paused); + + return result; +} + +// Stop an audio buffer, assuming the audio system mutex has been locked +static void StopAudioBufferInLockedState(AudioBuffer *buffer) +{ + if (buffer != NULL) + { + if (IsAudioBufferPlayingInLockedState(buffer)) + { + buffer->playing = false; + buffer->paused = false; + buffer->frameCursorPos = 0; + buffer->framesProcessed = 0; + buffer->isSubBufferProcessed[0] = true; + buffer->isSubBufferProcessed[1] = true; + } + } +} + +// Update audio stream, assuming the audio system mutex has been locked +static void UpdateAudioStreamInLockedState(AudioStream stream, const void *data, int frameCount) +{ + if (stream.buffer != NULL) + { + if (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]) + { + ma_uint32 subBufferToUpdate = 0; + + if (stream.buffer->isSubBufferProcessed[0] && stream.buffer->isSubBufferProcessed[1]) + { + // Both buffers are available for updating + // Update the first one and make sure the cursor is moved back to the front + subBufferToUpdate = 0; + stream.buffer->frameCursorPos = 0; + } + else + { + // Just update whichever sub-buffer is processed + subBufferToUpdate = (stream.buffer->isSubBufferProcessed[0])? 0 : 1; + } + + ma_uint32 subBufferSizeInFrames = stream.buffer->sizeInFrames/2; + unsigned char *subBuffer = stream.buffer->data + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate); + + // Total frames processed in buffer is always the complete size, filled with 0 if required + stream.buffer->framesProcessed += subBufferSizeInFrames; + + // Does this API expect a whole buffer to be updated in one go? + // Assuming so, but if not will need to change this logic + if (subBufferSizeInFrames >= (ma_uint32)frameCount) + { + ma_uint32 framesToWrite = (ma_uint32)frameCount; + + ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8); + memcpy(subBuffer, data, bytesToWrite); + + // Any leftover frames should be filled with zeros + ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite; + + if (leftoverFrameCount > 0) memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8)); + + stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false; + } + else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer"); + } + else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating"); + } +} + // Some required functions for audio standalone module version #if defined(RAUDIO_STANDALONE) // Check file extension @@ -2639,6 +2725,50 @@ static const char *GetFileExtension(const char *fileName) return dot; } +// String pointer reverse break: returns right-most occurrence of charset in s +static const char *strprbrk(const char *s, const char *charset) +{ + const char *latestMatch = NULL; + for (; s = strpbrk(s, charset), s != NULL; latestMatch = s++) { } + return latestMatch; +} + +// Get pointer to filename for a path string +static const char *GetFileName(const char *filePath) +{ + const char *fileName = NULL; + if (filePath != NULL) fileName = strprbrk(filePath, "\\/"); + + if (!fileName) return filePath; + + return fileName + 1; +} + +// Get filename string without extension (uses static string) +static const char *GetFileNameWithoutExt(const char *filePath) +{ + #define MAX_FILENAMEWITHOUTEXT_LENGTH 256 + + static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 }; + memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH); + + if (filePath != NULL) strcpy(fileName, GetFileName(filePath)); // Get filename with extension + + int size = (int)strlen(fileName); // Get size in bytes + + for (int i = 0; (i < size) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++) + { + if (fileName[i] == '.') + { + // NOTE: We break on first '.' found + fileName[i] = '\0'; + break; + } + } + + return fileName; +} + // Load data from file into a buffer static unsigned char *LoadFileData(const char *fileName, int *dataSize) { @@ -2696,9 +2826,19 @@ static bool SaveFileData(const char *fileName, void *data, int dataSize) fclose(file); } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); + else + { + TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); + return false; + } } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + else + { + TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + return false; + } + + return true; } // Save text data to file (write), string must be '\0' terminated @@ -2717,9 +2857,19 @@ static bool SaveFileText(const char *fileName, char *text) fclose(file); } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); + else + { + TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); + return false; + } } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + else + { + TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + return false; + } + + return true; } #endif diff --git a/raylib/raylib.h b/raylib/raylib.h index 1c4c4a0..035f6f2 100644 --- a/raylib/raylib.h +++ b/raylib/raylib.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* raylib v5.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) +* raylib v5.1-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) * * FEATURES: * - NO external dependencies, all required libraries included with raylib @@ -57,7 +57,7 @@ * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software: * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -82,21 +82,26 @@ #include // Required for: va_list - Only used by TraceLogCallback #define RAYLIB_VERSION_MAJOR 5 -#define RAYLIB_VERSION_MINOR 0 +#define RAYLIB_VERSION_MINOR 1 #define RAYLIB_VERSION_PATCH 0 -#define RAYLIB_VERSION "5.0" +#define RAYLIB_VERSION "5.1-dev" -// Function specifiers in case library is build/used as a shared library (Windows) +// Function specifiers in case library is build/used as a shared library // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +// NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden #if defined(_WIN32) + #if defined(__TINYC__) + #define __declspec(x) __attribute__((x)) + #endif #if defined(BUILD_LIBTYPE_SHARED) - #if defined(__TINYC__) - #define __declspec(x) __attribute__((x)) - #endif #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) #elif defined(USE_LIBTYPE_SHARED) #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) #endif +#else + #if defined(BUILD_LIBTYPE_SHARED) + #define RLAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib) + #endif #endif #ifndef RLAPI @@ -479,7 +484,6 @@ typedef struct VrDeviceInfo { int vResolution; // Vertical resolution in pixels float hScreenSize; // Horizontal size in meters float vScreenSize; // Vertical size in meters - float vScreenCenter; // Screen center in meters float eyeToScreenDistance; // Distance between eye and display in meters float lensSeparationDistance; // Lens separation distance in meters float interpupillaryDistance; // IPD (distance between pupils) in meters @@ -673,7 +677,7 @@ typedef enum { KEY_KP_EQUAL = 336, // Key: Keypad = // Android key buttons KEY_BACK = 4, // Key: Android back button - KEY_MENU = 82, // Key: Android menu button + KEY_MENU = 5, // Key: Android menu button KEY_VOLUME_UP = 24, // Key: Android volume up button KEY_VOLUME_DOWN = 25 // Key: Android volume down button } KeyboardKey; @@ -717,12 +721,12 @@ typedef enum { GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) - GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Square, Xbox: X) + GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Circle, Xbox: B) GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) - GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) + GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Square, Xbox: X) GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button - GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (one), it could be a trailing button + GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (first), it could be a trailing button GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button GAMEPAD_BUTTON_MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) GAMEPAD_BUTTON_MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) @@ -909,11 +913,11 @@ typedef enum { // Camera system modes typedef enum { - CAMERA_CUSTOM = 0, // Custom camera - CAMERA_FREE, // Free camera - CAMERA_ORBITAL, // Orbital camera - CAMERA_FIRST_PERSON, // First person camera - CAMERA_THIRD_PERSON // Third person camera + CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) + CAMERA_FREE, // Camera free mode + CAMERA_ORBITAL, // Camera orbital, around target, zoom supported + CAMERA_FIRST_PERSON, // Camera first person + CAMERA_THIRD_PERSON // Camera third person } CameraMode; // Camera projection @@ -1045,13 +1049,15 @@ RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture) RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) // Screen-space-related functions -RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position -RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix) -RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix -RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position -RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position +#define GetMouseRay GetScreenToWorldRay // Compatibility hack for previous raylib versions +RLAPI Ray GetScreenToWorldRay(Vector2 position, Camera camera); // Get a ray trace from screen position (i.e mouse) +RLAPI Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height); // Get a ray trace from screen position (i.e mouse) in a viewport +RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position -RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position +RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position +RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position +RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix) +RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix // Timing-related functions RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) @@ -1134,7 +1140,7 @@ RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize // Automation events functionality RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS -RLAPI void UnloadAutomationEventList(AutomationEventList *list); // Unload automation events list from file +RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording @@ -1157,16 +1163,17 @@ RLAPI int GetCharPressed(void); // Get char presse RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) // Input-related functions: gamepads -RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available -RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id -RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once -RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed -RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once -RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed -RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed -RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad -RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis -RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) +RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available +RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id +RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once +RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed +RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once +RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed +RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed +RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad +RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis +RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) +RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor); // Set gamepad vibration for both motors // Input-related functions: mouse RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once @@ -1216,6 +1223,8 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f // NOTE: It can be useful when using basic shapes and one single font, // defining a font char white rectangle would allow drawing everything in a single draw call RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing +RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing +RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing // Basic shapes drawing functions RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel @@ -1246,7 +1255,8 @@ RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges -RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline +RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle lines with rounded edges +RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) @@ -1296,6 +1306,7 @@ RLAPI Image LoadImage(const char *fileName); RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) +RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot) @@ -1329,6 +1340,7 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation +RLAPI void ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color @@ -1398,8 +1410,9 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, V RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely // Color/pixel related functions +RLAPI bool ColorIsEqual(Color col1, Color col2); // Check if two colors are equal RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f -RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color +RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color (0xRRGGBBAA) RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1] RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1] RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] @@ -1465,7 +1478,7 @@ RLAPI bool TextIsEqual(const char *text1, const char *text2); RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style) RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string -RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!) +RLAPI char *TextReplace(const char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!) RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!) RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings @@ -1475,6 +1488,7 @@ RLAPI const char *TextToUpper(const char *text); // Get upp RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) +RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported) //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) @@ -1530,9 +1544,10 @@ RLAPI void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms -RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents +RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success +RLAPI bool ExportMeshAsCode(Mesh mesh, const char *fileName); // Export mesh as code file (.h) defining multiple arrays of vertex attributes // Mesh generation functions RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh @@ -1649,10 +1664,10 @@ RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data -RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as s +RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as 'float' RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream -RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as s +RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as 'float' RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline #if defined(__cplusplus) diff --git a/raylib/raymath.h b/raylib/raymath.h index ff60170..19625f1 100644 --- a/raylib/raymath.h +++ b/raylib/raymath.h @@ -30,7 +30,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -59,7 +59,9 @@ // Function specifiers definition #if defined(RAYMATH_IMPLEMENTATION) #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) - #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll). + #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll) + #elif defined(BUILD_LIBTYPE_SHARED) + #define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) #else @@ -163,7 +165,7 @@ typedef struct float16 { float v[16]; } float16; -#include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs() +#include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf() //---------------------------------------------------------------------------------- // Module Functions Definition - Utils math @@ -172,7 +174,7 @@ typedef struct float16 { // Clamp float value RMAPI float Clamp(float value, float min, float max) { - float result = (value < min)? min : value; + float result = (value < min) ? min : value; if (result > max) result = max; @@ -429,6 +431,28 @@ RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal) return result; } +// Get min value for each pair of components +RMAPI Vector2 Vector2Min(Vector2 v1, Vector2 v2) +{ + Vector2 result = { 0 }; + + result.x = fminf(v1.x, v2.x); + result.y = fminf(v1.y, v2.y); + + return result; +} + +// Get max value for each pair of components +RMAPI Vector2 Vector2Max(Vector2 v1, Vector2 v2) +{ + Vector2 result = { 0 }; + + result.x = fmaxf(v1.x, v2.x); + result.y = fmaxf(v1.y, v2.y); + + return result; +} + // Rotate vector by angle RMAPI Vector2 Vector2Rotate(Vector2 v, float angle) { @@ -492,18 +516,18 @@ RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) { length = sqrtf(length); + float scale = 1; // By default, 1 as the neutral element. if (length < min) { - float scale = min/length; - result.x = v.x*scale; - result.y = v.y*scale; + scale = min/length; } else if (length > max) { - float scale = max/length; - result.x = v.x*scale; - result.y = v.y*scale; + scale = max/length; } + + result.x = v.x*scale; + result.y = v.y*scale; } return result; @@ -522,6 +546,31 @@ RMAPI int Vector2Equals(Vector2 p, Vector2 q) return result; } +// Compute the direction of a refracted ray +// v: normalized direction of the incoming ray +// n: normalized normal vector of the interface of two optical media +// r: ratio of the refractive index of the medium from where the ray comes +// to the refractive index of the medium on the other side of the surface +RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r) +{ + Vector2 result = { 0 }; + + float dot = v.x*n.x + v.y*n.y; + float d = 1.0f - r*r*(1.0f - dot*dot); + + if (d >= 0.0f) + { + d = sqrtf(d); + v.x = r*v.x - (r*dot + d)*n.x; + v.y = r*v.y - (r*dot + d)*n.y; + + result = v; + } + + return result; +} + + //---------------------------------------------------------------------------------- // Module Functions Definition - Vector3 math //---------------------------------------------------------------------------------- @@ -603,12 +652,12 @@ RMAPI Vector3 Vector3Perpendicular(Vector3 v) { Vector3 result = { 0 }; - float min = (float) fabs(v.x); + float min = fabsf(v.x); Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; if (fabsf(v.y) < min) { - min = (float) fabs(v.y); + min = fabsf(v.y); Vector3 tmp = {0.0f, 1.0f, 0.0f}; cardinalAxis = tmp; } @@ -728,7 +777,7 @@ RMAPI Vector3 Vector3Normalize(Vector3 v) RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) { Vector3 result = { 0 }; - + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); @@ -745,7 +794,7 @@ RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) { Vector3 result = { 0 }; - + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); @@ -832,7 +881,7 @@ RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) // Vector3Normalize(axis); float length = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); if (length == 0.0f) length = 1.0f; - float ilength = 1.0f / length; + float ilength = 1.0f/length; axis.x *= ilength; axis.y *= ilength; axis.z *= ilength; @@ -873,6 +922,27 @@ RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) return result; } +// Move Vector towards target +RMAPI Vector3 Vector3MoveTowards(Vector3 v, Vector3 target, float maxDistance) +{ + Vector3 result = { 0 }; + + float dx = target.x - v.x; + float dy = target.y - v.y; + float dz = target.z - v.z; + float value = (dx*dx) + (dy*dy) + (dz*dz); + + if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target; + + float dist = sqrtf(value); + + result.x = v.x + dx/dist*maxDistance; + result.y = v.y + dy/dist*maxDistance; + result.z = v.z + dz/dist*maxDistance; + + return result; +} + // Calculate linear interpolation between two vectors RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) { @@ -885,6 +955,22 @@ RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) return result; } +// Calculate cubic hermite interpolation between two vectors and their tangents +// as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic +RMAPI Vector3 Vector3CubicHermite(Vector3 v1, Vector3 tangent1, Vector3 v2, Vector3 tangent2, float amount) +{ + Vector3 result = { 0 }; + + float amountPow2 = amount * amount; + float amountPow3 = amount * amount * amount; + + result.x = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.x + (amountPow3 - 2 * amountPow2 + amount) * tangent1.x + (-2 * amountPow3 + 3 * amountPow2) * v2.x + (amountPow3 - amountPow2) * tangent2.x; + result.y = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.y + (amountPow3 - 2 * amountPow2 + amount) * tangent1.y + (-2 * amountPow3 + 3 * amountPow2) * v2.y + (amountPow3 - amountPow2) * tangent2.y; + result.z = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.z + (amountPow3 - 2 * amountPow2 + amount) * tangent1.z + (-2 * amountPow3 + 3 * amountPow2) * v2.z + (amountPow3 - amountPow2) * tangent2.z; + + return result; +} + // Calculate reflected vector to normal RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal) { @@ -1078,20 +1164,19 @@ RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max) { length = sqrtf(length); + float scale = 1; // By default, 1 as the neutral element. if (length < min) { - float scale = min/length; - result.x = v.x*scale; - result.y = v.y*scale; - result.z = v.z*scale; + scale = min/length; } else if (length > max) { - float scale = max/length; - result.x = v.x*scale; - result.y = v.y*scale; - result.z = v.z*scale; + scale = max/length; } + + result.x = v.x*scale; + result.y = v.y*scale; + result.z = v.z*scale; } return result; @@ -1136,6 +1221,233 @@ RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) return result; } + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vector4 math +//---------------------------------------------------------------------------------- + +RMAPI Vector4 Vector4Zero(void) +{ + Vector4 result = { 0.0f, 0.0f, 0.0f, 0.0f }; + return result; +} + +RMAPI Vector4 Vector4One(void) +{ + Vector4 result = { 1.0f, 1.0f, 1.0f, 1.0f }; + return result; +} + +RMAPI Vector4 Vector4Add(Vector4 v1, Vector4 v2) +{ + Vector4 result = { + v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z, + v1.w + v2.w + }; + return result; +} + +RMAPI Vector4 Vector4AddValue(Vector4 v, float add) +{ + Vector4 result = { + v.x + add, + v.y + add, + v.z + add, + v.w + add + }; + return result; +} + +RMAPI Vector4 Vector4Subtract(Vector4 v1, Vector4 v2) +{ + Vector4 result = { + v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z, + v1.w - v2.w + }; + return result; +} + +RMAPI Vector4 Vector4SubtractValue(Vector4 v, float add) +{ + Vector4 result = { + v.x - add, + v.y - add, + v.z - add, + v.w - add + }; + return result; +} + +RMAPI float Vector4Length(Vector4 v) +{ + float result = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w)); + return result; +} + +RMAPI float Vector4LengthSqr(Vector4 v) +{ + float result = (v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w); + return result; +} + +RMAPI float Vector4DotProduct(Vector4 v1, Vector4 v2) +{ + float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w); + return result; +} + +// Calculate distance between two vectors +RMAPI float Vector4Distance(Vector4 v1, Vector4 v2) +{ + float result = sqrtf( + (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) + + (v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w)); + return result; +} + +// Calculate square distance between two vectors +RMAPI float Vector4DistanceSqr(Vector4 v1, Vector4 v2) +{ + float result = + (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) + + (v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w); + + return result; +} + +RMAPI Vector4 Vector4Scale(Vector4 v, float scale) +{ + Vector4 result = { v.x*scale, v.y*scale, v.z*scale, v.w*scale }; + return result; +} + +// Multiply vector by vector +RMAPI Vector4 Vector4Multiply(Vector4 v1, Vector4 v2) +{ + Vector4 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z, v1.w*v2.w }; + return result; +} + +// Negate vector +RMAPI Vector4 Vector4Negate(Vector4 v) +{ + Vector4 result = { -v.x, -v.y, -v.z, -v.w }; + return result; +} + +// Divide vector by vector +RMAPI Vector4 Vector4Divide(Vector4 v1, Vector4 v2) +{ + Vector4 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z, v1.w/v2.w }; + return result; +} + +// Normalize provided vector +RMAPI Vector4 Vector4Normalize(Vector4 v) +{ + Vector4 result = { 0 }; + float length = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w)); + + if (length > 0) + { + float ilength = 1.0f/length; + result.x = v.x*ilength; + result.y = v.y*ilength; + result.z = v.z*ilength; + result.w = v.w*ilength; + } + + return result; +} + +// Get min value for each pair of components +RMAPI Vector4 Vector4Min(Vector4 v1, Vector4 v2) +{ + Vector4 result = { 0 }; + + result.x = fminf(v1.x, v2.x); + result.y = fminf(v1.y, v2.y); + result.z = fminf(v1.z, v2.z); + result.w = fminf(v1.w, v2.w); + + return result; +} + +// Get max value for each pair of components +RMAPI Vector4 Vector4Max(Vector4 v1, Vector4 v2) +{ + Vector4 result = { 0 }; + + result.x = fmaxf(v1.x, v2.x); + result.y = fmaxf(v1.y, v2.y); + result.z = fmaxf(v1.z, v2.z); + result.w = fmaxf(v1.w, v2.w); + + return result; +} + +// Calculate linear interpolation between two vectors +RMAPI Vector4 Vector4Lerp(Vector4 v1, Vector4 v2, float amount) +{ + Vector4 result = { 0 }; + + result.x = v1.x + amount*(v2.x - v1.x); + result.y = v1.y + amount*(v2.y - v1.y); + result.z = v1.z + amount*(v2.z - v1.z); + result.w = v1.w + amount*(v2.w - v1.w); + + return result; +} + +// Move Vector towards target +RMAPI Vector4 Vector4MoveTowards(Vector4 v, Vector4 target, float maxDistance) +{ + Vector4 result = { 0 }; + + float dx = target.x - v.x; + float dy = target.y - v.y; + float dz = target.z - v.z; + float dw = target.w - v.w; + float value = (dx*dx) + (dy*dy) + (dz*dz) + (dw*dw); + + if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target; + + float dist = sqrtf(value); + + result.x = v.x + dx/dist*maxDistance; + result.y = v.y + dy/dist*maxDistance; + result.z = v.z + dz/dist*maxDistance; + result.w = v.w + dw/dist*maxDistance; + + return result; +} + +// Invert the given vector +RMAPI Vector4 Vector4Invert(Vector4 v) +{ + Vector4 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z, 1.0f/v.w }; + return result; +} + +// Check whether two given vectors are almost equal +RMAPI int Vector4Equals(Vector4 p, Vector4 q) +{ +#if !defined(EPSILON) + #define EPSILON 0.000001f +#endif + + int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && + ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && + ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w))))); + return result; +} + + //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- @@ -1901,6 +2213,32 @@ RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) return result; } +// Calculate quaternion cubic spline interpolation using Cubic Hermite Spline algorithm +// as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic +RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion outTangent1, Quaternion q2, Quaternion inTangent2, float t) +{ + float t2 = t * t; + float t3 = t2 * t; + float h00 = 2 * t3 - 3 * t2 + 1; + float h10 = t3 - 2 * t2 + t; + float h01 = -2 * t3 + 3 * t2; + float h11 = t3 - t2; + + Quaternion p0 = QuaternionScale(q1, h00); + Quaternion m0 = QuaternionScale(outTangent1, h10); + Quaternion p1 = QuaternionScale(q2, h01); + Quaternion m1 = QuaternionScale(inTangent2, h11); + + Quaternion result = { 0 }; + + result = QuaternionAdd(p0, m0); + result = QuaternionAdd(result, p1); + result = QuaternionAdd(result, m1); + result = QuaternionNormalize(result); + + return result; +} + // Calculate quaternion based on the rotation from one vector to another RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) { @@ -1960,7 +2298,7 @@ RMAPI Quaternion QuaternionFromMatrix(Matrix mat) } float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f)*0.5f; - float mult = 0.25f / biggestVal; + float mult = 0.25f/biggestVal; switch (biggestIndex) { @@ -2042,8 +2380,7 @@ RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) float ilength = 0.0f; // Vector3Normalize(axis) - Vector3 v = axis; - length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + length = axisLength; if (length == 0.0f) length = 1.0f; ilength = 1.0f/length; axis.x *= ilength; diff --git a/raylib/rcamera.h b/raylib/rcamera.h index c999370..9c19556 100644 --- a/raylib/rcamera.h +++ b/raylib/rcamera.h @@ -20,7 +20,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) +* Copyright (c) 2022-2024 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -202,18 +202,10 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); // Camera mouse movement sensitivity #define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate -#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f +// Camera orbital speed in CAMERA_ORBITAL mode #define CAMERA_ORBITAL_SPEED 0.5f // Radians per second - -#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f -#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f -#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f - -// PLAYER (used by camera) -#define PLAYER_MOVEMENT_SENSITIVITY 20.0f - //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -251,7 +243,7 @@ Vector3 GetCameraRight(Camera *camera) Vector3 forward = GetCameraForward(camera); Vector3 up = GetCameraUp(camera); - return Vector3CrossProduct(forward, up); + return Vector3Normalize(Vector3CrossProduct(forward, up)); } // Moves the camera in its forward direction @@ -449,10 +441,11 @@ void UpdateCamera(Camera *camera, int mode) bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)); bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); - bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); + bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); bool rotateUp = false; - if (mode == CAMERA_ORBITAL) + if (mode == CAMERA_CUSTOM) {} + else if (mode == CAMERA_ORBITAL) { // Orbital can just orbit Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime()); @@ -471,31 +464,30 @@ void UpdateCamera(Camera *camera, int mode) if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED); // Camera movement - if (!IsGamepadAvailable(0)) + // Camera pan (for CAMERA_FREE) + if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))) { - // Camera pan (for CAMERA_FREE) - if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))) - { - const Vector2 mouseDelta = GetMouseDelta(); - if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane); - if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane); - if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED); - if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED); - } - else - { - // Mouse support - CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); - CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); - } - - // Keyboard support - if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); - if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); - if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); - if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + const Vector2 mouseDelta = GetMouseDelta(); + if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane); + if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane); + if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED); + if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED); } else + { + // Mouse support + CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); + CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); + } + + // Keyboard support + if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); + if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); + if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + + // Gamepad movement + if (IsGamepadAvailable(0)) { // Gamepad controller support CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); diff --git a/raylib/rcore.c b/raylib/rcore.c index 4539889..1db8651 100644 --- a/raylib/rcore.c +++ b/raylib/rcore.c @@ -63,7 +63,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -82,6 +82,19 @@ * **********************************************************************************************/ +//---------------------------------------------------------------------------------- +// Feature Test Macros required for this module +//---------------------------------------------------------------------------------- +#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_XOPEN_SOURCE < 500) + #undef _XOPEN_SOURCE + #define _XOPEN_SOURCE 500 // Required for: readlink if compiled with c99 without gnu ext. +#endif + +#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_POSIX_C_SOURCE < 199309L) + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. +#endif + #include "raylib.h" // Declares module functions // Check if config flags have been externally provided on compilation line @@ -105,12 +118,12 @@ #if defined(SUPPORT_GESTURES_SYSTEM) #define RGESTURES_IMPLEMENTATION - #include "rgestures.h" // Gestures detection functionality + #include "rgestures.h" // Gestures detection functionality #endif #if defined(SUPPORT_CAMERA_SYSTEM) #define RCAMERA_IMPLEMENTATION - #include "rcamera.h" // Camera system functionality + #include "rcamera.h" // Camera system functionality #endif #if defined(SUPPORT_GIF_RECORDING) @@ -141,13 +154,15 @@ #endif // Platform specific defines to handle GetApplicationDirectory() -#if defined(_WIN32) +#if (defined(_WIN32) && !defined(PLATFORM_DESKTOP_RGFW)) || (defined(_MSC_VER) && defined(PLATFORM_DESKTOP_RGFW)) #ifndef MAX_PATH #define MAX_PATH 1025 #endif __declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(void *hModule, void *lpFilename, unsigned long nSize); __declspec(dllimport) unsigned long __stdcall GetModuleFileNameW(void *hModule, void *lpFilename, unsigned long nSize); __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, void *widestr, int cchwide, void *str, int cbmb, void *defchar, int *used_default); +unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod); +unsigned int __stdcall timeEndPeriod(unsigned int uPeriod); #elif defined(__linux__) #include #elif defined(__APPLE__) @@ -211,6 +226,9 @@ __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigne #ifndef MAX_GAMEPAD_BUTTONS #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #endif +#ifndef MAX_GAMEPAD_VIBRATION_TIME + #define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds +#endif #ifndef MAX_TOUCH_POINTS #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #endif @@ -235,11 +253,6 @@ __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigne #define FLAG_TOGGLE(n, f) ((n) ^= (f)) #define FLAG_CHECK(n, f) ((n) & (f)) -#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_POSIX_C_SOURCE < 199309L) - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. -#endif - //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -281,16 +294,16 @@ typedef struct CoreData { struct { struct { int exitKey; // Default exit key - char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state - char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state + char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state + char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state // NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially - char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame. + char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame - int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue + int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue int keyPressedQueueCount; // Input keys queue count - int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) + int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) int charPressedQueueCount; // Input characters queue count } Keyboard; @@ -320,7 +333,7 @@ typedef struct CoreData { } Touch; struct { int lastButtonPressed; // Register last gamepad button pressed - int axisCount[MAX_GAMEPADS]; // Register number of available gamepad axis + int axisCount[MAX_GAMEPADS]; // Register number of available gamepad axis bool ready[MAX_GAMEPADS]; // Flag to know if gamepad is ready char name[MAX_GAMEPADS][64]; // Gamepad name holder char currentButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state @@ -354,7 +367,7 @@ static int screenshotCounter = 0; // Screenshots counter #endif #if defined(SUPPORT_GIF_RECORDING) -int gifFrameCounter = 0; // GIF frames counter +unsigned int gifFrameCounter = 0; // GIF frames counter bool gifRecording = false; // GIF recording state MsfGifState gifState = { 0 }; // MSGIF context state #endif @@ -471,7 +484,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *li static void RecordAutomationEvent(void); // Record frame events (to internal events array) #endif -#if defined(_WIN32) +#if defined(_WIN32) && !defined(PLATFORM_DESKTOP_RGFW) // NOTE: We declare Sleep() function symbol to avoid including windows.h (kernel32.lib linkage required) void __stdcall Sleep(unsigned long msTimeout); // Required for: WaitTime() #endif @@ -485,6 +498,8 @@ const char *TextFormat(const char *text, ...); // Formatting of tex #include "platforms/rcore_desktop.c" #elif defined(PLATFORM_DESKTOP_SDL) #include "platforms/rcore_desktop_sdl.c" +#elif defined(PLATFORM_DESKTOP_RGFW) + #include "platforms/rcore_desktop_rgfw.c" #elif defined(PLATFORM_WEB) #include "platforms/rcore_web.c" #elif defined(PLATFORM_DRM) @@ -795,7 +810,7 @@ bool IsCursorHidden(void) return CORE.Input.Mouse.cursorHidden; } -// Check if cursor is on the current screen. +// Check if cursor is on the current screen bool IsCursorOnScreen(void) { return CORE.Input.Mouse.cursorOnScreen; @@ -838,23 +853,33 @@ void EndDrawing(void) // Draw record indicator if (gifRecording) { + #ifndef GIF_RECORD_FRAMERATE #define GIF_RECORD_FRAMERATE 10 - gifFrameCounter++; + #endif + gifFrameCounter += GetFrameTime()*1000; - // NOTE: We record one gif frame every 10 game frames - if ((gifFrameCounter%GIF_RECORD_FRAMERATE) == 0) + // NOTE: We record one gif frame depending on the desired gif framerate + if (gifFrameCounter > 1000/GIF_RECORD_FRAMERATE) { // Get image data for the current frame (from backbuffer) // NOTE: This process is quite slow... :( Vector2 scale = GetWindowScaleDPI(); unsigned char *screenData = rlReadScreenPixels((int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); - msf_gif_frame(&gifState, screenData, 10, 16, (int)((float)CORE.Window.render.width*scale.x)*4); + + #ifndef GIF_RECORD_BITRATE + #define GIF_RECORD_BITRATE 16 + #endif + + // Add the frame to the gif recording, given how many frames have passed in centiseconds + msf_gif_frame(&gifState, screenData, gifFrameCounter/10, GIF_RECORD_BITRATE, (int)((float)CORE.Window.render.width*scale.x)*4); + gifFrameCounter -= 1000/GIF_RECORD_FRAMERATE; RL_FREE(screenData); // Free image data } #if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MODULE_RTEXT) - if (((gifFrameCounter/15)%2) == 1) + // Display the recording indicator every half-second + if ((int)(GetTime()/0.5)%2 == 1) { DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON); // WARNING: Module required: rshapes DrawText("GIF RECORDING", 50, CORE.Window.screen.height - 25, 10, RED); // WARNING: Module required: rtext @@ -944,9 +969,6 @@ void BeginMode2D(Camera2D camera) // Apply 2d camera transformation to modelview rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera))); - - // Apply screen scaling if required - rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); } // Ends 2D mode with custom camera @@ -955,7 +977,8 @@ void EndMode2D(void) rlDrawRenderBatchActive(); // Update and draw internal render batch rlLoadIdentity(); // Reset current matrix (modelview) - rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required + + if (rlGetActiveFramebuffer() == 0) rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required } // Initializes 3D mode with custom camera (3D) @@ -973,10 +996,10 @@ void BeginMode3D(Camera camera) if (camera.projection == CAMERA_PERSPECTIVE) { // Setup perspective projection - double top = RL_CULL_DISTANCE_NEAR*tan(camera.fovy*0.5*DEG2RAD); + double top = rlGetCullDistanceNear()*tan(camera.fovy*0.5*DEG2RAD); double right = top*aspect; - rlFrustum(-right, right, -top, top, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + rlFrustum(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar()); } else if (camera.projection == CAMERA_ORTHOGRAPHIC) { @@ -984,7 +1007,7 @@ void BeginMode3D(Camera camera) double top = camera.fovy/2.0; double right = top*aspect; - rlOrtho(-right, right, -top,top, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + rlOrtho(-right, right, -top,top, rlGetCullDistanceNear(), rlGetCullDistanceFar()); } rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix @@ -1008,7 +1031,7 @@ void EndMode3D(void) rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix rlLoadIdentity(); // Reset current matrix (modelview) - rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required + if (rlGetActiveFramebuffer() == 0) rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required rlDisableDepthTest(); // Disable DEPTH_TEST for 2D } @@ -1054,6 +1077,11 @@ void EndTextureMode(void) // Set viewport to default framebuffer size SetupViewport(CORE.Window.render.width, CORE.Window.render.height); + // Go back to the modelview state from BeginDrawing since we are back to the default FBO + rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix + rlLoadIdentity(); // Reset current matrix (modelview) + rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required + // Reset current fbo to screen size CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.height = CORE.Window.render.height; @@ -1183,17 +1211,17 @@ VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device) // Compute camera projection matrices float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1] - Matrix proj = MatrixPerspective(fovy, aspect, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + Matrix proj = MatrixPerspective(fovy, aspect, rlGetCullDistanceNear(), rlGetCullDistanceFar()); config.projection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f)); config.projection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f)); // Compute camera transformation matrices - // NOTE: Camera movement might seem more natural if we model the head. + // NOTE: Camera movement might seem more natural if we model the head // Our axis of rotation is the base of our head, so we might want to add - // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. - config.viewOffset[0] = MatrixTranslate(-device.interpupillaryDistance*0.5f, 0.075f, 0.045f); - config.viewOffset[1] = MatrixTranslate(device.interpupillaryDistance*0.5f, 0.075f, 0.045f); + // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions + config.viewOffset[0] = MatrixTranslate(device.interpupillaryDistance*0.5f, 0.075f, 0.045f); + config.viewOffset[1] = MatrixTranslate(-device.interpupillaryDistance*0.5f, 0.075f, 0.045f); // Compute eyes Viewports /* @@ -1392,15 +1420,23 @@ void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture) // Module Functions Definition: Screen-space Queries //---------------------------------------------------------------------------------- -// Get a ray trace from mouse position -Ray GetMouseRay(Vector2 mouse, Camera camera) +// Get a ray trace from screen position (i.e mouse) +Ray GetScreenToWorldRay(Vector2 position, Camera camera) +{ + Ray ray = GetScreenToWorldRayEx(position, camera, GetScreenWidth(), GetScreenHeight()); + + return ray; +} + +// Get a ray trace from the screen position (i.e mouse) within a specific section of the screen +Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height) { Ray ray = { 0 }; // Calculate normalized device coordinates // NOTE: y value is negative - float x = (2.0f*mouse.x)/(float)GetScreenWidth() - 1.0f; - float y = 1.0f - (2.0f*mouse.y)/(float)GetScreenHeight(); + float x = (2.0f*position.x)/(float)width - 1.0f; + float y = 1.0f - (2.0f*position.y)/(float)height; float z = 1.0f; // Store values in a vector @@ -1414,11 +1450,11 @@ Ray GetMouseRay(Vector2 mouse, Camera camera) if (camera.projection == CAMERA_PERSPECTIVE) { // Calculate projection matrix from perspective - matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)width/(double)height), rlGetCullDistanceNear(), rlGetCullDistanceFar()); } else if (camera.projection == CAMERA_ORTHOGRAPHIC) { - double aspect = (double)CORE.Window.screen.width/(double)CORE.Window.screen.height; + double aspect = (double)width/(double)height; double top = camera.fovy/2.0; double right = top*aspect; @@ -1430,9 +1466,10 @@ Ray GetMouseRay(Vector2 mouse, Camera camera) Vector3 nearPoint = Vector3Unproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView); Vector3 farPoint = Vector3Unproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView); - // Unproject the mouse cursor in the near plane. - // We need this as the source position because orthographic projects, compared to perspective doesn't have a - // convergence point, meaning that the "eye" of the camera is more like a plane than a point. + // Unproject the mouse cursor in the near plane + // We need this as the source position because orthographic projects, + // compared to perspective doesn't have a convergence point, + // meaning that the "eye" of the camera is more like a plane than a point Vector3 cameraPlanePointerPos = Vector3Unproject((Vector3){ deviceCoords.x, deviceCoords.y, -1.0f }, matProj, matView); // Calculate normalized direction vector @@ -1450,7 +1487,9 @@ Ray GetMouseRay(Vector2 mouse, Camera camera) // Get transform matrix for camera Matrix GetCameraMatrix(Camera camera) { - return MatrixLookAt(camera.position, camera.target, camera.up); + Matrix mat = MatrixLookAt(camera.position, camera.target, camera.up); + + return mat; } // Get camera 2d transform matrix @@ -1461,12 +1500,12 @@ Matrix GetCameraMatrix2D(Camera2D camera) // 1. Move it to target // 2. Rotate by -rotation and scale by (1/zoom) // When setting higher scale, it's more intuitive for the world to become bigger (= camera become smaller), - // not for the camera getting bigger, hence the invert. Same deal with rotation. + // not for the camera getting bigger, hence the invert. Same deal with rotation // 3. Move it by (-offset); // Offset defines target transform relative to screen, but since we're effectively "moving" screen (camera) // we need to do it into opposite direction (inverse transform) - // Having camera transform in world-space, inverse of it gives the modelview transform. + // Having camera transform in world-space, inverse of it gives the modelview transform // Since (A*B*C)' = C'*B'*A', the modelview is // 1. Move to offset // 2. Rotate and Scale @@ -1498,7 +1537,7 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh if (camera.projection == CAMERA_PERSPECTIVE) { // Calculate projection matrix from perspective - matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)width/(double)height), RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)width/(double)height), rlGetCullDistanceNear(), rlGetCullDistanceFar()); } else if (camera.projection == CAMERA_ORTHOGRAPHIC) { @@ -1507,7 +1546,7 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh double right = top*aspect; // Calculate projection matrix from orthographic - matProj = MatrixOrtho(-right, right, -top, top, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + matProj = MatrixOrtho(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar()); } // Calculate view matrix from camera look at (and transpose it) @@ -1631,7 +1670,7 @@ float GetFrameTime(void) // Ref: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timing on Win32! void WaitTime(double seconds) { - if (seconds < 0) return; + if (seconds < 0) return; // Security check #if defined(SUPPORT_BUSY_WAIT_LOOP) || defined(SUPPORT_PARTIALBUSY_WAIT_LOOP) double destinationTime = GetTime() + seconds; @@ -1657,7 +1696,7 @@ void WaitTime(double seconds) req.tv_sec = sec; req.tv_nsec = nsec; - // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated. + // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated while (nanosleep(&req, &req) == -1) continue; #endif #if defined(__APPLE__) @@ -1677,7 +1716,6 @@ void WaitTime(double seconds) // NOTE: Functions with a platform-specific implementation on rcore_.c //void OpenURL(const char *url) - // Set the seed for the random number generator void SetRandomSeed(unsigned int seed) { @@ -1725,7 +1763,7 @@ int *LoadRandomSequence(unsigned int count, int min, int max) #if defined(SUPPORT_RPRAND_GENERATOR) values = rprand_load_sequence(count, min, max); #else - if (count > ((unsigned int)abs(max - min) + 1)) return values; + if (count > ((unsigned int)abs(max - min) + 1)) return values; // Security check values = (int *)RL_CALLOC(count, sizeof(int)); @@ -1780,7 +1818,7 @@ void TakeScreenshot(const char *fileName) char path[512] = { 0 }; strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, GetFileName(fileName))); - + ExportImage(image, path); // WARNING: Module required: rtextures RL_FREE(imgData); @@ -1793,7 +1831,7 @@ void TakeScreenshot(const char *fileName) // Setup window configuration flags (view FLAGS) // NOTE: This function is expected to be called before window creation, -// because it sets up some flags for the window creation process. +// because it sets up some flags for the window creation process // To configure window states after creation, just use SetWindowState() void SetConfigFlags(unsigned int flags) { @@ -1829,7 +1867,7 @@ bool FileExists(const char *fileName) // NOTE: Extensions checking is not case-sensitive bool IsFileExtension(const char *fileName, const char *ext) { - #define MAX_FILE_EXTENSION_SIZE 16 + #define MAX_FILE_EXTENSION_LENGTH 16 bool result = false; const char *fileExt = GetFileExtension(fileName); @@ -1840,8 +1878,8 @@ bool IsFileExtension(const char *fileName, const char *ext) int extCount = 0; const char **checkExts = TextSplit(ext, ';', &extCount); // WARNING: Module required: rtext - char fileExtLower[MAX_FILE_EXTENSION_SIZE + 1] = { 0 }; - strncpy(fileExtLower, TextToLower(fileExt), MAX_FILE_EXTENSION_SIZE); // WARNING: Module required: rtext + char fileExtLower[MAX_FILE_EXTENSION_LENGTH + 1] = { 0 }; + strncpy(fileExtLower, TextToLower(fileExt), MAX_FILE_EXTENSION_LENGTH); // WARNING: Module required: rtext for (int i = 0; i < extCount; i++) { @@ -1917,7 +1955,9 @@ const char *GetFileExtension(const char *fileName) static const char *strprbrk(const char *s, const char *charset) { const char *latestMatch = NULL; + for (; s = strpbrk(s, charset), s != NULL; latestMatch = s++) { } + return latestMatch; } @@ -1925,9 +1965,10 @@ static const char *strprbrk(const char *s, const char *charset) const char *GetFileName(const char *filePath) { const char *fileName = NULL; + if (filePath != NULL) fileName = strprbrk(filePath, "\\/"); - if (!fileName) return filePath; + if (fileName == NULL) return filePath; return fileName + 1; } @@ -1935,22 +1976,24 @@ const char *GetFileName(const char *filePath) // Get filename string without extension (uses static string) const char *GetFileNameWithoutExt(const char *filePath) { - #define MAX_FILENAMEWITHOUTEXT_LENGTH 256 + #define MAX_FILENAME_LENGTH 256 - static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 }; - memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH); + static char fileName[MAX_FILENAME_LENGTH] = { 0 }; + memset(fileName, 0, MAX_FILENAME_LENGTH); - if (filePath != NULL) strcpy(fileName, GetFileName(filePath)); // Get filename with extension - - int size = (int)strlen(fileName); // Get size in bytes - - for (int i = 0; (i < size) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++) + if (filePath != NULL) { - if (fileName[i] == '.') + strcpy(fileName, GetFileName(filePath)); // Get filename.ext without path + int size = (int)strlen(fileName); // Get size in bytes + + for (int i = size; i > 0; i--) // Reverse search '.' { - // NOTE: We break on first '.' found - fileName[i] = '\0'; - break; + if (fileName[i] == '.') + { + // NOTE: We break on first '.' found + fileName[i] = '\0'; + break; + } } } @@ -2204,8 +2247,11 @@ bool IsPathFile(const char *path) // Check if a file has been dropped into window bool IsFileDropped(void) { - if (CORE.Window.dropFileCount > 0) return true; - else return false; + bool result = false; + + if (CORE.Window.dropFileCount > 0) result = true; + + return result; } // Load dropped filepaths @@ -2239,15 +2285,16 @@ void UnloadDroppedFiles(FilePathList files) long GetFileModTime(const char *fileName) { struct stat result = { 0 }; + long modTime = 0; if (stat(fileName, &result) == 0) { time_t mod = result.st_mtime; - return (long)mod; + modTime = (long)mod; } - return 0; + return modTime; } //---------------------------------------------------------------------------------- @@ -2316,7 +2363,7 @@ char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize) char *encodedData = (char *)RL_MALLOC(*outputSize); - if (encodedData == NULL) return NULL; + if (encodedData == NULL) return NULL; // Security check for (int i = 0, j = 0; i < dataSize;) { @@ -2480,13 +2527,10 @@ AutomationEventList LoadAutomationEventList(const char *fileName) } // Unload automation events list from file -void UnloadAutomationEventList(AutomationEventList *list) +void UnloadAutomationEventList(AutomationEventList list) { #if defined(SUPPORT_AUTOMATION_EVENTS) - RL_FREE(list->events); - list->events = NULL; - list->count = 0; - list->capacity = 0; + RL_FREE(list.events); #endif } @@ -2623,8 +2667,9 @@ void PlayAutomationEvent(AutomationEvent event) { CORE.Input.Gamepad.axisState[event.params[0]][event.params[1]] = ((float)event.params[2]/32768.0f); } break; + #if defined(SUPPORT_GESTURES_SYSTEM) case INPUT_GESTURE: GESTURES.current = event.params[0]; break; // param[0]: gesture (enum Gesture) -> rgestures.h: GESTURES.current - + #endif // Window event case WINDOW_CLOSE: CORE.Window.shouldClose = true; break; case WINDOW_MAXIMIZE: MaximizeWindow(); break; @@ -2632,11 +2677,13 @@ void PlayAutomationEvent(AutomationEvent event) case WINDOW_RESIZE: SetWindowSize(event.params[0], event.params[1]); break; // Custom event + #if defined(SUPPORT_SCREEN_CAPTURE) case ACTION_TAKE_SCREENSHOT: { TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); screenshotCounter++; } break; + #endif case ACTION_SETTARGETFPS: SetTargetFPS(event.params[0]); break; default: break; } @@ -2918,13 +2965,15 @@ bool IsMouseButtonUp(int button) // Get mouse position X int GetMouseX(void) { - return (int)((CORE.Input.Mouse.currentPosition.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x); + int mouseX = (int)((CORE.Input.Mouse.currentPosition.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x); + return mouseX; } // Get mouse position Y int GetMouseY(void) { - return (int)((CORE.Input.Mouse.currentPosition.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y); + int mouseY = (int)((CORE.Input.Mouse.currentPosition.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y); + return mouseY; } // Get mouse position XY @@ -2991,13 +3040,15 @@ Vector2 GetMouseWheelMoveV(void) // Get touch position X for touch point 0 (relative to screen size) int GetTouchX(void) { - return (int)CORE.Input.Touch.position[0].x; + int touchX = (int)CORE.Input.Touch.position[0].x; + return touchX; } // Get touch position Y for touch point 0 (relative to screen size) int GetTouchY(void) { - return (int)CORE.Input.Touch.position[0].y; + int touchY = (int)CORE.Input.Touch.position[0].y; + return touchY; } // Get touch position XY for a touch point index (relative to screen size) @@ -3039,10 +3090,10 @@ int GetTouchPointCount(void) // Initialize hi-resolution timer void InitTimer(void) { - // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. - // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. - // High resolutions can also prevent the CPU power management system from entering power-saving modes. - // Setting a higher resolution does not improve the accuracy of the high-resolution performance counter. + // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions + // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often + // High resolutions can also prevent the CPU power management system from entering power-saving modes + // Setting a higher resolution does not improve the accuracy of the high-resolution performance counter #if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP) && !defined(PLATFORM_DESKTOP_SDL) timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms) #endif @@ -3265,7 +3316,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi #if defined(SUPPORT_AUTOMATION_EVENTS) // Automation event recording -// NOTE: Recording is by default done at EndDrawing(), after PollInputEvents() +// NOTE: Recording is by default done at EndDrawing(), before PollInputEvents() static void RecordAutomationEvent(void) { // Checking events in current frame and save them into currentEventList @@ -3507,6 +3558,7 @@ static void RecordAutomationEvent(void) } //------------------------------------------------------------------------------------- +#if defined(SUPPORT_GESTURES_SYSTEM) // Gestures input currentEventList->events recording //------------------------------------------------------------------------------------- if (GESTURES.current != GESTURE_NONE) @@ -3524,16 +3576,7 @@ static void RecordAutomationEvent(void) if (currentEventList->count == currentEventList->capacity) return; // Security check } //------------------------------------------------------------------------------------- - - // Window events recording - //------------------------------------------------------------------------------------- - // TODO. - //------------------------------------------------------------------------------------- - - // Custom actions events recording - //------------------------------------------------------------------------------------- - // TODO. - //------------------------------------------------------------------------------------- +#endif } #endif diff --git a/raylib/rcore.go b/raylib/rcore.go index cad113d..7dfd092 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -920,7 +920,7 @@ func LoadAutomationEventList(fileName string) AutomationEventList { // UnloadAutomationEventList - Unload automation events list from file func UnloadAutomationEventList(list *AutomationEventList) { - C.UnloadAutomationEventList(list.cptr()) + C.UnloadAutomationEventList(*list.cptr()) } // ExportAutomationEventList - Export automation events list as text file diff --git a/raylib/rgestures.h b/raylib/rgestures.h index 9161b74..664a6e1 100644 --- a/raylib/rgestures.h +++ b/raylib/rgestures.h @@ -21,7 +21,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/raylib/rlgl.h b/raylib/rlgl.h index 6cf9c7e..513dd3e 100644 --- a/raylib/rlgl.h +++ b/raylib/rlgl.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* rlgl v4.5 - A multi-OpenGL abstraction layer with an immediate-mode style API +* rlgl v5.0 - A multi-OpenGL abstraction layer with an immediate-mode style API * * DESCRIPTION: * An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) @@ -62,17 +62,17 @@ * When loading a shader, the following vertex attributes and uniform * location names are tried to be set automatically: * -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))) * #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) @@ -85,7 +85,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -107,16 +107,17 @@ #ifndef RLGL_H #define RLGL_H -#define RLGL_VERSION "4.5" +#define RLGL_VERSION "5.0" -// Function specifiers in case library is build/used as a shared library (Windows) +// Function specifiers in case library is build/used as a shared library // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll -#if defined(_WIN32) - #if defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) - #elif defined(USE_LIBTYPE_SHARED) - #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) - #endif +// NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden +#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) + #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) +#elif defined(BUILD_LIBTYPE_SHARED) + #define RLAPI __attribute__((visibility("default"))) // We are building the library as a Unix shared library (.so/.dylib) +#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) + #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) #endif // Function specifiers definition @@ -318,6 +319,28 @@ #define RL_BLEND_SRC_ALPHA 0x80CB // GL_BLEND_SRC_ALPHA #define RL_BLEND_COLOR 0x8005 // GL_BLEND_COLOR +#define RL_READ_FRAMEBUFFER 0x8CA8 // GL_READ_FRAMEBUFFER +#define RL_DRAW_FRAMEBUFFER 0x8CA9 // GL_DRAW_FRAMEBUFFER + +// Default shader vertex attribute locations +#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION + #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD + #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL + #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR + #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3 +#endif + #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT +#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 + #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 +#endif //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -346,6 +369,7 @@ typedef struct rlVertexBuffer { float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + float *normals; // Vertex normal (XYZ - 3 components per vertex) (shader-location = 2) unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) unsigned int *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) @@ -354,7 +378,7 @@ typedef struct rlVertexBuffer { unsigned short *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) #endif unsigned int vaoId; // OpenGL Vertex Array Object id - unsigned int vboId[4]; // OpenGL Vertex Buffer Objects id (4 types of vertex data) + unsigned int vboId[5]; // OpenGL Vertex Buffer Objects id (5 types of vertex data) } rlVertexBuffer; // Draw call type @@ -555,30 +579,33 @@ typedef enum { extern "C" { // Prevents name mangling of functions #endif -RLAPI void rlMatrixMode(int mode); // Choose the current matrix to be transformed -RLAPI void rlPushMatrix(void); // Push the current matrix to stack -RLAPI void rlPopMatrix(void); // Pop latest inserted matrix from stack -RLAPI void rlLoadIdentity(void); // Reset current matrix to identity matrix -RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix -RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix -RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix -RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix +RLAPI void rlMatrixMode(int mode); // Choose the current matrix to be transformed +RLAPI void rlPushMatrix(void); // Push the current matrix to stack +RLAPI void rlPopMatrix(void); // Pop latest inserted matrix from stack +RLAPI void rlLoadIdentity(void); // Reset current matrix to identity matrix +RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix +RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix +RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix +RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar); RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar); RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area +RLAPI void rlSetClipPlanes(double near, double far); // Set clip planes distances +RLAPI double rlGetCullDistanceNear(); // Get cull plane distance near +RLAPI double rlGetCullDistanceFar(); // Get cull plane distance far //------------------------------------------------------------------------------------ // Functions Declaration - Vertex level operations //------------------------------------------------------------------------------------ -RLAPI void rlBegin(int mode); // Initialize drawing mode (how to organize vertex) -RLAPI void rlEnd(void); // Finish vertex providing -RLAPI void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int -RLAPI void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float -RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float -RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float -RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float -RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Define one vertex (color) - 4 byte -RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float +RLAPI void rlBegin(int mode); // Initialize drawing mode (how to organize vertex) +RLAPI void rlEnd(void); // Finish vertex providing +RLAPI void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int +RLAPI void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float +RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float +RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float +RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float +RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Define one vertex (color) - 4 byte +RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float //------------------------------------------------------------------------------------ @@ -592,13 +619,13 @@ RLAPI bool rlEnableVertexArray(unsigned int vaoId); // Enable vertex array ( RLAPI void rlDisableVertexArray(void); // Disable vertex array (VAO, if supported) RLAPI void rlEnableVertexBuffer(unsigned int id); // Enable vertex buffer (VBO) RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO) -RLAPI void rlEnableVertexBufferElement(unsigned int id);// Enable vertex buffer element (VBO element) +RLAPI void rlEnableVertexBufferElement(unsigned int id); // Enable vertex buffer element (VBO element) RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element) RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index -RLAPI void rlDisableVertexAttribute(unsigned int index);// Disable vertex attribute index +RLAPI void rlDisableVertexAttribute(unsigned int index); // Disable vertex attribute index #if defined(GRAPHICS_API_OPENGL_11) -RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer -RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer +RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer +RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer #endif // Textures state @@ -617,11 +644,13 @@ RLAPI void rlDisableShader(void); // Disable shader progra // Framebuffer state RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo) RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer +RLAPI unsigned int rlGetActiveFramebuffer(void); // Get the currently active render texture (fbo), 0 for default framebuffer RLAPI void rlActiveDrawBuffers(int count); // Activate multiple draw color buffers RLAPI void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask); // Blit active framebuffer to main framebuffer +RLAPI void rlBindFramebuffer(unsigned int target, unsigned int framebuffer); // Bind framebuffer (FBO) // General render state -RLAPI void rlEnableColorBlend(void); // Enable color blending +RLAPI void rlEnableColorBlend(void); // Enable color blending RLAPI void rlDisableColorBlend(void); // Disable color blending RLAPI void rlEnableDepthTest(void); // Enable depth test RLAPI void rlDisableDepthTest(void); // Disable depth test @@ -629,12 +658,13 @@ RLAPI void rlEnableDepthMask(void); // Enable depth write RLAPI void rlDisableDepthMask(void); // Disable depth write RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling +RLAPI void rlColorMask(bool r, bool g, bool b, bool a); // Color mask control RLAPI void rlSetCullFace(int mode); // Set face culling mode RLAPI void rlEnableScissorTest(void); // Enable scissor test RLAPI void rlDisableScissorTest(void); // Disable scissor test RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test RLAPI void rlEnableWireMode(void); // Enable wire mode -RLAPI void rlEnablePointMode(void); // Enable point mode +RLAPI void rlEnablePointMode(void); // Enable point mode RLAPI void rlDisableWireMode(void); // Disable wire mode ( and point ) maybe rename RLAPI void rlSetLineWidth(float width); // Set the line drawing width RLAPI float rlGetLineWidth(void); // Get the line drawing width @@ -671,48 +701,48 @@ RLAPI int *rlGetShaderLocsDefault(void); // Get default shader lo // Render batch management // NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode // but this render batch API is exposed in case of custom batches are required -RLAPI rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system -RLAPI void rlUnloadRenderBatch(rlRenderBatch batch); // Unload render batch system -RLAPI void rlDrawRenderBatch(rlRenderBatch *batch); // Draw render batch data (Update->Draw->Reset) -RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal) -RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch -RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex +RLAPI rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system +RLAPI void rlUnloadRenderBatch(rlRenderBatch batch); // Unload render batch system +RLAPI void rlDrawRenderBatch(rlRenderBatch *batch); // Draw render batch data (Update->Draw->Reset) +RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal) +RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch +RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits //------------------------------------------------------------------------------------------------------------------------ // Vertex buffers management -RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported -RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer attribute -RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load a new attributes element buffer -RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update GPU buffer with new data -RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements with new data -RLAPI void rlUnloadVertexArray(unsigned int vaoId); -RLAPI void rlUnloadVertexBuffer(unsigned int vboId); -RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer); -RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor); -RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value -RLAPI void rlDrawVertexArray(int offset, int count); -RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer); -RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances); -RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances); +RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported +RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer object +RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load vertex buffer elements object +RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update vertex buffer object data on GPU buffer +RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements data on GPU buffer +RLAPI void rlUnloadVertexArray(unsigned int vaoId); // Unload vertex array (vao) +RLAPI void rlUnloadVertexBuffer(unsigned int vboId); // Unload vertex buffer object +RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, int offset); // Set vertex attribute data configuration +RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor); // Set vertex attribute data divisor +RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value, when attribute to provided +RLAPI void rlDrawVertexArray(int offset, int count); // Draw vertex array (currently active vao) +RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer); // Draw vertex array elements +RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances); // Draw vertex array (currently active vao) with instancing +RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances); // Draw vertex array elements with instancing // Textures management -RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU -RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) -RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap -RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data -RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats +RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture data +RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) +RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap data +RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update texture with new data on GPU +RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format RLAPI void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory RLAPI void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps); // Generate mipmap data for selected texture -RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data +RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) // Framebuffer management (fbo) -RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer -RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer +RLAPI unsigned int rlLoadFramebuffer(void); // Load an empty framebuffer +RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU @@ -723,14 +753,14 @@ RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fSha RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute -RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform +RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations) // Compute shader management RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId); // Load compute shader program -RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) +RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) // Shader buffer storage object management (ssbo) RLAPI unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint); // Load shader storage buffer object (SSBO) @@ -773,6 +803,12 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad #if defined(RLGL_IMPLEMENTATION) +// Expose OpenGL functions from glad in raylib +#if defined(BUILD_LIBTYPE_SHARED) + #define GLAD_API_CALL_EXPORT + #define GLAD_API_CALL_EXPORT_BUILD +#endif + #if defined(GRAPHICS_API_OPENGL_11) #if defined(__APPLE__) #include // OpenGL 1.1 library for OSX @@ -891,6 +927,14 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #endif +#ifndef GL_PROGRAM_POINT_SIZE + #define GL_PROGRAM_POINT_SIZE 0x8642 +#endif + +#ifndef GL_LINE_WIDTH + #define GL_LINE_WIDTH 0x0B21 +#endif + #if defined(GRAPHICS_API_OPENGL_11) #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 @@ -912,22 +956,22 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad // Default shader vertex attribute names to set location points #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION - #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD - #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL - #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR - #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT - #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 - #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP @@ -1042,6 +1086,9 @@ typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- +static double rlCullDistanceNear = RL_CULL_DISTANCE_NEAR; +static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR; + #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) static rlglData RLGL = { 0 }; #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 @@ -1072,8 +1119,15 @@ static const char *rlGetCompressedFormatName(int format); // Get compressed form static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) // Auxiliar matrix math functions +typedef struct rl_float16 { + float v[16]; +} rl_float16; +static rl_float16 rlMatrixToFloatV(Matrix mat); // Get float array of matrix data +#define rlMatrixToFloat(mat) (rlMatrixToFloatV(mat).v) // Get float vector for Matrix static Matrix rlMatrixIdentity(void); // Get identity matrix static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices +static Matrix rlMatrixTranspose(Matrix mat); // Transposes provided matrix +static Matrix rlMatrixInvert(Matrix mat); // Invert provided matrix //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix operations @@ -1242,7 +1296,7 @@ void rlMultMatrixf(const float *matf) matf[2], matf[6], matf[10], matf[14], matf[3], matf[7], matf[11], matf[15] }; - *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, mat); + *RLGL.State.currentMatrix = rlMatrixMultiply(mat, *RLGL.State.currentMatrix); } // Multiply the current matrix by a perspective matrix generated by parameters @@ -1316,6 +1370,25 @@ void rlViewport(int x, int y, int width, int height) glViewport(x, y, width, height); } +// Set clip planes distances +void rlSetClipPlanes(double near, double far) +{ + rlCullDistanceNear = near; + rlCullDistanceFar = far; +} + +// Get cull plane distance near +double rlGetCullDistanceNear(void) +{ + return rlCullDistanceNear; +} + +// Get cull plane distance far +double rlGetCullDistanceFar(void) +{ + return rlCullDistanceFar; +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Vertex level operations //---------------------------------------------------------------------------------- @@ -1436,7 +1509,10 @@ void rlVertex3f(float x, float y, float z) RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx; RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy; - // WARNING: By default rlVertexBuffer struct does not store normals + // Add current normal + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].normals[3*RLGL.State.vertexCounter] = RLGL.State.normalx; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].normals[3*RLGL.State.vertexCounter + 1] = RLGL.State.normaly; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].normals[3*RLGL.State.vertexCounter + 2] = RLGL.State.normalz; // Add current color RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr; @@ -1472,9 +1548,26 @@ void rlTexCoord2f(float x, float y) // NOTE: Normals limited to TRIANGLES only? void rlNormal3f(float x, float y, float z) { - RLGL.State.normalx = x; - RLGL.State.normaly = y; - RLGL.State.normalz = z; + float normalx = x; + float normaly = y; + float normalz = z; + if (RLGL.State.transformRequired) + { + normalx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z; + normaly = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z; + normalz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z; + } + float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz); + if (length != 0.0f) + { + float ilength = 1.0f / length; + normalx *= ilength; + normaly *= ilength; + normalz *= ilength; + } + RLGL.State.normalx = normalx; + RLGL.State.normaly = normaly; + RLGL.State.normalz = normalz; } // Define one vertex (color) @@ -1713,6 +1806,16 @@ void rlEnableFramebuffer(unsigned int id) #endif } +// return the active render texture (fbo) +unsigned int rlGetActiveFramebuffer(void) +{ + GLint fboId = 0; +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId); +#endif + return fboId; +} + // Disable rendering to texture void rlDisableFramebuffer(void) { @@ -1729,6 +1832,14 @@ void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX #endif } +// Bind framebuffer object (fbo) +void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + glBindFramebuffer(target, framebuffer); +#endif +} + // Activate multiple draw color buffers // NOTE: One color buffer is always active by default void rlActiveDrawBuffers(int count) @@ -1805,6 +1916,9 @@ void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); } // Disable backface culling void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); } +// Set color mask active for screen read/draw +void rlColorMask(bool r, bool g, bool b, bool a) { glColorMask(r, g, b, a); } + // Set face culling mode void rlSetCullFace(int mode) { @@ -2122,7 +2236,10 @@ void rlglInit(int width, int height) RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs; // Init default vertex arrays buffers + // Simulate that the default shader has the location RL_SHADER_LOC_VERTEX_NORMAL to bind the normal buffer for the default render batch + RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_NORMAL] = RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL; RLGL.defaultBatch = rlLoadRenderBatch(RL_DEFAULT_BATCH_BUFFERS, RL_DEFAULT_BATCH_BUFFER_ELEMENTS); + RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_NORMAL] = -1; RLGL.currentBatch = &RLGL.defaultBatch; // Init stack matrices (emulating OpenGL 1.1) @@ -2567,6 +2684,7 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad + batch.vertexBuffer[i].normals = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad #if defined(GRAPHICS_API_OPENGL_33) batch.vertexBuffer[i].indices = (unsigned int *)RL_MALLOC(bufferElements*6*sizeof(unsigned int)); // 6 int by quad (indices) @@ -2577,6 +2695,7 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f; for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f; + for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].normals[j] = 0.0f; for (int j = 0; j < (4*4*bufferElements); j++) batch.vertexBuffer[i].colors[j] = 0; int k = 0; @@ -2626,16 +2745,23 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]); glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); - // Vertex color buffer (shader-location = 3) + // Vertex normal buffer (shader-location = 2) glGenBuffers(1, &batch.vertexBuffer[i].vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[2]); + glBufferData(GL_ARRAY_BUFFER, bufferElements*3*4*sizeof(float), batch.vertexBuffer[i].normals, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_NORMAL]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0); + + // Vertex color buffer (shader-location = 3) + glGenBuffers(1, &batch.vertexBuffer[i].vboId[3]); + glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[3]); glBufferData(GL_ARRAY_BUFFER, bufferElements*4*4*sizeof(unsigned char), batch.vertexBuffer[i].colors, GL_DYNAMIC_DRAW); glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]); glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); // Fill index buffer - glGenBuffers(1, &batch.vertexBuffer[i].vboId[3]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[3]); + glGenBuffers(1, &batch.vertexBuffer[i].vboId[4]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[4]); #if defined(GRAPHICS_API_OPENGL_33) glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(int), batch.vertexBuffer[i].indices, GL_STATIC_DRAW); #endif @@ -2690,10 +2816,10 @@ void rlUnloadRenderBatch(rlRenderBatch batch) if (RLGL.ExtSupported.vao) { glBindVertexArray(batch.vertexBuffer[i].vaoId); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); - glDisableVertexAttribArray(3); + glDisableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION); + glDisableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD); + glDisableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL); + glDisableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR); glBindVertexArray(0); } @@ -2702,6 +2828,7 @@ void rlUnloadRenderBatch(rlRenderBatch batch) glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[1]); glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[2]); glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[3]); + glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[4]); // Delete VAOs from GPU (VRAM) if (RLGL.ExtSupported.vao) glDeleteVertexArrays(1, &batch.vertexBuffer[i].vaoId); @@ -2709,6 +2836,7 @@ void rlUnloadRenderBatch(rlRenderBatch batch) // Free vertex arrays memory from CPU (RAM) RL_FREE(batch.vertexBuffer[i].vertices); RL_FREE(batch.vertexBuffer[i].texcoords); + RL_FREE(batch.vertexBuffer[i].normals); RL_FREE(batch.vertexBuffer[i].colors); RL_FREE(batch.vertexBuffer[i].indices); } @@ -2743,8 +2871,13 @@ void rlDrawRenderBatch(rlRenderBatch *batch) glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords); //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer - // Colors buffer + // Normals buffer glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]); + glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].normals); + //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].normals, GL_DYNAMIC_DRAW); // Update all buffer + + // Colors buffer + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[3]); glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors); //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer @@ -2797,13 +2930,30 @@ void rlDrawRenderBatch(rlRenderBatch *batch) // Create modelview-projection matrix and upload to shader Matrix matMVP = rlMatrixMultiply(RLGL.State.modelview, RLGL.State.projection); - float matMVPfloat[16] = { - matMVP.m0, matMVP.m1, matMVP.m2, matMVP.m3, - matMVP.m4, matMVP.m5, matMVP.m6, matMVP.m7, - matMVP.m8, matMVP.m9, matMVP.m10, matMVP.m11, - matMVP.m12, matMVP.m13, matMVP.m14, matMVP.m15 - }; - glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MVP], 1, false, matMVPfloat); + glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MVP], 1, false, rlMatrixToFloat(matMVP)); + + if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_PROJECTION] != -1) + { + glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_PROJECTION], 1, false, rlMatrixToFloat(RLGL.State.projection)); + } + + // WARNING: For the following setup of the view, model, and normal matrices, it is expected that + // transformations and rendering occur between rlPushMatrix and rlPopMatrix. + + if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_VIEW] != -1) + { + glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_VIEW], 1, false, rlMatrixToFloat(RLGL.State.modelview)); + } + + if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MODEL] != -1) + { + glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MODEL], 1, false, rlMatrixToFloat(RLGL.State.transform)); + } + + if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_NORMAL] != -1) + { + glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_NORMAL], 1, false, rlMatrixToFloat(rlMatrixTranspose(rlMatrixInvert(RLGL.State.transform)))); + } if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); else @@ -2818,12 +2968,17 @@ void rlDrawRenderBatch(rlRenderBatch *batch) glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]); - // Bind vertex attrib: color (shader-location = 3) + // Bind vertex attrib: normal (shader-location = 2) glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_NORMAL]); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[3]); glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[3]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[4]); } // Setup some default shader values @@ -3378,7 +3533,6 @@ void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int #endif } - // Read texture pixel data void *rlReadTexturePixels(unsigned int id, int width, int height, int format) { @@ -3422,7 +3576,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format) // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() // We are using Option 1, just need to care for texture format on retrieval // NOTE: This behaviour could be conditioned by graphic driver... - unsigned int fboId = rlLoadFramebuffer(width, height); + unsigned int fboId = rlLoadFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, fboId); glBindTexture(GL_TEXTURE_2D, 0); @@ -3476,7 +3630,7 @@ unsigned char *rlReadScreenPixels(int width, int height) //----------------------------------------------------------------------------------------- // Load a framebuffer to be used for rendering // NOTE: No textures attached -unsigned int rlLoadFramebuffer(int width, int height) +unsigned int rlLoadFramebuffer(void) { unsigned int fboId = 0; @@ -3784,10 +3938,14 @@ unsigned int rlLoadVertexArray(void) } // Set vertex attribute -void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer) +void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, int offset) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glVertexAttribPointer(index, compSize, type, normalized, stride, pointer); + // NOTE: Data type could be: GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT + // Additional types (depends on OpenGL version or extensions): + // - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, + // - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV + glVertexAttribPointer(index, compSize, type, normalized, stride, (void *)offset); #endif } @@ -3970,12 +4128,12 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId) glAttachShader(program, fShaderId); // NOTE: Default attribute shader locations must be Bound before linking - glBindAttribLocation(program, 0, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); - glBindAttribLocation(program, 1, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); - glBindAttribLocation(program, 2, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL); - glBindAttribLocation(program, 3, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); - glBindAttribLocation(program, 4, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); - glBindAttribLocation(program, 5, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); + glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); + glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); + glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL); + glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); + glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); + glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); // NOTE: If some attrib name is no found on the shader, it locations becomes -1 @@ -4108,7 +4266,14 @@ void rlSetUniformSampler(int locIndex, unsigned int textureId) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Check if texture is already active - for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) if (RLGL.State.activeTextureId[i] == textureId) return; + for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) + { + if (RLGL.State.activeTextureId[i] == textureId) + { + glUniform1i(locIndex, 1 + i); + return; + } + } // Register a new active texture for the internal batch system // NOTE: Default texture is always activated as GL_TEXTURE0 @@ -4431,10 +4596,10 @@ void rlLoadDrawQuad(void) glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW); // Bind vertex attributes (position, texcoords) - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)0); // Positions - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)(3*sizeof(float))); // Texcoords + glEnableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION); + glVertexAttribPointer(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)0); // Positions + glEnableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD); + glVertexAttribPointer(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)(3*sizeof(float))); // Texcoords // Draw quad glBindVertexArray(quadVAO); @@ -4505,12 +4670,12 @@ void rlLoadDrawCube(void) // Bind vertex attributes (position, normals, texcoords) glBindVertexArray(cubeVAO); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0); // Positions - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float))); // Normals - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float))); // Texcoords + glEnableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION); + glVertexAttribPointer(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0); // Positions + glEnableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL); + glVertexAttribPointer(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float))); // Normals + glEnableVertexAttribArray(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD); + glVertexAttribPointer(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float))); // Texcoords glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); @@ -4658,14 +4823,14 @@ static void rlLoadShaderDefault(void) TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId); // Set default shader locations: attributes locations - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_POSITION] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexPosition"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexTexCoord"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexColor"); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_POSITION] = glGetAttribLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); // Set default shader locations: uniform locations - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, "mvp"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "colDiffuse"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "texture0"); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0); } else TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to load default shader", RLGL.State.defaultShaderId); } @@ -4817,6 +4982,31 @@ static int rlGetPixelDataSize(int width, int height, int format) // Auxiliar math functions +// Get float array of matrix data +static rl_float16 rlMatrixToFloatV(Matrix mat) +{ + rl_float16 result = { 0 }; + + result.v[0] = mat.m0; + result.v[1] = mat.m1; + result.v[2] = mat.m2; + result.v[3] = mat.m3; + result.v[4] = mat.m4; + result.v[5] = mat.m5; + result.v[6] = mat.m6; + result.v[7] = mat.m7; + result.v[8] = mat.m8; + result.v[9] = mat.m9; + result.v[10] = mat.m10; + result.v[11] = mat.m11; + result.v[12] = mat.m12; + result.v[13] = mat.m13; + result.v[14] = mat.m14; + result.v[15] = mat.m15; + + return result; +} + // Get identity matrix static Matrix rlMatrixIdentity(void) { @@ -4856,4 +5046,76 @@ static Matrix rlMatrixMultiply(Matrix left, Matrix right) return result; } +// Transposes provided matrix +static Matrix rlMatrixTranspose(Matrix mat) +{ + Matrix result = { 0 }; + + result.m0 = mat.m0; + result.m1 = mat.m4; + result.m2 = mat.m8; + result.m3 = mat.m12; + result.m4 = mat.m1; + result.m5 = mat.m5; + result.m6 = mat.m9; + result.m7 = mat.m13; + result.m8 = mat.m2; + result.m9 = mat.m6; + result.m10 = mat.m10; + result.m11 = mat.m14; + result.m12 = mat.m3; + result.m13 = mat.m7; + result.m14 = mat.m11; + result.m15 = mat.m15; + + return result; +} + +// Invert provided matrix +static Matrix rlMatrixInvert(Matrix mat) +{ + Matrix result = { 0 }; + + // Cache the matrix values (speed optimization) + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; + + float b00 = a00*a11 - a01*a10; + float b01 = a00*a12 - a02*a10; + float b02 = a00*a13 - a03*a10; + float b03 = a01*a12 - a02*a11; + float b04 = a01*a13 - a03*a11; + float b05 = a02*a13 - a03*a12; + float b06 = a20*a31 - a21*a30; + float b07 = a20*a32 - a22*a30; + float b08 = a20*a33 - a23*a30; + float b09 = a21*a32 - a22*a31; + float b10 = a21*a33 - a23*a31; + float b11 = a22*a33 - a23*a32; + + // Calculate the invert determinant (inlined to avoid double-caching) + float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + + result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; + result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; + result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; + result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; + result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; + result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; + result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; + result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; + result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; + result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; + result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; + result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; + result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; + result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; + result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; + result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; + + return result; +} + #endif // RLGL_IMPLEMENTATION diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index 15f0067..0136791 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -587,9 +587,7 @@ func LoadTextureDepth(width, height int32, useRenderBuffer bool) { // LoadFramebuffer - Load an empty framebuffer func LoadFramebuffer(width int32, height int32) uint32 { - cwidth := C.int(width) - cheight := C.int(height) - return uint32(C.rlLoadFramebuffer(cwidth, cheight)) + return uint32(C.rlLoadFramebuffer()) } // FramebufferAttach - Attach texture/renderbuffer to a framebuffer diff --git a/raylib/rmodels.c b/raylib/rmodels.c index 229d373..27c19a3 100644 --- a/raylib/rmodels.c +++ b/raylib/rmodels.c @@ -21,7 +21,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -54,8 +54,8 @@ #include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality #include // Required for: sprintf() -#include // Required for: malloc(), free() -#include // Required for: memcmp(), strlen() +#include // Required for: malloc(), calloc(), free() +#include // Required for: memcmp(), strlen(), strncpy() #include // Required for: sinf(), cosf(), sqrtf(), fabsf() #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL) @@ -228,7 +228,7 @@ void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color) // Draw a triangle strip defined by points void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color) { - if (pointCount < 3) return; + if (pointCount < 3) return; // Security check rlBegin(RL_TRIANGLES); rlColor4ub(color.r, color.g, color.b, color.a); @@ -269,6 +269,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c rlColor4ub(color.r, color.g, color.b, color.a); // Front face + rlNormal3f(0.0f, 0.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left @@ -278,6 +279,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right // Back face + rlNormal3f(0.0f, 0.0f, -1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right @@ -287,6 +289,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left // Top face + rlNormal3f(0.0f, 1.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right @@ -296,6 +299,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right // Bottom face + rlNormal3f(0.0f, -1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Left rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left @@ -305,6 +309,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Left // Right face + rlNormal3f(1.0f, 0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left @@ -314,6 +319,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left // Left face + rlNormal3f(-1.0f, 0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right @@ -559,7 +565,7 @@ void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float e if (sides < 3) sides = 3; Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z }; - if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0)) return; + if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0)) return; // Security check // Construct a basis of the base and the top face: Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction)); @@ -570,8 +576,9 @@ void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float e rlBegin(RL_TRIANGLES); rlColor4ub(color.r, color.g, color.b, color.a); - for (int i = 0; i < sides; i++) { - // compute the four vertices + for (int i = 0; i < sides; i++) + { + // Compute the four vertices float s1 = sinf(baseAngle*(i + 0))*startRadius; float c1 = cosf(baseAngle*(i + 0))*startRadius; Vector3 w1 = { startPos.x + s1*b1.x + c1*b2.x, startPos.y + s1*b1.y + c1*b2.y, startPos.z + s1*b1.z + c1*b2.z }; @@ -585,11 +592,12 @@ void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float e float c4 = cosf(baseAngle*(i + 1))*endRadius; Vector3 w4 = { endPos.x + s4*b1.x + c4*b2.x, endPos.y + s4*b1.y + c4*b2.y, endPos.z + s4*b1.z + c4*b2.z }; - if (startRadius > 0) { // + if (startRadius > 0) + { rlVertex3f(startPos.x, startPos.y, startPos.z); // | rlVertex3f(w2.x, w2.y, w2.z); // T0 rlVertex3f(w1.x, w1.y, w1.z); // | - } // + } // w2 x.-----------x startPos rlVertex3f(w1.x, w1.y, w1.z); // | |\'. T0 / rlVertex3f(w2.x, w2.y, w2.z); // T1 | \ '. / @@ -599,7 +607,8 @@ void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float e rlVertex3f(w4.x, w4.y, w4.z); // T2 '. \ |T3/ rlVertex3f(w3.x, w3.y, w3.z); // | '. \ | / // '.\|/ - if (endRadius > 0) { // 'x w3 + if (endRadius > 0) // 'x w3 + { rlVertex3f(endPos.x, endPos.y, endPos.z); // | rlVertex3f(w3.x, w3.y, w3.z); // T3 rlVertex3f(w4.x, w4.y, w4.z); // | @@ -646,7 +655,7 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl if (sides < 3) sides = 3; Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z }; - if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0))return; + if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0)) return; // Security check // Construct a basis of the base and the top face: Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction)); @@ -657,8 +666,9 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - for (int i = 0; i < sides; i++) { - // compute the four vertices + for (int i = 0; i < sides; i++) + { + // Compute the four vertices float s1 = sinf(baseAngle*(i + 0))*startRadius; float c1 = cosf(baseAngle*(i + 0))*startRadius; Vector3 w1 = { startPos.x + s1*b1.x + c1*b2.x, startPos.y + s1*b1.y + c1*b2.y, startPos.z + s1*b1.z + c1*b2.z }; @@ -702,7 +712,7 @@ void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int Vector3 capCenter = endPos; float baseSliceAngle = (2.0f*PI)/slices; - float baseRingAngle = PI * 0.5f / rings; + float baseRingAngle = PI*0.5f/rings; rlBegin(RL_TRIANGLES); rlColor4ub(color.r, color.g, color.b, color.a); @@ -721,38 +731,38 @@ void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int // as we iterate through the rings they must get smaller by the cos(angle(i)) // compute the four vertices - float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 )); - float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 )); + float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 )); + float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 )); Vector3 w1 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z)*radius }; - float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 )); - float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 )); + float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 0 )); + float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 0 )); Vector3 w2 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z)*radius }; - float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 )); - float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 )); + float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 1 )); + float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 1 )); Vector3 w3 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z)*radius }; - float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 )); - float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 )); + float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 1 )); + float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 1 )); Vector3 w4 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z)*radius }; - // make sure cap triangle normals are facing outwards - if(c == 0) + // Make sure cap triangle normals are facing outwards + if (c == 0) { rlVertex3f(w1.x, w1.y, w1.z); rlVertex3f(w2.x, w2.y, w2.z); @@ -845,7 +855,7 @@ void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices Vector3 capCenter = endPos; float baseSliceAngle = (2.0f*PI)/slices; - float baseRingAngle = PI * 0.5f / rings; + float baseRingAngle = PI*0.5f/rings; rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); @@ -864,34 +874,34 @@ void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices // as we iterate through the rings they must get smaller by the cos(angle(i)) // compute the four vertices - float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 )); - float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 )); + float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 )); + float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 )); Vector3 w1 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z)*radius }; - float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 )); - float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 )); + float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 0 )); + float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 0 )); Vector3 w2 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z)*radius }; - float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 )); - float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 )); + float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 1 )); + float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 1 )); Vector3 w3 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z)*radius }; - float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 )); - float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 )); + float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 1 )); + float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle*( i + 1 )); Vector3 w4 = (Vector3){ - capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x) * radius, - capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y) * radius, - capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z) * radius + capCenter.x + (sinf(baseRingAngle*( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x)*radius, + capCenter.y + (sinf(baseRingAngle*( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y)*radius, + capCenter.z + (sinf(baseRingAngle*( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z)*radius }; rlVertex3f(w1.x, w1.y, w1.z); @@ -1100,13 +1110,17 @@ Model LoadModelFromMesh(Mesh mesh) // Check if a model is ready bool IsModelReady(Model model) { - return ((model.meshes != NULL) && // Validate model contains some mesh - (model.materials != NULL) && // Validate model contains some material (at least default one) - (model.meshMaterial != NULL) && // Validate mesh-material linkage - (model.meshCount > 0) && // Validate mesh count - (model.materialCount > 0)); // Validate material count + bool result = false; + + if ((model.meshes != NULL) && // Validate model contains some mesh + (model.materials != NULL) && // Validate model contains some material (at least default one) + (model.meshMaterial != NULL) && // Validate mesh-material linkage + (model.meshCount > 0) && // Validate mesh count + (model.materialCount > 0)) result = true; // Validate material count // NOTE: This is a very general model validation, many elements could be validated from a model... + + return result; } // Unload model (meshes/materials) from memory (RAM and/or VRAM) @@ -1200,13 +1214,13 @@ void UploadMesh(Mesh *mesh, bool dynamic) // Enable vertex attributes: position (shader-location = 0) void *vertices = (mesh->animVertices != NULL)? mesh->animVertices : mesh->vertices; mesh->vboId[0] = rlLoadVertexBuffer(vertices, mesh->vertexCount*3*sizeof(float), dynamic); - rlSetVertexAttribute(0, 3, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(0); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, 3, RL_FLOAT, 0, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION); // Enable vertex attributes: texcoords (shader-location = 1) mesh->vboId[1] = rlLoadVertexBuffer(mesh->texcoords, mesh->vertexCount*2*sizeof(float), dynamic); - rlSetVertexAttribute(1, 2, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(1); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, 2, RL_FLOAT, 0, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD); // WARNING: When setting default vertex attribute values, the values for each generic vertex attribute // is part of current state, and it is maintained even if a different program object is used @@ -1216,64 +1230,64 @@ void UploadMesh(Mesh *mesh, bool dynamic) // Enable vertex attributes: normals (shader-location = 2) void *normals = (mesh->animNormals != NULL)? mesh->animNormals : mesh->normals; mesh->vboId[2] = rlLoadVertexBuffer(normals, mesh->vertexCount*3*sizeof(float), dynamic); - rlSetVertexAttribute(2, 3, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(2); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, 3, RL_FLOAT, 0, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL); } else { // Default vertex attribute: normal // WARNING: Default value provided to shader if location available float value[3] = { 1.0f, 1.0f, 1.0f }; - rlSetVertexAttributeDefault(2, value, SHADER_ATTRIB_VEC3, 3); - rlDisableVertexAttribute(2); + rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, value, SHADER_ATTRIB_VEC3, 3); + rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL); } if (mesh->colors != NULL) { // Enable vertex attribute: color (shader-location = 3) mesh->vboId[3] = rlLoadVertexBuffer(mesh->colors, mesh->vertexCount*4*sizeof(unsigned char), dynamic); - rlSetVertexAttribute(3, 4, RL_UNSIGNED_BYTE, 1, 0, 0); - rlEnableVertexAttribute(3); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, 4, RL_UNSIGNED_BYTE, 1, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR); } else { // Default vertex attribute: color // WARNING: Default value provided to shader if location available float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; // WHITE - rlSetVertexAttributeDefault(3, value, SHADER_ATTRIB_VEC4, 4); - rlDisableVertexAttribute(3); + rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, value, SHADER_ATTRIB_VEC4, 4); + rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR); } if (mesh->tangents != NULL) { // Enable vertex attribute: tangent (shader-location = 4) mesh->vboId[4] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), dynamic); - rlSetVertexAttribute(4, 4, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(4); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, 4, RL_FLOAT, 0, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT); } else { // Default vertex attribute: tangent // WARNING: Default value provided to shader if location available float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - rlSetVertexAttributeDefault(4, value, SHADER_ATTRIB_VEC4, 4); - rlDisableVertexAttribute(4); + rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, value, SHADER_ATTRIB_VEC4, 4); + rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT); } if (mesh->texcoords2 != NULL) { // Enable vertex attribute: texcoord2 (shader-location = 5) mesh->vboId[5] = rlLoadVertexBuffer(mesh->texcoords2, mesh->vertexCount*2*sizeof(float), dynamic); - rlSetVertexAttribute(5, 2, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(5); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, 2, RL_FLOAT, 0, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2); } else { // Default vertex attribute: texcoord2 // WARNING: Default value provided to shader if location available float value[2] = { 0.0f, 0.0f }; - rlSetVertexAttributeDefault(5, value, SHADER_ATTRIB_VEC2, 2); - rlDisableVertexAttribute(5); + rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, value, SHADER_ATTRIB_VEC2, 2); + rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2); } if (mesh->indices != NULL) @@ -1352,10 +1366,10 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform) if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1) { float values[4] = { - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f, - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.g/255.0f, - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.b/255.0f, - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f + (float)material.maps[MATERIAL_MAP_SPECULAR].color.r/255.0f, + (float)material.maps[MATERIAL_MAP_SPECULAR].color.g/255.0f, + (float)material.maps[MATERIAL_MAP_SPECULAR].color.b/255.0f, + (float)material.maps[MATERIAL_MAP_SPECULAR].color.a/255.0f }; rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1); @@ -1470,9 +1484,6 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform) if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]); } - // WARNING: Disable vertex attribute color input if mesh can not provide that data (despite location being enabled in shader) - if (mesh.vboId[3] == 0) rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]); - int eyeCount = 1; if (rlIsStereoRenderEnabled()) eyeCount = 2; @@ -1588,7 +1599,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i // Enable mesh VAO to attach new buffer rlEnableVertexArray(mesh.vaoId); - // This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData(). + // This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData() // It isn't clear which would be reliably faster in all cases and on all platforms, // anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems // no faster, since we're transferring all the transform matrices anyway @@ -1598,7 +1609,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i for (unsigned int i = 0; i < 4; i++) { rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i); - rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4))); + rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4)); rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1); } @@ -1691,9 +1702,6 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]); } - // WARNING: Disable vertex attribute color input if mesh can not provide that data (despite location being enabled in shader) - if (mesh.vboId[3] == 0) rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]); - int eyeCount = 1; if (rlIsStereoRenderEnabled()) eyeCount = 2; @@ -1794,7 +1802,7 @@ bool ExportMesh(Mesh mesh, const char *fileName) byteCount += sprintf(txtData + byteCount, "# // more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "# // feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "# // //\n"); - byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2023 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2024 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "# // //\n"); byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n"); byteCount += sprintf(txtData + byteCount, "# Vertex Count: %i\n", mesh.vertexCount); @@ -1850,6 +1858,104 @@ bool ExportMesh(Mesh mesh, const char *fileName) return success; } +// Export mesh as code file (.h) defining multiple arrays of vertex attributes +bool ExportMeshAsCode(Mesh mesh, const char *fileName) +{ + bool success = false; + +#ifndef TEXT_BYTES_PER_LINE + #define TEXT_BYTES_PER_LINE 20 +#endif + + // NOTE: Text data buffer size is fixed to 64MB + char *txtData = (char *)RL_CALLOC(64*1024*1024, sizeof(char)); // 64 MB + + int byteCount = 0; + byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "// MeshAsCode exporter v1.0 - Mesh vertex data exported as arrays //\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); + byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2023 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); + + // Get file name from path and convert variable name to uppercase + char varFileName[256] = { 0 }; + strcpy(varFileName, GetFileNameWithoutExt(fileName)); + for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } + + // Add image information + byteCount += sprintf(txtData + byteCount, "// Mesh basic information\n"); + byteCount += sprintf(txtData + byteCount, "#define %s_VERTEX_COUNT %i\n", varFileName, mesh.vertexCount); + byteCount += sprintf(txtData + byteCount, "#define %s_TRIANGLE_COUNT %i\n\n", varFileName, mesh.triangleCount); + + // Define vertex attributes data as separate arrays + //----------------------------------------------------------------------------------------- + if (mesh.vertices != NULL) // Vertex position (XYZ - 3 components per vertex - float) + { + byteCount += sprintf(txtData + byteCount, "static float %s_VERTEX_DATA[%i] = { ", varFileName, mesh.vertexCount*3); + for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.vertices[i]); + byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.vertices[mesh.vertexCount*3 - 1]); + } + + if (mesh.texcoords != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) + { + byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD_DATA[%i] = { ", varFileName, mesh.vertexCount*2); + for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords[i]); + byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords[mesh.vertexCount*2 - 1]); + } + + if (mesh.texcoords2 != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) + { + byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD2_DATA[%i] = { ", varFileName, mesh.vertexCount*2); + for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords2[i]); + byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords2[mesh.vertexCount*2 - 1]); + } + + if (mesh.normals != NULL) // Vertex normals (XYZ - 3 components per vertex - float) + { + byteCount += sprintf(txtData + byteCount, "static float %s_NORMAL_DATA[%i] = { ", varFileName, mesh.vertexCount*3); + for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.normals[i]); + byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.normals[mesh.vertexCount*3 - 1]); + } + + if (mesh.tangents != NULL) // Vertex tangents (XYZW - 4 components per vertex - float) + { + byteCount += sprintf(txtData + byteCount, "static float %s_TANGENT_DATA[%i] = { ", varFileName, mesh.vertexCount*4); + for (int i = 0; i < mesh.vertexCount*4 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.tangents[i]); + byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.tangents[mesh.vertexCount*4 - 1]); + } + + if (mesh.colors != NULL) // Vertex colors (RGBA - 4 components per vertex - unsigned char) + { + byteCount += sprintf(txtData + byteCount, "static unsigned char %s_COLOR_DATA[%i] = { ", varFileName, mesh.vertexCount*4); + for (int i = 0; i < mesh.vertexCount*4 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), mesh.colors[i]); + byteCount += sprintf(txtData + byteCount, "0x%x };\n\n", mesh.colors[mesh.vertexCount*4 - 1]); + } + + if (mesh.indices != NULL) // Vertex indices (3 index per triangle - unsigned short) + { + byteCount += sprintf(txtData + byteCount, "static unsigned short %s_INDEX_DATA[%i] = { ", varFileName, mesh.triangleCount*3); + for (int i = 0; i < mesh.triangleCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%i,\n" : "%i, "), mesh.indices[i]); + byteCount += sprintf(txtData + byteCount, "%i };\n", mesh.indices[mesh.triangleCount*3 - 1]); + } + //----------------------------------------------------------------------------------------- + + // NOTE: Text data size exported is determined by '\0' (NULL) character + success = SaveFileText(fileName, txtData); + + RL_FREE(txtData); + + //if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName); + //else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName); + + return success; +} + + #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL) // Process obj materials static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount) @@ -1866,18 +1972,18 @@ static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, i materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; if (mats[m].diffuse_texname != NULL) materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture(mats[m].diffuse_texname); //char *diffuse_texname; // map_Kd - else materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(mats[m].diffuse[0]*255.0f), (unsigned char)(mats[m].diffuse[1]*255.0f), (unsigned char)(mats[m].diffuse[2] * 255.0f), 255 }; //float diffuse[3]; + else materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(mats[m].diffuse[0]*255.0f), (unsigned char)(mats[m].diffuse[1]*255.0f), (unsigned char)(mats[m].diffuse[2]*255.0f), 255 }; //float diffuse[3]; materials[m].maps[MATERIAL_MAP_DIFFUSE].value = 0.0f; if (mats[m].specular_texname != NULL) materials[m].maps[MATERIAL_MAP_SPECULAR].texture = LoadTexture(mats[m].specular_texname); //char *specular_texname; // map_Ks - materials[m].maps[MATERIAL_MAP_SPECULAR].color = (Color){ (unsigned char)(mats[m].specular[0]*255.0f), (unsigned char)(mats[m].specular[1]*255.0f), (unsigned char)(mats[m].specular[2] * 255.0f), 255 }; //float specular[3]; + materials[m].maps[MATERIAL_MAP_SPECULAR].color = (Color){ (unsigned char)(mats[m].specular[0]*255.0f), (unsigned char)(mats[m].specular[1]*255.0f), (unsigned char)(mats[m].specular[2]*255.0f), 255 }; //float specular[3]; materials[m].maps[MATERIAL_MAP_SPECULAR].value = 0.0f; if (mats[m].bump_texname != NULL) materials[m].maps[MATERIAL_MAP_NORMAL].texture = LoadTexture(mats[m].bump_texname); //char *bump_texname; // map_bump, bump materials[m].maps[MATERIAL_MAP_NORMAL].color = WHITE; materials[m].maps[MATERIAL_MAP_NORMAL].value = mats[m].shininess; - materials[m].maps[MATERIAL_MAP_EMISSION].color = (Color){ (unsigned char)(mats[m].emission[0]*255.0f), (unsigned char)(mats[m].emission[1]*255.0f), (unsigned char)(mats[m].emission[2] * 255.0f), 255 }; //float emission[3]; + materials[m].maps[MATERIAL_MAP_EMISSION].color = (Color){ (unsigned char)(mats[m].emission[0]*255.0f), (unsigned char)(mats[m].emission[1]*255.0f), (unsigned char)(mats[m].emission[2]*255.0f), 255 }; //float emission[3]; if (mats[m].displacement_texname != NULL) materials[m].maps[MATERIAL_MAP_HEIGHT].texture = LoadTexture(mats[m].displacement_texname); //char *displacement_texname; // disp } @@ -1937,8 +2043,12 @@ Material LoadMaterialDefault(void) // Check if a material is ready bool IsMaterialReady(Material material) { - return ((material.maps != NULL) && // Validate material contain some map - (material.shader.id > 0)); // Validate material shader is valid + bool result = false; + + if ((material.maps != NULL) && // Validate material contain some map + (material.shader.id > 0)) result = true; // Validate material shader is valid + + return result; } // Unload material from memory @@ -2134,7 +2244,7 @@ Mesh GenMeshPoly(int sides, float radius) { Mesh mesh = { 0 }; - if (sides < 3) return mesh; + if (sides < 3) return mesh; // Security check int vertexCount = sides*3; @@ -2245,7 +2355,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ) for (int face = 0; face < numFaces; face++) { // Retrieve lower left corner from face ind - int i = face + face / (resX - 1); + int i = face + face/(resX - 1); triangles[t++] = i + resX; triangles[t++] = i + 1; @@ -2591,7 +2701,7 @@ Mesh GenMeshCylinder(float radius, float height, int slices) { // Instance a cylinder that sits on the Z=0 plane using the given tessellation // levels across the UV domain. Think of "slices" like a number of pizza - // slices, and "stacks" like a number of stacked rings. + // slices, and "stacks" like a number of stacked rings // Height and radius are both 1.0, but they can easily be changed with par_shapes_scale par_shapes_mesh *cylinder = par_shapes_create_cylinder(slices, 8); par_shapes_scale(cylinder, radius, radius, height); @@ -2655,7 +2765,7 @@ Mesh GenMeshCone(float radius, float height, int slices) { // Instance a cone that sits on the Z=0 plane using the given tessellation // levels across the UV domain. Think of "slices" like a number of pizza - // slices, and "stacks" like a number of stacked rings. + // slices, and "stacks" like a number of stacked rings // Height and radius are both 1.0, but they can easily be changed with par_shapes_scale par_shapes_mesh *cone = par_shapes_create_cone(slices, 8); par_shapes_scale(cone, radius, radius, height); @@ -2934,7 +3044,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) Color *pixels = LoadImageColors(cubicmap); // NOTE: Max possible number of triangles numCubes*(12 triangles by cube) - int maxTriangles = cubicmap.width * cubicmap.height * 12; + int maxTriangles = cubicmap.width*cubicmap.height*12; int vCounter = 0; // Used to count vertices int tcCounter = 0; // Used to count texcoords @@ -3400,8 +3510,8 @@ void GenMeshTangents(Mesh *mesh) } rlEnableVertexArray(mesh->vaoId); - rlSetVertexAttribute(4, 4, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(4); + rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, 4, RL_FLOAT, 0, 0, 0); + rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT); rlDisableVertexArray(); } @@ -3484,6 +3594,8 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector DrawBillboardPro(camera, texture, source, position, up, size, Vector2Zero(), 0.0f, tint); } +// Draw a billboard with additional parameters +// NOTE: Size defines the destination rectangle size, stretching the source texture as required void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint) { // NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width @@ -3553,7 +3665,7 @@ void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, tint.a); - if (sizeRatio.x * sizeRatio.y >= 0.0f) + if (sizeRatio.x*sizeRatio.y >= 0.0f) { // Bottom-left corner for texture and quad rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height); @@ -3709,7 +3821,7 @@ RayCollision GetRayCollisionBox(Ray ray, BoundingBox box) RayCollision collision = { 0 }; // Note: If ray.position is inside the box, the distance is negative (as if the ray was reversed) - // Reversing ray.direction will give use the correct result. + // Reversing ray.direction will give use the correct result bool insideBox = (ray.position.x > box.min.x) && (ray.position.x < box.max.x) && (ray.position.y > box.min.y) && (ray.position.y < box.max.y) && (ray.position.z > box.min.z) && (ray.position.z < box.max.z); @@ -3952,7 +4064,7 @@ static Model LoadOBJ(const char *fileName) model.meshCount = meshCount; // Set number of materials available - // NOTE: There could be more materials available than meshes but it will be resolved at + // NOTE: There could be more materials available than meshes but it will be resolved at // model.meshMaterial, just assigning the right material to corresponding mesh model.materialCount = materialCount; if (model.materialCount == 0) @@ -3970,7 +4082,7 @@ static Model LoadOBJ(const char *fileName) for (int i = 0; i < model.meshCount; i++) { // WARNING: We need to calculate the mesh triangles manually using meshes[i].face_offset - // because in case of triangulated quads, meshes[i].length actually report quads, + // because in case of triangulated quads, meshes[i].length actually report quads, // despite the triangulation that is efectively considered on attrib.num_faces unsigned int tris = 0; if (i == model.meshCount - 1) tris = attrib.num_faces - meshes[i].face_offset; @@ -4397,7 +4509,7 @@ static Model LoadIQM(const char *fileName) BuildPoseFromParentJoints(model.bones, model.boneCount, model.bindPose); - RL_FREE(fileData); + UnloadFileData(fileData); RL_FREE(imesh); RL_FREE(tri); @@ -4629,7 +4741,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou } } - RL_FREE(fileData); + UnloadFileData(fileData); RL_FREE(joints); RL_FREE(framedata); @@ -4642,6 +4754,26 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou #endif #if defined(SUPPORT_FILEFORMAT_GLTF) +// Load file data callback for cgltf +static cgltf_result LoadFileGLTFCallback(const struct cgltf_memory_options *memoryOptions, const struct cgltf_file_options *fileOptions, const char *path, cgltf_size *size, void **data) +{ + int filesize; + unsigned char *filedata = LoadFileData(path, &filesize); + + if (filedata == NULL) return cgltf_result_io_error; + + *size = filesize; + *data = filedata; + + return cgltf_result_success; +} + +// Release file data callback for cgltf +static void ReleaseFileGLTFCallback(const struct cgltf_memory_options *memoryOptions, const struct cgltf_file_options *fileOptions, void *data) +{ + UnloadFileData(data); +} + // Load image from different glTF provided methods (uri, path, buffer_view) static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPath) { @@ -4670,6 +4802,8 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat void *data = NULL; cgltf_options options = { 0 }; + options.file.read = LoadFileGLTFCallback; + options.file.release = ReleaseFileGLTFCallback; cgltf_result result = cgltf_load_buffer_base64(&options, outSize, cgltfImage->uri + i + 1, &data); if (result == cgltf_result_success) @@ -4793,6 +4927,8 @@ static Model LoadGLTF(const char *fileName) // glTF data loading cgltf_options options = { 0 }; + options.file.read = LoadFileGLTFCallback; + options.file.release = ReleaseFileGLTFCallback; cgltf_data *data = NULL; cgltf_result result = cgltf_parse(&options, fileData, dataSize, &data); @@ -4936,13 +5072,13 @@ static Model LoadGLTF(const char *fileName) for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++) { // Check the different attributes for every primitive - if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_position) // POSITION + if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_position) // POSITION, vec3, float { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - // WARNING: SPECS: POSITION accessor MUST have its min and max properties defined. + // WARNING: SPECS: POSITION accessor MUST have its min and max properties defined - if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec3)) + if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f)) { // Init raylib mesh vertices to copy glTF attribute data model.meshes[meshIndex].vertexCount = (int)attribute->count; @@ -4953,11 +5089,11 @@ static Model LoadGLTF(const char *fileName) } else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName); } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec3)) + if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f)) { // Init raylib mesh normals to copy glTF attribute data model.meshes[meshIndex].normals = RL_MALLOC(attribute->count*3*sizeof(float)); @@ -4967,11 +5103,11 @@ static Model LoadGLTF(const char *fileName) } else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName); } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec3, float { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec4)) + if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f)) { // Init raylib mesh tangent to copy glTF attribute data model.meshes[meshIndex].tangents = RL_MALLOC(attribute->count*4*sizeof(float)); @@ -4981,65 +5117,177 @@ static Model LoadGLTF(const char *fileName) } else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName); } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_0 + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n { - // TODO: Support additional texture coordinates: TEXCOORD_1 -> mesh.texcoords2 + // Support up to 2 texture coordinates attributes + float *texcoordPtr = NULL; cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec2)) + if (attribute->type == cgltf_type_vec2) { - // Init raylib mesh texcoords to copy glTF attribute data - model.meshes[meshIndex].texcoords = RL_MALLOC(attribute->count*2*sizeof(float)); + if (attribute->component_type == cgltf_component_type_r_32f) // vec2, float + { + // Init raylib mesh texcoords to copy glTF attribute data + texcoordPtr = (float *)RL_MALLOC(attribute->count*2*sizeof(float)); - // Load 3 components of float data type into mesh.texcoords - LOAD_ATTRIBUTE(attribute, 2, float, model.meshes[meshIndex].texcoords) + // Load 3 components of float data type into mesh.texcoords + LOAD_ATTRIBUTE(attribute, 2, float, texcoordPtr) + } + else if (attribute->component_type == cgltf_component_type_r_8u) // vec2, u8n + { + // Init raylib mesh texcoords to copy glTF attribute data + texcoordPtr = (float *)RL_MALLOC(attribute->count*2*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned char *temp = (unsigned char *)RL_MALLOC(attribute->count*2*sizeof(unsigned char)); + LOAD_ATTRIBUTE(attribute, 2, unsigned char, temp); + + // Convert data to raylib texcoord data type (float) + for (unsigned int t = 0; t < attribute->count*2; t++) texcoordPtr[t] = (float)temp[t]/255.0f; + + RL_FREE(temp); + } + else if (attribute->component_type == cgltf_component_type_r_16u) // vec2, u16n + { + // Init raylib mesh texcoords to copy glTF attribute data + texcoordPtr = (float *)RL_MALLOC(attribute->count*2*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*2*sizeof(unsigned short)); + LOAD_ATTRIBUTE(attribute, 2, unsigned short, temp); + + // Convert data to raylib texcoord data type (float) + for (unsigned int t = 0; t < attribute->count*2; t++) texcoordPtr[t] = (float)temp[t]/65535.0f; + + RL_FREE(temp); + } + else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported", fileName); } else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); + + int index = data->meshes[i].primitives[p].attributes[j].index; + if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr; + else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr; + else + { + TRACELOG(LOG_WARNING, "MODEL: [%s] No more than 2 texture coordinates attributes supported", fileName); + if (texcoordPtr != NULL) RL_FREE(texcoordPtr); + } } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_0 + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_n, vec3/vec4, float/u8n/u16n { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - // WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range. + // WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range - if ((attribute->component_type == cgltf_component_type_r_8u) && (attribute->type == cgltf_type_vec4)) + if (attribute->type == cgltf_type_vec3) // RGB { - // Init raylib mesh color to copy glTF attribute data - model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); + if (attribute->component_type == cgltf_component_type_r_8u) + { + // Init raylib mesh color to copy glTF attribute data + model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); - // Load 4 components of unsigned char data type into mesh.colors - LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors) + // Load data into a temp buffer to be converted to raylib data type + unsigned char *temp = RL_MALLOC(attribute->count*3*sizeof(unsigned char)); + LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp); + + // Convert data to raylib color data type (4 bytes) + for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3) + { + model.meshes[meshIndex].colors[c] = temp[k]; + model.meshes[meshIndex].colors[c + 1] = temp[k + 1]; + model.meshes[meshIndex].colors[c + 2] = temp[k + 2]; + model.meshes[meshIndex].colors[c + 3] = 255; + } + + RL_FREE(temp); + } + else if (attribute->component_type == cgltf_component_type_r_16u) + { + // Init raylib mesh color to copy glTF attribute data + model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned short *temp = RL_MALLOC(attribute->count*3*sizeof(unsigned short)); + LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp); + + // Convert data to raylib color data type (4 bytes) + for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3) + { + model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[k]/65535.0f)*255.0f); + model.meshes[meshIndex].colors[c + 1] = (unsigned char)(((float)temp[k + 1]/65535.0f)*255.0f); + model.meshes[meshIndex].colors[c + 2] = (unsigned char)(((float)temp[k + 2]/65535.0f)*255.0f); + model.meshes[meshIndex].colors[c + 3] = 255; + } + + RL_FREE(temp); + } + else if (attribute->component_type == cgltf_component_type_r_32f) + { + // Init raylib mesh color to copy glTF attribute data + model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); + + // Load data into a temp buffer to be converted to raylib data type + float *temp = RL_MALLOC(attribute->count*3*sizeof(float)); + LOAD_ATTRIBUTE(attribute, 3, float, temp); + + // Convert data to raylib color data type (4 bytes) + for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3) + { + model.meshes[meshIndex].colors[c] = (unsigned char)(temp[k]*255.0f); + model.meshes[meshIndex].colors[c + 1] = (unsigned char)(temp[k + 1]*255.0f); + model.meshes[meshIndex].colors[c + 2] = (unsigned char)(temp[k + 2]*255.0f); + model.meshes[meshIndex].colors[c + 3] = 255; + } + + RL_FREE(temp); + } + else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName); } - else if ((attribute->component_type == cgltf_component_type_r_16u) && (attribute->type == cgltf_type_vec4)) + else if (attribute->type == cgltf_type_vec4) // RGBA { - // Init raylib mesh color to copy glTF attribute data - model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); + if (attribute->component_type == cgltf_component_type_r_8u) + { + // Init raylib mesh color to copy glTF attribute data + model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); - // Load data into a temp buffer to be converted to raylib data type - unsigned short *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned short)); - LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); + // Load 4 components of unsigned char data type into mesh.colors + LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors) + } + else if (attribute->component_type == cgltf_component_type_r_16u) + { + // Init raylib mesh color to copy glTF attribute data + model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); - // Convert data to raylib color data type (4 bytes) - for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[c]/65535.0f)*255.0f); + // Load data into a temp buffer to be converted to raylib data type + unsigned short *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned short)); + LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); - RL_FREE(temp); - } - else if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec4)) - { - // Init raylib mesh color to copy glTF attribute data - model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); + // Convert data to raylib color data type (4 bytes) + for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[c]/65535.0f)*255.0f); - // Load data into a temp buffer to be converted to raylib data type - float *temp = RL_MALLOC(attribute->count*4*sizeof(float)); - LOAD_ATTRIBUTE(attribute, 4, float, temp); + RL_FREE(temp); + } + else if (attribute->component_type == cgltf_component_type_r_32f) + { + // Init raylib mesh color to copy glTF attribute data + model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); - // Convert data to raylib color data type (4 bytes), we expect the color data normalized - for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f); + // Load data into a temp buffer to be converted to raylib data type + float *temp = RL_MALLOC(attribute->count*4*sizeof(float)); + LOAD_ATTRIBUTE(attribute, 4, float, temp); - RL_FREE(temp); + // Convert data to raylib color data type (4 bytes), we expect the color data normalized + for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f); + + RL_FREE(temp); + } + else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName); } else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName); + + } // NOTE: Attributes related to animations are processed separately @@ -5149,37 +5397,103 @@ static Model LoadGLTF(const char *fileName) { // NOTE: JOINTS_1 + WEIGHT_1 will be used for +4 joints influencing a vertex -> Not supported by raylib - if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_joints) // JOINTS_n (vec4: 4 bones max per vertex / u8, u16) + if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_joints) // JOINTS_n (vec4: 4 bones max per vertex / u8, u16) { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - if ((attribute->component_type == cgltf_component_type_r_8u) && (attribute->type == cgltf_type_vec4)) - { - // Init raylib mesh bone ids to copy glTF attribute data - model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); + // NOTE: JOINTS_n can only be vec4 and u8/u16 + // SPECS: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview - // Load 4 components of unsigned char data type into mesh.boneIds - // for cgltf_attribute_type_joints we have: - // - data.meshes[0] (256 vertices) - // - 256 values, provided as cgltf_type_vec4 of bytes (4 byte per joint, stride 4) - LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].boneIds) + // WARNING: raylib only supports model.meshes[].boneIds as u8 (unsigned char), + // if data is provided in any other format, it is converted to supported format but + // it could imply data loss (a warning message is issued in that case) + + if (attribute->type == cgltf_type_vec4) + { + if (attribute->component_type == cgltf_component_type_r_8u) + { + // Init raylib mesh boneIds to copy glTF attribute data + model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); + + // Load attribute: vec4, u8 (unsigned char) + LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].boneIds) + } + else if (attribute->component_type == cgltf_component_type_r_16u) + { + // Init raylib mesh boneIds to copy glTF attribute data + model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned short *temp = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned short)); + LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); + + // Convert data to raylib color data type (4 bytes) + bool boneIdOverflowWarning = false; + for (int b = 0; b < model.meshes[meshIndex].vertexCount*4; b++) + { + if ((temp[b] > 255) && !boneIdOverflowWarning) + { + TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format (u16) overflow", fileName); + boneIdOverflowWarning = true; + } + + // Despite the possible overflow, we convert data to unsigned char + model.meshes[meshIndex].boneIds[b] = (unsigned char)temp[b]; + } + + RL_FREE(temp); + } + else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName); } - else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported, use vec4 u8", fileName); + else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName); } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4 / u8, u16, f32) + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4, u8n/u16n/f32) { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; - if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec4)) + if (attribute->type == cgltf_type_vec4) { - // Init raylib mesh bone weight to copy glTF attribute data - model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); + // TODO: Support component types: u8, u16? + if (attribute->component_type == cgltf_component_type_r_8u) + { + // Init raylib mesh bone weight to copy glTF attribute data + model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); - // Load 4 components of float data type into mesh.boneWeights - // for cgltf_attribute_type_weights we have: - // - data.meshes[0] (256 vertices) - // - 256 values, provided as cgltf_type_vec4 of float (4 byte per joint, stride 16) - LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].boneWeights) + // Load data into a temp buffer to be converted to raylib data type + unsigned char *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); + LOAD_ATTRIBUTE(attribute, 4, unsigned char, temp); + + // Convert data to raylib bone weight data type (4 bytes) + for (unsigned int b = 0; b < attribute->count*4; b++) model.meshes[meshIndex].boneWeights[b] = (float)temp[b]/255.0f; + + RL_FREE(temp); + } + else if (attribute->component_type == cgltf_component_type_r_16u) + { + // Init raylib mesh bone weight to copy glTF attribute data + model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned short *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned short)); + LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); + + // Convert data to raylib bone weight data type + for (unsigned int b = 0; b < attribute->count*4; b++) model.meshes[meshIndex].boneWeights[b] = (float)temp[b]/65535.0f; + + RL_FREE(temp); + } + else if (attribute->component_type == cgltf_component_type_r_32f) + { + // Init raylib mesh bone weight to copy glTF attribute data + model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); + + // Load 4 components of float data type into mesh.boneWeights + // for cgltf_attribute_type_weights we have: + // - data.meshes[0] (256 vertices) + // - 256 values, provided as cgltf_type_vec4 of float (4 byte per joint, stride 16) + LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].boneWeights) + } + else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint weight attribute data format not supported, use vec4 float", fileName); } else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint weight attribute data format not supported, use vec4 float", fileName); } @@ -5189,7 +5503,8 @@ static Model LoadGLTF(const char *fileName) model.meshes[meshIndex].animVertices = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); memcpy(model.meshes[meshIndex].animVertices, model.meshes[meshIndex].vertices, model.meshes[meshIndex].vertexCount*3*sizeof(float)); model.meshes[meshIndex].animNormals = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); - if (model.meshes[meshIndex].normals != NULL) { + if (model.meshes[meshIndex].normals != NULL) + { memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float)); } @@ -5209,9 +5524,11 @@ static Model LoadGLTF(const char *fileName) return model; } -// Get interpolated pose for bone sampler at a specific time. Returns true on success. -static bool GetPoseAtTimeGLTF(cgltf_accessor *input, cgltf_accessor *output, float time, void *data) +// Get interpolated pose for bone sampler at a specific time. Returns true on success +static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_accessor *input, cgltf_accessor *output, float time, void *data) { + if (interpolationType >= cgltf_interpolation_type_max_enum) return false; + // Input and output should have the same count float tstart = 0.0f; float tend = 0.0f; @@ -5232,7 +5549,8 @@ static bool GetPoseAtTimeGLTF(cgltf_accessor *input, cgltf_accessor *output, flo } } - float t = (time - tstart)/(tend - tstart); + float duration = fmaxf((tend - tstart), EPSILON); + float t = (time - tstart)/duration; t = (t < 0.0f)? 0.0f : t; t = (t > 1.0f)? 1.0f : t; @@ -5240,25 +5558,99 @@ static bool GetPoseAtTimeGLTF(cgltf_accessor *input, cgltf_accessor *output, flo if (output->type == cgltf_type_vec3) { - float tmp[3] = { 0.0f }; - cgltf_accessor_read_float(output, keyframe, tmp, 3); - Vector3 v1 = {tmp[0], tmp[1], tmp[2]}; - cgltf_accessor_read_float(output, keyframe+1, tmp, 3); - Vector3 v2 = {tmp[0], tmp[1], tmp[2]}; - Vector3 *r = data; - *r = Vector3Lerp(v1, v2, t); + switch (interpolationType) + { + case cgltf_interpolation_type_step: + { + float tmp[3] = { 0.0f }; + cgltf_accessor_read_float(output, keyframe, tmp, 3); + Vector3 v1 = {tmp[0], tmp[1], tmp[2]}; + Vector3 *r = data; + + *r = v1; + } break; + case cgltf_interpolation_type_linear: + { + float tmp[3] = { 0.0f }; + cgltf_accessor_read_float(output, keyframe, tmp, 3); + Vector3 v1 = {tmp[0], tmp[1], tmp[2]}; + cgltf_accessor_read_float(output, keyframe+1, tmp, 3); + Vector3 v2 = {tmp[0], tmp[1], tmp[2]}; + Vector3 *r = data; + + *r = Vector3Lerp(v1, v2, t); + } break; + case cgltf_interpolation_type_cubic_spline: + { + float tmp[3] = { 0.0f }; + cgltf_accessor_read_float(output, 3*keyframe+1, tmp, 3); + Vector3 v1 = {tmp[0], tmp[1], tmp[2]}; + cgltf_accessor_read_float(output, 3*keyframe+2, tmp, 3); + Vector3 tangent1 = {tmp[0], tmp[1], tmp[2]}; + cgltf_accessor_read_float(output, 3*(keyframe+1)+1, tmp, 3); + Vector3 v2 = {tmp[0], tmp[1], tmp[2]}; + cgltf_accessor_read_float(output, 3*(keyframe+1), tmp, 3); + Vector3 tangent2 = {tmp[0], tmp[1], tmp[2]}; + Vector3 *r = data; + + *r = Vector3CubicHermite(v1, tangent1, v2, tangent2, t); + } break; + default: break; + } } else if (output->type == cgltf_type_vec4) { - float tmp[4] = { 0.0f }; - cgltf_accessor_read_float(output, keyframe, tmp, 4); - Vector4 v1 = {tmp[0], tmp[1], tmp[2], tmp[3]}; - cgltf_accessor_read_float(output, keyframe+1, tmp, 4); - Vector4 v2 = {tmp[0], tmp[1], tmp[2], tmp[3]}; - Vector4 *r = data; - // Only v4 is for rotations, so we know it's a quaternion - *r = QuaternionSlerp(v1, v2, t); + switch (interpolationType) + { + case cgltf_interpolation_type_step: + { + float tmp[4] = { 0.0f }; + cgltf_accessor_read_float(output, keyframe, tmp, 4); + Vector4 v1 = {tmp[0], tmp[1], tmp[2], tmp[3]}; + Vector4 *r = data; + + *r = v1; + } break; + case cgltf_interpolation_type_linear: + { + float tmp[4] = { 0.0f }; + cgltf_accessor_read_float(output, keyframe, tmp, 4); + Vector4 v1 = {tmp[0], tmp[1], tmp[2], tmp[3]}; + cgltf_accessor_read_float(output, keyframe+1, tmp, 4); + Vector4 v2 = {tmp[0], tmp[1], tmp[2], tmp[3]}; + Vector4 *r = data; + + *r = QuaternionSlerp(v1, v2, t); + } break; + case cgltf_interpolation_type_cubic_spline: + { + float tmp[4] = { 0.0f }; + cgltf_accessor_read_float(output, 3*keyframe+1, tmp, 4); + Vector4 v1 = {tmp[0], tmp[1], tmp[2], tmp[3]}; + cgltf_accessor_read_float(output, 3*keyframe+2, tmp, 4); + Vector4 outTangent1 = {tmp[0], tmp[1], tmp[2]}; + cgltf_accessor_read_float(output, 3*(keyframe+1)+1, tmp, 4); + Vector4 v2 = {tmp[0], tmp[1], tmp[2], tmp[3]}; + cgltf_accessor_read_float(output, 3*(keyframe+1), tmp, 4); + Vector4 inTangent2 = {tmp[0], tmp[1], tmp[2]}; + Vector4 *r = data; + + v1 = QuaternionNormalize(v1); + v2 = QuaternionNormalize(v2); + + if (Vector4DotProduct(v1, v2) < 0.0f) + { + v2 = Vector4Negate(v2); + } + + outTangent1 = Vector4Scale(outTangent1, duration); + inTangent2 = Vector4Scale(inTangent2, duration); + + *r = QuaternionCubicHermiteSpline(v1, outTangent1, v2, inTangent2, t); + } break; + default: break; + } } return true; @@ -5276,6 +5668,8 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo // glTF data loading cgltf_options options = { 0 }; + options.file.read = LoadFileGLTFCallback; + options.file.release = ReleaseFileGLTFCallback; cgltf_data *data = NULL; cgltf_result result = cgltf_parse(&options, fileData, dataSize, &data); @@ -5307,6 +5701,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo cgltf_animation_channel *translate; cgltf_animation_channel *rotate; cgltf_animation_channel *scale; + cgltf_interpolation_type interpolationType; }; struct Channels *boneChannels = RL_CALLOC(animations[i].boneCount, sizeof(struct Channels)); @@ -5332,7 +5727,9 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo continue; } - if (animData.channels[j].sampler->interpolation == cgltf_interpolation_type_linear) + boneChannels[boneIndex].interpolationType = animData.channels[j].sampler->interpolation; + + if (animData.channels[j].sampler->interpolation != cgltf_interpolation_type_max_enum) { if (channel.target_path == cgltf_animation_path_type_translation) { @@ -5351,7 +5748,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo TRACELOG(LOG_WARNING, "MODEL: [%s] Unsupported target_path on channel %d's sampler for animation %d. Skipping.", fileName, j, i); } } - else TRACELOG(LOG_WARNING, "MODEL: [%s] Only linear interpolation curves are supported for GLTF animation.", fileName); + else TRACELOG(LOG_WARNING, "MODEL: [%s] Invalid interpolation curve encountered for GLTF animation.", fileName); float t = 0.0f; cgltf_bool r = cgltf_accessor_read_float(channel.sampler->input, channel.sampler->input->count - 1, &t, 1); @@ -5368,7 +5765,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo strncpy(animations[i].name, animData.name, sizeof(animations[i].name)); animations[i].name[sizeof(animations[i].name) - 1] = '\0'; - animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY); + animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1; animations[i].framePoses = RL_MALLOC(animations[i].frameCount*sizeof(Transform *)); for (int j = 0; j < animations[i].frameCount; j++) @@ -5384,7 +5781,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo if (boneChannels[k].translate) { - if (!GetPoseAtTimeGLTF(boneChannels[k].translate->sampler->input, boneChannels[k].translate->sampler->output, time, &translation)) + if (!GetPoseAtTimeGLTF(boneChannels[k].interpolationType, boneChannels[k].translate->sampler->input, boneChannels[k].translate->sampler->output, time, &translation)) { TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load translate pose data for bone %s", fileName, animations[i].bones[k].name); } @@ -5392,7 +5789,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo if (boneChannels[k].rotate) { - if (!GetPoseAtTimeGLTF(boneChannels[k].rotate->sampler->input, boneChannels[k].rotate->sampler->output, time, &rotation)) + if (!GetPoseAtTimeGLTF(boneChannels[k].interpolationType, boneChannels[k].rotate->sampler->input, boneChannels[k].rotate->sampler->output, time, &rotation)) { TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load rotate pose data for bone %s", fileName, animations[i].bones[k].name); } @@ -5400,7 +5797,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo if (boneChannels[k].scale) { - if (!GetPoseAtTimeGLTF(boneChannels[k].scale->sampler->input, boneChannels[k].scale->sampler->output, time, &scale)) + if (!GetPoseAtTimeGLTF(boneChannels[k].interpolationType, boneChannels[k].scale->sampler->input, boneChannels[k].scale->sampler->output, time, &scale)) { TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load scale pose data for bone %s", fileName, animations[i].bones[k].name); } @@ -5487,6 +5884,7 @@ static Model LoadVOX(const char *fileName) // 6*4 = 12 vertices per voxel Vector3 *pvertices = (Vector3 *)voxarray.vertices.array; + Vector3 *pnormals = (Vector3 *)voxarray.normals.array; Color *pcolors = (Color *)voxarray.colors.array; unsigned short *pindices = voxarray.indices.array; // 5461*6*6 = 196596 indices max per mesh @@ -5502,12 +5900,16 @@ static Model LoadVOX(const char *fileName) pmesh->vertexCount = (int)fmin(verticesMax, verticesRemain); size = pmesh->vertexCount*sizeof(float)*3; - pmesh->vertices = RL_MALLOC(size); + pmesh->vertices = (float *)RL_MALLOC(size); memcpy(pmesh->vertices, pvertices, size); + // Copy normals + pmesh->normals = (float *)RL_MALLOC(size); + memcpy(pmesh->normals, pnormals, size); + // Copy indices size = voxarray.indices.used*sizeof(unsigned short); - pmesh->indices = RL_MALLOC(size); + pmesh->indices = (unsigned short *)RL_MALLOC(size); memcpy(pmesh->indices, pindices, size); pmesh->triangleCount = (pmesh->vertexCount/4)*2; @@ -5522,6 +5924,7 @@ static Model LoadVOX(const char *fileName) verticesRemain -= verticesMax; pvertices += verticesMax; + pnormals += verticesMax; pcolors += verticesMax; } @@ -5585,7 +5988,7 @@ static Model LoadM3D(const char *fileName) // We always need a default material, so we add +1 model.materialCount++; - // Faces must be in non-decreasing materialid order. Verify that quickly, sorting them otherwise. + // Faces must be in non-decreasing materialid order. Verify that quickly, sorting them otherwise // WARNING: Sorting is not needed, valid M3D model files should already be sorted // Just keeping the sorting function for reference (Check PR #3363 #3385) /* @@ -5593,12 +5996,12 @@ static Model LoadM3D(const char *fileName) { if (m3d->face[i-1].materialid <= m3d->face[i].materialid) continue; - // face[i-1] > face[i]. slide face[i] lower. + // face[i-1] > face[i]. slide face[i] lower m3df_t slider = m3d->face[i]; j = i-1; do - { // face[j] > slider, face[j+1] is svailable vacant gap. + { // face[j] > slider, face[j+1] is svailable vacant gap m3d->face[j+1] = m3d->face[j]; j = j-1; } @@ -5651,6 +6054,12 @@ static Model LoadM3D(const char *fileName) // M3D specs only consider vertex colors if no material is provided, however raylib uses both and mixes the colors if ((mi == M3D_UNDEF) || vcolor) model.meshes[k].colors = RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char)); + // If no map is provided and we allocated vertex colors, set them to white + if ((mi == M3D_UNDEF) && (model.meshes[k].colors != NULL)) + { + for (int c = 0; c < model.meshes[k].vertexCount*4; c++) model.meshes[k].colors[c] = 255; + } + if (m3d->numbone && m3d->numskin) { model.meshes[k].boneIds = (unsigned char *)RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char)); @@ -5853,10 +6262,10 @@ static Model LoadM3D(const char *fileName) } // Load bone-pose default mesh into animation vertices. These will be updated when UpdateModelAnimation gets - // called, but not before, however DrawMesh uses these if they exist (so not good if they are left empty). + // called, but not before, however DrawMesh uses these if they exist (so not good if they are left empty) if (m3d->numbone && m3d->numskin) { - for(i = 0; i < model.meshCount; i++) + for (i = 0; i < model.meshCount; i++) { memcpy(model.meshes[i].animVertices, model.meshes[i].vertices, model.meshes[i].vertexCount*3*sizeof(float)); memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float)); @@ -5910,11 +6319,13 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou for (unsigned int a = 0; a < m3d->numaction; a++) { - animations[a].frameCount = m3d->action[a].durationmsec / M3D_ANIMDELAY; + animations[a].frameCount = m3d->action[a].durationmsec/M3D_ANIMDELAY; animations[a].boneCount = m3d->numbone + 1; animations[a].bones = RL_MALLOC((m3d->numbone + 1)*sizeof(BoneInfo)); animations[a].framePoses = RL_MALLOC(animations[a].frameCount*sizeof(Transform *)); - // strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name)); + strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name)); + animations[a].name[sizeof(animations[a].name) - 1] = '\0'; + TRACELOG(LOG_INFO, "MODEL: [%s] animation #%i: %i msec, %i frames", fileName, a, m3d->action[a].durationmsec, animations[a].frameCount); for (i = 0; i < (int)m3d->numbone; i++) diff --git a/raylib/rshapes.c b/raylib/rshapes.c index bababf8..80df64e 100644 --- a/raylib/rshapes.c +++ b/raylib/rshapes.c @@ -25,7 +25,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -71,7 +71,6 @@ #define SPLINE_SEGMENT_DIVISIONS 24 // Spline segment divisions #endif - //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -112,6 +111,18 @@ void SetShapesTexture(Texture2D texture, Rectangle source) } } +// Get texture that is used for shapes drawing +Texture2D GetShapesTexture(void) +{ + return texShapes; +} + +// Get texture source rectangle that is used for shapes drawing +Rectangle GetShapesTextureRectangle(void) +{ + return texShapesRec; +} + // Draw a pixel void DrawPixel(int posX, int posY, Color color) { @@ -122,23 +133,24 @@ void DrawPixel(int posX, int posY, Color color) void DrawPixelV(Vector2 position, Color color) { #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); rlNormal3f(0.0f, 0.0f, 1.0f); rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(position.x, position.y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(position.x, position.y + 1); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(position.x + 1, position.y + 1); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(position.x + 1, position.y); rlEnd(); @@ -166,8 +178,9 @@ void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color colo { rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - rlVertex2f((float)startPosX, (float)startPosY); - rlVertex2f((float)endPosX, (float)endPosY); + // WARNING: Adding 0.5f offset to "center" point on selected pixel + rlVertex2f((float)startPosX + 0.5f, (float)startPosY + 0.5f); + rlVertex2f((float)endPosX + 0.5f, (float)endPosY + 0.5f); rlEnd(); } @@ -176,26 +189,26 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color) { rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - rlVertex2f(startPos.x, startPos.y); - rlVertex2f(endPos.x, endPos.y); + // WARNING: Adding 0.5f offset to "center" point on selected pixel + rlVertex2f(startPos.x + 0.5f, startPos.y + 0.5f); + rlVertex2f(endPos.x + 0.5f, endPos.y + 0.5f); rlEnd(); } // Draw lines sequuence (using gl lines) void DrawLineStrip(Vector2 *points, int pointCount, Color color) { - if (pointCount >= 2) - { - rlBegin(RL_LINES); - rlColor4ub(color.r, color.g, color.b, color.a); + if (pointCount < 2) return; // Security check - for (int i = 0; i < pointCount - 1; i++) - { - rlVertex2f(points[i].x, points[i].y); - rlVertex2f(points[i + 1].x, points[i + 1].y); - } - rlEnd(); - } + rlBegin(RL_LINES); + rlColor4ub(color.r, color.g, color.b, color.a); + + for (int i = 0; i < pointCount - 1; i++) + { + rlVertex2f(points[i].x, points[i].y); + rlVertex2f(points[i + 1].x, points[i + 1].y); + } + rlEnd(); } // Draw line using cubic-bezier spline, in-out interpolation, no control points @@ -300,7 +313,8 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA float angle = startAngle; #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); @@ -309,36 +323,36 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA { rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2.0f))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2.0f))*radius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); angle += (stepLength*2.0f); } // NOTE: In case number of segments is odd, we add one last piece to the cake - if ((segments%2) == 1) + if (((unsigned int)segments%2) == 1) { rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); } @@ -528,23 +542,24 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA float angle = startAngle; #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); for (int i = 0; i < segments; i++) { rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius); angle += stepLength; @@ -707,23 +722,24 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color } #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); rlNormal3f(0.0f, 0.0f, 1.0f); rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(topLeft.x, topLeft.y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(bottomLeft.x, bottomLeft.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(bottomRight.x, bottomRight.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(topRight.x, topRight.y); rlEnd(); @@ -764,26 +780,27 @@ void DrawRectangleGradientH(int posX, int posY, int width, int height, Color col // NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4) { - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); rlNormal3f(0.0f, 0.0f, 1.0f); // NOTE: Default raylib font character 95 is a white square rlColor4ub(col1.r, col1.g, col1.b, col1.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(rec.x, rec.y); rlColor4ub(col2.r, col2.g, col2.b, col2.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(rec.x, rec.y + rec.height); rlColor4ub(col3.r, col3.g, col3.b, col3.a); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(rec.x + rec.width, rec.y + rec.height); rlColor4ub(col4.r, col4.g, col4.b, col4.a); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(rec.x + rec.width, rec.y); rlEnd(); @@ -791,30 +808,25 @@ void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, } // Draw rectangle outline -// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues +// WARNING: All Draw*Lines() functions use RL_LINES for drawing, +// it implies flushing the current batch and changing draw mode to RL_LINES +// but it solves another issue: https://github.com/raysan5/raylib/issues/3884 void DrawRectangleLines(int posX, int posY, int width, int height, Color color) { -#if defined(SUPPORT_QUADS_DRAW_MODE) - DrawRectangle(posX, posY, width, 1, color); - DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color); - DrawRectangle(posX, posY + height - 1, width, 1, color); - DrawRectangle(posX, posY + 1, 1, height - 2, color); -#else rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - rlVertex2f(posX + 1, posY + 1); - rlVertex2f(posX + width, posY + 1); + rlVertex2f((float)posX, (float)posY); + rlVertex2f((float)posX + (float)width, (float)posY + 1); - rlVertex2f(posX + width, posY + 1); - rlVertex2f(posX + width, posY + height); + rlVertex2f((float)posX + (float)width, (float)posY + 1); + rlVertex2f((float)posX + (float)width, (float)posY + (float)height); - rlVertex2f(posX + width, posY + height); - rlVertex2f(posX + 1, posY + height); + rlVertex2f((float)posX + (float)width, (float)posY + (float)height); + rlVertex2f((float)posX + 1, (float)posY + (float)height); - rlVertex2f(posX + 1, posY + height); - rlVertex2f(posX + 1, posY + 1); + rlVertex2f((float)posX + 1, (float)posY + (float)height); + rlVertex2f((float)posX + 1, (float)posY + 1); rlEnd(); -#endif } // Draw rectangle outline with extended parameters @@ -904,7 +916,8 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f }; #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); // Draw all the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner @@ -917,16 +930,16 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co for (int i = 0; i < segments/2; i++) { rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2))*radius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); angle += (stepLength*2); @@ -936,73 +949,73 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co if (segments%2) { rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); } } // [2] Upper Rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[0].x, point[0].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[8].x, point[8].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[9].x, point[9].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[1].x, point[1].y); // [4] Right Rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[2].x, point[2].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[9].x, point[9].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[10].x, point[10].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[3].x, point[3].y); // [6] Bottom Rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[11].x, point[11].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[5].x, point[5].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[4].x, point[4].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[10].x, point[10].y); // [8] Left Rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[7].x, point[7].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[6].x, point[6].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[11].x, point[11].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[8].x, point[8].y); // [9] Middle Rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[8].x, point[8].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[11].x, point[11].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[10].x, point[10].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[9].x, point[9].y); rlEnd(); @@ -1073,8 +1086,15 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co #endif } +// Draw rectangle with rounded edges +// TODO: This function should be refactored to use RL_LINES, for consistency with other Draw*Lines() +void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color) +{ + DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color); +} + // Draw rectangle with rounded edges outline -void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color) +void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color) { if (lineThick < 0) lineThick = 0; @@ -1139,7 +1159,8 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo if (lineThick > 1) { #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); @@ -1152,16 +1173,16 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo { rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius); angle += stepLength; @@ -1170,46 +1191,46 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo // Upper rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[0].x, point[0].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[8].x, point[8].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[9].x, point[9].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[1].x, point[1].y); // Right rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[2].x, point[2].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[10].x, point[10].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[11].x, point[11].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[3].x, point[3].y); // Lower rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[13].x, point[13].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[5].x, point[5].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[4].x, point[4].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[12].x, point[12].y); // Left rectangle rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[15].x, point[15].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[7].x, point[7].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(point[6].x, point[6].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(point[14].x, point[14].y); rlEnd(); @@ -1314,21 +1335,22 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color) { #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); rlColor4ub(color.r, color.g, color.b, color.a); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(v1.x, v1.y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(v2.x, v2.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(v2.x, v2.y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(v3.x, v3.y); rlEnd(); @@ -1367,22 +1389,24 @@ void DrawTriangleFan(Vector2 *points, int pointCount, Color color) { if (pointCount >= 3) { - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); + rlBegin(RL_QUADS); rlColor4ub(color.r, color.g, color.b, color.a); for (int i = 1; i < pointCount - 1; i++) { - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(points[0].x, points[0].y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(points[i].x, points[i].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(points[i + 1].x, points[i + 1].y); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(points[i + 1].x, points[i + 1].y); } rlEnd(); @@ -1426,7 +1450,8 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col float angleStep = 360.0f/(float)sides*DEG2RAD; #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); for (int i = 0; i < sides; i++) @@ -1434,16 +1459,16 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col rlColor4ub(color.r, color.g, color.b, color.a); float nextAngle = centralAngle + angleStep; - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius); centralAngle = nextAngle; @@ -1494,7 +1519,8 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl float innerRadius = radius - (lineThick*cosf(DEG2RAD*exteriorAngle/2.0f)); #if defined(SUPPORT_QUADS_DRAW_MODE) - rlSetTexture(texShapes.id); + rlSetTexture(GetShapesTexture().id); + Rectangle shapeRect = GetShapesTextureRectangle(); rlBegin(RL_QUADS); for (int i = 0; i < sides; i++) @@ -1502,16 +1528,16 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl rlColor4ub(color.r, color.g, color.b, color.a); float nextAngle = centralAngle + exteriorAngle; - rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius); - rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius); - rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius); centralAngle = nextAngle; @@ -1546,10 +1572,96 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl // Draw spline: linear, minimum 2 points void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) { + if (pointCount < 2) return; + +#if defined(SUPPORT_SPLINE_MITERS) + Vector2 prevNormal = (Vector2){-(points[1].y - points[0].y), (points[1].x - points[0].x)}; + float prevLength = sqrtf(prevNormal.x*prevNormal.x + prevNormal.y*prevNormal.y); + + if (prevLength > 0.0f) + { + prevNormal.x /= prevLength; + prevNormal.y /= prevLength; + } + else + { + prevNormal.x = 0.0f; + prevNormal.y = 0.0f; + } + + Vector2 prevRadius = { 0.5f*thick*prevNormal.x, 0.5f*thick*prevNormal.y }; + + for (int i = 0; i < pointCount - 1; i++) + { + Vector2 normal = { 0 }; + + if (i < pointCount - 2) + { + normal = (Vector2){-(points[i + 2].y - points[i + 1].y), (points[i + 2].x - points[i + 1].x)}; + float normalLength = sqrtf(normal.x*normal.x + normal.y*normal.y); + + if (normalLength > 0.0f) + { + normal.x /= normalLength; + normal.y /= normalLength; + } + else + { + normal.x = 0.0f; + normal.y = 0.0f; + } + } + else + { + normal = prevNormal; + } + + Vector2 radius = { prevNormal.x + normal.x, prevNormal.y + normal.y }; + float radiusLength = sqrtf(radius.x*radius.x + radius.y*radius.y); + + if (radiusLength > 0.0f) + { + radius.x /= radiusLength; + radius.y /= radiusLength; + } + else + { + radius.x = 0.0f; + radius.y = 0.0f; + } + + float cosTheta = radius.x*normal.x + radius.y*normal.y; + + if (cosTheta != 0.0f) + { + radius.x *= (thick*0.5f/cosTheta); + radius.y *= (thick*0.5f/cosTheta); + } + else + { + radius.x = 0.0f; + radius.y = 0.0f; + } + + Vector2 strip[4] = { + { points[i].x - prevRadius.x, points[i].y - prevRadius.y }, + { points[i].x + prevRadius.x, points[i].y + prevRadius.y }, + { points[i + 1].x - radius.x, points[i + 1].y - radius.y }, + { points[i + 1].x + radius.x, points[i + 1].y + radius.y } + }; + + DrawTriangleStrip(strip, 4, color); + + prevRadius = radius; + prevNormal = normal; + } + +#else // !SUPPORT_SPLINE_MITTERS + Vector2 delta = { 0 }; float length = 0.0f; float scale = 0.0f; - + for (int i = 0; i < pointCount - 1; i++) { delta = (Vector2){ points[i + 1].x - points[i].x, points[i + 1].y - points[i].y }; @@ -1567,8 +1679,10 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) DrawTriangleStrip(strip, 4, color); } +#endif + #if defined(SUPPORT_SPLINE_SEGMENT_CAPS) - + // TODO: Add spline segment rounded caps at the begin/end of the spline #endif } @@ -1718,7 +1832,7 @@ void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color co void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color) { if (pointCount < 3) return; - + for (int i = 0; i < pointCount - 2; i++) { DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color); @@ -1729,7 +1843,7 @@ void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Col void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color) { if (pointCount < 4) return; - + for (int i = 0; i < pointCount - 3; i++) { DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color); @@ -1740,7 +1854,7 @@ void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color c void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color) { // NOTE: For the linear spline we don't use subdivisions, just a single quad - + Vector2 delta = { p2.x - p1.x, p2.y - p1.y }; float length = sqrtf(delta.x*delta.x + delta.y*delta.y); @@ -1768,9 +1882,9 @@ void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, floa Vector2 currentPoint = { 0 }; Vector2 nextPoint = { 0 }; float t = 0.0f; - + Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; - + float a[4] = { 0 }; float b[4] = { 0 }; @@ -1825,7 +1939,7 @@ void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 currentPoint = p1; Vector2 nextPoint = { 0 }; float t = 0.0f; - + Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; for (int i = 0; i <= SPLINE_SEGMENT_DIVISIONS; i++) @@ -2083,21 +2197,21 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 // NOTE: Based on http://jeffreythompson.org/collision-detection/poly-point.php bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount) { - bool collision = false; + bool inside = false; if (pointCount > 2) { - for (int i = 0; i < pointCount - 1; i++) + for (int i = 0, j = pointCount - 1; i < pointCount; j = i++) { - Vector2 vc = points[i]; - Vector2 vn = points[i + 1]; - - if ((((vc.y >= point.y) && (vn.y < point.y)) || ((vc.y < point.y) && (vn.y >= point.y))) && - (point.x < ((vn.x - vc.x)*(point.y - vc.y)/(vn.y - vc.y) + vc.x))) collision = !collision; + if ((points[i].y > point.y) != (points[j].y > point.y) && + (point.x < (points[j].x - points[i].x)*(point.y - points[i].y)/(points[j].y - points[i].y) + points[i].x)) + { + inside = !inside; + } } } - return collision; + return inside; } // Check collision between two rectangles @@ -2132,11 +2246,11 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) { bool collision = false; - int recCenterX = (int)(rec.x + rec.width/2.0f); - int recCenterY = (int)(rec.y + rec.height/2.0f); + float recCenterX = rec.x + rec.width/2.0f; + float recCenterY = rec.y + rec.height/2.0f; - float dx = fabsf(center.x - (float)recCenterX); - float dy = fabsf(center.y - (float)recCenterY); + float dx = fabsf(center.x - recCenterX); + float dy = fabsf(center.y - recCenterY); if (dx > (rec.width/2.0f + radius)) { return false; } if (dy > (rec.height/2.0f + radius)) { return false; } @@ -2234,11 +2348,16 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) // NOTE: Used by DrawLineBezier() only static float EaseCubicInOut(float t, float b, float c, float d) { - if ((t /= 0.5f*d) < 1) return 0.5f*c*t*t*t + b; + float result = 0.0f; - t -= 2; + if ((t /= 0.5f*d) < 1) result = 0.5f*c*t*t*t + b; + else + { + t -= 2; + result = 0.5f*c*(t*t*t + 2.0f) + b; + } - return 0.5f*c*(t*t*t + 2.0f) + b; + return result; } #endif // SUPPORT_MODULE_RSHAPES diff --git a/raylib/rshapes.go b/raylib/rshapes.go index 25fb1b7..2e2e18f 100644 --- a/raylib/rshapes.go +++ b/raylib/rshapes.go @@ -276,9 +276,8 @@ func DrawRectangleRoundedLines(rec Rectangle, roundness float32, segments, lineT crec := rec.cptr() croundness := (C.float)(roundness) csegments := (C.int)(segments) - clineThick := (C.float)(lineThick) ccolor := colorCptr(col) - C.DrawRectangleRoundedLines(*crec, croundness, csegments, clineThick, *ccolor) + C.DrawRectangleRoundedLines(*crec, croundness, csegments, *ccolor) } // DrawTriangle - Draw a color-filled triangle diff --git a/raylib/rtext.c b/raylib/rtext.c index dd7c83f..b5ba17e 100644 --- a/raylib/rtext.c +++ b/raylib/rtext.c @@ -12,6 +12,7 @@ * * #define SUPPORT_FILEFORMAT_FNT * #define SUPPORT_FILEFORMAT_TTF +* #define SUPPORT_FILEFORMAT_BDF * Selected desired fileformats to be supported for loading. Some of those formats are * supported by default, to remove support, just comment unrequired #define in this module * @@ -33,7 +34,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -70,14 +71,27 @@ #include // Required for: va_list, va_start(), vsprintf(), va_end() [Used in TextFormat()] #include // Required for: toupper(), tolower() [Used in TextToUpper(), TextToLower()] -#if defined(SUPPORT_FILEFORMAT_TTF) +#if defined(SUPPORT_FILEFORMAT_TTF) || defined(SUPPORT_FILEFORMAT_BDF) #if defined(__GNUC__) // GCC and Clang #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #endif #define STB_RECT_PACK_IMPLEMENTATION - #include "external/stb_rect_pack.h" // Required for: ttf font rectangles packaging + #include "external/stb_rect_pack.h" // Required for: ttf/bdf font rectangles packaging + + #include // Required for: ttf/bdf font rectangles packaging + + #if defined(__GNUC__) // GCC and Clang + #pragma GCC diagnostic pop + #endif +#endif + +#if defined(SUPPORT_FILEFORMAT_TTF) + #if defined(__GNUC__) // GCC and Clang + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + #endif #define STBTT_STATIC #define STB_TRUETYPE_IMPLEMENTATION @@ -105,7 +119,7 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -// ... +//... //---------------------------------------------------------------------------------- // Global variables @@ -127,7 +141,10 @@ static Font defaultFont = { 0 }; #if defined(SUPPORT_FILEFORMAT_FNT) static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) #endif -static int textLineSpacing = 15; // Text vertical line spacing in pixels +#if defined(SUPPORT_FILEFORMAT_BDF) +static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize); +#endif +static int textLineSpacing = 2; // Text vertical line spacing in pixels (between lines) #if defined(SUPPORT_DEFAULT_FONT) extern void LoadFontDefault(void); @@ -334,6 +351,10 @@ Font LoadFont(const char *fileName) #if defined(SUPPORT_FILEFORMAT_FNT) if (IsFileExtension(fileName, ".fnt")) font = LoadBMFont(fileName); else +#endif +#if defined(SUPPORT_FILEFORMAT_BDF) + if (IsFileExtension(fileName, ".bdf")) font = LoadFontEx(fileName, FONT_TTF_DEFAULT_SIZE, NULL, FONT_TTF_DEFAULT_NUMCHARS); + else #endif { Image image = LoadImage(fileName); @@ -355,7 +376,7 @@ Font LoadFont(const char *fileName) return font; } -// Load Font from TTF font file with generation parameters +// Load Font from TTF or BDF font file with generation parameters // NOTE: You can pass an array with desired characters, those characters should be available in the font // if array is NULL, default char set is selected 32..126 Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount) @@ -413,7 +434,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar) if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break; } - if ((x == 0) || (y == 0)) return font; + if ((x == 0) || (y == 0)) return font; // Security check charSpacing = x; lineSpacing = y; @@ -509,37 +530,51 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int Font font = { 0 }; char fileExtLower[16] = { 0 }; - strcpy(fileExtLower, TextToLower(fileType)); + strncpy(fileExtLower, TextToLower(fileType), 16 - 1); + + font.baseSize = fontSize; + font.glyphCount = (codepointCount > 0)? codepointCount : 95; + font.glyphPadding = 0; #if defined(SUPPORT_FILEFORMAT_TTF) if (TextIsEqual(fileExtLower, ".ttf") || TextIsEqual(fileExtLower, ".otf")) { - font.baseSize = fontSize; - font.glyphCount = (codepointCount > 0)? codepointCount : 95; - font.glyphPadding = 0; font.glyphs = LoadFontData(fileData, dataSize, font.baseSize, codepoints, font.glyphCount, FONT_DEFAULT); - - if (font.glyphs != NULL) - { - font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING; - - Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0); - font.texture = LoadTextureFromImage(atlas); - - // Update glyphs[i].image to use alpha, required to be used on ImageDrawText() - for (int i = 0; i < font.glyphCount; i++) - { - UnloadImage(font.glyphs[i].image); - font.glyphs[i].image = ImageFromImage(atlas, font.recs[i]); - } - - UnloadImage(atlas); - - TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount); - } - else font = GetFontDefault(); } + else +#endif +#if defined(SUPPORT_FILEFORMAT_BDF) + if (TextIsEqual(fileExtLower, ".bdf")) + { + font.glyphs = LoadFontDataBDF(fileData, dataSize, codepoints, font.glyphCount, &font.baseSize); + } + else +#endif + { + font.glyphs = NULL; + } + +#if defined(SUPPORT_FILEFORMAT_TTF) || defined(SUPPORT_FILEFORMAT_BDF) + if (font.glyphs != NULL) + { + font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING; + + Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0); + font.texture = LoadTextureFromImage(atlas); + + // Update glyphs[i].image to use alpha, required to be used on ImageDrawText() + for (int i = 0; i < font.glyphCount; i++) + { + UnloadImage(font.glyphs[i].image); + font.glyphs[i].image = ImageFromImage(atlas, font.recs[i]); + } + + UnloadImage(atlas); + + TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount); + } + else font = GetFontDefault(); #else font = GetFontDefault(); #endif @@ -604,7 +639,6 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Fill fontChars in case not provided externally // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) - if (codepoints == NULL) { codepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); @@ -612,7 +646,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz genFontChars = true; } - chars = (GlyphInfo *)RL_MALLOC(codepointCount*sizeof(GlyphInfo)); + chars = (GlyphInfo *)RL_CALLOC(codepointCount, sizeof(GlyphInfo)); // NOTE: Using simple packaging, one char after another for (int i = 0; i < codepointCount; i++) @@ -626,54 +660,67 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide - if (type != FONT_SDF) chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); - else if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); - else chars[i].image.data = NULL; + // Check if a glyph is available in the font + // WARNING: if (index == 0), glyph not found, it could fallback to default .notdef glyph (if defined in font) + int index = stbtt_FindGlyphIndex(&fontInfo, ch); - stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL); - chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor); - - // Load characters images - chars[i].image.width = chw; - chars[i].image.height = chh; - chars[i].image.mipmaps = 1; - chars[i].image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; - - chars[i].offsetY += (int)((float)ascent*scaleFactor); - - // NOTE: We create an empty image for space character, it could be further required for atlas packing - if (ch == 32) + if (index > 0) { - Image imSpace = { - .data = RL_CALLOC(chars[i].advanceX*fontSize, 2), - .width = chars[i].advanceX, - .height = fontSize, - .mipmaps = 1, - .format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE - }; - - chars[i].image = imSpace; - } - - if (type == FONT_BITMAP) - { - // Aliased bitmap (black & white) font generation, avoiding anti-aliasing - // NOTE: For optimum results, bitmap font should be generated at base pixel size - for (int p = 0; p < chw*chh; p++) + switch (type) { - if (((unsigned char *)chars[i].image.data)[p] < FONT_BITMAP_ALPHA_THRESHOLD) ((unsigned char *)chars[i].image.data)[p] = 0; - else ((unsigned char *)chars[i].image.data)[p] = 255; + case FONT_DEFAULT: + case FONT_BITMAP: chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break; + case FONT_SDF: if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break; + default: break; + } + + if (chars[i].image.data != NULL) // Glyph data has been found in the font + { + stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL); + chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor); + + // Load characters images + chars[i].image.width = chw; + chars[i].image.height = chh; + chars[i].image.mipmaps = 1; + chars[i].image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; + + chars[i].offsetY += (int)((float)ascent*scaleFactor); + } + + // NOTE: We create an empty image for space character, + // it could be further required for atlas packing + if (ch == 32) + { + stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL); + chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor); + + Image imSpace = { + .data = RL_CALLOC(chars[i].advanceX*fontSize, 2), + .width = chars[i].advanceX, + .height = fontSize, + .mipmaps = 1, + .format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE + }; + + chars[i].image = imSpace; + } + + if (type == FONT_BITMAP) + { + // Aliased bitmap (black & white) font generation, avoiding anti-aliasing + // NOTE: For optimum results, bitmap font should be generated at base pixel size + for (int p = 0; p < chw*chh; p++) + { + if (((unsigned char *)chars[i].image.data)[p] < FONT_BITMAP_ALPHA_THRESHOLD) ((unsigned char *)chars[i].image.data)[p] = 0; + else ((unsigned char *)chars[i].image.data)[p] = 255; + } } } - - // Get bounding box for character (maybe offset to account for chars that dip above or below the line) - /* - int chX1, chY1, chX2, chY2; - stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2); - - TRACELOGD("FONT: Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1); - TRACELOGD("FONT: Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1); - */ + else + { + // TODO: Use some fallback glyph for codepoints not found in the font + } } } else TRACELOG(LOG_WARNING, "FONT: Failed to process TTF font data"); @@ -687,7 +734,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Generate image font atlas using chars info // NOTE: Packing method: 0-Default, 1-Skyline -#if defined(SUPPORT_FILEFORMAT_TTF) +#if defined(SUPPORT_FILEFORMAT_TTF) || defined(SUPPORT_FILEFORMAT_BDF) Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod) { Image atlas = { 0 }; @@ -713,7 +760,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp for (int i = 0; i < glyphCount; i++) { if (glyphs[i].image.width > maxGlyphWidth) maxGlyphWidth = glyphs[i].image.width; - totalWidth += glyphs[i].image.width + 4*padding; + totalWidth += glyphs[i].image.width + 2*padding; } //#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE @@ -731,8 +778,9 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp atlas.width = imageSize; // Atlas bitmap width atlas.height = imageSize; // Atlas bitmap height #else + int paddedFontSize = fontSize + 2*padding; // No need for a so-conservative atlas generation - float totalArea = totalWidth*fontSize*1.2f; + float totalArea = totalWidth*paddedFontSize*1.2f; float imageMinSize = sqrtf(totalArea); int imageSize = (int)powf(2, ceilf(logf(imageMinSize)/logf(2))); @@ -775,10 +823,10 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp if (offsetY > (atlas.height - fontSize - padding)) { - for(int j = i + 1; j < glyphCount; j++) + for (int j = i + 1; j < glyphCount; j++) { TRACELOG(LOG_WARNING, "FONT: Failed to package character (%i)", j); - // make sure remaining recs contain valid data + // Make sure remaining recs contain valid data recs[j].x = 0; recs[j].y = 0; recs[j].width = 0; @@ -923,7 +971,7 @@ bool ExportFontAsCode(Font font, const char *fileName) // Get file name from path char fileNamePascal[256] = { 0 }; - strcpy(fileNamePascal, TextToPascal(GetFileNameWithoutExt(fileName))); + strncpy(fileNamePascal, TextToPascal(GetFileNameWithoutExt(fileName)), 256 - 1); // NOTE: Text data buffer size is estimated considering image data size in bytes // and requiring 6 char bytes for every byte: "0x00, " @@ -937,7 +985,7 @@ bool ExportFontAsCode(Font font, const char *fileName) byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2023 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2024 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// ---------------------------------------------------------------------------------- //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); @@ -1029,7 +1077,7 @@ bool ExportFontAsCode(Font font, const char *fileName) #endif // We have two possible mechanisms to assign font.recs and font.glyphs data, // that data is already available as global arrays, we two options to assign that data: - // - 1. Data copy. This option consumes more memory and Font MUST be unloaded by user, requiring additional code. + // - 1. Data copy. This option consumes more memory and Font MUST be unloaded by user, requiring additional code // - 2. Data assignment. This option consumes less memory and Font MUST NOT be unloaded by user because data is on protected DATA segment //#define SUPPORT_FONT_DATA_COPY #if defined(SUPPORT_FONT_DATA_COPY) @@ -1064,7 +1112,6 @@ bool ExportFontAsCode(Font font, const char *fileName) return success; } - // Draw current FPS // NOTE: Uses default font void DrawFPS(int posX, int posY) @@ -1104,7 +1151,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f int size = TextLength(text); // Total size in bytes of the text, scanned by codepoints in loop - int textOffsetY = 0; // Offset between lines (on linebreak '\n') + float textOffsetY = 0; // Offset between lines (on linebreak '\n') float textOffsetX = 0.0f; // Offset X to next character to draw float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor @@ -1119,7 +1166,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f if (codepoint == '\n') { // NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup - textOffsetY += textLineSpacing; + textOffsetY += (fontSize + textLineSpacing); textOffsetX = 0.0f; } else @@ -1178,7 +1225,7 @@ void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSiz // Draw multiple character (codepoints) void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint) { - int textOffsetY = 0; // Offset between lines (on linebreak '\n') + float textOffsetY = 0; // Offset between lines (on linebreak '\n') float textOffsetX = 0.0f; // Offset X to next character to draw float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor @@ -1190,7 +1237,7 @@ void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Ve if (codepoints[i] == '\n') { // NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup - textOffsetY += textLineSpacing; + textOffsetY += (fontSize + textLineSpacing); textOffsetX = 0.0f; } else @@ -1235,7 +1282,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing { Vector2 textSize = { 0 }; - if ((font.texture.id == 0) || (text == NULL)) return textSize; + if ((font.texture.id == 0) || (text == NULL)) return textSize; // Security check int size = TextLength(text); // Get size in bytes of text int tempByteCounter = 0; // Used to count longer text line num chars @@ -1244,7 +1291,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing float textWidth = 0.0f; float tempTextWidth = 0.0f; // Used to count longer text line width - float textHeight = (float)font.baseSize; + float textHeight = fontSize; float scaleFactor = fontSize/(float)font.baseSize; int letter = 0; // Current character @@ -1272,7 +1319,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing textWidth = 0; // NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup - textHeight += (float)textLineSpacing; + textHeight += (fontSize + textLineSpacing); } if (tempByteCounter < byteCounter) tempByteCounter = byteCounter; @@ -1281,7 +1328,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing if (tempTextWidth < textWidth) tempTextWidth = textWidth; textSize.x = tempTextWidth*scaleFactor + (float)((tempByteCounter - 1)*spacing); - textSize.y = textHeight*scaleFactor; + textSize.y = textHeight; return textSize; } @@ -1390,7 +1437,6 @@ const char *TextFormat(const char *text, ...) return currentBuffer; } - // Get integer value from text // NOTE: This function replaces atoi() [stdlib.h] int TextToInteger(const char *text) @@ -1409,6 +1455,37 @@ int TextToInteger(const char *text) return value*sign; } +// Get float value from text +// NOTE: This function replaces atof() [stdlib.h] +// WARNING: Only '.' character is understood as decimal point +float TextToFloat(const char *text) +{ + float value = 0.0f; + float sign = 1.0f; + + if ((text[0] == '+') || (text[0] == '-')) + { + if (text[0] == '-') sign = -1.0f; + text++; + } + + int i = 0; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0'); + + if (text[i++] != '.') value *= sign; + else + { + float divisor = 10.0f; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) + { + value += ((float)(text[i] - '0'))/divisor; + divisor = divisor*10.0f; + } + } + + return value; +} + #if defined(SUPPORT_TEXT_MANIPULATION) // Copy one string to another, returns bytes copied int TextCopy(char *dst, const char *src) @@ -1480,7 +1557,7 @@ const char *TextSubtext(const char *text, int position, int length) // Replace text string // REQUIRES: strlen(), strstr(), strncpy(), strcpy() // WARNING: Allocated memory must be manually freed -char *TextReplace(char *text, const char *replace, const char *by) +char *TextReplace(const char *text, const char *replace, const char *by) { // Sanity checks and initialization if (!text || !replace || !by) return NULL; @@ -1500,7 +1577,7 @@ char *TextReplace(char *text, const char *replace, const char *by) byLen = TextLength(by); // Count the number of replacements needed - insertPoint = text; + insertPoint = (char*)text; for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen; // Allocate returning string and point temp to it @@ -1620,7 +1697,8 @@ const char **TextSplit(const char *text, char delimiter, int *count) return result; } -// Append text at specific position and move cursor! +// Append text at specific position and move cursor +// WARNING: It's up to the user to make sure appended text does not overflow the buffer! // REQUIRES: strcpy() void TextAppend(char *text, const char *append, int *position) { @@ -1951,21 +2029,21 @@ int GetCodepointNext(const char *text, int *codepointSize) if (0xf0 == (0xf8 & ptr[0])) { // 4 byte UTF-8 codepoint - if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } // 10xxxxxx checks codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]); *codepointSize = 4; } else if (0xe0 == (0xf0 & ptr[0])) { // 3 byte UTF-8 codepoint */ - if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } // 10xxxxxx checks codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]); *codepointSize = 3; } else if (0xc0 == (0xe0 & ptr[0])) { // 2 byte UTF-8 codepoint - if((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks + if ((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } // 10xxxxxx checks codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]); *codepointSize = 2; } @@ -2001,23 +2079,27 @@ int GetCodepointPrevious(const char *text, int *codepointSize) //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- -#if defined(SUPPORT_FILEFORMAT_FNT) +#if defined(SUPPORT_FILEFORMAT_FNT) || defined(SUPPORT_FILEFORMAT_BDF) // Read a line from memory // REQUIRES: memcpy() // NOTE: Returns the number of bytes read static int GetLine(const char *origin, char *buffer, int maxLength) { int count = 0; - for (; count < maxLength; count++) if (origin[count] == '\n') break; + for (; count < maxLength - 1; count++) if (origin[count] == '\n') break; memcpy(buffer, origin, count); + buffer[count] = '\0'; return count; } +#endif +#if defined(SUPPORT_FILEFORMAT_FNT) // Load a BMFont file (AngelCode font file) // REQUIRES: strstr(), sscanf(), strrchr(), memcpy() static Font LoadBMFont(const char *fileName) { - #define MAX_BUFFER_SIZE 256 + #define MAX_BUFFER_SIZE 256 + #define MAX_FONT_IMAGE_PAGES 8 Font font = { 0 }; @@ -2029,7 +2111,8 @@ static Font LoadBMFont(const char *fileName) int imWidth = 0; int imHeight = 0; - char imFileName[129] = { 0 }; + int pageCount = 1; + char imFileName[MAX_FONT_IMAGE_PAGES][129] = { 0 }; int base = 0; // Useless data int readBytes = 0; // Data bytes read @@ -2048,17 +2131,26 @@ static Font LoadBMFont(const char *fileName) // Read line data readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); searchPoint = strstr(buffer, "lineHeight"); - readVars = sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &imWidth, &imHeight); + readVars = sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i pages=%i", &fontSize, &base, &imWidth, &imHeight, &pageCount); fileTextPtr += (readBytes + 1); - + if (readVars < 4) { UnloadFileText(fileText); return font; } // Some data not available, file malformed - readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); - searchPoint = strstr(buffer, "file"); - readVars = sscanf(searchPoint, "file=\"%128[^\"]\"", imFileName); - fileTextPtr += (readBytes + 1); + if (pageCount > MAX_FONT_IMAGE_PAGES) + { + TRACELOG(LOG_WARNING, "FONT: [%s] Font defines more pages than supported: %i/%i", fileName, pageCount, MAX_FONT_IMAGE_PAGES); + pageCount = MAX_FONT_IMAGE_PAGES; + } - if (readVars < 1) { UnloadFileText(fileText); return font; } // No fileName read + for (int i = 0; i < pageCount; i++) + { + readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); + searchPoint = strstr(buffer, "file"); + readVars = sscanf(searchPoint, "file=\"%128[^\"]\"", imFileName[i]); + fileTextPtr += (readBytes + 1); + + if (readVars < 1) { UnloadFileText(fileText); return font; } // No fileName read + } readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); searchPoint = strstr(buffer, "count"); @@ -2067,50 +2159,56 @@ static Font LoadBMFont(const char *fileName) if (readVars < 1) { UnloadFileText(fileText); return font; } // No glyphCount read - // Compose correct path using route of .fnt file (fileName) and imFileName - char *imPath = NULL; - char *lastSlash = NULL; + // Load all required images for further compose + Image *imFonts = (Image *)RL_CALLOC(pageCount, sizeof(Image)); // Font atlases, multiple images - lastSlash = strrchr(fileName, '/'); - if (lastSlash == NULL) lastSlash = strrchr(fileName, '\\'); - - if (lastSlash != NULL) + for (int i = 0; i < pageCount; i++) { - // NOTE: We need some extra space to avoid memory corruption on next allocations! - imPath = (char *)RL_CALLOC(TextLength(fileName) - TextLength(lastSlash) + TextLength(imFileName) + 4, 1); - memcpy(imPath, fileName, TextLength(fileName) - TextLength(lastSlash) + 1); - memcpy(imPath + TextLength(fileName) - TextLength(lastSlash) + 1, imFileName, TextLength(imFileName)); - } - else imPath = imFileName; + imFonts[i] = LoadImage(TextFormat("%s/%s", GetDirectoryPath(fileName), imFileName[i])); - TRACELOGD(" > Image loading path: %s", imPath); - - Image imFont = LoadImage(imPath); - - if (imFont.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) - { - // Convert image to GRAYSCALE + ALPHA, using the mask as the alpha channel - Image imFontAlpha = { - .data = RL_CALLOC(imFont.width*imFont.height, 2), - .width = imFont.width, - .height = imFont.height, - .mipmaps = 1, - .format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA - }; - - for (int p = 0, i = 0; p < (imFont.width*imFont.height*2); p += 2, i++) + if (imFonts[i].format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) { - ((unsigned char *)(imFontAlpha.data))[p] = 0xff; - ((unsigned char *)(imFontAlpha.data))[p + 1] = ((unsigned char *)imFont.data)[i]; - } + // Convert image to GRAYSCALE + ALPHA, using the mask as the alpha channel + Image imFontAlpha = { + .data = RL_CALLOC(imFonts[i].width*imFonts[i].height, 2), + .width = imFonts[i].width, + .height = imFonts[i].height, + .mipmaps = 1, + .format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA + }; - UnloadImage(imFont); - imFont = imFontAlpha; + for (int p = 0, pi = 0; p < (imFonts[i].width*imFonts[i].height*2); p += 2, pi++) + { + ((unsigned char *)(imFontAlpha.data))[p] = 0xff; + ((unsigned char *)(imFontAlpha.data))[p + 1] = ((unsigned char *)imFonts[i].data)[pi]; + } + + UnloadImage(imFonts[i]); + imFonts[i] = imFontAlpha; + } } - font.texture = LoadTextureFromImage(imFont); + Image fullFont = imFonts[0]; + for (int i = 1; i < pageCount; i++) UnloadImage(imFonts[i]); - if (lastSlash != NULL) RL_FREE(imPath); + // If multiple atlas, then merge atlas + // NOTE: WARNING: This process could be really slow! + if (pageCount > 1) + { + // Resize font atlas to draw additional images + ImageResizeCanvas(&fullFont, imWidth, imHeight*pageCount, 0, 0, BLACK); + + for (int i = 1; i < pageCount; i++) + { + Rectangle srcRec = { 0.0f, 0.0f, (float)imWidth, (float)imHeight }; + Rectangle destRec = { 0.0f, (float)imHeight*(float)i, (float)imWidth, (float)imHeight }; + ImageDraw(&fullFont, imFonts[i], srcRec, destRec, WHITE); + } + } + + RL_FREE(imFonts); + + font.texture = LoadTextureFromImage(fullFont); // Fill font characters info data font.baseSize = fontSize; @@ -2119,19 +2217,19 @@ static Font LoadBMFont(const char *fileName) font.glyphs = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo)); font.recs = (Rectangle *)RL_MALLOC(glyphCount*sizeof(Rectangle)); - int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX; + int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX, pageID; for (int i = 0; i < glyphCount; i++) { readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); - readVars = sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i", - &charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX); + readVars = sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i page=%i", + &charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX, &pageID); fileTextPtr += (readBytes + 1); - - if (readVars == 8) // Make sure all char data has been properly read + + if (readVars == 9) // Make sure all char data has been properly read { // Get character rectangle in the font atlas texture - font.recs[i] = (Rectangle){ (float)charX, (float)charY, (float)charWidth, (float)charHeight }; + font.recs[i] = (Rectangle){ (float)charX, (float)charY + (float)imHeight*pageID, (float)charWidth, (float)charHeight }; // Save data properly in sprite font font.glyphs[i].value = charId; @@ -2139,13 +2237,13 @@ static Font LoadBMFont(const char *fileName) font.glyphs[i].offsetY = charOffsetY; font.glyphs[i].advanceX = charAdvanceX; - // Fill character image data from imFont data - font.glyphs[i].image = ImageFromImage(imFont, font.recs[i]); + // Fill character image data from full font data + font.glyphs[i].image = ImageFromImage(fullFont, font.recs[i]); } else TRACELOG(LOG_WARNING, "FONT: [%s] Some characters data not correctly provided", fileName); } - UnloadImage(imFont); + UnloadImage(fullFont); UnloadFileText(fileText); if (font.texture.id == 0) @@ -2158,6 +2256,258 @@ static Font LoadBMFont(const char *fileName) return font; } + #endif +#if defined(SUPPORT_FILEFORMAT_BDF) + +// Convert hexadecimal to decimal (single digit) +static unsigned char HexToInt(char hex) +{ + if (hex >= '0' && hex <= '9') return hex - '0'; + else if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10; + else if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10; + else return 0; +} + +// Load font data for further use +// NOTE: Requires BDF font memory data +static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize) +{ + #define MAX_BUFFER_SIZE 256 + + char buffer[MAX_BUFFER_SIZE] = { 0 }; + + GlyphInfo *glyphs = NULL; + bool genFontChars = false; + + int totalReadBytes = 0; // Data bytes read (total) + int readBytes = 0; // Data bytes read (line) + int readVars = 0; // Variables filled by sscanf() + + const char *fileText = (const char*)fileData; + const char *fileTextPtr = fileText; + + bool fontMalformed = false; // Is the font malformed + bool fontStarted = false; // Has font started (STARTFONT) + int fontBBw = 0; // Font base character bounding box width + int fontBBh = 0; // Font base character bounding box height + int fontBBxoff0 = 0; // Font base character bounding box X0 offset + int fontBByoff0 = 0; // Font base character bounding box Y0 offset + int fontAscent = 0; // Font ascent + + bool charStarted = false; // Has character started (STARTCHAR) + bool charBitmapStarted = false; // Has bitmap data started (BITMAP) + int charBitmapNextRow = 0; // Y position for the next row of bitmap data + int charEncoding = -1; // The unicode value of the character (-1 if not set) + int charBBw = 0; // Character bounding box width + int charBBh = 0; // Character bounding box height + int charBBxoff0 = 0; // Character bounding box X0 offset + int charBByoff0 = 0; // Character bounding box Y0 offset + int charDWidthX = 0; // Character advance X + int charDWidthY = 0; // Character advance Y (unused) + GlyphInfo *charGlyphInfo = NULL; // Pointer to output glyph info (NULL if not set) + + if (fileData == NULL) return glyphs; + + // In case no chars count provided, default to 95 + codepointCount = (codepointCount > 0)? codepointCount : 95; + + // Fill fontChars in case not provided externally + // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) + if (codepoints == NULL) + { + codepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); + for (int i = 0; i < codepointCount; i++) codepoints[i] = i + 32; + genFontChars = true; + } + + glyphs = (GlyphInfo *)RL_CALLOC(codepointCount, sizeof(GlyphInfo)); + + while (totalReadBytes <= dataSize) + { + readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); + totalReadBytes += (readBytes + 1); + fileTextPtr += (readBytes + 1); + + // Line: COMMENT + if (strstr(buffer, "COMMENT") != NULL) continue; // Ignore line + + if (charStarted) + { + // Line: ENDCHAR + if (strstr(buffer, "ENDCHAR") != NULL) + { + charStarted = false; + continue; + } + + if (charBitmapStarted) + { + if (charGlyphInfo != NULL) + { + int pixelY = charBitmapNextRow++; + + if (pixelY >= charGlyphInfo->image.height) break; + + for (int x = 0; x < readBytes; x++) + { + unsigned char byte = HexToInt(buffer[x]); + + for (int bitX = 0; bitX < 4; bitX++) + { + int pixelX = ((x*4) + bitX); + + if (pixelX >= charGlyphInfo->image.width) break; + + if ((byte & (8 >> bitX)) > 0) ((unsigned char *)charGlyphInfo->image.data)[(pixelY*charGlyphInfo->image.width) + pixelX] = 255; + } + } + } + continue; + } + + // Line: ENCODING + if (strstr(buffer, "ENCODING") != NULL) + { + readVars = sscanf(buffer, "ENCODING %i", &charEncoding); + continue; + } + + // Line: BBX + if (strstr(buffer, "BBX") != NULL) + { + readVars = sscanf(buffer, "BBX %i %i %i %i", &charBBw, &charBBh, &charBBxoff0, &charBByoff0); + continue; + } + + // Line: DWIDTH + if (strstr(buffer, "DWIDTH") != NULL) + { + readVars = sscanf(buffer, "DWIDTH %i %i", &charDWidthX, &charDWidthY); + continue; + } + + // Line: BITMAP + if (strstr(buffer, "BITMAP") != NULL) + { + // Search for glyph index in codepoints + charGlyphInfo = NULL; + + for (int codepointIndex = 0; codepointIndex < codepointCount; codepointIndex++) + { + if (codepoints[codepointIndex] == charEncoding) + { + charGlyphInfo = &glyphs[codepointIndex]; + break; + } + } + + // Init glyph info + if (charGlyphInfo != NULL) + { + charGlyphInfo->value = charEncoding; + charGlyphInfo->offsetX = charBBxoff0 + fontBByoff0; + charGlyphInfo->offsetY = fontBBh - (charBBh + charBByoff0 + fontBByoff0 + fontAscent); + charGlyphInfo->advanceX = charDWidthX; + + charGlyphInfo->image.data = RL_CALLOC(charBBw*charBBh, 1); + charGlyphInfo->image.width = charBBw; + charGlyphInfo->image.height = charBBh; + charGlyphInfo->image.mipmaps = 1; + charGlyphInfo->image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; + } + + charBitmapStarted = true; + charBitmapNextRow = 0; + + continue; + } + } + else if (fontStarted) + { + // Line: ENDFONT + if (strstr(buffer, "ENDFONT") != NULL) + { + fontStarted = false; + break; + } + + // Line: SIZE + if (strstr(buffer, "SIZE") != NULL) + { + if (outFontSize != NULL) readVars = sscanf(buffer, "SIZE %i", outFontSize); + continue; + } + + // PIXEL_SIZE + if (strstr(buffer, "PIXEL_SIZE") != NULL) + { + if (outFontSize != NULL) readVars = sscanf(buffer, "PIXEL_SIZE %i", outFontSize); + continue; + } + + // FONTBOUNDINGBOX + if (strstr(buffer, "FONTBOUNDINGBOX") != NULL) + { + readVars = sscanf(buffer, "FONTBOUNDINGBOX %i %i %i %i", &fontBBw, &fontBBh, &fontBBxoff0, &fontBByoff0); + continue; + } + + // FONT_ASCENT + if (strstr(buffer, "FONT_ASCENT") != NULL) + { + readVars = sscanf(buffer, "FONT_ASCENT %i", &fontAscent); + continue; + } + + // STARTCHAR + if (strstr(buffer, "STARTCHAR") != NULL) + { + charStarted = true; + charEncoding = -1; + charGlyphInfo = NULL; + charBBw = 0; + charBBh = 0; + charBBxoff0 = 0; + charBByoff0 = 0; + charDWidthX = 0; + charDWidthY = 0; + charGlyphInfo = NULL; + charBitmapStarted = false; + charBitmapNextRow = 0; + continue; + } + } + else + { + // STARTFONT + if (strstr(buffer, "STARTFONT") != NULL) + { + if (fontStarted) + { + fontMalformed = true; + break; + } + else + { + fontStarted = true; + continue; + } + } + } + } + + if (genFontChars) RL_FREE(codepoints); + + if (fontMalformed) + { + RL_FREE(glyphs); + glyphs = NULL; + } + + return glyphs; +} +#endif // SUPPORT_FILEFORMAT_BDF + #endif // SUPPORT_MODULE_RTEXT diff --git a/raylib/rtextures.c b/raylib/rtextures.c index 98586db..47ff83f 100644 --- a/raylib/rtextures.c +++ b/raylib/rtextures.c @@ -42,7 +42,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -71,10 +71,10 @@ #if defined(SUPPORT_MODULE_RTEXTURES) #include "utils.h" // Required for: TRACELOG() -#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 +#include "rlgl.h" // OpenGL abstraction layer to multiple versions -#include // Required for: malloc(), free() -#include // Required for: strlen() [Used in ImageTextEx()], strcmp() [Used in LoadImageFromMemory()] +#include // Required for: malloc(), calloc(), free() +#include // Required for: strlen() [Used in ImageTextEx()], strcmp() [Used in LoadImageFromMemory()/LoadImageAnimFromMemory()/ExportImageToMemory()] #include // Required for: fabsf() [Used in DrawTextureRec()] #include // Required for: sprintf() [Used in ExportImageAsCode()] @@ -212,15 +212,25 @@ #define STBIR_MALLOC(size,c) ((void)(c), RL_MALLOC(size)) #define STBIR_FREE(ptr,c) ((void)(c), RL_FREE(ptr)) + +#if defined(__GNUC__) // GCC and Clang + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" +#endif + #define STB_IMAGE_RESIZE_IMPLEMENTATION -#include "external/stb_image_resize2.h" // Required for: stbir_resize_uint8_linear() [ImageResize()] +#include "external/stb_image_resize2.h" // Required for: stbir_resize_uint8_linear() [ImageResize()] + +#if defined(__GNUC__) // GCC and Clang + #pragma GCC diagnostic pop +#endif #if defined(SUPPORT_FILEFORMAT_SVG) - #define NANOSVG_IMPLEMENTATION // Expands implementation - #include "external/nanosvg.h" + #define NANOSVG_IMPLEMENTATION // Expands implementation + #include "external/nanosvg.h" - #define NANOSVGRAST_IMPLEMENTATION - #include "external/nanosvgrast.h" + #define NANOSVGRAST_IMPLEMENTATION + #include "external/nanosvgrast.h" #endif //---------------------------------------------------------------------------------- @@ -283,9 +293,12 @@ Image LoadImage(const char *fileName) unsigned char *fileData = LoadFileData(fileName, &dataSize); // Loading image from memory data - if (fileData != NULL) image = LoadImageFromMemory(GetFileExtension(fileName), fileData, dataSize); + if (fileData != NULL) + { + image = LoadImageFromMemory(GetFileExtension(fileName), fileData, dataSize); - RL_FREE(fileData); + UnloadFileData(fileData); + } return image; } @@ -301,18 +314,22 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int if (fileData != NULL) { unsigned char *dataPtr = fileData; - unsigned int size = GetPixelDataSize(width, height, format); + int size = GetPixelDataSize(width, height, format); - if (headerSize > 0) dataPtr += headerSize; + if (size <= dataSize) // Security check + { + // Offset file data to expected raw image by header size + if ((headerSize > 0) && ((headerSize + size) <= dataSize)) dataPtr += headerSize; - image.data = RL_MALLOC(size); // Allocate required memory in bytes - memcpy(image.data, dataPtr, size); // Copy required data to image - image.width = width; - image.height = height; - image.mipmaps = 1; - image.format = format; + image.data = RL_MALLOC(size); // Allocate required memory in bytes + memcpy(image.data, dataPtr, size); // Copy required data to image + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = format; + } - RL_FREE(fileData); + UnloadFileData(fileData); } return image; @@ -368,8 +385,8 @@ Image LoadImageSvg(const char *fileNameOrString, int width, int height) int offsetX = 0; int offsetY = 0; - if (scaleHeight > scaleWidth) offsetY = (height - svgImage->height*scale) / 2; - else offsetX = (width - svgImage->width*scale) / 2; + if (scaleHeight > scaleWidth) offsetY = (height - svgImage->height*scale)/2; + else offsetX = (width - svgImage->width*scale)/2; // Rasterize struct NSVGrasterizer *rast = nsvgCreateRasterizer(); @@ -421,7 +438,7 @@ Image LoadImageAnim(const char *fileName, int *frames) image.mipmaps = 1; image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; - RL_FREE(fileData); + UnloadFileData(fileData); RL_FREE(delays); // NOTE: Frames delays are discarded } } @@ -438,12 +455,56 @@ Image LoadImageAnim(const char *fileName, int *frames) return image; } +// Load animated image data +// - Image.data buffer includes all frames: [image#0][image#1][image#2][...] +// - Number of frames is returned through 'frames' parameter +// - All frames are returned in RGBA format +// - Frames delay data is discarded +Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames) +{ + Image image = { 0 }; + int frameCount = 0; + + // Security check for input data + if ((fileType == NULL) || (fileData == NULL) || (dataSize == 0)) return image; + +#if defined(SUPPORT_FILEFORMAT_GIF) + if ((strcmp(fileType, ".gif") == 0) || (strcmp(fileType, ".GIF") == 0)) + { + if (fileData != NULL) + { + int comp = 0; + int *delays = NULL; + image.data = stbi_load_gif_from_memory(fileData, dataSize, &delays, &image.width, &image.height, &frameCount, &comp, 4); + + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + + RL_FREE(delays); // NOTE: Frames delays are discarded + } + } +#else + if (false) { } +#endif + else + { + image = LoadImageFromMemory(fileType, fileData, dataSize); + frameCount = 1; + } + + *frames = frameCount; + return image; +} + // Load image from memory buffer, fileType refers to extension: i.e. ".png" // WARNING: File extension must be provided in lower-case Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize) { Image image = { 0 }; + // Security check for input data + if ((fileType == NULL) || (fileData == NULL) || (dataSize == 0)) return image; + if ((false) #if defined(SUPPORT_FILEFORMAT_PNG) || (strcmp(fileType, ".png") == 0) || (strcmp(fileType, ".PNG") == 0) @@ -633,10 +694,11 @@ Image LoadImageFromTexture(Texture2D texture) // Load image from screen buffer and (screenshot) Image LoadImageFromScreen(void) { + Vector2 scale = GetWindowScaleDPI(); Image image = { 0 }; - image.width = GetScreenWidth(); - image.height = GetScreenHeight(); + image.width = (int)(GetScreenWidth()*scale.x); + image.height = (int)(GetScreenHeight()*scale.y); image.mipmaps = 1; image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; image.data = rlReadScreenPixels(image.width, image.height); @@ -647,11 +709,15 @@ Image LoadImageFromScreen(void) // Check if an image is ready bool IsImageReady(Image image) { - return ((image.data != NULL) && // Validate pixel data available - (image.width > 0) && - (image.height > 0) && // Validate image size - (image.format > 0) && // Validate image format - (image.mipmaps > 0)); // Validate image mipmaps (at least 1 for basic mipmap level) + bool result = false; + + if ((image.data != NULL) && // Validate pixel data available + (image.width > 0) && + (image.height > 0) && // Validate image size + (image.format > 0) && // Validate image format + (image.mipmaps > 0)) result = true; // Validate image mipmaps (at least 1 for basic mipmap level) + + return result; } // Unload image from CPU memory (RAM) @@ -666,6 +732,7 @@ bool ExportImage(Image image, const char *fileName) { int result = 0; + // Security check for input data if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return result; #if defined(SUPPORT_IMAGE_EXPORT) @@ -753,6 +820,7 @@ unsigned char *ExportImageToMemory(Image image, const char *fileType, int *dataS unsigned char *fileData = NULL; *dataSize = 0; + // Security check for input data if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return NULL; #if defined(SUPPORT_IMAGE_EXPORT) @@ -800,7 +868,7 @@ bool ExportImageAsCode(Image image, const char *fileName) byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2023 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2024 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); @@ -856,8 +924,8 @@ Image GenImageColor(int width, int height, Color color) #if defined(SUPPORT_IMAGE_GENERATION) // Generate image: linear gradient // The direction value specifies the direction of the gradient (in degrees) -// with 0 being vertical (from top to bottom), 90 being horizontal (from left to right). -// The gradient effectively rotates counter-clockwise by the specified amount. +// with 0 being vertical (from top to bottom), 90 being horizontal (from left to right) +// The gradient effectively rotates counter-clockwise by the specified amount Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end) { Color *pixels = (Color *)RL_MALLOC(width*height*sizeof(Color)); @@ -950,8 +1018,8 @@ Image GenImageGradientSquare(int width, int height, float density, Color inner, float distY = fabsf(y - centerY); // Normalize the distances by the dimensions of the gradient rectangle - float normalizedDistX = distX / centerX; - float normalizedDistY = distY / centerY; + float normalizedDistX = distX/centerX; + float normalizedDistY = distY/centerY; // Calculate the total normalized Manhattan distance float manhattanDist = fmaxf(normalizedDistX, normalizedDistY); @@ -1008,6 +1076,7 @@ Image GenImageChecked(int width, int height, int checksX, int checksY, Color col } // Generate image: white noise +// NOTE: It requires GetRandomValue(), defined in [rcore] Image GenImageWhiteNoise(int width, int height, float factor) { Color *pixels = (Color *)RL_MALLOC(width*height*sizeof(Color)); @@ -1546,7 +1615,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co // Scale image depending on text size if (textSize.y != imSize.y) { - float scaleFactor = textSize.y / imSize.y; + float scaleFactor = textSize.y/imSize.y; TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor); // Using nearest-neighbor scaling algorithm for default font @@ -1600,7 +1669,6 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight) UnloadImageColors(pixels); } - // Resize and image to new size // NOTE: Uses stb default scaling filters (both bicubic): // STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM @@ -1693,8 +1761,22 @@ void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, i int bytesPerPixel = GetPixelDataSize(1, 1, image->format); unsigned char *resizedData = (unsigned char *)RL_CALLOC(newWidth*newHeight*bytesPerPixel, 1); - // TODO: Fill resized canvas with fill color (must be formatted to image->format) + // Fill resized canvas with fill color + // Set first pixel with image->format + SetPixelColor(resizedData, fill, image->format); + // Fill remaining bytes of first row + for (int x = 1; x < newWidth; x++) + { + memcpy(resizedData + x*bytesPerPixel, resizedData, bytesPerPixel); + } + // Copy the first row into the other rows + for (int y = 1; y < newHeight; y++) + { + memcpy(resizedData + y*newWidth*bytesPerPixel, resizedData, newWidth*bytesPerPixel); + } + + // Copy old image to resized canvas int dstOffsetSize = ((int)dstPos.y*newWidth + (int)dstPos.x)*bytesPerPixel; for (int y = 0; y < (int)srcRec.height; y++) @@ -1930,8 +2012,9 @@ void ImageAlphaPremultiply(Image *image) ImageFormat(image, format); } -// Apply box blur -void ImageBlurGaussian(Image *image, int blurSize) { +// Apply box blur to image +void ImageBlurGaussian(Image *image, int blurSize) +{ // Security check to avoid program crash if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return; @@ -1943,7 +2026,8 @@ void ImageBlurGaussian(Image *image, int blurSize) { Vector4 *pixelsCopy1 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4)); Vector4 *pixelsCopy2 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4)); - for (int i = 0; i < (image->height)*(image->width); i++) { + for (int i = 0; i < (image->height*image->width); i++) + { pixelsCopy1[i].x = pixels[i].r; pixelsCopy1[i].y = pixels[i].g; pixelsCopy1[i].z = pixels[i].b; @@ -1951,7 +2035,8 @@ void ImageBlurGaussian(Image *image, int blurSize) { } // Repeated convolution of rectangular window signal by itself converges to a gaussian distribution - for (int j = 0; j < GAUSSIAN_BLUR_ITERATIONS; j++) { + for (int j = 0; j < GAUSSIAN_BLUR_ITERATIONS; j++) + { // Horizontal motion blur for (int row = 0; row < image->height; row++) { @@ -1959,9 +2044,9 @@ void ImageBlurGaussian(Image *image, int blurSize) { float avgG = 0.0f; float avgB = 0.0f; float avgAlpha = 0.0f; - int convolutionSize = blurSize+1; + int convolutionSize = blurSize; - for (int i = 0; i < blurSize+1; i++) + for (int i = 0; i < blurSize; i++) { avgR += pixelsCopy1[row*image->width + i].x; avgG += pixelsCopy1[row*image->width + i].y; @@ -1969,19 +2054,14 @@ void ImageBlurGaussian(Image *image, int blurSize) { avgAlpha += pixelsCopy1[row*image->width + i].w; } - pixelsCopy2[row*image->width].x = avgR/convolutionSize; - pixelsCopy2[row*image->width].y = avgG/convolutionSize; - pixelsCopy2[row*image->width].z = avgB/convolutionSize; - pixelsCopy2[row*image->width].w = avgAlpha/convolutionSize; - - for (int x = 1; x < image->width; x++) + for (int x = 0; x < image->width; x++) { - if (x-blurSize >= 0) + if (x-blurSize-1 >= 0) { - avgR -= pixelsCopy1[row*image->width + x-blurSize].x; - avgG -= pixelsCopy1[row*image->width + x-blurSize].y; - avgB -= pixelsCopy1[row*image->width + x-blurSize].z; - avgAlpha -= pixelsCopy1[row*image->width + x-blurSize].w; + avgR -= pixelsCopy1[row*image->width + x-blurSize-1].x; + avgG -= pixelsCopy1[row*image->width + x-blurSize-1].y; + avgB -= pixelsCopy1[row*image->width + x-blurSize-1].z; + avgAlpha -= pixelsCopy1[row*image->width + x-blurSize-1].w; convolutionSize--; } @@ -1999,7 +2079,7 @@ void ImageBlurGaussian(Image *image, int blurSize) { pixelsCopy2[row*image->width + x].z = avgB/convolutionSize; pixelsCopy2[row*image->width + x].w = avgAlpha/convolutionSize; } - } + } // Vertical motion blur for (int col = 0; col < image->width; col++) @@ -2008,9 +2088,9 @@ void ImageBlurGaussian(Image *image, int blurSize) { float avgG = 0.0f; float avgB = 0.0f; float avgAlpha = 0.0f; - int convolutionSize = blurSize+1; + int convolutionSize = blurSize; - for (int i = 0; i < blurSize+1; i++) + for (int i = 0; i < blurSize; i++) { avgR += pixelsCopy2[i*image->width + col].x; avgG += pixelsCopy2[i*image->width + col].y; @@ -2018,19 +2098,14 @@ void ImageBlurGaussian(Image *image, int blurSize) { avgAlpha += pixelsCopy2[i*image->width + col].w; } - pixelsCopy1[col].x = (unsigned char) (avgR/convolutionSize); - pixelsCopy1[col].y = (unsigned char) (avgG/convolutionSize); - pixelsCopy1[col].z = (unsigned char) (avgB/convolutionSize); - pixelsCopy1[col].w = (unsigned char) (avgAlpha/convolutionSize); - - for (int y = 1; y < image->height; y++) + for (int y = 0; y < image->height; y++) { - if (y-blurSize >= 0) + if (y-blurSize-1 >= 0) { - avgR -= pixelsCopy2[(y-blurSize)*image->width + col].x; - avgG -= pixelsCopy2[(y-blurSize)*image->width + col].y; - avgB -= pixelsCopy2[(y-blurSize)*image->width + col].z; - avgAlpha -= pixelsCopy2[(y-blurSize)*image->width + col].w; + avgR -= pixelsCopy2[(y-blurSize-1)*image->width + col].x; + avgG -= pixelsCopy2[(y-blurSize-1)*image->width + col].y; + avgB -= pixelsCopy2[(y-blurSize-1)*image->width + col].z; + avgAlpha -= pixelsCopy2[(y-blurSize-1)*image->width + col].w; convolutionSize--; } if (y+blurSize < image->height) @@ -2050,7 +2125,6 @@ void ImageBlurGaussian(Image *image, int blurSize) { } } - // Reverse premultiply for (int i = 0; i < (image->width)*(image->height); i++) { @@ -2082,6 +2156,135 @@ void ImageBlurGaussian(Image *image, int blurSize) { ImageFormat(image, format); } +// The kernel matrix is assumed to be square. Only supply the width of the kernel +void ImageKernelConvolution(Image *image, float* kernel, int kernelSize) +{ + if ((image->data == NULL) || (image->width == 0) || (image->height == 0) || kernel == NULL) return; + + int kernelWidth = (int)sqrtf((float)kernelSize); + + if (kernelWidth*kernelWidth != kernelSize) + { + TRACELOG(LOG_WARNING, "IMAGE: Convolution kernel must be square to be applied"); + return; + } + + Color *pixels = LoadImageColors(*image); + + Vector4 *imageCopy2 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4)); + Vector4 *temp = RL_MALLOC(kernelSize*sizeof(Vector4)); + + for (int i = 0; i < kernelSize; i++) + { + temp[i].x = 0.0f; + temp[i].y = 0.0f; + temp[i].z = 0.0f; + temp[i].w = 0.0f; + } + + float rRes = 0.0f; + float gRes = 0.0f; + float bRes = 0.0f; + float aRes = 0.0f; + + int startRange = 0, endRange = 0; + + if (kernelWidth%2 == 0) + { + startRange = -kernelWidth/2; + endRange = kernelWidth/2; + } + else + { + startRange = -kernelWidth/2; + endRange = kernelWidth/2 + 1; + } + + for (int x = 0; x < image->height; x++) + { + for (int y = 0; y < image->width; y++) + { + for (int xk = startRange; xk < endRange; xk++) + { + for (int yk = startRange; yk < endRange; yk++) + { + int xkabs = xk + kernelWidth/2; + int ykabs = yk + kernelWidth/2; + unsigned int imgindex = image->width*(x + xk) + (y + yk); + + if (imgindex >= (unsigned int)(image->width*image->height)) + { + temp[kernelWidth*xkabs + ykabs].x = 0.0f; + temp[kernelWidth*xkabs + ykabs].y = 0.0f; + temp[kernelWidth*xkabs + ykabs].z = 0.0f; + temp[kernelWidth*xkabs + ykabs].w = 0.0f; + } + else + { + temp[kernelWidth*xkabs + ykabs].x = ((float)pixels[imgindex].r)/255.0f*kernel[kernelWidth*xkabs + ykabs]; + temp[kernelWidth*xkabs + ykabs].y = ((float)pixels[imgindex].g)/255.0f*kernel[kernelWidth*xkabs + ykabs]; + temp[kernelWidth*xkabs + ykabs].z = ((float)pixels[imgindex].b)/255.0f*kernel[kernelWidth*xkabs + ykabs]; + temp[kernelWidth*xkabs + ykabs].w = ((float)pixels[imgindex].a)/255.0f*kernel[kernelWidth*xkabs + ykabs]; + } + } + } + + for (int i = 0; i < kernelSize; i++) + { + rRes += temp[i].x; + gRes += temp[i].y; + bRes += temp[i].z; + aRes += temp[i].w; + } + + if (rRes < 0.0f) rRes = 0.0f; + if (gRes < 0.0f) gRes = 0.0f; + if (bRes < 0.0f) bRes = 0.0f; + + if (rRes > 1.0f) rRes = 1.0f; + if (gRes > 1.0f) gRes = 1.0f; + if (bRes > 1.0f) bRes = 1.0f; + + imageCopy2[image->width*x + y].x = rRes; + imageCopy2[image->width*x + y].y = gRes; + imageCopy2[image->width*x + y].z = bRes; + imageCopy2[image->width*x + y].w = aRes; + + rRes = 0.0f; + gRes = 0.0f; + bRes = 0.0f; + aRes = 0.0f; + + for (int i = 0; i < kernelSize; i++) + { + temp[i].x = 0.0f; + temp[i].y = 0.0f; + temp[i].z = 0.0f; + temp[i].w = 0.0f; + } + } + } + + for (int i = 0; i < (image->width*image->height); i++) + { + float alpha = (float)imageCopy2[i].w; + + pixels[i].r = (unsigned char)((imageCopy2[i].x)*255.0f); + pixels[i].g = (unsigned char)((imageCopy2[i].y)*255.0f); + pixels[i].b = (unsigned char)((imageCopy2[i].z)*255.0f); + pixels[i].a = (unsigned char)((alpha)*255.0f); + } + + int format = image->format; + RL_FREE(image->data); + RL_FREE(imageCopy2); + RL_FREE(temp); + + image->data = pixels; + image->format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + ImageFormat(image, format); +} + // Generate all mipmap levels for a provided image // NOTE 1: Supports POT and NPOT images // NOTE 2: image.data is scaled to include mipmap levels @@ -2469,21 +2672,17 @@ void ImageColorTint(Image *image, Color color) float cB = (float)color.b/255; float cA = (float)color.a/255; - for (int y = 0; y < image->height; y++) + for (int i = 0; i < image->width*image->height; i++) { - for (int x = 0; x < image->width; x++) - { - int index = y*image->width + x; - unsigned char r = (unsigned char)(((float)pixels[index].r/255*cR)*255.0f); - unsigned char g = (unsigned char)(((float)pixels[index].g/255*cG)*255.0f); - unsigned char b = (unsigned char)(((float)pixels[index].b/255*cB)*255.0f); - unsigned char a = (unsigned char)(((float)pixels[index].a/255*cA)*255.0f); + unsigned char r = (unsigned char)(((float)pixels[i].r/255*cR)*255.0f); + unsigned char g = (unsigned char)(((float)pixels[i].g/255*cG)*255.0f); + unsigned char b = (unsigned char)(((float)pixels[i].b/255*cB)*255.0f); + unsigned char a = (unsigned char)(((float)pixels[i].a/255*cA)*255.0f); - pixels[index].r = r; - pixels[index].g = g; - pixels[index].b = b; - pixels[index].a = a; - } + pixels[i].r = r; + pixels[i].g = g; + pixels[i].b = b; + pixels[i].a = a; } int format = image->format; @@ -2503,14 +2702,11 @@ void ImageColorInvert(Image *image) Color *pixels = LoadImageColors(*image); - for (int y = 0; y < image->height; y++) + for (int i = 0; i < image->width*image->height; i++) { - for (int x = 0; x < image->width; x++) - { - pixels[y*image->width + x].r = 255 - pixels[y*image->width + x].r; - pixels[y*image->width + x].g = 255 - pixels[y*image->width + x].g; - pixels[y*image->width + x].b = 255 - pixels[y*image->width + x].b; - } + pixels[i].r = 255 - pixels[i].r; + pixels[i].g = 255 - pixels[i].g; + pixels[i].b = 255 - pixels[i].b; } int format = image->format; @@ -2543,38 +2739,35 @@ void ImageColorContrast(Image *image, float contrast) Color *pixels = LoadImageColors(*image); - for (int y = 0; y < image->height; y++) + for (int i = 0; i < image->width*image->height; i++) { - for (int x = 0; x < image->width; x++) - { - float pR = (float)pixels[y*image->width + x].r/255.0f; - pR -= 0.5f; - pR *= contrast; - pR += 0.5f; - pR *= 255; - if (pR < 0) pR = 0; - if (pR > 255) pR = 255; + float pR = (float)pixels[i].r/255.0f; + pR -= 0.5f; + pR *= contrast; + pR += 0.5f; + pR *= 255; + if (pR < 0) pR = 0; + if (pR > 255) pR = 255; - float pG = (float)pixels[y*image->width + x].g/255.0f; - pG -= 0.5f; - pG *= contrast; - pG += 0.5f; - pG *= 255; - if (pG < 0) pG = 0; - if (pG > 255) pG = 255; + float pG = (float)pixels[i].g/255.0f; + pG -= 0.5f; + pG *= contrast; + pG += 0.5f; + pG *= 255; + if (pG < 0) pG = 0; + if (pG > 255) pG = 255; - float pB = (float)pixels[y*image->width + x].b/255.0f; - pB -= 0.5f; - pB *= contrast; - pB += 0.5f; - pB *= 255; - if (pB < 0) pB = 0; - if (pB > 255) pB = 255; + float pB = (float)pixels[i].b/255.0f; + pB -= 0.5f; + pB *= contrast; + pB += 0.5f; + pB *= 255; + if (pB < 0) pB = 0; + if (pB > 255) pB = 255; - pixels[y*image->width + x].r = (unsigned char)pR; - pixels[y*image->width + x].g = (unsigned char)pG; - pixels[y*image->width + x].b = (unsigned char)pB; - } + pixels[i].r = (unsigned char)pR; + pixels[i].g = (unsigned char)pG; + pixels[i].b = (unsigned char)pB; } int format = image->format; @@ -2598,27 +2791,24 @@ void ImageColorBrightness(Image *image, int brightness) Color *pixels = LoadImageColors(*image); - for (int y = 0; y < image->height; y++) + for (int i = 0; i < image->width*image->height; i++) { - for (int x = 0; x < image->width; x++) - { - int cR = pixels[y*image->width + x].r + brightness; - int cG = pixels[y*image->width + x].g + brightness; - int cB = pixels[y*image->width + x].b + brightness; + int cR = pixels[i].r + brightness; + int cG = pixels[i].g + brightness; + int cB = pixels[i].b + brightness; - if (cR < 0) cR = 1; - if (cR > 255) cR = 255; + if (cR < 0) cR = 1; + if (cR > 255) cR = 255; - if (cG < 0) cG = 1; - if (cG > 255) cG = 255; + if (cG < 0) cG = 1; + if (cG > 255) cG = 255; - if (cB < 0) cB = 1; - if (cB > 255) cB = 255; + if (cB < 0) cB = 1; + if (cB > 255) cB = 255; - pixels[y*image->width + x].r = (unsigned char)cR; - pixels[y*image->width + x].g = (unsigned char)cG; - pixels[y*image->width + x].b = (unsigned char)cB; - } + pixels[i].r = (unsigned char)cR; + pixels[i].g = (unsigned char)cG; + pixels[i].b = (unsigned char)cB; } int format = image->format; @@ -2638,20 +2828,17 @@ void ImageColorReplace(Image *image, Color color, Color replace) Color *pixels = LoadImageColors(*image); - for (int y = 0; y < image->height; y++) + for (int i = 0; i < image->width*image->height; i++) { - for (int x = 0; x < image->width; x++) + if ((pixels[i].r == color.r) && + (pixels[i].g == color.g) && + (pixels[i].b == color.b) && + (pixels[i].a == color.a)) { - if ((pixels[y*image->width + x].r == color.r) && - (pixels[y*image->width + x].g == color.g) && - (pixels[y*image->width + x].b == color.b) && - (pixels[y*image->width + x].a == color.a)) - { - pixels[y*image->width + x].r = replace.r; - pixels[y*image->width + x].g = replace.g; - pixels[y*image->width + x].b = replace.b; - pixels[y*image->width + x].a = replace.a; - } + pixels[i].r = replace.r; + pixels[i].g = replace.g; + pixels[i].b = replace.b; + pixels[i].a = replace.a; } } @@ -3398,8 +3585,8 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0)) return; // Security check to avoid drawing out of bounds in case of bad user data - if (rec.x < 0) { rec.width -= rec.x; rec.x = 0; } - if (rec.y < 0) { rec.height -= rec.y; rec.y = 0; } + if (rec.x < 0) { rec.width += rec.x; rec.x = 0; } + if (rec.y < 0) { rec.height += rec.y; rec.y = 0; } if (rec.width < 0) rec.width = 0; if (rec.height < 0) rec.height = 0; @@ -3408,8 +3595,8 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) if ((rec.y + rec.height) >= dst->height) rec.height = dst->height - rec.y; // Check if the rect is even inside the image - if ((rec.x > dst->width) || (rec.y > dst->height)) return; - if (((rec.x + rec.width) < 0) || (rec.y + rec.height < 0)) return; + if ((rec.x >= dst->width) || (rec.y >= dst->height)) return; + if (((rec.x + rec.width) <= 0) || (rec.y + rec.height <= 0)) return; int sy = (int)rec.y; int sx = (int)rec.x; @@ -3429,7 +3616,7 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) } // Repeat the first row data for all other rows - int bytesPerRow = bytesPerPixel * (int)rec.width; + int bytesPerRow = bytesPerPixel*(int)rec.width; for (int y = 1; y < (int)rec.height; y++) { memcpy(pSrcPixel + (y*dst->width)*bytesPerPixel, pSrcPixel, bytesPerRow); @@ -3564,7 +3751,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // Draw text (default font) within an image (destination) void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color) { -#if defined(SUPPORT_MODULE_RTEXT) +#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) // Make sure default font is loaded to be used on image text drawing if (GetFontDefault().texture.id == 0) LoadFontDefault(); @@ -3646,7 +3833,9 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) if ((image.height/6) == image.width) { layout = CUBEMAP_LAYOUT_LINE_VERTICAL; cubemap.width = image.height/6; } else if ((image.width/3) == (image.height/4)) { layout = CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR; cubemap.width = image.width/3; } } - } else { + } + else + { if (layout == CUBEMAP_LAYOUT_LINE_VERTICAL) cubemap.width = image.height/6; if (layout == CUBEMAP_LAYOUT_LINE_HORIZONTAL) cubemap.width = image.width/6; if (layout == CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR) cubemap.width = image.width/3; @@ -3663,6 +3852,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) Image faces = { 0 }; // Vertical column image Rectangle faceRecs[6] = { 0 }; // Face source rectangles + for (int i = 0; i < 6; i++) faceRecs[i] = (Rectangle){ 0, 0, (float)size, (float)size }; if (layout == CUBEMAP_LAYOUT_LINE_VERTICAL) @@ -3708,7 +3898,13 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) // NOTE: Cubemap data is expected to be provided as 6 images in a single data array, // one after the other (that's a vertical image), following convention: +X, -X, +Y, -Y, +Z, -Z cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format); - if (cubemap.id == 0) TRACELOG(LOG_WARNING, "IMAGE: Failed to load cubemap image"); + + if (cubemap.id != 0) + { + cubemap.format = faces.format; + cubemap.mipmaps = 1; + } + else TRACELOG(LOG_WARNING, "IMAGE: Failed to load cubemap image"); UnloadImage(faces); } @@ -3723,7 +3919,7 @@ RenderTexture2D LoadRenderTexture(int width, int height) { RenderTexture2D target = { 0 }; - target.id = rlLoadFramebuffer(width, height); // Load an empty framebuffer + target.id = rlLoadFramebuffer(); // Load an empty framebuffer if (target.id > 0) { @@ -3760,13 +3956,17 @@ RenderTexture2D LoadRenderTexture(int width, int height) // Check if a texture is ready bool IsTextureReady(Texture2D texture) { + bool result = false; + // TODO: Validate maximum texture size supported by GPU? - return ((texture.id > 0) && // Validate OpenGL id - (texture.width > 0) && - (texture.height > 0) && // Validate texture size - (texture.format > 0) && // Validate texture pixel format - (texture.mipmaps > 0)); // Validate texture mipmaps (at least 1 for basic mipmap level) + if ((texture.id > 0) && // Validate OpenGL id + (texture.width > 0) && + (texture.height > 0) && // Validate texture size + (texture.format > 0) && // Validate texture pixel format + (texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level) + + return result; } // Unload texture from GPU memory (VRAM) @@ -3783,9 +3983,13 @@ void UnloadTexture(Texture2D texture) // Check if a render texture is ready bool IsRenderTextureReady(RenderTexture2D target) { - return ((target.id > 0) && // Validate OpenGL id - IsTextureReady(target.depth) && // Validate FBO depth texture/renderbuffer - IsTextureReady(target.texture)); // Validate FBO texture + bool result = false; + + if ((target.id > 0) && // Validate OpenGL id + IsTextureReady(target.depth) && // Validate FBO depth texture/renderbuffer + IsTextureReady(target.texture)) result = true; // Validate FBO texture + + return result; } // Unload render texture from GPU memory (VRAM) @@ -4043,7 +4247,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 // NOTE: Vertex position can be transformed using matrices // but the process is way more costly than just calculating - // the vertex positions manually, like done above. + // the vertex positions manually, like done above // I leave here the old implementation for educational purposes, // just in case someone wants to do some performance test /* @@ -4280,19 +4484,35 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, } } +// Check if two colors are equal +bool ColorIsEqual(Color col1, Color col2) +{ + bool result = false; + + if ((col1.r == col2.r) && (col1.g == col2.g) && (col1.b == col2.b) && (col1.a == col2.a)) result = true; + + return result; +} + // Get color with alpha applied, alpha goes from 0.0f to 1.0f Color Fade(Color color, float alpha) { + Color result = color; + if (alpha < 0.0f) alpha = 0.0f; else if (alpha > 1.0f) alpha = 1.0f; - return (Color){ color.r, color.g, color.b, (unsigned char)(255.0f*alpha) }; + result.a = (unsigned char)(255.0f*alpha); + + return result; } // Get hexadecimal value for a Color int ColorToInt(Color color) { - return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a); + int result = (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a); + + return result; } // Get color normalized as float [0..1] @@ -4511,10 +4731,14 @@ Color ColorContrast(Color color, float contrast) // Get color with alpha applied, alpha goes from 0.0f to 1.0f Color ColorAlpha(Color color, float alpha) { + Color result = color; + if (alpha < 0.0f) alpha = 0.0f; else if (alpha > 1.0f) alpha = 1.0f; - return (Color){color.r, color.g, color.b, (unsigned char)(255.0f*alpha)}; + result.a = (unsigned char)(255.0f*alpha); + + return result; } // Get src alpha-blended into dst color with tint @@ -4813,22 +5037,35 @@ int GetPixelDataSize(int width, int height, int format) //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- -// From https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 +// Convert half-float (stored as unsigned short) to float +// REF: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 +static float HalfToFloat(unsigned short x) +{ + float result = 0.0f; -static float HalfToFloat(unsigned short x) { - const unsigned int e = (x&0x7C00)>>10; // exponent - const unsigned int m = (x&0x03FF)<<13; // mantissa + const unsigned int e = (x & 0x7C00) >> 10; // Exponent + const unsigned int m = (x & 0x03FF) << 13; // Mantissa const float fm = (float)m; - const unsigned int v = (*(unsigned int*)&fm)>>23; // evil log2 bit hack to count leading zeros in denormalized format - const unsigned int r = (x&0x8000)<<16 | (e!=0)*((e+112)<<23|m) | ((e==0)&(m!=0))*((v-37)<<23|((m<<(150-v))&0x007FE000)); // sign : normalized : denormalized - return *(float*)&r; + const unsigned int v = (*(unsigned int*)&fm) >> 23; // Evil log2 bit hack to count leading zeros in denormalized format + const unsigned int r = (x & 0x8000) << 16 | (e != 0)*((e + 112) << 23 | m) | ((e == 0)&(m != 0))*((v - 37) << 23 | ((m << (150 - v)) & 0x007FE000)); // sign : normalized : denormalized + + result = *(float *)&r; + + return result; } -static unsigned short FloatToHalf(float x) { - const unsigned int b = (*(unsigned int*)&x)+0x00001000; // round-to-nearest-even: add last bit after truncated mantissa - const unsigned int e = (b&0x7F800000)>>23; // exponent - const unsigned int m = b&0x007FFFFF; // mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal indicator flag - initial rounding - return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | ((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF; // sign : normalized : denormalized : saturate +// Convert float to half-float (stored as unsigned short) +static unsigned short FloatToHalf(float x) +{ + unsigned short result = 0; + + const unsigned int b = (*(unsigned int*) & x) + 0x00001000; // Round-to-nearest-even: add last bit after truncated mantissa + const unsigned int e = (b & 0x7F800000) >> 23; // Exponent + const unsigned int m = b & 0x007FFFFF; // Mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal indicator flag - initial rounding + + result = (b & 0x80000000) >> 16 | (e > 112)*((((e - 112) << 10) & 0x7C00) | m >> 13) | ((e < 113) & (e > 101))*((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | (e > 143)*0x7FFF; // sign : normalized : denormalized : saturate + + return result; } // Get pixel data from image as Vector4 array (float normalized) diff --git a/raylib/utils.c b/raylib/utils.c index 51d84cf..fcbdba0 100644 --- a/raylib/utils.c +++ b/raylib/utils.c @@ -10,7 +10,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -41,7 +41,7 @@ #if defined(PLATFORM_ANDROID) #include // Required for: Android error types #include // Required for: Android log system: __android_log_vprint() - #include // Required for: Android assets manager: AAsset, AAssetManager_open(), ... + #include // Required for: Android assets manager: AAsset, AAssetManager_open()... #endif #include // Required for: exit() @@ -211,13 +211,13 @@ unsigned char *LoadFileData(const char *fileName, int *dataSize) { // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] size_t count = fread(data, sizeof(unsigned char), size, file); - + // WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) // dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) we have a limitation if (count > 2147483647) { TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName); - + RL_FREE(data); data = NULL; } @@ -309,14 +309,20 @@ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileN byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2023 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2024 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); - // Get file name from path and convert variable name to uppercase + // Get file name from path char varFileName[256] = { 0 }; strcpy(varFileName, GetFileNameWithoutExt(fileName)); - for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } + for (int i = 0; varFileName[i] != '\0'; i++) + { + // Convert variable name to uppercase + if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } + // Replace non valid character for C identifier with '_' + else if (varFileName[i] == '.' || varFileName[i] == '-' || varFileName[i] == '?' || varFileName[i] == '!' || varFileName[i] == '+') { varFileName[i] = '_'; } + } byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize); diff --git a/raylib/utils.h b/raylib/utils.h index ff8246a..23eca8e 100644 --- a/raylib/utils.h +++ b/raylib/utils.h @@ -5,7 +5,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. From 18035cee692609115ad33e3f1ba5c30356584211 Mon Sep 17 00:00:00 2001 From: Zachary Bednarke Date: Tue, 7 May 2024 19:37:13 -0700 Subject: [PATCH 049/278] first in fork --- examples/audio/raw_stream/main.go | 59 +++++++++++++++++-------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index a0a952b..c970916 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -1,14 +1,19 @@ package main import ( + "fmt" "math" + "time" rl "github.com/gen2brain/raylib-go/raylib" ) const ( - maxSamples = 22050 - maxSamplesPerUpdate = 4096 + maxSamples = 6000 + sampleRate = 6000 + maxSamplesPerUpdate = 1600 + f = 440 + targetFPS = 240 ) func main() { @@ -16,56 +21,56 @@ func main() { rl.InitAudioDevice() - // Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono) - stream := rl.LoadAudioStream(22050, 32, 1) + // Init raw audio stream (sample rate: , sample size: 32bit-float, channels: 1-mono) + stream := rl.LoadAudioStream(maxSamples, 32, 1) - //// Fill audio stream with some samples (sine wave) + //// Fill create sine wave to play data := make([]float32, maxSamples) for i := 0; i < maxSamples; i++ { - data[i] = float32(math.Sin(float64((2*rl.Pi*float32(i))/2) * rl.Deg2rad)) + t := float32(i) / float32(maxSamples) + data[i] = float32(math.Sin(float64((2 * rl.Pi * f * t)))) } - // NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop - // for that reason, there is a clip everytime audio stream is looped + // NOTE: The buffer can only be updated when it has been processed, so there is clipping in the time between + // buffer exhaustion and next load. rl.PlayAudioStream(stream) - totalSamples := int32(maxSamples) - samplesLeft := int32(totalSamples) - position := rl.NewVector2(0, 0) - rl.SetTargetFPS(30) + startTime := time.Now() + + rl.SetTargetFPS(targetFPS) for !rl.WindowShouldClose() { - // Refill audio stream if required + + // Refill audio stream if buffer is processed if rl.IsAudioStreamProcessed(stream) { - numSamples := int32(0) - if samplesLeft >= maxSamplesPerUpdate { - numSamples = maxSamplesPerUpdate + elapsedTime := time.Since(startTime).Seconds() + currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(maxSamples))) + nextSampleIndex := currentSampleIndex + maxSamplesPerUpdate + + if nextSampleIndex > maxSamples { + nextSampleIndex = maxSamplesPerUpdate - (maxSamples - currentSampleIndex) + samplesToWrite := append(data[currentSampleIndex:], data[:nextSampleIndex]...) + rl.UpdateAudioStream(stream, samplesToWrite) } else { - numSamples = samplesLeft + samplesToWrite := data[currentSampleIndex:nextSampleIndex] + rl.UpdateAudioStream(stream, samplesToWrite) } - rl.UpdateAudioStream(stream, data[totalSamples-samplesLeft:]) - - samplesLeft -= numSamples - - // Reset samples feeding (loop audio) - if samplesLeft <= 0 { - samplesLeft = totalSamples - } + fmt.Printf("Writing samples from %d to %d \n", currentSampleIndex, nextSampleIndex) } rl.BeginDrawing() rl.ClearBackground(rl.RayWhite) - rl.DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, rl.LightGray) + rl.DrawText(fmt.Sprintf("%d Hz SINE WAVE SHOULD BE PLAYING!", f), 200, 140, 20, rl.LightGray) // NOTE: Draw a part of the sine wave (only screen width) for i := 0; i < int(rl.GetScreenWidth()); i++ { position.X = float32(i) - position.Y = 250 + 50*data[i] + position.Y = 250 + 10*data[i] rl.DrawPixelV(position, rl.Red) } From 95c2f5679acac0130b82cad8b2c1574b58fd7253 Mon Sep 17 00:00:00 2001 From: Zachary Bednarke Date: Tue, 7 May 2024 19:43:43 -0700 Subject: [PATCH 050/278] pretty it up --- examples/audio/raw_stream/main.go | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index c970916..0c3552d 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -18,13 +18,13 @@ const ( func main() { rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming") - + position := rl.NewVector2(0, 0) rl.InitAudioDevice() // Init raw audio stream (sample rate: , sample size: 32bit-float, channels: 1-mono) stream := rl.LoadAudioStream(maxSamples, 32, 1) - //// Fill create sine wave to play + //// Create sine wave to play data := make([]float32, maxSamples) for i := 0; i < maxSamples; i++ { @@ -32,18 +32,13 @@ func main() { data[i] = float32(math.Sin(float64((2 * rl.Pi * f * t)))) } - // NOTE: The buffer can only be updated when it has been processed, so there is clipping in the time between - // buffer exhaustion and next load. + // NOTE: The buffer can only be updated when it has been processed. Time between buffer processing and next load and causes clipping rl.PlayAudioStream(stream) - position := rl.NewVector2(0, 0) - startTime := time.Now() - rl.SetTargetFPS(targetFPS) for !rl.WindowShouldClose() { - // Refill audio stream if buffer is processed if rl.IsAudioStreamProcessed(stream) { elapsedTime := time.Since(startTime).Seconds() @@ -52,18 +47,13 @@ func main() { if nextSampleIndex > maxSamples { nextSampleIndex = maxSamplesPerUpdate - (maxSamples - currentSampleIndex) - samplesToWrite := append(data[currentSampleIndex:], data[:nextSampleIndex]...) - rl.UpdateAudioStream(stream, samplesToWrite) + rl.UpdateAudioStream(stream, append(data[currentSampleIndex:], data[:nextSampleIndex]...)) } else { - samplesToWrite := data[currentSampleIndex:nextSampleIndex] - rl.UpdateAudioStream(stream, samplesToWrite) + rl.UpdateAudioStream(stream, data[currentSampleIndex:nextSampleIndex]) } - - fmt.Printf("Writing samples from %d to %d \n", currentSampleIndex, nextSampleIndex) } rl.BeginDrawing() - rl.ClearBackground(rl.RayWhite) rl.DrawText(fmt.Sprintf("%d Hz SINE WAVE SHOULD BE PLAYING!", f), 200, 140, 20, rl.LightGray) From 65392e706d2b03045ad1ef3fc3d1d40d80c63641 Mon Sep 17 00:00:00 2001 From: Zachary Bednarke Date: Tue, 7 May 2024 19:51:43 -0700 Subject: [PATCH 051/278] rename f t frequency --- examples/audio/raw_stream/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index 0c3552d..9b6a65f 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -12,7 +12,7 @@ const ( maxSamples = 6000 sampleRate = 6000 maxSamplesPerUpdate = 1600 - f = 440 + frequency = 440 targetFPS = 240 ) @@ -29,7 +29,7 @@ func main() { for i := 0; i < maxSamples; i++ { t := float32(i) / float32(maxSamples) - data[i] = float32(math.Sin(float64((2 * rl.Pi * f * t)))) + data[i] = float32(math.Sin(float64((2 * rl.Pi * frequency * t)))) } // NOTE: The buffer can only be updated when it has been processed. Time between buffer processing and next load and causes clipping @@ -55,7 +55,7 @@ func main() { rl.BeginDrawing() rl.ClearBackground(rl.RayWhite) - rl.DrawText(fmt.Sprintf("%d Hz SINE WAVE SHOULD BE PLAYING!", f), 200, 140, 20, rl.LightGray) + rl.DrawText(fmt.Sprintf("%d Hz SINE WAVE SHOULD BE PLAYING!", frequency), 200, 140, 20, rl.LightGray) // NOTE: Draw a part of the sine wave (only screen width) for i := 0; i < int(rl.GetScreenWidth()); i++ { From db4aa35b123c3dcf5ff1000362680c88e59397d6 Mon Sep 17 00:00:00 2001 From: Zachary Bednarke Date: Tue, 7 May 2024 19:54:07 -0700 Subject: [PATCH 052/278] rename variables --- examples/audio/raw_stream/main.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index 9b6a65f..4fb0a9a 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -9,11 +9,11 @@ import ( ) const ( - maxSamples = 6000 - sampleRate = 6000 - maxSamplesPerUpdate = 1600 - frequency = 440 - targetFPS = 240 + nSamples = 6000 + sampleRate = 6000 + nSamplesPerUpdate = 1600 + frequency = 440 + targetFPS = 240 ) func main() { @@ -21,14 +21,14 @@ func main() { position := rl.NewVector2(0, 0) rl.InitAudioDevice() - // Init raw audio stream (sample rate: , sample size: 32bit-float, channels: 1-mono) - stream := rl.LoadAudioStream(maxSamples, 32, 1) + // Init raw audio stream (sample rate: , sample size: 32bit-float, channels: 1-mono) + stream := rl.LoadAudioStream(nSamples, 32, 1) //// Create sine wave to play - data := make([]float32, maxSamples) + data := make([]float32, nSamples) - for i := 0; i < maxSamples; i++ { - t := float32(i) / float32(maxSamples) + for i := 0; i < nSamples; i++ { + t := float32(i) / float32(nSamples) data[i] = float32(math.Sin(float64((2 * rl.Pi * frequency * t)))) } @@ -42,11 +42,11 @@ func main() { // Refill audio stream if buffer is processed if rl.IsAudioStreamProcessed(stream) { elapsedTime := time.Since(startTime).Seconds() - currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(maxSamples))) - nextSampleIndex := currentSampleIndex + maxSamplesPerUpdate + currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(nSamples))) + nextSampleIndex := currentSampleIndex + nSamplesPerUpdate - if nextSampleIndex > maxSamples { - nextSampleIndex = maxSamplesPerUpdate - (maxSamples - currentSampleIndex) + if nextSampleIndex > nSamples { + nextSampleIndex = nSamplesPerUpdate - (nSamples - currentSampleIndex) rl.UpdateAudioStream(stream, append(data[currentSampleIndex:], data[:nextSampleIndex]...)) } else { rl.UpdateAudioStream(stream, data[currentSampleIndex:nextSampleIndex]) From a7fccc35a1dc25f76e52f3940d1bab0b4cc81f86 Mon Sep 17 00:00:00 2001 From: zbednarke Date: Tue, 7 May 2024 20:20:12 -0700 Subject: [PATCH 053/278] lower n samples per update to be on safe side --- examples/audio/raw_stream/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index 4fb0a9a..17c27c7 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -11,7 +11,7 @@ import ( const ( nSamples = 6000 sampleRate = 6000 - nSamplesPerUpdate = 1600 + nSamplesPerUpdate = 1400 frequency = 440 targetFPS = 240 ) From 1a0035bfeda77f0c635ab31037b4cb54048f4667 Mon Sep 17 00:00:00 2001 From: zbednarke Date: Tue, 7 May 2024 20:36:38 -0700 Subject: [PATCH 054/278] make buffer bigger --- examples/audio/raw_stream/main.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index 17c27c7..3f7cd82 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -9,16 +9,19 @@ import ( ) const ( - nSamples = 6000 - sampleRate = 6000 - nSamplesPerUpdate = 1400 - frequency = 440 - targetFPS = 240 + nSamples = 44000 * 10 + sampleRate = 44000 + bufferSize = nSamples + frequency = 440 + targetFPS = 240 ) func main() { rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming") position := rl.NewVector2(0, 0) + + rl.SetAudioStreamBufferSizeDefault(bufferSize) + rl.InitAudioDevice() // Init raw audio stream (sample rate: , sample size: 32bit-float, channels: 1-mono) @@ -43,10 +46,10 @@ func main() { if rl.IsAudioStreamProcessed(stream) { elapsedTime := time.Since(startTime).Seconds() currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(nSamples))) - nextSampleIndex := currentSampleIndex + nSamplesPerUpdate + nextSampleIndex := currentSampleIndex + bufferSize if nextSampleIndex > nSamples { - nextSampleIndex = nSamplesPerUpdate - (nSamples - currentSampleIndex) + nextSampleIndex = bufferSize - (nSamples - currentSampleIndex) rl.UpdateAudioStream(stream, append(data[currentSampleIndex:], data[:nextSampleIndex]...)) } else { rl.UpdateAudioStream(stream, data[currentSampleIndex:nextSampleIndex]) From 74d0b22ad183036f89c66cee47633908bd0057eb Mon Sep 17 00:00:00 2001 From: zbednarke Date: Tue, 7 May 2024 20:38:52 -0700 Subject: [PATCH 055/278] lower sample rate --- examples/audio/raw_stream/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index 3f7cd82..05e653c 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -10,7 +10,7 @@ import ( const ( nSamples = 44000 * 10 - sampleRate = 44000 + sampleRate = 6000 bufferSize = nSamples frequency = 440 targetFPS = 240 From 266797ff04fe0aa7f239013a279f47ef3918a8cd Mon Sep 17 00:00:00 2001 From: zbednarke Date: Tue, 7 May 2024 20:42:31 -0700 Subject: [PATCH 056/278] sine graphic --- examples/audio/raw_stream/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audio/raw_stream/main.go b/examples/audio/raw_stream/main.go index 05e653c..5a4f4bf 100644 --- a/examples/audio/raw_stream/main.go +++ b/examples/audio/raw_stream/main.go @@ -63,7 +63,7 @@ func main() { // NOTE: Draw a part of the sine wave (only screen width) for i := 0; i < int(rl.GetScreenWidth()); i++ { position.X = float32(i) - position.Y = 250 + 10*data[i] + position.Y = 250 + 10*data[i*nSamples/int(20*rl.GetScreenWidth())] rl.DrawPixelV(position, rl.Red) } From 7810550d6308ffafdd0c77cfa4877c890ec685c2 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 10:30:05 +0200 Subject: [PATCH 057/278] Add RGFW backend --- raylib/cgo_darwin.go | 4 +- raylib/cgo_darwin_rgfw.go | 19 + raylib/cgo_darwin_sdl.go | 4 +- raylib/cgo_freebsd.go | 4 +- raylib/cgo_freebsd_rgfw.go | 19 + raylib/cgo_freebsd_sdl.go | 4 +- raylib/cgo_linux.go | 4 +- raylib/cgo_linux_drm.go | 4 +- raylib/cgo_linux_rgfw.go | 20 + raylib/cgo_linux_sdl.go | 4 +- raylib/cgo_openbsd.go | 4 +- raylib/cgo_openbsd_rgfw.go | 19 + raylib/cgo_openbsd_sdl.go | 4 +- raylib/cgo_windows.go | 4 +- raylib/cgo_windows_rgfw.go | 19 + raylib/cgo_windows_sdl.go | 4 +- raylib/external/RGFW.h | 6353 +++++++++++++++++++++++++ raylib/platform_android.go | 3 + raylib/platform_desktop.go | 4 +- raylib/platform_desktop_rgfw.go | 102 + raylib/platform_desktop_sdl.go | 8 +- raylib/platform_drm.go | 4 +- raylib/platforms/rcore_desktop_rgfw.c | 1524 ++++++ 23 files changed, 8110 insertions(+), 28 deletions(-) create mode 100644 raylib/cgo_darwin_rgfw.go create mode 100644 raylib/cgo_freebsd_rgfw.go create mode 100644 raylib/cgo_linux_rgfw.go create mode 100644 raylib/cgo_openbsd_rgfw.go create mode 100644 raylib/cgo_windows_rgfw.go create mode 100644 raylib/external/RGFW.h create mode 100644 raylib/platform_desktop_rgfw.go create mode 100644 raylib/platforms/rcore_desktop_rgfw.c diff --git a/raylib/cgo_darwin.go b/raylib/cgo_darwin.go index ce68341..919518c 100644 --- a/raylib/cgo_darwin.go +++ b/raylib/cgo_darwin.go @@ -1,5 +1,5 @@ -//go:build darwin && !sdl -// +build darwin,!sdl +//go:build darwin && !rgfw && !sdl +// +build darwin,!rgfw,!sdl package rl diff --git a/raylib/cgo_darwin_rgfw.go b/raylib/cgo_darwin_rgfw.go new file mode 100644 index 0000000..2c6f47c --- /dev/null +++ b/raylib/cgo_darwin_rgfw.go @@ -0,0 +1,19 @@ +//go:build darwin && rgfw && !sdl +// +build darwin,rgfw,!sdl + +package rl + +/* +#cgo darwin LDFLAGS: -framework Foundation -framework AppKit -framework CoreVideo +#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -DPLATFORM_DESKTOP_RGFW + +#cgo darwin,!es2,!es3 LDFLAGS: -framework OpenGL + +#cgo darwin,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 +#cgo darwin,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 +#cgo darwin,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 +#cgo darwin,!opengl11,!opengl21,!opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_33 +#cgo darwin,es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_ES2 +#cgo darwin,es3,!es2 CFLAGS: -DGRAPHICS_API_OPENGL_ES3 +*/ +import "C" diff --git a/raylib/cgo_darwin_sdl.go b/raylib/cgo_darwin_sdl.go index f059403..055f3eb 100644 --- a/raylib/cgo_darwin_sdl.go +++ b/raylib/cgo_darwin_sdl.go @@ -1,5 +1,5 @@ -//go:build darwin && sdl -// +build darwin,sdl +//go:build darwin && sdl && !rgfw +// +build darwin,sdl,!rgfw package rl diff --git a/raylib/cgo_freebsd.go b/raylib/cgo_freebsd.go index 8b71e4d..99d6491 100644 --- a/raylib/cgo_freebsd.go +++ b/raylib/cgo_freebsd.go @@ -1,5 +1,5 @@ -//go:build freebsd && !linux && !drm && !sdl && !android -// +build freebsd,!linux,!drm,!sdl,!android +//go:build freebsd && !linux && !rgfw && !drm && !sdl && !android +// +build freebsd,!linux,!rgfw,!drm,!sdl,!android package rl diff --git a/raylib/cgo_freebsd_rgfw.go b/raylib/cgo_freebsd_rgfw.go new file mode 100644 index 0000000..35c8142 --- /dev/null +++ b/raylib/cgo_freebsd_rgfw.go @@ -0,0 +1,19 @@ +//go:build freebsd && rgfw && !linux && !drm && !sdl && !android +// +build freebsd,rgfw,!linux,!drm,!sdl,!android + +package rl + +/* +#cgo freebsd CFLAGS: -I. -I/usr/local/include -DPLATFORM_DESKTOP_RGFW +#cgo freebsd LDFLAGS: -L/usr/local/lib -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -lpthread -ldl -lrt + +#cgo freebsd,!es2,!es3 LDFLAGS: -lGL + +#cgo freebsd,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 +#cgo freebsd,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 +#cgo freebsd,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 +#cgo freebsd,!opengl11,!opengl21,!opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_33 +#cgo freebsd,es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_ES2 +#cgo freebsd,es3,!es2 CFLAGS: -DGRAPHICS_API_OPENGL_ES3 +*/ +import "C" diff --git a/raylib/cgo_freebsd_sdl.go b/raylib/cgo_freebsd_sdl.go index 9f4319a..a54ff47 100644 --- a/raylib/cgo_freebsd_sdl.go +++ b/raylib/cgo_freebsd_sdl.go @@ -1,5 +1,5 @@ -//go:build freebsd && !linux && !drm && sdl && !android -// +build freebsd,!linux,!drm,sdl,!android +//go:build freebsd && !linux && sdl && !rgfw && !drm && !android +// +build freebsd,!linux,sdl,!rgfw,!drm,!android package rl diff --git a/raylib/cgo_linux.go b/raylib/cgo_linux.go index 9c8a507..07f9886 100644 --- a/raylib/cgo_linux.go +++ b/raylib/cgo_linux.go @@ -1,5 +1,5 @@ -//go:build linux && !drm && !sdl && !android -// +build linux,!drm,!sdl,!android +//go:build linux && !rgfw && !drm && !sdl && !android +// +build linux,!rgfw,!drm,!sdl,!android package rl diff --git a/raylib/cgo_linux_drm.go b/raylib/cgo_linux_drm.go index 2c8fe9a..afc1ac0 100644 --- a/raylib/cgo_linux_drm.go +++ b/raylib/cgo_linux_drm.go @@ -1,5 +1,5 @@ -//go:build linux && drm && !sdl && !android -// +build linux,drm,!sdl,!android +//go:build linux && drm && !rgfw && !sdl && !android +// +build linux,drm,!rgfw,!sdl,!android package rl diff --git a/raylib/cgo_linux_rgfw.go b/raylib/cgo_linux_rgfw.go new file mode 100644 index 0000000..54ea8f9 --- /dev/null +++ b/raylib/cgo_linux_rgfw.go @@ -0,0 +1,20 @@ +//go:build linux && rgfw && !drm && !sdl && !android +// +build linux,rgfw,!drm,!sdl,!android + +package rl + +/* +#cgo linux,!es2 LDFLAGS: -lm +#cgo linux CFLAGS: -DPLATFORM_DESKTOP_RGFW -Wno-builtin-declaration-mismatch -Wno-discarded-qualifiers -Wno-int-conversion +#cgo linux LDFLAGS: -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -lpthread -ldl -lrt + +#cgo linux,!es2,!es3 LDFLAGS: -lGL + +#cgo linux,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 +#cgo linux,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 +#cgo linux,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 +#cgo linux,!opengl11,!opengl21,!opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_33 +#cgo linux,es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_ES2 +#cgo linux,es3,!es2 CFLAGS: -DGRAPHICS_API_OPENGL_ES3 +*/ +import "C" diff --git a/raylib/cgo_linux_sdl.go b/raylib/cgo_linux_sdl.go index 55dbf58..90f3186 100644 --- a/raylib/cgo_linux_sdl.go +++ b/raylib/cgo_linux_sdl.go @@ -1,5 +1,5 @@ -//go:build linux && !drm && sdl && !android -// +build linux,!drm,sdl,!android +//go:build linux && sdl && !rgfw && !drm && !android +// +build linux,sdl,!rgfw,!drm,!android package rl diff --git a/raylib/cgo_openbsd.go b/raylib/cgo_openbsd.go index ce5244d..9e8d6b5 100644 --- a/raylib/cgo_openbsd.go +++ b/raylib/cgo_openbsd.go @@ -1,5 +1,5 @@ -//go:build openbsd && !linux && !drm && !sdl && !android -// +build openbsd,!linux,!drm,!sdl,!android +//go:build openbsd && !linux && !rgfw && !drm && !sdl && !android +// +build openbsd,!linux,!rgfw,!drm,!sdl,!android package rl diff --git a/raylib/cgo_openbsd_rgfw.go b/raylib/cgo_openbsd_rgfw.go new file mode 100644 index 0000000..a46ef7a --- /dev/null +++ b/raylib/cgo_openbsd_rgfw.go @@ -0,0 +1,19 @@ +//go:build openbsd && rgfw && !linux && !sdl && !drm && !android +// +build openbsd,rgfw,!linux,!sdl,!drm,!android + +package rl + +/* +#cgo openbsd CFLAGS: -I. -I/usr/X11R6/include -DPLATFORM_DESKTOP_RGFW +#cgo openbsd LDFLAGS: -L/usr/X11R6/lib -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -lpthread -ldl -lrt + +#cgo openbsd,!es2,!es3 LDFLAGS: -lGL + +#cgo openbsd,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 +#cgo openbsd,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 +#cgo openbsd,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 +#cgo openbsd,!opengl11,!opengl21,!opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_33 +#cgo openbsd,es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_ES2 +#cgo openbsd,es3,!es2 CFLAGS: -DGRAPHICS_API_OPENGL_ES3 +*/ +import "C" diff --git a/raylib/cgo_openbsd_sdl.go b/raylib/cgo_openbsd_sdl.go index 2bc9a8d..2bd9f10 100644 --- a/raylib/cgo_openbsd_sdl.go +++ b/raylib/cgo_openbsd_sdl.go @@ -1,5 +1,5 @@ -//go:build openbsd && !linux && !drm && sdl && !android -// +build openbsd,!linux,!drm,sdl,!android +//go:build openbsd && !linux && sdl && !rgfw && !drm && !android +// +build openbsd,!linux,sdl,!rgfw,!drm,!android package rl diff --git a/raylib/cgo_windows.go b/raylib/cgo_windows.go index 41d1761..ee4ef36 100644 --- a/raylib/cgo_windows.go +++ b/raylib/cgo_windows.go @@ -1,5 +1,5 @@ -//go:build windows && !sdl -// +build windows,!sdl +//go:build windows && !rgfw && !sdl +// +build windows,!rgfw,!sdl package rl diff --git a/raylib/cgo_windows_rgfw.go b/raylib/cgo_windows_rgfw.go new file mode 100644 index 0000000..3508152 --- /dev/null +++ b/raylib/cgo_windows_rgfw.go @@ -0,0 +1,19 @@ +//go:build windows && rgfw && !sdl +// +build windows,rgfw,!sdl + +package rl + +/* +#cgo windows LDFLAGS: -lgdi32 -lwinmm +#cgo windows CFLAGS: -Iexternal -DPLATFORM_DESKTOP_RGFW -Wno-stringop-overflow -Wno-discarded-qualifiers + +#cgo windows,!es2,!es3 LDFLAGS: -lopengl32 + +#cgo windows,opengl11,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_11 +#cgo windows,opengl21,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_21 +#cgo windows,opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_43 +#cgo windows,!opengl11,!opengl21,!opengl43,!es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_33 +#cgo windows,es2,!es3 CFLAGS: -DGRAPHICS_API_OPENGL_ES2 +#cgo windows,es3,!es2 CFLAGS: -DGRAPHICS_API_OPENGL_ES3 +*/ +import "C" diff --git a/raylib/cgo_windows_sdl.go b/raylib/cgo_windows_sdl.go index 6ee16fd..04cbd1e 100644 --- a/raylib/cgo_windows_sdl.go +++ b/raylib/cgo_windows_sdl.go @@ -1,5 +1,5 @@ -//go:build windows && sdl -// +build windows,sdl +//go:build windows && sdl && !rgfw +// +build windows,sdl,!rgfw package rl diff --git a/raylib/external/RGFW.h b/raylib/external/RGFW.h new file mode 100644 index 0000000..f806744 --- /dev/null +++ b/raylib/external/RGFW.h @@ -0,0 +1,6353 @@ +/* +* Copyright (C) 2023-24 ColleagueRiley +* +* libpng license +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +* +* +*/ + +/* + (MAKE SURE RGFW_IMPLEMENTATION is in exactly one header or you use -D RGFW_IMPLEMENTATION) + #define RGFW_IMPLEMENTATION - makes it so source code is included with header +*/ + +/* + #define RGFW_IMPLEMENTATION - (required) makes it so the source code is included + #define RGFW_PRINT_ERRORS - (optional) makes it so RGFW prints errors when they're found + #define RGFW_OSMESA - (optional) use OSmesa as backend (instead of system's opengl api + regular opengl) + #define RGFW_BUFFER - (optional) just draw directly to (RGFW) window pixel buffer that is drawn to screen (the buffer is in the RGBA format) + #define RGFW_EGL - (optional) use EGL for loading an OpenGL context (instead of the system's opengl api) + #define RGFW_OPENGL_ES1 - (optional) use EGL to load and use Opengl ES (version 1) for backend rendering (instead of the system's opengl api) + #define RGFW_OPENGL_ES2 - (optional) use OpenGL ES (version 2) + #define RGFW_VULKAN - (optional) use vulkan for the rendering backend (rather than opengl) + #define RGFW_DIRECTX - (optional) use directX for the rendering backend (rather than opengl) (windows only, defaults to opengl for unix) + #define RGFW_NO_API - (optional) don't use any rendering API (no opengl, no vulkan, no directX) + + #define RGFW_LINK_EGL (optional) (windows only) if EGL is being used, if EGL functions should be defined dymanically (using GetProcAddress) + #define RGFW_LINK_OSMESA (optional) (windows only) if EGL is being used, if OS Mesa functions should be defined dymanically (using GetProcAddress) + + #define RGFW_X11 (optional) (unix only) if X11 should be used. This option is turned on by default by unix systems except for MacOS + #define RGFW_WGL_LOAD (optional) (windows only) if WGL should be loaded dynamically during runtime + #define RGFW_NO_X11_CURSOR (optional) (unix only) don't use XCursor + #define RGFW_NO_X11_CURSOR_PRELOAD (optional) (unix only) Use XCursor, but don't link it in code, (you'll have to link it with -lXcursor) + + #define RGFW_NO_DPI - Do not include calculate DPI (no XRM nor libShcore included) + + #define RGFW_ALLOC_DROPFILES (optional) if room should be allocating for drop files (by default it's global data) + #define RGFW_MALLOC x - choose what function to use to allocate, by default the standard malloc is used + #define RGFW_CALLOC x - choose what function to use to allocate (calloc), by default the standard calloc is used + #define RGFW_FREE x - choose what function to use to allocated memory, by default the standard free is used +*/ + +/* + Credits : + EimaMei/Sacode : Much of the code for creating windows using winapi, Wrote the Silicon library, helped with MacOS Support + + stb - This project is heavily inspired by the stb single header files + + GLFW: + certain parts of winapi and X11 are very poorly documented, + GLFW's source code was referenced and used throughout the project (used code is marked in some way), + this mainly includes, code for drag and drops, code for setting the icon to a bitmap and the code for managing the clipboard for X11 (as these parts are not documented very well) + + GLFW Copyright, https::/github.com/GLFW/GLFW + + Copyright (c) 2002-2006 Marcus Geelnard + Copyright (c) 2006-2019 Camilla Löwy +*/ + +#ifndef RGFW_MALLOC +#include +#include +#define RGFW_MALLOC malloc +#define RGFW_CALLOC calloc +#define RGFW_FREE free +#endif + +#if !_MSC_VER +#ifndef inline +#ifndef __APPLE__ +#define inline __inline +#endif +#endif +#endif + +#ifndef RGFWDEF +#ifdef __APPLE__ +#define RGFWDEF extern inline +#else +#define RGFWDEF inline +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /* makes sure the header file part is only defined once by default */ +#ifndef RGFW_HEADER + +#define RGFW_HEADER + +#if !defined(u8) +#include + + typedef uint8_t u8; + typedef int8_t i8; + typedef uint16_t u16; + typedef int16_t i16; + typedef uint32_t u32; + typedef int32_t i32; + typedef uint64_t u64; + typedef int64_t i64; +#endif + +#if defined(RGFW_X11) && defined(__APPLE__) +#define RGFW_MACOS_X11 +#undef __APPLE__ +#endif + +#if defined(_WIN32) && !defined(RGFW_X11) /* (if you're using X11 on windows some how) */ + + /* this name looks better */ + /* plus it helps with cross-compiling because RGFW_X11 won't be accidently defined */ + +#define RGFW_WINDOWS + +#if defined(_WIN32) +#ifndef WIN32 +#define WIN32 +#endif +#endif + +#if defined(_WIN64) +#ifndef WIN64 +#define WIN64 +#endif +#define _AMD64_ +#undef _X86_ +#else +#undef _AMD64_ +#define _X86_ +#endif + +#include + +#ifdef __MINGW32__ +#include +#else +#include +#endif + +#else +#if defined(__unix__) || defined(RGFW_MACOS_X11) || defined(RGFW_X11) +#define RGFW_MACOS_X11 +#define RGFW_X11 +#include +#endif +#endif + +#if defined(__APPLE__) && !defined(RGFW_MACOS_X11) && !defined(RGFW_X11) +#define RGFW_MACOS +#endif + +#if (defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2)) && !defined(RGFW_EGL) +#define RGFW_EGL +#endif +#if defined(RGFW_EGL) && defined(__APPLE__) + #warning EGL is not supported for Cocoa, switching back to the native opengl api +#undef RGFW_EGL +#endif + +#if !defined(RGFW_OSMESA) && !defined(RGFW_EGL) && !defined(RGFW_OPENGL) && !defined (RGFW_VULKAN) && !defined(RGFW_DIRECTX) && !defined(RGFW_BUFFER) && !defined(RGFW_NO_API) +#define RGFW_OPENGL +#endif + +#ifdef RGFW_VULKAN +#ifndef RGFW_MAX_FRAMES_IN_FLIGHT +#define RGFW_MAX_FRAMES_IN_FLIGHT 2 +#endif + +#ifdef RGFW_X11 +#define VK_USE_PLATFORM_XLIB_KHR +#endif +#ifdef RGFW_WINDOWS +#define VK_USE_PLATFORM_WIN32_KHR +#endif +#ifdef RGFW_MACOS +#define VK_USE_PLATFORM_MACOS_MVK +#endif + +#include +#endif + +#if defined(RGFW_X11) && defined(RGFW_OPENGL) +#ifndef GLX_MESA_swap_control +#define GLX_MESA_swap_control +#endif +#include /* GLX defs, xlib.h, gl.h */ +#endif + +#ifdef RGFW_EGL +#include +#endif + +#ifdef RGFW_OSMESA +#ifndef __APPLE__ +#include +#else +#include +#endif +#endif + +#if defined(RGFW_DIRECTX) && defined(RGFW_WINDOWS) +#include +#include +#include +#include + +#ifndef __cplusplus +#define __uuidof(T) IID_##T +#endif +#endif + + /*! Optional arguments for making a windows */ +#define RGFW_TRANSPARENT_WINDOW (1L<<9) /*!< the window is transparent */ +#define RGFW_NO_BORDER (1L<<3) /*!< the window doesn't have border */ +#define RGFW_NO_RESIZE (1L<<4) /*!< the window cannot be resized by the user */ +#define RGFW_ALLOW_DND (1L<<5) /*!< the window supports drag and drop*/ +#define RGFW_HIDE_MOUSE (1L<<6) /*! the window should hide the mouse or not (can be toggled later on) using `RGFW_window_mouseShow*/ +#define RGFW_FULLSCREEN (1L<<8) /* the window is fullscreen by default or not */ +#define RGFW_CENTER (1L<<10) /*! center the window on the screen */ +#define RGFW_OPENGL_SOFTWARE (1L<<11) /*! use OpenGL software rendering */ +#define RGFW_COCOA_MOVE_TO_RESOURCE_DIR (1L << 12) /* (cocoa only), move to resource folder */ +#define RGFW_SCALE_TO_MONITOR (1L << 13) /* scale the window to the screen */ + +#define RGFW_NO_GPU_RENDER (1L<<14) /* don't render (using the GPU based API)*/ +#define RGFW_NO_CPU_RENDER (1L<<15) /* don't render (using the CPU based buffer rendering)*/ + + +/*! event codes */ +#define RGFW_keyPressed 2 /* a key has been pressed */ +#define RGFW_keyReleased 3 /*!< a key has been released*/ +/*! key event note + the code of the key pressed is stored in + RGFW_Event.keyCode + !!Keycodes defined at the bottom of the header file!! + + while a string version is stored in + RGFW_Event.KeyString + + RGFW_Event.lockState holds the current lockState + this means if CapsLock, NumLock are active or not +*/ +#define RGFW_mouseButtonPressed 4 /*!< a mouse button has been pressed (left,middle,right)*/ +#define RGFW_mouseButtonReleased 5 /*!< a mouse button has been released (left,middle,right)*/ +#define RGFW_mousePosChanged 6 /*!< the position of the mouse has been changed*/ +/*! mouse event note + the x and y of the mouse can be found in the vector, RGFW_Event.point + + RGFW_Event.button holds which mouse button was pressed +*/ +#define RGFW_jsButtonPressed 7 /*!< a joystick button was pressed */ +#define RGFW_jsButtonReleased 8 /*!< a joystick button was released */ +#define RGFW_jsAxisMove 9 /*!< an axis of a joystick was moved*/ +/*! joystick event note + RGFW_Event.joystick holds which joystick was altered, if any + RGFW_Event.button holds which joystick button was pressed + + RGFW_Event.axis holds the data of all the axis + RGFW_Event.axisCount says how many axis there are +*/ +#define RGFW_windowAttribsChange 10 /*!< the window was moved or resized (by the user) */ +/* attribs change event note + The event data is sent straight to the window structure + with win->r.x, win->r.y, win->r.w and win->r.h +*/ +#define RGFW_quit 33 /*!< the user clicked the quit button*/ +#define RGFW_dnd 34 /*!< a file has been dropped into the window*/ +#define RGFW_dnd_init 35 /*!< the start of a dnd event, when the place where the file drop is known */ +/* dnd data note + The x and y coords of the drop are stored in the vector RGFW_Event.point + + RGFW_Event.droppedFilesCount holds how many files were dropped + + This is also the size of the array which stores all the dropped file string, + RGFW_Event.droppedFiles +*/ + +/*! mouse button codes (RGFW_Event.button) */ +#define RGFW_mouseLeft 1 /*!< left mouse button is pressed*/ +#define RGFW_mouseMiddle 2 /*!< mouse-wheel-button is pressed*/ +#define RGFW_mouseRight 3 /*!< right mouse button is pressed*/ +#define RGFW_mouseScrollUp 4 /*!< mouse wheel is scrolling up*/ +#define RGFW_mouseScrollDown 5 /*!< mouse wheel is scrolling down*/ + +#ifndef RGFW_MAX_PATH +#define RGFW_MAX_PATH 260 /* max length of a path (for dnd) */ +#endif +#ifndef RGFW_MAX_DROPS +#define RGFW_MAX_DROPS 260 /* max items you can drop at once */ +#endif + + +/* for RGFW_Event.lockstate */ +#define RGFW_CAPSLOCK (1L << 1) +#define RGFW_NUMLOCK (1L << 2) + +/*! joystick button codes (based on xbox/playstation), you may need to change these values per controller */ +#ifndef RGFW_JS_A + +#define RGFW_JS_A 0 /* or PS X button */ +#define RGFW_JS_B 1 /* or PS circle button */ +#define RGFW_JS_Y 2 /* or PS triangle button */ +#define RGFW_JS_X 3 /* or PS square button */ +#define RGFW_JS_START 9 /* start button */ +#define RGFW_JS_SELECT 8 /* select button */ +#define RGFW_JS_HOME 10 /* home button */ +#define RGFW_JS_UP 13 /* dpad up */ +#define RGFW_JS_DOWN 14 /* dpad down*/ +#define RGFW_JS_LEFT 15 /* dpad left */ +#define RGFW_JS_RIGHT 16 /* dpad right */ +#define RGFW_JS_L1 4 /* left bump */ +#define RGFW_JS_L2 5 /* left trigger*/ +#define RGFW_JS_R1 6 /* right bumper */ +#define RGFW_JS_R2 7 /* right trigger */ + +#endif + +/* basic vector type, if there's not already a point/vector type of choice */ +#ifndef RGFW_vector +typedef struct { i32 x, y; } RGFW_vector; +#endif + + /* basic rect type, if there's not already a rect type of choice */ +#ifndef RGFW_rect + typedef struct { i32 x, y, w, h; } RGFW_rect; +#endif + + /* basic area type, if there's not already a area type of choice */ +#ifndef RGFW_area + typedef struct { u32 w, h; } RGFW_area; +#endif + +#define RGFW_VECTOR(x, y) (RGFW_vector){x, y} +#define RGFW_RECT(x, y, w, h) (RGFW_rect){x, y, w, h} +#define RGFW_AREA(w, h) (RGFW_area){w, h} + + typedef struct RGFW_monitor { + char name[128]; /* monitor name */ + RGFW_rect rect; /* monitor Workarea */ + float scaleX, scaleY; /* monitor content scale*/ + float physW, physH; /* monitor physical size */ + } RGFW_monitor; + + /* + NOTE : Monitor functions should be ran only as many times as needed (not in a loop) + */ + + /* get an array of all the monitors (max 6) */ + RGFWDEF RGFW_monitor* RGFW_getMonitors(void); + /* get the primary monitor */ + RGFWDEF RGFW_monitor RGFW_getPrimaryMonitor(void); + + /* NOTE: some parts of the data can represent different things based on the event (read comments in RGFW_Event struct) */ + typedef struct RGFW_Event { +#ifdef RGFW_WINDOWS + char keyName[16]; /* key name of event*/ +#else + char* keyName; /*!< key name of event */ +#endif + + /*! drag and drop data */ + /* 260 max paths with a max length of 260 */ +#ifdef RGFW_ALLOC_DROPFILES + char** droppedFiles; +#else + char droppedFiles[RGFW_MAX_DROPS][RGFW_MAX_PATH]; /*!< dropped files*/ +#endif + u32 droppedFilesCount; /*!< house many files were dropped */ + + u32 type; /*!< which event has been sent?*/ + RGFW_vector point; /*!< mouse x, y of event (or drop point) */ + u32 keyCode; /*!< keycode of event !!Keycodes defined at the bottom of the header file!! */ + + u32 inFocus; /*if the window is in focus or not*/ + + u32 fps; /*the current fps of the window [the fps is checked when events are checked]*/ + u32 current_ticks, frames; /* this is used for counting the fps */ + + u8 lockState; + + u16 joystick; /* which joystick this event applies to (if applicable to any) */ + + u8 button; /*!< which mouse button has been clicked (0) left (1) middle (2) right OR which joystick button was pressed*/ + double scroll; /* the raw mouse scroll value */ + + u8 axisesCount; /* number of axises */ + RGFW_vector axis[2]; /* x, y of axises (-100 to 100) */ + } RGFW_Event; /*!< Event structure for checking/getting events */ + + /* source data for the window (used by the APIs) */ + typedef struct RGFW_window_src { +#ifdef RGFW_WINDOWS + HWND window; /*!< source window */ + HDC hdc; /*!< source HDC */ + u32 hOffset; /*!< height offset for window */ +#endif +#ifdef RGFW_X11 + Display* display; /*!< source display */ + Window window; /*!< source window */ + Cursor cursor; +#endif +#ifdef RGFW_MACOS + u32 display; + void* displayLink; + void* window; +#endif + +#if defined(RGFW_OPENGL) && !defined(RGFW_OSMESA) +#ifdef RGFW_MACOS + void* rSurf; /*!< source graphics context */ +#endif +#ifdef RGFW_WINDOWS + HGLRC rSurf; /*!< source graphics context */ +#endif +#ifdef RGFW_X11 + GLXContext rSurf; /*!< source graphics context */ +#endif +#else +#ifdef RGFW_VULKAN + VkSurfaceKHR rSurf; /*!< source graphics context */ + + /* vulkan data */ + VkSwapchainKHR swapchain; + u32 image_count; + VkImage* swapchain_images; + VkImageView* swapchain_image_views; +#endif + +#ifdef RGFW_OSMESA + OSMesaContext rSurf; +#endif +#endif + +#ifdef RGFW_WINDOWS + RGFW_area maxSize, minSize; +#if defined(RGFW_DIRECTX) + IDXGISwapChain* swapchain; + ID3D11RenderTargetView* renderTargetView; + ID3D11DepthStencilView* pDepthStencilView; +#endif +#endif + +#if defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11) + void* view; /*apple viewpoint thingy*/ +#endif + +#ifdef RGFW_EGL + EGLSurface EGL_surface; + EGLDisplay EGL_display; +#endif + +#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER) +#ifdef RGFW_WINDOWS + HBITMAP bitmap; +#endif +#ifdef RGFW_X11 + XImage* bitmap; +#endif +#ifdef RGFW_MACOS + void* bitmap; /* API's bitmap for storing or managing */ + void* image; +#endif +#if defined(RGFW_BUFFER) && defined(RGFW_WINDOWS) + HDC hdcMem; /* window stored in memory that winapi needs to render buffers */ +#endif +#endif + + u8 jsPressed[4][16]; /* if a key is currently pressed or not (per joystick) */ + + i32 joysticks[4]; /* limit of 4 joysticks at a time */ + u16 joystickCount; /* the actual amount of joysticks */ + + RGFW_area scale; /* window scaling */ + +#ifdef RGFW_MACOS + u8 cursorChanged; /* for steve jobs */ +#endif + + u32 winArgs; /* windows args (for RGFW to check) */ + /* + !< if dnd is enabled or on (based on window creating args) + cursorChanged + */ + } RGFW_window_src; + + typedef struct RGFW_window { + RGFW_window_src src; + +#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER) + u8* buffer; /* buffer for non-GPU systems (OSMesa, basic software rendering) */ + /* when rendering using RGFW_BUFFER, the buffer is in the RGBA format */ +#endif + + RGFW_Event event; /*!< current event */ + + RGFW_rect r; /* the x, y, w and h of the struct */ + + u8 fpsCap; /*!< the fps cap of the window should run at (change this var to change the fps cap, 0 = no limit)*/ + /*[the fps is capped when events are checked]*/ + } RGFW_window; /*!< Window structure for managing the window */ + +#if defined(RGFW_X11) || defined(RGFW_MACOS) + typedef u64 RGFW_thread; /* thread type unix */ +#else + typedef void* RGFW_thread; /* thread type for window */ +#endif + + RGFW_window* RGFW_createWindow( + const char* name, /* name of the window */ + RGFW_rect rect, /* rect of window */ + u16 args /* extra arguments (NULL / (u16)0 means no args used)*/ + ); /*!< function to create a window struct */ + + /* get the size of the screen to an area struct */ + RGFWDEF RGFW_area RGFW_getScreenSize(void); + + /* + this function checks an *individual* event (and updates window structure attributes) + this means, using this function without a while loop may cause event lag + + ex. + + while (RGFW_window_checkEvent(win) != NULL) [this keeps checking events until it reaches the last one] + */ + + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check events (returns a pointer to win->event or NULL if there is no event)*/ + + /*! window managment functions*/ + RGFWDEF void RGFW_window_close(RGFW_window* win); /*!< close the window and free leftover data */ + + RGFWDEF void RGFW_window_move(RGFW_window* win, + RGFW_vector v/* new pos*/ + ); + + /* move to a specific monitor */ + RGFWDEF void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor m); + + RGFWDEF void RGFW_window_resize(RGFW_window* win, + RGFW_area a/* new size*/ + ); + + /* set the minimum size a user can shrink a window */ + RGFWDEF void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a); + /* set the minimum size a user can extend a window */ + RGFWDEF void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a); + + RGFWDEF void RGFW_window_maximize(RGFW_window* win); /* maximize the window size */ + RGFWDEF void RGFW_window_minimize(RGFW_window* win); /* minimize the window (in taskbar (per OS))*/ + RGFWDEF void RGFW_window_restore(RGFW_window* win); /* restore the window from minimized (per OS)*/ + + RGFWDEF void RGFW_window_setName(RGFW_window* win, + char* name + ); + + void RGFW_window_setIcon(RGFW_window* win, /*!< source window */ + u8* icon /*!< icon bitmap */, + RGFW_area a /*!< width and height of the bitmap*/, + i32 channels /*!< how many channels the bitmap has (rgb : 3, rgba : 4) */ + ); /*!< image resized by default */ + + /*!< sets mouse to bitmap (very simular to RGFW_window_setIcon), image NOT resized by default*/ + RGFWDEF void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels); + + /*!< sets the mouse to a standard API cursor (based on RGFW_MOUSE, as seen at the end of the file) */ +#ifdef RGFW_MACOS + RGFWDEF void RGFW_window_setMouseStandard(RGFW_window* win, void* mouse); +#else + RGFWDEF void RGFW_window_setMouseStandard(RGFW_window* win, i32 mouse); +#endif + + RGFWDEF void RGFW_window_setMouseDefault(RGFW_window* win); /* sets the mouse to1` the default mouse image */ + /* + holds the mouse in place by moving the mouse back each time it moves + you can still use win->event.point to see how much it moved before it was put back in place + + this is useful for a 3D camera + */ + RGFWDEF void RGFW_window_mouseHold(RGFW_window* win); + /* undo hold */ + RGFWDEF void RGFW_window_mouseUnhold(RGFW_window* win); + + /* hide the window */ + RGFWDEF void RGFW_window_hide(RGFW_window* win); + /* show the window */ + RGFWDEF void RGFW_window_show(RGFW_window* win); + + /* + makes it so `RGFW_window_shouldClose` returns true + by setting the window event.type to RGFW_quit + */ + RGFWDEF void RGFW_window_setShouldClose(RGFW_window* win); + + /* where the mouse is on the screen */ + RGFWDEF RGFW_vector RGFW_getGlobalMousePoint(void); + + /* show the mouse or hide the mouse*/ + RGFWDEF void RGFW_window_showMouse(RGFW_window* win, i8 show); + /* move the mouse to a set x, y pos*/ + RGFWDEF void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v); + + /* if the window should close (RGFW_close was sent or escape was pressed) */ + RGFWDEF u8 RGFW_window_shouldClose(RGFW_window* win); + /* if window is fullscreen'd */ + RGFWDEF u8 RGFW_window_isFullscreen(RGFW_window* win); + /* if window is hidden */ + RGFWDEF u8 RGFW_window_isHidden(RGFW_window* win); + /* if window is minimized */ + RGFWDEF u8 RGFW_window_isMinimized(RGFW_window* win); + /* if window is maximized */ + RGFWDEF u8 RGFW_window_isMaximized(RGFW_window* win); + + /* + scale the window to the monitor, + this is run by default if the user uses the arg `RGFW_SCALE_TO_MONITOR` during window creation + */ + RGFWDEF void RGFW_window_scaleToMonitor(RGFW_window* win); + + /* get the struct of the window's monitor */ + RGFWDEF RGFW_monitor RGFW_window_getMonitor(RGFW_window* win); + + /*!< make the window the current opengl drawing context */ + RGFWDEF void RGFW_window_makeCurrent(RGFW_window* win); + + /*error handling*/ + RGFWDEF u8 RGFW_Error(); /* returns true if an error has occurred (doesn't print errors itself) */ + + /*!< if window == NULL, it checks if the key is pressed globally. Otherwise, it checks only if the key is pressed while the window in focus.*/ + RGFWDEF u8 RGFW_isPressedI(RGFW_window* win, u32 key); /*!< if key is pressed (key code)*/ + + /* + !!Keycodes defined at the bottom of the header file!! + */ + /*!< converts a key code to it's key string */ + RGFWDEF char* RGFW_keyCodeTokeyStr(u64 key); + /*!< converts a string of a key to it's key code */ + RGFWDEF u32 RGFW_keyStrToKeyCode(char* key); + /*!< if key is pressed (key string) */ +#define RGFW_isPressedS(win, key) RGFW_isPressedI(win, RGFW_keyStrToKeyCode(key)) + +/*! clipboard functions*/ + RGFWDEF char* RGFW_readClipboard(size_t* size); /*!< read clipboard data */ +#define RGFW_clipboardFree free /* the string returned from RGFW_readClipboard must be freed */ + + RGFWDEF void RGFW_writeClipboard(const char* text, u32 textLen); /*!< write text to the clipboard */ + + /* + convert a keyString to a char version + */ + RGFWDEF char RGFW_keystrToChar(const char*); + /* + ex. + "parenleft" -> '(' + "A" -> 'A', + "Return" -> "\n" + */ + +#ifndef RGFW_NO_THREADS + /*! threading functions*/ + + /*! NOTE! (for X11/linux) : if you define a window in a thread, it must be run after the original thread's window is created or else there will be a memory error */ + /* + I'd suggest you use sili's threading functions instead + if you're going to use sili + which is a good idea generally + */ + RGFWDEF RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args); /*!< create a thread*/ + RGFWDEF void RGFW_cancelThread(RGFW_thread thread); /*!< cancels a thread*/ + RGFWDEF void RGFW_joinThread(RGFW_thread thread); /*!< join thread to current thread */ + RGFWDEF void RGFW_setThreadPriority(RGFW_thread thread, u8 priority); /*!< sets the priority priority */ +#endif + + /*! gamepad/joystick functions (linux-only currently) */ + + /*! joystick count starts at 0*/ + /*!< register joystick to window based on a number (the number is based on when it was connected eg. /dev/js0)*/ + RGFWDEF u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber); + RGFWDEF u16 RGFW_registerJoystickF(RGFW_window* win, char* file); + + RGFWDEF u32 RGFW_isPressedJS(RGFW_window* win, u16 controller, u8 button); + + /*! native opengl functions */ +#ifdef RGFW_OPENGL +/*! Get max OpenGL version */ + RGFWDEF u8* RGFW_getMaxGLVersion(); + /* OpenGL init hints */ + RGFWDEF void RGFW_setGLStencil(i32 stencil); /* set stencil buffer bit size (8 by default) */ + RGFWDEF void RGFW_setGLSamples(i32 samples); /* set number of sampiling buffers (4 by default) */ + RGFWDEF void RGFW_setGLStereo(i32 stereo); /* use GL_STEREO (GL_FALSE by default) */ + RGFWDEF void RGFW_setGLAuxBuffers(i32 auxBuffers); /* number of aux buffers (0 by default) */ + + /*! Set OpenGL version hint */ + RGFWDEF void RGFW_setGLVersion(i32 major, i32 minor); + RGFWDEF void* RGFW_getProcAddress(const char* procname); /* get native opengl proc address */ +#endif + /* supports openGL, directX, OSMesa, EGL and software rendering */ + RGFWDEF void RGFW_window_swapBuffers(RGFW_window* win); /* swap the rendering buffer */ + RGFWDEF void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval); + + RGFWDEF void RGFW_window_setGPURender(RGFW_window* win, i8 set); + +#ifdef RGFW_VULKAN + typedef struct { + VkInstance instance; + VkPhysicalDevice physical_device; + VkDevice device; + + VkDebugUtilsMessengerEXT debugMessenger; + + VkQueue graphics_queue; + VkQueue present_queue; + + VkFramebuffer* framebuffers; + + VkRenderPass render_pass; + VkPipelineLayout pipeline_layout; + VkPipeline graphics_pipeline; + + VkCommandPool command_pool; + VkCommandBuffer* command_buffers; + + VkSemaphore* available_semaphores; + VkSemaphore* finished_semaphore; + VkFence* in_flight_fences; + VkFence* image_in_flight; + size_t current_frame; + } RGFW_vulkanInfo; + + /*! initializes a vulkan rendering context for the RGFW window, + this outputs the vulkan surface into wwin->src.rSurf + other vulkan data is stored in the global instance of the RGFW_vulkanInfo structure which is returned + by the initVulkan() function + RGFW_VULKAN must be defined for this function to be defined + + */ + RGFWDEF RGFW_vulkanInfo* RGFW_initVulkan(RGFW_window* win); + RGFWDEF void RGFW_freeVulkan(void); + + RGFWDEF RGFW_vulkanInfo* RGFW_getVulkanInfo(void); + + RGFWDEF int RGFW_initData(RGFW_window* win); + RGFWDEF void RGFW_createSurface(VkInstance instance, RGFW_window* win); + int RGFW_deviceInitialization(RGFW_window* win); + int RGFW_createSwapchain(RGFW_window* win); + RGFWDEF int RGFW_createRenderPass(); + int RGFW_createCommandPool(); + int RGFW_createCommandBuffers(RGFW_window* win); + int RGFW_createSyncObjects(RGFW_window* win); + RGFWDEF int RGFW_createFramebuffers(RGFW_window* win); +#endif + +#ifdef RGFW_DIRECTX + typedef struct { + IDXGIFactory* pFactory; + IDXGIAdapter* pAdapter; + ID3D11Device* pDevice; + ID3D11DeviceContext* pDeviceContext; + } RGFW_directXinfo; + + /* + RGFW stores a global instance of RGFW_directXinfo, + you can use this function to get a pointer the instance + */ + RGFWDEF RGFW_directXinfo* RGFW_getDirectXInfo(void); +#endif + + /*! Supporting functions */ + RGFWDEF void RGFW_window_checkFPS(RGFW_window* win); /*!< updates fps / sets fps to cap (ran by RGFW_window_checkEvent)*/ + RGFWDEF u64 RGFW_getTime(void); /* get time in seconds */ + RGFWDEF u64 RGFW_getTimeNS(void); /* get time in nanoseconds */ + RGFWDEF u32 RGFW_getFPS(void); /* get current FPS (win->event.fps) */ + RGFWDEF void RGFW_sleep(u32 microsecond); /* sleep for a set time */ +#endif /* RGFW_HEADER */ + + /* + Example to get you started : + + linux : gcc main.c -lX11 -lXcursor -lGL + windows : gcc main.c -lopengl32 -lshell32 -lgdi32 + macos : gcc main.c -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo + + #define RGFW_IMPLEMENTATION + #include "RGFW.h" + + u8 icon[4 * 3 * 3] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; + + int main() { + RGFW_window* win = RGFW_createWindow("name", RGFW_RECT(500, 500, 500, 500), (u64)0); + + RGFW_window_setIcon(win, icon, RGFW_AREA(3, 3), 4); + + for (;;) { + RGFW_window_checkEvent(win); // NOTE: checking events outside of a while loop may cause input lag + if (win->event.type == RGFW_quit || RGFW_isPressedI(win, RGFW_Escape)) + break; + + RGFW_window_swapBuffers(win); + + glClearColor(0xFF, 0XFF, 0xFF, 0xFF); + glClear(GL_COLOR_BUFFER_BIT); + } + + RGFW_window_close(win); + } + + compiling : + + if you wish to compile the library all you have to do is create a new file with this in it + + rgfw.c + #define RGFW_IMPLEMENTATION + #include "RGFW.h" + + then you can use gcc (or whatever compile you wish to use) to compile the library into object file + + ex. gcc -c RGFW.c -fPIC + + after you compile the library into an object file, you can also turn the object file into an static or shared library + + (commands ar and gcc can be replaced with whatever equivalent your system uses) + static : ar rcs RGFW.a RGFW.o + shared : + windows: + gcc -shared RGFW.o -lopengl32 -lshell32 -lgdi32 -o RGFW.dll + linux: + gcc -shared RGFW.o -lX11 -lXcursor -lGL -o RGFW.so + macos: + gcc -shared RGFW.o -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo + */ + +#ifdef RGFW_X11 +#define RGFW_OS_BASED_VALUE(l, w, m) l +#endif +#ifdef RGFW_WINDOWS +#define RGFW_OS_BASED_VALUE(l, w, m) w +#endif +#ifdef RGFW_MACOS +#define RGFW_OS_BASED_VALUE(l, w, m) m +#endif + +#ifdef RGFW_IMPLEMENTATION + +#include +#include +#include +#include + +#ifdef RGFW_WINDOWS + +#define WIN32_LEAN_AND_MEAN + +#include + +#endif + +#ifdef RGFW_MACOS +#include + + /* + based on silicon.h + */ + +#define GL_SILENCE_DEPRECATION +#include +#include +#include +#include + + typedef CGRect NSRect; + typedef CGPoint NSPoint; + typedef CGSize NSSize; + + typedef void NSBitmapImageRep; + typedef void NSCursor; + typedef void NSDraggingInfo; + typedef void NSWindow; + typedef void NSApplication; + typedef void NSScreen; + typedef void NSEvent; + typedef void NSString; + typedef void NSOpenGLContext; + typedef void NSPasteboard; + typedef void NSColor; + typedef void NSArray; + typedef void NSImageRep; + typedef void NSImage; + typedef void NSOpenGLView; + + + typedef const char* NSPasteboardType; + typedef unsigned long NSUInteger; + typedef long NSInteger; + typedef NSInteger NSModalResponse; + +#ifdef __arm64__ + /* ARM just uses objc_msgSend */ +#define abi_objc_msgSend_stret objc_msgSend +#define abi_objc_msgSend_fpret objc_msgSend +#else /* __i386__ */ + /* x86 just uses abi_objc_msgSend_fpret and (NSColor *)objc_msgSend_id respectively */ +#define abi_objc_msgSend_stret objc_msgSend_stret +#define abi_objc_msgSend_fpret objc_msgSend_fpret +#endif + +#define NSAlloc(nsclass) objc_msgSend_id(nsclass, sel_registerName("alloc")) +#define objc_msgSend_bool ((BOOL (*)(id, SEL))objc_msgSend) +#define objc_msgSend_void ((void (*)(id, SEL))objc_msgSend) +#define objc_msgSend_void_id ((void (*)(id, SEL, id))objc_msgSend) +#define objc_msgSend_uint ((NSUInteger (*)(id, SEL))objc_msgSend) +#define objc_msgSend_void_bool ((void (*)(id, SEL, BOOL))objc_msgSend) +#define objc_msgSend_void_SEL ((void (*)(id, SEL, SEL))objc_msgSend) +#define objc_msgSend_id ((id (*)(id, SEL))objc_msgSend) + +#define si_declare_single(class, name, func) \ + void class##_##name(class* obj) { \ + return objc_msgSend_void(obj, sel_registerName(func)); \ + } + + +#define loadFunc(funcName) \ + static void* func = NULL;\ + if (func == NULL) \ + func = sel_registerName(funcName); + + void NSRelease(id obj) { + loadFunc("release"); + objc_msgSend_void(obj, func); + } + +#define release NSRelease + + si_declare_single(NSApplication, finishLaunching, "finishLaunching") + si_declare_single(NSOpenGLContext, flushBuffer, "flushBuffer") + + NSString* NSString_stringWithUTF8String(const char* str) { + loadFunc("stringWithUTF8String:"); + + return ((id(*)(id, SEL, const char*))objc_msgSend) + (objc_getClass("NSString"), func, str); + } + + const char* NSString_to_char(NSString* str) { + return ((const char* (*)(id, SEL)) objc_msgSend) (str, sel_registerName("UTF8String")); + } + + void si_impl_func_to_SEL_with_name(const char* class_name, const char* register_name, void* function) { + Class selected_class; + + if (strcmp(class_name, "NSView") == 0) { + selected_class = objc_getClass("ViewClass"); + } else if (strcmp(class_name, "NSWindow") == 0) { + selected_class = objc_getClass("WindowClass"); + } else { + selected_class = objc_getClass(class_name); + } + + class_addMethod(selected_class, sel_registerName(register_name), (IMP) function, 0); + } + + /* Header for the array. */ + typedef struct siArrayHeader { + size_t count; + /* TODO(EimaMei): Add a `type_width` later on. */ + } siArrayHeader; + + /* Gets the header of the siArray. */ +#define SI_ARRAY_HEADER(s) ((siArrayHeader*)s - 1) + + void* si_array_init_reserve(size_t sizeof_element, size_t count) { + siArrayHeader* ptr = malloc(sizeof(siArrayHeader) + (sizeof_element * count)); + void* array = ptr + sizeof(siArrayHeader); + + siArrayHeader* header = SI_ARRAY_HEADER(array); + header->count = count; + + return array; + } + +#define si_array_len(array) (SI_ARRAY_HEADER(array)->count) +#define si_func_to_SEL(class_name, function) si_impl_func_to_SEL_with_name(class_name, #function":", function) + /* Creates an Objective-C method (SEL) from a regular C function with the option to set the register name.*/ +#define si_func_to_SEL_with_name(class_name, register_name, function) si_impl_func_to_SEL_with_name(class_name, register_name":", function) + + NSRect NSMakeRect(double x, double y, double width, double height) { + NSRect r; + r.origin.x = x; + r.origin.y = y; + r.size.width = width; + r.size.height = height; + + return r; + } + + NSPoint NSMakePoint(double x, double y) { + NSPoint point; + point.x = x; + point.y = y; + return point; + } + + NSSize NSMakeSize(double w, double h) { + NSSize size; + size.width = w; + size.height = h; + return size; + } + + void* si_array_init(void* allocator, size_t sizeof_element, size_t count) { + void* array = si_array_init_reserve(sizeof_element, count); + memcpy(array, allocator, sizeof_element * count); + + return array; + } + + void si_array_free(void* array) { + if (array == NULL) + return; + + free(SI_ARRAY_HEADER(array)); + } + + unsigned char* NSBitmapImageRep_bitmapData(NSBitmapImageRep* imageRep) { + return ((unsigned char* (*)(id, SEL))objc_msgSend) + (imageRep, sel_registerName("bitmapData")); + } + +#define NS_ENUM(type, name) type name; enum + + typedef NS_ENUM(NSUInteger, NSBitmapFormat) { + NSBitmapFormatAlphaFirst = 1 << 0, // 0 means is alpha last (RGBA, CMYKA, etc.) + NSBitmapFormatAlphaNonpremultiplied = 1 << 1, // 0 means is premultiplied + NSBitmapFormatFloatingPointSamples = 1 << 2, // 0 is integer + + NSBitmapFormatSixteenBitLittleEndian API_AVAILABLE(macos(10.10)) = (1 << 8), + NSBitmapFormatThirtyTwoBitLittleEndian API_AVAILABLE(macos(10.10)) = (1 << 9), + NSBitmapFormatSixteenBitBigEndian API_AVAILABLE(macos(10.10)) = (1 << 10), + NSBitmapFormatThirtyTwoBitBigEndian API_AVAILABLE(macos(10.10)) = (1 << 11) + }; + + NSBitmapImageRep* NSBitmapImageRep_initWithBitmapData(unsigned char** planes, NSInteger width, NSInteger height, NSInteger bps, NSInteger spp, bool alpha, bool isPlanar, const char* colorSpaceName, NSBitmapFormat bitmapFormat, NSInteger rowBytes, NSInteger pixelBits) { + void* func = sel_registerName("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:"); + + return (NSBitmapImageRep*) ((id(*)(id, SEL, unsigned char**, NSInteger, NSInteger, NSInteger, NSInteger, bool, bool, const char*, NSBitmapFormat, NSInteger, NSInteger))objc_msgSend) + (NSAlloc(objc_getClass("NSBitmapImageRep")), func, planes, width, height, bps, spp, alpha, isPlanar, NSString_stringWithUTF8String(colorSpaceName), bitmapFormat, rowBytes, pixelBits); + } + + NSColor* NSColor_colorWithSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) { + void* nsclass = objc_getClass("NSColor"); + void* func = sel_registerName("colorWithSRGBRed:green:blue:alpha:"); + return ((id(*)(id, SEL, CGFloat, CGFloat, CGFloat, CGFloat))objc_msgSend) + (nsclass, func, red, green, blue, alpha); + } + + NSCursor* NSCursor_initWithImage(NSImage* newImage, NSPoint aPoint) { + void* func = sel_registerName("initWithImage:hotSpot:"); + void* nsclass = objc_getClass("NSCursor"); + + return (NSCursor*) ((id(*)(id, SEL, id, NSPoint))objc_msgSend) + (NSAlloc(nsclass), func, newImage, aPoint); + } + + void NSImage_addRepresentation(NSImage* image, NSImageRep* imageRep) { + void* func = sel_registerName("addRepresentation:"); + objc_msgSend_void_id(image, func, imageRep); + } + + NSImage* NSImage_initWithSize(NSSize size) { + void* func = sel_registerName("initWithSize:"); + return ((id(*)(id, SEL, NSSize))objc_msgSend) + (NSAlloc(objc_getClass("NSImage")), func, size); + } +#define NS_OPENGL_ENUM_DEPRECATED(minVers, maxVers) API_AVAILABLE(macos(minVers)) + typedef NS_ENUM(NSInteger, NSOpenGLContextParameter) { + NSOpenGLContextParameterSwapInterval NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 222, /* 1 param. 0 -> Don't sync, 1 -> Sync to vertical retrace */ + NSOpenGLContextParameterSurfaceOrder NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 235, /* 1 param. 1 -> Above Window (default), -1 -> Below Window */ + NSOpenGLContextParameterSurfaceOpacity NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 236, /* 1 param. 1-> Surface is opaque (default), 0 -> non-opaque */ + NSOpenGLContextParameterSurfaceBackingSize NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 304, /* 2 params. Width/height of surface backing size */ + NSOpenGLContextParameterReclaimResources NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 308, /* 0 params. */ + NSOpenGLContextParameterCurrentRendererID NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 309, /* 1 param. Retrieves the current renderer ID */ + NSOpenGLContextParameterGPUVertexProcessing NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 310, /* 1 param. Currently processing vertices with GPU (get) */ + NSOpenGLContextParameterGPUFragmentProcessing NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 311, /* 1 param. Currently processing fragments with GPU (get) */ + NSOpenGLContextParameterHasDrawable NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 314, /* 1 param. Boolean returned if drawable is attached */ + NSOpenGLContextParameterMPSwapsInFlight NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 315, /* 1 param. Max number of swaps queued by the MP GL engine */ + + NSOpenGLContextParameterSwapRectangle API_DEPRECATED("", macos(10.0, 10.14)) = 200, /* 4 params. Set or get the swap rectangle {x, y, w, h} */ + NSOpenGLContextParameterSwapRectangleEnable API_DEPRECATED("", macos(10.0, 10.14)) = 201, /* Enable or disable the swap rectangle */ + NSOpenGLContextParameterRasterizationEnable API_DEPRECATED("", macos(10.0, 10.14)) = 221, /* Enable or disable all rasterization */ + NSOpenGLContextParameterStateValidation API_DEPRECATED("", macos(10.0, 10.14)) = 301, /* Validate state for multi-screen functionality */ + NSOpenGLContextParameterSurfaceSurfaceVolatile API_DEPRECATED("", macos(10.0, 10.14)) = 306, /* 1 param. Surface volatile state */ + }; + + + void NSOpenGLContext_setValues(NSOpenGLContext* context, const int* vals, NSOpenGLContextParameter param) { + void* func = sel_registerName("setValues:forParameter:"); + ((void (*)(id, SEL, const int*, NSOpenGLContextParameter))objc_msgSend) + (context, func, vals, param); + } + + void* NSOpenGLPixelFormat_initWithAttributes(const uint32_t* attribs) { + void* func = sel_registerName("initWithAttributes:"); + return (void*) ((id(*)(id, SEL, const uint32_t*))objc_msgSend) + (NSAlloc(objc_getClass("NSOpenGLPixelFormat")), func, attribs); + } + + NSOpenGLView* NSOpenGLView_initWithFrame(NSRect frameRect, uint32_t* format) { + void* func = sel_registerName("initWithFrame:pixelFormat:"); + return (NSOpenGLView*) ((id(*)(id, SEL, NSRect, uint32_t*))objc_msgSend) + (NSAlloc(objc_getClass("NSOpenGLView")), func, frameRect, format); + } + + void NSCursor_performSelector(NSCursor* cursor, void* selector) { + void* func = sel_registerName("performSelector:"); + objc_msgSend_void_SEL(cursor, func, selector); + } + + NSPasteboard* NSPasteboard_generalPasteboard(void) { + return (NSPasteboard*) objc_msgSend_id(objc_getClass("NSPasteboard"), sel_registerName("generalPasteboard")); + } + + NSString** cstrToNSStringArray(char** strs, size_t len) { + static NSString* nstrs[6]; + size_t i; + for (i = 0; i < len; i++) + nstrs[i] = NSString_stringWithUTF8String(strs[i]); + + return nstrs; + } + + const char* NSPasteboard_stringForType(NSPasteboard* pasteboard, NSPasteboardType dataType) { + void* func = sel_registerName("stringForType:"); + return (const char*) NSString_to_char(((id(*)(id, SEL, const char*))objc_msgSend)(pasteboard, func, NSString_stringWithUTF8String(dataType))); + } + + NSArray* c_array_to_NSArray(void* array, size_t len) { + void* func = sel_registerName("initWithObjects:count:"); + void* nsclass = objc_getClass("NSArray"); + + return ((id(*)(id, SEL, void*, NSUInteger))objc_msgSend) + (NSAlloc(nsclass), func, array, len); + } + + void NSregisterForDraggedTypes(void* view, NSPasteboardType* newTypes, size_t len) { + NSString** ntypes = cstrToNSStringArray(newTypes, len); + + void* func = sel_registerName("registerForDraggedTypes:"); + + NSArray* array = c_array_to_NSArray(ntypes, len); + + objc_msgSend_void_id(view, sel_registerName("registerForDraggedTypes:"), array); + + NSRelease(array); + } + + NSInteger NSPasteBoard_declareTypes(NSPasteboard* pasteboard, NSPasteboardType* newTypes, size_t len, void* owner) { + NSString** ntypes = cstrToNSStringArray(newTypes, len); + + void* func = sel_registerName("declareTypes:owner:"); + + NSArray* array = c_array_to_NSArray(ntypes, len); + + NSInteger output = ((NSInteger(*)(id, SEL, id, void*))objc_msgSend) + (pasteboard, func, array, owner); + NSRelease(array); + + return output; + } + + bool NSPasteBoard_setString(NSPasteboard* pasteboard, const char* stringToWrite, NSPasteboardType dataType) { + void* func = sel_registerName("setString:forType:"); + return ((bool (*)(id, SEL, id, NSPasteboardType))objc_msgSend) + (pasteboard, func, NSString_stringWithUTF8String(stringToWrite), NSString_stringWithUTF8String(dataType)); + } + + void NSRetain(id obj) { objc_msgSend_void(obj, sel_registerName("retain")); } + + typedef enum NSApplicationActivationPolicy { + NSApplicationActivationPolicyRegular, + NSApplicationActivationPolicyAccessory, + NSApplicationActivationPolicyProhibited + } NSApplicationActivationPolicy; + + typedef NS_ENUM(u32, NSBackingStoreType) { + NSBackingStoreRetained = 0, + NSBackingStoreNonretained = 1, + NSBackingStoreBuffered = 2 + }; + + typedef NS_ENUM(u32, NSWindowStyleMask) { + NSWindowStyleMaskBorderless = 0, + NSWindowStyleMaskTitled = 1 << 0, + NSWindowStyleMaskClosable = 1 << 1, + NSWindowStyleMaskMiniaturizable = 1 << 2, + NSWindowStyleMaskResizable = 1 << 3, + NSWindowStyleMaskTexturedBackground = 1 << 8, /* deprecated */ + NSWindowStyleMaskUnifiedTitleAndToolbar = 1 << 12, + NSWindowStyleMaskFullScreen = 1 << 14, + NSWindowStyleMaskFullSizeContentView = 1 << 15, + NSWindowStyleMaskUtilityWindow = 1 << 4, + NSWindowStyleMaskDocModalWindow = 1 << 6, + NSWindowStyleMaskNonactivatingPanel = 1 << 7, + NSWindowStyleMaskHUDWindow = 1 << 13 + }; + + typedef const char* NSPasteboardType; + NSPasteboardType const NSPasteboardTypeString = "public.utf8-plain-text"; // Replaces NSStringPboardType + + + + typedef NS_ENUM(i32, NSDragOperation) { + NSDragOperationNone = 0, + NSDragOperationCopy = 1, + NSDragOperationLink = 2, + NSDragOperationGeneric = 4, + NSDragOperationPrivate = 8, + NSDragOperationMove = 16, + NSDragOperationDelete = 32, + NSDragOperationEvery = ULONG_MAX, + + //NSDragOperationAll_Obsolete API_DEPRECATED("", macos(10.0,10.10)) = 15, // Use NSDragOperationEvery + //NSDragOperationAll API_DEPRECATED("", macos(10.0,10.10)) = NSDragOperationAll_Obsolete, // Use NSDragOperationEvery + }; + + + NSUInteger NSArray_count(NSArray* array) { + void* func = sel_registerName("count"); + return ((NSUInteger(*)(id, SEL))objc_msgSend)(array, func); + } + + void* NSArray_objectAtIndex(NSArray* array, NSUInteger index) { + void* func = sel_registerName("objectAtIndex:"); + return ((id(*)(id, SEL, NSUInteger))objc_msgSend)(array, func, index); + } + + const char** NSPasteboard_readObjectsForClasses(NSPasteboard* pasteboard, Class* classArray, size_t len, void* options) { + void* func = sel_registerName("readObjectsForClasses:options:"); + + NSArray* array = c_array_to_NSArray(classArray, len); + + NSArray* output = (NSArray*) ((id(*)(id, SEL, id, void*))objc_msgSend) + (pasteboard, func, array, options); + + NSRelease(array); + + NSUInteger count = NSArray_count(output); + + const char** res = si_array_init_reserve(sizeof(const char*), count); + + for (NSUInteger i = 0; i < count; i++) + res[i] = NSString_to_char(NSArray_objectAtIndex(output, i)); + + return res; + } + + void* NSWindow_contentView(NSWindow* window) { + void* func = sel_registerName("contentView"); + return objc_msgSend_id(window, func); + } +#endif + + +#define RGFW_ASSERT(check, str) {\ + if (!(check)) { \ + printf(str); \ + assert(check); \ + } \ +} + + u8 RGFW_error = 0; + u8 RGFW_Error() { return RGFW_error; } + +#define SET_ATTRIB(a, v) { \ + assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ + attribs[index++] = a; \ + attribs[index++] = v; \ +} + +#define ADD_ATTRIB(a) { \ + assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ + attribs[index++] = a; \ +} + +#if defined(RGFW_X11) || defined(RGFW_WINDOWS) + void RGFW_window_showMouse(RGFW_window* win, i8 show) { + static u8 RGFW_blk[] = { 0, 0, 0, 0 }; + if (show == 0) + RGFW_window_setMouse(win, RGFW_blk, RGFW_AREA(1, 1), 4); + else + RGFW_window_setMouseDefault(win); + } +#endif + + RGFWDEF RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args); + RGFWDEF void RGFW_init_buffer(RGFW_window* win); + + RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) { + RGFW_window* win = (RGFW_window*) RGFW_MALLOC(sizeof(RGFW_window)); /* make a new RGFW struct */ + +#ifdef RGFW_ALLOC_DROPFILES + win->event.droppedFiles = (char**) RGFW_MALLOC(sizeof(char*) * RGFW_MAX_DROPS); + u32 i; + for (i = 0; i < RGFW_MAX_DROPS; i++) + win->event.droppedFiles[i] = (char*) RGFW_CALLOC(RGFW_MAX_PATH, sizeof(char)); +#endif + +#ifdef RGFW_X11 + /* open X11 display */ + /* this is done here so the screen size can be accessed */ + win->src.display = XOpenDisplay(NULL); + assert(win->src.display != NULL); +#endif + + #ifndef RGFW_X11 + RGFW_area screenR = RGFW_getScreenSize(); + #else + win->src.display = XOpenDisplay(NULL); + assert(win->src.display != NULL); + + Screen* scrn = DefaultScreenOfDisplay((Display*)win->src.display); + RGFW_area screenR = RGFW_AREA(scrn->width, scrn->height); + #endif + + if (args & RGFW_FULLSCREEN) + rect = RGFW_RECT(0, 0, screenR.w, screenR.h); + + if (args & RGFW_CENTER) + rect = RGFW_RECT((screenR.w - rect.w) / 2, (screenR.h - rect.h) / 2, rect.w, rect.h); + + /* set and init the new window's data */ + win->r = rect; + win->fpsCap = 0; + win->event.inFocus = 1; + win->event.droppedFilesCount = 0; + win->src.joystickCount = 0; +#ifdef RGFW_X11 + win->src.cursor = 0; +#endif +#ifdef RGFW_MACOS + RGFW_window_setMouseDefault(win); +#endif +#ifdef RGFW_WINDOWS + win->src.maxSize = RGFW_AREA(0, 0); + win->src.minSize = RGFW_AREA(0, 0); +#endif + win->src.winArgs = 0; + + return win; + } + + void RGFW_window_scaleToMonitor(RGFW_window* win) { + RGFW_monitor monitor = RGFW_window_getMonitor(win); + + RGFW_window_resize(win, RGFW_AREA(((u32) monitor.scaleX) * win->r.w, ((u32) monitor.scaleX) * win->r.h)); + } + + void RGFW_init_buffer(RGFW_window* win) { +#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER) + RGFW_area area = RGFW_getScreenSize(); +#if !(defined(RGFW_WINDOWS)) || defined(RGFW_OSMESA) + win->buffer = RGFW_MALLOC(area.w * area.h * 4); +#endif + +#ifdef RGFW_OSMESA + win->src.rSurf = OSMesaCreateContext(OSMESA_RGBA, NULL); + OSMesaMakeCurrent(win->src.rSurf, win->buffer, GL_UNSIGNED_BYTE, win->r.w, win->r.h); +#endif +#ifdef RGFW_X11 + win->src.bitmap = XCreateImage( + win->src.display, DefaultVisual(win->src.display, XDefaultScreen(win->src.display)), + DefaultDepth(win->src.display, XDefaultScreen(win->src.display)), + ZPixmap, 0, NULL, area.w, area.h, + 32, 0 + ); +#endif +#ifdef RGFW_WINDOWS + BITMAPV5HEADER bi = { 0 }; + ZeroMemory(&bi, sizeof(bi)); + bi.bV5Size = sizeof(bi); + bi.bV5Width = area.w; + bi.bV5Height = -((LONG) area.h); + bi.bV5Planes = 1; + bi.bV5BitCount = 32; + bi.bV5Compression = BI_BITFIELDS; + bi.bV5BlueMask = 0x00ff0000; + bi.bV5GreenMask = 0x0000ff00; + bi.bV5RedMask = 0x000000ff; + bi.bV5AlphaMask = 0xff000000; + + win->src.bitmap = CreateDIBSection(win->src.hdc, + (BITMAPINFO*) &bi, + DIB_RGB_COLORS, + (void**) &win->buffer, + NULL, + (DWORD) 0); + + win->src.hdcMem = CreateCompatibleDC(win->src.hdc); +#endif +#endif + } + +#if defined(RGFW_OPENGL) || defined(RGFW_EGL) || defined(RGFW_OSMESA) +#ifndef __APPLE__ +#include +#else +#include +#endif +#endif + +#ifdef RGFW_VULKAN + RGFW_vulkanInfo RGFW_vulkan_info; + + RGFW_vulkanInfo* RGFW_initVulkan(RGFW_window* win) { + assert(win != NULL); + + if ( + RGFW_initData(win) || + RGFW_deviceInitialization(win) || + RGFW_createSwapchain(win) + ) + return NULL; + + u32 graphics_family_index = 0; + u32 present_family_index = 0; + + vkGetDeviceQueue(RGFW_vulkan_info.device, graphics_family_index, 0, &RGFW_vulkan_info.graphics_queue); + vkGetDeviceQueue(RGFW_vulkan_info.device, present_family_index, 0, &RGFW_vulkan_info.present_queue); + + if ( + RGFW_createRenderPass() || + RGFW_createFramebuffers(win) || + RGFW_createCommandPool() || + RGFW_createCommandBuffers(win) || + RGFW_createSyncObjects(win) + ) + return NULL; + + return &RGFW_vulkan_info; + } + + int RGFW_initData(RGFW_window* win) { + assert(win != NULL); + + win->src.swapchain = VK_NULL_HANDLE; + win->src.image_count = 0; + RGFW_vulkan_info.current_frame = 0; + + return 0; + } + + void RGFW_createSurface(VkInstance instance, RGFW_window* win) { + assert(win != NULL); + assert(instance); + + win->src.rSurf = VK_NULL_HANDLE; + +#ifdef RGFW_X11 + VkXlibSurfaceCreateInfoKHR x11 = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, 0, 0, (Display*) win->src.display, (Window) win->src.window }; + + vkCreateXlibSurfaceKHR(RGFW_vulkan_info.instance, &x11, NULL, &win->src.rSurf); +#endif +#ifdef RGFW_WINDOWS + VkWin32SurfaceCreateInfoKHR win32 = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, 0, 0, GetModuleHandle(NULL), win->src.window }; + + vkCreateWin32SurfaceKHR(RGFW_vulkan_info.instance, &win32, NULL, &win->src.rSurf); +#endif +#if defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11) + VkMacOSSurfaceCreateFlagsMVK macos = { VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, 0, 0, win->src.display, win->src.window }; + + vkCreateMacOSSurfaceMVK(RGFW_vulkan_info.instance, &macos, NULL, &win->src.rSurf); +#endif + } + + RGFW_vulkanInfo* RGFW_getVulkanInfo(void) { + return &RGFW_vulkan_info; + } + + int RGFW_deviceInitialization(RGFW_window* win) { + assert(win != NULL); + + VkApplicationInfo appInfo = { 0 }; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = "RGFW app"; + appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0); + + char* extension = +#ifdef RGFW_WINDOWS + "VK_KHR_win32_surface"; +#elif defined(RGFW_X11) + VK_KHR_XLIB_SURFACE_EXTENSION_NAME; +#elif defined(RGFW_MACOS) + "VK_MVK_macos_surface"; +#else + NULL; +#endif + + VkInstanceCreateInfo instance_create_info = { 0 }; + instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.pApplicationInfo = &appInfo; + instance_create_info.enabledExtensionCount = extension ? 2 : 0, + instance_create_info.ppEnabledExtensionNames = (const char* [2]){ + VK_KHR_SURFACE_EXTENSION_NAME, + extension + }; + + if (vkCreateInstance(&instance_create_info, NULL, &RGFW_vulkan_info.instance) != VK_SUCCESS) { + fprintf(stderr, "failed to create instance!\n"); + return -1; + } + + + RGFW_createSurface(RGFW_vulkan_info.instance, win); + + u32 deviceCount = 0; + vkEnumeratePhysicalDevices(RGFW_vulkan_info.instance, &deviceCount, NULL); + VkPhysicalDevice* devices = (VkPhysicalDevice*) malloc(sizeof(VkPhysicalDevice) * deviceCount); + vkEnumeratePhysicalDevices(RGFW_vulkan_info.instance, &deviceCount, devices); + + RGFW_vulkan_info.physical_device = devices[0]; + + u32 queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(RGFW_vulkan_info.physical_device, &queue_family_count, NULL); + VkQueueFamilyProperties* queueFamilies = (VkQueueFamilyProperties*) malloc(sizeof(VkQueueFamilyProperties) * queue_family_count); + vkGetPhysicalDeviceQueueFamilyProperties(RGFW_vulkan_info.physical_device, &queue_family_count, queueFamilies); + + float queuePriority = 1.0f; + + VkPhysicalDeviceFeatures device_features = { 0 }; + + VkDeviceCreateInfo device_create_info = { 0 }; + device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + VkDeviceQueueCreateInfo queue_create_infos[2] = { + {0}, + {0}, + }; + queue_create_infos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_infos[0].queueCount = 1; + queue_create_infos[0].pQueuePriorities = &queuePriority; + queue_create_infos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_infos[1].queueCount = 1; + queue_create_infos[1].pQueuePriorities = &queuePriority; + device_create_info.queueCreateInfoCount = 2; + device_create_info.pQueueCreateInfos = queue_create_infos; + + device_create_info.enabledExtensionCount = 1; + + const char* device_extensions[] = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; + + device_create_info.ppEnabledExtensionNames = device_extensions; + device_create_info.pEnabledFeatures = &device_features; + + if (vkCreateDevice(RGFW_vulkan_info.physical_device, &device_create_info, NULL, &RGFW_vulkan_info.device) != VK_SUCCESS) { + fprintf(stderr, "failed to create logical device!\n"); + return -1; + } + + return 0; + } + + int RGFW_createSwapchain(RGFW_window* win) { + assert(win != NULL); + + VkSurfaceFormatKHR surfaceFormat = { VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; + VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; + + VkSurfaceCapabilitiesKHR capabilities = { 0 }; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(RGFW_vulkan_info.physical_device, win->src.rSurf, &capabilities); + + win->src.image_count = capabilities.minImageCount + 1; + if (capabilities.maxImageCount > 0 && win->src.image_count > capabilities.maxImageCount) { + win->src.image_count = capabilities.maxImageCount; + } + + VkSwapchainCreateInfoKHR swapchain_create_info = { 0 }; + swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchain_create_info.surface = win->src.rSurf; + swapchain_create_info.minImageCount = win->src.image_count; + swapchain_create_info.imageFormat = surfaceFormat.format; + swapchain_create_info.imageColorSpace = surfaceFormat.colorSpace; + swapchain_create_info.imageExtent = (VkExtent2D){ win->r.w, win->r.h }; + swapchain_create_info.imageArrayLayers = 1; + swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchain_create_info.queueFamilyIndexCount = 2; + swapchain_create_info.preTransform = capabilities.currentTransform; + swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchain_create_info.presentMode = presentMode; + swapchain_create_info.clipped = VK_TRUE; + swapchain_create_info.oldSwapchain = VK_NULL_HANDLE; + + if (vkCreateSwapchainKHR(RGFW_vulkan_info.device, &swapchain_create_info, NULL, &win->src.swapchain) != VK_SUCCESS) { + fprintf(stderr, "failed to create swap chain!\n"); + return -1; + } + + u32 imageCount; + vkGetSwapchainImagesKHR(RGFW_vulkan_info.device, win->src.swapchain, &imageCount, NULL); + win->src.swapchain_images = (VkImage*) malloc(sizeof(VkImage) * imageCount); + vkGetSwapchainImagesKHR(RGFW_vulkan_info.device, win->src.swapchain, &imageCount, win->src.swapchain_images); + + win->src.swapchain_image_views = (VkImageView*) malloc(sizeof(VkImageView) * imageCount); + for (u32 i = 0; i < imageCount; i++) { + VkImageViewCreateInfo image_view_cre_infos = { 0 }; + image_view_cre_infos.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_cre_infos.image = win->src.swapchain_images[i]; + image_view_cre_infos.viewType = VK_IMAGE_VIEW_TYPE_2D; + image_view_cre_infos.format = VK_FORMAT_B8G8R8A8_SRGB; + image_view_cre_infos.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_cre_infos.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_cre_infos.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_cre_infos.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_cre_infos.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_view_cre_infos.subresourceRange.baseMipLevel = 0; + image_view_cre_infos.subresourceRange.levelCount = 1; + image_view_cre_infos.subresourceRange.baseArrayLayer = 0; + image_view_cre_infos.subresourceRange.layerCount = 1; + if (vkCreateImageView(RGFW_vulkan_info.device, &image_view_cre_infos, NULL, &win->src.swapchain_image_views[i]) != VK_SUCCESS) { + fprintf(stderr, "failed to create image views!"); + return -1; + } + } + + return 0; + } + + int RGFW_createRenderPass(void) { + VkAttachmentDescription color_attachment = { 0 }; + color_attachment.format = VK_FORMAT_B8G8R8A8_SRGB; + color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + VkAttachmentReference color_attachment_ref = { 0 }; + color_attachment_ref.attachment = 0; + color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = { 0 }; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_attachment_ref; + + VkSubpassDependency dependency = { 0 }; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + VkRenderPassCreateInfo render_pass_info = { 0 }; + render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info.attachmentCount = 1; + render_pass_info.pAttachments = &color_attachment; + render_pass_info.subpassCount = 1; + render_pass_info.pSubpasses = &subpass; + render_pass_info.dependencyCount = 1; + render_pass_info.pDependencies = &dependency; + + if (vkCreateRenderPass(RGFW_vulkan_info.device, &render_pass_info, NULL, &RGFW_vulkan_info.render_pass) != VK_SUCCESS) { + fprintf(stderr, "failed to create render pass\n"); + return -1; // failed to create render pass! + } + return 0; + } + + int RGFW_createCommandPool(void) { + VkCommandPoolCreateInfo pool_info = { 0 }; + pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + pool_info.queueFamilyIndex = 0; + + if (vkCreateCommandPool(RGFW_vulkan_info.device, &pool_info, NULL, &RGFW_vulkan_info.command_pool) != VK_SUCCESS) { + fprintf(stderr, "failed to create command pool\n"); + return -1; // failed to create command pool + } + return 0; + } + + int RGFW_createCommandBuffers(RGFW_window* win) { + assert(win != NULL); + + RGFW_vulkan_info.command_buffers = (VkCommandBuffer*) malloc(sizeof(VkCommandBuffer) * win->src.image_count); + + VkCommandBufferAllocateInfo allocInfo = { 0 }; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.commandPool = RGFW_vulkan_info.command_pool; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandBufferCount = (u32) win->src.image_count; + + if (vkAllocateCommandBuffers(RGFW_vulkan_info.device, &allocInfo, RGFW_vulkan_info.command_buffers) != VK_SUCCESS) { + return -1; // failed to allocate command buffers; + } + + return 0; + } + + int RGFW_createSyncObjects(RGFW_window* win) { + assert(win != NULL); + + RGFW_vulkan_info.available_semaphores = (VkSemaphore*) malloc(sizeof(VkSemaphore) * RGFW_MAX_FRAMES_IN_FLIGHT); + RGFW_vulkan_info.finished_semaphore = (VkSemaphore*) malloc(sizeof(VkSemaphore) * RGFW_MAX_FRAMES_IN_FLIGHT); + RGFW_vulkan_info.in_flight_fences = (VkFence*) malloc(sizeof(VkFence) * RGFW_MAX_FRAMES_IN_FLIGHT); + RGFW_vulkan_info.image_in_flight = (VkFence*) malloc(sizeof(VkFence) * win->src.image_count); + + VkSemaphoreCreateInfo semaphore_info = { 0 }; + semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + VkFenceCreateInfo fence_info = { 0 }; + fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + for (size_t i = 0; i < RGFW_MAX_FRAMES_IN_FLIGHT; i++) { + if (vkCreateSemaphore(RGFW_vulkan_info.device, &semaphore_info, NULL, &RGFW_vulkan_info.available_semaphores[i]) != VK_SUCCESS || + vkCreateSemaphore(RGFW_vulkan_info.device, &semaphore_info, NULL, &RGFW_vulkan_info.finished_semaphore[i]) != VK_SUCCESS || + vkCreateFence(RGFW_vulkan_info.device, &fence_info, NULL, &RGFW_vulkan_info.in_flight_fences[i]) != VK_SUCCESS) { + fprintf(stderr, "failed to create sync objects\n"); + return -1; // failed to create synchronization objects for a frame + } + } + + for (size_t i = 0; i < win->src.image_count; i++) { + RGFW_vulkan_info.image_in_flight[i] = VK_NULL_HANDLE; + } + + return 0; + } + + int RGFW_createFramebuffers(RGFW_window* win) { + assert(win != NULL); + + RGFW_vulkan_info.framebuffers = (VkFramebuffer*) malloc(sizeof(VkFramebuffer) * win->src.image_count); + + for (size_t i = 0; i < win->src.image_count; i++) { + VkImageView attachments[] = { win->src.swapchain_image_views[i] }; + + VkFramebufferCreateInfo framebuffer_info = { 0 }; + framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_info.renderPass = RGFW_vulkan_info.render_pass; + framebuffer_info.attachmentCount = 1; + framebuffer_info.pAttachments = attachments; + framebuffer_info.width = win->r.w; + framebuffer_info.height = win->r.h; + framebuffer_info.layers = 1; + + if (vkCreateFramebuffer(RGFW_vulkan_info.device, &framebuffer_info, NULL, &RGFW_vulkan_info.framebuffers[i]) != VK_SUCCESS) { + return -1; // failed to create framebuffer + } + } + return 0; + } + + void RGFW_freeVulkan(void) { + vkDeviceWaitIdle(RGFW_vulkan_info.device); + + for (size_t i = 0; i < RGFW_MAX_FRAMES_IN_FLIGHT; i++) { + vkDestroySemaphore(RGFW_vulkan_info.device, RGFW_vulkan_info.finished_semaphore[i], NULL); + vkDestroySemaphore(RGFW_vulkan_info.device, RGFW_vulkan_info.available_semaphores[i], NULL); + vkDestroyFence(RGFW_vulkan_info.device, RGFW_vulkan_info.in_flight_fences[i], NULL); + } + + vkDestroyCommandPool(RGFW_vulkan_info.device, RGFW_vulkan_info.command_pool, NULL); + + vkDestroyPipeline(RGFW_vulkan_info.device, RGFW_vulkan_info.graphics_pipeline, NULL); + vkDestroyPipelineLayout(RGFW_vulkan_info.device, RGFW_vulkan_info.pipeline_layout, NULL); + vkDestroyRenderPass(RGFW_vulkan_info.device, RGFW_vulkan_info.render_pass, NULL); + +#ifdef RGFW_DEBUG + PFN_vkDestroyDebugUtilsMessengerEXT func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(RGFW_vulkan_info.instance, "vkDestroyDebugUtilsMessengerEXT"); + if (func != NULL) { + func(RGFW_vulkan_info.instance, RGFW_vulkan_info.debugMessenger, NULL); + } +#endif + + vkDestroyDevice(RGFW_vulkan_info.device, NULL); + vkDestroyInstance(RGFW_vulkan_info.instance, NULL); + + free(RGFW_vulkan_info.framebuffers); + free(RGFW_vulkan_info.command_buffers); + free(RGFW_vulkan_info.available_semaphores); + free(RGFW_vulkan_info.finished_semaphore); + free(RGFW_vulkan_info.in_flight_fences); + free(RGFW_vulkan_info.image_in_flight); + } + +#endif /* RGFW_VULKAN */ + + RGFW_window* RGFW_root = NULL; + +#ifdef RGFW_X11 +#include +#ifndef RGFW_NO_X11_CURSOR +#include +#endif +#include + +#ifndef RGFW_NO_DPI +#include +#include +#endif +#endif + +#define RGFW_MOUSE_CHANGED (1L<<1) /*!< mouse change (for winargs)*/ +#define RGFW_HOLD_MOUSE (1L<<2) /*!< hold the moues still */ + +#ifdef RGFW_WINDOWS +#include +#include +#include +#include +#include +#include +#endif + +#if defined(RGFW_MACOS) + u8 RGFW_keyMap[128] = { 0 }; +#endif + + char* RGFW_keyCodeTokeyStr(u64 key) { +#if defined(RGFW_MACOS) + static char* keyStrs[128] = { "a", "s", "d", "f", "h", "g", "z", "x", "c", "v", "0", "b", "q", "w", "e", "r", "y", "t", "1", "2", "3", "4", "6", "5", "Equals", "9", "7", "Minus", "8", "0", "CloseBracket", "o", "u", "Bracket", "i", "p", "Return", "l", "j", "Apostrophe", "k", "Semicolon", "BackSlash", "Comma", "Slash", "n", "m", "Period", "Tab", "Space", "Backtick", "BackSpace", "0", "Escape", "0", "Super", "Shift", "CapsLock", "Alt", "Control", "0", "0", "0", "0", "0", "KP_Period", "0", "KP_Minus", "0", "0", "0", "0", "Numlock", "0", "0", "0", "KP_Multiply", "KP_Return", "0", "0", "0", "0", "KP_Slash", "KP_0", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "0", "KP_8", "KP_9", "0", "0", "0", "F5", "F6", "F7", "F3", "F8", "F9", "0", "F11", "0", "F13", "0", "F14", "0", "F10", "0", "F12", "0", "F15", "Insert", "Home", "PageUp", "Delete", "F4", "End", "F2", "PageDown", "Left", "Right", "Down", "Up", "F1" }; + + return keyStrs[key]; +#endif +#ifdef RGFW_X11 + return XKeysymToString(key); +#endif +#ifdef RGFW_WINDOWS + static char keyName[16]; + GetKeyNameTextA((LONG) key, keyName, 16); + + if ((!(GetKeyState(VK_CAPITAL) & 0x0001) && !(GetKeyState(VK_SHIFT) & 0x8000)) || + ((GetKeyState(VK_CAPITAL) & 0x0001) && (GetKeyState(VK_SHIFT) & 0x8000))) { + CharLowerBuffA(keyName, 16); + } + + return keyName; +#endif + } + + u32 RGFW_keyStrToKeyCode(char* key) { +#if defined(RGFW_MACOS) + static char* keyStrs[128] = { "a", "s", "d", "f", "h", "g", "z", "x", "c", "v", "0", "b", "q", "w", "e", "r", "y", "t", "1", "2", "3", "4", "6", "5", "Equals", "9", "7", "Minus", "8", "0", "CloseBracket", "o", "u", "Bracket", "i", "p", "Return", "l", "j", "Apostrophe", "k", "Semicolon", "BackSlash", "Comma", "Slash", "n", "m", "Period", "Tab", "Space", "Backtick", "BackSpace", "0", "Escape", "0", "Super", "Shift", "CapsLock", "Alt", "Control", "0", "0", "0", "0", "0", "KP_Period", "0", "KP_Minus", "0", "0", "0", "0", "Numlock", "0", "0", "0", "KP_Multiply", "KP_Return", "0", "0", "0", "0", "KP_Slash", "KP_0", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "0", "KP_8", "KP_9", "0", "0", "0", "F5", "F6", "F7", "F3", "F8", "F9", "0", "F11", "0", "F13", "0", "F14", "0", "F10", "0", "F12", "0", "F15", "Insert", "Home", "PageUp", "Delete", "F4", "End", "F2", "PageDown", "Left", "Right", "Down", "Up", "F1" }; + + key--; + while (key++) { + u32 i; + for (i = 0; i < 128; i++) { + if (*keyStrs[i] == '\1') + continue; + + if (*keyStrs[i] != *key) { + keyStrs[i] = "\1"; + continue; + } + + if (*keyStrs[i] == '\0' && *key == '\0') + return i; + + else + keyStrs[i]++; + } + + if (*key == '\0') + break; + } + +#endif +#ifdef RGFW_X11 + if (strcmp(key, "Space") == 0) key = (char*) "space"; + + return XStringToKeysym(key); +#endif +#ifdef RGFW_WINDOWS + if (key[1]) { + struct { char* key; i32 code; } keyStrs[] = { + {"Super_L", VK_LWIN}, + {"Super_R", VK_RWIN}, + {"Space", VK_SPACE}, + {"Return", VK_RETURN}, + {"Caps_Lock", VK_CAPITAL}, + {"Tab", VK_TAB}, + {"Right", VK_RIGHT}, + {"Left", VK_LEFT}, + {"Up", VK_UP}, + {"Down", VK_DOWN}, + {"ShiftL", VK_LSHIFT}, + {"ShiftR", VK_RSHIFT}, + {"ControlL", VK_RCONTROL}, + {"ControlR", VK_RCONTROL} + }; + + + while (key++) { + u32 i; + for (i = 0; i < 14; i++) { + if (*keyStrs[i].key != '\0' && *keyStrs[i].key != '\1') + keyStrs[i].key++; + + if (*keyStrs[i].key != *key) { + keyStrs[i].key = "\1"; + continue; + } + + if (*keyStrs[i].key == '\0' && *key == '\0') + return keyStrs[i].code; + } + + if (*key == '\0') + break; + } + } + + i32 vKey = VkKeyScan(key[0]); + + return vKey; +#endif /* RGFW_WINDOWS */ + + return 0; + } + + + char RGFW_keystrToChar(const char* str) { + if (str[1] == 0) + return str[0]; + + static const char* map[] = { + "asciitilde", "`", + "grave", "~", + "exclam", "!", + "at", "@", + "numbersign", "#", + "dollar", "$", + "percent", "%%", + "asciicircum", "^", + "ampersand", "&", + "asterisk", "*", + "parenleft", "(", + "parenright", ")", + "underscore", "_", + "minus", "-", + "plus", "+", + "equal", "=", + "braceleft", "{", + "bracketleft", "[", + "bracketright", "]", + "braceright", "}", + "colon", ":", + "semicolon", ";", + "quotedbl", "\"", + "apostrophe", "'", + "bar", "|", + "backslash", "\'", + "less", "<", + "comma", ",", + "greater", ">", + "period", ".", + "question", "?", + "slash", "/", + "space", " ", + "Return", "\n", + "Enter", "\n", + "enter", "\n", + }; + + u8 i = 0; + for (i = 0; i < (sizeof(map) / sizeof(char*)); i += 2) + if (strcmp(map[i], str) == 0) + return *map[i + 1]; + + return '\0'; + } + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + + typedef struct RGFW_Timespec { + time_t tv_sec; /* Seconds. */ + u32 tv_nsec; /* Nanoseconds. */ + } RGFW_Timespec; /*time struct for fps functions*/ + +#ifndef RGFW_WINDOWS + u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { return win->src.jsPressed[c][button]; } +#else + + typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*); + PFN_XInputGetState XInputGetStateSRC = NULL; + #define XInputGetState XInputGetStateSRC + static HMODULE RGFW_XInput_dll = NULL; + + u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { + XINPUT_STATE state; + if (XInputGetState == NULL || XInputGetState(c, &state) == ERROR_DEVICE_NOT_CONNECTED) + return 0; + + if (button == RGFW_JS_A) return state.Gamepad.wButtons & XINPUT_GAMEPAD_A; + else if (button == RGFW_JS_B) return state.Gamepad.wButtons & XINPUT_GAMEPAD_B; + else if (button == RGFW_JS_Y) return state.Gamepad.wButtons & XINPUT_GAMEPAD_Y; + else if (button == RGFW_JS_X) return state.Gamepad.wButtons & XINPUT_GAMEPAD_X; + else if (button == RGFW_JS_START) return state.Gamepad.wButtons & XINPUT_GAMEPAD_START; + else if (button == RGFW_JS_SELECT) return state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK; + else if (button == RGFW_JS_UP) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP; + else if (button == RGFW_JS_DOWN) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN; + else if (button == RGFW_JS_LEFT) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT; + else if (button == RGFW_JS_RIGHT) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT; + else if (button == RGFW_JS_L1) return state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER; + else if (button == RGFW_JS_R1) return state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER; + else if (button == RGFW_JS_L2 && state.Gamepad.bLeftTrigger) return 1; + else if (button == RGFW_JS_R2 && state.Gamepad.bRightTrigger) return 1; + + return 0; + } +#endif + +#ifdef RGFW_OPENGL + i32 RGFW_majorVersion = 0, RGFW_minorVersion = 0; + i32 RGFW_STENCIL = 8, RGFW_SAMPLES = 4, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0; + + void RGFW_setGLStencil(i32 stencil) { RGFW_STENCIL = stencil; } + void RGFW_setGLSamples(i32 samples) { RGFW_SAMPLES = samples; } + void RGFW_setGLStereo(i32 stereo) { RGFW_STEREO = stereo; } + void RGFW_setGLAuxBuffers(i32 auxBuffers) { RGFW_AUX_BUFFERS = auxBuffers; } + + void RGFW_setGLVersion(i32 major, i32 minor) { + RGFW_majorVersion = major; + RGFW_minorVersion = minor; + } + + u8* RGFW_getMaxGLVersion() { + RGFW_window* dummy = RGFW_createWindow("dummy", RGFW_RECT(0, 0, 1, 1), 0); + + const char* versionStr = (const char*) glGetString(GL_VERSION); + + static u8 version[2]; + version[0] = versionStr[0] - '0', + version[1] = versionStr[2] - '0'; + + RGFW_window_close(dummy); + + return version; + } + +#define RGFW_GL_RENDER_TYPE RGFW_OS_BASED_VALUE(GLX_X_VISUAL_TYPE, 0x2003, 73) +#define RGFW_GL_ALPHA_SIZE RGFW_OS_BASED_VALUE(GLX_ALPHA_SIZE, 0x201b, 11) +#define RGFW_GL_DEPTH_SIZE RGFW_OS_BASED_VALUE(GLX_DEPTH_SIZE, 0x2022, 12) +#define RGFW_GL_DOUBLEBUFFER RGFW_OS_BASED_VALUE(GLX_DOUBLEBUFFER, 0x2011, 5) +#define RGFW_GL_STENCIL_SIZE RGFW_OS_BASED_VALUE(GLX_STENCIL_SIZE, 0x2023, 13) +#define RGFW_GL_SAMPLES RGFW_OS_BASED_VALUE(GLX_SAMPLES, 0x2042, 55) +#define RGFW_GL_STEREO RGFW_OS_BASED_VALUE(GLX_STEREO, 0x2012, 6) +#define RGFW_GL_AUX_BUFFERS RGFW_OS_BASED_VALUE(GLX_AUX_BUFFERS, 0x2024, 7) + +#if defined(RGFW_X11) || defined(RGFW_WINDOWS) +#define RGFW_GL_DRAW RGFW_OS_BASED_VALUE(GLX_X_RENDERABLE, 0x2001, 0) +#define RGFW_GL_DRAW_TYPE RGFW_OS_BASED_VALUE(GLX_RENDER_TYPE, 0x2013, 0) +#define RGFW_GL_USE_OPENGL RGFW_OS_BASED_VALUE(GLX_USE_GL, 0x2010, 0) +#define RGFW_GL_FULL_FORMAT RGFW_OS_BASED_VALUE(GLX_TRUE_COLOR, 0x2027, 0) +#define RGFW_GL_RED_SIZE RGFW_OS_BASED_VALUE(GLX_RED_SIZE, 0x2015, 0) +#define RGFW_GL_GREEN_SIZE RGFW_OS_BASED_VALUE(GLX_GREEN_SIZE, 0x2017, 0) +#define RGFW_GL_BLUE_SIZE RGFW_OS_BASED_VALUE(GLX_BLUE_SIZE, 0x2019, 0) +#define RGFW_GL_USE_RGBA RGFW_OS_BASED_VALUE(GLX_RGBA_BIT, 0x202B, 0) +#endif + +#ifdef RGFW_WINDOWS +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9 +#endif + + static u32* RGFW_initAttribs(u32 useSoftware) { + static u32 attribs[] = { + #ifndef RGFW_MACOS + RGFW_GL_RENDER_TYPE, + RGFW_GL_FULL_FORMAT, + #endif + RGFW_GL_ALPHA_SIZE , 8, + RGFW_GL_DEPTH_SIZE , 24, + RGFW_GL_DOUBLEBUFFER , + #ifndef RGFW_MACOS + 1, + #endif + + #if defined(RGFW_X11) || defined(RGFW_WINDOWS) + RGFW_GL_USE_OPENGL, 1, + RGFW_GL_DRAW, 1, + RGFW_GL_RED_SIZE , 8, + RGFW_GL_GREEN_SIZE , 8, + RGFW_GL_BLUE_SIZE , 8, + RGFW_GL_DRAW_TYPE , RGFW_GL_USE_RGBA, + #endif + + #ifdef RGFW_X11 + GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, + #endif + + #ifdef RGFW_MACOS + 72, + 8, 24, + #endif + + #ifdef RGFW_WINDOWS + WGL_COLOR_BITS_ARB, 32, + #endif + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + size_t index = (sizeof(attribs) / sizeof(attribs[0])) - 13; + +#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \ + if (attVal) { \ + attribs[index] = attrib;\ + attribs[index + 1] = attVal;\ + index += 2;\ + } + + RGFW_GL_ADD_ATTRIB(RGFW_GL_STENCIL_SIZE, RGFW_STENCIL); + RGFW_GL_ADD_ATTRIB(RGFW_GL_STEREO, RGFW_STEREO); + RGFW_GL_ADD_ATTRIB(RGFW_GL_AUX_BUFFERS, RGFW_AUX_BUFFERS); + +#ifndef RGFW_X11 + RGFW_GL_ADD_ATTRIB(RGFW_GL_SAMPLES, RGFW_SAMPLES); +#endif + +#ifdef RGFW_MACOS + if (useSoftware) { + RGFW_GL_ADD_ATTRIB(70, kCGLRendererGenericFloatID); + } else { + attribs[index] = RGFW_GL_RENDER_TYPE; + index += 1; + } +#endif + +#ifdef RGFW_MACOS + attribs[index] = 99; + attribs[index + 1] = 0x1000; + + if (RGFW_majorVersion >= 4 || RGFW_majorVersion >= 3) { + attribs[index + 1] = (u32) ((RGFW_majorVersion >= 4) ? 0x4100 : 0x3200); + } + +#endif + + RGFW_GL_ADD_ATTRIB(0, 0); + + return attribs; + } + +#endif + +#ifdef RGFW_EGL + +#if defined(RGFW_LINK_EGL) + typedef EGLBoolean(EGLAPIENTRY* PFN_eglInitialize)(EGLDisplay, EGLint*, EGLint*); + + PFNEGLINITIALIZEPROC eglInitializeSource; + PFNEGLGETCONFIGSPROC eglGetConfigsSource; + PFNEGLCHOOSECONFIGPROC eglChooseConfigSource; + PFNEGLCREATEWINDOWSURFACEPROC eglCreateWindowSurfaceSource; + PFNEGLCREATECONTEXTPROC eglCreateContextSource; + PFNEGLMAKECURRENTPROC eglMakeCurrentSource; + PFNEGLGETDISPLAYPROC eglGetDisplaySource; + PFNEGLSWAPBUFFERSPROC eglSwapBuffersSource; + PFNEGLSWAPINTERVALPROC eglSwapIntervalSource; + PFNEGLBINDAPIPROC eglBindAPISource; + PFNEGLDESTROYCONTEXTPROC eglDestroyContextSource; + PFNEGLTERMINATEPROC eglTerminateSource; + PFNEGLDESTROYSURFACEPROC eglDestroySurfaceSource; + +#define eglInitialize eglInitializeSource +#define eglGetConfigs eglGetConfigsSource +#define eglChooseConfig eglChooseConfigSource +#define eglCreateWindowSurface eglCreateWindowSurfaceSource +#define eglCreateContext eglCreateContextSource +#define eglMakeCurrent eglMakeCurrentSource +#define eglGetDisplay eglGetDisplaySource +#define eglSwapBuffers eglSwapBuffersSource +#define eglSwapInterval eglSwapIntervalSource +#define eglBindAPI eglBindAPISource +#define eglDestroyContext eglDestroyContextSource +#define eglTerminate eglTerminateSource +#define eglDestroySurface eglDestroySurfaceSource; +#endif + + +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb + +#ifndef RGFW_GL_ADD_ATTRIB +#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \ + if (attVal) { \ + attribs[index] = attrib;\ + attribs[index + 1] = attVal;\ + index += 2;\ + } +#endif + + void RGFW_createOpenGLContext(RGFW_window* win) { + static EGLContext globalCtx = EGL_NO_CONTEXT; + +#if defined(RGFW_LINK_EGL) + eglInitializeSource = (PFNEGLINITIALIZEPROC) eglGetProcAddress("eglInitialize"); + eglGetConfigsSource = (PFNEGLGETCONFIGSPROC) eglGetProcAddress("eglGetConfigs"); + eglChooseConfigSource = (PFNEGLCHOOSECONFIGPROC) eglGetProcAddress("eglChooseConfig"); + eglCreateWindowSurfaceSource = (PFNEGLCREATEWINDOWSURFACEPROC) eglGetProcAddress("eglCreateWindowSurface"); + eglCreateContextSource = (PFNEGLCREATECONTEXTPROC) eglGetProcAddress("eglCreateContext"); + eglMakeCurrentSource = (PFNEGLMAKECURRENTPROC) eglGetProcAddress("eglMakeCurrent"); + eglGetDisplaySource = (PFNEGLGETDISPLAYPROC) eglGetProcAddress("eglGetDisplay"); + eglSwapBuffersSource = (PFNEGLSWAPBUFFERSPROC) eglGetProcAddress("eglSwapBuffers"); + eglSwapIntervalSource = (PFNEGLSWAPINTERVALPROC) eglGetProcAddress("eglSwapInterval"); + eglBindAPISource = (PFNEGLBINDAPIPROC) eglGetProcAddress("eglBindAPI"); + eglDestroyContextSource = (PFNEGLDESTROYCONTEXTPROC) eglGetProcAddress("eglDestroyContext"); + eglTerminateSource = (PFNEGLTERMINATEPROC) eglGetProcAddress("eglTerminate"); + eglDestroySurfaceSource = (PFNEGLDESTROYSURFACEPROC) eglGetProcAddress("eglDestroySurface"); +#endif /* RGFW_LINK_EGL */ + + win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display); + + EGLint major, minor; + + eglInitialize(win->src.EGL_display, &major, &minor); + + EGLint config_attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, + #ifdef RGFW_OPENGL_ES1 + EGL_OPENGL_ES1_BIT, + #endif + #ifdef RGFW_OPENGL_ES2 + EGL_OPENGL_ES2_BIT, + #else + EGL_OPENGL_BIT, + #endif + EGL_NONE + }; + + EGLConfig config; + EGLint num_configs; + eglChooseConfig(win->src.EGL_display, config_attribs, &config, 1, &num_configs); + +#if defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES1) + eglBindAPI(EGL_OPENGL_ES_API); +#else + eglBindAPI(EGL_OPENGL_API); +#endif + + EGLint attribs[]{ + EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT, + 0, 0, 0, 0 + }; + + size_t index = 2; + RGFW_GL_ADD_ATTRIB(EGL_STENCIL_SIZE, RGFW_STENCIL); + RGFW_GL_ADD_ATTRIB(EGL_SAMPLES, RGFW_SAMPLES); + RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MAJOR_VERSION, RGFW_majorVersion); + RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MINOR_VERSION, RGFW_minorVersion); + + win->src.rSurf = eglCreateContext(win->src.EGL_display, config, globalCtx, attribs); + win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL); + + if (globalCtx == EGL_NO_CONTEXT) + RGFW_EGLglobalContext = win->src.rSurf; + + eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.rSurf); + eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface); + + eglSwapInterval(win->src.EGL_display, 1); + } + + void* RGFW_getProcAddress(const char* procname) { return (void*) eglGetProcAddress(procname); } + + void RGFW_closeEGL(RGFW_window* win) { + eglDestroySurface(win->src.EGL_display, win->src.EGL_surface); + eglDestroyContext(win->src.EGL_display, win->src.rSurf); + + eglTerminate(win->src.EGL_display); + } + +#endif /* RGFW_EGL */ + + /* + This is where OS specific stuff starts + */ + +#ifdef RGFW_X11 +#include +#include +#include +#include + +#include /* for converting keycode to string */ +#include /* for hiding */ + +#include /* for data limits (mainly used in drag and drop functions) */ +#include + +#ifdef __linux__ +#include +#endif + + /*atoms needed for drag and drop*/ + Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk, XdndActionPrivate; + + Atom wm_delete_window = 0; + +#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD) + typedef XcursorImage* (*PFN_XcursorImageCreate)(int, int); + typedef void (*PFN_XcursorImageDestroy)(XcursorImage*); + typedef Cursor(*PFN_XcursorImageLoadCursor)(Display*, const XcursorImage*); +#endif +#ifdef RGFW_OPENGL + typedef GLXContext(*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); +#endif + +#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD) + PFN_XcursorImageLoadCursor XcursorImageLoadCursorSrc = NULL; + PFN_XcursorImageCreate XcursorImageCreateSrc = NULL; + PFN_XcursorImageDestroy XcursorImageDestroySrc = NULL; + +#define XcursorImageLoadCursor XcursorImageLoadCursorSrc +#define XcursorImageCreate XcursorImageCreateSrc +#define XcursorImageDestroy XcursorImageDestroySrc + + void* X11Cursorhandle = NULL; +#endif + + u32 RGFW_windowsOpen = 0; + +#ifdef RGFW_OPENGL + void* RGFW_getProcAddress(const char* procname) { return (void*) glXGetProcAddress((GLubyte*) procname); } +#endif + + RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) { +#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD) + if (X11Cursorhandle == NULL) { +#if defined(__CYGWIN__) + X11Cursorhandle = dlopen("libXcursor-1.so", RTLD_LAZY | RTLD_LOCAL); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + X11Cursorhandle = dlopen("libXcursor.so", RTLD_LAZY | RTLD_LOCAL); +#else + X11Cursorhandle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_LOCAL); +#endif + + XcursorImageCreateSrc = (PFN_XcursorImageCreate) dlsym(X11Cursorhandle, "XcursorImageCreate"); + XcursorImageDestroySrc = (PFN_XcursorImageDestroy) dlsym(X11Cursorhandle, "XcursorImageDestroy"); + XcursorImageLoadCursorSrc = (PFN_XcursorImageLoadCursor) dlsym(X11Cursorhandle, "XcursorImageLoadCursor"); + } +#endif + + XInitThreads(); /* init X11 threading*/ + + if (args & RGFW_OPENGL_SOFTWARE) + setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1); + + RGFW_window* win = RGFW_window_basic_init(rect, args); + + u64 event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | FocusChangeMask; /* X11 events accepted*/ + +#ifdef RGFW_OPENGL + u32* visual_attribs = RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE); + i32 fbcount; + GLXFBConfig* fbc = glXChooseFBConfig((Display*) win->src.display, DefaultScreen(win->src.display), (i32*) visual_attribs, &fbcount); + + i32 best_fbc = -1; + + if (fbcount == 0) { + printf("Failed to find any valid GLX configs\n"); + return NULL; + } + + u32 i; + for (i = 0; i < fbcount; i++) { + XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, fbc[i]); + if (vi == NULL) + continue; + + XFree(vi); + + i32 samp_buf, samples; + glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); + glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLES, &samples); + if ((best_fbc < 0 || samp_buf) && (samples == RGFW_SAMPLES)) + best_fbc = i; + } + + if (best_fbc == -1) { + printf("Failed to get a valid GLX visual\n"); + return NULL; + } + + GLXFBConfig bestFbc = fbc[best_fbc]; + + /* Get a visual */ + XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, bestFbc); + + XFree(fbc); + + u32 valuemask = CWBorderPixel | CWColormap; +#else + XVisualInfo* vi = (XVisualInfo*) malloc(sizeof(XVisualInfo)); + vi->screen = DefaultScreen((Display*) win->src.display); + vi->visual = DefaultVisual((Display*) win->src.display, vi->screen); + + vi->depth = 0; + u32 valuemask = 0; +#endif + + /* make X window attrubutes*/ + XSetWindowAttributes swa; + Colormap cmap; + + swa.colormap = cmap = XCreateColormap((Display*) win->src.display, + RootWindow(win->src.display, vi->screen), + vi->visual, AllocNone); + + swa.background_pixmap = None; + swa.border_pixel = 0; + swa.event_mask = event_mask; + + /* create the window*/ + win->src.window = XCreateWindow((Display*) win->src.display, RootWindow((Display*) win->src.display, vi->screen), win->r.x, win->r.y, win->r.w, win->r.h, + 0, vi->depth, InputOutput, vi->visual, + valuemask | CWEventMask, &swa); + + + XFreeColors((Display*) win->src.display, cmap, NULL, 0, 0); + if (args & RGFW_TRANSPARENT_WINDOW) + XMatchVisualInfo((Display*) win->src.display, DefaultScreen((Display*) win->src.display), 32, TrueColor, vi); /* for RGBA backgrounds*/ + + XFree(vi); + +#ifdef RGFW_OPENGL + i32 context_attribs[7] = { 0, 0, 0, 0, 0, 0, 0 }; + context_attribs[0] = GLX_CONTEXT_PROFILE_MASK_ARB; + context_attribs[1] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + + if (RGFW_majorVersion || RGFW_minorVersion) { + context_attribs[2] = GLX_CONTEXT_MAJOR_VERSION_ARB; + context_attribs[3] = RGFW_majorVersion; + context_attribs[4] = GLX_CONTEXT_MINOR_VERSION_ARB; + context_attribs[5] = RGFW_minorVersion; + } + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) + glXGetProcAddressARB((GLubyte*) "glXCreateContextAttribsARB"); + + GLXContext ctx = NULL; + + if (RGFW_root != NULL) + ctx = RGFW_root->src.rSurf; + + win->src.rSurf = glXCreateContextAttribsARB((Display*) win->src.display, bestFbc, ctx, True, context_attribs); +#endif + +#ifdef RGFW_EGL + RGFW_createOpenGLContext(win); +#endif + + if (RGFW_root == NULL) + RGFW_root = win; + + RGFW_init_buffer(win); + +#ifdef RGFW_VULKAN + RGFW_initVulkan(win); +#endif + + if (args & RGFW_SCALE_TO_MONITOR) + RGFW_window_scaleToMonitor(win); + + if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/ + XSizeHints* sh = XAllocSizeHints(); + sh->flags = (1L << 4) | (1L << 5); + sh->min_width = sh->max_width = win->r.w; + sh->min_height = sh->max_height = win->r.h; + + XSetWMSizeHints((Display*) win->src.display, (Drawable) win->src.window, sh, XA_WM_NORMAL_HINTS); + XFree(sh); + } + + if (args & RGFW_NO_BORDER) { + /* Atom vars for no-border*/ + static Atom window_type = 0; + static Atom value = 0; + + if (window_type == 0) { + window_type = XInternAtom((Display*) win->src.display, "_NET_WM_WINDOW_TYPE", False); + value = XInternAtom((Display*) win->src.display, "_NET_WM_WINDOW_TYPE_DOCK", False); + } + + XChangeProperty((Display*) win->src.display, (Drawable) win->src.window, window_type, XA_ATOM, 32, PropModeReplace, (u8*) &value, 1); /* toggle border*/ + } + + XSelectInput((Display*) win->src.display, (Drawable) win->src.window, event_mask); /* tell X11 what events we want*/ + + /* make it so the user can't close the window until the program does*/ + if (wm_delete_window == 0) + wm_delete_window = XInternAtom((Display*) win->src.display, "WM_DELETE_WINDOW", 1); + + XSetWMProtocols((Display*) win->src.display, (Drawable) win->src.window, &wm_delete_window, 1); + + /* connect the context to the window*/ +#ifdef RGFW_OPENGL + glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.rSurf); +#endif + + /* set the background*/ + XStoreName((Display*) win->src.display, (Drawable) win->src.window, name); /* set the name*/ + + XMapWindow((Display*) win->src.display, (Drawable) win->src.window); /* draw the window*/ + XMoveWindow((Display*) win->src.display, (Drawable) win->src.window, win->r.x, win->r.y); /* move the window to it's proper cords*/ + + if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */ + win->src.winArgs |= RGFW_ALLOW_DND; + + XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False); + XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False); + XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False); + + /* client messages */ + XdndEnter = XInternAtom((Display*) win->src.display, "XdndEnter", False); + XdndPosition = XInternAtom((Display*) win->src.display, "XdndPosition", False); + XdndStatus = XInternAtom((Display*) win->src.display, "XdndStatus", False); + XdndLeave = XInternAtom((Display*) win->src.display, "XdndLeave", False); + XdndDrop = XInternAtom((Display*) win->src.display, "XdndDrop", False); + XdndFinished = XInternAtom((Display*) win->src.display, "XdndFinished", False); + + /* actions */ + XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False); + XdndActionMove = XInternAtom((Display*) win->src.display, "XdndActionMove", False); + XdndActionLink = XInternAtom((Display*) win->src.display, "XdndActionLink", False); + XdndActionAsk = XInternAtom((Display*) win->src.display, "XdndActionAsk", False); + XdndActionPrivate = XInternAtom((Display*) win->src.display, "XdndActionPrivate", False); + const Atom version = 5; + + XChangeProperty((Display*) win->src.display, (Window) win->src.window, + XdndAware, 4, 32, + PropModeReplace, (u8*) &version, 1); /* turns on drag and drop */ + } + + RGFW_window_setMouseDefault(win); + + RGFW_windowsOpen++; + + return win; /*return newly created window*/ + } + + RGFW_area RGFW_getScreenSize(void) { + assert(RGFW_root != NULL); + + Screen* scrn = DefaultScreenOfDisplay((Display*) RGFW_root->src.display); + return RGFW_AREA(scrn->width, scrn->height); + } + + RGFW_vector RGFW_getGlobalMousePoint(void) { + assert(RGFW_root != NULL); + + RGFW_vector RGFWMouse; + + i32 x, y; + u32 z; + Window window1, window2; + XQueryPointer((Display*) RGFW_root->src.display, XDefaultRootWindow((Display*) RGFW_root->src.display), &window1, &window2, &x, &RGFWMouse.x, &RGFWMouse.y, &y, &z); + + return RGFWMouse; + } + + typedef struct XDND { + long source, version; + i32 format; + } XDND; /* data structure for xdnd events */ + XDND xdnd; + + int xAxis = 0, yAxis = 0; + + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { + assert(win != NULL); + + win->event.type = 0; + +#ifdef __linux__ + { + u8 i; + for (i = 0; i < win->src.joystickCount; i++) { + struct js_event e; + + + if (!win->src.joysticks[i]) + continue; + + i32 flags = fcntl(win->src.joysticks[i], F_GETFL, 0); + fcntl(win->src.joysticks[i], F_SETFL, flags | O_NONBLOCK); + + ssize_t bytes; + while ((bytes = read(win->src.joysticks[i], &e, sizeof(e))) > 0) { + switch (e.type) { + case JS_EVENT_BUTTON: + win->event.type = e.value ? RGFW_jsButtonPressed : RGFW_jsButtonReleased; + win->event.button = e.number; + win->src.jsPressed[i][e.number] = e.value; + return &win->event; + case JS_EVENT_AXIS: + ioctl(win->src.joysticks[i], JSIOCGAXES, &win->event.axisesCount); + + if ((e.number == 0 || e.number % 2) && e.number != 1) + xAxis = e.value; + else + yAxis = e.value; + + win->event.axis[e.number / 2].x = xAxis; + win->event.axis[e.number / 2].y = yAxis; + win->event.type = RGFW_jsAxisMove; + win->event.joystick = e.number / 2; + return &win->event; + + default: break; + } + } + } + } +#endif + + XEvent E; /* raw X11 event */ + + /* if there is no unread qued events, get a new one */ + if (XEventsQueued((Display*) win->src.display, QueuedAlready) + XEventsQueued((Display*) win->src.display, QueuedAfterReading) && win->event.type != RGFW_quit) + XNextEvent((Display*) win->src.display, &E); + else { + return NULL; + } + + u32 i; + + if (win->event.droppedFilesCount) { + for (i = 0; i < win->event.droppedFilesCount; i++) + win->event.droppedFiles[i][0] = '\0'; + } + + win->event.droppedFilesCount = 0; + win->event.type = 0; + + + switch (E.type) { + case KeyPress: + case KeyRelease: + /* check if it's a real key release */ + if (E.type == KeyRelease && XEventsQueued((Display*) win->src.display, QueuedAfterReading)) { /* get next event if there is one*/ + XEvent NE; + XPeekEvent((Display*) win->src.display, &NE); + + if (E.xkey.time == NE.xkey.time && E.xkey.keycode == NE.xkey.keycode) /* check if the current and next are both the same*/ + break; + } + + /* set event key data */ + win->event.keyCode = XkbKeycodeToKeysym((Display*) win->src.display, E.xkey.keycode, 0, E.xkey.state & ShiftMask ? 1 : 0); + win->event.keyName = XKeysymToString(win->event.keyCode); /* convert to string */ + + /* get keystate data */ + win->event.type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased; + + if (win->event.type == RGFW_keyReleased) { + if (win->event.keyCode == XK_Caps_Lock && win->event.lockState & RGFW_CAPSLOCK) + win->event.lockState ^= RGFW_CAPSLOCK; + else if (win->event.keyCode == XK_Caps_Lock) + win->event.lockState |= RGFW_CAPSLOCK; + + else if (win->event.keyCode == XK_Num_Lock && win->event.lockState & RGFW_NUMLOCK) + win->event.lockState ^= RGFW_NUMLOCK; + else if (win->event.keyCode == XK_Num_Lock) + win->event.lockState |= RGFW_NUMLOCK; + } + break; + + case ButtonPress: + case ButtonRelease: + win->event.type = (E.type == ButtonPress) ? RGFW_mouseButtonPressed : RGFW_mouseButtonReleased; + + if (win->event.button == RGFW_mouseScrollUp) { + win->event.scroll = 1; + } + else if (win->event.button == RGFW_mouseScrollDown) { + win->event.scroll = -1; + } + + win->event.button = E.xbutton.button; + break; + + case MotionNotify: + win->event.point.x = E.xmotion.x; + win->event.point.y = E.xmotion.y; + win->event.type = RGFW_mousePosChanged; + break; + + case ClientMessage: + /* if the client closed the window*/ + if (E.xclient.data.l[0] == (i64) wm_delete_window) { + win->event.type = RGFW_quit; + break; + } + + /* + much of this event (drag and drop code) is source from glfw + */ + + if ((win->src.winArgs & RGFW_ALLOW_DND) == 0) + break; + + u8 formFree = 0; + if (E.xclient.message_type == XdndEnter) { + u64 count; + Atom* formats = (Atom*) 0; + Bool list = E.xclient.data.l[1] & 1; + + xdnd.source = E.xclient.data.l[0]; + xdnd.version = E.xclient.data.l[1] >> 24; + xdnd.format = None; + + if (xdnd.version > 5) + break; + + if (list) { + Atom actualType; + i32 actualFormat; + u64 bytesAfter; + + XGetWindowProperty((Display*) win->src.display, + xdnd.source, + XdndTypeList, + 0, + LONG_MAX, + False, + 4, + &actualType, + &actualFormat, + &count, + &bytesAfter, + (u8**) &formats); + } else { + formats = (Atom*) RGFW_MALLOC(E.xclient.data.l[2] + E.xclient.data.l[3] + E.xclient.data.l[4]); + formFree = 1; + + count = 0; + + if (E.xclient.data.l[2] != None) + formats[count++] = E.xclient.data.l[2]; + if (E.xclient.data.l[3] != None) + formats[count++] = E.xclient.data.l[3]; + if (E.xclient.data.l[4] != None) + formats[count++] = E.xclient.data.l[4]; + } + + u32 i; + for (i = 0; i < count; i++) { + char* name = XGetAtomName((Display*) win->src.display, formats[i]); + + char* links[2] = { (char*) (const char*) "text/uri-list", (char*) (const char*) "text/plain" }; + for (; 1; name++) { + u32 j; + for (j = 0; j < 2; j++) { + if (*links[j] != *name) { + links[j] = (char*) (const char*) "\1"; + continue; + } + + if (*links[j] == '\0' && *name == '\0') + xdnd.format = formats[i]; + + if (*links[j] != '\0' && *links[j] != '\1') + links[j]++; + } + + if (*name == '\0') + break; + } + } + + if (list && formats) { + XFree(formats); + formats = (Atom*) 0; + } else if (formFree && formats != (Atom*) 0) { + RGFW_FREE(formats); + + formats = (Atom*) 0; + formFree = 1; + } + + break; + } + if (E.xclient.message_type == XdndPosition) { + const i32 xabs = (E.xclient.data.l[2] >> 16) & 0xffff; + const i32 yabs = (E.xclient.data.l[2]) & 0xffff; + Window dummy; + i32 xpos, ypos; + + if (xdnd.version > 5) + break; + + XTranslateCoordinates((Display*) win->src.display, + XDefaultRootWindow((Display*) win->src.display), + (Window) win->src.window, + xabs, yabs, + &xpos, &ypos, + &dummy); + + win->event.point.x = xpos; + win->event.point.y = ypos; + + XEvent reply = { ClientMessage }; + reply.xclient.window = xdnd.source; + reply.xclient.message_type = XdndStatus; + reply.xclient.format = 32; + reply.xclient.data.l[0] = (long) win->src.window; + reply.xclient.data.l[2] = 0; + reply.xclient.data.l[3] = 0; + + if (xdnd.format) { + reply.xclient.data.l[1] = 1; + if (xdnd.version >= 2) + reply.xclient.data.l[4] = XdndActionCopy; + } + + XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply); + XFlush((Display*) win->src.display); + break; + } + + if (E.xclient.message_type != XdndDrop) + break; + + if (xdnd.version > 5) + break; + + win->event.type = RGFW_dnd_init; + + if (xdnd.format) { + Time time = CurrentTime; + + if (xdnd.version >= 1) + time = E.xclient.data.l[2]; + + XConvertSelection((Display*) win->src.display, + XdndSelection, + xdnd.format, + XdndSelection, + (Window) win->src.window, + time); + } else if (xdnd.version >= 2) { + XEvent reply = { ClientMessage }; + reply.xclient.window = xdnd.source; + reply.xclient.message_type = XdndFinished; + reply.xclient.format = 32; + reply.xclient.data.l[0] = (long) win->src.window; + reply.xclient.data.l[1] = 0; + reply.xclient.data.l[2] = None; + + XSendEvent((Display*) win->src.display, xdnd.source, + False, NoEventMask, &reply); + XFlush((Display*) win->src.display); + } + break; + case SelectionNotify: + /* this is only for checking for xdnd drops */ + if (E.xselection.property != XdndSelection || !(win->src.winArgs | RGFW_ALLOW_DND)) + break; + + char* data; + u64 result; + + Atom actualType; + i32 actualFormat; + u64 bytesAfter; + + XGetWindowProperty((Display*) win->src.display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (u8**) &data); + + if (result == 0) + break; + + /* + SOURCED FROM GLFW _glfwParseUriList + Copyright (c) 2002-2006 Marcus Geelnard + Copyright (c) 2006-2019 Camilla Löwy + */ + + const char* prefix = "file://"; + + char* line; + + win->event.droppedFilesCount = 0; + + win->event.type = RGFW_dnd; + + while ((line = strtok(data, "\r\n"))) { + char path[RGFW_MAX_PATH]; + + data = NULL; + + if (line[0] == '#') + continue; + + char* l; + for (l = line; 1; l++) { + if ((l - line) > 7) + break; + else if (*l != prefix[(l - line)]) + break; + else if (*l == '\0' && prefix[(l - line)] == '\0') { + line += 7; + while (*line != '/') + line++; + break; + } else if (*l == '\0') + break; + } + + win->event.droppedFilesCount++; + + size_t index = 0; + while (*line) { + if (line[0] == '%' && line[1] && line[2]) { + const char digits[3] = { line[1], line[2], '\0' }; + path[index] = (char) strtol(digits, NULL, 16); + line += 2; + } else + path[index] = *line; + + index++; + line++; + } + + strcpy(win->event.droppedFiles[win->event.droppedFilesCount - 1], path); + } + + if (data) + XFree(data); + + if (xdnd.version >= 2) { + XEvent reply = { ClientMessage }; + reply.xclient.window = xdnd.source; + reply.xclient.message_type = XdndFinished; + reply.xclient.format = 32; + reply.xclient.data.l[0] = (long) win->src.window; + reply.xclient.data.l[1] = result; + reply.xclient.data.l[2] = XdndActionCopy; + + XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply); + XFlush((Display*) win->src.display); + } + + break; + + case FocusIn: + win->event.inFocus = 1; + + XKeyboardState keystate; + XGetKeyboardControl((Display*) win->src.display, &keystate); + win->event.lockState = keystate.led_mask; + + break; + case FocusOut: + win->event.inFocus = 0; + RGFW_window_setMouseDefault(win); + break; + case ConfigureNotify: { +#ifndef RGFW_NO_X11_WINDOW_ATTRIB + XWindowAttributes a; + XGetWindowAttributes((Display*) win->src.display, (Window) win->src.window, &a); + win->r = RGFW_RECT(E.xconfigure.x, E.xconfigure.y, E.xconfigure.width, E.xconfigure.height); +#endif + + win->event.type = RGFW_windowAttribsChange; + break; + } + default: { + break; + } + } + + if (win->event.inFocus && (win->src.winArgs & RGFW_MOUSE_CHANGED)) { + XDefineCursor((Display*) win->src.display, (Window) win->src.window, (Cursor) win->src.cursor); + + win->src.winArgs &= ~RGFW_MOUSE_CHANGED; + } + + RGFW_vector mouse = RGFW_getGlobalMousePoint(); + if (win->src.winArgs & RGFW_HOLD_MOUSE && win->event.inFocus && win->event.type == RGFW_mousePosChanged) { + RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + + if (XEventsQueued((Display*) win->src.display, QueuedAfterReading) <= 1) + XSync(win->src.display, True); + } + + + XFlush((Display*) win->src.display); + + if (win->event.type) + return &win->event; + else + return NULL; + } + + void RGFW_window_close(RGFW_window* win) { + assert(win != NULL); + +#ifdef RGFW_VULKAN + for (int i = 0; i < win->src.image_count; i++) { + vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL); + } + + vkDestroySwapchainKHR(RGFW_vulkan_info.device, win->src.swapchain, NULL); + vkDestroySurfaceKHR(RGFW_vulkan_info.instance, win->src.rSurf, NULL); + free(win->src.swapchain_image_views); + free(win->src.swapchain_images); +#endif + +#ifdef RGFW_EGL + RGFW_closeEGL(win); +#endif + + XFreeCursor((Display*) win->src.display, (Cursor) win->src.cursor); + +#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER) + if (win->buffer != NULL) { + XDestroyImage((XImage*) win->src.bitmap); + } +#endif + + if ((Display*) win->src.display) { +#ifdef RGFW_OPENGL + glXDestroyContext((Display*) win->src.display, win->src.rSurf); +#endif + + if (win == RGFW_root) + RGFW_root = NULL; + + if ((Drawable) win->src.window) + XDestroyWindow((Display*) win->src.display, (Drawable) win->src.window); /* close the window*/ + + if (win->src.display) + XCloseDisplay((Display*) win->src.display); /* kill the display*/ + } + +#ifdef RGFW_ALLOC_DROPFILES + { + u32 i; + for (i = 0; i < RGFW_MAX_DROPS; i++) + RGFW_FREE(win->event.droppedFiles[i]); + + + RGFW_FREE(win->event.droppedFiles); + } +#endif + + RGFW_windowsOpen--; +#if !defined(RGFW_NO_X11_CURSOR_PRELOAD) && !defined(RGFW_NO_X11_CURSOR) + if (X11Cursorhandle != NULL && RGFW_windowsOpen <= 0) { + dlclose(X11Cursorhandle); + + X11Cursorhandle = NULL; + } +#endif + + /* set cleared display / window to NULL for error checking */ + win->src.display = (Display*) 0; + win->src.window = (Window) 0; + + u8 i; + for (i = 0; i < win->src.joystickCount; i++) + close(win->src.joysticks[i]); + + RGFW_FREE(win); /* free collected window data */ + } + + void RGFW_window_move(RGFW_window* win, RGFW_vector v) { + assert(win != NULL); + win->r.x = v.x; + win->r.y = v.y; + + XMoveWindow((Display*) win->src.display, (Window) win->src.window, v.x, v.y); + } + + + void RGFW_window_resize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + win->r.w = a.w; + win->r.h = a.h; + + XResizeWindow((Display*) win->src.display, (Window) win->src.window, a.w, a.h); + } + + void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + + XSizeHints hints; + long flags; + + XGetWMNormalHints(win->src.display, (Window) win->src.window, &hints, &flags); + + hints.flags |= PMinSize; + + hints.min_width = a.w; + hints.min_height = a.h; + + XSetWMNormalHints(win->src.display, (Window) win->src.window, &hints); + } + + void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + + XSizeHints hints; + long flags; + + XGetWMNormalHints(win->src.display, (Window) win->src.window, &hints, &flags); + + hints.flags |= PMaxSize; + + hints.max_width = a.w; + hints.max_height = a.h; + + XSetWMNormalHints(win->src.display, (Window) win->src.window, &hints); + } + + + void RGFW_window_minimize(RGFW_window* win) { + assert(win != NULL); + + XIconifyWindow(win->src.display, (Window) win->src.window, DefaultScreen(win->src.display)); + XFlush(win->src.display); + } + + void RGFW_window_restore(RGFW_window* win) { + assert(win != NULL); + + XMapWindow(win->src.display, (Window) win->src.window); + XFlush(win->src.display); + } + + void RGFW_window_setName(RGFW_window* win, char* name) { + assert(win != NULL); + + XStoreName((Display*) win->src.display, (Window) win->src.window, name); + } + + /* + the majority function is sourced from GLFW + */ + + void RGFW_window_setIcon(RGFW_window* win, u8* icon, RGFW_area a, i32 channels) { + assert(win != NULL); + + i32 longCount = 2 + a.w * a.h; + + u64* X11Icon = (u64*) RGFW_MALLOC(longCount * sizeof(u64)); + u64* target = X11Icon; + + *target++ = a.w; + *target++ = a.h; + + u32 i; + + for (i = 0; i < a.w * a.h; i++) { + if (channels == 3) + *target++ = ((icon[i * 3 + 0]) << 16) | + ((icon[i * 3 + 1]) << 8) | + ((icon[i * 3 + 2]) << 0) | + (0xFF << 24); + + else if (channels == 4) + *target++ = ((icon[i * 4 + 0]) << 16) | + ((icon[i * 4 + 1]) << 8) | + ((icon[i * 4 + 2]) << 0) | + ((icon[i * 4 + 3]) << 24); + } + + static Atom NET_WM_ICON = 0; + if (NET_WM_ICON == 0) + NET_WM_ICON = XInternAtom((Display*) win->src.display, "_NET_WM_ICON", False); + + XChangeProperty((Display*) win->src.display, (Window) win->src.window, + NET_WM_ICON, + 6, 32, + PropModeReplace, + (u8*) X11Icon, + longCount); + + RGFW_FREE(X11Icon); + + XFlush((Display*) win->src.display); + } + + void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) { + assert(win != NULL); + +#ifndef RGFW_NO_X11_CURSOR + /* free the previous cursor */ + if (win->src.cursor && win->src.cursor != -1) + XFreeCursor((Display*) win->src.display, (Cursor) win->src.cursor); + + XcursorImage* native = XcursorImageCreate(a.w, a.h); + native->xhot = 0; + native->yhot = 0; + + u8* source = (u8*) image; + XcursorPixel* target = native->pixels; + + u32 i; + for (i = 0; i < a.w * a.h; i++, target++, source += 4) { + u8 alpha = 0xFF; + if (channels == 4) + alpha = source[3]; + + *target = (alpha << 24) | (((source[0] * alpha) / 255) << 16) | (((source[1] * alpha) / 255) << 8) | (((source[2] * alpha) / 255) << 0); + } + + win->src.winArgs |= RGFW_MOUSE_CHANGED; + win->src.cursor = XcursorImageLoadCursor((Display*) win->src.display, native); + + XcursorImageDestroy(native); +#endif + } + + void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v) { + assert(win != NULL); + + XEvent event; + XQueryPointer(win->src.display, DefaultRootWindow(win->src.display), + &event.xbutton.root, &event.xbutton.window, + &event.xbutton.x_root, &event.xbutton.y_root, + &event.xbutton.x, &event.xbutton.y, + &event.xbutton.state); + + if (event.xbutton.x == v.x && event.xbutton.y == v.y) + return; + + XWarpPointer(win->src.display, None, None, 0, 0, 0, 0, -event.xbutton.x, -event.xbutton.y); + XWarpPointer(win->src.display, None, None, 0, 0, 0, 0, v.x, v.y); + } + + RGFWDEF void RGFW_window_disableMouse(RGFW_window* win) { + + } + + void RGFW_window_setMouseDefault(RGFW_window* win) { + RGFW_window_setMouseStandard(win, XC_left_ptr); + } + + void RGFW_window_setMouseStandard(RGFW_window* win, i32 mouse) { + assert(win != NULL); + + /* free the previous cursor */ + if (win->src.cursor && win->src.cursor != -1) + XFreeCursor((Display*) win->src.display, (Cursor) win->src.cursor); + + win->src.winArgs |= RGFW_MOUSE_CHANGED; + win->src.cursor = XCreateFontCursor((Display*) win->src.display, mouse); + } + + void RGFW_window_hide(RGFW_window* win) { + XMapWindow(win->src.display, win->src.window); + } + + void RGFW_window_show(RGFW_window* win) { + XUnmapWindow(win->src.display, win->src.window); + } + + /* + the majority function is sourced from GLFW + */ + char* RGFW_readClipboard(size_t* size) { + static Atom UTF8 = 0; + if (UTF8 == 0) + UTF8 = XInternAtom(RGFW_root->src.display, "UTF8_STRING", True); + + XEvent event; + int format; + unsigned long N, sizeN; + char* data, * s = NULL; + Atom target; + Atom CLIPBOARD = 0, XSEL_DATA = 0; + + if (CLIPBOARD == 0) { + CLIPBOARD = XInternAtom(RGFW_root->src.display, "CLIPBOARD", 0); + XSEL_DATA = XInternAtom(RGFW_root->src.display, "XSEL_DATA", 0); + } + + XConvertSelection(RGFW_root->src.display, CLIPBOARD, UTF8, XSEL_DATA, RGFW_root->src.window, CurrentTime); + XSync(RGFW_root->src.display, 0); + XNextEvent(RGFW_root->src.display, &event); + + if (event.type != SelectionNotify || event.xselection.selection != CLIPBOARD || event.xselection.property == 0) + return NULL; + + XGetWindowProperty(event.xselection.display, event.xselection.requestor, + event.xselection.property, 0L, (~0L), 0, AnyPropertyType, &target, + &format, &sizeN, &N, (unsigned char**) &data); + + if (target == UTF8 || target == XA_STRING) { + s = strndup(data, sizeN); + XFree(data); + } + + XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property); + + if (s != NULL && size != NULL) + *size = sizeN; + + return s; + } + + /* + almost all of this function is sourced from GLFW + */ + void RGFW_writeClipboard(const char* text, u32 textLen) { + static Atom CLIPBOARD = 0, + UTF8_STRING = 0, + SAVE_TARGETS = 0, + TARGETS = 0, + MULTIPLE = 0, + ATOM_PAIR = 0, + CLIPBOARD_MANAGER = 0; + + if (CLIPBOARD == 0) { + CLIPBOARD = XInternAtom((Display*) RGFW_root->src.display, "CLIPBOARD", False); + UTF8_STRING = XInternAtom((Display*) RGFW_root->src.display, "UTF8_STRING", False); + SAVE_TARGETS = XInternAtom((Display*) RGFW_root->src.display, "SAVE_TARGETS", False); + TARGETS = XInternAtom((Display*) RGFW_root->src.display, "TARGETS", False); + MULTIPLE = XInternAtom((Display*) RGFW_root->src.display, "MULTIPLE", False); + ATOM_PAIR = XInternAtom((Display*) RGFW_root->src.display, "ATOM_PAIR", False); + CLIPBOARD_MANAGER = XInternAtom((Display*) RGFW_root->src.display, "CLIPBOARD_MANAGER", False); + } + + XSetSelectionOwner((Display*) RGFW_root->src.display, CLIPBOARD, (Window) RGFW_root->src.window, CurrentTime); + + XConvertSelection((Display*) RGFW_root->src.display, CLIPBOARD_MANAGER, SAVE_TARGETS, None, (Window) RGFW_root->src.window, CurrentTime); + + for (;;) { + XEvent event; + + XNextEvent((Display*) RGFW_root->src.display, &event); + if (event.type != SelectionRequest) + return; + + const XSelectionRequestEvent* request = &event.xselectionrequest; + + XEvent reply = { SelectionNotify }; + + char* selectionString = NULL; + const Atom formats[] = { UTF8_STRING, XA_STRING }; + const i32 formatCount = sizeof(formats) / sizeof(formats[0]); + + selectionString = (char*) text; + + if (request->target == TARGETS) { + const Atom targets[] = { TARGETS, + MULTIPLE, + UTF8_STRING, + XA_STRING }; + + XChangeProperty((Display*) RGFW_root->src.display, + request->requestor, + request->property, + 4, + 32, + PropModeReplace, + (u8*) targets, + sizeof(targets) / sizeof(targets[0])); + + reply.xselection.property = request->property; + } + + if (request->target == MULTIPLE) { + + Atom* targets; + + Atom actualType; + i32 actualFormat; + u64 count, bytesAfter; + + XGetWindowProperty((Display*) RGFW_root->src.display, request->requestor, request->property, 0, LONG_MAX, False, ATOM_PAIR, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &targets); + + u64 i; + for (i = 0; i < count; i += 2) { + i32 j; + + for (j = 0; j < formatCount; j++) { + if (targets[i] == formats[j]) + break; + } + + if (j < formatCount) + { + XChangeProperty((Display*) RGFW_root->src.display, + request->requestor, + targets[i + 1], + targets[i], + 8, + PropModeReplace, + (u8*) selectionString, + textLen); + } else + targets[i + 1] = None; + } + + XChangeProperty((Display*) RGFW_root->src.display, + request->requestor, + request->property, + ATOM_PAIR, + 32, + PropModeReplace, + (u8*) targets, + count); + + XFree(targets); + + reply.xselection.property = request->property; + } + + reply.xselection.display = request->display; + reply.xselection.requestor = request->requestor; + reply.xselection.selection = request->selection; + reply.xselection.target = request->target; + reply.xselection.time = request->time; + + XSendEvent((Display*) RGFW_root->src.display, request->requestor, False, 0, &reply); + } + } + + u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { + assert(win != NULL); + +#ifdef __linux__ + char file[15]; + sprintf(file, "/dev/input/js%i", jsNumber); + + return RGFW_registerJoystickF(win, file); +#endif + } + + u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + assert(win != NULL); + +#ifdef __linux__ + + i32 js = open(file, O_RDONLY); + + if (js && win->src.joystickCount < 4) { + win->src.joystickCount++; + + win->src.joysticks[win->src.joystickCount - 1] = open(file, O_RDONLY); + + u8 i; + for (i = 0; i < 16; i++) + win->src.jsPressed[win->src.joystickCount - 1][i] = 0; + + } + + else { +#ifdef RGFW_PRINT_ERRORS + RGFW_error = 1; + fprintf(stderr, "Error RGFW_registerJoystickF : Cannot open file %s\n", file); +#endif + } + + return win->src.joystickCount - 1; +#endif + } + + u8 RGFW_window_isFullscreen(RGFW_window* win) { + assert(win != NULL); + + XWindowAttributes windowAttributes; + XGetWindowAttributes(win->src.display, (Window) win->src.window, &windowAttributes); + + /* check if the window is visable */ + if (windowAttributes.map_state != IsViewable) + return 0; + + /* check if the window covers the full screen */ + return (windowAttributes.x == 0 && windowAttributes.y == 0 && + windowAttributes.width == XDisplayWidth(win->src.display, DefaultScreen(win->src.display)) && + windowAttributes.height == XDisplayHeight(win->src.display, DefaultScreen(win->src.display))); + } + + u8 RGFW_window_isHidden(RGFW_window* win) { + assert(win != NULL); + + XWindowAttributes windowAttributes; + XGetWindowAttributes(win->src.display, (Window) win->src.window, &windowAttributes); + + return (windowAttributes.map_state == IsUnmapped && !RGFW_window_isMinimized(win)); + } + + u8 RGFW_window_isMinimized(RGFW_window* win) { + assert(win != NULL); + + static Atom prop = 0; + if (prop == 0) + prop = XInternAtom(win->src.display, "WM_STATE", False); + + Atom actual_type; + i32 actual_format; + u64 nitems, bytes_after; + unsigned char* prop_data; + + i16 status = XGetWindowProperty(win->src.display, (Window) win->src.window, prop, 0, 2, False, + AnyPropertyType, &actual_type, &actual_format, + &nitems, &bytes_after, &prop_data); + + if (status == Success && nitems >= 1 && *((int*) prop_data) == IconicState) { + XFree(prop_data); + return 1; + } + + if (prop_data != NULL) + XFree(prop_data); + + return 0; + } + + u8 RGFW_window_isMaximized(RGFW_window* win) { + assert(win != NULL); + + static Atom net_wm_state = 0; + static Atom net_wm_state_maximized_horz = 0; + static Atom net_wm_state_maximized_vert = 0; + + if (net_wm_state == 0) { + net_wm_state = XInternAtom(win->src.display, "_NET_WM_STATE", False); + net_wm_state_maximized_vert = XInternAtom(win->src.display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + net_wm_state_maximized_horz = XInternAtom(win->src.display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + } + + Atom actual_type; + i32 actual_format; + u64 nitems, bytes_after; + unsigned char* prop_data; + + i16 status = XGetWindowProperty(win->src.display, (Window) win->src.window, net_wm_state, 0, 1024, False, + XA_ATOM, &actual_type, &actual_format, + &nitems, &bytes_after, &prop_data); + + if (status != Success) { + if (prop_data != NULL) + XFree(prop_data); + + return 0; + } + + Atom* atoms = (Atom*) prop_data; + u64 i; + for (i = 0; i < nitems; ++i) { + if (atoms[i] == net_wm_state_maximized_horz || + atoms[i] == net_wm_state_maximized_vert) { + XFree(prop_data); + return 1; + } + } + + return 0; + } + + static void XGetSystemContentScale(Display* display, float* xscale, float* yscale) { + float xdpi = 96.f, ydpi = 96.f; + +#ifndef RGFW_NO_DPI + char* rms = XResourceManagerString(display); + XrmDatabase db = NULL; + + if (rms && db) + db = XrmGetStringDatabase(rms); + + if (db == 0) { + *xscale = xdpi / 96.f; + *yscale = ydpi / 96.f; + return; + } + + XrmValue value; + char* type = NULL; + + if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value) && type && strcmp(type, "String") == 0) + xdpi = ydpi = atof(value.addr); + XrmDestroyDatabase(db); +#endif + + * xscale = xdpi / 96.f; + *yscale = ydpi / 96.f; + } + + RGFW_monitor RGFW_XCreateMonitor(i32 screen) { + RGFW_monitor monitor; + + Display* display = XOpenDisplay(NULL); + + monitor.rect = RGFW_RECT(0, 0, DisplayWidth(display, screen), DisplayHeight(display, screen)); + monitor.physW = (monitor.rect.w * 25.4f / 96.f); + monitor.physH = (monitor.rect.h * 25.4f / 96.f); + + strncpy(monitor.name, DisplayString(display), 128); + + XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY); + + XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen)); + + XRRCrtcInfo* ci = NULL; + int crtc = 0; + + if (sr->ncrtc > crtc) { + ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]); + } + + if (ci == NULL) { + XRRFreeScreenResources(sr); + XCloseDisplay(display); + return monitor; + } + + monitor.rect.x = ci->x; + monitor.rect.y = ci->y; + + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); + + XCloseDisplay(display); + + return monitor; + } + + RGFW_monitor RGFW_monitors[6]; + RGFW_monitor* RGFW_getMonitors(void) { + size_t i; + for (i = 0; i < ScreenCount(RGFW_root->src.display) && i < 6; i++) + RGFW_monitors[i] = RGFW_XCreateMonitor(i); + + return RGFW_monitors; + } + + RGFW_monitor RGFW_getPrimaryMonitor(void) { + assert(RGFW_root != NULL); + + i32 primary = -1; + Window root = DefaultRootWindow(RGFW_root->src.display); + XRRScreenResources* res = XRRGetScreenResources(RGFW_root->src.display, root); + + for (int i = 0; i < res->noutput; i++) { + XRROutputInfo* output_info = XRRGetOutputInfo(RGFW_root->src.display, res, res->outputs[i]); + if (output_info->connection == RR_Connected && output_info->crtc) { + XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(RGFW_root->src.display, res, output_info->crtc); + if (crtc_info->mode != None && crtc_info->x == 0 && crtc_info->y == 0) { + primary = i; + XRRFreeCrtcInfo(crtc_info); + XRRFreeOutputInfo(output_info); + break; + } + XRRFreeCrtcInfo(crtc_info); + } + XRRFreeOutputInfo(output_info); + } + + XRRFreeScreenResources(res); + + return RGFW_XCreateMonitor(primary); + } + + RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) { + return RGFW_XCreateMonitor(DefaultScreen(win->src.display)); + } + + char keyboard[32]; + + u8 RGFW_isPressedI(RGFW_window* win, u32 key) { + Display* d; + if (win == (RGFW_window*) 0) + d = RGFW_root->src.display; + else if (!win->event.inFocus) + return 0; + else + d = (Display*) win->src.display; + + XQueryKeymap(d, keyboard); /* query the keymap */ + + KeyCode kc2 = XKeysymToKeycode(d, key); /* convert the key to a keycode */ + return !!(keyboard[kc2 >> 3] & (1 << (kc2 & 7))); /* check if the key is pressed */ + } + +#endif + +#ifdef RGFW_WINDOWS + char* createUTF8FromWideStringWin32(const WCHAR* source); + +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 + +#if defined(RGFW_OSMESA) && defined(RGFW_LINK_OSMESA) + + typedef void (GLAPIENTRY* PFN_OSMesaDestroyContext)(OSMesaContext); + typedef i32(GLAPIENTRY* PFN_OSMesaMakeCurrent)(OSMesaContext, void*, int, int, int); + typedef OSMesaContext(GLAPIENTRY* PFN_OSMesaCreateContext)(GLenum, OSMesaContext); + + PFN_OSMesaMakeCurrent OSMesaMakeCurrentSource; + PFN_OSMesaCreateContext OSMesaCreateContextSource; + PFN_OSMesaDestroyContext OSMesaDestroyContextSource; + +#define OSMesaCreateContext OSMesaCreateContextSource +#define OSMesaMakeCurrent OSMesaMakeCurrentSource +#define OSMesaDestroyContext OSMesaDestroyContextSource +#endif + + typedef int (*PFN_wglGetSwapIntervalEXT)(void); + PFN_wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc = NULL; +#define wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc + + + +#if defined(RGFW_DIRECTX) + RGFW_directXinfo RGFW_dxInfo; + + RGFW_directXinfo* RGFW_getDirectXInfo(void) { return &RGFW_dxInfo; } +#endif + + void* RGFWjoystickApi = NULL; + + /* these two wgl functions need to be preloaded */ + typedef HGLRC(WINAPI* wglCreateContextAttribsARB_type)(HDC hdc, HGLRC hShareContext, + const i32* attribList); + wglCreateContextAttribsARB_type wglCreateContextAttribsARB = NULL; + + /* defines for creating ARB attributes */ +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201a +#define WGL_ALPHA_BITS_ARB 0x201b +#define WGL_ALPHA_SHIFT_ARB 0x201c +#define WGL_ACCUM_BITS_ARB 0x201d +#define WGL_ACCUM_RED_BITS_ARB 0x201e +#define WGL_ACCUM_GREEN_BITS_ARB 0x201f +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_STEREO_ARB 0x2012 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9 + +static HMODULE wglinstance = NULL; + +#ifdef RGFW_WGL_LOAD + typedef HGLRC(WINAPI* PFN_wglCreateContext)(HDC); + typedef BOOL(WINAPI* PFN_wglDeleteContext)(HGLRC); + typedef PROC(WINAPI* PFN_wglGetProcAddress)(LPCSTR); + typedef BOOL(WINAPI* PFN_wglMakeCurrent)(HDC, HGLRC); + typedef HDC(WINAPI* PFN_wglGetCurrentDC)(); + typedef HGLRC(WINAPI* PFN_wglGetCurrentContext)(); + + PFN_wglCreateContext wglCreateContextSRC; + PFN_wglDeleteContext wglDeleteContextSRC; + PFN_wglGetProcAddress wglGetProcAddressSRC; + PFN_wglMakeCurrent wglMakeCurrentSRC; + PFN_wglGetCurrentDC wglGetCurrentDCSRC; + PFN_wglGetCurrentContext wglGetCurrentContextSRC; + +#define wglCreateContext wglCreateContextSRC +#define wglDeleteContext wglDeleteContextSRC +#define wglGetProcAddress wglGetProcAddressSRC +#define wglMakeCurrent wglMakeCurrentSRC + +#define wglGetCurrentDC wglGetCurrentDCSRC +#define wglGetCurrentContext wglGetCurrentContextSRC +#endif + +#ifdef RGFW_OPENGL + void* RGFW_getProcAddress(const char* procname) { + void* proc = (void*) wglGetProcAddress(procname); + if (proc) + return proc; + + return (void*) GetProcAddress(wglinstance, procname); + } + + typedef BOOL(APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); + static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; +#endif + + RGFW_window RGFW_eventWindow = { {NULL} }; + + LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + switch (message) { + case WM_MOVE: + RGFW_eventWindow.r.x = LOWORD(lParam); + RGFW_eventWindow.r.y = HIWORD(lParam); + RGFW_eventWindow.src.window = hWnd; + return DefWindowProcA(hWnd, message, wParam, lParam); + case WM_SIZE: + RGFW_eventWindow.r.w = LOWORD(lParam); + RGFW_eventWindow.r.h = HIWORD(lParam); + RGFW_eventWindow.src.window = hWnd; + return DefWindowProcA(hWnd, message, wParam, lParam); // Call DefWindowProc after handling + default: + return DefWindowProcA(hWnd, message, wParam, lParam); + } + } + + #ifndef RGFW_NO_DPI + static HMODULE RGFW_Shcore_dll = NULL; + typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*); + PFN_GetDpiForMonitor GetDpiForMonitorSRC = NULL; + #define GetDpiForMonitor GetDpiForMonitorSRC + #endif + + void RGFW_loadXInput(void) { + u32 i; + static const char* names[] = { + "xinput1_4.dll", + "xinput1_3.dll", + "xinput9_1_0.dll", + "xinput1_2.dll", + "xinput1_1.dll" + }; + + for (i = 0; i < sizeof(names) / sizeof(const char*); i++) { + RGFW_XInput_dll = LoadLibraryA(names[i]); + + if (RGFW_XInput_dll) { + XInputGetStateSRC = (PFN_XInputGetState)GetProcAddress(RGFW_XInput_dll, "XInputGetState"); + + if (XInputGetStateSRC == NULL) + printf("Failed to load XInputGetState"); + } + } + } + + RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) { + if (RGFW_XInput_dll == NULL) + RGFW_loadXInput(); + + #ifndef RGFW_NO_DPI + if (RGFW_Shcore_dll == NULL) { + RGFW_Shcore_dll = LoadLibraryA("shcore.dll"); + GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor"); + } + #endif + + if (wglinstance == NULL) { + wglinstance = LoadLibraryA("opengl32.dll"); +#ifdef RGFW_WGL_LOAD + wglCreateContextSRC = (PFN_wglCreateContext) GetProcAddress(wglinstance, "wglCreateContext"); + wglDeleteContextSRC = (PFN_wglDeleteContext) GetProcAddress(wglinstance, "wglDeleteContext"); + wglGetProcAddressSRC = (PFN_wglGetProcAddress) GetProcAddress(wglinstance, "wglGetProcAddress"); + wglMakeCurrentSRC = (PFN_wglMakeCurrent) GetProcAddress(wglinstance, "wglMakeCurrent"); + wglGetCurrentDCSRC = (PFN_wglGetCurrentDC) GetProcAddress(wglinstance, "wglGetCurrentDC"); + wglGetCurrentContextSRC = (PFN_wglGetCurrentContext) GetProcAddress(wglinstance, "wglGetCurrentContext"); +#endif + } + + if (name[0] == 0) name = (char*) " "; + + RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1); + + RGFW_window* win = RGFW_window_basic_init(rect, args); + + if (RGFW_root == NULL) { + RGFW_root = win; + } + + HINSTANCE inh = GetModuleHandleA(NULL); + + WNDCLASSA Class = { 0 }; /* Setup the Window class. */ + Class.lpszClassName = name; + Class.hInstance = inh; + Class.hCursor = LoadCursor(NULL, IDC_ARROW); + Class.lpfnWndProc = WndProc; + + RegisterClassA(&Class); + + DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + + RECT windowRect, clientRect; + + if (!(args & RGFW_NO_BORDER)) { + window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_VISIBLE | WS_MINIMIZEBOX; + + if (!(args & RGFW_NO_RESIZE)) + window_style |= WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME; + } else + window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX; + + HWND dummyWin = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h, 0, 0, inh, 0); + + GetWindowRect(dummyWin, &windowRect); + GetClientRect(dummyWin, &clientRect); + + win->src.hOffset = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top); + win->src.window = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + win->src.hOffset, 0, 0, inh, 0); + + if (args & RGFW_TRANSPARENT_WINDOW) { + SetWindowLongA(win->src.window, GWL_EXSTYLE, GetWindowLongA(win->src.window, GWL_EXSTYLE) | WS_EX_LAYERED); + } + if (args & RGFW_ALLOW_DND) { + win->src.winArgs |= RGFW_ALLOW_DND; + DragAcceptFiles(win->src.window, TRUE); + } + win->src.hdc = GetDC(win->src.window); + +#ifdef RGFW_DIRECTX + assert(FAILED(CreateDXGIFactory(&__uuidof(IDXGIFactory), (void**) &RGFW_dxInfo.pFactory)) == 0); + + if (FAILED(RGFW_dxInfo.pFactory->lpVtbl->EnumAdapters(RGFW_dxInfo.pFactory, 0, &RGFW_dxInfo.pAdapter))) { + fprintf(stderr, "Failed to enumerate DXGI adapters\n"); + RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory); + return NULL; + } + + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 }; + + if (FAILED(D3D11CreateDevice(RGFW_dxInfo.pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, featureLevels, 1, D3D11_SDK_VERSION, &RGFW_dxInfo.pDevice, NULL, &RGFW_dxInfo.pDeviceContext))) { + fprintf(stderr, "Failed to create Direct3D device\n"); + RGFW_dxInfo.pAdapter->lpVtbl->Release(RGFW_dxInfo.pAdapter); + RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory); + return NULL; + } + + DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; + swapChainDesc.BufferCount = 1; + swapChainDesc.BufferDesc.Width = win->r.w; + swapChainDesc.BufferDesc.Height = win->r.h; + swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.OutputWindow = win->src.window; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.Windowed = TRUE; + RGFW_dxInfo.pFactory->lpVtbl->CreateSwapChain(RGFW_dxInfo.pFactory, (IUnknown*) RGFW_dxInfo.pDevice, &swapChainDesc, &win->src.swapchain); + + ID3D11Texture2D* pBackBuffer; + win->src.swapchain->lpVtbl->GetBuffer(win->src.swapchain, 0, &__uuidof(ID3D11Texture2D), (LPVOID*) &pBackBuffer); + RGFW_dxInfo.pDevice->lpVtbl->CreateRenderTargetView(RGFW_dxInfo.pDevice, (ID3D11Resource*) pBackBuffer, NULL, &win->src.renderTargetView); + pBackBuffer->lpVtbl->Release(pBackBuffer); + + D3D11_TEXTURE2D_DESC depthStencilDesc = { 0 }; + depthStencilDesc.Width = win->r.w; + depthStencilDesc.Height = win->r.h; + depthStencilDesc.MipLevels = 1; + depthStencilDesc.ArraySize = 1; + depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthStencilDesc.SampleDesc.Count = 1; + depthStencilDesc.SampleDesc.Quality = 0; + depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; + depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + + ID3D11Texture2D* pDepthStencilTexture = NULL; + RGFW_dxInfo.pDevice->lpVtbl->CreateTexture2D(RGFW_dxInfo.pDevice, &depthStencilDesc, NULL, &pDepthStencilTexture); + + D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = { 0 }; + depthStencilViewDesc.Format = depthStencilDesc.Format; + depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + depthStencilViewDesc.Texture2D.MipSlice = 0; + + RGFW_dxInfo.pDevice->lpVtbl->CreateDepthStencilView(RGFW_dxInfo.pDevice, (ID3D11Resource*) pDepthStencilTexture, &depthStencilViewDesc, &win->src.pDepthStencilView); + + pDepthStencilTexture->lpVtbl->Release(pDepthStencilTexture); + + RGFW_dxInfo.pDeviceContext->lpVtbl->OMSetRenderTargets(RGFW_dxInfo.pDeviceContext, 1, &win->src.renderTargetView, win->src.pDepthStencilView); +#endif + +#ifdef RGFW_OPENGL + HDC dummy_dc = GetDC(dummyWin); + + PIXELFORMATDESCRIPTOR pfd = { + .nSize = sizeof(pfd), + .nVersion = 1, + .iPixelType = PFD_TYPE_RGBA, + .dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + .cColorBits = 32, + .cAlphaBits = 8, + .iLayerType = PFD_MAIN_PLANE, + .cDepthBits = 24, + .cStencilBits = 8, + }; + + int pixel_format = ChoosePixelFormat(dummy_dc, &pfd); + SetPixelFormat(dummy_dc, pixel_format, &pfd); + + HGLRC dummy_context = wglCreateContext(dummy_dc); + wglMakeCurrent(dummy_dc, dummy_context); + + if (wglChoosePixelFormatARB == NULL) { + wglCreateContextAttribsARB = (wglCreateContextAttribsARB_type) wglGetProcAddress("wglCreateContextAttribsARB"); + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB"); + } + + wglMakeCurrent(dummy_dc, 0); + wglDeleteContext(dummy_context); + ReleaseDC(dummyWin, dummy_dc); + + if (wglCreateContextAttribsARB != NULL) { + PIXELFORMATDESCRIPTOR pfd = { sizeof(pfd), 1, PFD_TYPE_RGBA, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 8, PFD_MAIN_PLANE, 24, 8 }; + + if (args & RGFW_OPENGL_SOFTWARE) + pfd.dwFlags |= PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED; + + if (wglChoosePixelFormatARB != NULL) { + i32* pixel_format_attribs = (i32*)RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE); + + int pixel_format; + UINT num_formats; + wglChoosePixelFormatARB(win->src.hdc, pixel_format_attribs, 0, 1, &pixel_format, &num_formats); + if (!num_formats) { + printf("Failed to set the OpenGL 3.3 pixel format.\n"); + } + + DescribePixelFormat(win->src.hdc, pixel_format, sizeof(pfd), &pfd); + if (!SetPixelFormat(win->src.hdc, pixel_format, &pfd)) { + printf("Failed to set the OpenGL 3.3 pixel format.\n"); + } + } + + u32 index = 0; + i32 attribs[40]; +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 + SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB); + + if (RGFW_majorVersion || RGFW_minorVersion) { + SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion); + SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion); + } + + SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB); + + if (RGFW_majorVersion || RGFW_minorVersion) { + SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion); + SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion); + } + + SET_ATTRIB(0, 0); + + win->src.rSurf = wglCreateContextAttribsARB(win->src.hdc, NULL, attribs); + } else { + fprintf(stderr, "Failed to create an accelerated OpenGL Context\n"); + + int pixel_format = ChoosePixelFormat(win->src.hdc, &pfd); + SetPixelFormat(win->src.hdc, pixel_format, &pfd); + + win->src.rSurf = wglCreateContext(win->src.hdc); + } + + wglMakeCurrent(win->src.hdc, win->src.rSurf); + wglShareLists(RGFW_root->src.rSurf, win->src.rSurf); +#endif + +#ifdef RGFW_OSMESA +#ifdef RGFW_LINK_OSM ESA + OSMesaMakeCurrentSource = (PFN_OSMesaMakeCurrent) GetProcAddress(win->src.hdc, "OSMesaMakeCurrent"); + OSMesaCreateContextSource = (PFN_OSMesaCreateContext) GetProcAddress(win->src.hdc, "OSMesaCreateContext"); + OSMesaDestroyContextSource = (PFN_OSMesaDestroyContext) GetProcAddress(win->src.hdc, "OSMesaDestroyContext"); +#endif +#endif + +#ifdef RGFW_OPENGL + ReleaseDC(win->src.window, win->src.hdc); + win->src.hdc = GetDC(win->src.window); + wglMakeCurrent(win->src.hdc, win->src.rSurf); +#endif + + DestroyWindow(dummyWin); + RGFW_init_buffer(win); + +#ifdef RGFW_VULKAN + RGFW_initVulkan(win); +#endif + + if (args & RGFW_SCALE_TO_MONITOR) + RGFW_window_scaleToMonitor(win); + +#ifdef RGFW_EGL + RGFW_createOpenGLContext(win); +#endif + + if (args & RGFW_HIDE_MOUSE) + RGFW_window_showMouse(win, 0); + + ShowWindow(win->src.window, SW_SHOWNORMAL); + + return win; + } + + + RGFW_area RGFW_getScreenSize(void) { + return RGFW_AREA(GetDeviceCaps(GetDC(NULL), HORZRES), GetDeviceCaps(GetDC(NULL), VERTRES)); + } + + RGFW_vector RGFW_getGlobalMousePoint(void) { + POINT p; + GetCursorPos(&p); + + return RGFW_VECTOR(p.x, p.y); + } + + void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + win->src.minSize = a; + } + + void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + win->src.maxSize = a; + } + + + void RGFW_window_minimize(RGFW_window* win) { + assert(win != NULL); + + ShowWindow(win->src.window, SW_MINIMIZE); + } + + void RGFW_window_restore(RGFW_window* win) { + assert(win != NULL); + + ShowWindow(win->src.window, SW_RESTORE); + } + + static i32 RGFW_checkXInput(RGFW_Event* e) { + static WORD buttons[4]; + static BYTE triggers[4][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} }; + + size_t i; + for (i = 0; i < 4; i++) { + XINPUT_STATE state; + if (XInputGetState == NULL || + XInputGetState((DWORD) i, &state) == ERROR_DEVICE_NOT_CONNECTED + ) + return 0; + + e->button = 0; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A && !(buttons[i] & XINPUT_GAMEPAD_A)) { + e->button = RGFW_JS_A; + e->type = RGFW_jsButtonPressed; + buttons[i] = state.Gamepad.wButtons; + return 1; + } else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B && !(buttons[i] & XINPUT_GAMEPAD_B)) + e->button = RGFW_JS_B; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y && !(buttons[i] & XINPUT_GAMEPAD_Y)) + e->button = RGFW_JS_Y; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X && !(buttons[i] & XINPUT_GAMEPAD_X)) + e->button = RGFW_JS_X; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START && !(buttons[i] & XINPUT_GAMEPAD_START)) + e->button = RGFW_JS_START; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK && !(buttons[i] & XINPUT_GAMEPAD_BACK)) + e->button = RGFW_JS_SELECT; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP && !(buttons[i] & XINPUT_GAMEPAD_DPAD_UP)) + e->button = RGFW_JS_UP; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN && !(buttons[i] & XINPUT_GAMEPAD_DPAD_DOWN)) + e->button = RGFW_JS_DOWN; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT && !(buttons[i] & XINPUT_GAMEPAD_DPAD_LEFT)) + e->button = RGFW_JS_LEFT; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT && !(buttons[i] & XINPUT_GAMEPAD_DPAD_RIGHT)) + e->button = RGFW_JS_RIGHT; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER && !(buttons[i] & XINPUT_GAMEPAD_LEFT_SHOULDER)) + e->button = RGFW_JS_L1; + else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER && !(buttons[i] & XINPUT_GAMEPAD_RIGHT_SHOULDER)) + e->button = RGFW_JS_R1; + else if (state.Gamepad.bLeftTrigger && triggers[i][0] == 0) + e->button = RGFW_JS_L2; + else if (state.Gamepad.bRightTrigger && triggers[i][1] == 0) + e->button = RGFW_JS_R2; + + triggers[i][0] = state.Gamepad.bLeftTrigger; + triggers[i][1] = state.Gamepad.bRightTrigger; + + if (e->button) { + buttons[i] = state.Gamepad.wButtons; + e->type = RGFW_jsButtonPressed; + return 1; + } + + if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_A) && (buttons[i] & XINPUT_GAMEPAD_A)) { + e->button = RGFW_JS_A; + e->type = RGFW_jsButtonReleased; + buttons[i] = state.Gamepad.wButtons; + return 1; + } else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_B) && (buttons[i] & XINPUT_GAMEPAD_B)) + e->button = RGFW_JS_B; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) && (buttons[i] & XINPUT_GAMEPAD_Y)) + e->button = RGFW_JS_Y; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_X) && (buttons[i] & XINPUT_GAMEPAD_X)) + e->button = RGFW_JS_X; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_START) && (buttons[i] & XINPUT_GAMEPAD_START)) + e->button = RGFW_JS_START; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) && (buttons[i] & XINPUT_GAMEPAD_BACK)) + e->button = RGFW_JS_SELECT; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) && (buttons[i] & XINPUT_GAMEPAD_DPAD_UP)) + e->button = RGFW_JS_UP; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) && (buttons[i] & XINPUT_GAMEPAD_DPAD_DOWN)) + e->button = RGFW_JS_DOWN; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) && (buttons[i] & XINPUT_GAMEPAD_DPAD_LEFT)) + e->button = RGFW_JS_LEFT; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) && (buttons[i] & XINPUT_GAMEPAD_DPAD_RIGHT)) + e->button = RGFW_JS_RIGHT; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) && (buttons[i] & XINPUT_GAMEPAD_LEFT_SHOULDER)) + e->button = RGFW_JS_L1; + else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) && (buttons[i] & XINPUT_GAMEPAD_RIGHT_SHOULDER)) + e->button = RGFW_JS_R1; + else if (state.Gamepad.bLeftTrigger == 0 && triggers[i][0] != 0) + e->button = RGFW_JS_L2; + else if (state.Gamepad.bRightTrigger == 0 && triggers[i][1] != 0) + e->button = RGFW_JS_R2; + + buttons[i] = state.Gamepad.wButtons; + + if (e->button) { + e->type = RGFW_jsButtonReleased; + return 1; + } +#define INPUT_DEADZONE ( 0.24f * (float)(0x7FFF) ) // Default to 24% of the +/- 32767 range. This is a reasonable default value but can be altered if needed. + + if ((state.Gamepad.sThumbLX < INPUT_DEADZONE && + state.Gamepad.sThumbLX > -INPUT_DEADZONE) && + (state.Gamepad.sThumbLY < INPUT_DEADZONE && + state.Gamepad.sThumbLY > -INPUT_DEADZONE)) + { + state.Gamepad.sThumbLX = 0; + state.Gamepad.sThumbLY = 0; + } + + if ((state.Gamepad.sThumbRX < INPUT_DEADZONE && + state.Gamepad.sThumbRX > -INPUT_DEADZONE) && + (state.Gamepad.sThumbRY < INPUT_DEADZONE && + state.Gamepad.sThumbRY > -INPUT_DEADZONE)) + { + state.Gamepad.sThumbRX = 0; + state.Gamepad.sThumbRY = 0; + } + + e->axisesCount = 2; + RGFW_vector axis1 = RGFW_VECTOR(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY); + RGFW_vector axis2 = RGFW_VECTOR(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY); + + if (axis1.x != e->axis[0].x || axis1.y != e->axis[0].y || axis2.x != e->axis[1].x || axis2.y != e->axis[1].y) { + e->type = RGFW_jsAxisMove; + + e->axis[0] = axis1; + e->axis[1] = axis2; + + return 1; + } + + e->axis[0] = axis1; + e->axis[1] = axis2; + } + + return 0; + } + + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { + assert(win != NULL); + + MSG msg; + + if (RGFW_eventWindow.src.window == win->src.window) { + if (RGFW_eventWindow.r.x != -1) { + win->r.x = RGFW_eventWindow.r.x; + win->r.y = RGFW_eventWindow.r.y; + } + + if (RGFW_eventWindow.r.w != -1) { + win->r.w = RGFW_eventWindow.r.w; + win->r.h = RGFW_eventWindow.r.h; + } + + win->event.type = RGFW_windowAttribsChange; + + RGFW_eventWindow.src.window = NULL; + RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1); + + return &win->event; + } + + if (win->event.droppedFilesCount) { + u32 i; + for (i = 0; i < win->event.droppedFilesCount; i++) + win->event.droppedFiles[i][0] = '\0'; + } + + win->event.droppedFilesCount = 0; + + win->event.inFocus = (GetForegroundWindow() == win->src.window); + + if (RGFW_checkXInput(&win->event)) + return &win->event; + + if (win->event.type == RGFW_quit) + return NULL; + + static BYTE keyboardState[256]; + GetKeyboardState(keyboardState); + + if (PeekMessageA(&msg, win->src.window, 0u, 0u, PM_REMOVE)) { + switch (msg.message) { + case WM_CLOSE: + case WM_QUIT: + win->event.type = RGFW_quit; + break; + + case WM_KEYUP: + win->event.keyCode = (u32) msg.wParam; + strncpy(win->event.keyName, RGFW_keyCodeTokeyStr(msg.lParam), 16); + if (GetKeyState(VK_SHIFT) & 0x8000) { + ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR), + keyboardState, (LPWORD) win->event.keyName, 0); + } + + win->event.type = RGFW_keyReleased; + break; + + case WM_KEYDOWN: + win->event.keyCode = (u32) msg.wParam; + strncpy(win->event.keyName, RGFW_keyCodeTokeyStr(msg.lParam), 16); + if (GetKeyState(VK_SHIFT) & 0x8000) { + ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR), + keyboardState, (LPWORD) win->event.keyName, 0); + } + + win->event.type = RGFW_keyPressed; + break; + + case WM_MOUSEMOVE: + win->event.point.x = GET_X_LPARAM(msg.lParam); + win->event.point.y = GET_Y_LPARAM(msg.lParam); + + win->event.type = RGFW_mousePosChanged; + break; + + case WM_LBUTTONDOWN: + win->event.button = RGFW_mouseLeft; + win->event.type = RGFW_mouseButtonPressed; + break; + case WM_RBUTTONDOWN: + win->event.button = RGFW_mouseRight; + win->event.type = RGFW_mouseButtonPressed; + break; + case WM_MBUTTONDOWN: + win->event.button = RGFW_mouseMiddle; + win->event.type = RGFW_mouseButtonPressed; + break; + + case WM_MOUSEWHEEL: + if (msg.wParam > 0) + win->event.button = RGFW_mouseScrollUp; + else + win->event.button = RGFW_mouseScrollDown; + + win->event.scroll = (SHORT) HIWORD(msg.wParam) / (double) WHEEL_DELTA; + + win->event.type = RGFW_mouseButtonPressed; + break; + + case WM_LBUTTONUP: + win->event.button = RGFW_mouseLeft; + win->event.type = RGFW_mouseButtonReleased; + break; + case WM_RBUTTONUP: + win->event.button = RGFW_mouseRight; + win->event.type = RGFW_mouseButtonReleased; + break; + case WM_MBUTTONUP: + win->event.button = RGFW_mouseMiddle; + win->event.type = RGFW_mouseButtonReleased; + break; + + /* + much of this event is source from glfw + */ + case WM_DROPFILES: { + win->event.type = RGFW_dnd; + + HDROP drop = (HDROP) msg.wParam; + POINT pt; + u32 i; + + win->event.droppedFilesCount = DragQueryFileW(drop, 0xffffffff, NULL, 0); + //win->event.droppedFiles = (char**)RGFW_CALLOC(win->event.droppedFilesCount, sizeof(char*)); + + /* Move the mouse to the position of the drop */ + DragQueryPoint(drop, &pt); + + win->event.point.x = pt.x; + win->event.point.y = pt.y; + + for (i = 0; i < win->event.droppedFilesCount; i++) { + const UINT length = DragQueryFileW(drop, i, NULL, 0); + WCHAR* buffer = (WCHAR*) RGFW_CALLOC((size_t) length + 1, sizeof(WCHAR)); + + DragQueryFileW(drop, i, buffer, length + 1); + strcpy(win->event.droppedFiles[i], createUTF8FromWideStringWin32(buffer)); + + RGFW_FREE(buffer); + } + + DragFinish(drop); + } + break; + case WM_GETMINMAXINFO: + { + if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0) + break; + + MINMAXINFO* mmi = (MINMAXINFO*) msg.lParam; + mmi->ptMinTrackSize.x = win->src.minSize.w; + mmi->ptMinTrackSize.y = win->src.minSize.h; + mmi->ptMaxTrackSize.x = win->src.maxSize.w; + mmi->ptMaxTrackSize.y = win->src.maxSize.h; + return 0; + } + default: + win->event.type = 0; + break; + } + + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + else + win->event.type = 0; + + RGFW_vector mouse = RGFW_getGlobalMousePoint(); + if (win->src.winArgs & RGFW_HOLD_MOUSE && win->event.inFocus && + (mouse.x != win->r.x + (win->r.w / 2) || mouse.y != win->r.y + (win->r.h / 2))) { + RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + } + + win->event.lockState = 0; + + if ((GetKeyState(VK_CAPITAL) & 0x0001) != 0) + win->event.lockState |= RGFW_CAPSLOCK; + if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0) + win->event.lockState |= RGFW_NUMLOCK; + if ((GetKeyState(VK_SCROLL) & 0x0001) != 0) + win->event.lockState |= 3; + + + if (!IsWindow(win->src.window)) + win->event.type = RGFW_quit; + + if (win->event.type) + return &win->event; + else + return NULL; + } + + u8 RGFW_window_isFullscreen(RGFW_window* win) { + assert(win != NULL); + + WINDOWPLACEMENT placement = { 0 }; + GetWindowPlacement(win->src.window, &placement); + return placement.showCmd == SW_SHOWMAXIMIZED; + } + + u8 RGFW_window_isHidden(RGFW_window* win) { + assert(win != NULL); + + return IsWindowVisible(win->src.window) == 0 && !RGFW_window_isMinimized(win); + } + + u8 RGFW_window_isMinimized(RGFW_window* win) { + assert(win != NULL); + + WINDOWPLACEMENT placement = { 0 }; + GetWindowPlacement(win->src.window, &placement); + return placement.showCmd == SW_SHOWMINIMIZED; + } + + u8 RGFW_window_isMaximized(RGFW_window* win) { + assert(win != NULL); + + WINDOWPLACEMENT placement = { 0 }; + GetWindowPlacement(win->src.window, &placement); + return placement.showCmd == SW_SHOWMAXIMIZED; + } + + typedef struct { int iIndex; HMONITOR hMonitor; } RGFW_mInfo; + BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + RGFW_mInfo* info = (RGFW_mInfo*) dwData; + if (info->hMonitor == hMonitor) + return FALSE; + + info->iIndex++; + return TRUE; + } + + RGFW_monitor win32CreateMonitor(HMONITOR src) { + RGFW_monitor monitor; + MONITORINFO monitorInfo; + + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfoA(src, &monitorInfo); + + RGFW_mInfo info; + info.iIndex = 0; + info.hMonitor = src; + + /* get the monitor's index */ + if (EnumDisplayMonitors(NULL, NULL, GetMonitorByHandle, (LPARAM) &info)) { + DISPLAY_DEVICEA dd; + dd.cb = sizeof(dd); + + /* loop through the devices until you find a device with the monitor's index */ + size_t deviceIndex; + for (deviceIndex = 0; EnumDisplayDevicesA(0, (DWORD) deviceIndex, &dd, 0); deviceIndex++) { + char* deviceName = dd.DeviceName; + if (EnumDisplayDevicesA(deviceName, info.iIndex, &dd, 0)) { + strcpy(monitor.name, dd.DeviceString); /* copy the monitor's name */ + break; + } + } + } + + monitor.rect.x = monitorInfo.rcWork.left; + monitor.rect.y = monitorInfo.rcWork.top; + monitor.rect.w = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + monitor.rect.h = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + +#ifndef RGFW_NO_DPI + if (GetDpiForMonitor != NULL) { + u32 x, y; + GetDpiForMonitor(src, MDT_ANGULAR_DPI, &x, &y); + monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI; + monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI; + } +#endif + + HDC hdc = GetDC(NULL); + /* get pixels per inch */ + i32 ppiX = GetDeviceCaps(hdc, LOGPIXELSX); + i32 ppiY = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + + /* Calculate physical height in inches */ + monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX; + monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY; + + return monitor; + } + + RGFW_monitor RGFW_monitors[6]; + BOOL CALLBACK GetMonitorHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + RGFW_mInfo* info = (RGFW_mInfo*) dwData; + + if (info->iIndex >= 6) + return FALSE; + + RGFW_monitors[info->iIndex] = win32CreateMonitor(hMonitor); + info->iIndex++; + + return TRUE; + } + + RGFW_monitor RGFW_getPrimaryMonitor(void) { + return win32CreateMonitor(MonitorFromPoint((POINT) { 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); + } + + RGFW_monitor* RGFW_getMonitors(void) { + RGFW_mInfo info; + info.iIndex = 0; + while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info)); + + return RGFW_monitors; + } + + RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) { + HMONITOR src = MonitorFromWindow(win->src.window, MONITOR_DEFAULTTOPRIMARY); + return win32CreateMonitor(src); + } + + u8 RGFW_isPressedI(RGFW_window* win, u32 key) { + if (win != NULL && !win->event.inFocus) + return 0; + + if (GetAsyncKeyState(key) & 0x8000) + return 1; + else return 0; + } + + HICON RGFW_loadHandleImage(RGFW_window* win, u8* src, RGFW_area a, BOOL icon) { + assert(win != NULL); + + u32 i; + HDC dc; + HICON handle; + HBITMAP color, mask; + BITMAPV5HEADER bi; + ICONINFO ii; + u8* target = NULL; + u8* source = src; + + ZeroMemory(&bi, sizeof(bi)); + bi.bV5Size = sizeof(bi); + bi.bV5Width = a.w; + bi.bV5Height = -((LONG) a.h); + bi.bV5Planes = 1; + bi.bV5BitCount = 32; + bi.bV5Compression = BI_BITFIELDS; + bi.bV5RedMask = 0x00ff0000; + bi.bV5GreenMask = 0x0000ff00; + bi.bV5BlueMask = 0x000000ff; + bi.bV5AlphaMask = 0xff000000; + + dc = GetDC(NULL); + color = CreateDIBSection(dc, + (BITMAPINFO*) &bi, + DIB_RGB_COLORS, + (void**) &target, + NULL, + (DWORD) 0); + ReleaseDC(NULL, dc); + + mask = CreateBitmap(a.w, a.h, 1, 1, NULL); + + for (i = 0; i < a.w * a.h; i++) { + target[0] = source[2]; + target[1] = source[1]; + target[2] = source[0]; + target[3] = source[3]; + target += 4; + source += 4; + } + + ZeroMemory(&ii, sizeof(ii)); + ii.fIcon = icon; + ii.xHotspot = 0; + ii.yHotspot = 0; + ii.hbmMask = mask; + ii.hbmColor = color; + + handle = CreateIconIndirect(&ii); + + DeleteObject(color); + DeleteObject(mask); + + return handle; + } + + void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) { + assert(win != NULL); + + HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(win, image, a, FALSE); + SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) cursor); + SetCursor(cursor); + DestroyCursor(cursor); + } + + void RGFW_window_setMouseDefault(RGFW_window* win) { + RGFW_window_setMouseStandard(win, 32512); + } + + void RGFW_window_setMouseStandard(RGFW_window* win, i32 mouse) { + assert(win != NULL); + + char* icon = MAKEINTRESOURCEA(mouse); + + SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) LoadCursorA(NULL, icon)); + SetCursor(LoadCursorA(NULL, icon)); + } + + void RGFW_window_hide(RGFW_window* win) { + ShowWindow(win->src.window, SW_HIDE); + } + + void RGFW_window_show(RGFW_window* win) { + ShowWindow(win->src.window, SW_RESTORE); + } + + void RGFW_window_close(RGFW_window* win) { + assert(win != NULL); + +#ifdef RGFW_VULKAN + for (u32 i = 0; i < win->src.image_count; i++) { + vkDestroyFramebuffer(RGFW_vulkan_info.device, RGFW_vulkan_info.framebuffers[i], NULL); + } + + for (u32 i = 0; i < win->src.image_count; i++) { + vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL); + } + + vkDestroySwapchainKHR(RGFW_vulkan_info.device, win->src.swapchain, NULL); + vkDestroySurfaceKHR(RGFW_vulkan_info.instance, win->src.rSurf, NULL); + free(win->src.swapchain_image_views); + free(win->src.swapchain_images); +#endif + +#ifdef RGFW_EGL + RGFW_closeEGL(win); +#endif + + if (win == RGFW_root) { +#ifdef RGFW_DIRECTX + RGFW_dxInfo.pDeviceContext->lpVtbl->Release(RGFW_dxInfo.pDeviceContext); + RGFW_dxInfo.pDevice->lpVtbl->Release(RGFW_dxInfo.pDevice); + RGFW_dxInfo.pAdapter->lpVtbl->Release(RGFW_dxInfo.pAdapter); + RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory); +#endif + + if (RGFW_XInput_dll != NULL) { + FreeLibrary(RGFW_XInput_dll); + RGFW_XInput_dll = NULL; + } + + #ifndef RGFW_NO_DPI + if (RGFW_Shcore_dll != NULL) { + FreeLibrary(RGFW_Shcore_dll); + RGFW_Shcore_dll = NULL; + } + #endif + + if (wglinstance != NULL) { + FreeLibrary(wglinstance); + wglinstance = NULL; + } + + RGFW_root = NULL; + } + +#ifdef RGFW_DIRECTX + win->src.swapchain->lpVtbl->Release(win->src.swapchain); + win->src.renderTargetView->lpVtbl->Release(win->src.renderTargetView); + win->src.pDepthStencilView->lpVtbl->Release(win->src.pDepthStencilView); +#endif + +#ifdef RGFW_BUFFER + DeleteDC(win->src.hdcMem); + DeleteObject(win->src.bitmap); +#endif + +#ifdef RGFW_OPENGL + wglDeleteContext((HGLRC) win->src.rSurf); /* delete opengl context */ +#endif + DeleteDC(win->src.hdc); /* delete device context */ + DestroyWindow(win->src.window); /* delete window */ + +#if defined(RGFW_OSMESA) + if (win->buffer != NULL) + RGFW_FREE(win->buffer); +#endif + +#ifdef RGFW_ALLOC_DROPFILES + { + u32 i; + for (i = 0; i < RGFW_MAX_DROPS; i++) + RGFW_FREE(win->event.droppedFiles[i]); + + + RGFW_FREE(win->event.droppedFiles); + } +#endif + + RGFW_FREE(win); + } + + void RGFW_window_move(RGFW_window* win, RGFW_vector v) { + assert(win != NULL); + + win->r.x = v.x; + win->r.y = v.y; + SetWindowPos(win->src.window, HWND_TOP, win->r.x, win->r.y, 0, 0, SWP_NOSIZE); + } + + void RGFW_window_resize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + + win->r.w = a.w; + win->r.h = a.h; + SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w, win->r.h + win->src.hOffset, SWP_NOMOVE); + } + + + void RGFW_window_setName(RGFW_window* win, char* name) { + assert(win != NULL); + + SetWindowTextA(win->src.window, name); + } + + /* much of this function is sourced from GLFW */ + void RGFW_window_setIcon(RGFW_window* win, u8* src, RGFW_area a, i32 channels) { + assert(win != NULL); + + HICON handle = RGFW_loadHandleImage(win, src, a, TRUE); + + SetClassLongPtrA(win->src.window, GCLP_HICON, (LPARAM) handle); + + DestroyIcon(handle); + } + + char* RGFW_readClipboard(size_t* size) { + /* Open the clipboard */ + if (OpenClipboard(NULL) == 0) + return (char*) ""; + + /* Get the clipboard data as a Unicode string */ + HANDLE hData = GetClipboardData(CF_UNICODETEXT); + if (hData == NULL) { + CloseClipboard(); + return (char*) ""; + } + + wchar_t* wstr = (wchar_t*) GlobalLock(hData); + + char* text; + + { + setlocale(LC_ALL, "en_US.UTF-8"); + + size_t textLen = wcstombs(NULL, wstr, 0); + if (textLen == 0) + return (char*) ""; + + text = (char*) malloc((textLen * sizeof(char)) + 1); + + wcstombs(text, wstr, (textLen) +1); + + if (size != NULL) + *size = textLen + 1; + } + + /* Release the clipboard data */ + GlobalUnlock(hData); + CloseClipboard(); + + return text; + } + + void RGFW_writeClipboard(const char* text, u32 textLen) { + HANDLE object; + WCHAR* buffer; + + object = GlobalAlloc(GMEM_MOVEABLE, (1 + textLen) * sizeof(WCHAR)); + if (!object) + return; + + buffer = (WCHAR*) GlobalLock(object); + if (!buffer) { + GlobalFree(object); + return; + } + + MultiByteToWideChar(CP_UTF8, 0, text, -1, buffer, textLen); + GlobalUnlock(object); + + if (!OpenClipboard(RGFW_root->src.window)) { + GlobalFree(object); + return; + } + + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, object); + CloseClipboard(); + } + + u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { + assert(win != NULL); + + return RGFW_registerJoystickF(win, (char*) ""); + } + + u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + assert(win != NULL); + + + return win->src.joystickCount - 1; + } + + void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector p) { + assert(win != NULL); + + SetCursorPos(p.x, p.y); + } + + char* createUTF8FromWideStringWin32(const WCHAR* source) { + char* target; + i32 size; + + size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); + if (!size) { + return NULL; + } + + target = (char*) RGFW_CALLOC(size, 1); + + if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) { + RGFW_FREE(target); + return NULL; + } + + return target; + } + +#ifndef RGFW_NO_THREADS + RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args) { return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) *function_ptr, args, 0, NULL); } + void RGFW_cancelThread(RGFW_thread thread) { CloseHandle((HANDLE) thread); } + void RGFW_joinThread(RGFW_thread thread) { WaitForSingleObject((HANDLE) thread, INFINITE); } + void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { SetThreadPriority((HANDLE) thread, priority); } +#endif +#endif + +#if defined(RGFW_MACOS) + + void* RGFWnsglFramework = NULL; + +#ifdef RGFW_OPENGL + void* RGFW_getProcAddress(const char* procname) { + if (RGFWnsglFramework == NULL) + RGFWnsglFramework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); + + CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, procname, kCFStringEncodingASCII); + + void* symbol = CFBundleGetFunctionPointerForName(RGFWnsglFramework, symbolName); + + CFRelease(symbolName); + + return symbol; + } +#endif + + CVReturn displayCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) { return kCVReturnSuccess; } + + RGFW_window* RGFW_windows[10]; + u32 RGFW_windows_size = 0; + + id NSWindow_delegate(RGFW_window* win) { + return (id) objc_msgSend_id(win->src.window, sel_registerName("delegate")); + } + + u32 RGFW_OnClose(void* self) { + u32 i; + for (i = 0; i < RGFW_windows_size; i++) + if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) { + RGFW_windows[i]->event.type = RGFW_quit; + return true; + } + + return true; + } + + /* NOTE(EimaMei): Fixes the constant clicking when the app is running under a terminal. */ + bool acceptsFirstResponder() { return true; } + bool performKeyEquivalent(NSEvent* event) { return true; } + + NSDragOperation draggingEntered(id self, SEL sel, id sender) { return NSDragOperationCopy; } + NSDragOperation draggingUpdated(id self, SEL sel, id sender) { return NSDragOperationCopy; } + bool prepareForDragOperation(void) { return true; } + + void RGFW__osxDraggingEnded(id self, SEL sel, id sender) { return; } + + /* NOTE(EimaMei): Usually, you never need 'id self, SEL cmd' for C -> Obj-C methods. This isn't the case. */ + bool performDragOperation(id self, SEL sel, id sender) { + NSWindow* window = objc_msgSend_id(sender, sel_registerName("draggingDestinationWindow")); + u32 i; + bool found = false; + + for (i = 0; i < RGFW_windows_size; i++) + if (RGFW_windows[i]->src.window == window) { + found = true; + break; + } + + if (!found) + i = 0; + + Class* array[] = { objc_getClass("NSURL"), NULL }; + char** droppedFiles = (char**) NSPasteboard_readObjectsForClasses( + (NSPasteboard*) objc_msgSend_id(sender, sel_registerName("draggingPasteboard")), + array, 1, NULL); + + RGFW_windows[i]->event.droppedFilesCount = si_array_len(droppedFiles); + + u32 y; + + for (y = 0; y < RGFW_windows[i]->event.droppedFilesCount; y++) + strcpy(RGFW_windows[i]->event.droppedFiles[y], droppedFiles[y]); + + RGFW_windows[i]->event.type = RGFW_dnd; + + NSPoint p = *(NSPoint*) objc_msgSend_id(sender, sel_registerName("draggingLocation")); + RGFW_windows[i]->event.point.x = p.x; + RGFW_windows[i]->event.point.x = p.y; + + return true; + } + + + NSApplication* NSApp = NULL; + + static void NSMoveToResourceDir(void) { + /* sourced from glfw */ + char resourcesPath[255]; + + CFBundleRef bundle = CFBundleGetMainBundle(); + if (!bundle) + return; + + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle); + CFStringRef last = CFURLCopyLastPathComponent(resourcesURL); + + if ( + CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo || + CFURLGetFileSystemRepresentation(resourcesURL, true, (u8*) resourcesPath, 255) == 0 + ) { + CFRelease(last); + CFRelease(resourcesURL); + return; + } + + CFRelease(last); + CFRelease(resourcesURL); + + chdir(resourcesPath); + } + + + NSSize RGFW__osxWindowResize(void* self, SEL sel, NSSize frameSize) { + u32 i; + for (i = 0; i < RGFW_windows_size; i++) { + if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) { + RGFW_windows[i]->r.w = frameSize.width; + RGFW_windows[i]->r.h = frameSize.height; + RGFW_windows[i]->event.type = RGFW_windowAttribsChange; + + return frameSize; + } + } + + return frameSize; + } + + void RGFW__osxWindowMove(void* self, SEL sel) { + u32 i; + for (i = 0; i < RGFW_windows_size; i++) { + if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) { + NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)(RGFW_windows[i]->src.window, sel_registerName("frame")); + RGFW_windows[i]->r.x = (i32) frame.origin.x; + RGFW_windows[i]->r.y = (i32) frame.origin.y; + + RGFW_windows[i]->event.type = RGFW_windowAttribsChange; + return; + } + } + } + + #ifdef __cplusplus + #define APPKIT_EXTERN extern "C" + #else + #define APPKIT_EXTERN extern + #endif + + APPKIT_EXTERN NSPasteboardType const NSPasteboardTypeURL = "public.url"; API_AVAILABLE(macos(10.13)); // Equivalent to kUTTypeURL + APPKIT_EXTERN NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url"; API_AVAILABLE(macos(10.13)); // Equivalent to kUTTypeFileURL + + RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) { + static u8 RGFW_loaded = 0; + + /* NOTE(EimaMei): Why does Apple hate good code? Like wtf, who thought of methods being a great idea??? + Imagine a universe, where MacOS had a proper system API (we would probably have like 20% better performance). + */ + si_func_to_SEL_with_name("NSObject", "windowShouldClose", RGFW_OnClose); + + /* NOTE(EimaMei): Fixes the 'Boop' sfx from constantly playing each time you click a key. Only a problem when running in the terminal. */ + si_func_to_SEL("NSWindow", acceptsFirstResponder); + si_func_to_SEL("NSWindow", performKeyEquivalent); + + if (NSApp == NULL) { + NSApp = objc_msgSend_id(objc_getClass("NSApplication"), sel_registerName("sharedApplication")); + + ((void (*)(id, SEL, NSUInteger))objc_msgSend) + (NSApp, sel_registerName("setActivationPolicy:"), NSApplicationActivationPolicyRegular); + } + + RGFW_window* win = RGFW_window_basic_init(rect, args); + + NSRect windowRect; + windowRect.origin.x = win->r.x; + windowRect.origin.y = win->r.y; + windowRect.size.width = win->r.w; + windowRect.size.height = win->r.h; + + NSBackingStoreType macArgs = NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSBackingStoreBuffered | NSWindowStyleMaskTitled; + + if (!(args & RGFW_NO_RESIZE)) + macArgs |= NSWindowStyleMaskResizable; + if (!(args & RGFW_NO_BORDER)) + macArgs |= NSWindowStyleMaskTitled; + else + macArgs = NSWindowStyleMaskBorderless; + { + void* nsclass = objc_getClass("NSWindow"); + void* func = sel_registerName("initWithContentRect:styleMask:backing:defer:"); + + win->src.window = ((id(*)(id, SEL, NSRect, NSWindowStyleMask, NSBackingStoreType, bool))objc_msgSend) + (NSAlloc(nsclass), func, windowRect, macArgs, macArgs, false); + } + + NSString* str = NSString_stringWithUTF8String(name); + objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str); + +#ifdef RGFW_OPENGL + void* attrs = RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE); + void* format = NSOpenGLPixelFormat_initWithAttributes(attrs); + + if (format == NULL) { + printf("Failed to load pixel format "); + + void* attrs = RGFW_initAttribs(1); + format = NSOpenGLPixelFormat_initWithAttributes(attrs); + if (format == NULL) + printf("and loading software rendering OpenGL failed\n"); + else + printf("Switching to software rendering\n"); + } + + win->src.view = NSOpenGLView_initWithFrame(NSMakeRect(0, 0, win->r.w, win->r.h), format); + objc_msgSend_void(win->src.view, sel_registerName("prepareOpenGL")); + win->src.rSurf = objc_msgSend_id(win->src.view, sel_registerName("openGLContext")); + +#else + NSRect contentRect = NSMakeRect(0, 0, win->r.w, win->r.h); + win->src.view = ((id(*)(id, SEL, NSRect))objc_msgSend) + (NSAlloc(objc_getClass("NSView")), sel_registerName("initWithFrame:"), + contentRect); +#endif + + + void* contentView = NSWindow_contentView(win->src.window); + objc_msgSend_void_bool(contentView, sel_registerName("setWantsLayer:"), true); + + objc_msgSend_void_id(win->src.window, sel_registerName("setContentView:"), win->src.view); + +#ifdef RGFW_OPENGL + objc_msgSend_void(win->src.rSurf, sel_registerName("makeCurrentContext")); +#endif + if (args & RGFW_TRANSPARENT_WINDOW) { +#ifdef RGFW_OPENGL + i32 opacity = 0; + NSOpenGLContext_setValues(win->src.rSurf, &opacity, 304); +#endif + + objc_msgSend_void_bool(win->src.window, sel_registerName("setOpaque:"), false); + + objc_msgSend_void_id(win->src.window, sel_registerName("setBackgroundColor:"), + NSColor_colorWithSRGB(0, 0, 0, 0)); + + ((void (*)(id, SEL, CGFloat))objc_msgSend) + (win->src.window, sel_registerName("setAlphaValue:"), 0x00); + } + + win->src.display = CGMainDisplayID(); + CVDisplayLinkCreateWithCGDisplay(win->src.display, &win->src.displayLink); + CVDisplayLinkSetOutputCallback(win->src.displayLink, displayCallback, win); + CVDisplayLinkStart(win->src.displayLink); + + RGFW_init_buffer(win); + +#ifdef RGFW_VULKAN + RGFW_initVulkan(win); +#endif + + if (args & RGFW_SCALE_TO_MONITOR) + RGFW_window_scaleToMonitor(win); + + if (args & RGFW_HIDE_MOUSE) + RGFW_window_showMouse(win, 0); + + if (args & RGFW_COCOA_MOVE_TO_RESOURCE_DIR) + NSMoveToResourceDir(); + + Class delegateClass = objc_allocateClassPair(objc_getClass("NSObject"), "WindowDelegate", 0); + class_addMethod(delegateClass, sel_registerName("windowWillResize:toSize:"), (IMP) RGFW__osxWindowResize, "{NSSize=ff}@:{NSSize=ff}"); + class_addMethod(delegateClass, sel_registerName("windowWillMove:"), (IMP) RGFW__osxWindowMove, ""); + class_addMethod(delegateClass, sel_registerName("windowDidMove:"), (IMP) RGFW__osxWindowMove, ""); + + + if (args & RGFW_ALLOW_DND) { + win->src.winArgs |= RGFW_ALLOW_DND; + +/* + NSPasteboardType types[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString}; + + siArray(NSPasteboardType) array = sic_arrayInit(types, sizeof(id), countof(types)); + NSWindow_registerForDraggedTypes(win->hwnd, array); + + win->dndHead = win->dndPrev = out; +*/ + + NSPasteboardType array[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString}; + NSregisterForDraggedTypes(win->src.window, array, 3); + + /* NOTE(EimaMei): Drag 'n Drop requires too many damn functions for just a Drag 'n Drop event. */ + class_addMethod(delegateClass, "draggingEntered:", draggingEntered, "l@:@"); + class_addMethod(delegateClass, "draggingUpdated:", draggingUpdated, "l@:@"); + class_addMethod(delegateClass, "draggingExited:", RGFW__osxDraggingEnded, "v@:@"); + class_addMethod(delegateClass, "draggingEnded:", RGFW__osxDraggingEnded, "v@:@"); + class_addMethod(delegateClass, "prepareForDragOperation:", prepareForDragOperation, "B@:@"); + class_addMethod(delegateClass, "performDragOperation:", performDragOperation, "B@:@"); + + } + + id delegate = objc_msgSend_id(NSAlloc(delegateClass), sel_registerName("init")); + + object_setInstanceVariable(delegate, "RGFW_window", win); + + objc_msgSend_void_id(win->src.window, sel_registerName("setDelegate:"), delegate); + + // Show the window + ((id(*)(id, SEL, SEL))objc_msgSend)(win->src.window, sel_registerName("makeKeyAndOrderFront:"), NULL); + objc_msgSend_void_bool(win->src.window, sel_registerName("setIsVisible:"), true); + + if (!RGFW_loaded) { + objc_msgSend_void(win->src.window, sel_registerName("makeMainWindow")); + + RGFW_loaded = 1; + } + + NSApplication_finishLaunching(NSApp); + + RGFW_windows_size++; + + size_t i; + for (i = 0; i < RGFW_windows_size; i++) + if (!RGFW_windows[i]) { + RGFW_windows[i] = win; + break; + } + + if (RGFW_root == NULL) + RGFW_root = win; + + NSRetain(win->src.window); + NSRetain(NSApp); + + return win; + } + + + RGFW_area RGFW_getScreenSize(void) { + static CGDirectDisplayID display = 0; + + if (display == 0) + display = CGMainDisplayID(); + + return RGFW_AREA(CGDisplayPixelsWide(display), CGDisplayPixelsHigh(display)); + } + + RGFW_vector RGFW_getGlobalMousePoint(void) { + assert(RGFW_root != NULL); + + CGEventRef e = CGEventCreate(NULL); + CGPoint point = CGEventGetLocation(e); + CFRelease(e); + + return RGFW_VECTOR((u32) point.x, (u32) point.y); /* the point is loaded during event checks */ + } + + u32 RGFW_keysPressed[10]; /*10 keys at a time*/ + typedef NS_ENUM(u32, NSEventType) { /* various types of events */ + NSEventTypeLeftMouseDown = 1, + NSEventTypeLeftMouseUp = 2, + NSEventTypeRightMouseDown = 3, + NSEventTypeRightMouseUp = 4, + NSEventTypeMouseMoved = 5, + NSEventTypeLeftMouseDragged = 6, + NSEventTypeRightMouseDragged = 7, + NSEventTypeMouseEntered = 8, + NSEventTypeMouseExited = 9, + NSEventTypeKeyDown = 10, + NSEventTypeKeyUp = 11, + NSEventTypeFlagsChanged = 12, + NSEventTypeAppKitDefined = 13, + NSEventTypeSystemDefined = 14, + NSEventTypeApplicationDefined = 15, + NSEventTypePeriodic = 16, + NSEventTypeCursorUpdate = 17, + NSEventTypeScrollWheel = 22, + NSEventTypeTabletPoint = 23, + NSEventTypeTabletProximity = 24, + NSEventTypeOtherMouseDown = 25, + NSEventTypeOtherMouseUp = 26, + NSEventTypeOtherMouseDragged = 27, + /* The following event types are available on some hardware on 10.5.2 and later */ + NSEventTypeGesture API_AVAILABLE(macos(10.5)) = 29, + NSEventTypeMagnify API_AVAILABLE(macos(10.5)) = 30, + NSEventTypeSwipe API_AVAILABLE(macos(10.5)) = 31, + NSEventTypeRotate API_AVAILABLE(macos(10.5)) = 18, + NSEventTypeBeginGesture API_AVAILABLE(macos(10.5)) = 19, + NSEventTypeEndGesture API_AVAILABLE(macos(10.5)) = 20, + + NSEventTypeSmartMagnify API_AVAILABLE(macos(10.8)) = 32, + NSEventTypeQuickLook API_AVAILABLE(macos(10.8)) = 33, + + NSEventTypePressure API_AVAILABLE(macos(10.10.3)) = 34, + NSEventTypeDirectTouch API_AVAILABLE(macos(10.10)) = 37, + + NSEventTypeChangeMode API_AVAILABLE(macos(10.15)) = 38, + }; + + typedef NS_ENUM(unsigned long long, NSEventMask) { /* masks for the types of events */ + NSEventMaskLeftMouseDown = 1ULL << NSEventTypeLeftMouseDown, + NSEventMaskLeftMouseUp = 1ULL << NSEventTypeLeftMouseUp, + NSEventMaskRightMouseDown = 1ULL << NSEventTypeRightMouseDown, + NSEventMaskRightMouseUp = 1ULL << NSEventTypeRightMouseUp, + NSEventMaskMouseMoved = 1ULL << NSEventTypeMouseMoved, + NSEventMaskLeftMouseDragged = 1ULL << NSEventTypeLeftMouseDragged, + NSEventMaskRightMouseDragged = 1ULL << NSEventTypeRightMouseDragged, + NSEventMaskMouseEntered = 1ULL << NSEventTypeMouseEntered, + NSEventMaskMouseExited = 1ULL << NSEventTypeMouseExited, + NSEventMaskKeyDown = 1ULL << NSEventTypeKeyDown, + NSEventMaskKeyUp = 1ULL << NSEventTypeKeyUp, + NSEventMaskFlagsChanged = 1ULL << NSEventTypeFlagsChanged, + NSEventMaskAppKitDefined = 1ULL << NSEventTypeAppKitDefined, + NSEventMaskSystemDefined = 1ULL << NSEventTypeSystemDefined, + NSEventMaskApplicationDefined = 1ULL << NSEventTypeApplicationDefined, + NSEventMaskPeriodic = 1ULL << NSEventTypePeriodic, + NSEventMaskCursorUpdate = 1ULL << NSEventTypeCursorUpdate, + NSEventMaskScrollWheel = 1ULL << NSEventTypeScrollWheel, + NSEventMaskTabletPoint = 1ULL << NSEventTypeTabletPoint, + NSEventMaskTabletProximity = 1ULL << NSEventTypeTabletProximity, + NSEventMaskOtherMouseDown = 1ULL << NSEventTypeOtherMouseDown, + NSEventMaskOtherMouseUp = 1ULL << NSEventTypeOtherMouseUp, + NSEventMaskOtherMouseDragged = 1ULL << NSEventTypeOtherMouseDragged, + /* The following event masks are available on some hardware on 10.5.2 and later */ + NSEventMaskGesture API_AVAILABLE(macos(10.5)) = 1ULL << NSEventTypeGesture, + NSEventMaskMagnify API_AVAILABLE(macos(10.5)) = 1ULL << NSEventTypeMagnify, + NSEventMaskSwipe API_AVAILABLE(macos(10.5)) = 1ULL << NSEventTypeSwipe, + NSEventMaskRotate API_AVAILABLE(macos(10.5)) = 1ULL << NSEventTypeRotate, + NSEventMaskBeginGesture API_AVAILABLE(macos(10.5)) = 1ULL << NSEventTypeBeginGesture, + NSEventMaskEndGesture API_AVAILABLE(macos(10.5)) = 1ULL << NSEventTypeEndGesture, + + /* Note: You can only use these event masks on 64 bit. In other words, you cannot setup a local, nor global, event monitor for these event types on 32 bit. Also, you cannot search the event queue for them (nextEventMatchingMask:...) on 32 bit. + */ + NSEventMaskSmartMagnify API_AVAILABLE(macos(10.8)) = 1ULL << NSEventTypeSmartMagnify, + NSEventMaskPressure API_AVAILABLE(macos(10.10.3)) = 1ULL << NSEventTypePressure, + NSEventMaskDirectTouch API_AVAILABLE(macos(10.12.2)) = 1ULL << NSEventTypeDirectTouch, + + NSEventMaskChangeMode API_AVAILABLE(macos(10.15)) = 1ULL << NSEventTypeChangeMode, + + NSEventMaskAny = ULONG_MAX, + + }; + + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { + assert(win != NULL); + + if (win->event.type == RGFW_quit) + return &win->event; + + static void* eventFunc = NULL; + if (eventFunc == NULL) + eventFunc = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:"); + + if (win->event.type == RGFW_windowAttribsChange && win->event.keyCode != 120) { + win->event.keyCode = 120; + return &win->event; + } + + NSEvent* e = (NSEvent*) ((id(*)(id, SEL, NSEventMask, void*, NSString*, bool))objc_msgSend) + (NSApp, eventFunc, ULONG_MAX, NULL, NSString_stringWithUTF8String("kCFRunLoopDefaultMode"), true); + + + if (e == NULL) + return NULL; + + if (objc_msgSend_id(e, sel_registerName("window")) != win->src.window) { + ((void (*)(id, SEL, id, bool))objc_msgSend) + (NSApp, sel_registerName("postEvent:atStart:"), e, 0); + + return NULL; + } + + if (win->event.droppedFilesCount) { + u32 i; + for (i = 0; i < win->event.droppedFilesCount; i++) + win->event.droppedFiles[i][0] = '\0'; + } + + win->event.droppedFilesCount = 0; + win->event.type = 0; + + win->event.inFocus = (bool) objc_msgSend_bool(win->src.window, sel_registerName("isKeyWindow")); + + switch (objc_msgSend_uint(e, sel_registerName("type"))) { + case NSEventTypeKeyDown: + win->event.type = RGFW_keyPressed; + win->event.keyCode = (u16) objc_msgSend_uint(e, sel_registerName("keyCode")); + win->event.keyName = (const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters"))); + + RGFW_keyMap[win->event.keyCode] = 1; + break; + + case NSEventTypeKeyUp: + win->event.type = RGFW_keyReleased; + win->event.keyCode = (u16) objc_msgSend_uint(e, sel_registerName("keyCode")); + win->event.keyName = (const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters"))); + + RGFW_keyMap[win->event.keyCode] = 0; + break; + + case NSEventTypeLeftMouseDragged: + case NSEventTypeOtherMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeMouseMoved: + win->event.type = RGFW_mousePosChanged; + NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName("locationInWindow")); + + win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y)); + + if (win->src.winArgs & RGFW_HOLD_MOUSE) { + RGFW_vector mouse = RGFW_getGlobalMousePoint(); + if ((mouse.x != win->r.x + (win->r.w / 2) || mouse.y != win->r.y + (win->r.h / 2))) { + RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + } + } + break; + + case NSEventTypeLeftMouseDown: + win->event.button = RGFW_mouseLeft; + win->event.type = RGFW_mouseButtonPressed; + break; + + case NSEventTypeOtherMouseDown: + win->event.button = RGFW_mouseMiddle; + win->event.type = RGFW_mouseButtonPressed; + break; + + case NSEventTypeRightMouseDown: + win->event.button = RGFW_mouseRight; + win->event.type = RGFW_mouseButtonPressed; + break; + + case NSEventTypeLeftMouseUp: + win->event.button = RGFW_mouseLeft; + win->event.type = RGFW_mouseButtonReleased; + break; + + case NSEventTypeOtherMouseUp: + win->event.button = RGFW_mouseMiddle; + win->event.type = RGFW_mouseButtonReleased; + break; + + case NSEventTypeScrollWheel: { + double deltaY = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaY")); + + if (deltaY > 0) + win->event.button = RGFW_mouseScrollUp; + + else if (deltaY < 0) + win->event.button = RGFW_mouseScrollDown; + + win->event.scroll = deltaY; + + win->event.type = RGFW_mouseButtonReleased; + break; + } + case NSEventTypeRightMouseUp: + win->event.button = RGFW_mouseRight; + win->event.type = RGFW_mouseButtonReleased; + break; + + default: + break; + } + + objc_msgSend_void_id(NSApp, sel_registerName("sendEvent:"), e); + + return &win->event; + } + + + void RGFW_window_move(RGFW_window* win, RGFW_vector v) { + assert(win != NULL); + + win->r.x = v.x; + win->r.y = v.y; + ((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend) + (win->src.window, sel_registerName("setFrame:display:animate:"), NSMakeRect(win->r.x, win->r.y, win->r.w, win->r.h), true, true); + } + + void RGFW_window_resize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + + win->r.w = a.w; + win->r.h = a.h; + ((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend) + (win->src.window, sel_registerName("setFrame:display:animate:"), NSMakeRect(win->r.x, win->r.y, win->r.w, win->r.h), true, true); + } + + void RGFW_window_minimize(RGFW_window* win) { + assert(win != NULL); + + objc_msgSend_void_SEL(win->src.window, sel_registerName("performMiniaturize:"), NULL); + } + + void RGFW_window_restore(RGFW_window* win) { + assert(win != NULL); + + objc_msgSend_void_SEL(win->src.window, sel_registerName("deminiaturize:"), NULL); + } + + void RGFW_window_setName(RGFW_window* win, char* name) { + assert(win != NULL); + + NSString* str = NSString_stringWithUTF8String(name); + objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str); + } + + void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) { + ((void (*)(id, SEL, NSSize))objc_msgSend) + (win->src.window, sel_registerName("setMinSize:"), NSMakeSize(a.w, a.h)); + } + + void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) { + ((void (*)(id, SEL, NSSize))objc_msgSend) + (win->src.window, sel_registerName("setMaxSize:"), NSMakeSize(a.w, a.h)); + } + + void RGFW_window_setIcon(RGFW_window* win, u8* data, RGFW_area area, i32 channels) { + assert(win != NULL); + + /* code by EimaMei */ + // Make a bitmap representation, then copy the loaded image into it. + void* representation = NSBitmapImageRep_initWithBitmapData(NULL, area.w, area.h, 8, channels, (channels == 4), false, "NSCalibratedRGBColorSpace", 1 << 1, area.w * channels, 8 * channels); + memcpy(NSBitmapImageRep_bitmapData(representation), data, area.w * area.h * channels); + + // Add ze representation. + void* dock_image = NSImage_initWithSize(NSMakeSize(area.w, area.h)); + NSImage_addRepresentation(dock_image, (void*) representation); + + // Finally, set the dock image to it. + objc_msgSend_void_id(NSApp, sel_registerName("setApplicationIconImage:"), dock_image); + // Free the garbage. + release(dock_image); + release(representation); + } + + NSCursor* NSCursor_arrowStr(char* str) { + void* nclass = objc_getClass("NSCursor"); + void* func = sel_registerName(str); + return (NSCursor*) objc_msgSend_id(nclass, func); + } + + void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) { + assert(win != NULL); + + if (image == NULL) { + objc_msgSend_void(NSCursor_arrowStr("arrowCursor"), sel_registerName("set")); + return; + } + + /* NOTE(EimaMei): Code by yours truly. */ + // Make a bitmap representation, then copy the loaded image into it. + void* representation = NSBitmapImageRep_initWithBitmapData(NULL, a.w, a.h, 8, channels, (channels == 4), false, "NSCalibratedRGBColorSpace", 1 << 1, a.w * channels, 8 * channels); + memcpy(NSBitmapImageRep_bitmapData(representation), image, a.w * a.h * channels); + + // Add ze representation. + void* cursor_image = NSImage_initWithSize(NSMakeSize(a.w, a.h)); + NSImage_addRepresentation(cursor_image, representation); + + // Finally, set the cursor image. + void* cursor = NSCursor_initWithImage(cursor_image, NSMakePoint(0, 0)); + + objc_msgSend_void(cursor, sel_registerName("set")); + + // Free the garbage. + release(cursor_image); + release(representation); + } + + void RGFW_window_setMouseDefault(RGFW_window* win) { + RGFW_window_setMouseStandard(win, NSCursor_arrowStr("arrowCursor")); + } + + void RGFW_window_showMouse(RGFW_window* win, i8 show) { + if (show) { + CGDisplayShowCursor(kCGDirectMainDisplay); + } + else { + CGDisplayHideCursor(kCGDirectMainDisplay); + } + } + + void RGFW_window_setMouseStandard(RGFW_window* win, void* mouse) { + CGDisplayShowCursor(kCGDirectMainDisplay); + objc_msgSend_void(mouse, sel_registerName("set")); + } + + void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v) { + assert(win != NULL); + + CGWarpMouseCursorPosition(CGPointMake(v.x, v.y)); + } + + + void RGFW_window_hide(RGFW_window* win) { + objc_msgSend_void_bool(win->src.window, sel_registerName("setIsVisible:"), false); + } + + void RGFW_window_show(RGFW_window* win) { + ((id(*)(id, SEL, SEL))objc_msgSend)(win->src.window, sel_registerName("makeKeyAndOrderFront:"), NULL); + objc_msgSend_void_bool(win->src.window, sel_registerName("setIsVisible:"), true); + } + + u8 RGFW_window_isFullscreen(RGFW_window* win) { + assert(win != NULL); + + NSWindowStyleMask mask = (NSWindowStyleMask) objc_msgSend_uint(win->src.window, sel_registerName("styleMask")); + return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen; + } + + u8 RGFW_window_isHidden(RGFW_window* win) { + assert(win != NULL); + + bool visible = objc_msgSend_bool(win->src.window, sel_registerName("isVisible")); + return visible == NO && !RGFW_window_isMinimized(win); + } + + u8 RGFW_window_isMinimized(RGFW_window* win) { + assert(win != NULL); + + return objc_msgSend_bool(win->src.window, sel_registerName("isMiniaturized")) == YES; + } + + u8 RGFW_window_isMaximized(RGFW_window* win) { + assert(win != NULL); + + return objc_msgSend_bool(win->src.window, sel_registerName("isZoomed")); + } + + static RGFW_monitor RGFW_NSCreateMonitor(CGDirectDisplayID display) { + RGFW_monitor monitor; + + CGRect bounds = CGDisplayBounds(display); + monitor.rect = RGFW_RECT((int) bounds.origin.x, (int) bounds.origin.y, (int) bounds.size.width, (int) bounds.size.height); + + CGSize screenSizeMM = CGDisplayScreenSize(display); + monitor.physW = screenSizeMM.width / 25.4; + monitor.physH = screenSizeMM.height / 25.4; + + monitor.scaleX = (monitor.rect.w / (screenSizeMM.width)) / 2.6; + monitor.scaleY = (monitor.rect.h / (screenSizeMM.height)) / 2.6; + + snprintf(monitor.name, 128, "%i %i %i", CGDisplayModelNumber(display), CGDisplayVendorNumber(display), CGDisplaySerialNumber(display)); + + return monitor; + } + + + static RGFW_monitor RGFW_monitors[7]; + + RGFW_monitor* RGFW_getMonitors(void) { + static CGDirectDisplayID displays[7]; + u32 count; + + if (CGGetActiveDisplayList(6, displays, &count) != kCGErrorSuccess) + return NULL; + + for (u32 i = 0; i < count; i++) + RGFW_monitors[i] = RGFW_NSCreateMonitor(displays[i]); + + return RGFW_monitors; + } + + RGFW_monitor RGFW_getPrimaryMonitor(void) { + CGDirectDisplayID primary = CGMainDisplayID(); + return RGFW_NSCreateMonitor(primary); + } + + RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) { + return RGFW_NSCreateMonitor(win->src.display); + } + + u8 RGFW_isPressedI(RGFW_window* win, u32 key) { + if (key >= 128) { +#ifdef RGFW_PRINT_ERRORS + fprintf(stderr, "RGFW_isPressedI : invalid keycode\n"); +#endif + RGFW_error = 1; + } + + return RGFW_keyMap[key]; + } + +#ifdef __cplusplus +#define APPKIT_EXTERN extern "C" +#else +#define APPKIT_EXTERN extern +#endif + + char* RGFW_readClipboard(size_t* size) { + char* str = strdup((char*) NSPasteboard_stringForType(NSPasteboard_generalPasteboard(), NSPasteboardTypeString)); + if (size != NULL) + *size = strlen(str); + return str; + } + + void RGFW_writeClipboard(const char* text, u32 textLen) { + NSPasteboardType array[] = { NSPasteboardTypeString, NULL }; + NSPasteBoard_declareTypes(NSPasteboard_generalPasteboard(), array, 1, NULL); + + NSPasteBoard_setString(NSPasteboard_generalPasteboard(), text, NSPasteboardTypeString); + } + + u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { + assert(win != NULL); + + return RGFW_registerJoystickF(win, (char*) ""); + } + + u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + assert(win != NULL); + + return win->src.joystickCount - 1; + } + + void RGFW_window_close(RGFW_window* win) { + assert(win != NULL); + +#ifdef RGFW_VULKAN + for (int i = 0; i < win->src.image_count; i++) { + vkDestroyFramebuffer(RGFW_vulkan_info.device, RGFW_vulkan_info.framebuffers[i], NULL); + } + + for (int i = 0; i < win->src.image_count; i++) { + vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL); + } + + vkDestroySwapchainKHR(RGFW_vulkan_info.device, win->src.swapchain, NULL); + vkDestroySurfaceKHR(RGFW_vulkan_info.instance, win->src.rSurf, NULL); + free(win->src.swapchain_image_views); + free(win->src.swapchain_images); +#endif + + release(win->src.view); + +#ifdef RGFW_ALLOC_DROPFILES + { + u32 i; + for (i = 0; i < RGFW_MAX_DROPS; i++) + RGFW_FREE(win->event.droppedFiles[i]); + + + RGFW_FREE(win->event.droppedFiles); + } +#endif + + u32 i; + for (i = 0; i < RGFW_windows_size; i++) + if (RGFW_windows[i]->src.window == win->src.window) { + RGFW_windows[i] = NULL; + break; + } + + if (!i) { + RGFW_windows_size = 0; + + objc_msgSend_void_id(NSApp, sel_registerName("terminate:"), (id) win->src.window); + NSApp = NULL; + } + +#ifdef RGFW_BUFFER + release(win->src.bitmap); + release(win->src.image); +#endif + + CVDisplayLinkStop(win->src.displayLink); + CVDisplayLinkRelease(win->src.displayLink); + + free(win); + } +#endif + +#if defined(RGFW_X11) || defined(RGFW_MACOS) + +#ifndef RGFW_NO_THREADS +#include + + RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args) { + RGFW_thread t; + pthread_create((pthread_t*) &t, NULL, *function_ptr, NULL); + return t; + } + void RGFW_cancelThread(RGFW_thread thread) { pthread_cancel((pthread_t) thread); } + void RGFW_joinThread(RGFW_thread thread) { pthread_join((pthread_t) thread, NULL); } +#ifdef __linux__ + void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { pthread_setschedprio(thread, priority); } +#endif +#endif +#endif + + void RGFW_window_makeCurrent_OpenGL(RGFW_window* win) { + assert(win != NULL); + +#ifdef RGFW_OPENGL +#ifdef RGFW_X11 + glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.rSurf); +#endif +#ifdef RGFW_WINDOWS + wglMakeCurrent(win->src.hdc, (HGLRC) win->src.rSurf); +#endif +#if defined(RGFW_MACOS) + objc_msgSend_void(win->src.rSurf, sel_registerName("makeCurrentContext")); +#endif +#else +#ifdef RGFW_EGL + eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.rSurf); +#endif +#endif + + } + + void RGFW_window_makeCurrent(RGFW_window* win) { + assert(win != NULL); + +#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX) + RGFW_dxInfo.pDeviceContext->lpVtbl->OMSetRenderTargets(RGFW_dxInfo.pDeviceContext, 1, &win->src.renderTargetView, NULL); +#endif + +#ifdef RGFW_OPENGL + RGFW_window_makeCurrent_OpenGL(win); +#endif + } + + void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) { + assert(win != NULL); + +#ifdef RGFW_OPENGL +#ifdef RGFW_X11 + ((PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress((GLubyte*) "glXSwapIntervalEXT"))((Display*) win->src.display, (Window) win->src.window, swapInterval); +#endif +#ifdef RGFW_WINDOWS + + typedef BOOL(APIENTRY* PFNWGLSWAPINTERVALEXTPROC)(int interval); + static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; + static void* loadSwapFunc = (void*) 1; + + if (loadSwapFunc == NULL) { + fprintf(stderr, "wglSwapIntervalEXT not supported\n"); + win->fpsCap = (swapInterval == 1) ? 0 : swapInterval; + return; + } + + if (wglSwapIntervalEXT == NULL) { + loadSwapFunc = (void*) wglGetProcAddress("wglSwapIntervalEXT"); + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) loadSwapFunc; + } + + if (wglSwapIntervalEXT(swapInterval) == FALSE) + fprintf(stderr, "Failed to set swap interval\n"); + +#endif +#if defined(RGFW_MACOS) + NSOpenGLContext_setValues(win->src.rSurf, &swapInterval, 222); +#endif +#endif + +#ifdef RGFW_EGL + eglSwapInterval(win->src.EGL_display, swapInterval); +#endif + + win->fpsCap = (swapInterval == 1) ? 0 : swapInterval; + + } + + void RGFW_window_setGPURender(RGFW_window* win, i8 set) { + if (!set && !(win->src.winArgs & RGFW_NO_GPU_RENDER)) + win->src.winArgs |= RGFW_NO_GPU_RENDER; + + else if (set && win->src.winArgs & RGFW_NO_GPU_RENDER) + win->src.winArgs ^= RGFW_NO_GPU_RENDER; + } + + void RGFW_window_setCPURender(RGFW_window* win, i8 set) { + if (!set && !(win->src.winArgs & RGFW_NO_CPU_RENDER)) + win->src.winArgs |= RGFW_NO_CPU_RENDER; + + else if (set && win->src.winArgs & RGFW_NO_CPU_RENDER) + win->src.winArgs ^= RGFW_NO_CPU_RENDER; + } + + + void RGFW_window_swapBuffers(RGFW_window* win) { + assert(win != NULL); + + win->event.frames++; + RGFW_window_checkFPS(win); + + RGFW_window_makeCurrent(win); + + /* clear the window*/ + + if (!(win->src.winArgs & RGFW_NO_CPU_RENDER)) { +#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER) +#ifdef RGFW_OSMESA + u8* row = (u8*) RGFW_MALLOC(win->r.w * 3); + + i32 half_height = win->r.h / 2; + i32 stride = win->r.w * 3; + + i32 y; + for (y = 0; y < half_height; ++y) { + i32 top_offset = y * stride; + i32 bottom_offset = (win->r.h - y - 1) * stride; + memcpy(row, win->buffer + top_offset, stride); + memcpy(win->buffer + top_offset, win->buffer + bottom_offset, stride); + memcpy(win->buffer + bottom_offset, row, stride); + } + + RGFW_FREE(row); +#endif + +#ifdef RGFW_X11 + RGFW_area area = RGFW_getScreenSize(); + +#ifndef RGFW_X11_DONT_CONVERT_BGR + win->src.bitmap->data = (const char*) win->buffer; + u32 x, y; + for (y = 0; y < win->r.h; y++) { + for (x = 0; x < win->r.w; x++) { + u32 index = (y * 4 * area.w) + x * 4; + + u8 red = win->src.bitmap->data[index]; + win->src.bitmap->data[index] = win->buffer[index + 2]; + win->src.bitmap->data[index + 2] = red; + } + } +#endif + + XPutImage(win->src.display, (Window) win->src.window, XDefaultGC(win->src.display, XDefaultScreen(win->src.display)), win->src.bitmap, 0, 0, 0, 0, win->r.w, win->r.h); +#endif +#ifdef RGFW_WINDOWS + HGDIOBJ oldbmp = SelectObject(win->src.hdcMem, win->src.bitmap); + BitBlt(win->src.hdc, 0, 0, win->r.w, win->r.h, win->src.hdcMem, 0, 0, SRCCOPY); + SelectObject(win->src.hdcMem, oldbmp); +#endif +#if defined(RGFW_MACOS) + RGFW_area area = RGFW_getScreenSize(); + void* view = NSWindow_contentView(win->src.window); + void* layer = objc_msgSend_id(view, sel_registerName("layer")); + + ((void(*)(id, SEL, NSRect))objc_msgSend)(layer, + sel_registerName("setFrame:"), + NSMakeRect(0, 0, win->r.w, win->r.h)); + + NSBitmapImageRep* rep = NSBitmapImageRep_initWithBitmapData( + &win->buffer, win->r.w, win->r.h, 8, 4, true, false, + "NSDeviceRGBColorSpace", 0, + area.w * 4, 32 + ); + id image = NSAlloc(objc_getClass("NSImage")); + NSImage_addRepresentation(image, rep); + objc_msgSend_void_id(layer, sel_registerName("setContents:"), (id) image); + + release(image); + release(rep); +#endif +#endif + +#ifdef RGFW_VULKAN +#ifdef RGFW_PRINT_ERRORS + fprintf(stderr, "RGFW_window_swapBuffers %s\n", "RGFW_window_swapBuffers is not yet supported for Vulkan"); + RGFW_error = 1; +#endif +#endif + } + + if (win->src.winArgs & RGFW_NO_GPU_RENDER) + return; + +#ifdef RGFW_OPENGL +#ifdef RGFW_EGL + eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface); +#else +#if defined(RGFW_X11) && defined(RGFW_OPENGL) + glXSwapBuffers((Display*) win->src.display, (Window) win->src.window); +#endif +#ifdef RGFW_WINDOWS + SwapBuffers(win->src.hdc); +#endif +#if defined(RGFW_MACOS) + NSOpenGLContext_flushBuffer(win->src.rSurf); +#endif +#endif +#endif + +#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX) + win->src.swapchain->lpVtbl->Present(win->src.swapchain, 0, 0); +#endif + } + + void RGFW_window_maximize(RGFW_window* win) { + assert(win != NULL); + + RGFW_area screen = RGFW_getScreenSize(); + + RGFW_window_move(win, RGFW_VECTOR(0, 0)); + RGFW_window_resize(win, screen); + } + + u8 RGFW_window_shouldClose(RGFW_window* win) { + assert(win != NULL); + + /* || RGFW_isPressedI(win, RGFW_Escape) */ + return (win->event.type == RGFW_quit || RGFW_isPressedI(win, RGFW_OS_BASED_VALUE(0xff1b, 0x1B, 53))); + } + + void RGFW_window_setShouldClose(RGFW_window* win) { win->event.type = RGFW_quit; } + + void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor m) { + RGFW_window_move(win, RGFW_VECTOR(m.rect.x + win->r.x, m.rect.y + win->r.y)); + } + + void RGFW_window_mouseHold(RGFW_window* win) { + win->src.winArgs |= RGFW_HOLD_MOUSE; + + #ifdef RGFW_WINDOWS + RECT rect = {win->r.x, win->r.y, win->r.x + win->r.w, win->r.y + win->r.h}; + ClipCursor(&rect); + #endif + } + + void RGFW_window_mouseUnhold(RGFW_window* win) { + win->src.winArgs ^= RGFW_HOLD_MOUSE; + + #ifdef RGFW_WINDOWS + ClipCursor(NULL); + #endif + } + + void RGFW_sleep(u32 ms) { +#if !defined(_MSC_VER) && !defined(__MINGW32__) + struct timespec time; + time.tv_sec = 0; + time.tv_nsec = ms * 1000; + + nanosleep(&time, NULL); +#else + Sleep(ms); +#endif + } + + static float currentFrameTime = 0; + + void RGFW_window_checkFPS(RGFW_window* win) { + assert(win != NULL); + + win->event.fps = RGFW_getFPS(); + + if (win->fpsCap == 0) + return; + + double targetFrameTime = 1.0 / win->fpsCap; + double elapsedTime = RGFW_getTime() - currentFrameTime; + + if (elapsedTime < targetFrameTime) { + u32 sleepTime = (u32) ((targetFrameTime - elapsedTime) * 1e3); + RGFW_sleep(sleepTime); + } + + currentFrameTime = (float) RGFW_getTime(); + + if (elapsedTime < targetFrameTime) { + u32 sleepTime = (u32) ((targetFrameTime - elapsedTime) * 1e3); + RGFW_sleep(sleepTime); + } + + currentFrameTime = (float) RGFW_getTime(); + } + +#ifdef __APPLE__ +#include +#endif + + u64 RGFW_getTimeNS(void) { +#ifdef RGFW_WINDOWS + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + + return (u64) (counter.QuadPart * 1e9 / frequency.QuadPart); +#elif defined(__unix__) + struct timespec ts = { 0 }; + clock_gettime(CLOCK_MONOTONIC, &ts); + unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; + + return nanoSeconds; +#elif defined(__APPLE__) + static mach_timebase_info_data_t timebase_info; + if (timebase_info.denom == 0) { + mach_timebase_info(&timebase_info); + } + return mach_absolute_time() * timebase_info.numer / timebase_info.denom; +#endif + return 0; + } + + u64 RGFW_getTime(void) { +#ifdef RGFW_WINDOWS + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + return (u64) (counter.QuadPart / (double) frequency.QuadPart); +#elif defined(__unix__) + struct timespec ts = { 0 }; + clock_gettime(CLOCK_MONOTONIC, &ts); + unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; + + return (double)(nanoSeconds) * 1e-9; +#elif defined(__APPLE__) + static mach_timebase_info_data_t timebase_info; + if (timebase_info.denom == 0) { + mach_timebase_info(&timebase_info); + } + return (double) mach_absolute_time() * (double) timebase_info.numer / ((double) timebase_info.denom * 1e9); +#endif + return 0; + } + + u32 RGFW_getFPS(void) { + static double previousSeconds = 0.0; + if (previousSeconds == 0.0) + previousSeconds = (double) RGFW_getTime();//glfwGetTime(); + + static i16 frameCount; + double currentSeconds = (double) RGFW_getTime();//glfwGetTime(); + double elapsedSeconds = currentSeconds - previousSeconds; + static double fps = 0; + + if (elapsedSeconds > 0.25) { + previousSeconds = currentSeconds; + fps = (double) frameCount / elapsedSeconds; + frameCount = 0; + } + + frameCount++; + + return (u32) fps; + } + +#endif /*RGFW_IMPLEMENTATION*/ + +#define RGFW_Escape RGFW_OS_BASED_VALUE(0xff1b, 0x1B, 53) +#define RGFW_F1 RGFW_OS_BASED_VALUE(0xffbe, 0x70, 127) +#define RGFW_F2 RGFW_OS_BASED_VALUE(0xffbf, 0x71, 121) +#define RGFW_F3 RGFW_OS_BASED_VALUE(0xffc0, 0x72, 100) +#define RGFW_F4 RGFW_OS_BASED_VALUE(0xffc1, 0x73, 119) +#define RGFW_F5 RGFW_OS_BASED_VALUE(0xffc2, 0x74, 97) +#define RGFW_F6 RGFW_OS_BASED_VALUE(0xffc3, 0x75, 98) +#define RGFW_F7 RGFW_OS_BASED_VALUE(0xffc4, 0x76, 99) +#define RGFW_F8 RGFW_OS_BASED_VALUE(0xffc5, 0x77, 101) +#define RGFW_F9 RGFW_OS_BASED_VALUE(0xffc6, 0x78, 102) +#define RGFW_F10 RGFW_OS_BASED_VALUE(0xffc7, 0x79, 110) +#define RGFW_F11 RGFW_OS_BASED_VALUE(0xffc8, 0x7A, 104) +#define RGFW_F12 RGFW_OS_BASED_VALUE(0xffc9, 0x7B, 112) +#define RGFW_F13 RGFW_OS_BASED_VALUE(0xffca, 0x7C, 106) +#define RGFW_F14 RGFW_OS_BASED_VALUE(0xffcb, 0x7D, 108) +#define RGFW_F15 RGFW_OS_BASED_VALUE(0xffcc, 0x7E, 114) + +#define RGFW_Backtick RGFW_OS_BASED_VALUE(96 , 192, 50) + +#define RGFW_0 RGFW_OS_BASED_VALUE(0x0030, 0x30, 29) +#define RGFW_1 RGFW_OS_BASED_VALUE(0x0031, 0x31, 18) +#define RGFW_2 RGFW_OS_BASED_VALUE(0x0032, 0x32, 19) +#define RGFW_3 RGFW_OS_BASED_VALUE(0x0033, 0x33, 20) +#define RGFW_4 RGFW_OS_BASED_VALUE(0x0034, 0x34, 21) +#define RGFW_5 RGFW_OS_BASED_VALUE(0x0035, 0x35, 23) +#define RGFW_6 RGFW_OS_BASED_VALUE(0x0036, 0x36, 22) +#define RGFW_7 RGFW_OS_BASED_VALUE(0x0037, 0x37, 26) +#define RGFW_8 RGFW_OS_BASED_VALUE(0x0038, 0x38, 28) +#define RGFW_9 RGFW_OS_BASED_VALUE(0x0039, 0x39, 25) + +#define RGFW_Minus RGFW_OS_BASED_VALUE(0x002d, 189, 27) +#define RGFW_Equals RGFW_OS_BASED_VALUE(0x003d, 187, 24) +#define RGFW_BackSpace RGFW_OS_BASED_VALUE(0xff08, 8, 51) +#define RGFW_Tab RGFW_OS_BASED_VALUE(0xff89, 0x09, 48) +#define RGFW_CapsLock RGFW_OS_BASED_VALUE(0xffe5, 20, 57) +#define RGFW_ShiftL RGFW_OS_BASED_VALUE(0xffe1, 0xA0, 56) +#define RGFW_ControlL RGFW_OS_BASED_VALUE(0xffe3, 0x11, 59) +#define RGFW_AltL RGFW_OS_BASED_VALUE(0xffe9, 164, 58) +#define RGFW_SuperL RGFW_OS_BASED_VALUE(0xffeb, 0x5B, 55) +#define RGFW_ShiftR RGFW_OS_BASED_VALUE(0xffe2, 0x5C, 56) +#define RGFW_ControlR RGFW_OS_BASED_VALUE(0xffe4, 0x11, 59) +#define RGFW_AltR RGFW_OS_BASED_VALUE(0xffea, 165, 58) +#define RGFW_SuperR RGFW_OS_BASED_VALUE(0xffec, 0xA4, 55) +#define RGFW_Space RGFW_OS_BASED_VALUE(0x0020, 0x20, 49) + +#define RGFW_A RGFW_OS_BASED_VALUE(0x0041, 0x41, 0) +#define RGFW_B RGFW_OS_BASED_VALUE(0x0042, 0x42, 11) +#define RGFW_C RGFW_OS_BASED_VALUE(0x0043, 0x43, 8) +#define RGFW_D RGFW_OS_BASED_VALUE(0x0044, 0x44, 2) +#define RGFW_E RGFW_OS_BASED_VALUE(0x0045, 0x45, 14) +#define RGFW_F RGFW_OS_BASED_VALUE(0x0046, 0x46, 3) +#define RGFW_G RGFW_OS_BASED_VALUE(0x0047, 0x47, 5) +#define RGFW_H RGFW_OS_BASED_VALUE(0x0048, 0x48, 4) +#define RGFW_I RGFW_OS_BASED_VALUE(0x0049, 0x49, 34) +#define RGFW_J RGFW_OS_BASED_VALUE(0x004a, 0x4A, 38) +#define RGFW_K RGFW_OS_BASED_VALUE(0x004b, 0x4B, 40) +#define RGFW_L RGFW_OS_BASED_VALUE(0x004c, 0x4C, 37) +#define RGFW_M RGFW_OS_BASED_VALUE(0x004d, 0x4D, 46) +#define RGFW_N RGFW_OS_BASED_VALUE(0x004e, 0x4E, 45) +#define RGFW_O RGFW_OS_BASED_VALUE(0x004f, 0x4F, 31) +#define RGFW_P RGFW_OS_BASED_VALUE(0x0050, 0x50, 35) +#define RGFW_Q RGFW_OS_BASED_VALUE(0x0051, 0x51, 12) +#define RGFW_R RGFW_OS_BASED_VALUE(0x0052, 0x52, 15) +#define RGFW_S RGFW_OS_BASED_VALUE(0x0053, 0x53, 1) +#define RGFW_T RGFW_OS_BASED_VALUE(0x0054, 0x54, 17) +#define RGFW_U RGFW_OS_BASED_VALUE(0x0055, 0x55, 32) +#define RGFW_V RGFW_OS_BASED_VALUE(0x0056, 0x56, 9) +#define RGFW_W RGFW_OS_BASED_VALUE(0x0057, 0x57, 13) +#define RGFW_X RGFW_OS_BASED_VALUE(0x0058, 0x58, 7) +#define RGFW_Y RGFW_OS_BASED_VALUE(0x0059, 0x59, 16) +#define RGFW_Z RGFW_OS_BASED_VALUE(0x005a, 0x5A, 6) + +#define RGFW_a RGFW_OS_BASED_VALUE(0x0061, 0x41, 0) +#define RGFW_b RGFW_OS_BASED_VALUE(0x0062, 0x42, 11) +#define RGFW_c RGFW_OS_BASED_VALUE(0x0063, 0x43, 8) +#define RGFW_d RGFW_OS_BASED_VALUE(0x0064, 0x44, 2) +#define RGFW_e RGFW_OS_BASED_VALUE(0x0065, 0x45, 14) +#define RGFW_f RGFW_OS_BASED_VALUE(0x0066, 0x46, 3) +#define RGFW_g RGFW_OS_BASED_VALUE(0x0067, 0x47, 5) +#define RGFW_h RGFW_OS_BASED_VALUE(0x0068, 0x48, 4) +#define RGFW_i RGFW_OS_BASED_VALUE(0x0069, 0x49, 34) +#define RGFW_j RGFW_OS_BASED_VALUE(0x006a, 0x4a, 38) +#define RGFW_k RGFW_OS_BASED_VALUE(0x006b, 0x4b, 40) +#define RGFW_l RGFW_OS_BASED_VALUE(0x006c, 0x4c, 37) +#define RGFW_m RGFW_OS_BASED_VALUE(0x006d, 0x4d, 46) +#define RGFW_n RGFW_OS_BASED_VALUE(0x006e, 0x4e, 45) +#define RGFW_o RGFW_OS_BASED_VALUE(0x006f, 0x4f, 31) +#define RGFW_p RGFW_OS_BASED_VALUE(0x0070, 0x50, 35) +#define RGFW_q RGFW_OS_BASED_VALUE(0x0071, 0x51, 12) +#define RGFW_r RGFW_OS_BASED_VALUE(0x0072, 0x52, 15) +#define RGFW_s RGFW_OS_BASED_VALUE(0x0073, 0x53, 1) +#define RGFW_t RGFW_OS_BASED_VALUE(0x0074, 0x54, 17) +#define RGFW_u RGFW_OS_BASED_VALUE(0x0075, 0x55, 32) +#define RGFW_v RGFW_OS_BASED_VALUE(0x0076, 0x56, 9) +#define RGFW_w RGFW_OS_BASED_VALUE(0x0077, 0x57, 13) +#define RGFW_x RGFW_OS_BASED_VALUE(0x0078, 0x58, 7) +#define RGFW_y RGFW_OS_BASED_VALUE(0x0079, 0x59, 16) +#define RGFW_z RGFW_OS_BASED_VALUE(0x007a, 0x5A, 6) + +#define RGFW_Period RGFW_OS_BASED_VALUE(0x002e, 190, 47) +#define RGFW_Comma RGFW_OS_BASED_VALUE(0x002c, 188, 43) +#define RGFW_Slash RGFW_OS_BASED_VALUE(0x002f, 191, 44) +#define RGFW_Bracket RGFW_OS_BASED_VALUE(0x005b, 219, 33) +#define RGFW_CloseBracket RGFW_OS_BASED_VALUE(0x005d, 221, 30) +#define RGFW_Semicolon RGFW_OS_BASED_VALUE(0x003b, 186, 41) +#define RGFW_Return RGFW_OS_BASED_VALUE(0xff0d, 0x0D, 36) +#define RGFW_Quote RGFW_OS_BASED_VALUE(0x0022, 222, 39) +#define RGFW_BackSlash RGFW_OS_BASED_VALUE(0x005c, 322, 42) + +#define RGFW_Up RGFW_OS_BASED_VALUE(0xff52, 0x26, 126) +#define RGFW_Down RGFW_OS_BASED_VALUE(0xff54, 0x28, 125) +#define RGFW_Left RGFW_OS_BASED_VALUE(0xff51, 0x25, 123) +#define RGFW_Right RGFW_OS_BASED_VALUE(0xff53, 0x27, 124) + +#define RGFW_Delete RGFW_OS_BASED_VALUE(0xffff, 0x2E, 118) +#define RGFW_Insert RGFW_OS_BASED_VALUE(0xff63, 0x2D, 115) +#define RGFW_End RGFW_OS_BASED_VALUE(0xff57, 0x23, 120) +#define RGFW_Home RGFW_OS_BASED_VALUE(0xff50, 0x24, 116) +#define RGFW_PageUp RGFW_OS_BASED_VALUE(0xff55, 336, 117) +#define RGFW_PageDown RGFW_OS_BASED_VALUE(0xff56, 325, 122) + +#define RGFW_Numlock RGFW_OS_BASED_VALUE(0xff7f, 0x90, 72) +#define RGFW_KP_Slash RGFW_OS_BASED_VALUE(0xffaf, 0x6F, 82) +#define RGFW_Multiply RGFW_OS_BASED_VALUE(0xffaa, 0x6A, 76) +#define RGFW_KP_Minus RGFW_OS_BASED_VALUE(0xffad, 0x6D, 67) +#define RGFW_KP_1 RGFW_OS_BASED_VALUE(0xffb1, 0x61, 84) +#define RGFW_KP_2 RGFW_OS_BASED_VALUE(0xffb2, 0x62, 85) +#define RGFW_KP_3 RGFW_OS_BASED_VALUE(0xffb3, 0x63, 86) +#define RGFW_KP_4 RGFW_OS_BASED_VALUE(0xffb4, 0x64, 87) +#define RGFW_KP_5 RGFW_OS_BASED_VALUE(0xffb5, 0x65, 88) +#define RGFW_KP_6 RGFW_OS_BASED_VALUE(0xffb6, 0x66, 89) +#define RGFW_KP_7 RGFW_OS_BASED_VALUE(0xffb7, 0x67, 90) +#define RGFW_KP_8 RGFW_OS_BASED_VALUE(0xffb8, 0x68, 92) +#define RGFW_KP_9 RGFW_OS_BASED_VALUE(0xffb9, 0x619, 93) +#define RGFW_KP_0 RGFW_OS_BASED_VALUE(0xffb0, 0x60, 83) +#define RGFW_KP_Period RGFW_OS_BASED_VALUE(0xffae, 0x6E, 65) +#define RGFW_KP_Return RGFW_OS_BASED_VALUE(0xff8d, 0x92, 77) + +#ifdef __APPLE__ + void* NSCursor_arrowStr(char* str); + void NSCursor_performSelector(void* cursor, void* selector); +#endif + + /* mouse icons */ +#define RGFW_MOUSE_ARROW RGFW_OS_BASED_VALUE(68, 32512, NSCursor_arrowStr("arrowCursor")) +#define RGFW_MOUSE_IBEAM RGFW_OS_BASED_VALUE(152, 32513, NSCursor_arrowStr("IBeamCursor")) +#define RGFW_MOUSE_CROSSHAIR RGFW_OS_BASED_VALUE(34, 32515, NSCursor_arrowStr("crosshairCursor")) +#define RGFW_MOUSE_POINTING_HAND RGFW_OS_BASED_VALUE(60, 32649, NSCursor_arrowStr("pointingHandCursor")) +#define RGFW_MOUSE_RESIZE_EW RGFW_OS_BASED_VALUE(108, 32644, NSCursor_arrowStr("resizeLeftRightCursor")) +#define RGFW_MOUSE_RESIZE_NS RGFW_OS_BASED_VALUE(116, 32645, NSCursor_arrowStr("resizeUpDownCursor")) +#define RGFW_MOUSE_RESIZE_ALL RGFW_OS_BASED_VALUE(52, 32646, NSCursor_arrowStr("closedHandCursor")) +#define RGFW_MOUSE_RESIZE_NWSE RGFW_OS_BASED_VALUE(12, 32642, NSCursor_performSelector(selector("_windowResizeNorthWestSouthEastCursor"))) +#define RGFW_MOUSE_RESIZE_NESW RGFW_OS_BASED_VALUE(14, 32643, NSCursor_performSelector(selector("_windowResizeNorthEastSouthWestCursor"))) +#define RGFW_MOUSE_NOT_ALLOWED RGFW_OS_BASED_VALUE(0, 32648, NSCursor_arrowStr("operationNotAllowedCursor")) + +#ifdef __cplusplus +} +#endif diff --git a/raylib/platform_android.go b/raylib/platform_android.go index e80c8bc..4059899 100644 --- a/raylib/platform_android.go +++ b/raylib/platform_android.go @@ -116,6 +116,7 @@ func (a *asset) Read(p []byte) (n int, err error) { if n == 0 && len(p) > 0 { return 0, io.EOF } + return n, nil } @@ -124,11 +125,13 @@ func (a *asset) Seek(offset int64, whence int) (int64, error) { if off == -1 { return 0, fmt.Errorf("bad result for offset=%d, whence=%d", offset, whence) } + return int64(off), nil } func (a *asset) Close() error { C.AAsset_close(a.ptr) + return nil } diff --git a/raylib/platform_desktop.go b/raylib/platform_desktop.go index a2bad87..bda078d 100644 --- a/raylib/platform_desktop.go +++ b/raylib/platform_desktop.go @@ -1,5 +1,5 @@ -//go:build !sdl && !drm && !android -// +build !sdl,!drm,!android +//go:build !rgfw && !sdl && !drm && !android +// +build !rgfw,!sdl,!drm,!android package rl diff --git a/raylib/platform_desktop_rgfw.go b/raylib/platform_desktop_rgfw.go new file mode 100644 index 0000000..5cfe6a2 --- /dev/null +++ b/raylib/platform_desktop_rgfw.go @@ -0,0 +1,102 @@ +//go:build rgfw && !sdl && !drm && !android +// +build rgfw,!sdl,!drm,!android + +package rl + +/* +#include "raylib.h" +#include +*/ +import "C" + +import ( + "os" + "unsafe" +) + +// InitWindow - Initialize Window and OpenGL Graphics +func InitWindow(width int32, height int32, title string) { + cwidth := (C.int)(width) + cheight := (C.int)(height) + + ctitle := C.CString(title) + defer C.free(unsafe.Pointer(ctitle)) + + C.InitWindow(cwidth, cheight, ctitle) +} + +// SetCallbackFunc - Sets callback function +func SetCallbackFunc(func()) { +} + +// ShowCursor - Shows cursor +func ShowCursor() { + C.ShowCursor() +} + +// HideCursor - Hides cursor +func HideCursor() { + C.HideCursor() +} + +// IsCursorHidden - Returns true if cursor is not visible +func IsCursorHidden() bool { + ret := C.IsCursorHidden() + v := bool(ret) + + return v +} + +// IsCursorOnScreen - Check if cursor is on the current screen. +func IsCursorOnScreen() bool { + ret := C.IsCursorOnScreen() + v := bool(ret) + + return v +} + +// EnableCursor - Enables cursor +func EnableCursor() { + C.EnableCursor() +} + +// DisableCursor - Disables cursor +func DisableCursor() { + C.DisableCursor() +} + +// IsFileDropped - Check if a file have been dropped into window +func IsFileDropped() bool { + ret := C.IsFileDropped() + v := bool(ret) + + return v +} + +// LoadDroppedFiles - Load dropped filepaths +func LoadDroppedFiles() []string { + ret := C.LoadDroppedFiles() + defer C.UnloadDroppedFiles(ret) + + tmpslice := (*[1 << 24]*C.char)(unsafe.Pointer(ret.paths))[:ret.count:ret.count] + gostrings := make([]string, ret.count) + for i, s := range tmpslice { + gostrings[i] = C.GoString(s) + } + + return gostrings +} + +// UnloadDroppedFiles - Unload dropped filepaths +func UnloadDroppedFiles() { +} + +// OpenAsset - Open asset +func OpenAsset(name string) (Asset, error) { + f, err := os.Open(name) + if err != nil { + return nil, err + } + + return f, nil +} diff --git a/raylib/platform_desktop_sdl.go b/raylib/platform_desktop_sdl.go index 73d1ac7..ee930d6 100644 --- a/raylib/platform_desktop_sdl.go +++ b/raylib/platform_desktop_sdl.go @@ -1,5 +1,5 @@ -//go:build sdl && !drm && !android -// +build sdl,!drm,!android +//go:build sdl && !rgfw && !drm && !android +// +build sdl,!rgfw,!drm,!android package rl @@ -43,6 +43,7 @@ func HideCursor() { func IsCursorHidden() bool { ret := C.IsCursorHidden() v := bool(ret) + return v } @@ -50,6 +51,7 @@ func IsCursorHidden() bool { func IsCursorOnScreen() bool { ret := C.IsCursorOnScreen() v := bool(ret) + return v } @@ -67,6 +69,7 @@ func DisableCursor() { func IsFileDropped() bool { ret := C.IsFileDropped() v := bool(ret) + return v } @@ -94,5 +97,6 @@ func OpenAsset(name string) (Asset, error) { if err != nil { return nil, err } + return f, nil } diff --git a/raylib/platform_drm.go b/raylib/platform_drm.go index 520f1b8..6618e0e 100644 --- a/raylib/platform_drm.go +++ b/raylib/platform_drm.go @@ -1,5 +1,5 @@ -//go:build linux && drm && !sdl && !android -// +build linux,drm,!sdl,!android +//go:build linux && drm && !rgfw && !sdl && !android +// +build linux,drm,!rgfw,!sdl,!android package rl diff --git a/raylib/platforms/rcore_desktop_rgfw.c b/raylib/platforms/rcore_desktop_rgfw.c new file mode 100644 index 0000000..12e18af --- /dev/null +++ b/raylib/platforms/rcore_desktop_rgfw.c @@ -0,0 +1,1524 @@ +/********************************************************************************************** +* +* rcore_desktop_rgfw template - Functions to manage window, graphics device and inputs +* +* PLATFORM: RGFW +* - Windows (Win32, Win64) +* - Linux (X11/Wayland desktop mode) +* - MacOS (Cocoa) +* +* LIMITATIONS: +* - Limitation 01 +* - Limitation 02 +* +* POSSIBLE IMPROVEMENTS: +* - Improvement 01 +* - Improvement 02 +* +* ADDITIONAL NOTES: +* - TRACELOG() function is located in raylib [utils] module +* +* CONFIGURATION: +* #define RCORE_PLATFORM_CUSTOM_FLAG +* Custom flag for rcore on target platform -not used- +* +* DEPENDENCIES: +* - RGFW.h (main library): Windowing and inputs management +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5), Colleague Riley and contributors +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifdef GRAPHICS_API_OPENGL_ES2 +#define RGFW_OPENGL_ES2 +#endif + +void ShowCursor(void); +void CloseWindow(void); + +#define _INPUT_EVENT_CODES_H +#define _APISETSTRING_ +#define RGFWDEF +#define _XTYPEDEF_FONT +#define RGFW_IMPLEMENTATION + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#define Rectangle rectangle_win32 +#define CloseWindow CloseWindow_win32 +#define ShowCursor __imp_ShowCursor + +#endif // _WIN32 + +#define Point NSPOINT +#define Size NSSIZE + +#ifdef _MSC_VER +__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar); +#endif + +#include "../external/RGFW.h" +#undef DrawText +#undef ShowCursor +#undef CloseWindow +#undef Point +#undef Size +#undef Rectangle + +#define Rectangle struct Rectangle +void CloseWindow(void); +void ShowCursor(void); + + +#include + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct { + // TODO: Define the platform specific variables required + + RGFW_window* window; // Native display device (physical screen connection) +} PlatformData; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +extern CoreData CORE; // Global CORE state context + +static PlatformData platform = { NULL }; // Platform specific + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +bool InitGraphicsDevice(void); // Initialize graphics device + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +// NOTE: Functions declaration is provided by raylib.h + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Window and Graphics Device +//---------------------------------------------------------------------------------- + +// Check if application should close +bool WindowShouldClose(void) +{ + if (CORE.Window.shouldClose == false) + CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window); + if (CORE.Window.ready) return CORE.Window.shouldClose; + else return true; +} + +// Toggle fullscreen mode +void ToggleFullscreen(void) +{ + RGFW_window_maximize(platform.window); + ToggleBorderlessWindowed(); +} + +// Toggle borderless windowed mode +void ToggleBorderlessWindowed(void) +{ + CORE.Window.flags & FLAG_WINDOW_UNDECORATED; + + if (platform.window != NULL) + TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() after window creation not available on target platform"); +} + +// Set window state: maximized, if resizable +void MaximizeWindow(void) +{ + RGFW_window_maximize(platform.window); +} + +// Set window state: minimized +void MinimizeWindow(void) +{ + RGFW_window_minimize(platform.window); +} + +// Set window state: not minimized/maximized +void RestoreWindow(void) +{ + RGFW_window_restore(platform.window); +} + +// Set window configuration state using flags +void SetWindowState(unsigned int flags) +{ + CORE.Window.flags |= flags; + + if (flags & FLAG_VSYNC_HINT) + { + RGFW_window_swapInterval(platform.window, 1); + } + if (flags & FLAG_FULLSCREEN_MODE) + { + RGFW_window_maximize(platform.window); + ToggleBorderlessWindowed(); + } + if (flags & FLAG_WINDOW_RESIZABLE) + { + RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); + RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); + } + if (flags & FLAG_WINDOW_UNDECORATED) + { + ToggleBorderlessWindowed(); + } + if (flags & FLAG_WINDOW_HIDDEN) + { + RGFW_window_hide(platform.window); + } + if (flags & FLAG_WINDOW_MINIMIZED) + { + RGFW_window_minimize(platform.window); + } + if (flags & FLAG_WINDOW_MAXIMIZED) + { + RGFW_window_maximize(platform.window); + } + if (flags & FLAG_WINDOW_UNFOCUSED) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_TOPMOST) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TOPMOST is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_ALWAYS_RUN) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_TRANSPARENT) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_HIGHDPI) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + { + ToggleBorderlessWindowed(); + } + if (flags & FLAG_MSAA_4X_HINT) + { + RGFW_setGLSamples(4); + } + if (flags & FLAG_INTERLACED_HINT) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_RGFW"); + } +} + +// Clear window configuration state flags +void ClearWindowState(unsigned int flags) +{ + CORE.Window.flags &= ~flags; + + if (flags & FLAG_VSYNC_HINT) + { + RGFW_window_swapInterval(platform.window, 0); + } + if (flags & FLAG_FULLSCREEN_MODE) + { + ToggleBorderlessWindowed(); + RGFW_window_restore(platform.window); + CORE.Window.fullscreen = false; + } + if (flags & FLAG_WINDOW_RESIZABLE) + { + RGFW_window_setMaxSize(platform.window, RGFW_AREA(0, 0)); + RGFW_window_setMinSize(platform.window, RGFW_AREA(0, 0)); + } + if (flags & FLAG_WINDOW_UNDECORATED) + { + ToggleBorderlessWindowed(); + } + if (flags & FLAG_WINDOW_HIDDEN) + { + RGFW_window_show(platform.window); + } + if (flags & FLAG_WINDOW_MINIMIZED) + { + RGFW_window_restore(platform.window); + } + if (flags & FLAG_WINDOW_MAXIMIZED) + { + RGFW_window_restore(platform.window); + } + if (flags & FLAG_WINDOW_UNFOCUSED) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_TOPMOST) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TOPMOST is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_ALWAYS_RUN) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_TRANSPARENT) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_HIGHDPI) + { + // NOTE: There also doesn't seem to be a feature to disable high DPI once enabled + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + { + //SDL_SetWindowGrab(platform.window, SDL_TRUE); + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW"); + } + if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + { + ToggleFullscreen(); + } + if (flags & FLAG_MSAA_4X_HINT) + { + RGFW_setGLSamples(0); + } + if (flags & FLAG_INTERLACED_HINT) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_RGFW"); + } +} + +// Set icon for window +void SetWindowIcon(Image image) +{ + i32 channels = 4; + + switch (image.format) { + case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: + case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float) + case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float) + channels = 1; + break; + + case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels) + case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp + case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp + case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha) + case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha) + case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp + channels = 2; + break; + + case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float) + case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float) + case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha) + case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp + case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp + case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp + channels = 3; + break; + + case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float) + case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float) + case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha) + case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp + case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp + case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp + case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp + case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp + case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp + channels = 4; + break; + + default: break; + } + + RGFW_window_setIcon(platform.window, image.data, RGFW_AREA(image.width, image.height), channels); +} + +// Set icon for window +void SetWindowIcons(Image *images, int count) +{ + TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform"); +} + +// Set title for window +void SetWindowTitle(const char *title) +{ + RGFW_window_setName(platform.window, title); + CORE.Window.title = title; +} + +// Set window position on screen (windowed mode) +void SetWindowPosition(int x, int y) +{ + RGFW_window_move(platform.window, RGFW_VECTOR(x, y)); +} + +// Set monitor for the current window +void SetWindowMonitor(int monitor) +{ + RGFW_window_moveToMonitor(platform.window, RGFW_getMonitors()[monitor]); +} + +// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMinSize(int width, int height) +{ + RGFW_window_setMinSize(platform.window, RGFW_AREA(width, height)); + CORE.Window.screenMin.width = width; + CORE.Window.screenMin.height = height; +} + +// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMaxSize(int width, int height) +{ + RGFW_window_setMaxSize(platform.window, RGFW_AREA(width, height)); + CORE.Window.screenMax.width = width; + CORE.Window.screenMax.height = height; +} + +// Set window dimensions +void SetWindowSize(int width, int height) +{ + RGFW_window_resize(platform.window, RGFW_AREA(width, height)); +} + +// Set window opacity, value opacity is between 0.0 and 1.0 +void SetWindowOpacity(float opacity) +{ + TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform"); +} + +// Set window focused +void SetWindowFocused(void) +{ + RGFW_window_show(platform.window); +} + +// Get native window handle +void *GetWindowHandle(void) +{ + return platform.window->src.window; +} + +// Get number of monitors +int GetMonitorCount(void) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + u32 i; + for (i = 0; i < 6; i++) { + if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h) + return i; + } + + return 6; +} + +// Get number of monitors +int GetCurrentMonitor(void) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + RGFW_monitor mon = RGFW_window_getMonitor(platform.window); + + u32 i; + for (i = 0; i < 6; i++) { + if (mons[i].rect.x == mon.rect.x && + mons[i].rect.y == mon.rect.y) + return i; + } + + return 0; +} + +// Get selected monitor position +Vector2 GetMonitorPosition(int monitor) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + + return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y}; +} + +// Get selected monitor width (currently used by monitor) +int GetMonitorWidth(int monitor) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + + return mons[monitor].rect.w; +} + +// Get selected monitor height (currently used by monitor) +int GetMonitorHeight(int monitor) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + + return mons[monitor].rect.h; + return 0; +} + +// Get selected monitor physical width in millimetres +int GetMonitorPhysicalWidth(int monitor) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + + return mons[monitor].physW; +} + +// Get selected monitor physical height in millimetres +int GetMonitorPhysicalHeight(int monitor) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + + return mons[monitor].physH; +} + +// Get selected monitor refresh rate +int GetMonitorRefreshRate(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform"); + return 0; +} + +// Get the human-readable, UTF-8 encoded name of the selected monitor +const char *GetMonitorName(int monitor) +{ + RGFW_monitor* mons = RGFW_getMonitors(); + + return mons[monitor].name; +} + +// Get window position XY on monitor +Vector2 GetWindowPosition(void) +{ + return (Vector2){ platform.window->r.x, platform.window->r.y }; +} + +// Get window scale DPI factor for current monitor +Vector2 GetWindowScaleDPI(void) +{ + RGFW_monitor monitor = RGFW_window_getMonitor(platform.window); + + return (Vector2){((u32)monitor.scaleX) * platform.window->r.w, ((u32) monitor.scaleX) * platform.window->r.h}; +} + +// Set clipboard text content +void SetClipboardText(const char *text) +{ + RGFW_writeClipboard(text, strlen(text)); +} + +// Get clipboard text content +// NOTE: returned string is allocated and freed by GLFW +const char *GetClipboardText(void) +{ + return RGFW_readClipboard(NULL); +} + +// Show mouse cursor +void ShowCursor(void) +{ + RGFW_window_showMouse(platform.window, true); + CORE.Input.Mouse.cursorHidden = false; +} + +// Hides mouse cursor +void HideCursor(void) +{ + RGFW_window_showMouse(platform.window, false); + CORE.Input.Mouse.cursorHidden = true; +} + +// Enables cursor (unlock cursor) +void EnableCursor(void) +{ + RGFW_window_mouseUnhold(platform.window); + + // Set cursor position in the middle + SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + RGFW_window_showMouse(platform.window, true); + CORE.Input.Mouse.cursorHidden = false; +} + +// Disables cursor (lock cursor) +void DisableCursor(void) +{ + RGFW_window_mouseHold(platform.window); + // Set cursor position in the middle + SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + + HideCursor(); +} + +// Swap back buffer with front buffer (screen drawing) +void SwapScreenBuffer(void) +{ + RGFW_window_swapBuffers(platform.window); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Misc +//---------------------------------------------------------------------------------- + +// Get elapsed time measure in seconds since InitTimer() +double GetTime(void) +{ + double time = 0.0; + unsigned long long int nanoSeconds = RGFW_getTimeNS(); + time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() + + return time; +} + +// Open URL with default system browser (if available) +// NOTE: This function is only safe to use if you control the URL given. +// A user could craft a malicious string performing another action. +// Only call this function yourself not with user input or make sure to check the string yourself. +// Ref: https://github.com/raysan5/raylib/issues/686 +void OpenURL(const char *url) +{ + // Security check to (partially) avoid malicious code on target platform + if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + else + { + // TODO: + } +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Inputs +//---------------------------------------------------------------------------------- + +// Set internal gamepad mappings +int SetGamepadMappings(const char *mappings) +{ + TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform"); + return 0; +} + +// Set mouse position XY +void SetMousePosition(int x, int y) +{ + RGFW_window_moveMouse(platform.window, RGFW_VECTOR(x, y)); + CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; +} + +// Set mouse cursor +void SetMouseCursor(int cursor) +{ + switch (cursor) { + case MOUSE_CURSOR_DEFAULT: + return RGFW_window_setMouseDefault(platform.window); + case MOUSE_CURSOR_ARROW: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_ARROW); + case MOUSE_CURSOR_IBEAM: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_IBEAM); + case MOUSE_CURSOR_CROSSHAIR: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_CROSSHAIR); + case MOUSE_CURSOR_POINTING_HAND: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_POINTING_HAND); + case MOUSE_CURSOR_RESIZE_EW: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_EW); + case MOUSE_CURSOR_RESIZE_NS: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_NS); + #ifndef RGFW_MACOS + case MOUSE_CURSOR_RESIZE_NWSE: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_NWSE); + case MOUSE_CURSOR_RESIZE_NESW: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_NESW); + #endif + case MOUSE_CURSOR_RESIZE_ALL: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_ALL); + case MOUSE_CURSOR_NOT_ALLOWED: + return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_NOT_ALLOWED); + default: + break; + } +} + +static KeyboardKey ConvertScancodeToKey(u32 keycode); + +// Register all input events +void PollInputEvents(void) +{ +#if defined(SUPPORT_GESTURES_SYSTEM) + // NOTE: Gestures update must be called every frame to reset gestures correctly + // because ProcessGestureEvent() is just called on an event, not every frame + UpdateGestures(); +#endif + + // Reset keys/chars pressed registered + CORE.Input.Keyboard.keyPressedQueueCount = 0; + CORE.Input.Keyboard.charPressedQueueCount = 0; + + // Reset mouse wheel + CORE.Input.Mouse.currentWheelMove.x = 0; + CORE.Input.Mouse.currentWheelMove.y = 0; + + // Register previous mouse position + + // Reset last gamepad button/axis registered state + + for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) + { + // Check if gamepad is available + if (CORE.Input.Gamepad.ready[i]) + { + // Register previous gamepad button states + for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) + { + CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; + } + } + } + + // Register previous touch states + for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; + + // Map touch position to mouse position for convenience + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + + int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE + bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones + + // Register previous keys states + // NOTE: Android supports up to 260 keys + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) + { + CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } + + // Register previous mouse states + for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) + CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; + + // Poll input events for current platform + //----------------------------------------------------------------------------- + CORE.Window.resizedLastFrame = false; + + + #define RGFW_HOLD_MOUSE (1L<<2) + #if defined(RGFW_X11) //|| defined(RGFW_MACOS) + if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) + { + CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; + CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f }; + } + else { + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; + } + #endif + + while (RGFW_window_checkEvent(platform.window)) + { + + if (platform.window->event.type >= RGFW_jsButtonPressed && platform.window->event.type <= RGFW_jsAxisMove) { + if (!CORE.Input.Gamepad.ready[platform.window->event.joystick]) + { + CORE.Input.Gamepad.ready[platform.window->event.joystick] = true; + CORE.Input.Gamepad.axisCount[platform.window->event.joystick] = platform.window->event.axisesCount; + CORE.Input.Gamepad.name[platform.window->event.joystick][0] = '\0'; + CORE.Input.Gamepad.axisState[platform.window->event.joystick][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[platform.window->event.joystick][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + } + } + + RGFW_Event* event = &platform.window->event; + + // All input events can be processed after polling + switch (event->type) + { + case RGFW_quit: CORE.Window.shouldClose = true; break; + + case RGFW_dnd: // Dropped file + { + size_t i; + for (i = 0; i < event->droppedFilesCount; i++) { + if (CORE.Window.dropFileCount == 0) + { + // When a new file is dropped, we reserve a fixed number of slots for all possible dropped files + // at the moment we limit the number of drops at once to 1024 files but this behaviour should probably be reviewed + // TODO: Pointers should probably be reallocated for any new file added... + CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *)); + + CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]); + + CORE.Window.dropFileCount++; + } + else if (CORE.Window.dropFileCount < 1024) + { + CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]); + + CORE.Window.dropFileCount++; + } + else TRACELOG(LOG_WARNING, "FILE: Maximum drag and drop files at once is limited to 1024 files!"); + } + } break; + + // Window events are also polled (Minimized, maximized, close...) + case RGFW_windowAttribsChange: + { + SetupViewport(platform.window->r.w, platform.window->r.h); + CORE.Window.position.x = platform.window->r.x; + CORE.Window.position.y = platform.window->r.x; + CORE.Window.screen.width = platform.window->r.w; + CORE.Window.screen.height = platform.window->r.h; + CORE.Window.currentFbo.width = platform.window->r.w;; + CORE.Window.currentFbo.height = platform.window->r.h; + CORE.Window.resizedLastFrame = true; + } break; + + // Keyboard events + case RGFW_keyPressed: + { + KeyboardKey key = ConvertScancodeToKey(event->keyCode); + + if (key != KEY_NULL) { + // If key was up, add it to the key pressed queue + if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) + { + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + + CORE.Input.Keyboard.currentKeyState[key] = 1; + } + + // TODO: Put exitKey verification outside the switch? + if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) + { + CORE.Window.shouldClose = true; + } + + // NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int) + // Check if there is space available in the queue + if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) + { + // Add character (codepoint) to the queue + CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RGFW_keystrToChar(event->keyName); + CORE.Input.Keyboard.charPressedQueueCount++; + } + } break; + + case RGFW_keyReleased: + { + KeyboardKey key = ConvertScancodeToKey(event->keyCode); + if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0; + } break; + + // Check mouse events + case RGFW_mouseButtonPressed: + { + if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) { + CORE.Input.Mouse.currentWheelMove.y = event->scroll; + break; + } + + int btn = event->button; + if (btn == RGFW_mouseLeft) btn = 1; + else if (btn == RGFW_mouseRight) btn = 2; + else if (btn == RGFW_mouseMiddle) btn = 3; + + CORE.Input.Mouse.currentButtonState[btn - 1] = 1; + CORE.Input.Touch.currentTouchState[btn - 1] = 1; + + touchAction = 1; + } break; + case RGFW_mouseButtonReleased: + { + + if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) { + CORE.Input.Mouse.currentWheelMove.y = event->scroll; + break; + } + + int btn = event->button; + if (btn == RGFW_mouseLeft) btn = 1; + else if (btn == RGFW_mouseRight) btn = 2; + else if (btn == RGFW_mouseMiddle) btn = 3; + + CORE.Input.Mouse.currentButtonState[btn - 1] = 0; + CORE.Input.Touch.currentTouchState[btn - 1] = 0; + + touchAction = 0; + } break; + case RGFW_mousePosChanged: + { + if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) { + + CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; + + if ((event->point.x - (platform.window->r.w / 2)) * 2) + CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x; + if ((event->point.y - (platform.window->r.h / 2)) * 2) + CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y; + + CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w / 2)) * 2; + CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h / 2)) * 2; + + RGFW_window_showMouse(platform.window, 1); + } + else { + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; + CORE.Input.Mouse.currentPosition.x = (float)event->point.x; + CORE.Input.Mouse.currentPosition.y = (float)event->point.y; + } + + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + touchAction = 2; + } break; + + case RGFW_jsButtonPressed: + { + int button = -1; + + switch (event->button) + { + case RGFW_JS_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; + case RGFW_JS_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; + case RGFW_JS_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; + case RGFW_JS_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; + + case RGFW_JS_L1: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; + case RGFW_JS_R1: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; + + case RGFW_JS_L2: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break; + case RGFW_JS_R2: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break; + + case RGFW_JS_SELECT: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; + case RGFW_JS_HOME: button = GAMEPAD_BUTTON_MIDDLE; break; + case RGFW_JS_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; + + case RGFW_JS_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; + case RGFW_JS_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; + case RGFW_JS_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; + case RGFW_JS_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; + + default: break; + } + + if (button >= 0) + { + CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 1; + CORE.Input.Gamepad.lastButtonPressed = button; + } + } break; + case RGFW_jsButtonReleased: + { + int button = -1; + switch (event->button) + { + case RGFW_JS_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; + case RGFW_JS_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; + case RGFW_JS_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; + case RGFW_JS_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; + + case RGFW_JS_L1: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; + case RGFW_JS_R1: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; + + case RGFW_JS_L2: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break; + case RGFW_JS_R2: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break; + + case RGFW_JS_SELECT: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; + case RGFW_JS_HOME: button = GAMEPAD_BUTTON_MIDDLE; break; + case RGFW_JS_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; + + case RGFW_JS_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; + case RGFW_JS_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; + case RGFW_JS_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; + case RGFW_JS_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; + default: break; + } + + if (button >= 0) + { + CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 0; + if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; + } + } break; + case RGFW_jsAxisMove: + { + int axis = -1; + + size_t i; + for (i = 0; i < event->axisesCount; i++) + { + switch(i) { + case 0: + if (abs(event->axis[i].x) > abs(event->axis[i].y)) { + axis = GAMEPAD_AXIS_LEFT_X; + break; + } + + axis = GAMEPAD_AXIS_LEFT_Y; + break; + case 1: + if (abs(event->axis[i].x) > abs(event->axis[i].y)) { + axis = GAMEPAD_AXIS_RIGHT_X; break; + } + + axis = GAMEPAD_AXIS_RIGHT_Y; break; + case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break; + case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break; + default: break; + } + + #ifdef __linux__ + float value = (event->axis[i].x + event->axis[i].y) / (float) 32767; + #else + float value = (event->axis[i].x + -event->axis[i].y) / (float) 32767; + #endif + CORE.Input.Gamepad.axisState[event->joystick][axis] = value; + + // Register button state for triggers in addition to their axes + if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER)) + { + int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER) ? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2; + int pressed = (value > 0.1f); + CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed; + if (pressed) CORE.Input.Gamepad.lastButtonPressed = button; + else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; + } + } + } break; + default: break; + } + +#if defined(SUPPORT_GESTURES_SYSTEM) + if (touchAction > -1) + { + // Process mouse events as touches to be able to use mouse-gestures + GestureEvent gestureEvent = { 0 }; + + // Register touch actions + gestureEvent.touchAction = touchAction; + + // Assign a pointer ID + gestureEvent.pointId[0] = 0; + + // Register touch points count + gestureEvent.pointCount = 1; + + // Register touch points position, only one point registered + if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0]; + else gestureEvent.position[0] = GetMousePosition(); + + // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + // Gesture data is sent to gestures-system for processing + ProcessGestureEvent(gestureEvent); + + touchAction = -1; + } +#endif + } + //----------------------------------------------------------------------------- +} + + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- + +// Initialize platform: graphics, inputs and more +int InitPlatform(void) +{ + // TODO: Initialize graphic device: display/window + // It usually requires setting up the platform display system configuration + // and connexion with the GPU through some system graphic API + // raylib uses OpenGL so, platform should create that kind of connection + // Below example illustrates that process using EGL library + //---------------------------------------------------------------------------- + // Initialize RGFW internal global state, only required systems + // Initialize graphic device: display/window and graphic context + //---------------------------------------------------------------------------- + unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND; + + // Check window creation flags + if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) + { + CORE.Window.fullscreen = true; + flags |= RGFW_FULLSCREEN; + } + + if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= RGFW_NO_BORDER; + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) flags |= RGFW_NO_RESIZE; + + if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= RGFW_TRANSPARENT_WINDOW; + + if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) flags |= RGFW_FULLSCREEN; + + // NOTE: Some OpenGL context attributes must be set before window creation + + // Check selection OpenGL version + if (rlGetVersion() == RL_OPENGL_21) + { + RGFW_setGLVersion(2, 1); + } + else if (rlGetVersion() == RL_OPENGL_33) + { + RGFW_setGLVersion(3, 3); + } + else if (rlGetVersion() == RL_OPENGL_43) + { + RGFW_setGLVersion(4, 1); + } + + if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + { + RGFW_setGLSamples(4); + } + + platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags); + + if (CORE.Window.flags & FLAG_VSYNC_HINT) + RGFW_window_swapInterval(platform.window, 1); + + RGFW_window_makeCurrent(platform.window); + + // Check surface and context activation + if (platform.window != NULL) + { + CORE.Window.ready = true; + + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = CORE.Window.screen.height; + CORE.Window.currentFbo.width = CORE.Window.render.width; + CORE.Window.currentFbo.height = CORE.Window.render.height; + + TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); + TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); + TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); + TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); + TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); + } + else + { + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); + return -1; + } + //---------------------------------------------------------------------------- + + // If everything work as expected, we can continue + CORE.Window.position.x = platform.window->r.x; + CORE.Window.position.y = platform.window->r.y; + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = CORE.Window.screen.height; + CORE.Window.currentFbo.width = CORE.Window.render.width; + CORE.Window.currentFbo.height = CORE.Window.render.height; + + TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); + TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); + TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); + TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); + TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); + + // TODO: Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + //---------------------------------------------------------------------------- + rlLoadExtensions((void*)RGFW_getProcAddress); + //---------------------------------------------------------------------------- + + // TODO: Initialize input events system + // It could imply keyboard, mouse, gamepad, touch... + // Depending on the platform libraries/SDK it could use a callback mechanism + // For system events and inputs evens polling on a per-frame basis, use PollInputEvents() + //---------------------------------------------------------------------------- + // ... + //---------------------------------------------------------------------------- + + // TODO: Initialize timing system + //---------------------------------------------------------------------------- + InitTimer(); + //---------------------------------------------------------------------------- + + // TODO: Initialize storage system + //---------------------------------------------------------------------------- + CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- + + #ifdef RGFW_X11 + for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) + { + RGFW_registerJoystick(platform.window, i); + } + #endif + + TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); + + return 0; +} + +// Close platform +void ClosePlatform(void) +{ + RGFW_window_close(platform.window); + // TODO: De-initialize graphics, inputs and more +} + + +static KeyboardKey ConvertScancodeToKey(u32 keycode) { + switch (keycode) { + case RGFW_Quote: + return KEY_APOSTROPHE; + case RGFW_Comma: + return KEY_COMMA; + case RGFW_Minus: + return KEY_MINUS; + case RGFW_Period: + return KEY_PERIOD; + case RGFW_Slash: + return KEY_SLASH; + case RGFW_Escape: + return KEY_ESCAPE; + case RGFW_F1: + return KEY_F1; + case RGFW_F2: + return KEY_F2; + case RGFW_F3: + return KEY_F3; + case RGFW_F4: + return KEY_F4; + case RGFW_F5: + return KEY_F5; + case RGFW_F6: + return KEY_F6; + case RGFW_F7: + return KEY_F7; + case RGFW_F8: + return KEY_F8; + case RGFW_F9: + return KEY_F9; + case RGFW_F10: + return KEY_F10; + case RGFW_F11: + return KEY_F11; + case RGFW_F12: + return KEY_F12; + case RGFW_Backtick: + return KEY_GRAVE; + case RGFW_0: + return KEY_ZERO; + case RGFW_1: + return KEY_ONE; + case RGFW_2: + return KEY_TWO; + case RGFW_3: + return KEY_THREE; + case RGFW_4: + return KEY_FOUR; + case RGFW_5: + return KEY_FIVE; + case RGFW_6: + return KEY_SIX; + case RGFW_7: + return KEY_SEVEN; + case RGFW_8: + return KEY_EIGHT; + case RGFW_9: + return KEY_NINE; + case RGFW_Equals: + return KEY_EQUAL; + case RGFW_BackSpace: + return KEY_BACKSPACE; + case RGFW_Tab: + return KEY_TAB; + case RGFW_CapsLock: + return KEY_CAPS_LOCK; + case RGFW_ShiftL: + return KEY_LEFT_SHIFT; + case RGFW_ControlL: + return KEY_LEFT_CONTROL; + case RGFW_AltL: + return KEY_LEFT_ALT; + case RGFW_SuperL: + return KEY_LEFT_SUPER; + #ifndef RGFW_MACOS + case RGFW_ShiftR: + return KEY_RIGHT_SHIFT; + + case RGFW_AltR: + return KEY_RIGHT_ALT; + #endif + case RGFW_Space: + return KEY_SPACE; + + #ifdef RGFW_X11 + case RGFW_a: + #endif + + case RGFW_A: + return KEY_A; + + #ifdef RGFW_X11 + case RGFW_b: + #endif + + case RGFW_B: + return KEY_B; + + #ifdef RGFW_X11 + case RGFW_c: + #endif + + case RGFW_C: + return KEY_C; + + #ifdef RGFW_X11 + case RGFW_d: + #endif + + case RGFW_D: + return KEY_D; + + #ifdef RGFW_X11 + case RGFW_e: + #endif + + case RGFW_E: + return KEY_E; + + #ifdef RGFW_X11 + case RGFW_f: + #endif + + case RGFW_F: + return KEY_F; + + #ifdef RGFW_X11 + case RGFW_g: + #endif + + case RGFW_G: + return KEY_G; + + #ifdef RGFW_X11 + case RGFW_h: + #endif + + case RGFW_H: + return KEY_H; + + #ifdef RGFW_X11 + case RGFW_i: + #endif + + case RGFW_I: + return KEY_I; + + #ifdef RGFW_X11 + case RGFW_j: + #endif + + case RGFW_J: + return KEY_J; + + #ifdef RGFW_X11 + case RGFW_k: + #endif + + case RGFW_K: + return KEY_K; + + #ifdef RGFW_X11 + case RGFW_l: + #endif + + case RGFW_L: + return KEY_L; + + #ifdef RGFW_X11 + case RGFW_m: + #endif + + case RGFW_M: + return KEY_M; + + #ifdef RGFW_X11 + case RGFW_n: + #endif + + case RGFW_N: + return KEY_N; + + #ifdef RGFW_X11 + case RGFW_o: + #endif + + case RGFW_O: + return KEY_O; + + #ifdef RGFW_X11 + case RGFW_p: + #endif + + case RGFW_P: + return KEY_P; + + #ifdef RGFW_X11 + case RGFW_q: + #endif + + case RGFW_Q: + return KEY_Q; + + #ifdef RGFW_X11 + case RGFW_r: + #endif + + case RGFW_R: + return KEY_R; + + #ifdef RGFW_X11 + case RGFW_s: + #endif + + case RGFW_S: + return KEY_S; + + #ifdef RGFW_X11 + case RGFW_t: + #endif + + case RGFW_T: + return KEY_T; + + #ifdef RGFW_X11 + case RGFW_u: + #endif + + case RGFW_U: + return KEY_U; + + #ifdef RGFW_X11 + case RGFW_v: + #endif + + case RGFW_V: + return KEY_V; + + #ifdef RGFW_X11 + case RGFW_w: + #endif + + case RGFW_W: + return KEY_W; + + #ifdef RGFW_X11 + case RGFW_x: + #endif + + case RGFW_X: + return KEY_X; + + #ifdef RGFW_X11 + case RGFW_y: + #endif + + case RGFW_Y: + return KEY_Y; + + #ifdef RGFW_X11 + case RGFW_z: + #endif + + case RGFW_Z: + return KEY_Z; + case RGFW_Bracket: + return KEY_LEFT_BRACKET; + case RGFW_BackSlash: + return KEY_BACKSLASH; + case RGFW_CloseBracket: + return KEY_RIGHT_BRACKET; + case RGFW_Semicolon: + return KEY_SEMICOLON; + case RGFW_Insert: + return KEY_INSERT; + case RGFW_Home: + return KEY_HOME; + case RGFW_PageUp: + return KEY_PAGE_UP; + case RGFW_Delete: + return KEY_DELETE; + case RGFW_End: + return KEY_END; + case RGFW_PageDown: + return KEY_PAGE_DOWN; + case RGFW_Right: + return KEY_RIGHT; + case RGFW_Left: + return KEY_LEFT; + case RGFW_Down: + return KEY_DOWN; + case RGFW_Up: + return KEY_UP; + case RGFW_Numlock: + return KEY_NUM_LOCK; + case RGFW_KP_Slash: + return KEY_KP_DIVIDE; + case RGFW_Multiply: + return KEY_KP_MULTIPLY; + case RGFW_KP_Minus: + return KEY_KP_SUBTRACT; + case RGFW_KP_Return: + return KEY_KP_ENTER; + case RGFW_KP_1: + return KEY_KP_1; + case RGFW_KP_2: + return KEY_KP_2; + case RGFW_KP_3: + return KEY_KP_3; + case RGFW_KP_4: + return KEY_KP_4; + case RGFW_KP_5: + return KEY_KP_5; + case RGFW_KP_6: + return KEY_KP_6; + case RGFW_KP_7: + return KEY_KP_7; + case RGFW_KP_8: + return KEY_KP_8; + case RGFW_KP_9: + return KEY_KP_9; + case RGFW_KP_0: + return KEY_KP_0; + case RGFW_KP_Period: + return KEY_KP_DECIMAL; + default: + return 0; + } + + return 0; +} +// EOF From 6fa153fa5319bb049e83b98ade6c4873f0a226c9 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 10:31:41 +0200 Subject: [PATCH 058/278] Update dependencies --- raylib/go.mod | 4 ++-- raylib/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/raylib/go.mod b/raylib/go.mod index c0c536c..9d3e538 100644 --- a/raylib/go.mod +++ b/raylib/go.mod @@ -3,6 +3,6 @@ module github.com/gen2brain/raylib-go/raylib go 1.21 require ( - github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa - golang.org/x/sys v0.14.0 + github.com/ebitengine/purego v0.7.1 + golang.org/x/sys v0.20.0 ) diff --git a/raylib/go.sum b/raylib/go.sum index 96d4ea7..7ea3273 100644 --- a/raylib/go.sum +++ b/raylib/go.sum @@ -1,4 +1,4 @@ -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa h1:Ik7QikRgeH+bFOfAcMpttCbs6XxWXxCLXMm4awxtOXk= -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= +github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= From 8a207901da4e4548ffca804e4abd8f3f96504094 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 10:50:08 +0200 Subject: [PATCH 059/278] Fix DRM build --- .github/workflows/build.yml | 2 +- raylib/platforms/rcore_drm.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2fd4f5..7fa5a4e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,7 +55,7 @@ jobs: uses: actions/checkout@v3 - name: Install package run: | - sudo apt-get update -y; sudo apt-get -y install libegl1-mesa-dev libdrm-dev + sudo apt-get update -y; sudo apt-get -y install libegl1-mesa-dev libdrm-dev libgbm-dev - name: Build run: go build -tags drm working-directory: raylib diff --git a/raylib/platforms/rcore_drm.c b/raylib/platforms/rcore_drm.c index ba60714..b6318fe 100644 --- a/raylib/platforms/rcore_drm.c +++ b/raylib/platforms/rcore_drm.c @@ -89,6 +89,7 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- +typedef unsigned int uint; typedef struct { // Display data From 54ab84ca0c6fe2cffa39c5682403c9d114061f0f Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 10:51:01 +0200 Subject: [PATCH 060/278] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d391fcd..9f849d8 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Put the raylib.dll into the root folder of your project or copy it into `C:\Wind As of November 15, 2023, raylib 5.0 is the required version. -It is also possible build the dll yourself. You can find more infos at [raylib's wiki](https://github.com/raysan5/raylib/wiki/Working-on-Windows). +It is also possible to build the DLL yourself. You can find more info at [raylib's wiki](https://github.com/raysan5/raylib/wiki/Working-on-Windows). ##### Android @@ -54,14 +54,15 @@ It is also possible build the dll yourself. You can find more infos at [raylib's ### Build tags * `drm` - build for Linux native DRM mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM) -* `sdl` - build for SDL backend instead of internal GLFW (PLATFORM_DESKTOP_SDL) +* `sdl` - build for [SDL](https://github.com/libsdl-org/SDL) backend (PLATFORM_DESKTOP_SDL) +* `rgfw` - build for [RGFW](https://github.com/ColleagueRiley/RGFW) backend (PLATFORM_DESKTOP_RGFW) * `noaudio` - disables audio functions * `opengl43` - uses OpenGL 4.3 backend * `opengl21` - uses OpenGL 2.1 backend (default is 3.3 on desktop) * `opengl11` - uses OpenGL 1.1 backend (pseudo OpenGL 1.1 style) * `es2` - uses OpenGL ES 2.0 backend (can be used to link against [Google's ANGLE](https://github.com/google/angle)) * `es3` - experimental support for OpenGL ES 3.0 -* `x11` - force X11 compatibility mode on Wayland +* `x11` - force X11 compatibility mode on Wayland (PLATFORM_DESKTOP/GLFW) ### Documentation From 7c4c1eed60c8ce1c0888972ceee8ddd77dd0552c Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 10:54:48 +0200 Subject: [PATCH 061/278] Update dependencies --- examples/go.mod | 4 ++-- examples/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index 32ed05e..e1f47a1 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -20,6 +20,6 @@ require ( ) require ( - github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa // indirect - golang.org/x/sys v0.14.0 // indirect + github.com/ebitengine/purego v0.7.1 // indirect + golang.org/x/sys v0.20.0 // indirect ) diff --git a/examples/go.sum b/examples/go.sum index 881382a..19ef93f 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,8 +1,8 @@ -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa h1:Ik7QikRgeH+bFOfAcMpttCbs6XxWXxCLXMm4awxtOXk= -github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= +github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI= github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b/go.mod h1:kvKwD9codtns5mvpA53V3vLnqFb/Ahcu8zgkGM0SIbI= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= From 6031600b18501e9292776384d23ff7f02d38306e Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 11:09:31 +0200 Subject: [PATCH 062/278] Test RGFW --- .github/workflows/build.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7fa5a4e..97bfa8b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,6 +80,27 @@ jobs: run: go build -tags sdl working-directory: raylib + test-rgfw: + strategy: + matrix: + go-version: [1.21.x] + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v3 + - name: Install package + run: | + sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev libxkbcommon-dev + if: runner.os == 'Linux' + - name: Build + run: go build -tags rgfw + working-directory: raylib + test-examples: strategy: matrix: From 45279d6d2532273f1056605e769b5916fab14ce5 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 11:19:01 +0200 Subject: [PATCH 063/278] Silence warnings --- raylib/cgo_darwin_rgfw.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/raylib/cgo_darwin_rgfw.go b/raylib/cgo_darwin_rgfw.go index 2c6f47c..dbbee02 100644 --- a/raylib/cgo_darwin_rgfw.go +++ b/raylib/cgo_darwin_rgfw.go @@ -5,7 +5,8 @@ package rl /* #cgo darwin LDFLAGS: -framework Foundation -framework AppKit -framework CoreVideo -#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -DPLATFORM_DESKTOP_RGFW +#cgo darwin CFLAGS: -x objective-c -DPLATFORM_DESKTOP_RGFW -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion +#cgo darwin CFLAGS: -Wno-incompatible-pointer-types -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types-discards-qualifiers -Wno-macro-redefined #cgo darwin,!es2,!es3 LDFLAGS: -framework OpenGL From 64a63d59144ba3fa1798a7a52c3769de35dc87d3 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 11:20:15 +0200 Subject: [PATCH 064/278] Update actions --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97bfa8b..611e99e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,7 @@ name: Build jobs: test: strategy: + fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest, macos-latest, windows-latest] @@ -42,6 +43,7 @@ jobs: test-drm: strategy: + fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest] @@ -62,6 +64,7 @@ jobs: test-sdl: strategy: + fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest] @@ -82,6 +85,7 @@ jobs: test-rgfw: strategy: + fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest, macos-latest, windows-latest] @@ -103,6 +107,7 @@ jobs: test-examples: strategy: + fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest] From 451c14ce9f4136194867bda2f0277df4b115eaba Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 11:25:08 +0200 Subject: [PATCH 065/278] Comment redefinitions --- raylib/external/RGFW.h | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/raylib/external/RGFW.h b/raylib/external/RGFW.h index f806744..903642f 100644 --- a/raylib/external/RGFW.h +++ b/raylib/external/RGFW.h @@ -893,13 +893,13 @@ typedef struct { i32 x, y; } RGFW_vector; typedef void NSApplication; typedef void NSScreen; typedef void NSEvent; - typedef void NSString; + //typedef void NSString; typedef void NSOpenGLContext; typedef void NSPasteboard; typedef void NSColor; - typedef void NSArray; + //typedef void NSArray; typedef void NSImageRep; - typedef void NSImage; + //typedef void NSImage; typedef void NSOpenGLView; @@ -997,29 +997,29 @@ typedef struct { i32 x, y; } RGFW_vector; /* Creates an Objective-C method (SEL) from a regular C function with the option to set the register name.*/ #define si_func_to_SEL_with_name(class_name, register_name, function) si_impl_func_to_SEL_with_name(class_name, register_name":", function) - NSRect NSMakeRect(double x, double y, double width, double height) { - NSRect r; - r.origin.x = x; - r.origin.y = y; - r.size.width = width; - r.size.height = height; + //NSRect NSMakeRect(double x, double y, double width, double height) { + //NSRect r; + //r.origin.x = x; + //r.origin.y = y; + //r.size.width = width; + //r.size.height = height; - return r; - } + //return r; + //} - NSPoint NSMakePoint(double x, double y) { - NSPoint point; - point.x = x; - point.y = y; - return point; - } + //NSPoint NSMakePoint(double x, double y) { + //NSPoint point; + //point.x = x; + //point.y = y; + //return point; + //} - NSSize NSMakeSize(double w, double h) { - NSSize size; - size.width = w; - size.height = h; - return size; - } + //NSSize NSMakeSize(double w, double h) { + //NSSize size; + //size.width = w; + //size.height = h; + //return size; + //} void* si_array_init(void* allocator, size_t sizeof_element, size_t count) { void* array = si_array_init_reserve(sizeof_element, count); From 21775d2dee1bb2b93370a39a1684660e897e78a3 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 11:26:39 +0200 Subject: [PATCH 066/278] Silence warnings --- raylib/cgo_darwin_rgfw.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/cgo_darwin_rgfw.go b/raylib/cgo_darwin_rgfw.go index dbbee02..5c56c41 100644 --- a/raylib/cgo_darwin_rgfw.go +++ b/raylib/cgo_darwin_rgfw.go @@ -5,7 +5,7 @@ package rl /* #cgo darwin LDFLAGS: -framework Foundation -framework AppKit -framework CoreVideo -#cgo darwin CFLAGS: -x objective-c -DPLATFORM_DESKTOP_RGFW -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion +#cgo darwin CFLAGS: -x objective-c -DPLATFORM_DESKTOP_RGFW -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -Wno-typedef-redefinition -Wno-extern-initializer -Wno-unused-value #cgo darwin CFLAGS: -Wno-incompatible-pointer-types -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types-discards-qualifiers -Wno-macro-redefined #cgo darwin,!es2,!es3 LDFLAGS: -framework OpenGL From 48e419d11fa763bcef9b98e682b71ab8eaed5992 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 11:36:02 +0200 Subject: [PATCH 067/278] Update actions --- .github/workflows/build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 611e99e..12a6c17 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,6 @@ jobs: test-drm: strategy: - fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest] @@ -64,7 +63,6 @@ jobs: test-sdl: strategy: - fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest] @@ -107,7 +105,6 @@ jobs: test-examples: strategy: - fail-fast: false matrix: go-version: [1.21.x] os: [ubuntu-latest] From c09c9462b4ba895c9213240079ddffc885c5fa84 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 8 May 2024 19:14:57 +0200 Subject: [PATCH 068/278] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f849d8..d11c3da 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ It is also possible to build the DLL yourself. You can find more info at [raylib ### Build tags -* `drm` - build for Linux native DRM mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM) +* `drm` - build for Linux native [DRM](https://en.wikipedia.org/wiki/Direct_Rendering_Manager) mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM) * `sdl` - build for [SDL](https://github.com/libsdl-org/SDL) backend (PLATFORM_DESKTOP_SDL) * `rgfw` - build for [RGFW](https://github.com/ColleagueRiley/RGFW) backend (PLATFORM_DESKTOP_RGFW) * `noaudio` - disables audio functions From 9b53342ac0617583005414aac357b1854cf58fae Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Thu, 9 May 2024 08:27:51 +0200 Subject: [PATCH 069/278] Fix Android internal storage, issue #365 --- raylib/platform_android.c | 12 ------------ raylib/platform_android.go | 18 ++++++++++++------ 2 files changed, 12 insertions(+), 18 deletions(-) delete mode 100644 raylib/platform_android.c diff --git a/raylib/platform_android.c b/raylib/platform_android.c deleted file mode 100644 index 1e5574b..0000000 --- a/raylib/platform_android.c +++ /dev/null @@ -1,12 +0,0 @@ -// +build android - -#include "_cgo_export.h" - -struct android_app *GetAndroidApp(); - -void android_init() { - struct android_app *app; - app = GetAndroidApp(); - asset_manager = app->activity->assetManager; - internal_storage_path = app->activity->internalDataPath; -} diff --git a/raylib/platform_android.go b/raylib/platform_android.go index 4059899..ecde316 100644 --- a/raylib/platform_android.go +++ b/raylib/platform_android.go @@ -9,10 +9,17 @@ package rl #include #include -extern void android_init(); +extern struct android_app* GetAndroidApp(); -static AAssetManager* asset_manager; -static const char* internal_storage_path; +static AAssetManager* GetAssetManager() { + struct android_app* app = GetAndroidApp(); + return app->activity->assetManager; +} + +static const char* GetInternalStoragePath() { + struct android_app* app = GetAndroidApp(); + return app->activity->internalDataPath; +} */ import "C" @@ -33,7 +40,6 @@ func InitWindow(width int32, height int32, title string) { defer C.free(unsafe.Pointer(ctitle)) C.InitWindow(cwidth, cheight, ctitle) - C.android_init() } // SetCallbackFunc - Sets callback function @@ -98,7 +104,7 @@ func OpenAsset(name string) (Asset, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - a := &asset{C.AAssetManager_open(C.asset_manager, cname, C.AASSET_MODE_UNKNOWN)} + a := &asset{C.AAssetManager_open(C.GetAssetManager(), cname, C.AASSET_MODE_UNKNOWN)} if a.ptr == nil { return nil, fmt.Errorf("asset file could not be opened") @@ -136,5 +142,5 @@ func (a *asset) Close() error { } func getInternalStoragePath() string { - return C.GoString(C.internal_storage_path) + return C.GoString(C.GetInternalStoragePath()) } From 4b3ab504c8024e49ff5888a55acc5d4d2928e5e1 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Thu, 9 May 2024 17:21:05 +0200 Subject: [PATCH 070/278] Update RGFW --- raylib/external/RGFW.h | 56 +++++++++++++-------------- raylib/platforms/rcore_desktop_rgfw.c | 6 +-- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/raylib/external/RGFW.h b/raylib/external/RGFW.h index 903642f..11503a2 100644 --- a/raylib/external/RGFW.h +++ b/raylib/external/RGFW.h @@ -130,16 +130,12 @@ extern "C" { #define RGFW_WINDOWS -#if defined(_WIN32) -#ifndef WIN32 +#if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif -#endif #if defined(_WIN64) -#ifndef WIN64 -#define WIN64 -#endif +//#define WIN64 #define _AMD64_ #undef _X86_ #else @@ -893,13 +889,13 @@ typedef struct { i32 x, y; } RGFW_vector; typedef void NSApplication; typedef void NSScreen; typedef void NSEvent; - //typedef void NSString; + typedef void NSString; typedef void NSOpenGLContext; typedef void NSPasteboard; typedef void NSColor; - //typedef void NSArray; + typedef void NSArray; typedef void NSImageRep; - //typedef void NSImage; + typedef void NSImage; typedef void NSOpenGLView; @@ -997,29 +993,29 @@ typedef struct { i32 x, y; } RGFW_vector; /* Creates an Objective-C method (SEL) from a regular C function with the option to set the register name.*/ #define si_func_to_SEL_with_name(class_name, register_name, function) si_impl_func_to_SEL_with_name(class_name, register_name":", function) - //NSRect NSMakeRect(double x, double y, double width, double height) { - //NSRect r; - //r.origin.x = x; - //r.origin.y = y; - //r.size.width = width; - //r.size.height = height; + NSRect NSMakeRect(double x, double y, double width, double height) { + NSRect r; + r.origin.x = x; + r.origin.y = y; + r.size.width = width; + r.size.height = height; - //return r; - //} + return r; + } - //NSPoint NSMakePoint(double x, double y) { - //NSPoint point; - //point.x = x; - //point.y = y; - //return point; - //} + NSPoint NSMakePoint(double x, double y) { + NSPoint point; + point.x = x; + point.y = y; + return point; + } - //NSSize NSMakeSize(double w, double h) { - //NSSize size; - //size.width = w; - //size.height = h; - //return size; - //} + NSSize NSMakeSize(double w, double h) { + NSSize size; + size.width = w; + size.height = h; + return size; + } void* si_array_init(void* allocator, size_t sizeof_element, size_t count) { void* array = si_array_init_reserve(sizeof_element, count); @@ -6078,7 +6074,7 @@ static HMODULE wglinstance = NULL; } void RGFW_sleep(u32 ms) { -#if !defined(_MSC_VER) && !defined(__MINGW32__) +#ifndef RGFW_WINDOWS struct timespec time; time.tv_sec = 0; time.tv_nsec = ms * 1000; diff --git a/raylib/platforms/rcore_desktop_rgfw.c b/raylib/platforms/rcore_desktop_rgfw.c index 12e18af..858fd71 100644 --- a/raylib/platforms/rcore_desktop_rgfw.c +++ b/raylib/platforms/rcore_desktop_rgfw.c @@ -61,15 +61,11 @@ void CloseWindow(void); #define _XTYPEDEF_FONT #define RGFW_IMPLEMENTATION -#if defined(_WIN32) - #define WIN32_LEAN_AND_MEAN #define Rectangle rectangle_win32 #define CloseWindow CloseWindow_win32 #define ShowCursor __imp_ShowCursor -#endif // _WIN32 - #define Point NSPOINT #define Size NSSIZE @@ -79,11 +75,11 @@ __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, #include "../external/RGFW.h" #undef DrawText +#undef Rectangle #undef ShowCursor #undef CloseWindow #undef Point #undef Size -#undef Rectangle #define Rectangle struct Rectangle void CloseWindow(void); From f68049cf26487b24c5b170e62bf4ca632db275c0 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Thu, 9 May 2024 17:21:52 +0200 Subject: [PATCH 071/278] Update darwin flags --- raylib/cgo_darwin_rgfw.go | 2 +- raylib/cgo_darwin_sdl.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/raylib/cgo_darwin_rgfw.go b/raylib/cgo_darwin_rgfw.go index 5c56c41..619c3fd 100644 --- a/raylib/cgo_darwin_rgfw.go +++ b/raylib/cgo_darwin_rgfw.go @@ -5,7 +5,7 @@ package rl /* #cgo darwin LDFLAGS: -framework Foundation -framework AppKit -framework CoreVideo -#cgo darwin CFLAGS: -x objective-c -DPLATFORM_DESKTOP_RGFW -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -Wno-typedef-redefinition -Wno-extern-initializer -Wno-unused-value +#cgo darwin CFLAGS: -DPLATFORM_DESKTOP_RGFW -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -Wno-typedef-redefinition -Wno-extern-initializer -Wno-unused-value #cgo darwin CFLAGS: -Wno-incompatible-pointer-types -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types-discards-qualifiers -Wno-macro-redefined #cgo darwin,!es2,!es3 LDFLAGS: -framework OpenGL diff --git a/raylib/cgo_darwin_sdl.go b/raylib/cgo_darwin_sdl.go index 055f3eb..e0902ea 100644 --- a/raylib/cgo_darwin_sdl.go +++ b/raylib/cgo_darwin_sdl.go @@ -5,7 +5,7 @@ package rl /* #cgo darwin LDFLAGS: -framework Cocoa -framework IOKit -framework CoreVideo -framework CoreFoundation -#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -DPLATFORM_DESKTOP_SDL +#cgo darwin CFLAGS: -Wno-deprecated-declarations -Wno-implicit-const-int-float-conversion -DPLATFORM_DESKTOP_SDL #cgo darwin pkg-config: sdl2 #cgo darwin,!es2,!es3 LDFLAGS: -framework OpenGL From 032352a5ba0744fbd5d17084130b9b5626837160 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sat, 11 May 2024 19:16:35 -0500 Subject: [PATCH 072/278] Update rlgl_cgo.go --- raylib/rlgl_cgo.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index 0136791..3ad2e42 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -90,6 +90,11 @@ func Scalef(x float32, y float32, z float32) { C.rlScalef(cx, cy, cz) } +// MultMatrix - Multiply the current matrix by another matrix +func MultMatrix(m Matrix) { + C.rlMultMatrixf(MatrixToFloat(m)) +} + // Frustum . func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { cleft := C.double(left) From da79f1d8b66a27ce377653ba5509ce7885d82315 Mon Sep 17 00:00:00 2001 From: Kyle Rockman Date: Sat, 11 May 2024 19:38:23 -0500 Subject: [PATCH 073/278] fix function to actually work --- raylib/rlgl_cgo.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index 3ad2e42..c27d357 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -92,7 +92,8 @@ func Scalef(x float32, y float32, z float32) { // MultMatrix - Multiply the current matrix by another matrix func MultMatrix(m Matrix) { - C.rlMultMatrixf(MatrixToFloat(m)) + f := MatrixToFloat(m) + C.rlMultMatrixf((*C.float)(&f[0])) } // Frustum . From 49242a59c92f1665931e0ff6ac36f5fc6d5f6f4e Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 13 May 2024 07:15:11 -0500 Subject: [PATCH 074/278] Update rlgl_purego.go --- raylib/rlgl_purego.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index ccb5029..9c6d3d1 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -16,6 +16,7 @@ var rlLoadIdentity func() var rlTranslatef func(x float32, y float32, z float32) var rlRotatef func(angle float32, x float32, y float32, z float32) var rlScalef func(x float32, y float32, z float32) +var rlMultMatrix func(m []float32) var rlFrustum func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlOrtho func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlViewport func(x int32, y int32, width int32, height int32) @@ -138,6 +139,7 @@ func initRlglPurego() { purego.RegisterLibFunc(&rlTranslatef, raylibDll, "rlTranslatef") purego.RegisterLibFunc(&rlRotatef, raylibDll, "rlRotatef") purego.RegisterLibFunc(&rlScalef, raylibDll, "rlScalef") + purego.RegisterLibFunc(&rlMultMatrix, raylibDll, "rlMultMatrix") purego.RegisterLibFunc(&rlFrustum, raylibDll, "rlFrustum") purego.RegisterLibFunc(&rlOrtho, raylibDll, "rlOrtho") purego.RegisterLibFunc(&rlViewport, raylibDll, "rlViewport") From ac27873749c667aef020ddba21d771c8d8c3b8b1 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 14 May 2024 22:49:48 +0200 Subject: [PATCH 075/278] MAX_TRACELOG_BUFFER_SIZE is 256 since raylib 4.5 --- raylib/utils_log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/utils_log.c b/raylib/utils_log.c index 212a4ae..7d3d95e 100644 --- a/raylib/utils_log.c +++ b/raylib/utils_log.c @@ -3,7 +3,7 @@ #include // Required for: vprintf() #include // Required for: strcpy(), strcat() -#define MAX_TRACELOG_BUFFER_SIZE 128 // As defined in utils.c from raylib +#define MAX_TRACELOG_BUFFER_SIZE 256 // As defined in utils.c from raylib void rayLogWrapperCallback(int logType, const char *text, va_list args) { char buffer[MAX_TRACELOG_BUFFER_SIZE] = { 0 }; From 6fd7907d3108570fca76c772fcc190291b891f9e Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 14 May 2024 23:09:47 +0200 Subject: [PATCH 076/278] Use fmt.Sprintf for TraceLog to match with cgo --- raylib/raylib_purego.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index ef58489..55cbfdf 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -4,6 +4,7 @@ package rl import ( + "fmt" "image" "image/color" "os" @@ -121,7 +122,7 @@ var unloadRandomSequence func(sequence *int32) var takeScreenshot func(fileName string) var setConfigFlags func(flags uint32) var openURL func(url string) -var traceLog func(logLevel int32, text string, args ...any) +var traceLog func(logLevel int32, text string) var setTraceLogLevel func(logLevel int32) var memAlloc func(size uint32) unsafe.Pointer var memRealloc func(ptr unsafe.Pointer, size uint32) unsafe.Pointer @@ -1556,7 +1557,7 @@ func OpenURL(url string) { // TraceLog - Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) func TraceLog(logLevel TraceLogLevel, text string, args ...any) { - traceLog(int32(logLevel), text, args...) + traceLog(int32(logLevel), fmt.Sprintf(text, args...)) } // SetTraceLogLevel - Set the current threshold (minimum) log level From fa7e76c6a6e4bffc1e65de850d05dee247149dfd Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 14 May 2024 23:17:31 +0200 Subject: [PATCH 077/278] implement va_list for tracelog callbacks in purego --- raylib/purego_windows.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/raylib/purego_windows.go b/raylib/purego_windows.go index 470d16d..a46c878 100644 --- a/raylib/purego_windows.go +++ b/raylib/purego_windows.go @@ -5,6 +5,7 @@ package rl import ( "fmt" + "syscall" "unsafe" "github.com/ebitengine/purego" @@ -16,6 +17,15 @@ const ( requiredVersion = "5.0" ) +var wvsprintfA uintptr + +func init() { + handle, err := windows.LoadLibrary("user32.dll") + if err == nil { + wvsprintfA, _ = windows.GetProcAddress(handle, "wvsprintfA") + } +} + // loadLibrary loads the raylib dll and panics on error func loadLibrary() uintptr { handle, err := windows.LoadLibrary(libname) @@ -37,7 +47,14 @@ func loadLibrary() uintptr { } func traceLogCallbackWrapper(fn TraceLogCallbackFun) uintptr { - return purego.NewCallback(func(logLevel int32, text *byte) uintptr { + return purego.NewCallback(func(logLevel int32, text *byte, args unsafe.Pointer) uintptr { + if wvsprintfA != 0 { + var buffer [1024]byte // Max size is 1024 (see https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-wvsprintfa) + _, _, errno := syscall.SyscallN(wvsprintfA, uintptr(unsafe.Pointer(&buffer[0])), uintptr(unsafe.Pointer(text)), uintptr(args)) + if errno == 0 { + text = &buffer[0] + } + } fn(int(logLevel), windows.BytePtrToString(text)) return 0 }) From 4c0391d2175200adf5d227cda9c5e1e1ff501e1d Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 14 May 2024 23:22:31 +0200 Subject: [PATCH 078/278] comment fixed --- raylib/raylib_purego.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 55cbfdf..53d061d 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -1581,8 +1581,6 @@ func MemFree(ptr unsafe.Pointer) { } // SetTraceLogCallback - Set custom trace log -// -// REVIEW NEEDED! 2023-11-15 JupiterRider: The argument list paramter isn't impelmented yet. func SetTraceLogCallback(fn TraceLogCallbackFun) { setTraceLogCallback(traceLogCallbackWrapper(fn)) } From c212c3388657742aa15f3996db911dac0cf53961 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Thu, 16 May 2024 19:05:18 +0200 Subject: [PATCH 079/278] [raygui] empty string will cause the draw of a title-bar, but nil doesn't --- raygui/raygui.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/raygui/raygui.go b/raygui/raygui.go index 2e7a6ed..379875a 100644 --- a/raygui/raygui.go +++ b/raygui/raygui.go @@ -356,8 +356,11 @@ func ScrollPanel(bounds rl.Rectangle, text string, content rl.Rectangle, scroll cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } var ccontent C.struct_Rectangle ccontent.x = C.float(content.X) ccontent.y = C.float(content.Y) From 7c239d105098ecabd34a27c4c12fbea0fb025dc7 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Thu, 16 May 2024 20:41:28 +0200 Subject: [PATCH 080/278] [raygui] use nil for empty strings; fixes #386 --- raygui/raygui.go | 254 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 184 insertions(+), 70 deletions(-) diff --git a/raygui/raygui.go b/raygui/raygui.go index 379875a..2d7c173 100644 --- a/raygui/raygui.go +++ b/raygui/raygui.go @@ -308,8 +308,11 @@ func WindowBox(bounds rl.Rectangle, title string) bool { cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) - ctitle := C.CString(title) - defer C.free(unsafe.Pointer(ctitle)) + var ctitle *C.char + if len(title) > 0 { + ctitle = C.CString(title) + defer C.free(unsafe.Pointer(ctitle)) + } return C.GuiWindowBox(cbounds, ctitle) != 0 } @@ -320,8 +323,11 @@ func GroupBox(bounds rl.Rectangle, text string) { cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } C.GuiGroupBox(cbounds, ctext) } @@ -332,8 +338,11 @@ func Line(bounds rl.Rectangle, text string) { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } C.GuiLine(cbounds, ctext) } @@ -344,8 +353,11 @@ func Panel(bounds rl.Rectangle, text string) { cbounds.height = C.float(bounds.Height) cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } C.GuiPanel(cbounds, ctext) } @@ -412,8 +424,11 @@ func Label(bounds rl.Rectangle, text string) { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } C.GuiLabel(cbounds, ctext) } @@ -424,8 +439,11 @@ func Button(bounds rl.Rectangle, text string) bool { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } return C.GuiButton(cbounds, ctext) != 0 } @@ -436,8 +454,11 @@ func LabelButton(bounds rl.Rectangle, text string) bool { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } return C.GuiLabelButton(cbounds, ctext) != 0 } @@ -448,8 +469,11 @@ func Toggle(bounds rl.Rectangle, text string, active bool) bool { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cactive := C.bool(active) C.GuiToggle(cbounds, ctext, &cactive) return bool(cactive) @@ -462,8 +486,11 @@ func ToggleGroup(bounds rl.Rectangle, text string, active int32) int32 { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cactive := C.int(active) C.GuiToggleGroup(cbounds, ctext, &cactive) return int32(cactive) @@ -476,8 +503,11 @@ func ToggleSlider(bounds rl.Rectangle, text string, active int32) int32 { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cactive := C.int(active) C.GuiToggleSlider(cbounds, ctext, &cactive) return int32(cactive) @@ -490,8 +520,11 @@ func CheckBox(bounds rl.Rectangle, text string, checked bool) bool { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cchecked := C.bool(checked) C.GuiCheckBox(cbounds, ctext, &cchecked) return bool(cchecked) @@ -504,8 +537,11 @@ func ComboBox(bounds rl.Rectangle, text string, active int32) int32 { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cactive := C.int(active) C.GuiComboBox(cbounds, ctext, &cactive) return int32(cactive) @@ -518,8 +554,11 @@ func Spinner(bounds rl.Rectangle, text string, value *int32, minValue, maxValue cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } if value == nil { value = new(int32) @@ -544,10 +583,19 @@ func Slider(bounds rl.Rectangle, textLeft string, textRight string, value float3 cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctextLeft := C.CString(textLeft) - defer C.free(unsafe.Pointer(ctextLeft)) - ctextRight := C.CString(textRight) - defer C.free(unsafe.Pointer(ctextRight)) + + var ctextLeft *C.char + if len(textLeft) > 0 { + ctextLeft = C.CString(textLeft) + defer C.free(unsafe.Pointer(ctextLeft)) + } + + var ctextRight *C.char + if len(textRight) > 0 { + ctextRight = C.CString(textRight) + defer C.free(unsafe.Pointer(ctextRight)) + } + cvalue := C.float(value) cminValue := C.float(minValue) cmaxValue := C.float(maxValue) @@ -562,10 +610,19 @@ func SliderBar(bounds rl.Rectangle, textLeft string, textRight string, value flo cbounds.height = C.float(bounds.Height) cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctextLeft := C.CString(textLeft) - defer C.free(unsafe.Pointer(ctextLeft)) - ctextRight := C.CString(textRight) - defer C.free(unsafe.Pointer(ctextRight)) + + var ctextLeft *C.char + if len(textLeft) > 0 { + ctextLeft = C.CString(textLeft) + defer C.free(unsafe.Pointer(ctextLeft)) + } + + var ctextRight *C.char + if len(textRight) > 0 { + ctextRight = C.CString(textRight) + defer C.free(unsafe.Pointer(ctextRight)) + } + cvalue := C.float(value) cminValue := C.float(minValue) cmaxValue := C.float(maxValue) @@ -580,10 +637,19 @@ func ProgressBar(bounds rl.Rectangle, textLeft string, textRight string, value f cbounds.height = C.float(bounds.Height) cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctextLeft := C.CString(textLeft) - defer C.free(unsafe.Pointer(ctextLeft)) - ctextRight := C.CString(textRight) - defer C.free(unsafe.Pointer(ctextRight)) + + var ctextLeft *C.char + if len(textLeft) > 0 { + ctextLeft = C.CString(textLeft) + defer C.free(unsafe.Pointer(ctextLeft)) + } + + var ctextRight *C.char + if len(textRight) > 0 { + ctextRight = C.CString(textRight) + defer C.free(unsafe.Pointer(ctextRight)) + } + cvalue := C.float(value) cminValue := C.float(minValue) cmaxValue := C.float(maxValue) @@ -598,8 +664,11 @@ func StatusBar(bounds rl.Rectangle, text string) { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } C.GuiStatusBar(cbounds, ctext) } @@ -610,8 +679,11 @@ func DummyRec(bounds rl.Rectangle, text string) { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } C.GuiDummyRec(cbounds, ctext) } @@ -622,8 +694,11 @@ func Grid(bounds rl.Rectangle, text string, spacing float32, subdivs int32, mous cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) cbounds.x = C.float(bounds.X) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cspacing := C.float(spacing) csubdivs := C.int(subdivs) var cmouseCell C.struct_Vector2 @@ -642,8 +717,11 @@ func ListView(bounds rl.Rectangle, text string, scrollIndex *int32, active int32 cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } if scrollIndex == nil { scrollIndex = new(int32) @@ -666,10 +744,16 @@ func MessageBox(bounds rl.Rectangle, title string, message string, buttons strin cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctitle := C.CString(title) - defer C.free(unsafe.Pointer(ctitle)) - cmessage := C.CString(message) - defer C.free(unsafe.Pointer(cmessage)) + var ctitle *C.char + if len(title) > 0 { + ctitle = C.CString(title) + defer C.free(unsafe.Pointer(ctitle)) + } + var cmessage *C.char + if len(message) > 0 { + cmessage = C.CString(message) + defer C.free(unsafe.Pointer(cmessage)) + } cbuttons := C.CString(buttons) defer C.free(unsafe.Pointer(cbuttons)) return int32(C.GuiMessageBox(cbounds, ctitle, cmessage, cbuttons)) @@ -682,8 +766,11 @@ func ColorPicker(bounds rl.Rectangle, text string, color rl.Color) rl.Color { cbounds.height = C.float(bounds.Height) cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } var ccolor C.struct_Color ccolor.r = C.uchar(color.R) ccolor.g = C.uchar(color.G) @@ -705,8 +792,11 @@ func ColorPanel(bounds rl.Rectangle, text string, color rl.Color) rl.Color { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } var ccolor C.struct_Color ccolor.b = C.uchar(color.B) ccolor.a = C.uchar(color.A) @@ -728,8 +818,11 @@ func ColorBarAlpha(bounds rl.Rectangle, text string, alpha float32) float32 { cbounds.height = C.float(bounds.Height) cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } calpha := C.float(alpha) C.GuiColorBarAlpha(cbounds, ctext, &calpha) return float32(calpha) @@ -742,8 +835,11 @@ func ColorBarHue(bounds rl.Rectangle, text string, value float32) float32 { cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } cvalue := C.float(value) C.GuiColorBarHue(cbounds, ctext, &cvalue) return float32(cvalue) @@ -757,8 +853,11 @@ func ColorPickerHSV(bounds rl.Rectangle, text string, colorHSV *rl.Vector3) int3 cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } var ccolorHSV C.struct_Vector3 ccolorHSV.x = C.float(colorHSV.X) @@ -781,8 +880,11 @@ func ColorPanelHSV(bounds rl.Rectangle, text string, colorHSV *rl.Vector3) int32 cbounds.x = C.float(bounds.X) cbounds.y = C.float(bounds.Y) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } var ccolorHSV C.struct_Vector3 ccolorHSV.x = C.float(colorHSV.X) @@ -804,8 +906,11 @@ func DropdownBox(bounds rl.Rectangle, text string, active *int32, editMode bool) cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } if active == nil { active = new(int32) @@ -827,8 +932,11 @@ func ValueBox(bounds rl.Rectangle, text string, value *int32, minValue, maxValue cbounds.y = C.float(bounds.Y) cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctext := C.CString(text) - defer C.free(unsafe.Pointer(ctext)) + var ctext *C.char + if len(text) > 0 { + ctext = C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + } if value == nil { value = new(int32) @@ -1165,11 +1273,17 @@ func TextInputBox(bounds rl.Rectangle, title, message, buttons string, text *str cbounds.width = C.float(bounds.Width) cbounds.height = C.float(bounds.Height) - ctitle := C.CString(title) - defer C.free(unsafe.Pointer(ctitle)) + var ctitle *C.char + if len(title) > 0 { + ctitle = C.CString(title) + defer C.free(unsafe.Pointer(ctitle)) + } - cmessage := C.CString(message) - defer C.free(unsafe.Pointer(cmessage)) + var cmessage *C.char + if len(message) > 0 { + cmessage = C.CString(message) + defer C.free(unsafe.Pointer(cmessage)) + } cbuttons := C.CString(buttons) defer C.free(unsafe.Pointer(cbuttons)) From a158bd444e6ee9b70cb60b725b375aed615c4221 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sat, 18 May 2024 17:56:40 +0200 Subject: [PATCH 081/278] [raygui] don't trim leading and trailing white spaces (fix #351) --- raygui/raygui.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raygui/raygui.go b/raygui/raygui.go index 2d7c173..5c643f7 100644 --- a/raygui/raygui.go +++ b/raygui/raygui.go @@ -970,7 +970,7 @@ func TextBox(bounds rl.Rectangle, text *string, textSize int, editMode bool) boo } ctext := (*C.char)(unsafe.Pointer(&bs[0])) defer func() { - *text = strings.TrimSpace(strings.Trim(string(bs), "\x00")) + *text = strings.Trim(string(bs), "\x00") // no need : C.free(unsafe.Pointer(ctext)) }() From b56bfca1e8a9c5c793bb986dafc8728a0bc86fbf Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 21 May 2024 15:31:37 -0500 Subject: [PATCH 082/278] Update rlgl_purego.go correctly --- raylib/rlgl_purego.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index 9c6d3d1..518b487 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -16,7 +16,7 @@ var rlLoadIdentity func() var rlTranslatef func(x float32, y float32, z float32) var rlRotatef func(angle float32, x float32, y float32, z float32) var rlScalef func(x float32, y float32, z float32) -var rlMultMatrix func(m []float32) +var rlMultMatrix func(m *float32) var rlFrustum func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlOrtho func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlViewport func(x int32, y int32, width int32, height int32) @@ -300,6 +300,12 @@ func Scalef(x float32, y float32, z float32) { rlScalef(x, y, z) } +// MultMatrix - Multiply the current matrix by another matrix +func MultMatrix(m Matrix) { + f := MatrixToFloat(m) + rlMultMatrixf(unsafe.Pointer(&f[0])) +} + // Frustum . func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { rlFrustum(left, right, bottom, top, znear, zfar) From 426bcb352915ec37cf4242661771399bd66cf7a2 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 22 May 2024 07:12:22 -0500 Subject: [PATCH 083/278] Fix typo --- raylib/rlgl_purego.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index 518b487..53825b6 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -303,7 +303,7 @@ func Scalef(x float32, y float32, z float32) { // MultMatrix - Multiply the current matrix by another matrix func MultMatrix(m Matrix) { f := MatrixToFloat(m) - rlMultMatrixf(unsafe.Pointer(&f[0])) + rlMultMatrix(unsafe.Pointer(&f[0])) } // Frustum . From 86d08a7b8682ead7ebd0eb09878a70467646f289 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 22 May 2024 15:37:00 +0200 Subject: [PATCH 084/278] MultMatrix for purego added --- raylib/raymath.go | 24 ++++++++++++++++++++++++ raylib/rcore.go | 24 ------------------------ raylib/rlgl_purego.go | 8 ++++++++ 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/raylib/raymath.go b/raylib/raymath.go index 94401af..372bf46 100644 --- a/raylib/raymath.go +++ b/raylib/raymath.go @@ -1360,6 +1360,30 @@ func MatrixToFloatV(mat Matrix) [16]float32 { return result } +// MatrixToFloat - Converts Matrix to float32 slice +func MatrixToFloat(mat Matrix) []float32 { + data := make([]float32, 16) + + data[0] = mat.M0 + data[1] = mat.M4 + data[2] = mat.M8 + data[3] = mat.M12 + data[4] = mat.M1 + data[5] = mat.M5 + data[6] = mat.M9 + data[7] = mat.M13 + data[8] = mat.M2 + data[9] = mat.M6 + data[10] = mat.M10 + data[11] = mat.M14 + data[12] = mat.M3 + data[13] = mat.M7 + data[14] = mat.M11 + data[15] = mat.M15 + + return data +} + // QuaternionAdd - Add two quaternions func QuaternionAdd(q1 Quaternion, q2 Quaternion) Quaternion { var result = Quaternion{X: q1.X + q2.X, Y: q1.Y + q2.Y, Z: q1.Z + q2.Z, W: q1.W + q2.W} diff --git a/raylib/rcore.go b/raylib/rcore.go index 7dfd092..9737e08 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -854,30 +854,6 @@ func Vector3ToFloat(vec Vector3) []float32 { return data } -// MatrixToFloat - Converts Matrix to float32 slice -func MatrixToFloat(mat Matrix) []float32 { - data := make([]float32, 16) - - data[0] = mat.M0 - data[1] = mat.M4 - data[2] = mat.M8 - data[3] = mat.M12 - data[4] = mat.M1 - data[5] = mat.M5 - data[6] = mat.M9 - data[7] = mat.M13 - data[8] = mat.M2 - data[9] = mat.M6 - data[10] = mat.M10 - data[11] = mat.M14 - data[12] = mat.M3 - data[13] = mat.M7 - data[14] = mat.M11 - data[15] = mat.M15 - - return data -} - // GetRandomValue - Returns a random value between min and max (both included) func GetRandomValue(min, max int32) int32 { cmin := (C.int)(min) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index ccb5029..a8c15d3 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -16,6 +16,7 @@ var rlLoadIdentity func() var rlTranslatef func(x float32, y float32, z float32) var rlRotatef func(angle float32, x float32, y float32, z float32) var rlScalef func(x float32, y float32, z float32) +var rlMultMatrixf func(matf *float32) var rlFrustum func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlOrtho func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlViewport func(x int32, y int32, width int32, height int32) @@ -138,6 +139,7 @@ func initRlglPurego() { purego.RegisterLibFunc(&rlTranslatef, raylibDll, "rlTranslatef") purego.RegisterLibFunc(&rlRotatef, raylibDll, "rlRotatef") purego.RegisterLibFunc(&rlScalef, raylibDll, "rlScalef") + purego.RegisterLibFunc(&rlMultMatrixf, raylibDll, "rlMultMatrixf") purego.RegisterLibFunc(&rlFrustum, raylibDll, "rlFrustum") purego.RegisterLibFunc(&rlOrtho, raylibDll, "rlOrtho") purego.RegisterLibFunc(&rlViewport, raylibDll, "rlViewport") @@ -298,6 +300,12 @@ func Scalef(x float32, y float32, z float32) { rlScalef(x, y, z) } +// MultMatrix - Multiply the current matrix by another matrix +func MultMatrix(m Matrix) { + f := MatrixToFloat(m) + rlMultMatrixf((*float32)(&f[0])) +} + // Frustum . func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { rlFrustum(left, right, bottom, top, znear, zfar) From 9fe64ac4bde8f4e758abfbe9383191f86fb4c4c8 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 22 May 2024 16:23:31 +0200 Subject: [PATCH 085/278] Fix MatrixToFloat --- raylib/raymath.go | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/raylib/raymath.go b/raylib/raymath.go index 372bf46..5330912 100644 --- a/raylib/raymath.go +++ b/raylib/raymath.go @@ -1362,26 +1362,8 @@ func MatrixToFloatV(mat Matrix) [16]float32 { // MatrixToFloat - Converts Matrix to float32 slice func MatrixToFloat(mat Matrix) []float32 { - data := make([]float32, 16) - - data[0] = mat.M0 - data[1] = mat.M4 - data[2] = mat.M8 - data[3] = mat.M12 - data[4] = mat.M1 - data[5] = mat.M5 - data[6] = mat.M9 - data[7] = mat.M13 - data[8] = mat.M2 - data[9] = mat.M6 - data[10] = mat.M10 - data[11] = mat.M14 - data[12] = mat.M3 - data[13] = mat.M7 - data[14] = mat.M11 - data[15] = mat.M15 - - return data + data := MatrixToFloatV(mat) + return data[:] } // QuaternionAdd - Add two quaternions From 4a4f1ef82ea81ce5521544d5f4a399f88a4e02cc Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 22 May 2024 09:55:19 -0500 Subject: [PATCH 086/278] Remove purego implementation --- raylib/rlgl_purego.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index 53825b6..ccb5029 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -16,7 +16,6 @@ var rlLoadIdentity func() var rlTranslatef func(x float32, y float32, z float32) var rlRotatef func(angle float32, x float32, y float32, z float32) var rlScalef func(x float32, y float32, z float32) -var rlMultMatrix func(m *float32) var rlFrustum func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlOrtho func(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) var rlViewport func(x int32, y int32, width int32, height int32) @@ -139,7 +138,6 @@ func initRlglPurego() { purego.RegisterLibFunc(&rlTranslatef, raylibDll, "rlTranslatef") purego.RegisterLibFunc(&rlRotatef, raylibDll, "rlRotatef") purego.RegisterLibFunc(&rlScalef, raylibDll, "rlScalef") - purego.RegisterLibFunc(&rlMultMatrix, raylibDll, "rlMultMatrix") purego.RegisterLibFunc(&rlFrustum, raylibDll, "rlFrustum") purego.RegisterLibFunc(&rlOrtho, raylibDll, "rlOrtho") purego.RegisterLibFunc(&rlViewport, raylibDll, "rlViewport") @@ -300,12 +298,6 @@ func Scalef(x float32, y float32, z float32) { rlScalef(x, y, z) } -// MultMatrix - Multiply the current matrix by another matrix -func MultMatrix(m Matrix) { - f := MatrixToFloat(m) - rlMultMatrix(unsafe.Pointer(&f[0])) -} - // Frustum . func Frustum(left float64, right float64, bottom float64, top float64, znear float64, zfar float64) { rlFrustum(left, right, bottom, top, znear, zfar) From 6c4349fd5ca70c03f32658190cb982ac6af6f37d Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 22 May 2024 17:12:50 +0200 Subject: [PATCH 087/278] Test purego --- .github/workflows/build.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12a6c17..e320161 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,6 +103,25 @@ jobs: run: go build -tags rgfw working-directory: raylib + test-purego: + strategy: + matrix: + go-version: [1.21.x] + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v3 + - name: Build + run: go build + working-directory: raylib + env: + GOOS: windows + test-examples: strategy: matrix: From d86638ae103fbe1c8b4f8ee4e8e9e479cfeb30c9 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 22 May 2024 18:51:38 +0200 Subject: [PATCH 088/278] [raygui] LoadIcons-, DrawIcon-function and example added --- examples/gui/icons/README.md | 3 +++ examples/gui/icons/default_icons_with_255.rgi | Bin 0 -> 16396 bytes examples/gui/icons/main.go | 20 ++++++++++++++++++ examples/gui/icons/screenshot.png | Bin 0 -> 8240 bytes raygui/raygui.go | 13 ++++++++++++ 5 files changed, 36 insertions(+) create mode 100644 examples/gui/icons/README.md create mode 100644 examples/gui/icons/default_icons_with_255.rgi create mode 100644 examples/gui/icons/main.go create mode 100644 examples/gui/icons/screenshot.png diff --git a/examples/gui/icons/README.md b/examples/gui/icons/README.md new file mode 100644 index 0000000..8c114f4 --- /dev/null +++ b/examples/gui/icons/README.md @@ -0,0 +1,3 @@ +This example loads a custom .rgi-file and draws the 255th icon. You can use the [rGuiIcons](https://raylibtech.itch.io/rguiicons) tool to view or create icon files. + +![Screenshot](./screenshot.png) diff --git a/examples/gui/icons/default_icons_with_255.rgi b/examples/gui/icons/default_icons_with_255.rgi new file mode 100644 index 0000000000000000000000000000000000000000..82716175787ae31b6027dbc0b62101b6fe0036a5 GIT binary patch literal 16396 zcmeHNO^h2yb}lws!#2ewdq!iKfT&>)HJ0e{!b6XuV6Yw!n?F6nwm8!?eB55{5-2J9Gwp#VBLhEF*-03qx_SmZz` zIuHs$<-Mx@CA;Yya>zmT!0zh$URAxS_v+QFn)%x;ReFO!3W#J!+fgvQK>dJ z)w0smD$33{9|dZ;OG>j)&edvaVT{43?^Ts@8aTEvR+D}Dc5HB4{d?9XgyPDTidL1EP8@aNb#alR_gxp)nBS8&AM{Ms|T!4@m!;*YLmTKxVoL&^60|CE9Klvlhvtw zwEatJQJLEQ&ZY;<##hiPUTtG{bo_;e*U+dm6tCoJKGQ=AjcQG+HcPo3?)zW$mJY}-7HqMio0F& ztDu!(_!YHq(Q9;sR2%ucH^N$A_45s=@2LYcyQU|?>Qg*tN;CPc6>?<{v$GhhN=` zRX_74Cf+P*RrO_Ur=D{glZ9VWs&y46%P}_0mX)2_Sdr@!aewP0M0pAP>V#Ldo1pmS zrd=?WGv>GMXMYSItK|5s=c-#u-CutOUfa%<$A?Z^F>v4YW#HSIkAFAT_jlpGW@^-@ zc(bZ*mB!YB3ok31V=!s#6usP{HA7Y9yYT58+l@MS2&=h?OjY|1T&XCzaiJZp)Jl!b zO;5{bOv-kp{!(7M;;7=vGX1!UTpv#TV-zrM1h)RYP(mE~_hfMBe;Us8>(ReUzf}M3 zW?VSx-wjj!j}^JbkJ_D%Pv>Cz_iusee+o|Z?~fb$_hm5k-}G6*Q%r--1K{9XeKt4X zFmSJ>XVv#umew3&{k&GMYunyU*tk{2m9g=r$LePCc>+c&ru=?9h!+&^*aVxPxLPeh zc)XpfU3AHY9~EuN;su;;ZO!dQxvo~q9=jC7p?QzJ6WcGU^^#ImcYMMdvaMFOa~1zB z3gzFbs@}mFv_B2Q{^|I&>W)&ad779L_u3>jwMG>T;ELiSBKGfV+(!R&_I$#Wmo=~~ zAKORyDZZ@~)y6h{P9%zZ32tyw+-Gk@7K%?XAe^6~R`;GfsBhsuGO+pG!5*p;hcBZ( zokO4c+QlY>HIsIWvSWhytLCE`is!0T?XvgMbKw3SfYmQ*mwjR&hBtg2klnwxl`!06 zW1!N(`lIq=|I_L>D&8p6_deDct;6}rcjsj+m;DaDMhl2HYwAwJM+pq4L9o@QGedDO zjoi*wqwL{BsD7s`5IlBbd|y>AshWonCJt=Pd~VW^9Jo^~D{tbtM$I!yGVq$;9%SG< z-luQyzfAtBQqZbiP7Y4pJKiTNCSqADT!iDH<}Dq>|A_nEZov9M25YpFnYyNxeN;=C zxBMKx(G=p-&KG&rXJHxj@nFuPfA3Q$TNZ~3$9*Z@>Jg=&a?hYo3_XF z=h?IaZ@$pj_I42$6^~8T(Ogm4_LU9U==r&#Rs6)H^RM_X@

PQ8@aiI8%V98Pp(v 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 literal 0 HcmV?d00001 diff --git a/raygui/raygui.go b/raygui/raygui.go index 5c643f7..b72e28b 100644 --- a/raygui/raygui.go +++ b/raygui/raygui.go @@ -8,6 +8,7 @@ package raygui import "C" import ( + "image/color" "strings" "unsafe" @@ -1381,3 +1382,15 @@ func GetFont() rl.Font { ptr := unsafe.Pointer(&ret) return *(*rl.Font)(ptr) } + +// LoadIcons - load raygui icons file (.rgi) into internal icons data +func LoadIcons(fileName string, loadIconsName bool) { + cfileName := C.CString(fileName) + defer C.free(unsafe.Pointer(cfileName)) + C.GuiLoadIcons(cfileName, C.bool(loadIconsName)) +} + +// DrawIcon - draw icon using pixel size at specified position +func DrawIcon(iconId, posX, posY, pixelSize int32, col color.RGBA) { + C.GuiDrawIcon(C.int(iconId), C.int(posX), C.int(posY), C.int(pixelSize), *(*C.Color)(unsafe.Pointer(&col))) +} From a997a44fb95b521f6ef5642dabd363cca7f89808 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Fri, 24 May 2024 09:43:10 +0200 Subject: [PATCH 089/278] Support Windows 7, issue #392 --- raylib/compat.go | 98 +++++++++++++++++++++++++++++++++++++++++ raylib/compat_compat.go | 69 +++++++++++++++++++++++++++++ raylib/go.mod | 2 + raylib/go.sum | 2 + raylib/rmodels.go | 85 ----------------------------------- 5 files changed, 171 insertions(+), 85 deletions(-) create mode 100644 raylib/compat.go create mode 100644 raylib/compat_compat.go diff --git a/raylib/compat.go b/raylib/compat.go new file mode 100644 index 0000000..3cd0337 --- /dev/null +++ b/raylib/compat.go @@ -0,0 +1,98 @@ +//go:build go1.21 +// +build go1.21 + +package rl + +/* +#include "raylib.h" +#include +*/ +import "C" + +import ( + "runtime" + "slices" +) + +// List of VaoIDs of meshes created by calling UploadMesh() +// Used by UnloadMesh() to determine if mesh is go-managed or C-allocated +var goManagedMeshIDs = make([]uint32, 0) + +// UploadMesh - Upload vertex data into a VAO (if supported) and VBO +func UploadMesh(mesh *Mesh, dynamic bool) { + // check if mesh has already been uploaded to prevent duplication + if mesh.VaoID != 0 { + TraceLog(LogWarning, "VAO: [ID %d] Trying to re-load an already loaded mesh", mesh.VaoID) + return + } + + pinner := runtime.Pinner{} + // Mesh pointer fields must be pinned to allow a Mesh pointer to be passed to C.UploadMesh() below + // nil checks are required because Pin() will panic if passed nil + if mesh.Vertices != nil { + pinner.Pin(mesh.Vertices) + } + if mesh.Texcoords != nil { + pinner.Pin(mesh.Texcoords) + } + if mesh.Texcoords2 != nil { + pinner.Pin(mesh.Texcoords2) + } + if mesh.Normals != nil { + pinner.Pin(mesh.Normals) + } + if mesh.Tangents != nil { + pinner.Pin(mesh.Tangents) + } + if mesh.Colors != nil { + pinner.Pin(mesh.Colors) + } + if mesh.Indices != nil { + pinner.Pin(mesh.Indices) + } + if mesh.AnimVertices != nil { + pinner.Pin(mesh.AnimVertices) + } + if mesh.AnimNormals != nil { + pinner.Pin(mesh.AnimNormals) + } + if mesh.BoneIds != nil { + pinner.Pin(mesh.BoneIds) + } + if mesh.BoneWeights != nil { + pinner.Pin(mesh.BoneWeights) + } + // VboID of a new mesh should always be nil before uploading, but including this in case a mesh happens to have it set. + if mesh.VboID != nil { + pinner.Pin(mesh.VboID) + } + + cMesh := mesh.cptr() + C.UploadMesh(cMesh, C.bool(dynamic)) + + // Add new mesh VaoID to list + goManagedMeshIDs = append(goManagedMeshIDs, mesh.VaoID) + + pinner.Unpin() +} + +// UnloadMesh - Unload mesh from memory (RAM and/or VRAM) +func UnloadMesh(mesh *Mesh) { + // Check list of go-managed mesh IDs + if slices.Contains(goManagedMeshIDs, mesh.VaoID) { + // C.UnloadMesh() only needs to read the VaoID & VboID + // passing a temporary struct with all other fields nil makes it safe for the C code to call free() + tempMesh := Mesh{ + VaoID: mesh.VaoID, + VboID: mesh.VboID, + } + cmesh := tempMesh.cptr() + C.UnloadMesh(*cmesh) + + // remove mesh VaoID from list + goManagedMeshIDs = slices.DeleteFunc(goManagedMeshIDs, func(id uint32) bool { return id == mesh.VaoID }) + } else { + cmesh := mesh.cptr() + C.UnloadMesh(*cmesh) + } +} diff --git a/raylib/compat_compat.go b/raylib/compat_compat.go new file mode 100644 index 0000000..1c362fb --- /dev/null +++ b/raylib/compat_compat.go @@ -0,0 +1,69 @@ +//go:build !go1.21 +// +build !go1.21 + +package rl + +/* +#include "raylib.h" +#include +*/ +import "C" + +import ( + "runtime" + + "golang.org/x/exp/slices" +) + +// List of VaoIDs of meshes created by calling UploadMesh() +// Used by UnloadMesh() to determine if mesh is go-managed or C-allocated +var goManagedMeshIDs = make([]uint32, 0) + +// UploadMesh - Upload vertex data into a VAO (if supported) and VBO +func UploadMesh(mesh *Mesh, dynamic bool) { + // check if mesh has already been uploaded to prevent duplication + if mesh.VaoID != 0 { + TraceLog(LogWarning, "VAO: [ID %d] Trying to re-load an already loaded mesh", mesh.VaoID) + return + } + + defer runtime.KeepAlive(mesh.Vertices) + defer runtime.KeepAlive(mesh.Texcoords) + defer runtime.KeepAlive(mesh.Texcoords2) + defer runtime.KeepAlive(mesh.Normals) + defer runtime.KeepAlive(mesh.Tangents) + defer runtime.KeepAlive(mesh.Colors) + defer runtime.KeepAlive(mesh.Indices) + defer runtime.KeepAlive(mesh.AnimVertices) + defer runtime.KeepAlive(mesh.AnimNormals) + defer runtime.KeepAlive(mesh.BoneIds) + defer runtime.KeepAlive(mesh.BoneWeights) + defer runtime.KeepAlive(mesh.VboID) + + cMesh := mesh.cptr() + C.UploadMesh(cMesh, C.bool(dynamic)) + + // Add new mesh VaoID to list + goManagedMeshIDs = append(goManagedMeshIDs, mesh.VaoID) +} + +// UnloadMesh - Unload mesh from memory (RAM and/or VRAM) +func UnloadMesh(mesh *Mesh) { + // Check list of go-managed mesh IDs + if slices.Contains(goManagedMeshIDs, mesh.VaoID) { + // C.UnloadMesh() only needs to read the VaoID & VboID + // passing a temporary struct with all other fields nil makes it safe for the C code to call free() + tempMesh := Mesh{ + VaoID: mesh.VaoID, + VboID: mesh.VboID, + } + cmesh := tempMesh.cptr() + C.UnloadMesh(*cmesh) + + // remove mesh VaoID from list + goManagedMeshIDs = slices.DeleteFunc(goManagedMeshIDs, func(id uint32) bool { return id == mesh.VaoID }) + } else { + cmesh := mesh.cptr() + C.UnloadMesh(*cmesh) + } +} diff --git a/raylib/go.mod b/raylib/go.mod index 9d3e538..4dc010b 100644 --- a/raylib/go.mod +++ b/raylib/go.mod @@ -6,3 +6,5 @@ require ( github.com/ebitengine/purego v0.7.1 golang.org/x/sys v0.20.0 ) + +require golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 diff --git a/raylib/go.sum b/raylib/go.sum index 7ea3273..2241fa5 100644 --- a/raylib/go.sum +++ b/raylib/go.sum @@ -1,4 +1,6 @@ github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/raylib/rmodels.go b/raylib/rmodels.go index dc876de..5ae017e 100644 --- a/raylib/rmodels.go +++ b/raylib/rmodels.go @@ -8,8 +8,6 @@ import "C" import ( "image/color" - "runtime" - "slices" "unsafe" ) @@ -375,68 +373,6 @@ func DrawBillboardPro(camera Camera, texture Texture2D, sourceRec Rectangle, pos C.DrawBillboardPro(*ccamera, *ctexture, *csourceRec, *cposition, *cup, *csize, *corigin, crotation, *ctint) } -// List of VaoIDs of meshes created by calling UploadMesh() -// Used by UnloadMesh() to determine if mesh is go-managed or C-allocated -var goManagedMeshIDs = make([]uint32, 0) - -// UploadMesh - Upload vertex data into a VAO (if supported) and VBO -func UploadMesh(mesh *Mesh, dynamic bool) { - // check if mesh has already been uploaded to prevent duplication - if mesh.VaoID != 0 { - TraceLog(LogWarning, "VAO: [ID %d] Trying to re-load an already loaded mesh", mesh.VaoID) - return - } - - pinner := runtime.Pinner{} - // Mesh pointer fields must be pinned to allow a Mesh pointer to be passed to C.UploadMesh() below - // nil checks are required because Pin() will panic if passed nil - if mesh.Vertices != nil { - pinner.Pin(mesh.Vertices) - } - if mesh.Texcoords != nil { - pinner.Pin(mesh.Texcoords) - } - if mesh.Texcoords2 != nil { - pinner.Pin(mesh.Texcoords2) - } - if mesh.Normals != nil { - pinner.Pin(mesh.Normals) - } - if mesh.Tangents != nil { - pinner.Pin(mesh.Tangents) - } - if mesh.Colors != nil { - pinner.Pin(mesh.Colors) - } - if mesh.Indices != nil { - pinner.Pin(mesh.Indices) - } - if mesh.AnimVertices != nil { - pinner.Pin(mesh.AnimVertices) - } - if mesh.AnimNormals != nil { - pinner.Pin(mesh.AnimNormals) - } - if mesh.BoneIds != nil { - pinner.Pin(mesh.BoneIds) - } - if mesh.BoneWeights != nil { - pinner.Pin(mesh.BoneWeights) - } - // VboID of a new mesh should always be nil before uploading, but including this in case a mesh happens to have it set. - if mesh.VboID != nil { - pinner.Pin(mesh.VboID) - } - - cMesh := mesh.cptr() - C.UploadMesh(cMesh, C.bool(dynamic)) - - // Add new mesh VaoID to list - goManagedMeshIDs = append(goManagedMeshIDs, mesh.VaoID) - - pinner.Unpin() -} - // UpdateMeshBuffer - Update mesh vertex data in GPU for a specific buffer index func UpdateMeshBuffer(mesh Mesh, index int, data []byte, offset int) { cindex := (C.int)(index) @@ -445,27 +381,6 @@ func UpdateMeshBuffer(mesh Mesh, index int, data []byte, offset int) { C.UpdateMeshBuffer(*mesh.cptr(), cindex, unsafe.Pointer(&data[0]), cdataSize, coffset) } -// UnloadMesh - Unload mesh from memory (RAM and/or VRAM) -func UnloadMesh(mesh *Mesh) { - // Check list of go-managed mesh IDs - if slices.Contains(goManagedMeshIDs, mesh.VaoID) { - // C.UnloadMesh() only needs to read the VaoID & VboID - // passing a temporary struct with all other fields nil makes it safe for the C code to call free() - tempMesh := Mesh{ - VaoID: mesh.VaoID, - VboID: mesh.VboID, - } - cmesh := tempMesh.cptr() - C.UnloadMesh(*cmesh) - - // remove mesh VaoID from list - goManagedMeshIDs = slices.DeleteFunc(goManagedMeshIDs, func(id uint32) bool { return id == mesh.VaoID }) - } else { - cmesh := mesh.cptr() - C.UnloadMesh(*cmesh) - } -} - // DrawMesh - Draw a single mesh func DrawMesh(mesh Mesh, material Material, transform Matrix) { C.DrawMesh(*mesh.cptr(), *material.cptr(), *transform.cptr()) From f529bc28970511c9ae5eb92fee8f743b7003d6b4 Mon Sep 17 00:00:00 2001 From: Palessan Date: Fri, 28 Jun 2024 12:50:30 +0300 Subject: [PATCH 090/278] Adding gif and sprite animation examples. -Added new UpdateTextureUnsafe method to support it. --- examples/textures/textures_gif_player/main.go | 111 ++++++++++++++++++ .../textures_gif_player/scarfy_run.gif | Bin 0 -> 21261 bytes .../textures/textures_sprite_anim/main.go | 94 +++++++++++++++ .../textures/textures_sprite_anim/scarfy.png | Bin 0 -> 10394 bytes raylib/raylib.go | 4 +- raylib/rtextures.go | 8 ++ 6 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 examples/textures/textures_gif_player/main.go create mode 100644 examples/textures/textures_gif_player/scarfy_run.gif create mode 100644 examples/textures/textures_sprite_anim/main.go create mode 100644 examples/textures/textures_sprite_anim/scarfy.png diff --git a/examples/textures/textures_gif_player/main.go b/examples/textures/textures_gif_player/main.go new file mode 100644 index 0000000..784513a --- /dev/null +++ b/examples/textures/textures_gif_player/main.go @@ -0,0 +1,111 @@ +package main + +import ( + "fmt" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + + const MAX_FRAME_DELAY int32 = 20 + const MIN_FRAME_DELAY int32 = 1 + + // Initialization + const screenWidth int32 = 800 + const screenHeight int32 = 450 + + rl.InitWindow(screenWidth, screenHeight, "raylib [textures] example - gif playing") + + var animFrames int32 = 0 + + // Load all GIF animation frames into a single Image + // NOTE: GIF data is always loaded as RGBA (32bit) by default + // NOTE: Frames are just appended one after another in image.data memory + var imScarfyAnim *rl.Image = rl.LoadImageAnim("scarfy_run.gif", &animFrames) + + // Load texture from image + // NOTE: We will update this texture when required with next frame data + // WARNING: It's not recommended to use this technique for sprites animation, + // use spritesheets instead, like illustrated in textures_sprite_anim example + var texScarfyAnim rl.Texture2D = rl.LoadTextureFromImage(imScarfyAnim) + + var nextFrameDataOffset uint32 = 0 // Current byte offset to next frame in image.data + + var currentAnimFrame int32 = 0 // Current animation frame to load and draw + var frameDelay int32 = 8 // Frame delay to switch between animation frames + var frameCounter int32 = 0 // General frames counter + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + frameCounter++ + if frameCounter >= frameDelay { + // Move to next frame + // NOTE: If final frame is reached we return to first frame + currentAnimFrame++ + if currentAnimFrame >= animFrames { + currentAnimFrame = 0 + } + + // Get memory offset position for next frame data in image.data + nextFrameDataOffset = uint32(imScarfyAnim.Width * imScarfyAnim.Height * int32(4) * currentAnimFrame) + + // Update GPU texture data with next frame image data + // WARNING: Data size (frame size) and pixel format must match already created texture + // here we needed to make the Data as public + rl.UpdateTextureUnsafe(texScarfyAnim, unsafe.Pointer(uintptr(imScarfyAnim.Data)+uintptr(nextFrameDataOffset))) + + frameCounter = 0 + } + + // Control frames delay + if rl.IsKeyPressed(rl.KeyRight) { + frameDelay++ + } else if rl.IsKeyPressed(rl.KeyLeft) { + frameDelay-- + } + + if frameDelay > MAX_FRAME_DELAY { + frameDelay = MAX_FRAME_DELAY + } else if frameDelay < MIN_FRAME_DELAY { + frameDelay = MIN_FRAME_DELAY + } + + // Draw + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.DrawText(fmt.Sprintf("TOTAL GIF FRAMES: %02d", animFrames), 50, 30, 20, rl.LightGray) + rl.DrawText(fmt.Sprintf("CURRENT FRAME: %02d", currentAnimFrame), 50, 60, 20, rl.Gray) + rl.DrawText(fmt.Sprintf("CURRENT FRAME IMAGE.DATA OFFSET: %02d", nextFrameDataOffset), 50, 90, 20, rl.Gray) + + rl.DrawText("FRAMES DELAY: ", 100, 305, 10, rl.DarkGray) + rl.DrawText(fmt.Sprintf("%02d frames", frameDelay), 620, 305, 10, rl.DarkGray) + rl.DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 350, 10, rl.DarkGray) + + for i := int32(0); i < MAX_FRAME_DELAY; i++ { + if i < frameDelay { + rl.DrawRectangle(190+21*i, 300, 20, 20, rl.Red) + } + rl.DrawRectangleLines(190+21*i, 300, 20, 20, rl.Maroon) + } + + rl.DrawTexture(texScarfyAnim, int32(rl.GetScreenWidth()/2)-texScarfyAnim.Width/2, 140, rl.White) + + rl.DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth-200, screenHeight-20, 10, rl.Gray) + + rl.EndDrawing() + } + + // De-Initialization + defer rl.UnloadTexture(texScarfyAnim) // Unload texture + defer rl.UnloadImage(imScarfyAnim) // Unload image (contains all frames) + + defer rl.CloseWindow() // Close window and OpenGL context + +} diff --git a/examples/textures/textures_gif_player/scarfy_run.gif b/examples/textures/textures_gif_player/scarfy_run.gif new file mode 100644 index 0000000000000000000000000000000000000000..f0f712ccdc1fa1b8addc74f1fef5cf61b93c0ab7 GIT binary patch literal 21261 zcmbrmbyQRjyT3g_4C&C_4bt5p-6h@K-6ah}cPk(u-6$yy0@5KVsRB|GO3L_-exE$& zIlr~edH1^3UN1h#1q`A^MxsGMrv42QB`Ojr8WI5-7zzPlqJWTq z03hHuAOHXb06_f%VnBcd0DuwC0FeMdWB>^DH;Cc)k0<~z76AMR0LDgvJi^3+Vn4$9 z11>fc7Yi2`g8&bm5FeF<0F9IogM<*5gczTM1ecf$osb5MM-RYb0^l(N@L2%_e;{N7 z`~gV7ib}$UOU+Kgz)r@-LCndC!^4Hn&jk|Z28bZw`NLoHzdphX5atI7iJ%BQ!4Ou1 zis|7?m=Z}_lgQYS{((%!o*aR!J;fiWWbNqWY}pm9g;gzO)Xfz&&6E&mnJH+Q$v!og zG_Vjdv*fU|q4BUM3~vjG{#vk(%B%)**MtQJiyh;$KB4^ z+r!{llyE}>M_(WF=qSzXEc)3Q01p2*e*FUc&(QqBP?vkEBO|RT$HTz|M!a{=Bj~md@v>N@zGfUk;_= zh!Mh9YOPSqVAQIy>EyAS%om74uOHJ)(&A>$WHgP>*q_K{Ge6}+^Q_XXl}lySeb1M? zP^o1}`8BZo@Ixyt2`hh>p6YZK(*m)nLVLqTw{Jx0Ms2g)dYk*!^oYtzgIO<(z;1(8 zKZ%5w*_@~7`5yQCK_3#v&9_a+>-F;NmFcSa+@JaKmL2ydjZWrivy|8vI=PQ0hU%`n z+|Ywtj>})ut>vt837RjQgsfR?`epJFAcBxL=dEKSaOQ6hojmXN z=PLF4ib8|^tm+%92zDbT>Li|6ZEHWlpge2EhWg>O)Uu6zT^vj$qB6euVS^37Ma_lc@Rd~u z`e2oJuuqvJa`CnpPYZ4;avD9p+A>=t2vg*%78%+lJBf@l%ImZ|J&4k`BT-9Q*6Ofg z#`j{W<_o12F3WeucG7yOJ!rVA^Oog(6|o%JoK8cvT*wI*LZ0@Pp+o~ zXJZ2G<0#;x3@?1V46Q2~{q&4g=;yl**xGhU!yA+?3Q8L10o`>?e7MGswThm6Fs^(e z5X|NivFX&%ihm{OloaaJ&0e>G&RtZRjN-x3Ik^_h(e<_Z{=M&U+a1TtALI95UD>}c z?{t1SO+;gC_ghGQP4SMnsT)l9xn$sqg>_?aPax!U2uDMeyO*fDpxNsD^s^`5?kU@4 z{UiH~@yWes&&@K~yvdd{&@_m6r|GP%c;~hb9#hPS4^7}{U_Mk{))SdnL?G*$hx&ft zx1WErWTaou>$7V4@w;M?#6!g**HIz=l3rY>^s;#r*7XW7tNsGMiY#1yHNjm=*CFD* zUKh_OAXz8G7-=r<7BtH})!uv_$@aRp9a}x%V=Ue2kKLr&PaUlyDiVSAHZ+r8X1By# z;u+9~8vqA+Z;Jv>n%K^64$+EEeQ=~MIa-f8N7cJeiu)+Uzc=iyABmx{Q6ySl(Y5nSm*O~;n_rE*!7RFtu%B1 zW(fdQu^+g*9WFE`jSU@>BL6-UhRITb!~~H-VQq?lgltzBQTIO%IE$kEIYcFPfGP<9 zK^Y#ugy`R(60~^499xV6`5}$ik!Mk~^e@r0@&<|8W*@;N@GUXz6^Ek8XQKd%k%VGZ zvJ87%7_>ewG0Gsr1Vv}jPm*3@QW(fak#l1xnOG4PRK+l9pC_?B-=%7Rz#e0#Cz|5J zK-n-^0xm5Ktubr-Cqhq{QRZTdFv|(06^Dfmty8R!wkdveC`ew+#f9VBP@|!Z(o&wq zC%k>hczZA`$*h%Z^OlYQizQ9viaWFL?MsO0?Ko>gOMK~13z|;>{kTiq*&V|>R2R%6 z6fI}y`p})n-3BU>A9->+@M$<}4W2x1faVR>(PNRoln7?IF{sBX1lj}Dpgb1^^{Owq zTT7&5v@f%k@IMJGqeZ$sJ1expv_}^=P&eA`&kuy#FoCYdXP(*VgcA*yNO3z%2e*0V zYR%e965Y)JP<%?D*%c^{#-?33vWk1pMkG=_lakDQ3Oym!iaUU~G$VZA>SG5vX^*+k zAbcQsXtm@UmihD?K5Qm6M{$%-}FYVWm?i2DH|uV^%a z-_I1I_?F4?vubA-Jgqprtkya)7ZC1`D6-=#lVxBv5)E2Tw4`g8X&xmR(A&HNQS1V+;{%nZ?HTADbDn|Yuc+HUN;4EhhShabqqau;Bx)6 zZ9U2M@MZg<@7W-i@*0*4J#>=O;!PZU9RdsoUXS<$c%JZGy`qXMXjkKzpASy1Q>JX*l`*0J@#Jck*RPJLaRn zYz6hGj9+J;KULhkUwGJgJNWz)U!(AVJLT&0>$chA=^uD1d86^m*B^? z!pTN&FR&){hIhA$KUVB3N*vycTHM&myXM$S@f1bZn>iMj1e!E0>_Jbg~N5H=E^elt& znrFY~yZ^V~iZY3d8m6Wk26&pn-ClYr`;1H1FV&>WtA(r1%G=nl&gb%Y^j}d?CG4Xc zcTfC_@3jEGoJUi?UVwl8Bx(0iYJY}1`wRsbhQbsEOLt-2Gh5%6-Xuc)lH(i2@bvzv z3ATq1IM0Gt4#&pU8y!Z7xf0HI7H$ZQz&r4B^3{8Yjv%diMhe$-; zKm|czVc*|GJS^#q#)N-u59KA$qZ|YF`3GSLxr;bht}aGhqeinbMZc4ap0khUfkoqK zg$femuYZ3^^ug|w!09`(s$>U9vME+F&BsUHDwXxdV84JHgdOrc$Y#P zTR)N6STwC=JYj5nWL3P=SnP|Nc;o@tSA_&+hfo@6XL?01)omm45%t1@grW}6j9@4q zQ$jqqw@N@ldTwIGSmNk*Vtq$!BXd%_Lekg@tPDoHtQb!~6C&y7u(jf?I%_6<^{jp+ zejy+kS0>MgjYX-dMEi4F>Hr8<%*ZToj^jr1thUir?wktN$$C& zkHqlirmQkUlMYhma>>refB>Wrw*VZr>@@USw~~XjJy=hD>$x+zt3AEK8}A zNG=ejew(G)nZ==$tt^~vpp<6RnQeBP4WkjV$S1QB&Y{)HvCAiR$j@H4IR)t-^D(n=v$Arsv2w7puyZl8@YB+XlaVRl zK2pa()j&r^fN=T$f;KvmE*97r3PLEqB>}*S0N_Ln2&DpKvH)KEKS&N|VKIze^@ zp4LWoX2wSP#yU?;G_+0Cv`kgCOjR^Zl{HNfiY>2U_C(!WQq4kG#gbdeib=tSM$VQ} z){b1}U-{$de^eb|>*R9wWD52qDh|XN4!9;x7;Y{oL2jTZcR=jlO#F|JdjR794RC@7 zB+27ZiaTSDmqbZ`MTJ{Vt8H7i^~|8>)d z!ues$=jTYs&!O<2gHeBo{y7+Z|99>NVr~XvzxT(V_9gH2rEm7;EcQHq|F-mPS4~TM z(~IuztlqxF;i2f!ccJ6sK2uY6a|=2vAC)$?sm?CYZ}0voy#KT6{y!`j@f1Q}PyQjW ztR`cB1eQ+uZvxBf^l_~DkH997E47r5XEN*5n2fi)n#kp{e*b)&>j@G>$op{7QHN=& z_$ug>JVA$9y@VErT664@F&auE;v1>_rbf3)BHiohd%jA|D(%LER|UGY@~=!Vc7J|X zsxfXa;8P-yZs*u&Ht;W~hxt_-L0q9*eIGmaqC8Pque|R zs1&LtRX6tty$7Q{B_Oxk&=SZG5XIu1By<0Hkr*k9BR3l~O8%+X6@Z>c5;3S0TcVE6 zb3h%9bI1>kA#BMtwbE>^GIT3|R_YM)Eg8^6VWQI|MPln!m876IFxlWsV0&A7agbKf zB;_daTPO2v!syb5z6VUEijoS`r|UbdQmS+4F;GPE@l=&WYR1Aotdkw7kZijG?Fw8A0xL?q3DNh{efNkW6Tz`iB6Z9w;YtEMsd($CK1CMV=i2kI zgWNCNU6xM^r0!zNJ+z%zQuNG3>?`4hAq5*R5}btct1%mv?PI#07?wp6Ob0raH`f^K zOTEsqcV_J9onwo7E5CEpID~|;-&9E$TqiBEL-3?kMjPEV!B|=Jq*KQ2UccTdf~~y6 zUDo)t^8mfNL0aGqtkQYwB44gS>t<&(D7PUFl``mno4)7EX0T>&;wc%qdT0X^*MJad zQq$lQp0}@tZsa`(Ak?3AJ@L_~OxymmyU5-iayFoIBuzK3gz@^duG&3@$C9DGINy?vyPEy- z@!Ff#O07Kh{*OM(;_ZC%uOEBBH~2)DYln_WbMh8ECS0#~0*+2lw+wGgTc<=A1UmX+ z3MsH?^6<3%cXN!B6&k~~$ZmTxWjf9F^PSZN_g{dq{Fjy4$j+x_{5E+6R*+r>L)-LU za2=#FZCv%LFT07Jc3*A=^Ys;ybqxvZsOIz$VjPcN%xTJ~?V~ww{k)`B;B3(yL3I(o zTJvsrfE&g{CT2X8 zhEB5m9lr_{6}>J3wXOsi8D$`Pdl*2C`4VyudV-s97ELP_fv#UQi0y>|VkW0CQWhE_ zE=`Mhyr_)9TZ)g<5{?Y#@ECYxx|2YKfK&}qv0!s z8cNBs(`v=5V}8Q3q#0o;DoL<^3&Co>k>O-aPi%l#5gC@C>%ws2RUcd9*F*3m)NPU> z086rngGkOntrWTPGKwMCD8u1glEZ75Hp;CG^c^({%a{#1hte?hl2*J0<|kG?969Bd z{!|X>FEWfuN-9>`na`8TFeK1MHAOtLUX_=#YFUk#GRme!lhbplkqm3Go@czK-(}8s zcrSf7Pv4_TCmT*8Ye`y?AI--|o?ea4z~LRg@^gn*1$W95SC(b%tqlWK$+VrFSDNgk z4TW|5u*i~D(G{GJN%)mxDtQAg@N3e5$hzZu|2FO-mOOh*n1M#{ZfnY2v>mCgqAZlv zKIMZ89mKQa2`J!u88XBXD3+kcG|y9dj}MVEwVaD#MlLfpVN%e&(Mn6mDxczW6x0~k z$ZtA}D^pFBmJ)hz;B+2GNnoj#-oIEOl3h*tqWY-@Ko?Y^6(eODqlxikQJ0uM@3Ep2 zB=>HyMc%iDyxxg5cx?u6(ld)W#F2L2;eElMj2>MjA6 z1LUg_R?B?dI|870IUB>t-CRGdWn<_Ao5khY;s9X|AWqE%csHg&Ks%qK^0R`FS9z($ ziV)2T3Li4F7Byad25fGYdu-Nsjx~t5*in68cSN%?B9hh1stspxmaJJ_p1;DF3FUAb zDOsmITWar@i}cV3Q3I;+<4D9$J$Zx13;eDD&9+W1#m4J=9oIc?rr53Kn$|a2ciRV$ z0V>n?ri8Kn4clU$2`BF7E-Q%Ijy9Zww~jV%wEcU3jJQ41^)kaS=A8uWW{dN~14x=k~m-VCBrpQ53R@8rcUl+mE{!&E|c z*Gr{G*d)A2$uX^u)~?(6mcA*uxmd#6vP*WvIK!Wl8si#wpo&ZJ*vcHv_4XR{s`fO% zlkyW*NOPm#3%zSXZ%$HUrwX62I%`4he{9#Ckq@ww;I&%#`T4lb@V&rkLrm>Q)Au4> z{eBYRQP=2plxN#Bz%d`dllM>G_Ua9wH#8KSCn8;U<CEo^u83Ch zRgI`*LGFgHDw*6`yO4Cw{gfk*DEU)M+gde%wk?F@r@hG*LF04XM&j~hD?X^v;2N@D zDUk12&i%G})Xk}dsOR`vAh>m=t?qTT>u2Xi;dOjMzeg}rV;cq1#bLPDql$aup(pDt zwwuRYocA$Xr6g#HiZ`^+?vDbzgEtc!+B?40Z-;yf+;V`q_DSEnPosQnLEWq!fKyFA zjo~B*VC^@&WhXaXKmD*vh{B&|zX?tUQ!h~MKdy?Jyo6qo0nqkcX>oCEa-X-avyTc+ z+Nxg`5dGW(js=>#ZeCLV57ds{-79E~w_}coZtI^p!cpZ3lB|B`o&ic)7qc6okMYIUDIfcE<+4Tw( zaEIaO@9B!uy=)%*`U7Rm_|R9^>vxir7vfE?KYOa)_8Lnp=Ph^cnNHqv1{48G+MQJ8 z-GQ2o8-qD*9k55+TIthkH^9`Bz88m^v$O)`%B$huD>)x#zrg_;SD_gZ@EPz9M*asBeVd+7sWQI@>>s!?Enk_HHbL~ zwZ!GSz43-$81!YB#z+|3Uf2n0_ySWnQU~CC*|bmBhI8Nbh6zWPC=#%(g>Mi^HcLco z=R*nskl!E==S1SrMCvL;GD5c)&WfGUP#%m}D}G)fp*%glpd%jR zEGo4M20D*z62i%bB&^aTRvIMg2E=zcz=-A&I}DfrR^UkoaDzciL`MQaUQ&Gk;8%O1 zQFGGNO;V^@parY+Sa{$hsA|xyTFjRCHx{zfLCz#F47&5MGsO%BmS|{v29;+7a2&QjW|RTl$xsx6aw(^H z^FL){0CG^zvSmA=K;Yjr^zeVDp=S6%a{_=74(KT+SnE$1tBQssiwYJ%0}LI$IQ5c%ovxb;6Bh=&nzE5ct9AQD%!zo)EF0Qe6`P{40+0LXX%R004R zF#wwifXn#zD3uL>P}RTjJ6T00V8SG%!6Bl=CnhH%CM6;!AtELwA|fInAjHGN$HBvg z;^IBR#l^zILj<-EB0MBgd>{n@fbw6UCI&E30=St0!dw8+|E9bmyZ{k?kgzaVPz;S< zoR~+5lZ#85lhu-gB9H?&l^s&Rj#SJJEMW(hvj29|W=?{3&cBqD5)noIgHA50E*_d5 zeuhEO$M2+g$DZ(y$q0wN^;?VdF_gN>w$FX0Xg)*UUnz% zapS0V70Y!|N_A0BbkX{gK>l{qxZm-kZlsf5sH0(kgRz&Lse_e;g}J4Hk)^i2g@&$$ z+Ea5C9dl)Eb45h_t7#^yVJ@j|A*5>gSkZ=7&W`d=T>RTa{{=Ex``^gflPEjj891W5 zxgZC*f+F31%V_+6!~>Av0ZR0Qr1;=w2GJBoa+W5DR;5YRWXRNJDb(dC*5xSI<*L`` z>D1>NH5A%3zVK}>jcKXKeO*!B{;IXJbgZ{vaWG|fB>Kx($kDjpw+YXSN!K4!&ezip zx6}4_GqyixtRH57^K;hv`<(5!d55C~r-Mb8Paix!F8M4h2aT>pv~MKFf2qzLGt$UMsoZj+Dj;;1+&qbn0>qr(dD+$?? zX!*OWkmoDJ!cw3$nFo+pN~w0PcRq4YOP=a3@hR)E>6JUodAZIlI!rY&jpp#z^1H6R zaTV{0A#15%(eeJufu(xYs5NB6qE#?{U1r|zjrxf37>(PiEP+IDQz-LdYa&`&hodlm zZ!htMOc`K zDJJt!_K*6T9*0^vgnGPa5EQBq6Yu0G=)2F9&t$UGww*DYK9qz*l@)2I2vNdc29i#{ zSqe&{$yqj69O0vihQ1>zjmCSwPZ>>Q1uJ1G`fR;FX?psA5^h#RjA#T0?&IW0tPS$Wo4sQ@n02!{b}q44Ynkrc_2s15map z{|Eda1N63vP|sL2hVXCf@t^numRPWDqN7eE) zEBy$DtOSEN|J$!$UczIBS)J@MtE_TpV%_!>1NfK#z?n;;JGKtAca>=$;N@K6!-Gq`D z=N)o;`myz$BQ9$Y6ILHMxhqJ(^T`DS9*g4ZG*0A5S{^2f8Iy z%$2ssR?pARLlV#MI}5{}-5s^2rroU$gugFEPp|Dr$&|Aw~>=u;Q~ z%hNugBJhp@QgmE!^kaG;G+t4TXFfgc(#D>R9yhTgHRx2ar^GFoPx@^4dJM{BM!G;H&avY3# zjsfSkCsJaL@p+f|;>2V~G@E2beY&-1*9B9;d`u35)Y~sD>bZz9+N>ODdj7fzSm=Z# zCx)=xyN7NIK$j2^4_eG5nmXVRESUB5OQUxAY=V2uB1dC}>m_kEptO&sk<@^fH-~Sh z^6gfe@Ljl+L24rTW6Nfzl}-`9W~6e&XS%W87^756)(HbA=aG64c3abz9r&Sr z1o0Sm&4;@57cL-x3LxO(M-AlU*#1aiePoR=wL`q#E%0bP(9W-Q;KV^|D*$Oc=G)8V zw>HY+EQX7W;jnQrYo1KBY589MTH%5Hy}EnZW7fuM2KHTz>?6}NLaDc(*c%z9YiAd6 zh656kBfo582uJPtmE_d#hOqT-qlk9&Ro#C>K{@CFZsCJb^f)3HEY@p8ZiWc@3qKD! z2}eMMN`+szhX$)?(sIma3c;F_?0;HdCg;UAur-UQtLhOPE%nNWoQv73+K?{_i4G-J zf5sfN#uO81-=yG_jyWDDGq^?JZR1In`S_fk%6A;u@gnnUtuaft5RgEvAD-R(*qVJJ zZ(zXD0s}8&+$Mv+Q;YH&ZMB#Ns(t>HTMGAcQ}hKmP5Cr(N2}xI^GWft{1=Jey$gX; zcGBMYtRjRk1+_^7(6h9wQqK_8i5i0{}tv)7f3Z}6)mq{hqZ_<>eEOd$s2C4-v zUfJ5ooMdQ~rNP~B78K3=c166%h+jWRakaIzu3E-@@GVGIJO%;2ue8}gTHUvg7ru9O zV}>{4ObEGx%DJ10!~{Nfg{HZ-c5`o?HgvqAIPNd)o*|(A+KsV$YC41*vyI}Psb=I( zc==|D%%HuGDDo^66?q$&d))ua@XSh-bO$|7afk@+0g)BkwYma!!lT%oBdf^3*zW$w z^p%HAd1s%1k8a0q4;?c1MN3%(A%n*1*||evABp^G#v)FXqAke3klWu(1#;jQ54|0? zd2uV2+`%H)pg`780SVUK=pV{BPu&{9gSymcov z64UCnANVF1XR?i~aZ{tB?xQ#3ySkG+32Mr|wEHf0pd@lPUbuN!nOe1k*LM>@%Kf%@ zdeBes%`1l956OL(pTlls8CAKN-oS4|W{aQS#h9C3h4w39 z>(Aw;R^DARnBN(TV)vHIef}m~EdNcP@@rIk59-c0gIl7x$vpwoD}NWvoUm8zVY#wK zYop3nx<0I^R_OjV*u!Dv{JOQa9y-_IRD=;&Z8A*qMs{!19r?Tx%b!&;Dj}Umq!2{n z6KG;rdGEwUvIIOy{b4|27kSDQ1&(;aZ(t-?6(L*|<+B`RryE@n6GgBMNofjl8@7;j zh*p3^D|JMBGeu*g#1t<_Ais>xVv3$vvM^wd01d=&AH*m##j*+pg;$2yF~_Xw0iE(d zE-SGl0~TeK(ar`jJ~vQ5;(!3=xS)=>5QEsr031_he9-^ZmjGZ)L~-;th#u*m<|z;W zLID5~5grZ*NQnfdMMg$Ihm6Dm0x^NXh=Cr_UqwYBM@J{Y!Xku132|`=@$m@>2@x{$ z$7)CshVzJs8bV0__vG#$B7_)N0eCC`TzUW@1%QkYfG`{cRKx%d27n;vp9t@d*dY3) z!o0xWRZ>AD0TEPwaSUDwD7QEX;A>3=~B9_Ft1bZ44xRY_KT~$N~>&Ljdw1K@OvYq|swMXU2ZT3T=k0{7h@ZfVI7v@>V3l3CL@?9`@~XKhf&t%ujcB%on`DP{)OKK*MIPr zqR85l{((f+{y!jRPb}|1tmr_5&=?)Whl&%rs|#{4B42X@#QhH%^E+ts{8vEno=9TH3ZQUKs{ay7VJyq}f%BKfP<_DiI z4d<v%Woay#pGGv|3d=XWt5GP(w<-%NkCo%3R+Q2lHQU8I>}b4O{puL3WUQ z{@=Y*E=_9jAWc@&nnh-v3K1IY7b0&C=E^nlMWzZeUp=j{kmE5)$f`ALHBQc;MdqtB zP6m!yiL10bQfE1>3WQALI)vA&B)^N-X+JA?>r8TG8ZvvRGZ2lnAXk^$Z0l=%qP+Q> z|9o>Ig!fa=L?@r}OoDXWlnZ{--e3b(uwIYI>CRHB(sHtCfPiaFX@0|0aKYl<>#mri z(2LL4v)d|hs7A&=g&a3WNO=4?@b5?ux02y;qwxZrE%8%$tjJwym;^6+w0=(7qDa zc^Tv3>OdR!IPk_Y0P~d~ZTvIo@`WU(`W(WMr#)ld*Y-*R+1I$}YX-rp#7Z ziK6US|0N~Z4bV_=bkK!jNYL1_k|J7NaX{I@+4lgqb$G+}fz-ZJEMCQN;E;CGO(x&y zzUeue&++-_IO(emJObnA9^Jp*uYVbR+z9oerptA?7;nq2tyZECExnu;(RrdYD#63| zju>@Uu=RERYF)+<-RH^6X$kPjt65nY%kOiFg0hG&tb9&>ETIt3zL}Abe0Yt{8j>Wi zMq!OrEn^(~zz?)cRcl)nYdtxKuQ@hux0#!|KMZ1U4|Cn@aQY+(&1f}-3+zgS(cXS` z{l)IOjf80?v>V0tOz4xOXaneTma2N^Ru0?Z4@_Rn>ASu7#{OFj@ywIkZJT|wJErW) zl-a}jzO$~K<{7i#Pvu9w!QXnx7JYYOTBn0XXJx`d4i;rnMHxisQv5Fah%|e?^V*m{ z{GihB3%!mDdn6%k>a6~AJJq`=cr<9@QSfRCAH4SxIj#6w-d=J&e%kvm82Ibwbsv}< z0EED(c1q&fkO))4C<-?>?*v4PJHLfuN0%Vg>Pw%fL8I7aso_Ef{g3XjBQan*pl}6A zkXxh2n@jQ|@@)XS!%HbR@-EqKUako7`?Ofjsx2(*G?`U2cNDSjG|)ck;USzkSM01E z5IuDS@srtz)%DFQu_{ofB@hGo{otd@n-~H!9B0EU8loN;fUChGEQ^?qVb)Hb@0m1) zp@lWsBUo1-iB_Wb$5JHa011V$Mr-4BBV^WXFx7LdG~~$bdu*0b4%UqHCGXEjG$i9n zdKVdai{;;Tt48$RpZTFrenRq%ZKGScfEbQNvV?NUQ5I=sS6jbgGe%P>9#73-?f8NN z=$tSU+0KP9(}H4^rjYx!lk`jm=$QiF@t$VHwaLEXs}-Jfe&+>S`)DWFe5QsPy^#8e zzLIt*K*;*pG>!v&osofUe1bFlGN<7%StKKa^4F_c{v0|O)GzY6SV(0qN2sHHeYSxj zS6YwhY0%nSzG}EuzvERt$KVkMsKo~=9PB);6g8FBhzmk`3G&T1Qb0khWJVJvDw0`RkekAG&k1X^?Pgd#o+< z2C`;50Q)K;T0zyy0(X4SGaC?#QDRBxod>{>cY!IXe)?5FED!zZ#uR+ikEP>1L=k)P zMDC}#Dkwb;Of0p`R{~ryVje}=^b83;-lggm8hiE8P9@Oc^J~VyakUhiXC>q^#)m@b zJFghwIo3BupaXwrfSxtSi}4{Wm+)~vJD$uJs$@Kz{gYbq-h3bCEcF`#W4(iUfdEWJ zsrgl4;F47N^<%rWVXgcIe7>LP9(y-dhRvDBMk@hT?}|VMGa0?SHTpgLA589Y@~_I{ zyO+M6zw2mS$A1GX9b4ipGMdRW<9~Gz8sMY^47MflQwY{u%LcU!nby)<4dvL7GTpAN zOkXV>e{|}_7p)wVh-@L^a#mMZUB$5Dg@tmtf}a)+uclnTY43?}L;bS8g)JEU;)NnQ zM)@pD?6=5nLZ`-&b-ES#H$C=|->i9?YBaMb32x4>a|s5Lcvmb@E$|z#AV_07fWnmuXIzp(q)qc z0~fP5UE~BdfEqJ?i_$#4AV}z*%1M2EW=LdP zasL}H6+X!?;((g)DFD|f?1QD6&YP|0CvI`UA2FKVG_{*BBO0UfSL&CZL;fdVk9#za z@Th?GHyJ(}7sl_OU8NJPtfu9PePIu~om}2vf1Y|ft3>Hsj)8RMO4XAQckQOwM$uFp^2L73d;R`7XJ_N}sT^qgUAuO}I|0Zx3+Fw3S(oz)2mB4m_sq}r zESq#wME?B*BoE~ZW;Y+G`hQ@gJ*-(5-h;#)cD1jqXZ>Y=aLn!vPs!gAuxcNS^)@5Op*pc~r145{L@~VE@|=Ab<@BVE8Ro zNHoaE#7IcszZ#N%wIzRV{{0saYk!CpKSXm9`%mEXSL_4@p+Hg4anP`EFtKsap}1(c zxG4B|NW}O+QX&8;8Gw-KZ=K1%*7^|peSfX^{Wbjk48&sv;Ul6cW(*<*JQ7+`N_u(* zRwib478Z`*dWC@P4}WGBRt_dMPFi+OLT)ZBer{wTZs6}tKm`B2d-*$y0tyQuvM6Lh zX*3}vY!Pi-F+)NLGh!(#QfZq%JAe)pvVY@`E;;-qO$bpUk#+cuoCC3fBayNro~{$7 zgDY~dJ23k1)|21~_|5M)=l2lr35oG03khKL4ia(+m2wD^wF^_Q4Og@dRk93JHuX|5 zbWt^MR5Nf;H?Y?4!5ZN3+Stvq>j&f01%LpME@_eYjBYb+KgsL)F6SYopUe+M7e1|B@U1!;Joa z2T1>2m;OzW{&&qr)vu)$7%*WmT=p|%9M5nG&|50#mH2UJDR|1& zDQXN_onCciRm)dux>G(k`f<3_YT_F7#bDu3r#$q|;Dt(igK4d2`<01tv+Ij?g-@Fl zA%cxdJt0hYzW1-2DMa?b#ho#d)K8q znO6*FC17icxJ8-$@Zq^x``!7`dZzjGaSwKY;J`DV|yWAd&*iD_T=}0E}!cBEa+6)KM7oAE*N!ff#9G2=A6xHJ*;VTZ!YswI7YU zz*?d(%`-$A}@dQ+Cr03;^MNSR_rvj(vq zF!+DpST<23cmhrap#$=ZvgIs_%B5mu{ft(0}W#7qM;_PU+pb7|u=Wo^;Ath(@=4^kYj)3ojj^)QvTi``ja!r1CY7BhQhse00y*$b!LsmBK%S)L}U1tXIAIrwYp@ZxGVU$}bY%`r2JWZ~@9&Rcd z$G$I^bG|)0!-M@Sm67~OGW+cA6V+YQwdATJN66vW2Ef<9kIUdJ(waC5+0uW2>p;Vg zqRxz-7Ke1@C3YlkbjcGZ?E&mqnkceGX~+WVAVxx3bTT)Mjy7{Ym?zp5zA!;e+;4%x z+msw7@N^iNBOHjy1&yU#ET)yOl6iT?6)9l?f#T4}(voT+DZaM&k+U+) zsEqden1ZAkAk7X+PqW-1Bj2KyM_g12gR$jHj|Rt1vmDT^`JZOez-BfC-Bluha$~+pGfS zw~Qdvkm=91eBzxGntn|MmWp5aTW^&qJ$VB*e-=R!VB?qf}2M}J>e0Cj@ z1F)1Y0?ni~mH1{)Y)W&6`=budE#I~T_v}mET&}@L;Uhel}TO3{z<&Y;$ z@oGO`AtQ7uXRRLvXlpOPM8Dt{#K%o-Tcrp#)P@z|zhcD#s~9^)=2~UF7{Qcc13E24 z3viUvjLDYE^?pSxdK_u zO0s~KOi)Sdv1iC$)$duFSv6#Gs8XvLgEqofra(}uBUzx|W5iW6d+dzC4l$6h@@b0E zW#u;RG^|+jZ4P*|&0-$#4pSL7<+|1Z3Fh>48u#jzr#Re29$Dn2_~wU%WD0hCwcvNM z6}m_@w(P3lJEIjZzv@wOH&>jR*^Pp$W;=$H9~BCV&$?QQo8AB|nX*hjSb4Xdn4G$b zel=l!vQ)HG=H}aI{B*@l5U}xsiE4;+6R<+~I?1=rA>!-cVS`|yUegoL)$Y;AF0WKy zEC9o3@RNs(rDiw-t0>syqh8HYKdRK3wq&rm&W2Yx-APH{RLNSd)iTQQXAYMhvIuay zK}GQhSClB4DKzmWN$znomilw6n+Aj4t%p3~|5~^*y?*H-)P#;J_C=YOHVu!)n{KCZRzOfr#8(;=ONO7q5WW zTx>^TTbO+vqglsi%A4f&zozr2QEi!uF5lW)Qu<^+v#YVf5Q`89iyomIdtD(o<*3%) zR2uyQMPT; zR%Vso(%6#E%ixW*M0MsFy#pqO)oROf4uV(2+Xso}8|l_eWUCWxPyD#=j>S~g>tz}Q zOdFH6UAwzh7+-oJ^-ejK+O74qpVr7T(I4_!cgJ&M1>|fPX=6$*E&0%u~#baGQOAIg6Fuo{n78axzGItaXz8AqmAxA zoTRdeeh#D*Mi?b9tCsu=o}gE^CCB&VV&Me})OIux(*t8vA!QYlh{a0vAMw_O^G_%{ z=5*tI3TD>!sN-4}>H$A6G#`%HnnaYFu^k15L>ZdZMHX_++`ESI2lHKN*J@9fq6R}i z{qK0%H$r?KjrE**_xVSk!&iGW#Ala(25)b0;QjKW_&na$8Aj4*fhkn<&1Ez|4OJ3% zf^72$v+{oV#LRU1=;2bkuS1%SI%t?O{5vzt_d^2CD@_H8t5p5&53e>gdJoK&3Q{lY z5gFBMjIiBd!HDYql#r#%&83&8_LuGOU$?t5ad+_=4?o=NLr)8f4>$K=Okz7YXZpYH zN~U|C%WVh5S4km%@sGqiZG3j+Z~Q|UHEd1Y_yoW@=5Gn%<@g7a{}%7A5s2zJ{Dowx{W2M`%^=oV^t{%FtxBb1Ril=x+Y z`Ye)Kf5f}}NMK$NcNI2o2S`K+M*tQj(-Flf^h|eF=3q3E)G|t;gOHjz5*HS#D&(uB zh@*KB&2Hd;$84eN5r!P#XQ&v>NbM^Gi)`45VUO{*QVg>hi{TH5WlM|2=)j>oh&Zta zIX9tfDm-n{k2O+^lV^@2N{^d>x5tIv#IX~=Vuj)y@}g2ZV%cM$5XCsYo3M0dSiJPp z99UQ$b9822WT8+3w>7jVz|p5F%qbuNJv||q*|#nru7TM*nmPUr1n-MJtn&sp-65{$ z0Jm=ish&8A(KEifD(D>X&m_htR9&BzUiDV$@Q0l2zKR6MRd}N=z$c(cDOI|yO z`?!+4Rh6)sm+aDy655gS@Hu%u59c8(MXV|1WDMmSbMmqZt^&XP4 z7m&;VNh_jGLr25;zlz`QE+Ia^g5WpCxIo0}*FV$_;dKb)P{D$~)eeZbw+lk*{%RM} zA%Urpkq`w#5@awg7=#7<+d3R#4emc3e{SjW*IwLTy+Xtp2?|7lBB4T2(V*yvO+1=>A)yP?QHO%8f6?&dSfE!b9%Mg`L0&$>Tt@2thB|LFMeojhwiD zVl%`y+kg1eBK)gA*eAp?EWtJUgbz_3{EL572!HnnmAF^689y159b4mGIAUJ8LT)^e zuRW2!d7^*v#GCb?>2l+$aFr-e!QI_mW5}l^&+;jf8&vWl5xF6$v-rxILJD#B2zmH=s+InkRA)%Ik zo5BAq>i!!KN}k}sKkGODlkQFU+HDXrh&v*fJuw9M*Rbt>D8j!o=bws@HzQKyQ5=Ml ztX7OSqGn#Gy#E&@w4^^ev4mFioU8O)yXrjWYRb*$g+aAX;$D=J>njQxsFh9SEv^5@ zmQcm#O`(-g-(Z1Y(Aq;{{Yp0_Uk3<09T6}l4NsM?{w$-<1elOeN*Ow>rUnf-BS?n>t=mEgwqICVZylkC1XWr@{PS7idEYgxctDuj8s%v z{uI1|r}53w9o&r`~_0{7(mv{$C(rYI|XdhpcIErT1pBm|{#(eU` ztK{!E+^Bxaq*QuZ>uC&xIGy_%=$tuD3EGz38E*1##B~JakW^GeL)|*3482+oXA5e? zzRS05#hl?Hf9@TV+~Dk)a4FvHmmE9`i5D;-kF|xQIRD z-`4J5R(ilQFr-zw+jG3d2(4QHd1!a=t`F6ZiU5Xd$3O#8*IwV5A?wjE_zw^1j`}V{ zie9+e{&~#FaX#poSQR~T)FV*ksNoK7s^BPi(pA{h@qTFFLgv)U=@}=1@hTRQ??Ugjn|gCasldU{NAWfM z@`CsPiyb)!BJbRXb2q82Aet@dn$)7i$Vo`-0)j|t@0Y?6VD<2@=uLK{_$e(*og(dY zT{q~N29;MEMEfxL!cy@;1Vg9jEf5rqm4|d2!f2RG(R&{t=3vAnnc^&*v9G+?3`4}l zHpb>2lvh2*N|*d1i>e2e0#_n@WlOUq{_y=)CwAo@S#{*f-X&H2nKvgxeS96+TUa{@ zz=3tht)N4doQa6;E}b+Op!_GoZ3szuK*rLM8Uii9a2xLDKJ1n^&lB%Hl@U&wGyW(p zczxIrRafwyBi&HUY(zcQo^OSv;B$VV)|UI_-Fyn!-%y*8HMp=9$3lAYV4Ll1*7hl_ z6J=1T-J$xSY@9o}Sj&@YpGw;!gQVqkYE&IaDc6cPCU428M_I&~2@=HZSNU%O9JA`i z^UCLxG$Gm!t}eoAZcfmv)vNCyPcyJO<+p9xW^8rVUKWrxDmCNSjSNOYV|MRys^h5k zeZ#{1ZezaelJ?fYYmNlqaJrq{FZr~_v7*JnHJ7&O$(q!L0;GDCP7To|niff0eXZib z{oQiH*^!{zpeC=Z1+-AAC!0;6bblUSdnogT#`6Qhb1E*Ww-Z253#PNn1f?>j!s=44 zS0&JCZpykf^XU zz)osZd!|aLUzkqoL#~=yhom_Lk;9R(<%Z7k%TzS{-bHyjymwYfik$nZfJZMK4e_5SRmOFFFwj6J>&ba#a&Ia|NzjI7rkYKl6Z7ZR*#w z&sTfJqw4z+u%7hzv`Zzdi4H4$ji}IBTWHW}UN=j#^cQq{F5T<0wx}x8;=;vIAGwzU z0-7w_>bc=_LHYe2sK>e2F{UC)p9=fF(DJX-Q5JO)_pOS;3MB@N1cxMgR2y{7cF2GW zSC6{-zSOe^@~xVla_7KZd}(KGoRtRhZ7wgYE>n!}m*tn_B_nGW&F1_Bk+^ZT-7k5; zmEI1SvnNMEY&qBFlbtcmlZ4U*1)`zlFYqLSzpy4kqR=+119+FD3=J(TUCM zupG46C+W?wT>H*F#rnk$RiR?*Q@|~kx~^9jLf?#m7v`J|(T79?UQ=ulK-F$%iS&FR zJt?0PztY_A?|vu#Jw;X!a?}L}80EKdEUAuui_D(g!(WwLmP9>-{e5siOi;woE5aMP3E=&9)&19fB4iytUg=9PW? zH;e`o(A0r8_Q35}^VyIuO$Iou{6ly(v0_E^C4lbzDCRA@%wj(VKAu25&&6f}v=?LT z5L}IiFLy-`{G>!GT{)#M_=ivCtp09jV&mA|EOx06#jDs<^h{>RuN{jy(T}3Q_;jBiN0q1ks9{Ol?+2GP^=fkIavzn&k5KlV`T4BT7@`T}ThBK9 z;Bz`q1o@8g`hEP`8L6G^xQlzA3=-x3Sz$d9D!sOKc(1l*edg%Yi^uWhF;@NFN4b}_ zCKIt17J;Hk>jp{E_DQ@ENkyE#;78tXQV|>_JS15#C?~2Dmaqa%E?RP${uCx|2$p0d z3oIwgfqjfDP(_?B-zUPA1HgiKzn5YuaDOyW5d-P7vvI|6hG7s{m?Lv@w4bX4Ix+eX z6|{ojOva*~VX~I<1p2N=^b8?5HTH%W}s!i20tI*NMUejOyjNdFlRXk>=*= (60 / framesSpeed) { + framesCounter = 0 + currentFrame++ + + if currentFrame > int(spriteFrames)-1 { + currentFrame = 0 + } + + frameRec.X = float32(currentFrame) * float32(scarfy.Width) / spriteFrames // select which image to show + } + + // Control frames speed + if rl.IsKeyPressed(rl.KeyRight) { + framesSpeed++ + } else if rl.IsKeyPressed(rl.KeyLeft) { + framesSpeed-- + } + + if framesSpeed > MAX_FRAME_SPEED { + framesSpeed = MAX_FRAME_SPEED + } else if framesSpeed < MIN_FRAME_SPEED { + framesSpeed = MIN_FRAME_SPEED + } + + // Draw + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.DrawTexture(scarfy, 15, 40, rl.White) + rl.DrawRectangleLines(15, 40, int32(scarfy.Width), int32(scarfy.Height), rl.Lime) + rl.DrawRectangleLines(15+int32(frameRec.X), 40+int32(frameRec.Y), int32(frameRec.Width), int32(frameRec.Height), rl.Red) + + rl.DrawText("FRAME SPEED: ", 165, 210, 10, rl.DarkGray) + rl.DrawText(fmt.Sprintf("%02d FPS", framesSpeed), 575, 210, 10, rl.DarkGray) + rl.DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, rl.DarkGray) + + for i := 0; i < MAX_FRAME_SPEED; i++ { + if i < framesSpeed { + rl.DrawRectangle(250+21*int32(i), screenHeight/2.5+15, 20, 20, rl.Red) + } + rl.DrawRectangleLines(250+21*int32(i), screenHeight/2.5+15, 20, 20, rl.Maroon) + } + + rl.DrawTextureRec(scarfy, frameRec, position, rl.White) // Draw part of the texture + + rl.DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth-200, screenHeight-20, 10, rl.Gray) + + rl.EndDrawing() + } + + // De-Initialization + defer rl.UnloadTexture(scarfy) // Texture unloading + + defer rl.CloseWindow() // Close window and OpenGL context +} diff --git a/examples/textures/textures_sprite_anim/scarfy.png b/examples/textures/textures_sprite_anim/scarfy.png new file mode 100644 index 0000000000000000000000000000000000000000..be3b83d0e7f523e2cf80da19e274a8479e33fe13 GIT binary patch literal 10394 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 E4?57ykpKVy literal 0 HcmV?d00001 diff --git a/raylib/raylib.go b/raylib/raylib.go index 1fa3d5c..8c9e46b 100644 --- a/raylib/raylib.go +++ b/raylib/raylib.go @@ -1090,8 +1090,8 @@ const ( // Image type, bpp always RGBA (32bit) // NOTE: Data stored in CPU memory (RAM) type Image struct { - // Image raw data - data unsafe.Pointer + // Image raw Data + Data unsafe.Pointer // Image base width Width int32 // Image base height diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 23a1f37..9fce2a1 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -246,6 +246,14 @@ func UpdateTexture(texture Texture2D, pixels []color.RGBA) { C.UpdateTexture(*ctexture, cpixels) } +// UpdateTexture - Update GPU texture with new data +// NOTE: pixels data must match texture.format +func UpdateTextureUnsafe(texture Texture2D, pixels unsafe.Pointer) { + ctexture := texture.cptr() + cpixels := pixels + C.UpdateTexture(*ctexture, cpixels) +} + // UpdateTextureRec - Update GPU texture rectangle with new data func UpdateTextureRec(texture Texture2D, rec Rectangle, pixels []color.RGBA) { ctexture := texture.cptr() From 6c3961f894075a7b55cfd9a7dd0d27f21c2d1f68 Mon Sep 17 00:00:00 2001 From: Palessan Date: Fri, 28 Jun 2024 15:11:11 +0300 Subject: [PATCH 091/278] better to use the using existing method by passing the required []color.RGBA instead of the unsafe.Pointer --- examples/textures/textures_gif_player/main.go | 14 ++++++++------ raylib/rtextures.go | 8 -------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/examples/textures/textures_gif_player/main.go b/examples/textures/textures_gif_player/main.go index 784513a..82a9e2f 100644 --- a/examples/textures/textures_gif_player/main.go +++ b/examples/textures/textures_gif_player/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "image/color" "unsafe" rl "github.com/gen2brain/raylib-go/raylib" @@ -30,12 +31,12 @@ func main() { // WARNING: It's not recommended to use this technique for sprites animation, // use spritesheets instead, like illustrated in textures_sprite_anim example var texScarfyAnim rl.Texture2D = rl.LoadTextureFromImage(imScarfyAnim) + var texScarfyAnimSize int32 = imScarfyAnim.Width * imScarfyAnim.Height var nextFrameDataOffset uint32 = 0 // Current byte offset to next frame in image.data - - var currentAnimFrame int32 = 0 // Current animation frame to load and draw - var frameDelay int32 = 8 // Frame delay to switch between animation frames - var frameCounter int32 = 0 // General frames counter + var currentAnimFrame int32 = 0 // Current animation frame to load and draw + var frameDelay int32 = 8 // Frame delay to switch between animation frames + var frameCounter int32 = 0 // General frames counter rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second @@ -43,6 +44,7 @@ func main() { for !rl.WindowShouldClose() { // Detect window close button or ESC key // Update frameCounter++ + if frameCounter >= frameDelay { // Move to next frame // NOTE: If final frame is reached we return to first frame @@ -53,11 +55,11 @@ func main() { // Get memory offset position for next frame data in image.data nextFrameDataOffset = uint32(imScarfyAnim.Width * imScarfyAnim.Height * int32(4) * currentAnimFrame) - // Update GPU texture data with next frame image data // WARNING: Data size (frame size) and pixel format must match already created texture // here we needed to make the Data as public - rl.UpdateTextureUnsafe(texScarfyAnim, unsafe.Pointer(uintptr(imScarfyAnim.Data)+uintptr(nextFrameDataOffset))) + rl.UpdateTexture(texScarfyAnim, + unsafe.Slice((*color.RGBA)(unsafe.Pointer(uintptr(imScarfyAnim.Data)+uintptr(nextFrameDataOffset))), texScarfyAnimSize)) frameCounter = 0 } diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 9fce2a1..23a1f37 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -246,14 +246,6 @@ func UpdateTexture(texture Texture2D, pixels []color.RGBA) { C.UpdateTexture(*ctexture, cpixels) } -// UpdateTexture - Update GPU texture with new data -// NOTE: pixels data must match texture.format -func UpdateTextureUnsafe(texture Texture2D, pixels unsafe.Pointer) { - ctexture := texture.cptr() - cpixels := pixels - C.UpdateTexture(*ctexture, cpixels) -} - // UpdateTextureRec - Update GPU texture rectangle with new data func UpdateTextureRec(texture Texture2D, rec Rectangle, pixels []color.RGBA) { ctexture := texture.cptr() From 49d7e623032078835eca56ea09c4009bd81778ac Mon Sep 17 00:00:00 2001 From: Palessan Date: Fri, 28 Jun 2024 15:18:23 +0300 Subject: [PATCH 092/278] rectangle will be renamed to textures_sprite_anim part 1/2 --- .../textures/textures_sprite_anim/main.go | 94 ------------------ .../textures/textures_sprite_anim/scarfy.png | Bin 10394 -> 0 bytes 2 files changed, 94 deletions(-) delete mode 100644 examples/textures/textures_sprite_anim/main.go delete mode 100644 examples/textures/textures_sprite_anim/scarfy.png diff --git a/examples/textures/textures_sprite_anim/main.go b/examples/textures/textures_sprite_anim/main.go deleted file mode 100644 index 52471e6..0000000 --- a/examples/textures/textures_sprite_anim/main.go +++ /dev/null @@ -1,94 +0,0 @@ -package main - -import ( - "fmt" - - rl "github.com/gen2brain/raylib-go/raylib" -) - -const ( - MAX_FRAME_SPEED = 15 - MIN_FRAME_SPEED = 1 -) - -func main() { - // Initialization - const screenWidth = 800 - const screenHeight = 450 - - rl.InitWindow(screenWidth, screenHeight, "raylib [texture] example - sprite anim") - - // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - spriteFrames := float32(6) - scarfy := rl.LoadTexture("scarfy.png") // Texture loading - - position := rl.Vector2{X: 350.0, Y: 280.0} - frameRec := rl.Rectangle{X: 0.0, Y: 0.0, Width: float32(scarfy.Width) / spriteFrames, Height: float32(scarfy.Height)} - currentFrame := 0 - - framesCounter := 0 - framesSpeed := 8 // Number of spritesheet frames shown by second - - rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second - - // Main game loop - for !rl.WindowShouldClose() { // Detect window close button or ESC key - // Update - framesCounter++ - - if framesCounter >= (60 / framesSpeed) { - framesCounter = 0 - currentFrame++ - - if currentFrame > int(spriteFrames)-1 { - currentFrame = 0 - } - - frameRec.X = float32(currentFrame) * float32(scarfy.Width) / spriteFrames // select which image to show - } - - // Control frames speed - if rl.IsKeyPressed(rl.KeyRight) { - framesSpeed++ - } else if rl.IsKeyPressed(rl.KeyLeft) { - framesSpeed-- - } - - if framesSpeed > MAX_FRAME_SPEED { - framesSpeed = MAX_FRAME_SPEED - } else if framesSpeed < MIN_FRAME_SPEED { - framesSpeed = MIN_FRAME_SPEED - } - - // Draw - rl.BeginDrawing() - - rl.ClearBackground(rl.RayWhite) - - rl.DrawTexture(scarfy, 15, 40, rl.White) - rl.DrawRectangleLines(15, 40, int32(scarfy.Width), int32(scarfy.Height), rl.Lime) - rl.DrawRectangleLines(15+int32(frameRec.X), 40+int32(frameRec.Y), int32(frameRec.Width), int32(frameRec.Height), rl.Red) - - rl.DrawText("FRAME SPEED: ", 165, 210, 10, rl.DarkGray) - rl.DrawText(fmt.Sprintf("%02d FPS", framesSpeed), 575, 210, 10, rl.DarkGray) - rl.DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, rl.DarkGray) - - for i := 0; i < MAX_FRAME_SPEED; i++ { - if i < framesSpeed { - rl.DrawRectangle(250+21*int32(i), screenHeight/2.5+15, 20, 20, rl.Red) - } - rl.DrawRectangleLines(250+21*int32(i), screenHeight/2.5+15, 20, 20, rl.Maroon) - } - - rl.DrawTextureRec(scarfy, frameRec, position, rl.White) // Draw part of the texture - - rl.DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth-200, screenHeight-20, 10, rl.Gray) - - rl.EndDrawing() - } - - // De-Initialization - defer rl.UnloadTexture(scarfy) // Texture unloading - - defer rl.CloseWindow() // Close window and OpenGL context -} diff --git a/examples/textures/textures_sprite_anim/scarfy.png b/examples/textures/textures_sprite_anim/scarfy.png deleted file mode 100644 index be3b83d0e7f523e2cf80da19e274a8479e33fe13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10394 zcmd^Fi93|v7r*bAF*CLq`@R#hO;SV{OIeb=NS3h_vWt+Iu@j-iQi_o%DNA;WK}Au7 zB3mPS_OI;A{HDL-cc1gT?|sg5pZlEm-1E6-dy_593|W~3m;eB*#zqEK05H&}fQ0(@ zN3kV1RHZd6IQNTqfdBAfN@X((MfKMLqDS%VQz^UUv^BB-n0h+4dvdpVCW@acum;AQ`o>uP6h%)p{ zI^&gW?3rZbnQVORwy9ULsn>0g z16Xe%r2&vKHa5_;33FO{l0xMA{i&U@BeG)_5;ZC-!!>(tko=Hu5-s?BWeEPlOGb^Ys( zR*(PJ^~cw*TCat`-C3`BZ`>TxKk2P)ietbr8Yy4}lfjI1D#XG3{;VvNbj>OEWKEs_ z@W7l~e{lk%6W{xNmlzfCN|LuaJ3cZ}kJc?lpT}YGCr7?jhOV^6E@=x0hMzcjGR)Iw zw8CZmDoZpvOIgj?h|2eYM}4lauzk4jomM5DOA3}_XauK8Iwz1cpc*i}4%2B^RyFbs4`biucISH#BsO#u>qJ{uwB;5K5es#^&kgzcM$}((>+I z0i=)0Xz~Bm8p}Zu^na`#*un>FnJq4Rn`I*k70JCF%?wRTbM-_8Y(CKg=4lSkKoLG3 zbAxqWEy#Lr8+UmNbCmpU*uLmPS9bO<(3L%+5 z)`6naAsL7Vf8Ti2wQ6owbjX<1S5pjpA31K0t%+KKjg8@|FLee|Fj-q+4k(rJ%GVqq z)>5d?kT2D|wB*DxV8-3pr1LjmZ}UrTo!?kP`$I6(m9|P@xZ1&Bo4ES>6ZuQ7nxFeZ z^VAxdWi<6NOu6D414A1tD-zRK9;-mwV`!@Bt#okq^bh5SU#a?FTNpyzvtw0U!SqZOsl}B>=XMHbx#zWeLVYp{P3fo zUsrak+~j*SqlTPr2WMtkOX=&7D-a{$E~!m;$d>;toA6UMAB>Q!&ffA4MjA-a8e~Yj zy9S`}+~6;1m@Gn?iLidv$-s{5=QrIG+WV_B=SPLvjbK7!^?`evilRvr2MQ!|tK!{( zF6I&2aGifSG7g2#J?V8bX`+Qw=5UMnGphsjK&f9|?Au+>*`!e4W6@0lLrS89gIxl7 zRg>qk+Z*4I?3dC5^9ju!zqE(T@3Doe2arNHiJMjWi5ePac?#L^(e-?k7#9aLng}CX z^a)-W5BK&@IzU!y4S;(X9NWm*9Qw* z9v8N36l8v7SLxC&dPw-0jgW=1b;4FDP(B+*C?r@cT1~4y8-HpWqX_;Z{p29&?Al9_ zHYK2H8Q5z2i-&0(kUA%bHRS+Xw2vRTQcM-Yr)p4nd6ei|CV& zj!uRKFK#_5mkt-|pT1Hhe{uDz^T~nZHZT2~PzbWKO-j@z!nE~AISHD!X6E&y;GQ88 zrWudoVe8W{(i>Sbucmb8wfj+f3TQNtX>QaX<&N)xs@mj4Gi`u zLe(qzCSapVfkZ#xs-vX7?fi@2#_Bn<5BS0HcTA+lMkU8Te{Rwa1l6<;bI#rf-=@Z{ z&+eE)94;BTABhJcN6+l2w~Qa_(B|AJje3;U6nWW@QtaB1HrBvdC(^4t%Qdd z0w1IHHi=|0eSH$gn-pEigUx}y*}J*bhl~W~KEi5hQ22JXYP$#|rg^7W=+}|f z2l899!q9JSHNW>BEw}c2yrD4q6>=7I#|0f>CrLtfuk3W$0DG`}oVKH*ZJEP66NbBO zMdxhGZ-k2Km`&8v{=u=HH74iJQ??)5PN9qJc>N1>++;)@M~5!(+z+~;QC6B#SieD# z#k(_SlplYYZs%f;<#%P=yyiVt^UI#}pX!F;&l|~1U2RgxNHdhp<%N$h`HQF5;H@j4 z?i2SVSC*Fin;VFsj-uALNpF<*9AY{7P`4lR5#ff;&`NV9;wD9?|CWZ&Ee^|W8k zFbeEJHj2Vc2R5k)tDrVqQBa!|)7aS9r0m=rjNWPqV~0{x9o}vawuor{7&~ZV4nC`P zdbDx+EA#@IuV*ox3?vp!aGG}@%9s7F-%Y|Ebh4?%-qdh(Vs+|_=KS$P@09P^!-42B zyE^3cyEzp+0K(k4gJkQ37Av)VJ@KGS0l!`2(%u|tMEIrcK$|jd6B`{f!C#KoF#^zN z!+JWA64PMn{ve%Z0Hj@l7_irS^1vLXgNbx~D;@m)PgD=|b_JnAPB29%Io?~Z66S9R zUGXP21HE$0~%%OBa5;UiP!)5MzCSfXgGCG_n+e(;fwu23?6B9%dCp#n}ag z^|dFkZfxvrF8y*|+^2uj1~=@Oa6*L7P`c}|8%Vh^K4N@kQI`wqD=+^D?v_W zz91~X@=%DKgtz3NxTU|ov_9na>tK1Sg*N0SDM{Pu>Fnfn-lrnzyvcN(O+MD=Fh2yP zhgQN9vGqnOmr+zRVdPgsEEPT~GCOOHN_I~4$+{96bm~P1urOyjvYQ#j&IcP|)o;!f zGcY69URFc;oT}Y}*o0jPy-yGXQTBj^)&sOb4!nIwIy#Nb82<@(-^Hl+JjO!lkP~_k zX8>G(F_FjHBW1wC&93Z8_l`97#r+wz7TUp9^Vas{)^g(0?4gT) zf=;n8#n=-PhV6wO7nl`KYVX9EVQ|8RCR3#o`lw^h>8U<9R-7`sL>LLqY{{1Oa(JBr zF|sL#%J}4SDoh+ZeaWzH#V0m9?Pt53gFQv1#fx)`XrdmB;&ngAH_#hE1E2F1~hw;4K(h`NY_7k}Pt2rE(OSk0Du-gc+!~shQ(i;>WK4)0plmGmMyseV6 z2>;HX(%HPd@8wgw&QZpEf4|$d>`SLeZOhj!V?KU0>i^`}+#SFR&xo=<%B+HIU7HNP zJyUv&tdzq6?LE5jROux$**3IJn1g~H8*_B*NOuEjA!Ht5VLO6PZ(*xtLre(K4^yTH zw%*fpcZ{eMs2`mx0Nm?+cP5CKl27NL?|Imp;R?vX%JH zh)ux$Wk&A7?;#t1oDcPMgAO9L!dimom&YQunpXqnIpivKo?4&Y$9>7-mjW@BDZFwk z+ku+Gi4!M;XRq?%a<5#<JwAY;+s}XT-QZ60od)dio1?=cn zHFwZ2e7=x6Io@+7C5;eEuAG+NpGY*0F~=71=-0F38@A2i791Q9Y0m+ui^f+`<_gox z9FAQ{h2&5p%YNAmWQZ@da3WW&KOi0-)ykN(R+z4UW=U=gjHM#CsQ45PcMz8Z#oT;# zECX_fsnt+md@c2VKYnyrR*Y@dmZJ1ggX~Ce)O@H%)EjS6bL#5kkq{0naak$< zAnvNdAj^2ij}$;p8mB>(49LXf@KZaPNCywGc!xuMH0fF|yP}iBwAv@JWmJkgFBGy4GT zF;JSv4m2|yMLe5+rSS3#IaMXte}XG~x-R{GjYmDStQ@novNZkf77yWQTJQDXh44?p z8+{%=#KU!;&3ImiIQ)lzF4}2s(pk-`=HN!PbTicEs)QoY7k;S*qidp8fD5y9{`{9O z=S6NtdJ2!n&Yw_0BN*$VI=AioK3B$<9 zmE8ch=wSQHa55tB!|TC_%E<*s@jq*mWe92(U9Saq|H;OkDF4T!>(qbI2szMM_VVU` zpNfm=VOwKO9WR>tUl7guc?Lc|aeO@VSLE!IAQXT-K=iJz&+;z{@{6P1eBnVjM}4Yz zRXo|v`$X5vjsUb$#TigrEOT*RvV|lnNFhXc?_lWiVl>I8fuN{~=SaEsBK5j`E#-?nSlzFWJICI?yfBkuwzk^dmA%lRJLkIL*(`;Rt&v(;9y^!)`INBjrArqO zJ0@pJUmBh17YTE&O_lm&EGqxGMy=4vc1w`CXzO z`Cotj)v6wymGK=!C>^CqaDH<0_^N0-u*9jsv7<{ey!h~;&`(4ZG!+zg8l%Pa%$Z!5 zZ87&rCXjaAqxPofwclrEeVXTl9%bkQh1iM=6nqm4p)+>w>DydrZFR+HBSdz0ALXL= z1N6z*-U}QW0?~*Et4F6?sP};pkA>s!Y^Mtw8-rb04;e%;5vVNjDn!HR&#E{AsifX{ z|7q>!3eiLE>CPkT`Y9cDJX{J!I@q%S&&^J#l?Jd_D8$l*@Uc`eop|@oTXYhC9gR=0fA^ZbD!tVo9f@|qZk()^+^})O5L|2vNSIDB@aM4Gp z$DMTg*7E!}4~rd; zdGeznQRLpGi{a$2GxBD-bC#FpBOW68VSl)>Dq?8s<*xsTg(Bk@MsMleRw=F(!a$q z?Nhx&S|1Kfk0=d|bG*Qm;gO3c!Hcqw2bb+@ecNFTLPb`bpY7jiOc%5eJw3^|MaeS6 z)Ze#Nqjv>UiNoZVe-?kvTrK|H=e4k^d1Gqb=T|=Ua=xZb!opw zZ_Sum-{)}!&t67XgpLP}A+Af30`B4PTJLXDw5Q!b_D9=oNvOK|m3>j){AONEDa zZs@uq7~JpRpxl*A2EPT!Hc~L`)$`!wV(ZVJn_Hnb*jRdz4)s(bm3ypz{ig@*aO-*g z=3g;Vdt#xW%bS(ir?H@ZNKt~i3l62=G>ZP=ld+e_o8&9;d5Lu}3{YprGNQ_~7{X^ZYCp zv;4D+Gx`|6^Webf&Om8nXfFPZ9ai(zDsKr?#Vk=K0~WAB)Hh%vpXRn-h-PF zc1^XfU)N-g^siRz1i4dJnND2z`m^dJd(@mbnp|S6_H1e71Ib=T^+C^MRD*+dc}pmA z>!0}XB`gHG`^BAut$y0FV1%fLnVE6gv9SjS>Zcj}OzIL6un>%FH!Ave+f`c!hrI(D z77b#<=2gF%O_sh43Wj*L9|@arIM#U&tP&U!^1Z{E{# zctMG79u;#BH98M|-Spo0qk-}DZMwmVnLI?1>~qQu&uaLN43DOEZEYYp#11m|X4e}} zz1%SUz{)DD^_l;k>%lw02eEXIB5rXTO440%hPdAHY9EV$p}L4@7`YTm#Bly`sPFxy z9P01;WzPa<@Mq(9N`91y!2VAUEv=C{$vbl#UsX|H=*RNey?fMp z>3Xz9j*+@)tLN{MdWMAMf&xA9e4Sf4lB5YoG+`0Qiou5)xj#wnJEUo97fl}4e;~;K zJ@)I#op!Y>TiNjHE6EHP;pL%%RV0*@SmV9$$FqSi!}=^QrF$(OMbPV3hPXbW$T%vR zQX1c2;BLT8BGR1s=rECE+(N>2OjSFvd?W-rOKRUz2AuQo){L%hZ<_Foo^<<3t!zo^ zsmMp}DZwd)gfPxQq+yzn)@K8u{-BsYUC)H_*;p^wF5H~J{Q#ZG$-;__h*2)F{oxaQ zcLh5aM+PZtX@@zvh0 zpH=&ON9Z*-vUfm65nuh&l>?Ef+pk~GSQX%|@ApJN!AD@La0@lrg(5}L zzVyImYJd?@e6tPFK>PYco$G8X7S6kK%ez!41DiCTm?sh=R;ziVSNv=y=(>gut9~1e zRvLBg$`6RtI89pMjPoL8O<|6SoYE5}OZ&;ZBAH-@fBshjF}^5`y_K4}XwafT&C9cO zKGzyo;*1c4V}0NAPG9pAZ*1D>02vQ5BOmE9>>R0Kb~j;5IGt;; zD0>tIic=67pDMQb2kT%)MHS~A$0pi2NPbM}&bJ`3Xv&7~LioV+;-&nU&#k(~8LNrD zN6)YZt9|77rieREzmRgc)*V3J84f7t-1%rZIH8H(%9%&Ax<;I&c$r68=>{>Y;~0}} zWqDZG&K39G{&rWC9vSzg`~~@~&F#qZn@QW?A&WIGGxOIPxkAS7-m%lBTHn#b*d$eT zdx0Ya(5K{-6C=P*BDm+cPyu?@?F8`SDb+}MXREV z1+9oQaz4|eb072qC4}tS%i}P^Y5rK+3MjW-z)fTofp0>xq%ScjH@Y)U0N3 zW4(5bt9sV(%`Gj=Kv9*oc<)5}+9>5lYYyp?%r*Dt1hNJWJW;-7Arc!v+qE4np=X~A z@{pfN30DLhZ-jTjE7>UJn$JI4pb=5^rX>Mgce7-1*`RVIDPapo;6Eo-fKENB{am)Vb$(R?17)qQy`S-DjR7 zVC3VN&cBi4v76$#AW<~RsyB9D>cXL(ej$pIfVZ^9CAdI)Kelu7=0z1T&%b1h^}UJI zoU(2{!Q{)cpK?a;i1p&`aCuqQB=h2BbSG^3 zoKoLKYR-$EtGGn!C_GjEwk`bnL?>DBs%}=~Y3pvvodhaDPtU-Q53qSwhG<193(-qV z&!YF_o}4eb?b!F3G>i+*FzaVn#Y;KBL$Gbe6y^8$D>c=gy_vj9OYu0vA4 zBvkvhy~XeRw-jH=2~Ai3NErVsI>1%;ehf2q`Hk z%A=r{Wq!WWJJl1I55JdB?g*#czP+(y}|0N&)FcO z=sJJm+L@?gUdtS2!??bR-=afj!VJ^fzI=W1`n5@`(fVA}k~?`W{Rk9xVFV~Xu>+*Y zcwJxL%uG9S@ex}0@x#{?3xA771W7oi;>u6Oujwq5uTMr_%s~~mn+x)dDH|JlTos&- zU}7gRkhFK5!R+~SzfcL1+%XJ-u&by4PPYM$$5c=d6una4ky;-wuZjGMD=LHKlSwR5 zpMQo4B`{$ZZ|#koIFa!o1u}7DWw0o+qWhDJFm*M@S0aad>-n$uV*gxA@REkKIP`tX z9Nl)2YVcY%OY*ZWfmV9spNFK|MDS;LfS%^5u(EFoyhSd(+-t@fbIp=r+0W(SM@2M= zNAYDzE9`LktoUODU^|a34w8)z8j_qpf|6j7z_ww+jCgqJmt5AaEp#mK^a~; z?T?sPtXhrvn{qO3Dd3c?$!dZ8op>P!i*vVS+Tg}9aK1yCAfk9G!UyXvEoO0#`!SLD zx1C&DTTtLVSnKcH82pLD>0DN)^cqwA3#NqbcsIh$L-w7`$0SS((;s23F5^A}1ONr1xRs$m`cQs59rXDz?*JBOWN&zjv}hzt~WT zBmf?W0FsdV(*_V$_RA9P3dp?L^*t6>;phW7q+jvWfE~sc8-y`qnT-96TFW2I?!H~T z#NlE^5QMeX7EB9vv(WA{6ON*9t?NpVk~2_LZFZ89;ui0Xd{4wI*csl#FC8M^2>GZXlq?Jb}bgGKhhZ_bTrhRzoTkCb$H8ac-1YC&z$U?0$-AtU8a_BEKT^2|zX%Kd*(WedkAL%d62in_9N>hg4#A#MmkCjo^epXB26M zy3bO&_SGO1PxHg5CO*x%(NSpue^TKT<`4m$y7*v%W;o*rc}?zAQeix4AZ`l+{+$ zuTJYL;#|)+Id+2ISH02ZaP58ajMAkNVf~R;_u+V{&t5;vl>rkX8LKpe!flB=WqRZ zAk!=0$j7ITz{Q+_Q-5+Phg?RL&Ktu z1M4wT#8_wMkL9T zGUd@qSqgW%_00+UgzWPM##P>c8F!y-KDhLCPV>`cHoj7~2f9xu_!a!YmWl$rf$4G|uwj z%tG8Hv8NaA@Bw{7jO#8p%{z5`* zedM3Wob=~(i}pJ91HAG#h2tV%IZ3o|3BZCou~FVqHfZzW)o4{>{>n!_Rfn9fH7EEv zoq#F3%9<-HxkEV|^z29b11Ss3wZ$qF<#AqN&SzLr1?GNJ=;gx`2OlEj_6-}L%(j-( znzI5}E_*&I2FUl`%QIumDJdP_4zt_m6uaXW{LZJM@%^6~-{9bCkJ3g&+o|WCpUL%vQt#)U07kBBrucS zo|rh7-Ul&c#o=`@=)1SiFCO~AD{!yLBjyd;GC%@x^0}S_Jw!5sV|my005g9*F_?jL zo9O^A*%h#3dGY!%in=j4R!`GIEQ>0Fnw;CTkcHp$tb!~>cXP4fk{~z8tI49#O=Pel z`Oz>}(G`o=`4TSXvtr|V9uAZrW*2iXUaJGxy;adC2gy5wms%gA?$Em$uzQ@4LF;J_ zfI{Wd22!qddOQ?J=>7RZQP8|5i#jZAH}i}^0WNQ6$V= z1(!Et0PefxF;T3viOHhObIuJxTgzGz*yx3x}ndR?zqWFId*r{JMDzbaVxEHbc z%&P3Njb)`r&qDb*_>7G#UHD`J(C;#i2Jh!z%y4)j9hH-D5pQ$TAM1`O<76IBgkY|Q zI_WvtIBib;tDl}^*%RqTd(cbtOe{Mh-O1SP-31!bqE(We_l)SNfB%sgpD{Bi(<8+E E4?57ykpKVy From ded439d8498b602e8df8fda1a097011434db790b Mon Sep 17 00:00:00 2001 From: Palessan Date: Fri, 28 Jun 2024 15:27:21 +0300 Subject: [PATCH 093/278] rectangle will be renamed to textures_sprite_anim part 2/2 (using git mv to preserve git history) --- .../{rectangle => textures_sprite_anim}/main.go | 0 .../{rectangle => textures_sprite_anim}/scarfy.png | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/textures/{rectangle => textures_sprite_anim}/main.go (100%) rename examples/textures/{rectangle => textures_sprite_anim}/scarfy.png (100%) diff --git a/examples/textures/rectangle/main.go b/examples/textures/textures_sprite_anim/main.go similarity index 100% rename from examples/textures/rectangle/main.go rename to examples/textures/textures_sprite_anim/main.go diff --git a/examples/textures/rectangle/scarfy.png b/examples/textures/textures_sprite_anim/scarfy.png similarity index 100% rename from examples/textures/rectangle/scarfy.png rename to examples/textures/textures_sprite_anim/scarfy.png From 64b25f38d95fd07e6c52beebc0946143ff7b08e1 Mon Sep 17 00:00:00 2001 From: Arold Date: Tue, 6 Aug 2024 22:53:40 -0400 Subject: [PATCH 094/278] Android example: Added windows.bat and updated Readme --- examples/others/android/example/README.md | 8 ++- .../others/android/example/androidcompile.bat | 68 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 examples/others/android/example/androidcompile.bat diff --git a/examples/others/android/example/README.md b/examples/others/android/example/README.md index 6ef631d..8ab1a50 100644 --- a/examples/others/android/example/README.md +++ b/examples/others/android/example/README.md @@ -3,7 +3,7 @@ To compile example to shared library you will need [Android NDK](https://developer.android.com/ndk/downloads/index.html). To build Android apk you will need [Android SDK](http://developer.android.com/sdk/index.html#Other). -Export path to Android NDK, point to location where you have unpacked archive: +Export path to Android NDK, point to location where you have unpacked archive (WARNING: NDK 27 is not supported . See https://github.com/raysan5/raylib/issues/4166): export ANDROID_NDK_HOME=/opt/android-ndk @@ -41,3 +41,9 @@ If everything is successfully built apk can be found in the android/build/output For aarch64/arm64 replace `arm-linux-androideabi` with `aarch64-linux-android`, set GOARCH to arm64 and use minimum `ANDROID_API=21`. + +### Windows + +To build shared libraries on Windows you can inspect the file `androidcompile.bat` by opening it on a text editor, it can then be configured to generate the libraries when running the .bat file + +See also [instructions](https://developer.android.com/build/building-cmdline#build_bundle) to build a android app bundle for appstore distribution \ No newline at end of file diff --git a/examples/others/android/example/androidcompile.bat b/examples/others/android/example/androidcompile.bat new file mode 100644 index 0000000..ba18ba2 --- /dev/null +++ b/examples/others/android/example/androidcompile.bat @@ -0,0 +1,68 @@ +@REM Set your desired api. Max is 31 +@set ANDROID_API=31 +@REM Your library name. If you change it here you should also change it in your android manifest... +@set LIBRARY_NAME=example +@REM Set your android sdk folder here +@set ANDROID_HOME=F:/AndroidSDK +@REM Set your android NDK folder here. WARNING: NDK 27 is not supported yet. See https://github.com/raysan5/raylib/issues/4166 +@set ANDROID_NDK_HOME=F:/AndroidSDK/ndk/23.2.8568313 +@REM The target architecture for android. See https://developer.android.com/ndk/guides/abis. +@REM Valid options are: armeabi-v7a,arm64-v8a,x86,x86_64 or "all" if you want to build for all architectures. +@set TARGET_ARCH="all" +@REM Automatic setup. Should work by default. Do not change anything below here +@set PATH=%ANDROID_NDK_HOME%/toolchains/llvm/prebuilt/windows-x86_64/bin;%PATH% +@set ANDROID_SYSROOT=%ANDROID_NDK_HOME%/toolchains/llvm/prebuilt/windows-x86_64/sysroot +@set ANDROID_TOOLCHAIN=%ANDROID_NDK_HOME%/toolchains/llvm/prebuilt/windows-x86_64 +@IF %TARGET_ARCH% == "all" ( + @GOTO:BUILDALL +) else ( + @GOTO:MAIN +) + +:COMPILE + @echo compiling for platform %FL% + @set CGO_CFLAGS="-I%ANDROID_SYSROOT%/usr/include -I%ANDROID_SYSROOT%/usr/include/%TRIPLE% --sysroot=%ANDROID_SYSROOT% -D__ANDROID_API__=%ANDROID_API%" + @set CGO_LDFLAGS="-L%ANDROID_SYSROOT%/usr/lib/%TRIPLE%/%ANDROID_API% -L%ANDROID_TOOLCHAIN%/%TRIPLE%/lib --sysroot=%ANDROID_SYSROOT%" + @set CGO_ENABLED=1 + @set GOOS=android + @set GOARCH=arm + @go build -buildmode=c-shared -ldflags="-s -w -extldflags=-Wl,-soname,lib%LIBRARY_NAME%.so" -o=android/libs/%FL%/lib%LIBRARY_NAME%.so +@EXIT /B + +:BUILDALL + @set TARGET_ARCH="armeabi-v7a" + @CALL:MAIN + @set TARGET_ARCH="arm64-v8a" + @CALL:MAIN + @set TARGET_ARCH="x86" + @CALL:MAIN + @set TARGET_ARCH="x86_64" + @CALL:MAIN +@EXIT /B + +:MAIN + @IF %TARGET_ARCH% == "armeabi-v7a" ( + @set CC="armv7a-linux-androideabi%ANDROID_API%-clang" + @set TRIPLE=arm-linux-androideabi + @set FL=armeabi-v7a + @set GOARCH=arm + @CALL:COMPILE ) + @IF %TARGET_ARCH% == "arm64-v8a" ( + @set CC="armv7a-linux-androideabi%ANDROID_API%-clang" + @set TRIPLE=aarch64-linux-android + @set FL=arm64-v8a + @set GOARCH=arm64 + @CALL:COMPILE ) + @IF %TARGET_ARCH% == "x86" ( + @set CC="armv7a-linux-androideabi%ANDROID_API%-clang" + @set TRIPLE=i686-linux-android + @set FL=x86 + @set GOARCH=arm + @CALL:COMPILE ) + @IF %TARGET_ARCH% == "x86_64" ( + @set CC="armv7a-linux-androideabi%ANDROID_API%-clang" + @set TRIPLE=x86_64-linux-android + @set FL=x86_64 + @set GOARCH=arm64 + @CALL:COMPILE ) +@EXIT /B From afca9ac4b576efc36ee149236753a835f12f988f Mon Sep 17 00:00:00 2001 From: Aurora Date: Mon, 12 Aug 2024 22:52:35 +0100 Subject: [PATCH 095/278] Added MouseButton newtype --- raylib/raylib.go | 4 +++- raylib/rcore.go | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/raylib/raylib.go b/raylib/raylib.go index 8c9e46b..661d691 100644 --- a/raylib/raylib.go +++ b/raylib/raylib.go @@ -366,9 +366,11 @@ const ( MouseMiddleButton = MouseButtonMiddle ) +type MouseButton int32 + // Mouse Buttons const ( - MouseButtonLeft = iota + MouseButtonLeft MouseButton = iota MouseButtonRight MouseButtonMiddle MouseButtonSide diff --git a/raylib/rcore.go b/raylib/rcore.go index 9737e08..8c322ae 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -1082,7 +1082,7 @@ func SetGamepadMappings(mappings string) int32 { } // IsMouseButtonPressed - Detect if a mouse button has been pressed once -func IsMouseButtonPressed(button int32) bool { +func IsMouseButtonPressed(button MouseButton) bool { cbutton := (C.int)(button) ret := C.IsMouseButtonPressed(cbutton) v := bool(ret) @@ -1090,7 +1090,7 @@ func IsMouseButtonPressed(button int32) bool { } // IsMouseButtonDown - Detect if a mouse button is being pressed -func IsMouseButtonDown(button int32) bool { +func IsMouseButtonDown(button MouseButton) bool { cbutton := (C.int)(button) ret := C.IsMouseButtonDown(cbutton) v := bool(ret) @@ -1098,7 +1098,7 @@ func IsMouseButtonDown(button int32) bool { } // IsMouseButtonReleased - Detect if a mouse button has been released once -func IsMouseButtonReleased(button int32) bool { +func IsMouseButtonReleased(button MouseButton) bool { cbutton := (C.int)(button) ret := C.IsMouseButtonReleased(cbutton) v := bool(ret) @@ -1106,7 +1106,7 @@ func IsMouseButtonReleased(button int32) bool { } // IsMouseButtonUp - Detect if a mouse button is NOT being pressed -func IsMouseButtonUp(button int32) bool { +func IsMouseButtonUp(button MouseButton) bool { cbutton := (C.int)(button) ret := C.IsMouseButtonUp(cbutton) v := bool(ret) From a30a52c553688c5d3b9a9b42b171de224b2f9b43 Mon Sep 17 00:00:00 2001 From: Aurora Date: Tue, 13 Aug 2024 12:27:47 +0100 Subject: [PATCH 096/278] changed raylib_purego.go to use the new type --- raylib/raylib_purego.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 53d061d..9714804 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -1757,23 +1757,23 @@ func SetGamepadMappings(mappings string) int32 { } // IsMouseButtonPressed - Check if a mouse button has been pressed once -func IsMouseButtonPressed(button int32) bool { - return isMouseButtonPressed(button) +func IsMouseButtonPressed(button MouseButton) bool { + return isMouseButtonPressed(int32(button)) } // IsMouseButtonDown - Check if a mouse button is being pressed -func IsMouseButtonDown(button int32) bool { - return isMouseButtonDown(button) +func IsMouseButtonDown(button MouseButton) bool { + return isMouseButtonDown(int32(button)) } // IsMouseButtonReleased - Check if a mouse button has been released once -func IsMouseButtonReleased(button int32) bool { - return isMouseButtonReleased(button) +func IsMouseButtonReleased(button MouseButton) bool { + return isMouseButtonReleased(int32(button)) } // IsMouseButtonUp - Check if a mouse button is NOT being pressed -func IsMouseButtonUp(button int32) bool { - return isMouseButtonUp(button) +func IsMouseButtonUp(button MouseButton) bool { + return isMouseButtonUp(int32(button)) } // GetMouseX - Get mouse position X From d374f90b4594c58f40c8e6a81d6ea8551236e0a8 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:49:35 +0200 Subject: [PATCH 097/278] shader has to be passed as pointer --- raylib/raylib_purego.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 53d061d..ccbc163 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -1328,7 +1328,7 @@ func EndTextureMode() { // BeginShaderMode - Begin custom shader drawing func BeginShaderMode(shader Shader) { - beginShaderMode(*(*uintptr)(unsafe.Pointer(&shader))) + beginShaderMode(uintptr(unsafe.Pointer(&shader))) } // EndShaderMode - End custom shader drawing (use default shader) From 26bdccfe6fe3b40833cdd9f3a2b2638523c869a8 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:54:05 +0200 Subject: [PATCH 098/278] allow passing nil to LoadShader for purego as well (#172) --- raylib/raylib_purego.go | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index ccbc163..4456dab 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -11,6 +11,7 @@ import ( "unsafe" "github.com/ebitengine/purego" + "golang.org/x/sys/windows" ) var ( @@ -91,8 +92,8 @@ var beginVrStereoMode func(config uintptr) var endVrStereoMode func() var loadVrStereoConfig func(config uintptr, device uintptr) var unloadVrStereoConfig func(config uintptr) -var loadShader func(shader uintptr, vsFileName string, fsFileName string) -var loadShaderFromMemory func(shader uintptr, vsCode string, fsCode string) +var loadShader func(shader uintptr, vsFileName uintptr, fsFileName uintptr) +var loadShaderFromMemory func(shader uintptr, vsCode uintptr, fsCode uintptr) var isShaderReady func(shader uintptr) bool var getShaderLocation func(shader uintptr, uniformName string) int32 var getShaderLocationAttrib func(shader uintptr, attribName string) int32 @@ -1377,14 +1378,44 @@ func UnloadVrStereoConfig(config VrStereoConfig) { // LoadShader - Load shader from files and bind default locations func LoadShader(vsFileName string, fsFileName string) Shader { var shader Shader - loadShader(uintptr(unsafe.Pointer(&shader)), vsFileName, fsFileName) + var cvsFileName, cfsFileName *byte + if vsFileName != "" { + var err error + cvsFileName, err = windows.BytePtrFromString(vsFileName) + if err != nil { + panic(err) + } + } + if fsFileName != "" { + var err error + cfsFileName, err = windows.BytePtrFromString(fsFileName) + if err != nil { + panic(err) + } + } + loadShader(uintptr(unsafe.Pointer(&shader)), uintptr(unsafe.Pointer(cvsFileName)), uintptr(unsafe.Pointer(cfsFileName))) return shader } // LoadShaderFromMemory - Load shader from code strings and bind default locations func LoadShaderFromMemory(vsCode string, fsCode string) Shader { var shader Shader - loadShaderFromMemory(uintptr(unsafe.Pointer(&shader)), vsCode, fsCode) + var cvsCode, cfsCode *byte + if vsCode != "" { + var err error + cvsCode, err = windows.BytePtrFromString(vsCode) + if err != nil { + panic(err) + } + } + if fsCode != "" { + var err error + cfsCode, err = windows.BytePtrFromString(fsCode) + if err != nil { + panic(err) + } + } + loadShaderFromMemory(uintptr(unsafe.Pointer(&shader)), uintptr(unsafe.Pointer(cvsCode)), uintptr(unsafe.Pointer(cfsCode))) return shader } From 6c2499adffe8867e81e6ad5a6ab96125ba776e1d Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:00:35 +0200 Subject: [PATCH 099/278] purego fix for ColorFromNormalized: Vector4 has to be passed as pointer (not by value) --- raylib/raylib_purego.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index df44ce2..c9c457f 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -2780,7 +2780,7 @@ func ColorNormalize(col color.RGBA) Vector4 { // ColorFromNormalized - Get Color from normalized values [0..1] func ColorFromNormalized(normalized Vector4) color.RGBA { - ret := colorFromNormalized(*(*uintptr)(unsafe.Pointer(&normalized))) + ret := colorFromNormalized(uintptr(unsafe.Pointer(&normalized))) return *(*color.RGBA)(unsafe.Pointer(&ret)) } From 2053879bfbbcb15691ff954286ce5b216bc8c4bb Mon Sep 17 00:00:00 2001 From: imprity Date: Sun, 15 Sep 2024 09:54:51 +0900 Subject: [PATCH 100/278] Fix NewImageFromImage color converting Old version of NewImageFromImage converted colors incorrectly. This commit fixes the issue. --- raylib/raylib_purego.go | 2 +- raylib/rtextures.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index c9c457f..fa9a944 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -3776,7 +3776,7 @@ func NewImageFromImage(img image.Image) *Image { for x := 0; x < size.X; x++ { col := img.At(x, y) r, g, b, a := col.RGBA() - rcolor := NewColor(uint8(r), uint8(g), uint8(b), uint8(a)) + rcolor := NewColor(uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)) ImageDrawPixel(ret, int32(x), int32(y), rcolor) } } diff --git a/raylib/rtextures.go b/raylib/rtextures.go index 23a1f37..0a990a8 100644 --- a/raylib/rtextures.go +++ b/raylib/rtextures.go @@ -69,7 +69,7 @@ func NewImageFromImage(img image.Image) *Image { for x := 0; x < size.X; x++ { color := img.At(x, y) r, g, b, a := color.RGBA() - rcolor := NewColor(uint8(r), uint8(g), uint8(b), uint8(a)) + rcolor := NewColor(uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)) ccolor = colorCptr(rcolor) cx = (C.int)(x) From c2c8150de9c2eb880a9f04c9c0021b110279a76a Mon Sep 17 00:00:00 2001 From: agrigoryan Date: Mon, 30 Sep 2024 01:44:08 -0400 Subject: [PATCH 101/278] bindings for attaching/detaching mixed audio processor --- raylib/raudio.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/raylib/raudio.go b/raylib/raudio.go index 479b9db..2c8aa59 100644 --- a/raylib/raudio.go +++ b/raylib/raudio.go @@ -16,13 +16,33 @@ static void audioStreamWrapperCallback(void *data, unsigned int frames) { static void setAudioStreamCallbackWrapper(AudioStream stream) { SetAudioStreamCallback(stream, audioStreamWrapperCallback); } + +extern void internalAudioMixedProcessorGo(void *, int); + +static void audioMixedProcessorCallback(void *data, unsigned int frames) { + internalAudioMixedProcessorGo(data, frames); +} + +static void setAudioMixedProcessorCallbackWrapper() { + AttachAudioMixedProcessor(audioMixedProcessorCallback); +} + +static void unsetAudioMixedProcessorCallbackWrapper() { + DetachAudioMixedProcessor(audioMixedProcessorCallback); +} */ import "C" import ( + "reflect" + "sync" "unsafe" ) -var internalAudioStreamCallback AudioCallback +var ( + internalAudioStreamCallback AudioCallback + audioMixedProcessorsMutex = sync.RWMutex{} + audioMixedProcessors = []AudioCallback{} +) // SetAudioStreamCallback - Audio thread callback to request new data func SetAudioStreamCallback(stream AudioStream, callback AudioCallback) { @@ -37,6 +57,41 @@ func internalAudioStreamCallbackGo(data unsafe.Pointer, frames C.int) { } } +func AttachAudioMixedProcessor(callback AudioCallback) { + audioMixedProcessorsMutex.Lock() + defer audioMixedProcessorsMutex.Unlock() + + if len(audioMixedProcessors) == 0 { + C.setAudioMixedProcessorCallbackWrapper() + } + + audioMixedProcessors = append(audioMixedProcessors, callback) +} + +func DetachAudioMixedProcessor(callback AudioCallback) { + audioMixedProcessorsMutex.Lock() + defer audioMixedProcessorsMutex.Unlock() + + callbackPtr := reflect.ValueOf(callback).Pointer() + for i := len(audioMixedProcessors) - 1; i >= 0; i-- { + if reflect.ValueOf(audioMixedProcessors[i]).Pointer() == callbackPtr { + audioMixedProcessors = append(audioMixedProcessors[:i], audioMixedProcessors[i+1:]...) + break + } + } + + if len(audioMixedProcessors) == 0 { + C.unsetAudioMixedProcessorCallbackWrapper() + } +} + +//export internalAudioMixedProcessorGo +func internalAudioMixedProcessorGo(data unsafe.Pointer, frames C.int) { + for _, callback := range audioMixedProcessors { + callback(unsafe.Slice((*float32)(data), frames), int(frames)) + } +} + // newWaveFromPointer - Returns new Wave from pointer func newWaveFromPointer(ptr unsafe.Pointer) Wave { return *(*Wave)(ptr) From 54b89f5a68bf4cca2320a02f76146089c718fa38 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Mon, 14 Oct 2024 12:11:58 +0200 Subject: [PATCH 102/278] 3d camera first person example updated to match https://www.raylib.com/examples/core/loader.html?name=core_3d_camera_first_person --- examples/core/3d_camera_first_person/main.go | 165 ++++++++++++++++--- 1 file changed, 146 insertions(+), 19 deletions(-) diff --git a/examples/core/3d_camera_first_person/main.go b/examples/core/3d_camera_first_person/main.go index 7b42f47..7eba060 100644 --- a/examples/core/3d_camera_first_person/main.go +++ b/examples/core/3d_camera_first_person/main.go @@ -1,22 +1,43 @@ package main import ( + "fmt" + rl "github.com/gen2brain/raylib-go/raylib" ) const ( - maxColumns = 20 + maxColumns = 20 + screenWidth = 800 + screenHeight = 450 + False = 0 + True = 1 ) -func main() { - rl.InitWindow(800, 450, "raylib [core] example - 3d camera first person") +var camModes = map[rl.CameraMode]string{ + rl.CameraFree: "FREE", + rl.CameraOrbital: "ORBITAL", + rl.CameraFirstPerson: "FIRST PERSON", + rl.CameraThirdPerson: "THIRD PERSON", +} +var camProjections = map[rl.CameraProjection]string{ + rl.CameraPerspective: "PERSPECTIVE", + rl.CameraOrthographic: "ORTHOGRAPHIC", +} + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person") + + // Define the camera to look into our 3d world (position, target, up vector) camera := rl.Camera3D{} - camera.Position = rl.NewVector3(4.0, 2.0, 4.0) - camera.Target = rl.NewVector3(0.0, 1.8, 0.0) - camera.Up = rl.NewVector3(0.0, 1.0, 0.0) - camera.Fovy = 60.0 - camera.Projection = rl.CameraPerspective + camera.Position = rl.NewVector3(0.0, 2.0, 4.0) // Camera position + camera.Target = rl.NewVector3(0.0, 2.0, 0.0) // Camera looking at point + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Camera up vector (rotation towards target) + camera.Fovy = 60.0 // Camera field-of-view Y + camera.Projection = rl.CameraPerspective // Camera projection type + + cameraMode := rl.CameraFirstPerson // Generates some random columns heights := make([]float32, maxColumns) @@ -24,15 +45,81 @@ func main() { colors := make([]rl.Color, maxColumns) for i := 0; i < maxColumns; i++ { - heights[i] = float32(rl.GetRandomValue(1, 12)) - positions[i] = rl.NewVector3(float32(rl.GetRandomValue(-15, 15)), heights[i]/2, float32(rl.GetRandomValue(-15, 15))) - colors[i] = rl.NewColor(uint8(rl.GetRandomValue(20, 255)), uint8(rl.GetRandomValue(10, 55)), 30, 255) + heights[i] = rndF(1, 12) + positions[i] = rl.NewVector3(rndF(-15, 15), heights[i]/2, rndF(-15, 15)) + colors[i] = rl.NewColor(rndU(20, 255), rndU(10, 55), 30, 255) } - rl.SetTargetFPS(60) + rl.DisableCursor() // Limit cursor to relative movement inside the window + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second - for !rl.WindowShouldClose() { - rl.UpdateCamera(&camera, rl.CameraFirstPerson) // Update camera with first person mode + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Switch camera mode + if rl.IsKeyPressed(rl.KeyOne) { + cameraMode = rl.CameraFree + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll + } + if rl.IsKeyPressed(rl.KeyTwo) { + cameraMode = rl.CameraFirstPerson + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll + } + if rl.IsKeyPressed(rl.KeyThree) { + cameraMode = rl.CameraThirdPerson + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll + } + if rl.IsKeyPressed(rl.KeyFour) { + cameraMode = rl.CameraOrbital + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll + } + + // Switch camera projection + if rl.IsKeyPressed(rl.KeyP) { + cameraMode = rl.CameraThirdPerson + if camera.Projection == rl.CameraPerspective { + // Create isometric view + // Note: The target distance is related to the render distance in the orthographic projection + camera.Position = rl.NewVector3(0.0, 2.0, -100.0) + camera.Target = rl.NewVector3(0.0, 2.0, 0.0) + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) + camera.Projection = rl.CameraOrthographic + camera.Fovy = 20.0 // near plane width in CAMERA_ORTHOGRAPHIC + rl.CameraYaw(&camera, -135*rl.Deg2rad, True) + rl.CameraPitch(&camera, -45*rl.Deg2rad, True, True, False) + } else if camera.Projection == rl.CameraOrthographic { + // Reset to default view + camera.Position = rl.NewVector3(0.0, 2.0, 10.0) + camera.Target = rl.NewVector3(0.0, 2.0, 0.0) + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) + camera.Projection = rl.CameraPerspective + camera.Fovy = 60.0 + } + } + + // Update camera computes movement internally depending on the camera mode. + // Some default standard keyboard/mouse inputs are hardcoded to simplify use. + // For advance camera controls, it's recommended to compute camera movement manually. + rl.UpdateCamera(&camera, cameraMode) // Update camera + + /* + // Camera PRO usage example (EXPERIMENTAL) + // This new camera function allows custom movement/rotation values to be directly provided + // as input parameters, with this approach, rcamera module is internally independent of raylib inputs + UpdateCameraPro(&camera, + (Vector3){ + (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward + (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, + (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left + (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, + 0.0f // Move up-down + }, + (Vector3){ + GetMouseDelta().x*0.05f, // Rotation: yaw + GetMouseDelta().y*0.05f, // Rotation: pitch + 0.0f // Rotation: roll + }, + GetMouseWheelMove()*2.0f); // Move to target (zoom) + */ rl.BeginDrawing() @@ -51,17 +138,57 @@ func main() { rl.DrawCubeWires(positions[i], 2.0, heights[i], 2.0, rl.Maroon) } + // Draw player cube + if cameraMode == rl.CameraThirdPerson { + rl.DrawCube(camera.Target, 0.5, 0.5, 0.5, rl.Purple) + rl.DrawCubeWires(camera.Target, 0.5, 0.5, 0.5, rl.DarkPurple) + } + rl.EndMode3D() - rl.DrawRectangle(10, 10, 220, 70, rl.Fade(rl.SkyBlue, 0.5)) - rl.DrawRectangleLines(10, 10, 220, 70, rl.Blue) + // Draw info boxes + rl.DrawRectangle(5, 5, 330, 100, rl.Fade(rl.SkyBlue, 0.5)) + rl.DrawRectangleLines(5, 5, 330, 100, rl.Blue) - rl.DrawText("First person camera default controls:", 20, 20, 10, rl.Black) - rl.DrawText("- Move with keys: W, A, S, D", 40, 40, 10, rl.DarkGray) - rl.DrawText("- Mouse move to look around", 40, 60, 10, rl.DarkGray) + rl.DrawText("Camera controls:", 15, 15, 10, rl.Black) + rl.DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, rl.Black) + rl.DrawText("- Look around: arrow keys or mouse", 15, 45, 10, rl.Black) + rl.DrawText("- Camera mode keys: 1,2,3,4", 15, 60, 10, rl.Black) + rl.DrawText("- Zoom keys: num-plus, num-minus or mouse scroll", 15, 75, 10, rl.Black) + rl.DrawText("- Camera projection key: P", 15, 90, 10, rl.Black) + + rl.DrawRectangle(600, 5, 195, 100, rl.Fade(rl.SkyBlue, 0.5)) + rl.DrawRectangleLines(600, 5, 195, 100, rl.Blue) + + rl.DrawText("Camera status:", 610, 15, 10, rl.Black) + rl.DrawText(s2T("Mode:", camModes[cameraMode]), 610, 30, 10, rl.Black) + rl.DrawText(s2T("Projection:", camProjections[camera.Projection]), 610, 45, 10, rl.Black) + rl.DrawText(s2T("Position:", v2T(camera.Position)), 610, 60, 10, rl.Black) + rl.DrawText(s2T("Target:", v2T(camera.Target)), 610, 75, 10, rl.Black) + rl.DrawText(s2T("Up:", v2T(camera.Up)), 610, 90, 10, rl.Black) rl.EndDrawing() } rl.CloseWindow() } + +// rndU generates a random uint8 value between min and max +func rndU(min, max int32) uint8 { + return uint8(rl.GetRandomValue(min, max)) +} + +// rndF generates a random float32 value between min and max +func rndF(min, max int32) float32 { + return float32(rl.GetRandomValue(min, max)) +} + +// s2t generates a Status item string from a name and value +func s2T(name, value string) string { + return fmt.Sprintf(" - %s %s", name, value) +} + +// v2T generates a string from a rl.Vector3 +func v2T(v rl.Vector3) string { + return fmt.Sprintf("%6.3f, %6.3f, %6.3f", v.X, v.Y, v.Z) +} From e43e3885497f552b22f6a3a6161240c73852ec7f Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Mon, 14 Oct 2024 17:15:36 +0200 Subject: [PATCH 103/278] Removed erroneous instructions --- examples/core/3d_camera_free/main.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/core/3d_camera_free/main.go b/examples/core/3d_camera_free/main.go index dd48372..95689b1 100644 --- a/examples/core/3d_camera_free/main.go +++ b/examples/core/3d_camera_free/main.go @@ -44,8 +44,6 @@ func main() { rl.DrawText("Free camera default controls:", 20, 20, 10, rl.Black) rl.DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, rl.DarkGray) rl.DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, rl.DarkGray) - rl.DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 80, 10, rl.DarkGray) - rl.DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, rl.DarkGray) rl.DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, rl.DarkGray) rl.EndDrawing() From 5bf50a5c5bff230a0d2d8c4fb90184ed0c991387 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Mon, 14 Oct 2024 18:17:15 +0200 Subject: [PATCH 104/278] Synced up another raylib-go example with raylib:s example --- examples/core/3d_camera_splitscreen/main.go | 61 ++++++++++----------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/examples/core/3d_camera_splitscreen/main.go b/examples/core/3d_camera_splitscreen/main.go index dd34697..22181d1 100644 --- a/examples/core/3d_camera_splitscreen/main.go +++ b/examples/core/3d_camera_splitscreen/main.go @@ -7,7 +7,6 @@ import ( var ( screenW = int32(800) screenH = int32(450) - playerSize = float32(40) cam1, cam2 rl.Camera3D ) @@ -15,67 +14,63 @@ func main() { rl.InitWindow(screenW, screenH, "raylib [core] example - 3d camera split screen") + // Setup player 1 camera and screen cam1.Fovy = 45 cam1.Up.Y = 1 cam1.Target.Y = 1 cam1.Position.Z = -3 - cam1.Position.Y = 0.5 + cam1.Position.Y = 1 - cam2 = cam1 - cam1.Position.Z = 3 + // Setup player two camera and screen + cam2.Fovy = 45 + cam2.Up.Y = 1 + cam2.Target.Y = 3 + cam2.Position.X = -3 + cam2.Position.Y = 3 screenCam1 := rl.LoadRenderTexture(screenW/2, screenH) screenCam2 := rl.LoadRenderTexture(screenW/2, screenH) splitScreenRec := rl.NewRectangle(0, 0, float32(screenCam1.Texture.Width), -float32(screenCam1.Texture.Height)) - count := 5 + count := float32(5) spacing := float32(4) rl.SetTargetFPS(60) for !rl.WindowShouldClose() { - + // If anyone moves this frame, how far will they move based on the time + // since the last frame this moves things at 10 world units per second, + // regardless of the actual FPS frameOffset := 10 * rl.GetFrameTime() + // Move Player1 forward and backwards (no turning) if rl.IsKeyDown(rl.KeyW) { - cam1.Position.Z -= frameOffset - cam1.Target.Z -= frameOffset - } else if rl.IsKeyDown(rl.KeyS) { cam1.Position.Z += frameOffset cam1.Target.Z += frameOffset - } - if rl.IsKeyDown(rl.KeyD) { - cam1.Position.X += frameOffset - cam1.Target.X += frameOffset - } else if rl.IsKeyDown(rl.KeyA) { - cam1.Position.X -= frameOffset - cam1.Target.X -= frameOffset + } else if rl.IsKeyDown(rl.KeyS) { + cam1.Position.Z -= frameOffset + cam1.Target.Z -= frameOffset } + // Move Player2 forward and backwards (no turning) if rl.IsKeyDown(rl.KeyUp) { - cam2.Position.Z += frameOffset - cam2.Target.Z += frameOffset - } else if rl.IsKeyDown(rl.KeyDown) { - cam2.Position.Z -= frameOffset - cam2.Target.Z -= frameOffset - } - if rl.IsKeyDown(rl.KeyRight) { - cam2.Position.X -= frameOffset - cam2.Target.X -= frameOffset - } else if rl.IsKeyDown(rl.KeyLeft) { cam2.Position.X += frameOffset cam2.Target.X += frameOffset + } else if rl.IsKeyDown(rl.KeyDown) { + cam2.Position.X -= frameOffset + cam2.Target.X -= frameOffset } + // Draw Player1 view to the render texture rl.BeginTextureMode(screenCam1) rl.ClearBackground(rl.SkyBlue) rl.BeginMode3D(cam1) rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige) - for x := -float32(count) * spacing; x <= float32(count)*spacing; x += spacing { - for z := -float32(count) * spacing; z <= float32(count)*spacing; z += spacing { + for x := -count * spacing; x <= count*spacing; x += spacing { + for z := -count * spacing; z <= count*spacing; z += spacing { rl.DrawCube(rl.NewVector3(x-0.5, 1.5, z), 1, 1, 1, rl.Lime) rl.DrawCube(rl.NewVector3(x-0.5, 0.5, z), 0.25, 1, 0.25, rl.Brown) } @@ -87,17 +82,18 @@ func main() { rl.EndMode3D() rl.DrawRectangle(0, 0, screenW/2, 40, rl.Fade(rl.RayWhite, 0.8)) - rl.DrawText("PLAYER 1 WASD KEYS", 10, 10, 20, rl.Maroon) + rl.DrawText("PLAYER1: W/S to move", 10, 10, 20, rl.Maroon) rl.EndTextureMode() + // Draw Player2 view to the render texture rl.BeginTextureMode(screenCam2) rl.ClearBackground(rl.SkyBlue) rl.BeginMode3D(cam2) rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige) - for x := -float32(count) * spacing; x <= float32(count)*spacing; x += spacing { - for z := -float32(count) * spacing; z <= float32(count)*spacing; z += spacing { + for x := -count * spacing; x <= count*spacing; x += spacing { + for z := -count * spacing; z <= count*spacing; z += spacing { rl.DrawCube(rl.NewVector3(x, 1.5, z), 1, 1, 1, rl.Lime) rl.DrawCube(rl.NewVector3(x, 0.5, z), 0.25, 1, 0.25, rl.Brown) } @@ -109,9 +105,10 @@ func main() { rl.EndMode3D() rl.DrawRectangle(0, 0, screenW/2, 40, rl.Fade(rl.RayWhite, 0.8)) - rl.DrawText("PLAYER 2 ARROW KEYS", 10, 10, 20, rl.Maroon) + rl.DrawText("PLAYER2: UP/DOWN to move", 10, 10, 20, rl.Maroon) rl.EndTextureMode() + // Draw both views render textures to the screen side by side rl.BeginDrawing() rl.ClearBackground(rl.Black) From afe70ad4c892e3b06c4640c90fbbc6add95a5943 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Tue, 15 Oct 2024 15:18:58 +0200 Subject: [PATCH 105/278] New example : 2d camera platform --- examples/core/2d_camera_platformer/main.go | 261 +++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 examples/core/2d_camera_platformer/main.go diff --git a/examples/core/2d_camera_platformer/main.go b/examples/core/2d_camera_platformer/main.go new file mode 100644 index 0000000..a6286ad --- /dev/null +++ b/examples/core/2d_camera_platformer/main.go @@ -0,0 +1,261 @@ +package main + +import rl "github.com/gen2brain/raylib-go/raylib" + +const ( + screenWidth = 800 + screenHeight = 450 + gravity = 400 + playerJumpSpeed = 350.0 + playerHORSpeed = 200.0 +) + +type Player struct { + position rl.Vector2 + speed float32 + canJump bool +} + +type EnvironmentItem struct { + rect rl.Rectangle + blocking bool + color rl.Color +} + +type cameraUpdater func(*rl.Camera2D, *Player, []EnvironmentItem, float32) + +// These 3 variables are used only for camera 4, +// but they need to be declared on module level +// for camera 4 to work (static in C) +var eveningOut = false +var evenOutSpeed float32 = 700 +var evenOutTarget float32 = 0 + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera platformer") + + player := Player{ + position: rl.NewVector2(400, 280), + speed: 0, + canJump: false, + } + + envItems := []EnvironmentItem{ + {rect: rl.Rectangle{Width: 1000, Height: 400}, blocking: false, color: rl.LightGray}, + {rect: rl.Rectangle{Y: 400, Width: 1000, Height: 200}, blocking: true, color: rl.Gray}, + {rect: rl.Rectangle{X: 300, Y: 200, Width: 400, Height: 10}, blocking: true, color: rl.Gray}, + {rect: rl.Rectangle{X: 250, Y: 300, Width: 100, Height: 10}, blocking: true, color: rl.Gray}, + {rect: rl.Rectangle{X: 650, Y: 300, Width: 100, Height: 10}, blocking: true, color: rl.Gray}, + } + + camera := rl.Camera2D{ + Offset: rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2}, + Target: player.position, + Rotation: 0, + Zoom: 1, + } + + cameraUpdaters := []cameraUpdater{ + updateCameraCenter, + updateCameraCenterInsideMap, + updateCameraCenterSmoothFollow, + updateCameraEvenOutOnLanding, + updateCameraPlayerBoundsPush, + } + cameraDescriptions := []string{ + "1. Follow player center", + "2. Follow player center, but clamp to map edges", + "3. Follow player center; smoothed", + "4. Follow player center horizontally; update player center vertically after landing", + "5. Player push camera on getting too close to screen edge", + } + + cameraOption := 0 + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + deltaTime := rl.GetFrameTime() + + updatePlayer(&player, envItems, deltaTime) + + camera.Zoom += rl.GetMouseWheelMove() * 0.05 + + camera.Zoom = clamp(camera.Zoom, 0.25, 3) + + if rl.IsKeyPressed(rl.KeyC) { + cameraOption = (cameraOption + 1) % len(cameraUpdaters) + } + // Call update camera function by its pointer + cameraUpdaters[cameraOption](&camera, &player, envItems, deltaTime) + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + rl.BeginMode2D(camera) + + for _, item := range envItems { + rl.DrawRectangleRec(item.rect, item.color) + } + + playerRect := rl.Rectangle{ + X: player.position.X - 20, + Y: player.position.Y - 40, + Width: 40, + Height: 40, + } + rl.DrawRectangleRec(playerRect, rl.Red) + rl.DrawCircleV(player.position, 5, rl.Gold) + + rl.EndMode2D() + + rl.DrawText("Controls:", 20, 20, 10, rl.Black) + rl.DrawText(" - Right/Left to move", 40, 40, 10, rl.DarkGray) + rl.DrawText(" - Space to jump", 40, 60, 10, rl.DarkGray) + rl.DrawText(" - Mouse Wheel to Zoom in-out, R to reset zoom", 40, 80, 10, rl.DarkGray) + rl.DrawText(" - C to change camera mode", 20, 100, 10, rl.Black) + rl.DrawText("Current Camera Mode:", 20, 120, 10, rl.DarkGray) + rl.DrawText(cameraDescriptions[cameraOption], 40, 140, 10, rl.DarkGray) + + rl.EndDrawing() + } + rl.CloseWindow() +} + +func updatePlayer(player *Player, envItems []EnvironmentItem, delta float32) { + if rl.IsKeyDown(rl.KeyLeft) { + player.position.X -= playerHORSpeed * delta + } + if rl.IsKeyDown(rl.KeyRight) { + player.position.X += playerHORSpeed * delta + } + if rl.IsKeyDown(rl.KeySpace) && player.canJump { + player.speed = -playerJumpSpeed + player.canJump = false + } + + hitObstacle := false + for _, item := range envItems { + if item.blocking && + item.rect.X <= player.position.X && item.rect.X+item.rect.Width >= player.position.X && + item.rect.Y >= player.position.Y && item.rect.Y <= player.position.Y+player.speed*delta { + hitObstacle = true + player.speed = 0 + player.position.Y = item.rect.Y + break + } + } + + if !hitObstacle { + player.position.Y += player.speed * delta + player.speed += gravity * delta + player.canJump = false + } else { + player.canJump = true + } +} + +func updateCameraCenter(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, _ float32) { + camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2} + camera.Target = player.position +} + +func updateCameraCenterInsideMap(camera *rl.Camera2D, player *Player, envItems []EnvironmentItem, _ float32) { + camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2} + camera.Target = player.position + + var minX, minY, maxX, maxY float32 = 1000, 1000, -1000, -10000 + + for _, item := range envItems { + minX = min(item.rect.X, minX) + maxX = max(item.rect.X+item.rect.Width, maxX) + minY = min(item.rect.Y, minY) + maxY = max(item.rect.Y+item.rect.Height, maxY) + } + + maxV := rl.GetWorldToScreen2D(rl.Vector2{X: maxX, Y: maxY}, *camera) + minV := rl.GetWorldToScreen2D(rl.Vector2{X: minX, Y: minY}, *camera) + + if maxV.X < screenWidth { + camera.Offset.X = screenWidth - (maxV.X - screenWidth/2) + } + if maxV.Y < screenHeight { + camera.Offset.Y = screenHeight - (maxV.Y - screenHeight/2) + } + if minV.X > 0 { + camera.Offset.X = screenWidth/2 - minV.X + } + if minV.Y > 0 { + camera.Offset.Y = screenHeight/2 - minV.Y + } +} + +func updateCameraCenterSmoothFollow(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, delta float32) { + var minSpeed, minEffectLength, fractionSpeed float32 = 30.0, 10.0, 0.8 + + camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2} + diff := rl.Vector2Subtract(player.position, camera.Target) + length := rl.Vector2Length(diff) + + if length > minEffectLength { + speed := max(fractionSpeed*length, minSpeed) + camera.Target = rl.Vector2Add(camera.Target, rl.Vector2Scale(diff, speed*delta/length)) + } +} + +func updateCameraEvenOutOnLanding(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, delta float32) { + camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2} + camera.Target.X = player.position.X + + if eveningOut { + if evenOutTarget > camera.Target.Y { + camera.Target.Y += evenOutSpeed * delta + if camera.Target.Y > evenOutTarget { + camera.Target.Y = evenOutTarget + eveningOut = false + } + } else { + camera.Target.Y -= evenOutSpeed * delta + if camera.Target.Y < evenOutTarget { + camera.Target.Y = evenOutTarget + eveningOut = false + } + } + } else { + if player.canJump && player.speed == 0 && player.position.Y != camera.Target.Y { + eveningOut = true + evenOutTarget = player.position.Y + } + } +} + +func updateCameraPlayerBoundsPush(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, _ float32) { + bbox := rl.Vector2{X: 0.2, Y: 0.2} + + bboxWorldMin := rl.GetScreenToWorld2D(rl.Vector2{X: (1 - bbox.X) * 0.5 * screenWidth, Y: (1 - bbox.Y) * 0.5 * screenHeight}, *camera) + bboxWorldMax := rl.GetScreenToWorld2D(rl.Vector2{X: (1 + bbox.X) * 0.5 * screenWidth, Y: (1 + bbox.Y) * 0.5 * screenHeight}, *camera) + camera.Offset = rl.Vector2{X: (1 - bbox.X) * 0.5 * screenWidth, Y: (1 - bbox.Y) * 0.5 * screenHeight} + + if player.position.X < bboxWorldMin.X { + camera.Target.X = player.position.X + } + if player.position.Y < bboxWorldMin.Y { + camera.Target.Y = player.position.Y + } + if player.position.X > bboxWorldMax.X { + camera.Target.X = bboxWorldMin.X + (player.position.X - bboxWorldMax.X) + } + if player.position.Y > bboxWorldMax.Y { + camera.Target.Y = bboxWorldMin.Y + (player.position.Y - bboxWorldMax.Y) + } +} + +func clamp(zoom float32, min float32, max float32) float32 { + if zoom < min { + return min + } + if zoom > max { + return max + } + return zoom +} From 4e4f18a37c665fb41b7402e515d02b9a92c1c7c2 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Tue, 15 Oct 2024 15:19:15 +0200 Subject: [PATCH 106/278] New example : Window should close --- examples/core/window_should_close/main.go | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/core/window_should_close/main.go diff --git a/examples/core/window_should_close/main.go b/examples/core/window_should_close/main.go new file mode 100644 index 0000000..19324d1 --- /dev/null +++ b/examples/core/window_should_close/main.go @@ -0,0 +1,47 @@ +package main + +import rl "github.com/gen2brain/raylib-go/raylib" + +const ( + screenWidth = 850 + screenHeight = 480 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - window should close") + + rl.SetExitKey(rl.KeyNull) // Disable KEY_ESCAPE to close window, X-button still works + + exitWindowRequested := false // Flag to request window to exit + exitWindow := false // Flag to set window to exit + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !exitWindow { + if rl.WindowShouldClose() || rl.IsMouseButtonPressed(rl.KeyEscape) { + exitWindowRequested = true + } + + if exitWindowRequested { + if rl.IsKeyPressed(rl.KeyY) { + exitWindow = true + } else if rl.IsKeyPressed(rl.KeyN) { + exitWindowRequested = false + } + } + + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + if exitWindowRequested { + rl.DrawRectangle(0, 100, screenWidth, 200, rl.Black) + rl.DrawText("Are you sure you want to exit the program? [Y/N]", 40, 180, 30, rl.White) + } else { + rl.DrawText("Try to close the window to get confirmation message!", 120, 200, 20, rl.LightGray) + } + + rl.EndDrawing() + } + + rl.CloseWindow() // Close window and OpenGL context +} From 10a7b71ee0cf1a1ff94c39bbd409662e45db6e71 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Tue, 15 Oct 2024 16:10:41 +0200 Subject: [PATCH 107/278] New example : Custom Logging --- examples/core/custom_logging/main.go | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 examples/core/custom_logging/main.go diff --git a/examples/core/custom_logging/main.go b/examples/core/custom_logging/main.go new file mode 100644 index 0000000..785590e --- /dev/null +++ b/examples/core/custom_logging/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "time" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + // Set custom logger + rl.SetTraceLogCallback(customLog) + + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Custom Logging") + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + rl.DrawText("Check the console output to see the custom logger in action!", 60, 200, 20, rl.LightGray) + rl.EndDrawing() + } + + rl.CloseWindow() +} + +// Custom logging function +func customLog(msgType int, text string) { + now := time.Now() + + switch rl.TraceLogLevel(msgType) { + case rl.LogInfo: + fmt.Println("[INFO] : ", now, text) + case rl.LogError: + fmt.Println("[ERROR] : ", now, text) + case rl.LogWarning: + fmt.Println("[WARNING] : ", now, text) + case rl.LogDebug: + fmt.Println("[DEBUG] : ", now, text) + default: + fmt.Println("[UNKNOWN] : ", now, text) + } +} From c2b8b9ee3a0894dce2e8edd93740e625f8b3519d Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Tue, 15 Oct 2024 17:09:11 +0200 Subject: [PATCH 108/278] New example : Custom Frame Control --- examples/core/custom_frame_control/main.go | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 examples/core/custom_frame_control/main.go diff --git a/examples/core/custom_frame_control/main.go b/examples/core/custom_frame_control/main.go new file mode 100644 index 0000000..7dfc374 --- /dev/null +++ b/examples/core/custom_frame_control/main.go @@ -0,0 +1,131 @@ +package main + +/******************************************************************************************* +* +* raylib [core] example - custom frame control +* +* NOTE: WARNING: This is an example for advanced users willing to have full control over +* the frame processes. By default, EndDrawing() calls the following processes: +* 1. Draw remaining batch data: rlDrawRenderBatchActive() +* 2. SwapScreenBuffer() +* 3. Frame time control: WaitTime() +* 4. PollInputEvents() +* +* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in +* config.h (it requires recompiling raylib). This way those steps are up to the user. +* +* Note that enabling this flag invalidates some functions: +* - GetFrameTime() +* - SetTargetFPS() +* - GetFPS() +* +* Example originally created with raylib 4.0, last time updated with raylib 4.0 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2021-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Custom Frame Control") + + previousTime := rl.GetTime() + currentTime := 0.0 + updateDrawTime := 0.0 + waitTime := 0.0 + deltaTime := 0.0 + + timeCounter := 0.0 + position := 0.0 + pause := false + + targetFPS := 60 + + for !rl.WindowShouldClose() { + rl.PollInputEvents() // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL) + + if rl.IsKeyPressed(rl.KeySpace) { + pause = !pause + } + if rl.IsKeyPressed(rl.KeyUp) { + targetFPS += 20 + } else if rl.IsKeyPressed(rl.KeyDown) { + targetFPS -= 20 + } + + if targetFPS < 0 { + targetFPS = 0 + } + + if !pause { + position += 200 * deltaTime // We move at 200 pixels per second + if position >= float64(rl.GetScreenWidth()) { + position = 0 + } + timeCounter += deltaTime // We count time (seconds) + } + + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + for i := 0; i < rl.GetScreenWidth()/200; i++ { + rl.DrawRectangle(200*int32(i), 0, 1, int32(rl.GetScreenHeight()), rl.SkyBlue) + } + + rl.DrawCircle(int32(position), int32(rl.GetScreenHeight()/2-25), 50, rl.Red) + + msg := fmt.Sprintf("%03.0f ms", timeCounter*1000) + rl.DrawText(msg, int32(position-40), int32(rl.GetScreenHeight()/2-100), 20, rl.Maroon) + msg = fmt.Sprintf("PosX: %03.0f", position) + rl.DrawText(msg, int32(position-50), int32(rl.GetScreenHeight()/2+40), 20, rl.Black) + + msg = "Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate." + rl.DrawText(msg, 10, 10, 20, rl.DarkGray) + msg = "PRESS SPACE to PAUSE MOVEMENT" + rl.DrawText(msg, 10, int32(rl.GetScreenHeight()-60), 20, rl.Gray) + msg = "PRESS UP | DOWN to CHANGE TARGET FPS" + rl.DrawText(msg, 10, int32(rl.GetScreenHeight()-30), 20, rl.Gray) + msg = fmt.Sprintf("TARGET FPS: %d", targetFPS) + rl.DrawText(msg, int32(rl.GetScreenWidth()-220), 10, 20, rl.Lime) + msg = fmt.Sprintf("CURRENT FPS: %d", int(1/deltaTime)) + rl.DrawText(msg, int32(rl.GetScreenWidth()-220), 40, 20, rl.Lime) + + rl.EndDrawing() + + // NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL, + // Events polling, screen buffer swap and frame time control must be managed by the user + + rl.SwapScreenBuffer() // We want a fixed frame rate + + currentTime = rl.GetTime() + updateDrawTime = currentTime - previousTime + + if targetFPS > 0 { // We want a fixed frame rate + waitTime = (1 / float64(targetFPS)) - updateDrawTime + if waitTime > 0 { + rl.WaitTime(waitTime) + currentTime = rl.GetTime() + deltaTime = currentTime - previousTime + } + } else { + deltaTime = updateDrawTime + } + + previousTime = currentTime + } + + rl.CloseWindow() +} From 1ff1eefdf15c0937c78fff00b68f74c36333ca15 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Wed, 16 Oct 2024 13:33:49 +0200 Subject: [PATCH 109/278] New example : Window letterbox --- examples/core/window_letterbox/main.go | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 examples/core/window_letterbox/main.go diff --git a/examples/core/window_letterbox/main.go b/examples/core/window_letterbox/main.go new file mode 100644 index 0000000..ef7518f --- /dev/null +++ b/examples/core/window_letterbox/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "fmt" + "image/color" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + // Enable config flags for resizable window and vertical synchro + rl.SetConfigFlags(rl.FlagWindowResizable | rl.FlagVsyncHint) + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Window Scale Letterbox") + rl.SetWindowMinSize(320, 240) + + gameScreenWidth, gameScreenHeight := int32(640), int32(480) + + // Render texture initialization, used to hold the rendering result so we can easily resize it + target := rl.LoadRenderTexture(gameScreenWidth, gameScreenHeight) + rl.SetTextureFilter(target.Texture, rl.FilterBilinear) // Texture scale filter to use + + colors := getRandomColors() + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Compute required frame buffer scaling + scale := min(float32(rl.GetScreenWidth())/float32(gameScreenWidth), + float32(rl.GetScreenHeight())/float32(gameScreenHeight)) + + if rl.IsKeyPressed(rl.KeySpace) { + // Recalculate random colors for the bars + colors = getRandomColors() + } + + // Update virtual mouse (clamped mouse value behind game screen) + mouse := rl.GetMousePosition() + virtualMouse := rl.Vector2{ + X: (mouse.X - (float32(rl.GetScreenWidth())-(float32(gameScreenWidth)*scale))*0.5) / scale, + Y: (mouse.Y - (float32(rl.GetScreenHeight())-(float32(gameScreenHeight)*scale))*0.5) / scale, + } + virtualMouse = rl.Vector2Clamp( + virtualMouse, + rl.Vector2{}, + rl.Vector2{X: float32(gameScreenWidth), Y: float32(gameScreenHeight)}, + ) + + // Apply the same transformation as the virtual mouse to the real mouse (i.e. to work with raygui) + //rl.SetMouseOffset( + // int(-(float32(rl.GetScreenWidth())-(float32(gameScreenWidth)*scale))*0.5), + // int(-(float32(rl.GetScreenHeight())-(float32(gameScreenHeight)*scale))*0.5), + //) + //rl.SetMouseScale(1/scale, 1/scale) + + // Draw everything in the render texture, note this will not be rendered on screen, yet + rl.BeginTextureMode(target) + + rl.ClearBackground(rl.White) + for i := int32(0); i < 10; i++ { + rl.DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]) + } + + text := "If executed inside a window,\nyou can resize the window,\nand see the screen scaling!" + rl.DrawText(text, 10, 25, 20, rl.White) + text = fmt.Sprintf("Default Mouse: [%.0f , %.0f]", mouse.X, mouse.Y) + rl.DrawText(text, 350, 25, 20, rl.Green) + text = fmt.Sprintf("Virtual Mouse: [%.0f , %.0f]", virtualMouse.X, virtualMouse.Y) + rl.DrawText(text, 350, 55, 20, rl.Yellow) + + rl.EndTextureMode() + + rl.BeginDrawing() + rl.ClearBackground(rl.Black) + // Draw render texture to screen, properly scaled + rl.DrawTexturePro( + target.Texture, + rl.Rectangle{Width: float32(target.Texture.Width), Height: float32(-target.Texture.Height)}, + rl.Rectangle{ + X: (float32(rl.GetScreenWidth()) - float32(gameScreenWidth)*scale) * 0.5, + Y: (float32(rl.GetScreenHeight()) - float32(gameScreenHeight)*scale) * 0.5, + Width: float32(gameScreenWidth) * scale, + Height: float32(gameScreenHeight) * scale, + }, + rl.Vector2{X: 0, Y: 0}, 0, rl.White, + ) + rl.EndDrawing() + } + rl.UnloadRenderTexture(target) + rl.CloseWindow() // Close window and OpenGL context +} + +func getRandomColors() []color.RGBA { + var colors []color.RGBA + + for i := 0; i < 10; i++ { + randomColor := color.RGBA{ + R: rndUint8(100, 250), + G: rndUint8(50, 150), + B: rndUint8(10, 100), + A: 255, + } + colors = append(colors, randomColor) + } + + return colors +} + +func rndUint8(min, max int32) uint8 { + return uint8(rl.GetRandomValue(min, max)) +} From d7bd66f339a84865c2f9a38f18041cd12342c23b Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Wed, 16 Oct 2024 15:41:18 +0200 Subject: [PATCH 110/278] New example : Window flags --- examples/core/window_flags/main.go | 260 +++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 examples/core/window_flags/main.go diff --git a/examples/core/window_flags/main.go b/examples/core/window_flags/main.go new file mode 100644 index 0000000..6e26ebe --- /dev/null +++ b/examples/core/window_flags/main.go @@ -0,0 +1,260 @@ +/******************************************************************************************* +* +* raylib [core] example - window flags +* +* Example originally created with raylib 3.5, last time updated with raylib 3.5 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2020-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +// Possible window flags +/* + FLAG_VSYNC_HINT + FLAG_FULLSCREEN_MODE -> not working properly -> wrong scaling! + FLAG_WINDOW_RESIZABLE + FLAG_WINDOW_UNDECORATED + FLAG_WINDOW_TRANSPARENT + FLAG_WINDOW_HIDDEN + FLAG_WINDOW_MINIMIZED -> Not supported on window creation + FLAG_WINDOW_MAXIMIZED -> Not supported on window creation + FLAG_WINDOW_UNFOCUSED + FLAG_WINDOW_TOPMOST + FLAG_WINDOW_HIGHDPI -> errors after minimize-resize, fb size is recalculated + FLAG_WINDOW_ALWAYS_RUN + FLAG_MSAA_4X_HINT +*/ + +func main() { + // Set configuration flags for window creation + //SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI); + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Window Flags") + + ballPosition := rl.Vector2{X: float32(rl.GetScreenWidth()) / 2.0, Y: float32(rl.GetScreenHeight()) / 2.0} + ballSpeed := rl.Vector2{X: 5.0, Y: 4.0} + ballRadius := float32(20.0) + framesCounter := 0 + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !rl.WindowShouldClose() { // Detect window close button or ESC key + if rl.IsKeyPressed(rl.KeyF) { + rl.ToggleFullscreen() // modifies window size when scaling! + } + + if rl.IsKeyPressed(rl.KeyR) { + if rl.IsWindowState(rl.FlagWindowResizable) { + rl.ClearWindowState(rl.FlagWindowResizable) + } else { + rl.SetWindowState(rl.FlagWindowResizable) + } + } + + if rl.IsKeyPressed(rl.KeyD) { + if rl.IsWindowState(rl.FlagWindowUndecorated) { + rl.ClearWindowState(rl.FlagWindowUndecorated) + } else { + rl.SetWindowState(rl.FlagWindowUndecorated) + } + } + + if rl.IsKeyPressed(rl.KeyH) { + if !rl.IsWindowState(rl.FlagWindowHidden) { + rl.SetWindowState(rl.FlagWindowHidden) + } + + framesCounter = 0 + } + + if rl.IsWindowState(rl.FlagWindowHidden) { + framesCounter++ + if framesCounter >= 240 { + rl.ClearWindowState(rl.FlagWindowHidden) // Show window after 3 seconds + } + } + + if rl.IsKeyPressed(rl.KeyN) { + if !rl.IsWindowState(rl.FlagWindowMinimized) { + rl.MinimizeWindow() + } + + framesCounter = 0 + } + + if rl.IsWindowState(rl.FlagWindowMinimized) { + framesCounter++ + if framesCounter >= 240 { + rl.RestoreWindow() // Restore window after 3 seconds + } + } + + if rl.IsKeyPressed(rl.KeyM) { + // NOTE: Requires FLAG_WINDOW_RESIZABLE enabled! + if rl.IsWindowState(rl.FlagWindowMaximized) { + rl.RestoreWindow() + } else { + rl.MaximizeWindow() + } + } + + if rl.IsKeyPressed(rl.KeyU) { + if rl.IsWindowState(rl.FlagWindowUnfocused) { + rl.ClearWindowState(rl.FlagWindowUnfocused) + } else { + rl.SetWindowState(rl.FlagWindowUnfocused) + } + } + + if rl.IsKeyPressed(rl.KeyT) { + if rl.IsWindowState(rl.FlagWindowTopmost) { + rl.ClearWindowState(rl.FlagWindowTopmost) + } else { + rl.SetWindowState(rl.FlagWindowTopmost) + } + } + + if rl.IsKeyPressed(rl.KeyA) { + if rl.IsWindowState(rl.FlagWindowAlwaysRun) { + rl.ClearWindowState(rl.FlagWindowAlwaysRun) + } else { + rl.SetWindowState(rl.FlagWindowAlwaysRun) + } + } + + if rl.IsKeyPressed(rl.KeyV) { + if rl.IsWindowState(rl.FlagVsyncHint) { + rl.ClearWindowState(rl.FlagVsyncHint) + } else { + rl.SetWindowState(rl.FlagVsyncHint) + } + } + + // Bouncing ball logic + ballPosition.X += ballSpeed.X + ballPosition.Y += ballSpeed.Y + if (ballPosition.X >= (float32(rl.GetScreenWidth()) - ballRadius)) || (ballPosition.X <= ballRadius) { + ballSpeed.X *= -1.0 + } + if (ballPosition.Y >= (float32(rl.GetScreenHeight()) - ballRadius)) || (ballPosition.Y <= ballRadius) { + ballSpeed.Y *= -1.0 + } + + rl.BeginDrawing() + if rl.IsWindowState(rl.FlagWindowTransparent) { + rl.ClearBackground(rl.Blank) + } else { + rl.ClearBackground(rl.White) + } + + rl.DrawCircleV(ballPosition, ballRadius, rl.Maroon) + rl.DrawRectangleLinesEx( + rl.Rectangle{ + Width: float32(rl.GetScreenWidth()), + Height: float32(rl.GetScreenHeight()), + }, + 4, rl.White, + ) + + rl.DrawCircleV(rl.GetMousePosition(), 10, rl.DarkBlue) + + rl.DrawFPS(10, 10) + + rl.DrawText( + fmt.Sprintf("Screen Size: [%d, %d]", rl.GetScreenWidth(), rl.GetScreenHeight()), + 10, + 40, + 10, + rl.Green, + ) + + // Draw window state info + rl.DrawText("Following flags can be set after window creation:", 10, 60, 10, rl.Gray) + if rl.IsWindowState(rl.FlagFullscreenMode) { + rl.DrawText("[F] FLAG_FULLSCREEN_MODE: on", 10, 80, 10, rl.Lime) + } else { + rl.DrawText("[F] FLAG_FULLSCREEN_MODE: off", 10, 80, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowResizable) { + rl.DrawText("[R] FLAG_WINDOW_RESIZABLE: on", 10, 100, 10, rl.Lime) + } else { + rl.DrawText("[R] FLAG_WINDOW_RESIZABLE: off", 10, 100, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowUndecorated) { + rl.DrawText("[D] FLAG_WINDOW_UNDECORATED: on", 10, 120, 10, rl.Lime) + } else { + rl.DrawText("[D] FLAG_WINDOW_UNDECORATED: off", 10, 120, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowHidden) { + rl.DrawText("[H] FLAG_WINDOW_HIDDEN: on", 10, 140, 10, rl.Lime) + } else { + rl.DrawText("[H] FLAG_WINDOW_HIDDEN: off", 10, 140, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowMinimized) { + rl.DrawText("[N] FLAG_WINDOW_MINIMIZED: on", 10, 160, 10, rl.Lime) + } else { + rl.DrawText("[N] FLAG_WINDOW_MINIMIZED: off", 10, 160, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowMaximized) { + rl.DrawText("[M] FLAG_WINDOW_MAXIMIZED: on", 10, 180, 10, rl.Lime) + } else { + rl.DrawText("[M] FLAG_WINDOW_MAXIMIZED: off", 10, 180, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowUnfocused) { + rl.DrawText("[G] FLAG_WINDOW_UNFOCUSED: on", 10, 200, 10, rl.Lime) + } else { + rl.DrawText("[U] FLAG_WINDOW_UNFOCUSED: off", 10, 200, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowTopmost) { + rl.DrawText("[T] FLAG_WINDOW_TOPMOST: on", 10, 220, 10, rl.Lime) + } else { + rl.DrawText("[T] FLAG_WINDOW_TOPMOST: off", 10, 220, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowAlwaysRun) { + rl.DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: on", 10, 240, 10, rl.Lime) + } else { + rl.DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: off", 10, 240, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagVsyncHint) { + rl.DrawText("[V] FLAG_VSYNC_HINT: on", 10, 260, 10, + rl.Lime) + } else { + rl.DrawText("[V] FLAG_VSYNC_HINT: off", 10, 260, 10, rl.Maroon) + } + + rl.DrawText("Following flags can only be set before window creation:", 10, 300, 10, rl.Gray) + if rl.IsWindowState(rl.FlagWindowHighdpi) { + rl.DrawText("FLAG_WINDOW_HIGHDPI: on", 10, 320, 10, rl.Lime) + } else { + rl.DrawText("FLAG_WINDOW_HIGHDPI: off", 10, 320, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagWindowTransparent) { + rl.DrawText("FLAG_WINDOW_TRANSPARENT: on", 10, 340, 10, rl.Lime) + } else { + rl.DrawText("FLAG_WINDOW_TRANSPARENT: off", 10, 340, 10, rl.Maroon) + } + if rl.IsWindowState(rl.FlagMsaa4xHint) { + rl.DrawText("FLAG_MSAA_4X_HINT: on", 10, 360, 10, rl.Lime) + } else { + rl.DrawText("FLAG_MSAA_4X_HINT: off", 10, 360, 10, rl.Maroon) + } + + rl.EndDrawing() + } + rl.CloseWindow() +} From 5bed8af6d468926469eddf21ed993302eb052226 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 17 Oct 2024 08:12:14 +0200 Subject: [PATCH 111/278] New example : Audio/sound_multi --- examples/audio/sound_multi/main.go | 65 +++++++++++++++++++++++++++ examples/audio/sound_multi/sound.wav | Bin 0 -> 97512 bytes 2 files changed, 65 insertions(+) create mode 100644 examples/audio/sound_multi/main.go create mode 100644 examples/audio/sound_multi/sound.wav diff --git a/examples/audio/sound_multi/main.go b/examples/audio/sound_multi/main.go new file mode 100644 index 0000000..b91485c --- /dev/null +++ b/examples/audio/sound_multi/main.go @@ -0,0 +1,65 @@ +/******************************************************************************************* +* +* raylib [audio] example - Playing sound multiple times +* +* Example originally created with raylib 4.6 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2023 Jeffery Myers (@JeffM2501) +* +********************************************************************************************/ +package main + +import rl "github.com/gen2brain/raylib-go/raylib" + +const ( + screenWidth = 800 + screenHeight = 450 + maxSounds = 10 +) + +var soundArray [maxSounds]rl.Sound +var currentSound int32 + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [audio] example - playing sound multiple times") + + // Initialize audio device + rl.InitAudioDevice() + + // Load WAV audio file into the first slot as the 'source' sound + // this sound owns the sample data + soundArray[0] = rl.LoadSound("sound.wav") + + for i := 1; i < maxSounds; i++ { + // Load an alias of the sound into slots 1-9. + // These do not own the sound data, but can be played + soundArray[i] = rl.LoadSoundAlias(soundArray[0]) + } + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !rl.WindowShouldClose() { // Detect window close button or ESC key + if rl.IsKeyPressed(rl.KeySpace) { + rl.PlaySound(soundArray[currentSound]) // play the next open sound slot + currentSound++ // increment the sound slot + if currentSound >= maxSounds { // if the sound slot is out of bounds, go back to 0 + currentSound = 0 + } + + // Note: a better way would be to look at the list for the first sound that is not playing and use that slot + } + + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + rl.DrawText("Press SPACE to PLAY a WAV sound!", 200, 180, 20, rl.LightGray) + rl.EndDrawing() + } + + rl.UnloadSound(soundArray[0]) // Unload source sound data + rl.CloseAudioDevice() // Close audio device + + rl.CloseWindow() // Close window and OpenGL context +} diff --git a/examples/audio/sound_multi/sound.wav b/examples/audio/sound_multi/sound.wav new file mode 100644 index 0000000000000000000000000000000000000000..b5d01c9b3a928d211a15d959f62b45a4e80ed457 GIT binary patch literal 97512 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 Y{PQKzN5YHCSLj;JnG$a)_W$4i07a?8Q~&?~ literal 0 HcmV?d00001 From a9a0a28119905d6533d17c9f8440f28fb14bfc48 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 17 Oct 2024 11:04:50 +0200 Subject: [PATCH 112/278] New example : Audio/mixed processor --- examples/audio/mixed_processor/coin.wav | Bin 0 -> 18114 bytes examples/audio/mixed_processor/country.mp3 | Bin 0 -> 1497964 bytes examples/audio/mixed_processor/main.go | 155 +++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 examples/audio/mixed_processor/coin.wav create mode 100644 examples/audio/mixed_processor/country.mp3 create mode 100644 examples/audio/mixed_processor/main.go diff --git a/examples/audio/mixed_processor/coin.wav b/examples/audio/mixed_processor/coin.wav new file mode 100644 index 0000000000000000000000000000000000000000..ad95bfb55a2e50da93fdb1e639b4635dfcc2b463 GIT binary patch literal 18114 zcmds6it(nIp@%ldd7o+ z7mEc9|0%!cRux$!ixMfRXU4w74DNaQ)qBn@0TNYp4qIxfs(!5c@S*cB9UsRhP5<)G zA3l8e1782y@qzvKhY$bsVQknmoP=hvaM>1ZSc?nXqCFNLF50+z1`k87tO|10j~p!opeFW6fKv(|FB$-5xBrb(*b39}Arp7FnG>kJsb%+RW1y zEUT9-&m0%dEqQ$ap6Mye)YO#4=J)!rTxJ9aU4DvuHlxKnWuBT|V#_yYoHAq0E&C|; zPMIh&+k!s-lHcz(noU?{cL0IkZ`YZP2rbLY6!~ZM2#v2x#EU>G1^(CD;y*%E-`q>a}hrE!QG`LAS~IE9Xl$uaG!l*YRGLXF?NTBV#d65CYJ`SZjG~Bj zLZhBktF5U>EE zwOlcQmwh9aPNq`JGQ|XzD!7_Rr&1~BkZOEFKA}mcQ+OpUBT9sF%X%`CPN(B4*~GY9 zF1K$bR??YtU{pRXA0JnQ)>8;G&H;rC;pECn1}kM5oERG)`KbKI{ZCI{zg{(bSN%iP z$7<*QT>t0e*Qd=tSAVRks;b-h+x?G^PfxyoYxwJ@k5wICzdk-aKHaPTSog!Hs%rJ$ z@4h}fJzh3`UsF|GUE}=ks~^8SK5YD@rutL$r-tocZl4hP{=M-dKKwkpBn1w>lz$?JH5ZYy;-eBRA1k^{`KPa`sT*_ z=eEy{^$oqZH`h1U*B9FFTWb+&emcLsy1qW{_}odDA`f8=7siCp4v2E?~ z{O0oN%JW@&T~lLI|Mk`7)#c@x_J{WR=Ef%N)9Lla<>g^#T}xwgQ?ujeqnq=~i%e}x z6QYjQFQ-@M7Z;xII~!V>n+Gm05nP<;syZ55np?CFCzodz=Lg*lZOtt$t&SfLug=cT z()DdEtu3uxD|g2i2t6OWn*avS&(E-q^)+41ZLMv(`=j&Iv(vqvruNphwsyzU{>91Z zX{xcK4XZnIb9i=gdg7_>Y3XQdA3i-j!8+8}_Oy1ix9e{YPLEHHcl%m8+dDcs9S^%_ zM<>V0W{Ns`)0YP)N5@C*&wXuO9i1b`$46NEhWg(2uFg*V_5ShU(b0B)TX$zyXSd^S z=j7n%Fwu&rtE)eCzISwRc<8R{@96I89z8ldI6OGmGc@*h_H=a{E_M(14-U2lJ9@i& zx_cZqTSt2b`|)-}Jv{@-)18C8{e5@CU{`NXkL+N753e0#%RqN;Pp|Q8dw*|lZ)2#d zucx=S&wjaiu)DV#>+J9C>+Ks#9B=RK?(VvphkN?_`o{NmcMxrv+J<`j`}&P1TYEdZ zJL@Ao1AYDd1NQUvz3rWyX!k(>K!5*m{BUz;duQ9#I?^}TKOo=P*~Z#1b&T{64h)!% zHg>kQw^qmch6V-)hwP_oJDXcuk=~&}tkKy1`u675rmJIYU}$h?Vry#?Yu(&6IygKu zWZGZb+SuG!kqwLt4G$07k5;zUH#frlBM63N(cQJp^^FZzmuzTcctp9ev5vKB?v)LX zj*OUhS2xzy*VFQ$(Gk4t2kDKqjAlSKGOAi%Ut3#S>X(g-joJ6p>#G^w+`f&U=7rw)A)m$aN%j-nir_RC3x(@2@aqk0OwxHKzX`?}=nA5e5#czgq<$28O@$a9QYLvglS=U3 z?}{fT@J%cB2HuSGnBI|K(J5bz`L{KNCX#qeA;R)(%9n5o1xl#j1E*l3EcON-{r%x& zLN8n@ae;(UtcKoc3UzP9)87=wrBm{l3SpHf@P-(bl*BTnT%jpe%ajueZMoRMtMRs* zzG;*a@4@5w7;n|zhLheg6jfyM9ylp&@(iZGJnZXvrzG{SfKv(K!qQ(s*_6*=RHdaq zkqXom;qk26Bb<^_GECOVXRuOK2(Kc<;67>v5vkM3+n^zBN|UHObX2q~vjuKV?ab`cQX~Iv>Yl205<1j!q*|$799{ zG4e>65GLz{XI!X+yvxBV6%Lli4QHhdF-U-L0 zz25`JrA=};B0kQmaRS$5g1;srlNT}F8uG9kL$=jOPW>E~(`_W%N+b~zQZjWR)+Z{$ zB#wLXOpu4WcU6FeTUyUx+!EspoD`{Xb1a9|S?_W&ZmA(Dv8BoBJbDY zn6ybgHYxa&FX2oi9*c<8R4eW^R)%qBQZT_S%9w{Yc_Y@aO2YAIzPBWHPZVM*Bvu|) ztMyW9X{-@p+_k0KvQ%J6Jel>*Q$K@o(-(E;s|~m}Tp^C~CTXESc7r*VkCn*7yu~sF>GN}Z|q}A_?>2`Uxz?}EH<51R{tg|UYu?T-ncucqPZRzJR?(<8jU&eSs zko6X+@mK**6}U>Iv363EO({}KVzY|FcrM{qV#|BK7DuE_D#DSRIvNRQD=7zuq}9)2 zBc8zId2?zbQE?@|0;Y^Y$|N2f@hJ;%n6O5J2TytG^01B`N+pBQ0<|<&iLg4C5?HI{ zO-f^WGDZdFsqvMiF`lDIsVl`{X_Fj|;P7g$5ba4AfeM{8s1DK#E@8aZ_qhk~UrJtWPl@wk*speAe*Oe(^9X|)~?Y9+imjOVp1 zrA|m$jPXF%r7i5&L%!3Q@@A<+%+L_ z$dywErZjY^q_FTbzCbO)ctX!AA(LVp{8l&?2p4(l^|mb53&%lAL3ubx*Q8i2#vv{x zd5bVw8Q3W~9287A3_~-irE&0`u!gIfQd($FDdAl$ID2When^31#^#E#HNO&{&pSgVzd81x)xWqBfBD#g0Rcg6 z;g5rp6=KW~I3%&R66}>$=V1>WhbqAggUDOJH0n?`CUK!!n3pIp5n+r}uxsL(!DZm5 zD;#XL;&m898r+CRzDY60(8kPEnRp5F9}?;}V#;o@6`8z*J$aR6)#c*pX-dhdr)Rit z8cYbgfoEwCj1xN~u}2bn-i~PmN5Z=ZTc|*y9(%4p_bg58yo4cPrz}tt_Tlhv!8AJr z6HF21RZ<3qgs&UZNI8@8Fq>6E$^!Mb#%}49&X6)+&0`#$H*ukEtF-{T-QNJy zBpm84^cG|6g-UXGZu)nCX`IhhTnQWcD}`wkFn1hbL~ssx1{j8RoU9nTB(bXkOmm46 zCK7mNW|pYSPDSxEj3`iqvFAn`C9o3{j}>6#ky5`Cc1nAfk7=GWUrnQ(i_c?7=I8?A z3X0Vg;TdUl1=#7FlTsJq*;zUchi6eYPE2(dVT{1SuRKgsvBhdOD~rKdvB~W0oPaS< zo2}%H7?$(MQs^y-**tHtx)jDJu!J{eguf|vNEC>aj(M6w&bxwCNj{#V3;R5VL@*Jn zb9nZ3*nvtUOgKEpr-Wi|j!juJHDOF#+oZ6g7|*k5?IJZd)6HY@BX42U8yIV`QjD>1 zDU;t9rjun4&z+JAEF0UU)rFY+a0N?ayEtV|T^6POu}z{9sPi#t@R1V?V=vVG0=B^fFQ{$!xC*u#8mvg#rX5jhvCE63zfkdjP9m~FYw+bA2eGZd@;Z(!~tMp&)fmVFKh z|H&iofyI8Jy=c22+KaZp6tSv`@Z#bE{z1T`AvHc!1$dEdXiJNruorDP%z*fRC9qiX J|9Ai4e*s?d4dVa+ literal 0 HcmV?d00001 diff --git a/examples/audio/mixed_processor/country.mp3 b/examples/audio/mixed_processor/country.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..91066cce371af83b6680e47bf5b1cb825ec5d1d6 GIT binary patch literal 1497964 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 GaHI;I#g~21&(q9t`9rRHO2|eFI?t0dmC$fIp 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%0AH5C>oe~Au`6_0T{B>dCX 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 z BIME*oo3U=`p>MSW>v*OMJ(}?|Lu*w)4xfns+-2Dl?e`4gt&gWGN6k zd3QU*stU`L-7d|4l@V4shSw1UHxFuKy5SPzknpbTHe0hK!PP%uM)y)4%*cb_vE(Kn!#4!Sx*_R!<4bn zpQ(D7OH5m?&n?Op4{kQs0F(_lW~iCDkU`P-9-MzQbcYz0puRw?BCw=FFYxp!7B!Ak z&`6QsOiiow?Bu@cmVZuMsa`5r)A4;JRg|SRC%Y~(X3Li~l#O)}up>0hUqS{TC=E5Y z+1A&|XQy`mt!612#%V)%xm1V_etoXZ0v|8ZvUt6p49xd~!9?IU8+oFt3yCVlXCswlM(%ITSwF3ANyL_{ak1KEXjk_AA~5I$#Sy1ANj4en&4ew27|F&iB!?v zSUb$wPDgFPGL^ZgJ!p)W+(!~BFvhKL#KD*V?y~`80s>Kh{bcYAEBNWeyYhq_Z3hJ# zhJXzY9!eEp5ea1qAO{ebh7!<0$w$%xNlee0WhF+-o!$`|5E}DtL+ePN$)b#*9%;rFR z902N`G_*3jYyiRvf)rO#%)y^S7rmUq->B*WC6Iegamr8Y3k@(>?>Phjiy0y*0fdP;ILMz-m8i!#ie-LDR>hpD z(EjiZ4BA(E5+V89>*4?YSmt{Hzy~W5U?Rgq%-a(6nRW&EK1)lq+J%J1?oBXRW({jC zgE;>gHvIyFJB5S5Aoc9*9%0A>zVWirFo)_}zT^LqMsqD8K|_Is>ZvE93Z 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

Vc1m8k&`OZGDcLTrYBxnI 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

uTAA9OQ0m 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

int{e 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∾s_t2ijUTra$YR@B2B~j}iUCi}Q{? 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�l|*Am^cPVA_C9*(jd{bb10M{#}Sp}}eT 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 literal 0 HcmV?d00001 diff --git a/examples/audio/mixed_processor/main.go b/examples/audio/mixed_processor/main.go new file mode 100644 index 0000000..d9d8835 --- /dev/null +++ b/examples/audio/mixed_processor/main.go @@ -0,0 +1,155 @@ +/******************************************************************************************* +* +* raylib [audio] example - Mixed audio processing +* +* Example originally created with raylib 4.2, last time updated with raylib 4.2 +* +* Example contributed by hkc (@hatkidchan) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2023 hkc (@hatkidchan) +* +********************************************************************************************/ +package main + +import ( + "fmt" + "math" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +var exponent float32 = 1.0 // Audio exponentiation value +var averageVolume [400]float32 // Average volume history + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output") + + rl.InitAudioDevice() // Initialize audio device + rl.AttachAudioMixedProcessor(ProcessAudio) + + music := rl.LoadMusicStream("country.mp3") + sound := rl.LoadSound("coin.wav") + + rl.PlayMusicStream(music) + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + rl.UpdateMusicStream(music) // Update music buffer with new stream data + + // Modify processing variables + if rl.IsKeyPressed(rl.KeyLeft) { + exponent -= 0.05 + } + if rl.IsKeyPressed(rl.KeyRight) { + exponent += 0.05 + } + if rl.IsKeyPressed(rl.KeyDown) { + exponent -= 0.25 + } + if rl.IsKeyPressed(rl.KeyUp) { + exponent += 0.25 + } + + // Make sure that exponent stays between 0.5 and 3 + exponent = clamp(exponent, 0.5, 3) + + if rl.IsKeyPressed(rl.KeySpace) { + rl.PlaySound(sound) + } + + // Draw + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, rl.LightGray) + + rl.DrawText(fmt.Sprintf("EXPONENT = %.2f", exponent), 215, 180, 20, rl.LightGray) + + rl.DrawRectangle(199, 199, 402, 34, rl.LightGray) + for i := int32(0); i < 400; i++ { + rl.DrawLine(201+i, 232-int32(averageVolume[i]*32), 201+i, 232, rl.Maroon) + } + rl.DrawRectangleLines(199, 199, 402, 34, rl.Gray) + + rl.DrawText("PRESS SPACE TO PLAY OTHER SOUND", 200, 250, 20, rl.LightGray) + rl.DrawText("USE LEFT AND RIGHT ARROWS TO ALTER DISTORTION", 140, 280, 20, rl.LightGray) + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadMusicStream(music) // Unload music stream buffers from RAM + rl.DetachAudioMixedProcessor(ProcessAudio) // Disconnect audio processor + rl.CloseAudioDevice() // Close audio device (music streaming is automatically stopped) + + rl.CloseWindow() // Close window and OpenGL context +} + +// ProcessAudio is the audio processing function +func ProcessAudio(buffer []float32, frames int) { + var average float32 // Temporary average volume + maxFrame := frames / 2 + + // Each frame has 2 samples (left and right), + // so we should loop `frames / 2` times + for frame := 0; frame < maxFrame; frame++ { + left := &buffer[frame*2+0] // Left channel + right := &buffer[frame*2+1] // Right channel + + // Modify left and right channel samples with exponent + *left = pow(abs(*left), exponent) * sgn(*left) + *right = pow(abs(*right), exponent) * sgn(*right) + + // Accumulating average volume + average += abs(*left) / float32(maxFrame) + average += abs(*right) / float32(maxFrame) + } + + // Shift average volume history buffer to the left + for i := 0; i < 399; i++ { + averageVolume[i] = averageVolume[i+1] + } + + // Add the new average value + averageVolume[399] = average +} + +// Helper functions to make the code shorter +// (using less type conversions) +// (Golang: Please make the `math` package generic! This is ridiculous :-) +func abs(value float32) float32 { + return float32(math.Abs(float64(value))) +} + +func pow(value, exponent float32) float32 { + return float32(math.Pow(float64(value), float64(exponent))) +} + +func sgn(value float32) float32 { + if value < 0 { + return -1 + } else if value > 0 { + return 1 + } + return 0 +} +func clamp(value, min, max float32) float32 { + if value < min { + return min + } + if value > max { + return max + } + return value +} From 274a0b58548fddff11a5ef29adcb17a1e290e645 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 17 Oct 2024 11:54:12 +0200 Subject: [PATCH 113/278] New example : Textures/npatch_drawing --- examples/textures/npatch_drawing/main.go | 134 ++++++++++++++++++ .../npatch_drawing/ninepatch_button.png | Bin 0 -> 5902 bytes 2 files changed, 134 insertions(+) create mode 100644 examples/textures/npatch_drawing/main.go create mode 100644 examples/textures/npatch_drawing/ninepatch_button.png diff --git a/examples/textures/npatch_drawing/main.go b/examples/textures/npatch_drawing/main.go new file mode 100644 index 0000000..84048c0 --- /dev/null +++ b/examples/textures/npatch_drawing/main.go @@ -0,0 +1,134 @@ +/******************************************************************************************* +* +* raylib [textures] example - N-patch drawing +* +* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) +* +* Example originally created with raylib 2.0, last time updated with raylib 2.5 +* +* Example contributed by Jorge A. Gomes (@overdev) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2018-2024 Jorge A. Gomes (@overdev) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import rl "github.com/gen2brain/raylib-go/raylib" + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [textures] example - N-patch drawing") + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + nPatchTexture := rl.LoadTexture("ninepatch_button.png") + + var mousePosition rl.Vector2 + var origin rl.Vector2 + + // Position and size of the n-patches + dstRec1 := rl.Rectangle{X: 480.0, Y: 160.0, Width: 32.0, Height: 32.0} + dstRec2 := rl.Rectangle{X: 160.0, Y: 160.0, Width: 32.0, Height: 32.0} + dstRecH := rl.Rectangle{X: 160.0, Y: 93.0, Width: 32.0, Height: 32.0} + dstRecV := rl.Rectangle{X: 92.0, Y: 160.0, Width: 32.0, Height: 32.0} + + // A 9-patch (NPatchNinePatch) changes its sizes in both axis + ninePatchInfo1 := rl.NPatchInfo{ + Source: rl.Rectangle{Width: 64.0, Height: 64.0}, + Left: 12, + Top: 40, + Right: 12, + Bottom: 12, + Layout: rl.NPatchNinePatch, + } + ninePatchInfo2 := rl.NPatchInfo{ + Source: rl.Rectangle{Y: 128.0, Width: 64.0, Height: 64.0}, + Left: 16, + Top: 16, + Right: 16, + Bottom: 16, + Layout: rl.NPatchNinePatch, + } + + // A horizontal 3-patch (NPatchThreePatchHorizontal) changes its sizes along the x-axis only + h3PatchInfo := rl.NPatchInfo{ + Source: rl.Rectangle{Y: 64.0, Width: 64.0, Height: 64.0}, + Left: 8, + Top: 8, + Right: 8, + Bottom: 8, + Layout: rl.NPatchThreePatchHorizontal, + } + + // A vertical 3-patch (NPatchThreePatchVertical) changes its sizes along the y-axis only + v3PatchInfo := rl.NPatchInfo{ + Source: rl.Rectangle{Y: 192.0, Width: 64.0, Height: 64.0}, + Left: 6, + Top: 6, + Right: 6, + Bottom: 6, + Layout: rl.NPatchThreePatchVertical, + } + + rl.SetTargetFPS(60) + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + mousePosition = rl.GetMousePosition() + + // Resize the n-patches based on mouse position + dstRec1.Width = mousePosition.X - dstRec1.X + dstRec1.Height = mousePosition.Y - dstRec1.Y + dstRec2.Width = mousePosition.X - dstRec2.X + dstRec2.Height = mousePosition.Y - dstRec2.Y + dstRecH.Width = mousePosition.X - dstRecH.X + dstRecV.Height = mousePosition.Y - dstRecV.Y + + // Set a minimum Width and/or Height + dstRec1.Width = clamp(dstRec1.Width, 1, 300) + dstRec1.Height = clamp(dstRec1.Height, 1, screenHeight) + dstRec2.Width = clamp(dstRec2.Width, 1, 300) + dstRec2.Height = clamp(dstRec2.Height, 1, screenHeight) + dstRecH.Width = clamp(dstRecH.Width, 1, screenWidth) + dstRecV.Height = clamp(dstRecV.Height, 1, screenHeight) + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + // Draw the n-patches + rl.DrawTextureNPatch(nPatchTexture, ninePatchInfo2, dstRec2, origin, 0.0, rl.White) + rl.DrawTextureNPatch(nPatchTexture, ninePatchInfo1, dstRec1, origin, 0.0, rl.White) + rl.DrawTextureNPatch(nPatchTexture, h3PatchInfo, dstRecH, origin, 0.0, rl.White) + rl.DrawTextureNPatch(nPatchTexture, v3PatchInfo, dstRecV, origin, 0.0, rl.White) + + // Draw the source texture + rl.DrawRectangleLines(5, 88, 74, 266, rl.Blue) + rl.DrawTexture(nPatchTexture, 10, 93, rl.White) + rl.DrawText("TEXTURE", 15, 360, 10, rl.DarkGray) + + rl.DrawText("Move the mouse to stretch or shrink the n-patches", 10, 20, 20, rl.DarkGray) + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadTexture(nPatchTexture) // Texture unloading + rl.CloseWindow() // Close window and OpenGL context +} + +func clamp(value, min, max float32) float32 { + if value < min { + return min + } + if value > max { + return max + } + return value +} diff --git a/examples/textures/npatch_drawing/ninepatch_button.png b/examples/textures/npatch_drawing/ninepatch_button.png new file mode 100644 index 0000000000000000000000000000000000000000..f10037a0fc1664dcbdcc027ec3cdbb5757098835 GIT binary patch literal 5902 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 literal 0 HcmV?d00001 From cf5c9f8b9ad62a69a1e7a53a518cc033593687d2 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 17 Oct 2024 12:25:19 +0200 Subject: [PATCH 114/278] New example : Textures/sprite_anim --- examples/textures/sprite_anim/main.go | 98 +++++++++++++++++++++++ examples/textures/sprite_anim/scarfy.png | Bin 0 -> 10394 bytes 2 files changed, 98 insertions(+) create mode 100644 examples/textures/sprite_anim/main.go create mode 100644 examples/textures/sprite_anim/scarfy.png diff --git a/examples/textures/sprite_anim/main.go b/examples/textures/sprite_anim/main.go new file mode 100644 index 0000000..10e5383 --- /dev/null +++ b/examples/textures/sprite_anim/main.go @@ -0,0 +1,98 @@ +/******************************************************************************************* +* +* raylib [textures] example - Sprite animation +* +* Example originally created with raylib 1.3, last time updated with raylib 1.3 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + maxFramesSpeed = 15 + minFramesSpeed = 1 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [texture] example - sprite anim") + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + scarfy := rl.LoadTexture("scarfy.png") // Texture loading + + position := rl.Vector2{X: 350.0, Y: 280.0} + frameRec := rl.Rectangle{Width: float32(scarfy.Width / 6), Height: float32(scarfy.Height)} + var currentFrame, framesCounter, framesSpeed int32 = 0, 0, 8 + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + framesCounter++ + + if framesCounter >= (60 / framesSpeed) { + framesCounter = 0 + currentFrame++ + + if currentFrame > 5 { + currentFrame = 0 + } + + frameRec.X = float32(currentFrame*scarfy.Width) / 6 + } + + // Control frames speed + if rl.IsKeyPressed(rl.KeyRight) { + framesSpeed++ + } else if rl.IsKeyPressed(rl.KeyLeft) { + framesSpeed-- + } + + // Make sure that framesSpeed is between minFramesSpeed and maxFramesSpeed + framesSpeed = clamp(framesSpeed, minFramesSpeed, maxFramesSpeed) + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawTexture(scarfy, 15, 40, rl.White) + rl.DrawRectangleLines(15, 40, scarfy.Width, scarfy.Height, rl.Lime) + rl.DrawRectangleLines(15+int32(frameRec.X), 40+int32(frameRec.Y), int32(frameRec.Width), int32(frameRec.Height), rl.Red) + + rl.DrawText("FRAME SPEED: ", 165, 210, 10, rl.DarkGray) + rl.DrawText(fmt.Sprintf("%02d FPS", framesSpeed), 575, 210, 10, rl.DarkGray) + rl.DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, rl.DarkGray) + + for i := int32(0); i < maxFramesSpeed; i++ { + if i < framesSpeed { + rl.DrawRectangle(250+21*i, 205, 20, 20, rl.Red) + } + rl.DrawRectangleLines(250+21*i, 205, 20, 20, rl.Maroon) + } + + rl.DrawTextureRec(scarfy, frameRec, position, rl.White) // Draw part of the texture + + rl.DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth-200, screenHeight-20, 10, rl.Gray) + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadTexture(scarfy) // Texture unloading + rl.CloseWindow() // Close window and OpenGL context +} + +func clamp(value, minValue, maxValue int32) int32 { + return max(minValue, min(value, maxValue)) +} diff --git a/examples/textures/sprite_anim/scarfy.png b/examples/textures/sprite_anim/scarfy.png new file mode 100644 index 0000000000000000000000000000000000000000..be3b83d0e7f523e2cf80da19e274a8479e33fe13 GIT binary patch literal 10394 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 E4?57ykpKVy literal 0 HcmV?d00001 From f1236640f94ffb9051762d89174c31c0c38256d6 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 17 Oct 2024 12:44:25 +0200 Subject: [PATCH 115/278] New example : Textures/sprite_button --- examples/textures/sprite_button/button.png | Bin 0 -> 23459 bytes examples/textures/sprite_button/buttonfx.wav | Bin 0 -> 88244 bytes examples/textures/sprite_button/main.go | 94 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 examples/textures/sprite_button/button.png create mode 100644 examples/textures/sprite_button/buttonfx.wav create mode 100644 examples/textures/sprite_button/main.go diff --git a/examples/textures/sprite_button/button.png b/examples/textures/sprite_button/button.png new file mode 100644 index 0000000000000000000000000000000000000000..99a383b697b4ab5d794f93f6a7c28eb89b791e28 GIT binary patch literal 23459 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 literal 0 HcmV?d00001 diff --git a/examples/textures/sprite_button/buttonfx.wav b/examples/textures/sprite_button/buttonfx.wav new file mode 100644 index 0000000000000000000000000000000000000000..b93b0ca0b5f4dbdac2e7eb0a279ff925b813afbc GIT binary patch literal 88244 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 Date: Thu, 17 Oct 2024 14:58:47 +0200 Subject: [PATCH 116/278] New example : Textures/draw_tiled --- examples/textures/draw_tiled/main.go | 302 ++++++++++++++++++++++ examples/textures/draw_tiled/patterns.png | Bin 0 -> 7387 bytes 2 files changed, 302 insertions(+) create mode 100644 examples/textures/draw_tiled/main.go create mode 100644 examples/textures/draw_tiled/patterns.png diff --git a/examples/textures/draw_tiled/main.go b/examples/textures/draw_tiled/main.go new file mode 100644 index 0000000..9d38c18 --- /dev/null +++ b/examples/textures/draw_tiled/main.go @@ -0,0 +1,302 @@ +/******************************************************************************************* + * + * raylib [textures] example - Draw part of the texture tiled + * + * Example originally created with raylib 3.0, last time updated with raylib 4.2 + * + * Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) + * + * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, + * BSD-like license that allows static linking with closed source software + * + * Copyright (c) 2020-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) + * + ********************************************************************************************/ +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + optWidth = 220 // Max width for the options container + marginSize = 8 // Size for the margins + colorSize = 16 // Size of the color select buttons +) + +func main() { + rl.SetConfigFlags(rl.FlagWindowResizable) // Make the window resizable + rl.InitWindow(screenWidth, screenHeight, "raylib [textures] example - Draw part of a texture tiled") + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + texPattern := rl.LoadTexture("patterns.png") + rl.SetTextureFilter(texPattern, rl.TextureFilterNearestMipLinear) // Makes the texture smoother when upscaled + + // Coordinates for all patterns inside the texture + recPattern := []rl.Rectangle{ + {3, 3, 66, 66}, + {75, 3, 100, 100}, + {3, 75, 66, 66}, + {7, 156, 50, 50}, + {85, 106, 90, 45}, + {75, 154, 100, 60}, + } + + // Setup colors + colors := []rl.Color{rl.Black, rl.Maroon, rl.Orange, rl.Blue, rl.Purple, + rl.Beige, rl.Lime, rl.Red, rl.DarkGray, rl.SkyBlue} + var maxColors = len(colors) + colorRec := make([]rl.Rectangle, maxColors) + + // Calculate rectangle for each color + var x, y float32 + for i := 0; i < maxColors; i++ { + colorRec[i].X = 2.0 + marginSize + x + colorRec[i].Y = 22.0 + 256.0 + marginSize + y + colorRec[i].Width = colorSize * 2.0 + colorRec[i].Height = colorSize + + if i == (maxColors/2 - 1) { + x = 0 + y += colorSize + marginSize + } else { + x += colorSize*2 + marginSize + } + } + + activePattern := 0 + activeCol := 0 + scale := float32(1.0) + rotation := float32(0.0) + + rl.SetTargetFPS(60) + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Handle mouse + if rl.IsMouseButtonPressed(rl.MouseButtonLeft) { + mouse := rl.GetMousePosition() + + // Check which pattern was clicked and set it as the active pattern + for i := 0; i < len(recPattern); i++ { + r := rl.Rectangle{ + X: 2 + marginSize + recPattern[i].X, + Y: 40 + marginSize + recPattern[i].Y, + Width: recPattern[i].Width, + Height: recPattern[i].Height, + } + if rl.CheckCollisionPointRec(mouse, r) { + activePattern = i + break + } + } + + // Check to see which color was clicked and set it as the active color + for i := 0; i < maxColors; i++ { + if rl.CheckCollisionPointRec(mouse, colorRec[i]) { + activeCol = i + break + } + } + } + + // Handle keys + + // Change scale + if rl.IsKeyPressed(rl.KeyUp) { + scale += 0.25 + } + if rl.IsKeyPressed(rl.KeyDown) { + scale -= 0.25 + } + scale = clamp(scale, 0.25, 10) + + // Change rotation + if rl.IsKeyPressed(rl.KeyLeft) { + rotation -= 25.0 + } + if rl.IsKeyPressed(rl.KeyRight) { + rotation += 25.0 + } + + // Reset + if rl.IsKeyPressed(rl.KeySpace) { + rotation = 0.0 + scale = 1.0 + } + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + // Draw the tiled area + src := rl.Rectangle{ + X: optWidth + marginSize, + Y: marginSize, + Width: float32(rl.GetScreenWidth()) - optWidth - 2.0*marginSize, + Height: float32(rl.GetScreenHeight()) - 2.0*marginSize, + } + DrawTextureTiled(texPattern, recPattern[activePattern], src, rl.Vector2{}, rotation, scale, colors[activeCol]) + + // Draw options + rl.DrawRectangle(marginSize, marginSize, optWidth-marginSize, int32(rl.GetScreenHeight())-2*marginSize, + rl.ColorAlpha(rl.LightGray, 0.5)) + + rl.DrawText("Select Pattern", 2+marginSize, 30+marginSize, 10, rl.Black) + rl.DrawTexture(texPattern, 2+marginSize, 40+marginSize, rl.Black) + rl.DrawRectangle(int32(2+marginSize+recPattern[activePattern].X), + int32(40+marginSize+recPattern[activePattern].Y), + int32(recPattern[activePattern].Width), + int32(recPattern[activePattern].Height), rl.ColorAlpha(rl.DarkBlue, 0.3)) + + rl.DrawText("Select Color", 2+marginSize, 10+256+marginSize, 10, rl.Black) + for i := 0; i < maxColors; i++ { + rl.DrawRectangleRec(colorRec[i], colors[i]) + if activeCol == i { + rl.DrawRectangleLinesEx(colorRec[i], 3, rl.ColorAlpha(rl.White, 0.5)) + } + } + + rl.DrawText("Scale (UP/DOWN to change)", 2+marginSize, 80+256+marginSize, 10, rl.Black) + rl.DrawText(fmt.Sprintf("%.2fx", scale), 2+marginSize, 92+256+marginSize, 20, rl.Black) + + rl.DrawText("Rotation (LEFT/RIGHT to change)", 2+marginSize, 122+256+marginSize, 10, rl.Black) + rl.DrawText(fmt.Sprintf("%.0f degrees", rotation), 2+marginSize, 134+256+marginSize, 20, rl.Black) + + rl.DrawText("Press [SPACE] to reset", 2+marginSize, 164+256+marginSize, 10, rl.DarkBlue) + + // Draw FPS + rl.DrawText(fmt.Sprintf("%d FPS", rl.GetFPS()), 2+marginSize, 2+marginSize, 20, rl.Black) + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadTexture(texPattern) // Unload texture + + rl.CloseWindow() // Close window and OpenGL context +} + +// DrawTextureTiled draws a part of a texture (defined by a rectangle) with rotation and scale tiled into dest. +func DrawTextureTiled(texture rl.Texture2D, source, dest rl.Rectangle, origin rl.Vector2, rotation, scale float32, + tint rl.Color) { + + if (texture.ID <= 0) || (scale <= 0.0) { // Want see an infinite loop?!...just delete this line! + return + } + if (source.Width == 0) || (source.Height == 0) { + return + } + + tileWidth := source.Width * scale + tileHeight := source.Height * scale + if (dest.Width < tileWidth) && (dest.Height < tileHeight) { + // Can fit only one tile + src := rl.Rectangle{ + X: source.X, + Y: source.Y, + Width: dest.Width / tileWidth * source.Width, + Height: dest.Height / tileHeight * source.Height, + } + dst := rl.Rectangle{X: dest.X, Y: dest.Y, Width: dest.Width, Height: dest.Height} + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } else if dest.Width <= tileWidth { + // Tiled vertically (one column) + var dy float32 + for ; dy+tileHeight < dest.Height; dy += tileHeight { + src := rl.Rectangle{ + X: source.X, + Y: source.Y, + Width: dest.Width / tileWidth * source.Width, + Height: source.Height, + } + dst := rl.Rectangle{X: dest.X, Y: dest.Y + dy, Width: dest.Width, Height: tileHeight} + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } + + // Fit last tile + if dy < dest.Height { + src := rl.Rectangle{X: source.X, Y: source.Y, + Width: (dest.Width / tileWidth) * source.Width, + Height: ((dest.Height - dy) / tileHeight) * source.Height, + } + dst := rl.Rectangle{X: dest.X, Y: dest.Y + dy, Width: dest.Width, Height: dest.Height - dy} + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } + } else if dest.Height <= tileHeight { + // Tiled horizontally (one row) + var dx float32 + for ; dx+tileWidth < dest.Width; dx += tileWidth { + src := rl.Rectangle{ + X: source.X, Y: source.Y, Width: source.Width, + Height: (dest.Height / tileHeight) * source.Height, + } + dst := rl.Rectangle{X: dest.X + dx, Y: dest.Y, Width: tileWidth, Height: dest.Height} + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } + + // Fit last tile + if dx < dest.Width { + src := rl.Rectangle{ + X: source.X, Y: source.Y, Width: ((dest.Width - dx) / tileWidth) * source.Width, + Height: (dest.Height / tileHeight) * source.Height, + } + dst := rl.Rectangle{X: dest.X + dx, Y: dest.Y, Width: dest.Width - dx, Height: dest.Height} + rl.DrawTexturePro(texture, src, + dst, origin, rotation, tint) + } + } else { + // Tiled both horizontally and vertically (rows and columns) + var dx float32 + for ; dx+tileWidth < dest.Width; dx += tileWidth { + var dy float32 + for ; dy+tileHeight < dest.Height; dy += tileHeight { + dst := rl.Rectangle{X: dest.X + dx, Y: dest.Y + dy, Width: tileWidth, Height: tileHeight} + rl.DrawTexturePro(texture, source, dst, origin, rotation, tint) + } + + if dy < dest.Height { + src := rl.Rectangle{ + X: source.X, Y: source.Y, + Width: source.Width, Height: ((dest.Height - dy) / tileHeight) * source.Height, + } + dst := rl.Rectangle{ + X: dest.X + dx, Y: dest.Y + dy, + Width: tileWidth, Height: dest.Height - dy, + } + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } + } + + // Fit last column of tiles + if dx < dest.Width { + var dy float32 + for ; dy+tileHeight < dest.Height; dy += tileHeight { + src := rl.Rectangle{ + X: source.X, Y: source.Y, + Width: ((dest.Width - dx) / tileWidth) * source.Width, Height: source.Height, + } + dst := rl.Rectangle{X: dest.X + dx, Y: dest.Y + dy, Width: dest.Width - dx, Height: tileHeight} + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } + + // Draw final tile in the bottom right corner + if dy < dest.Height { + src := rl.Rectangle{ + X: source.X, Y: source.Y, + Width: ((dest.Width - dx) / tileWidth) * source.Width, + Height: ((dest.Height - dy) / tileHeight) * source.Height, + } + dst := rl.Rectangle{X: dest.X + dx, Y: dest.Y + dy, Width: dest.Width - dx, Height: dest.Height - dy} + rl.DrawTexturePro(texture, src, dst, origin, rotation, tint) + } + } + } +} + +func clamp(value, minValue, maxValue float32) float32 { + return min(maxValue, max(value, minValue)) +} diff --git a/examples/textures/draw_tiled/patterns.png b/examples/textures/draw_tiled/patterns.png new file mode 100644 index 0000000000000000000000000000000000000000..58b3c372c7dbfaf53bca771a9dc32e83d37dbd0d GIT binary patch literal 7387 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 Date: Thu, 17 Oct 2024 16:35:11 +0200 Subject: [PATCH 117/278] Revert "New example : Textures/sprite_anim" This reverts commit cf5c9f8b9ad62a69a1e7a53a518cc033593687d2. --- examples/textures/sprite_anim/main.go | 98 ----------------------- examples/textures/sprite_anim/scarfy.png | Bin 10394 -> 0 bytes 2 files changed, 98 deletions(-) delete mode 100644 examples/textures/sprite_anim/main.go delete mode 100644 examples/textures/sprite_anim/scarfy.png diff --git a/examples/textures/sprite_anim/main.go b/examples/textures/sprite_anim/main.go deleted file mode 100644 index 10e5383..0000000 --- a/examples/textures/sprite_anim/main.go +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************************* -* -* raylib [textures] example - Sprite animation -* -* Example originally created with raylib 1.3, last time updated with raylib 1.3 -* -* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, -* BSD-like license that allows static linking with closed source software -* -* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) -* -********************************************************************************************/ -package main - -import ( - "fmt" - - rl "github.com/gen2brain/raylib-go/raylib" -) - -const ( - screenWidth = 800 - screenHeight = 450 - maxFramesSpeed = 15 - minFramesSpeed = 1 -) - -func main() { - rl.InitWindow(screenWidth, screenHeight, "raylib [texture] example - sprite anim") - - // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - scarfy := rl.LoadTexture("scarfy.png") // Texture loading - - position := rl.Vector2{X: 350.0, Y: 280.0} - frameRec := rl.Rectangle{Width: float32(scarfy.Width / 6), Height: float32(scarfy.Height)} - var currentFrame, framesCounter, framesSpeed int32 = 0, 0, 8 - - rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second - - // Main game loop - for !rl.WindowShouldClose() { // Detect window close button or ESC key - framesCounter++ - - if framesCounter >= (60 / framesSpeed) { - framesCounter = 0 - currentFrame++ - - if currentFrame > 5 { - currentFrame = 0 - } - - frameRec.X = float32(currentFrame*scarfy.Width) / 6 - } - - // Control frames speed - if rl.IsKeyPressed(rl.KeyRight) { - framesSpeed++ - } else if rl.IsKeyPressed(rl.KeyLeft) { - framesSpeed-- - } - - // Make sure that framesSpeed is between minFramesSpeed and maxFramesSpeed - framesSpeed = clamp(framesSpeed, minFramesSpeed, maxFramesSpeed) - - // Draw - rl.BeginDrawing() - rl.ClearBackground(rl.RayWhite) - - rl.DrawTexture(scarfy, 15, 40, rl.White) - rl.DrawRectangleLines(15, 40, scarfy.Width, scarfy.Height, rl.Lime) - rl.DrawRectangleLines(15+int32(frameRec.X), 40+int32(frameRec.Y), int32(frameRec.Width), int32(frameRec.Height), rl.Red) - - rl.DrawText("FRAME SPEED: ", 165, 210, 10, rl.DarkGray) - rl.DrawText(fmt.Sprintf("%02d FPS", framesSpeed), 575, 210, 10, rl.DarkGray) - rl.DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, rl.DarkGray) - - for i := int32(0); i < maxFramesSpeed; i++ { - if i < framesSpeed { - rl.DrawRectangle(250+21*i, 205, 20, 20, rl.Red) - } - rl.DrawRectangleLines(250+21*i, 205, 20, 20, rl.Maroon) - } - - rl.DrawTextureRec(scarfy, frameRec, position, rl.White) // Draw part of the texture - - rl.DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth-200, screenHeight-20, 10, rl.Gray) - - rl.EndDrawing() - } - - // De-Initialization - rl.UnloadTexture(scarfy) // Texture unloading - rl.CloseWindow() // Close window and OpenGL context -} - -func clamp(value, minValue, maxValue int32) int32 { - return max(minValue, min(value, maxValue)) -} diff --git a/examples/textures/sprite_anim/scarfy.png b/examples/textures/sprite_anim/scarfy.png deleted file mode 100644 index be3b83d0e7f523e2cf80da19e274a8479e33fe13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10394 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 E4?57ykpKVy From 1eacaf732cef9c81642808edf52bad9c8a0f8cc9 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:45:15 +0200 Subject: [PATCH 118/278] #428 cgo vr functions added --- raylib/rcore.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/raylib/rcore.go b/raylib/rcore.go index 8c322ae..ccfd221 100644 --- a/raylib/rcore.go +++ b/raylib/rcore.go @@ -1218,3 +1218,24 @@ func GetTouchPointCount() int32 { v := (int32)(ret) return v } + +// BeginVrStereoMode - Begin stereo rendering (requires VR simulator) +func BeginVrStereoMode(config VrStereoConfig) { + C.BeginVrStereoMode(*(*C.VrStereoConfig)(unsafe.Pointer(&config))) +} + +// EndVrStereoMode - End stereo rendering (requires VR simulator) +func EndVrStereoMode() { + C.EndVrStereoMode() +} + +// LoadVrStereoConfig - Load VR stereo config for VR simulator device parameters +func LoadVrStereoConfig(device VrDeviceInfo) VrStereoConfig { + ret := C.LoadVrStereoConfig(*(*C.VrDeviceInfo)(unsafe.Pointer(&device))) + return *(*VrStereoConfig)(unsafe.Pointer(&ret)) +} + +// UnloadVrStereoConfig - Unload VR stereo config +func UnloadVrStereoConfig(config VrStereoConfig) { + C.UnloadVrStereoConfig(*(*C.VrStereoConfig)(unsafe.Pointer(&config))) +} From e9d222595d3482f477adbd921dffae290749d860 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:47:52 +0200 Subject: [PATCH 119/278] #428 BeginVrStereoMode and EndVrStereoMode purgo body added --- raylib/raylib_purego.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index fa9a944..73f83bb 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -1358,10 +1358,14 @@ func EndScissorMode() { } // BeginVrStereoMode - Begin stereo rendering (requires VR simulator) -func BeginVrStereoMode(config VrStereoConfig) {} +func BeginVrStereoMode(config VrStereoConfig) { + beginVrStereoMode(uintptr(unsafe.Pointer(&config))) +} // EndVrStereoMode - End stereo rendering (requires VR simulator) -func EndVrStereoMode() {} +func EndVrStereoMode() { + endVrStereoMode() +} // LoadVrStereoConfig - Load VR stereo config for VR simulator device parameters func LoadVrStereoConfig(device VrDeviceInfo) VrStereoConfig { From eb60c30db123621d9c451fafacde1be4ba20bab1 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Sat, 19 Oct 2024 09:55:40 +0200 Subject: [PATCH 120/278] Textures/draw_tiled : Changed to the correct texture filter --- examples/textures/draw_tiled/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/textures/draw_tiled/main.go b/examples/textures/draw_tiled/main.go index 9d38c18..377c6d3 100644 --- a/examples/textures/draw_tiled/main.go +++ b/examples/textures/draw_tiled/main.go @@ -34,7 +34,7 @@ func main() { // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) texPattern := rl.LoadTexture("patterns.png") - rl.SetTextureFilter(texPattern, rl.TextureFilterNearestMipLinear) // Makes the texture smoother when upscaled + rl.SetTextureFilter(texPattern, rl.FilterTrilinear) // Makes the texture smoother when upscaled // Coordinates for all patterns inside the texture recPattern := []rl.Rectangle{ From f84ecd5b6385dca1398b112a27cd56b9081c35eb Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Sat, 19 Oct 2024 16:27:24 +0200 Subject: [PATCH 121/278] New example : core/storage_values --- examples/core/storage_values/main.go | 127 +++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 examples/core/storage_values/main.go diff --git a/examples/core/storage_values/main.go b/examples/core/storage_values/main.go new file mode 100644 index 0000000..8e4c658 --- /dev/null +++ b/examples/core/storage_values/main.go @@ -0,0 +1,127 @@ +/******************************************************************************************* +* +* raylib [core] example - Storage save/load values +* +* Example originally created with raylib 1.4, last time updated with raylib 4.2 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "encoding/binary" + "fmt" + "os" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + storageDataFile = "storage.data" + // NOTE: Storage positions must start with 0, directly related to file memory layout + storagePositionScore = 0 + storagePositionHiscore = 1 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - storage save/load values") + + var score int32 + var hiscore int32 + var framesCounter int32 + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + if rl.IsKeyPressed(rl.KeyR) { + score = rl.GetRandomValue(1000, 2000) + hiscore = rl.GetRandomValue(2000, 4000) + } + + if rl.IsKeyPressed(rl.KeyEnter) { + _ = SaveStorageValue(storagePositionScore, score) + _ = SaveStorageValue(storagePositionHiscore, hiscore) + } else if rl.IsKeyPressed(rl.KeySpace) { + // NOTE: If requested position could not be found, value 0 is returned + score, _ = LoadStorageValue(storagePositionScore) + hiscore, _ = LoadStorageValue(storagePositionHiscore) + } + + framesCounter++ + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawText(fmt.Sprintf("SCORE: %d", score), 280, 130, 40, rl.Maroon) + rl.DrawText(fmt.Sprintf("HI-SCORE: %d", hiscore), 210, 200, 50, rl.Black) + + rl.DrawText(fmt.Sprintf("frames: %d", framesCounter), 10, 10, 20, rl.Lime) + + rl.DrawText("Press R to generate random numbers", 220, 40, 20, rl.LightGray) + rl.DrawText("Press ENTER to SAVE values", 250, 310, 20, rl.LightGray) + rl.DrawText("Press SPACE to LOAD values", 252, 350, 20, rl.LightGray) + + rl.EndDrawing() + } + + // De-Initialization + rl.CloseWindow() // Close window and OpenGL context +} + +// SaveStorageValue saves an integer value to storage file (to defined position) +// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer) +func SaveStorageValue(position uint32, value int32) error { + // Load the file data + fileData, err := os.ReadFile(storageDataFile) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to load file: %v", err) + } + + dataSize := len(fileData) + requiredSize := int((position + 1) * 4) // Each int32 is 4 bytes + newFileData := make([]byte, requiredSize) + + // Copy existing file data to newFileData + if dataSize > 0 { + copy(newFileData, fileData) + } + + // Update the value at the specified position + binary.LittleEndian.PutUint32(newFileData[position*4:], uint32(value)) + + // Save the updated data back to the file + err = os.WriteFile(storageDataFile, newFileData, 0644) + if err != nil { + return fmt.Errorf("failed to save file: %v", err) + } + + return nil +} + +// LoadStorageValue loads an integer value from storage file (from defined position) +// NOTE: If requested position could not be found, value 0 is returned +func LoadStorageValue(position uint32) (int32, error) { + // Load the file data + fileData, err := os.ReadFile(storageDataFile) + if err != nil { + return 0, fmt.Errorf("failed to load file: %v", err) + } + + dataSize := len(fileData) + if dataSize < int((position+1)*4) { + return 0, fmt.Errorf("position out of bounds") + } + + // Read the value at the specified position + value := int32(binary.LittleEndian.Uint32(fileData[position*4:])) + return value, nil +} From d6c07f1bbf907d62b659fa8198bba69eae62a033 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Sat, 19 Oct 2024 18:08:02 +0200 Subject: [PATCH 122/278] New example : core/vr_simulator --- examples/core/vr_simulator/distortion100.fs | 52 ++++++++ examples/core/vr_simulator/distortion330.fs | 53 ++++++++ examples/core/vr_simulator/main.go | 137 ++++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100644 examples/core/vr_simulator/distortion100.fs create mode 100644 examples/core/vr_simulator/distortion330.fs create mode 100644 examples/core/vr_simulator/main.go diff --git a/examples/core/vr_simulator/distortion100.fs b/examples/core/vr_simulator/distortion100.fs new file mode 100644 index 0000000..f72c689 --- /dev/null +++ b/examples/core/vr_simulator/distortion100.fs @@ -0,0 +1,52 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables +uniform vec2 leftLensCenter; +uniform vec2 rightLensCenter; +uniform vec2 leftScreenCenter; +uniform vec2 rightScreenCenter; +uniform vec2 scale; +uniform vec2 scaleIn; +uniform vec4 deviceWarpParam; +uniform vec4 chromaAbParam; + +void main() +{ + // Compute lens distortion + vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter; + vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter; + vec2 theta = (fragTexCoord - lensCenter)*scaleIn; + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(deviceWarpParam.x + deviceWarpParam.y*rSq + deviceWarpParam.z*rSq*rSq + deviceWarpParam.w*rSq*rSq*rSq); + vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq); + vec2 tcBlue = lensCenter + scale*thetaBlue; + + if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue))) + { + // Set black fragment for everything outside the lens border + gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + } + else + { + // Compute color chroma aberration + float blue = texture2D(texture0, tcBlue).b; + vec2 tcGreen = lensCenter + scale*theta1; + float green = texture2D(texture0, tcGreen).g; + + vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq); + vec2 tcRed = lensCenter + scale*thetaRed; + + float red = texture2D(texture0, tcRed).r; + gl_FragColor = vec4(red, green, blue, 1.0); + } +} diff --git a/examples/core/vr_simulator/distortion330.fs b/examples/core/vr_simulator/distortion330.fs new file mode 100644 index 0000000..97044c4 --- /dev/null +++ b/examples/core/vr_simulator/distortion330.fs @@ -0,0 +1,53 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +uniform vec2 leftLensCenter = vec2(0.288, 0.5); +uniform vec2 rightLensCenter = vec2(0.712, 0.5); +uniform vec2 leftScreenCenter = vec2(0.25, 0.5); +uniform vec2 rightScreenCenter = vec2(0.75, 0.5); +uniform vec2 scale = vec2(0.25, 0.45); +uniform vec2 scaleIn = vec2(4, 2.2222); +uniform vec4 deviceWarpParam = vec4(1, 0.22, 0.24, 0); +uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); + +void main() +{ + // Compute lens distortion + vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter; + vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter; + vec2 theta = (fragTexCoord - lensCenter)*scaleIn; + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(deviceWarpParam.x + deviceWarpParam.y*rSq + deviceWarpParam.z*rSq*rSq + deviceWarpParam.w*rSq*rSq*rSq); + vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq); + vec2 tcBlue = lensCenter + scale*thetaBlue; + + if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue))) + { + // Set black fragment for everything outside the lens border + finalColor = vec4(0.0, 0.0, 0.0, 1.0); + } + else + { + // Compute color chroma aberration + float blue = texture(texture0, tcBlue).b; + vec2 tcGreen = lensCenter + scale*theta1; + float green = texture(texture0, tcGreen).g; + + vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq); + vec2 tcRed = lensCenter + scale*thetaRed; + + float red = texture(texture0, tcRed).r; + finalColor = vec4(red, green, blue, 1.0); + } +} diff --git a/examples/core/vr_simulator/main.go b/examples/core/vr_simulator/main.go new file mode 100644 index 0000000..55bc185 --- /dev/null +++ b/examples/core/vr_simulator/main.go @@ -0,0 +1,137 @@ +/******************************************************************************************* +* +* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters) +* +* Example originally created with raylib 2.5, last time updated with raylib 4.0 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2017-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + glslVersion = 330 // Desktop + // glslVersion = 100 // Android, web +) + +func main() { + // NOTE: screenWidth/screenHeight should match VR device aspect ratio + rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator") + + // VR device parameters definition + device := rl.VrDeviceInfo{ + // Oculus Rift CV1 parameters for simulator + HResolution: 2160, // Horizontal resolution in pixels + VResolution: 1200, // Vertical resolution in pixels + HScreenSize: 0.133793, // Horizontal size in meters + VScreenSize: 0.0669, // Vertical size in meters + EyeToScreenDistance: 0.041, // Distance between eye and display in meters + LensSeparationDistance: 0.07, // Lens separation distance in meters + InterpupillaryDistance: 0.07, // IPD (distance between pupils) in meters + + // NOTE: CV1 uses fresnel-hybrid-asymmetric lenses with specific compute shaders + // Following parameters are just an approximation to CV1 distortion stereo rendering + + // Lens distortion constant parameters + LensDistortionValues: [4]float32{1.0, 0.22, 0.24, 0.0}, + // Chromatic aberration correction parameters + ChromaAbCorrection: [4]float32{0.996, -0.004, 1.014, 0.0}, + } + + // Load VR stereo config for VR device parameters (Oculus Rift CV1 parameters) + config := rl.LoadVrStereoConfig(device) + + // Distortion shader (uses device lens distortion and chroma) + fileName := fmt.Sprintf("distortion%d.fs", glslVersion) + distortion := rl.LoadShader("", fileName) + + // Update distortion shader with lens and distortion-scale parameters + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "leftLensCenter"), + config.LeftLensCenter[:], rl.ShaderUniformVec2) + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "rightLensCenter"), + config.RightLensCenter[:], rl.ShaderUniformVec2) + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "leftScreenCenter"), + config.LeftScreenCenter[:], rl.ShaderUniformVec2) + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "rightScreenCenter"), + config.RightScreenCenter[:], rl.ShaderUniformVec2) + + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "scale"), + config.Scale[:], rl.ShaderUniformVec2) + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "scaleIn"), + config.ScaleIn[:], rl.ShaderUniformVec2) + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "deviceWarpParam"), + device.LensDistortionValues[:], rl.ShaderUniformVec4) + rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "chromaAbParam"), + device.ChromaAbCorrection[:], rl.ShaderUniformVec4) + + // Initialize frame buffer for stereo rendering + // NOTE: Screen size should match HMD aspect ratio + target := rl.LoadRenderTexture(device.HResolution, device.VResolution) + + // The target's height is flipped (in the source Rectangle), due to OpenGL reasons + sourceRec := rl.Rectangle{Width: float32(target.Texture.Width), Height: float32(-target.Texture.Height)} + destRec := rl.Rectangle{Width: float32(rl.GetScreenWidth()), Height: float32(rl.GetScreenHeight())} + + // Define the camera to look into our 3d world + + camera := rl.Camera{ + Position: rl.Vector3{X: 5, Y: 2, Z: 5}, + Target: rl.Vector3{Y: 2}, + Up: rl.Vector3{Y: 1}, + Fovy: 60.0, + Projection: rl.CameraPerspective, + } + + cubePosition := rl.Vector3{} + + rl.DisableCursor() // Limit cursor to relative movement inside the window + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + rl.UpdateCamera(&camera, rl.CameraFirstPerson) + + // Draw texture + rl.BeginTextureMode(target) + rl.ClearBackground(rl.RayWhite) + rl.BeginVrStereoMode(config) + rl.BeginMode3D(camera) + + rl.DrawCube(cubePosition, 2.0, 2.0, 2.0, rl.Red) + rl.DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, rl.Maroon) + rl.DrawGrid(40, 1.0) + + rl.EndMode3D() + rl.EndVrStereoMode() + rl.EndTextureMode() + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + rl.BeginShaderMode(distortion) + rl.DrawTexturePro(target.Texture, sourceRec, destRec, rl.Vector2{}, 0.0, rl.White) + rl.EndShaderMode() + rl.DrawFPS(10, 10) + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadVrStereoConfig(config) // Unload stereo config + + rl.UnloadRenderTexture(target) // Unload stereo render fbo + rl.UnloadShader(distortion) // Unload distortion shader + + rl.CloseWindow() // Close window and OpenGL context +} From da901b89c1ef90a758b40864b9c77c5a5a7b1550 Mon Sep 17 00:00:00 2001 From: anasrar Date: Wed, 23 Oct 2024 01:10:52 +1300 Subject: [PATCH 123/278] feat(raymath): `MatrixDecompose` --- raylib/raymath.go | 53 +++++++++++++++++++++++++++++++++++++++++++++ raylib/raymath.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/raylib/raymath.go b/raylib/raymath.go index 5330912..63f1941 100644 --- a/raylib/raymath.go +++ b/raylib/raymath.go @@ -1792,3 +1792,56 @@ func QuaternionEquals(p, q Quaternion) bool { math.Abs(float64(p.Z+q.Z)) <= 0.000001*math.Max(1.0, math.Max(math.Abs(float64(p.Z)), math.Abs(float64(q.Z)))) && math.Abs(float64(p.W+q.W)) <= 0.000001*math.Max(1.0, math.Max(math.Abs(float64(p.W)), math.Abs(float64(q.W))))) } + +// MatrixDecompose - Decompose a transformation matrix into its rotational, translational and scaling components +func MatrixDecompose(mat Matrix, translational *Vector3, rotation *Quaternion, scale *Vector3) { + // Extract translation. + translational.X = mat.M12 + translational.Y = mat.M13 + translational.Z = mat.M14 + + // Extract upper-left for determinant computation + a := mat.M0 + b := mat.M4 + c := mat.M8 + d := mat.M1 + e := mat.M5 + f := mat.M9 + g := mat.M2 + h := mat.M6 + i := mat.M10 + A := e*i - f*h + B := f*g - d*i + C := d*h - e*g + + // Extract scale + det := a*A + b*B + c*C + abc := NewVector3(a, b, c) + def := NewVector3(d, e, f) + ghi := NewVector3(g, h, i) + + scalex := Vector3Length(abc) + scaley := Vector3Length(def) + scalez := Vector3Length(ghi) + s := NewVector3(scalex, scaley, scalez) + + if det < 0 { + s = Vector3Negate(s) + } + + *scale = s + + // Remove scale from the matrix if it is not close to zero + clone := mat + if !FloatEquals(det, 0) { + clone.M0 /= s.X + clone.M5 /= s.Y + clone.M10 /= s.Z + + // Extract rotation + *rotation = QuaternionFromMatrix(clone) + } else { + // Set to identity if close to zero + *rotation = QuaternionIdentity() + } +} diff --git a/raylib/raymath.h b/raylib/raymath.h index 19625f1..ebee6ba 100644 --- a/raylib/raymath.h +++ b/raylib/raymath.h @@ -2524,4 +2524,59 @@ RMAPI int QuaternionEquals(Quaternion p, Quaternion q) return result; } +// Decompose a transformation matrix into its rotational, translational and scaling components +RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotation, Vector3 *scale) +{ + // Extract translation. + translation->x = mat.m12; + translation->y = mat.m13; + translation->z = mat.m14; + + // Extract upper-left for determinant computation + const float a = mat.m0; + const float b = mat.m4; + const float c = mat.m8; + const float d = mat.m1; + const float e = mat.m5; + const float f = mat.m9; + const float g = mat.m2; + const float h = mat.m6; + const float i = mat.m10; + const float A = e*i - f*h; + const float B = f*g - d*i; + const float C = d*h - e*g; + + // Extract scale + const float det = a*A + b*B + c*C; + Vector3 abc = { a, b, c }; + Vector3 def = { d, e, f }; + Vector3 ghi = { g, h, i }; + + float scalex = Vector3Length(abc); + float scaley = Vector3Length(def); + float scalez = Vector3Length(ghi); + Vector3 s = { scalex, scaley, scalez }; + + if (det < 0) s = Vector3Negate(s); + + *scale = s; + + // Remove scale from the matrix if it is not close to zero + Matrix clone = mat; + if (!FloatEquals(det, 0)) + { + clone.m0 /= s.x; + clone.m5 /= s.y; + clone.m10 /= s.z; + + // Extract rotation + *rotation = QuaternionFromMatrix(clone); + } + else + { + // Set to identity if close to zero + *rotation = QuaternionIdentity(); + } +} + #endif // RAYMATH_H From f9b5993843021dc868cf1581de4319c6f7a2e649 Mon Sep 17 00:00:00 2001 From: anasrar Date: Wed, 23 Oct 2024 01:44:47 +1300 Subject: [PATCH 124/278] refactor(raymath): parameter typo --- raylib/raymath.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/raylib/raymath.go b/raylib/raymath.go index 63f1941..e0aefc6 100644 --- a/raylib/raymath.go +++ b/raylib/raymath.go @@ -1794,11 +1794,11 @@ func QuaternionEquals(p, q Quaternion) bool { } // MatrixDecompose - Decompose a transformation matrix into its rotational, translational and scaling components -func MatrixDecompose(mat Matrix, translational *Vector3, rotation *Quaternion, scale *Vector3) { +func MatrixDecompose(mat Matrix, translation *Vector3, rotation *Quaternion, scale *Vector3) { // Extract translation. - translational.X = mat.M12 - translational.Y = mat.M13 - translational.Z = mat.M14 + translation.X = mat.M12 + translation.Y = mat.M13 + translation.Z = mat.M14 // Extract upper-left for determinant computation a := mat.M0 From 5268babfe01db32e80949f7df63ad609e07d635e Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 23 Oct 2024 20:48:36 +0200 Subject: [PATCH 125/278] #431 AutomationEventList.GetEvents method added --- raylib/raylib.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/raylib/raylib.go b/raylib/raylib.go index 661d691..d8ecb5f 100644 --- a/raylib/raylib.go +++ b/raylib/raylib.go @@ -176,7 +176,14 @@ type AutomationEvent struct { type AutomationEventList struct { Capacity uint32 Count uint32 - Events *AutomationEvent + // Events array (c array) + // + // Use AutomationEventList.GetEvents instead (go slice) + Events *AutomationEvent +} + +func (a *AutomationEventList) GetEvents() []AutomationEvent { + return unsafe.Slice(a.Events, a.Count) } // CameraMode type From 5c0fc5c528e31eea5bbff272f7d4c4e27fd4b147 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:26:52 +0200 Subject: [PATCH 126/278] #436 DrawCircleLinesV to cgo-version added --- raylib/rshapes.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/raylib/rshapes.go b/raylib/rshapes.go index 2e2e18f..587b3a0 100644 --- a/raylib/rshapes.go +++ b/raylib/rshapes.go @@ -134,6 +134,14 @@ func DrawCircleLines(centerX, centerY int32, radius float32, col color.RGBA) { C.DrawCircleLines(ccenterX, ccenterY, cradius, *ccolor) } +// DrawCircleLinesV - Draw circle outline (Vector version) +func DrawCircleLinesV(center Vector2, radius float32, col color.RGBA) { + ccenter := center.cptr() + cradius := (C.float)(radius) + ccolor := colorCptr(col) + C.DrawCircleLinesV(*ccenter, cradius, *ccolor) +} + // DrawEllipse - Draw ellipse func DrawEllipse(centerX, centerY int32, radiusH, radiusV float32, col color.RGBA) { ccenterX := (C.int)(centerX) From badf94c43388c2c51b2f4b5c1374df9cedfe748a Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:36:14 +0200 Subject: [PATCH 127/278] #437 take rl.BlendMode instead of int32 --- raylib/rlgl_cgo.go | 2 +- raylib/rlgl_purego.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/raylib/rlgl_cgo.go b/raylib/rlgl_cgo.go index c27d357..c0801a7 100644 --- a/raylib/rlgl_cgo.go +++ b/raylib/rlgl_cgo.go @@ -454,7 +454,7 @@ func CheckErrors() { } // SetBlendMode - Set blending mode -func SetBlendMode(mode int32) { +func SetBlendMode(mode BlendMode) { cmode := C.int(mode) C.rlSetBlendMode(cmode) } diff --git a/raylib/rlgl_purego.go b/raylib/rlgl_purego.go index a8c15d3..27e5deb 100644 --- a/raylib/rlgl_purego.go +++ b/raylib/rlgl_purego.go @@ -597,8 +597,8 @@ func CheckErrors() { } // SetBlendMode - Set blending mode -func SetBlendMode(mode int32) { - rlSetBlendMode(mode) +func SetBlendMode(mode BlendMode) { + rlSetBlendMode(int32(mode)) } // SetBlendFactors - Set blending mode factor and equation (using OpenGL factors) From bd66c8b623f8de2cde0489b5b1b77bbe1990de87 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 24 Oct 2024 17:15:30 +0200 Subject: [PATCH 128/278] New example : shapes/draw_ring --- examples/shapes/draw_ring/main.go | 121 ++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 examples/shapes/draw_ring/main.go diff --git a/examples/shapes/draw_ring/main.go b/examples/shapes/draw_ring/main.go new file mode 100644 index 0000000..d869ca9 --- /dev/null +++ b/examples/shapes/draw_ring/main.go @@ -0,0 +1,121 @@ +/******************************************************************************************* +* +* raylib [shapes] example - draw ring (with gui options) +* +* Example originally created with raylib 2.5, last time updated with raylib 2.5 +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "fmt" + "math" + + gui "github.com/gen2brain/raylib-go/raygui" + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw ring") + + center := rl.Vector2{X: (float32(rl.GetScreenWidth()) - 300) / 2.0, Y: float32(rl.GetScreenHeight()) / 2.0} + + var innerRadius, outerRadius float32 = 80.0, 190.0 + var startAngle, endAngle float32 = 0.0, 360 + var segments float32 = 0.0 + + drawRing, drawRingLines, drawSectorLines := true, false, false + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + // NOTE: All variables update happens inside GUI control functions + + // Draw + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.DrawLine(500, 0, 500, int32(rl.GetScreenHeight()), rl.Fade(rl.LightGray, 0.6)) + rl.DrawRectangle(500, 0, int32(rl.GetScreenWidth())-500, int32(rl.GetScreenHeight()), + rl.Fade(rl.LightGray, 0.3)) + + if drawRing { + rl.DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, int32( + segments), rl.Fade(rl.Maroon, 0.3)) + } + if drawRingLines { + rl.DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, int32( + segments), rl.Fade(rl.Black, 0.4)) + } + if drawSectorLines { + rl.DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, int32( + segments), rl.Fade(rl.Black, 0.4)) + } + + // Draw GUI controls + //------------------------------------------------------------------------------ + startAngle = gui.Slider(rl.Rectangle{ + X: 600, Y: 40, Width: 120, Height: 20, + }, "StartAngle", fmt.Sprintf("%.2f", startAngle), startAngle, -450, 450) + endAngle = gui.Slider(rl.Rectangle{ + X: 600, Y: 70, Width: 120, Height: 20, + }, "EndAngle", fmt.Sprintf("%.2f", endAngle), endAngle, -450, 450) + + innerRadius = gui.Slider(rl.Rectangle{ + X: 600, Y: 140, Width: 120, Height: 20, + }, "InnerRadius", fmt.Sprintf("%.2f", innerRadius), innerRadius, 0, 100) + outerRadius = gui.Slider(rl.Rectangle{ + X: 600, Y: 170, Width: 120, Height: 20, + }, "OuterRadius", fmt.Sprintf("%.2f", outerRadius), outerRadius, 0, 200) + + segments = gui.Slider(rl.Rectangle{ + X: 600, Y: 240, Width: 120, Height: 20, + }, "Segments", fmt.Sprintf("%.2f", segments), segments, 0, 100) + + drawRing = gui.CheckBox(rl.Rectangle{ + X: 600, Y: 320, Width: 20, Height: 20, + }, "Draw Ring", drawRing) + drawRingLines = gui.CheckBox(rl.Rectangle{ + X: 600, Y: 350, Width: 20, Height: 20, + }, "Draw Ring Lines", drawRingLines) + drawSectorLines = gui.CheckBox(rl.Rectangle{ + X: 600, Y: 380, Width: 20, Height: 20, + }, "Draw Sector Lines", drawSectorLines) + + minSegments := ceil((endAngle - startAngle) / 90) + var color = rl.DarkGray + if segments >= minSegments { + color = rl.Maroon + } + var mode = "AUTO" + if segments >= minSegments { + mode = "MANUAL" + } + rl.DrawText(fmt.Sprintf("MODE: %s", mode), 600, 270, 10, color) + rl.DrawFPS(10, 10) + + rl.EndDrawing() + } + + // De-Initialization + rl.CloseWindow() // Close window and OpenGL context +} + +func ceil(value float32) float32 { + return float32(math.Ceil(float64(value))) +} From 1f7ddfca095596571b217f4d698b3db23a96da6c Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 24 Oct 2024 17:21:11 +0200 Subject: [PATCH 129/278] New example : shapes/draw_circle_sector --- examples/shapes/draw_circle_sector/main.go | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 examples/shapes/draw_circle_sector/main.go diff --git a/examples/shapes/draw_circle_sector/main.go b/examples/shapes/draw_circle_sector/main.go new file mode 100644 index 0000000..fc3f92c --- /dev/null +++ b/examples/shapes/draw_circle_sector/main.go @@ -0,0 +1,88 @@ +/******************************************************************************************* + * + * raylib [shapes] example - draw circle sector (with gui options) + * + * Example originally created with raylib 2.5, last time updated with raylib 2.5 + * + * Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) + * + * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, + * BSD-like license that allows static linking with closed source software + * + * Copyright (c) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) + * + ********************************************************************************************/ +package main + +import ( + "fmt" + "math" + + gui "github.com/gen2brain/raylib-go/raygui" + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw circle sector") + + center := rl.Vector2{X: (float32(screenWidth) - 300) / 2.0, Y: float32(screenHeight / 2.0)} + var outerRadius, startAngle, endAngle, segments, minSegments float32 = 180.0, 0.0, 180.0, 10.0, 4 + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Draw + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.DrawLine(500, 0, 500, screenWidth, rl.Fade(rl.LightGray, 0.6)) + rl.DrawRectangle(500, 0, screenWidth-500, screenHeight, rl.Fade(rl.LightGray, 0.3)) + + rl.DrawCircleSector(center, outerRadius, startAngle, endAngle, int32(segments), rl.Fade(rl.Maroon, 0.3)) + rl.DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, int32(segments), rl.Fade(rl.Maroon, 0.6)) + + // Draw GUI controls + r := rl.Rectangle{X: 600, Y: 40, Width: 120, Height: 20} + msg := fmt.Sprintf("%.2f", startAngle) + startAngle = gui.Slider(r, "StartAngle", msg, startAngle, 0, 720) + + r = rl.Rectangle{X: 600, Y: 70, Width: 120, Height: 20} + msg = fmt.Sprintf("%.2f", endAngle) + endAngle = gui.Slider(r, "EndAngle", msg, endAngle, 0, 720) + + r = rl.Rectangle{X: 600, Y: 140, Width: 120, Height: 20} + msg = fmt.Sprintf("%.2f", outerRadius) + outerRadius = gui.Slider(r, "Radius", msg, outerRadius, 0, 200) + + r = rl.Rectangle{X: 600, Y: 170, Width: 120, Height: 20} + msg = fmt.Sprintf("%.2f", segments) + segments = gui.Slider(r, "Segments", msg, segments, 0, 100) + + minSegments = calculateMinSegments(startAngle, endAngle) + text := "MODE: AUTO" + color := rl.DarkGray + if segments >= minSegments { + text = "MODE: MANUAL" + color = rl.Maroon + } + rl.DrawText(text, 600, 200, 10, color) + + rl.DrawFPS(10, 10) + + rl.EndDrawing() + } + + // De-Initialization + rl.CloseWindow() // Close window and OpenGL context +} + +func calculateMinSegments(startAngle, endAngle float32) float32 { + return float32(math.Trunc(math.Ceil((float64(endAngle - startAngle)) / 90))) +} From 8d78eefeee41e21e9d1a476fb2ce9891ff10e97a Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 31 Oct 2024 13:06:59 +0100 Subject: [PATCH 130/278] New example: font_filters --- examples/text/font_filters/KAISG.ttf | Bin 0 -> 79912 bytes examples/text/font_filters/main.go | 125 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 examples/text/font_filters/KAISG.ttf create mode 100644 examples/text/font_filters/main.go diff --git a/examples/text/font_filters/KAISG.ttf b/examples/text/font_filters/KAISG.ttf new file mode 100644 index 0000000000000000000000000000000000000000..04478b25ceb5a5e0e74b0d6da7dbb16c68fdbb32 GIT binary patch literal 79912 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 literal 0 HcmV?d00001 diff --git a/examples/text/font_filters/main.go b/examples/text/font_filters/main.go new file mode 100644 index 0000000..dc6bb82 --- /dev/null +++ b/examples/text/font_filters/main.go @@ -0,0 +1,125 @@ +/******************************************************************************************* +* +* raylib [text] example - Font filters +* +* NOTE: After font loading, font texture atlas filter could be configured for a softer +* display of the font when scaling it to different sizes, that way, it's not required +* to generate multiple fonts at multiple sizes (as long as the scaling is not very different) +* +* Example originally created with raylib 1.3, last time updated with raylib 4.2 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "fmt" + "path/filepath" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - font filters") + msg := "Loaded Font" + + // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) + + // TTF Font loading with custom generation parameters + font := rl.LoadFontEx("KAISG.ttf", 96, nil, 0) + + // Generate mipmap levels to use trilinear filtering + // NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR + rl.GenTextureMipmaps(&font.Texture) + + fontSize := float32(font.BaseSize) + fontPosition := rl.Vector2{X: 40.0, Y: screenHeight/2.0 - 80.0} + textSize := rl.Vector2{} + + // Setup texture scaling filter + rl.SetTextureFilter(font.Texture, rl.FilterPoint) + currentFontFilter := 0 // TEXTURE_FILTER_POINT + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + for !rl.WindowShouldClose() { // Detect window close button or ESC key + fontSize += rl.GetMouseWheelMove() * 4.0 + + // Choose font texture filter method + if rl.IsKeyPressed(rl.KeyOne) { + rl.SetTextureFilter(font.Texture, rl.FilterPoint) + currentFontFilter = 0 + } else if rl.IsKeyPressed(rl.KeyTwo) { + rl.SetTextureFilter(font.Texture, rl.FilterBilinear) + currentFontFilter = 1 + } else if rl.IsKeyPressed(rl.KeyThree) { + // NOTE: Trilinear filter won't be noticed on 2D drawing + rl.SetTextureFilter(font.Texture, rl.FilterTrilinear) + currentFontFilter = 2 + } + + textSize = rl.MeasureTextEx(font, msg, fontSize, 0) + + if rl.IsKeyDown(rl.KeyLeft) { + fontPosition.X -= 10 + } else if rl.IsKeyDown(rl.KeyRight) { + fontPosition.X += 10 + } + + // Load a dropped TTF file dynamically (at current fontSize) + if rl.IsFileDropped() { + droppedFiles := rl.LoadDroppedFiles() + + // NOTE: We only support first ttf file dropped + if filepath.Ext(droppedFiles[0]) == ".ttf" { + rl.UnloadFont(font) + font = rl.LoadFontEx(droppedFiles[0], int32(fontSize), nil, 0) + } + + rl.UnloadDroppedFiles() // Unload file paths from memory + } + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawText("Use mouse wheel to change font size", 20, 20, 10, rl.Gray) + rl.DrawText("Use KEY_RIGHT and KEY_LEFT to move text", 20, 40, 10, rl.Gray) + rl.DrawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, rl.Gray) + rl.DrawText("Drop a new TTF font for dynamic loading", 20, 80, 10, rl.DarkGray) + rl.DrawTextEx(font, msg, fontPosition, fontSize, 0, rl.Black) + + // TODO: It seems texSize measurement is not accurate due to chars offsets... + //rl.DrawRectangleLines(fontPosition.X, fontPosition.Y, textSize.X, textSize.Y, rl.Red); + + rl.DrawRectangle(0, screenHeight-80, screenWidth, 80, rl.LightGray) + text := fmt.Sprintf("Font size: %02.02f", fontSize) + rl.DrawText(text, 20, screenHeight-50, 10, rl.DarkGray) + text = fmt.Sprintf("Text size: [%02.02f, %02.02f]", textSize.X, textSize.Y) + rl.DrawText(text, 20, screenHeight-30, 10, rl.DarkGray) + rl.DrawText("CURRENT TEXTURE FILTER:", 250, 400, 20, rl.Gray) + + switch currentFontFilter { + case 0: + rl.DrawText("POINT", 570, 400, 20, rl.Black) + case 1: + rl.DrawText("BILINEAR", 570, 400, 20, rl.Black) + case 2: + rl.DrawText("TRILINEAR", 570, 400, 20, rl.Black) + } + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadFont(font) // Font unloading + rl.CloseWindow() // Close window and OpenGL context +} From c3e8a0f84a95e657dd42c6da992d0eb962968baa Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 31 Oct 2024 13:34:37 +0100 Subject: [PATCH 131/278] New example: font_loading --- examples/text/font_loading/main.go | 79 +++++++++ examples/text/font_loading/pixantiqua.fnt | 188 ++++++++++++++++++++++ examples/text/font_loading/pixantiqua.png | Bin 0 -> 4531 bytes examples/text/font_loading/pixantiqua.ttf | Bin 0 -> 35408 bytes 4 files changed, 267 insertions(+) create mode 100644 examples/text/font_loading/main.go create mode 100644 examples/text/font_loading/pixantiqua.fnt create mode 100644 examples/text/font_loading/pixantiqua.png create mode 100644 examples/text/font_loading/pixantiqua.ttf diff --git a/examples/text/font_loading/main.go b/examples/text/font_loading/main.go new file mode 100644 index 0000000..28cb4a7 --- /dev/null +++ b/examples/text/font_loading/main.go @@ -0,0 +1,79 @@ +/******************************************************************************************* +* +* raylib [text] example - Font loading +* +* NOTE: raylib can load fonts from multiple input file formats: +* +* - TTF/OTF > Sprite font atlas is generated on loading, user can configure +* some of the generation parameters (size, characters to include) +* - BMFonts > Angel code font fileformat, sprite font image must be provided +* together with the .fnt file, font generation cna not be configured +* - XNA Spritefont > Sprite font image, following XNA Spritefont conventions, +* Characters in image must follow some spacing and order rules +* +* Example originally created with raylib 1.4, last time updated with raylib 3.0 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2016-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import rl "github.com/gen2brain/raylib-go/raylib" + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - font loading") + + // Define characters to draw + // NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally + msg := "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz" + + "{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ" + + // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) + + // BMFont (AngelCode) : Font data and image atlas have been generated using external program + fontBm := rl.LoadFont("pixantiqua.fnt") + + // TTF font : Font data and atlas are generated directly from TTF + // NOTE: We define a font base size of 32 pixels tall and up-to 250 characters + fontTtf := rl.LoadFontEx("pixantiqua.ttf", 32, nil, 250) + + rl.SetTextLineSpacing(16) // Set line spacing for multiline text (when line breaks are included '\n') + + useTtf := false + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + useTtf = rl.IsKeyDown(rl.KeySpace) + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawText("Hold SPACE to use TTF generated font", 20, 20, 20, rl.LightGray) + + if !useTtf { + rl.DrawTextEx(fontBm, msg, rl.Vector2{X: 20.0, Y: 100.0}, float32(fontBm.BaseSize), 2, rl.Maroon) + rl.DrawText("Using BMFont (Angelcode) imported", 20, int32(rl.GetScreenHeight())-30, 20, rl.Gray) + } else { + rl.DrawTextEx(fontTtf, msg, rl.Vector2{X: 20.0, Y: 100.0}, float32(fontTtf.BaseSize), 2, rl.Lime) + rl.DrawText("Using TTF font generated", 20, int32(rl.GetScreenHeight())-30, 20, rl.Gray) + } + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadFont(fontBm) // AngelCode Font unloading + rl.UnloadFont(fontTtf) // TTF Font unloading + rl.CloseWindow() // Close window and OpenGL context +} diff --git a/examples/text/font_loading/pixantiqua.fnt b/examples/text/font_loading/pixantiqua.fnt new file mode 100644 index 0000000..fd9f9db --- /dev/null +++ b/examples/text/font_loading/pixantiqua.fnt @@ -0,0 +1,188 @@ +info face="PixAntiqua" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=2,2,2,2 spacing=2,2 outline=0 +common lineHeight=32 base=27 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4 +page id=0 file="pixantiqua.png" +chars count=184 +char id=32 x=9 y=304 width=7 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=33 x=391 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=34 x=240 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=35 x=468 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=36 x=152 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=37 x=176 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=38 x=303 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=39 x=495 y=266 width=8 height=36 xoffset=-3 yoffset=-2 xadvance=5 page=0 chnl=15 +char id=40 x=256 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=199 x=432 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=200 x=126 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=201 x=147 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=202 x=288 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=203 x=189 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=204 x=468 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=205 x=486 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=206 x=0 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=207 x=72 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=208 x=329 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=209 x=277 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=210 x=182 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=211 x=26 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=41 x=272 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=42 x=288 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=43 x=414 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=44 x=378 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=45 x=414 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=46 x=443 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=47 x=392 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=48 x=485 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=49 x=450 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=50 x=21 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=51 x=42 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=59 x=456 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=60 x=168 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=61 x=309 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=62 x=336 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=63 x=315 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=64 x=364 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=65 x=390 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=66 x=120 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=67 x=144 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=68 x=168 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=69 x=294 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=52 x=488 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=53 x=63 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=54 x=24 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=55 x=48 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=56 x=72 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=57 x=96 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=58 x=404 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=70 x=252 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=71 x=192 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=72 x=78 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=78 x=78 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=79 x=355 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=80 x=264 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=81 x=381 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=82 x=288 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=83 x=312 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=91 x=144 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=92 x=108 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=93 x=304 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=94 x=34 y=0 width=32 height=36 xoffset=-3 yoffset=-2 xadvance=29 page=0 chnl=15 +char id=95 x=231 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=96 x=442 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=97 x=408 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=98 x=432 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=99 x=210 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=84 x=336 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=85 x=360 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=86 x=0 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=87 x=68 y=0 width=30 height=36 xoffset=-3 yoffset=-2 xadvance=27 page=0 chnl=15 +char id=88 x=26 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=89 x=384 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=90 x=84 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=100 x=456 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=101 x=480 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=102 x=54 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=103 x=0 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=104 x=24 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=105 x=469 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=106 x=18 y=266 width=16 height=36 xoffset=-8 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=107 x=48 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=108 x=417 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=109 x=161 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=110 x=72 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=111 x=96 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=117 x=192 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=118 x=216 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=119 x=248 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=120 x=240 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=121 x=264 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=122 x=288 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=123 x=432 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=124 x=365 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=125 x=378 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=126 x=393 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=127 x=132 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=160 x=0 y=304 width=7 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=161 x=352 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=162 x=351 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=163 x=336 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=165 x=360 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=167 x=384 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=169 x=433 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=170 x=224 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=171 x=105 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=172 x=0 y=0 width=32 height=36 xoffset=-3 yoffset=-2 xadvance=29 page=0 chnl=15 +char id=173 x=494 y=38 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=174 x=52 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=175 x=52 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=176 x=126 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=177 x=435 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=178 x=320 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=179 x=336 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=181 x=459 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=112 x=120 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=113 x=144 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=114 x=396 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=115 x=168 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=116 x=36 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=182 x=408 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=183 x=498 y=190 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=185 x=192 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=186 x=208 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=187 x=477 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=191 x=456 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=192 x=407 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=193 x=234 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=194 x=416 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=195 x=156 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=196 x=130 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=197 x=104 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=198 x=190 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=212 x=0 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=213 x=338 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=214 x=312 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=215 x=357 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=216 x=286 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=217 x=456 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=218 x=480 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=219 x=0 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=220 x=24 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=221 x=48 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=222 x=260 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=223 x=72 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=224 x=96 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=225 x=120 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=226 x=144 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=227 x=168 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=228 x=192 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=229 x=216 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=230 x=219 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=231 x=372 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=73 x=90 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=74 x=216 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=75 x=240 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=76 x=273 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=77 x=100 y=0 width=30 height=36 xoffset=-3 yoffset=-2 xadvance=27 page=0 chnl=15 +char id=232 x=312 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=233 x=240 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=234 x=264 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=235 x=104 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=236 x=430 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=237 x=482 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=238 x=160 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=239 x=176 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=240 x=128 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=241 x=200 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=242 x=224 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=243 x=248 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=244 x=272 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=245 x=296 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=246 x=320 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=247 x=330 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=248 x=208 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=249 x=344 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=250 x=368 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=251 x=416 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=252 x=440 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=253 x=464 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=254 x=0 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=255 x=0 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 diff --git a/examples/text/font_loading/pixantiqua.png b/examples/text/font_loading/pixantiqua.png new file mode 100644 index 0000000000000000000000000000000000000000..2aa2870f3bda380705f8ae2a15f1e52896e5bdea GIT binary patch literal 4531 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 E1I+QH8~^|S literal 0 HcmV?d00001 diff --git a/examples/text/font_loading/pixantiqua.ttf b/examples/text/font_loading/pixantiqua.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e012875da0aeb2a662409ca5f2ae12cbab2213d0 GIT binary patch literal 35408 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 Date: Sun, 3 Nov 2024 12:29:12 +0100 Subject: [PATCH 132/278] golang.org/x/exp is not in your go.mod file --- examples/go.mod | 1 + examples/go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/examples/go.mod b/examples/go.mod index e1f47a1..948c9e4 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -21,5 +21,6 @@ require ( require ( github.com/ebitengine/purego v0.7.1 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/sys v0.20.0 // indirect ) diff --git a/examples/go.sum b/examples/go.sum index 19ef93f..ed625b8 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -4,5 +4,7 @@ github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI= github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI= github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b/go.mod h1:kvKwD9codtns5mvpA53V3vLnqFb/Ahcu8zgkGM0SIbI= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= From 893dfa5f8539e07cd9a8118d3b54ae4ad55798dc Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 3 Nov 2024 15:13:14 +0100 Subject: [PATCH 133/278] GenImageFontAtlas function added to cgo version as well --- raylib/rtext.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/raylib/rtext.go b/raylib/rtext.go index 25f980d..d1ffd2e 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -223,3 +223,13 @@ func GetGlyphAtlasRec(font Font, codepoint int32) Rectangle { v := newRectangleFromPointer(unsafe.Pointer(&ret)) return v } + +// GenImageFontAtlas - Generate image font atlas using chars info +func GenImageFontAtlas(glyphs []GlyphInfo, glyphRecs []*Rectangle, fontSize int32, padding int32, packMethod int32) Image { + cglyphs := (*C.GlyphInfo)(unsafe.Pointer(&glyphs[0])) + cglyphRecs := (**C.Rectangle)(unsafe.Pointer(&glyphRecs[0])) + cglyphCount := C.int(len(glyphs)) + ret := C.GenImageFontAtlas(cglyphs, cglyphRecs, cglyphCount, C.int(fontSize), C.int(padding), C.int(packMethod)) + v := newImageFromPointer(unsafe.Pointer(&ret)) + return *v +} From 735af12e7fc9469d536d1f751a4ca7b6b99dfcfd Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 3 Nov 2024 15:36:07 +0100 Subject: [PATCH 134/278] update LoadFontData: codePoints can now be nil, codepointCount defaults to 95 (like C raylib does) --- raylib/raylib_purego.go | 7 +++++-- raylib/rtext.go | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/raylib/raylib_purego.go b/raylib/raylib_purego.go index 73f83bb..e94af0c 100644 --- a/raylib/raylib_purego.go +++ b/raylib/raylib_purego.go @@ -2900,9 +2900,12 @@ func IsFontReady(font Font) bool { } // LoadFontData - Load font data for further use -func LoadFontData(fileData []byte, fontSize int32, codepoints []rune, typ int32) []GlyphInfo { +func LoadFontData(fileData []byte, fontSize int32, codepoints []rune, codepointCount, typ int32) []GlyphInfo { dataSize := int32(len(fileData)) - codepointCount := int32(len(codepoints)) + // In case no chars count provided, default to 95 + if codepointCount <= 0 { + codepointCount = 95 + } ret := loadFontData(fileData, dataSize, fontSize, codepoints, codepointCount, typ) return unsafe.Slice(ret, codepointCount) } diff --git a/raylib/rtext.go b/raylib/rtext.go index d1ffd2e..1e0c305 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -101,12 +101,16 @@ func IsFontReady(font Font) bool { } // LoadFontData - Load font data for further use -func LoadFontData(fileData []byte, fontSize int32, codePoints []int32, typ int32) []GlyphInfo { +func LoadFontData(fileData []byte, fontSize int32, codePoints []rune, codepointCount, typ int32) []GlyphInfo { cfileData := (*C.uchar)(unsafe.Pointer(&fileData[0])) cdataSize := (C.int)(len(fileData)) cfontSize := (C.int)(fontSize) - ccodePoints := (*C.int)(unsafe.Pointer(&codePoints[0])) - ccodePointCount := (C.int)(len(codePoints)) + ccodePoints := (*C.int)(unsafe.SliceData(codePoints)) + // In case no chars count provided, default to 95 + if codepointCount <= 0 { + codepointCount = 95 + } + ccodePointCount := (C.int)(codepointCount) ctype := (C.int)(typ) ret := C.LoadFontData(cfileData, cdataSize, cfontSize, ccodePoints, ccodePointCount, ctype) v := unsafe.Slice((*GlyphInfo)(unsafe.Pointer(ret)), ccodePointCount) From 549dbcf4d846584abec4960b01b8b40f6071eee5 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 3 Nov 2024 15:38:02 +0100 Subject: [PATCH 135/278] SDF-font loading example added --- examples/text/font_sdf/AnonymousPro-Bold.ttf | Bin 0 -> 107832 bytes examples/text/font_sdf/OFL.txt | 94 ++++++++++++++++ examples/text/font_sdf/main.go | 106 +++++++++++++++++++ examples/text/font_sdf/sdf.fs | 26 +++++ 4 files changed, 226 insertions(+) create mode 100644 examples/text/font_sdf/AnonymousPro-Bold.ttf create mode 100644 examples/text/font_sdf/OFL.txt create mode 100644 examples/text/font_sdf/main.go create mode 100644 examples/text/font_sdf/sdf.fs diff --git a/examples/text/font_sdf/AnonymousPro-Bold.ttf b/examples/text/font_sdf/AnonymousPro-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f14c18c15686555f87d27352e33d071dc642ca82 GIT binary patch literal 107832 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 Al>h($ literal 0 HcmV?d00001 diff --git a/examples/text/font_sdf/OFL.txt b/examples/text/font_sdf/OFL.txt new file mode 100644 index 0000000..d89cf45 --- /dev/null +++ b/examples/text/font_sdf/OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2009, Mark Simonson (http://www.ms-studio.com, mark@marksimonson.com), +with Reserved Font Name Anonymous Pro. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/examples/text/font_sdf/main.go b/examples/text/font_sdf/main.go new file mode 100644 index 0000000..a626512 --- /dev/null +++ b/examples/text/font_sdf/main.go @@ -0,0 +1,106 @@ +package main + +import ( + _ "embed" + "fmt" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +//go:embed AnonymousPro-Bold.ttf +var fileData []byte + +func main() { + // Initialization + const screenWidth, screenHeight = 800, 450 + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - SDF fonts") + defer rl.CloseWindow() // Close window and OpenGL context + + // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) + + const msg = "Signed Distance Fields" + + // Default font generation from TTF font + fontDefault := rl.Font{BaseSize: 16, CharsCount: 95} + defer rl.UnloadFont(fontDefault) // Default font unloading + + // Loading font data from memory data + // Parameters > font size: 16, no glyphs array provided (nil), glyphs count: 95 (autogenerate chars array) + glyphs := rl.LoadFontData(fileData, 16, nil, 95, rl.FontDefault) + fontDefault.Chars = &glyphs[0] + + // Parameters > font size: 16, glyphs padding in image: 4 px, pack method: 0 (default) + atlas := rl.GenImageFontAtlas(unsafe.Slice(fontDefault.Chars, fontDefault.CharsCount), unsafe.Slice(&fontDefault.Recs, fontDefault.CharsCount), 16, 4, 0) + fontDefault.Texture = rl.LoadTextureFromImage(&atlas) + rl.UnloadImage(&atlas) + + // SDF font generation from TTF font + fontSDF := rl.Font{BaseSize: 16, CharsCount: 95} + defer rl.UnloadFont(fontSDF) // SDF font unloading + + // Parameters > font size: 16, no glyphs array provided (nil), glyphs count: 0 (defaults to 95) + glyphsSDF := rl.LoadFontData(fileData, 16, nil, 0, rl.FontSdf) + fontSDF.Chars = &glyphsSDF[0] + // Parameters > font size: 16, glyphs padding in image: 0 px, pack method: 1 (Skyline algorithm) + atlas = rl.GenImageFontAtlas(unsafe.Slice(fontSDF.Chars, fontSDF.CharsCount), unsafe.Slice(&fontSDF.Recs, fontSDF.CharsCount), 16, 0, 1) + fontSDF.Texture = rl.LoadTextureFromImage(&atlas) + rl.UnloadImage(&atlas) + + // Load SDF required shader (we use default vertex shader) + shader := rl.LoadShader("", "sdf.fs") + defer rl.UnloadShader(shader) // Unload SDF shader + rl.SetTextureFilter(fontSDF.Texture, rl.FilterBilinear) // Required for SDF font + + fontPosition := rl.NewVector2(40, screenHeight/2.0-50) + textSize := rl.Vector2Zero() + fontSize := float32(16) + currentFont := 0 // 0 - fontDefault, 1 - fontSDF + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + fontSize += rl.GetMouseWheelMove() * 8.0 + + if fontSize < 6 { + fontSize = 6 + } + + if rl.IsKeyDown(rl.KeySpace) { + currentFont = 1 + textSize = rl.MeasureTextEx(fontSDF, msg, fontSize, 0) + } else { + currentFont = 0 + textSize = rl.MeasureTextEx(fontDefault, msg, fontSize, 0) + } + + fontPosition.X = float32(rl.GetScreenWidth()/2) - textSize.X/2 + fontPosition.Y = float32(rl.GetScreenHeight()/2) - textSize.Y/2 + 80 + + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + if currentFont == 1 { + // NOTE: SDF fonts require a custom SDf shader to compute fragment color + rl.BeginShaderMode(shader) // Activate SDF font shader + rl.DrawTextEx(fontSDF, msg, fontPosition, fontSize, 0, rl.Black) + rl.EndShaderMode() // Activate our default shader for next drawings + rl.DrawTexture(fontSDF.Texture, 10, 10, rl.Black) + rl.DrawText("SDF!", 320, 20, 80, rl.Red) + } else { + rl.DrawTextEx(fontDefault, msg, fontPosition, fontSize, 0, rl.Black) + rl.DrawTexture(fontDefault.Texture, 10, 10, rl.Black) + rl.DrawText("default font", 315, 40, 30, rl.Gray) + } + + rl.DrawText("FONT SIZE: 16.0", int32(rl.GetScreenWidth()-240), 20, 20, rl.DarkGray) + rl.DrawText(fmt.Sprintf("RENDER SIZE: %02.02f", fontSize), int32(rl.GetScreenWidth()-240), 50, 20, rl.DarkGray) + rl.DrawText("Use MOUSE WHEEL to SCALE TEXT!", int32(rl.GetScreenWidth()-240), 90, 10, rl.DarkGray) + + rl.DrawText("HOLD SPACE to USE SDF FONT VERSION!", 340, int32(rl.GetScreenHeight()-30), 20, rl.Maroon) + + rl.EndDrawing() + + } +} diff --git a/examples/text/font_sdf/sdf.fs b/examples/text/font_sdf/sdf.fs new file mode 100644 index 0000000..545f450 --- /dev/null +++ b/examples/text/font_sdf/sdf.fs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + // NOTE: Calculate alpha using signed distance field (SDF) + float distanceFromOutline = texture(texture0, fragTexCoord).a - 0.5; + float distanceChangePerFragment = length(vec2(dFdx(distanceFromOutline), dFdy(distanceFromOutline))); + float alpha = smoothstep(-distanceChangePerFragment, distanceChangePerFragment, distanceFromOutline); + + // Calculate final fragment color + finalColor = vec4(fragColor.rgb, fragColor.a*alpha); +} From 8c4ce9e206093e9f083e068f46a8890f7e2d5ce5 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 3 Nov 2024 15:40:48 +0100 Subject: [PATCH 136/278] remove trailing whitespace and carriage return in License file --- examples/text/font_sdf/OFL.txt | 188 ++++++++++++++++----------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/examples/text/font_sdf/OFL.txt b/examples/text/font_sdf/OFL.txt index d89cf45..45b11f5 100644 --- a/examples/text/font_sdf/OFL.txt +++ b/examples/text/font_sdf/OFL.txt @@ -1,94 +1,94 @@ -Copyright (c) 2009, Mark Simonson (http://www.ms-studio.com, mark@marksimonson.com), -with Reserved Font Name Anonymous Pro. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -https://openfontlicense.org - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. +Copyright (c) 2009, Mark Simonson (http://www.ms-studio.com, mark@marksimonson.com), +with Reserved Font Name Anonymous Pro. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. From 44e76696ccb25529cbe81f8729f06fc6207f40a3 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Sun, 3 Nov 2024 17:04:02 +0100 Subject: [PATCH 137/278] New example: input_box --- examples/text/input_box/main.go | 122 ++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 examples/text/input_box/main.go diff --git a/examples/text/input_box/main.go b/examples/text/input_box/main.go new file mode 100644 index 0000000..75d23f0 --- /dev/null +++ b/examples/text/input_box/main.go @@ -0,0 +1,122 @@ +/******************************************************************************************* + * + * raylib [text] example - Input Box + * + * Example originally created with raylib 1.7, last time updated with raylib 3.5 + * + * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, + * BSD-like license that allows static linking with closed source software + * + * Copyright (c) 2017-2024 Ramon Santamaria (@raysan5) + * + ********************************************************************************************/ +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + maxInputChars = 9 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - input box") + + var name [maxInputChars]rune + var letterCount, framesCounter int32 + var mouseOnText bool + + textBox := rl.Rectangle{X: screenWidth/2.0 - 100, Y: 180, Width: 225, Height: 50} + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + mouseOnText = rl.CheckCollisionPointRec(rl.GetMousePosition(), textBox) + + if mouseOnText { + // Set the window's cursor to the I-Beam + rl.SetMouseCursor(rl.MouseCursorIBeam) + + // Get char pressed (unicode character) on the queue + key := rl.GetCharPressed() + + // Check if more characters have been pressed on the same frame + for key > 0 { + // NOTE: Only allow keys in range [32..125] + if (key >= 32) && (key <= 125) && (letterCount < maxInputChars) { + name[letterCount] = key + letterCount++ + } + + key = rl.GetCharPressed() // Check next character in the queue + } + + if rl.IsKeyPressed(rl.KeyBackspace) { + letterCount-- + if letterCount < 0 { + letterCount = 0 + } + name[letterCount] = 0 + } + } else { + rl.SetMouseCursor(rl.MouseCursorDefault) + } + + if mouseOnText { + framesCounter++ + } else { + framesCounter = 0 + } + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawText("PLACE MOUSE OVER INPUT BOX!", 240, 140, 20, rl.Gray) + + rl.DrawRectangleRec(textBox, rl.LightGray) + col := rl.DarkGray + if mouseOnText { + col = rl.Red + } + rl.DrawRectangleLines(int32(textBox.X), int32(textBox.Y), int32(textBox.Width), int32(textBox.Height), col) + + rl.DrawText(getString(name), int32(textBox.X)+5, int32(textBox.Y)+8, 40, rl.Maroon) + text := fmt.Sprintf("INPUT CHARS: %d/%d", letterCount, maxInputChars) + rl.DrawText(text, 315, 250, 20, rl.DarkGray) + + if mouseOnText { + if letterCount < maxInputChars { + // Draw blinking underscore char + if ((framesCounter / 20) % 2) == 0 { + x := int32(textBox.X) + 8 + rl.MeasureText(getString(name), 40) + rl.DrawText("_", x, int32(textBox.Y)+12, 40, rl.Maroon) + } + } else { + rl.DrawText("Press BACKSPACE to delete chars...", 230, 300, 20, rl.Gray) + } + } + + rl.EndDrawing() + } + + // De-Initialization + rl.CloseWindow() // Close window and OpenGL context +} + +func getString(r [maxInputChars]rune) string { + var s string + for _, char := range r { + if char == 0 { + return s + } + s += string(char) + } + return s +} From b7ac6957d35e3db3f154d7e011b50336550311c3 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Mon, 4 Nov 2024 14:02:36 +0100 Subject: [PATCH 138/278] New example: rectangle_bounds --- examples/text/rectangle_bounds/main.go | 282 +++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 examples/text/rectangle_bounds/main.go diff --git a/examples/text/rectangle_bounds/main.go b/examples/text/rectangle_bounds/main.go new file mode 100644 index 0000000..e020f03 --- /dev/null +++ b/examples/text/rectangle_bounds/main.go @@ -0,0 +1,282 @@ +/******************************************************************************************* +* +* raylib [text] example - Rectangle bounds +* +* Example originally created with raylib 2.5, last time updated with raylib 4.0 +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "unicode/utf8" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + MeasureState = 0 + DrawState = 1 +) + +func main() { + + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - draw text inside a rectangle") + + text := `Text cannot escape this container ...word wrap also works when active so here's a long text for testing. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet risus nullam eget felis eget.` + + resizing, wordWrap := false, true + + container := rl.Rectangle{X: 25.0, Y: 25.0, Width: screenWidth - 50.0, Height: screenHeight - 250.0} + resizer := rl.Rectangle{X: container.X + container.Width - 17, Y: container.Y + container.Height - 17, Width: 14, Height: 14} + + // Minimum width and height for the container rectangle + minWidth := float32(60.0) + minHeight := float32(60.0) + maxWidth := screenWidth - float32(50.0) + maxHeight := screenHeight - float32(160.0) + + lastMouse := rl.Vector2{} // Stores last mouse coordinates + borderColor := rl.Maroon // Container border color + font := rl.GetFontDefault() // Get default system font + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + if rl.IsKeyPressed(rl.KeySpace) { + wordWrap = !wordWrap + } + + mouse := rl.GetMousePosition() + + // Check if the mouse is inside the container and toggle border color + if rl.CheckCollisionPointRec(mouse, container) { + borderColor = rl.Fade(rl.Maroon, 0.4) + } else if !resizing { + borderColor = rl.Maroon + } + + // Container resizing logic + if resizing { + if rl.IsMouseButtonReleased(rl.MouseButtonLeft) { + resizing = false + } + + width := container.Width + (mouse.X - lastMouse.X) + height := container.Height + (mouse.Y - lastMouse.Y) + + container.Width = rl.Clamp(width, minWidth, maxWidth) + container.Height = rl.Clamp(height, minHeight, maxHeight) + } else { + // Check if we're resizing + if rl.IsMouseButtonDown(rl.MouseButtonLeft) && rl.CheckCollisionPointRec(mouse, resizer) { + resizing = true + } + } + + // Move resizer rectangle properly + resizer.X = container.X + container.Width - 17 + resizer.Y = container.Y + container.Height - 17 + + lastMouse = mouse // Update mouse + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawRectangleLinesEx(container, 3, borderColor) // Draw container border + + // Draw text in container (add some padding) + DrawTextBoxed(font, text, rl.Rectangle{X: container.X + 4, Y: container.Y + 4, Width: container.Width - 4, + Height: container.Height - 4}, 20.0, 2.0, wordWrap, rl.Gray) + + rl.DrawRectangleRec(resizer, borderColor) // Draw the resize box + + // Draw bottom info + rl.DrawRectangle(0, screenHeight-54, screenWidth, 54, rl.Gray) + rl.DrawRectangleRec(rl.Rectangle{X: 382.0, Y: screenHeight - 34.0, Width: 12.0, Height: 12.0}, rl.Maroon) + + rl.DrawText("Word Wrap: ", 313, screenHeight-115, 20, rl.Black) + if wordWrap { + rl.DrawText("ON", 447, screenHeight-115, 20, rl.Red) + } else { + rl.DrawText("OFF", 447, screenHeight-115, 20, rl.Black) + } + + rl.DrawText("Press [SPACE] to toggle word wrap", 218, screenHeight-86, 20, rl.Gray) + rl.DrawText("Click hold & drag the to resize the container", 155, screenHeight-38, 20, rl.RayWhite) + + rl.EndDrawing() + } + + // De-Initialization + rl.CloseWindow() // Close window and OpenGL context +} + +//-------------------------------------------------------------------------------------- +// Module functions definition +//-------------------------------------------------------------------------------------- + +// DrawTextBoxed draws text using font inside rectangle limits +func DrawTextBoxed(font rl.Font, text string, rec rl.Rectangle, fontSize, spacing float32, wordWrap bool, tint rl.Color) { + DrawTextBoxedSelectable(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, rl.White, rl.White) +} + +// DrawTextBoxedSelectable draws text using font inside rectangle limits with support for text selection +func DrawTextBoxedSelectable(font rl.Font, text string, rec rl.Rectangle, fontSize, spacing float32, + wordWrap bool, tint rl.Color, selectStart, selectLength int32, selectTint, selectBackTint rl.Color) { + + length := int32(utf8.RuneCountInString(text)) // Total length in bytes of the text, scanned by codepoints in loop + + // TextOffsetY : Offset between lines (on line break '\n') + // TextOffsetX : Offset X to next character to draw + var textOffsetY, textOffsetX float32 + + scaleFactor := fontSize / float32(font.BaseSize) // Character rectangle scaling factor + + // Word/character wrapping mechanism variables + state := DrawState + if wordWrap { + state = MeasureState + } + + // StartLine : Index where to begin drawing (where a line begins) + // EndLine : Index where to stop drawing (where a line ends) + // LastK : Holds last value of the character position + var startLine, endLine, lastk int32 = -1, -1, -1 + + for i, k := int32(0), int32(0); i < length; i, k = i+1, k+1 { + // Get next codepoint from byte string and glyph index in font + codepoint, width := utf8.DecodeRuneInString(text[i:]) + codepointByteCount := int32(width) + index := rl.GetGlyphIndex(font, codepoint) + + // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all the bad bytes using the '?' symbol moving one byte + if codepoint == 0x3f { + codepointByteCount = 1 + } + i += codepointByteCount - 1 + + var glyphWidth float32 + if codepoint != '\n' { + chars := unsafe.Slice(font.Chars, font.CharsCount) + if chars[index].AdvanceX == 0 { + glyphWidth = unsafe.Slice(font.Recs, font.CharsCount)[index].Width * scaleFactor + } else { + glyphWidth = float32(chars[index].AdvanceX) * scaleFactor + } + + if i+1 < length { + glyphWidth = glyphWidth + spacing + } + } + + // NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside the rec container + // We store this info in startLine and endLine, then we change states, draw the text between those two variables + // and change states again and again recursively until the end of the text (or until we get outside the container). + // When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately + // and begin drawing on the next line before we can get outside the container. + if state == MeasureState { + // TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more + // Ref: http://jkorpela.fi/chars/spaces.html + if (codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n') { + endLine = i + } + + if (textOffsetX + glyphWidth) > rec.Width { + if endLine < 1 { + endLine = i + } + + if i == endLine { + endLine -= codepointByteCount + } + if (startLine + codepointByteCount) == endLine { + endLine = i - codepointByteCount + } + + state = 1 - state // Toggle state between MeasureState and DrawState + } else if (i + 1) == length { + endLine = i + state = 1 - state // Toggle state between MeasureState and DrawState + } else if codepoint == '\n' { + state = 1 - state // Toggle state between MeasureState and DrawState + } + + if state == DrawState { + textOffsetX = 0 + i = startLine + glyphWidth = 0 + + // Save character position when we switch states + tmp := lastk + lastk = k - 1 + k = tmp + } + } else { + if codepoint == '\n' { + if !wordWrap { + textOffsetY += float32(font.BaseSize+font.BaseSize/2) * scaleFactor + textOffsetX = 0 + } + } else { + if !wordWrap && ((textOffsetX + glyphWidth) > rec.Width) { + textOffsetY += float32(font.BaseSize+font.BaseSize/2) * scaleFactor + textOffsetX = 0 + } + + // When text overflows rectangle height limit, just stop drawing + if (textOffsetY + float32(font.BaseSize)*scaleFactor) > rec.Height { + break + } + + // Draw selection background + isGlyphSelected := false + if (selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)) { + rl.DrawRectangleRec(rl.Rectangle{X: rec.X + textOffsetX - 1, Y: rec.Y + textOffsetY, Width: glyphWidth, + Height: float32(font.BaseSize) * scaleFactor}, selectBackTint) + isGlyphSelected = true + } + + // Draw current character glyph + if (codepoint != ' ') && (codepoint != '\t') { + col := tint + if isGlyphSelected { + col = selectTint + } + pos := rl.Vector2{X: rec.X + textOffsetX, Y: rec.Y + textOffsetY} + rl.DrawTextEx(font, string(codepoint), pos, fontSize, 0, col) + } + } + + if wordWrap && (i == endLine) { + textOffsetY += float32(font.BaseSize+font.BaseSize/2) * scaleFactor + textOffsetX = 0 + startLine = endLine + endLine = -1 + glyphWidth = 0 + selectStart += lastk - k + k = lastk + + state = 1 - state // Toggle state between MeasureState and DrawState + } + } + + if (textOffsetX != 0) || (codepoint != ' ') { // avoid leading spaces + textOffsetX += glyphWidth + } + } +} From e171bb37511ed34a693ef306b0d192fb72f77729 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:33:03 +0100 Subject: [PATCH 139/278] DrawTextCodepoint(s) functions added to cgo version --- raylib/rtext.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/raylib/rtext.go b/raylib/rtext.go index 1e0c305..6c91974 100644 --- a/raylib/rtext.go +++ b/raylib/rtext.go @@ -237,3 +237,25 @@ func GenImageFontAtlas(glyphs []GlyphInfo, glyphRecs []*Rectangle, fontSize int3 v := newImageFromPointer(unsafe.Pointer(&ret)) return *v } + +// DrawTextCodepoint - Draw one character (codepoint) +func DrawTextCodepoint(font Font, codepoint rune, position Vector2, fontSize float32, tint color.RGBA) { + cfont := font.cptr() + ccodepoint := (C.int)(codepoint) + cposition := position.cptr() + cfontSize := (C.float)(fontSize) + ctint := colorCptr(tint) + C.DrawTextCodepoint(*cfont, ccodepoint, *cposition, cfontSize, *ctint) +} + +// DrawTextCodepoints - Draw multiple character (codepoint) +func DrawTextCodepoints(font Font, codepoints []rune, position Vector2, fontSize float32, spacing float32, tint color.RGBA) { + cfont := font.cptr() + ccodepoints := (*C.int)(unsafe.SliceData(codepoints)) + ccodepointCount := C.int(len(codepoints)) + cposition := position.cptr() + cfontSize := (C.float)(fontSize) + cspacing := (C.float)(spacing) + ctint := colorCptr(tint) + C.DrawTextCodepoints(*cfont, ccodepoints, ccodepointCount, *cposition, cfontSize, cspacing, *ctint) +} From 52946ea71d8797de3ffb5bf6a5553d8968437079 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Thu, 7 Nov 2024 19:55:42 +0100 Subject: [PATCH 140/278] New example: text/unicode --- examples/text/unicode/main.go | 396 +++++++ examples/text/unicode/resources/dejavu.fnt | 1115 ++++++++++++++++++ examples/text/unicode/resources/dejavu.png | Bin 0 -> 102143 bytes examples/text/unicode/resources/noto_cjk.fnt | 580 +++++++++ examples/text/unicode/resources/noto_cjk.png | Bin 0 -> 92070 bytes examples/text/unicode/resources/symbola.fnt | 191 +++ examples/text/unicode/resources/symbola.png | Bin 0 -> 244613 bytes examples/text/unicode/unicode.go | 298 +++++ 8 files changed, 2580 insertions(+) create mode 100644 examples/text/unicode/main.go create mode 100644 examples/text/unicode/resources/dejavu.fnt create mode 100644 examples/text/unicode/resources/dejavu.png create mode 100644 examples/text/unicode/resources/noto_cjk.fnt create mode 100644 examples/text/unicode/resources/noto_cjk.png create mode 100644 examples/text/unicode/resources/symbola.fnt create mode 100644 examples/text/unicode/resources/symbola.png create mode 100644 examples/text/unicode/unicode.go diff --git a/examples/text/unicode/main.go b/examples/text/unicode/main.go new file mode 100644 index 0000000..99f51d3 --- /dev/null +++ b/examples/text/unicode/main.go @@ -0,0 +1,396 @@ +/******************************************************************************************* +* +* raylib [text] example - Unicode +* +* Example originally created with raylib 2.5, last time updated with raylib 4.0 +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2019-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "fmt" + "unicode/utf8" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 + emojiPerWidth = 8 + emojiPerHeight = 4 + MeasureState = 0 + DrawState = 1 +) + +type Messages struct { + text string + language string +} + +type Emoji struct { + index int32 // Index inside `emojiCodepoints` + message int32 // Message index + color rl.Color // Emoji color +} + +// Arrays that holds the random emojis +var emoji [emojiPerWidth * emojiPerHeight]Emoji +var hovered, selected int32 = -1, -1 + +func main() { + rl.SetConfigFlags(rl.FlagMsaa4xHint | rl.FlagVsyncHint) + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - unicode") + + // Load the font resources + // NOTE: fontAsian is for asian languages, + // fontEmoji is the emojis and fontDefault is used for everything else + fontDefault := rl.LoadFont("resources/dejavu.fnt") + fontAsian := rl.LoadFont("resources/noto_cjk.fnt") + fontEmoji := rl.LoadFont("resources/symbola.fnt") + + hoveredPos := rl.Vector2{} + selectedPos := rl.Vector2{} + + RandomizeEmoji() + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + + // Add a new set of emojis when SPACE is pressed + if rl.IsKeyPressed(rl.KeySpace) { + RandomizeEmoji() + } + + // Set the selected emoji + if rl.IsMouseButtonPressed(rl.MouseButtonLeft) && (hovered != -1) && (hovered != selected) { + selected = hovered + selectedPos = hoveredPos + } + + mouse := rl.GetMousePosition() + position := rl.Vector2{ + X: 28.8, + Y: 10.0, + } + hovered = -1 + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + // Draw random emojis in the background + for i := int32(0); i < emojiPerWidth*emojiPerHeight; i++ { + txt := emojiCodepoints[emoji[i].index : emoji[i].index+4] + emojiRect := rl.Rectangle{ + X: position.X, + Y: position.Y, + Width: float32(fontEmoji.BaseSize), + Height: float32(fontEmoji.BaseSize), + } + + if !rl.CheckCollisionPointRec(mouse, emojiRect) { + col := rl.Fade(rl.LightGray, 0.4) + if selected == i { + col = emoji[i].color + } + rl.DrawTextEx(fontEmoji, txt, position, float32(fontEmoji.BaseSize), 1.0, col) + } else { + rl.DrawTextEx(fontEmoji, txt, position, float32(fontEmoji.BaseSize), 1.0, emoji[i].color) + hovered = i + hoveredPos = position + } + + if (i != 0) && (i%emojiPerWidth == 0) { + position.Y += float32(fontEmoji.BaseSize) + 24.25 + position.X = 28.8 + } else { + position.X += float32(fontEmoji.BaseSize) + 28.8 + } + } + + // Draw the message when an emoji is selected + if selected != -1 { + message := emoji[selected].message + horizontalPadding := 20 + verticalPadding := 30 + font := fontDefault + + // Set correct font for asian languages + if messages[message].language == "Chinese" || + messages[message].language == "Korean" || + messages[message].language == "Japanese" { + font = fontAsian + } + + // Calculate size for the message box (approximate the height and width) + sz := rl.MeasureTextEx(font, messages[message].text, float32(font.BaseSize), 1.0) + if sz.X > 300 { + sz.Y *= sz.X / 300 + sz.X = 300 + } else if sz.X < 160 { + sz.X = 160 + } + + msgRect := rl.Rectangle{ + X: selectedPos.X - 38.8, + Y: selectedPos.Y, + Width: float32(2*horizontalPadding) + sz.X, + Height: float32(2*verticalPadding) + sz.Y, + } + msgRect.Y -= msgRect.Height + + // Coordinates for the chat bubble triangle + a := rl.Vector2{ + X: selectedPos.X, + Y: msgRect.Y + msgRect.Height, + } + b := rl.Vector2{ + X: a.X + 8, + Y: a.Y + 10, + } + c := rl.Vector2{ + X: a.X + 10, + Y: a.Y, + } + + // Don't go outside the screen + if msgRect.X < 10 { + msgRect.X += 28 + } + if msgRect.Y < 10 { + msgRect.Y = selectedPos.Y + 84 + a.Y = msgRect.Y + c.Y = a.Y + b.Y = a.Y - 10 + + // Swap values so we can actually render the triangle :( + a, b = b, a + } + + if msgRect.X+msgRect.Width > screenWidth { + msgRect.X -= (msgRect.X + msgRect.Width) - screenWidth + 10 + } + + // Draw chat bubble + rl.DrawRectangleRec(msgRect, emoji[selected].color) + rl.DrawTriangle(a, b, c, emoji[selected].color) + + // Draw the main text message + textRect := rl.Rectangle{ + X: msgRect.X + float32(horizontalPadding)/2, + Y: msgRect.Y + float32(verticalPadding)/2, + Width: msgRect.Width - float32(horizontalPadding), + Height: msgRect.Height, + } + DrawTextBoxed(font, messages[message].text, textRect, float32(font.BaseSize), 1.0, true, rl.White) + + // Draw the info text below the main message + size := len(messages[message].text) + length := utf8.RuneCountInString(messages[message].text) + info := fmt.Sprintf("%s %d characters %d bytes", messages[message].language, length, size) + sz = rl.MeasureTextEx(rl.GetFontDefault(), info, 10, 1.0) + + rl.DrawText(info, int32(textRect.X+textRect.Width-sz.X), int32(msgRect.Y+msgRect.Height-sz.Y-2), 10, + rl.RayWhite) + + } + + // Draw the info text + rl.DrawText("These emojis have something to tell you, click each to find out!", (screenWidth-650)/2, + screenHeight-40, 20, rl.Gray) + rl.DrawText("Each emoji is a unicode character from a font, not a texture... Press [SPACEBAR] to refresh", + (screenWidth-484)/2, screenHeight-16, 10, rl.Gray) + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadFont(fontDefault) // Unload font resource + rl.UnloadFont(fontAsian) // Unload font resource + rl.UnloadFont(fontEmoji) // Unload font resource + + rl.CloseWindow() // Close window and OpenGL context +} + +// RandomizeEmoji fills the emoji array with random emoji (only those emojis present in fontEmoji) +func RandomizeEmoji() { + hovered, selected = -1, -1 + start := rl.GetRandomValue(45, 360) + + for i := int32(0); i < emojiPerWidth*emojiPerHeight; i++ { + // 0-179 emoji codepoints (from emoji char array) each 4bytes + null char + emoji[i].index = rl.GetRandomValue(0, 179) * 5 + + // Generate a random color for this emoji + emoji[i].color = rl.Fade(rl.ColorFromHSV(float32((start*(i+1))%360), 0.6, 0.85), 0.8) + + // Set a random message for this emoji + emoji[i].message = rl.GetRandomValue(0, int32(len(messages)-1)) + } +} + +// DrawTextBoxed draws text using font inside rectangle limits +func DrawTextBoxed(font rl.Font, text string, rec rl.Rectangle, fontSize, spacing float32, wordWrap bool, tint rl.Color) { + DrawTextBoxedSelectable(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, rl.White, rl.White) +} + +// DrawTextBoxedSelectable draws text using font inside rectangle limits with support for text selection +func DrawTextBoxedSelectable(font rl.Font, text string, rec rl.Rectangle, fontSize, spacing float32, + wordWrap bool, tint rl.Color, selectStart, selectLength int32, selectTint, selectBackTint rl.Color) { + + length := int32(len(text)) // Total length in bytes of the text, scanned by codepoints in loop + + // TextOffsetY : Offset between lines (on line break '\n') + // TextOffsetX : Offset X to next character to draw + var textOffsetY, textOffsetX float32 + + scaleFactor := fontSize / float32(font.BaseSize) // Character rectangle scaling factor + + // Word/character wrapping mechanism variables + state := DrawState + if wordWrap { + state = MeasureState + } + + // StartLine : Index where to begin drawing (where a line begins) + // EndLine : Index where to stop drawing (where a line ends) + // LastK : Holds last value of the character position + var startLine, endLine, lastk int32 = -1, -1, -1 + for i, k := int32(0), int32(0); i < length; i, k = i+1, k+1 { + // Get next codepoint from byte string and glyph index in font + codepoint, width := utf8.DecodeRuneInString(text[i:]) + codepointByteCount := int32(width) + index := rl.GetGlyphIndex(font, codepoint) + + // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all the bad bytes using the '?' symbol moving one byte + if codepoint == 0x3f { + codepointByteCount = 1 + } + i += codepointByteCount - 1 + + var glyphWidth float32 + if codepoint != '\n' { + chars := unsafe.Slice(font.Chars, font.CharsCount) + if chars[index].AdvanceX == 0 { + glyphWidth = unsafe.Slice(font.Recs, font.CharsCount)[index].Width * scaleFactor + } else { + glyphWidth = float32(chars[index].AdvanceX) * scaleFactor + } + + if i+1 < length { + glyphWidth = glyphWidth + spacing + } + } + + // NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside the rec container + // We store this info in startLine and endLine, then we change states, draw the text between those two variables + // and change states again and again recursively until the end of the text (or until we get outside the container). + // When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately + // and begin drawing on the next line before we can get outside the container. + if state == MeasureState { + // TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more + // Ref: http://jkorpela.fi/chars/spaces.html + if (codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n') { + endLine = i + } + + if (textOffsetX + glyphWidth) > rec.Width { + if endLine < 1 { + endLine = i + } + + if i == endLine { + endLine -= codepointByteCount + } + if (startLine + codepointByteCount) == endLine { + endLine = i - codepointByteCount + } + + state = 1 - state // Toggle state between MeasureState and DrawState + } else if (i + 1) == length { + endLine = i + state = 1 - state // Toggle state between MeasureState and DrawState + } else if codepoint == '\n' { + state = 1 - state // Toggle state between MeasureState and DrawState + } + + if state == DrawState { + textOffsetX = 0 + i = startLine + glyphWidth = 0 + + // Save character position when we switch states + lastk, k = k-1, lastk + } + } else { + if codepoint == '\n' { + if !wordWrap { + textOffsetY += float32(font.BaseSize+font.BaseSize/2) * scaleFactor + textOffsetX = 0 + } + } else { + if !wordWrap && ((textOffsetX + glyphWidth) > rec.Width) { + textOffsetY += float32(font.BaseSize+font.BaseSize/2) * scaleFactor + textOffsetX = 0 + } + + // When text overflows rectangle height limit, just stop drawing + if (textOffsetY + float32(font.BaseSize)*scaleFactor) > rec.Height { + break + } + + // Draw selection background + isGlyphSelected := false + if (selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)) { + rl.DrawRectangleRec(rl.Rectangle{ + X: rec.X + textOffsetX - 1, + Y: rec.Y + textOffsetY, + Width: glyphWidth, + Height: float32(font.BaseSize) * scaleFactor, + }, selectBackTint) + isGlyphSelected = true + } + + // Draw current character glyph + if (codepoint != ' ') && (codepoint != '\t') { + col := tint + if isGlyphSelected { + col = selectTint + } + pos := rl.Vector2{ + X: rec.X + textOffsetX, + Y: rec.Y + textOffsetY, + } + rl.DrawTextEx(font, string(codepoint), pos, fontSize, 0, col) + } + } + + if wordWrap && (i == endLine) { + textOffsetY += float32(font.BaseSize+font.BaseSize/2) * scaleFactor + textOffsetX = 0 + startLine = endLine + endLine = -1 + glyphWidth = 0 + selectStart += lastk - k + k = lastk + + state = 1 - state // Toggle state between MeasureState and DrawState + } + } + + textOffsetX += glyphWidth + } +} diff --git a/examples/text/unicode/resources/dejavu.fnt b/examples/text/unicode/resources/dejavu.fnt new file mode 100644 index 0000000..6503b35 --- /dev/null +++ b/examples/text/unicode/resources/dejavu.fnt @@ -0,0 +1,1115 @@ +info face="DejaVu Sans" size=-16 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2 outline=1 +common lineHeight=19 base=15 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4 +page id=0 file="dejavu.png" +chars count=1111 +char id=32 x=259 y=464 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=33 x=464 y=382 width=4 height=14 xoffset=1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=34 x=112 y=461 width=7 height=7 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=15 +char id=35 x=33 y=407 width=14 height=13 xoffset=0 yoffset=3 xadvance=13 page=0 chnl=15 +char id=36 x=381 y=153 width=10 height=16 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=37 x=493 y=222 width=17 height=14 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=38 x=275 y=257 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=39 x=506 y=395 width=4 height=7 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=15 +char id=40 x=18 y=178 width=6 height=16 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=41 x=10 y=178 width=6 height=16 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=42 x=192 y=444 width=10 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=43 x=369 y=415 width=13 height=11 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=44 x=474 y=450 width=5 height=6 xoffset=0 yoffset=12 xadvance=5 page=0 chnl=15 +char id=45 x=191 y=468 width=7 height=4 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 +char id=46 x=207 y=465 width=5 height=4 xoffset=0 yoffset=12 xadvance=5 page=0 chnl=15 +char id=47 x=331 y=224 width=8 height=15 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=15 +char id=48 x=396 y=304 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=49 x=290 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=50 x=386 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=51 x=374 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=52 x=466 y=302 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=53 x=338 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=54 x=273 y=353 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=55 x=326 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=56 x=286 y=353 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=57 x=42 y=327 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=58 x=428 y=441 width=5 height=10 xoffset=0 yoffset=6 xadvance=5 page=0 chnl=15 +char id=59 x=472 y=398 width=5 height=12 xoffset=0 yoffset=6 xadvance=5 page=0 chnl=15 +char id=60 x=339 y=415 width=13 height=11 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=61 x=42 y=461 width=13 height=7 xoffset=0 yoffset=7 xadvance=13 page=0 chnl=15 +char id=62 x=324 y=415 width=13 height=11 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=63 x=501 y=238 width=9 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=64 x=368 y=135 width=17 height=16 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15 +char id=65 x=60 y=295 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=66 x=299 y=353 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=67 x=90 y=295 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=68 x=105 y=294 width=13 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=69 x=325 y=353 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=70 x=194 y=371 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=71 x=208 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=72 x=420 y=320 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=73 x=423 y=384 width=5 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=74 x=237 y=136 width=7 height=17 xoffset=-2 yoffset=2 xadvance=5 page=0 chnl=15 +char id=75 x=60 y=311 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=76 x=72 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=77 x=288 y=273 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=78 x=74 y=311 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=79 x=320 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=80 x=351 y=353 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=81 x=467 y=135 width=14 height=16 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=82 x=102 y=311 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=83 x=116 y=310 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=84 x=130 y=310 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=85 x=144 y=307 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=86 x=496 y=270 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=87 x=164 y=242 width=18 height=14 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=88 x=150 y=291 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=89 x=158 y=307 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=90 x=210 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=91 x=34 y=178 width=6 height=16 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=92 x=321 y=224 width=8 height=15 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=15 +char id=93 x=26 y=178 width=6 height=16 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=94 x=27 y=461 width=13 height=7 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=95 x=107 y=470 width=12 height=4 xoffset=-2 yoffset=16 xadvance=8 page=0 chnl=15 +char id=96 x=398 y=453 width=7 height=6 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=15 +char id=97 x=312 y=428 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=98 x=455 y=350 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=99 x=36 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=100 x=468 y=350 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=101 x=286 y=428 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=102 x=311 y=385 width=8 height=14 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=103 x=65 y=375 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=104 x=410 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=105 x=476 y=382 width=4 height=14 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=15 +char id=106 x=289 y=136 width=6 height=17 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=107 x=130 y=374 width=11 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=108 x=482 y=382 width=4 height=14 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=15 +char id=109 x=93 y=422 width=16 height=11 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15 +char id=110 x=495 y=424 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=111 x=260 y=430 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=112 x=143 y=374 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=113 x=156 y=371 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=114 x=292 y=441 width=8 height=11 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=15 +char id=115 x=435 y=428 width=10 height=11 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=116 x=229 y=402 width=8 height=13 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=15 +char id=117 x=411 y=428 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=118 x=143 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=119 x=213 y=418 width=15 height=11 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=120 x=130 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=121 x=476 y=318 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=122 x=363 y=428 width=10 height=11 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=123 x=60 y=141 width=10 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=124 x=469 y=20 width=5 height=18 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=125 x=48 y=141 width=10 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=126 x=266 y=456 width=13 height=6 xoffset=0 yoffset=7 xadvance=13 page=0 chnl=15 +char id=160 x=284 y=463 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=161 x=506 y=153 width=4 height=14 xoffset=1 yoffset=5 xadvance=6 page=0 chnl=15 +char id=162 x=492 y=205 width=10 height=15 xoffset=0 yoffset=3 xadvance=10 page=0 chnl=15 +char id=163 x=0 y=343 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=164 x=440 y=414 width=12 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=165 x=0 y=327 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=166 x=42 y=178 width=5 height=16 xoffset=0 yoffset=3 xadvance=5 page=0 chnl=15 +char id=167 x=345 y=154 width=10 height=16 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=168 x=502 y=447 width=8 height=5 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=169 x=352 y=273 width=14 height=14 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=170 x=237 y=443 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=171 x=337 y=441 width=10 height=10 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=15 +char id=172 x=462 y=440 width=13 height=8 xoffset=0 yoffset=7 xadvance=13 page=0 chnl=15 +char id=173 x=155 y=470 width=7 height=4 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 +char id=174 x=400 y=272 width=14 height=14 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=175 x=145 y=470 width=8 height=4 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=176 x=0 y=461 width=8 height=8 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=177 x=337 y=401 width=13 height=12 xoffset=0 yoffset=4 xadvance=13 page=0 chnl=15 +char id=178 x=392 y=441 width=8 height=10 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=179 x=382 y=441 width=8 height=10 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=180 x=380 y=453 width=7 height=6 xoffset=1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=181 x=169 y=371 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=182 x=393 y=153 width=10 height=16 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=183 x=14 y=471 width=5 height=5 xoffset=0 yoffset=7 xadvance=5 page=0 chnl=15 +char id=184 x=423 y=453 width=6 height=6 xoffset=1 yoffset=13 xadvance=8 page=0 chnl=15 +char id=185 x=411 y=441 width=7 height=10 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=186 x=259 y=443 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=187 x=349 y=441 width=10 height=10 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=15 +char id=188 x=411 y=238 width=16 height=14 xoffset=0 yoffset=2 xadvance=16 page=0 chnl=15 +char id=189 x=447 y=238 width=16 height=14 xoffset=0 yoffset=2 xadvance=16 page=0 chnl=15 +char id=190 x=356 y=240 width=17 height=14 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=191 x=228 y=386 width=9 height=14 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=192 x=135 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=193 x=150 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=194 x=165 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=195 x=180 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=196 x=195 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=197 x=210 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=198 x=299 y=241 width=17 height=14 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=199 x=225 y=79 width=13 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=200 x=119 y=118 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=201 x=106 y=119 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=202 x=80 y=119 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=203 x=353 y=116 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=204 x=504 y=97 width=6 height=17 xoffset=-1 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=205 x=321 y=136 width=6 height=17 xoffset=-1 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=206 x=187 y=136 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=207 x=147 y=136 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=208 x=448 y=270 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=209 x=420 y=97 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=210 x=112 y=61 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=211 x=32 y=65 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=212 x=128 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=213 x=457 y=40 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=214 x=473 y=40 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=215 x=380 y=401 width=12 height=12 xoffset=1 yoffset=4 xadvance=13 page=0 chnl=15 +char id=216 x=451 y=135 width=14 height=16 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15 +char id=217 x=329 y=79 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=218 x=476 y=97 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=219 x=308 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=220 x=70 y=100 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=221 x=56 y=103 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=222 x=26 y=375 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=223 x=0 y=375 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=224 x=52 y=213 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=225 x=39 y=213 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=226 x=26 y=213 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=227 x=494 y=350 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=228 x=481 y=350 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=229 x=293 y=155 width=11 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=230 x=0 y=422 width=17 height=11 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15 +char id=231 x=192 y=387 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=232 x=478 y=188 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=233 x=452 y=188 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=234 x=426 y=188 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=235 x=429 y=352 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=236 x=380 y=223 width=7 height=15 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=237 x=371 y=223 width=7 height=15 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=15 +char id=238 x=351 y=223 width=8 height=15 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=239 x=321 y=385 width=8 height=14 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=240 x=403 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=241 x=422 y=368 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=242 x=286 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=243 x=260 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=244 x=234 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=245 x=364 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=246 x=338 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=247 x=310 y=441 width=13 height=10 xoffset=0 yoffset=6 xadvance=13 page=0 chnl=15 +char id=248 x=64 y=407 width=12 height=13 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15 +char id=249 x=96 y=229 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=250 x=84 y=229 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=251 x=24 y=230 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=252 x=60 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=253 x=315 y=20 width=11 height=18 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=254 x=158 y=117 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=255 x=171 y=117 width=11 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=256 x=45 y=160 width=13 height=16 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=15 +char id=257 x=312 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=258 x=0 y=26 width=13 height=18 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=259 x=195 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=260 x=80 y=62 width=14 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=261 x=322 y=321 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=262 x=255 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=263 x=312 y=207 width=10 height=15 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=264 x=270 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=265 x=384 y=206 width=10 height=15 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=266 x=285 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=267 x=24 y=391 width=10 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=268 x=300 y=79 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=269 x=456 y=205 width=10 height=15 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=270 x=288 y=60 width=13 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=271 x=432 y=270 width=14 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=272 x=368 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=273 x=266 y=321 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=274 x=254 y=155 width=11 height=16 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=275 x=234 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=276 x=197 y=117 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=277 x=169 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=278 x=210 y=117 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=279 x=247 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=280 x=223 y=117 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=281 x=260 y=353 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=282 x=236 y=117 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=283 x=156 y=208 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=284 x=425 y=40 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=285 x=172 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=286 x=377 y=40 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=287 x=328 y=20 width=11 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=288 x=48 y=62 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=289 x=444 y=116 width=11 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=290 x=394 y=0 width=14 height=18 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=291 x=185 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=292 x=42 y=103 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=293 x=322 y=98 width=12 height=17 xoffset=-2 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=294 x=108 y=262 width=15 height=14 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15 +char id=295 x=298 y=305 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=296 x=157 y=136 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=297 x=281 y=385 width=8 height=14 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=298 x=486 y=153 width=8 height=16 xoffset=-2 yoffset=0 xadvance=5 page=0 chnl=15 +char id=299 x=271 y=385 width=8 height=14 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=300 x=107 y=138 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=301 x=311 y=224 width=8 height=15 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=302 x=305 y=136 width=6 height=17 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=303 x=313 y=136 width=6 height=17 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=15 +char id=304 x=505 y=116 width=5 height=17 xoffset=0 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=305 x=506 y=382 width=4 height=11 xoffset=0 yoffset=5 xadvance=4 page=0 chnl=15 +char id=306 x=84 y=138 width=10 height=17 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=307 x=137 y=137 width=8 height=17 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=308 x=101 y=0 width=8 height=20 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=309 x=443 y=20 width=8 height=18 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=310 x=88 y=22 width=12 height=18 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=311 x=302 y=21 width=11 height=18 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=312 x=0 y=435 width=11 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=313 x=493 y=116 width=10 height=17 xoffset=0 yoffset=-1 xadvance=9 page=0 chnl=15 +char id=314 x=297 y=136 width=6 height=17 xoffset=0 yoffset=-1 xadvance=4 page=0 chnl=15 +char id=315 x=401 y=20 width=10 height=18 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=316 x=461 y=20 width=6 height=18 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=15 +char id=317 x=48 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=318 x=406 y=385 width=7 height=14 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=319 x=302 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=320 x=379 y=385 width=7 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=321 x=340 y=305 width=12 height=14 xoffset=-2 yoffset=2 xadvance=9 page=0 chnl=15 +char id=322 x=397 y=385 width=7 height=14 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=15 +char id=323 x=238 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=324 x=108 y=229 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=325 x=60 y=23 width=12 height=18 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=326 x=144 y=226 width=10 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=327 x=210 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=328 x=336 y=207 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=329 x=315 y=289 width=13 height=14 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=330 x=168 y=98 width=12 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=331 x=216 y=387 width=10 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=332 x=483 y=135 width=14 height=16 xoffset=-1 yoffset=0 xadvance=13 page=0 chnl=15 +char id=333 x=13 y=343 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=334 x=64 y=62 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=335 x=374 y=189 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=336 x=176 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=337 x=400 y=188 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=338 x=63 y=247 width=19 height=14 xoffset=-1 yoffset=2 xadvance=17 page=0 chnl=15 +char id=339 x=486 y=398 width=18 height=11 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15 +char id=340 x=14 y=103 width=12 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=341 x=236 y=224 width=9 height=15 xoffset=0 yoffset=1 xadvance=7 page=0 chnl=15 +char id=342 x=116 y=21 width=12 height=18 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=343 x=192 y=224 width=9 height=15 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=15 +char id=344 x=455 y=78 width=12 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=345 x=291 y=224 width=8 height=15 xoffset=0 yoffset=1 xadvance=7 page=0 chnl=15 +char id=346 x=182 y=98 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=347 x=360 y=206 width=10 height=15 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=348 x=462 y=97 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=349 x=396 y=205 width=10 height=15 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=350 x=497 y=78 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=351 x=180 y=387 width=10 height=14 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=352 x=84 y=100 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=353 x=444 y=205 width=10 height=15 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=354 x=98 y=100 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=355 x=0 y=178 width=8 height=16 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=15 +char id=356 x=126 y=99 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=357 x=361 y=223 width=8 height=15 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=15 +char id=358 x=294 y=321 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=359 x=239 y=402 width=8 height=13 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=15 +char id=360 x=196 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=361 x=84 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=362 x=173 y=155 width=12 height=16 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15 +char id=363 x=230 y=370 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=364 x=280 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=365 x=132 y=226 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=366 x=294 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=367 x=453 y=153 width=10 height=16 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=368 x=350 y=97 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=369 x=12 y=230 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=370 x=364 y=97 width=12 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=371 x=104 y=343 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=372 x=126 y=41 width=18 height=17 xoffset=-1 yoffset=-1 xadvance=16 page=0 chnl=15 +char id=373 x=343 y=172 width=15 height=15 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15 +char id=374 x=434 y=97 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=375 x=289 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=376 x=14 y=122 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=377 x=105 y=80 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=378 x=348 y=206 width=10 height=15 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=379 x=90 y=81 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=380 x=156 y=387 width=10 height=14 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=381 x=60 y=81 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=382 x=156 y=225 width=10 height=15 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=383 x=331 y=385 width=8 height=14 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=384 x=434 y=320 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=385 x=243 y=257 width=14 height=14 xoffset=-2 yoffset=2 xadvance=12 page=0 chnl=15 +char id=386 x=78 y=375 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=387 x=416 y=352 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=388 x=364 y=321 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=389 x=480 y=302 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=390 x=225 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=391 x=310 y=41 width=15 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=392 x=270 y=305 width=12 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=393 x=259 y=257 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=394 x=483 y=238 width=16 height=14 xoffset=-2 yoffset=2 xadvance=13 page=0 chnl=15 +char id=395 x=130 y=358 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=396 x=377 y=337 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=397 x=52 y=359 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=398 x=325 y=337 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=399 x=419 y=254 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=400 x=12 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=401 x=336 y=98 width=12 height=17 xoffset=-2 yoffset=2 xadvance=9 page=0 chnl=15 +char id=402 x=96 y=138 width=9 height=17 xoffset=-2 yoffset=2 xadvance=6 page=0 chnl=15 +char id=403 x=239 y=41 width=16 height=17 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=404 x=363 y=59 width=13 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=405 x=36 y=263 width=16 height=14 xoffset=0 yoffset=2 xadvance=16 page=0 chnl=15 +char id=406 x=361 y=385 width=7 height=14 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15 +char id=407 x=388 y=385 width=7 height=14 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=15 +char id=408 x=165 y=291 width=13 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=409 x=442 y=336 width=11 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=410 x=370 y=385 width=7 height=14 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=15 +char id=411 x=468 y=334 width=11 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=412 x=429 y=238 width=16 height=14 xoffset=0 yoffset=2 xadvance=16 page=0 chnl=15 +char id=413 x=409 y=40 width=14 height=17 xoffset=-2 yoffset=2 xadvance=12 page=0 chnl=15 +char id=414 x=218 y=370 width=10 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=415 x=96 y=278 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=416 x=112 y=278 width=14 height=14 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=417 x=352 y=401 width=12 height=12 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15 +char id=418 x=18 y=263 width=16 height=14 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=419 x=450 y=286 width=13 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15 +char id=420 x=405 y=288 width=13 height=14 xoffset=-2 yoffset=2 xadvance=10 page=0 chnl=15 +char id=421 x=288 y=117 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=422 x=159 y=155 width=12 height=16 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=423 x=14 y=327 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=424 x=132 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=425 x=143 y=358 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=426 x=327 y=117 width=11 height=17 xoffset=-4 yoffset=2 xadvance=5 page=0 chnl=15 +char id=427 x=476 y=153 width=8 height=16 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=15 +char id=428 x=326 y=305 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=429 x=341 y=385 width=8 height=14 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=430 x=112 y=99 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=431 x=192 y=274 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=432 x=366 y=401 width=12 height=12 xoffset=0 yoffset=4 xadvance=10 page=0 chnl=15 +char id=433 x=240 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=434 x=70 y=327 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=435 x=128 y=275 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=436 x=176 y=274 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15 +char id=437 x=330 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=438 x=423 y=428 width=10 height=11 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=439 x=489 y=318 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=440 x=242 y=305 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=441 x=104 y=375 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=442 x=0 y=230 width=10 height=15 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=443 x=350 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=444 x=126 y=326 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=445 x=208 y=354 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=446 x=372 y=206 width=10 height=15 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=447 x=195 y=355 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=448 x=505 y=39 width=5 height=17 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=449 x=117 y=138 width=8 height=17 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=450 x=36 y=141 width=10 height=17 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=15 +char id=451 x=458 y=382 width=4 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=452 x=476 y=20 width=23 height=17 xoffset=0 yoffset=-1 xadvance=23 page=0 chnl=15 +char id=453 x=80 y=178 width=21 height=15 xoffset=0 yoffset=1 xadvance=21 page=0 chnl=15 +char id=454 x=103 y=175 width=19 height=15 xoffset=-1 yoffset=1 xadvance=18 page=0 chnl=15 +char id=455 x=441 y=40 width=14 height=17 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=456 x=393 y=59 width=13 height=17 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=457 x=264 y=136 width=7 height=17 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=15 +char id=458 x=257 y=41 width=16 height=17 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15 +char id=459 x=160 y=60 width=14 height=17 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15 +char id=460 x=0 y=84 width=13 height=17 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=461 x=408 y=59 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=462 x=221 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=463 x=217 y=136 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=464 x=301 y=224 width=8 height=15 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=465 x=272 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=466 x=247 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=467 x=483 y=78 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=468 x=432 y=205 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=469 x=158 y=21 width=12 height=18 xoffset=0 yoffset=-2 xadvance=12 page=0 chnl=15 +char id=470 x=369 y=153 width=10 height=16 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=471 x=242 y=0 width=12 height=19 xoffset=0 yoffset=-3 xadvance=12 page=0 chnl=15 +char id=472 x=72 y=141 width=10 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=473 x=256 y=0 width=12 height=19 xoffset=0 yoffset=-3 xadvance=12 page=0 chnl=15 +char id=474 x=457 y=116 width=10 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=475 x=270 y=0 width=12 height=19 xoffset=0 yoffset=-3 xadvance=12 page=0 chnl=15 +char id=476 x=0 y=141 width=10 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=477 x=91 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=478 x=488 y=0 width=13 height=18 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=479 x=332 y=154 width=11 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=480 x=458 y=0 width=13 height=18 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=481 x=306 y=155 width=11 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=482 x=349 y=136 width=17 height=16 xoffset=-1 yoffset=0 xadvance=16 page=0 chnl=15 +char id=483 x=318 y=241 width=17 height=14 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=484 x=144 y=275 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=485 x=238 y=321 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=486 x=16 y=65 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=487 x=224 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=488 x=490 y=97 width=12 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=489 x=423 y=59 width=13 height=17 xoffset=-2 yoffset=-1 xadvance=9 page=0 chnl=15 +char id=490 x=96 y=61 width=14 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=491 x=78 y=359 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=492 x=182 y=0 width=14 height=19 xoffset=-1 yoffset=0 xadvance=13 page=0 chnl=15 +char id=493 x=262 y=117 width=11 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=494 x=54 y=122 width=11 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=495 x=211 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=496 x=433 y=20 width=8 height=18 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=497 x=398 y=222 width=23 height=14 xoffset=0 yoffset=2 xadvance=23 page=0 chnl=15 +char id=498 x=448 y=222 width=21 height=14 xoffset=0 yoffset=2 xadvance=21 page=0 chnl=15 +char id=499 x=0 y=247 width=19 height=14 xoffset=-1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=500 x=208 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=501 x=263 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=502 x=124 y=243 width=18 height=14 xoffset=0 yoffset=2 xadvance=18 page=0 chnl=15 +char id=503 x=67 y=122 width=11 height=17 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=504 x=224 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=505 x=48 y=230 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=506 x=438 y=59 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=507 x=154 y=98 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=508 x=146 y=41 width=17 height=17 xoffset=-1 yoffset=-1 xadvance=16 page=0 chnl=15 +char id=509 x=181 y=173 width=17 height=15 xoffset=-1 yoffset=1 xadvance=16 page=0 chnl=15 +char id=510 x=410 y=0 width=14 height=18 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=511 x=145 y=156 width=12 height=16 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=512 x=453 y=59 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=513 x=273 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=514 x=60 y=160 width=13 height=16 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=15 +char id=515 x=338 y=337 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=516 x=132 y=118 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=517 x=143 y=209 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=518 x=267 y=155 width=11 height=16 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=519 x=273 y=337 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=520 x=501 y=20 width=9 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=521 x=203 y=224 width=9 height=15 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=15 +char id=522 x=496 y=153 width=8 height=16 xoffset=-2 yoffset=0 xadvance=5 page=0 chnl=15 +char id=523 x=502 y=318 width=8 height=14 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=524 x=144 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=525 x=104 y=212 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=526 x=387 y=135 width=14 height=16 xoffset=-1 yoffset=0 xadvance=13 page=0 chnl=15 +char id=527 x=208 y=338 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=528 x=385 y=78 width=12 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=529 x=214 y=224 width=9 height=15 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=15 +char id=530 x=201 y=155 width=12 height=16 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15 +char id=531 x=261 y=385 width=8 height=14 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=15 +char id=532 x=427 y=78 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=533 x=36 y=230 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=534 x=75 y=160 width=12 height=16 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15 +char id=535 x=446 y=368 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=536 x=144 y=21 width=12 height=18 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=537 x=60 y=230 width=10 height=15 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=538 x=102 y=22 width=12 height=18 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=539 x=177 y=136 width=8 height=17 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=15 +char id=540 x=341 y=20 width=10 height=18 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=541 x=120 y=226 width=10 height=15 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=542 x=378 y=97 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=543 x=392 y=97 width=12 height=17 xoffset=-2 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=544 x=406 y=97 width=12 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=545 x=327 y=40 width=15 height=17 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15 +char id=546 x=375 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=547 x=422 y=401 width=11 height=12 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15 +char id=548 x=240 y=79 width=13 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=549 x=458 y=366 width=10 height=14 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=550 x=483 y=59 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=551 x=221 y=354 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=552 x=41 y=122 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=553 x=182 y=355 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=554 x=362 y=0 width=14 height=18 xoffset=-1 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=555 x=215 y=155 width=11 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=556 x=378 y=0 width=14 height=18 xoffset=-1 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=557 x=78 y=212 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=558 x=489 y=39 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=559 x=169 y=355 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=560 x=426 y=0 width=14 height=18 xoffset=-1 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=561 x=319 y=155 width=11 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=562 x=89 y=157 width=12 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=563 x=431 y=116 width=11 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=564 x=227 y=136 width=8 height=17 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=15 +char id=565 x=17 y=407 width=14 height=13 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=566 x=465 y=153 width=9 height=16 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=567 x=415 y=385 width=6 height=14 xoffset=-2 yoffset=5 xadvance=4 page=0 chnl=15 +char id=568 x=104 y=246 width=18 height=14 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=569 x=144 y=243 width=18 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15 +char id=570 x=15 y=160 width=13 height=16 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=571 x=419 y=135 width=14 height=16 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=572 x=146 y=406 width=11 height=13 xoffset=-1 yoffset=4 xadvance=9 page=0 chnl=15 +char id=573 x=39 y=375 width=11 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=574 x=435 y=135 width=14 height=16 xoffset=-2 yoffset=1 xadvance=10 page=0 chnl=15 +char id=575 x=13 y=213 width=11 height=15 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=576 x=0 y=213 width=11 height=15 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=577 x=200 y=306 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=578 x=399 y=428 width=10 height=11 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=579 x=336 y=321 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=580 x=355 y=257 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=581 x=390 y=288 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=582 x=250 y=21 width=11 height=18 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=583 x=387 y=188 width=11 height=15 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15 +char id=584 x=207 y=136 width=8 height=17 xoffset=-2 yoffset=2 xadvance=5 page=0 chnl=15 +char id=585 x=197 y=136 width=8 height=17 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=586 x=203 y=41 width=16 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=587 x=270 y=289 width=13 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=588 x=255 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=589 x=215 y=444 width=9 height=11 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=15 +char id=590 x=480 y=286 width=13 height=14 xoffset=-2 yoffset=2 xadvance=10 page=0 chnl=15 +char id=591 x=234 y=190 width=12 height=15 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=880 x=108 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=881 x=226 y=444 width=9 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=882 x=291 y=257 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=883 x=266 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=884 x=121 y=461 width=5 height=7 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=15 +char id=885 x=439 y=452 width=5 height=6 xoffset=0 yoffset=13 xadvance=4 page=0 chnl=15 +char id=886 x=350 y=321 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=887 x=471 y=425 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=890 x=446 y=452 width=5 height=6 xoffset=2 yoffset=14 xadvance=8 page=0 chnl=15 +char id=891 x=351 y=428 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=892 x=12 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=893 x=48 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=894 x=479 y=398 width=5 height=12 xoffset=0 yoffset=6 xadvance=5 page=0 chnl=15 +char id=895 x=255 y=136 width=7 height=17 xoffset=-2 yoffset=2 xadvance=5 page=0 chnl=15 +char id=900 x=389 y=453 width=7 height=6 xoffset=1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=901 x=435 y=441 width=8 height=9 xoffset=0 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=902 x=90 y=195 width=13 height=15 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=903 x=0 y=471 width=5 height=5 xoffset=0 yoffset=7 xadvance=5 page=0 chnl=15 +char id=904 x=428 y=171 width=15 height=15 xoffset=-2 yoffset=1 xadvance=12 page=0 chnl=15 +char id=905 x=308 y=173 width=16 height=15 xoffset=-2 yoffset=1 xadvance=14 page=0 chnl=15 +char id=906 x=225 y=224 width=9 height=15 xoffset=-2 yoffset=1 xadvance=7 page=0 chnl=15 +char id=908 x=411 y=171 width=15 height=15 xoffset=-2 yoffset=1 xadvance=13 page=0 chnl=15 +char id=910 x=236 y=173 width=16 height=15 xoffset=-2 yoffset=1 xadvance=13 page=0 chnl=15 +char id=911 x=326 y=173 width=15 height=15 xoffset=-2 yoffset=1 xadvance=13 page=0 chnl=15 +char id=912 x=423 y=20 width=8 height=18 xoffset=-2 yoffset=-2 xadvance=5 page=0 chnl=15 +char id=913 x=30 y=295 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=914 x=91 y=343 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=915 x=434 y=368 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=916 x=30 y=311 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=917 x=117 y=359 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=918 x=15 y=311 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=919 x=378 y=321 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=920 x=480 y=270 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=921 x=437 y=384 width=5 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=922 x=112 y=327 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=923 x=465 y=286 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=924 x=307 y=257 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=925 x=140 y=326 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=926 x=482 y=366 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=927 x=403 y=256 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=928 x=168 y=323 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=929 x=65 y=343 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=931 x=78 y=343 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=932 x=210 y=322 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=933 x=224 y=321 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=934 x=16 y=279 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=935 x=495 y=286 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=936 x=48 y=279 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=937 x=64 y=279 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=938 x=167 y=136 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=939 x=399 y=78 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=940 x=192 y=190 width=12 height=15 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=941 x=180 y=224 width=10 height=15 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=942 x=377 y=20 width=10 height=18 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=943 x=389 y=223 width=7 height=15 xoffset=0 yoffset=1 xadvance=5 page=0 chnl=15 +char id=944 x=365 y=20 width=10 height=18 xoffset=0 yoffset=-2 xadvance=9 page=0 chnl=15 +char id=945 x=426 y=415 width=12 height=11 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=946 x=237 y=21 width=11 height=18 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=947 x=130 y=342 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=948 x=143 y=342 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=949 x=60 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=950 x=24 y=141 width=10 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=951 x=362 y=369 width=10 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=952 x=364 y=337 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=953 x=302 y=441 width=6 height=11 xoffset=0 yoffset=5 xadvance=5 page=0 chnl=15 +char id=954 x=24 y=448 width=10 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=955 x=169 y=339 width=11 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=956 x=182 y=339 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=957 x=221 y=431 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=958 x=12 y=141 width=10 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=959 x=195 y=431 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=960 x=384 y=415 width=12 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=961 x=91 y=375 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=962 x=314 y=369 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=963 x=398 y=415 width=12 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=964 x=169 y=431 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=965 x=0 y=448 width=10 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=966 x=406 y=320 width=12 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=967 x=52 y=375 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=968 x=392 y=321 width=12 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=969 x=128 y=422 width=15 height=11 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=970 x=301 y=385 width=8 height=14 xoffset=-2 yoffset=2 xadvance=5 page=0 chnl=15 +char id=971 x=168 y=387 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=972 x=299 y=207 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=973 x=480 y=205 width=10 height=15 xoffset=0 yoffset=1 xadvance=9 page=0 chnl=15 +char id=974 x=394 y=171 width=15 height=15 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15 +char id=975 x=130 y=21 width=12 height=18 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=976 x=278 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=977 x=390 y=353 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=978 x=195 y=290 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=979 x=143 y=174 width=17 height=15 xoffset=-2 yoffset=1 xadvance=13 page=0 chnl=15 +char id=980 x=75 y=81 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=981 x=357 y=78 width=12 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=982 x=145 y=421 width=15 height=11 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=983 x=346 y=189 width=12 height=15 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=984 x=192 y=60 width=14 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=985 x=26 y=343 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=986 x=301 y=117 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=987 x=104 y=359 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=988 x=494 y=366 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=989 x=340 y=117 width=11 height=17 xoffset=-3 yoffset=2 xadvance=7 page=0 chnl=15 +char id=990 x=39 y=359 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=991 x=26 y=359 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=992 x=328 y=0 width=15 height=18 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=993 x=494 y=302 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=994 x=221 y=41 width=16 height=17 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=995 x=159 y=259 width=15 height=14 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=996 x=45 y=84 width=13 height=17 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=997 x=410 y=304 width=12 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=998 x=30 y=84 width=13 height=17 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=999 x=106 y=407 width=12 height=13 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15 +char id=1000 x=15 y=26 width=13 height=18 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1001 x=439 y=188 width=11 height=15 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1002 x=387 y=256 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1003 x=454 y=414 width=12 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1004 x=30 y=160 width=13 height=16 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=1005 x=499 y=135 width=11 height=16 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1006 x=0 y=103 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1007 x=379 y=116 width=11 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1008 x=394 y=401 width=12 height=12 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1009 x=299 y=337 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1010 x=387 y=428 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1011 x=273 y=136 width=6 height=17 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=1012 x=416 y=272 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1013 x=448 y=400 width=10 height=12 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1014 x=460 y=398 width=10 height=12 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1015 x=286 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1016 x=405 y=116 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1017 x=15 y=295 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1018 x=451 y=254 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1019 x=252 y=321 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1020 x=332 y=190 width=12 height=15 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1021 x=345 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1022 x=0 y=295 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1023 x=135 y=291 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1024 x=418 y=116 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1025 x=28 y=122 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1026 x=0 y=65 width=14 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1027 x=481 y=116 width=10 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1028 x=120 y=294 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1029 x=438 y=302 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1030 x=430 y=384 width=5 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=1031 x=127 y=137 width=8 height=17 xoffset=-2 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=1032 x=246 y=136 width=7 height=17 xoffset=-2 yoffset=2 xadvance=5 page=0 chnl=15 +char id=1033 x=42 y=247 width=19 height=14 xoffset=-1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=1034 x=261 y=241 width=17 height=14 xoffset=0 yoffset=2 xadvance=17 page=0 chnl=15 +char id=1035 x=467 y=254 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1036 x=448 y=97 width=12 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=1037 x=441 y=78 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=1038 x=413 y=78 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1039 x=371 y=78 width=12 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1040 x=435 y=286 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1041 x=221 y=338 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1042 x=234 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1043 x=36 y=391 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1044 x=361 y=40 width=14 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1045 x=247 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1046 x=21 y=247 width=19 height=14 xoffset=-1 yoffset=2 xadvance=17 page=0 chnl=15 +char id=1047 x=260 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1048 x=214 y=305 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1049 x=315 y=79 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=1050 x=354 y=305 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1051 x=360 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1052 x=0 y=279 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1053 x=182 y=323 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1054 x=32 y=279 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1055 x=88 y=311 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1056 x=312 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1057 x=285 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1058 x=56 y=327 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1059 x=196 y=322 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1060 x=125 y=259 width=15 height=14 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1061 x=75 y=295 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1062 x=468 y=59 width=13 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1063 x=351 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1064 x=204 y=241 width=17 height=14 xoffset=0 yoffset=2 xadvance=17 page=0 chnl=15 +char id=1065 x=86 y=42 width=18 height=17 xoffset=0 yoffset=2 xadvance=18 page=0 chnl=15 +char id=1066 x=142 y=259 width=15 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1067 x=80 y=279 width=14 height=14 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1068 x=390 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1069 x=420 y=288 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1070 x=184 y=241 width=18 height=14 xoffset=0 yoffset=2 xadvance=17 page=0 chnl=15 +char id=1071 x=403 y=337 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1072 x=13 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1073 x=117 y=209 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1074 x=375 y=428 width=10 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1075 x=204 y=444 width=9 height=11 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=15 +char id=1076 x=49 y=407 width=13 height=13 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1077 x=52 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1078 x=57 y=422 width=16 height=11 xoffset=-1 yoffset=5 xadvance=14 page=0 chnl=15 +char id=1079 x=84 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1080 x=96 y=448 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1081 x=468 y=205 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1082 x=495 y=411 width=11 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1083 x=338 y=428 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1084 x=412 y=415 width=12 height=11 xoffset=0 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1085 x=459 y=427 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1086 x=325 y=428 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1087 x=144 y=448 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1088 x=494 y=334 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1089 x=180 y=444 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1090 x=299 y=428 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1091 x=0 y=359 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1092 x=344 y=40 width=15 height=17 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1093 x=273 y=429 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1094 x=92 y=407 width=12 height=13 xoffset=0 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1095 x=270 y=443 width=9 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1096 x=111 y=422 width=15 height=11 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15 +char id=1097 x=488 y=382 width=16 height=13 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15 +char id=1098 x=309 y=415 width=13 height=11 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1099 x=468 y=412 width=12 height=11 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1100 x=447 y=427 width=10 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1101 x=120 y=448 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1102 x=247 y=417 width=14 height=11 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1103 x=117 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1104 x=65 y=212 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1105 x=91 y=359 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1106 x=0 y=122 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1107 x=247 y=224 width=9 height=15 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=15 +char id=1108 x=168 y=447 width=10 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1109 x=483 y=425 width=10 height=11 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=1110 x=506 y=366 width=4 height=14 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=15 +char id=1111 x=291 y=385 width=8 height=14 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=1112 x=281 y=136 width=6 height=17 xoffset=-2 yoffset=2 xadvance=4 page=0 chnl=15 +char id=1113 x=75 y=422 width=16 height=11 xoffset=-1 yoffset=5 xadvance=14 page=0 chnl=15 +char id=1114 x=196 y=418 width=15 height=11 xoffset=0 yoffset=5 xadvance=14 page=0 chnl=15 +char id=1115 x=368 y=305 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1116 x=491 y=188 width=11 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1117 x=72 y=229 width=10 height=15 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1118 x=276 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=1119 x=184 y=403 width=10 height=13 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1120 x=375 y=240 width=16 height=14 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1121 x=162 y=418 width=15 height=11 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1122 x=160 y=275 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1123 x=228 y=305 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1124 x=290 y=173 width=16 height=15 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1125 x=408 y=401 width=12 height=12 xoffset=0 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1126 x=54 y=263 width=16 height=14 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1127 x=179 y=418 width=15 height=11 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1128 x=471 y=222 width=20 height=14 xoffset=0 yoffset=2 xadvance=19 page=0 chnl=15 +char id=1129 x=19 y=422 width=17 height=11 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15 +char id=1130 x=224 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1131 x=78 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1132 x=337 y=241 width=17 height=14 xoffset=0 yoffset=2 xadvance=16 page=0 chnl=15 +char id=1133 x=263 y=416 width=14 height=11 xoffset=0 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1134 x=60 y=0 width=11 height=21 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1135 x=353 y=20 width=10 height=18 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1136 x=90 y=262 width=16 height=14 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1137 x=129 y=0 width=16 height=19 xoffset=-1 yoffset=1 xadvance=14 page=0 chnl=15 +char id=1138 x=256 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1139 x=65 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1140 x=210 y=257 width=15 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1141 x=294 y=415 width=13 height=11 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1142 x=293 y=41 width=15 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=1143 x=135 y=192 width=13 height=15 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=1144 x=308 y=0 width=18 height=18 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=1145 x=218 y=173 width=16 height=15 xoffset=-1 yoffset=5 xadvance=14 page=0 chnl=15 +char id=1146 x=124 y=175 width=17 height=15 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1147 x=306 y=401 width=14 height=12 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1148 x=22 y=46 width=20 height=17 xoffset=-1 yoffset=-1 xadvance=19 page=0 chnl=15 +char id=1149 x=162 y=173 width=17 height=15 xoffset=0 yoffset=1 xadvance=16 page=0 chnl=15 +char id=1150 x=275 y=41 width=16 height=17 xoffset=-1 yoffset=-1 xadvance=15 page=0 chnl=15 +char id=1151 x=193 y=257 width=15 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1152 x=378 y=59 width=13 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1153 x=242 y=369 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1154 x=72 y=448 width=10 height=11 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=15 +char id=1155 x=319 y=453 width=10 height=6 xoffset=-10 yoffset=1 xadvance=0 page=0 chnl=15 +char id=1156 x=481 y=448 width=9 height=5 xoffset=-7 yoffset=1 xadvance=0 page=0 chnl=15 +char id=1157 x=453 y=452 width=5 height=6 xoffset=-6 yoffset=1 xadvance=0 page=0 chnl=15 +char id=1158 x=467 y=450 width=5 height=6 xoffset=-6 yoffset=1 xadvance=0 page=0 chnl=15 +char id=1159 x=233 y=457 width=16 height=6 xoffset=-14 yoffset=1 xadvance=0 page=0 chnl=15 +char id=1160 x=73 y=0 width=26 height=20 xoffset=-18 yoffset=-1 xadvance=7 page=0 chnl=15 +char id=1161 x=0 y=0 width=24 height=24 xoffset=-17 yoffset=-3 xadvance=7 page=0 chnl=15 +char id=1162 x=45 y=0 width=13 height=21 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=1163 x=228 y=0 width=12 height=19 xoffset=0 yoffset=1 xadvance=11 page=0 chnl=15 +char id=1164 x=172 y=307 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1165 x=133 y=406 width=11 height=13 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15 +char id=1166 x=156 y=355 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1167 x=182 y=207 width=11 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1168 x=357 y=154 width=10 height=16 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=1169 x=207 y=403 width=9 height=13 xoffset=0 yoffset=3 xadvance=8 page=0 chnl=15 +char id=1170 x=424 y=304 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1171 x=104 y=435 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1172 x=314 y=117 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1173 x=204 y=387 width=10 height=14 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=15 +char id=1174 x=0 y=46 width=20 height=17 xoffset=-1 yoffset=2 xadvance=17 page=0 chnl=15 +char id=1175 x=72 y=263 width=16 height=14 xoffset=-1 yoffset=5 xadvance=14 page=0 chnl=15 +char id=1176 x=275 y=117 width=11 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1177 x=96 y=391 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1178 x=348 y=59 width=13 height=17 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1179 x=65 y=359 width=11 height=14 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1180 x=98 y=327 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1181 x=156 y=434 width=11 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1182 x=240 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1183 x=276 y=190 width=12 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1184 x=0 y=263 width=16 height=14 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1185 x=279 y=415 width=13 height=11 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1186 x=333 y=59 width=13 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1187 x=78 y=407 width=12 height=13 xoffset=0 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1188 x=84 y=246 width=18 height=14 xoffset=0 yoffset=2 xadvance=16 page=0 chnl=15 +char id=1189 x=230 y=417 width=15 height=11 xoffset=0 yoffset=5 xadvance=14 page=0 chnl=15 +char id=1190 x=106 y=42 width=18 height=17 xoffset=0 yoffset=2 xadvance=17 page=0 chnl=15 +char id=1191 x=465 y=238 width=16 height=14 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15 +char id=1192 x=272 y=173 width=16 height=15 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1193 x=322 y=401 width=13 height=12 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1194 x=303 y=60 width=13 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1195 x=398 y=369 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1196 x=498 y=58 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1197 x=159 y=403 width=11 height=13 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1198 x=28 y=327 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1199 x=481 y=334 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1200 x=308 y=321 width=12 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1201 x=130 y=209 width=11 height=15 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1202 x=318 y=60 width=13 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1203 x=455 y=334 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1204 x=184 y=41 width=17 height=17 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1205 x=0 y=407 width=15 height=13 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15 +char id=1206 x=343 y=78 width=12 height=17 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1207 x=120 y=407 width=11 height=13 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1208 x=429 y=336 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1209 x=248 y=443 width=9 height=11 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1210 x=416 y=336 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1211 x=206 y=371 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1212 x=242 y=241 width=17 height=14 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1213 x=354 y=415 width=13 height=11 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1214 x=165 y=41 width=17 height=17 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1215 x=180 y=290 width=13 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1216 x=444 y=384 width=5 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=1217 x=44 y=43 width=19 height=17 xoffset=-1 yoffset=-1 xadvance=17 page=0 chnl=15 +char id=1218 x=200 y=173 width=16 height=15 xoffset=-1 yoffset=1 xadvance=14 page=0 chnl=15 +char id=1219 x=74 y=22 width=12 height=18 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1220 x=91 y=212 width=11 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1221 x=442 y=0 width=14 height=18 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1222 x=60 y=195 width=13 height=15 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1223 x=469 y=78 width=12 height=17 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1224 x=13 y=359 width=11 height=14 xoffset=0 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1225 x=473 y=0 width=13 height=18 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1226 x=150 y=191 width=12 height=15 xoffset=0 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1227 x=392 y=116 width=11 height=17 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1228 x=196 y=403 width=9 height=13 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1229 x=345 y=0 width=15 height=18 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1230 x=45 y=196 width=13 height=15 xoffset=0 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1231 x=470 y=382 width=4 height=14 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=15 +char id=1232 x=30 y=23 width=13 height=18 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=1233 x=465 y=188 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1234 x=15 y=84 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=1235 x=442 y=352 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1236 x=280 y=241 width=17 height=14 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=1237 x=38 y=422 width=17 height=11 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15 +char id=1238 x=366 y=116 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1239 x=413 y=188 width=11 height=15 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1240 x=227 y=257 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1241 x=182 y=431 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1242 x=256 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=1243 x=195 y=339 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1244 x=65 y=43 width=19 height=17 xoffset=-1 yoffset=-1 xadvance=17 page=0 chnl=15 +char id=1245 x=393 y=240 width=16 height=14 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1246 x=249 y=117 width=11 height=17 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1247 x=120 y=391 width=10 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1248 x=156 y=339 width=11 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1249 x=117 y=343 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1250 x=187 y=155 width=12 height=16 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15 +char id=1251 x=132 y=390 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1252 x=266 y=98 width=12 height=17 xoffset=0 yoffset=-1 xadvance=12 page=0 chnl=15 +char id=1253 x=254 y=369 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1254 x=224 y=60 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=1255 x=52 y=343 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1256 x=464 y=270 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1257 x=482 y=412 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1258 x=393 y=40 width=14 height=17 xoffset=-1 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=1259 x=39 y=343 width=11 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1260 x=120 y=80 width=13 height=17 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=1261 x=0 y=391 width=10 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1262 x=131 y=156 width=12 height=16 xoffset=-1 yoffset=0 xadvance=10 page=0 chnl=15 +char id=1263 x=184 y=117 width=11 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1264 x=140 y=98 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1265 x=93 y=119 width=11 height=17 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1266 x=28 y=103 width=12 height=17 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=1267 x=198 y=21 width=11 height=18 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=15 +char id=1268 x=145 y=117 width=11 height=17 xoffset=0 yoffset=-1 xadvance=11 page=0 chnl=15 +char id=1269 x=239 y=386 width=9 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1270 x=469 y=116 width=10 height=17 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1271 x=218 y=403 width=9 height=13 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=15 +char id=1272 x=240 y=60 width=14 height=17 xoffset=0 yoffset=-1 xadvance=14 page=0 chnl=15 +char id=1273 x=382 y=305 width=12 height=14 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1274 x=252 y=98 width=12 height=17 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1275 x=499 y=254 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1276 x=45 y=23 width=13 height=18 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1277 x=208 y=207 width=11 height=15 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1278 x=300 y=289 width=13 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1279 x=247 y=430 width=11 height=11 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1329 x=248 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1330 x=256 y=305 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1331 x=483 y=254 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1332 x=371 y=256 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1333 x=206 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1334 x=45 y=295 width=13 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1335 x=377 y=353 width=11 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1336 x=186 y=306 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1337 x=377 y=171 width=15 height=15 xoffset=0 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1338 x=477 y=171 width=14 height=15 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1339 x=154 y=323 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1340 x=182 y=371 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1341 x=360 y=172 width=15 height=15 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15 +char id=1342 x=493 y=171 width=13 height=15 xoffset=1 yoffset=2 xadvance=14 page=0 chnl=15 +char id=1343 x=84 y=327 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1344 x=120 y=192 width=13 height=15 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1345 x=290 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1346 x=339 y=257 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1347 x=323 y=257 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1348 x=461 y=171 width=14 height=15 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1349 x=262 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1350 x=75 y=195 width=13 height=15 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1351 x=304 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1352 x=284 y=305 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1353 x=0 y=196 width=13 height=15 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1354 x=272 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1355 x=452 y=302 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1356 x=304 y=273 width=14 height=14 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1357 x=312 y=305 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1358 x=336 y=273 width=14 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1359 x=318 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1360 x=280 y=321 width=12 height=14 xoffset=0 yoffset=2 xadvance=11 page=0 chnl=15 +char id=1361 x=220 y=190 width=12 height=15 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1362 x=470 y=366 width=10 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=1363 x=435 y=254 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1364 x=0 y=311 width=13 height=14 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=1365 x=384 y=272 width=14 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1366 x=445 y=171 width=14 height=15 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=1369 x=19 y=461 width=6 height=8 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=15 +char id=1370 x=135 y=461 width=5 height=7 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=1371 x=415 y=453 width=6 height=6 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=15 +char id=1372 x=487 y=438 width=8 height=8 xoffset=-1 yoffset=-1 xadvance=6 page=0 chnl=15 +char id=1373 x=371 y=453 width=7 height=6 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=15 +char id=1374 x=71 y=461 width=9 height=7 xoffset=-1 yoffset=0 xadvance=6 page=0 chnl=15 +char id=1375 x=307 y=454 width=10 height=6 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=15 +char id=1377 x=288 y=401 width=16 height=12 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15 +char id=1378 x=420 y=205 width=10 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1379 x=15 y=196 width=13 height=15 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1380 x=178 y=190 width=12 height=15 xoffset=0 yoffset=5 xadvance=11 page=0 chnl=15 +char id=1381 x=429 y=153 width=10 height=16 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1382 x=30 y=196 width=13 height=15 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1383 x=258 y=224 width=9 height=15 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=15 +char id=1384 x=168 y=225 width=10 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1385 x=105 y=192 width=13 height=15 xoffset=0 yoffset=5 xadvance=12 page=0 chnl=15 +char id=1386 x=0 y=160 width=13 height=16 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15 +char id=1387 x=296 y=0 width=10 height=19 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1388 x=504 y=188 width=6 height=15 xoffset=0 yoffset=5 xadvance=4 page=0 chnl=15 +char id=1389 x=111 y=0 width=16 height=19 xoffset=0 yoffset=1 xadvance=16 page=0 chnl=15 +char id=1390 x=241 y=155 width=11 height=16 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1391 x=284 y=0 width=10 height=19 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1392 x=144 y=390 width=10 height=14 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=1393 x=228 y=155 width=11 height=16 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1394 x=360 y=189 width=12 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1395 x=441 y=153 width=10 height=16 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1396 x=117 y=157 width=12 height=16 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1397 x=504 y=205 width=6 height=15 xoffset=-2 yoffset=5 xadvance=4 page=0 chnl=15 +char id=1398 x=103 y=157 width=12 height=16 xoffset=-2 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1399 x=269 y=224 width=9 height=15 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=1400 x=108 y=448 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1401 x=341 y=224 width=8 height=15 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=15 +char id=1402 x=254 y=173 width=16 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15 +char id=1403 x=324 y=207 width=10 height=15 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=1404 x=208 y=431 width=11 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1405 x=156 y=447 width=10 height=11 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1406 x=214 y=0 width=12 height=19 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=15 +char id=1407 x=270 y=401 width=16 height=12 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15 +char id=1408 x=408 y=205 width=10 height=15 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1409 x=13 y=375 width=11 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1410 x=281 y=442 width=9 height=11 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=15 +char id=1411 x=147 y=0 width=16 height=19 xoffset=0 yoffset=1 xadvance=16 page=0 chnl=15 +char id=1412 x=164 y=190 width=12 height=15 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1413 x=234 y=430 width=11 height=11 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15 +char id=1414 x=165 y=0 width=15 height=19 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15 +char id=1415 x=403 y=135 width=14 height=16 xoffset=0 yoffset=1 xadvance=13 page=0 chnl=15 +char id=1417 x=455 y=440 width=5 height=9 xoffset=0 yoffset=7 xadvance=5 page=0 chnl=15 +char id=1418 x=164 y=468 width=7 height=4 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 +char id=8192 x=289 y=463 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=8 page=0 chnl=15 +char id=8193 x=507 y=349 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=16 page=0 chnl=15 +char id=8194 x=507 y=334 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=8 page=0 chnl=15 +char id=8195 x=507 y=339 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=16 page=0 chnl=15 +char id=8196 x=249 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=8197 x=244 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=4 page=0 chnl=15 +char id=8198 x=214 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=15 +char id=8199 x=507 y=439 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=15 +char id=8200 x=507 y=424 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=5 page=0 chnl=15 +char id=8201 x=219 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=15 +char id=8202 x=224 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=2 page=0 chnl=15 +char id=8203 x=234 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8204 x=239 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8205 x=264 y=464 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8206 x=269 y=464 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8207 x=274 y=464 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8208 x=182 y=468 width=7 height=4 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 +char id=8209 x=173 y=468 width=7 height=4 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 +char id=8210 x=79 y=470 width=12 height=4 xoffset=-1 yoffset=9 xadvance=10 page=0 chnl=15 +char id=8211 x=121 y=470 width=10 height=4 xoffset=-1 yoffset=9 xadvance=8 page=0 chnl=15 +char id=8212 x=21 y=471 width=18 height=4 xoffset=-1 yoffset=9 xadvance=16 page=0 chnl=15 +char id=8213 x=41 y=470 width=18 height=4 xoffset=-1 yoffset=9 xadvance=16 page=0 chnl=15 +char id=8214 x=413 y=20 width=8 height=18 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8215 x=57 y=461 width=12 height=7 xoffset=-2 yoffset=13 xadvance=8 page=0 chnl=15 +char id=8216 x=142 y=461 width=5 height=7 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=8217 x=128 y=461 width=5 height=7 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=8218 x=460 y=451 width=5 height=6 xoffset=0 yoffset=12 xadvance=5 page=0 chnl=15 +char id=8219 x=149 y=461 width=5 height=7 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=8220 x=82 y=461 width=8 height=7 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8221 x=92 y=461 width=8 height=7 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8222 x=361 y=453 width=8 height=6 xoffset=0 yoffset=12 xadvance=8 page=0 chnl=15 +char id=8223 x=102 y=461 width=8 height=7 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8224 x=417 y=153 width=10 height=16 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8225 x=405 y=153 width=10 height=16 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8226 x=10 y=461 width=7 height=8 xoffset=1 yoffset=6 xadvance=9 page=0 chnl=15 +char id=8227 x=445 y=441 width=8 height=9 xoffset=1 yoffset=5 xadvance=9 page=0 chnl=15 +char id=8228 x=200 y=465 width=5 height=4 xoffset=0 yoffset=12 xadvance=5 page=0 chnl=15 +char id=8229 x=133 y=470 width=10 height=4 xoffset=0 yoffset=12 xadvance=11 page=0 chnl=15 +char id=8230 x=61 y=470 width=16 height=4 xoffset=0 yoffset=12 xadvance=16 page=0 chnl=15 +char id=8231 x=7 y=471 width=5 height=5 xoffset=0 yoffset=7 xadvance=5 page=0 chnl=15 +char id=8232 x=507 y=359 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8233 x=229 y=465 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8234 x=254 y=464 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8235 x=507 y=434 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8236 x=507 y=429 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8237 x=279 y=464 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8238 x=507 y=354 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8239 x=507 y=344 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=15 +char id=8240 x=423 y=222 width=23 height=14 xoffset=-1 yoffset=2 xadvance=21 page=0 chnl=15 +char id=8241 x=49 y=178 width=29 height=15 xoffset=-1 yoffset=2 xadvance=28 page=0 chnl=15 +char id=8242 x=407 y=453 width=6 height=6 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=15 +char id=8243 x=331 y=453 width=8 height=6 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=8244 x=294 y=454 width=11 height=6 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8245 x=431 y=453 width=6 height=6 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=15 +char id=8246 x=351 y=453 width=8 height=6 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=8247 x=281 y=455 width=11 height=6 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8248 x=341 y=453 width=8 height=6 xoffset=-1 yoffset=14 xadvance=5 page=0 chnl=15 +char id=8249 x=420 y=441 width=6 height=10 xoffset=0 yoffset=6 xadvance=6 page=0 chnl=15 +char id=8250 x=402 y=441 width=7 height=10 xoffset=0 yoffset=6 xadvance=6 page=0 chnl=15 +char id=8251 x=45 y=311 width=13 height=14 xoffset=0 yoffset=2 xadvance=13 page=0 chnl=15 +char id=8252 x=351 y=385 width=8 height=14 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8253 x=250 y=385 width=9 height=14 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=8254 x=93 y=470 width=12 height=4 xoffset=-2 yoffset=2 xadvance=8 page=0 chnl=15 +char id=8255 x=214 y=457 width=17 height=6 xoffset=-2 yoffset=14 xadvance=13 page=0 chnl=15 +char id=8256 x=176 y=460 width=17 height=6 xoffset=-2 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=8257 x=372 y=441 width=8 height=10 xoffset=-2 yoffset=10 xadvance=4 page=0 chnl=15 +char id=8258 x=329 y=136 width=18 height=16 xoffset=-1 yoffset=1 xadvance=16 page=0 chnl=15 +char id=8259 x=492 y=448 width=8 height=5 xoffset=0 yoffset=7 xadvance=8 page=0 chnl=15 +char id=8260 x=117 y=375 width=11 height=14 xoffset=-4 yoffset=2 xadvance=3 page=0 chnl=15 +char id=8261 x=503 y=0 width=6 height=18 xoffset=0 yoffset=1 xadvance=6 page=0 chnl=15 +char id=8262 x=453 y=20 width=6 height=18 xoffset=0 yoffset=1 xadvance=6 page=0 chnl=15 +char id=8263 x=223 y=241 width=17 height=14 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=8264 x=448 y=318 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=8265 x=462 y=318 width=12 height=14 xoffset=0 yoffset=2 xadvance=12 page=0 chnl=15 +char id=8266 x=172 y=403 width=10 height=13 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=15 +char id=8267 x=280 y=155 width=11 height=16 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=15 +char id=8268 x=497 y=437 width=8 height=8 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=15 +char id=8269 x=477 y=438 width=8 height=8 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=15 +char id=8270 x=325 y=441 width=10 height=10 xoffset=-1 yoffset=7 xadvance=8 page=0 chnl=15 +char id=8271 x=263 y=401 width=5 height=13 xoffset=1 yoffset=5 xadvance=5 page=0 chnl=15 +char id=8272 x=26 y=0 width=17 height=21 xoffset=-2 yoffset=-1 xadvance=13 page=0 chnl=15 +char id=8273 x=389 y=20 width=10 height=18 xoffset=-1 yoffset=-1 xadvance=8 page=0 chnl=15 +char id=8274 x=280 y=224 width=9 height=15 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=15 +char id=8275 x=156 y=460 width=18 height=6 xoffset=-1 yoffset=7 xadvance=16 page=0 chnl=15 +char id=8276 x=195 y=457 width=17 height=6 xoffset=-2 yoffset=14 xadvance=13 page=0 chnl=15 +char id=8277 x=435 y=400 width=11 height=12 xoffset=1 yoffset=3 xadvance=13 page=0 chnl=15 +char id=8278 x=361 y=441 width=9 height=10 xoffset=0 yoffset=4 xadvance=9 page=0 chnl=15 +char id=8279 x=251 y=456 width=13 height=6 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=8280 x=26 y=435 width=11 height=11 xoffset=1 yoffset=4 xadvance=13 page=0 chnl=15 +char id=8281 x=39 y=435 width=11 height=11 xoffset=1 yoffset=4 xadvance=13 page=0 chnl=15 +char id=8282 x=451 y=384 width=5 height=14 xoffset=0 yoffset=2 xadvance=5 page=0 chnl=15 +char id=8283 x=198 y=0 width=14 height=19 xoffset=-1 yoffset=0 xadvance=13 page=0 chnl=15 +char id=8284 x=176 y=258 width=15 height=14 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15 +char id=8285 x=256 y=401 width=5 height=13 xoffset=0 yoffset=3 xadvance=5 page=0 chnl=15 +char id=8286 x=249 y=402 width=5 height=13 xoffset=0 yoffset=3 xadvance=5 page=0 chnl=15 +char id=8287 x=294 y=462 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=4 page=0 chnl=15 +char id=8288 x=299 y=462 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8289 x=304 y=462 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8290 x=309 y=462 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8291 x=314 y=462 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8292 x=319 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8298 x=324 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8299 x=329 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8300 x=334 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8301 x=339 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8302 x=344 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 +char id=8303 x=349 y=461 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=0 page=0 chnl=15 diff --git a/examples/text/unicode/resources/dejavu.png b/examples/text/unicode/resources/dejavu.png new file mode 100644 index 0000000000000000000000000000000000000000..77fe4b3be586c9c9095813240b93e061a97e09ca GIT binary patch literal 102143 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%0DCYL^i{CQBvrpN3oVE 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%0D=5$`H`1er%og!G5jwIeYiWHyu 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%0DSqtQj*1f=J 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 literal 0 HcmV?d00001 diff --git a/examples/text/unicode/resources/symbola.fnt b/examples/text/unicode/resources/symbola.fnt new file mode 100644 index 0000000..5a39fcd --- /dev/null +++ b/examples/text/unicode/resources/symbola.fnt @@ -0,0 +1,191 @@ +info face="Symbola" size=-64 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2 outline=2 +common lineHeight=81 base=59 scaleW=1024 scaleH=1024 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4 +page id=0 file="symbola.png" +chars count=187 +char id=9749 x=135 y=333 width=63 height=61 xoffset=1 yoffset=9 xadvance=65 page=0 chnl=15 +char id=9752 x=366 y=396 width=57 height=59 xoffset=0 yoffset=10 xadvance=58 page=0 chnl=15 +char id=9760 x=257 y=0 width=46 height=68 xoffset=0 yoffset=7 xadvance=47 page=0 chnl=15 +char id=9785 x=61 y=579 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=9786 x=183 y=578 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=10083 x=984 y=200 width=35 height=50 xoffset=1 yoffset=12 xadvance=37 page=0 chnl=15 +char id=10084 x=266 y=697 width=58 height=44 xoffset=1 yoffset=15 xadvance=60 page=0 chnl=15 +char id=127744 x=736 y=266 width=40 height=63 xoffset=4 yoffset=10 xadvance=48 page=0 chnl=15 +char id=127789 x=401 y=637 width=64 height=56 xoffset=0 yoffset=14 xadvance=64 page=0 chnl=15 +char id=127790 x=697 y=331 width=62 height=60 xoffset=1 yoffset=10 xadvance=64 page=0 chnl=15 +char id=127791 x=0 y=699 width=64 height=51 xoffset=0 yoffset=17 xadvance=64 page=0 chnl=15 +char id=127792 x=456 y=202 width=64 height=63 xoffset=0 yoffset=9 xadvance=64 page=0 chnl=15 +char id=127798 x=523 y=695 width=58 height=35 xoffset=3 yoffset=27 xadvance=64 page=0 chnl=15 +char id=127805 x=825 y=330 width=60 height=60 xoffset=0 yoffset=11 xadvance=60 page=0 chnl=15 +char id=127806 x=259 y=268 width=60 height=63 xoffset=0 yoffset=10 xadvance=60 page=0 chnl=15 +char id=127807 x=322 y=333 width=59 height=61 xoffset=0 yoffset=10 xadvance=60 page=0 chnl=15 +char id=127808 x=0 y=269 width=63 height=63 xoffset=0 yoffset=9 xadvance=63 page=0 chnl=15 +char id=127811 x=305 y=396 width=59 height=59 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=127812 x=696 y=0 width=64 height=66 xoffset=2 yoffset=8 xadvance=68 page=0 chnl=15 +char id=127813 x=61 y=397 width=58 height=60 xoffset=0 yoffset=11 xadvance=58 page=0 chnl=15 +char id=127814 x=946 y=265 width=61 height=62 xoffset=0 yoffset=9 xadvance=61 page=0 chnl=15 +char id=127815 x=584 y=635 width=56 height=56 xoffset=0 yoffset=12 xadvance=56 page=0 chnl=15 +char id=127827 x=121 y=397 width=58 height=60 xoffset=0 yoffset=10 xadvance=58 page=0 chnl=15 +char id=127828 x=0 y=334 width=68 height=61 xoffset=0 yoffset=10 xadvance=68 page=0 chnl=15 +char id=127829 x=68 y=70 width=65 height=65 xoffset=0 yoffset=8 xadvance=65 page=0 chnl=15 +char id=127830 x=737 y=135 width=59 height=64 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=127831 x=560 y=0 width=66 height=66 xoffset=0 yoffset=8 xadvance=66 page=0 chnl=15 +char id=127832 x=135 y=70 width=65 height=65 xoffset=0 yoffset=8 xadvance=65 page=0 chnl=15 +char id=127837 x=630 y=331 width=65 height=60 xoffset=0 yoffset=13 xadvance=65 page=0 chnl=15 +char id=127838 x=628 y=0 width=66 height=66 xoffset=0 yoffset=8 xadvance=66 page=0 chnl=15 +char id=127839 x=566 y=267 width=59 height=63 xoffset=0 yoffset=9 xadvance=59 page=0 chnl=15 +char id=127840 x=562 y=332 width=66 height=60 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15 +char id=127841 x=798 y=135 width=57 height=64 xoffset=0 yoffset=9 xadvance=57 page=0 chnl=15 +char id=127842 x=467 y=637 width=57 height=56 xoffset=0 yoffset=13 xadvance=57 page=0 chnl=15 +char id=127845 x=213 y=137 width=65 height=64 xoffset=0 yoffset=9 xadvance=65 page=0 chnl=15 +char id=127846 x=950 y=67 width=34 height=65 xoffset=0 yoffset=8 xadvance=34 page=0 chnl=15 +char id=127850 x=522 y=202 width=64 height=63 xoffset=0 yoffset=9 xadvance=64 page=0 chnl=15 +char id=127851 x=544 y=135 width=64 height=64 xoffset=0 yoffset=9 xadvance=65 page=0 chnl=15 +char id=127855 x=440 y=333 width=49 height=61 xoffset=0 yoffset=10 xadvance=49 page=0 chnl=15 +char id=127856 x=207 y=638 width=64 height=57 xoffset=0 yoffset=11 xadvance=64 page=0 chnl=15 +char id=127857 x=710 y=633 width=65 height=55 xoffset=0 yoffset=13 xadvance=66 page=0 chnl=15 +char id=127858 x=237 y=396 width=66 height=59 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15 +char id=127859 x=195 y=268 width=62 height=63 xoffset=1 yoffset=9 xadvance=64 page=0 chnl=15 +char id=127861 x=77 y=0 width=65 height=68 xoffset=0 yoffset=6 xadvance=65 page=0 chnl=15 +char id=127862 x=857 y=135 width=57 height=64 xoffset=0 yoffset=9 xadvance=58 page=0 chnl=15 +char id=127863 x=47 y=203 width=41 height=64 xoffset=0 yoffset=9 xadvance=41 page=0 chnl=15 +char id=127867 x=833 y=633 width=66 height=54 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15 +char id=127868 x=986 y=67 width=25 height=53 xoffset=0 yoffset=12 xadvance=25 page=0 chnl=15 +char id=127870 x=383 y=333 width=55 height=61 xoffset=1 yoffset=10 xadvance=57 page=0 chnl=15 +char id=127871 x=530 y=394 width=42 height=59 xoffset=0 yoffset=12 xadvance=42 page=0 chnl=15 +char id=127874 x=0 y=70 width=66 height=65 xoffset=0 yoffset=8 xadvance=66 page=0 chnl=15 +char id=128065 x=384 y=696 width=68 height=39 xoffset=-2 yoffset=19 xadvance=64 page=0 chnl=15 +char id=128068 x=132 y=698 width=57 height=47 xoffset=0 yoffset=15 xadvance=57 page=0 chnl=15 +char id=128069 x=777 y=633 width=54 height=55 xoffset=0 yoffset=14 xadvance=54 page=0 chnl=15 +char id=128121 x=478 y=136 width=64 height=64 xoffset=0 yoffset=8 xadvance=64 page=0 chnl=15 +char id=128122 x=65 y=269 width=63 height=63 xoffset=0 yoffset=9 xadvance=63 page=0 chnl=15 +char id=128123 x=339 y=637 width=60 height=57 xoffset=2 yoffset=14 xadvance=64 page=0 chnl=15 +char id=128125 x=505 y=267 width=59 height=63 xoffset=0 yoffset=9 xadvance=60 page=0 chnl=15 +char id=128126 x=321 y=268 width=60 height=63 xoffset=2 yoffset=7 xadvance=64 page=0 chnl=15 +char id=128127 x=889 y=67 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128128 x=627 y=266 width=55 height=63 xoffset=0 yoffset=9 xadvance=55 page=0 chnl=15 +char id=128139 x=574 y=394 width=68 height=58 xoffset=0 yoffset=12 xadvance=68 page=0 chnl=15 +char id=128140 x=202 y=70 width=65 height=65 xoffset=0 yoffset=8 xadvance=65 page=0 chnl=15 +char id=128147 x=642 y=634 width=66 height=55 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15 +char id=128151 x=588 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 +char id=128152 x=280 y=137 width=64 height=64 xoffset=0 yoffset=9 xadvance=64 page=0 chnl=15 +char id=128153 x=654 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 +char id=128155 x=720 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 +char id=128156 x=786 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 +char id=128157 x=77 y=137 width=67 height=64 xoffset=0 yoffset=9 xadvance=68 page=0 chnl=15 +char id=128159 x=335 y=69 width=64 height=65 xoffset=0 yoffset=8 xadvance=64 page=0 chnl=15 +char id=128162 x=130 y=268 width=63 height=63 xoffset=0 yoffset=9 xadvance=63 page=0 chnl=15 +char id=128163 x=146 y=137 width=65 height=64 xoffset=0 yoffset=9 xadvance=65 page=0 chnl=15 +char id=128164 x=454 y=695 width=67 height=38 xoffset=0 yoffset=23 xadvance=67 page=0 chnl=15 +char id=128169 x=916 y=134 width=57 height=64 xoffset=0 yoffset=9 xadvance=58 page=0 chnl=15 +char id=128420 x=852 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 +char id=128512 x=732 y=513 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128514 x=644 y=393 width=63 height=58 xoffset=0 yoffset=12 xadvance=63 page=0 chnl=15 +char id=128515 x=610 y=514 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128518 x=488 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128519 x=144 y=0 width=59 height=68 xoffset=0 yoffset=7 xadvance=59 page=0 chnl=15 +char id=128520 x=584 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128521 x=427 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128523 x=61 y=519 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128524 x=0 y=519 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128525 x=915 y=452 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128526 x=854 y=452 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128527 x=793 y=453 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128528 x=732 y=453 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128529 x=671 y=453 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128530 x=488 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128533 x=122 y=459 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128534 x=854 y=572 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128535 x=305 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128536 x=122 y=579 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128537 x=366 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128538 x=244 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128539 x=305 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128541 x=366 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128542 x=427 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128543 x=488 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128544 x=549 y=575 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128545 x=671 y=573 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128546 x=732 y=573 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128547 x=793 y=573 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128548 x=427 y=0 width=59 height=67 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128549 x=915 y=572 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128550 x=0 y=639 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128553 x=898 y=392 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128554 x=959 y=391 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128555 x=0 y=459 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128556 x=61 y=459 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128557 x=305 y=0 width=59 height=67 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128558 x=183 y=458 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128559 x=244 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128560 x=709 y=393 width=61 height=58 xoffset=0 yoffset=12 xadvance=62 page=0 chnl=15 +char id=128561 x=835 y=392 width=61 height=58 xoffset=0 yoffset=12 xadvance=61 page=0 chnl=15 +char id=128562 x=366 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128563 x=427 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128564 x=90 y=203 width=88 height=63 xoffset=0 yoffset=7 xadvance=59 page=0 chnl=15 +char id=128565 x=549 y=455 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128566 x=610 y=574 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128567 x=610 y=454 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128568 x=401 y=69 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128569 x=878 y=0 width=67 height=65 xoffset=0 yoffset=8 xadvance=67 page=0 chnl=15 +char id=128570 x=523 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128571 x=828 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128573 x=767 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128575 x=706 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128576 x=645 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=128577 x=122 y=519 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128578 x=183 y=518 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128579 x=244 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=128580 x=305 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129296 x=200 y=333 width=59 height=61 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129297 x=366 y=0 width=59 height=67 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=129298 x=383 y=268 width=59 height=63 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129299 x=549 y=515 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129300 x=0 y=0 width=75 height=68 xoffset=0 yoffset=7 xadvance=72 page=0 chnl=15 +char id=129301 x=671 y=513 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129302 x=181 y=396 width=54 height=60 xoffset=2 yoffset=7 xadvance=59 page=0 chnl=15 +char id=129303 x=778 y=266 width=98 height=62 xoffset=-1 yoffset=12 xadvance=96 page=0 chnl=15 +char id=129312 x=0 y=137 width=75 height=64 xoffset=-1 yoffset=9 xadvance=74 page=0 chnl=15 +char id=129314 x=793 y=513 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129315 x=346 y=136 width=64 height=64 xoffset=-1 yoffset=9 xadvance=64 page=0 chnl=15 +char id=129316 x=444 y=267 width=59 height=63 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129319 x=488 y=0 width=70 height=66 xoffset=0 yoffset=8 xadvance=70 page=0 chnl=15 +char id=129320 x=854 y=512 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129321 x=915 y=512 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129322 x=0 y=579 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129323 x=762 y=0 width=59 height=66 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=129324 x=772 y=393 width=61 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129325 x=949 y=329 width=59 height=60 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129326 x=261 y=333 width=59 height=61 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129327 x=462 y=69 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15 +char id=129346 x=975 y=134 width=46 height=64 xoffset=-1 yoffset=8 xadvance=44 page=0 chnl=15 +char id=129347 x=675 y=135 width=60 height=64 xoffset=-1 yoffset=9 xadvance=58 page=0 chnl=15 +char id=129360 x=70 y=334 width=63 height=61 xoffset=-1 yoffset=10 xadvance=61 page=0 chnl=15 +char id=129361 x=191 y=698 width=73 height=45 xoffset=-1 yoffset=18 xadvance=72 page=0 chnl=15 +char id=129362 x=253 y=203 width=66 height=63 xoffset=-1 yoffset=9 xadvance=64 page=0 chnl=15 +char id=129363 x=122 y=639 width=83 height=57 xoffset=-1 yoffset=14 xadvance=82 page=0 chnl=15 +char id=129364 x=491 y=332 width=69 height=60 xoffset=-1 yoffset=11 xadvance=68 page=0 chnl=15 +char id=129365 x=412 y=136 width=64 height=64 xoffset=-1 yoffset=8 xadvance=63 page=0 chnl=15 +char id=129366 x=947 y=0 width=66 height=65 xoffset=-1 yoffset=8 xadvance=65 page=0 chnl=15 +char id=129367 x=180 y=203 width=71 height=63 xoffset=-1 yoffset=8 xadvance=70 page=0 chnl=15 +char id=129368 x=878 y=266 width=66 height=62 xoffset=-1 yoffset=9 xadvance=65 page=0 chnl=15 +char id=129369 x=269 y=70 width=64 height=65 xoffset=-1 yoffset=8 xadvance=63 page=0 chnl=15 +char id=129370 x=823 y=0 width=53 height=66 xoffset=1 yoffset=8 xadvance=55 page=0 chnl=15 +char id=129371 x=205 y=0 width=50 height=68 xoffset=1 yoffset=7 xadvance=52 page=0 chnl=15 +char id=129372 x=389 y=202 width=65 height=63 xoffset=1 yoffset=9 xadvance=67 page=0 chnl=15 +char id=129373 x=887 y=330 width=60 height=60 xoffset=1 yoffset=10 xadvance=62 page=0 chnl=15 +char id=129374 x=961 y=632 width=61 height=51 xoffset=1 yoffset=15 xadvance=64 page=0 chnl=15 +char id=129375 x=526 y=637 width=56 height=56 xoffset=1 yoffset=12 xadvance=58 page=0 chnl=15 +char id=129377 x=425 y=396 width=53 height=59 xoffset=1 yoffset=10 xadvance=56 page=0 chnl=15 +char id=129378 x=321 y=203 width=66 height=63 xoffset=-1 yoffset=9 xadvance=64 page=0 chnl=15 +char id=129379 x=761 y=331 width=62 height=60 xoffset=1 yoffset=12 xadvance=64 page=0 chnl=15 +char id=129380 x=480 y=396 width=48 height=59 xoffset=4 yoffset=13 xadvance=56 page=0 chnl=15 +char id=129381 x=0 y=397 width=59 height=60 xoffset=0 yoffset=10 xadvance=59 page=0 chnl=15 +char id=129382 x=684 y=266 width=50 height=63 xoffset=1 yoffset=10 xadvance=53 page=0 chnl=15 +char id=129383 x=610 y=135 width=63 height=64 xoffset=1 yoffset=8 xadvance=65 page=0 chnl=15 +char id=129384 x=901 y=632 width=58 height=53 xoffset=2 yoffset=16 xadvance=63 page=0 chnl=15 +char id=129385 x=326 y=696 width=56 height=41 xoffset=2 yoffset=19 xadvance=60 page=0 chnl=15 +char id=129386 x=273 y=637 width=64 height=57 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 +char id=129387 x=0 y=203 width=45 height=64 xoffset=4 yoffset=9 xadvance=53 page=0 chnl=15 +char id=129472 x=66 y=699 width=64 height=49 xoffset=0 yoffset=14 xadvance=64 page=0 chnl=15 +char id=129488 x=61 y=639 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15 +char id=129505 x=918 y=200 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15 diff --git a/examples/text/unicode/resources/symbola.png b/examples/text/unicode/resources/symbola.png new file mode 100644 index 0000000000000000000000000000000000000000..e9426061047a5b7afa272d2f3abb2a9c28e6f826 GIT binary patch literal 244613 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%0A@R^-j5GfmfSLc#$8yHi5MF2}n6dd97(NriDU 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�8$$NNg4h1JaOrpi|G|lgm(9hilDpy|F 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 z z`+D)yy2VFS5a&gNnu$acZe3Od`Xeh?Ip{$`mZ*MTJBRdmo+oad?}6NYU%Ok-bV2#^ zx5W~LU0A+2&BM@pUY6sm2UI(3pIbMNj+rb7_dbhuJoIl{7m-FiKYntyuAU|0cBaEh z;=;ym3Rj!)rV+d(CndvT^FdP1vRL(;%uA%iigiAda`#>jmC+(1BfCw=T{I z_V%g)UjMJrqymk{|I>ujLLa;tAXcNK4R@kf3W4T;Tpp8BGmrb?us;%(nAhzcm4rV! zvlk?s6b+glb8Vs4GTkxAUjk80TpyFs;&usceCtG6_Khh;-~unXl& z-Q|?=i~IjQD1y9)c)Y3Q!JQ)jg}pZC_qE749n|XYgWDphmEZVG8sZP>fCT?v(+YAY zrKCpkrEV3Prk&$l8CVzfiH`4hVnMooEloAiz$&O!FjoJ!aidp58GY)~yH;&S!*z1K z9;MlAMFsD-)cZ%iip=T3F@9Oq~4QthF56Zt@`1jPCMD z9p#?nq{wmW8179sfi!Aa%Yz}9 zS0}|W*g$&17ys`Cv-$|9ncs7Vv3wWZhHtP6GQ@+fZhBE`VRYHJ$}}Ig9GqV;od)R^ zSW8LV2%^SuCNT7v>Rt+!EiCJ@m9b=FBPrlh!&Z0QddM8BSFh|@iz1++)8-m!a z^;O#niuoXG8=kX;T8e`D$a6QMz*LaE%!ZFcLp)>(5GNncXPEJZs7dHhhj-Dc ztz&5Z+{B_H1R71>xiAd!*O}y_zz__SWsQF6_ZLAC-RC|Zy32zxbybQjG?zud$b%#KK)zBNtiChHdx)gl3xriS0p+BP|>$u_F zHF{y_p?seHuQBM$a+pMc3Wop9}|nT zkVX)*+k zZf8=nJnJZ#nBOdF>&U!CHR(UiCszwBn+Tt+qet|bQIt)NPocUzoswsNnu{NTILAKP z4Ej(1FLJIi^OqBzj+aiAk3E~x0CU|1soT(WRIAjArIN|O50z3f=HJSHfHdMF55J2@ zO&W~h$ZVdIo^uf=G+OMG%zLMVZRJJhHycB^p0EklirJ`1Hz-)pRq`SE)}YX6Gm&<) zo&W@Qw(Cl8Kd)`|P09mwzl{LxAig$}R9f@|c{aoZGQ{LyMJ zm}6ApMYuajA~o_*0uJRFi$9yLl_>Y)|9r_{7C^Kn5c9{MvwwVI5u6SU3+~hqwkD$` zgI`6dv6KTn|NhtWUtxsyRb1-+@FI z@ZEi%_?z&(68E;pzgkH;i+7acJQfwd>b*cel6@Sj+Ym)3yGU>Na6sf~UecE*75Osb zi@Z$8zQdP{Lg@=3Tkhsr^tKN)h=5!1{wbDyB4TFNTO$C!Uwytc>4g#{Iik& z`UTO2+`{E~5=7stILv}AYV17@63OWWGiF?aYp~NhGzBZb7ZKc~=*4`Z0p>6TwS3bH zr?95G=@;EbDtnZ9>hG$XOO`?z<={T!i;g3Fj7Dus-Y~Z@JD)cDc)Nq*bL(cx?L>v!+e(g1o|uO>diVwR=)XIRmKpKH*^gaMczSw zFd%%2cmD_adi&UcXQtDku2K9qdJ+%p#_EL~UI)2U$j_4-a8p=Txn_+*Euf}9Z3!o} zK{|7nN|PeIza)9DzQAu#x@1XDafN?WK^sNshRWh!E8rQ-I6O%;vDa$l^Hm|V}&un(O4j(xHqcZD7r+9XA1zTVi|NPONQu1F`V}Ax>BPNlO0r(PhSD`8*E0 z39Em_EE=(uTXOzyap38mt$CpVnXwSXK)nH=}d5v9-V>&e#_zUVbFV zFlh<`+QY%i> zHXW3NzZ3izmBDk#)!1ahXdI>X8tKNW2lF5DY&82gp#By2Phqt~i|;XP(Cb$OBQXu#g{{<*^rgqVMOu{G~Ybq$rB3!3KEEppi#^?DPNB=2BYjGVpIJqj*W_P;eKbWM50u1t!5s{D9d7sXLml8OR|(C zy<9eC$CD0112g|*wTA&KB^zW4qh%&!$mq~p@6_)b72hjg$D1PHlodX%9FaLIePc!W zfOVEc7#~a?c^UO=NEL^Tz(_Gm8sR~q+j&Iv=*s>`+9Lk<<3^#}hM}n@$ua?SdZCQZ zf+Pea8IwzdTVA0Wc{KhL0Js|N)sdN(sqR@R3*jOQz>RGpb_?kIeamlWOrCxoAKeHf z-IBd?OnL^QmQetxmqZR-(swRuzP-fIQzd5fC4Kr~mo@SLGH)RTA5JbIv3R=1Zy>OE zY5aboS|p?gd$Z*`p-OxE=r@hWNWN~x`G2m+pv@@NIXYP^R|cMJITh%R_hqJDva!*> zQY^zquHHSB#v+ZeEqXkd+U@>n^o`6qiLLfq^#1($XUW2`i1oO!ePWsy1z*Tc}`fVv#KUJlb} znq^G-10ZcPgFoccMt!wVemZd9q;6syy+)C8`SYuYU0ZRT{RR z@*sK+v=m^^nrP%^6mNjqf5$Pgz2gCP^GhFU=t$1EE1{?iN?j|(t-SE_^5Ljq|3Vy$c zajH3l$#1eLa)3vB^xJw_0Y8)K=@;XZ*L@8qY1ZoL2fq_XTP?NhJjh&<+a)CizfX|X zRVMV?_X&h4r#jqMF!Wcw2pwhFqp3LMsn}+ts*}F)D!k?OksoR{ zXQF~I?AGsRtE>sSC((sfIa*w(h=*!QHsP$N>d{8?q>rOURBcm5 zW7$TDjE^$L^YVCz<;f@iYB?>M7b%xc>{YG^?R$Z`t?H#9WY=_cJLDqNPe-6Ss646RpX@ zTMN~xUUOIy*x&qMgCQ2DScX4-V5&cPznjuu;3v$fKQ2lP@04%LljqX@PC3s8IvV(y zu&G~Rn*Z)q##Z6-Yh5P)gHN6_e#9SCcydh?+Im#*l@yK&w0*bf|4kE6i#UV2PUUom z1(>8wML*wS_GVvl*p^`QTBN%Q>x?UgsIr6z%bnrVEg5(9Rufgy!iUnI=U>0))JlWw zu@9T46*^@&M0=;YP&V2UhOX$+m&aSyR$Le~=$h|QR<{L=WIebFf2T5;lsaKu6pNKw6h?j;drHIQtp#f#h0O-rspW)Aa~KaCxR;RB%btI+&OgfTP)!;=(#j{zcVTd4)v*ZDf?r;~YOocR>? zp6V&=Oz$1kGTZ4kqk+ueXLM)@oG~;_b1F3%n>aak#oo7IRP6FI5fpQvR_rEdp9_kE84WYS zti!UsFHsl+Kh02=lAzAIrhB5mPR#4G+vVGcHy!5KfleBAg#_vMRhY$oYgU#_hoqdV{85^u{Y-i#%P(Vi zCS9%+dni`E@mB9~`l&~j4u3*^3XU1J0C3iCqc8gLd-+`y7=GjR>a8CNb1bm)xP8)J zcFO29Gi)s`qm+{8X3fISK#}xcu^A>?z66X=CK&CK?Q&n@?l=h0F-tj7v!3$p1Ss19 zImtbTX%AzD6V4Pm#SaJjPou`ZJCM9Ea$5->ms!TKNI8t@jkKasfW+C(gf}O0{u*VM zaZUqO&P;He5P-CuCg**1fpFcQ)<^lQG3;MC8Fvp=_yQoMt_rRUHBC3N_51yHZ{((V zEyoSR;(s2j+j7Qj$w)3+DBCjLzG-T3B!On>I(!yjOB(KP7hWbG4T4FE{&|#s!vXUb z-x6NnWpR(PCPTiz%TC#hU(fp|#BdPUu5--VndOSyl`s~bTHlQ^&cr(UTO3S+*D?k+ zSj;yekwwSlET9ia58vUmlzlg&-NA8;4kL0%dvgMbSgS|O{H6WDIi4!vam}dwoCXOq zR3H=Xc1psUveJ}8u=~yLpSC2)zNl_0azr?(#C~pC7OJj$Tr<2{`yM{pV zTgu;J2tK|j&wjUf&vEtEJ;WjF^zI0A;nr$1Glu2!78I{#ds*T*!)VICbl+81Fy; zMl=0x3k1U4oM;@pB9Mylj-aJlETkU=$M47}J-P^Z6mtcp9*!6noDl`hl#ngE-GUn4 zZ^uRaOzls0)fucF=z49Z-qVhhrr7bOuIHQ!S157`sCZWN>E5B|C59Zl)NJTVJk}bX zsT{&3vAhw0apeTMdkS8@ws#J!P`BTy;(1|w_22}??f)CUauh@Dcosj~Y@Tpcm;O9S zrZ&oiL5%!}iJMuPdYWE1_9ES5S$0=5ncF_3DQv_&p*7hTKhSjqKJ5w35Ih$woCy65 zx8K+*{aA`M8*mT(o7Q!Y!I{%=h0z66ta^yL>jWLgnLdty0L%0+$6N`YL_BcA=Aq!- znP78qduPj=%K1ic_w2S=c`RoCNtLj&)_JBl=5auX;!+I2;H4aVH#dzo0NrEzIz5vJ z`al~PAS+zxmh5+9dCCM@A807A5p=XK&efv`?N*Eh&lonCgeen+R`j3Ga5Z(eso*i? z@mir>Y7|nUG61X_GpPxWcK0ddQN=W$_ctnu9o(W}pO zbrOIh>}|5gvgK3qkmw;?`No}OGwo{}%Tt^;4vSn}qvx;FB6nw=qXj^`6lTFKQF71G zP2itHx1`FFr}eu2xT`A?^yW0{B$Yz!Fp(PGF@DMSi?18N=+NJ8R!rFw)z41I+ae+_ z&#u60I@~liW|b4=yw}P`YA=y{3p*>vs-~0Te#`nGeSTEV1iKuQ;?(|?eyJ2kl2Uhp zv_Smgz;HqH!!Eo)0njH5&n2IJ7w03D(j4`x7lHR!1HW~El0;EX9vJT&T>=2^sI9Cl$*A%wl;xA zBM95P@37dyZ!iu(UbOWMBGRrOrdc-v49u>mgW)imWRO|Uy%gk>T}7UtXJWBMUaEFf zsqo~g{Mnfo>n@Z(V~ftzsViFQKktr!h@FbF#C2?K4qv5hD+ zbVD8UR7b_gN7rIu9=P`^W zIB^)&e9sr3`}i3h!M0i~H^Ndhx(D?}_TtG?DHYnlWv&3_5{rj|USc#KjzlJ#6(aP; z^0orYATy7wCViibEO%mbWjxP!oNgy271;_5E*FwJxQunern;Gt++#{%&!X2nR{wt6+Qqo~ zGT{`6+T($YT5Uhc)c(Wx*X=``u2#uNTYQ5E)=G4F-wz#1opV~u0rpjPjPL{%Gh-a# zu7=&7&LKs|9()A}!E^%(m~GZ1a8HfgPa^My&xUKo3`cga3vvM;!AGVST7Ur|5J-LV z@_EdDSx-Q4G)gJw^v$C>y`15qn1|uDKz(x>*ysyzCteFA126+HGix}12>H*oc=-Eh zh(Uo_mRmtg;|(??!Lf)h>SLTlVPH(p9xk`_q2BllYca|#XJSjrsV0rLRQF?z_Pxr{ zJg+`($(d$nfVSssx|}{>Bb*}IEo$G4A*#yZ9k|I*fR`qZANDP_Sc2Y^e245JoBS}H z_ijuHE-<@-^J-5Jm#uvAY*<2V@RP>lz1c^xtR$NK_g0sO;z1kNUTU@(n7ma3T__u= zd#5_#l%O*c^iku9ZwBvOT>jkj-YGOb%L30I#X`UFWcD&YX(dBK6=MnR!r8Oo#TDYm z>_{{Co(F-uqFLqmpULObX!hKrFv=!kq4ZygG>I;O+B(RS@#~*LIUW;@L^IP=Eo%k8)~$^MvelC^xM zTP&`R+m=R^;B`r!QvhK_<$X$iEW;K~m|*(UJMcY-*Zx`iDOND*fPe);_ok-sP8C4R zlbQ2Q2S=#nFoFfA?_j<8XM)4-Gn8Qg>tU|EWuImdAp5W+RDUI)|r>Fp1( zfyb~1rUmeHAB;$dl4c5w@5CH8T`b@$#5n&;B*eXG(azg5tD{94;l*wjNKYKf!<8g; zL6&5R9TG0nf!x0MFK34dYCu6eB%-PV{G!kn>ZrR))%6D|la%l1#lp*>dgDi~^HNUJ=8?qfdZ3QdC2)F-NFZ|BG9*d3Mat59}x zx<5>&N5sEUrXq`d0NUK)yYFr<=M%P4db901f#PspVFfavWo(L{y{kET;r->FTOoAj z0!`fh7^cqxN2$kX$NizDiZA{x8bA5-C66(7Fh!6t2o*vyL>><_0AK9Rv~966(PN(|=*iX19k_1W@MFk?0x-M% z>Bixns*8n})swJ84|Ve1$H1;lK$VPXL8)~_jni(ZLw;5Uyjq1}fTXbN3)yyP1xe(Y z8Cj(rCf>Xn*D*|fFf<+$srds0DIINqL!0K~`a z53~|vU#cA5x*bgTuShyODoO(SsWEQS^u_mObXYFQ9qoi3Wp!W9xixbWGXC&x$C`#< z^xI@)%f#ZN#}}D7(_{QAQnh^5?m;8S^)$P!t`)Xd_R#t|%4z@BrXg9aw`kDLTHWJ= z)`4z+`_F-V1a3Lkcu6UvT_x=M`ve!+*DBm~0FK|Rgve6KK*FQwO)njBZk$+Jnv-v5qZT*)}LGrfr zrUTIzaI>nkCB*94a|SxtWoNo`xdQqRc&t?Fx=se>uOeMx=g`b`ASW{gCc2hxy(@n( z@2_>h!@;2RL9BAPRL(4>Pqgy=On^2BiQJ(h@Q^8}wT4tCn~IZ~1vDJ?x)pfIPi|x) z#$KgcqcdjLjiR?NY|0E6n~HSKGfR7#WDIJ?!Sv+>D7|G1^yAOY2GZUiMC^jpSBgk4 zk0y^E8i@DTqossa6y^a!dh3c{ab>hX-`z8*rv9brqqv)C(dF7wHX5SCcbwgB*U6-3 zMTJxhlLkCXZaK|^r)8m)geG_^4nO_8VBsEdvD)}Eg!lvTQ7|GQdW7nY)Y1Owk)KhX zRVfdurNqV~axh~4T!5s)1JY>9LkPH8945h>J|L@pKrvp-*i^zwoxJm7=9OrFJHMpH zM6lT}rfAby`*hqGewIawgoH#}P7QfpD(JIWJPH@4hv>GSw!NmK{8~o+^$nd)UaEYy z#!TJUV-4kQ1=k!3aSK9Ox;V(;Ftq&qq|^05J=Olqfc*qSF8Ld`<3x(f;U9>FG(|Y- z;r7a_+p>XH@kh&pSFiB4eZ%s?)?5x3)nfUrSwGL$-qdd>ee%!+-l0b(UjZ3)dy_pz zO82J@X-S@in9>ERf)^XkGo^MK!8rBYi=S$-H@CYB|| zk0IF-<6$%8ar6c(>UxmMpnFk!XM!#|O~X#i-3Ij~!ho4jwoY_`115ak0u=BJE=Gtn zdM=(v+-ZHdA{<~EUADjR;W(4UV|od6_u7i4GO*c_6sRG6er`(nD;!U`XRICq3cpW- z=gf1wIGm2k%*m+u7C_*NU14EcbnVx`U{I2s-|U$l7rep1IdRUxP5PYG^(#v{#wsfo zIuL<#Jd<*HC<9!pGJpwOSk9IByGDZh&bYfFM%`8}-2gLOwyTaC%w+q-TW0f{iz<0} zrQV-H9z<8s@@4&gbi=n#ig2P|cP@wNE&2-3FcjCwpAYJj2Hb#Uu#P4}qLZ~4_0Uw> zKwKJWAzIq9S)HXV18?LG-O9tNE)9c;y_k!ycS@CkS3>+#S=yK{jIFgJ39U+?suK%8xz<*gWy=jb9TNhd5CSlcI@FgPqN!&4OA zx?_VK0X1xh{cCA7%4Rg<)QE)klD8Rs#mc8VD!!3^dBN7AJ1>1tWDnQa(JKn zASZzKN6zx+z=k0-Go!~1=5y{~+VzUa8zRPkiY-&)!z-L_P!LK32`k{{ z3Ve+3KgdZIuxk*%= zP@^#ORL65rkUuTLXGbcFk?6KC34hU9?rZ(>!)7wYpU6w%DMkGRd9fa0p<<8G5B{Qk zSvXnW1VX%8gErbMbvDAm@@uDJbgs(4ej*2})pTC#`re^4fWesqJe7BWi(Ig3;h(CC z!^y$1cD2b`;P5h^QbMwo=b*Az`Uwqd1S=byJw_+ER7eHSAJ>!t0~SIX-!3+}I7&kW zV2FKztU0Ia5n=sA;m~;hmXR$$Gl3ax)+D_p4i#fP z;2ur3(x&{vr82HN&2&HD_@^p({qK<+f{DXm@7kTcF@(gZ!cE%`6 zgExCAzWoKF1Qt~L_Vtuf?XTi<`d0VAIn4&M+j-8K2MsG_>_{n|Ix7kGaYHLszW<~g z!RW+OIB)mt<)m`7nGt|j1VBwf2D=1a4R|pGdSE$)Ld~8Sx5mO2=Nk8dW_PBe0#?RM zqJW@Z6c-Z&Pv5s3eJvX*EtuWpa|vE6flz#-ajRkENOYz*(;tktia`q~0mc5Ru$2b< z%<|gm&ZkAM!Hj9q62P}$o7~1<=3siTf|p4!Jic7JP21LA@o#8>iPxE9s=Y<43WQLh z+7>&#luesaXUL9ck!iwAIlBOG=)keBbR89AB#Vzeg8!!uhRXOEO45Ua@6(asIx(Mr{a*Z0=t6o-m%j-l)*Jo9l3(+6Fj z=c}hcIs;2u7!{y2%vB!LeS~R-zrmX&GYAT^>RFdCsP>_!tiBJ^nY2 ze#QZ#ilVD6p1%WYRRFtA&Wva%p9{+L06jHV;_6ntGIS8_GCcf9BX=3<81`?C@;_ehOeWGYUvaLJJz~q!ce3I zM2#_HO=E*`fOV|bJ+_Ypn}1|l;r{n=U<`} zd(g2P;BL)XuaIzmIkv{L#-o?`e8) z<-;3VVSxN>V>l}(e(WE>64Ry((5#1E=e< z+=A?W>p)J6^-e%tJjV<3o^INYrlT(b5tGZ+X^Ede-20Dg9`s)jeo1|nTg96P|Q-|!-j@du5CL^po1AJx( zC?km*fcsSEwwFr}y0Fe#nDE}R<;02I`jbloiw!0T{||OQPwPbrdgJpl8z$FXMFZ2Z z^#Ece?>| z6ZRjduB?}5?0-@6|Nd}<@sfgs=hgoQ2>O3tXq)2i__aRhGUsOW;7ohv$3JKz4no6? zFh9dgKxo(cyxd2&s_E&-s9BOr3ZUVv}Q>&z){~Z<| zjS6K$1WDo^I{;0NmZE_fKW<>Qhq?wjh!KWQ8Dn@Xw*006SS1*hA{e7?W}cvzEB=p= z*(<;fUDV48`X4$2wKW5R8$nmj#^?to0BhnAfYBHu7-3<3t2ZC#^O{s1NI?k{4yEC^ zfugHAv(_4i&sH7v1~C4LS+y^LvM{#0i={?QPDgKftlDLA0O0+je}M7sZk$7N(W$ln z@W}?Bt(n0$wiNWcPXl{FDi~KGGDf$i>+9E`aE!8$?5^2RlEiN^trLs5la{e-N~=DC z_^av?V{`bcUd~xF)&IfMKS3N|0_k=DF~!+gKJLq?2z%Y73y%`QD5n&bZp%c~dO z%x40}Bu?VeE@!gWsUld%#DUrGXU>8)yrU;LbDDToa67ii=BqWIFUiE&JxecrlMI=m zV9=1(d%-}baMHxi;1nruB60YtMljumA2}?u*&E6q7d>e3ug0frD9T1&dfNLw?&Dxu zq%V=?m>-dswzP1Dyj{dh_-_1#5k&&<3c)SazQjxd@NF4S7FS6soP(KgJH~T+grvm zBGPv~^G06UJ!&wRc)nWt>CDMxAp%7si+;$|zS1;V+-?B8DUIo|cDuOh3O1bCx#L~; zGPdcz@o6b=QGw25rI)_a9yi=iYz%fM{(k`NC!C&UD;If@WvT1r9b%}ZFb-Sje<4li~6nmm%~XxB3tn&FK=ArzEn&3y+NO9GChq zE|tW>7a^S}CBn#?5T)FMzTKGWGca;;bJOlzy6r%@imEA(E&Td*?y9Zp=dXQEER&U% zgSR)#sH*nIfNV5GJrT+}8ujAG?Z_Q%a={;=Mi$=R%0WKmg_I-w7x8GkAD{K-hLfuG zGELr64cH4RBuKrr=gKwiO}czH5c1mP$m+i0BYdSekAnZL!be0#ce6qdpY0`Zm78*f z_7WViiSZC6+-8#i-=r3*1dsAtU7bA5s*bt0!MQZ{0`Dugt0g{G0~0Ed{vIp*PNray zv=gkWFv@)SHMzZ*^C8>s`gjeM|lp|GhHr?$G5UGz|JEdK%wkb&a${|#`qO>J^e=tC?* z7sn>UrYZHKMx|(Y`=(JuVu3RvFDEYL-8~JX34c~)561lV8o7*udWnI;p0>fIA`f+; zVBTmo$qnXFeTuuyG|_wvOxxLiyy+5+Ge(lq5@VB8FZy*#f*k(cs!+XXC4%I@k=nzB ze@av#%ZJ)aa%#RnS=WR$1O298{9$?#qs%CBb&+w6%HEg-28c**ls%;OE10VqaXjNV z^#qzcEi4k=uHwd`z|4|+W%bj;Pvg!^aYaa3FH2A&N)bZ#{nd*umZ_{A;bg{SebQ!F zTl7tZO2uV@+nx@1Mk6KJx;#WT%Vp)p!F=A?Vx2{%|JOpR@~DOKu$SB?pK^;9RU~(S zko`mh{%SIM)}lF?byG4fb2YSh28_Ji> zHG*TdR<9;H^nQDO2*|z^;W{j~|0vXVA!dmCg`Zd1XWHXSUq1=mDBGi2hXXxpuN&_j zoFNe@b1DSx%WG@<^h8o2fe`pq=r*sUf`DdaRVqsEXyOt9|n?K(0$=fx|{^QPCzEjLg~N83BTcvI^<`ftvFHn7>Xdcl#qDEPM7{xjc{E!2 z!yT3k&QryT_RPsqnS2cajd_n?UKPL>d`P z5qMo}CC_b*2?gSfF-A#z zc0YAj#){s@(KqpuN*S5G%L~ABj?UYmQ$4yD`F+i59Kkvo+O`uFRe+#L>e#n?l{UR+ zl#-Z~d^#UV+AA}Cz93q`{KMxa5Ut-Zvsr0lqqW0Z7V(aZQ!tzS61@bwGj;ed|Q#^~C8&D9R>m|U(@wW4{?Dwgda zB`>P~-=HC3^pGS{(p>MXIY9}Y(Gf;ifQDlVZj?fn$m8~TUmQ~QDC_mOZxVx64Bnjs-YJ(nWf4VcaslCHAxG1?g+Am zi#C_#XslAZ=d{9+C*B|XcuJG`CS-&ldyt{JCwlb*&f{cKnr3MyP1cc6wMMRO!tGv0&WzT{0mZqQIy^Z8-a*X;kKhKG7&lPMh(e5dy*skt$Fk7qUZKxP5>6CWv7^gPdC=*etqDUo1 zthVwESgs3Cnqm{iSXG~Wx93aCza51#vdlEUBFtSz-v3s1RewCEhuW@(YkPxrgUxN( zzzy8?qDx8%_*<;-8e~Ru_T;va`oo1?9WbHibf-Pj*9>>#4@oB_HdJCYvNQ;Z%Sm$V znX9S1g)h0Q=+_Ahh;u)N$3DjS#Zj9bwf0V?yFQ29g-AlC8Sy^n;&9f8Khj%Q&i;ra zkFoFcaV<{yMh!nCQ$+Mb(OrdQB)41I_`8S+ADu@wqOTRGX!HFBW(jw=#@|-M)$|Lp zoeO3f_tYlM=EeIwgZnN*C=2mEy*#~0ErA>Tjx7+AW9^Ch;|G-q)IvoJN7seb%uS0h zogL+b@v-*U>STY7M!#%nXSJLa@Qh%=A)%-V-D#N_(@C%&s#1DW`Wc?0d-)_fW`W}) zH;klei+$amt+)2Tu=A^r|ET(wg>L$Aqq@I&4DmnaR&XPn zH(N7#W3zHT)$5s!3|*a;g^~ANWZJqLKHW#<1u{wBeiz z-W>Ueb6fhKPSvQ4*naof)joOa?U#R9<~zy;NDK#hDa)O(Z3HS*ZQ?#uk7(h~{=&1@ zpj=IPQ$_|aL>_1nr|up(P022^O;c7VjqYbi)u)l0y0zJ{T7>cj(G;D94e(WHJBKOh zBAfeEf>zafJbpAS&#XIyFZs#t%5C}Z{dzH~2TNk0bhNI%JJbkA=YjS%+hW}5)xrdC zjtHwVGxu$@g}C@u_%xG%-Fn+>Ie%pLlil0RWIm#IjclUfAr+K+e#7KpO|c9%i2OkU zPPs705ob~OO2=;!Z0_%8l=?-91;sS9=g8>OABh5Fu~TD2T7~A6e`1l)p|sOi7Ss7+ zxd>o~R`y(!Ds*WP-Skp&vuWA`W+#r&X&Hp?!{Lhc6}J(Z>^#a?ChX)p36;b}_R z0zAf+2PNWm&qlbrw^{u(>Z6pN=%Tz+a;x5tYRdYZRlk3@v|m>HC)#+$V~(6U;tTD< z7L0;z-%yEQsFmMNBtqunTED;$vJfne^bL_*LKu*$CL-Ut#5(q#3)arq(OTbq$Z{0A z`P41E6|>){-n8G}4;!mF+irZpDo5wT{9s>JXPbxGvTt0A@{Gs*bs-@lzs&y?$tG$4&i%Oo>;&Ua`95jxS#_r6J6E+|2mxr*p0iBM!P%<~%(y?HANcp_ z%nL?O@7On4`@L#x1~ou_LR0oX5VZ_1$wqla9xPGg+7D*5N(vHM*4)0k+-4h6oYHRx zG>dxF`+Yhu_)j_02R&lslkry~2+cUaW9i8eVMT}H-CRIT?A|Bafpsat_U%i_PW0CvLVG77qCi^-|d6 zvTsysm&X1R(>@Qi);}>Nnb+_&qh8&D-$G~S8soM%FM}%0-xVfW7C9tcTZ$>*QcmlJ zv!VtjHvi-&H4C}=dHzB~eBlyEJgW97A2=_NhNd9B6o-B0YkiZ8;Cpt_@;^0c`!VQKEK4V4kE8ZnjWv`Q*;b5u64A#1=5yah){uY5P-X|meN`Wd)SuXVln)gL2E`MD5fSl~^Q5Uat1NiAMuI4w= zxiJ3foi-Bu6%Fh}kF=^nJ21M^23~g{oC43Xg*Glr;X|G3P+HZ~eXF$JyH}K55wcV- zFJJ>!A8216+3nwR!3K0C`(INyPQ|X^978w$jwR3z91XJAWV;)>L-#%LyI#klJuqjF z1jX^G23!#lp9%wTRt0F?)Mkrmbbsg#c*MKki*Q*yUY7J0IqefWoQ*)^OT4nddj{4Ub_e{{J6QXBiO17qQ%yD7XjVKRV5sNR-+Pj!08T2Qg;4J>t2Hk01 zW9W1!OoG^m%SnQ!4ln4^F(SN}Fpp&qGC4e>_knO?12b4yc(JEv@475=-P`B(#eVxW zqWW)!SOe!OibV->bMEsf*8MoS@RV8#fTyBK%6SFxLQJ6d&flFuKq4wvQJ+X}@60`W zE#-T0yRgxZrq!bNR@HR`C62&|nXo>7&Pk?f59H5dYL3J6;j&FUP(7Y4&g_8Y&>N75 zI?yo&(lp`NyphMmk4}+ zGDJQ6bX`Qvu}cBx2aDt60UaCaOuFcdXrmTA5}(_#A3(9-Fu`38R%5h=rO&g8*NN!M zj#NhSM|nQgvIKwYp!!k|x*^kW#>@>PBjuarx(Qz3g!_YTxcKcDcs)R$=Zp;rk#D1% zLC3~vgKQLMf}nb}sBm9Oyig`_8Kt6vFxF5tH4;=r80osrFk6?gAcQ(R2#e`0p_1iX zZ^)w8X%U!HU?B8(1Ub4HR4hBGz~0}qqj=Jx-M2wd9(|{9WJ&1sNG#WwpMveS;J#8+ zf>EIIQ}Ca`1`oE;^XnAe4;_{tl=EH*ZRv{~ zT_q@(w?bBX4B9zxT^)X3bzwW1 zQypeHhS&wzHQF>P~tId!Q0EX_|sOBh?roSG8do2vsxY-ogGxh_*QM zLLTC$aaP*w23w=!+CN#mH)a^&uRbVjK4?4Keia{nMPp9t z<{eG4rYe&!{ueKnw3yE8oN3=-b?-RdWUk@G&5`%{&hTciw#m6LrTQlLU|F8>GW20b zadPCdOehw|*sW2yZ_S#@c2jn9x8*a@JM@-9g7Z72>yxXsaU&~bin#<4=~O&I5LLDyN) z8A(#fgzRJxZT}^G`R$=bAjj3@Wo?Ln8~^v zHNf<1+gRIW4}C6vVVZ`z!e?`+<(~)JGi%fZ;FXqpgex>9v%!Ys*+${!y1f+ao9$zu z2NAU8$+qd`WIBB=^ZiG+#O9>eL?nY4bMH`syO06c7-jAVZ}qomyv;B=rx5Z9D{Pkm z5jF?RCtXWA_S;{)97yr-K3Kw-UYHE*<~0#(yJIXRJXv+SR7hz}#qoIMxESZ0d+Qa0 zPAKTOjdDSrOJICRR`$shCnz|hoPF4Fdz0*`49pczZ$se*Pm;^`vq2IN{TK4?5VbF@ zSTOjpn=w57@Wy7Vo{hNFtx>MHV9bi{5;Uz>mPE197lZXA*an>XWI9yU+=VnOoG^)^ zL?Qwq4Z0%;#}ItMkTmEkgQ!sBN;lZwYCelqxr07ayKP300Gbqu_`5@`sw%yqrRPdk z7q$I#&wE#fX%FcVf-NKLe!A%PMcMs1ACg6eVL{P{>c|3Lx~QS%p^)%hS-ZFJhQE+l z>^loW^aqUO#~}%wNxT|1tsquBk*Fpm?W<;+zW)6aKq2|BARiv(PNLMP%P6562E!LO zZIs+QzRil?YuFs%KT|3wm0{yM;ECvL_M<5g_PCF-li3wqWcPM|cjLVT2}JN`Fv1Uh zGnLLeZV>2TuK2^l)GxdXMABWt;(m|zUEXyLUQxo8wUmm-Qn=@PyD`k6*MDzF50O+r zSW;s2SxIl2BBg~Ph#hCojnaPDdgkiBMnf=}xXkv(5M|AT4Q0hHkB=eoTIm58%D9k7 z)#K#uQ$yNE9@M^Kb8HH$j|fpTq5=nq%hs7Ngc6{}&)?tf_lBQZSXt# zs3lk&vCFG*k%(o?CO&}&vAdz{QPM8_aVnnKJu^Kjm8vinXBa8W-V@0KrT$yyi)q(t+fqe2ZZy=L~+z9;RUOA@8J~ zZS!m;G7!7ov~)`1%RBzdFnz&2(m1m2HT7DB zH;^8xX5KF+$5s^hW=KWTRf~Ce!5g%Vxh-u5TAzI~sB%j1C|Auib7QS!Wj_A56QP~_ z8xB}nr@F4XY#4zU$As$Y5gpsnF++1t6diRis>R^0ydBPt1 z(O4m6$*i_a(EE&n}kTxk(c^sq@TVVq8h&cAtRNMIwdBT};*G+c^ z`9RSNtF2$gXNV8>kEPhK{w5KOH!2~NVV?A^S`l^|UY${HKTLls>nOB>&j9I*mZ4YM zilrn~4OmIJu}QxH_CLv_!2G(V!)yDW-Uz8kMKzbWfA=IkP-Lx(8gG#vFiKs6`JFBm zri7kI>k^^hK8@%7T55^m1!!(=CV=kJv?>M8X! z?PdFW=6WxLOG%I2bUNkM5e)H5+mQI{^Vq-V+vSGRuYIqvO^^~Pmm6-e5uPNAC)$>J zCd1xKw(s4)A2aIEWQ+e^#m$ABC_!YSPEm^Y`Au-y3w&kI^c=PSp3D0Tm5dR+Df0JP zrGVBeMKv1?JNa~drR2KWd>E^~?*5DOr@9OUSKY9TdmJFSQamgbXHwTSpxFYVbqvm5 za@VO*%W#a`&KT&AvPF8OT$WfO7D7{XCUd0QU}3zyO4fJUxZf`-RmmAI^V^<%(*uHr~u#=+3LLbGB*k#}^G7vB_vj72> zi~ou0_lUn?K)h7OUy#qIApIj~P8d1H=M=N-F1*n5%woYs1D@LS4sXa;u2<`>$~9!2 zF_$jxe;x%8X7i^$7WCj6(;KR0L|Yjz$Ik1Gc0SUTR>`t6L= zgo!NLnJp%^{@9?GgabljN*=-y|pv`k;lTKvpV6&!fgK`U7Jwb2n%liV;+l=c(kRmBb7rFY=E|d;m zVp9B35E=>i-X_N1*eK1Bsyz92l9Ob#Ju zK!kKJ|47f!qK-!LxPQ9`)I5iibRPYK)o;fO;xq#S4HR2~u*!ZqLl4wNbxFsmr3(~%b;2m_J&5C?UU#-zE|iC=n^|Vt>?VIm#T(@ zkzEf{s1r6Z@-2~ab1+0snR%+u@qt#f!F;};^3{5NXG`GCyAN;5MN} zC%MZb&=xsx>EiPMilN~^_WsQ65nRR=1NFjAkydtX2;oua`g?8Ae~+C;D_$p2V)OzS z{6W6Yj!#FF#}>&ojx3kowNPvJICZTTy=RF$)tpCWt!kXR!{=3S=gE%q6?j`VJLl-n z9{}A%pI1=?p&6?>Zk@Zdj2Z9>UME8Sy@`9zB&@m5OKzq--{%Z@(loxh!7`J8uaQu3 zocOU2RG-lwMkWkdsBE{yu;u4Ief#snQ!z8*NEAwuV8@7#?ck8p;}a~Pp7m`MQ6Dx` ztL|*TCEaB_@vHk=`kEt^P{;3D<@1;r0o}M0_0K0a52kr%AKYnUA5z89O@)$Yr<_mi z{&^}kzPXPBQ6IEQz|?Cw%?_!34Z>RCht-$d3VA#pMJ=>BLe@i2o)Z1Ni|0V6DBMp2 zVTFs7^f`kTk2}n(4o11Kp~})?fI027sV*}e+vW*mG2~9-vIdQ; zf06A_Je#C0OF^qs-JI*3@CJ#`uUPLTlanqTbwVV(HumV4p1Y%V1(MBqGSMNfoS}VZ)O;fnxVkB^z4>|b>J!U+dZ?S|_^JHo9uD|z##P~orP*(8=w0rE_5`uSLT>NX*BL$BycoWbP2E*!TD~4)f#b6FX*PjkUG7g*AET#; z&8p1$FdCNS@ea{>?{e2!t7}rc!p8M-PMj=z`DLYcqKnZ?{q6IS7AJnl%mLoTr^*Dk zK#ZC7$+kcb89a?iU>M2|4Yi!~)g22e*y)vV>3F3luk0bKZ134KbP+aae02NB6aHA8 zbf^jM2*~-_ry-m7Y>t|15<9;Ks1!BpsqQK#Qiz|1_m z2!(qo(locz|6W)H$>8(*&5G(SY(*v4KW-a)ymUg&j`!%;R@a1l_QcGdtV#f1*SUuD z*06a;c(9&+rayPX=|64lBR@-ODZsG+Nbp4OjAFL@#wtjqXnD?B^(aDHB`H2!IcwX4J~ zieGL3Gq$eqOjHQ_M@?Fx$2eb5ry5HQKdly?#W&T{qD!w(y|FNkbz9E+sMp-q!KmH2 zOU*0GV)Y&;cG|OAaTav<>d-yqnl1EMQM7kmSv`wknvoR+G15)n3a#Fq-}AdW^0!wt z2lj{JMX2yzVa;jivDQezSJC8+H+qaYGX1XgErMjJ!8y)Hg8Y;I0?5Tq1z4riSR2Jv zIkP^Rd#j{rOL!pY6`U3Ah+wQZZPC=bZr1xvQpu@kO$8Fx>obwDI_}6XXp=>;yk~C8 z>NZ`xgpOUlOK8kWgIE@vp=-$DmOIV|SLv?k_)i&9OBu5k*@am-D`7UbC8Tim48JEi zPNBGma(Y}^mLnELXCV|o^4?+D!&ttk1yL+MI=;6QKlt~GSe8OxJdCfDtA#JocpFq( zb#_YkI-XCLz2JW$e$Z7+S~ajZ zWAN|x(5|5~$Gi1K13qUyWc74l*+ZzCqE3O8KI6S)TA`|k@Jfyo$+7&VtA;`glh*;S zFZL;CAT3Fjda(hk1r13rWn`WBH-$7uJZ7!zZoaMvfVpi`gGCC!lO;m+Dm9 zx(3Z2qT~GsOH`94849d>x3y2v0t&j7PFsXy(!n{zvm*t_YKp*~WBOJ;>cPA6I?HFJ zgoMdWL6KivvEVNx?!%_e{3@R~4BRH|#gMv76@Yv1_p;8>`<)mnj2hN&cy&e>sIGVC zq1qI?(US?(=v)KwcSvC?F5-Pb`qKttewvI8dS*ve<7BLX;lol3_~ z{8bX1psdnH<&$+8=PRNBllp#ajUrV;erm~pnrqv{vH$ug%4FZwr*FClugIBC<;lsS z*nN^__TZJ%b;`6d3%D!HkO677wyc*rKXFT*^(U!vABc)Gi=^vTbb=5R{HQc{N}KXN zuUg{o$IfNr?&sWm@}J7~dyEm5zGIeaeVRj5k5~B*Zo0RE=WNYdL#(QQFQZ4!9b(fQ zrFNaTm1JhFg5|3AI~8=dHIT$mQiDBbx@VOVsQQ|BO~M}&<$MHP36)-m4XE3U9_ty? ztMxbuF9O2Zp6WZ$$i43DT#@eihD&{OXWp6o&-{p%zwbSZqymJS0%D;n1rxHGKQT}k zqdtDgf6d4^xum1PvhDbz3&8kU#%&Pk*?B6~(}I;&CszewFREOj;T$d#P0NYQ@#Vhy zeUZKbx`9Cpjx^EG%Eab)noDjMTP4Fb*O|xPr}X6$T{1}Pk|p#8O+vhwXKt_fPKNrc zW%BXW>{fkGT~^+;jo;{0HOeMWu@HGiO&{u=18l^E%Y41T=p)XyEN9jjfLQpSf@qE| z#2Ga)(K7bfkz17i^0q*H55?8;%h_3k^U7YLDRT$Hur)dRZ9(5OsT20w21ZuxD=;9a zY7ZLdar%UK(35B+vEO5>of~}C8TKW3<5Te*{nhzLqBu4QBl%a}GNkvA&YLV_G^&z5 z-ADJ4M2kap;L&-F!;%n%2eW>*{3RRz8cl|=(ac3&%*-GLir#A(5;YQ2Fx;V*;IcEg zgEwMm)bsm2^Lj9EQb*e8^wNr?W*%Bxyi66Z>_U79eL`w3UgkL|zQWtupxEpBvQxy6 z5uLk3iy@QGS<2=8@ba}0NCsb`06LZ_lGCoR0VAqO1D_pyFtiHW8vVQ+4J-16_7 zodR<_4c1lYs7gnc_=S6U?W3T)1(81-w+fd%Phh+<7sTq)dk2HRR^-Mu5SJHoU3PQy z+ZEEkJ~HLVjNK&mH@Y)-5=qs?_zt?$)CSZuH~59uUZOCbgO||F#l-z(ebGIo+ueVu zR?6|G^wo>A;(|L=>BP71xxi=N3u!Lx^QMbtT;-jDw<<%;Nmae*S8Ugn)M;cTT*m9H z#F)TN-%c#&ns9FUH0^#gjDH5V_<9!U?C!|JCQPq--E^PV%b>xda>ldi&FSYh5MX7J zTZQDFQ?5_1&I5NKG+3ABt5+v0eikME-&ca!WFi zn!>7teC;a76(^e@x(j7K9=NY-jOsHtGHdCp&!z6eH0PSA)@9^}u0qYyMtjk0d@#Yc z5`0I6P!E&S829snQ9bpH%dy#?@P^KcG_WU2CB0;EX~I&IuABw~=E&cAiK5{8VTU2D zc^ZtLTEB=+lH_PQ4ALI@muqFEyiGX4&APMEGTY6ONyY56tjRLEL+H|YwWuDWX&%R|9$#jZz&auc6hL~hs3f6Rzh zNH~3h_-`;BJZAQLaOo$e$o_N05~^nlzGTdFwLeF)T-z|Pa76QuVl)DGoV2F z{mUmBxL`vefuf|f7up;)Z#)RjXUmBO$Ng@IFT_s{HG}2Xa)qdfsrg;kC7WKon`mdv z1kl0V=G4Q9ecQ?eF(s-6b(+mzWi&<|Znbu=I*Qwq3JCbNzXt$8`O{tG zBUoyaqFb2;NZ<6zg<7Wm)Q@F$%JXxMc(>Tc`I-#qr3^O$lU`oy#6Ma-5g<=E>Y1Kd z-jw0DvSZn2A15Sda6Ml&eD{PNP&^)`N~B${jRiYwnV^DS@o&zRATC62IX+V~-t|aw zAeHo#a)Dp{{0jZF#llXn0l%I57X;w{Ts8RrbmW|=8BCrkv%IjHeD zthcRf!5K}ay>w|BA|}*=o&)*Hb8hCjUeuiZmB^Bb%wx;`Ao(CP(Zp~E#SCjo6t5Om zH`zMRL7NAb0{*&PFbRLGF{mEYu6})RFC1{sw*0=H`wAuevI26)@l*^q2i57NC1rk- z-CON>?F6F7KkoGM09{ai;RJ=+pl)Fx1<*QC`O>9Aco*oV7IEEi%ogs%c566v4YCba zh#a%Y062N0w7N&|5aM-1P~So64M%LjQfxsyr?+95MZx{&DS?V_;hj6}gzJLC%YH1V z+NW6U*k61>bt4^!qx!c!hOX(&Aw+!L*87JV2^C zJH1~3YP$#ErDbCat|<%<1<@Z!wKafEl4XVdzjIc+ZSklS^1eYSmn=(m{`c32f|y~b zr_6u9)X;eSXAbm!N`sr<`ynvrv(%me#JRvpj{j{zoE-nQ2g!}3AUUA@{v(iUIf*C# z`(yvJ!-*F7|HqjA-vMKSIrUNxkEmero9D3wA&(q84j5v)Lj-h-v1RZVs$3|U-BcuG z=Oe1gK>zO?D&P0-h}99@-m)H1LOngyhl=gi?VxpsVc4n%)!*~Z8+h-zO1=k&_afi!{!14rdw@oH#%)6+16b!nTWU8&p07RWcG$+UqKh%RYbJ3gK>49_>NVjstU@wUKe zCle=MeJP89dLLT6-O75)<9*2Z-$kM*@_sAMPyq~g>d6alK$B-Q)*aPW79>rDJP=Gh zp^r+xBo8Bpl6&B^TTh3uV0p4S7R>)83}?;sOit;POoZ66KLBxX^fwTRzjjlx3h2e( z`MO1;F?GeETdWp^T$_JBb2!BXBv}yFz$FpO6u^_S3Fxk@RN2wMhC327N1-H9Gd~wS zoY;=ej08K8GLAQ$GZ(i8Apf!g)F$5lLoXOzJCHQ7Em7|IR%M`53g# zrnX@9XHCi@4M^sAKcq;7gq08#l!-6bO{T}{nK1lm0qTR~sW|drB&2ROG>GvF%Pc4B zD!JJ9E*eAmh4}-#eMtiz@~#n(QjbM*UZ=hMFqPrwt{T3?{4fJoq}XDjJOLl9pz%;bgKF7z zuvps#u_OufVgKVyfSAF`0B-RU4YFT+MXy_Mf@@xR($(_eKd`%P=Lsw7Cv*=V0nXx# z{}*@svs?hzp0Ci2v!`BK;89?$(hxKAofIlFA^p!ia3xcNo@z53paI+agv)xAXyjaG z^(8e*3cFZWrvvx8Ru4ZU;C2>*&dI$ZS@tM19(0aN=ZN<=OXEOt?5I}$4Q4%-oZ*|< zoFMX(PLfXjA5R6s-qXu=|?~7$U?1Q>bs0Qa6+%lBb*PjqL*?|LcO08+$J%LmR)8NgxqC=m+f>MDQK?|QD z6=ap?doJYzyyJ`tCZ1(iuqIHvJASs@?psv938cdoG9>sy~Rs7iXt`>|1OmjC+ z)4vYpD6;H0e>;)=WQh8Bb*d*;``p^u#_m62G-f40*zeTd*Uu|7G$rwEe>h@hU$SoJ z?30@A^khdu`polQOYL5wNYkgiUYy17nm6!Qi{rZ-Pv%WYv)Ey490l`YiacZy{?I7r z%ZsgHD6kBnK9mLaiH3ViqLncy6=6JzYjggJ*cWOJyeU`B5D^)R1$d1v+yyMsZL=N~cVvQo0s!7)zW&s<6 ze{35+=3z8@AZd+p+Vg!M(t=mlW9l;*^@8_vhqU=m_9efAK1U)#{rWTBRRac!7Kk>} zmO}m3^_NtS^sl@w<4bQ4GixoK_tkqQ#>7t(xX$MGHXbNZmj8LU}giTg|mO`>Doy!8S-0tRNJ`G3R|ULPN9pQxHQ zpVdC?GOTWjAJz_@(rCkaoJ>cw4^$~aE)3@(+w z1>2j|dz{i=akEC-JD{v*c_aN9&}K4f82>AlMQL^=4dV-Q+*esYoSt`8x^nAEI~F?l z_2vIWbrfB{iFC+XF6)!$b=j`1I%qEYW0FkEUHx;;DQO${hyo9y~F{MMj@I zfT_srP{(eFqV*O!qRAjve&YAw&J#`*5t;0Yn=YBI1Q6KsP>UgSxjk(7=G6mHRC``X zp9RZ+S6ppN=Jy_p{4}H_Rlt$+rlmy**TJ+*r)R-s@hd4#P5t2hR&6h#vIK!lu9H1n zsU!4fFO0%aiaTh+B<=LiSmYy!l#irqDw_^3|%$ z>!e%F`!7Ql42n|AUE!0ATL?`oWj929IzaxXz$;l0hL!R^gfd} zfHyKViiRvsm-%__m3$R3*9lFsy^@}<6p5b?cy>9zvtyz4HDU%A8RcVf<#0KpMhNe2p z;{}3`dfd9%A+9hki1pZBS*M9_Ug3eB)_^1+0R$4k$zouY*+MZn_tm z$TemAs%_Gxd0%mx8lo5G9ZBSwTQm_tGqHOT_*sBu&Ij`xMEZVW>!d--#Z z%I;(*ew^~jp0l?;?>20g6pj`K7CWHYvR5eT?E8MgGsAID7CvrSHY?P(U+Vh;vb3P) ziI7v|jF?|t{wHsMtMYpqVa71pr`OpiQ<&c74iB7tmRph#*JPAoEnN^VFfc&#Rpjy4 zu@kObz07`D;49@~c|SjrCO1fQY7TjAGa9xwNIcgV3Z1-~FX759`YZISf8IO~CA4Xi zd}a2LYsYp1T)Bm`ugtFPoWs;OK3JQGRSF^XA7ScwLOPV&L*=L=UtHFmT!M0^f_Ij@ z=>#D;fIlM@{YyH-wt~GZ!A5bN>9+#;R(IYs>*=i`kg;vg@O`PpSr_;nI@cSd8APHsT(T1}^n zQ#2gjnB(Qg_p!@hp|QoSe(5q)&&tSnaF1i|mX>=F9LJI4S{~%AFCt6fqR?i#dRbZ^ zZM=Oq;TmIaG13t$t}uQY-`z!wG4!M3j6Tu~Sh#mLVGwvD2&F2`;eZgY80powJUO zDuYMlCtkwqp1?T=LwK=|<`Yr%CJb8PfLlVLqso1P)3FPioy&wgXr&V6`)f_4a??FVy$;BuqwYfYrZgrKI$j89yO zZ+i9s+SI|22}`91rj zHFhmfh<@RxR0!3UU4;Ql!MymVF#Y=g3Jm*4zXf*9CuA zoPydDxazK*pp!mFKZyJciI3hOZP+sdmv%)HElme6YjxY}9>J83nrafCkFQ$mY;fK7 z!>++LTe6+=jUJA29Qs4{FgL^JbVviAAm3#1zQk5!Mrw;`K)pdh;$ z&NVRJ+MP{H+G%N7Qg6QLt}{VXBB*MIj_hgn%l6E3FMS5v6UViQ=CS3`C(Io3F`h-! zs3P+Am`f$UvYQ%5h>3oXZOxd@$$hUP(cQU3)X{H+ib9LV`oK0HSz&;a=Q$zBj#2Fi zwq!3vn<|8POu3nxx)>=#5XL2cTfgo|EM~L%Z2o(Pe;wCx~|EX;r%4jZA591^d~1L+uO-(tVP)@B8I*iJgd*Ux$+hmm7EXnNQe?1%V z(8D(mvilGUz<2-IQFK8TZ!mqO%yz{$w@ifrv|k>B-0?i=!jnO+t%#ZWzK5GPa-bp5 zGQkUT)Dl04E^U(xv}$N(3NX43 zOLpo=A9hCyC4c}MiSXc&1t@^@OFrni?0jEdhF7}Rp#$N380c8tP%*Ccgn99A6|mCH zh%&l1fRNJ5vvu7iD4WSJlOqBg+QvftPY^X@**LOty|`Px!SsGZw0JT$~KN1fj3q~~;} z7A)FuP+bZi=1~EasmY(8Q&pwR~6c?#;cAuPg1p6Ko@HAw(05U=LZ2_ zn}R_B1RN*Up9`+Br~7(G_%|`2UnKJAWHuBWJb4vd!3AMr{a^?r_syg^t&p>f1jaz>E?~kXsadRM(tQQy8|3e znRLV(7DnayiNsEAHC}cYa>ig64o44g@6m0M#*!aXY9!yFzqmBLm+8a)A$b2#?@lTA zCWPm*Oa77(Xb|=fK!?*w%Gk#(PO_DhVR+?KZciwDGq;ur%N=Y<7-m`DcISlQuJ@_n zx;=WQh`r9gc@?twmyEJRgaQb&*ep z>xy>39ad=iY(oUn=U2iT9wm)H(L$icBbq^q+36Vf*ob=1`_mC$@pKrkiGL}-<%=S& znOX=t?^kTN4R4+*c9J34BE9IF^erKW%fUeU>QN6)Y#&CicWiu{ zmPZd;k|1(*@JSP^HMr?27P{$gi2FR!iD=teg8~1B6z`$tIX(VkhF(&J$2RRzt>G>M zM=3`)GI+{PSWlAEa6uUCoiYlQ-E$_5$|X?P)-h|kILljwNFmKMbZ2^UkQa z5ez0;7onVMqf5YqAp4)dLC2GPMwb>B_r9#Lx$$*jO;?$*UXW>o8j}~|m66)Pad50~ z!z1cr?CJf$N{#2u zPDH1*B84ur*!a3ZeX%6e5JDH^Pn{sUkn8iuEYNdVcu#UOo8v&+@kw52a`TIPq%Zkd zQ3y`%1yTsv8_~_%H_kusZ6!rYidP@Je65`u#NfpWQ_Nz4lE(yC~lzq!OD$S{Z~~J&7uN)m-iuZIp&ARXu#j zK7sDI40!)m6t3A*KDkxUhuhYF!;HGWB5|D08XlOj!OCg%wU02j?_}^un+=jhR>gL7 z?O$~E@iD;krCy3@e8B|iII4Wm1~7T(NqxF_9AC~qF9M(izYw1Op&Xch5UsJfZU6P6 zj~Jd@au9wc7N;$rbMfE{ChByLV4d~sGvF%uUCa2Qeti5C!OT6Xx*Hr|MRPW4w2dy*UyWy+6`Do$TTyUVY}}L{ zgr1I({WYY*T*Y?#o#3BdzD~#$I80-^&2}_{(dvy^cS;Gp0LiT#b+J1vE3%wnRU>a? zZ!#8ShdPp{$_@wg zfHu4&ZlZ2k*#;+L*dP=9IxBXO-SX`A9sjlMfj(G3KZZj$i~>_pKzszcs6kxyMb(NO zJ-v+6GkMUntq|9IgCY*MWAE`nzXHiaMj5!^V0OT2a(=bXI#WM2RMG9nL<1L5aon|F z6HlGqDbl%v{X_2Y!xbnZAF?UGD!9fA$KW?SsKY+)6Pm|4ARzGx9L`iLI}E|u-=q7P z7jmDaZ%~Hy_kV4DR$`y}PCOfOmz_f9>Q`oJ*-6sB>6Ls9vOlOTMiZguycoVHV_npz zyu~~pE}~J6=zDp?t&!3x@Np~?Fy1)!ld0P530xETeyX_J(miv-pG|KcFvL2< zTHm`j;=|B5yJeIve#gkAp-`WUU>6v0CXMS)iBUC4V^No{KH*q2_EgqrhA+rjCzVIk9)%At8`@Qec3MMbaZaC`Ht*cT#5w#^rzg2pkFkh#Fnea^oR;mH|Hh3ha>=Xwneg1 z+eYGMN4-||>{{TDTJW$|TF-NbXZV24r9QeCWE*v2lx9Y=ra}|dcUVgLo&_G%(g%h; ztrl}*EMHxztr5yU0S`~ZLMSWFZ?64 zf{y%OLSAc!29t_Cy<9#Div8-%>nJhr^24_DoTr~73b>^Wko!<*|F`H50cl*CWYp=r zs;zclK`7}#g*pJecGPlnMfP{-M|sX|%?h%o()Hs1rv0{lgFAgR!=S@>D~Y_Kid_zs zo_?%o8^PDj-uU5AW_%{Ib7MbVtQ@><%18V0in)=qA26c-^Gv`|qWfHcoPH@tK6Y_RAhHn-!bJq|MVgIb4_Xg!HH{f|DM4?GwUm^#`M0M_aPc52dHk~lwG zPbSl6$yQbUsi>vQMgS^$Z55MMF23=bDRbkirj4G7a>*LtUu#~=mv}Az=TNKDC@*OJ z=HBn}eEqw%NLL({J}>u@6?B~3EQ+#!p>=k_Kju2*v$lmzdVy86Ys`20ad;U?sarAx$XM8DbjgBqxT0c!|>aM7a zA+H@68s*>B0jeTFiB@u7bn{3)rTP?;1{A&GIE){{I~TLA%q~Qaxvr~e78Ycn$-&PT z_d7cD|Mm|Wcn2g<0aMvmuNAfuD{uhik56fm|6#X$x+^c4!?m%Pa6RvFhzN1*aD+F3 zlzO9eNEHE-Y$;J(nxLpy3I zQJW6iJwL;4L{9`#A8vh-9$@}a<3PXD^BpCXB|N&IL4v9%Ez^Y>sgTlH;ves^rwV(h z4K7p}2j7rx{Wr4rvcQT}5sSw}08_lXVVnzp{7#5`v`QcA;q1AyLPLoiWOVQy~zK zGXqC)FNraW^s5Z2z&=|(T@@=`6T?RN7t%R4WPjh+{Rj2&2 z?BNHoH9D~zs>yp_VBhp+(T*;B!*yH^V7|-`Uh;h8m>acdAvAkz3M{jtDh-O_(^ZD~ zh=%Z)V+vt{Kgi2O}Y(dxsVJ|KS*MHBoMwHXii&iT950q*ZUjduHkHL9HoXEAQF8{T$dgJ5|*Y z`&#!$fevjZ;~Fa%|1YJ4(NES@XxgaaB*hf&Ze=wj{+7~X z_cNU+*^B7881JXAu>xpO*7eeGo2ce%YRbsT@~p#1AzmqDMh)9whOAChg2+Ep2r#NX zp%@Th@7i1?CZfAya;rc97@1(o;3ecDME(4l3uBGKFsCF*66{b0rFYsyNw!ZoSf9?2 zfi*!1s`y#ADPJ#{rn8VxPz+mPFk_sNjGP+HKq!if3@dml?aK+|>j;Q$2RrbH_?fkR2PY}vV1a=) z_3ahB*!Ka_`!2efFWc!j2AHCQc{^YK@f6A2uq`3y9{I+nv29{pRkOSx@2SX@=Yw@G zlzDO0S5TKioykS&J4WB+oSIU5&^?ym0&v?WNO*b#=e4z&iO7Tzcd;Kk#7YNKXt?J` z@eNU^s`VQ%{1q5J$-((N*F>%&2Jh1ftPSE5EZbtCOMN;Wrh-(mt}p4KSr;o$e00R# z<1rS-=62da#^K^*FFd_jw+9)KQU6^W!r2JfA(pNf2e6akBolT(9fbVCi{~h)FzxW@LaXyCtxY=Tdy6CCTOJCn_up zQXJIW?bKC!f;$4344l)9Qmt3M_f$2b3=xQfY(MwZf{6g0C0&-bn>(Trdsy4a)3O44 z?bW9!YaLYLgQ5YsPqxY1h>+)F*Y1X^Szn>r-~SI`XBpN;*S-4yEwo4}#Y@o^_u$2f zyB94E!KFCCofelM!J$ZTcWZG87Tn8&1`EZVljnW^=Q`)pIr)%eu1qGAJ$q*D+3Wt@ zOQcwys<1$ivo5(zr#QClTR=ONjp)~5#9M&AkD{6^S zXE`Z7tyy<_byt^EZjZlu^oPfPP=OklkVpb0p=go-Q1jW3B@d;;fLB5`GazO#6+^Yl zXk+g%lBIQ^@WB9V?RM(f3x;F^pMWwu>>rU1!%SyuSqE(!BI*iH*7bk${EW-m;DQe+ zQM-JvQ1)vPOcDCFVcDD(1X&gfK?NnR`)f>=^aZ5T^*pnDvo?-I93ZuPj8E+fUG$1~ zIydjmo0hYZb#tHPUNPMfvOh%=pQXa zC*d>PTR|(ys4UZi-E`WUUV&QXOI7JhWuVr|Y>X3Z&N;ddmW)TpP?Q-=S`uWN7o7HZ z24mPOV*y35g`A96~zw*Aw-^9{Iu9rVbVuGz+vHxqj?R)KJo}u+FlPlwVo)!XM3?mUqxsf@t3naX1J6p5w z3FXCqmwiF%%eQ3%H8Kf=SM}PWy(ikXMJ8OiDZQUket}s|9y|YZ#P!oPDQD#|y$+ph z7O2xo=LqR9{w1Y_1^@?cHX=d>i=tSo`Q zXuYvjEUT(_de?cI86Q&$ZGRZ=l8MbVF&!1utS4D#Ym_Wfx$+bDCd1-gPbzyK-KRuG z?TC8^WA7Xfl6tL{F5*FoeM$nL=5#8liMsSq-mrStegB?Q%4Dr!H~qprM{QTCbQA}1 z$`w;@Oho&+ulIEU*}g5|k#PtpO6F2yB&_Z`;%nv@k;EUF&9#pXp{_bC1!R{aJbrPf zN!3;^7{6#q?5$U|zJ6dt+BJ!WL_=QIMp^$54;7ILC9nL45IPyH4sTS((Lgnjb)&0a zr}e69j&*DLtBxmBW;xF_2m9YQjQ$XQyFJAf5^)fiSQ^yH5B># z^*5_gw?0W%T5H>supDvSdM$3tp0P{gSyXx}|AbM`kORtp>?H{1*MeO2LF_#S^*I0a zOw0kXMqFv$9=@p`oURkZ=N6qGPy1#4jqXfb>94!^Pz`vf+5Z?(5I~zn&35hJ5BF@_ zg`w6%K`CFsWD$DQs@B?qjKqJr!k8jhV(YYM1XakTrG$|rQIRWs4Z9a8-1DPoZ~H>) ztKAPr`MzS_QTmrb#^g_59*1uSF5x*nmsGH$zd%^!X45XMgD8{-rK<(S$L)xv=Cibm z&22{VWww8?Os6ItEJ%-IB*LgqMR0HP{&I{Ov6ib*$xuI5XmrzMPY?Q7VWaaL25i=| zAM&zXdwWOy=frci^!X(YJMn0?+zmTkMkNGT1;A8S-0z>zNKBCS_V(Gn#zX@(8l-6@ zy~-ZpNpTu6JjLdp-RmmsWAkGNy_2ZsMudjlKg8#_htAZwa9A4d5nGFn*=)mvPobC{ z1rNn(nYf9-SHv&LjaA5{l&f!nXLvLoF2-`cGd%$$S0bz9R`UUMCgS6uRgu#N;<{NKY#aU9HA4QmCt}oUetA7o~)b zx5}4Ea{DbY@i-q=@Kjp(_)RRybGaI$4PX8k?LDdR&HL8a@iUV4GxrK; zh0%HUGJ$uXA;Blhsi>Z!zs70eglqbM*%}%ree#>)a6GxtH&T_y%J+Jn+=F^p* zc1%%tkHqxHV9gz{U7M_Fx)WLx2aa&OY}bSolE_dA4SAl=SrbKu*%BEsXGv*lXQ^PA zb)Ogyp68&C;;xgjyHe#@-c4dt8Ex-Ib}C{R6jawc$)~T2dnCZ*l+l$znZQ(~O1av?5`0+g7+o zl~tQ~$2)J6njCewElxAtK&^2FH%zhEH1i?=5v4P98WXVP7q1cFXlTP-8Ad{IeXvs@ z2MDV&y4on97_7&w^>CXTtnP(fLY#hxew1V<9Evj6IIuR7)Php5%7FAH@k8nrAId&J z3B*xuiI0sbwm-5bNIl%UG*FJg?J7;*8t5p3(o*K?c?>F)cdfL9t~^jF+Fi4BP~(fm zck)F}qPUyqTDZ-&;JBK$INx>`>MuD?#J$Ggh%~5EuFFm&BJoX}ZUm#ky7R`nvsi|m z49|xpU1sBdE|jmrNn~7>WVzpf$c2utepXlMvDGgOhZRgBVF zf8y2o2u+m*)NIu5{VtlSJ|pVdGd+M|XnB{c(1noj^a+So-U5Ni2B6hsEb+dS=*1j= zpcv}n^Yddw`nj?(m{OGN)63w-gv9IHe*XzXb6r9?2P3cB^~xK$vP-lG)0 zUc(;nZ8Mu%H_pe5woWMk zuE?Tzlx`DoCX}L=N3h(ILPC>uV?MhZylwqO+E#-h~P>c-oK+_ zPCXf9R?IwQh*vjWi?lVt_fOy0Skd+-GmOf|)-qvHpD$1dzoDKFD3|1}==E(%wdEXE zP|AUBtpJw~qRLM{Kr`8MtQJm_JrpR#xkfbfikUQcAYFuTYnVLB?nW!Du&l#c%K*H~ zG*U2Oa3G;)k=`sFPPE#r*v~LsX&c)o!2cR)lSVT&TZ zRH}JPb^%N!&7C^8fw^^8`7}^F$}DBA-s8}ZAkBvK-JAwd>C2-h7Ey)eg&T#g0$*X= z`iG;d+7J*f_k#>}ot~w#aaoUVQ#f!h;zeF)!@!Az6>A^uItBHI@h=O^=d3^XvQkhJ zcc{)js$cXI*NcutfmIEq^v?WEKKy_zdgz?4g^1+pkC1sY35mhRtDP3VCiGvviq6uN zKONrMG+RJbWrwS(d$!|Ox>Hg`0Ev5nnv_vy+Btl zN$LI?Y&E!S6s;M>!+X*F%MXstE6AImThC1XS~s;AsfvJ7h5v8`C@F6>%Iz|0qy{BV zKb7kKSDw!EFIKhOro9FiA+%;roNKNZgYu&)UY}!q*!ZpiKnd0r?vB0y;?b_tV(bk7 zRVt_cNZ%hZzTN15UL7?n0X#9T=Q&2kdOZQoXnI8tm*`<<_{3|vW?HUKd`r$qj26OG zQ8m)21~=%{v5YXrFMbr)(V}>Fgahye+!qx1zC!bUgMv(|CIbQqQ7{UJuDb~#KDsw1 zBH)$0i7(o(NTWFr?&-U$PXic~xstbM&h1RyFX(pp>30A5mNktUpoEhY8mr~iJALFp zzs3eOXGe;ZYbUr|e+0~Lt?W7uWnF{PF4zfs6IxyIgD4bP&gd+~eEv6A@~>#%3+?GB z@$n(E9}ZZ2P4RJ#c0DEd|9~YlZNW+U)gc|#q-a@aHGn^Efb|*U-qR`R@s#&{0Km|* zvyX7>w>0Se|8g>#okahFGEkUD|DlK_;97t9sy_ewzj9=9zyNJ>&&2@J8GRx8^jRM5 zx4g>_@Q@w)p|gkGq+`O6*aZG{Qz0+xU%mjbkn`a6Z3y2pf=`UJ$>(ExS%sVuVIz#{ zx%s`){~r{k7)+K?M#f*6jb_TXbt7&mbVVEF|N60;Q~i?RMTsb&ihtbyIl)4JcHTg=z^+2&AX+_3xXH00GHoYMHOAu8(CrMn6hU z{kuKGS9H6NQiMX*sBFZ4sE$}U0Zc$1lnP}5j#8Ohha0_KvpSb+Zh7{HPo5&s$aN7^ z@O`ZwMahgyZHWkG{TEQ7<8`+OsM{1o{xM6Bgt10taZbUfSf=aJhJ)yqZWnF*>g%}QpLLU)Lt5b3s}!WPs{aTL ziP;t%C6fGKhz)Ie(BVsW)}S=Ny%zpK9SI#xH~tOXG^Zj*pmt=tNy~f$wAG7ZM!tq<3FY~akT+;fA#R2XIyUT~Ij1EpUJeDTOt_lyzTW8K1V>8k| zbq}Loe55oFZHIq9nc-OC9(um?ei0|ZUl2%W^tP`6jpjcz5glE@6Q{h2fWGCDuefyzXMqs)%iaW)C}Oe5u>GoMdpRRo31iu#CxXZj zzbRV`>6dq}%`FA1w_7=cs`(*0CZn49D~gLxlEPlk`YR^*zI}ULVlNc4lH52V%n~Mq<7$V*Vj_?bOuK7m&zV<{5tC zcnSXh)0wPuPYcN=wN?uu_AiAyxAs#8xT}^}BC4L>>VVkvr^M_jL=fsP`>Q%&$ z8-aOC+sn(#c^5P|@}k!Ng}M9^U?V@3$Z~^qDCt}7_DVU%e-JC~q4Xf!1YPv&NUHfF z?rLfY7R$NlnrLnukN5 zhPxHM*JvpEdhJzy;JzlNEN!OtYQcji%S}0JeHzWkXL3mg0$d3qKckIS$o(a5kjYhn zCW%8hQ+TsocXsfLLz$i+WF!-f{K$ibYX?<rPB@P^HF~?I4K81V6K!Xa$i=S!U&7J{i*YxJ3NV0_LUdhIUR9_u^o{#$lAAR z)l$9|EqDr4XR853@W3ZY)?LqU8;+bhsc0-X?D8#7gsCWRTg7Ypn!t}8&$;hc?F`-U z+L99)Xw0sfuFl^Sa(1Mw+%bGJ>%q!pxG}mji}|#(vAW0W#MFU~czUG3Op0MHPR~e@ zRS;7?eLcMSVV%CU5`UjKBO-mkhI*znvmtJ4`u=Ir_wKcDIiJbNd_Cnzei%07b$%G- zx3o9^yp9y?Q|f@Ibo9|0n-fL~evn#3E%!0-`%Fn>X3J(SZ1L89kLCa9z*+lU1>Ps+ z@DHsmOXLD-1=O-gU$N`A$hy*ZERm<`LZ4rC-)!nnRO}l0cIMu#wtI@)Vc~1vJ?J5C zjVFA%NQ6f11l3$QhilQ8Mro#A4C^Wwvuec0q78Yi^2)km45NyhFx*fLPeUG?AeyAn ztO*l(t7-`%5~rHOSGO`03UR4^)>*)(q%HJe|Kp6#?uk{ccSiY_g8d&jlCu=SUAbo` z-Xj-dAF9*uITBZNXdhA)EGpZZvJso~_@l@EDuINcmKaiyh;|k8g|4l{5$T zq{Dgl^C&;;Do_=}ZaQzrjdkbJ+Lf&#TdE^jvPsj&xBN*5dv_UY;v=VSup`At@{knZS_gzovx8#?`VBl`R9XpphO&u+_{(uLO{3g3vpr2kB5t@j-j$v8_Y z9}`{uxtv+4ij=?19rCTA`7HU!;52djlkf{_c7w1$rG>EIVI+zQ_gg7){gT(Z^Y=5$ zBYlg_pk(uC$*+=(h`i-q9HloDq z)4-40@am9?(Ltp`4@T+U){&xow9T~$RGlrUou~5OzFwayXxD;Heq2d-Pw@MRJ{W)Z zi;>!Y4ERRet2hDOe9eB8o#1+D{xI$0%ecR>Josn%1Rr*hM(g;qg!f(xZ@rE3D*#Bv z=G1B*ICbOA;*g7JnR}7TvSm$exe{^xYn%DdVwuKXQojQS(f)R~=a?QDHuKv$q3c9T zo-NgD3PE*3Zs~N*cRCp^{XzC1`@@f)#q<#}jQ!~x?}zmyZjIQ^6tzMNe&+~yc!$$b zipVFPcPb{zn&jKGjB9*o>bAcSmT<){3MBr0j5g$^VTTDeLEJ-%G@?lO8HVX)&b*@F zB_>5M{AnUQ>1fN$t#F9f#e@I7nO%Lf`snPDnJ$(JLu0A1!g$flYAxDOpvICC0!zCg zN$CTpW`h!^R)ZRrZXOl?)Wq)Y9-sFC)4?Vkhze&tvvB_0*o^x~-Dt*ix1(*yJY&c4 z_y$Zeoi2dj>mNN|+B2RWmAF~6a1~orcJ4QIX~PFcSK5*;+KyeewRX$bhA`j8rh=Ol zrhv)jrNm=c(L>I?#525D{j^>3@jt7{CukQOCZI#XV3;KxF+)r&lJhi20M0lej-ZQ3f!%DU)jr4&O4mnO+(Qud6bPfDnCgmZ1hOrb9@4FWY z84T-67zw$+hG3Wcjd$U#D|&R58j8YHAj5R7-bbexos73t9H~q=Eynd{7ZvSYoSG(u z4ZXbK630bCw#^Nq^iQ-T%#tDe53=HpRDOdUUN!h2J>+R~pDJ2m2FaiyWB>uJlsXI) zZd4Y{w$h|o9RceKRQoFVO*mPeDa#(@;VF+Z4(54l_AUuV(eY`e*|=;&+=;Ctvi_qWPs?Gd`Qt zvil4qs{2s}abRHb@YZXY=`1+=OrBHSNsGS}6!u}mPfGDFWh1<&4R4w?dG3Sos#_{K zX&K6ntn~RMRzB;BaH6%br7C&*(K8CBP#U~wh^kLIaG``b+b;?pT#Vq;=Vq=m|6X^E zhyMPuU2jLC;C*pisuAUZEK63*66A78USH(1l&1?|L_>g&DLU-JH)i9RFyrs9ZV-mm zcOTy7Tj$Al=eJYZUtoo3*@@&fYL$hF68CVnpAM2exG1jM&!uy!a9(yQFjx?0nY+Ra z);8pSBO77DDhvWAKdPw4r=5){&MAW3AU9S&?tDXT(1SE?$L@)*?)iNrbl+-KqthSk zcFY=0cX@uV`Z%j9Te%Yu5%Y zh=4o5ah}c9yLDt2Hb@EhI}wI6E=iU?>C2Vu34GgSvPTMnHYo@dV=_NxSni5RR_duBj}Jk$#;!auaUycHT5Uy!qvOav0`cvye;vLKPo zCtf0&CgudG>wNtxHY7LHn+%Kqvb&Y(*oD>!#S;6()p6;X@eeZLL9D9$zISpX$Ww1F z^F$?95A&@1cJ}D&&(2|6m?P3l=D zas>?Skygh0L{-mJ>>}24TXdCtX!yG4mzp>)Ja!m8S+dIU{Opn~nW5aQCSQLxfn?)q^?b)OUzy+t3FzqK=S*YD%mUuSFt1b{rt?Qq{gvaC+EcUh zs-M0lYglqPKzB2ho&Kn)Uw2`Grkm1?0q!|H^X${r+MGZWK%UVIOHYBdT1T+Lxe*FsR3G9@2zA>HObKAMQt;B$gbs4;2A~6)=ljmN2x~*yi z70*cJ0^p2{vck6(D}!*uFb9w8E$D$#1-BBzyjzo2qul}Z?< z$ELn?<)OG-_FM(_K#N!V*g<=`qP*4mlw0K} ztiOhPxL@sj2jq(%(Tyq;jwWHVv!@ES94)hV4ysnpQ28)utQuDYwvJ;(LxlJpIdsco zr!myW6U<|zv}u3s(_|apWgI9_<;zMb@U=}R`qo4E^4C+z_q)}i)R`<{a!{hKPE{mh zdrppiF6YfEX0o6>B8|eXDikxB0@yw^ee>a+^>mEA!}Qmv#p1<-1@P%75|Z?pasAQs z`7w_JQa{?wJ4N<0zvKXnz~BImg^>?SL>s@@im1HWMBbS-0shEb-7yKXOARP5)%uNR z_|!1m@EqSdD7F@_Ae)8*b^K#Am)7Fu8#yNGmH**-(1X5$f7dtb8c{`)>rJs8F|^O% zl_LFVPh>nX{>6@5-%4yndcxVb7*t!UUQi6o7_n7+7}vNR27(+MJZ>~cO|?}K z0>(x0k0#-~o=R*wip?|T{^{1PlyT5UFZ;&)nOAT}Vm~C4aQ+e{lR&QDwltE51%V>1n+mh);(KQ&}bW=aM5~Wday@lj;F6R>-r$ zs0J}<*7NXPi}ftMk{($KGj(M$m=Q|k-T&#uHLaJS)YTrfS1#3jmkzwR&~^TOeD-C^@o;J78E(W zcI{py%xCV=VhcrMa?P;%RhonJI&L&JDO>iK85T99iuz7=FGns9gqz&1^m8r2+@j0~ zgEMerb&3j9WBTp5~T0L z(c(T=doQ%<#=M;YywS3p9YoW8bwt<(7XH1(aEA?ADdYMS3XGe|9VaU8jLf#bZ1H`f z^IzTfQ57Mnlb!ju2itnHU@tx7{92}@{QDlWI~i)fMlv0}(oM(u92 zl^ssVR;WQH{snDFp-i zsS;+K-#?Y!L!t)1#xyrGd>%tr&_6F`O7_r4OS}j@z8Yv?QsJRcI`7G4zQyxe?YaOB z1IM>UZZ{&20U&9ukckH7_lQV)1 zAOz?Ot)|8CAfbP{$ladXOjZX^{}ycwY8yx)KhW6&%Gnae%H-cHjcsME6ynd2+m%cY zRRwGP?tIBGw%tx}tZ&cNu266AiMUD6YT8bBzHZ^x-X%t%d@%G}vK?6UJc>Duv>a{5 z?+a<9h(Js#xLcw7Ri`S{LY5hXxB1p)bkd`KD<<$riUgnU!Q27U=cx~kUqt&AH;ilbOKFtyk`i9B*5+S$V020sUTS<&5O za9>#*|FP9$gRZj`ffDZpwAP|8>*>ff9i!OQbqa?u+i~8_Sa#(~D~A~BMwV*s7;A}- ztgsqT5BpN>FiQrL6s<`mcg{kFRf}Bh9(_WxbqJMUSLH&(%REeZe5|>}^GT3ZQq5lvq`r)!Tmc%&QQ??2=6lpC(y9 zn?#~)WUdAOME&FWdGYIL&lm(!PZ9Ye1M2ESJ?lRzGH>aM5tt#SD9+?JZ0tiDH*qHkM)4SxvTWdU{LTa_ulk7G%{k)jjmjji*_PW0G z&(bt>2x-#dDSe@{HOR8`CmBC@kJx=F1;0PBhVdk`?P97&3@)W6MVNnw&rgp`DT6sj zmUlr`S;O^ZX;4ZPHy%+8P3`0bPbBpS(-xC3`JxlOt@fxP>GqA|RUNFeARBgtK?e%y zNWFvPDNJl3i`VZbG}7_!I^Un;WL}oyDVtsg0d25sMD~LZeEQ4Py!@lfcI`-mCCvj}tu+yZcZMb4O%jAXf z^OZT=fOs&6JzF!(?cci-U$XVrrE>-XD|Vf=ISBM1{i~-qc^?bqxSOlJ6uSMLLW;<< z^Wx*XbRrJD;J8%#kq4*D^XYwaERZNA=;Fm5Yxoi5Z^9r?Zr;_EPFl#<)tsW4C!%s3 z1&=CL3kCiWRr^1q$_BOkOg-PVAdL?{N6X_zf%ix9g;Y{XX=M$O2)F)}j4n4C`76m_ zuO2eND5c+S7LcybeVw!u=H^+z0Q~yvrLIqb_eCnKW7_;XuF0%`8Y_@K#l}ld%rEJ~ z3c|AaeO7S@N>9iz-X!n7l9lpPq{Rc|l6=p)is2;TEyP~qX!C~T_+a%{hw5yY`2Br>{LR^~VdTatG< z6}5L3rwe6Bs?e3}jp0{UehsJ;x_DE+s?wyslcS4MEUIc-&Emw?G&a0EaZBHHgCAN| zI@39(N>sVYn_-myG1HPUbh7yThM_b5NVYha!Hwzt!{0xPZ6R93^hQq>=s{O2o#_;7 zFNFE39*VzeeI78cp`5wnlhfTph2`D!F0sW}M`Bvt(T-{gUwh3;x7fCfpP!0{j|C2+ zFxX1WltM2(4oH67%UNoWgLhLzcptb^PfShY-M&;(;W42CGZ|0KC zjj&|rQsruuvjdVV9mF?oHYuaPKBm(CpKDN}8z`z6H_#SDkq`c!Fe)z-z z5qq-2mTM(@;m>!|vt}4p>uCwy(*vd)cv=@fN^^E*m*k!})a2BR^K&8W60Eyg-!#lY zz_gl-Sj;dja;-=8YYpqHXh-FYu2~6C4Oxe8_yf;xY719C>oNKR=t>3gOBTz!JL1&o zOTKhN?-9&0eT68;$I6ol;DBjKxA7i}X86uxpgnX}`SM9<=PJ43kFBl0i`I!@clbM& ztVW7?On;MHP)9E7dd(YdpPnv-R8kSu=NADP*~ci;PAbPV5-b~-h*o&uq9oF~YW}=^ z&cyg`w&8Ad=a0lHpn|#;+bRPB9Or7!ZHBe~d*Uu#RcXu_Zkz2e9TiE^^7Ug)KL_|^ zL)un8k$2~lX#J%FsV?-mO3cmp=WPe5)z&}M-O9l#ZapQ|A~Y*$@!L@0j~J7T9&~?X z%FSBp0r8M;98yV(z}EB98khriE+0I<8Yl6p9CHs|6HM-~3x%s{olEfk9{;rnF1%^@ zXjrIn*=>EIKjX zFFW=y4V+O{5RPx+<{(yZ!+D`XRpyya2dWA+f4tYXkvrAUh5E|OF`fd8oKgtzD_Ler zq96)t0y`GR#+h^y!t(kK+9OtD*It=V+DpZnfhou3eJ(k}!>8KV7T_G= zyx79IQTCWgLvUlo^*Qd&#DIF&knBPBSRNrOtA&TGDvAoH_mye+1Psr~&)BHCO(Cdy znN30~gd)?NS5SgmFwE|gz|;ioJRQhslE;Tse{8E$HNz9k{66S;r!NNLM^TBW{n(*N z%!+e*LtE{)8jsRU!vo0z`>jIXrf=mY-T9I+E{fSkg`_KddKKLb%04Qd*Z{Ut_-2sr z@w=j&LrnO;C$BTtamG)ICh&k-;-o8;m1}72AGmKMYPJB5^|N6+!?k;PXSL!s{hy;~ zlKRo&5IQ51&qE-AxF5#`nebHb!7+&s&TC3>VU@N)CPzMn4GmJJqeUyR__{UG5|^qB zh!~~Y#AIFhr_ygGJ~jlhbM?pJ2S8?j-Ud3|EYnsG-=yr3*@BQK1Vkj^FQAdOpAFw9 z7Npp|+dsTNQ6Ts#}dKLA7PpQ(JDuhC+&gdPV5L#nHZaf^6e7TJX z5_!sl)*go~WJ zhguSWHMOm&uH8muuT*kJMPQ{>V5M&C#ig08cQdMVxx_2-z+?*2fhX z3aV{*;kS#tbDM8&<(<%)gJGP{JwISR``JcBbYsX%DwSqWKIhx4JKPaPAG?C4K<@*&vFp~aig$3XR@P7U)koE6s2k?sn`U%>{ zgHL~Hf_4FZ8;_4}U!N!d_^nUfuImq^ZcmJWCUkG=u8MVZ8^CoXxM~@Ag@WS2=s{kz zM?XF87=pUpo}5EwcmRGcO3O_!1fTs0mv39gXuKo)=#W9idWNelHkeTF~?bp+(~aOc|Gs?>wj`5 z2Cz>Qa}K{|w~Sjv28iR4ducDX>yib>ES9``Ap2znpq3ceUvJyJ{Iq{6CjZpAT=-Yi z68GL0?*{w^_;~xWo!|e3{`-+X%?Xzen8PlmXNT17-B+2u^R#C!)h;+dlJ$s~jrDZj zr=8;my3;j006wa&q}$2ax}xN6>K#w+ejmm$GJuF85ann~RX5)C5_&)#S`lv+!0@`d zn`QFRba2i&VH^h!T}R?p*2w>+B;n?s8DJuL9sgQ@#vX^p|CavhX*Hqg5x36ii3A>) z`wHH+|0ou*_3@OwP{mooJ5`vbqlae)8fmyzS2Hk$#nfetDij5A)?N$6_*U(DY!B^< ztk}>8-IHiO31An3IW0T(4W7uukly1DU06NM{^+*LHEOFENXD?KOC^ayoNZj z=`_(;JM}CL_v>;VVZ-yx4D8&oM_`gP7}9Db=8#CHtY}BWHmN)nY~9-D6`iV2AI6RN z{I=(P8RSyEuv!02xZ#@v$<`Tkq)=8zceZP zkss9pkH6ZCEa%Mw*rx37kRQNLmR94{kvc-^H=rc%Vz!urjAKdS6X2*-|t-(0??I){;$xRfEh61$n&&j+u}@y$N+j7 zfAi>6AuEo6?_xotyu$Bqll$Yc-WK78Sp639`m$4SQI`T#2*)sut4s7r9KNja-)Lwr zhN%cAIa8$fIw>};RdFHaJ)u2^Ca&vExaGiF&i3{Cb94d^iJAbl4StK08b@VigEQJhtO8_=og9cI7Boec(J%An8okQo)#sxeU<3HcJDOp3e_1Mo$7ov79P-jT#;2Tp^9gKf*w-S6#*RvZ~2(qGKe3?;5?~w)y`F;&Y;TKjfeqElDC>kvP>5A_S2rh{kICU zzk(glD#0U$sQGrr`l>K6u01iFyE!Kmbzc^YTdp};IFEZA+iEYvtVE{4U+Kiuq}qT= z2+t@P)YMCaWptA|9xxZ<0E$;G{E5VBGXZfkL#rZ@#9!{9m&N_Sj~Z$XSu zr8Q+(1)wua5hOR3fyR4PVXP(eUqJS8&)C*H;ZajU$uJA1c>FcvDwT-d6F89D( z$(7YD)}i~)v*(=B7{KE-Ik<8sMMVTeVOP|{%>aXZ{*KnI@E@zR^?IuyYN;K%{`%kb zy6yKm&3bsycvkFNRcSj)diFPXbQ(`y-0uajTl^WaIH@Vs*$atb z&S2R0K{wwGHlF}qJtYyxI=M>lxW|ysy?p_n*nf*}A~}~BsWGv%fa3>!k_T0UHk_>r zP0R)(X%G6;LJzb~obo^?>}AlWFCzE|FPW|fJWH{=H*j6|3K4Xum$_4C(8(+6Pq$SW zP3t)N7*rle(%<&-yCvo=SctRSV`8V4jy{$0=-$gIKBGdn+0MY(hgaZTPFlZ>hu6l( zm`V4ZZ^u6^!J4Mx0r$I6H-5nD2ZeLy-_P=)Jlk$1X%3IndT_Zsa5|P<}a|- ziVUtO9Tv5rA*eA3qGJe>iGMbn66|+u*O}$W;pDfm2C*J^ew3Ct2XZwkz+@$wpE*cN56>7a&_vv z{N+B8M5G1Bt z?LX$0UAk|_wY|nk0hqW9O>Z2e-^pA7B_55+gdEvCF}dEGq(7xGKa|)dlykkz52)pBVji~WOJyTsDfbFa{cvaEp_$LB5o~a{4Y6Nf@uvXUbjx>9*LFK8Lg)J5 zMU!Pc-`Dhw57V*s_-b@_vVh{I_!+QfxUrK#|)Q0A+d3yOh zR=STTHkrKd^2KpJ#yC_C(lw4XjcY+O?y9eLMArXnTVDv~2 zWmV6kB#?;}{G8YR^us9ojG{_f^?Ukt9NUa+iZ~e^YNey7i>5c0?|qV2p;sPKgy+i6 znQ+n>yy3Wf`jHOo5kvDkh*ROg__83#sbaL>jva+W{!;xtAy^+TU3P0UT0_k{Z=MNl zdl;~oF+J_rcNqx(rxq*)-S*gdXba=9Eu;vuXJZH&ic%ryr6;kVnhihbM4#Z_doDk> zUG=3d^YP*x%mQ$bK5D?wS^T4>LYL_t0mkljje_fX@_;`hoqWW$A?;pEtLyTJ>1CrX zIc5w0I0Y)3sK>%0Fm`n#R6*j>c0_P#r0`|q00Eq^scNda)$z;_dJDDkd(<-(N}D6V zuCB@6zOLkQN;HRV@1ihbr_l$U9Cx-;n2%>0*4FmfJ5WsdNs$U?(7Fne|4Yhv=DDP< zBr&edVq8tj^3)6An-NfId^8_%q1lfo($em9;ZNTz=;1LbJQ1wto0gQDwU|AwD6-_~ zi~d-nFJWh{X+xEuRPzSR@2(a2t72s=HPCfT+H*VKU`h-sDQ`>J^##YpfaJ%4iuJ^ zFfd&ybHS@<%)I!!KD_0}XQHKFZ$o_+-tNf2x7!ZQ67PAeRo2&S!@DPWU#>lj4WrQf z+1e&go!+QGZ7p~3L{@*WW|v%ov-8{OmDh|Oqe0UTHY!Ms$sWHR6g4bav`nHFkt5gI zgmkrr19ffgm?zp&jOADJUZ6p`CmTVHN?!tzKOA1nxB9-tJ>=>{XCQi)Q+Q(6^c15p zpgeS6&e=2$b=0b=^B@uqsfdbbVNt{GlIu>bt zf>+AVC7vlD2nQFkx0eXg)_}rShGTgSEZMyv8bKO2Tg4{F zoGr{d3KqT2$#Bq@EzH&;1$(FTFb#%L+l5a>ZRLM^3DQuEmh_410i0*#H(hvVzyqd* z8lVUb>k`ARqXk3LT5$fDs?9HQ``dTDpejRmXZtpaol@8iJhl7FL0CY7#~t$9bAIVyo$;_HL`|Lfl z&)(N{6;e0~MmxW-0$;yOv!nRv^eck^>Q)3cKQIjHYfHG$q&*sA$QF(j(C zs4qrd)SM=np~L=eAI&^Ubh^IoVsXIk-(kVDx}Pf{ZmY{~Dj7+Pd3-#;mu#CnISaYGdU((>-CRH%*Df+& z@($~{znOS7pw7v1&Qy22Jni1p zHjfxZyrjD^I za8&N7WLP3eJ|t30m1NyM@=WP%jV%$zz~ zypPHS=ucRMRMaF(dVQnW_+K*wOEMf6-hUZ(($B5NJef^z8REVfzI%zI#*(Z}E-P>k zQmaeh03bc~a`Xn=Sbo2qQV8unqFIpY#w2jgh^*X4)w$q4F&}`ZgL02H!ee_QS>(C% z!@;I>G#73xA#kQJFs;u3-iSXVn?c^vJw z!eWsD5ZoasqSO6llbpsDwjSe&_REZ`!epr#6RvmJ5I>DNSx!c!6J-AR{Juv42t2Rw zt@CCqRJHr2dg1LSDE+wG#jSVdDFNE~LCk$YQ@+rA*1!iMI3IoN4ga6ph%T@9|LSgg z*Sv<&yr67e!g8d8CuIZ)GlgNQ zLQxjZXJ@#*!PxtfC$mto*JiXxs;9e9))Axk*Ex6Q=(c7&fTkQKo($27|MFJXJu60T zEwv^b2Vv3uEWuj}Iy*1cP2F#`9&_w8v4mb&!4<-*2_Xah`Yo#ndO;;8P7*|L6fa9y z10my@5>F6?TKx%AiNrXSAp)V-yqH3otZ2=4Nk-^afWe#ev~Xx}$_XvP9Yv2Xi=a;M zIwMfqWL9kd$`@M8a(zu;EnpQ^0l_Knj8BxVksPzb0kl||@FmtWE8>nCAIAPch+03H zTC;vAA0OvAjE#My9TSv*WT2LIrLy(*af_3C$)(K2R=KAQIikA=F7ze?V}xv4mWg|B z9~U1`Qc}9tPs0UiBVN5~WjVX$lVJ1U&I{Je=wz{38YDXJ4{qJUs}Kr^);6VcVoB~; zg!rJluv7gx#NODyK#{Rx?fIz%-I2vSbr!U%lx@az;UAvH+=W$eUv{->>pvysn1Ix0<34Z7y+_#5wK6`wY;oRx%P9< z8T93!32|)Tl;?L878qk#&H$Cgmq|0V_1b#{51@*K8|#B-rmNu5 z#U!-_?2{4+c=^5m>&){g~D4C=2*o#PFml=)Co|~i}v0jk?}2}4-h1eOgJY`9>%#{ zLUNBx1X$Nc;rN`H#mW6W>o8EQQ&aBvz|S`i=m+UEU3HrFTUC5-;&nUUwDj}xD$G?o z>6Qpzw)$c0ugplm6>hOMh%~b(m74S*ii6cZ?4FTQ`uz^KwLsmti9cX=81>77P7q0` zBfH8Dkq?&|d$vK~&^yd>*`DizTA0c2ggCLf11J{7+yEqoEHL>>`w$a*l+Lq=P9o^p!Z*UlT3qJQ5bbZKarv zkyTQ~sc)nzbrNmUGE|B*?>-v|XD;7nQQ3q_r*bvEbo$W|p)Siz?;($+Q(ms_`y+rR zM-l7SV8HwRBVe*h2JzOHm33X}a9Va?hqLE8&K;;>c<+r!JOQx(Cga3Q`J^diz5y)d zrs|06Ww@Jb(4-&ZQ8TIX#vKmqmtII(v0qubjP2Om zeV5P-u{zUYHw9D-ZU0h8z6xwVt6A}7`uJ(Xac%!AO-T)P z1|!~EQ@faqY1n7Kxyu!KK{x$Y%#NnTMw5hp33{C{PM9J}lnm~zIL{lL zdJq01Mx-AGffp{Xw6=g3Upz>3S#wYD3X)8*mT$DM3)s#0Ep`q53xxnGQvKMvJP&oF z(oQ&)bo`!~IrUQOFz3s!+7flK6Y0kMcN~v_|QPYM6Hdu;%{!$UBw!6 z{+MQpBBV1kkkE_;n9r0rOVZR1`Pph9IdIgJA0{gdd8a$r_zNcG#?u}^I(mn8Lke+b zBKKztQ>K$1(ru)Pr=Z;jfkGX*)uQg_yAGn2zj-f@~gppFPLn z_aJpAzMpXbo^y7jf5jR_Zjx9K?@d)q41A5k^^d#1=lv7l#in%fh4~LAF*%7sn%EYv zM0MkFzhnAiBss~uR{MUZH8-?kd4<=#(}-{VqCQ;y!hbRF;B_%HFL?gFJ=e7;a(&au zIkd^k$hhbGUnhqrNZd_Ja>_5Hsw1mP?dtjI(AGPcugDIL!0;rVg%kvA!ALR)Te9gf!0(U(W0>a+M~ zYBL6|47OgrI=)D2?rkG5B$81|TI$8&GJdK;Hw|QImoKzsxgJUKEyF=%3oaRJ;`;D> z#eT;b7|-}G(c5GIUAaF+#{iu*soM81L=&P_2wmDP_~$eT8$&h2+td<4P^+&Aa`#pH z!1&6Je(SulP-N&VRlTr>Xw`1vDe#QO%6MLC z*KCHRxAZb7kNUI}zeL%)`ovx!8?-TV1%J=WN_B{3=OE(D7+;a=EF{V4JagMh=ny=n z7w0gU(Y2K7y4pVC*Vca*nnyKiMbqVw*Z{IOC*tE(;nZWr>C zUq2I@zH(d?S8W1|XI%|%eth%tm$8v0Oe@tP`wLZInfgrHn)|P7(S?H!L+hkS*{ut` z1qFU7ke+*ldi5>S-7{w`-OxkVPc62-JTE_+gpEFmj{YsnEtygNO7ibb`ciI+*TjwS z#@xK9)}rqInJd=ciTC^GfxM-r5GwVe1?4yWedjm$ebuqX4Tik$k6VC8M3N?1%43Bh zDh{nK{BcFRdbPq=XY^1$tNW?&D-Iq&|5^C7IFH6((|P87O5dZCZgTap9kr!~T8}B? zqx;7Z4>yIT?|NvK;CoY*=ntjfV6~)EaoI?F(GT2+ko)^Kjr+hT?@w4=vfJ)z57OT} zWe@OJpU&5^B-O(bn2Htnn0~Z(Z79sTeZefu?I93YaA~`;0`1ai?(+HOXGO9;oibK? zJ9qMjBx=8!9vImB^LGn0v?+Bc_%$gk(soU33e)0Q63EbwH7kjkm5Jpa6CyY$=ycZH zflufCuAzEv2(y*;Ps#C8_SuIaXs|s-XLHXT?kJ0+7q*3S-@Q#f8k84A$~C2`=15`| z3^ty6Zpu?2XcPUXfHNkJ95_IK*uzhm&8kNi43_n}J~LN5-sX)Sc1AoE%7+(1EvK6m z3wq9aL+pR~{H_(=LD#$tt&KtJCx@)QJl}*9zAoGz8>`v@kgUa~vVuoY1<{Fv-gXh@ zu%_}m^RnvZKHo*T#a!9%y|a|i;MmUmJ!u2B7Ude3h!jZ|7qx-bgvYh&UgQ+3S0IBBzcX(< z$OsV2W{4-rB6Sb?ur&18UG!efSQeXWCpp3EuWZ}FBV9w9G(qNNp6Zv)Ik`N-ILIZo zwN#BDeDUY~mb<0tBpbqhC)G_uGMg> zu_ds?31db2-V%@9wUaz`5#2Kw@w-vJtm3Kvhlla_bzHwogGbwN2^eU*u zZn{jp-iRW~`YX=uJB6>mrSusxvhcjqUG7Fmx} z(IP&X>dY+uDSsPy2K3U?c}WasE>&Z6=88?1ZU=bYcvnGk;vy5hayXWc((Oe@C23mc zSxRIbI=|T^kv)$_%tDDb9rmU2m7l%2XphsTG+HZU>|tTgkudc3C}~Qd6Lw5P>(%Q5YNgT? zR$)uI_L?nrJMfSWZT-D#GV8=p1Y4ui2tSQ|&|SDFvFTYTZW?Fsw~L@)lN4y#Xl`O# zL2IrIG)-I!`OW$A(Jhtj&HkF}7m62acgrh1kJHc`%Bo17{b518=7eR_1=Jn-G`^tz zT9vUNf51oA7wWp$u2@4#$KQ>`Kjob_o55Jm#^$fQ-C<@&97o^{ZC^$A$rxdT-;+)o zS29}N-7N?-9bK0Ei{Z7+(9yde5UNrR3nY0S5v#h`_^FP+TgIxUb-lTQ$k@McjQFdt z`mAut*B`a~yU$X7)MAF>2C`%oX=?k23LSN;3P#k2?Id;fY`_xAXHUF; z(-q`@NTU^hll_x7g=0g!=DiroOJEbInF zR1zVka5{K7D7whJJf4*G`R2L(N3hgC{1ef^mKs|R3foI;n=03eTVrL1luAfcPb_lJ!w zG0s4%#D+%^TI!^H+b?sK{2zgY+LS-i-&{JcnFwU}PVmdpy-q!a?dvSn_#ECJdB*pM z?#6 z!>M{Jmnz1AGkv)m1~VG_GhM1_?-1jYDI|VKJ7hzc?3jsd`dSodI?pFepZ$}aD`sB( z?E|B&x004q^XDj#B6FjKeWNf_AN%FwTepsEc7d~z2d^5}AMG7)&W<@?#jzyN?q^p< zb#pa6ErLDxak_VJv-=rVfrnih2P~4b1-RXVkgse;8P7v zxhqD@(l~f2f^Ondf_zAPNo}Xs`Ygfi$b&~+X>?uwGjY^ zY?KZAcw6qMU$t|}`G2s#%ve8NoeHF8Z+j<-mB$6gzPUx;UM~Bd^B>&?x3ufM3~I?6 zDTaC0s^6kH;@PB;X?e5n(*cK=5xtTJ7v1p-J1M`u47#2Ub6!?RS34y>NDmf{YRx~y zonzB9NDiun{nN#rAA13NaEGsJjV-@cqqS0{(U-|B)qmBkb%eLZ^}x4#IdGTbJ{1`n zX|tbGOii_12zh2=YTcYrdmu&6q%U?>GljPHh`&>2ikOi}k%)KWw*~`}QK>nOc_ABD zl?&%fQo@0n}`n^+Ywx8@jd!oqbaNOzo2xu^;oGHcvNJ){gBEI6#0 zK>CnHI{O*cN(=KsRDIlko|Z5*yNWJnS!U|wA8bGp1Z9DS3}RUUtH`iXU?9^aO%}pV z(AbdJGTY2!rr3u}y(l-Op1vqBMUbIrDYN=Wc5wGaV8ou-T7mk#pZ74u;IUKUHG$Kb z{3?f`nMPffkbe0fx*34bW;eN$d&E>b^I6qJ|C*vC$Wx*u?zEm%r0 z%iFqP(_JadXXbRZ0JHp%@^ld)9Oy}6PLfwXJ<;xkRq<>w+BOLkM<~9ZondlmW_$ak z6?_jI%bGotGAn^LgVyBpEER6qG^tr4Lg>ntS5zzZJtUJoOa=H_Q-(4r&KYdnB8EEb z>ZoEirbWkS-ZS|yjvJHI7U4hXe+&xF9UGgLC}kF*+}$<;9(|+e81!@+wNJHVy;AE> zC2tYey|Aty!3=plK$I2&qkLAsO8JwTQhW?8rY5|9%a-U=jk&iX_etnjq@337%Vh%l z1h?@%?%c%pbWTQNYM`ipeVANk(lr>e{>>r(r)HM_gm@Zf^06e;$9X&J)4|G#H*2M& zqo1K;R#(%}6lBr6UFB1-&zzeknNYidYsuBiaZWRD*qI>gtbq4R%Y=60T-M;73U^$c zu8y1F@C!C3$H|N1H}l7)wq-0;+ZPhbw8GsMsd>s-Y3ttN@nE8xyKg@HvF+Ay%38Lv zg3>ipB6)(Bt4*L8@d8*M_py~Ivx@@*fH(puYt+B&OOFOv0g9qT2vx2fUpS39WPpIq2S ztAiI4Y-5L(S9&{}`*9-<-tHLA^VyL__#BnUS>y;UUhdEF@cvrH7wBSop`%)=%0=HZ zcbbxBUcejeB^bDfPI?BZZqoczfk(FBW<8)Ek4Axm)oN+c+st7u7Z*Of=&jJo{J>bU zDDK~{YTmI&8NwymOM1bR>H|V@Jc8x_W9ZCvgvqB4(Wul{Eg2L|Cbj`4u{ylCRV#bM z5l2lf4Vttbc&4j(oSKGdL9d}^VO>Yy&K8!z0;^Aj{Hk?P;Xxz*LdSZkLF;3*bi4c<`l z(vS?hJGHy5@)>8h_jkhmW zl~Us#)6Bf4{MoePH#XF5bNH%6z}$ULX8Ynvwv#b56IAOVm}UD^SQ@E!_;#U!YeSt% z*O&kO{z-Dm?XiviqstXl)pP;+guYm}sJ}}UGNvnW7Jy2PlI>ojTEsS8tsdVm?c2~zNp{A8L+cSIc7s>4V$H~o_ z%%Wlp0z@eUHsAh9bgA_U=G)ePw@fSagQz>`#=WmobHK`#>$hN29u6>c{?y^^Og>}V z{#c(l`fpzQ*(`gB%eb?UxM1MsWc19>(nbFjF5;X|Us1m-vy9UgXNRW`OTODv0bhYy zJWUk<^rz4d`Qu_vJ?JJ0SDff^Ugm^qe8bXxO`|;J}v*t<^u| z6KkDyI}~g0_0J$Sb2K$fS!#Hj#&xHQS@X{KIQ^&yd2qe9LisD11}OYJlL@53ha7>L zj?bWA zG`PqbWHBmX&t^mF=&^^n%N0TQLAmuGzCzF-Xuh(<@bawbi^0UbB&~y&;v%6#;t}yy z?C3bU9_X44D>Xb_0WSZ*bTFy}+l=AL;TW(%Thn}gFSw6CkYvt_i1%|-INn!(1TGI( z%N0leT)Ig;@0{D;bY#E(#2DI~rd~U`%dj+IGHY>TvTl8$rn>iXRg>_2tI{T;dV5b; z?(}V!OU=TJ?9kEDkMSz;QjJ5sSy(%Nu|wJ#`DDFEQE69z>7p8k;i*y`Xd!;^Kd>;g zbDXcZP{k}Q2=F#2y|JXOo^qu0SfB}O)O^Bz`cph8qwv-5#zch=|B{<+|6KBx?GZHV zq#e0@9MPb3th+QQerYSbj zek*G6Ag2z?d68QOJh+}Ndo=YCu>EGnSk=0uGC5X-+@;gU|K)rA{SRx+He+5r)R`@&uz%;uMtj92m@0=ejq}z&Ql0wy3MNcX(A0I>I3Qsb(z$X@S@K!9=XA{I1&Rc{ z{G`1s=F*dhyC&v^{eG;7@v1*QbrZ?M2rSR$ox7EC%=WZh3F5)yIgfAW7d>2B=n$Dv zK7Q`vVKMyo0}zrc|OQ6W3Yw4%bnQJOuuszbdoovOBh= zw=r9WLi2rWNGJ)8ovPXtw#jbVdeOygv(nhGIp~9-cTJ_nm6Y0=No{42v#0~rjmBib zd-jc}3WM&OP;_T(5OXqeHMU6iibHmAC@}0Ahw1~*Mg`$|heMWnG0v~9Tn9dzQ>LF_ z!*s*brZy>FUF!=Kn1we`75$m2{IY`)Ctl|DQAW8)sOg4HX(!Vr=AQAwhviPg6k z&6Xa1L^rNC+En4qq(ZNQX}9ybk|2SC?}*7PL1A!N2Zos($bJ>fGe z$(twaMXRlv9kp2pceJq_aaruLXBZ>elypT`zn!j#KCGpj*hh${W-=*@hBLx|Z_PP7 z5@okHTZtjK(dTLtU#K~W{$Y$Mjad6Q zcdXn}2LF;7E@5iGUin|j4&R0E@+G^@nXY9g+AZJ?WuRi9ccO1Qn@rw(7Fw@5DU-2t-SrD?V} zgUcphJ5abAQCBBHUl{=Ur5D{ePt(`C+qDGvOx4E*g?j;<0LYF$alRW2U!E_4vca-^ znR@RvF?|X8gaOc3OSM?Ognin&o0aI`^O>&C3W}NnAUOa<0GZ(3YxZD{?fX$%fZaMu z0D#bdqu6~OCP&17U?CW0;r;i_0ED92N^eLCHNYDKkB?ExJo(275EN0GAZU@O? zZW)erUA?ki55(OH1Ta4jtXU=8dUkoQ3qYxUhjE+Xo|oP}UI&kI12yT11v1{Jqb(C9tk1j5W z8nZtx$Q1jp)sDx=Yw*cZ5r6gYM6);msh;k~7xP}NH-NY8krQe1g?x4jV8{Vl-;tV7 zSd7X}@B`laVCmRtcR-d{U6RCb$1O#zb7aU(dXFEE8L0MoNSs(tHtJ!xNh<)AHhd=G-( zOX8bfx#3*qMN)<1VJ8KglfD=>t^LOu9E4xvBA*1|k2X$dKgZNoOV$lUtngXX(169ie;wLtHbFIQA9Sn>?GIHy;nz{F3%cCUiC5 zY6(!O4LF949?!@P*l$GZ4PGg%swAGCmfBZWznJ?gbs5IG_;J6G0yj+enf3zI%wiVo zmePY-zN5G6aYMX`rZ@@L*a_88zPIScMcS0YTDjZh_eqZF`)9 z>&BJ_rS@;;E$w5UpRKE)$ploHm$vW+zx>i=Yq{mBZ8VUUx^7;PoUDG8n+$G3(O6%^evxCu5jKx+39t#ic;Fu-%TtYul1N;ME$7uL?OqjZUC!68?F zkmiEiQ|Z8lw_h4@|7&;(o5Da2UksKrwpQZEVF~q^g*6S{10E~edx>SK@)Y1t_of?u z@dsdSnW}A|guVnl?Tcp#Y`~vvJDBQ=A9P6X`D+S5RR`!{0M=Nn6#uVh;3z$kAG63Fn*dYSr{Hy9$2p=anE(KPchYDldg6FB26oKE_?Amm|(3Vs@2M==QJEn@nkTTaba>GItWzEuwEMH#|TjxGv_CLcCDusrDUy{AisqBeok-A{1 z@@G|HStLP2mgIVu%2_Q(63N3?7n?3?D;XX>Qh3B_Bq<)jo}bL%MrMskjru=vv`ul# z)0tBKA$asLvvK6kHEGk$pqgAkz3L|OJa$z*c_@bmrdMjLuxw|QwDoc*3|NgV3heoh zM>U8j%>3n>aeB=jdRJ3f(}?8gj2OaNRy-=}bo#1-{A6k`uEki6On3$S-!Pf0E+&~sLDG+3LdR;WYrm7 z|MqHANcovmKjO{6fu`ROO+5W{oR?Osb@faGW&_ht`?C8dh$kt6?n#!SBB>W(v1E9J z%wlG!(ax3|8m3xlZDugw!OHv!~yQ-x2 zP#9x@)TaG@>3c0(2t|2*M3Rf5Sb_DvfIa20uGJW}kC9hcWnFl5r^H&+&oC(n4rfXF z`&g4Tg)+yhmez$utj@%y*HylL^G~xRElT_p)1iLV0d}yawxf?yTa)sXohEtk{JbGl zv)xUS0umj!oW^hGkqKrH1#bRlEV+y2BT@+JLYhXt0-0l6<@nHuXHZImptLC~iO!t? z4TD{{&SRnK?H{o7coL<^BvpW2ctZ#w4n`xds}M~G*@P}QR{PyCylLE6{7H88oAakO zq%#+#1c{ZiU+>tI_3vJDYS@UO>V0^Byx$-BY-(ibmU;7hUhLL^Os+e!c z@5#A0HShLQt-w@2`QGpMrQOpD7X+o|)#Bq|Uj}kQywiv#OUrQh>eeNM_mAtD&&0Hj zAYMv0Od=+>sP&STI$;Z&CnnZ`WnSz2O?iL!mq~vqZx@Jv{v5uc*g?WIjw4r3XW8P{ z+kPYVqHfKN)izeZt4EKgC!CC~iPUlxjY2oaI6n{tO=Sge&4$`sV?A(s(4{31ccFXL zOs*Au&M*KdIzJF)*X?7QKb$m*U_)9>93v|@Lv#br9p}C9UUovTpxq4p<)G{5&JFF44_0hqTFdZOyJn>`FBy)s;ScI@j#X8`8`@>ojb`C|?T#`_(M@;^~mefj^?g z3HM8QOIchB5ZyAMPJ2l#Avfvp;&D|bSGmO_y!X8tRswZv4~*f#xrQ`~?cOw=>-}RH zv9%Fx%YxbEq?&EA_WyTr13RMxngw;_^3cQ!(5X~KJeCMad zq{8Bb{B_^`G_jl>jrw8ui#ZJ2zK1I&ym=n`tN?+n1GN+GfzuXug^B3#I(wp6ztLDm zv3`vb;nPQp_=+eq4+tlbDTo-<{)FqSEs(SCsC%4Ig+GB_Kl$9cb#lZyg1hC1u=4&I zk;>aRI6!WDPsaGj-;FY}w%-O}tYEI2E3V#Sy*SX4 z3zwYw*{a%;_S;=8-xSA?W2&F|;7(czKELS@F$pO^s>lIC1%Xc%ly+YNj#-+k=a3C+6~tA1FHl;t+xz%tcHEHUfepe)Q;p z`-YG&_=OW}N%1@aB-94NwTw1yb-2L~&kQ6{cUdCAXG110Yl!w40g(6&=ilslK!jW# zXjLDckNZ-Ge*XkmXr+;gzH@(DSrnp0&tq?Kqm%&&ZjV8o{YHRwe!Cnkh1D~4{KiN8 zfKCyX*piNia9gm~j&~zAAjvLAe-JeXN3VkXxtJH6kk4nf$Dns72!j|&$2-nr@Erh=B?vIHcA%%Myct*szp zz2i+ZI~ivGyc;K}wIjk;pKVF6;L-0d8}Z|Q8}Se;axC!NPKhjQZJiwLSbxyZ_6AIV zGMJZm8i|?Pi*Y*Fr5N1n>s1mNf2xt3Us4Pf?{z?jUVfq z%OO%-Ukmko3NmP+7H*X@&QKoE`@ z%uL6m49Bc_o)LbPE>DeV66q{-Oo-n>`dleMAhbylr+$}9tA32dYKVsByf&tcp(7h&_`lXb0wY5sfJknmcMls{3 zZfYvM*v4u>q}N%>IV!p-slUBDKj06FQnBdK41-W6#f; zFk+0+EYlEuHCeJ`^0}I^`hJh(er| zJzrJ<74I|l3;=kJMCVT)iA4d?7BA6kK8pj{SKk(i3!M7MNOlrr8gY+8gC#I6_6nkn zLmZDNIzk?CEhmIV6n_10H2a^B_Kl{H<@hPUpen){z#NGfO!A)7&C3%~95>AMj7mTpo48DrkR{8S3rvJaEi81eQtyKt+#v82lqLUGV8>Ya6%<#S=0t8(1g~-sp@&DW_@jon;S{%UtyXC)s z0Bi*r9TES>mHvM_yNBNaUj29LianME&=bG!L)_7X{QBAP+xUdn{9(Zh08-30%+V#@ z;BLyfEI=JzpMS!QGsd!kB2(mlqWU+Qzby(Y_S^q^<}2o%1VB-|oMlCo5WFWMXYrgM zIOrs3@rxkFo5g=1Rk+;WqIDdCj0)94Gq0fDNZHBBc6=e54nQL?zF4MwjK6#J}<4Zbc0GNE02aXtn5QB4v=_{1C8QR*4W*hdv0&J*hjBXiRTo_T_{z*f`{YETc+%2qy;7<{nnLI@6S1wQV z6swE*yk{U*F)w^iIwMpV>L2E))kA_#YWMDO3k79!=)$h2LSS3U zPmfRh<5beU$2^|9N*`QG_<9Gp&gwUwX9XYteas!G6LP?M@O=AZ1bS5B3z7A$UVo)u zh@yh=zdi!`^wjcO+AuQ7^1gxPD_KqklgSHcSWc$04^Nrd&Y>@-Eb10#{yPBaK{QDP?e+c4uB z1iOo<9Nq-npy^`S0wLm#X#u^Oes+A}f&r5cpou`c>E`y2f*4#d{tu8-qxDed*PC*I z#E%l`w(t1@=v?KRhEW-p>)s<7P`yqhpEbj^0*emi4*B-t9C^W}Mnc2m;)XxQri6+q zMo*;uE7=fd*AHrSv_fR-I4cOGtn`Q*mJpSBSgVfO0N)7W5pyv5$CC&vkGWE2>_J z&dZ8fDZ$E}vO()t!p;k827>^AA$_ePwpBbDVZd@}suvqBh;$`L{=adD0&x26l?+^g z=GOxNL?tDR@u@gJ%sH?53oFkD>3BjP_#v>}g5DM0&8V*6#cHfgVH}za%qw;zbaNcs_nT{!^SI9?xnU<$F zr5O872TmfEI4lG@5B&~(-K5CympuFRpWjAFtYYrp(Z3Qz^qytcl)9jWIF_4Y7Me8l z=f1se0uqlFi$gpaIfb{Xn%wG9q2%Kf>JvmQdtrQLoY4O z)NiVM)_WOxb?FDB$Ens^*K!hL*`OUOQHGaY_)^kI8z`$bS2pK(V< zAZ=_0$fu$YVO9YMl%jWk`BucF z;xXCOWsOK3bota}KrfKn>jxR$6}8T9Wc>$u#6K{^^KN6_9figyc$H&b?X0Y8-QDNJD*hb}mJZ-_%p)#ouncS_B8Gykxxks2uk$J!i=5LQZ9L>GZ zjJmv?a{tr84%tA#=D2~DBzrpjd&o=7blPD{zU$oAM)yHnPUF3)6&tV|?Lcu5uUCFM zXgy}gSCHP=Y&|Jn@8lK0;CpTk;P5V^XZrC$r$THinwSuK;DM%g;^*St>W4a!8aGFA zq4N^^yS2d5VO>!LYMltgl5X>-9YRm1^4-DWCsR|Un8mF+5$84Kuo~ihbrAPxkjX;i z2n!-e`s3%W`DR|zrxrZTmg)Uoru?PCWv}p;^i0m!EWg`m%cE zJwT^X-X%{lihyJBwy$2V@H&+nt$mEucs2U@)y2`gUzh2o`h|9j`$MjD`A_7(53}3R z^VgS}6+A;;FU!s(dOs)13~zd?-_!O$dQkCMrMH@MBL22rAo#RcP^Cjw z*cr-O6xfJ9z<=#JpxYsfxoPSiEl=J0W2za2nva&5<3Jx%7ntA7HFYAhMsju|Gw*u8 z;K9%scy_<%TVf(ht!#8re_YX0^vjddOl^L@b@DdL= zx4tRkV?HNR+l0#B^I(Hr4(sOK&z076-mmudcI?`+UvEbTR29;#X`-tLq- zoCnknGPRf9})J5=8W#r~GtnzNM(SVmKW{<7;w22DPsoR{aUFxWlH*%bP z0FquXxe7A<_cgg9_1+pc@D|>R3KIVq=H)`=^yMM*=GLv$@k-0~YvU9a?L3q?ejmAV zbM0f}1bhx}TKml3Og7wH*wztvgWc@E-ZTrWSrX$shTXEyoICmK)dTk=?Q}&U zK_XX3xRCvVm(-5zlu^aEfOWYrJDmfBcN2DoNZn=uuPoxUtsF1j_Hj|7i0N(IOQBQE z<2=85CzMZFO{8nztZ=#0W40ma?M!hGR*hz0>BEYla3G-XM_uw$09i3+k&|x7PI|)~ zDBCo_SBU8Qzrrg;iZJ1H}E%nY`oZ7d^Xi^*tAP!VD`W7 zZa&l@UHQ*E^^(`q9p6f?D&BPG5eLtp>^*A_s_@tec#^6;t=X3-GdYEAecD3lP)~sw5@RBCYH!sp9;6J`!VKAxf@L%rwmQ2sw)XO|^ zN~^i=&f5$V7(BoXW_06t0k|n9)QZ&oeY>-gH?xZ#ggc+I&}fuX%t@#8$Jf$1gm0&s zPJ*NDUswZVn1=QPNiV_#5adzWd z_`99>;ir&P=)=lt$+LP;4%Vq8y@bN(Rd+fHHW1ET$E%CmX!+DFcg|vWZFMfA*a;Hx<@mBYZ-ro;UgzF^Rj?{X)tqrUx?*VT(k%@@j^ws5~ zW25*PtTn#t@e+7F#b64vdbW9TV)Y0)yUZuj_T+S)QjcLCG9%PYa7EJX95v~#^mQ}aM76&uVe^F&1}HB&qi zR8&M)69oYg6$OFs>_74SY58S_VIITGYu>Nt>-BoRp7S2ogp$+>mg3i+BI{p|uWnEi zO%NsK*!ZE4L*3W!GUy@Nzx(Dwov#f)2<#tTGYX6?NP7#l5NUPCCyO>^ji|E1 z0yS-Q?M^OfSMvi{uPS@Pd#XZ3hG{9+6ymzdmVuaa>>-2qcgEd*-H+DKpZeizTK{+= zj1$${7@t)o*d1%0)PAGN%`oYQtKnZ0*Ih}qq9_s()aR8gk)*$RXOm8HP`3QOjT#n~ zD4E37cy&4>%sx05qn>L!(%tf}&;y%ZN)B;(5m-{k>|K%yPB-d^i|BOl%$ogbk*#%p+Go!j5n z8Lbjg$15)5rv|uE$Ut&1|q{>E4-@hS}hq)$e$@=6fNA zG5ZUndG9NO83rC5BZ3g%)>f77RA zx5ZMKkPG(8WlUde_NWoOE9vvK_iBP^jV&y+#&Vx+fo0YuMB9K7qSK6V;593=Z3H4N zR$X*0QWdC`tO^$MXT2hRRBP;AtAMHR71#Bxzm~1XN=K$5$&K?Z-j|gTl$KVuXJ#J4 z{>{|+xp|to6X%{u?oZK}ZxU=k!-KW3Z!=2$PCG(Bzj5RT#r`^20+0`t^$GLYh;8K{ zcFt&CTad5cN>}6ysT}ZocQsJ;izOQ1&J&TMCH}$s=bTj0Joj>!zCCkupoTm|_i;R~C{9)lycQMjuw~;Mn3sO0x`}lWUdQ8e8v7!}*&Zfw zliw%~7>_yPbFEc4$4#C#u-{ zC2mq=05Ri{ndb~IGE^Xj+xJTymbL>4JpfWE%t|8h!RtBNy(0aHGD%vAR`{Fmn{z6W z^tTL`3na*?AK5^{k3Aa6Yq;MM&q=(U)f0TW+YN3~BQBz>Dtcp;Sxn%pBoBbhxT!o6 zOaroffYcWc^KlP1fYddZmd00I}3+gWTkQit{ z8guOnoUXxGSMT|=&@5*#5FKUNy^@U|y5SpT+(u5{SbfOGe?zHoM(v%bQL*71cgk}T z&*nwD0ADEkY!zO^-6%yaiqCS!TdXk9+*MnnBECZfaW^Ebwof1z7c19^ijyl+;!H%$ z&#P)O+gMu+L6!?DmvWH1)^3n8yG1#8$bku*u4(;N>K(0(%DBFPb4nG#EU6E*D%HN@ z*gs&{@u*Hg|F!f-R)vgWmX~pMf5dIHg3LHt-ZOb1S@ZSnOsAfBRmk#S`xVH-74^$d zC-p5q2gM}(lL$aoB&%#hPQ?(;&6OODBlSoBmiU+a3EoNl0{I2S2aU5EG%TskHQY%a z6AM%}tn#j0)~{Bq`ad5({jzOtbntH5YzEKd&;@M`2`E^B4#c?FW~JCa3?o}w6z6Uf z*yCA!f$I;d_Xz>yo5=do&yQ%f_kOMJdo*x%wlNvH!8_Zb>o9veu$K)}y_!L?m%Td% znIH(G_Pb#_u{kr{4Q~jp#e6O2Iy{kP0(GTtb zxnt2g!lmom6waK3@p?6JohFz49rNU&rJKKK!IY(iV-Yw~al46_6Z4?~Sf6(cZ#IPu z(^0gm2|td2gCJs`!rOC57tTsyE}XUqe12-eurorK-U7MBXgB~e0;aDf*yl+)cdc?a za3@_f2dTPE3qLJ-ovV(Kfn}(y16eIH3>0$W!;|SjL z=OYNa=cCv{vpTLu@~)Q4=lE@JLYu9s_duj3@21>~DC@0(lDtqMUT&vGH&xr-cp15crcP4n-Yl@Td<3jsHFb@z?@}^}^66I6U_9DZ5u0^Zu zg*i+ZYE3vL!WHl}yJm)Vc>rb5?5BCU42!Ot31)yO@H_HJ^>{wDZS`KQxoz8FTfAjS zqb#2Oig&FBYvO}dhs>4n93cz#>Zb}Wt2<`sEtgxav9k4EK~Xr{%(6PeIn_L7)50)u zm7WNE;>>M)axFp4fkp1)N@)y^)H=G7!m^ug?ki4Lf);Hm!y=Ta<@UT3z`dl?bk52u zeD~xtC>cbf(zUDdr z+?qmk>D(a#&|9dn zqeV<{WVG}JNTtEvj^Rhw*&b1Gu45pMZZ$1|v&94YKK1ge=2+8fnJdU$R-v8`rq=1s z0g^NFE9O6+#-52e*+s!Gt(7BhfIjetEE~{p>`-={&UaRx{=AuP^Rg{@Q|V$DXMFuS znSXn8Ki+XkjqNsUqw(?Tfgxq#V0tOx>uYi=gC^rDE!E;HmccB^et8hw^aG)(!7;AFqfwiz2?_GkfG7N9s?`>%`gaugGkh z-|=mqRq%T)$Vk;yuOzH7n9PQKYqE2O6=(ObwnS%n0iV9_0pmj9wH9FI9oO{LC%(cV zRD=Lp73Z%G?`_$>R~NRj3Lu}~3I*}ss7Uqhuz&xh=zLR+<%&4dE&Dm*#fmC5$i_YPf)h_gR-)^WL#*EMo4JBV!7GThWr*Mo@)F)sT9(HleuBqw!DeBnoI8aDF zt2Qc@RtD#?Yo}~F4bULT5#Wx7Tn7{P2uJ@4w}6TIznb$yIpdPH2Dkx3()h?342v*rM(~-6^wuMU2I6|- ze(zJ{1x~L=-5EUP6P!D1lxr!*jmzaL#9)5DACsJGIm;s4iNOugPR4=r!gvmYjL4_t z;nazYAOluTWkCfsiYeG>BPRc@u_YZZ!xrDT9Y-@2sKz2>wpDJ!OYI&9dO8+S;Z){BiBumq;JA zlASC)BnXV%{wNz>(=;t{XXT_IDs9qd#A7VAK;!)z*1i7IBU+!C=|r<2XaOdW<^dRL zbg%BA7-DRbd!uf}WuX&VvMi1M*qRu7T15SB(p&Go7F|9cz;ogWTvE}(c#d0hj-=Of zW?UIU9J#V-l7sY(!Ew43^T|egSp|BR!-~~b`K!&^PU?|_Z>#D*O@!f69U%HBXHsR9 zr3-|7vW8OLP+qY zS(H!mcKzOxRN;G_6*BlT6d8{dgkXQE3W#MwJ^P&W?>lGCy~N$);j2Zx zeFI0knT&fk?&ikqZ<6SEPFkTYK{l6T{wbm{mU~h2!Jz*$W4ly>qOWarj z(xqnfy)grU@4NNGE$GYf>RgVkwB?P07pww17Gzf9MPIr?zKau}S&9OKaxo{+FN0-w zlXQIU{V*?7EUbiD(2MR3p|KW;{4M`7p7d2*>4>w~Tr+PHR{~69PNohNyXlx|;(Q-q z7Q$*P<^_>!f0(k)ST=3=_uPx0KvoOv*%LO@**mecx8fWx5S&N=aYZDly!O7duYTHU z{!T1KgY_QlnKwGzjsG6fQVT_KCWMKRnz#w1NbZ_T6&EK`JNTRJP#prXRbCe}aiU-` z_hQy<7#BAYQfAd(&x;G$&W#EC6y&qgTxj*U(5q;l@Hz;bth5|+v0_Efk6YcFtVh!x%4_=sAs*<_q)Ctvo$@bAcNpkbI6T2_No1rC8kB+6!8@r z6q^zOHyf`Yx)buh&WegPjrmzGhVw7u#e=J&awJcx1#oBnoDH{St;5rClu7g-F!Vpo z6D^%0#+nz1O6GN?Rd$5Ng7}y=u{?xht>xYKCZvfE^0>xf2b=w?_CW{libdBe0!8rKrY{^_LBbSOv><}H*>Ona&VBX}&uq!} zmSZdJc7m^Lmb3cJ@^2fkp$aE;V{J!ueFC+8`xje0s^y*siLsJ{T)L4nkU^GLLW>g8 zrp~+Vzt8Ji)iwWP4}=-1^^K$Y7!7Qazd$~ZXp+SgRQ(*-P~s(cgM=(PlD4<&^*x)q zA9dos%u}%zn4j@in0CGX z8_fa^ttKK=@Ae0ZS6E1PnR#iv5k}yC5epcuk5TU%a~!2>13PTF_47ZcmGI}o1D1p% znVcKK5c5d8199Ym<)haFS(a+ul4@-x^;%$?|1mT3X(fTN;{R%s$vt4hD+l?fZMgCHPDs?@F1s9&SzU=_ulEbm zickAqbT>zmNXhxJ_0N0yE_ty5dd5+vE#-KM-bs&xBAVJhOHk>M2RnAp( zwS~)1Jk*m3kT1^8DW89UR8ssY6@RSKu>?y$sm1mda3+dfAGN6waYSq*7cN}{g-bis zMr+l#!sF^eQuVm5E6<;EK%0t^?8f>9dOGzM^|D>W#bBe%N9-KUaz$)wROqfSZ|mo6 zW*c5xiq|{qh#F7vFlj0N+(m0xZ>F_Ac`_CNKO3)y;g^wEQc?mJ0c>flA5{csU5V=~ z__lW8>)TZSdz&U(XyVpWx~2!d2+9t8QG-M#NAHGs@rFx*(dLUSU)6}J(IWHTWuAIb zF?N|Z>kq)>LF?`$a}KoU-amU|5K{is4%CWM394M){q+ucw1RAM(<#ney%IE5x-!VH zORGn0TP$4W!_ z^PRk~V`l6ai@~-GjU8EMdba|ztNEpIuS9;<_Kw99JrDR5*?vqH1eZg7u7)-J!wf{cK3 z1FQ>?lhOL>#@-p!8dEl0`MyPURX>BCd+6KpdC)k|#h0ZbVTb^UPFib5wke?0d;e_G zf$6R>LbR{pMskq88|3XRtP_CWDw@Y)ejThP@-%BsB>u0TjZYA+A{Qsr_Zb!SW=!)M zd%>2$3g~Z%8u>l~VlN@uPB4M26yDs&<=R-%J=jA1iJ)lRYYtkaM{h0E#8D{r-Z1|;c{)c7-bCA&R`Ui3IYAdqape%pO}sKjPRbd|d zk>nCWy5vUMbtXK0CX-gRKvY`TZHfzj7AkY+xEYMr)uS1=uqy2Co1u4IlkOhIIBgh< zJREq{+>DKBW$)}{XGnhNa82d~S^@GknIe;tXe$wsGtv9u4?;eyTs3knSrv97*gZ`( zSps5ecl)~rvSsGidzRgGKbnWjCML}A?V{gl;}vwB_F(@9&`JTSIq z-aSc-f_;8ypy;1}T}ER^Yoi``zVR-p7dAm4wjV$kL<7HUFp$5jdXr#^v<@_sr%Rs1771!)QktgpFOz4`yPsTEXTT#J##EwJCC`{-u|^lmXy4; zO4Xuh)0+K}1!t2!w_Rh`o%PO`m2H!>*A`rfwZZeyOLi4ZAm&rywb1)kBuylrPQy|o zYxj|jO405FT5Uz6W)Eq2{YJW?{?m#Q#OmvKgO1JcrhTko~l%EV2Z5l1i z@yx5VQ2*kc(VqJJ6loB;UI#}GTT7cA%WHU&Y=XU+U5i0pNy1p3 zDyiIFeb@eAPBXLdoSLp#8pXl|!c(ml6sxRxm_HEGcSyeWX^t#7X=RkcrMIqLUu!^4 z(suf<71F9aBLfr5D`YM}tF+6r@f^W6qit@y&VT(*@BmO|tLN>w6mGQgM-j?BEnvx7 z4Bo;|0$9|>jZwU%0NVUiz}Q(Cc^IQ$Y};I9c*9kttD0+iK5U~m)|6Sl9DdP++;i%PR+2(QiUs~zD|=7k4EqZ zHgpruF6JhO|E)*?RiJN>4^}Vh4G8aMq0QGL$>pUVMxKhi-u@%+(OwKYt<;|qr8u9? z^1SI_!P#wNPrp$9)~fZbZMNi){jm!9=Y2zF!N0VoeaMD)mEcWoh})32ta7)U&cH`k z)Stn4#hD~BY-(@VVEU{xRb!or3372^hbH8{`hoJe20isJ@`0CZuxy*dS*tH<_06_& z_XC@_TEML6bGZ|JLl6#S1uIMZjq9f}H3*Q?X3I@>U9UCxNx+v*f&O|+l9R=7XlE0( zkK8aq21;rzE7k=?2_HTKL))3JAp4K}dCh^|YC9p9IiXH1m960rX8oe%oASRZ=?}Xi z*C+_~Ao_QO6#=iYp=%cSDZIA3d`Cxoy-p%GG<^`buRwB43wqn3gAmC50u3ifkLkrh zBRGtyuvWLeTQgPo;LD@PIMyKvi;sLB<)`-(g^Wc^=osWF_Q4=` z3n{Fe_QwC+EhH22B<~;a-LRX>@otmNI?*QT%j21-XNzHa8kP9OE}nxj#|tMz@M6l} z?vp-4CUD_m!Gu!~qLU{!T6yfa_yq7DMetb8vrF}^8;9xi;E!Zb;k4>P5As1*LZbz zUkR#~JplWwzJMh2{_+{{YyR8z3oiR$@?zquAP??$IM%GI1Y!F7IKwvbRu7llM~><7 zt0VU2<&CXaKR-B6(bPW)%yj8iH|7pfV03dz!`l_!sZNA6tVBhD2ZuF&&$X6|J0TF` z8>f|SS*su7=Zb2Ei&1et&~-&N++bUy620*ZU*M#ysFsxapqPhvgSm^^PRhq!YbdN2 zs*{A=jr3=7GzzMHMOjqW8zpzw3%=#2Co~TJ)_OZE+(+E;$>R*eC&>87dHA!85_p+i zYO%Xx>@oFsc0;!8L0;e1F@iHFLC};$dq^c<*Ftm;MZn5F*OmIL`RJ|(0ZJ22t$rkc_|Y)oNxzt_{9sDzT>CkthuHMTU!E!hogPIeAWSR++P1eb{L}C3cMo{N{s6Q(`#S?_c1o=<6b$crv*;*83WVv^5R>+sGs(Fq56HoQMoKUK)SV_ ztgHSGXPrU*<$c|li1v`T9yg4-Taanoj-0@$(1 ziJlI_(_ns)_ixTAHnopOf8$0LZ^Bk}jk$zcx%<>|Dd^i5u&3n0mCGa!#OQh(^h zAr9GHR(@InKc~Ot6BueHBb4mVzb%3nZ#7!KrInAI z#F(qsr=U?XHD7=e&emR;k&TR#}u@A?39`+MyB?Qzv8LJl3yz7nD0FPf8I=>vCF4 zqh6xY%xcA&4cI#$bS`$+ZX%$RjDZuNnISeO4V0eKmT&hFbC+?Z>VJCE<;|41-kjAl zm;6S{1IhxHUSg}?cit3$`}P>0P Date: Thu, 7 Nov 2024 19:59:39 +0100 Subject: [PATCH 141/278] New example: text/unicode - small fix --- examples/text/rectangle_bounds/main.go | 44 ++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/examples/text/rectangle_bounds/main.go b/examples/text/rectangle_bounds/main.go index e020f03..89976b1 100644 --- a/examples/text/rectangle_bounds/main.go +++ b/examples/text/rectangle_bounds/main.go @@ -38,8 +38,18 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i resizing, wordWrap := false, true - container := rl.Rectangle{X: 25.0, Y: 25.0, Width: screenWidth - 50.0, Height: screenHeight - 250.0} - resizer := rl.Rectangle{X: container.X + container.Width - 17, Y: container.Y + container.Height - 17, Width: 14, Height: 14} + container := rl.Rectangle{ + X: 25.0, + Y: 25.0, + Width: screenWidth - 50.0, + Height: screenHeight - 250.0, + } + resizer := rl.Rectangle{ + X: container.X + container.Width - 17, + Y: container.Y + container.Height - 17, + Width: 14, + Height: 14, + } // Minimum width and height for the container rectangle minWidth := float32(60.0) @@ -99,14 +109,23 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i rl.DrawRectangleLinesEx(container, 3, borderColor) // Draw container border // Draw text in container (add some padding) - DrawTextBoxed(font, text, rl.Rectangle{X: container.X + 4, Y: container.Y + 4, Width: container.Width - 4, - Height: container.Height - 4}, 20.0, 2.0, wordWrap, rl.Gray) + DrawTextBoxed(font, text, rl.Rectangle{ + X: container.X + 4, + Y: container.Y + 4, + Width: container.Width - 4, + Height: container.Height - 4, + }, 20.0, 2.0, wordWrap, rl.Gray) rl.DrawRectangleRec(resizer, borderColor) // Draw the resize box // Draw bottom info rl.DrawRectangle(0, screenHeight-54, screenWidth, 54, rl.Gray) - rl.DrawRectangleRec(rl.Rectangle{X: 382.0, Y: screenHeight - 34.0, Width: 12.0, Height: 12.0}, rl.Maroon) + rl.DrawRectangleRec(rl.Rectangle{ + X: 382.0, + Y: screenHeight - 34.0, + Width: 12.0, + Height: 12.0, + }, rl.Maroon) rl.DrawText("Word Wrap: ", 313, screenHeight-115, 20, rl.Black) if wordWrap { @@ -138,7 +157,7 @@ func DrawTextBoxed(font rl.Font, text string, rec rl.Rectangle, fontSize, spacin func DrawTextBoxedSelectable(font rl.Font, text string, rec rl.Rectangle, fontSize, spacing float32, wordWrap bool, tint rl.Color, selectStart, selectLength int32, selectTint, selectBackTint rl.Color) { - length := int32(utf8.RuneCountInString(text)) // Total length in bytes of the text, scanned by codepoints in loop + length := int32(len(text)) // Total length in bytes of the text, scanned by codepoints in loop // TextOffsetY : Offset between lines (on line break '\n') // TextOffsetX : Offset X to next character to draw @@ -246,8 +265,12 @@ func DrawTextBoxedSelectable(font rl.Font, text string, rec rl.Rectangle, fontSi // Draw selection background isGlyphSelected := false if (selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)) { - rl.DrawRectangleRec(rl.Rectangle{X: rec.X + textOffsetX - 1, Y: rec.Y + textOffsetY, Width: glyphWidth, - Height: float32(font.BaseSize) * scaleFactor}, selectBackTint) + rl.DrawRectangleRec(rl.Rectangle{ + X: rec.X + textOffsetX - 1, + Y: rec.Y + textOffsetY, + Width: glyphWidth, + Height: float32(font.BaseSize) * scaleFactor, + }, selectBackTint) isGlyphSelected = true } @@ -257,7 +280,10 @@ func DrawTextBoxedSelectable(font rl.Font, text string, rec rl.Rectangle, fontSi if isGlyphSelected { col = selectTint } - pos := rl.Vector2{X: rec.X + textOffsetX, Y: rec.Y + textOffsetY} + pos := rl.Vector2{ + X: rec.X + textOffsetX, + Y: rec.Y + textOffsetY, + } rl.DrawTextEx(font, string(codepoint), pos, fontSize, 0, col) } } From 382cbda3dec3a8c9a45febbd14bc6f95e9c6a841 Mon Sep 17 00:00:00 2001 From: skullbulb Date: Sat, 9 Nov 2024 19:34:09 +0000 Subject: [PATCH 142/278] Added [models] example - skybox loading and drawing --- examples/models/skybox/main.go | 125 ++++++++++++++++++++++++++++++ examples/models/skybox/skybox.fs | 19 +++++ examples/models/skybox/skybox.png | Bin 0 -> 10992 bytes examples/models/skybox/skybox.vs | 24 ++++++ 4 files changed, 168 insertions(+) create mode 100644 examples/models/skybox/main.go create mode 100644 examples/models/skybox/skybox.fs create mode 100644 examples/models/skybox/skybox.png create mode 100644 examples/models/skybox/skybox.vs diff --git a/examples/models/skybox/main.go b/examples/models/skybox/main.go new file mode 100644 index 0000000..f43d633 --- /dev/null +++ b/examples/models/skybox/main.go @@ -0,0 +1,125 @@ +package main + +import ( + "fmt" + "path/filepath" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + skyboxFilename := "skybox.png" + + rl.InitWindow(800, 450, "raylib [models] example - skybox loading and drawing") + + camera := rl.NewCamera3D( + rl.NewVector3(1.0, 1.0, 1.0), + rl.NewVector3(4.0, 1.0, 4.0), + rl.NewVector3(0.0, 1.0, 0.0), + 45.0, + rl.CameraPerspective, + ) + + // load skybox shader and set required locations + skyboxShader := rl.LoadShader("skybox.vs", "skybox.fs") + + setShaderIntValue(skyboxShader, "environmentMap", rl.MapCubemap) + + // load skybox model + cube := rl.GenMeshCube(1.0, 1.0, 1.0) + skybox := rl.LoadModelFromMesh(cube) + + skybox.Materials.Shader = skyboxShader + + // load cubemap texture + skyboxImg := rl.LoadImage(skyboxFilename) + + skyboxTexture := rl.LoadTextureCubemap(skyboxImg, rl.CubemapLayoutAutoDetect) + + rl.UnloadImage(skyboxImg) + + rl.SetMaterialTexture(skybox.Materials, rl.MapCubemap, skyboxTexture) + + // limit cursor to relative movement inside the window + rl.DisableCursor() + + // set our game to run at 60 frames-per-second + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + rl.UpdateCamera(&camera, rl.CameraFirstPerson) + + // load new cubemap texture on drag&drop + if rl.IsFileDropped() { + droppedFiles := rl.LoadDroppedFiles() + + // only support one file dropped + if len(droppedFiles) == 1 { + switch filepath.Ext(droppedFiles[0]) { + case ".png", ".jpg", ".bmp", ".tga": + skyboxFilename = droppedFiles[0] + + rl.UnloadTexture(skyboxTexture) + + img := rl.LoadImage(skyboxFilename) + + skyboxTexture = rl.LoadTextureCubemap(img, rl.CubemapLayoutAutoDetect) + + rl.UnloadImage(img) + + rl.SetMaterialTexture(skybox.Materials, rl.MapCubemap, skyboxTexture) + } + } + + rl.UnloadDroppedFiles() + } + + rl.BeginDrawing() + + rl.ClearBackground(rl.White) + + rl.BeginMode3D(camera) + + // we are inside the cube, we need to disable backface culling + rl.DisableBackfaceCulling() + rl.DisableDepthMask() + + rl.DrawModel(skybox, rl.NewVector3(0, 0, 0), 1.0, rl.White) + + // restore depth and backface culling + rl.EnableBackfaceCulling() + rl.EnableDepthMask() + + rl.DrawGrid(10, 1.0) + + rl.EndMode3D() + + rl.DrawText( + fmt.Sprintf("File: %s", skyboxFilename), + 10, + int32(rl.GetScreenHeight()-20), + 10, + rl.Black, + ) + + rl.DrawFPS(10, 10) + + rl.EndDrawing() + } + + rl.UnloadModel(skybox) + rl.UnloadTexture(skyboxTexture) + rl.UnloadShader(skyboxShader) + + rl.CloseWindow() +} + +func setShaderIntValue(shader rl.Shader, name string, value int32) { + rl.SetShaderValue( + shader, + rl.GetShaderLocation(shader, name), + unsafe.Slice((*float32)(unsafe.Pointer(&value)), 4), + rl.ShaderUniformInt, + ) +} diff --git a/examples/models/skybox/skybox.fs b/examples/models/skybox/skybox.fs new file mode 100644 index 0000000..25ae075 --- /dev/null +++ b/examples/models/skybox/skybox.fs @@ -0,0 +1,19 @@ +#version 330 + +// input vertex attributes (from vertex shader) +in vec3 fragPosition; + +// input uniform values +uniform samplerCube environmentMap; + +// output fragment color +out vec4 finalColor; + +void main() +{ + // fetch color from texture map + vec3 color = texture(environmentMap, fragPosition).rgb; + + // calculate final fragment color + finalColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/examples/models/skybox/skybox.png b/examples/models/skybox/skybox.png new file mode 100644 index 0000000000000000000000000000000000000000..36a79b2de5bee79b932730011d25e1e5f6209d48 GIT binary patch literal 10992 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 Date: Sun, 10 Nov 2024 14:02:00 +0100 Subject: [PATCH 143/278] New example: text/draw_3d --- examples/text/draw_3d/main.go | 822 ++++++++++++++++++ .../shaders/glsl330/alpha_discard.fs | 19 + 2 files changed, 841 insertions(+) create mode 100644 examples/text/draw_3d/main.go create mode 100644 examples/text/draw_3d/resources/shaders/glsl330/alpha_discard.fs diff --git a/examples/text/draw_3d/main.go b/examples/text/draw_3d/main.go new file mode 100644 index 0000000..f111aa6 --- /dev/null +++ b/examples/text/draw_3d/main.go @@ -0,0 +1,822 @@ +/******************************************************************************************* +* +* raylib [text] example - Draw 3d +* +* NOTE: Draw a 2D text in 3D space, each letter is drawn in a quad (or 2 quads if back face is set) +* where the texture coordinates of each quad map to the texture coordinates of the glyphs +* inside the font texture. +* +* A more efficient approach, i believe, would be to render the text in a render texture and +* map that texture to a plane and render that, or maybe a shader but my method allows more +* flexibility...for example to change position of each letter individually to make some think +* like a wavy text effect. +* +* Special thanks to: +* @Nighten for the DrawTextStyle() code https://github.com/NightenDushi/Raylib_DrawTextStyle +* Chris Camacho (codifies - http://bedroomcoders.co.uk/) for the alpha discard shader +* +* Example originally created with raylib 3.5, last time updated with raylib 4.0 +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2021-2024 Vlad Adrian (@demizdor) +* +********************************************************************************************/ +package main + +import ( + "fmt" + "math" + "path/filepath" + "unicode/utf8" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +// Globals +const ( + letterBoundarySize = 0.25 + textMaxLayers = 32 + maxTextLength = 64 + screenWidth = 800 + screenHeight = 450 +) + +var letterBoundaryColor = rl.Violet +var showLetterBoundary, showTextBoundary = false, false + +// Data Types definition + +// WaveTextConfig is a configuration structure for waving the text +type WaveTextConfig struct { + waveRange, waveSpeed, waveOffset rl.Vector3 +} + +// Program main entry point +func main() { + // Initialization + rl.SetConfigFlags(rl.FlagMsaa4xHint | rl.FlagVsyncHint) + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - draw 2D text in 3D") + + spin := true // Spin the camera? + multicolor := false // Multicolor mode + + // Define the camera to look into our 3d world + camera := rl.Camera3D{ + Position: rl.Vector3{ + X: -10.0, + Y: 15.0, + Z: -10.0, + }, // Camera position + Target: rl.Vector3{}, // Camera looking at point + Up: rl.Vector3{Y: 1.0}, // Camera up vector (rotation towards target) + Fovy: 45.0, // Camera field-of-view Y + Projection: rl.CameraPerspective, // Camera projection type + } + + cameraMode := rl.CameraOrbital + + cubePosition := rl.Vector3{Y: 1.0} + cubeSize := rl.Vector3{ + X: 2.0, + Y: 2.0, + Z: 2.0, + } + + // Use the default font + font := rl.GetFontDefault() + var fontSize, fontSpacing, lineSpacing float32 = 8.0, 0.5, -1 + + // Set the text (using markdown!) + text := "Hello ~~World~~ in 3D!" + tbox := rl.Vector3{} + var layers, quads int32 = 1, 0 + var layerDistance float32 = 0.01 + + wcfg := WaveTextConfig{ + waveSpeed: rl.Vector3{ + X: 3, + Y: 3, + Z: 0.5, + }, + waveOffset: rl.Vector3{ + X: 0.35, + Y: 0.35, + Z: 0.35, + }, + waveRange: rl.Vector3{ + X: 0.45, + Y: 0.45, + Z: 0.45, + }, + } + + var time float32 + + // Set up a light and dark color + light, dark := rl.Maroon, rl.Red + + // Load the alpha discard shader + alphaDiscard := rl.LoadShader("", "resources/shaders/glsl330/alpha_discard.fs") + + // Array filled with multiple random colors (when multicolor mode is set) + var multi [textMaxLayers]rl.Color + + rl.DisableCursor() // Limit cursor to relative movement inside the window + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + rl.UpdateCamera(&camera, cameraMode) + + // Handle font files dropped + if rl.IsFileDropped() { + droppedFiles := rl.LoadDroppedFiles() + + // NOTE: We only support first ttf file dropped + rl.UnloadFont(font) + if filepath.Ext(droppedFiles[0]) == ".ttf" { + font = rl.LoadFontEx(droppedFiles[0], int32(fontSize), nil, 0) + } else if filepath.Ext(droppedFiles[0]) == ".fnt" { + font = rl.LoadFont(droppedFiles[0]) + fontSize = float32(font.BaseSize) + } + + rl.UnloadDroppedFiles() // Unload file paths from memory + } + + // Handle Events + if rl.IsKeyPressed(rl.KeyF1) { + showLetterBoundary = !showLetterBoundary + } + if rl.IsKeyPressed(rl.KeyF2) { + showTextBoundary = !showTextBoundary + } + if rl.IsKeyPressed(rl.KeyF3) { + // Handle camera change + spin = !spin + // we need to reset the camera when changing modes + camera = rl.Camera3D{ + Target: rl.Vector3{}, // Camera looking at point + Up: rl.Vector3{Y: 1.0}, // Camera up vector (rotation towards target) + Fovy: 45.0, // Camera field-of-view Y + Projection: rl.CameraPerspective, // Camera projection type + } + + if spin { + camera.Position = rl.Vector3{ + X: -10.0, + Y: 15.0, + Z: -10.0, + } // Camera position + cameraMode = rl.CameraOrbital + } else { + camera.Position = rl.Vector3{ + X: 10.0, + Y: 10.0, + Z: -10.0, + } // Camera position + cameraMode = rl.CameraFree + } + } + + // Handle clicking the cube + if rl.IsMouseButtonPressed(rl.MouseButtonLeft) { + // TODO : Missing function, see issue https://github.com/gen2brain/raylib-go/issues/457 + //ray := rl.GetScreenToWorldRay(rl.GetMousePosition(), camera) + ray := rl.GetMouseRay(rl.GetMousePosition(), camera) + + // Check collision between ray and box + v1 := rl.Vector3{ + X: cubePosition.X - cubeSize.X/2, + Y: cubePosition.Y - cubeSize.Y/2, + Z: cubePosition.Z - cubeSize.Z/2, + } + v2 := rl.Vector3{ + X: cubePosition.X + cubeSize.X/2, + Y: cubePosition.Y + cubeSize.Y/2, + Z: cubePosition.Z + cubeSize.Z/2, + } + collision := rl.GetRayCollisionBox(ray, rl.BoundingBox{ + Min: v1, + Max: v2, + }) + + if collision.Hit { + // Generate new random colors + light = generateRandomColor(0.5, 0.78) + dark = generateRandomColor(0.4, 0.58) + } + } + + // Handle text layers changes + if rl.IsKeyPressed(rl.KeyHome) && layers > 1 { + layers-- + } else if rl.IsKeyPressed(rl.KeyEnd) && layers < textMaxLayers { + layers++ + } + + // Handle text changes + if rl.IsKeyPressed(rl.KeyLeft) { + fontSize -= 0.5 + } else if rl.IsKeyPressed(rl.KeyRight) { + fontSize += 0.5 + } else if rl.IsKeyPressed(rl.KeyUp) { + fontSpacing -= 0.1 + } else if rl.IsKeyPressed(rl.KeyDown) { + fontSpacing += 0.1 + } else if rl.IsKeyPressed(rl.KeyPageUp) { + lineSpacing -= 0.5 + } else if rl.IsKeyPressed(rl.KeyPageDown) { + lineSpacing += 0.5 + } else if rl.IsKeyDown(rl.KeyInsert) { + layerDistance -= 0.001 + } else if rl.IsKeyDown(rl.KeyDelete) { + layerDistance += 0.001 + } else if rl.IsKeyPressed(rl.KeyTab) { + multicolor = !multicolor // Enable /disable multicolor mode + + if multicolor { + // Fill color array with random colors + for i := 0; i < textMaxLayers; i++ { + multi[i] = generateRandomColor(0.5, 0.8) + multi[i].A = uint8(rl.GetRandomValue(0, 255)) + } + } + } + + // Handle text input + ch := rl.GetCharPressed() + if rl.IsKeyPressed(rl.KeyBackspace) { + // Remove last char + text = text[:len(text)-1] + } else if rl.IsKeyPressed(rl.KeyEnter) { + // handle newline + text += "\n" + } else if ch != 0 && len(text) < maxTextLength { + // append only printable chars + text += string(ch) + } + + // Measure 3D text so we can center it + tbox = measureTextWave3D(font, text, fontSize, fontSpacing, lineSpacing) + + quads = 0 // Reset quad counter + time += rl.GetFrameTime() // Update timer needed by `drawTextWave3D()` + + // Draw + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginMode3D(camera) + rl.DrawCubeV(cubePosition, cubeSize, dark) + rl.DrawCubeWires(cubePosition, 2.1, 2.1, 2.1, light) + + rl.DrawGrid(10, 2.0) + + // Use a shader to handle the depth buffer issue with transparent textures + // NOTE: more info at https://bedroomcoders.co.uk/raylib-billboards-advanced-use/ + rl.BeginShaderMode(alphaDiscard) + + // Draw the 3D text above the red cube + rl.PushMatrix() + rl.Rotatef(90.0, 1.0, 0.0, 0.0) + rl.Rotatef(90.0, 0.0, 0.0, -1.0) + + for i := int32(0); i < layers; i++ { + clr := light + if multicolor { + clr = multi[i] + } + + vec := rl.Vector3{ + X: -tbox.X / 2.0, + Y: layerDistance * float32(i), + Z: -4.5, + } + drawTextWave3D(font, text, vec, fontSize, fontSpacing, lineSpacing, true, &wcfg, time, clr) + } + + // Draw the text boundary if set + if showTextBoundary { + rl.DrawCubeWiresV(rl.Vector3{Z: -4.5 + tbox.Z/2}, tbox, dark) + } + rl.PopMatrix() + + // Don't draw the letter boundaries for the 3D text below + slb := showLetterBoundary + showLetterBoundary = false + + // Draw 3D options (use default font) + rl.PushMatrix() + rl.Rotatef(180.0, 0.0, 1.0, 0.0) + opt := fmt.Sprintf("< SIZE: %2.1f >", fontSize) + quads += int32(len(opt)) + m := measureText3D(rl.GetFontDefault(), opt, 8.0, 1.0, 0.0) + pos := rl.Vector3{ + X: -m.X / 2.0, + Y: 0.01, + Z: 2.0, + } + drawText3D(rl.GetFontDefault(), opt, pos, 8.0, 1.0, 0.0, false, rl.Blue) + pos.Z += 0.5 + m.Z + + opt = fmt.Sprintf("< SPACING: %2.1f >", fontSpacing) + quads += int32(len(opt)) + m = measureText3D(rl.GetFontDefault(), opt, 8.0, 1.0, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 8.0, 1.0, 0.0, false, rl.Blue) + pos.Z += 0.5 + m.Z + + opt = fmt.Sprintf("< LINE: %2.1f >", lineSpacing) + quads += int32(len(opt)) + m = measureText3D(rl.GetFontDefault(), opt, 8.0, 1.0, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 8.0, 1.0, 0.0, false, rl.Blue) + pos.Z += 1.0 + m.Z + + lbox := "OFF" + if slb { + lbox = "ON" + } + opt = fmt.Sprintf("< LBOX: %3s >", lbox) + quads += int32(len(opt)) + m = measureText3D(rl.GetFontDefault(), opt, 8.0, 1.0, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 8.0, 1.0, 0.0, false, rl.Red) + pos.Z += 0.5 + m.Z + + tb := "OFF" + if showTextBoundary { + tb = "ON" + } + opt = fmt.Sprintf("< TBOX: %3s >", tb) + quads += int32(len(opt)) + m = measureText3D(rl.GetFontDefault(), opt, 8.0, 1.0, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 8.0, 1.0, 0.0, false, rl.Red) + pos.Z += 0.5 + m.Z + + opt = fmt.Sprintf("< LAYER DISTANCE: %.3f >", layerDistance) + quads += int32(len(opt)) + m = measureText3D(rl.GetFontDefault(), opt, 8.0, 1.0, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 8.0, 1.0, 0.0, false, rl.DarkPurple) + rl.PopMatrix() + + // Draw 3D info text (use default font) + opt = "All the text displayed here is in 3D" + quads += 36 + m = measureText3D(rl.GetFontDefault(), opt, 10.0, 0.5, 0.0) + pos = rl.Vector3{ + X: -m.X / 2.0, + Y: 0.01, + Z: 2.0, + } + drawText3D(rl.GetFontDefault(), opt, pos, 10.0, 0.5, 0.0, false, rl.DarkBlue) + pos.Z += 1.5 + m.Z + + opt = "press [Left]/[Right] to change the font size" + quads += 44 + m = measureText3D(rl.GetFontDefault(), opt, 6.0, 0.5, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 6.0, 0.5, 0.0, false, rl.DarkBlue) + pos.Z += 0.5 + m.Z + + opt = "press [Up]/[Down] to change the font spacing" + quads += 44 + m = measureText3D(rl.GetFontDefault(), opt, 6.0, 0.5, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 6.0, 0.5, 0.0, false, rl.DarkBlue) + pos.Z += 0.5 + m.Z + + opt = "press [PgUp]/[PgDown] to change the line spacing" + quads += 48 + m = measureText3D(rl.GetFontDefault(), opt, 6.0, 0.5, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 6.0, 0.5, 0.0, false, rl.DarkBlue) + pos.Z += 0.5 + m.Z + + opt = "press [F1] to toggle the letter boundary" + quads += 39 + m = measureText3D(rl.GetFontDefault(), opt, 6.0, 0.5, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 6.0, 0.5, 0.0, false, rl.DarkBlue) + pos.Z += 0.5 + m.Z + + opt = "press [F2] to toggle the text boundary" + quads += 37 + m = measureText3D(rl.GetFontDefault(), opt, 6.0, 0.5, 0.0) + pos.X = -m.X / 2.0 + drawText3D(rl.GetFontDefault(), opt, pos, 6.0, 0.5, 0.0, false, rl.DarkBlue) + + showLetterBoundary = slb + rl.EndShaderMode() + + rl.EndMode3D() + + // Draw 2D info text & stats + msg := `Drag & drop a font file to change the font! +Type something, see what happens! + +Press [F3] to toggle the camera` + rl.DrawText(msg, 10, 35, 10, rl.Black) + + cam := "FREE" + if spin { + cam = "ORBITAL" + } + quads += int32(len(text)) * 2 * layers + tmp := fmt.Sprintf("%2d layer(s) | %s camera | %4d quads (%4d verts)", layers, cam, quads, quads*4) + width := rl.MeasureText(tmp, 10) + rl.DrawText(tmp, screenWidth-20-width, 10, 10, rl.DarkGreen) + + tmp = "[Home]/[End] to add/remove 3D text layers" + width = rl.MeasureText(tmp, 10) + rl.DrawText(tmp, screenWidth-20-width, 25, 10, rl.DarkGray) + + tmp = "[Insert]/[Delete] to increase/decrease distance between layers" + width = rl.MeasureText(tmp, 10) + rl.DrawText(tmp, screenWidth-20-width, 40, 10, rl.DarkGray) + + tmp = "click the [CUBE] for a random color" + width = rl.MeasureText(tmp, 10) + rl.DrawText(tmp, screenWidth-20-width, 55, 10, rl.DarkGray) + + tmp = "[Tab] to toggle multicolor mode" + width = rl.MeasureText(tmp, 10) + rl.DrawText(tmp, screenWidth-20-width, 70, 10, rl.DarkGray) + + rl.DrawFPS(10, 10) + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadFont(font) + rl.CloseWindow() // Close window and OpenGL context + +} + +// Module Functions Definitions + +// drawTextCodepoint3D draws codepoint at specified position in 3D space +func drawTextCodepoint3D(font rl.Font, codepoint rune, position rl.Vector3, fontSize float32, backface bool, + tint rl.Color) { + // Character index position in sprite font + // NOTE: In case a codepoint is not available in the font, index returned points to '?' + index := rl.GetGlyphIndex(font, codepoint) + scale := fontSize / float32(font.BaseSize) + + // Character destination rectangle on screen + // NOTE: We consider charsPadding on drawing + glyphs := unsafe.Slice(font.Chars, font.CharsCount) + position.X += float32(glyphs[index].OffsetX-font.CharsPadding) / float32(font.BaseSize) * scale + position.Z += float32(glyphs[index].OffsetY-font.CharsPadding) / float32(font.BaseSize) * scale + + // Character source rectangle from font texture atlas + // NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects + recs := unsafe.Slice(font.Recs, font.CharsCount) + srcRec := rl.Rectangle{ + X: recs[index].X - float32(font.CharsPadding), + Y: recs[index].Y - float32(font.CharsPadding), + Width: recs[index].Width + 2.0*float32(font.CharsPadding), + Height: recs[index].Height + 2.0*float32(font.CharsPadding), + } + + width := (recs[index].Width + 2.0*float32(font.CharsPadding)) / float32(font.BaseSize) * scale + height := (recs[index].Height + 2.0*float32(font.CharsPadding)) / float32(font.BaseSize) * scale + + if font.Texture.ID > 0 { + var x, y, z float32 + + // normalized texture coordinates of the glyph inside the font texture (0.0f -> 1.0f) + tx := srcRec.X / float32(font.Texture.Width) + ty := srcRec.Y / float32(font.Texture.Height) + tw := (srcRec.X + srcRec.Width) / float32(font.Texture.Width) + th := (srcRec.Y + srcRec.Height) / float32(font.Texture.Height) + + if showLetterBoundary { + pos := rl.Vector3{ + X: position.X + width/2, + Y: position.Y, + Z: position.Z + height/2, + } + size := rl.Vector3{ + X: width, + Y: letterBoundarySize, + Z: height, + } + rl.DrawCubeWiresV(pos, size, letterBoundaryColor) + } + + var limit int32 = 4 + if backface { + limit = 8 + } + rl.CheckRenderBatchLimit(limit) + rl.SetTexture(font.Texture.ID) + + rl.PushMatrix() + rl.Translatef(position.X, position.Y, position.Z) + + rl.Begin(rl.Quads) + rl.Color4ub(tint.R, tint.G, tint.B, tint.A) + + // Front Face + rl.Normal3f(0.0, 1.0, 0.0) // Normal Pointing Up + rl.TexCoord2f(tx, ty) + rl.Vertex3f(x, y, z) // Top Left Of The Texture and Quad + rl.TexCoord2f(tx, th) + rl.Vertex3f(x, y, z+height) // Bottom Left Of The Texture and Quad + rl.TexCoord2f(tw, th) + rl.Vertex3f(x+width, y, z+height) // Bottom Right Of The Texture and Quad + rl.TexCoord2f(tw, ty) + rl.Vertex3f(x+width, y, z) // Top Right Of The Texture and Quad + + if backface { + // Back Face + rl.Normal3f(0.0, -1.0, 0.0) // Normal Pointing Down + rl.TexCoord2f(tx, ty) + rl.Vertex3f(x, y, z) // Top Right Of The Texture and Quad + rl.TexCoord2f(tw, ty) + rl.Vertex3f(x+width, y, z) // Top Left Of The Texture and Quad + rl.TexCoord2f(tw, th) + rl.Vertex3f(x+width, y, z+height) // Bottom Left Of The Texture and Quad + rl.TexCoord2f(tx, th) + rl.Vertex3f(x, y, z+height) // Bottom Right Of The Texture and Quad + } + rl.End() + rl.PopMatrix() + rl.SetTexture(0) + } +} + +// drawText3D draws a 2D text in 3D space +func drawText3D(font rl.Font, text string, position rl.Vector3, fontSize, fontSpacing, + lineSpacing float32, backface bool, tint rl.Color) { + length := int32(len(text)) // Total length in bytes of the text, + // scanned by codepoints in loop + + // TextOffsetY : Offset between lines (on line break '\n') + // TextOffsetX : Offset X to next character to draw + var textOffsetY, textOffsetX float32 + + scale := fontSize / float32(font.BaseSize) + for i := int32(0); i < length; { + + // Get next codepoint from byte string and glyph index in font + codepoint, codepointByteCount := getCodepoint(text, i) + index := rl.GetGlyphIndex(font, codepoint) + + // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all the bad bytes using the '?' symbol moving one byte + if codepoint == 0x3f { + codepointByteCount = 1 + } + + if codepoint == 0 || codepoint == '\n' { + // NOTE: Fixed line spacing of 1.5 line-height + // TODO: Support custom line spacing defined by user + textOffsetY += scale + lineSpacing/float32(font.BaseSize)*scale + textOffsetX = 0.0 + } else { + if (codepoint != ' ') && (codepoint != '\t') { + vec := rl.Vector3{ + X: position.X + textOffsetX, + Y: position.Y, + Z: position.Z + textOffsetY, + } + drawTextCodepoint3D(font, codepoint, vec, fontSize, backface, tint) + } + + textOffsetX += getTextWidth(font, index, fontSpacing, scale) + } + + i += codepointByteCount // Move text bytes counter to next codepoint + } +} + +// measureText3D measures a text in 3D. For some reason `MeasureTextEx()` +// just doesn't seem to work, so I had to use this instead. +func measureText3D(font rl.Font, text string, fontSize, fontSpacing, lineSpacing float32) rl.Vector3 { + length := int32(len(text)) + var tempLen, lenCounter int32 // Used to count longer text line num chars + + var ( + tempTextWidth float32 // Used to count longer text line width + scale = fontSize / float32(font.BaseSize) + textHeight = scale + textWidth float32 + ) + + var ( + letter rune // Current character + index int32 // Index position in sprite font + ) + + for i := int32(0); i < length; i++ { + lenCounter++ + + var next int32 + letter, next = getCodepoint(text, i) + index = rl.GetGlyphIndex(font, letter) + + // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all the bad bytes using the '?' symbol so to not skip any we set next = 1 + if letter == 0x3f { + next = 1 + } + i += next - 1 + + if letter != 0 && letter != '\n' { + textWidth += getTextWidth(font, index, fontSpacing, scale) + } else { + if tempTextWidth < textWidth { + tempTextWidth = textWidth + } + lenCounter = 0 + textWidth = 0.0 + textHeight += scale + lineSpacing/float32(font.BaseSize)*scale + } + + if tempLen < lenCounter { + tempLen = lenCounter + } + } + + if tempTextWidth < textWidth { + tempTextWidth = textWidth + } + + // Adds chars spacing to measure + vec := rl.Vector3{ + X: tempTextWidth + float32(tempLen-1)*fontSpacing/float32(font.BaseSize)*scale, + Y: 0.25, + Z: textHeight, + } + return vec +} + +// drawTextWave3D draws a 2D text in 3D space and wave the parts that start with `~~` and end with `~~`. +// This is a modified version of the original code by @Nighten found here https://github.com/NightenDushi/Raylib_DrawTextStyle +func drawTextWave3D(font rl.Font, text string, position rl.Vector3, fontSize, fontSpacing, + lineSpacing float32, backface bool, config *WaveTextConfig, time float32, tint rl.Color) { + length := int32(len(text)) // Total length in bytes of the text, scanned by codepoints in loop + + // TextOffsetY : Offset between lines (on line break '\n') + // TextOffsetX : Offset X to next character to draw + var textOffsetY, textOffsetX float32 + var wave bool + + scale := fontSize / float32(font.BaseSize) + + for i, k := int32(0), int32(0); i < length; k++ { + // Get next codepoint from byte string and glyph index in font + codepoint, codepointByteCount := getCodepoint(text, i) + index := rl.GetGlyphIndex(font, codepoint) + + // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all the bad bytes using the '?' symbol moving one byte + if codepoint == 0x3f { + codepointByteCount = 1 + } + + if codepoint == 0 || codepoint == '\n' { + // NOTE: Fixed line spacing of 1.5 line-height + // TODO: Support custom line spacing defined by user + textOffsetY += scale + lineSpacing/float32(font.BaseSize)*scale + textOffsetX = 0.0 + k = 0 + } else if codepoint == '~' { + var r rune + r, codepointByteCount = getCodepoint(text, i+1) + if r == '~' { + codepointByteCount += 1 + wave = !wave + } + } else { + if (codepoint != ' ') && (codepoint != '\t') { + pos := position + if wave { // Apply the wave effect + kk := float32(k) + pos.X += sin(time*config.waveSpeed.X-kk*config.waveOffset.X) * config.waveRange.X + pos.Y += sin(time*config.waveSpeed.Y-kk*config.waveOffset.Y) * config.waveRange.Y + pos.Z += sin(time*config.waveSpeed.Z-kk*config.waveOffset.Z) * config.waveRange.Z + } + + vec := rl.Vector3{ + X: pos.X + textOffsetX, + Y: pos.Y, + Z: pos.Z + textOffsetY, + } + drawTextCodepoint3D(font, codepoint, vec, fontSize, backface, tint) + } + + textOffsetX += getTextWidth(font, index, fontSpacing, scale) + } + + i += codepointByteCount // Move text bytes counter to next codepoint + } +} + +// measureTextWave3D measures a text in 3D ignoring the `~~` chars. +func measureTextWave3D(font rl.Font, text string, fontSize, fontSpacing, lineSpacing float32) rl.Vector3 { + length := int32(len(text)) + var tempLen, lenCounter int32 // Used to count longer text line num chars + + var ( + tempTextWidth float32 = 0.0 // Used to count longer text line width + scale = fontSize / float32(font.BaseSize) + textHeight = scale + textWidth float32 = 0.0 + ) + + var letter, index int32 // Current character and Index position in sprite font + + for i := int32(0); i < length; i++ { + lenCounter++ + var next int32 + + letter, next = getCodepoint(text, i) + index = rl.GetGlyphIndex(font, letter) + + // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all the bad bytes using the '?' symbol so to not skip any we set next = 1 + if letter == 0x3f { + next = 1 + } + i += next - 1 + + if letter != 0 && letter != '\n' { + r, _ := getCodepoint(text, i+1) + if letter == '~' && r == '~' { + i++ + } else { + textWidth += getTextWidth(font, index, fontSpacing, scale) + } + } else { + if tempTextWidth < textWidth { + tempTextWidth = textWidth + } + lenCounter = 0 + textWidth = 0.0 + textHeight += scale + lineSpacing/float32(font.BaseSize)*scale + } + + if tempLen < lenCounter { + tempLen = lenCounter + } + } + + if tempTextWidth < textWidth { + tempTextWidth = textWidth + } + + vec := rl.Vector3{ + X: tempTextWidth + float32(tempLen-1)*fontSpacing/float32(font.BaseSize)*scale, // Adds chars spacing to measure + Y: 0.25, + Z: textHeight, + } + + return vec +} + +// generateRandomColor generates a nice color with a random hue +func generateRandomColor(s, v float32) rl.Color { + const Phi = float64(0.618033988749895) // Golden ratio conjugate + h := float64(rl.GetRandomValue(0, 360)) + h = math.Mod(h+h*Phi, 360.0) + return rl.ColorFromHSV(float32(h), s, v) +} + +// getCodepoint returns the rune starting at index, plus the length of that rune in bytes +func getCodepoint(s string, index int32) (rune, int32) { + if index == int32(len(s)) { + return 0, 0 + } + r := []rune(s[index:]) + return r[0], int32(utf8.RuneLen(r[0])) +} + +// sin is just a convenience function to avoid a bunch of type conversions +func sin(value float32) float32 { + return float32(math.Sin(float64(value))) +} + +func getTextWidth(font rl.Font, index int32, spacing, scale float32) float32 { + glyphs := unsafe.Slice(font.Chars, font.CharsCount) + if glyphs[index].AdvanceX == 0 { + recs := unsafe.Slice(font.Recs, font.CharsCount) + return (recs[index].Width + spacing) / float32(font.BaseSize) * scale + } else { + return (float32(glyphs[index].AdvanceX) + spacing) / float32(font.BaseSize) * scale + } +} diff --git a/examples/text/draw_3d/resources/shaders/glsl330/alpha_discard.fs b/examples/text/draw_3d/resources/shaders/glsl330/alpha_discard.fs new file mode 100644 index 0000000..d2134a6 --- /dev/null +++ b/examples/text/draw_3d/resources/shaders/glsl330/alpha_discard.fs @@ -0,0 +1,19 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +void main() +{ + vec4 texelColor = texture(texture0, fragTexCoord); + if (texelColor.a == 0.0) discard; + finalColor = texelColor * fragColor * colDiffuse; +} From 9108b3b7b0d81c39f667bb3aa9d2446536f2b1e6 Mon Sep 17 00:00:00 2001 From: Per Hultqvist Date: Sun, 10 Nov 2024 16:06:52 +0100 Subject: [PATCH 144/278] New example: text/codepoints_loading --- examples/text/codepoints_loading/main.go | 108 ++++++++++++++++++ .../resources/DotGothic16-Regular.ttf | Bin 0 -> 2026816 bytes 2 files changed, 108 insertions(+) create mode 100644 examples/text/codepoints_loading/main.go create mode 100644 examples/text/codepoints_loading/resources/DotGothic16-Regular.ttf diff --git a/examples/text/codepoints_loading/main.go b/examples/text/codepoints_loading/main.go new file mode 100644 index 0000000..8e78a4a --- /dev/null +++ b/examples/text/codepoints_loading/main.go @@ -0,0 +1,108 @@ +/******************************************************************************************* +* +* raylib [text] example - Codepoints loading +* +* Example originally created with raylib 4.2, last time updated with raylib 2.5 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2022-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +const ( + screenWidth = 800 + screenHeight = 450 +) + +func main() { + rl.InitWindow(screenWidth, screenHeight, "raylib [text] example - codepoints loading") + + // Text to be displayed, must be UTF-8 (save this code file as UTF-8) + // NOTE: It can contain all the required text for the game, + // this text will be scanned to get all the required codepoints + text := "いろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす" + + // Get codepoints from text + allCodepoints := []rune(text) + + // Removed duplicate codepoints to generate smaller font atlas + codepoints := CodepointRemoveDuplicates(allCodepoints) + codepointsCount := len(codepoints) + + // Load font containing all the provided codepoint glyphs + // A texture font atlas is automatically generated + font := rl.LoadFontEx("resources/DotGothic16-Regular.ttf", 36, codepoints, int32(codepointsCount)) + + // Set bi-linear scale filter for better font scaling + rl.SetTextureFilter(font.Texture, rl.FilterBilinear) + // Set line spacing for multiline text (when line breaks are included '\n') + rl.SetTextLineSpacing(20) + + showFontAtlas := false + + rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second + + // Main game loop + for !rl.WindowShouldClose() { // Detect window close button or ESC key + // Update + if rl.IsKeyPressed(rl.KeySpace) { + showFontAtlas = !showFontAtlas + } + + // Draw + rl.BeginDrawing() + rl.ClearBackground(rl.RayWhite) + + rl.DrawRectangle(0, 0, screenWidth, 70, rl.Black) + msg := fmt.Sprintf("Total codepoints contained in provided text: %d", len(allCodepoints)) + rl.DrawText(msg, 10, 10, 20, rl.Green) + msg = fmt.Sprintf("Total codepoints required for font atlas (duplicates excluded): %d", codepointsCount) + rl.DrawText(msg, 10, 40, 20, rl.Green) + + if showFontAtlas { + // Draw generated font texture atlas containing provided codepoints + rl.DrawTexture(font.Texture, 150, 100, rl.Black) + rl.DrawRectangleLines(150, 100, font.Texture.Width, font.Texture.Height, rl.Black) + } else { + // Draw provided text with loaded font, containing all required codepoint glyphs + pos := rl.Vector2{ + X: 160, + Y: 110, + } + rl.DrawTextEx(font, text, pos, 48, 5, rl.Black) + } + + msg = "Press SPACE to toggle font atlas view!" + rl.DrawText(msg, 10, screenHeight-30, 20, rl.Gray) + + rl.EndDrawing() + } + + // De-Initialization + rl.UnloadFont(font) // Unload font + rl.CloseWindow() // Close window and OpenGL context +} + +// CodepointRemoveDuplicates removes codepoint duplicates if requested +func CodepointRemoveDuplicates[T comparable](sliceList []T) []T { + allKeys := make(map[T]bool) + var list []T + + for _, item := range sliceList { + if _, value := allKeys[item]; !value { + allKeys[item] = true + list = append(list, item) + } + } + + return list +} diff --git a/examples/text/codepoints_loading/resources/DotGothic16-Regular.ttf b/examples/text/codepoints_loading/resources/DotGothic16-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..18b0c1e736970f4f495be54487474d9aa5da66b0 GIT binary patch literal 2026816 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

P*yaE+|Q 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%0AR~}~Pv}SBJJiO6 zBj~mH_pGojq{-j*b#O4hw`h7RvG)(Pk;h&c#UMiifDXQ~_R{~u?w2pkw>`aPF$_%W zPk}SEDBkC5YtOm~z1hjM0EiglfF~v#C?60YkBCoU*wvva;}DSgIW%c~utaFZCXM%G zY))bG2p;C~{E5Z;-py9N$+mT~Kkfb8>`$BTOT`>UvwJ{CMrWCvrL<8+QvP5oOt=X} zm}ptub-XN|V+4rHt9T*J?3F!h4AyIF7f8axX>Wj}F8hPg zF|<1xZoRlkgYh8lFTjQiabLo{5dR5CQE0f_F#+fEQAuaJhrTRA}fO3CNn#9K_K4ppQSMx zs*z=Q&`oH+a^||IS=b;ZQY9Of#2FsVTTLvn!qRm5(npC#*gLwBly|1z4D+Wh;@{A3 zfQbNh+%C8KJKl{&0E=*!y_@-KiN<%!mAvXJ_sLp(xRp5^r+;DK95-8&Xy=vkG@%Fl zBQp~AJ;9MlSK{dn3jxJl3_q2}C}M z+;o$TQdHs4#ilX=Cg0M0e}a=M0y5W5ZEVm_B~2&I-Shd{i2&KwFNeO9j4S4d!8=>A zBzz4<7O#LA1CDF46u6T^D6wD`M9U>^!2vfx*Kh7vJG8Fbp1w7#U-CP=aR@V7!geq2 zZ#18>a7piL8Ej>w%lL#aX* zLUAr@#wl`yC&!sWO9LqGQ`V<&p5OvwQh!qJZ=)(0$5P-{suvde6N=S~{=XYnn zzh$us77*pgjyE=7P1pT+8@^YI#>k=Hd)@nqf%zROF>FOGhW`coI|ZC_3Z(|8&?yc& ziD{0{3_GX1Ongjq1?*~|&U+Mm|52m{WpUJ5iRv3Q zvo(skRDF^8b1Mt9gXf&uWJo3E)~j3>YIsz}+*VQH>d4QN7FE*pPDI}}&+l&!4@>y1 zuJlI~5J*fSI*o8qh`jeF02*{WoV|;bevDkk-%Xn55BAnx#CJms9$TjtV8gt2$Yp}J z*C0@fCoZ>^zYGh=piq@8tvoUyNyrro(^1#ZPbXdz^S%?(yOwzSrN?h`32)=w5&JrL5S2=zYnM_+9$GQ0QQH zenVygm(m?nfBfwH3zrk|AlMAx!2!FX|4N+>Xb+n)!5#!)p_>?tb+TT^+l-8TnUgqR zY8MfJ2t)wlYkaD&ECUXKl`Nb`KRbOK7`U7S&p*g&hzbLHn1VK;RYjjDnl(AZ#x