diff options
| author | Uneven Prankster <unevenprankster@protonmail.com> | 2023-11-16 21:12:27 -0300 |
|---|---|---|
| committer | Uneven Prankster <unevenprankster@protonmail.com> | 2023-11-16 21:12:27 -0300 |
| commit | 2bbf92ad5ae7708bf18ac7ef333e9a979d8d1bde (patch) | |
| tree | c9d22bb0d73d9cc0c8586e4d31c93a561ea8e910 | |
| parent | 1c0cc775732201f4c4d3ee0d6772be786b3b4aa1 (diff) | |
Working so hard like a soldiermain
Can't afford a thing on TV
142 files changed, 14587 insertions, 4846 deletions
diff --git a/assets/UP_Intro.ogg b/assets/UP_Intro.ogg Binary files differnew file mode 100644 index 0000000..4b0bc3c --- /dev/null +++ b/assets/UP_Intro.ogg diff --git a/assets/berry-rotunda.ttf b/assets/berry-rotunda.ttf Binary files differdeleted file mode 100644 index 679276e..0000000 --- a/assets/berry-rotunda.ttf +++ /dev/null diff --git a/assets/berry-rotunda.fnt b/assets/fonts/berry-rotunda.fnt index 624cde0..624cde0 100644 --- a/assets/berry-rotunda.fnt +++ b/assets/fonts/berry-rotunda.fnt diff --git a/assets/berry-rotunda_0.png b/assets/fonts/berry-rotunda_0.png Binary files differindex 3810d6e..3810d6e 100644 --- a/assets/berry-rotunda_0.png +++ b/assets/fonts/berry-rotunda_0.png diff --git a/assets/fonts/cell-provider.fnt b/assets/fonts/cell-provider.fnt new file mode 100644 index 0000000..ca400aa --- /dev/null +++ b/assets/fonts/cell-provider.fnt @@ -0,0 +1,99 @@ +info face="CellProvider" size=-16 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=1,1 outline=0 +common lineHeight=15 base=12 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4 +page id=0 file="cell-provider_0.png" +chars count=95 +char id=32 x=16 y=32 width=3 height=15 xoffset=-1 yoffset=0 xadvance=3 page=0 chnl=15 +char id=33 x=24 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=34 x=125 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=35 x=61 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15 +char id=36 x=91 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15 +char id=37 x=0 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15 +char id=38 x=69 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15 +char id=39 x=27 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=40 x=0 y=32 width=3 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15 +char id=41 x=4 y=32 width=3 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15 +char id=42 x=149 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=43 x=77 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15 +char id=44 x=30 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=45 x=167 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=46 x=39 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=47 x=173 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=48 x=179 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=49 x=239 y=16 width=4 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15 +char id=50 x=185 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=51 x=191 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=52 x=197 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=53 x=203 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=54 x=155 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=55 x=209 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=56 x=215 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=57 x=221 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=58 x=48 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=59 x=33 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=60 x=227 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=61 x=233 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=62 x=239 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=63 x=245 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=64 x=12 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15 +char id=65 x=0 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=66 x=6 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=67 x=12 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=68 x=18 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=69 x=24 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=70 x=30 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=71 x=36 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=72 x=42 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=73 x=234 y=16 width=4 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15 +char id=74 x=48 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=75 x=54 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=76 x=60 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=77 x=24 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15 +char id=78 x=84 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15 +char id=79 x=66 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=80 x=72 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=81 x=78 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=82 x=84 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=83 x=90 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=84 x=98 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15 +char id=85 x=96 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=86 x=102 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=87 x=52 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15 +char id=88 x=108 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=89 x=105 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15 +char id=90 x=114 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=91 x=12 y=32 width=3 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15 +char id=92 x=120 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=93 x=20 y=32 width=3 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15 +char id=94 x=126 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=95 x=132 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=96 x=8 y=32 width=3 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15 +char id=97 x=138 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=98 x=144 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=99 x=150 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=100 x=156 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=101 x=162 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=102 x=168 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=103 x=174 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=104 x=216 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=105 x=36 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=106 x=251 y=0 width=4 height=15 xoffset=-2 yoffset=0 xadvance=3 page=0 chnl=15 +char id=107 x=180 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=108 x=42 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=109 x=43 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15 +char id=110 x=186 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=111 x=192 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=112 x=198 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=113 x=204 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=114 x=210 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=115 x=161 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=116 x=222 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=117 x=228 y=16 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=118 x=119 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=119 x=34 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15 +char id=120 x=131 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=121 x=137 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=122 x=143 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15 +char id=123 x=244 y=16 width=4 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15 +char id=124 x=45 y=32 width=2 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15 +char id=125 x=249 y=16 width=4 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15 +char id=126 x=112 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15 diff --git a/assets/fonts/cell-provider_0.png b/assets/fonts/cell-provider_0.png Binary files differnew file mode 100644 index 0000000..83d8e94 --- /dev/null +++ b/assets/fonts/cell-provider_0.png diff --git a/assets/models/amanita.glb b/assets/models/amanita.glb Binary files differnew file mode 100644 index 0000000..97d7f45 --- /dev/null +++ b/assets/models/amanita.glb diff --git a/assets/models/amanita.m3d b/assets/models/amanita.m3d Binary files differnew file mode 100644 index 0000000..15abfa9 --- /dev/null +++ b/assets/models/amanita.m3d diff --git a/assets/models/amanita.png b/assets/models/amanita.png Binary files differnew file mode 100644 index 0000000..e193d08 --- /dev/null +++ b/assets/models/amanita.png diff --git a/assets/shaders/ntsc.fs b/assets/shaders/ntsc.fs new file mode 100644 index 0000000..871565b --- /dev/null +++ b/assets/shaders/ntsc.fs @@ -0,0 +1,99 @@ +#version 330 + +in vec2 fragTexCoord; +uniform sampler2D texture0; + +vec3 rgb2yiq(vec3 c){ + return vec3( + (0.2989 * c.x + 0.5959 * c.y + 0.2115 * c.z), + (0.5870 * c.x - 0.2744 * c.y - 0.5229 * c.z), + (0.1140 * c.x - 0.3216 * c.y + 0.3114 * c.z) + ); +} +vec3 yiq2rgb(vec3 c){ + return vec3( + (1.0 * c.x + 1.0 * c.y + 1.0 * c.z), + (0.956 * c.x - 0.2720 * c.y - 1.1060 * c.z), + (0.6210 * c.x - 0.6474 * c.y + 1.7046 * c.z) + ); +} + +vec2 Circle(float Start, float Points, float Point){ + float Rad = (3.141592 * 2.0 * (1.0 / Points)) * (Point + Start); + return vec2(-(.3+Rad), cos(Rad)); +} + +vec3 Blur(vec2 uv, float f, float d, sampler2D iChannel0){ + vec2 PixelOffset = vec2(d, 0); + + float Start = 2.0 / 14.0; + vec2 Scale = 0.66 * 3.0 * 2.0 * PixelOffset.xy; + + vec3 N0 = texture(iChannel0, uv + Circle(Start, 14.0, 0.0) * Scale).rgb; + vec3 N1 = texture(iChannel0, uv + Circle(Start, 14.0, 1.0) * Scale).rgb; + vec3 N2 = texture(iChannel0, uv + Circle(Start, 14.0, 2.0) * Scale).rgb; + vec3 N3 = texture(iChannel0, uv + Circle(Start, 14.0, 3.0) * Scale).rgb; + vec3 N4 = texture(iChannel0, uv + Circle(Start, 14.0, 4.0) * Scale).rgb; + vec3 N5 = texture(iChannel0, uv + Circle(Start, 14.0, 5.0) * Scale).rgb; + vec3 N6 = texture(iChannel0, uv + Circle(Start, 14.0, 6.0) * Scale).rgb; + vec3 N7 = texture(iChannel0, uv + Circle(Start, 14.0, 7.0) * Scale).rgb; + vec3 N8 = texture(iChannel0, uv + Circle(Start, 14.0, 8.0) * Scale).rgb; + vec3 N9 = texture(iChannel0, uv + Circle(Start, 14.0, 9.0) * Scale).rgb; + vec3 N10 = texture(iChannel0, uv + Circle(Start, 14.0, 10.0) * Scale).rgb; + vec3 N11 = texture(iChannel0, uv + Circle(Start, 14.0, 11.0) * Scale).rgb; + vec3 N12 = texture(iChannel0, uv + Circle(Start, 14.0, 12.0) * Scale).rgb; + vec3 N13 = texture(iChannel0, uv + Circle(Start, 14.0, 13.0) * Scale).rgb; + vec3 N14 = texture(iChannel0, uv).rgb; + + vec3 clr = N14; + float W = 1.0 / 15.0; + + clr = + (N0 * W) + + (N1 * W) + + (N2 * W) + + (N3 * W) + + (N4 * W) + + (N5 * W) + + (N6 * W) + + (N7 * W) + + (N8 * W) + + (N9 * W) + + (N10 * W) + + (N11 * W) + + (N12 * W) + + (N13 * W) + + (N14 * W); + + return clr; +} + +out vec4 finalColor; + +void main(){ + vec2 uv = gl_FragCoord.xy / vec2(textureSize(texture0, 0)); + vec3 color; + + // Apply blur + float d = 0.051; + float c = 0.002 * d; + + color.xyz = Blur(uv, 0.0, c + c * (uv.x), texture0); + float y = rgb2yiq(color.xyz).r; + + uv.x += 0.01 * d; + c *= 6.0; + color.xyz = Blur(uv, 0.333, c, texture0); + float i = rgb2yiq(color.xyz).g; + + uv.x += 0.005 * d; + + c *= 2.50; + color.xyz = Blur(uv, 0.666, c + c * (-uv.x), texture0); + float q = rgb2yiq(color.xyz).b; + + color.xyz = yiq2rgb(vec3(y, i, q)); + color.xyz *= smoothstep(1.0, 0.999, uv.x - .1); + + finalColor = vec4(color, 1.0); +}
\ No newline at end of file diff --git a/assets/shaders/ps1frag.fs b/assets/shaders/ps1frag.fs new file mode 100644 index 0000000..efdb0b8 --- /dev/null +++ b/assets/shaders/ps1frag.fs @@ -0,0 +1,18 @@ +#version 330 + +noperspective in vec2 fragTexCoord; +noperspective in vec3 fragColor; + +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +out vec4 finalColor; + +void main() +{ + vec4 texelColor = texture(texture0, fragTexCoord); + if(texelColor.a < 0.8) + discard; + + finalColor = texelColor*colDiffuse*vec4(fragColor, 1.0); +}
\ No newline at end of file diff --git a/assets/shaders/ps1vert.vs b/assets/shaders/ps1vert.vs new file mode 100644 index 0000000..7d8d506 --- /dev/null +++ b/assets/shaders/ps1vert.vs @@ -0,0 +1,26 @@ +#version 330 + +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +uniform mat4 mvp; + +noperspective out vec2 fragTexCoord; +noperspective out vec3 fragColor; + +void main() +{ + vec2 res = vec2(160.0, 120.0); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor.rgb; + + vec4 pop = mvp*vec4(vertexPosition, 1.0); + gl_Position = pop; + gl_Position.xyz = pop.xyz / pop.w; + gl_Position.xy = floor(res * gl_Position.xy) / res; + gl_Position.xyz *= pop.w; + + fragColor = mix(fragColor, vec3(0.0), clamp(smoothstep(20.0, 24.0, length(pop.xyz)), 0.0, 1.0)); +}
\ No newline at end of file diff --git a/assets/shaders/psx_filter.fs b/assets/shaders/psx_filter.fs new file mode 100644 index 0000000..21eaada --- /dev/null +++ b/assets/shaders/psx_filter.fs @@ -0,0 +1,38 @@ +#version 330 + +uniform sampler2D texture0; + +in vec2 fragTexCoord; + +out vec4 finalColor; + +const float neareight = 255.0; +vec3 dither(vec3 col, uvec2 fc) +{ + const int mat[16] = int[16] ( + -4, 0, -3, 1, + 2, -2, 3, -1, + -3, 1, -4, 0, + 3, -1, 2, -2 + ); + + ivec3 uncol = ivec3(col * neareight) + mat[(fc.y & uint(3)) * uint(4) + (fc.x & uint(3))]; + return vec3(uncol) / neareight; +} + +vec3 band_color(vec3 lol) +{ + ivec3 res = ivec3(clamp(lol, 0.0, 1.0) * neareight) & ivec3(0xFF); + ivec3 ires = res >> 3; + ivec3 dres = (ires >> 2) & ivec3(7); + res = (ires << 3) | dres; + return vec3(res) / neareight; +} + +void main() +{ + vec4 texelColor = texture(texture0, fragTexCoord); + texelColor.rgb = band_color(dither(texelColor.rgb, uvec2(gl_FragCoord.xy))); + + finalColor = texelColor; +}
\ No newline at end of file diff --git a/assets/shaders/rvm.fs b/assets/shaders/rvm.fs new file mode 100644 index 0000000..3f94c52 --- /dev/null +++ b/assets/shaders/rvm.fs @@ -0,0 +1,208 @@ +#version 330 + +in vec2 fragTexCoord; + +uniform sampler2D texture0; +uniform vec4 resolution; + +// Horizonal scan blur +// 0.50 := blurry +// 0.75 := default +// 1.00 := blocky +#define INPUT_BLUR 0.5 + +//-------------------------------------------------------------- +// Setup the function which returns gather4 results +// Have to emulate gather4 as ShaderToy doesn't support it +// Gather 4 ordering +// W Z +// X Y +vec4 RvmR4F(sampler2D tex, vec2 uv){ + vec2 px = vec2(1.0) / vec2(textureSize(tex, 0)); + px *= 0.5; + + vec4 sample; + sample.w = texture(tex, uv.xy + vec2(-px.x,-px.y)).r; + sample.z = texture(tex, uv.xy + vec2( px.x,-px.y)).r; + sample.x = texture(tex, uv.xy + vec2(-px.x, px.y)).r; + sample.y = texture(tex, uv.xy + vec2( px.x, px.y)).r; + + return sample; +} +// +vec4 RvmG4F(sampler2D tex, vec2 uv){ + vec2 px = vec2(1.0) / vec2(textureSize(tex, 0)); + px *= 0.5; + + vec4 sample; + sample.w = texture(tex, uv.xy + vec2(-px.x,-px.y)).g; + sample.z = texture(tex, uv.xy + vec2( px.x,-px.y)).g; + sample.x = texture(tex, uv.xy + vec2(-px.x, px.y)).g; + sample.y = texture(tex, uv.xy + vec2( px.x, px.y)).g; + + return sample; +} +// +vec4 RvmB4F(sampler2D tex, vec2 uv){ + vec2 px = vec2(1.0) / vec2(textureSize(tex, 0)); + px *= 0.5; + + vec4 sample; + sample.w = texture(tex, uv.xy + vec2(-px.x,-px.y)).b; + sample.z = texture(tex, uv.xy + vec2( px.x,-px.y)).b; + sample.x = texture(tex, uv.xy + vec2(-px.x, px.y)).b; + sample.y = texture(tex, uv.xy + vec2( px.x, px.y)).b; + + return sample; +} + +#define RVM_DARK 1 +#define RVM_SCAN_DIV 3.0 +#define RVM_SCAN_MAX (8.0/15.0) +#define RVM_SCAN_MIN (RVM_SCAN_DIV*RVM_SCAN_MAX) +#define RVM_SCAN_SIZ (RVM_SCAN_MAX-RVM_SCAN_MIN) + +vec2 RvmPolyF2(vec2 x){ + x=clamp(-x*x+vec2(1.0,1.0), 0.0, 1.0); + return x*x; +} + +vec3 rvm_func( +sampler2D tex, +//-------------------------------------------------------------- + // SV_POSITION, fragCoord.xy, etc + vec2 ipos, +//-------------------------------------------------------------- + // inputSize / outputSize (in pixels) + vec2 inputSizeDivOutputSize, +//-------------------------------------------------------------- + // 0.5 * inputSize (in pixels) + vec2 halfInputSize, +//-------------------------------------------------------------- + // 1.0 / inputSize (in pixels) + vec2 rcpInputSize, +//-------------------------------------------------------------- + // 2.0 / outputSize (in pixels) + vec2 twoDivOutputSize, +//-------------------------------------------------------------- + // inputSize.y + float inputHeight, +//-------------------------------------------------------------- + // Warp scanlines + // 0.0 = no warp + // 1.0/64.0 = light warping + // 1.0/32.0 = more warping + // Want x and y warping to be different (based on aspect) + vec2 warp, +//-------------------------------------------------------------- + // Control horizontal blur + // 0.50 := blurry + // 0.75 := default + // 1.00 := blocky + float blur, + // Derived constant {0.5*blur,-0.5*blur,-1.5*blur,-2.5*blur} + vec4 blur4){ + // Optional apply warp + vec2 pos; + pos=ipos*inputSizeDivOutputSize; + pos -= (halfInputSize * 2.0) / (resolution.zw / resolution.xy); + + // Get to center for first gather 4 + // W Z + // X Y + // W Z + // X Y + vec2 g=floor(pos+vec2(-0.5,-1.5))+vec2(1.0); + vec2 gp=g*rcpInputSize; + g.x-=float(0.5); + + // 2x4 sampled footprint + // W Z |s + // X Y |s + // W Z :t + // X Y :t + vec4 colRS=RvmR4F(tex, gp); + vec4 colGS=RvmG4F(tex, gp); + vec4 colBS=RvmB4F(tex, gp); + gp.y+=float(2.0*rcpInputSize.y); + vec4 colRT=RvmR4F(tex, gp); + vec4 colGT=RvmG4F(tex, gp); + vec4 colBT=RvmB4F(tex, gp); + + // Vertical + float offB=float(pos.y-g.y); + vec2 offS=vec2(offB,offB)*vec2(blur)+blur4.xy; + vec2 offT=vec2(offB,offB)*vec2(blur)+blur4.zw; + + vec2 horS=RvmPolyF2(offS); + vec2 horT=RvmPolyF2(offT); + + // Get kernel totals and then rcp + vec2 hor0=horS+horT; + float horD=1.0 / (hor0.x+hor0.y); + + //horD*=float(vin); + + // Apply vertical filter + vec2 colRL=colRS.wz*horS.xx+colRS.xy*horS.yy+ + colRT.wz*horT.xx+colRT.xy*horT.yy; + vec2 colGL=colGS.wz*horS.xx+colGS.xy*horS.yy+ + colGT.wz*horT.xx+colGT.xy*horT.yy; + vec2 colBL=colBS.wz*horS.xx+colBS.xy*horS.yy+ + colBT.wz*horT.xx+colBT.xy*horT.yy; + + // Normalize by kernel total + colRL*=vec2(horD); + colGL*=vec2(horD); + colBL*=vec2(horD); + + float offX=float(pos.x-g.x); + vec2 scnL=vec2(float(1.0)-offX,offX); + // Apply scan + colRL*=scnL; + colGL*=scnL; + colBL*=scnL; + // Merge contribution from both nearest lines + vec3 col; + col.r=colRL.x+colRL.y; + col.g=colGL.x+colGL.y; + col.b=colBL.x+colBL.y; + + // Slot mask + float lim=float(1.0/((3.0/12.0)+(9.0/12.0)*RVM_DARK)); + if(fract(ipos.x*float(1.0/6.0))>float(0.5)) + ipos.y+=float(2.0); + ipos.y=fract(ipos.y*float(1.0/4.0)); + + vec3 colD=col*col; + + colD*=RVM_DARK; + + vec3 amp= vec3(1.0) / vec3( + vec3(lim*3.0/12.0)+vec3(lim*9.0/12.0)*col); + ipos.x=fract(ipos.x*float(1.0/3.0)); + + col*=amp;colD*=amp; + if(ipos.y>float(1.0/4.0)){ + if( ipos.x<float(1.0/3.0)){colD.r=col.r;} + else if(ipos.x<float(2.0/3.0)){colD.g=col.g;} + else {colD.b=col.b;} + } + return colD; +//-------------------------------------------------------------- + return col; +} + +out vec4 finalColor; + +void main() { + vec2 input_size = vec2(textureSize(texture0, 0)); + vec2 out_size = resolution.zw; + + vec3 color = rvm_func(texture0, + gl_FragCoord.xy, input_size / out_size, + input_size * 0.5, 1.0 / input_size, 2.0 / out_size, input_size.y, vec2(1.0/48.0,1.0/24.0), INPUT_BLUR, + vec4(0.5*INPUT_BLUR,-0.5*INPUT_BLUR,-1.5*INPUT_BLUR,-2.5*INPUT_BLUR)); + + finalColor = vec4(color, 1.0); +} diff --git a/assets/src/gunner.h b/assets/src/gunner.h deleted file mode 100644 index be1b32e..0000000 --- a/assets/src/gunner.h +++ /dev/null @@ -1,223 +0,0 @@ -#pragma once - -// Defines // - -typedef struct{ - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; -}Color; - -#define WHITE (Color){255, 255, 255, 255} -#define BLACK (Color){0, 0, 0, 255} - -typedef char i8; -typedef unsigned char u8; - -typedef short i16; -typedef unsigned short u16; - -typedef int i32; -typedef long long i64; - -typedef unsigned int u32; -typedef unsigned long long u64; - -typedef float f32; -typedef double f64; - -// 24.8 format -typedef i32 fx32; -#define FIXED_POINT_BITS 8 -#define FIXED_POINT_ONE (1 << FIXED_POINT_BITS) -#define TO_FIXED(x) ((fx32)(x) << FIXED_POINT_BITS) -#define FROM_FIXED(x) ((x) >> FIXED_POINT_BITS) -#define FP_TO_FIXED(x) (fx32)((x) * FIXED_POINT_ONE) - -typedef struct{ - fx32 x, y; -}vec2; - -typedef i8 b32; -#define false 0 -#define true 1 - -typedef enum { - KEY_NULL = 0, // Key: NULL, used for no key pressed - // Alphanumeric keys - KEY_APOSTROPHE = 39, // Key: ' - KEY_COMMA = 44, // Key: , - KEY_MINUS = 45, // Key: - - KEY_PERIOD = 46, // Key: . - KEY_SLASH = 47, // Key: / - KEY_ZERO = 48, // Key: 0 - KEY_ONE = 49, // Key: 1 - KEY_TWO = 50, // Key: 2 - KEY_THREE = 51, // Key: 3 - KEY_FOUR = 52, // Key: 4 - KEY_FIVE = 53, // Key: 5 - KEY_SIX = 54, // Key: 6 - KEY_SEVEN = 55, // Key: 7 - KEY_EIGHT = 56, // Key: 8 - KEY_NINE = 57, // Key: 9 - KEY_SEMICOLON = 59, // Key: ; - KEY_EQUAL = 61, // Key: = - KEY_A = 65, // Key: A | a - KEY_B = 66, // Key: B | b - KEY_C = 67, // Key: C | c - KEY_D = 68, // Key: D | d - KEY_E = 69, // Key: E | e - KEY_F = 70, // Key: F | f - KEY_G = 71, // Key: G | g - KEY_H = 72, // Key: H | h - KEY_I = 73, // Key: I | i - KEY_J = 74, // Key: J | j - KEY_K = 75, // Key: K | k - KEY_L = 76, // Key: L | l - KEY_M = 77, // Key: M | m - KEY_N = 78, // Key: N | n - KEY_O = 79, // Key: O | o - KEY_P = 80, // Key: P | p - KEY_Q = 81, // Key: Q | q - KEY_R = 82, // Key: R | r - KEY_S = 83, // Key: S | s - KEY_T = 84, // Key: T | t - KEY_U = 85, // Key: U | u - KEY_V = 86, // Key: V | v - KEY_W = 87, // Key: W | w - KEY_X = 88, // Key: X | x - KEY_Y = 89, // Key: Y | y - KEY_Z = 90, // Key: Z | z - KEY_LEFT_BRACKET = 91, // Key: [ - KEY_BACKSLASH = 92, // Key: '\' - KEY_RIGHT_BRACKET = 93, // Key: ] - KEY_GRAVE = 96, // Key: ` - // Function keys - KEY_SPACE = 32, // Key: Space - KEY_ESCAPE = 256, // Key: Esc - KEY_ENTER = 257, // Key: Enter - KEY_TAB = 258, // Key: Tab - KEY_BACKSPACE = 259, // Key: Backspace - KEY_INSERT = 260, // Key: Ins - KEY_DELETE = 261, // Key: Del - KEY_RIGHT = 262, // Key: Cursor right - KEY_LEFT = 263, // Key: Cursor left - KEY_DOWN = 264, // Key: Cursor down - KEY_UP = 265, // Key: Cursor up - KEY_PAGE_UP = 266, // Key: Page up - KEY_PAGE_DOWN = 267, // Key: Page down - KEY_HOME = 268, // Key: Home - KEY_END = 269, // Key: End - KEY_CAPS_LOCK = 280, // Key: Caps lock - KEY_SCROLL_LOCK = 281, // Key: Scroll down - KEY_NUM_LOCK = 282, // Key: Num lock - KEY_PRINT_SCREEN = 283, // Key: Print screen - KEY_PAUSE = 284, // Key: Pause - KEY_F1 = 290, // Key: F1 - KEY_F2 = 291, // Key: F2 - KEY_F3 = 292, // Key: F3 - KEY_F4 = 293, // Key: F4 - KEY_F5 = 294, // Key: F5 - KEY_F6 = 295, // Key: F6 - KEY_F7 = 296, // Key: F7 - KEY_F8 = 297, // Key: F8 - KEY_F9 = 298, // Key: F9 - KEY_F10 = 299, // Key: F10 - KEY_F11 = 300, // Key: F11 - KEY_F12 = 301, // Key: F12 - KEY_LEFT_SHIFT = 340, // Key: Shift left - KEY_LEFT_CONTROL = 341, // Key: Control left - KEY_LEFT_ALT = 342, // Key: Alt left - KEY_LEFT_SUPER = 343, // Key: Super left - KEY_RIGHT_SHIFT = 344, // Key: Shift right - KEY_RIGHT_CONTROL = 345, // Key: Control right - KEY_RIGHT_ALT = 346, // Key: Alt right - KEY_RIGHT_SUPER = 347, // Key: Super right - KEY_KB_MENU = 348, // Key: KB menu - // Keypad keys - KEY_KP_0 = 320, // Key: Keypad 0 - KEY_KP_1 = 321, // Key: Keypad 1 - KEY_KP_2 = 322, // Key: Keypad 2 - KEY_KP_3 = 323, // Key: Keypad 3 - KEY_KP_4 = 324, // Key: Keypad 4 - KEY_KP_5 = 325, // Key: Keypad 5 - KEY_KP_6 = 326, // Key: Keypad 6 - KEY_KP_7 = 327, // Key: Keypad 7 - KEY_KP_8 = 328, // Key: Keypad 8 - KEY_KP_9 = 329, // Key: Keypad 9 - KEY_KP_DECIMAL = 330, // Key: Keypad . - KEY_KP_DIVIDE = 331, // Key: Keypad / - KEY_KP_MULTIPLY = 332, // Key: Keypad * - KEY_KP_SUBTRACT = 333, // Key: Keypad - - KEY_KP_ADD = 334, // Key: Keypad + - KEY_KP_ENTER = 335, // Key: Keypad Enter - KEY_KP_EQUAL = 336, // Key: Keypad = - // Android key buttons - KEY_BACK = 4, // Key: Android back button - KEY_MENU = 82, // Key: Android menu button - KEY_VOLUME_UP = 24, // Key: Android volume up button - KEY_VOLUME_DOWN = 25 // Key: Android volume down button -} KeyboardKey; - -// Texture // - -int load_new_tex(const char* path); - -void draw_texture(int idx, int x, int y); - -void unload_tex(int idx); - -void unload_active_textures(void); - -// Shader // - -int load_new_shader(const char* path); - -void set_active_shader(int idx); - -void reset_active_shader(void); - -void unload_shader(int idx); - -void unload_active_shaders(void); - -// Text // - -void draw_text(const char* txt, int x, int y, int size, Color col); - -i32 load_font(const char* path); - -void draw_text_font(i32 idx, const char* text, vec2 pos, fx32 size, Color col); - -// Controller // - -b32 is_key_pressed(i32 btn); -b32 is_key_held(i32 btn); -b32 is_key_released(i32 btn); - -vec2 get_dir_input(void); - -void set_rumble(f32 duration, f32 strength); - -void stop_rumble(void); - -// Random // - -u32 rand_u32(void); - -int rand_range(i32 min, i32 max); - -// Audio // - -i32 load_audio(const char* path); - -void play_audio(i32 idx); - -void load_music(const char* path); - -void play_music(void); - -void set_music_loop(b32 loop); - -void set_music_loop_point(f32 point); diff --git a/assets/src/main.c b/assets/src/main.c deleted file mode 100644 index 0913641..0000000 --- a/assets/src/main.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "gunner.h" - -static int femme = -1; -static int grayscale = -1; -static int berry = -1; -static int night = -1; - -static vec2 position = (vec2){TO_FIXED(32), TO_FIXED(48)}; -static vec2 text_pos = (vec2){TO_FIXED(64), TO_FIXED(16)}; - -void init(void) -{ - femme = load_new_tex("assets/femme.png"); - grayscale = load_new_shader("assets/gs_full.glsl"); - berry = load_font("assets/berry-rotunda.fnt"); - - load_music("assets/wicked_glee.ogg"); - set_music_loop_point(15.73f); - - play_music(); -} - -void update(void) -{ - draw_text_font(berry, "Femme is a cute", text_pos, 24, BLACK); - - vec2 current_input = get_dir_input(); - if(current_input.x != 0 || current_input.y != 0){ - position.x += current_input.x; - position.y += current_input.y; - } - - set_active_shader(grayscale); - draw_texture(femme, FROM_FIXED(position.x), FROM_FIXED(position.y)); - reset_active_shader(); -} - -void exit(void) -{ - -}
\ No newline at end of file @@ -69,7 +69,6 @@ fi ROOT_DIR=$PWD SOURCES="$ROOT_DIR/$SOURCES" RAYLIB_SRC="$ROOT_DIR/$RAYLIB_SRC" -TINYCC_SRC="$ROOT_DIR/tinycc" # Flags COMPILATION_FLAGS="-std=gnu99 -Os -flto=auto -s -D__USE_MINGW_ANSI_STDIO=0 -mno-stack-arg-probe -Xlinker --stack=0x200000,0x200000 @@ -105,13 +104,6 @@ if [ ! -d "$TEMP_DIR" ]; then mkdir -p $TEMP_DIR cd $TEMP_DIR - TCC_DEFINES="-DTCC_TARGET_PE -DTCC_TARGET_X86_64 -DCONFIG_TCC_PREDEFS" - - TCC_VERS=$(cat "$TINYCC_SRC/VERSION") - echo "#define TCC_VERSION \"$TCC_VERS\"" >> "$TINYCC_SRC/config.h" - - $CC -c $TCC_DEFINES $COMPILATION_FLAGS "$TINYCC_SRC/libtcc.c" - RAYLIB_DEFINES="-D_DEFAULT_SOURCE -DPLATFORM_DESKTOP -DGRAPHICS_API_OPENGL_33" RAYLIB_C_FILES="$RAYLIB_SRC/rcore.c $RAYLIB_SRC/rshapes.c $RAYLIB_SRC/rtextures.c $RAYLIB_SRC/rtext.c $RAYLIB_SRC/rmodels.c $RAYLIB_SRC/utils.c $RAYLIB_SRC/raudio.c $RAYLIB_SRC/rglfw.c" RAYLIB_INCLUDE_FLAGS="-I$RAYLIB_SRC -I$RAYLIB_SRC/external/glfw/include" diff --git a/raylib/.github/workflows/codeql.yml b/raylib/.github/workflows/codeql.yml new file mode 100644 index 0000000..d886db7 --- /dev/null +++ b/raylib/.github/workflows/codeql.yml @@ -0,0 +1,134 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: "CodeQL" + +on: + workflow_dispatch: + # push: + # branches: [ "main", "master" ] + pull_request: + branches: '*' + schedule: + - cron: '0 0 * * 1' + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Setup Environment + run: | + sudo apt-get update -qq + sudo apt-get install gcc-multilib + sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPLATFORM=Desktop + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + queries: security-and-quality + + - name: Build + # Execute the build. You can specify a specific target with "--target <NAME>" + run: | + cd build + cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPLATFORM=Desktop + cmake --build . --config $BUILD_TYPE + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" + upload: false + id: step1 + + # Filter out rules with low severity or high false positve rate + # Also filter out warnings in third-party code + - name: Filter out unwanted errors and warnings + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + -**:cpp/path-injection + -**:cpp/world-writable-file-creation + -**:cpp/poorly-documented-function + -**:cpp/potentially-dangerous-function + -**:cpp/use-of-goto + -**:cpp/integer-multiplication-cast-to-long + -**:cpp/comparison-with-wider-type + -**:cpp/leap-year/* + -**:cpp/ambiguously-signed-bit-field + -**:cpp/suspicious-pointer-scaling + -**:cpp/suspicious-pointer-scaling-void + -**:cpp/unsigned-comparison-zero + -**/cmake*/Modules/** + -**/src/external/glfw/** + input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + + - name: Upload CodeQL results to code scanning + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ steps.step1.outputs.sarif-output }} + category: "/language:${{matrix.language}}" + + - name: Upload CodeQL results as an artifact + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: codeql-results + path: ${{ steps.step1.outputs.sarif-output }} + retention-days: 5 diff --git a/raylib/.gitignore b/raylib/.gitignore index fb4865b..559f9f0 100644 --- a/raylib/.gitignore +++ b/raylib/.gitignore @@ -88,6 +88,7 @@ CMakeFiles CMakeScripts Testing cmake_install.cmake +cmake_uninstall.cmake install_manifest.txt compile_commands.json CTestTestfile.cmake diff --git a/raylib/BINDINGS.md b/raylib/BINDINGS.md index e08f8f7..ab1bf6f 100644 --- a/raylib/BINDINGS.md +++ b/raylib/BINDINGS.md @@ -27,20 +27,21 @@ Some people ported raylib to other languages in form of bindings or wrappers to | raylib-freebasic | **4.5** | [FreeBASIC](https://www.freebasic.net/) | MIT | https://github.com/WIITD/raylib-freebasic | | fortran-raylib | **4.5** | [Fortran](https://fortran-lang.org/) | ISC | https://github.com/interkosmos/fortran-raylib | | raylib for Pascal | **4.5** | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | Modified Zlib | https://github.com/tinyBigGAMES/raylib | -| raylib-go | 4.5 | [Go](https://golang.org/) | Zlib | https://github.com/gen2brain/raylib-go | +| raylib-go | **5.0** | [Go](https://golang.org/) | Zlib | https://github.com/gen2brain/raylib-go | | raylib-guile | **auto** | [Guile](https://www.gnu.org/software/guile/) | Zlib | https://github.com/petelliott/raylib-guile | | gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib | | h-raylib | **4.6-dev** | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib | | raylib-hx | 4.2 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx | | hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | MIT | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib | | jaylib | 4.5 | [Janet](https://janet-lang.org/) | MIT | https://github.com/janet-lang/jaylib | -| jaylib | 4.2 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ | +| jaylib | **4.5** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ | | raylib-j | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J | | raylib.jl | 4.2 | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl | | kaylib | 3.7 | [Kotlin/native](https://kotlinlang.org) | ? | https://github.com/electronstudio/kaylib | | KaylibKit | **4.5**| [Kotlin/native](https://kotlinlang.org) | Zlib | https://codeberg.org/Kenta/KaylibKit | | raylib-lua | **4.5** | [Lua](http://www.lua.org/) | ISC | https://github.com/TSnake41/raylib-lua | | raylua | 4.0 | [Lua](http://www.lua.org/) | MIT | https://github.com/Rabios/raylua | +| raylib-matte | 4.6-dev | [Matte](https://github.com/jcorks/matte/) | MIT | https://github.com/jcorks/raylib-matte | | nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib | | Raylib.nelua | **4.5** | [nelua](https://nelua.io/) | Zlib | https://github.com/Its-Kenta/Raylib-Nelua | | NimraylibNow! | 4.2 | [Nim](https://nim-lang.org/) | MIT | https://github.com/greenfork/nimraylib_now | diff --git a/raylib/CHANGELOG b/raylib/CHANGELOG index 43ab3ab..77df794 100644 --- a/raylib/CHANGELOG +++ b/raylib/CHANGELOG @@ -1,7 +1,247 @@ changelog --------- -Current Release: raylib 4.5.0 (18 March 2023) +Current Release: raylib 5.0 (18 November 2023) + +------------------------------------------------------------------------- +Release: raylib 5.0 - 10th Anniversary Edition (18 November 2023) +------------------------------------------------------------------------- +KEY CHANGES: + - REDESIGNED: rcore module platform-split, by @ubkp, @michaelfiber, @Bigfoot71, @raysan5 + - ADDED: New platform backend supported: SDL + - ADDED: New platform backend supported: Nintendo Switch (closed source) + - ADDED: New Splines drawing and evaluation API + - ADDED: New pseudo-random numbers generator: rprand + - ADDED: Automation Events System API + - UPDATED: raygui 4.0: New version of this immediate-mode gui system for tools development with raylib + +Detailed changes: +[rcore] ADDED: RAYLIB_VERSION_* values to raylib.h (#2856) by @RobLoach +[rcore] ADDED: IsKeyPressedRepeat() on PLATFORM_DESKTOP (#3245) by @actondev +[rcore] ADDED: SetWindowTitle() for PLATFORM_WEB (#3222) by @VitusVeit +[rcore] ADDED: FLAG_WINDOW_RESIZABLE for web (#3305) by @Peter0x44 +[rcore] ADDED: SetWindowMaxSize() for desktop and web (#3309) by @ubkp +[rcore] ADDED: SetMouseCursor() for PLATFORM_WEB (#3414) by @BeardedBread +[rcore] ADDED: LoadRandomSequence()/UnloadRandomSequence() by @raysan5 +[rcore] REMOVED: PLATFORM_RPI (#3232) by @michaelfiber +[rcore] REVIEWED: GetFileLength(), added comment (#3262) by @raysan5 +[rcore] REVIEWED: Default shaders precission issue on PLATFORM_WEB (#3261) by @branc116 +[rcore] REVIEWED: IsKey*() key validation checks (#3256) by @n77y +[rcore] REVIEWED: SetClipboardText() for PLATFORM_WEB (#3257) by @ubkp +[rcore] REVIEWED: Check if Ctrl modifier is among the currently set modifiers (#3230) by @mohad12211 +[rcore] REVIEWED: Android app black screen when reopening by @Bigfoot71 +[rcore] REVIEWED: Warnings when casting int to floats (#3218) by @JeffM2501 +[rcore] REVIEWED: GetCurrentMonitor() detection inconsistency issue (#3215) by @ubkp +[rcore] REVIEWED: SetWindowMonitor() to no longer force fullscreen (#3209) by @ubkp +[rcore] REVIEWED: Fix mouse wheel not working in PLATFORM_RPI or PLATFORM_DRM (#3193) by @ubkp +[rcore] REVIEWED: GetMonitorName() description (#3184) (#3189) by @danilwhale +[rcore] REVIEWED: BeginScissorMode(), identify rendering to texture (#3510) by @gulrak +[rcore] REVIEWED: Window flags order (#3114) by @lesleyrs +[rcore] REVIEWED: Full movement for right analog stick (#3095) by @PixelPhobicGames +[rcore] REVIEWED: Fix Android app freeze after calling CloseWindow() (#3067) by @Bigfoot71 +[rcore] REVIEWED: Lazy loading of default font used on image drawing (no InitWindow) by @raysan5 +[rcore] REVIEWED: Minor tweaks to raylib events automation system @raysan5 +[rcore] REVIEWED: GetCurrentMonitor() bugfix (#3058) by @hamyyy +[rcore] REVIEWED: Update CORE.Input.Touch.pointCount (#3024) by @raysan5 +[rcore] REVIEWED: Mouse offset and scaling must be considered also on web! +[rcore] REVIEWED: CompressData(), possible stack overflow +[rcore] REVIEWED: GetWorldToScreenEx() (#3351) by @Brian-ED +[rcore] REVIEWED: Fix GetMouseDelta() issue for Android (#3404) by @Bigfoot71 +[rcore] REVIEWED: GetFPS(), reset FPS averages when window is inited (#3445) by @JeffM2501 +[rcore] REVIEWED: GetCurrentMonitor(), check window center position by @M374LX +[rcore] REVIEWED: GetRender*() issue on macOS highDPI (#3367) by @raysan5 +[rcore] REVIEWED: ScanDirectoryFiles*(), paths building slashes sides (#3507) +[rlgl] ADDED: Experimental support for OpenGL ES 3.0 by @raysan5 +[rlgl] ADDED: Support 16-Bit HDR textures (#3220) by @Not-Nik +[rlgl] ADDED: rlEnablePointMode() (#3490) by @JettMonstersGoBoom +[rlgl] ADDED: rlBlitFramebuffer(), required for deferred render +[rlgl] REVIEWED: LoadModel(), removed cube fallback mechanism (#3459) +[rlgl] REVIEWED: Improved support for ES3/WebGL2 (#3107) by @chemaguerra +[rlgl] REVIEWED: OpenGL 2.1 half floats support as part of an extension by @Not-Nik +[rlgl] REVIEWED: Avoid shader attribute not found log by @raysan5 +[rlgl] REVIEWED: Avoid tracelog about not found uniforms (#3003) by @raysan5 +[rlgl] REVIEWED: rLoadTexture() UBSAN complaints #1891 (#3321) by @Codom +[rlgl] REVIEWED: glInternalFormat as unsigned int +[rlgl] REVIEWED: OpenGL ES 3.0 support +[rshapes] ADDED: Spline drawing functions by @raysan5 +[rshapes] ADDED: GetSplinePoint*() functions for spline evaluation by @raysan5 +[rshapes] ADDED: DrawCircleLinesV() for consistency (#3452) by @Peter0x44 +[rshapes] REVIEWED: DrawSplineCatmullRom() by @raysan5 +[rshapes] REVIEWED: Minor fix in DrawLineBezier* (#3006) by @eternalStudent +[rshapes] REVIEWED: GetCollisionRec(), more performant (#3052) by @manuel5975p +[rshapes] REVIEWED: Fix off-by-one error in CheckCollisionPointRec() (#3022) by @dbechrd +[rtextures] ADDED: Basic SVG loading support (#2738) by @bXi +[rtextures] ADDED: Support 16-Bit HDR textures (#3220) by @Not-Nik +[rtextures] ADDED: ExportImageToMemory() by @raysan5 +[rtextures] ADDED: ImageRotate() (#3078) by @danemadsen +[rtextures] ADDED: GenImageGradientSquare() (#3077) by @danemadsen +[rtextures] ADDED: GenImageLinearGradient() by @danemadsen +[rtextures] REMOVED: GenImageGradientH() and GenImageGradientV() by @danemadsen +[rtextures] REVIEWED: LoadImageSvg() by @raysan5 +[rtextures] REVIEWED: Uninitialized thread-locals in stbi (#3282) (#3283) by @jbarthelmes +[rtextures] REVIEWED: ImageDrawRectangleRec(), validate drawing inside bounds by @JeffM2501 +[rtextures] REVIEWED: LoadTextureCubemap() for manual layouts (#3204) by @Not-Nik +[rtextures] REVIEWED: Optimization of ImageDrawRectangleRec() (#3185) by @smalltimewizard +[rtextures] REVIEWED: ImageRotate() formatting by @raysan5 +[rtextures] REVIEWED: GenImagePerlinNoise(), clamp values (#3071) by @raysan5 +[rtextures] REVIEWED: Packing logic error in GenImageFontAtlas() (#2979) by @hanaxar +[rtextures] REVIEWED: Calculate exact image size in GenImageFontAtlas() (#2963) by @hanaxar +[rtextures] REVIEWED: ImageDrawRectangleRec() (#3027) by @raysan5 +[rtextures] REVIEWED: ImageDraw() source clipping when drawing beyond top left (#3306) by @RobLoach +[rtextures] REVIEWED: UnloadRenderTexture(), additional checks +[rtextures] REVIEWED: Fixed compressed DDS texture loading issues (#3483) by @JaanDev +[rtext] ADDED: Font altas white rectangle and flag SUPPORT_FONT_ATLAS_WHITE_REC by @raysan5 +[rtext] ADDED: SetTextLineSpacing() to define line breaks text drawing spacing by @raysan5 +[rtext] RENAMED: LoadFont*() parameter names for consistency and coherence by @raysan5 +[rtext] REVIEWED: GetCodepointCount(), ignore unused return value of GetCodepointNext by @ashn-dot-dev +[rtext] REVIEWED: TextFormat() warn user if buffer overflow occured (#3399) by @Murlocohol +[rtext] REVIEWED: TextFormat(), added "..." for truncation (#3366) by @raysan5 +[rtext] REVIEWED: GetGlyphIndex() (#3000) by @raysan5 +[rtext] REVIEWED: GetCodepointNext() to return default value by @chocolate42 +[rtext] REVIEWED: TextToPascal() issue when first char is uppercase +[rmodels] ADDED: ModelAnimation.name field, initially with GLTF animation names by @alfredbaudisch +[rmodels] REDESIGNED: LoadOBJ(), avoid mesh splitting by materials, fix (#3398) by @raysan5 +[rmodels] REVIEWED: Support .vox model files version 200 (#3097) by @Bigfoot71 +[rmodels] REVIEWED: Materials loading (#3126) @raysan5 +[rmodels] REVIEWED: DrawBillboardPro() to allow source of negative size (#3197) by @bohonghuang +[rmodels] REVIEWED: glTF loading segfault in animNormals memcpy by @charles-l +[rmodels] REVIEWED: LoadModelAnimationsGLTF(), free fileData after use (#3065) by @crynux +[rmodels] REVIEWED: GenMeshCubicmap(), correction of values (#3032) by @Bigfoot71 +[rmodels] REVIEWED: DrawMesh() to avoid UBSAN complaining (#1891) +[rmodels] REVIEWED: GenMeshPlane() when resX != resZ (#3425) by @neyrox, @s-yablonskiy +[rmodels] REVIEWED: GetModelBoundingBox() (#3485) +[raudio] ADDED: LoadSoundAlias() by @JeffM2501 +[raudio] ADDED: Missing structure on standalone mode (#3160) by @raysan5 +[raudio] ADDED: GetMasterVolume() (#3434) by @rexim +[raudio] REVIEWED: Comments about sample format to AttachAudioStreamProcessor() (#3188) by @AlbertoGP +[raudio] REVIEWED: Documented buffer format for audio processors (#3186) by @AlbertoGP +[raudio] REVIEWED: ExportWaveAsCode() file saving by @RadsammyT +[raudio] REVIEWED: Fix warning on discarded const qualifier (#2967) by @RobLoach +[raudio] REVIEWED: Move mutex initialization before ma_device_start() (#3325) by @Bigfoot71 +[raudio] REVIEWED: Fix UpdateSound() parameter name (#3405) by @KislyjKisel +[raudio] REVIEWED: Fix QOA seeking (#3494) by @veins1 +[rcamera] REVIEWED: File-macros for consistency (#3161) by @raysan5 +[rcamera] REVIEWED: Support analog stick camera controls (#3066) by @PixelPhobicGames +[rcamera] REVIEWED: CameraMoveToTarget(), ensure distance is greater than 0 (#3031) by @kolunmi +[rcamera] REVIEWED: Exposing rcamera functions to the dll (#3355) by @JeffM2501 +[raymath] ADDED: Vector3Projection() and Vector3Rejection() (#3263) by @Dial0 +[raymath] ADDED: EPSILON macro to each function requiring it (#3330) by @Brian-ED +[raymath] REVIEWED: Usage of 'sinf()' and 'cosf()' to be correct (#3181) by @RokasPuzonas +[raymath] REVIEWED: Slightly optimized Vector3Normalize() (#2982) by @RicoP +[raymath] REVIEWED: Comment to clarify raymath semantics by @raysan5 +[raymath] REVIEWED: Comment about Matrix conventions by @raysan5 +[raymath] REVIEWED: Vector2Angle() and Vector2LineAngle() (#3396) by @Murlocohol +[rgestures] REVIEWED: Optimize and simplify the gesture system (#3190) by @ubkp +[rgestures] REVIEWED: GESTURE_DRAG and GESTURE_SWIPE_* issues (mostly) for web (#3183) by @ubkp +[rgestures] REVIEWED: Touch pointCount for web (#3163) by @ubkp +[rgestures] REVIEWED: IsGestureDetected() parameter type +[utils] ADDED: Security checks to file reading (memory allocations) by @raysan5 +[utils] REVIEWED: LoadFileData() potential issues with dataSize +[examples] ADDED: shaders_lightmap (#3043) by @nullstare +[examples] ADDED: core_2d_camera_split_screen (#3298) by @gabrielssanches +[examples] ADDED: LoadSoundAlias() usage example (#3223) by @JeffM2501 +[examples] ADDED: textures_tiling (#3353) by @luis605 +[examples] ADDED: shader_deferred_render (#3496) by @27justin +[examples] RENAMED: 2d_camera examples for consistency +[examples] REVIEWED: Text examples SetTextLineSpacing() to multiline examples by @raysan5 +[examples] REVIEWED: examples/shapes/shapes_collision_area.c help instructions (#3279) by @asdqwe +[examples] REVIEWED: examples/shaders/shaders_texture_outline.c help instructions (#3278) by @asdqwe +[examples] REVIEWED: examples/others/easings_testbed.c help instructions and small twe… by @asdqwe +[examples] REVIEWED: example/audio/audio_module_player.c help instructions and small b… by @asdqwe +[examples] REVIEWED: example/models/models_loading_m3d.c controls (#3269) by @asdqwe +[examples] REVIEWED: example/models/models_loading_gltf.c controls (#3268) by @asdqwe +[examples] REVIEWED: text_unicode.c example crashing (#3250) by @ubkp +[examples] REVIEWED: rlgl_standalone.c compilation issue (#3242) by @ubkp +[examples] REVIEWED: core_input_gestures for Web (#3172) by @ubkp +[examples] REVIEWED: core_input_gamepad (#3110) by @iacore +[examples] REVIEWED: examples using raygui to raygui 4.0 by @raysan5 +[examples] REVIEWED: Julia set shader example (#3467) by @joshcol9232 +[build] ADDED: CMake option for SUPPORT_CUSTOM_FRAME_CONTROL (#3221) by @ubkp +[build] ADDED: New BORDERLESS_WINDOWED_MODE for PLATFORM_DESKTOP (#3216) by @ubkp +[build] ADDED: New examples to VS2022 solution by @raysan5 +[build] REVIEWED: Updated Makefile and Makefile.Web, include new examples +[build] REVIEWED: Fix CMake extraneous -lglfw (#3266) by @iacore +[build] REVIEWED: Add missing cmake options (#3267) by @asdqwe +[build] REVIEWED: Match CMakeOptions.txt options default values (#3258) by @asdqwe +[build] REVIEWED: Add build.zig options for individual modules (#3254) by @actondev +[build] REVIEWED: build.zig to work with cross-compiling (#3225) by @yujiri8 +[build] REVIEWED: Makefile build on PLATFORM_ANDROID, soname (#3211) by @ndytts +[build] REVIEWED: src/Makefile, fix misleading indentation (#3202) by @ashn-dot-dev +[build] REVIEWED: build.zig: Support for building with PLAFORM_DRM (#3191) by @jakubvf +[build] REVIEWED: Update CMakeOptions.txt by @raysan5 +[build] REVIEWED: fix: cmake option "OPENGL_VERSION" doesn't work (#3170) by @royqh1979 +[build] REVIEWED: Add error if raylib.h is included in a C++98 program (#3093) by @Peter0x44 +[build] REVIEWED: Cross compilation for PLATFORM_DRM (#3091) by @TheLastBilly +[build] REVIEWED: build.zigm fixed cross-compiling from Linux (#3090)by @yujiri8 +[build] REVIEWED: Enhanced cmake part for OpenBSD (#3086) by @rayit +[build] REVIEWED: Fixed compile on OpenBSD (#3085)by @rayit +[build] REVIEWED: CMake project example: fix a couple of typos (#3014) by @benjamin-thomas +[build] REVIEWED: Fix warnings in raylib for MSVC (#3004) by @JeffM2501 +[build] REVIEWED: Update cmake example project (#3062) by @lesleyrs +[build] REVIEWED: Update build.zig be be able to build with current zig master (#3064) by @ryupold +[build] REVIEWED: VSCode project template (#3048) by @Shoozza +[build] REVIEWED: Fixed broken build.zig files. Now works with latest stable compiler (… by @Gamer-Kold +[build] REVIEWED: Fix missing symbol when rglfw.c on BSD platforms (#2968) by @Koromix +[build] REVIEWED: Update Makefile comment to indicate arm64 as a supported Linux deskto… @ashn-dot-dev +[build] REVIEWED: Update Makefile : clean raygui.c & physac.c (#3296) by @SuperUserNameMan +[build] REVIEWED: Update webassembly.yml and linux.yml +[build] REVIEWED: Update zig build system to zig version 0.11.0 (#3393) by @purple4pur +[build] REVIEWED: Fix for latest zig master (#3037) by @star-tek-mb +[build] REVIEWED: Examples Makefile to use Makefile.Web when building for web (#3449) by @keithstellyes +[build] REVIEWED: build.zig updates for 0.11.0 release. (#3501) by @cabarger +[build] REVIEWED: Support OpenGL ES 3.0 building on Web platform +[build] REVIEWED: Fix warnings in Visual Studio (#3512) by @JeffM2501 +[build] REVIEWED: OpenGL ES 3.0 flags on CMakeOptions (#3514) by @awfulcooking +[bindings] ADDED: fortran-raylib +[bindings] ADDED: raylib-raku to bindings (#3299) by @vushu +[bindings] ADDED: claw-raylib to BINDINGS.md (#3310) by @bohonghuang +[bindings] ADDED: vaiorabbit/raylib-bindings (#3318) by @wilsonsilva +[bindings] ADDED: TurboRaylib (#3317) by @turborium +[bindings] ADDED: raylib-ffi to bindings list (#3164) by @ewpratten +[bindings] ADDED: raylib-pkpy-bindings (#3361) by @blueloveTH +[bindings] ADDED: Raylib.lean to BINDINGS.md (#3409) by @KislyjKisel +[bindings] UPDATED: BINDINGS.md (#3217) by @joseph-montanez +[bindings] UPDATED: BINDINGS.md to include rayjs (#3212) by @mode777 +[bindings] UPDATED: latest h-raylib version (#3166) by @Anut-py +[bindings] UPDATED: bindbd-raylib3 to raylib 4.5 (#3157) by @o3o +[bindings] UPDATED: Janet bindings supported version update (#3083)by @archydragon +[bindings] UPDATED: BINDINGS.md (raylib-py -> 4.5) (#2992) by @overdev +[bindings] UPDATED: BINDINGS.md (raylib-lua -> 4.5) (#2989) by @TSnake41 +[bindings] UPDATED: raylib-d binding version to 4.5 (#2988) by @schveiguy +[bindings] UPDATED: raylib-freebasic to 4.5 (#2986) by @WIITD +[bindings] UPDATED: BINDINGS.md (#2983) by @jarroddavis68 +[bindings] UPDATED: BINDINGS.md for raylib Odin 4.5 (#2981) by @gingerBill +[bindings] UPDATED: BINDINGS.md (#2980) by @GuvaCode +[bindings] UPDATED: BINDINGS.md (#3002) by @fubark +[bindings] UPDATED: BINDINGS.md (#3053) by @JupiterRider +[bindings] UPDATED: BINDINGS.md (#3050) by @Its-Kenta +[bindings] UPDATED: CL bindings version (#3049) by @shelvick +[bindings] UPDATED: BINDINGS.md (#3026) by @ChrisDill +[bindings] UPDATED: BINDINGS.md (#3023) by @sDos280 +[bindings] UPDATED: BINDINGS.md (#3017) by @Soutaisei +[bindings] UPDATED: Various versions to 4.5 (#2974) by @RobLoach +[bindings] UPDATED: raylib.zig version to 4.5 (#2971) by @ryupold +[bindings] UPDATED: h-raylib version (#2970) by @Anut-py +[bindings] UPDATED: Factor's raylib binding to v4.5 (#3350) by @WraithGlade +[bindings] UPDATED: raylib-ocaml bindings to 4.5 version (#3322) by @tjammer +[bindings] UPDATED: Jaylib binding (#3508) by @glowiak +[external] UPDATED: sdefl and sinfl DEFLATE compression libraries by @raysan5 +[external] UPDATED: miniaudio v0.11.12 --> v0.11.19 by @raysan5 +[external] UPDATED: rl_gputex.h compressed images loading library by @raysan5 +[external] UPDATED: Replaced stb_image_resize.c by stb_image_resize2.h (#3403) by @BabakSamimi +[external] UPDATED: qoi and qoa libraries +[external] UPDATED: stb libraries (required ones) +[external] UPDATED: cgltf and m3d libraries +[external] REVIEWED: msf_gif.h, some warnings +[external] REVIEWED: sinfl external library to avoid ASAN complaints (#3349) by @raysan5 +[misc] ADDED: New task point to issue template about checking the wiki (#3169) by @ubkp +[misc] ADDED: CodeQL for static code analysis (#3476) by @b4yuan +[misc] REVIEWED: Update FAQ.md by @raysan5 +[misc] REVIEWED: Potential code issues reported by CodeQL (#3476) +[misc] REVIEWED: Fix a link in the FAQ (#3082)by @jasonliang-dev +[misc] REVIEWED: New file formats to FAQ (#3079) by @Luramoth +[misc] REVIEWED: Make assets loading extension case insensitive #3008 by @raysan5 +[misc] REVIEWED: Updated web shells open-graph info by @raysan5 ------------------------------------------------------------------------- Release: raylib 4.5 (18 March 2023) @@ -445,7 +685,7 @@ Detailed changes: [raymath] REVIEWED: QuaternionFromAxisAngle() (#1892) [raymath] REVIEWED: QuaternionToMatrix() returning transposed result. (#1793) by @object71 [shapes] ADDED: RenderPolyLinesEx() (#1758) by @lambertwang -[shapes] ADDED: DrawLineBezierCubic() (#2021) by @SAOMDVN +[shapes] ADDED: DrawSplineBezierCubic() (#2021) by @SAOMDVN [textures] ADDED: GetImageColor() #2024 [textures] REMOVED: GenImagePerlinNoise() [textures] RENAMED: GetTextureData() to LoadImageFromTexture() @@ -583,7 +823,7 @@ Detailed changes: [rlgl] REDESIGNED: rlLoadExtensions(), more details exposed [raymath] REVIEWED: QuaternionFromEuler() (#1651) [raymath] REVIEWED: MatrixRotateZYX() (#1642) -[shapes] ADDED: DrawLineBezierQuad() (#1468) by @epsilon-phase +[shapes] ADDED: DrawSplineBezierQuad() (#1468) by @epsilon-phase [shapes] ADDED: CheckCollisionLines() [shapes] ADDED: CheckCollisionPointLine() by @mkupiec1 [shapes] REVIEWED: CheckCollisionPointTriangle() by @mkupiec1 @@ -1665,9 +1905,9 @@ other changes: [models] Added function DrawCubeTexture() [models] Added function DrawQuad() [models] Added function DrawRay() -[models] Simplified funtion DrawPlane() +[models] Simplified function DrawPlane() [models] Removed function DrawPlaneEx() -[models] Simplified funtion DrawGizmo() +[models] Simplified function DrawGizmo() [models] Removed function DrawGizmoEx() [models] Added function LoadModelEx() [models] Review of function LoadCubicMap() diff --git a/raylib/CMakeLists.txt b/raylib/CMakeLists.txt index be978d1..236aa9a 100644 --- a/raylib/CMakeLists.txt +++ b/raylib/CMakeLists.txt @@ -37,6 +37,17 @@ include(BuildOptions) # Main sources directory (the second parameter sets the output directory name to raylib) add_subdirectory(src raylib) +# Uninstall target +if(NOT TARGET uninstall) + configure_file( + "${CMAKE_MODULE_PATH}/Uninstall.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) +endif() + if (${BUILD_EXAMPLES}) MESSAGE(STATUS "Building examples is enabled") add_subdirectory(examples) diff --git a/raylib/CMakeOptions.txt b/raylib/CMakeOptions.txt index 7995309..db0a1a1 100644 --- a/raylib/CMakeOptions.txt +++ b/raylib/CMakeOptions.txt @@ -4,7 +4,7 @@ include(EnumOption) enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM" "Platform to build for.") -enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0" "Force a specific OpenGL Version?") +enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific OpenGL Version?") # Configuration options option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN}) @@ -37,6 +37,7 @@ cmake_dependent_option(SUPPORT_MODULE_RAUDIO "Include module: raudio" ON CUSTOMI # rcore.c cmake_dependent_option(SUPPORT_CAMERA_SYSTEM "Provide camera module (rcamera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_RPRAND_GENERATOR "Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON CUSTOMIZE_BUILD ON) diff --git a/raylib/HISTORY.md b/raylib/HISTORY.md index 735e665..f1a67bb 100644 --- a/raylib/HISTORY.md +++ b/raylib/HISTORY.md @@ -140,7 +140,7 @@ notes on raylib 1.7 On May 2017, around 6 month after raylib 1.6, comes another raylib instalment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are: - - More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, funtions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions! + - More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, functions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions! - Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality. @@ -379,13 +379,13 @@ Some numbers to start with: Highlights for `raylib 4.2`: - **raylib extra libraries cleanup**: raylib has been on diet and all the _extra_ libraries included on previous releases have been removed from raylib. Now raylib only includes the original **7** raylib modules: `rcore`, `rlgl`, `rshapes`, `rtextures`, `rtext`, `rmodels` and `raudio`. But no worries, _extra_ libraries have not been deleted, they have been moved to their own repos for better maintainability and more focus on its functionality. The libraries moved out from raylib repo are: [`raygui`](https://github.com/raysan5/raygui), [`physac`](https://github.com/raysan5/physac), [`rmem`](https://github.com/raylib-extras/rmem), [`reasings`](https://github.com/raylib-extras/reasings) and [`raudio`](https://github.com/raysan5/raudio) (standalone mode). On that same line, a new **amazing GitHub group:** [`raylib-extras`](https://github.com/raylib-extras) has been created by @JeffM2501 to contain raylib extra libraries as well as other raylib add-ons provided by the community. Jeff has done an amazing work on that line, providing multiple libraries and examples for raylib, like [custom first-person and third person camera systems](https://github.com/raylib-extras/extras-c/tree/main/cameras), [Dear ImGui raylib integration](https://github.com/raylib-extras/rlImGui), [multiple specific examples](https://github.com/raylib-extras/examples-c) and even a complete [RPG Game Example](https://github.com/raylib-extras/RPGExample)! Great work Jeff! :D - - - **raylib examples review**: The +120 raylib examples have been reviewed to add clearer information about when the were first created (raylib version used) and when they were updated for the last time. But the greatest improvement for users has been the **addition of an estimated difficulty level** for every example, [web has been updated accordingly](https://www.raylib.com/examples.html) to reflect those difficulty levels. Now examples are classified with **1 to 4 stars** depending on difficulty to help users with their learning process. Personally, I think this "small" addition could be a game-changer to better guide new users on the library adoption! Additionally, this new raylib release includes 7 new examples; the most interesting one: [`text_codepoints_loading`](https://www.raylib.com/examples/text/loader.html?name=text_codepoints_loading) that illustrates how to load and draw custom codepoints from a font file, very useful for Asian languages. + + - **raylib examples review**: The +120 raylib examples have been reviewed to add clearer information about when the were first created (raylib version used) and when they were updated for the last time. But the greatest improvement for users has been the **addition of an estimated difficulty level** for every example, [web has been updated accordingly](https://www.raylib.com/examples.html) to reflect those difficulty levels. Now examples are classified with **1 to 4 stars** depending on difficulty to help users with their learning process. Personally, I think this "small" addition could be a game-changer to better guide new users on the library adoption! Additionally, this new raylib release includes 7 new examples; the most interesting one: [`text_codepoints_loading`](https://www.raylib.com/examples/text/loader.html?name=text_codepoints_loading) that illustrates how to load and draw custom codepoints from a font file, very useful for Asian languages. - [**`rres 1.0`**](https://github.com/raysan5/rres): New `rres` **resources packaging file-format**, including a [`rres-raylib`](https://github.com/raysan5/rres/blob/master/src/rres-raylib.h) library implementation and [`rrespacker`](https://raylibtech.itch.io/rrespacker) tool. `rres` file format has been [under development for +8 years](https://github.com/raysan5/rres#design-history) and it was originally created to be part of raylib. It was highly inspired by _XNA XNB_ resources file format but design has changed a lot along the years. This first release of the format specs is engine-agnostic and has been designed to be portable to any engine, including lots of professional features like data processing, compression and encryption. - [**`raygui 3.2`**](https://github.com/raysan5/raygui): The **official raylib immediate-mode gui library** designed for tools development has been updated to a new version aligned with raylib 4.2. Multiple controls have been reviewed for library consistency, now all controls follow a similar function signature. It has been battle-tested with the development of +8 published tools in the last months. The tools can be seen and used for free in the [raylib technologies tools page](https://raylibtech.itch.io/). Worth mentioning that several of those **tools have been open sourced** for anyone to use, compile, contribute or learn how the code works. - + - [**`raylib_parser`**](https://github.com/raysan5/raylib/tree/master/parser): Multiple contributors **using the tool to automatize bindings creation** have contributed with improvements of this **tool to parse `raylib.h`** (and other raylib-style headers) to tokenize its enums, structs and functions. Processed data can be exported to custom file formats (i.e XML, JSON, LUA) for bindings generation or even docs generation if required. - **New file system API**: Current API has been redesigned to be more comprehensive and better aligned with raylib naming conventions, two new functions are provided `LoadDirectoryFiles()`/`LoadDirectoryFilesEx()` to load a `FilePathList` for provided path, supporting extension filtering and recursive directory scan. `LoadDroppedFiles()` has been renamed to better reflect its internal functionality. Now, all raylib functions that start with `Load*()` allocate memory internally and a equivalent `Unload*()` function is defined to take care of that memory internally when not required any more! @@ -414,21 +414,60 @@ Highlights for `raylib 4.5`: - **`NEW` Improved ANGLE support on Desktop platforms**: Support for OpenGL ES 2.0 on Desktop platforms (Windows, Linux, macOS) has been reviewed by @wtnbgo GitHub user. Now raylib can be compiled on desktop for OpenGL ES 2.0 and linked against [`ANGLE`](https://github.com/google/angle). This _small_ addition open the door to building raylib for all **ANGLE supported backends: Direct3D 11, Vulkan and Metal**. Please note that this new feature is still experimental and requires further testing! - **`NEW` Camera module**: A brand new implementation from scratch for `rcamera` module, contributed by @Crydsch GitHub user! **New camera system is simpler, more flexible, more granular and more extendable**. Specific camera math transformations (movement/rotation) have been moved to individual functions, exposing them to users if required. Global state has been removed from the module and standalone usage has been greatly improved; now `rcamera.h` single-file header-only library can be used externally, independently of raylib. A new `UpdateCameraPro()` function has been added to address input-dependency of `UpdateCamera()`, now advance users have **full control over camera inputs and movement/rotation speeds**! - + - **`NEW` Support for M3D models and M3D/GLTF animations**: 3d models animations support has been a limited aspect of raylib for long time, some versions ago IQM animations were supported but raylib 4.5 also adds support for the brand new [M3D file format](https://bztsrc.gitlab.io/model3d/), including animations and the long expected support for **GLTF animations**! The new M3D file format is **simple, portable, feature complete, extensible and open source**. It also provides a complete set of tools to export/visualize M3D models from/to Blender! Now raylib supports up to **3 model file-formats with animations**: `IQM`, `GLTF` and `M3D`. - + - **`NEW` Support QOA audio format (import/export)**: Just a couple of months ago the new [QOA file format](https://qoaformat.org/) was published, a very simple, portable and open source quite-ok-audio file format. raylib already supports it, added to `raudio` module and including audio loading from file, loading from memory, streaming from file, streaming from memory and **exporting to QOA** audio format. **Because simplicity really matters to raylib!** - + - **`NEW` Module for compressed textures loading**: [`rl_gputex`](https://github.com/raysan5/raylib/blob/master/src/external/rl_gputex.h), a portable single-file header-only small library to load compressed texture file-formats (DDS, PKM, KTX, PVR, ASTC). Provided functionality is not new to raylib but it was part of the raylib `rtextures` module, now it has been moved into a separate self-contained library, **improving portability**. Note that this module is only intended to **load compressed data from files, ready to be uploaded to GPU**, no compression/decompression functionality is provided. This change is a first step towards a better modularization of raylib library. - + - **Reviewed `rlgl` module for automatic limits checking**: Again, [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been reviewed to simplify usage. Now users do not need to worry about reaching the internal render-batch limits when they send their triangles to draw 2d/3d, `rlgl` manages it automatically! This change allows a **great simplification for other modules** like `rshapes`, `rtextures` and `rmodels` that do not need to worry about bufffer overflows and can just define as many vertex as desired! - - - **Reviewed `rshapes` module to minimize the rlgl dependency**: Now `rshapes` 2d shapes drawing functions **only depend on 6 low-level functions**: `rlBegin()`, `rlEnd()`, `rlVertex3f()`, `rlTexCoord2f()`, `rlNormal3f()`, `rlSetTexture()`. With only those pseudo-OpenGl 1.1 minimal functionality, everything can be drawn! This improvement converts `rshapes` module in a **self-contained, portable shapes-drawing library that can be used independently of raylib**, as far as entry points for those 6 functions are provided by the user. It even allows to be used for software rendering, with the proper backend! + + - **Reviewed `rshapes` module to minimize the rlgl dependency**: Now `rshapes` 2d shapes drawing functions **only depend on 6 low-level functions**: `rlBegin()`, `rlEnd()`, `rlVertex3f()`, `rlTexCoord2f()`, `rlNormal3f()`, `rlSetTexture()`. With only those pseudo-OpenGl 1.1 minimal functionality, everything can be drawn! This improvement converts `rshapes` module in a **self-contained, portable shapes-drawing library that can be used independently of raylib**, as far as entry points for those 6 functions are provided by the user. It even allows to be used for software rendering, with the proper backend! - **Added data structures validation functions**: Multiple functions have been added by @RobLoach GitHub user to ease the validation of raylib data structures: `IsImageReady()`, `IsTextureReady()`, `IsSoundReady()`... Now users have a simple mechanism to **make sure data has been correctly loaded**, instead of checking internal structure values by themselfs. - + As usual, those are only some highlights but there is much more! New image generators, new color transformation functionality, improved blending support for color/alpha, etc... Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! Please, note that all breaking changes have been flagged with a `WARNING` in the CHANGELOG, specially useful for binding creators! -**raylib keeps improving one more version** with a special focus on maintainability and sustainability. Always working towards making the library more **simple and easy-to-use**. +**raylib keeps improving one more version** with a special focus on maintainability and sustainability. Always working towards making the library more **simple and easy-to-use**. Let's keep **enjoying games/tools/graphics programming!** :) + +notes on raylib 5.0 +------------------- + +It's been **7 months** since latest raylib release and **10 years** since raylib 1.0 was officially released... what an adventure! In the last 10 years raylib has improved a lot, new functions have been added, many new features and improvements implemented, up to **500 contributors** have helped to shape the library as it is today. `raylib 5.0` is the final result of all this incredible amount of work and dedication. Here it is the summary with the key features and additions of this NEW major version of raylib. + +Some numbers for this release: + + - **+200** closed issues (for a TOTAL of **+1540**!) + - **+550** commits since previous RELEASE (for a TOTAL of **+6950**!) + - **+35** functions ADDED to raylib API (for a TOTAL of **552**!) + - **+60** functions REVIEWED/REDESIGNED + - **+80** new contributors (for a TOTAL of **+500**!) + +Highlights for `raylib 5.0`: + + - **`rcore` module platform-split**: Probably the biggest raylib redesign in the last 10 years. raylib started as a library targeting 3 desktop platforms: `Windows`, `Linux` and `macOS` (thanks to `GLFW` underlying library) but with the years support for several new platforms has been added (`Android`, `Web`, `Rapsberry Pi`, `RPI native`...); lot of the platform code was shared so the logic was all together on `rcore.c` module, separated by compilation flags. This approach was very handy but also made it very difficult to support new platforms and specially painful for contributors not familiar with the module, navigating +8000 lines of code in a single file. A big redesign was really needed but the amount of work required was humungus and quite scary for a solo-developer like me, moreover considering that everything was working and the chances to break things were really high. Fortunately, some contributors were ready for the task (@ubkp, @michaelfiber, @Bigfoot71) and thanks to their initiative and super-hard work, the `rcore` [platform split](https://github.com/raysan5/raylib/blob/master/src/platforms) has been possible! This new raylib architecture greatly improves the platforms maintenance but also greatly simplifies the addition of new platforms. A [`platforms/rcore_template.c`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_template.c) file is provided with the required structure and functions to be filled for the addition of new platforms, actually it has been simplified to mostly filling some pre-defined functions: `InitPlatform()`, `ClosePlatform`, `PollInputEvents`... Undoubtely, **this redesign opens the doors to a new era for raylib**, letting the users to plug new platforms as desired. + + - **`NEW` Platform backend supported: SDL**: Thanks to the new `rcore` platform-split, the addition of new platforms/backends to raylib has been greatly simplified. As a proof of concept, [`SDL2`](https://libsdl.org/) platform backend has been added to raylib as an aternative for `GLFW` library for desktop builds: [`platforms/rcore_desktop_sdl`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_sdl.c). Lot of work has been put to provide exactly the same features as the other platforms and carefully test the new implementation. Now `SDL2` fans can use this new backend, just providing the required include libraries on compilation and linkage (not included in raylib, like `GLFW`). `SDL` backend support also **eases the process of supporting a wider range of platforms** that already support `SDL`. + + - **`NEW` Platform backend supported: Nintendo Switch (closed source)**: The addition of the `SDL` backend was quite a challenge but to really verify the robustness and ease of the new platform plugin system, adding support for a console was a more demanding adventure. Surprisingly, only two days of work were required to add support for `Nintendo Switch` to raylib! Implementation result showed an outstanding level of simplicity, with a **self-contained module** (`rcore_swith.cpp`) supporting graphics and inputs. Unfortunately this module can not be open-sourced due to licensing restrictions. + + - **`NEW` Splines drawing and evaluation API**: A complete set of functions has been added to [draw](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1258) and [evaluate](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1270) different types of splines: `Linear`, `Basis`, `Catmull-Rom`, `Quadratic Bezier` and `Cubic Bezier`. Splines are extremely useful for game development (describe paths, control NPC movement...) but they can also be very useful on tools development (node-conections, elements-movement, 3d modelling, animations...). This was the missing feature on the raylib [`rshapes`](https://github.com/raysan5/raylib/blob/master/src/rshapes.h) module to make it complete! Note that `rshapes` module can also be used independently of raylib just providing the **only 6 functions required for vertex definition and drawing**. + + - **`NEW` Pseudo-random numbers generator: rprand**: After several years of users asking for this missing piece, a brand new pseudo-random generator module has been added to raylib. [`rprand`](https://github.com/raysan5/raylib/blob/master/src/external/rprand.h) implements the `Xoshiro128**` algorithm combined with `SplitMix64`, specially suited for **fast software pseudo-random numbers generation**. The module also implies some useful functions to generate non-repetitive random numbers sequences, functionality exposed by raylib. usage of this module can be controlled by a compilation flag, in case the default libc `rand()` function was preferred. + + - **`NEW` Automation Events System API**: This new system was first added in `raylib 4.0` as an experimental feature but it was a bit clumsy and there was no API exposed to users. For the new `raylib 5.0` the system has been redesigned and [proper API](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1135) added for the users. With this new events automation system, users can **record input events for later replay**, very useful feature for testing automation, tutorials generation, assisted game playing, in-game cinematics, speedruns saving or even AI assited game playing! + + - **`NEW` [`raygui 4.0`](https://github.com/raysan5/raygui)**: The **official raylib immediate-mode gui library** designed for tools development has been updated to a new version, aligned with raylib 5.0. This new version is a complete redesign of raygui to unify all controls structure and usage, now all controls have the same function signature!. `raygui` has been battle-tested with the development of +12 published tools in the last few years. The tools can be seen and used for free in the [raylib technologies tools page](https://raylibtech.itch.io/). Worth mentioning that several of those **tools have been open sourced** for anyone to use, compile, contribute or learn how the code works. + + - **`NEW` raylib web examples functionality**: Beside the addition of several new examples, the web examples functionality has been improved. Examples have been organized by [complexity level](https://www.raylib.com/examples.html), marked with one star for simple examples and up to 4 stars for more complex ones. A new option has been added to web to allow to **filter examples by function-name** usage, to ease the learning process when looking for an usage example of some function. Finally, **open-graph metadata** information has been added to all examples individual webpages, improving a the visuals and information when sharing those webpages on social networks, sharing the example screenshot and details. + +As always, those are only some highlights of the new `raylib 5.0` but there is many more improvements! Support for 16-bit HDR images/textures, SVG loading and scaling support, new OpenGL ES 3.0 graphic backend, new image gradient generators, sound alias loading, improved 3d models loading, multiple optimizations, new bindings, CodeQL integration and much more! + +Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! + +Undoubtely, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainabiliy and long-term sustainability. **Undoubtely, this is the raylib of the future**. + +**Enjoy programming!** :) diff --git a/raylib/README.md b/raylib/README.md index bff6980..9d2b78e 100644 --- a/raylib/README.md +++ b/raylib/README.md @@ -27,7 +27,6 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html) [](https://github.com/raysan5/raylib/actions?query=workflow%3AWindows) [](https://github.com/raysan5/raylib/actions?query=workflow%3ALinux) [](https://github.com/raysan5/raylib/actions?query=workflow%3AmacOS) -[](https://github.com/raysan5/raylib/actions?query=workflow%3AAndroid) [](https://github.com/raysan5/raylib/actions?query=workflow%3AWebAssembly) [](https://github.com/raysan5/raylib/actions?query=workflow%3ACMakeBuilds) @@ -39,24 +38,24 @@ features - **NO external dependencies**, all required libraries are [bundled into raylib](https://github.com/raysan5/raylib/tree/master/src/external) - Multiple platforms supported: **Windows, Linux, MacOS, RPI, Android, HTML5... and more!** - Written in plain C code (C99) using PascalCase/camelCase notation - - Hardware accelerated with OpenGL (**1.1, 2.1, 3.3, 4.3 or ES 2.0**) + - Hardware accelerated with OpenGL (**1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**) - **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) - - Multiple **Fonts** formats supported (TTF, Image fonts, AngelCode fonts) + - Multiple **Fonts** formats supported (TTF, OTF, Image fonts, AngelCode fonts) - Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC) - **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more! - Flexible Materials system, supporting classic maps and **PBR maps** - - **Animated 3D models** supported (skeletal bones animation) (IQM) - - Shaders support, including model and **postprocessing** shaders. + - **Animated 3D models** supported (skeletal bones animation) (IQM, M3D, glTF) + - Shaders support, including model shaders and **postprocessing** shaders - **Powerful math module** for Vector, Matrix and Quaternion operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) - - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD) + - Audio loading and playing with streaming support (WAV, QOA, OGG, MP3, FLAC, XM, MOD) - **VR stereo rendering** support with configurable HMD device parameters - - Huge examples collection with [+120 code examples](https://github.com/raysan5/raylib/tree/master/examples)! - - Bindings to [+60 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)! - - **Free and open source**. + - Huge examples collection with [+140 code examples](https://github.com/raysan5/raylib/tree/master/examples)! + - Bindings to [+70 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)! + - **Free and open source** basic example -------------- -This is a basic raylib example, it creates a window and it draws the text `"Congrats! You created your first window!"` in the middle of the screen. Check this example [running live on web here](https://www.raylib.com/examples/core/loader.html?name=core_basic_window). +This is a basic raylib example, it creates a window and draws the text `"Congrats! You created your first window!"` in the middle of the screen. Check this example [running live on web here](https://www.raylib.com/examples/core/loader.html?name=core_basic_window). ```c #include "raylib.h" @@ -114,7 +113,7 @@ learning and docs raylib is designed to be learned using [the examples](https://github.com/raysan5/raylib/tree/master/examples) as the main reference. There is no standard API documentation but there is a [**cheatsheet**](https://www.raylib.com/cheatsheet/cheatsheet.html) containing all the functions available on the library a short description of each one of them, input parameters and result value names should be intuitive enough to understand how each function works. -Some additional documentation about raylib design can be found in raylib GitHub Wiki. Here are the relevant links: +Some additional documentation about raylib design can be found in [raylib GitHub Wiki](https://github.com/raysan5/raylib/wiki). Here are the relevant links: - [raylib cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html) - [raylib architecture](https://github.com/raysan5/raylib/wiki/raylib-architecture) @@ -136,9 +135,16 @@ raylib is present in several networks and raylib community is growing everyday. - Patreon: [https://www.patreon.com/raylib](https://www.patreon.com/raylib) - YouTube: [https://www.youtube.com/channel/raylib](https://www.youtube.com/c/raylib) +contributors +------------ + +<a href="https://github.com/raysan5/raylib/graphs/contributors"> + <img src="https://contrib.rocks/image?repo=raysan5/raylib&max=500&columns=20&anon=1" /> +</a> + license ------- 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. Check [LICENSE](LICENSE) for further details. -raylib uses internally some libraries for window/graphics/inputs management and also to support different file formats loading, all those libraries are embedded with and are available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory. Check [raylib dependencies LICENSES](https://github.com/raysan5/raylib/wiki/raylib-dependencies) on raylib Wiki for details. +raylib uses internally some libraries for window/graphics/inputs management and also to support different file formats loading, all those libraries are embedded with and are available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory. Check [raylib dependencies LICENSES](https://github.com/raysan5/raylib/wiki/raylib-dependencies) on [raylib Wiki](https://github.com/raysan5/raylib/wiki) for details. diff --git a/raylib/ROADMAP.md b/raylib/ROADMAP.md index 61c6b56..8755333 100644 --- a/raylib/ROADMAP.md +++ b/raylib/ROADMAP.md @@ -11,16 +11,25 @@ Here it is a wishlist with features and ideas to improve the library. Note that _Current version of raylib is complete and functional but there is always room for improvements._ +**raylib 5.x** + - [ ] `rcore`: Support additional platforms: iOS, Xbox Series S|X + - [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK + - [ ] `rlgl`: Review GLSL shaders naming conventions for consistency + - [ ] `textures`: Improve compressed textures support, loading and saving + - [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf) + - [ ] `raudio`: Implement miniaudio high-level provided features + - [ ] `examples`: Review all examples, add more and better code explanations + - [ ] Software renderer backend? Maybe using `Image` provided API + **raylib 4.x** - - [ ] Split core module into separate platforms? - - [ ] Basic 2d software renderer, using `Image` provided API - - [ ] Redesign gestures system, improve touch inputs management - - [ ] Redesign audio module, implement miniaudio high-level provided features + - [x] Split core module into separate platforms? + - [x] Redesign gestures system, improve touch inputs management - [x] Redesign camera module (more flexible) ([#1143](https://github.com/raysan5/raylib/issues/1143), https://github.com/raysan5/raylib/discussions/2507) - [x] Better documentation and improved examples, reviewed webpage with examples complexity level - [x] Focus on HTML5 ([raylib 5k gamejam](https://itch.io/jam/raylib-5k-gamejam)) and embedded platforms (RPI and similar SOCs) - [x] Additional support libraries: [raygui](https://github.com/raysan5/raygui), [rres](https://github.com/raysan5/rres) + **raylib 4.0** - [x] Improved consistency and coherency in raylib API - [x] Continuous Deployment using GitHub Actions diff --git a/raylib/build.zig b/raylib/build.zig index 2163860..f4d7d15 100644 --- a/raylib/build.zig +++ b/raylib/build.zig @@ -1,7 +1,7 @@ const std = @import("std"); const raylib = @import("src/build.zig"); -// This has been tested to work with zig 0.11.0 (67709b6, Aug 4 2023) +// This has been tested to work with zig 0.11.0 pub fn build(b: *std.Build) void { raylib.build(b); } diff --git a/raylib/cmake/LibraryConfigurations.cmake b/raylib/cmake/LibraryConfigurations.cmake index 1debfeb..d4bf45a 100644 --- a/raylib/cmake/LibraryConfigurations.cmake +++ b/raylib/cmake/LibraryConfigurations.cmake @@ -105,6 +105,8 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF") set(GRAPHICS "GRAPHICS_API_OPENGL_11") elseif (${OPENGL_VERSION} MATCHES "ES 2.0") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") + elseif (${OPENGL_VERSION} MATCHES "ES 3.0") + set(GRAPHICS "GRAPHICS_API_OPENGL_ES3") endif () if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}") message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail") diff --git a/raylib/cmake/Uninstall.cmake b/raylib/cmake/Uninstall.cmake new file mode 100644 index 0000000..c2d34d4 --- /dev/null +++ b/raylib/cmake/Uninstall.cmake @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach() diff --git a/raylib/examples/Makefile b/raylib/examples/Makefile index 6031f05..5cd8e6b 100644 --- a/raylib/examples/Makefile +++ b/raylib/examples/Makefile @@ -1,6 +1,25 @@ #************************************************************************************************** # -# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5 +# raylib makefile for multiple platforms +# +# This file supports building raylib examples for the following platforms: +# +# > PLATFORM_DESKTOP (GLFW backend): +# - Windows (Win32, Win64) +# - Linux (X11/Wayland desktop mode) +# - macOS/OSX (x64, arm64) +# - FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop) +# > PLATFORM_DESKTOP_SDL (SDL backend): +# - Windows (Win32, Win64) +# - Linux (X11/Wayland desktop mode) +# - Others (not tested) +# > PLATFORM_WEB: +# - HTML5 (WebAssembly) +# > PLATFORM_DRM: +# - Raspberry Pi 0-5 (DRM/KMS) +# - Linux DRM subsystem (KMS mode) +# > PLATFORM_ANDROID: +# - Android (ARM, ARM64) # # Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) # @@ -25,14 +44,17 @@ # Define required environment variables #------------------------------------------------------------------------------------------------ -# Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB +# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB PLATFORM ?= PLATFORM_DESKTOP # Define required raylib variables PROJECT_NAME ?= raylib_examples -RAYLIB_VERSION ?= 4.5.0 +RAYLIB_VERSION ?= 5.0.0 RAYLIB_PATH ?= .. +# Define raylib source code path +RAYLIB_SRC_PATH ?= ../src + # Locations of raylib.h and libraylib.a/libraylib.so # NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD RAYLIB_INCLUDE_PATH ?= /usr/local/include @@ -47,6 +69,11 @@ BUILD_MODE ?= RELEASE # Use external GLFW library instead of rglfw module USE_EXTERNAL_GLFW ?= FALSE +# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally +# WARNING: Library is not included in raylib, it MUST be configured by users +SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2-2.28.4/include +SDL_LIBRARY_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2-2.28.4/lib/x64 + # Use Wayland display server protocol on Linux desktop (by default it uses X11 windowing system) # NOTE: This variable is only used for PLATFORM_OS: LINUX USE_WAYLAND_DISPLAY ?= FALSE @@ -58,8 +85,8 @@ BUILD_WEB_HEAP_SIZE ?= 134217728 BUILD_WEB_RESOURCES ?= TRUE BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources -# Determine PLATFORM_OS in case PLATFORM_DESKTOP or PLATFORM_WEB selected -ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB)) +# Determine PLATFORM_OS when required +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! # ifeq ($(UNAME),Msys) -> Windows ifeq ($(OS),Windows_NT) @@ -156,7 +183,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID) MAKE = mingw32-make endif ifeq ($(PLATFORM),PLATFORM_WEB) - MAKE = mingw32-make + MAKE = emmake make endif # Define compiler flags: CFLAGS @@ -224,6 +251,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) endif endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH) +endif ifeq ($(PLATFORM),PLATFORM_DRM) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) INCLUDE_PATHS += -I/usr/include/libdrm @@ -254,6 +284,17 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDFLAGS += -Lsrc -L$(RAYLIB_LIB_PATH) endif endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + ifeq ($(PLATFORM_OS),WINDOWS) + # NOTE: The resource .rc file contains windows executable icon and properties + LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data + # -Wl,--subsystem,windows hides the console window + ifeq ($(BUILD_MODE), RELEASE) + LDFLAGS += -Wl,--subsystem,windows + endif + endif + LDFLAGS += -L$(SDL_LIBRARY_PATH) +endif ifeq ($(PLATFORM),PLATFORM_WEB) # -Os # size optimization # -O2 # optimization level 2, if used, also set --memory-init-file 0 @@ -346,6 +387,34 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDLIBS += -lglfw endif endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + ifeq ($(PLATFORM_OS),WINDOWS) + # Libraries for Windows desktop compilation + LDLIBS = -lraylib -lSDL2 -lSDL2main -lopengl32 -lgdi32 + endif + ifeq ($(PLATFORM_OS),LINUX) + # Libraries for Debian GNU/Linux desktop compiling + # NOTE: Required packages: libegl1-mesa-dev + LDLIBS = -lraylib -lSDL2 -lSDL2main -lGL -lm -lpthread -ldl -lrt + + # On X11 requires also below libraries + LDLIBS += -lX11 + # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them + #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + + # On Wayland windowing system, additional libraries requires + ifeq ($(USE_WAYLAND_DISPLAY),TRUE) + LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon + endif + # Explicit link to libc + ifeq ($(RAYLIB_LIBTYPE),SHARED) + LDLIBS += -lc + endif + + # NOTE: On ARM 32bit arch, miniaudio requires atomics library + LDLIBS += -latomic + endif +endif ifeq ($(PLATFORM),PLATFORM_DRM) # Libraries for DRM compiling # NOTE: Required packages: libasound2-dev (ALSA) @@ -359,97 +428,99 @@ endif # Define source code object files required #------------------------------------------------------------------------------------------------ CORE = \ - core/core_basic_window \ - core/core_basic_screen_manager \ - core/core_input_keys \ - core/core_input_mouse \ - core/core_input_mouse_wheel \ - core/core_input_gamepad \ - core/core_input_gamepad_info \ - core/core_input_multitouch \ - core/core_input_gestures \ - core/core_input_gestures_web \ core/core_2d_camera \ - core/core_2d_camera_platformer \ core/core_2d_camera_mouse_zoom \ + core/core_2d_camera_platformer \ core/core_2d_camera_split_screen \ - core/core_3d_camera_mode \ - core/core_3d_camera_free \ core/core_3d_camera_first_person \ + core/core_3d_camera_free \ + core/core_3d_camera_mode \ core/core_3d_camera_split_screen \ core/core_3d_picking \ - core/core_world_screen \ + core/core_automation_events \ + core/core_basic_screen_manager \ + core/core_basic_window \ + core/core_custom_frame_control \ core/core_custom_logging \ core/core_drop_files \ + core/core_input_gamepad \ + core/core_input_gamepad_info \ + core/core_input_gestures \ + core/core_input_gestures_web \ + core/core_input_keys \ + core/core_input_mouse \ + core/core_input_mouse_wheel \ + core/core_input_multitouch \ + core/core_loading_thread \ core/core_random_values \ core/core_scissor_test \ + core/core_smooth_pixelperfect \ core/core_storage_values \ core/core_vr_simulator \ - core/core_loading_thread \ core/core_window_flags \ core/core_window_letterbox \ core/core_window_should_close \ - core/core_smooth_pixelperfect \ - core/core_custom_frame_control + core/core_world_screen SHAPES = \ shapes/shapes_basic_shapes \ shapes/shapes_bouncing_ball \ - shapes/shapes_colors_palette \ - shapes/shapes_logo_raylib \ - shapes/shapes_logo_raylib_anim \ - shapes/shapes_rectangle_scaling \ - shapes/shapes_lines_bezier \ shapes/shapes_collision_area \ - shapes/shapes_following_eyes \ + shapes/shapes_colors_palette \ + shapes/shapes_draw_circle_sector \ + shapes/shapes_draw_rectangle_rounded \ + shapes/shapes_draw_ring \ shapes/shapes_easings_ball_anim \ shapes/shapes_easings_box_anim \ shapes/shapes_easings_rectangle_array \ - shapes/shapes_draw_ring \ - shapes/shapes_draw_circle_sector \ - shapes/shapes_draw_rectangle_rounded \ + shapes/shapes_following_eyes \ + shapes/shapes_lines_bezier \ + shapes/shapes_logo_raylib \ + shapes/shapes_logo_raylib_anim \ + shapes/shapes_rectangle_scaling \ + shapes/shapes_splines_drawing \ shapes/shapes_top_down_lights TEXTURES = \ - textures/textures_logo_raylib \ - textures/textures_mouse_painting \ - textures/textures_srcrec_dstrec \ + textures/textures_background_scrolling \ + textures/textures_blend_modes \ + textures/textures_bunnymark \ + textures/textures_draw_tiled \ + textures/textures_fog_of_war \ + textures/textures_gif_player \ textures/textures_image_drawing \ textures/textures_image_generation \ textures/textures_image_loading \ textures/textures_image_processing \ textures/textures_image_rotate \ textures/textures_image_text \ - textures/textures_to_image \ - textures/textures_raw_data \ - textures/textures_particles_blending \ + textures/textures_logo_raylib \ + textures/textures_mouse_painting \ textures/textures_npatch_drawing \ - textures/textures_background_scrolling \ + textures/textures_particles_blending \ + textures/textures_polygon \ + textures/textures_raw_data \ textures/textures_sprite_anim \ textures/textures_sprite_button \ textures/textures_sprite_explosion \ + textures/textures_srcrec_dstrec \ + textures/textures_svg_loading \ textures/textures_textured_curve \ - textures/textures_bunnymark \ - textures/textures_blend_modes \ - textures/textures_draw_tiled \ - textures/textures_polygon \ - textures/textures_gif_player \ - textures/textures_fog_of_war \ - textures/textures_svg_loading + textures/textures_to_image TEXT = \ - text/text_raylib_fonts \ - text/text_font_spritefont \ - text/text_font_loading \ + text/text_codepoints_loading \ + text/text_draw_3d \ text/text_font_filters \ + text/text_font_loading \ text/text_font_sdf \ + text/text_font_spritefont \ text/text_format_text \ text/text_input_box \ - text/text_writing_anim \ + text/text_raylib_fonts \ text/text_rectangle_bounds \ text/text_unicode \ - text/text_draw_3d \ - text/text_codepoints_loading + text/text_writing_anim MODELS = \ models/models_animation \ @@ -459,50 +530,52 @@ MODELS = \ models/models_draw_cube_texture \ models/models_first_person_maze \ models/models_geometric_shapes \ - models/models_mesh_generation \ - models/models_mesh_picking \ + models/models_heightmap \ models/models_loading \ - models/models_loading_vox \ models/models_loading_gltf \ models/models_loading_m3d \ + models/models_loading_vox \ + models/models_mesh_generation \ + models/models_mesh_picking \ models/models_orthographic_projection \ models/models_rlgl_solar_system \ models/models_skybox \ - models/models_yaw_pitch_roll \ - models/models_heightmap \ - models/models_waving_cubes + models/models_waving_cubes \ + models/models_yaw_pitch_roll SHADERS = \ - shaders/shaders_model_shader \ - shaders/shaders_shapes_textures \ + shaders/shaders_basic_lighting \ shaders/shaders_custom_uniform \ - shaders/shaders_postprocessing \ - shaders/shaders_palette_switch \ - shaders/shaders_raymarching \ - shaders/shaders_texture_drawing \ - shaders/shaders_texture_waves \ - shaders/shaders_texture_outline \ - shaders/shaders_julia_set \ + shaders/shaders_deferred_render \ shaders/shaders_eratosthenes \ - shaders/shaders_basic_lighting \ shaders/shaders_fog \ - shaders/shaders_simple_mask \ - shaders/shaders_spotlight \ shaders/shaders_hot_reloading \ + shaders/shaders_hybrid_render \ + shaders/shaders_julia_set \ shaders/shaders_lightmap \ shaders/shaders_mesh_instancing \ + shaders/shaders_model_shader \ shaders/shaders_multi_sample2d \ - shaders/shaders_write_depth \ - shaders/shaders_hybrid_render + shaders/shaders_palette_switch \ + shaders/shaders_postprocessing \ + shaders/shaders_raymarching \ + shaders/shaders_shapes_textures \ + shaders/shaders_simple_mask \ + shaders/shaders_spotlight \ + shaders/shaders_texture_drawing \ + shaders/shaders_texture_outline \ + shaders/shaders_texture_tiling \ + shaders/shaders_texture_waves \ + shaders/shaders_write_depth AUDIO = \ + audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ audio/audio_raw_stream \ audio/audio_sound_loading \ audio/audio_sound_multi \ - audio/audio_stream_effects \ - audio/audio_mixed_processor + audio/audio_stream_effects OTHERS = \ others/easings_testbed \ @@ -533,6 +606,8 @@ others: $(OTHERS) %: %.c ifeq ($(PLATFORM),PLATFORM_ANDROID) $(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$< +else ifeq ($(PLATFORM),PLATFORM_WEB) + $(MAKE) -f Makefile.Web $@ else $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) endif diff --git a/raylib/examples/Makefile.Web b/raylib/examples/Makefile.Web index 267e023..e8a7266 100644 --- a/raylib/examples/Makefile.Web +++ b/raylib/examples/Makefile.Web @@ -30,7 +30,7 @@ PLATFORM ?= PLATFORM_WEB # Define required raylib variables PROJECT_NAME ?= raylib_examples -RAYLIB_VERSION ?= 4.5.0 +RAYLIB_VERSION ?= 5.0.0 RAYLIB_PATH ?= .. # Locations of raylib.h and libraylib.a/libraylib.so @@ -138,7 +138,7 @@ endif # Define default make program: MAKE #------------------------------------------------------------------------------------------------ -MAKE ?= make +MAKE ?= emmake make ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM_OS),WINDOWS) @@ -149,7 +149,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID) MAKE = mingw32-make endif ifeq ($(PLATFORM),PLATFORM_WEB) - MAKE = mingw32-make + MAKE = emmake make endif # Define compiler flags: CFLAGS @@ -334,95 +334,99 @@ endif # Define source code object files required #------------------------------------------------------------------------------------------------ CORE = \ - core/core_basic_window \ - core/core_basic_screen_manager \ - core/core_input_keys \ - core/core_input_mouse \ - core/core_input_mouse_wheel \ - core/core_input_gamepad \ - core/core_input_multitouch \ - core/core_input_gestures \ - core/core_input_gestures_web \ core/core_2d_camera \ - core/core_2d_camera_platformer \ core/core_2d_camera_mouse_zoom \ + core/core_2d_camera_platformer \ core/core_2d_camera_split_screen \ - core/core_3d_camera_mode \ - core/core_3d_camera_free \ core/core_3d_camera_first_person \ + core/core_3d_camera_free \ + core/core_3d_camera_mode \ core/core_3d_camera_split_screen \ core/core_3d_picking \ - core/core_world_screen \ + core/core_automation_events \ + core/core_basic_screen_manager \ + core/core_basic_window \ + core/core_custom_frame_control \ core/core_custom_logging \ core/core_drop_files \ + core/core_input_gamepad \ + core/core_input_gamepad_info \ + core/core_input_gestures \ + core/core_input_gestures_web \ + core/core_input_keys \ + core/core_input_mouse \ + core/core_input_mouse_wheel \ + core/core_input_multitouch \ + core/core_loading_thread \ core/core_random_values \ core/core_scissor_test \ + core/core_smooth_pixelperfect \ core/core_storage_values \ core/core_vr_simulator \ core/core_window_flags \ core/core_window_letterbox \ core/core_window_should_close \ - core/core_smooth_pixelperfect \ - core/core_custom_frame_control \ - core/core_loading_thread + core/core_world_screen SHAPES = \ shapes/shapes_basic_shapes \ shapes/shapes_bouncing_ball \ - shapes/shapes_colors_palette \ - shapes/shapes_logo_raylib \ - shapes/shapes_logo_raylib_anim \ - shapes/shapes_rectangle_scaling \ - shapes/shapes_lines_bezier \ shapes/shapes_collision_area \ - shapes/shapes_following_eyes \ + shapes/shapes_colors_palette \ + shapes/shapes_draw_circle_sector \ + shapes/shapes_draw_rectangle_rounded \ + shapes/shapes_draw_ring \ shapes/shapes_easings_ball_anim \ shapes/shapes_easings_box_anim \ shapes/shapes_easings_rectangle_array \ - shapes/shapes_draw_ring \ - shapes/shapes_draw_circle_sector \ - shapes/shapes_draw_rectangle_rounded \ + shapes/shapes_following_eyes \ + shapes/shapes_lines_bezier \ + shapes/shapes_logo_raylib \ + shapes/shapes_logo_raylib_anim \ + shapes/shapes_rectangle_scaling \ + shapes/shapes_splines_drawing \ shapes/shapes_top_down_lights TEXTURES = \ - textures/textures_logo_raylib \ - textures/textures_mouse_painting \ - textures/textures_srcrec_dstrec \ + textures/textures_background_scrolling \ + textures/textures_blend_modes \ + textures/textures_bunnymark \ + textures/textures_draw_tiled \ + textures/textures_fog_of_war \ + textures/textures_gif_player \ textures/textures_image_drawing \ textures/textures_image_generation \ textures/textures_image_loading \ textures/textures_image_processing \ + textures/textures_image_rotate \ textures/textures_image_text \ - textures/textures_to_image \ - textures/textures_raw_data \ - textures/textures_particles_blending \ + textures/textures_logo_raylib \ + textures/textures_mouse_painting \ textures/textures_npatch_drawing \ - textures/textures_background_scrolling \ + textures/textures_particles_blending \ + textures/textures_polygon \ + textures/textures_raw_data \ textures/textures_sprite_anim \ textures/textures_sprite_button \ textures/textures_sprite_explosion \ + textures/textures_srcrec_dstrec \ + textures/textures_svg_loading \ textures/textures_textured_curve \ - textures/textures_bunnymark \ - textures/textures_blend_modes \ - textures/textures_draw_tiled \ - textures/textures_polygon \ - textures/textures_gif_player \ - textures/textures_fog_of_war \ - textures/textures_svg_loading + textures/textures_to_image TEXT = \ - text/text_raylib_fonts \ - text/text_font_spritefont \ - text/text_font_loading \ + text/text_codepoints_loading \ + text/text_draw_3d \ text/text_font_filters \ + text/text_font_loading \ text/text_font_sdf \ + text/text_font_spritefont \ text/text_format_text \ text/text_input_box \ - text/text_writing_anim \ + text/text_raylib_fonts \ text/text_rectangle_bounds \ text/text_unicode \ - text/text_draw_3d \ - text/text_codepoints_loading + text/text_writing_anim MODELS = \ models/models_animation \ @@ -432,49 +436,60 @@ MODELS = \ models/models_draw_cube_texture \ models/models_first_person_maze \ models/models_geometric_shapes \ - models/models_mesh_generation \ - models/models_mesh_picking \ + models/models_heightmap \ models/models_loading \ - models/models_loading_vox \ models/models_loading_gltf \ models/models_loading_m3d \ + models/models_loading_vox \ + models/models_mesh_generation \ + models/models_mesh_picking \ models/models_orthographic_projection \ models/models_rlgl_solar_system \ models/models_skybox \ - models/models_yaw_pitch_roll \ - models/models_heightmap \ - models/models_waving_cubes + models/models_waving_cubes \ + models/models_yaw_pitch_roll SHADERS = \ - shaders/shaders_model_shader \ - shaders/shaders_shapes_textures \ + shaders/shaders_basic_lighting \ shaders/shaders_custom_uniform \ - shaders/shaders_postprocessing \ - shaders/shaders_palette_switch \ - shaders/shaders_raymarching \ - shaders/shaders_texture_drawing \ - shaders/shaders_texture_waves \ - shaders/shaders_texture_outline \ - shaders/shaders_julia_set \ + shaders/shaders_deferred_render \ shaders/shaders_eratosthenes \ - shaders/shaders_basic_lighting \ shaders/shaders_fog \ - shaders/shaders_simple_mask \ - shaders/shaders_spotlight \ shaders/shaders_hot_reloading \ + shaders/shaders_hybrid_render \ + shaders/shaders_julia_set \ shaders/shaders_lightmap \ shaders/shaders_mesh_instancing \ + shaders/shaders_model_shader \ shaders/shaders_multi_sample2d \ - shaders/shaders_write_depth \ - shaders/shaders_hybrid_render + shaders/shaders_palette_switch \ + shaders/shaders_postprocessing \ + shaders/shaders_raymarching \ + shaders/shaders_shapes_textures \ + shaders/shaders_simple_mask \ + shaders/shaders_spotlight \ + shaders/shaders_texture_drawing \ + shaders/shaders_texture_outline \ + shaders/shaders_texture_tiling \ + shaders/shaders_texture_waves \ + shaders/shaders_write_depth AUDIO = \ + audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ audio/audio_raw_stream \ audio/audio_sound_loading \ - audio/audio_stream_effects \ - audio/audio_mixed_processor + audio/audio_sound_multi \ + audio/audio_stream_effects + +OTHERS = \ + others/easings_testbed \ + others/embedded_files_loading \ + others/raylib_opengl_interop \ + others/raymath_vector_angle \ + others/rlgl_compute_shader \ + others/rlgl_standalone CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST)) @@ -492,73 +507,83 @@ shaders: $(SHADERS) audio: $(AUDIO) # Compile CORE examples -core/core_basic_window: core/core_basic_window.c +core/core_2d_camera: core/core_2d_camera.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_basic_screen_manager: core/core_basic_screen_manager.c +core/core_2d_camera_mouse_zoom: core/core_2d_camera_mouse_zoom.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_input_keys: core/core_input_keys.c +core/core_2d_camera_platformer: core/core_2d_camera_platformer.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_input_mouse: core/core_input_mouse.c +core/core_2d_camera_split_screen: core/core_2d_camera_split_screen.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_input_mouse_wheel: core/core_input_mouse_wheel.c +core/core_3d_camera_first_person: core/core_3d_camera_first_person.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_input_gamepad: core/core_input_gamepad.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file core/resources/ps3.png@resources/ps3.png \ - --preload-file core/resources/xbox.png@resources/xbox.png - -core/core_input_multitouch: core/core_input_multitouch.c +core/core_3d_camera_free: core/core_3d_camera_free.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_input_gestures: core/core_input_gestures.c +core/core_3d_camera_mode: core/core_3d_camera_mode.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_input_gestures_web: core/core_input_gestures_web.c +core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_2d_camera: core/core_2d_camera.c +core/core_3d_picking: core/core_3d_picking.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - -core/core_2d_camera_platformer: core/core_2d_camera_platformer.c + +core/core_automation_events : core/core_automation_events.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +core/core_basic_window: core/core_basic_window.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_2d_camera_mouse_zoom: core/core_2d_camera_mouse_zoom.c +core/core_basic_screen_manager: core/core_basic_screen_manager.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - -core/core_2d_camera_split_screen: core/core_2d_camera_split_screen.c + +core/core_custom_frame_control: core/core_custom_frame_control.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_3d_camera_mode: core/core_3d_camera_mode.c +core/core_custom_logging: core/core_custom_logging.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_3d_camera_free: core/core_3d_camera_free.c +core/core_drop_files: core/core_drop_files.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 -s FORCE_FILESYSTEM=1 + +core/core_input_gamepad: core/core_input_gamepad.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file core/resources/ps3.png@resources/ps3.png \ + --preload-file core/resources/xbox.png@resources/xbox.png + +core/core_input_gamepad_info: core/core_input_gamepad_info.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_3d_camera_first_person: core/core_3d_camera_first_person.c +core/core_input_gestures: core/core_input_gestures.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - -core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c + +core/core_input_gestures_web: core/core_input_gestures_web.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_3d_picking: core/core_3d_picking.c +core/core_input_keys: core/core_input_keys.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_world_screen: core/core_world_screen.c +core/core_input_mouse: core/core_input_mouse.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_custom_logging: core/core_custom_logging.c +core/core_input_mouse_wheel: core/core_input_mouse_wheel.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_window_letterbox: core/core_window_letterbox.c +core/core_input_multitouch: core/core_input_multitouch.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_drop_files: core/core_drop_files.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 -s FORCE_FILESYSTEM=1 +# NOTE: To use multi-threading raylib must be compiled with multi-theading support (-s USE_PTHREADS=1) +# WARNING: For security reasons multi-threading is not supported on browsers, it requires cross-origin isolation (Oct.2021) +# WARNING: It requires raylib to be compiled using -pthread, so atomic operations and thread-local data (if any) +# in its source were transformed to non-atomic operations and non-thread-local data +core/core_loading_thread: core/core_loading_thread.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s USE_PTHREADS=1 core/core_random_values: core/core_random_values.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -566,6 +591,9 @@ core/core_random_values: core/core_random_values.c core/core_scissor_test: core/core_scissor_test.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_smooth_pixelperfect: core/core_smooth_pixelperfect.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_storage_values: core/core_storage_values.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s FORCE_FILESYSTEM=1 @@ -576,21 +604,14 @@ core/core_vr_simulator: core/core_vr_simulator.c core/core_window_flags: core/core_window_flags.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_smooth_pixelperfect: core/core_smooth_pixelperfect.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - -core/core_custom_frame_control: core/core_custom_frame_control.c +core/core_window_letterbox: core/core_window_letterbox.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) core/core_window_should_close: core/core_window_should_close.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -# NOTE: To use multi-threading raylib must be compiled with multi-theading support (-s USE_PTHREADS=1) -# WARNING: For security reasons multi-threading is not supported on browsers, it requires cross-origin isolation (Oct.2021) -# WARNING: It requires raylib to be compiled using -pthread, so atomic operations and thread-local data (if any) -# in its source were transformed to non-atomic operations and non-thread-local data -core/core_loading_thread: core/core_loading_thread.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s USE_PTHREADS=1 +core/core_world_screen: core/core_world_screen.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) # Compile SHAPES examples @@ -600,67 +621,78 @@ shapes/shapes_basic_shapes: shapes/shapes_basic_shapes.c shapes/shapes_bouncing_ball: shapes/shapes_bouncing_ball.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_colors_palette: shapes/shapes_colors_palette.c +shapes/shapes_collision_area: shapes/shapes_collision_area.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c +shapes/shapes_colors_palette: shapes/shapes_colors_palette.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c +shapes/shapes_draw_circle_sector: shapes/shapes_draw_circle_sector.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_rectangle_scaling: shapes/shapes_rectangle_scaling.c +shapes/shapes_draw_rectangle_rounded: shapes/shapes_draw_rectangle_rounded.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +shapes/shapes_draw_ring: shapes/shapes_draw_ring.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c +shapes/shapes_easings_ball_anim: shapes/shapes_easings_ball_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_collision_area: shapes/shapes_collision_area.c +shapes/shapes_easings_box_anim: shapes/shapes_easings_box_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_following_eyes: shapes/shapes_following_eyes.c +shapes/shapes_easings_rectangle_array: shapes/shapes_easings_rectangle_array.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_easings_ball_anim: shapes/shapes_easings_ball_anim.c +shapes/shapes_following_eyes: shapes/shapes_following_eyes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_easings_box_anim: shapes/shapes_easings_box_anim.c +shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_easings_rectangle_array: shapes/shapes_easings_rectangle_array.c +shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_draw_ring: shapes/shapes_draw_ring.c +shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_draw_circle_sector: shapes/shapes_draw_circle_sector.c +shapes/shapes_rectangle_scaling: shapes/shapes_rectangle_scaling.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -shapes/shapes_draw_rectangle_rounded: shapes/shapes_draw_rectangle_rounded.c +shapes/shapes_splines_drawing: shapes/shapes_splines_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) shapes/shapes_top_down_lights: shapes/shapes_top_down_lights.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + # Compile TEXTURES examples -textures/textures_logo_raylib: textures/textures_logo_raylib.c +textures/textures_background_scrolling: textures/textures_background_scrolling.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png + --preload-file textures/resources/cyberpunk_street_background.png@resources/cyberpunk_street_background.png \ + --preload-file textures/resources/cyberpunk_street_midground.png@resources/cyberpunk_street_midground.png \ + --preload-file textures/resources/cyberpunk_street_foreground.png@resources/cyberpunk_street_foreground.png -textures/textures_mouse_painting: textures/textures_mouse_painting.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +textures/textures_blend_modes: textures/textures_blend_modes.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file textures/resources/cyberpunk_street_background.png@resources/cyberpunk_street_background.png \ + --preload-file textures/resources/cyberpunk_street_foreground.png@resources/cyberpunk_street_foreground.png -textures/textures_sprite_anim: textures/textures_sprite_anim.c +textures/textures_bunnymark: textures/textures_bunnymark.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/scarfy.png@resources/scarfy.png + --preload-file textures/resources/wabbit_alpha.png@resources/wabbit_alpha.png -textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c +textures/textures_draw_tiled: textures/textures_draw_tiled.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/scarfy.png@resources/scarfy.png + --preload-file textures/resources/patterns.png@resources/patterns.png -textures/textures_image_loading: textures/textures_image_loading.c +textures/textures_fog_of_war: textures/textures_fog_of_war.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +textures/textures_gif_player: textures/textures_gif_player.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png + --preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif textures/textures_image_drawing: textures/textures_image_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ @@ -671,36 +703,49 @@ textures/textures_image_drawing: textures/textures_image_drawing.c textures/textures_image_generation: textures/textures_image_generation.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 +textures/textures_image_loading: textures/textures_image_loading.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png + textures/textures_image_processing: textures/textures_image_processing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/parrots.png@resources/parrots.png +textures/textures_image_rotate: textures/textures_image_rotate.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file textures/resources/raylib_logo.png + textures/textures_image_text: textures/textures_image_text.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file textures/resources/parrots.png@resources/parrots.png \ --preload-file textures/resources/KAISG.ttf@resources/KAISG.ttf -textures/textures_to_image: textures/textures_to_image.c +textures/textures_logo_raylib: textures/textures_logo_raylib.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png -textures/textures_raw_data: textures/textures_raw_data.c +textures/textures_mouse_painting: textures/textures_mouse_painting.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +textures/textures_npatch_drawing: textures/textures_npatch_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw + --preload-file textures/resources/ninepatch_button.png@resources/ninepatch_button.png textures/textures_particles_blending: textures/textures_particles_blending.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/spark_flame.png@resources/spark_flame.png -textures/textures_npatch_drawing: textures/textures_npatch_drawing.c +textures/textures_polygon: textures/textures_polygon.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/ninepatch_button.png@resources/ninepatch_button.png + --preload-file textures/resources/cat.png@resources/cat.png -textures/textures_background_scrolling: textures/textures_background_scrolling.c +textures/textures_raw_data: textures/textures_raw_data.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/cyberpunk_street_background.png@resources/cyberpunk_street_background.png \ - --preload-file textures/resources/cyberpunk_street_midground.png@resources/cyberpunk_street_midground.png \ - --preload-file textures/resources/cyberpunk_street_foreground.png@resources/cyberpunk_street_foreground.png + --preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw + +textures/textures_sprite_anim: textures/textures_sprite_anim.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file textures/resources/scarfy.png@resources/scarfy.png textures/textures_sprite_button: textures/textures_sprite_button.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ @@ -712,51 +757,35 @@ textures/textures_sprite_explosion: textures/textures_sprite_explosion.c --preload-file textures/resources/explosion.png@resources/explosion.png \ --preload-file textures/resources/boom.wav@resources/boom.wav -textures/textures_textured_curve: textures/textures_textured_curve.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/road.png@resources/road.png - -textures/textures_bunnymark: textures/textures_bunnymark.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/wabbit_alpha.png@resources/wabbit_alpha.png - -textures/textures_blend_modes: textures/textures_blend_modes.c +textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/cyberpunk_street_background.png@resources/cyberpunk_street_background.png \ - --preload-file textures/resources/cyberpunk_street_foreground.png@resources/cyberpunk_street_foreground.png + --preload-file textures/resources/scarfy.png@resources/scarfy.png -textures/textures_draw_tiled: textures/textures_draw_tiled.c +textures/textures_svg_loading: textures/textures_svg_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/patterns.png@resources/patterns.png + --preload-file textures/resources/test.svg -textures/textures_polygon: textures/textures_polygon.c +textures/textures_textured_curve: textures/textures_textured_curve.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/cat.png@resources/cat.png + --preload-file textures/resources/road.png@resources/road.png -textures/textures_gif_player: textures/textures_gif_player.c +textures/textures_to_image: textures/textures_to_image.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif + --preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png -textures/textures_fog_of_war: textures/textures_fog_of_war.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) # Compile TEXT examples -text/text_raylib_fonts: text/text_raylib_fonts.c +text/text_codepoints_loading: text/text_codepoints_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file text/resources/fonts/alagard.png@resources/fonts/alagard.png \ - --preload-file text/resources/fonts/pixelplay.png@resources/fonts/pixelplay.png \ - --preload-file text/resources/fonts/mecha.png@resources/fonts/mecha.png \ - --preload-file text/resources/fonts/setback.png@resources/fonts/setback.png \ - --preload-file text/resources/fonts/romulus.png@resources/fonts/romulus.png \ - --preload-file text/resources/fonts/pixantiqua.png@resources/fonts/pixantiqua.png \ - --preload-file text/resources/fonts/alpha_beta.png@resources/fonts/alpha_beta.png \ - --preload-file text/resources/fonts/jupiter_crash.png@resources/fonts/jupiter_crash.png - -text/text_font_spritefont: text/text_font_spritefont.c + --preload-file text/resources/DotGothic16-Regular.ttf@resources/DotGothic16-Regular.ttf + +text/text_draw_3d: text/text_draw_3d.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file text/resources/custom_mecha.png@resources/custom_mecha.png \ - --preload-file text/resources/custom_alagard.png@resources/custom_alagard.png \ - --preload-file text/resources/custom_jupiter_crash.png@resources/custom_jupiter_crash.png + --preload-file text/resources/shaders/glsl100/alpha_discard.fs@resources/shaders/glsl100/alpha_discard.fs + +text/text_font_filters: text/text_font_filters.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ + --preload-file text/resources/KAISG.ttf@resources/KAISG.ttf text/text_font_loading: text/text_font_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ @@ -764,23 +793,33 @@ text/text_font_loading: text/text_font_loading.c --preload-file text/resources/pixantiqua.png@resources/pixantiqua.png \ --preload-file text/resources/pixantiqua.ttf@resources/pixantiqua.ttf -text/text_font_filters: text/text_font_filters.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ - --preload-file text/resources/KAISG.ttf@resources/KAISG.ttf - text/text_font_sdf: text/text_font_sdf.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file text/resources/anonymous_pro_bold.ttf@resources/anonymous_pro_bold.ttf \ --preload-file text/resources/shaders/glsl100/sdf.fs@resources/shaders/glsl100/sdf.fs +text/text_font_spritefont: text/text_font_spritefont.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file text/resources/custom_mecha.png@resources/custom_mecha.png \ + --preload-file text/resources/custom_alagard.png@resources/custom_alagard.png \ + --preload-file text/resources/custom_jupiter_crash.png@resources/custom_jupiter_crash.png + text/text_format_text: text/text_format_text.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) text/text_input_box: text/text_input_box.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -text/text_writing_anim: text/text_writing_anim.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +text/text_raylib_fonts: text/text_raylib_fonts.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file text/resources/fonts/alagard.png@resources/fonts/alagard.png \ + --preload-file text/resources/fonts/pixelplay.png@resources/fonts/pixelplay.png \ + --preload-file text/resources/fonts/mecha.png@resources/fonts/mecha.png \ + --preload-file text/resources/fonts/setback.png@resources/fonts/setback.png \ + --preload-file text/resources/fonts/romulus.png@resources/fonts/romulus.png \ + --preload-file text/resources/fonts/pixantiqua.png@resources/fonts/pixantiqua.png \ + --preload-file text/resources/fonts/alpha_beta.png@resources/fonts/alpha_beta.png \ + --preload-file text/resources/fonts/jupiter_crash.png@resources/fonts/jupiter_crash.png text/text_rectangle_bounds: text/text_rectangle_bounds.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -794,13 +833,9 @@ text/text_unicode: text/text_unicode.c --preload-file text/resources/symbola.fnt@resources/symbola.fnt \ --preload-file text/resources/symbola.png@resources/symbola.png -text/text_draw_3d: text/text_draw_3d.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file text/resources/shaders/glsl100/alpha_discard.fs@resources/shaders/glsl100/alpha_discard.fs +text/text_writing_anim: text/text_writing_anim.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -text/text_codepoints_loading: text/text_codepoints_loading.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file text/resources/DotGothic16-Regular.ttf@resources/DotGothic16-Regular.ttf # Compile MODELS examples models/models_animation: models/models_animation.c @@ -832,26 +867,16 @@ models/models_first_person_maze: models/models_first_person_maze.c models/models_geometric_shapes: models/models_geometric_shapes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - -models/models_mesh_generation: models/models_mesh_generation.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - -models/models_mesh_picking: models/models_mesh_picking.c + +models/models_heightmap: models/models_heightmap.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file models/resources/models/obj/turret.obj@resources/models/obj/turret.obj \ - --preload-file models/resources/models/obj/turret_diffuse.png@resources/models/obj/turret_diffuse.png + --preload-file models/resources/heightmap.png@resources/heightmap.png models/models_loading: models/models_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file models/resources/models/obj/castle.obj@resources/models/obj/castle.obj \ --preload-file models/resources/models/obj/castle_diffuse.png@resources/models/obj/castle_diffuse.png - -models/models_loading_vox: models/models_loading_vox.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ - --preload-file models/resources/models/vox/chr_knight.vox@resources/models/vox/chr_knight.vox \ - --preload-file models/resources/models/vox/chr_sword.vox@resources/models/vox/chr_sword.vox \ - --preload-file models/resources/models/vox/monu9.vox@resources/models/vox/monu9.vox - + models/models_loading_gltf: models/models_loading_gltf.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb @@ -859,6 +884,20 @@ models/models_loading_gltf: models/models_loading_gltf.c models/models_loading_m3d: models/models_loading_m3d.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file models/resources/models/m3d/cesium_man.m3d@resources/models/m3d/cesium_man.m3d + +models/models_loading_vox: models/models_loading_vox.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ + --preload-file models/resources/models/vox/chr_knight.vox@resources/models/vox/chr_knight.vox \ + --preload-file models/resources/models/vox/chr_sword.vox@resources/models/vox/chr_sword.vox \ + --preload-file models/resources/models/vox/monu9.vox@resources/models/vox/monu9.vox + +models/models_mesh_generation: models/models_mesh_generation.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +models/models_mesh_picking: models/models_mesh_picking.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file models/resources/models/obj/turret.obj@resources/models/obj/turret.obj \ + --preload-file models/resources/models/obj/turret_diffuse.png@resources/models/obj/turret_diffuse.png models/models_orthographic_projection: models/models_orthographic_projection.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -874,30 +913,21 @@ models/models_skybox: models/models_skybox.c --preload-file models/resources/shaders/glsl100/cubemap.vs@resources/shaders/glsl100/cubemap.vs \ --preload-file models/resources/shaders/glsl100/cubemap.fs@resources/shaders/glsl100/cubemap.fs +models/models_waving_cubes: models/models_waving_cubes.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + models/models_yaw_pitch_roll: models/models_yaw_pitch_roll.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file models/resources/models/obj/plane.obj@resources/models/obj/plane.obj \ --preload-file models/resources/models/obj/plane_diffuse.png@resources/models/obj/plane_diffuse.png -models/models_heightmap: models/models_heightmap.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file models/resources/heightmap.png@resources/heightmap.png - -models/models_waving_cubes: models/models_waving_cubes.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) # Compile SHADER examples -shaders/shaders_model_shader: shaders/shaders_model_shader.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ - --preload-file shaders/resources/models/watermill.obj@resources/models/watermill.obj \ - --preload-file shaders/resources/models/watermill_diffuse.png@resources/models/watermill_diffuse.png \ - --preload-file shaders/resources/shaders/glsl100/grayscale.fs@resources/shaders/glsl100/grayscale.fs - -shaders/shaders_shapes_textures: shaders/shaders_shapes_textures.c +shaders/shaders_basic_lighting: shaders/shaders_basic_lighting.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \ - --preload-file shaders/resources/shaders/glsl100/base.vs@resources/shaders/glsl100/base.vs \ - --preload-file shaders/resources/shaders/glsl100/grayscale.fs@resources/shaders/glsl100/grayscale.fs + --preload-file shaders/resources/texel_checker.png@resources/texel_checker.png \ + --preload-file shaders/resources/shaders/glsl100/lighting.fs@resources/shaders/glsl100/lighting.fs \ + --preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ @@ -905,48 +935,78 @@ shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.c --preload-file shaders/resources/models/barracks_diffuse.png@resources/models/barracks_diffuse.png \ --preload-file shaders/resources/shaders/glsl100/swirl.fs@resources/shaders/glsl100/swirl.fs -shaders/shaders_postprocessing: shaders/shaders_postprocessing.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ - --preload-file shaders/resources/models/church.obj@resources/models/church.obj \ - --preload-file shaders/resources/models/church_diffuse.png@resources/models/church_diffuse.png \ - --preload-file shaders/resources/shaders/glsl100@resources/shaders/glsl100 - -shaders/shaders_palette_switch: shaders/shaders_palette_switch.c +shaders/shaders_deferred_render: shaders/shaders_deferred_render.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/palette_switch.fs@resources/shaders/glsl100/palette_switch.fs + --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \ + --preload-file shaders/resources/shaders/glsl330/gbuffer.vs@resources/shaders/glsl330/gbuffer.vs \ + --preload-file shaders/resources/shaders/glsl330/gbuffer.fs@resources/shaders/glsl330/gbuffer.fs \ + --preload-file shaders/resources/shaders/glsl330/deferred_shading.fs@resources/shaders/glsl330/deferred_shading.fs \ + --preload-file shaders/resources/shaders/glsl330/deferred_shading.fs@resources/shaders/glsl330/deferred_shading.fs -shaders/shaders_raymarching: shaders/shaders_raymarching.c +shaders/shaders_eratosthenes: shaders/shaders_eratosthenes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/raymarching.fs@resources/shaders/glsl100/raymarching.fs + --preload-file shaders/resources/shaders/glsl100/eratosthenes.fs@resources/shaders/glsl100/eratosthenes.fs -shaders/shaders_texture_drawing: shaders/shaders_texture_drawing.c +shaders/shaders_fog: shaders/shaders_fog.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/cubes_panning.fs@resources/shaders/glsl100/cubes_panning.fs + --preload-file shaders/resources/texel_checker.png@resources/texel_checker.png \ + --preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs \ + --preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs -shaders/shaders_texture_waves: shaders/shaders_texture_waves.c +shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s FORCE_FILESYSTEM=1 \ + --preload-file shaders/resources/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs + +shaders/shaders_hybrid_render: shaders/shaders_hybrid_render.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/space.png@resources/space.png \ - --preload-file shaders/resources/shaders/glsl100/wave.fs@resources/shaders/glsl100/wave.fs + --preload-file shaders/resources/shaders/glsl100/hybrid_raymarch.fs@resources/shaders/glsl100/hybrid_raymarch.fs \ + --preload-file shaders/resources/shaders/glsl100/hybrid_raster.fs@resources/shaders/glsl100/hybrid_raster.fs shaders/shaders_julia_set: shaders/shaders_julia_set.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/shaders/glsl100/julia_set.fs@resources/shaders/glsl100/julia_set.fs -shaders/shaders_eratosthenes: shaders/shaders_eratosthenes.c +shaders/shaders_lightmap: shaders/shaders_lightmap.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s FORCE_FILESYSTEM=1 \ + --preload-file shaders/resources/shaders/glsl330/lightmap.vs \ + --preload-file shaders/resources/shaders/glsl330/lightmap.fs \ + --preload-file shaders/resources/cubicmap_atlas.png \ + --preload-file shaders/resources/spark_flame.png + +shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/eratosthenes.fs@resources/shaders/glsl100/eratosthenes.fs + --preload-file shaders/resources/shaders/glsl100/lighting_instancing.vs@resources/shaders/glsl100/lighting_instancing.vs \ + --preload-file shaders/resources/shaders/glsl100/lighting.fs@resources/shaders/glsl100/lighting.fs -shaders/shaders_basic_lighting: shaders/shaders_basic_lighting.c +shaders/shaders_model_shader: shaders/shaders_model_shader.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ + --preload-file shaders/resources/models/watermill.obj@resources/models/watermill.obj \ + --preload-file shaders/resources/models/watermill_diffuse.png@resources/models/watermill_diffuse.png \ + --preload-file shaders/resources/shaders/glsl100/grayscale.fs@resources/shaders/glsl100/grayscale.fs + +shaders/shaders_multi_sample2d: shaders/shaders_multi_sample2d.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/texel_checker.png@resources/texel_checker.png \ - --preload-file shaders/resources/shaders/glsl100/lighting.fs@resources/shaders/glsl100/lighting.fs \ - --preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs + --preload-file shaders/resources/shaders/glsl100/color_mix.fs@resources/shaders/glsl100/color_mix.fs -shaders/shaders_fog: shaders/shaders_fog.c +shaders/shaders_palette_switch: shaders/shaders_palette_switch.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/texel_checker.png@resources/texel_checker.png \ - --preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs \ - --preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs + --preload-file shaders/resources/shaders/glsl100/palette_switch.fs@resources/shaders/glsl100/palette_switch.fs + +shaders/shaders_postprocessing: shaders/shaders_postprocessing.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ + --preload-file shaders/resources/models/church.obj@resources/models/church.obj \ + --preload-file shaders/resources/models/church_diffuse.png@resources/models/church_diffuse.png \ + --preload-file shaders/resources/shaders/glsl100@resources/shaders/glsl100 + +shaders/shaders_raymarching: shaders/shaders_raymarching.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file shaders/resources/shaders/glsl100/raymarching.fs@resources/shaders/glsl100/raymarching.fs + +shaders/shaders_shapes_textures: shaders/shaders_shapes_textures.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \ + --preload-file shaders/resources/shaders/glsl100/base.vs@resources/shaders/glsl100/base.vs \ + --preload-file shaders/resources/shaders/glsl100/grayscale.fs@resources/shaders/glsl100/grayscale.fs shaders/shaders_simple_mask: shaders/shaders_simple_mask.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ @@ -959,34 +1019,36 @@ shaders/shaders_spotlight: shaders/shaders_spotlight.c --preload-file shaders/resources/raysan.png@resources/raysan.png \ --preload-file shaders/resources/shaders/glsl100/spotlight.fs@resources/shaders/glsl100/spotlight.fs -shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s FORCE_FILESYSTEM=1 \ - --preload-file shaders/resources/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs - -shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/lighting_instancing.vs@resources/shaders/glsl100/lighting_instancing.vs \ - --preload-file shaders/resources/shaders/glsl100/lighting.fs@resources/shaders/glsl100/lighting.fs - -shaders/shaders_multi_sample2d: shaders/shaders_multi_sample2d.c +shaders/shaders_texture_drawing: shaders/shaders_texture_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/color_mix.fs@resources/shaders/glsl100/color_mix.fs + --preload-file shaders/resources/shaders/glsl100/cubes_panning.fs@resources/shaders/glsl100/cubes_panning.fs shaders/shaders_texture_outline: shaders/shaders_texture_outline.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/shaders/glsl100/outline.fs@resources/shaders/glsl100/outline.fs \ --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png +shaders/shaders_texture_tiling: shaders/shaders_texture_tiling.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file shaders/resources/shaders/glsl100/tiling.fs@resources/shaders/glsl100/tiling.fs \ + --preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png + +shaders/shaders_texture_waves: shaders/shaders_texture_waves.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file shaders/resources/space.png@resources/space.png \ + --preload-file shaders/resources/shaders/glsl100/wave.fs@resources/shaders/glsl100/wave.fs + shaders/shaders_write_depth: shaders/shaders_write_depth.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/shaders/glsl100/write_depth.fs@resources/shaders/glsl100/write_depth.fs -shaders/shaders_hybrid_render: shaders/shaders_hybrid_render.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/hybrid_raymarch.fs@resources/shaders/glsl100/hybrid_raymarch.fs \ - --preload-file shaders/resources/shaders/glsl100/hybrid_raster.fs@resources/shaders/glsl100/hybrid_raster.fs # Compile AUDIO examples +audio/audio_mixed_processor: audio/audio_mixed_processor.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ + --preload-file audio/resources/country.mp3@resources/country.mp3 \ + --preload-file audio/resources/coin.wav@resources/coin.wav + audio/audio_module_playing: audio/audio_module_playing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file audio/resources/mini1111.xm@resources/mini1111.xm @@ -1003,14 +1065,33 @@ audio/audio_sound_loading: audio/audio_sound_loading.c --preload-file audio/resources/sound.wav@resources/sound.wav \ --preload-file audio/resources/target.ogg@resources/target.ogg +audio/audio_sound_multi: audio/audio_sound_multi.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file audio/resources/sound.wav@resources/sound.wav + audio/audio_stream_effects: audio/audio_stream_effects.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ --preload-file audio/resources/country.mp3@resources/country.mp3 -audio/audio_mixed_processor: audio/audio_mixed_processor.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 \ - --preload-file audio/resources/country.mp3@resources/country.mp3 \ - --preload-file audio/resources/coin.wav@resources/coin.wav + +# Compile OTHERS examples +others/easings_testbed: others/easings_testbed.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +others/embedded_files_loading: others/embedded_files_loading.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +others/raylib_opengl_interop: + $(info Skipping_others_raylib_opengl_interop) + +others/raymath_vector_angle: others/raymath_vector_angle.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +others/rlgl_compute_shader: + $(info Skipping_others_rlgl_compute_shader) + +others/rlgl_standalone: + $(info Skipping_others_rlgl_standalone) # Clean everything clean: diff --git a/raylib/examples/README.md b/raylib/examples/README.md index 82e4b78..0fed8ac 100644 --- a/raylib/examples/README.md +++ b/raylib/examples/README.md @@ -176,6 +176,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete | 114 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | âï¸âï¸âï¸âï¸ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) | | 115 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | âï¸âï¸â˜†â˜† | 3.5 | 3.5 | [Ray](https://github.com/raysan5) | | 116 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | âï¸âï¸â˜†â˜† | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) | +| 117 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | âï¸âï¸âï¸âï¸ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) | ### category: audio @@ -183,10 +184,10 @@ Examples using raylib audio functionality, including sound/music loading and pla | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| -| 117 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | âï¸â˜†â˜†â˜† | 1.5 | 3.5 | [Ray](https://github.com/raysan5) | -| 118 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | âï¸â˜†â˜†â˜† | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | -| 119 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | âï¸âï¸âï¸â˜† | 1.6 | **4.2** | [Ray](https://github.com/raysan5) | -| 120 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | âï¸â˜†â˜†â˜† | 1.1 | 3.5 | [Ray](https://github.com/raysan5) | +| 118 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | âï¸â˜†â˜†â˜† | 1.5 | 3.5 | [Ray](https://github.com/raysan5) | +| 119 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | âï¸â˜†â˜†â˜† | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | +| 120 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | âï¸âï¸âï¸â˜† | 1.6 | **4.2** | [Ray](https://github.com/raysan5) | +| 121 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | âï¸â˜†â˜†â˜† | 1.1 | 3.5 | [Ray](https://github.com/raysan5) | ### category: others diff --git a/raylib/examples/core/core_2d_camera.c b/raylib/examples/core/core_2d_camera.c index 24cca69..759c099 100644 --- a/raylib/examples/core/core_2d_camera.c +++ b/raylib/examples/core/core_2d_camera.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - 2d camera +* raylib [core] example - 2D Camera system * * Example originally created with raylib 1.5, last time updated with raylib 3.0 * diff --git a/raylib/examples/core/core_2d_camera_platformer.c b/raylib/examples/core/core_2d_camera_platformer.c index b149ea8..72b1ee1 100644 --- a/raylib/examples/core/core_2d_camera_platformer.c +++ b/raylib/examples/core/core_2d_camera_platformer.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - 2d camera platformer +* raylib [core] example - 2D Camera platformer * * Example originally created with raylib 2.5, last time updated with raylib 3.0 * diff --git a/raylib/examples/core/core_2d_camera_split_screen.c b/raylib/examples/core/core_2d_camera_split_screen.c index 57a0dfd..60b5a2e 100644 --- a/raylib/examples/core/core_2d_camera_split_screen.c +++ b/raylib/examples/core/core_2d_camera_split_screen.c @@ -85,12 +85,12 @@ int main(void) // Draw full scene with first camera for (int i = 0; i < screenWidth/PLAYER_SIZE + 1; i++) { - DrawLineV((Vector2){PLAYER_SIZE*i, 0}, (Vector2){PLAYER_SIZE*i, screenHeight}, LIGHTGRAY); + DrawLineV((Vector2){(float)PLAYER_SIZE*i, 0}, (Vector2){ (float)PLAYER_SIZE*i, (float)screenHeight}, LIGHTGRAY); } for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++) { - DrawLineV((Vector2){0, PLAYER_SIZE*i}, (Vector2){screenWidth, PLAYER_SIZE*i}, LIGHTGRAY); + DrawLineV((Vector2){0, (float)PLAYER_SIZE*i}, (Vector2){ (float)screenWidth, (float)PLAYER_SIZE*i}, LIGHTGRAY); } for (int i = 0; i < screenWidth/PLAYER_SIZE; i++) @@ -118,12 +118,12 @@ int main(void) // Draw full scene with second camera for (int i = 0; i < screenWidth/PLAYER_SIZE + 1; i++) { - DrawLineV((Vector2){PLAYER_SIZE*i, 0}, (Vector2){PLAYER_SIZE*i, screenHeight}, LIGHTGRAY); + DrawLineV((Vector2){ (float)PLAYER_SIZE*i, 0}, (Vector2){ (float)PLAYER_SIZE*i, (float)screenHeight}, LIGHTGRAY); } for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++) { - DrawLineV((Vector2){0, PLAYER_SIZE*i}, (Vector2){screenWidth, PLAYER_SIZE*i}, LIGHTGRAY); + DrawLineV((Vector2){0, (float)PLAYER_SIZE*i}, (Vector2){ (float)screenWidth, (float)PLAYER_SIZE*i}, LIGHTGRAY); } for (int i = 0; i < screenWidth/PLAYER_SIZE; i++) diff --git a/raylib/examples/core/core_3d_camera_free.c b/raylib/examples/core/core_3d_camera_free.c index 78200a6..3c30a42 100644 --- a/raylib/examples/core/core_3d_camera_free.c +++ b/raylib/examples/core/core_3d_camera_free.c @@ -47,7 +47,7 @@ int main(void) //---------------------------------------------------------------------------------- UpdateCamera(&camera, CAMERA_FREE); - if (IsKeyDown('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + if (IsKeyPressed('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; //---------------------------------------------------------------------------------- // Draw @@ -65,15 +65,13 @@ int main(void) EndMode3D(); - DrawRectangle( 10, 10, 320, 133, Fade(SKYBLUE, 0.5f)); - DrawRectangleLines( 10, 10, 320, 133, BLUE); + DrawRectangle( 10, 10, 320, 93, Fade(SKYBLUE, 0.5f)); + DrawRectangleLines( 10, 10, 320, 93, BLUE); DrawText("Free camera default controls:", 20, 20, 10, BLACK); DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, DARKGRAY); DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, DARKGRAY); - DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 80, 10, DARKGRAY); - //DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, DARKGRAY); - DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, DARKGRAY); + DrawText("- Z to zoom to (0, 0, 0)", 40, 80, 10, DARKGRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -85,4 +83,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -}
\ No newline at end of file +} diff --git a/raylib/examples/core/core_3d_camera_free.png b/raylib/examples/core/core_3d_camera_free.png Binary files differindex 7874eed..71dfc1c 100644 --- a/raylib/examples/core/core_3d_camera_free.png +++ b/raylib/examples/core/core_3d_camera_free.png diff --git a/raylib/examples/core/core_automation_events.c b/raylib/examples/core/core_automation_events.c new file mode 100644 index 0000000..b58d572 --- /dev/null +++ b/raylib/examples/core/core_automation_events.c @@ -0,0 +1,334 @@ +/******************************************************************************************* +* +* raylib [core] example - automation events +* +* Example originally created with raylib 5.0, last time updated with raylib 5.0 +* +* Example based on 2d_camera_platformer example by arvyy (@arvyy) +* +* 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 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" + +#define GRAVITY 400 +#define PLAYER_JUMP_SPD 350.0f +#define PLAYER_HOR_SPD 200.0f + +#define MAX_ENVIRONMENT_ELEMENTS 5 + +typedef struct Player { + Vector2 position; + float speed; + bool canJump; +} Player; + +typedef struct EnvElement { + Rectangle rect; + int blocking; + Color color; +} EnvElement; + + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - automation events"); + + // Define player + Player player = { 0 }; + player.position = (Vector2){ 400, 280 }; + player.speed = 0; + player.canJump = false; + + // Define environment elements (platforms) + EnvElement envElements[MAX_ENVIRONMENT_ELEMENTS] = { + {{ 0, 0, 1000, 400 }, 0, LIGHTGRAY }, + {{ 0, 400, 1000, 200 }, 1, GRAY }, + {{ 300, 200, 400, 10 }, 1, GRAY }, + {{ 250, 300, 100, 10 }, 1, GRAY }, + {{ 650, 300, 100, 10 }, 1, GRAY } + }; + + // Define camera + Camera2D camera = { 0 }; + camera.target = player.position; + camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f }; + camera.rotation = 0.0f; + camera.zoom = 1.0f; + + // Automation events + AutomationEventList aelist = LoadAutomationEventList(0); // Initialize list of automation events to record new events + SetAutomationEventList(&aelist); + bool eventRecording = false; + bool eventPlaying = false; + + unsigned int frameCounter = 0; + unsigned int playFrameCounter = 0; + unsigned int currentPlayFrame = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + float deltaTime = 0.015f;//GetFrameTime(); + + // Dropped files logic + //---------------------------------------------------------------------------------- + if (IsFileDropped()) + { + FilePathList droppedFiles = LoadDroppedFiles(); + + // Supports loading .rgs style files (text or binary) and .png style palette images + if (IsFileExtension(droppedFiles.paths[0], ".txt;.rae")) + { + UnloadAutomationEventList(&aelist); + aelist = LoadAutomationEventList(droppedFiles.paths[0]); + + eventRecording = false; + + // Reset scene state to play + eventPlaying = true; + playFrameCounter = 0; + currentPlayFrame = 0; + + player.position = (Vector2){ 400, 280 }; + player.speed = 0; + player.canJump = false; + + camera.target = player.position; + camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f }; + camera.rotation = 0.0f; + camera.zoom = 1.0f; + } + + UnloadDroppedFiles(droppedFiles); // Unload filepaths from memory + } + //---------------------------------------------------------------------------------- + + // Update player + //---------------------------------------------------------------------------------- + if (IsKeyDown(KEY_LEFT)) player.position.x -= PLAYER_HOR_SPD*deltaTime; + if (IsKeyDown(KEY_RIGHT)) player.position.x += PLAYER_HOR_SPD*deltaTime; + if (IsKeyDown(KEY_SPACE) && player.canJump) + { + player.speed = -PLAYER_JUMP_SPD; + player.canJump = false; + } + + int hitObstacle = 0; + for (int i = 0; i < MAX_ENVIRONMENT_ELEMENTS; i++) + { + EnvElement *element = &envElements[i]; + Vector2 *p = &(player.position); + if (element->blocking && + element->rect.x <= p->x && + element->rect.x + element->rect.width >= p->x && + element->rect.y >= p->y && + element->rect.y <= p->y + player.speed*deltaTime) + { + hitObstacle = 1; + player.speed = 0.0f; + p->y = element->rect.y; + } + } + + if (!hitObstacle) + { + player.position.y += player.speed*deltaTime; + player.speed += GRAVITY*deltaTime; + player.canJump = false; + } + else player.canJump = true; + + camera.zoom += ((float)GetMouseWheelMove()*0.05f); + + if (camera.zoom > 3.0f) camera.zoom = 3.0f; + else if (camera.zoom < 0.25f) camera.zoom = 0.25f; + + if (IsKeyPressed(KEY_R)) + { + // Reset game state + player.position = (Vector2){ 400, 280 }; + player.speed = 0; + player.canJump = false; + + camera.target = player.position; + camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f }; + camera.rotation = 0.0f; + camera.zoom = 1.0f; + } + //---------------------------------------------------------------------------------- + + // Update camera + //---------------------------------------------------------------------------------- + camera.target = player.position; + camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f }; + float minX = 1000, minY = 1000, maxX = -1000, maxY = -1000; + + for (int i = 0; i < MAX_ENVIRONMENT_ELEMENTS; i++) + { + EnvElement *element = &envElements[i]; + minX = fminf(element->rect.x, minX); + maxX = fmaxf(element->rect.x + element->rect.width, maxX); + minY = fminf(element->rect.y, minY); + maxY = fmaxf(element->rect.y + element->rect.height, maxY); + } + + Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera); + Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera); + + if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2); + if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2); + if (min.x > 0) camera.offset.x = screenWidth/2 - min.x; + if (min.y > 0) camera.offset.y = screenHeight/2 - min.y; + //---------------------------------------------------------------------------------- + + // Toggle events recording + if (IsKeyPressed(KEY_S)) + { + if (!eventPlaying) + { + if (eventRecording) + { + StopAutomationEventRecording(); + eventRecording = false; + + ExportAutomationEventList(aelist, "automation.rae"); + + TraceLog(LOG_INFO, "RECORDED FRAMES: %i", aelist.count); + } + else + { + SetAutomationEventBaseFrame(180); + StartAutomationEventRecording(); + eventRecording = true; + } + } + } + else if (IsKeyPressed(KEY_A)) + { + if (!eventRecording && (aelist.count > 0)) + { + // Reset scene state to play + eventPlaying = true; + playFrameCounter = 0; + currentPlayFrame = 0; + + player.position = (Vector2){ 400, 280 }; + player.speed = 0; + player.canJump = false; + + camera.target = player.position; + camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f }; + camera.rotation = 0.0f; + camera.zoom = 1.0f; + } + } + + if (eventPlaying) + { + // NOTE: Multiple events could be executed in a single frame + while (playFrameCounter == aelist.events[currentPlayFrame].frame) + { + TraceLog(LOG_INFO, "PLAYING: PlayFrameCount: %i | currentPlayFrame: %i | Event Frame: %i, param: %i", + playFrameCounter, currentPlayFrame, aelist.events[currentPlayFrame].frame, aelist.events[currentPlayFrame].params[0]); + + PlayAutomationEvent(aelist.events[currentPlayFrame]); + currentPlayFrame++; + + if (currentPlayFrame == aelist.count) + { + eventPlaying = false; + currentPlayFrame = 0; + playFrameCounter = 0; + + TraceLog(LOG_INFO, "FINISH PLAYING!"); + break; + } + } + + playFrameCounter++; + } + + if (eventRecording || eventPlaying) frameCounter++; + else frameCounter = 0; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(LIGHTGRAY); + + BeginMode2D(camera); + + // Draw environment elements + for (int i = 0; i < MAX_ENVIRONMENT_ELEMENTS; i++) + { + DrawRectangleRec(envElements[i].rect, envElements[i].color); + } + + // Draw player rectangle + DrawRectangleRec((Rectangle){ player.position.x - 20, player.position.y - 40, 40, 40 }, RED); + + EndMode2D(); + + // Draw game controls + DrawRectangle(10, 10, 290, 145, Fade(SKYBLUE, 0.5f)); + DrawRectangleLines(10, 10, 290, 145, Fade(BLUE, 0.8f)); + + DrawText("Controls:", 20, 20, 10, BLACK); + DrawText("- RIGHT | LEFT: Player movement", 30, 40, 10, DARKGRAY); + DrawText("- SPACE: Player jump", 30, 60, 10, DARKGRAY); + DrawText("- R: Reset game state", 30, 80, 10, DARKGRAY); + + DrawText("- S: START/STOP RECORDING INPUT EVENTS", 30, 110, 10, BLACK); + DrawText("- A: REPLAY LAST RECORDED INPUT EVENTS", 30, 130, 10, BLACK); + + // Draw automation events recording indicator + if (eventRecording) + { + DrawRectangle(10, 160, 290, 30, Fade(RED, 0.3f)); + DrawRectangleLines(10, 160, 290, 30, Fade(MAROON, 0.8f)); + DrawCircle(30, 175, 10, MAROON); + + if (((frameCounter/15)%2) == 1) DrawText(TextFormat("RECORDING EVENTS... [%i]", aelist.count), 50, 170, 10, MAROON); + } + else if (eventPlaying) + { + DrawRectangle(10, 160, 290, 30, Fade(LIME, 0.3f)); + DrawRectangleLines(10, 160, 290, 30, Fade(DARKGREEN, 0.8f)); + DrawTriangle((Vector2){ 20, 155 + 10 }, (Vector2){ 20, 155 + 30 }, (Vector2){ 40, 155 + 20 }, DARKGREEN); + + if (((frameCounter/15)%2) == 1) DrawText(TextFormat("PLAYING RECORDED EVENTS... [%i]", currentPlayFrame), 50, 170, 10, DARKGREEN); + } + + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/raylib/examples/core/core_automation_events.png b/raylib/examples/core/core_automation_events.png Binary files differnew file mode 100644 index 0000000..ac8cb3b --- /dev/null +++ b/raylib/examples/core/core_automation_events.png diff --git a/raylib/examples/core/core_drop_files.c b/raylib/examples/core/core_drop_files.c index 9f62203..d4ddd9e 100644 --- a/raylib/examples/core/core_drop_files.c +++ b/raylib/examples/core/core_drop_files.c @@ -53,7 +53,7 @@ int main(void) { FilePathList droppedFiles = LoadDroppedFiles(); - for (int i = 0, offset = filePathCounter; i < droppedFiles.count; i++) + for (int i = 0, offset = filePathCounter; i < (int)droppedFiles.count; i++) { if (filePathCounter < (MAX_FILEPATH_RECORDED - 1)) { @@ -77,7 +77,7 @@ int main(void) { DrawText("Dropped files:", 100, 40, 20, DARKGRAY); - for (unsigned int i = 0; i < filePathCounter; i++) + for (int i = 0; i < filePathCounter; i++) { if (i%2 == 0) DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.5f)); else DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.3f)); diff --git a/raylib/examples/core/core_input_gamepad_info.c b/raylib/examples/core/core_input_gamepad_info.c index 55f0354..9aebb81 100644 --- a/raylib/examples/core/core_input_gamepad_info.c +++ b/raylib/examples/core/core_input_gamepad_info.c @@ -31,40 +31,49 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad information"); SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { - int y = 10; + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + // Draw + //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(RAYWHITE); + ClearBackground(RAYWHITE); - for (int i = 0; i < 4; i++) // by default rcore.h has a MAX_GAMEPADS of 4 so mimmic that here. - { - if (IsGamepadAvailable(i)) + for (int i = 0, y = 10; i < 4; i++) // MAX_GAMEPADS = 4 { - DrawText(TextFormat("Gamepad name: %s", GetGamepadName(i)), 10, y, 20, BLACK); - y += 30; - DrawText(TextFormat("\tAxis count: %d", GetGamepadAxisCount(i)), 10, y, 20, BLACK); - y += 30; - for (int axis = 0; axis < GetGamepadAxisCount(i); axis++) + if (IsGamepadAvailable(i)) { - DrawText(TextFormat("\tAxis %d = %f", axis, GetGamepadAxisMovement(i, axis)), 10, y, 20, BLACK); + DrawText(TextFormat("Gamepad name: %s", GetGamepadName(i)), 10, y, 20, BLACK); y += 30; - } - for (int button = 0; button < 32; button++) - { - DrawText(TextFormat("\tButton %d = %d", button, IsGamepadButtonDown(i, button)), 10, y, 20, BLACK); + DrawText(TextFormat("\tAxis count: %d", GetGamepadAxisCount(i)), 10, y, 20, BLACK); y += 30; + + for (int axis = 0; axis < GetGamepadAxisCount(i); axis++) + { + DrawText(TextFormat("\tAxis %d = %f", axis, GetGamepadAxisMovement(i, axis)), 10, y, 20, BLACK); + y += 30; + } + + for (int button = 0; button < 32; button++) + { + DrawText(TextFormat("\tButton %d = %d", button, IsGamepadButtonDown(i, button)), 10, y, 20, BLACK); + y += 30; + } } } - } - DrawFPS(GetScreenWidth() - 100, 100); + DrawFPS(GetScreenWidth() - 100, 100); EndDrawing(); + //---------------------------------------------------------------------------------- } // De-Initialization diff --git a/raylib/examples/core/core_loading_thread.c b/raylib/examples/core/core_loading_thread.c index 0538dce..8451ff0 100644 --- a/raylib/examples/core/core_loading_thread.c +++ b/raylib/examples/core/core_loading_thread.c @@ -41,7 +41,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - loading thread"); - pthread_t threadId; // Loading data thread id + pthread_t threadId = { 0 }; // Loading data thread id enum { STATE_WAITING, STATE_LOADING, STATE_FINISHED } state = STATE_WAITING; int framesCounter = 0; diff --git a/raylib/examples/core/core_random_values.c b/raylib/examples/core/core_random_values.c index c2225bc..bec1de2 100644 --- a/raylib/examples/core/core_random_values.c +++ b/raylib/examples/core/core_random_values.c @@ -29,7 +29,7 @@ int main(void) int randValue = GetRandomValue(-8, 5); // Get a random integer number between -8 and 5 (both included) - int framesCounter = 0; // Variable used to count frames + unsigned int framesCounter = 0; // Variable used to count frames SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- diff --git a/raylib/examples/core/core_smooth_pixelperfect.c b/raylib/examples/core/core_smooth_pixelperfect.c index 776706c..3d5ed94 100644 --- a/raylib/examples/core/core_smooth_pixelperfect.c +++ b/raylib/examples/core/core_smooth_pixelperfect.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - smooth pixel-perfect camera +* raylib [core] example - Smooth Pixel-perfect camera * * Example originally created with raylib 3.7, last time updated with raylib 4.0 * diff --git a/raylib/examples/core/core_storage_values.c b/raylib/examples/core/core_storage_values.c index 1273991..c7fd7d9 100644 --- a/raylib/examples/core/core_storage_values.c +++ b/raylib/examples/core/core_storage_values.c @@ -104,7 +104,7 @@ int main(void) bool SaveStorageValue(unsigned int position, int value) { bool success = false; - unsigned int dataSize = 0; + int dataSize = 0; unsigned int newDataSize = 0; unsigned char *fileData = LoadFileData(STORAGE_DATA_FILE, &dataSize); unsigned char *newFileData = NULL; @@ -172,7 +172,7 @@ bool SaveStorageValue(unsigned int position, int value) int LoadStorageValue(unsigned int position) { int value = 0; - unsigned int dataSize = 0; + int dataSize = 0; unsigned char *fileData = LoadFileData(STORAGE_DATA_FILE, &dataSize); if (fileData != NULL) diff --git a/raylib/examples/models/models_animation.c b/raylib/examples/models/models_animation.c index ffe2d01..8e6f7f8 100644 --- a/raylib/examples/models/models_animation.c +++ b/raylib/examples/models/models_animation.c @@ -48,7 +48,7 @@ int main(void) Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position // Load animation data - unsigned int animsCount = 0; + int animsCount = 0; ModelAnimation *anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", &animsCount); int animFrameCounter = 0; diff --git a/raylib/examples/models/models_loading_gltf.c b/raylib/examples/models/models_loading_gltf.c index 2884731..1d5d516 100644 --- a/raylib/examples/models/models_loading_gltf.c +++ b/raylib/examples/models/models_loading_gltf.c @@ -44,7 +44,7 @@ int main(void) Model model = LoadModel("resources/models/gltf/robot.glb"); // Load gltf model animations - unsigned int animsCount = 0; + int animsCount = 0; unsigned int animIndex = 0; unsigned int animCurrentFrame = 0; ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount); diff --git a/raylib/examples/models/models_loading_m3d.c b/raylib/examples/models/models_loading_m3d.c index 1e56d51..71dbc8d 100644 --- a/raylib/examples/models/models_loading_m3d.c +++ b/raylib/examples/models/models_loading_m3d.c @@ -50,7 +50,7 @@ int main(void) Model model = LoadModel(modelFileName); // Load the bind-pose model mesh and basic data // Load animations - unsigned int animsCount = 0; + int animsCount = 0; int animFrameCounter = 0, animId = 0; ModelAnimation *anims = LoadModelAnimations(modelFileName, &animsCount); // Load skeletal animation data @@ -85,7 +85,7 @@ int main(void) animFrameCounter = 0; animId++; - if (animId >= animsCount) animId = 0; + if (animId >= (int)animsCount) animId = 0; UpdateModelAnimation(model, anims[animId], 0); animPlaying = true; } diff --git a/raylib/examples/models/models_mesh_generation.c b/raylib/examples/models/models_mesh_generation.c index d17a20a..94e0a4c 100644 --- a/raylib/examples/models/models_mesh_generation.c +++ b/raylib/examples/models/models_mesh_generation.c @@ -36,7 +36,7 @@ int main(void) Model models[NUM_MODELS] = { 0 }; - models[0] = LoadModelFromMesh(GenMeshPlane(2, 2, 5, 5)); + models[0] = LoadModelFromMesh(GenMeshPlane(2, 2, 4, 3)); models[1] = LoadModelFromMesh(GenMeshCube(2.0f, 1.0f, 2.0f)); models[2] = LoadModelFromMesh(GenMeshSphere(2, 32, 32)); models[3] = LoadModelFromMesh(GenMeshHemiSphere(2, 16, 16)); diff --git a/raylib/examples/models/models_skybox.c b/raylib/examples/models/models_skybox.c index 7a500e0..c583128 100644 --- a/raylib/examples/models/models_skybox.c +++ b/raylib/examples/models/models_skybox.c @@ -68,14 +68,12 @@ int main(void) char skyboxFileName[256] = { 0 }; - Texture2D panorama; - if (useHDR) { TextCopy(skyboxFileName, "resources/dresden_square_2k.hdr"); // Load HDR panorama (sphere) texture - panorama = LoadTexture(skyboxFileName); + Texture2D panorama = LoadTexture(skyboxFileName); // Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture // NOTE 1: New texture is generated rendering to texture, shader calculates the sphere->cube coordinates mapping @@ -83,7 +81,7 @@ int main(void) // despite texture can be successfully created.. so using PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 instead of PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8); - //UnloadTexture(panorama); // Texture not required anymore, cubemap already generated + UnloadTexture(panorama); // Texture not required anymore, cubemap already generated } else { @@ -113,15 +111,18 @@ int main(void) { if (IsFileExtension(droppedFiles.paths[0], ".png;.jpg;.hdr;.bmp;.tga")) { - // Unload current cubemap texture and load new one + // Unload current cubemap texture to load new one UnloadTexture(skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture); + if (useHDR) { + // Load HDR panorama (sphere) texture Texture2D panorama = LoadTexture(droppedFiles.paths[0]); // Generate cubemap from panorama texture skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8); - UnloadTexture(panorama); + + UnloadTexture(panorama); // Texture not required anymore, cubemap already generated } else { diff --git a/raylib/examples/others/external/include/GLFW/glfw3.h b/raylib/examples/others/external/include/GLFW/glfw3.h index 990fe3f..31b201a 100644 --- a/raylib/examples/others/external/include/GLFW/glfw3.h +++ b/raylib/examples/others/external/include/GLFW/glfw3.h @@ -3,7 +3,7 @@ * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard - * Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org> + * Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -52,7 +52,7 @@ extern "C" { * This is the reference documentation for OpenGL and OpenGL ES context related * functions. For more task-oriented information, see the @ref context_guide. */ -/*! @defgroup vulkan Vulkan reference +/*! @defgroup vulkan Vulkan support reference * @brief Functions and types related to Vulkan. * * This is the reference documentation for Vulkan related functions and types. @@ -96,11 +96,30 @@ extern "C" { #define _WIN32 #endif /* _WIN32 */ +/* Include because most Windows GLU headers need wchar_t and + * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h. + * Include it unconditionally to avoid surprising side-effects. + */ +#include <stddef.h> + +/* Include because it is needed by Vulkan and related functions. + * Include it unconditionally to avoid surprising side-effects. + */ +#include <stdint.h> + +#if defined(GLFW_INCLUDE_VULKAN) + #include <vulkan/vulkan.h> +#endif /* Vulkan header */ + +/* The Vulkan header may have indirectly included windows.h (because of + * VK_USE_PLATFORM_WIN32_KHR) so we offer our replacement symbols after it. + */ + /* It is customary to use APIENTRY for OpenGL function pointer declarations on * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. */ -#ifndef APIENTRY - #ifdef _WIN32 +#if !defined(APIENTRY) + #if defined(_WIN32) #define APIENTRY __stdcall #else #define APIENTRY @@ -122,17 +141,6 @@ extern "C" { #define GLFW_CALLBACK_DEFINED #endif /* CALLBACK */ -/* Include because most Windows GLU headers need wchar_t and - * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h. - * Include it unconditionally to avoid surprising side-effects. - */ -#include <stddef.h> - -/* Include because it is needed by Vulkan and related functions. - * Include it unconditionally to avoid surprising side-effects. - */ -#include <stdint.h> - /* Include the chosen OpenGL or OpenGL ES headers. */ #if defined(GLFW_INCLUDE_ES1) @@ -182,10 +190,44 @@ extern "C" { #else /*__APPLE__*/ #include <GL/glcorearb.h> + #if defined(GLFW_INCLUDE_GLEXT) + #include <GL/glext.h> + #endif #endif /*__APPLE__*/ -#elif !defined(GLFW_INCLUDE_NONE) +#elif defined(GLFW_INCLUDE_GLU) + + #if defined(__APPLE__) + + #if defined(GLFW_INCLUDE_GLU) + #include <OpenGL/glu.h> + #endif + + #else /*__APPLE__*/ + + #if defined(GLFW_INCLUDE_GLU) + #include <GL/glu.h> + #endif + + #endif /*__APPLE__*/ + +#elif !defined(GLFW_INCLUDE_NONE) && \ + !defined(__gl_h_) && \ + !defined(__gles1_gl_h_) && \ + !defined(__gles2_gl2_h_) && \ + !defined(__gles2_gl3_h_) && \ + !defined(__gles2_gl31_h_) && \ + !defined(__gles2_gl32_h_) && \ + !defined(__gl_glcorearb_h_) && \ + !defined(__gl2_h_) /*legacy*/ && \ + !defined(__gl3_h_) /*legacy*/ && \ + !defined(__gl31_h_) /*legacy*/ && \ + !defined(__gl32_h_) /*legacy*/ && \ + !defined(__glcorearb_h_) /*legacy*/ && \ + !defined(__GL_H__) /*non-standard*/ && \ + !defined(__gltypes_h_) /*non-standard*/ && \ + !defined(__glee_h_) /*non-standard*/ #if defined(__APPLE__) @@ -193,9 +235,6 @@ extern "C" { #define GL_GLEXT_LEGACY #endif #include <OpenGL/gl.h> - #if defined(GLFW_INCLUDE_GLU) - #include <OpenGL/glu.h> - #endif #else /*__APPLE__*/ @@ -203,18 +242,11 @@ extern "C" { #if defined(GLFW_INCLUDE_GLEXT) #include <GL/glext.h> #endif - #if defined(GLFW_INCLUDE_GLU) - #include <GL/glu.h> - #endif #endif /*__APPLE__*/ #endif /* OpenGL and OpenGL ES headers */ -#if defined(GLFW_INCLUDE_VULKAN) - #include <vulkan/vulkan.h> -#endif /* Vulkan header */ - #if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) /* GLFW_DLL must be defined by applications that are linking against the DLL * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW @@ -230,13 +262,12 @@ extern "C" { /* We are building GLFW as a Win32 DLL */ #define GLFWAPI __declspec(dllexport) #elif defined(_WIN32) && defined(GLFW_DLL) - /* We are calling GLFW as a Win32 DLL */ + /* We are calling a GLFW Win32 DLL */ #define GLFWAPI __declspec(dllimport) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) - /* We are building GLFW as a shared / dynamic library */ + /* We are building GLFW as a Unix shared library */ #define GLFWAPI __attribute__((visibility("default"))) #else - /* We are building or calling GLFW as a static library */ #define GLFWAPI #endif @@ -247,45 +278,47 @@ extern "C" { /*! @name GLFW version macros * @{ */ -/*! @brief The major version number of the GLFW library. +/*! @brief The major version number of the GLFW header. * - * This is incremented when the API is changed in non-compatible ways. + * The major version number of the GLFW header. This is incremented when the + * API is changed in non-compatible ways. * @ingroup init */ #define GLFW_VERSION_MAJOR 3 -/*! @brief The minor version number of the GLFW library. +/*! @brief The minor version number of the GLFW header. * - * This is incremented when features are added to the API but it remains - * backward-compatible. + * The minor version number of the GLFW header. This is incremented when + * features are added to the API but it remains backward-compatible. * @ingroup init */ #define GLFW_VERSION_MINOR 3 -/*! @brief The revision number of the GLFW library. +/*! @brief The revision number of the GLFW header. * - * This is incremented when a bug fix release is made that does not contain any - * API changes. + * The revision number of the GLFW header. This is incremented when a bug fix + * release is made that does not contain any API changes. * @ingroup init */ -#define GLFW_VERSION_REVISION 0 +#define GLFW_VERSION_REVISION 8 /*! @} */ -/*! @name Boolean values - * @{ */ /*! @brief One. * - * One. Seriously. You don't _need_ to use this symbol in your code. It's - * semantic sugar for the number 1. You can also use `1` or `true` or `_True` - * or `GL_TRUE` or whatever you want. + * This is only semantic sugar for the number 1. You can instead use `1` or + * `true` or `_True` or `GL_TRUE` or `VK_TRUE` or anything else that is equal + * to one. + * + * @ingroup init */ #define GLFW_TRUE 1 /*! @brief Zero. * - * Zero. Seriously. You don't _need_ to use this symbol in your code. It's - * semantic sugar for the number 0. You can also use `0` or `false` or - * `_False` or `GL_FALSE` or whatever you want. + * This is only semantic sugar for the number 0. You can instead use `0` or + * `false` or `_False` or `GL_FALSE` or `VK_FALSE` or anything else that is + * equal to zero. + * + * @ingroup init */ #define GLFW_FALSE 0 -/*! @} */ /*! @name Key and button actions * @{ */ @@ -313,6 +346,7 @@ extern "C" { /*! @} */ /*! @defgroup hat_state Joystick hat states + * @brief Joystick hat states. * * See [joystick hat input](@ref joystick_hat) for how these are used. * @@ -915,70 +949,87 @@ extern "C" { #define GLFW_CLIENT_API 0x00022001 /*! @brief Context client API major version hint and attribute. * - * Context client API major version [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint) + * and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib). */ #define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 /*! @brief Context client API minor version hint and attribute. * - * Context client API minor version [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint) + * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib). */ #define GLFW_CONTEXT_VERSION_MINOR 0x00022003 -/*! @brief Context client API revision number hint and attribute. +/*! @brief Context client API revision number attribute. * - * Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context client API revision number + * [attribute](@ref GLFW_CONTEXT_REVISION_attrib). */ #define GLFW_CONTEXT_REVISION 0x00022004 /*! @brief Context robustness hint and attribute. * - * Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint) + * and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib). */ #define GLFW_CONTEXT_ROBUSTNESS 0x00022005 /*! @brief OpenGL forward-compatibility hint and attribute. * - * OpenGL forward-compatibility [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) + * and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib). */ #define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 -/*! @brief OpenGL debug context hint and attribute. +/*! @brief Debug mode context hint and attribute. * - * OpenGL debug context [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Debug mode context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and + * [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib). */ #define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 /*! @brief OpenGL profile hint and attribute. * - * OpenGL profile [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and + * [attribute](@ref GLFW_OPENGL_PROFILE_attrib). */ #define GLFW_OPENGL_PROFILE 0x00022008 /*! @brief Context flush-on-release hint and attribute. * - * Context flush-on-release [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and + * [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib). */ #define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 /*! @brief Context error suppression hint and attribute. * - * Context error suppression [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and + * [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib). */ #define GLFW_CONTEXT_NO_ERROR 0x0002200A /*! @brief Context creation API hint and attribute. * - * Context creation API [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). + * Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and + * [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib). */ #define GLFW_CONTEXT_CREATION_API 0x0002200B - +/*! @brief Window content area scaling window + * [window hint](@ref GLFW_SCALE_TO_MONITOR). + */ +#define GLFW_SCALE_TO_MONITOR 0x0002200C +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). + */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint). + */ #define GLFW_COCOA_FRAME_NAME 0x00023002 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint). + */ #define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003 - +/*! @brief X11 specific + * [window hint](@ref GLFW_X11_CLASS_NAME_hint). + */ #define GLFW_X11_CLASS_NAME 0x00024001 +/*! @brief X11 specific + * [window hint](@ref GLFW_X11_CLASS_NAME_hint). + */ #define GLFW_X11_INSTANCE_NAME 0x00024002 /*! @} */ @@ -998,6 +1049,7 @@ extern "C" { #define GLFW_STICKY_KEYS 0x00033002 #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_LOCK_KEY_MODS 0x00033004 +#define GLFW_RAW_MOUSE_MOTION 0x00033005 #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 @@ -1056,9 +1108,20 @@ extern "C" { /*! @addtogroup init * @{ */ +/*! @brief Joystick hat buttons init hint. + * + * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). + */ #define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 - +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). + */ #define GLFW_COCOA_CHDIR_RESOURCES 0x00051001 +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). + */ #define GLFW_COCOA_MENUBAR 0x00051002 /*! @} */ @@ -1129,17 +1192,25 @@ typedef struct GLFWwindow GLFWwindow; * * @since Added in version 3.1. * - * @ingroup cursor + * @ingroup input */ typedef struct GLFWcursor GLFWcursor; -/*! @brief The function signature for error callbacks. +/*! @brief The function pointer type for error callbacks. * - * This is the function signature for error callback functions. + * This is the function pointer type for error callbacks. An error callback + * function has the following signature: + * @code + * void callback_name(int error_code, const char* description) + * @endcode * - * @param[in] error An [error code](@ref errors). + * @param[in] error_code An [error code](@ref errors). Future releases may add + * more error codes. * @param[in] description A UTF-8 encoded string describing the error. * + * @pointer_lifetime The error description string is valid until the callback + * function returns. + * * @sa @ref error_handling * @sa @ref glfwSetErrorCallback * @@ -1147,17 +1218,21 @@ typedef struct GLFWcursor GLFWcursor; * * @ingroup init */ -typedef void (* GLFWerrorfun)(int,const char*); +typedef void (* GLFWerrorfun)(int error_code, const char* description); -/*! @brief The function signature for window position callbacks. +/*! @brief The function pointer type for window position callbacks. * - * This is the function signature for window position callback functions. + * This is the function pointer type for window position callbacks. A window + * position callback function has the following signature: + * @code + * void callback_name(GLFWwindow* window, int xpos, int ypos) + * @endcode * * @param[in] window The window that was moved. * @param[in] xpos The new x-coordinate, in screen coordinates, of the - * upper-left corner of the client area of the window. + * upper-left corner of the content area of the window. * @param[in] ypos The new y-coordinate, in screen coordinates, of the - * upper-left corner of the client area of the window. + * upper-left corner of the content area of the window. * * @sa @ref window_pos * @sa @ref glfwSetWindowPosCallback @@ -1166,11 +1241,15 @@ typedef void (* GLFWerrorfun)(int,const char*); * * @ingroup window */ -typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); +typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos); -/*! @brief The function signature for window resize callbacks. +/*! @brief The function pointer type for window size callbacks. * - * This is the function signature for window size callback functions. + * This is the function pointer type for window size callbacks. A window size + * callback function has the following signature: + * @code + * void callback_name(GLFWwindow* window, int width, int height) + * @endcode * * @param[in] window The window that was resized. * @param[in] width The new width, in screen coordinates, of the window. @@ -1184,11 +1263,15 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); * * @ingroup window */ -typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); +typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height); -/*! @brief The function signature for window close callbacks. +/*! @brief The function pointer type for window close callbacks. * - * This is the function signature for window close callback functions. + * This is the function pointer type for window close callbacks. A window + * close callback function has the following signature: + * @code + * void function_name(GLFWwindow* window) + * @endcode * * @param[in] window The window that the user attempted to close. * @@ -1200,11 +1283,15 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); * * @ingroup window */ -typedef void (* GLFWwindowclosefun)(GLFWwindow*); +typedef void (* GLFWwindowclosefun)(GLFWwindow* window); -/*! @brief The function signature for window content refresh callbacks. +/*! @brief The function pointer type for window content refresh callbacks. * - * This is the function signature for window refresh callback functions. + * This is the function pointer type for window content refresh callbacks. + * A window content refresh callback function has the following signature: + * @code + * void function_name(GLFWwindow* window); + * @endcode * * @param[in] window The window whose content needs to be refreshed. * @@ -1216,11 +1303,15 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*); * * @ingroup window */ -typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); +typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window); -/*! @brief The function signature for window focus/defocus callbacks. +/*! @brief The function pointer type for window focus callbacks. * - * This is the function signature for window focus callback functions. + * This is the function pointer type for window focus callbacks. A window + * focus callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int focused) + * @endcode * * @param[in] window The window that gained or lost input focus. * @param[in] focused `GLFW_TRUE` if the window was given input focus, or @@ -1233,12 +1324,15 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); * * @ingroup window */ -typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); +typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused); -/*! @brief The function signature for window iconify/restore callbacks. +/*! @brief The function pointer type for window iconify callbacks. * - * This is the function signature for window iconify/restore callback - * functions. + * This is the function pointer type for window iconify callbacks. A window + * iconify callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int iconified) + * @endcode * * @param[in] window The window that was iconified or restored. * @param[in] iconified `GLFW_TRUE` if the window was iconified, or @@ -1251,15 +1345,18 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); * * @ingroup window */ -typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); +typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified); -/*! @brief The function signature for window maximize/restore callbacks. +/*! @brief The function pointer type for window maximize callbacks. * - * This is the function signature for window maximize/restore callback - * functions. + * This is the function pointer type for window maximize callbacks. A window + * maximize callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int maximized) + * @endcode * * @param[in] window The window that was maximized or restored. - * @param[in] iconified `GLFW_TRUE` if the window was maximized, or + * @param[in] maximized `GLFW_TRUE` if the window was maximized, or * `GLFW_FALSE` if it was restored. * * @sa @ref window_maximize @@ -1269,12 +1366,15 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); * * @ingroup window */ -typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int); +typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized); -/*! @brief The function signature for framebuffer resize callbacks. +/*! @brief The function pointer type for framebuffer size callbacks. * - * This is the function signature for framebuffer resize callback - * functions. + * This is the function pointer type for framebuffer size callbacks. + * A framebuffer size callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode * * @param[in] window The window whose framebuffer was resized. * @param[in] width The new width, in pixels, of the framebuffer. @@ -1287,12 +1387,15 @@ typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int); * * @ingroup window */ -typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); +typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height); -/*! @brief The function signature for window content scale callbacks. +/*! @brief The function pointer type for window content scale callbacks. * - * This is the function signature for window content scale callback - * functions. + * This is the function pointer type for window content scale callbacks. + * A window content scale callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, float xscale, float yscale) + * @endcode * * @param[in] window The window whose content scale changed. * @param[in] xscale The new x-axis content scale of the window. @@ -1305,16 +1408,21 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); * * @ingroup window */ -typedef void (* GLFWwindowcontentscalefun)(GLFWwindow*,float,float); +typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale); -/*! @brief The function signature for mouse button callbacks. +/*! @brief The function pointer type for mouse button callbacks. * - * This is the function signature for mouse button callback functions. + * This is the function pointer type for mouse button callback functions. + * A mouse button callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int button, int action, int mods) + * @endcode * * @param[in] window The window that received the event. * @param[in] button The [mouse button](@ref buttons) that was pressed or * released. - * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. + * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. Future releases + * may add more actions. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * @@ -1326,17 +1434,21 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow*,float,float); * * @ingroup input */ -typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); +typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods); -/*! @brief The function signature for cursor position callbacks. +/*! @brief The function pointer type for cursor position callbacks. * - * This is the function signature for cursor position callback functions. + * This is the function pointer type for cursor position callbacks. A cursor + * position callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, double xpos, double ypos); + * @endcode * * @param[in] window The window that received the event. * @param[in] xpos The new cursor x-coordinate, relative to the left edge of - * the client area. + * the content area. * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the - * client area. + * content area. * * @sa @ref cursor_pos * @sa @ref glfwSetCursorPosCallback @@ -1345,14 +1457,18 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); * * @ingroup input */ -typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); +typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos); -/*! @brief The function signature for cursor enter/leave callbacks. +/*! @brief The function pointer type for cursor enter/leave callbacks. * - * This is the function signature for cursor enter/leave callback functions. + * This is the function pointer type for cursor enter/leave callbacks. + * A cursor enter/leave callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int entered) + * @endcode * * @param[in] window The window that received the event. - * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client + * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content * area, or `GLFW_FALSE` if it left it. * * @sa @ref cursor_enter @@ -1362,11 +1478,15 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); * * @ingroup input */ -typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); +typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered); -/*! @brief The function signature for scroll callbacks. +/*! @brief The function pointer type for scroll callbacks. * - * This is the function signature for scroll callback functions. + * This is the function pointer type for scroll callbacks. A scroll callback + * function has the following signature: + * @code + * void function_name(GLFWwindow* window, double xoffset, double yoffset) + * @endcode * * @param[in] window The window that received the event. * @param[in] xoffset The scroll offset along the x-axis. @@ -1379,16 +1499,21 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); * * @ingroup input */ -typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); +typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset); -/*! @brief The function signature for keyboard key callbacks. +/*! @brief The function pointer type for keyboard key callbacks. * - * This is the function signature for keyboard key callback functions. + * This is the function pointer type for keyboard key callbacks. A keyboard + * key callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) + * @endcode * * @param[in] window The window that received the event. * @param[in] key The [keyboard key](@ref keys) that was pressed or released. * @param[in] scancode The system-specific scancode of the key. - * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. + * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future + * releases may add more actions. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * @@ -1400,11 +1525,15 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * * @ingroup input */ -typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); +typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods); -/*! @brief The function signature for Unicode character callbacks. +/*! @brief The function pointer type for Unicode character callbacks. * - * This is the function signature for Unicode character callback functions. + * This is the function pointer type for Unicode character callbacks. + * A Unicode character callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint) + * @endcode * * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. @@ -1417,14 +1546,18 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); * * @ingroup input */ -typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); +typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint); -/*! @brief The function signature for Unicode character with modifiers +/*! @brief The function pointer type for Unicode character with modifiers * callbacks. * - * This is the function signature for Unicode character with modifiers callback - * functions. It is called for each input character, regardless of what - * modifier keys are held down. + * This is the function pointer type for Unicode character with modifiers + * callbacks. It is called for each input character, regardless of what + * modifier keys are held down. A Unicode character with modifiers callback + * function has the following signature: + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) + * @endcode * * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. @@ -1440,16 +1573,23 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); * * @ingroup input */ -typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); +typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods); -/*! @brief The function signature for file drop callbacks. +/*! @brief The function pointer type for path drop callbacks. * - * This is the function signature for file drop callbacks. + * This is the function pointer type for path drop callbacks. A path drop + * callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int path_count, const char* paths[]) + * @endcode * * @param[in] window The window that received the event. - * @param[in] count The number of dropped files. + * @param[in] path_count The number of dropped paths. * @param[in] paths The UTF-8 encoded file and/or directory path names. * + * @pointer_lifetime The path array and its strings are valid until the + * callback function returns. + * * @sa @ref path_drop * @sa @ref glfwSetDropCallback * @@ -1457,15 +1597,19 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); * * @ingroup input */ -typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); +typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]); -/*! @brief The function signature for monitor configuration callbacks. +/*! @brief The function pointer type for monitor configuration callbacks. * - * This is the function signature for monitor configuration callback functions. + * This is the function pointer type for monitor configuration callbacks. + * A monitor callback function has the following signature: + * @code + * void function_name(GLFWmonitor* monitor, int event) + * @endcode * * @param[in] monitor The monitor that was connected or disconnected. - * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Remaining - * values reserved for future use. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future + * releases may add more events. * * @sa @ref monitor_event * @sa @ref glfwSetMonitorCallback @@ -1474,16 +1618,19 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); * * @ingroup monitor */ -typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); +typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event); -/*! @brief The function signature for joystick configuration callbacks. +/*! @brief The function pointer type for joystick configuration callbacks. * - * This is the function signature for joystick configuration callback - * functions. + * This is the function pointer type for joystick configuration callbacks. + * A joystick configuration callback function has the following signature: + * @code + * void function_name(int jid, int event) + * @endcode * * @param[in] jid The joystick that was connected or disconnected. - * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Remaining - * values reserved for future use. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future + * releases may add more events. * * @sa @ref joystick_event * @sa @ref glfwSetJoystickCallback @@ -1492,7 +1639,7 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); * * @ingroup input */ -typedef void (* GLFWjoystickfun)(int,int); +typedef void (* GLFWjoystickfun)(int jid, int event); /*! @brief Video mode type. * @@ -1567,6 +1714,8 @@ typedef struct GLFWgammaramp * * @since Added in version 2.1. * @glfw3 Removed format and bytes-per-pixel members. + * + * @ingroup window */ typedef struct GLFWimage { @@ -1589,6 +1738,8 @@ typedef struct GLFWimage * @sa @ref glfwGetGamepadState * * @since Added in version 3.3. + * + * @ingroup input */ typedef struct GLFWgamepadstate { @@ -1630,6 +1781,10 @@ typedef struct GLFWgamepadstate * bundle, if present. This can be disabled with the @ref * GLFW_COCOA_CHDIR_RESOURCES init hint. * + * @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. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init @@ -1653,6 +1808,8 @@ GLFWAPI int glfwInit(void); * call this function, as it is called by @ref glfwInit before it returns * failure. * + * This function has no effect if GLFW is not initialized. + * * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * * @remark This function may be called before @ref glfwInit. @@ -1814,10 +1971,17 @@ GLFWAPI int glfwGetError(const char** description); * Once set, the error callback remains set even after the library has been * terminated. * - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set. * + * @callback_signature + * @code + * void callback_name(int error_code, const char* description) + * @endcode + * For more information about the callback parameters, see the + * [callback pointer type](@ref GLFWerrorfun). + * * @errors None. * * @remark This function may be called before @ref glfwInit. @@ -1831,7 +1995,7 @@ GLFWAPI int glfwGetError(const char** description); * * @ingroup init */ -GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); +GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback); /*! @brief Returns the currently connected monitors. * @@ -1911,6 +2075,37 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); */ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); +/*! @brief Retrieves the work area of the monitor. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the work area of the specified monitor along with the work area + * size in screen coordinates. The work area is defined as the area of the + * monitor not occluded by the operating system task bar where present. If no + * task bar exists then the work area is the monitor resolution in screen + * coordinates. + * + * Any or all of the position and size arguments may be `NULL`. If an error + * occurs, all non-`NULL` position and size arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. + * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. + * @param[out] width Where to store the monitor width, or `NULL`. + * @param[out] height Where to store the monitor height, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_workarea + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); + /*! @brief Returns the physical size of the monitor. * * This function returns the size, in millimetres, of the display area of the @@ -1932,8 +2127,8 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @remark @win32 calculates the returned physical size from the - * current resolution and system DPI instead of querying the monitor EDID data. + * @remark @win32 On Windows 8 and earlier the physical size is calculated from + * the current resolution and system DPI instead of querying the monitor EDID data. * * @thread_safety This function must only be called from the main thread. * @@ -1949,9 +2144,11 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * * This function retrieves the content scale for the specified monitor. The * content scale is the ratio between the current DPI and the platform's - * default DPI. If you scale all pixel dimensions by this scale then your - * content should appear at an appropriate size. This is especially important - * for text and any UI elements. + * default DPI. This is especially important for text and any UI elements. If + * the pixel dimensions of your UI scaled by this look appropriate on your + * machine then it should appear at a reasonable size on other machines + * regardless of their DPI and scaling settings. This relies on the system DPI + * and scaling settings being somewhat correct. * * The content scale may depend on both the monitor resolution and pixel * density and on user settings. It may be very different from the raw DPI @@ -2057,11 +2254,18 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* monitor); * currently set callback. This is called when a monitor is connected to or * disconnected from the system. * - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWmonitor* monitor, int event) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWmonitorfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -2072,14 +2276,15 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* monitor); * * @ingroup monitor */ -GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); +GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback); /*! @brief Returns the available video modes for the specified monitor. * * This function returns an array of all video modes supported by the specified * monitor. The returned array is sorted in ascending order, first by color - * bit depth (the sum of all channel depths) and then by resolution area (the - * product of width and height). + * bit depth (the sum of all channel depths), then by resolution area (the + * product of width and height), then resolution width and finally by refresh + * rate. * * @param[in] monitor The monitor to query. * @param[out] count Where to store the number of video modes in the returned @@ -2137,9 +2342,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * - * This function generates a 256-element gamma ramp from the specified exponent - * and then calls @ref glfwSetGammaRamp with it. The value must be a finite - * number greater than zero. + * This function generates an appropriately sized gamma ramp from the specified + * exponent and then calls @ref glfwSetGammaRamp with it. The value must be + * a finite number greater than zero. * * The software controlled gamma ramp is applied _in addition_ to the hardware * gamma correction, which today is usually an approximation of sRGB gamma. @@ -2155,7 +2360,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * - * @remark @wayland Gamma handling is a priviledged protocol, this function + * @remark @wayland Gamma handling is a privileged protocol, this function * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. @@ -2179,7 +2384,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland Gamma handling is a priviledged protocol, this function + * @remark @wayland Gamma handling is a privileged protocol, this function * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while * returning `NULL`. * @@ -2218,12 +2423,12 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark Gamma ramp sizes other than 256 are not supported by all platforms - * or graphics hardware. + * @remark The size of the specified gamma ramp should match the size of the + * current ramp for that monitor. * * @remark @win32 The gamma ramp size must be 256. * - * @remark @wayland Gamma handling is a priviledged protocol, this function + * @remark @wayland Gamma handling is a privileged protocol, this function * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified gamma ramp is copied before this function @@ -2442,7 +2647,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * * @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 overriden by previously saved values. + * window size and position may be overridden by previously saved values. * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. @@ -2455,15 +2660,18 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * @remark @x11 The class part of the `WM_CLASS` window property will by * default be set to the window title passed to this function. The instance * part will use the contents of the `RESOURCE_NAME` environment variable, if - * present and not empty, or fall back to the window title. Set the @ref - * GLFW_X11_CLASS_NAME and @ref GLFW_X11_INSTANCE_NAME window hints to override - * this. - * - * @remark @wayland The window frame is currently very simple, only allowing - * window resize or move. A compositor can still emit close, maximize or - * fullscreen events, using for example a keybind mechanism. Additionally, - * the wp_viewporter protocol is required for this feature, otherwise the - * window will not be decorated. + * present and not empty, or fall back to the window title. Set the + * [GLFW_X11_CLASS_NAME](@ref GLFW_X11_CLASS_NAME_hint) and + * [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. @@ -2599,8 +2807,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @param[in] images The images to create the icon from. This is ignored if * count is zero. * - * @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 and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. @@ -2625,19 +2833,19 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); */ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); -/*! @brief Retrieves the position of the client area of the specified window. +/*! @brief Retrieves the position of the content area of the specified window. * * This function retrieves the position, in screen coordinates, of the - * upper-left corner of the client area of the specified window. + * upper-left corner of the content area of the specified window. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] window The window to query. * @param[out] xpos Where to store the x-coordinate of the upper-left corner of - * the client area, or `NULL`. + * the content area, or `NULL`. * @param[out] ypos Where to store the y-coordinate of the upper-left corner of - * the client area, or `NULL`. + * the content area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2657,10 +2865,10 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i */ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); -/*! @brief Sets the position of the client area of the specified window. +/*! @brief Sets the position of the content area of the specified window. * * This function sets the position, in screen coordinates, of the upper-left - * corner of the client area of the specified windowed mode window. If the + * corner of the content area of the specified windowed mode window. If the * window is a full screen window, this function does nothing. * * __Do not use this function__ to move an already visible window unless you @@ -2670,8 +2878,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * cannot and should not override these limits. * * @param[in] window The window to query. - * @param[in] xpos The x-coordinate of the upper-left corner of the client area. - * @param[in] ypos The y-coordinate of the upper-left corner of the client area. + * @param[in] xpos The x-coordinate of the upper-left corner of the content area. + * @param[in] ypos The y-coordinate of the upper-left corner of the content area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2692,9 +2900,9 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); */ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); -/*! @brief Retrieves the size of the client area of the specified window. +/*! @brief Retrieves the size of the content area of the specified window. * - * This function retrieves the size, in screen coordinates, of the client area + * This function retrieves the size, in screen coordinates, of the content area * of the specified window. If you wish to retrieve the size of the * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. * @@ -2703,9 +2911,9 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); * * @param[in] window The window whose size to retrieve. * @param[out] width Where to store the width, in screen coordinates, of the - * client area, or `NULL`. + * content area, or `NULL`. * @param[out] height Where to store the height, in screen coordinates, of the - * client area, or `NULL`. + * content area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2724,7 +2932,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); /*! @brief Sets the size limits of the specified window. * - * This function sets the size limits of the client area of the specified + * This function sets the size limits of the content area of the specified * window. If the window is full screen, the size limits only take effect * once it is made windowed. If the window is not resizable, this function * does nothing. @@ -2736,14 +2944,14 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); * dimensions and all must be greater than or equal to zero. * * @param[in] window The window to set limits for. - * @param[in] minwidth The minimum width, in screen coordinates, of the client + * @param[in] minwidth The minimum width, in screen coordinates, of the content * area, or `GLFW_DONT_CARE`. * @param[in] minheight The minimum height, in screen coordinates, of the - * client area, or `GLFW_DONT_CARE`. - * @param[in] maxwidth The maximum width, in screen coordinates, of the client + * content area, or `GLFW_DONT_CARE`. + * @param[in] maxwidth The maximum width, in screen coordinates, of the content * area, or `GLFW_DONT_CARE`. * @param[in] maxheight The maximum height, in screen coordinates, of the - * client area, or `GLFW_DONT_CARE`. + * content area, or `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. @@ -2767,7 +2975,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe /*! @brief Sets the aspect ratio of the specified window. * - * This function sets the required aspect ratio of the client area of the + * This function sets the required aspect ratio of the content area of the * specified window. If the window is full screen, the aspect ratio only takes * effect once it is made windowed. If the window is not resizable, this * function does nothing. @@ -2808,9 +3016,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe */ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); -/*! @brief Sets the size of the client area of the specified window. +/*! @brief Sets the size of the content area of the specified window. * - * This function sets the size, in screen coordinates, of the client area of + * This function sets the size, in screen coordinates, of the content area of * the specified window. * * For full screen windows, this function updates the resolution of its desired @@ -2826,9 +3034,9 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * * @param[in] window The window to resize. * @param[in] width The desired width, in screen coordinates, of the window - * client area. + * content area. * @param[in] height The desired height, in screen coordinates, of the window - * client area. + * content area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -2919,9 +3127,11 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int * * This function retrieves the content scale for the specified window. The * content scale is the ratio between the current DPI and the platform's - * default DPI. If you scale all pixel dimensions by this scale then your - * content should appear at an appropriate size. This is especially important - * for text and any UI elements. + * default DPI. This is especially important for text and any UI elements. If + * the pixel dimensions of your UI scaled by this look appropriate on your + * machine then it should appear at a reasonable size on other machines + * regardless of their DPI and scaling settings. This relies on the system DPI + * and scaling settings being somewhat correct. * * On systems where each monitors can have its own content scale, the window * content scale will depend on which monitor the system considers the window @@ -3008,18 +3218,15 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); * previously restored. If the window is already iconified, this function does * nothing. * - * If the specified window is a full screen window, the original monitor - * resolution is restored until the window is restored. + * If the specified window is a full screen window, GLFW restores the original + * video mode of the monitor. The window's desired video mode is set again + * when the window is restored. * * @param[in] window The window to iconify. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland There is no concept of iconification in wl_shell, this - * function will emit @ref GLFW_PLATFORM_ERROR when using this deprecated - * protocol. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -3039,8 +3246,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); * (minimized) or maximized. If the window is already restored, this function * does nothing. * - * If the specified window is a full screen window, the resolution chosen for - * the window is restored on the selected monitor. + * If the specified window is an iconified full screen window, its desired + * video mode is set again for its monitor when the window is restored. * * @param[in] window The window to restore. * @@ -3101,6 +3308,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @wayland Because Wayland wants every frame of the desktop to be + * complete, this function does not immediately make the window visible. + * Instead it will become visible the next time the window framebuffer is + * updated after this call. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide @@ -3232,7 +3444,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * The window position is ignored when setting a monitor. * * When the monitor is `NULL`, the position, width and height are used to - * place the window client area. The refresh rate is ignored when no monitor + * place the window content area. The refresh rate is ignored when no monitor * is specified. * * If you only wish to update the resolution of a full screen window or the @@ -3245,12 +3457,12 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @param[in] window The window whose monitor, size or video mode to set. * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. * @param[in] xpos The desired x-coordinate of the upper-left corner of the - * client area. + * content area. * @param[in] ypos The desired y-coordinate of the upper-left corner of the - * client area. - * @param[in] width The desired with, in screen coordinates, of the client area - * or video mode. - * @param[in] height The desired height, in screen coordinates, of the client + * content area. + * @param[in] width The desired with, in screen coordinates, of the content + * area or video mode. + * @param[in] height The desired height, in screen coordinates, of the content * area or video mode. * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, * or `GLFW_DONT_CARE`. @@ -3303,6 +3515,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int * errors. However, this function should not fail as long as it is passed * valid arguments and the library has been [initialized](@ref intro_init). * + * @remark @wayland The Wayland protocol provides no way to check whether a + * window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs @@ -3400,15 +3615,22 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * * This function sets the position callback of the specified window, which is * called when the window is moved. The callback is provided with the - * position, in screen coordinates, of the upper-left corner of the client area - * of the window. + * position, in screen coordinates, of the upper-left corner of the content + * area of the window. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int xpos, int ypos) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowposfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @wayland This callback will never be called, as there is no way for @@ -3422,20 +3644,27 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * * @ingroup window */ -GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun); +GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback); /*! @brief Sets the size callback for the specified window. * * This function sets the size callback of the specified window, which is * called when the window is resized. The callback is provided with the size, - * in screen coordinates, of the client area of the window. + * in screen coordinates, of the content area of the window. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowsizefun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -3447,7 +3676,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow * * @ingroup window */ -GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun); +GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun callback); /*! @brief Sets the close callback for the specified window. * @@ -3461,11 +3690,18 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind * The close callback is not triggered by @ref glfwDestroyWindow. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowclosefun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @macos Selecting Quit from the application menu will trigger the @@ -3480,12 +3716,12 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind * * @ingroup window */ -GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun); +GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback); /*! @brief Sets the refresh callback for the specified window. * * This function sets the refresh callback of the specified window, which is - * called when the client area of the window needs to be redrawn, for example + * called when the content area of the window needs to be redrawn, for example * if the window has been exposed after having been covered by another window. * * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where @@ -3493,11 +3729,18 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi * very infrequently or never at all. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window); + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowrefreshfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -3509,7 +3752,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi * * @ingroup window */ -GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun); +GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback); /*! @brief Sets the focus callback for the specified window. * @@ -3522,11 +3765,18 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL * and @ref glfwSetMouseButtonCallback. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int focused) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowfocusfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -3537,7 +3787,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL * * @ingroup window */ -GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun); +GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun callback); /*! @brief Sets the iconify callback for the specified window. * @@ -3545,15 +3795,22 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * is called when the window is iconified or restored. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int iconified) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowiconifyfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @remark @wayland The wl_shell protocol has no concept of iconification, - * this callback will never be called when using this deprecated protocol. + * @remark @wayland The XDG-shell protocol has no event for iconification, so + * this callback will never be called. * * @thread_safety This function must only be called from the main thread. * @@ -3563,7 +3820,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * * @ingroup window */ -GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun); +GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun callback); /*! @brief Sets the maximize callback for the specified window. * @@ -3571,11 +3828,18 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL * is called when the window is maximized or restored. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int maximized) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowmaximizefun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -3586,7 +3850,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL * * @ingroup window */ -GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun cbfun); +GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun callback); /*! @brief Sets the framebuffer resize callback for the specified window. * @@ -3594,11 +3858,18 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, * which is called when the framebuffer of the specified window is resized. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWframebuffersizefun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -3609,7 +3880,7 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, * * @ingroup window */ -GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun); +GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun callback); /*! @brief Sets the window content scale callback for the specified window. * @@ -3617,11 +3888,18 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * which is called when the content scale of the specified window changes. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, float xscale, float yscale) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowcontentscalefun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -3633,7 +3911,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * * @ingroup window */ -GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun cbfun); +GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun callback); /*! @brief Processes all pending events. * @@ -3699,10 +3977,6 @@ GLFWAPI void glfwPollEvents(void); * GLFW will pass those events on to the application callbacks before * returning. * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * * Event processing is not required for joystick input to work. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref @@ -3750,14 +4024,13 @@ GLFWAPI void glfwWaitEvents(void); * GLFW will pass those events on to the application callbacks before * returning. * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * * Event processing is not required for joystick input to work. * * @param[in] timeout The maximum amount of time, in seconds, to wait. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. @@ -3777,10 +4050,6 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout); * This function posts an empty event from the current thread to the event * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return. * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * @@ -3800,11 +4069,13 @@ GLFWAPI void glfwPostEmptyEvent(void); * * This function returns the value of an input option for the specified window. * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS or @ref GLFW_LOCK_KEY_MODS. + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or + * @ref GLFW_RAW_MOUSE_MOTION. * * @param[in] window The window to query. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS` or `GLFW_LOCK_KEY_MODS`. + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. @@ -3823,13 +4094,14 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * * This function sets an input mode option for the specified window. The mode * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS or @ref GLFW_LOCK_KEY_MODS. + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or + * @ref GLFW_RAW_MOUSE_MOTION. * * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. - * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client - * area of the window but does not restrict the cursor from leaving. + * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the + * content area of the window but does not restrict the cursor from leaving. * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. @@ -3855,9 +4127,16 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on. * + * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE` + * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is + * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported, + * attempting to set this will emit @ref GLFW_PLATFORM_ERROR. Call @ref + * glfwRawMouseMotionSupported to check for support. + * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS` or `GLFW_LOCK_KEY_MODS`. + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. * @param[in] value The new value of the specified input mode. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref @@ -3873,6 +4152,35 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); +/*! @brief Returns whether raw mouse motion is supported. + * + * This function returns whether raw mouse motion is supported on the current + * system. This status does not change after GLFW has been initialized so you + * only need to check this once. If you attempt to enable raw motion on + * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted. + * + * Raw mouse motion is closer to the actual motion of the mouse across + * a surface. It is not affected by the scaling and acceleration applied to + * the motion of the desktop cursor. That processing is suitable for a cursor + * while raw motion is better for controlling for example a 3D camera. Because + * of this, raw mouse motion is only provided when the cursor is disabled. + * + * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine, + * or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref raw_mouse_motion + * @sa @ref glfwSetInputMode + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwRawMouseMotionSupported(void); + /*! @brief Returns the layout-specific name of the specified printable key. * * This function returns the name of the specified printable key, encoded as @@ -3925,9 +4233,11 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark The contents of the returned string may change when a keyboard + * layout change event is received. + * * @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 - * glfwGetKeyName, or until the library is terminated. + * should not free it yourself. It is valid until the library is terminated. * * @thread_safety This function must only be called from the main thread. * @@ -3968,8 +4278,7 @@ GLFWAPI int glfwGetKeyScancode(int key); * * This function returns the last state reported for the specified key to the * specified window. The returned state is one of `GLFW_PRESS` or - * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to - * the key callback. + * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback. * * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns * `GLFW_PRESS` the first time you call it for a key that was pressed, even if @@ -4011,8 +4320,8 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); * `GLFW_RELEASE`. * * If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function - * `GLFW_PRESS` the first time you call it for a mouse button that was pressed, - * even if that mouse button has already been released. + * returns `GLFW_PRESS` the first time you call it for a mouse button that was + * pressed, even if that mouse button has already been released. * * @param[in] window The desired window. * @param[in] button The desired [mouse button](@ref buttons). @@ -4032,11 +4341,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); */ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); -/*! @brief Retrieves the position of the cursor relative to the client area of +/*! @brief Retrieves the position of the cursor relative to the content area of * the window. * * This function returns the position of the cursor, in screen coordinates, - * relative to the upper-left corner of the client area of the specified + * relative to the upper-left corner of the content area of the specified * window. * * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor @@ -4052,9 +4361,9 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); * * @param[in] window The desired window. * @param[out] xpos Where to store the cursor x-coordinate, relative to the - * left edge of the client area, or `NULL`. + * left edge of the content area, or `NULL`. * @param[out] ypos Where to store the cursor y-coordinate, relative to the to - * top edge of the client area, or `NULL`. + * top edge of the content area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -4070,11 +4379,11 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); */ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); -/*! @brief Sets the position of the cursor, relative to the client area of the +/*! @brief Sets the position of the cursor, relative to the content area of the * window. * * This function sets the position, in screen coordinates, of the cursor - * relative to the upper-left corner of the client area of the specified + * relative to the upper-left corner of the content area of the specified * window. The window must have input focus. If the window does not have * input focus when this function is called, it fails silently. * @@ -4089,9 +4398,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * * @param[in] window The desired window. * @param[in] xpos The desired x-coordinate, relative to the left edge of the - * client area. + * content area. * @param[in] ypos The desired y-coordinate, relative to the top edge of the - * client area. + * content area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. @@ -4130,8 +4439,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * @return The handle of the created cursor, 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_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. @@ -4201,7 +4510,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); /*! @brief Sets the cursor for the window. * * This function sets the cursor image to be used when the cursor is over the - * client area of the specified window. The set cursor will only be visible + * content area of the specified window. The set cursor will only be visible * when the [cursor mode](@ref cursor_mode) of the window is * `GLFW_CURSOR_NORMAL`. * @@ -4250,11 +4559,18 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * scancode may be zero. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new key callback, or `NULL` to remove the currently + * @param[in] callback The new key callback, or `NULL` to remove the currently * set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWkeyfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4266,7 +4582,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * * @ingroup input */ -GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); +GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback); /*! @brief Sets the Unicode character callback. * @@ -4283,16 +4599,21 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * The character callback behaves as system text input normally does and will * not be called if modifier keys are held down that would prevent normal text * input on that platform, for example a Super (Command) key on macOS or Alt key - * on Windows. There is a - * [character with modifiers callback](@ref glfwSetCharModsCallback) that - * receives these events. + * on Windows. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcharfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4304,7 +4625,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * * @ingroup input */ -GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); +GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback); /*! @brief Sets the Unicode character with modifiers callback. * @@ -4322,11 +4643,18 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); * [key callback](@ref glfwSetKeyCallback) instead. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or an * [error](@ref error_handling) occurred. * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcharmodsfun). + * * @deprecated Scheduled for removal in version 4.0. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. @@ -4339,7 +4667,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); * * @ingroup input */ -GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun); +GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback); /*! @brief Sets the mouse button callback. * @@ -4353,11 +4681,18 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int button, int action, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWmousebuttonfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4369,21 +4704,28 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * * @ingroup input */ -GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun); +GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun callback); /*! @brief Sets the cursor position callback. * * This function sets the cursor position callback of the specified window, * which is called when the cursor is moved. The callback is provided with the * position, in screen coordinates, relative to the upper-left corner of the - * client area of the window. + * content area of the window. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double xpos, double ypos); + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcursorposfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4394,20 +4736,27 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo * * @ingroup input */ -GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun); +GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun callback); -/*! @brief Sets the cursor enter/exit callback. +/*! @brief Sets the cursor enter/leave callback. * * This function sets the cursor boundary crossing callback of the specified - * window, which is called when the cursor enters or leaves the client area of + * window, which is called when the cursor enters or leaves the content area of * the window. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int entered) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcursorenterfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4418,7 +4767,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor * * @ingroup input */ -GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun); +GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun callback); /*! @brief Sets the scroll callback. * @@ -4430,11 +4779,18 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu * wheel or a touchpad scrolling area. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently - * set callback. + * @param[in] callback The new scroll callback, or `NULL` to remove the + * currently set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double xoffset, double yoffset) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWscrollfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4445,12 +4801,12 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu * * @ingroup input */ -GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); +GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback); -/*! @brief Sets the file drop callback. +/*! @brief Sets the path drop callback. * - * This function sets the file drop callback of the specified window, which is - * called when one or more dragged files are dropped on the window. + * This function sets the path drop callback of the specified window, which is + * called when one or more dragged paths are dropped on the window. * * Because the path array and its strings may have been generated specifically * for that event, they are not guaranteed to be valid after the callback has @@ -4458,11 +4814,18 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * make a deep copy. * * @param[in] window The window whose callback to set. - * @param[in] cbfun The new file drop callback, or `NULL` to remove the + * @param[in] callback The new file drop callback, or `NULL` to remove the * currently set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int path_count, const char* paths[]) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWdropfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @wayland File drop is currently unimplemented. @@ -4475,7 +4838,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * * @ingroup input */ -GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback); /*! @brief Returns whether the specified joystick is present. * @@ -4581,7 +4944,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count); * Each element in the array is one of the following values: * * Name | Value - * --------------------- | -------------------------------- + * ---- | ----- * `GLFW_HAT_CENTERED` | 0 * `GLFW_HAT_UP` | 1 * `GLFW_HAT_RIGHT` | 2 @@ -4663,7 +5026,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count); */ GLFWAPI const char* glfwGetJoystickName(int jid); -/*! @brief Returns the SDL comaptible GUID of the specified joystick. +/*! @brief Returns the SDL compatible GUID of the specified joystick. * * This function returns the SDL compatible GUID, as a UTF-8 encoded * hexadecimal string, of the specified joystick. The returned string is @@ -4794,11 +5157,18 @@ GLFWAPI int glfwJoystickIsGamepad(int jid); * called by joystick functions. The function will then return whatever it * returns if the joystick is not present. * - * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * @param[in] callback The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @callback_signature + * @code + * void function_name(int jid, int event) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWjoystickfun). + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. @@ -4809,7 +5179,7 @@ GLFWAPI int glfwJoystickIsGamepad(int jid); * * @ingroup input */ -GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun); +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback); /*! @brief Adds the specified SDL_GameControllerDB gamepad mappings. * @@ -4860,6 +5230,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string); * joystick is not present, does not have a mapping or an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, the gamepad mappings are updated or the library is terminated. @@ -4877,7 +5249,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid); /*! @brief Retrieves the state of the specified joystick remapped as a gamepad. * - * This function retrives the state of the specified joystick remapped to + * This function retrieves the state of the specified joystick remapped to * an Xbox-like gamepad. * * If the specified joystick is not present or does not have a gamepad mapping @@ -4901,6 +5273,8 @@ GLFWAPI const char* glfwGetGamepadName(int jid); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * + * @thread_safety This function must only be called from the main thread. + * * @sa @ref gamepad * @sa @ref glfwUpdateGamepadMappings * @sa @ref glfwJoystickIsGamepad @@ -4922,8 +5296,6 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland Clipboard is currently unimplemented. - * * @pointer_lifetime The specified string is copied before this function * returns. * @@ -4949,10 +5321,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @return The contents of the clipboard 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. - * - * @remark @wayland Clipboard is currently unimplemented. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_FORMAT_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 @@ -4970,23 +5340,26 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); */ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); -/*! @brief Returns the value of the GLFW timer. +/*! @brief Returns the GLFW time. + * + * This function returns the current GLFW time, in seconds. Unless the time + * has been set using @ref glfwSetTime it measures time elapsed since GLFW was + * initialized. * - * This function returns the value of the GLFW timer. Unless the timer has - * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW - * was initialized. + * This function and @ref glfwSetTime are helper functions on top of @ref + * glfwGetTimerFrequency and @ref glfwGetTimerValue. * * The resolution of the timer is system dependent, but is usually on the order * of a few micro- or nanoseconds. It uses the highest-resolution monotonic * time source on each supported platform. * - * @return The current value, in seconds, or zero if an + * @return The current time, in seconds, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Reading and - * writing of the internal timer offset is not atomic, so it needs to be + * writing of the internal base time is not atomic, so it needs to be * externally synchronized with calls to @ref glfwSetTime. * * @sa @ref time @@ -4997,23 +5370,26 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); */ GLFWAPI double glfwGetTime(void); -/*! @brief Sets the GLFW timer. +/*! @brief Sets the GLFW time. * - * This function sets the value of the GLFW timer. It then continues to count - * up from that value. The value must be a positive finite number less than - * or equal to 18446744073.0, which is approximately 584.5 years. + * This function sets the current GLFW time, in seconds. The value must be + * a positive finite number less than or equal to 18446744073.0, which is + * approximately 584.5 years. + * + * This function and @ref glfwGetTime are helper functions on top of @ref + * glfwGetTimerFrequency and @ref glfwGetTimerValue. * * @param[in] time The new value, in seconds. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_VALUE. * - * @remark The upper limit of the timer is calculated as + * @remark The upper limit of GLFW time is calculated as * floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations * storing nanoseconds in 64 bits. The limit may be increased in the future. * * @thread_safety This function may be called from any thread. Reading and - * writing of the internal timer offset is not atomic, so it needs to be + * writing of the internal base time is not atomic, so it needs to be * externally synchronized with calls to @ref glfwGetTime. * * @sa @ref time @@ -5290,13 +5666,11 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); * This function returns whether the Vulkan loader and any minimally functional * ICD have been found. * - * The availability of a Vulkan loader and even an ICD does not by itself - * guarantee that surface creation or even instance creation is possible. - * For example, on Fermi systems Nvidia will install an ICD that provides no - * actual Vulkan support. Call @ref glfwGetRequiredInstanceExtensions to check - * whether the extensions necessary for Vulkan surface creation are available - * and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue - * family of a physical device supports image presentation. + * The availability of a Vulkan loader and even an ICD does not by itself guarantee that + * surface creation or even instance creation is possible. Call @ref + * glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan + * surface creation are available and @ref glfwGetPhysicalDevicePresentationSupport to + * check whether a queue family of a physical device supports image presentation. * * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE` * otherwise. @@ -5317,7 +5691,7 @@ GLFWAPI int glfwVulkanSupported(void); * * This function returns an array of names of Vulkan instance extensions required * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the - * list will always contains `VK_KHR_surface`, so if you don't require any + * list will always contain `VK_KHR_surface`, so if you don't require any * additional extensions you can pass this list directly to the * `VkInstanceCreateInfo` struct. * @@ -5342,9 +5716,6 @@ GLFWAPI int glfwVulkanSupported(void); * returned array, as it is an error to specify an extension more than once in * the `VkInstanceCreateInfo` struct. * - * @remark @macos This function currently only supports the - * `VK_MVK_macos_surface` extension from MoltenVK. - * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * library is terminated. @@ -5426,7 +5797,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @remark @macos This function currently always returns `GLFW_TRUE`, as the - * `VK_MVK_macos_surface` extension does not provide + * `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide * a `vkGetPhysicalDevice*PresentationSupport` type function. * * @thread_safety This function may be called from any thread. For @@ -5483,8 +5854,10 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should * eliminate almost all occurrences of these errors. * - * @remark @macos This function currently only supports the - * `VK_MVK_macos_surface` extension from MoltenVK. + * @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the + * `VK_MVK_macos_surface` extension as a fallback. The name of the selected + * extension, if any, is included in the array returned by @ref + * glfwGetRequiredInstanceExtensions. * * @remark @macos This function creates and sets a `CAMetalLayer` instance for * the window content view, which is required for MoltenVK to function. @@ -5525,6 +5898,7 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window */ #ifndef GLAPIENTRY #define GLAPIENTRY APIENTRY + #define GLFW_GLAPIENTRY_DEFINED #endif /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ diff --git a/raylib/examples/others/external/include/GLFW/glfw3native.h b/raylib/examples/others/external/include/GLFW/glfw3native.h index 4372cb7..7be0227 100644 --- a/raylib/examples/others/external/include/GLFW/glfw3native.h +++ b/raylib/examples/others/external/include/GLFW/glfw3native.h @@ -3,7 +3,7 @@ * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard - * Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org> + * Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org> * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -62,7 +62,6 @@ extern "C" { * * `GLFW_EXPOSE_NATIVE_COCOA` * * `GLFW_EXPOSE_NATIVE_X11` * * `GLFW_EXPOSE_NATIVE_WAYLAND` - * * `GLFW_EXPOSE_NATIVE_MIR` * * The available context API macros are: * * `GLFW_EXPOSE_NATIVE_WGL` @@ -75,6 +74,16 @@ extern "C" { * and which platform-specific headers to include. It is then up your (by * definition platform-specific) code to handle which of these should be * defined. + * + * If you do not want the platform-specific headers to be included, define + * `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header. + * + * @code + * #define GLFW_EXPOSE_NATIVE_WIN32 + * #define GLFW_EXPOSE_NATIVE_WGL + * #define GLFW_NATIVE_INCLUDE_NONE + * #include <GLFW/glfw3native.h> + * @endcode */ @@ -82,46 +91,65 @@ extern "C" { * System headers and types *************************************************************************/ -#if defined(GLFW_EXPOSE_NATIVE_WIN32) - // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for - // example to allow applications to correctly declare a GL_ARB_debug_output - // callback) but windows.h assumes no one will define APIENTRY before it does - #if defined(GLFW_APIENTRY_DEFINED) - #undef APIENTRY - #undef GLFW_APIENTRY_DEFINED +#if !defined(GLFW_NATIVE_INCLUDE_NONE) + + #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) + /* 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 + */ + #if defined(GLFW_APIENTRY_DEFINED) + #undef APIENTRY + #undef GLFW_APIENTRY_DEFINED + #endif + #include <windows.h> + #elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) + #if defined(__OBJC__) + #import <Cocoa/Cocoa.h> + #else + #include <ApplicationServices/ApplicationServices.h> + #include <objc/objc.h> + #endif + #elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) + #include <X11/Xlib.h> + #include <X11/extensions/Xrandr.h> + #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include <wayland-client.h> #endif - #include <windows.h> -#elif defined(GLFW_EXPOSE_NATIVE_COCOA) - #include <ApplicationServices/ApplicationServices.h> - #if defined(__OBJC__) - #import <Cocoa/Cocoa.h> - #else - typedef void* id; + + #if defined(GLFW_EXPOSE_NATIVE_WGL) + /* WGL is declared by windows.h */ + #endif + #if defined(GLFW_EXPOSE_NATIVE_NSGL) + /* NSGL is declared by Cocoa.h */ + #endif + #if defined(GLFW_EXPOSE_NATIVE_GLX) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, glx.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif + #include <GL/glx.h> + #endif + #if defined(GLFW_EXPOSE_NATIVE_EGL) + #include <EGL/egl.h> + #endif + #if defined(GLFW_EXPOSE_NATIVE_OSMESA) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, osmesa.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif + #include <GL/osmesa.h> #endif -#elif defined(GLFW_EXPOSE_NATIVE_X11) - #include <X11/Xlib.h> - #include <X11/extensions/Xrandr.h> -#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) - #include <wayland-client.h> -#elif defined(GLFW_EXPOSE_NATIVE_MIR) - #include <mir_toolkit/mir_client_library.h> -#endif -#if defined(GLFW_EXPOSE_NATIVE_WGL) - /* WGL is declared by windows.h */ -#endif -#if defined(GLFW_EXPOSE_NATIVE_NSGL) - /* NSGL is declared by Cocoa.h */ -#endif -#if defined(GLFW_EXPOSE_NATIVE_GLX) - #include <GL/glx.h> -#endif -#if defined(GLFW_EXPOSE_NATIVE_EGL) - #include <EGL/egl.h> -#endif -#if defined(GLFW_EXPOSE_NATIVE_OSMESA) - #include <GL/osmesa.h> -#endif +#endif /*GLFW_NATIVE_INCLUDE_NONE*/ /************************************************************************* @@ -135,6 +163,8 @@ extern "C" { * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -150,6 +180,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -164,6 +196,16 @@ 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. + * + * @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) + * function. + * @code + * HDC dc = GetDC(glfwGetWin32Window(window)); + * @endcode + * This DC is private and does not need to be released. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -180,6 +222,17 @@ 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. + * + * @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) + * function. + * @code + * HDC dc = GetDC(glfwGetWin32Window(window)); + * @endcode + * This DC is private and does not need to be released. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -196,6 +249,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -210,6 +265,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -226,6 +283,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -242,6 +302,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -256,6 +318,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -270,6 +334,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -284,6 +350,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -350,6 +418,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -364,6 +435,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -380,6 +454,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -394,6 +470,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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -408,35 +486,7 @@ 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. * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_MIR) -/*! @brief Returns the `MirConnection*` used by GLFW. - * - * @return The `MirConnection*` used by GLFW, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI MirConnection* glfwGetMirDisplay(void); - -/*! @brief Returns the Mir output ID of the specified monitor. - * - * @return The Mir output ID of the specified monitor, or zero if an - * [error](@ref error_handling) occurred. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. @@ -445,21 +495,7 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void); * * @ingroup native */ -GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); - -/*! @brief Returns the `MirWindow*` of the specified window. - * - * @return The `MirWindow*` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* window); +GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) @@ -468,6 +504,11 @@ GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* window); * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark Because EGL is initialized on demand, this function will return + * `EGL_NO_DISPLAY` until the first context has been created via EGL. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -482,6 +523,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -496,6 +540,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -519,6 +566,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -540,6 +590,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -554,6 +607,9 @@ 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. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * diff --git a/raylib/examples/others/raymath_vector_angle.c b/raylib/examples/others/raymath_vector_angle.c index ad573f5..d0f8154 100644 --- a/raylib/examples/others/raymath_vector_angle.c +++ b/raylib/examples/others/raymath_vector_angle.c @@ -42,7 +42,7 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - float startangle; + float startangle = 0.0f; if (angleMode == 0) startangle = -Vector2LineAngle(v0, v1)*RAD2DEG; if (angleMode == 1) startangle = 0.0f; diff --git a/raylib/examples/others/rlgl_standalone.c b/raylib/examples/others/rlgl_standalone.c index 43cc328..ad5e5e9 100644 --- a/raylib/examples/others/rlgl_standalone.c +++ b/raylib/examples/others/rlgl_standalone.c @@ -5,8 +5,8 @@ * rlgl library is an abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, ES 2.0) * that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) * -* NOTE: This example requires OpenGL 3.3 or OpenGL ES 2.0 for shaders support, -* OpenGL 1.1 does not support shaders but it can also be used. +* WARNING: This example is intended only for PLATFORM_DESKTOP and OpenGL 3.3 Core profile. +* It could work on other platforms if redesigned for those platforms (out-of-scope) * * DEPENDENCIES: * glfw3 - Windows and context initialization library @@ -64,9 +64,6 @@ #define RAYMATH_STATIC_INLINE #include "raymath.h" // Vector2, Vector3, Quaternion and Matrix functionality -#if defined(__EMSCRIPTEN__) - #define GLFW_INCLUDE_ES2 -#endif #include "GLFW/glfw3.h" // Windows/Context and inputs management #include <stdio.h> // Required for: printf() @@ -136,6 +133,8 @@ int main(void) glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_DEPTH_BITS, 16); + + // WARNING: OpenGL 3.3 Core profile only glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); diff --git a/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs b/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs index 44d0834..82d0a75 100644 --- a/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs +++ b/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs @@ -6,30 +6,30 @@ precision mediump float; varying vec2 fragTexCoord; varying vec4 fragColor; -uniform vec2 screenDims; // Dimensions of the screen uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c uniform vec2 offset; // Offset of the scale. uniform float zoom; // Zoom of the scale. // NOTE: Maximum number of shader for-loop iterations depend on GPU, // for example, on RasperryPi for this examply only supports up to 60 -const int MAX_ITERATIONS = 48; // Max iterations to do +const int maxIterations = 48; // Max iterations to do. +const float colorCycles = 1.0f; // Number of times the color palette repeats. // Square a complex number vec2 ComplexSquare(vec2 z) { return vec2( - z.x * z.x - z.y * z.y, - z.x * z.y * 2.0 + z.x*z.x - z.y*z.y, + z.x*z.y*2.0f ); } // Convert Hue Saturation Value (HSV) color into RGB vec3 Hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + vec4 K = vec4(1.0f, 2.0f/3.0f, 1.0f/3.0f, 3.0f); + vec3 p = abs(fract(c.xxx + K.xyz)*6.0f - K.www); + return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y); } void main() @@ -45,8 +45,8 @@ void main() If the number is below 2, we keep iterating. But when do we stop iterating if the number is always below 2 (it converges)? - That is what MAX_ITERATIONS is for. - Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can + That is what maxIterations is for. + Then we can divide the iterations by the maxIterations value to get a normalized value that we can then map to a color. We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared. @@ -55,13 +55,15 @@ void main() // The pixel coordinates are scaled so they are on the mandelbrot scale // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom - vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom); + vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5f, (fragTexCoord.y - 0.5f)*1.5f)/zoom; + z.x += offset.x; + z.y += offset.y; int iter = 0; for (int iterations = 0; iterations < 60; iterations++) { z = ComplexSquare(z) + c; // Iterate function - if (dot(z, z) > 4.0) break; + if (dot(z, z) > 4.0f) break; iter = iterations; } @@ -72,12 +74,12 @@ void main() z = ComplexSquare(z) + c; // This last part smooths the color (again see link above). - float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0)); + float smoothVal = float(iter) + 1.0f - (log(log(length(z)))/log(2.0f)); // Normalize the value so it is between 0 and 1. - float norm = smoothVal/float(MAX_ITERATIONS); + float norm = smoothVal/float(maxIterations); // If in set, color black. 0.999 allows for some float accuracy error. - if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - else gl_FragColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0); + if (norm > 0.999f) gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f); + else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0f, 1.0f)), 1.0f); } diff --git a/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs b/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs index 7367161..73531a8 100644 --- a/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs +++ b/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs @@ -18,12 +18,6 @@ uniform vec4 colDiffuse; #define LIGHT_DIRECTIONAL 0 #define LIGHT_POINT 1 -struct MaterialProperty { - vec3 color; - int useSampler; - sampler2D sampler; -}; - struct Light { int enabled; int type; diff --git a/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs b/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs index ec6c664..7ff401a 100644 --- a/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs +++ b/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs @@ -42,5 +42,5 @@ void main() tc += center; vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; - gl_FragColor = vec4(color.rgb, 1.0);; + gl_FragColor = vec4(color.rgb, 1.0); } diff --git a/raylib/examples/shaders/resources/shaders/glsl100/tiling.fs b/raylib/examples/shaders/resources/shaders/glsl100/tiling.fs new file mode 100644 index 0000000..392786a --- /dev/null +++ b/raylib/examples/shaders/resources/shaders/glsl100/tiling.fs @@ -0,0 +1,21 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D diffuseMap; +uniform vec4 tiling; + +// NOTE: Add here your custom variables + +void main() +{ + vec2 texCoord = fragTexCoord*tiling; + fragColor = texture2D(diffuseMap, texCoord); + + gl_FragColor = fragColor; +} diff --git a/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs b/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs index d9cfb44..8dda5a5 100644 --- a/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs +++ b/raylib/examples/shaders/resources/shaders/glsl120/lighting.fs @@ -16,12 +16,6 @@ uniform vec4 colDiffuse; #define LIGHT_DIRECTIONAL 0 #define LIGHT_POINT 1 -struct MaterialProperty { - vec3 color; - int useSampler; - sampler2D sampler; -}; - struct Light { int enabled; int type; diff --git a/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs new file mode 100644 index 0000000..c9c6a31 --- /dev/null +++ b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.fs @@ -0,0 +1,55 @@ +#version 330 core +out vec4 finalColor; + +in vec2 texCoord; +in vec2 texCoord2; + +uniform sampler2D gPosition; +uniform sampler2D gNormal; +uniform sampler2D gAlbedoSpec; + +struct Light { + int enabled; + int type; // Unused in this demo. + vec3 position; + vec3 target; // Unused in this demo. + vec4 color; +}; + +const int NR_LIGHTS = 4; +uniform Light lights[NR_LIGHTS]; +uniform vec3 viewPosition; + +const float QUADRATIC = 0.032; +const float LINEAR = 0.09; + +void main() { + vec3 fragPosition = texture(gPosition, texCoord).rgb; + vec3 normal = texture(gNormal, texCoord).rgb; + vec3 albedo = texture(gAlbedoSpec, texCoord).rgb; + float specular = texture(gAlbedoSpec, texCoord).a; + + vec3 ambient = albedo * vec3(0.1f); + vec3 viewDirection = normalize(viewPosition - fragPosition); + + for(int i = 0; i < NR_LIGHTS; ++i) + { + if(lights[i].enabled == 0) continue; + vec3 lightDirection = lights[i].position - fragPosition; + vec3 diffuse = max(dot(normal, lightDirection), 0.0) * albedo * lights[i].color.xyz; + + vec3 halfwayDirection = normalize(lightDirection + viewDirection); + float spec = pow(max(dot(normal, halfwayDirection), 0.0), 32.0); + vec3 specular = specular * spec * lights[i].color.xyz; + + // Attenuation + float distance = length(lights[i].position - fragPosition); + float attenuation = 1.0 / (1.0 + LINEAR * distance + QUADRATIC * distance * distance); + diffuse *= attenuation; + specular *= attenuation; + ambient += diffuse + specular; + } + + finalColor = vec4(ambient, 1.0); +} + diff --git a/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs new file mode 100644 index 0000000..f2b1bd7 --- /dev/null +++ b/raylib/examples/shaders/resources/shaders/glsl330/deferred_shading.vs @@ -0,0 +1,11 @@ +#version 330 core + +layout (location = 0) in vec3 vertexPosition; +layout (location = 1) in vec2 vertexTexCoord; + +out vec2 texCoord; + +void main() { + gl_Position = vec4(vertexPosition, 1.0); + texCoord = vertexTexCoord; +} diff --git a/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs new file mode 100644 index 0000000..c86e20a --- /dev/null +++ b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.fs @@ -0,0 +1,22 @@ +#version 330 core +layout (location = 0) out vec3 gPosition; +layout (location = 1) out vec3 gNormal; +layout (location = 2) out vec4 gAlbedoSpec; + +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec3 fragNormal; + +uniform sampler2D diffuseTexture; +uniform sampler2D specularTexture; + +void main() { + // store the fragment position vector in the first gbuffer texture + gPosition = fragPosition; + // also store the per-fragment normals into the gbuffer + gNormal = normalize(fragNormal); + // and the diffuse per-fragment color + gAlbedoSpec.rgb = texture(diffuseTexture, fragTexCoord).rgb; + // store specular intensity in gAlbedoSpec's alpha component + gAlbedoSpec.a = texture(specularTexture, fragTexCoord).r; +} diff --git a/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs new file mode 100644 index 0000000..7d264ba --- /dev/null +++ b/raylib/examples/shaders/resources/shaders/glsl330/gbuffer.vs @@ -0,0 +1,24 @@ +#version 330 core +layout (location = 0) in vec3 vertexPosition; +layout (location = 1) in vec2 vertexTexCoord; +layout (location = 2) in vec3 vertexNormal; + +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec3 fragNormal; + +uniform mat4 matModel; +uniform mat4 matView; +uniform mat4 matProjection; + +void main() +{ + vec4 worldPos = matModel * vec4(vertexPosition, 1.0); + fragPosition = worldPos.xyz; + fragTexCoord = vertexTexCoord; + + mat3 normalMatrix = transpose(inverse(mat3(matModel))); + fragNormal = normalMatrix * vertexNormal; + + gl_Position = matProjection * matView * worldPos; +} diff --git a/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs b/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs index c5ee0da..7a6f069 100644 --- a/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs +++ b/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs @@ -7,28 +7,28 @@ in vec4 fragColor; // Output fragment color out vec4 finalColor; -uniform vec2 screenDims; // Dimensions of the screen uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c uniform vec2 offset; // Offset of the scale. uniform float zoom; // Zoom of the scale. -const int MAX_ITERATIONS = 255; // Max iterations to do. +const int maxIterations = 255; // Max iterations to do. +const float colorCycles = 2.0f; // Number of times the color palette repeats. Can show higher detail for higher iteration numbers. // Square a complex number vec2 ComplexSquare(vec2 z) { return vec2( - z.x * z.x - z.y * z.y, - z.x * z.y * 2.0 + z.x*z.x - z.y*z.y, + z.x*z.y*2.0f ); } // Convert Hue Saturation Value (HSV) color into RGB vec3 Hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + vec4 K = vec4(1.0f, 2.0f/3.0f, 1.0f/3.0f, 3.0f); + vec3 p = abs(fract(c.xxx + K.xyz)*6.0f - K.www); + return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y); } void main() @@ -44,8 +44,8 @@ void main() If the number is below 2, we keep iterating. But when do we stop iterating if the number is always below 2 (it converges)? - That is what MAX_ITERATIONS is for. - Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can + That is what maxIterations is for. + Then we can divide the iterations by the maxIterations value to get a normalized value that we can then map to a color. We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared. @@ -54,14 +54,16 @@ void main() // The pixel coordinates are scaled so they are on the mandelbrot scale // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom - vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom); + vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5f, (fragTexCoord.y - 0.5f)*1.5f)/zoom; + z.x += offset.x; + z.y += offset.y; int iterations = 0; - for (iterations = 0; iterations < MAX_ITERATIONS; iterations++) + for (iterations = 0; iterations < maxIterations; iterations++) { z = ComplexSquare(z) + c; // Iterate function - if (dot(z, z) > 4.0) break; + if (dot(z, z) > 4.0f) break; } // Another few iterations decreases errors in the smoothing calculation. @@ -70,12 +72,12 @@ void main() z = ComplexSquare(z) + c; // This last part smooths the color (again see link above). - float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0)); + float smoothVal = float(iterations) + 1.0f - (log(log(length(z)))/log(2.0f)); // Normalize the value so it is between 0 and 1. - float norm = smoothVal/float(MAX_ITERATIONS); + float norm = smoothVal/float(maxIterations); // If in set, color black. 0.999 allows for some float accuracy error. - if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else finalColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0); + if (norm > 0.999f) finalColor = vec4(0.0f, 0.0f, 0.0f, 1.0f); + else finalColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0f, 1.0f)), 1.0f); } diff --git a/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs b/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs index 58845c8..d1f3140 100644 --- a/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs +++ b/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs @@ -19,12 +19,6 @@ out vec4 finalColor; #define LIGHT_DIRECTIONAL 0 #define LIGHT_POINT 1 -struct MaterialProperty { - vec3 color; - int useSampler; - sampler2D sampler; -}; - struct Light { int enabled; int type; diff --git a/raylib/examples/shaders/shader_texture_tiling.c b/raylib/examples/shaders/shader_texture_tiling.c deleted file mode 100644 index 868d6b8..0000000 --- a/raylib/examples/shaders/shader_texture_tiling.c +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************************* -* -* raylib [textures] example - Texture Tiling -* -* Example demonstrates how to tile a texture on a 3D model using raylib. -* -* Example contributed by LuÃs Almeida (https://github.com/luis605) -* -* 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 LuÃs Almeida (https://github.com/luis605) -* -********************************************************************************************/ - -#include "raylib.h" - -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ - -int main(void) -{ - const int screenWidth = 800; - const int screenHeight = 600; - - // Initialization - //-------------------------------------------------------------------------------------- - InitWindow(screenWidth, screenHeight, "Raylib Texture Tiling"); - - SetTargetFPS(60); - - // Load a texture - Texture2D texture = LoadTexture("resources/raylib_logo.png"); - - // Create a cube mesh - Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); - - // Load the texture onto the GPU - Model model = LoadModelFromMesh(cube); - model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; - - // Set the tiling of the texture - float tiling[2] = {3.0f, 3.0f}; - Shader shader = LoadShader(0, "resources/shaders/glsl330/tiling.fs"); // Create a custom shader in a .glsl file - SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2); - model.materials[0].shader = shader; - - // Camera setup - Camera camera = { 0 }; - camera.position = (Vector3){ 3.0f, 3.0f, 3.0f }; - camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; - camera.fovy = 45.0f; - camera.projection = CAMERA_PERSPECTIVE; - - // Main game loop - while (!WindowShouldClose()) - { - // Update - //---------------------------------------------------------------------------------- - - BeginDrawing(); - ClearBackground(RAYWHITE); - UpdateCamera(&camera, CAMERA_FREE); - - // Draw the model - { - BeginMode3D(camera); - BeginShaderMode(shader); - - DrawModel(model, (Vector3){ 0.0f, 0.0f, 0.0f }, 5.0f, WHITE); - - EndShaderMode(); - EndMode3D(); - } - - DrawText("Use mouse to rotate the camera", 10, 10, 20, DARKGRAY); - - EndDrawing(); - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - - UnloadTexture(texture); // Unload texture - UnloadModel(model); // Unload model - UnloadShader(shader); // Unload shader - - - CloseWindow(); // Close window and OpenGL context - - return 0; -} diff --git a/raylib/examples/shaders/shaders_custom_uniform.c b/raylib/examples/shaders/shaders_custom_uniform.c index 0a1a764..b3b8040 100644 --- a/raylib/examples/shaders/shaders_custom_uniform.c +++ b/raylib/examples/shaders/shaders_custom_uniform.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [shaders] example - Apply a postprocessing shader and connect a custom uniform variable +* raylib [shaders] example - Postprocessing with custom uniform variable * * NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, * OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. diff --git a/raylib/examples/shaders/shaders_deferred_render.c b/raylib/examples/shaders/shaders_deferred_render.c new file mode 100644 index 0000000..21d2af3 --- /dev/null +++ b/raylib/examples/shaders/shaders_deferred_render.c @@ -0,0 +1,336 @@ +/******************************************************************************************* +* +* raylib [shaders] example - deferred rendering +* +* NOTE: This example requires raylib OpenGL 3.3 or OpenGL ES 3.0 +* +* Example originally created with raylib 4.5, last time updated with raylib 4.5 +* +* Example contributed by Justin Andreas Lacoste (@27justin) 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 Justin Andreas Lacoste (@27justin) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "rlgl.h" +#include "raymath.h" + +#define RLIGHTS_IMPLEMENTATION +#include "rlights.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +#include <stdlib.h> // Required for: NULL + +#define MAX_CUBES 30 + +typedef struct GBuffer { + unsigned int framebuffer; + + unsigned int positionTexture; + unsigned int normalTexture; + unsigned int albedoSpecTexture; + + unsigned int depthRenderbuffer; +} GBuffer; + +typedef enum { + DEFERRED_POSITION, + DEFERRED_NORMAL, + DEFERRED_ALBEDO, + DEFERRED_SHADING +} DeferredMode; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + // ------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - deferred render"); + + Camera camera = { 0 }; + camera.position = (Vector3){ 5.0f, 4.0f, 5.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 60.0f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera projection type + + // Load plane model from a generated mesh + Model model = LoadModelFromMesh(GenMeshPlane(10.0f, 10.0f, 3, 3)); + Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 2.0f, 2.0f)); + + // Load geometry buffer (G-buffer) shader and deferred shader + Shader gbufferShader = LoadShader("resources/shaders/glsl330/gbuffer.vs", + "resources/shaders/glsl330/gbuffer.fs"); + + Shader deferredShader = LoadShader("resources/shaders/glsl330/deferred_shading.vs", + "resources/shaders/glsl330/deferred_shading.fs"); + deferredShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(deferredShader, "viewPosition"); + + // Initialize the G-buffer + GBuffer gBuffer = { 0 }; + gBuffer.framebuffer = rlLoadFramebuffer(screenWidth, screenHeight); + + if (!gBuffer.framebuffer) + { + TraceLog(LOG_WARNING, "Failed to create framebuffer"); + exit(1); + } + + rlEnableFramebuffer(gBuffer.framebuffer); + + // Since we are storing position and normal data in these textures, + // we need to use a floating point format. + gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1); + + gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1); + // Albedo (diffuse color) and specular strength can be combined into one texture. + // The color in RGB, and the specular strength in the alpha channel. + gBuffer.albedoSpecTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); + + // Activate the draw buffers for our framebuffer + rlActiveDrawBuffers(3); + + // Now we attach our textures to the framebuffer. + rlFramebufferAttach(gBuffer.framebuffer, gBuffer.positionTexture, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); + rlFramebufferAttach(gBuffer.framebuffer, gBuffer.normalTexture, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0); + rlFramebufferAttach(gBuffer.framebuffer, gBuffer.albedoSpecTexture, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0); + + // Finally we attach the depth buffer. + gBuffer.depthRenderbuffer = rlLoadTextureDepth(screenWidth, screenHeight, true); + rlFramebufferAttach(gBuffer.framebuffer, gBuffer.depthRenderbuffer, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); + + // Make sure our framebuffer is complete. + // NOTE: rlFramebufferComplete() automatically unbinds the framebuffer, so we don't have + // to rlDisableFramebuffer() here. + if (!rlFramebufferComplete(gBuffer.framebuffer)) + { + TraceLog(LOG_WARNING, "Framebuffer is not complete"); + exit(1); + } + + // Now we initialize the sampler2D uniform's in the deferred shader. + // We do this by setting the uniform's value to the color channel slot we earlier + // bound our textures to. + rlEnableShader(deferredShader.id); + + rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gPosition"), 0); + rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gNormal"), 1); + rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), 2); + + rlDisableShader(); + + // Assign out lighting shader to model + model.materials[0].shader = gbufferShader; + cube.materials[0].shader = gbufferShader; + + // Create lights + //-------------------------------------------------------------------------------------- + Light lights[MAX_LIGHTS] = { 0 }; + lights[0] = CreateLight(LIGHT_POINT, (Vector3){ -2, 1, -2 }, Vector3Zero(), YELLOW, deferredShader); + lights[1] = CreateLight(LIGHT_POINT, (Vector3){ 2, 1, 2 }, Vector3Zero(), RED, deferredShader); + lights[2] = CreateLight(LIGHT_POINT, (Vector3){ -2, 1, 2 }, Vector3Zero(), GREEN, deferredShader); + lights[3] = CreateLight(LIGHT_POINT, (Vector3){ 2, 1, -2 }, Vector3Zero(), BLUE, deferredShader); + + const float CUBE_SCALE = 0.25; + Vector3 cubePositions[MAX_CUBES] = { 0 }; + float cubeRotations[MAX_CUBES] = { 0 }; + + for (int i = 0; i < MAX_CUBES; i++) + { + cubePositions[i] = (Vector3){ + .x = (float)(rand()%10) - 5, + .y = (float)(rand()%5), + .z = (float)(rand()%10) - 5, + }; + + cubeRotations[i] = (float)(rand()%360); + } + + DeferredMode mode = DEFERRED_SHADING; + + rlEnableDepthTest(); + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera, CAMERA_ORBITAL); + + // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f }) + float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; + SetShaderValue(deferredShader, deferredShader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3); + + // Check key inputs to enable/disable lights + if (IsKeyPressed(KEY_Y)) { lights[0].enabled = !lights[0].enabled; } + if (IsKeyPressed(KEY_R)) { lights[1].enabled = !lights[1].enabled; } + if (IsKeyPressed(KEY_G)) { lights[2].enabled = !lights[2].enabled; } + if (IsKeyPressed(KEY_B)) { lights[3].enabled = !lights[3].enabled; } + + // Check key inputs to switch between G-buffer textures + if (IsKeyPressed(KEY_ONE)) mode = DEFERRED_POSITION; + if (IsKeyPressed(KEY_TWO)) mode = DEFERRED_NORMAL; + if (IsKeyPressed(KEY_THREE)) mode = DEFERRED_ALBEDO; + if (IsKeyPressed(KEY_FOUR)) mode = DEFERRED_SHADING; + + // Update light values (actually, only enable/disable them) + for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(deferredShader, lights[i]); + //---------------------------------------------------------------------------------- + + // Draw + // --------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw to the geometry buffer by first activating it + rlEnableFramebuffer(gBuffer.framebuffer); + rlClearScreenBuffers(); // Clear color and depth buffer + + rlDisableColorBlend(); + BeginMode3D(camera); + // NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader` + // will not work, as they won't immediately load the shader program. + rlEnableShader(gbufferShader.id); + // When drawing a model here, make sure that the material's shaders + // are set to the gbuffer shader! + DrawModel(model, Vector3Zero(), 1.0f, WHITE); + DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE); + + for (int i = 0; i < MAX_CUBES; i++) + { + Vector3 position = cubePositions[i]; + DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE); + } + + rlDisableShader(); + EndMode3D(); + rlEnableColorBlend(); + + // Go back to the default framebuffer (0) and draw our deferred shading. + rlDisableFramebuffer(); + rlClearScreenBuffers(); // Clear color & depth buffer + + switch (mode) + { + case DEFERRED_SHADING: + { + BeginMode3D(camera); + rlDisableColorBlend(); + rlEnableShader(deferredShader.id); + // Activate our g-buffer textures + // These will now be bound to the sampler2D uniforms `gPosition`, `gNormal`, + // and `gAlbedoSpec` + rlActiveTextureSlot(0); + rlEnableTexture(gBuffer.positionTexture); + rlActiveTextureSlot(1); + rlEnableTexture(gBuffer.normalTexture); + rlActiveTextureSlot(2); + rlEnableTexture(gBuffer.albedoSpecTexture); + + // Finally, we draw a fullscreen quad to our default framebuffer + // This will now be shaded using our deferred shader + rlLoadDrawQuad(); + rlDisableShader(); + rlEnableColorBlend(); + EndMode3D(); + + // As a last step, we now copy over the depth buffer from our g-buffer to the default framebuffer. + rlEnableFramebuffer(gBuffer.framebuffer); //glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer.framebuffer); + rlEnableFramebuffer(0); //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT + rlDisableFramebuffer(); + + // Since our shader is now done and disabled, we can draw our lights in default + // forward rendering + BeginMode3D(camera); + rlEnableShader(rlGetShaderIdDefault()); + for(int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color); + else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f)); + } + rlDisableShader(); + EndMode3D(); + DrawText("FINAL RESULT", 10, screenHeight - 30, 20, DARKGREEN); + } break; + + case DEFERRED_POSITION: + { + DrawTextureRec((Texture2D){ + .id = gBuffer.positionTexture, + .width = screenWidth, + .height = screenHeight, + }, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE); + DrawText("POSITION TEXTURE", 10, screenHeight - 30, 20, DARKGREEN); + } break; + + case DEFERRED_NORMAL: + { + DrawTextureRec((Texture2D){ + .id = gBuffer.normalTexture, + .width = screenWidth, + .height = screenHeight, + }, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE); + DrawText("NORMAL TEXTURE", 10, screenHeight - 30, 20, DARKGREEN); + } break; + + case DEFERRED_ALBEDO: + { + DrawTextureRec((Texture2D){ + .id = gBuffer.albedoSpecTexture, + .width = screenWidth, + .height = screenHeight, + }, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE); + DrawText("ALBEDO TEXTURE", 10, screenHeight - 30, 20, DARKGREEN); + } break; + } + + DrawText("Toggle lights keys: [Y][R][G][B]", 10, 40, 20, DARKGRAY); + DrawText("Switch G-buffer textures: [1][2][3][4]", 10, 70, 20, DARKGRAY); + + DrawFPS(10, 10); + + EndDrawing(); + // ----------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModel(model); // Unload the models + UnloadModel(cube); + + UnloadShader(deferredShader); // Unload shaders + UnloadShader(gbufferShader); + + // Unload geometry buffer and all attached textures + rlUnloadFramebuffer(gBuffer.framebuffer); + rlUnloadTexture(gBuffer.positionTexture); + rlUnloadTexture(gBuffer.normalTexture); + rlUnloadTexture(gBuffer.albedoSpecTexture); + rlUnloadTexture(gBuffer.depthRenderbuffer); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + diff --git a/raylib/examples/shaders/shaders_deferred_render.png b/raylib/examples/shaders/shaders_deferred_render.png Binary files differnew file mode 100644 index 0000000..90fa012 --- /dev/null +++ b/raylib/examples/shaders/shaders_deferred_render.png diff --git a/raylib/examples/shaders/shaders_hybrid_render.c b/raylib/examples/shaders/shaders_hybrid_render.c index 53e14b8..6242b30 100644 --- a/raylib/examples/shaders/shaders_hybrid_render.c +++ b/raylib/examples/shaders/shaders_hybrid_render.c @@ -1,4 +1,4 @@ -/******************************************************************************************* +/******************************************************************************************* * * raylib [shaders] example - Hybrid Rendering * @@ -68,7 +68,7 @@ int main(void) marchLocs.screenCenter = GetShaderLocation(shdrRaymarch, "screenCenter"); // Transfer screenCenter position to shader. Which is used to calculate ray direction. - Vector2 screenCenter = {.x = screenWidth/2.0, .y = screenHeight/2.0}; + Vector2 screenCenter = {.x = screenWidth/2.0f, .y = screenHeight/2.0f}; SetShaderValue(shdrRaymarch, marchLocs.screenCenter , &screenCenter , SHADER_UNIFORM_VEC2); // Use Customized function to create writable depth texture buffer @@ -84,7 +84,7 @@ int main(void) }; // Camera FOV is pre-calculated in the camera Distance. - double camDist = 1.0/(tan(camera.fovy*0.5*DEG2RAD)); + float camDist = 1.0f/(tanf(camera.fovy*0.5f*DEG2RAD)); SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -113,7 +113,7 @@ int main(void) // Raymarch Scene rlEnableDepthTest(); //Manually enable Depth Test to handle multiple rendering methods. BeginShaderMode(shdrRaymarch); - DrawRectangleRec((Rectangle){0,0,screenWidth,screenHeight},WHITE); + DrawRectangleRec((Rectangle){0,0, (float)screenWidth, (float)screenHeight},WHITE); EndShaderMode(); // Raserize Scene @@ -132,7 +132,7 @@ int main(void) BeginDrawing(); ClearBackground(RAYWHITE); - DrawTextureRec(target.texture, (Rectangle) { 0, 0, screenWidth, -screenHeight }, (Vector2) { 0, 0 }, WHITE); + DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/raylib/examples/shaders/shaders_julia_set.c b/raylib/examples/shaders/shaders_julia_set.c index aebb287..608d3b5 100644 --- a/raylib/examples/shaders/shaders_julia_set.c +++ b/raylib/examples/shaders/shaders_julia_set.c @@ -9,12 +9,12 @@ * * Example originally created with raylib 2.5, last time updated with raylib 4.0 * -* Example contributed by eggmund (@eggmund) and reviewed by Ramon Santamaria (@raysan5) +* Example contributed by Josh Colclough (@joshcol9232) 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-2023 eggmund (@eggmund) and Ramon Santamaria (@raysan5) +* Copyright (c) 2019-2023 Josh Colclough (@joshcol9232) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -37,6 +37,13 @@ const float pointsOfInterest[6][2] = { -0.70176f, -0.3842f }, }; +const int screenWidth = 800; +const int screenHeight = 450; +const float zoomSpeed = 1.01f; +const float offsetSpeedMul = 2.0f; + +const float startingZoom = 0.75f; + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -44,10 +51,6 @@ int main(void) { // Initialization //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; - - //SetConfigFlags(FLAG_WINDOW_HIGHDPI); InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets"); // Load julia set shader @@ -61,10 +64,8 @@ int main(void) float c[2] = { pointsOfInterest[0][0], pointsOfInterest[0][1] }; // Offset and zoom to draw the julia set at. (centered on screen and default size) - float offset[2] = { -(float)GetScreenWidth()/2, -(float)GetScreenHeight()/2 }; - float zoom = 1.0f; - - Vector2 offsetSpeed = { 0.0f, 0.0f }; + float offset[2] = { 0.0f, 0.0f }; + float zoom = startingZoom; // Get variable (uniform) locations on the shader to connect with the program // NOTE: If uniform variable could not be found in the shader, function returns -1 @@ -72,17 +73,13 @@ int main(void) int zoomLoc = GetShaderLocation(shader, "zoom"); int offsetLoc = GetShaderLocation(shader, "offset"); - // Tell the shader what the screen dimensions, zoom, offset and c are - float screenDims[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() }; - SetShaderValue(shader, GetShaderLocation(shader, "screenDims"), screenDims, SHADER_UNIFORM_VEC2); - + // Upload the shader uniform values! SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2); SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT); SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2); int incrementSpeed = 0; // Multiplier of speed to change c value bool showControls = true; // Show controls - bool pause = false; // Pause animation SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -110,42 +107,50 @@ int main(void) SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2); } - if (IsKeyPressed(KEY_SPACE)) pause = !pause; // Pause animation (c change) - if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls - - if (!pause) + // If "R" is pressed, reset zoom and offset. + if (IsKeyPressed(KEY_R)) { - if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++; - else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--; - - // TODO: The idea is to zoom and move around with mouse - // Probably offset movement should be proportional to zoom level - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) - { - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) zoom += zoom*0.003f; - if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) zoom -= zoom*0.003f; - - Vector2 mousePos = GetMousePosition(); + zoom = startingZoom; + offset[0] = 0.0f; + offset[1] = 0.0f; + SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT); + SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2); + } - offsetSpeed.x = mousePos.x -(float)screenWidth/2; - offsetSpeed.y = mousePos.y -(float)screenHeight/2; + if (IsKeyPressed(KEY_SPACE)) incrementSpeed = 0; // Pause animation (c change) + if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls - // Slowly move camera to targetOffset - offset[0] += GetFrameTime()*offsetSpeed.x*0.8f; - offset[1] += GetFrameTime()*offsetSpeed.y*0.8f; - } - else offsetSpeed = (Vector2){ 0.0f, 0.0f }; + if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++; + else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--; + // If either left or right button is pressed, zoom in/out. + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) + { + // Change zoom. If Mouse left -> zoom in. Mouse right -> zoom out. + zoom *= IsMouseButtonDown(MOUSE_BUTTON_LEFT)? zoomSpeed : 1.0f/zoomSpeed; + + const Vector2 mousePos = GetMousePosition(); + Vector2 offsetVelocity; + // Find the velocity at which to change the camera. Take the distance of the mouse + // from the center of the screen as the direction, and adjust magnitude based on + // the current zoom. + offsetVelocity.x = (mousePos.x/(float)screenWidth - 0.5f)*offsetSpeedMul/zoom; + offsetVelocity.y = (mousePos.y/(float)screenHeight - 0.5f)*offsetSpeedMul/zoom; + + // Apply move velocity to camera + offset[0] += GetFrameTime()*offsetVelocity.x; + offset[1] += GetFrameTime()*offsetVelocity.y; + + // Update the shader uniform values! SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT); SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2); - - // Increment c value with time - float amount = GetFrameTime()*incrementSpeed*0.0005f; - c[0] += amount; - c[1] += amount; - - SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2); } + + // Increment c value with time + const float dc = GetFrameTime()*(float)incrementSpeed*0.0005f; + c[0] += dc; + c[1] += dc; + SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2); //---------------------------------------------------------------------------------- // Draw @@ -178,7 +183,8 @@ int main(void) DrawText("Press KEY_F1 to toggle these controls", 10, 30, 10, RAYWHITE); DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE); DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE); - DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE); + DrawText("Press KEY_SPACE to stop movement animation", 10, 75, 10, RAYWHITE); + DrawText("Press KEY_R to recenter the camera", 10, 90, 10, RAYWHITE); } EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/raylib/examples/shaders/shaders_raymarching.c b/raylib/examples/shaders/shaders_raymarching.c index e9b7755..ff403e6 100644 --- a/raylib/examples/shaders/shaders_raymarching.c +++ b/raylib/examples/shaders/shaders_raymarching.c @@ -82,7 +82,8 @@ int main(void) // Check if screen is resized if (IsWindowResized()) { - float resolution[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() }; + resolution[0] = (float)GetScreenWidth(); + resolution[1] = (float)GetScreenHeight(); SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2); } //---------------------------------------------------------------------------------- diff --git a/raylib/examples/shaders/shaders_texture_tiling.c b/raylib/examples/shaders/shaders_texture_tiling.c new file mode 100644 index 0000000..0d07bdf --- /dev/null +++ b/raylib/examples/shaders/shaders_texture_tiling.c @@ -0,0 +1,105 @@ +/******************************************************************************************* +* +* raylib [shaders] example - texture tiling +* +* Example demonstrates how to tile a texture on a 3D model using raylib. +* +* Example contributed by Luis Almeida (@luis605) 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 Luis Almeida (@luis605) +* +********************************************************************************************/ + +#include "raylib.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - texture tiling"); + + // Define the camera to look into our 3d world + Camera3D camera = { 0 }; + camera.position = (Vector3){ 4.0f, 4.0f, 4.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera projection type + + // Load a cube model + Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); + Model model = LoadModelFromMesh(cube); + + // Load a texture and assign to cube model + Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); + model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; + + // Set the texture tiling using a shader + float tiling[2] = { 3.0f, 3.0f }; + Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/tiling.fs", GLSL_VERSION)); + SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2); + model.materials[0].shader = shader; + + DisableCursor(); // Limit cursor to relative movement inside the window + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera, CAMERA_FREE); + + if (IsKeyPressed('Z')) camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + BeginShaderMode(shader); + DrawModel(model, (Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, WHITE); + EndShaderMode(); + + DrawGrid(10, 1.0f); + + EndMode3D(); + + DrawText("Use mouse to rotate the camera", 10, 10, 20, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModel(model); // Unload model + UnloadShader(shader); // Unload shader + UnloadTexture(texture); // Unload texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/raylib/examples/shaders/shaders_texture_tiling.png b/raylib/examples/shaders/shaders_texture_tiling.png Binary files differnew file mode 100644 index 0000000..5dfe76e --- /dev/null +++ b/raylib/examples/shaders/shaders_texture_tiling.png diff --git a/raylib/examples/shaders/shaders_write_depth.c b/raylib/examples/shaders/shaders_write_depth.c index d9e40d0..3169724 100644 --- a/raylib/examples/shaders/shaders_write_depth.c +++ b/raylib/examples/shaders/shaders_write_depth.c @@ -1,4 +1,4 @@ -/******************************************************************************************* +/******************************************************************************************* * * raylib [shaders] example - Depth buffer writing * @@ -92,7 +92,7 @@ int main(void) BeginDrawing(); ClearBackground(RAYWHITE); - DrawTextureRec(target.texture, (Rectangle) { 0, 0, screenWidth, -screenHeight }, (Vector2) { 0, 0 }, WHITE); + DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/raylib/examples/shapes/raygui.h b/raylib/examples/shapes/raygui.h index 26d6bac..9127710 100644 --- a/raylib/examples/shapes/raygui.h +++ b/raylib/examples/shapes/raygui.h @@ -136,7 +136,7 @@ * * #define RAYGUI_DEBUG_RECS_BOUNDS * Draw control bounds rectangles for debug -* +* * #define RAYGUI_DEBUG_TEXT_BOUNDS * Draw text bounds rectangles for debug * @@ -246,7 +246,7 @@ * 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria. * * DEPENDENCIES: -* raylib 4.6-dev Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing +* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing * * STANDALONE MODE: * By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled @@ -498,7 +498,7 @@ typedef enum { typedef enum { // Default -> populates to all controls when set DEFAULT = 0, - + // Basic controls LABEL, // Used also for: LABELBUTTON BUTTON, @@ -1775,7 +1775,7 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector { #define RAYGUI_MIN_SCROLLBAR_WIDTH 40 #define RAYGUI_MIN_SCROLLBAR_HEIGHT 40 - + int result = 0; GuiState state = guiState; float mouseWheelSpeed = 20.0f; // Default movement speed with mouse wheel @@ -1806,27 +1806,27 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0; int verticalScrollBarWidth = hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0; - Rectangle horizontalScrollBar = { - (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH), - (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH), - (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH), - (float)horizontalScrollBarWidth + Rectangle horizontalScrollBar = { + (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)horizontalScrollBarWidth }; - Rectangle verticalScrollBar = { - (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)), - (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), - (float)verticalScrollBarWidth, - (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) + Rectangle verticalScrollBar = { + (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)), + (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)verticalScrollBarWidth, + (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) }; // Make sure scroll bars have a minimum width/height // NOTE: If content >>> bounds, size could be very small or even 0 - if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) + if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) { horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH; mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.height vs bounds.height } - if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) + if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) { verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT; mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.width vs bounds.width @@ -2155,7 +2155,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) } else state = STATE_FOCUSED; } - + if ((*active) && (state != STATE_FOCUSED)) state = STATE_PRESSED; } @@ -2625,8 +2625,6 @@ int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode) if (CheckCollisionPointRec(mousePosition, textBounds)) // Mouse hover text { float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize; - int codepoint = 0; - int codepointSize = 0; int codepointIndex = 0; float glyphWidth = 0.0f; float widthToMouseX = 0; @@ -2646,7 +2644,7 @@ int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode) mouseCursorIndex = i; break; } - + widthToMouseX += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); } @@ -2655,7 +2653,7 @@ int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode) if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; - mouseCursorIndex = strlen(text); + mouseCursorIndex = (int)strlen(text); } // Place cursor at required index on mouse click @@ -2743,7 +2741,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int bufferSize, bool editMode GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE); GuiSetStyle(TEXTBOX, TEXT_READONLY, 0); - + return pressed; } */ @@ -2937,6 +2935,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth) { int result = 0; + float oldValue = *value; GuiState state = guiState; float temp = (maxValue - minValue)/2.0f; @@ -3006,6 +3005,10 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, else if (*value < minValue) *value = minValue; } + // Control value change check + if(oldValue == *value) result = 0; + else result = 1; + // Bar limits check if (sliderWidth > 0) // Slider { @@ -3085,7 +3088,7 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight if (*value > maxValue) *value = maxValue; // WARNING: Working with floats could lead to rounding issues - if ((state != STATE_DISABLED)) progress.width = (float)(*value/(maxValue - minValue))*bounds.width - ((*value >= maxValue) ? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f); + if ((state != STATE_DISABLED)) progress.width = (float)(*value/(maxValue - minValue))*bounds.width - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f); //-------------------------------------------------------------------- // Draw control @@ -3366,8 +3369,7 @@ int GuiColorPanel(Rectangle bounds, const char *text, Color *color) pickerSelector.x = bounds.x + (float)hsv.y*bounds.width; // HSV: Saturation pickerSelector.y = bounds.y + (1.0f - (float)hsv.z)*bounds.height; // HSV: Value - float hue = -1.0f; - Vector3 maxHue = { hue >= 0.0f ? hue : hsv.x, 1.0f, 1.0f }; + Vector3 maxHue = { hsv.x, 1.0f, 1.0f }; Vector3 rgbHue = ConvertHSVtoRGB(maxHue); Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x), (unsigned char)(255.0f*rgbHue.y), @@ -3680,8 +3682,7 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) pickerSelector.x = bounds.x + (float)colorHsv->y*bounds.width; // HSV: Saturation pickerSelector.y = bounds.y + (1.0f - (float)colorHsv->z)*bounds.height; // HSV: Value - float hue = -1.0f; - Vector3 maxHue = { hue >= 0.0f ? hue : colorHsv->x, 1.0f, 1.0f }; + Vector3 maxHue = { colorHsv->x, 1.0f, 1.0f }; Vector3 rgbHue = ConvertHSVtoRGB(maxHue); Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x), (unsigned char)(255.0f*rgbHue.y), @@ -3894,12 +3895,14 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect GuiState state = guiState; Vector2 mousePoint = GetMousePosition(); - Vector2 currentMouseCell = { 0 }; + Vector2 currentMouseCell = { -1, -1 }; float spaceWidth = spacing/(float)subdivs; int linesV = (int)(bounds.width/spaceWidth) + 1; int linesH = (int)(bounds.height/spaceWidth) + 1; + int color = GuiGetStyle(DEFAULT, LINE_COLOR); + // Update control //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) @@ -3915,28 +3918,23 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect // Draw control //-------------------------------------------------------------------- - switch (state) + if (state == STATE_DISABLED) color = GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED); + + if (subdivs > 0) { - case STATE_NORMAL: + // Draw vertical grid lines + for (int i = 0; i < linesV; i++) { - if (subdivs > 0) - { - // Draw vertical grid lines - for (int i = 0; i < linesV; i++) - { - Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height }; - GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA)); - } + Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height }; + GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA)); + } - // Draw horizontal grid lines - for (int i = 0; i < linesH; i++) - { - Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1 }; - GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA)); - } - } - } break; - default: break; + // Draw horizontal grid lines + for (int i = 0; i < linesH; i++) + { + Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1 }; + GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA)); + } } if (mouseCell != NULL) *mouseCell = currentMouseCell; @@ -4101,7 +4099,7 @@ void GuiLoadStyleDefault(void) GuiSetStyle(DEFAULT, BORDER_WIDTH, 1); GuiSetStyle(DEFAULT, TEXT_PADDING, 0); GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - + // Initialize default extended property values // NOTE: By default, extended property values are initialized to 0 GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls @@ -4189,7 +4187,7 @@ const char *GuiIconText(int iconId, const char *text) return NULL; #else static char buffer[1024] = { 0 }; - static char iconBuffer[6] = { 0 }; + static char iconBuffer[16] = { 0 }; if (text != NULL) { @@ -4206,7 +4204,7 @@ const char *GuiIconText(int iconId, const char *text) } else { - sprintf(iconBuffer, "#%03i#", iconId & 0x1ff); + sprintf(iconBuffer, "#%03i#", iconId); return iconBuffer; } @@ -4876,7 +4874,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint else { - // TODO: There are multiple types of spaces in Unicode, + // TODO: There are multiple types of spaces in Unicode, // maybe it's a good idea to add support for more: http://jkorpela.fi/chars/spaces.html if ((codepoint != ' ') && (codepoint != '\t')) // Do not draw codepoints with no glyph { @@ -4888,7 +4886,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); } } - else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) + else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) { // Draw only glyphs inside the bounds if ((textBoundsPosition.y + textOffsetY) <= (textBounds.y + textBounds.height - GuiGetStyle(DEFAULT, TEXT_SIZE))) diff --git a/raylib/examples/shapes/shapes_bouncing_ball.c b/raylib/examples/shapes/shapes_bouncing_ball.c index 203d88a..38fade6 100644 --- a/raylib/examples/shapes/shapes_bouncing_ball.c +++ b/raylib/examples/shapes/shapes_bouncing_ball.c @@ -67,9 +67,6 @@ int main(void) // On pause, we draw a blinking message if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY); - DrawCircle(400.5, 300.5, 50, BLACK); - DrawCircle(528.0, 172.0, 26, BLACK); - DrawFPS(10, 10); EndDrawing(); diff --git a/raylib/examples/shapes/shapes_draw_circle_sector.c b/raylib/examples/shapes/shapes_draw_circle_sector.c index 1c283e1..90e8e6a 100644 --- a/raylib/examples/shapes/shapes_draw_circle_sector.c +++ b/raylib/examples/shapes/shapes_draw_circle_sector.c @@ -70,7 +70,7 @@ int main(void) GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", NULL, &segments, 0, 100); //------------------------------------------------------------------------------ - minSegments = (int)ceilf((endAngle - startAngle) / 90); + minSegments = truncf(ceilf((endAngle - startAngle) / 90)); DrawText(TextFormat("MODE: %s", (segments >= minSegments)? "MANUAL" : "AUTO"), 600, 200, 10, (segments >= minSegments)? MAROON : DARKGRAY); DrawFPS(10, 10); diff --git a/raylib/examples/shapes/shapes_lines_bezier.c b/raylib/examples/shapes/shapes_lines_bezier.c index f015768..aaad680 100644 --- a/raylib/examples/shapes/shapes_lines_bezier.c +++ b/raylib/examples/shapes/shapes_lines_bezier.c @@ -26,11 +26,10 @@ int main(void) SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - cubic-bezier lines"); - Vector2 start = { 0, 0 }; - Vector2 end = { (float)screenWidth, (float)screenHeight }; - - Vector2 startControl = { 100, 0 }; - Vector2 endControl = { GetScreenWidth() - 100, GetScreenHeight() }; + Vector2 startPoint = { 30, 30 }; + Vector2 endPoint = { (float)screenWidth - 30, (float)screenHeight - 30 }; + bool moveStartPoint = false; + bool moveEndPoint = false; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -40,15 +39,21 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - if (IsKeyDown(KEY_LEFT_CONTROL)) + Vector2 mouse = GetMousePosition(); + + if (CheckCollisionPointCircle(mouse, startPoint, 10.0f) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) moveStartPoint = true; + else if (CheckCollisionPointCircle(mouse, endPoint, 10.0f) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) moveEndPoint = true; + + if (moveStartPoint) { - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) startControl = GetMousePosition(); - else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) endControl = GetMousePosition(); + startPoint = mouse; + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) moveStartPoint = false; } - else + + if (moveEndPoint) { - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) start = GetMousePosition(); - else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) end = GetMousePosition(); + endPoint = mouse; + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) moveEndPoint = false; } //---------------------------------------------------------------------------------- @@ -58,16 +63,14 @@ int main(void) ClearBackground(RAYWHITE); - DrawText("USE MOUSE LEFT-RIGHT CLICK to DEFINE LINE START and END POINTS", 15, 20, 20, GRAY); + DrawText("MOVE START-END POINTS WITH MOUSE", 15, 20, 20, GRAY); - //DrawLineBezier(start, end, 2.0f, RED); - - DrawLineBezierCubic(start, end, startControl, endControl, 2.0f, RED); + // Draw line Cubic Bezier, in-out interpolation (easing), no control points + DrawLineBezier(startPoint, endPoint, 4.0f, BLUE); - DrawLineEx(start, startControl, 1.0, LIGHTGRAY); - DrawLineEx(end, endControl, 1.0, LIGHTGRAY); - DrawCircleV(startControl, 10, RED); - DrawCircleV(endControl, 10, RED); + // Draw start-end spline circles with some details + DrawCircleV(startPoint, CheckCollisionPointCircle(mouse, startPoint, 10.0f)? 14 : 8, moveStartPoint? RED : BLUE); + DrawCircleV(endPoint, CheckCollisionPointCircle(mouse, endPoint, 10.0f)? 14 : 8, moveEndPoint? RED : BLUE); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/raylib/examples/shapes/shapes_lines_bezier.png b/raylib/examples/shapes/shapes_lines_bezier.png Binary files differindex 390a49a..aa5edf3 100644 --- a/raylib/examples/shapes/shapes_lines_bezier.png +++ b/raylib/examples/shapes/shapes_lines_bezier.png diff --git a/raylib/examples/shapes/shapes_lines_splines.c b/raylib/examples/shapes/shapes_lines_splines.c deleted file mode 100644 index c020c60..0000000 --- a/raylib/examples/shapes/shapes_lines_splines.c +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************************* -* -* raylib [shapes] example - splines drawing -* -* Example originally created with raylib 4.6-dev, last time updated with raylib 4.6-dev -* -* 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 Ramon Santamaria (@raysan5) -* -********************************************************************************************/ - -#include "raylib.h" - -#define MAX_CONTROL_POINTS 32 - -typedef struct { - Vector2 start; - Vector2 end; -} ControlPoint; - -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ -int main(void) -{ - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; - - SetConfigFlags(FLAG_MSAA_4X_HINT); - InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing"); - - Vector2 points[MAX_CONTROL_POINTS] = { - { 100.0f, 200.0f }, - { 300.0f, 400.0f }, - { 500.0f, 300.0f }, - { 700.0f, 100.0f }, - { 200.0f, 100.0f }, - }; - - int pointCount = 5; - int selectedPoint = -1; - - int splineType = 0; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier - - // Cubic Bezier control points - ControlPoint control[MAX_CONTROL_POINTS] = { 0 }; - for (int i = 0; i < pointCount - 1; i++) - { - control[i].start = points[i]; - control[i].end = points[i + 1]; - } - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - // Points movement logic - if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_CONTROL_POINTS)) - { - points[pointCount] = GetMousePosition(); - pointCount++; - } - - for (int i = 0; i < pointCount; i++) - { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointCircle(GetMousePosition(), points[i], 6.0f)) - { - selectedPoint = i; - break; - } - } - - if (selectedPoint >= 0) - { - points[selectedPoint] = GetMousePosition(); - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1; - } - - // TODO: Cubic Bezier spline control points logic - - - // Spline selection logic - if (IsKeyPressed(KEY_ONE)) splineType = 0; - else if (IsKeyPressed(KEY_TWO)) splineType = 1; - else if (IsKeyPressed(KEY_THREE)) splineType = 2; - else if (IsKeyPressed(KEY_FOUR)) splineType = 3; - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - if (splineType == 0) // Linear - { - // Draw linear spline - for (int i = 0; i < pointCount - 1; i++) - { - DrawLineEx(points[i], points[i + 1], 2.0f, RED); - } - } - else if (splineType == 1) // B-Spline - { - // Draw b-spline - DrawLineBSpline(points, pointCount, 2.0f, RED); - //for (int i = 0; i < (pointCount - 3); i++) DrawLineBSplineSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, BLUE); - } - else if (splineType == 2) // CatmullRom Spline - { - // Draw spline: catmull-rom - DrawLineCatmullRom(points, pointCount, 2.0f, RED); - //for (int i = 0; i < (pointCount - 3); i++) DrawLineCatmullRomSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, Fade(BLUE, 0.4f)); - } - else if (splineType == 3) // Cubic Bezier - { - // Draw line bezier cubic (with control points) - for (int i = 0; i < pointCount - 1; i++) - { - DrawLineBezierCubic(points[i], points[i + 1], control[i].start, control[i + 1].end, 2.0f, RED); - - // TODO: Every cubic bezier point should have two control points - DrawCircleV(control[i].start, 4, GOLD); - DrawCircleV(control[i].end, 4, GOLD); - DrawLineEx(points[i], control[i].start, 1.0, LIGHTGRAY); - DrawLineEx(points[i + 1], control[i].end, 1.0, LIGHTGRAY); - } - } - - // Draw control points - for (int i = 0; i < pointCount; i++) - { - DrawCircleV(points[i], 6.0f, RED); - if ((splineType != 0) && (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY); - } - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -}
\ No newline at end of file diff --git a/raylib/examples/shapes/shapes_splines_drawing.c b/raylib/examples/shapes/shapes_splines_drawing.c new file mode 100644 index 0000000..8df5f09 --- /dev/null +++ b/raylib/examples/shapes/shapes_splines_drawing.c @@ -0,0 +1,247 @@ +/******************************************************************************************* +* +* raylib [shapes] example - splines drawing +* +* Example originally created with raylib 5.0, last time updated with raylib 5.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) 2023 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for UI controls + +#include <stdlib.h> // Required for: NULL + +#define MAX_SPLINE_POINTS 32 + +// Cubic Bezier spline control points +// NOTE: Every segment has two control points +typedef struct { + Vector2 start; + Vector2 end; +} ControlPoint; + +// Spline types +typedef enum { + SPLINE_LINEAR = 0, // Linear + SPLINE_BASIS, // B-Spline + SPLINE_CATMULLROM, // Catmull-Rom + SPLINE_BEZIER // Cubic Bezier +} SplineType; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing"); + + Vector2 points[MAX_SPLINE_POINTS] = { + { 50.0f, 400.0f }, + { 160.0f, 220.0f }, + { 340.0f, 380.0f }, + { 520.0f, 60.0f }, + { 710.0f, 260.0f }, + }; + + int pointCount = 5; + int selectedPoint = -1; + int focusedPoint = -1; + Vector2 *selectedControlPoint = NULL; + Vector2 *focusedControlPoint = NULL; + + // Cubic Bezier control points initialization + ControlPoint control[MAX_SPLINE_POINTS] = { 0 }; + for (int i = 0; i < pointCount - 1; i++) + { + control[i].start = (Vector2){ points[i].x + 50, points[i].y }; + control[i].end = (Vector2){ points[i + 1].x - 50, points[i + 1].y }; + } + + // Spline config variables + float splineThickness = 8.0f; + int splineTypeActive = SPLINE_LINEAR; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier + bool splineTypeEditMode = false; + bool splineHelpersActive = true; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Spline points creation logic (at the end of spline) + if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_SPLINE_POINTS)) + { + points[pointCount] = GetMousePosition(); + pointCount++; + } + + // Spline point focus and selection logic + for (int i = 0; i < pointCount; i++) + { + if (CheckCollisionPointCircle(GetMousePosition(), points[i], 8.0f)) + { + focusedPoint = i; + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedPoint = i; + break; + } + else focusedPoint = -1; + } + + // Spline point movement logic + if (selectedPoint >= 0) + { + points[selectedPoint] = GetMousePosition(); + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1; + } + + // Cubic Bezier spline control points logic + if ((splineTypeActive == SPLINE_BEZIER) && (focusedPoint == -1)) + { + // Spline control point focus and selection logic + for (int i = 0; i < pointCount; i++) + { + if (CheckCollisionPointCircle(GetMousePosition(), control[i].start, 6.0f)) + { + focusedControlPoint = &control[i].start; + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].start; + break; + } + else if (CheckCollisionPointCircle(GetMousePosition(), control[i].end, 6.0f)) + { + focusedControlPoint = &control[i].end; + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].end; + break; + } + else focusedControlPoint = NULL; + } + + // Spline control point movement logic + if (selectedControlPoint != NULL) + { + *selectedControlPoint = GetMousePosition(); + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedControlPoint = NULL; + } + } + + // Spline selection logic + if (IsKeyPressed(KEY_ONE)) splineTypeActive = 0; + else if (IsKeyPressed(KEY_TWO)) splineTypeActive = 1; + else if (IsKeyPressed(KEY_THREE)) splineTypeActive = 2; + else if (IsKeyPressed(KEY_FOUR)) splineTypeActive = 3; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (splineTypeActive == SPLINE_LINEAR) + { + // Draw spline: linear + DrawSplineLinear(points, pointCount, splineThickness, RED); + } + else if (splineTypeActive == SPLINE_BASIS) + { + // Draw spline: basis + DrawSplineBasis(points, pointCount, splineThickness, RED); // Provide connected points array + + /* + for (int i = 0; i < (pointCount - 3); i++) + { + // Drawing individual segments, not considering thickness connection compensation + DrawSplineSegmentBasis(points[i], points[i + 1], points[i + 2], points[i + 3], splineThickness, MAROON); + } + */ + } + else if (splineTypeActive == SPLINE_CATMULLROM) + { + // Draw spline: catmull-rom + DrawSplineCatmullRom(points, pointCount, splineThickness, RED); // Provide connected points array + + /* + for (int i = 0; i < (pointCount - 3); i++) + { + // Drawing individual segments, not considering thickness connection compensation + DrawSplineSegmentCatmullRom(points[i], points[i + 1], points[i + 2], points[i + 3], splineThickness, MAROON); + } + */ + } + else if (splineTypeActive == SPLINE_BEZIER) + { + // Draw spline: cubic-bezier (with control points) + for (int i = 0; i < pointCount - 1; i++) + { + // Drawing individual segments, not considering thickness connection compensation + DrawSplineSegmentBezierCubic(points[i], control[i].start, control[i].end, points[i + 1], splineThickness, RED); + + // Every cubic bezier point should have two control points + DrawCircleV(control[i].start, 6, GOLD); + DrawCircleV(control[i].end, 6, GOLD); + if (focusedControlPoint == &control[i].start) DrawCircleV(control[i].start, 8, GREEN); + else if (focusedControlPoint == &control[i].end) DrawCircleV(control[i].end, 8, GREEN); + DrawLineEx(points[i], control[i].start, 1.0f, LIGHTGRAY); + DrawLineEx(points[i + 1], control[i].end, 1.0f, LIGHTGRAY); + + // Draw spline control lines + DrawLineV(points[i], control[i].start, GRAY); + //DrawLineV(control[i].start, control[i].end, LIGHTGRAY); + DrawLineV(control[i].end, points[i + 1], GRAY); + } + } + + if (splineHelpersActive) + { + // Draw spline point helpers + for (int i = 0; i < pointCount; i++) + { + DrawCircleLinesV(points[i], (focusedPoint == i)? 12.0f : 8.0f, (focusedPoint == i)? BLUE: DARKBLUE); + if ((splineTypeActive != SPLINE_LINEAR) && + (splineTypeActive != SPLINE_BEZIER) && + (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY); + + DrawText(TextFormat("[%.0f, %.0f]", points[i].x, points[i].y), points[i].x, points[i].y + 10, 10, BLACK); + } + } + + // Check all possible UI states that require controls lock + if (splineTypeEditMode) GuiLock(); + + // Draw spline config + GuiLabel((Rectangle){ 12, 62, 140, 24 }, TextFormat("Spline thickness: %i", (int)splineThickness)); + GuiSliderBar((Rectangle){ 12, 60 + 24, 140, 16 }, NULL, NULL, &splineThickness, 1.0f, 40.0f); + + GuiCheckBox((Rectangle){ 12, 110, 20, 20 }, "Show point helpers", &splineHelpersActive); + + GuiUnlock(); + + GuiLabel((Rectangle){ 12, 10, 140, 24 }, "Spline type:"); + if (GuiDropdownBox((Rectangle){ 12, 8 + 24, 140, 28 }, "LINEAR;BSPLINE;CATMULLROM;BEZIER", &splineTypeActive, splineTypeEditMode)) splineTypeEditMode = !splineTypeEditMode; + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/raylib/examples/shapes/shapes_splines_drawing.png b/raylib/examples/shapes/shapes_splines_drawing.png Binary files differnew file mode 100644 index 0000000..686f04c --- /dev/null +++ b/raylib/examples/shapes/shapes_splines_drawing.png diff --git a/raylib/examples/shapes/shapes_top_down_lights.c b/raylib/examples/shapes/shapes_top_down_lights.c index b09137c..f22cf3c 100644 --- a/raylib/examples/shapes/shapes_top_down_lights.c +++ b/raylib/examples/shapes/shapes_top_down_lights.c @@ -335,6 +335,7 @@ int main(void) DrawFPS(screenWidth - 80, 10); DrawText("Drag to move light #1", 10, 10, 10, DARKGREEN); DrawText("Right click to add new light", 10, 30, 10, DARKGREEN); + EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/raylib/examples/text/text_font_sdf.c b/raylib/examples/text/text_font_sdf.c index cba47b4..40a3fa4 100644 --- a/raylib/examples/text/text_font_sdf.c +++ b/raylib/examples/text/text_font_sdf.c @@ -38,7 +38,7 @@ int main(void) const char msg[50] = "Signed Distance Fields"; // Loading file to memory - unsigned int fileSize = 0; + int fileSize = 0; unsigned char *fileData = LoadFileData("resources/anonymous_pro_bold.ttf", &fileSize); // Default font generation from TTF font diff --git a/raylib/examples/text/text_unicode.c b/raylib/examples/text/text_unicode.c index b25e327..42227f8 100644 --- a/raylib/examples/text/text_unicode.c +++ b/raylib/examples/text/text_unicode.c @@ -195,7 +195,7 @@ int main(void) } Vector2 mouse = GetMousePosition(); - Vector2 pos = { 28.8f, 10.0f }; + Vector2 position = { 28.8f, 10.0f }; hovered = -1; //---------------------------------------------------------------------------------- @@ -210,21 +210,21 @@ int main(void) for (int i = 0; i < SIZEOF(emoji); ++i) { const char *txt = &emojiCodepoints[emoji[i].index]; - Rectangle emojiRect = { pos.x, pos.y, (float)fontEmoji.baseSize, (float)fontEmoji.baseSize }; + Rectangle emojiRect = { position.x, position.y, (float)fontEmoji.baseSize, (float)fontEmoji.baseSize }; if (!CheckCollisionPointRec(mouse, emojiRect)) { - DrawTextEx(fontEmoji, txt, pos, (float)fontEmoji.baseSize, 1.0f, selected == i ? emoji[i].color : Fade(LIGHTGRAY, 0.4f)); + DrawTextEx(fontEmoji, txt, position, (float)fontEmoji.baseSize, 1.0f, selected == i ? emoji[i].color : Fade(LIGHTGRAY, 0.4f)); } else { - DrawTextEx(fontEmoji, txt, pos, (float)fontEmoji.baseSize, 1.0f, emoji[i].color ); + DrawTextEx(fontEmoji, txt, position, (float)fontEmoji.baseSize, 1.0f, emoji[i].color ); hovered = i; - hoveredPos = pos; + hoveredPos = position; } - if ((i != 0) && (i%EMOJI_PER_WIDTH == 0)) { pos.y += fontEmoji.baseSize + 24.25f; pos.x = 28.8f; } - else pos.x += fontEmoji.baseSize + 28.8f; + if ((i != 0) && (i%EMOJI_PER_WIDTH == 0)) { position.y += fontEmoji.baseSize + 24.25f; position.x = 28.8f; } + else position.x += fontEmoji.baseSize + 28.8f; } //------------------------------------------------------------------------------ @@ -282,8 +282,8 @@ int main(void) int length = GetCodepointCount(messages[message].text); const char *info = TextFormat("%s %u characters %i bytes", messages[message].language, length, size); sz = MeasureTextEx(GetFontDefault(), info, 10, 1.0f); - Vector2 pos = { textRect.x + textRect.width - sz.x, msgRect.y + msgRect.height - sz.y - 2 }; - DrawText(info, (int)pos.x, (int)pos.y, 10, RAYWHITE); + + DrawText(info, (int)(textRect.x + textRect.width - sz.x), (int)(msgRect.y + msgRect.height - sz.y - 2), 10, RAYWHITE); } //------------------------------------------------------------------------------ diff --git a/raylib/examples/textures/textures_textured_curve.c b/raylib/examples/textures/textures_textured_curve.c index 3c2f060..cf426be 100644 --- a/raylib/examples/textures/textures_textured_curve.c +++ b/raylib/examples/textures/textures_textured_curve.c @@ -13,7 +13,6 @@ * ********************************************************************************************/ - #include "raylib.h" #include "raymath.h" @@ -43,12 +42,8 @@ static Vector2 *curveSelectedPoint = NULL; //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- -static void UpdateOptions(void); -static void UpdateCurve(void); -static void DrawCurve(void); static void DrawTexturedCurve(void); - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -81,9 +76,31 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdateCurve(); - UpdateOptions(); - + // Curve config options + if (IsKeyPressed(KEY_SPACE)) showCurve = !showCurve; + if (IsKeyPressed(KEY_EQUAL)) curveWidth += 2; + if (IsKeyPressed(KEY_MINUS)) curveWidth -= 2; + if (curveWidth < 2) curveWidth = 2; + + // Update segments + if (IsKeyPressed(KEY_LEFT)) curveSegments -= 2; + if (IsKeyPressed(KEY_RIGHT)) curveSegments += 2; + + if (curveSegments < 2) curveSegments = 2; + + // Update curve logic + // If the mouse is not down, we are not editing the curve so clear the selection + if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON)) curveSelectedPoint = NULL; + + // If a point was selected, move it + if (curveSelectedPoint) *curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta()); + + // The mouse is down, and nothing was selected, so see if anything was picked + Vector2 mouse = GetMousePosition(); + if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) curveSelectedPoint = &curveStartPosition; + else if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) curveSelectedPoint = &curveStartPositionTangent; + else if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) curveSelectedPoint = &curveEndPosition; + else if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) curveSelectedPoint = &curveEndPositionTangent; //---------------------------------------------------------------------------------- // Draw @@ -92,9 +109,29 @@ int main() ClearBackground(RAYWHITE); - DrawTexturedCurve(); - DrawCurve(); - + DrawTexturedCurve(); // Draw a textured Spline Cubic Bezier + + // Draw spline for reference + if (showCurve) DrawSplineSegmentBezierCubic(curveStartPosition, curveEndPosition, curveStartPositionTangent, curveEndPositionTangent, 2, BLUE); + + // Draw the various control points and highlight where the mouse is + DrawLineV(curveStartPosition, curveStartPositionTangent, SKYBLUE); + DrawLineV(curveStartPositionTangent, curveEndPositionTangent, Fade(LIGHTGRAY, 0.4f)); + DrawLineV(curveEndPosition, curveEndPositionTangent, PURPLE); + + if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) DrawCircleV(curveStartPosition, 7, YELLOW); + DrawCircleV(curveStartPosition, 5, RED); + + if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) DrawCircleV(curveStartPositionTangent, 7, YELLOW); + DrawCircleV(curveStartPositionTangent, 5, MAROON); + + if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) DrawCircleV(curveEndPosition, 7, YELLOW); + DrawCircleV(curveEndPosition, 5, GREEN); + + if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) DrawCircleV(curveEndPositionTangent, 7, YELLOW); + DrawCircleV(curveEndPositionTangent, 5, DARKGREEN); + + // Draw usage info DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, DARKGRAY); DrawText(TextFormat("Curve width: %2.0f (Use + and - to adjust)", curveWidth), 10, 30, 10, DARKGRAY); DrawText(TextFormat("Curve segments: %d (Use LEFT and RIGHT to adjust)", curveSegments), 10, 50, 10, DARKGRAY); @@ -116,53 +153,8 @@ int main() //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- -static void DrawCurve(void) -{ - if (showCurve) DrawLineBezierCubic(curveStartPosition, curveEndPosition, curveStartPositionTangent, curveEndPositionTangent, 2, BLUE); - - // Draw the various control points and highlight where the mouse is - DrawLineV(curveStartPosition, curveStartPositionTangent, SKYBLUE); - DrawLineV(curveEndPosition, curveEndPositionTangent, PURPLE); - Vector2 mouse = GetMousePosition(); - - if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) DrawCircleV(curveStartPosition, 7, YELLOW); - DrawCircleV(curveStartPosition, 5, RED); - - if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) DrawCircleV(curveStartPositionTangent, 7, YELLOW); - DrawCircleV(curveStartPositionTangent, 5, MAROON); - - if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) DrawCircleV(curveEndPosition, 7, YELLOW); - DrawCircleV(curveEndPosition, 5, GREEN); - - if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) DrawCircleV(curveEndPositionTangent, 7, YELLOW); - DrawCircleV(curveEndPositionTangent, 5, DARKGREEN); -} - -static void UpdateCurve(void) -{ - // If the mouse is not down, we are not editing the curve so clear the selection - if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON)) - { - curveSelectedPoint = NULL; - return; - } - - // If a point was selected, move it - if (curveSelectedPoint) - { - *curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta()); - return; - } - - // The mouse is down, and nothing was selected, so see if anything was picked - Vector2 mouse = GetMousePosition(); - - if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) curveSelectedPoint = &curveStartPosition; - else if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) curveSelectedPoint = &curveStartPositionTangent; - else if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) curveSelectedPoint = &curveEndPosition; - else if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) curveSelectedPoint = &curveEndPositionTangent; -} +// Draw textured curve using Spline Cubic Bezier static void DrawTexturedCurve(void) { const float step = 1.0f/curveSegments; @@ -179,11 +171,11 @@ static void DrawTexturedCurve(void) for (int i = 1; i <= curveSegments; i++) { - // Segment the curve - t = step*i; - float a = powf(1 - t, 3); - float b = 3*powf(1 - t, 2)*t; - float c = 3*(1 - t)*powf(t, 2); + t = step*(float)i; + + float a = powf(1.0f - t, 3); + float b = 3.0f*powf(1.0f - t, 2)*t; + float c = 3.0f*(1.0f - t)*powf(t, 2); float d = powf(t, 3); // Compute the endpoint for this segment @@ -216,22 +208,20 @@ static void DrawTexturedCurve(void) // Draw the segment as a quad rlSetTexture(texRoad.id); rlBegin(RL_QUADS); + rlColor4ub(255,255,255,255); + rlNormal3f(0.0f, 0.0f, 1.0f); - rlColor4ub(255,255,255,255); - rlNormal3f(0.0f, 0.0f, 1.0f); - - rlTexCoord2f(0, previousV); - rlVertex2f(prevNegNormal.x, prevNegNormal.y); - - rlTexCoord2f(1, previousV); - rlVertex2f(prevPosNormal.x, prevPosNormal.y); + rlTexCoord2f(0, previousV); + rlVertex2f(prevNegNormal.x, prevNegNormal.y); - rlTexCoord2f(1, v); - rlVertex2f(currentPosNormal.x, currentPosNormal.y); + rlTexCoord2f(1, previousV); + rlVertex2f(prevPosNormal.x, prevPosNormal.y); - rlTexCoord2f(0, v); - rlVertex2f(currentNegNormal.x, currentNegNormal.y); + rlTexCoord2f(1, v); + rlVertex2f(currentPosNormal.x, currentPosNormal.y); + rlTexCoord2f(0, v); + rlVertex2f(currentNegNormal.x, currentNegNormal.y); rlEnd(); // The current step is the start of the next step @@ -241,19 +231,3 @@ static void DrawTexturedCurve(void) } } -static void UpdateOptions(void) -{ - if (IsKeyPressed(KEY_SPACE)) showCurve = !showCurve; - - // Update with - if (IsKeyPressed(KEY_EQUAL)) curveWidth += 2; - if (IsKeyPressed(KEY_MINUS)) curveWidth -= 2; - - if (curveWidth < 2) curveWidth = 2; - - // Update segments - if (IsKeyPressed(KEY_LEFT)) curveSegments -= 2; - if (IsKeyPressed(KEY_RIGHT)) curveSegments += 2; - - if (curveSegments < 2) curveSegments = 2; -} diff --git a/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml b/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml index 883183c..6c05529 100644 --- a/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +++ b/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml @@ -10,12 +10,12 @@ <Param name="const char *title" /> </Overload> </KeyWord> - <KeyWord name="WindowShouldClose" func="yes"> - <Overload retVal="bool" descr="Check if KEY_ESCAPE pressed or Close icon pressed"></Overload> - </KeyWord> <KeyWord name="CloseWindow" func="yes"> <Overload retVal="void" descr="Close window and unload OpenGL context"></Overload> </KeyWord> + <KeyWord name="WindowShouldClose" func="yes"> + <Overload retVal="bool" descr="Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)"></Overload> + </KeyWord> <KeyWord name="IsWindowReady" func="yes"> <Overload retVal="bool" descr="Check if window has been initialized successfully"></Overload> </KeyWord> @@ -55,6 +55,9 @@ <KeyWord name="ToggleFullscreen" func="yes"> <Overload retVal="void" descr="Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)"></Overload> </KeyWord> + <KeyWord name="ToggleBorderlessWindowed" func="yes"> + <Overload retVal="void" descr="Toggle window state: borderless windowed (only PLATFORM_DESKTOP)"></Overload> + </KeyWord> <KeyWord name="MaximizeWindow" func="yes"> <Overload retVal="void" descr="Set window state: maximized, if resizable (only PLATFORM_DESKTOP)"></Overload> </KeyWord> @@ -76,7 +79,7 @@ </Overload> </KeyWord> <KeyWord name="SetWindowTitle" func="yes"> - <Overload retVal="void" descr="Set title for window (only PLATFORM_DESKTOP)"> + <Overload retVal="void" descr="Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)"> <Param name="const char *title" /> </Overload> </KeyWord> @@ -87,7 +90,7 @@ </Overload> </KeyWord> <KeyWord name="SetWindowMonitor" func="yes"> - <Overload retVal="void" descr="Set monitor for the current window (fullscreen mode)"> + <Overload retVal="void" descr="Set monitor for the current window"> <Param name="int monitor" /> </Overload> </KeyWord> @@ -97,6 +100,12 @@ <Param name="int height" /> </Overload> </KeyWord> + <KeyWord name="SetWindowMaxSize" func="yes"> + <Overload retVal="void" descr="Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE)"> + <Param name="int width" /> + <Param name="int height" /> + </Overload> + </KeyWord> <KeyWord name="SetWindowSize" func="yes"> <Overload retVal="void" descr="Set window dimensions"> <Param name="int width" /> @@ -108,6 +117,9 @@ <Param name="float opacity" /> </Overload> </KeyWord> + <KeyWord name="SetWindowFocused" func="yes"> + <Overload retVal="void" descr="Set window focused (only PLATFORM_DESKTOP)"></Overload> + </KeyWord> <KeyWord name="GetWindowHandle" func="yes"> <Overload retVal="void" descr="Get native window handle"></Overload> </KeyWord> @@ -166,7 +178,7 @@ <Overload retVal="Vector2" descr="Get window scale DPI factor"></Overload> </KeyWord> <KeyWord name="GetMonitorName" func="yes"> - <Overload retVal="const char" descr="Get the human-readable, UTF-8 encoded name of the primary monitor"> + <Overload retVal="const char" descr="Get the human-readable, UTF-8 encoded name of the specified monitor"> <Param name="int monitor" /> </Overload> </KeyWord> @@ -185,22 +197,6 @@ <Overload retVal="void" descr="Disable waiting for events on EndDrawing(), automatic events polling"></Overload> </KeyWord> - <!-- Custom frame control functions --> - <!-- NOTE: Those functions are intended for advance 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, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL --> - <KeyWord name="SwapScreenBuffer" func="yes"> - <Overload retVal="void" descr="Swap back buffer with front buffer (screen drawing)"></Overload> - </KeyWord> - <KeyWord name="PollInputEvents" func="yes"> - <Overload retVal="void" descr="Register all input events"></Overload> - </KeyWord> - <KeyWord name="WaitTime" func="yes"> - <Overload retVal="void" descr="Wait for some time (halt program execution)"> - <Param name="double seconds" /> - </Overload> - </KeyWord> - <!-- Cursor-related functions --> <KeyWord name="ShowCursor" func="yes"> <Overload retVal="void" descr="Shows cursor"></Overload> @@ -423,28 +419,55 @@ <Param name="int fps" /> </Overload> </KeyWord> - <KeyWord name="GetFPS" func="yes"> - <Overload retVal="int" descr="Get current FPS"></Overload> - </KeyWord> <KeyWord name="GetFrameTime" func="yes"> <Overload retVal="float" descr="Get time in seconds for last frame drawn (delta time)"></Overload> </KeyWord> <KeyWord name="GetTime" func="yes"> <Overload retVal="double" descr="Get elapsed time in seconds since InitWindow()"></Overload> </KeyWord> + <KeyWord name="GetFPS" func="yes"> + <Overload retVal="int" descr="Get current FPS"></Overload> + </KeyWord> - <!-- Misc. functions --> + <!-- Custom frame control functions --> + <KeyWord name="SwapScreenBuffer" func="yes"> + <Overload retVal="void" descr="Swap back buffer with front buffer (screen drawing)"></Overload> + </KeyWord> + <KeyWord name="PollInputEvents" func="yes"> + <Overload retVal="void" descr="Register all input events"></Overload> + </KeyWord> + <KeyWord name="WaitTime" func="yes"> + <Overload retVal="void" descr="Wait for some time (halt program execution)"> + <Param name="double seconds" /> + </Overload> + </KeyWord> + + <!-- Random values generation functions --> + <KeyWord name="SetRandomSeed" func="yes"> + <Overload retVal="void" descr="Set the seed for the random number generator"> + <Param name="unsigned int seed" /> + </Overload> + </KeyWord> <KeyWord name="GetRandomValue" func="yes"> <Overload retVal="int" descr="Get a random value between min and max (both included)"> <Param name="int min" /> <Param name="int max" /> </Overload> </KeyWord> - <KeyWord name="SetRandomSeed" func="yes"> - <Overload retVal="void" descr="Set the seed for the random number generator"> - <Param name="unsigned int seed" /> + <KeyWord name="LoadRandomSequence" func="yes"> + <Overload retVal="int" descr="Load random values sequence, no values repeated"> + <Param name="unsigned int count" /> + <Param name="int min" /> + <Param name="int max" /> + </Overload> + </KeyWord> + <KeyWord name="UnloadRandomSequence" func="yes"> + <Overload retVal="void" descr="Unload random values sequence"> + <Param name="int *sequence" /> </Overload> </KeyWord> + + <!-- Misc. functions --> <KeyWord name="TakeScreenshot" func="yes"> <Overload retVal="void" descr="Takes a screenshot of current screen (filename extension defines format)"> <Param name="const char *fileName" /> @@ -455,6 +478,11 @@ <Param name="unsigned int flags" /> </Overload> </KeyWord> + <KeyWord name="OpenURL" func="yes"> + <Overload retVal="void" descr="Open URL with default system browser (if available)"> + <Param name="const char *url" /> + </Overload> + </KeyWord> <KeyWord name="TraceLog" func="yes"> <Overload retVal="void" descr="Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)"> @@ -480,12 +508,6 @@ <Overload retVal="void" descr="Internal memory free"></Overload> </KeyWord> - <KeyWord name="OpenURL" func="yes"> - <Overload retVal="void" descr="Open URL with default system browser (if available)"> - <Param name="const char *url" /> - </Overload> - </KeyWord> - <!-- Set custom callbacks --> <!-- WARNING: Callbacks setup is intended for advance users --> <KeyWord name="SetTraceLogCallback" func="yes"> @@ -518,7 +540,7 @@ <KeyWord name="char *LoadFileData" func="yes"> <Overload retVal="unsigned" descr="Load file data as byte array (read)"> <Param name="const char *fileName" /> - <Param name="unsigned int *bytesRead" /> + <Param name="int *dataSize" /> </Overload> </KeyWord> <KeyWord name="UnloadFileData" func="yes"> @@ -533,7 +555,7 @@ <KeyWord name="ExportDataAsCode" func="yes"> <Overload retVal="bool" descr="Export data to code (.h), returns true on success"> <Param name="const unsigned char" /> - <Param name="unsigned int size" /> + <Param name="int dataSize" /> <Param name="const char *fileName" /> </Overload> </KeyWord> @@ -553,6 +575,8 @@ <Param name="char *text" /> </Overload> </KeyWord> + + <!-- File system functions --> <KeyWord name="FileExists" func="yes"> <Overload retVal="bool" descr="Check if file exists"> <Param name="const char *fileName" /> @@ -603,7 +627,7 @@ <Overload retVal="const char" descr="Get current working directory (uses static string)"></Overload> </KeyWord> <KeyWord name="GetApplicationDirectory" func="yes"> - <Overload retVal="const char" descr="Get the directory if the running application (uses static string)"></Overload> + <Overload retVal="const char" descr="Get the directory of the running application (uses static string)"></Overload> </KeyWord> <KeyWord name="ChangeDirectory" func="yes"> <Overload retVal="bool" descr="Change working directory, return true on success"> @@ -678,6 +702,45 @@ </Overload> </KeyWord> + <!-- Automation events functionality --> + <KeyWord name="LoadAutomationEventList" func="yes"> + <Overload retVal="AutomationEventList" descr="Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS"> + <Param name="const char *fileName" /> + </Overload> + </KeyWord> + <KeyWord name="UnloadAutomationEventList" func="yes"> + <Overload retVal="void" descr="Unload automation events list from file"> + <Param name="AutomationEventList *list" /> + </Overload> + </KeyWord> + <KeyWord name="ExportAutomationEventList" func="yes"> + <Overload retVal="bool" descr="Export automation events list as text file"> + <Param name="AutomationEventList list" /> + <Param name="const char *fileName" /> + </Overload> + </KeyWord> + <KeyWord name="SetAutomationEventList" func="yes"> + <Overload retVal="void" descr="Set automation event list to record to"> + <Param name="AutomationEventList *list" /> + </Overload> + </KeyWord> + <KeyWord name="SetAutomationEventBaseFrame" func="yes"> + <Overload retVal="void" descr="Set automation event internal base frame to start recording"> + <Param name="int frame" /> + </Overload> + </KeyWord> + <KeyWord name="StartAutomationEventRecording" func="yes"> + <Overload retVal="void" descr="Start recording automation events (AutomationEventList must be set)"></Overload> + </KeyWord> + <KeyWord name="StopAutomationEventRecording" func="yes"> + <Overload retVal="void" descr="Stop recording automation events"></Overload> + </KeyWord> + <KeyWord name="PlayAutomationEvent" func="yes"> + <Overload retVal="void" descr="Play a recorded automation event"> + <Param name="AutomationEvent event" /> + </Overload> + </KeyWord> + <!-------------------------------------------------------------------------------------- --> <!-- Input Handling Functions (Module: core) --> <!-------------------------------------------------------------------------------------- --> @@ -688,6 +751,11 @@ <Param name="int key" /> </Overload> </KeyWord> + <KeyWord name="IsKeyPressedRepeat" func="yes"> + <Overload retVal="bool" descr="Check if a key has been pressed again (Only PLATFORM_DESKTOP)"> + <Param name="int key" /> + </Overload> + </KeyWord> <KeyWord name="IsKeyDown" func="yes"> <Overload retVal="bool" descr="Check if a key is being pressed"> <Param name="int key" /> @@ -703,17 +771,17 @@ <Param name="int key" /> </Overload> </KeyWord> - <KeyWord name="SetExitKey" func="yes"> - <Overload retVal="void" descr="Set a custom key to exit program (default is ESC)"> - <Param name="int key" /> - </Overload> - </KeyWord> <KeyWord name="GetKeyPressed" func="yes"> <Overload retVal="int" descr="Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty"></Overload> </KeyWord> <KeyWord name="GetCharPressed" func="yes"> <Overload retVal="int" descr="Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty"></Overload> </KeyWord> + <KeyWord name="SetExitKey" func="yes"> + <Overload retVal="void" descr="Set a custom key to exit program (default is ESC)"> + <Param name="int key" /> + </Overload> + </KeyWord> <!-- Input-related functions: gamepads --> <KeyWord name="IsGamepadAvailable" func="yes"> @@ -864,7 +932,7 @@ </KeyWord> <KeyWord name="IsGestureDetected" func="yes"> <Overload retVal="bool" descr="Check if a gesture have been detected"> - <Param name="int gesture" /> + <Param name="unsigned int gesture" /> </Overload> </KeyWord> <KeyWord name="GetGestureDetected" func="yes"> @@ -941,54 +1009,35 @@ </Overload> </KeyWord> <KeyWord name="DrawLineV" func="yes"> - <Overload retVal="void" descr="Draw a line (Vector version)"> + <Overload retVal="void" descr="Draw a line (using gl lines)"> <Param name="Vector2 startPos" /> <Param name="Vector2 endPos" /> <Param name="Color color" /> </Overload> </KeyWord> <KeyWord name="DrawLineEx" func="yes"> - <Overload retVal="void" descr="Draw a line defining thickness"> + <Overload retVal="void" descr="Draw a line (using triangles/quads)"> <Param name="Vector2 startPos" /> <Param name="Vector2 endPos" /> <Param name="float thick" /> <Param name="Color color" /> </Overload> </KeyWord> - <KeyWord name="DrawLineBezier" func="yes"> - <Overload retVal="void" descr="Draw a line using cubic-bezier curves in-out"> - <Param name="Vector2 startPos" /> - <Param name="Vector2 endPos" /> - <Param name="float thick" /> - <Param name="Color color" /> - </Overload> - </KeyWord> - <KeyWord name="DrawLineBezierQuad" func="yes"> - <Overload retVal="void" descr="Draw line using quadratic bezier curves with a control point"> - <Param name="Vector2 startPos" /> - <Param name="Vector2 endPos" /> - <Param name="Vector2 controlPos" /> - <Param name="float thick" /> + <KeyWord name="DrawLineStrip" func="yes"> + <Overload retVal="void" descr="Draw lines sequence (using gl lines)"> + <Param name="Vector2 *points" /> + <Param name="int pointCount" /> <Param name="Color color" /> </Overload> </KeyWord> - <KeyWord name="DrawLineBezierCubic" func="yes"> - <Overload retVal="void" descr="Draw line using cubic bezier curves with 2 control points"> + <KeyWord name="DrawLineBezier" func="yes"> + <Overload retVal="void" descr="Draw line segment cubic-bezier in-out interpolation"> <Param name="Vector2 startPos" /> <Param name="Vector2 endPos" /> - <Param name="Vector2 startControlPos" /> - <Param name="Vector2 endControlPos" /> <Param name="float thick" /> <Param name="Color color" /> </Overload> </KeyWord> - <KeyWord name="DrawLineStrip" func="yes"> - <Overload retVal="void" descr="Draw lines sequence"> - <Param name="Vector2 *points" /> - <Param name="int pointCount" /> - <Param name="Color color" /> - </Overload> - </KeyWord> <KeyWord name="DrawCircle" func="yes"> <Overload retVal="void" descr="Draw a color-filled circle"> <Param name="int centerX" /> @@ -1041,6 +1090,13 @@ <Param name="Color color" /> </Overload> </KeyWord> + <KeyWord name="DrawCircleLinesV" func="yes"> + <Overload retVal="void" descr="Draw circle outline (Vector version)"> + <Param name="Vector2 center" /> + <Param name="float radius" /> + <Param name="Color color" /> + </Overload> + </KeyWord> <KeyWord name="DrawEllipse" func="yes"> <Overload retVal="void" descr="Draw ellipse"> <Param name="int centerX" /> @@ -1232,6 +1288,139 @@ </Overload> </KeyWord> + <!-- Splines drawing functions --> + <KeyWord name="DrawSplineLinear" func="yes"> + <Overload retVal="void" descr="Draw spline: Linear, minimum 2 points"> + <Param name="Vector2 *points" /> + <Param name="int pointCount" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineBasis" func="yes"> + <Overload retVal="void" descr="Draw spline: B-Spline, minimum 4 points"> + <Param name="Vector2 *points" /> + <Param name="int pointCount" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineCatmullRom" func="yes"> + <Overload retVal="void" descr="Draw spline: Catmull-Rom, minimum 4 points"> + <Param name="Vector2 *points" /> + <Param name="int pointCount" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineBezierQuadratic" func="yes"> + <Overload retVal="void" descr="Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]"> + <Param name="Vector2 *points" /> + <Param name="int pointCount" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineBezierCubic" func="yes"> + <Overload retVal="void" descr="Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]"> + <Param name="Vector2 *points" /> + <Param name="int pointCount" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineSegmentLinear" func="yes"> + <Overload retVal="void" descr="Draw spline segment: Linear, 2 points"> + <Param name="Vector2 p1" /> + <Param name="Vector2 p2" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineSegmentBasis" func="yes"> + <Overload retVal="void" descr="Draw spline segment: B-Spline, 4 points"> + <Param name="Vector2 p1" /> + <Param name="Vector2 p2" /> + <Param name="Vector2 p3" /> + <Param name="Vector2 p4" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineSegmentCatmullRom" func="yes"> + <Overload retVal="void" descr="Draw spline segment: Catmull-Rom, 4 points"> + <Param name="Vector2 p1" /> + <Param name="Vector2 p2" /> + <Param name="Vector2 p3" /> + <Param name="Vector2 p4" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineSegmentBezierQuadratic" func="yes"> + <Overload retVal="void" descr="Draw spline segment: Quadratic Bezier, 2 points, 1 control point"> + <Param name="Vector2 p1" /> + <Param name="Vector2 c2" /> + <Param name="Vector2 p3" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + <KeyWord name="DrawSplineSegmentBezierCubic" func="yes"> + <Overload retVal="void" descr="Draw spline segment: Cubic Bezier, 2 points, 2 control points"> + <Param name="Vector2 p1" /> + <Param name="Vector2 c2" /> + <Param name="Vector2 c3" /> + <Param name="Vector2 p4" /> + <Param name="float thick" /> + <Param name="Color color" /> + </Overload> + </KeyWord> + + <!-- Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] --> + <KeyWord name="GetSplinePointLinear" func="yes"> + <Overload retVal="Vector2" descr="Get (evaluate) spline point: Linear"> + <Param name="Vector2 startPos" /> + <Param name="Vector2 endPos" /> + <Param name="float t" /> + </Overload> + </KeyWord> + <KeyWord name="GetSplinePointBasis" func="yes"> + <Overload retVal="Vector2" descr="Get (evaluate) spline point: B-Spline"> + <Param name="Vector2 p1" /> + <Param name="Vector2 p2" /> + <Param name="Vector2 p3" /> + <Param name="Vector2 p4" /> + <Param name="float t" /> + </Overload> + </KeyWord> + <KeyWord name="GetSplinePointCatmullRom" func="yes"> + <Overload retVal="Vector2" descr="Get (evaluate) spline point: Catmull-Rom"> + <Param name="Vector2 p1" /> + <Param name="Vector2 p2" /> + <Param name="Vector2 p3" /> + <Param name="Vector2 p4" /> + <Param name="float t" /> + </Overload> + </KeyWord> + <KeyWord name="GetSplinePointBezierQuad" func="yes"> + <Overload retVal="Vector2" descr="Get (evaluate) spline point: Quadratic Bezier"> + <Param name="Vector2 p1" /> + <Param name="Vector2 c2" /> + <Param name="Vector2 p3" /> + <Param name="float t" /> + </Overload> + </KeyWord> + <KeyWord name="GetSplinePointBezierCubic" func="yes"> + <Overload retVal="Vector2" descr="Get (evaluate) spline point: Cubic Bezier"> + <Param name="Vector2 p1" /> + <Param name="Vector2 c2" /> + <Param name="Vector2 c3" /> + <Param name="Vector2 p4" /> + <Param name="float t" /> + </Overload> + </KeyWord> + <!-- Basic shapes collision detection functions --> <KeyWord name="CheckCollisionRecs" func="yes"> <Overload retVal="bool" descr="Check collision between two rectangles"> @@ -1326,6 +1515,13 @@ <Param name="int headerSize" /> </Overload> </KeyWord> + <KeyWord name="LoadImageSvg" func="yes"> + <Overload retVal="Image" descr="Load image from SVG file data or string with specified size"> + <Param name="const char *fileNameOrString" /> + <Param name="int width" /> + <Param name="int height" /> + </Overload> + </KeyWord> <KeyWord name="LoadImageAnim" func="yes"> <Overload retVal="Image" descr="Load image sequence from file (frames appended to image.data)"> <Param name="const char *fileName" /> @@ -1363,6 +1559,13 @@ <Param name="const char *fileName" /> </Overload> </KeyWord> + <KeyWord name="char *ExportImageToMemory" func="yes"> + <Overload retVal="unsigned" descr="Export image to memory buffer"> + <Param name="Image image" /> + <Param name="const char *fileType" /> + <Param name="int *fileSize" /> + </Overload> + </KeyWord> <KeyWord name="ExportImageAsCode" func="yes"> <Overload retVal="bool" descr="Export image as code file defining an array of bytes, returns true on success"> <Param name="Image image" /> @@ -1379,7 +1582,7 @@ </Overload> </KeyWord> <KeyWord name="GenImageGradientLinear" func="yes"> - <Overload retVal="Image" descr="Generate image: linear gradient"> + <Overload retVal="Image" descr="Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient"> <Param name="int width" /> <Param name="int height" /> <Param name="int direction" /> @@ -2025,11 +2228,11 @@ </Overload> </KeyWord> <KeyWord name="LoadFontEx" func="yes"> - <Overload retVal="Font" descr="Load font from file with extended parameters, use NULL for fontChars and 0 for glyphCount to load the default character set"> + <Overload retVal="Font" descr="Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set"> <Param name="const char *fileName" /> <Param name="int fontSize" /> - <Param name="int *fontChars" /> - <Param name="int glyphCount" /> + <Param name="int *codepoints" /> + <Param name="int codepointCount" /> </Overload> </KeyWord> <KeyWord name="LoadFontFromImage" func="yes"> @@ -2045,8 +2248,8 @@ <Param name="const unsigned char" /> <Param name="int dataSize" /> <Param name="int fontSize" /> - <Param name="int *fontChars" /> - <Param name="int glyphCount" /> + <Param name="int *codepoints" /> + <Param name="int codepointCount" /> </Overload> </KeyWord> <KeyWord name="IsFontReady" func="yes"> @@ -2059,15 +2262,15 @@ <Param name="const unsigned char" /> <Param name="int dataSize" /> <Param name="int fontSize" /> - <Param name="int *fontChars" /> - <Param name="int glyphCount" /> + <Param name="int *codepoints" /> + <Param name="int codepointCount" /> <Param name="int type" /> </Overload> </KeyWord> <KeyWord name="GenImageFontAtlas" func="yes"> <Overload retVal="Image" descr="Generate image font atlas using chars info"> - <Param name="const GlyphInfo *chars" /> - <Param name="Rectangle **recs" /> + <Param name="const GlyphInfo *glyphs" /> + <Param name="Rectangle **glyphRecs" /> <Param name="int glyphCount" /> <Param name="int fontSize" /> <Param name="int padding" /> @@ -2076,7 +2279,7 @@ </KeyWord> <KeyWord name="UnloadFontData" func="yes"> <Overload retVal="void" descr="Unload font chars info data (RAM)"> - <Param name="GlyphInfo *chars" /> + <Param name="GlyphInfo *glyphs" /> <Param name="int glyphCount" /> </Overload> </KeyWord> @@ -2143,7 +2346,7 @@ <Overload retVal="void" descr="Draw multiple character (codepoint)"> <Param name="Font font" /> <Param name="const int *codepoints" /> - <Param name="int count" /> + <Param name="int codepointCount" /> <Param name="Vector2 position" /> <Param name="float fontSize" /> <Param name="float spacing" /> @@ -2152,6 +2355,11 @@ </KeyWord> <!-- Text font info functions --> + <KeyWord name="SetTextLineSpacing" func="yes"> + <Overload retVal="void" descr="Set vertical line spacing when drawing with line-breaks"> + <Param name="int spacing" /> + </Overload> + </KeyWord> <KeyWord name="MeasureText" func="yes"> <Overload retVal="int" descr="Measure string width for default font"> <Param name="const char *text" /> @@ -2614,7 +2822,7 @@ <Param name="Vector2 size" /> <Param name="Vector2 origin" /> <Param name="float rotation" /> - <Param name="Color tint" /> + <Param name="0ó¿8± " /> </Overload> </KeyWord> @@ -2789,7 +2997,7 @@ <KeyWord name="LoadModelAnimations" func="yes"> <Overload retVal="ModelAnimation" descr="Load model animations from file"> <Param name="const char *fileName" /> - <Param name="unsigned int *animCount" /> + <Param name="int *animCount" /> </Overload> </KeyWord> <KeyWord name="UpdateModelAnimation" func="yes"> @@ -2807,7 +3015,7 @@ <KeyWord name="UnloadModelAnimations" func="yes"> <Overload retVal="void" descr="Unload animation array data"> <Param name="ModelAnimation *animations" /> - <Param name="unsigned int count" /> + <Param name="int animCount" /> </Overload> </KeyWord> <KeyWord name="IsModelAnimationValid" func="yes"> @@ -2896,6 +3104,9 @@ <Param name="float volume" /> </Overload> </KeyWord> + <KeyWord name="GetMasterVolume" func="yes"> + <Overload retVal="float" descr="Get master volume (listener)"></Overload> + </KeyWord> <!-- Wave/Sound loading/unloading functions --> <KeyWord name="LoadWave" func="yes"> @@ -2925,6 +3136,11 @@ <Param name="Wave wave" /> </Overload> </KeyWord> + <KeyWord name="LoadSoundAlias" func="yes"> + <Overload retVal="Sound" descr="Create a new sound that shares the same sample data as the source sound, does not own the sound data"> + <Param name="Sound source" /> + </Overload> + </KeyWord> <KeyWord name="IsSoundReady" func="yes"> <Overload retVal="bool" descr="Checks if a sound is ready"> <Param name="Sound sound" /> @@ -2947,6 +3163,11 @@ <Param name="Sound sound" /> </Overload> </KeyWord> + <KeyWord name="UnloadSoundAlias" func="yes"> + <Overload retVal="void" descr="Unload a sound alias (does not deallocate sample data)"> + <Param name="Sound alias" /> + </Overload> + </KeyWord> <KeyWord name="ExportWave" func="yes"> <Overload retVal="bool" descr="Export wave data to file, returns true on success"> <Param name="Wave wave" /> @@ -3209,7 +3430,7 @@ </KeyWord> <KeyWord name="AttachAudioStreamProcessor" func="yes"> - <Overload retVal="void" descr="Attach audio stream processor to stream"> + <Overload retVal="void" descr="Attach audio stream processor to stream, receives the samples as <float>s"> <Param name="AudioStream stream" /> <Param name="AudioCallback processor" /> </Overload> @@ -3222,7 +3443,7 @@ </KeyWord> <KeyWord name="AttachAudioMixedProcessor" func="yes"> - <Overload retVal="void" descr="Attach audio stream processor to the entire audio pipeline"> + <Overload retVal="void" descr="Attach audio stream processor to the entire audio pipeline, receives the samples as <float>s"> <Param name="AudioCallback processor" /> </Overload> </KeyWord> diff --git a/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h b/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h index c32cdb2..2c033c9 100644 --- a/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +++ b/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h @@ -4,8 +4,8 @@ // Window-related functions RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context -RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed RLAPI void CloseWindow(void); // Close window and unload OpenGL context +RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP) @@ -17,17 +17,20 @@ RLAPI bool IsWindowState(unsigned int flag); // Check if on RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP) RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) +RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP) RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) -RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP) +RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) -RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode) +RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) +RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) RLAPI void SetWindowSize(int width, int height); // Set window dimensions RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) +RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP) RLAPI void *GetWindowHandle(void); // Get native window handle RLAPI int GetScreenWidth(void); // Get current screen width RLAPI int GetScreenHeight(void); // Get current screen height @@ -43,20 +46,12 @@ RLAPI int GetMonitorPhysicalHeight(int monitor); // Get specifi RLAPI int GetMonitorRefreshRate(int monitor); // Get specified monitor refresh rate RLAPI Vector2 GetWindowPosition(void); // Get window position XY on monitor RLAPI Vector2 GetWindowScaleDPI(void); // Get window scale DPI factor -RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the primary monitor +RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor RLAPI void SetClipboardText(const char *text); // Set clipboard text content RLAPI const char *GetClipboardText(void); // Get clipboard text content RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling -// Custom frame control functions -// NOTE: Those functions are intended for advance 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, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL -RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) -RLAPI void PollInputEvents(void); // Register all input events -RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) - // Cursor-related functions RLAPI void ShowCursor(void); // Shows cursor RLAPI void HideCursor(void); // Hides cursor @@ -112,15 +107,25 @@ RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the // Timing-related functions RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) -RLAPI int GetFPS(void); // Get current FPS RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() +RLAPI int GetFPS(void); // Get current FPS -// Misc. functions -RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +// Custom frame control functions +RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) +RLAPI void PollInputEvents(void); // Register all input events +RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) + +// Random values generation functions RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator +RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +RLAPI int *LoadRandomSequence(unsigned int count, int min, int max); // Load random values sequence, no values repeated +RLAPI void UnloadRandomSequence(int *sequence); // Unload random values sequence + +// Misc. functions RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) +RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level @@ -128,8 +133,6 @@ RLAPI void *MemAlloc(unsigned int size); // Internal me RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator RLAPI void MemFree(void *ptr); // Internal memory free -RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) - // Set custom callbacks // WARNING: Callbacks setup is intended for advance users RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log @@ -139,13 +142,15 @@ RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver // Files management functions -RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read) +RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() -RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success -RLAPI bool ExportDataAsCode(const unsigned char *data, unsigned int size, const char *fileName); // Export data to code (.h), returns true on success +RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success +RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success + +// File system functions RLAPI bool FileExists(const char *fileName); // Check if file exists RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav) @@ -156,7 +161,7 @@ RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filenam RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) -RLAPI const char *GetApplicationDirectory(void); // Get the directory if the running application (uses static string) +RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths @@ -173,18 +178,29 @@ RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataS RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree() RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree() +// 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 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 +RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set) +RLAPI void StopAutomationEventRecording(void); // Stop recording automation events +RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event + //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) //------------------------------------------------------------------------------------ // Input-related functions: keyboard RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once +RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP) RLAPI bool IsKeyDown(int key); // Check if a key is being pressed RLAPI bool IsKeyReleased(int key); // Check if a key has been released once RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed -RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty +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 @@ -225,7 +241,7 @@ RLAPI int GetTouchPointCount(void); // Get number of t // Gestures and Touch Handling Functions (Module: rgestures) //------------------------------------------------------------------------------------ RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags -RLAPI bool IsGestureDetected(int gesture); // Check if a gesture have been detected +RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected RLAPI int GetGestureDetected(void); // Get latest detected gesture RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector @@ -251,18 +267,17 @@ RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set t RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line -RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) -RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness -RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out -RLAPI void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color); // Draw line using quadratic bezier curves with a control point -RLAPI void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlPos, Vector2 endControlPos, float thick, Color color); // Draw line using cubic bezier curves with 2 control points -RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence +RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) +RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads) +RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines) +RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline +RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version) RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring @@ -286,6 +301,25 @@ RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Col RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters +// Splines drawing functions +RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points +RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points +RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points +RLAPI void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +RLAPI void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points +RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points +RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points +RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point +RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points + +// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] +RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear +RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline +RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom +RLAPI Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier +RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier + // Basic shapes collision detection functions RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles @@ -306,6 +340,7 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // NOTE: These functions do not require GPU access RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) 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 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 @@ -313,11 +348,12 @@ RLAPI Image LoadImageFromScreen(void); RLAPI bool IsImageReady(Image image); // Check if an image is ready RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success +RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success // Image generation functions RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color -RLAPI Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end); // Generate image: linear gradient +RLAPI Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end); // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient RLAPI Image GenImageGradientSquare(int width, int height, float density, Color inner, Color outer); // Generate image: square gradient RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked @@ -389,7 +425,7 @@ RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) -RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready +RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data @@ -431,13 +467,13 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G // Font loading/unloading functions RLAPI Font GetFontDefault(void); // Get the default Font RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) -RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount); // Load font from file with extended parameters, use NULL for fontChars and 0 for glyphCount to load the default character set +RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) -RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' +RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' RLAPI bool IsFontReady(Font font); // Check if a font is ready -RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount, int type); // Load font data for further use -RLAPI Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **recs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info -RLAPI void UnloadFontData(GlyphInfo *chars, int glyphCount); // Unload font chars info data (RAM) +RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use +RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info +RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM) RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM) RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success @@ -447,9 +483,10 @@ RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color co RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation) RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) -RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) +RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) // Text font info functions +RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found @@ -565,10 +602,10 @@ RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh // Model animations loading/unloading functions -RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, unsigned int *animCount); // Load model animations from file +RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data -RLAPI void UnloadModelAnimations(ModelAnimation *animations, unsigned int count); // Unload animation array data +RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match // Collision detection functions @@ -591,6 +628,7 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully RLAPI void SetMasterVolume(float volume); // Set master volume (listener) +RLAPI float GetMasterVolume(void); // Get master volume (listener) // Wave/Sound loading/unloading functions RLAPI Wave LoadWave(const char *fileName); // Load wave data from file @@ -598,10 +636,12 @@ RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileDat RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready RLAPI Sound LoadSound(const char *fileName); // Load sound from file RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound +RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data) RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success @@ -653,11 +693,11 @@ RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set vol RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered) 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 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 +RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as <float>s 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 +RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as <float>s RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline diff --git a/raylib/projects/VS2022/examples/audio_mixed_processor.vcxproj b/raylib/projects/VS2022/examples/audio_mixed_processor.vcxproj new file mode 100644 index 0000000..26eb504 --- /dev/null +++ b/raylib/projects/VS2022/examples/audio_mixed_processor.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A4B0D971-3CD6-41C9-8AB2-055D25A33373}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>audio_mixed_processor</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>audio_mixed_processor</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\audio</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\audio\audio_mixed_processor.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/core_automation_events.vcxproj b/raylib/projects/VS2022/examples/core_automation_events.vcxproj new file mode 100644 index 0000000..e70a6b1 --- /dev/null +++ b/raylib/projects/VS2022/examples/core_automation_events.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>core_automation_events</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>core_automation_events</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\core\core_automation_events.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/core_input_gamepad_info.vcxproj b/raylib/projects/VS2022/examples/core_input_gamepad_info.vcxproj new file mode 100644 index 0000000..7227ef2 --- /dev/null +++ b/raylib/projects/VS2022/examples/core_input_gamepad_info.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{27AA7BDA-0C34-4733-9009-73D3E64234FB}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>core_input_gamepad_info</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>core_input_gamepad_info</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\core\core_input_gamepad_info.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/core_input_mouse_wheel.vcxproj b/raylib/projects/VS2022/examples/core_input_mouse_wheel.vcxproj index e9dcf2b..6f0a312 100644 --- a/raylib/projects/VS2022/examples/core_input_mouse_wheel.vcxproj +++ b/raylib/projects/VS2022/examples/core_input_mouse_wheel.vcxproj @@ -35,7 +35,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{0981CA98-E4A5-4DF1-987F-A41D09131EFC}</ProjectGuid> + <ProjectGuid>{15CDD310-6980-42A6-8082-3A6B7730D13F}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>core_input_mouse_wheel</RootNamespace> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> @@ -210,7 +210,7 @@ <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -228,7 +228,7 @@ <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> @@ -245,7 +245,7 @@ <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> <PostBuildEvent> <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> @@ -266,7 +266,7 @@ <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> <PostBuildEvent> <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> @@ -291,7 +291,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -313,7 +313,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -335,7 +335,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> </Link> <PostBuildEvent> @@ -363,7 +363,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>raylib.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> </Link> <PostBuildEvent> @@ -377,6 +377,9 @@ <ClCompile Include="..\..\..\examples\core\core_input_mouse_wheel.c" /> </ItemGroup> <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> <ProjectReference Include="..\raylib\raylib.vcxproj"> <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> </ProjectReference> diff --git a/raylib/projects/VS2022/examples/core_smooth_pixelperfect.vcxproj b/raylib/projects/VS2022/examples/core_smooth_pixelperfect.vcxproj new file mode 100644 index 0000000..7c4daf2 --- /dev/null +++ b/raylib/projects/VS2022/examples/core_smooth_pixelperfect.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{71DB4284-5B1C-4E86-9AF5-B91542D44A6F}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>core_smooth_pixelperfect</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>core_smooth_pixelperfect</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\core\core_smooth_pixelperfect.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/models_draw_cube_texture.vcxproj b/raylib/projects/VS2022/examples/models_draw_cube_texture.vcxproj new file mode 100644 index 0000000..d5e0e8b --- /dev/null +++ b/raylib/projects/VS2022/examples/models_draw_cube_texture.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>models_draw_cube_texture</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>models_draw_cube_texture</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\models\models_draw_cube_texture.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/shaders_deferred_render.vcxproj b/raylib/projects/VS2022/examples/shaders_deferred_render.vcxproj new file mode 100644 index 0000000..d26fd8d --- /dev/null +++ b/raylib/projects/VS2022/examples/shaders_deferred_render.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{88DE5AD6-0074-4A5A-BE22-C840153E35D5}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>shaders_deferred_render</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>shaders_deferred_render</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\shaders\shaders_deferred_render.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/shaders_texture_outline.vcxproj b/raylib/projects/VS2022/examples/shaders_texture_outline.vcxproj new file mode 100644 index 0000000..dd90ef9 --- /dev/null +++ b/raylib/projects/VS2022/examples/shaders_texture_outline.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A546E75A-5242-46E6-9A9E-6C91554EAB84}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>shaders_texture_outline</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>shaders_texture_outline</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\shaders\shaders_texture_outline.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/shaders_texture_tiling.vcxproj b/raylib/projects/VS2022/examples/shaders_texture_tiling.vcxproj new file mode 100644 index 0000000..9374059 --- /dev/null +++ b/raylib/projects/VS2022/examples/shaders_texture_tiling.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>shaders_texture_tiling</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>shaders_texture_tiling</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shaders</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\shaders\shaders_texture_tiling.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/shapes_splines_drawing.vcxproj b/raylib/projects/VS2022/examples/shapes_splines_drawing.vcxproj new file mode 100644 index 0000000..77b17a8 --- /dev/null +++ b/raylib/projects/VS2022/examples/shapes_splines_drawing.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DF25E545-00FF-4E64-844C-7DF98991F901}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>shapes_splines_drawing</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>shapes_splines_drawing</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\shapes\shapes_splines_drawing.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/shapes_top_down_lights.vcxproj b/raylib/projects/VS2022/examples/shapes_top_down_lights.vcxproj new file mode 100644 index 0000000..668ce6a --- /dev/null +++ b/raylib/projects/VS2022/examples/shapes_top_down_lights.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{703BE7BA-5B99-4F70-806D-3A259F6A991E}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>shapes_top_down_lights</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>shapes_top_down_lights</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\shapes\shapes_top_down_lights.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/examples/textures_svg_loading.vcxproj b/raylib/projects/VS2022/examples/textures_svg_loading.vcxproj new file mode 100644 index 0000000..8b59d95 --- /dev/null +++ b/raylib/projects/VS2022/examples/textures_svg_loading.vcxproj @@ -0,0 +1,390 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug.DLL|Win32"> + <Configuration>Debug.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug.DLL|x64"> + <Configuration>Debug.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|Win32"> + <Configuration>Release.DLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release.DLL|x64"> + <Configuration>Release.DLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D8026C60-CCBC-45DF-9085-BF21569EB414}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>textures_svg_loading</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>textures_svg_loading</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + <Message>Copy Debug DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <CompileAs>CompileAsC</CompileAs> + <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy Release DLL to output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\examples\textures\textures_svg_loading.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\src\raylib.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\raylib\raylib.vcxproj"> + <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/raylib/projects/VS2022/raylib.sln b/raylib/projects/VS2022/raylib.sln index 007f796..3ce44a9 100644 --- a/raylib/projects/VS2022/raylib.sln +++ b/raylib/projects/VS2022/raylib.sln @@ -273,6 +273,30 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_multi", "exampl EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_split_screen", "examples\core_2d_camera_split_screen.vcxproj", "{CC62F7DB-D089-4677-8575-CAB7A7815C43}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_automation_events", "examples\core_automation_events.vcxproj", "{7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_mixed_processor", "examples\audio_mixed_processor.vcxproj", "{A4B0D971-3CD6-41C9-8AB2-055D25A33373}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gamepad_info", "examples\core_input_gamepad_info.vcxproj", "{27AA7BDA-0C34-4733-9009-73D3E64234FB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_mouse_wheel", "examples\core_input_mouse_wheel.vcxproj", "{15CDD310-6980-42A6-8082-3A6B7730D13F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_smooth_pixelperfect", "examples\core_smooth_pixelperfect.vcxproj", "{71DB4284-5B1C-4E86-9AF5-B91542D44A6F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_draw_cube_texture", "examples\models_draw_cube_texture.vcxproj", "{4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_deferred_render", "examples\shaders_deferred_render.vcxproj", "{88DE5AD6-0074-4A5A-BE22-C840153E35D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_outline", "examples\shaders_texture_outline.vcxproj", "{A546E75A-5242-46E6-9A9E-6C91554EAB84}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_svg_loading", "examples\textures_svg_loading.vcxproj", "{D8026C60-CCBC-45DF-9085-BF21569EB414}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|x64 = Debug.DLL|x64 @@ -2297,6 +2321,198 @@ Global {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x64.Build.0 = Release|x64 {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x86.ActiveCfg = Release|Win32 {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x86.Build.0 = Release|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x64.ActiveCfg = Debug|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x64.Build.0 = Debug|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x86.ActiveCfg = Debug|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x86.Build.0 = Debug|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x64.ActiveCfg = Release|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x64.Build.0 = Release|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x86.ActiveCfg = Release|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x86.Build.0 = Release|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x64.ActiveCfg = Debug|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x64.Build.0 = Debug|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x86.ActiveCfg = Debug|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x86.Build.0 = Debug|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x64.ActiveCfg = Release|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x64.Build.0 = Release|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x86.ActiveCfg = Release|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x86.Build.0 = Release|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug|x64.ActiveCfg = Debug|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug|x64.Build.0 = Debug|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug|x86.ActiveCfg = Debug|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Debug|x86.Build.0 = Debug|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release|x64.ActiveCfg = Release|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release|x64.Build.0 = Release|x64 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release|x86.ActiveCfg = Release|Win32 + {27AA7BDA-0C34-4733-9009-73D3E64234FB}.Release|x86.Build.0 = Release|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x64.ActiveCfg = Debug|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x64.Build.0 = Debug|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x86.ActiveCfg = Debug|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x86.Build.0 = Debug|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x64.ActiveCfg = Release|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x64.Build.0 = Release|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x86.ActiveCfg = Release|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x86.Build.0 = Release|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x64.ActiveCfg = Debug|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x64.Build.0 = Debug|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x86.ActiveCfg = Debug|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x86.Build.0 = Debug|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x64.ActiveCfg = Release|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x64.Build.0 = Release|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x86.ActiveCfg = Release|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x86.Build.0 = Release|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x64.ActiveCfg = Debug|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x64.Build.0 = Debug|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x86.ActiveCfg = Debug|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x86.Build.0 = Debug|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x64.ActiveCfg = Release|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x64.Build.0 = Release|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x86.ActiveCfg = Release|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x86.Build.0 = Release|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x64.ActiveCfg = Debug|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x64.Build.0 = Debug|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x86.ActiveCfg = Debug|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x86.Build.0 = Debug|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x64.ActiveCfg = Release|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x64.Build.0 = Release|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x86.ActiveCfg = Release|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x86.Build.0 = Release|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x64.ActiveCfg = Debug|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x64.Build.0 = Debug|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x86.ActiveCfg = Debug|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x86.Build.0 = Debug|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x64.ActiveCfg = Release|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x64.Build.0 = Release|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x86.ActiveCfg = Release|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x86.Build.0 = Release|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x64.ActiveCfg = Debug|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x64.Build.0 = Debug|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x86.ActiveCfg = Debug|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x86.Build.0 = Debug|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.ActiveCfg = Release|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.Build.0 = Release|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.ActiveCfg = Release|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.Build.0 = Release|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x64.ActiveCfg = Debug|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x64.Build.0 = Debug|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x86.ActiveCfg = Debug|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x86.Build.0 = Debug|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x64.ActiveCfg = Release|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x64.Build.0 = Release|x64 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x86.ActiveCfg = Release|Win32 + {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x86.Build.0 = Release|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x64.ActiveCfg = Debug|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x64.Build.0 = Debug|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x86.ActiveCfg = Debug|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x86.Build.0 = Debug|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x64.ActiveCfg = Release|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x64.Build.0 = Release|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x86.ActiveCfg = Release|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x86.Build.0 = Release|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x64.ActiveCfg = Debug|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x64.Build.0 = Debug|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x86.ActiveCfg = Debug|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x86.Build.0 = Debug|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.ActiveCfg = Release|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.Build.0 = Release|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.ActiveCfg = Release|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2435,6 +2651,18 @@ Global {3755E9F4-CB48-4EC3-B561-3B85964EBDEF} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {F81C5819-85B4-4D2E-B6DC-104A7634461B} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {CC62F7DB-D089-4677-8575-CAB7A7815C43} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {A4B0D971-3CD6-41C9-8AB2-055D25A33373} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {27AA7BDA-0C34-4733-9009-73D3E64234FB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {15CDD310-6980-42A6-8082-3A6B7730D13F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {88DE5AD6-0074-4A5A-BE22-C840153E35D5} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {A546E75A-5242-46E6-9A9E-6C91554EAB84} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {D8026C60-CCBC-45DF-9085-BF21569EB414} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {DF25E545-00FF-4E64-844C-7DF98991F901} = {278D8859-20B1-428F-8448-064F46E1F021} + {703BE7BA-5B99-4F70-806D-3A259F6A991E} = {278D8859-20B1-428F-8448-064F46E1F021} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/raylib/src/Makefile b/raylib/src/Makefile index 2381eb8..9da4d73 100644 --- a/raylib/src/Makefile +++ b/raylib/src/Makefile @@ -1,18 +1,28 @@ #****************************************************************************** # -# raylib makefile +# raylib makefile # -# Platforms supported: -# PLATFORM_DESKTOP: Windows (Win32, Win64) -# PLATFORM_DESKTOP: Linux (arm64, i386, x64) -# PLATFORM_DESKTOP: OSX/macOS (arm64, x86_64) -# PLATFORM_DESKTOP: FreeBSD, OpenBSD, NetBSD, DragonFly -# PLATFORM_ANDROID: Android (arm, i686, arm64, x86_64) -# PLATFORM_DRM: Linux native mode, including Raspberry Pi (RPI OS Bullseye) -# PLATFORM_WEB: HTML5 (Chrome, Firefox) +# This file supports building raylib library for the following platforms: # -# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline. -# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline. +# > PLATFORM_DESKTOP (GLFW backend): +# - Windows (Win32, Win64) +# - Linux (X11/Wayland desktop mode) +# - macOS/OSX (x64, arm64) +# - FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop) +# > PLATFORM_DESKTOP_SDL (SDL backend): +# - Windows (Win32, Win64) +# - Linux (X11/Wayland desktop mode) +# - Others (not tested) +# > PLATFORM_WEB: +# - HTML5 (WebAssembly) +# > PLATFORM_DRM: +# - Raspberry Pi 0-5 (DRM/KMS) +# - Linux DRM subsystem (KMS mode) +# > PLATFORM_ANDROID: +# - Android (ARM, ARM64) +# +# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline. +# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline. # # Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) # @@ -44,8 +54,8 @@ PLATFORM ?= PLATFORM_DESKTOP # Define required raylib variables -RAYLIB_VERSION = 4.5.0 -RAYLIB_API_VERSION = 450 +RAYLIB_VERSION = 5.0.0 +RAYLIB_API_VERSION = 500 # Define raylib source code path RAYLIB_SRC_PATH ?= ../src @@ -78,17 +88,19 @@ RAYLIB_CONFIG_FLAGS ?= NONE RAYLIB_MODULE_AUDIO ?= TRUE RAYLIB_MODULE_MODELS ?= TRUE RAYLIB_MODULE_RAYGUI ?= FALSE -RAYLIB_MODULE_PHYSAC ?= FALSE # NOTE: Additional libraries have been moved to their own repos: # raygui: https://github.com/raysan5/raygui -# physac: https://github.com/raysan5/physac RAYLIB_MODULE_RAYGUI_PATH ?= $(RAYLIB_SRC_PATH)/../../raygui/src -RAYLIB_MODULE_PHYSAC_PATH ?= $(RAYLIB_SRC_PATH)/../../physac/src # Use external GLFW library instead of rglfw module USE_EXTERNAL_GLFW ?= FALSE +# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally +# WARNING: Library is not included in raylib, it MUST be configured by users +SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2-2.28.4/include +SDL_LIBRARY_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2-2.28.4/lib/x64 + # Use Wayland display server protocol on Linux desktop (by default it uses X11 windowing system) # NOTE: This variable is only used for PLATFORM_OS: LINUX USE_WAYLAND_DISPLAY ?= FALSE @@ -101,8 +113,8 @@ ROOT = $(shell whoami) HOST_PLATFORM_OS ?= WINDOWS PLATFORM_OS ?= WINDOWS -# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected -ifeq ($(PLATFORM),PLATFORM_DESKTOP) +# Determine PLATFORM_OS when required +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! # ifeq ($(UNAME),Msys) -> Windows ifeq ($(OS),Windows_NT) @@ -145,16 +157,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM) endif endif ifeq ($(PLATFORM),PLATFORM_WEB) - ifeq ($(OS),Windows_NT) - PLATFORM_OS = WINDOWS - ifndef PLATFORM_SHELL - PLATFORM_SHELL = cmd - endif - else - UNAMEOS = $(shell uname) - ifeq ($(UNAMEOS),Linux) - PLATFORM_OS = LINUX - endif + ifeq ($(PLATFORM_OS),LINUX) ifndef PLATFORM_SHELL PLATFORM_SHELL = sh endif @@ -217,7 +220,10 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) #GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3 #GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE) endif - +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + # By default use OpenGL 3.3 on desktop platform with SDL backend + GRAPHICS ?= GRAPHICS_API_OPENGL_33 +endif ifeq ($(PLATFORM),PLATFORM_DRM) # On DRM OpenGL ES 2.0 must be used GRAPHICS = GRAPHICS_API_OPENGL_ES2 @@ -416,14 +422,21 @@ endif # Define include paths for required headers: INCLUDE_PATHS # NOTE: Several external required libraries (stb and others) #------------------------------------------------------------------------------------------------ -INCLUDE_PATHS = -I. -Iexternal/glfw/include -Iexternal/glfw/deps/mingw +INCLUDE_PATHS = -I. # Define additional directories containing required header files ifeq ($(PLATFORM),PLATFORM_DESKTOP) + INCLUDE_PATHS += -Iexternal/glfw/include -Iexternal/glfw/deps/mingw ifeq ($(PLATFORM_OS),BSD) INCLUDE_PATHS += -I/usr/local/include endif endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH) +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + INCLUDE_PATHS += -Iexternal/glfw/include -Iexternal/glfw/deps/mingw +endif ifeq ($(PLATFORM),PLATFORM_DRM) INCLUDE_PATHS += -I/usr/include/libdrm ifeq ($(USE_RPI_CROSSCOMPILER), TRUE) @@ -473,10 +486,14 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).$(RAYLIB_API_VERSION).so -Lsrc -L/usr/local/lib endif endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) + LDFLAGS += -L$(SDL_LIBRARY_PATH) +endif ifeq ($(PLATFORM),PLATFORM_DRM) LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) ifeq ($(USE_RPI_CROSSCOMPILER), TRUE) - INCLUDE_PATHS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -L$(RPI_TOOLCHAIN_SYSROOT)/usr/lib + LDFLAGS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -L$(RPI_TOOLCHAIN_SYSROOT)/usr/lib endif endif ifeq ($(PLATFORM),PLATFORM_ANDROID) @@ -521,6 +538,18 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDLIBS = -lglfw endif endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) + ifeq ($(PLATFORM_OS),WINDOWS) + LDLIBS = -static-libgcc -lopengl32 -lgdi32 + endif + ifeq ($(PLATFORM_OS),LINUX) + LDLIBS = -lGL -lc -lm -lpthread -ldl -lrt + ifeq ($(USE_WAYLAND_DISPLAY),FALSE) + LDLIBS += -lX11 + endif + endif + LDLIBS += -lSDL2 -lSDL2main +endif ifeq ($(PLATFORM),PLATFORM_DRM) LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl ifeq ($(RAYLIB_MODULE_AUDIO),TRUE) @@ -553,9 +582,6 @@ endif ifeq ($(RAYLIB_MODULE_RAYGUI),TRUE) OBJS += raygui.o endif -ifeq ($(RAYLIB_MODULE_PHYSAC),TRUE) - OBJS += physac.o -endif ifeq ($(PLATFORM),PLATFORM_ANDROID) OBJS += android_native_app_glue.o @@ -576,7 +602,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB) @echo "raylib library generated (lib$(RAYLIB_LIB_NAME).a)!" else ifeq ($(RAYLIB_LIBTYPE),SHARED) - ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL)) ifeq ($(PLATFORM_OS),WINDOWS) # NOTE: Linking with provided resource file $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/$(RAYLIB_LIB_NAME).dll $(OBJS) $(RAYLIB_RES_FILE) $(LDFLAGS) $(LDLIBS) @@ -632,6 +658,9 @@ endif # Compile all modules with their prerequisites +# Prerequisites of core module +rcore.o : platforms/*.c + # Compile core module rcore.o : rcore.c raylib.h rlgl.h utils.h raymath.h rcamera.h rgestures.h $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) @@ -677,23 +706,10 @@ else @echo "#include \"$(RAYLIB_MODULE_RAYGUI_PATH)/raygui.h\"" >> raygui.c endif -# Compile physac module -# NOTE: physac header should be distributed with raylib.h -physac.o : physac.c - $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -physac.c: -ifeq ($(PLATFORM_SHELL), cmd) - @echo #define PHYSAC_IMPLEMENTATION > physac.c - @echo #include "$(RAYLIB_MODULE_PHYSAC_PATH)/physac.h" >> physac.c -else - @echo "#define PHYSAC_IMPLEMENTATION" > physac.c - @echo "#include \"$(RAYLIB_MODULE_PHYSAC_PATH)/physac.h\"" >> physac.c -endif # Compile android_native_app_glue module android_native_app_glue.o : $(NATIVE_APP_GLUE)/android_native_app_glue.c $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) - # Install generated and needed files to desired directories. # On GNU/Linux and BSDs, there are some standard directories that contain extra # libraries and header files. These directories (often /usr/local/lib and @@ -777,7 +793,7 @@ clean: clean_shell_$(PLATFORM_SHELL) @echo "removed all generated files!" clean_shell_sh: - rm -fv *.o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so* raygui.c physac.c + rm -fv *.o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so* raygui.c ifeq ($(PLATFORM),PLATFORM_ANDROID) rm -fv $(NATIVE_APP_GLUE)/android_native_app_glue.o endif @@ -791,4 +807,3 @@ clean_shell_cmd: del lib$(RAYLIB_LIB_NAME)dll.a /s & \ del $(RAYLIB_LIB_NAME).dll /s & \ del raygui.c /s & \ - del physac.c /s diff --git a/raylib/src/build.zig b/raylib/src/build.zig index 5d7ddbf..12d4a7a 100644 --- a/raylib/src/build.zig +++ b/raylib/src/build.zig @@ -1,6 +1,7 @@ const std = @import("std"); +const builtin = @import("builtin"); -// This has been tested to work with zig 0.11.0 (67709b6, Aug 4 2023) +// This has been tested to work with zig 0.11.0 and zig 0.12.0-dev.1390+94cee4fb2 pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.builtin.OptimizeMode, options: Options) *std.Build.CompileStep { const raylib_flags = &[_][]const u8{ "-std=gnu99", @@ -20,35 +21,35 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built raylib.addIncludePath(.{ .path = srcdir ++ "/external/glfw/include" }); } - raylib.addCSourceFiles(&.{ + addCSourceFilesVersioned(raylib, &.{ srcdir ++ "/rcore.c", srcdir ++ "/utils.c", }, raylib_flags); if (options.raudio) { - raylib.addCSourceFiles(&.{ + addCSourceFilesVersioned(raylib, &.{ srcdir ++ "/raudio.c", }, raylib_flags); } if (options.rmodels) { - raylib.addCSourceFiles(&.{ + addCSourceFilesVersioned(raylib, &.{ srcdir ++ "/rmodels.c", }, &[_][]const u8{ "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 } ++ raylib_flags); } if (options.rshapes) { - raylib.addCSourceFiles(&.{ + addCSourceFilesVersioned(raylib, &.{ srcdir ++ "/rshapes.c", }, raylib_flags); } if (options.rtext) { - raylib.addCSourceFiles(&.{ + addCSourceFilesVersioned(raylib, &.{ srcdir ++ "/rtext.c", }, raylib_flags); } if (options.rtextures) { - raylib.addCSourceFiles(&.{ + addCSourceFilesVersioned(raylib, &.{ srcdir ++ "/rtextures.c", }, raylib_flags); } @@ -65,7 +66,9 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built switch (target.getOsTag()) { .windows => { - raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags); + addCSourceFilesVersioned(raylib, &.{ + srcdir ++ "/rglfw.c", + }, raylib_flags); raylib.linkSystemLibrary("winmm"); raylib.linkSystemLibrary("gdi32"); raylib.linkSystemLibrary("opengl32"); @@ -75,7 +78,9 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built }, .linux => { if (!options.platform_drm) { - raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags); + addCSourceFilesVersioned(raylib, &.{ + srcdir ++ "/rglfw.c", + }, raylib_flags); raylib.linkSystemLibrary("GL"); raylib.linkSystemLibrary("rt"); raylib.linkSystemLibrary("dl"); @@ -103,7 +108,9 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built } }, .freebsd, .openbsd, .netbsd, .dragonfly => { - raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags); + addCSourceFilesVersioned(raylib, &.{ + srcdir ++ "/rglfw.c", + }, raylib_flags); raylib.linkSystemLibrary("GL"); raylib.linkSystemLibrary("rt"); raylib.linkSystemLibrary("dl"); @@ -122,10 +129,9 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built const raylib_flags_extra_macos = &[_][]const u8{ "-ObjC", }; - raylib.addCSourceFiles( - &.{srcdir ++ "/rglfw.c"}, - raylib_flags ++ raylib_flags_extra_macos, - ); + addCSourceFilesVersioned(raylib, &.{ + srcdir ++ "/rglfw.c", + }, raylib_flags ++ raylib_flags_extra_macos); raylib.linkFramework("Foundation"); raylib.linkFramework("CoreServices"); raylib.linkFramework("CoreGraphics"); @@ -208,3 +214,14 @@ const srcdir = struct { return std.fs.path.dirname(@src().file).?; } }.getSrcDir(); + +fn addCSourceFilesVersioned(exe: *std.Build.Step.Compile, files: []const []const u8, flags: []const []const u8) void { + if (comptime builtin.zig_version.minor >= 12) { + exe.addCSourceFiles(.{ + .files = files, + .flags = flags, + }); + } else { + exe.addCSourceFiles(files, flags); + } +} diff --git a/raylib/src/config.h b/raylib/src/config.h index 7289e00..9b405a3 100644 --- a/raylib/src/config.h +++ b/raylib/src/config.h @@ -45,6 +45,8 @@ #define SUPPORT_CAMERA_SYSTEM 1 // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag #define SUPPORT_GESTURES_SYSTEM 1 +// Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64 +//#define SUPPORT_RPRAND_GENERATOR 1 // Mouse gestures are directly mapped like touches and processed by gestures system #define SUPPORT_MOUSE_GESTURES 1 // Reconfigure standard input to receive key inputs, works with SSH connection. @@ -63,7 +65,7 @@ // Support CompressData() and DecompressData() functions #define SUPPORT_COMPRESSION_API 1 // Support automatic generated events, loading and recording of those events when required -//#define SUPPORT_EVENTS_AUTOMATION 1 +#define SUPPORT_AUTOMATION_EVENTS 1 // Support custom frame control, only for advance users // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // Enabling this flag allows manual control of the frame processes, use at your own risk @@ -85,6 +87,7 @@ #define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB +#define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record //------------------------------------------------------------------------------------ // Module: rlgl - Configuration values @@ -135,6 +138,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 @@ -173,7 +180,7 @@ #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_TTF 1 // Support text management functions // If not defined, still some functions are supported: TextLength(), TextFormat() diff --git a/raylib/src/external/cgltf.h b/raylib/src/external/cgltf.h index d2a9097..ddec501 100644 --- a/raylib/src/external/cgltf.h +++ b/raylib/src/external/cgltf.h @@ -328,15 +328,6 @@ typedef struct cgltf_accessor_sparse cgltf_component_type indices_component_type; cgltf_buffer_view* values_buffer_view; cgltf_size values_byte_offset; - cgltf_extras extras; - cgltf_extras indices_extras; - cgltf_extras values_extras; - cgltf_size extensions_count; - cgltf_extension* extensions; - cgltf_size indices_extensions_count; - cgltf_extension* indices_extensions; - cgltf_size values_extensions_count; - cgltf_extension* values_extensions; } cgltf_accessor_sparse; typedef struct cgltf_accessor @@ -419,9 +410,6 @@ typedef struct cgltf_texture_view cgltf_float scale; /* equivalent to strength for occlusion_texture */ cgltf_bool has_transform; cgltf_texture_transform transform; - cgltf_extras extras; - cgltf_size extensions_count; - cgltf_extension* extensions; } cgltf_texture_view; typedef struct cgltf_pbr_metallic_roughness @@ -504,6 +492,13 @@ typedef struct cgltf_iridescence cgltf_texture_view iridescence_thickness_texture; } cgltf_iridescence; +typedef struct cgltf_anisotropy +{ + cgltf_float anisotropy_strength; + cgltf_float anisotropy_rotation; + cgltf_texture_view anisotropy_texture; +} cgltf_anisotropy; + typedef struct cgltf_material { char* name; @@ -517,6 +512,7 @@ typedef struct cgltf_material cgltf_bool has_sheen; cgltf_bool has_emissive_strength; cgltf_bool has_iridescence; + cgltf_bool has_anisotropy; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; cgltf_clearcoat clearcoat; @@ -527,6 +523,7 @@ typedef struct cgltf_material cgltf_volume volume; cgltf_emissive_strength emissive_strength; cgltf_iridescence iridescence; + cgltf_anisotropy anisotropy; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture; @@ -559,7 +556,6 @@ typedef struct cgltf_draco_mesh_compression { } cgltf_draco_mesh_compression; typedef struct cgltf_mesh_gpu_instancing { - cgltf_buffer_view* buffer_view; cgltf_attribute* attributes; cgltf_size attributes_count; } cgltf_mesh_gpu_instancing; @@ -842,10 +838,28 @@ 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); /* 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); +cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object); +cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object); +cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object); +cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object); +cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object); +cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object); +cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object); +cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object); +cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object); +cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object); +cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object); +cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object); +cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object); +cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object); +cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object); +cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object); + #ifdef __cplusplus } #endif @@ -866,6 +880,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* #ifdef CGLTF_IMPLEMENTATION +#include <assert.h> /* For assert */ #include <string.h> /* For strncpy */ #include <stdio.h> /* For fopen */ #include <limits.h> /* For UINT_MAX etc */ @@ -875,10 +890,6 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* #include <stdlib.h> /* For malloc, free, atoi, atof */ #endif -#if CGLTF_VALIDATE_ENABLE_ASSERTS -#include <assert.h> -#endif - /* JSMN_PARENT_LINKS is necessary to make parsing large structures linear in input size */ #define JSMN_PARENT_LINKS @@ -1000,7 +1011,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m { fseek(file, 0, SEEK_END); -#ifdef _WIN32 +#ifdef _MSC_VER __int64 length = _ftelli64(file); #else long length = ftell(file); @@ -1144,7 +1155,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s json_chunk += GlbChunkHeaderSize; - const void* bin = 0; + const void* bin = NULL; cgltf_size bin_size = 0; if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size) @@ -1763,12 +1774,6 @@ static void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, data->memory.free_func(data->memory.user_data, extensions); } -static void cgltf_free_texture_view(cgltf_data* data, cgltf_texture_view* view) -{ - cgltf_free_extensions(data, view->extensions, view->extensions_count); - cgltf_free_extras(data, &view->extras); -} - void cgltf_free(cgltf_data* data) { if (!data) @@ -1790,15 +1795,6 @@ void cgltf_free(cgltf_data* data) { data->memory.free_func(data->memory.user_data, data->accessors[i].name); - if(data->accessors[i].is_sparse) - { - cgltf_free_extensions(data, data->accessors[i].sparse.extensions, data->accessors[i].sparse.extensions_count); - cgltf_free_extensions(data, data->accessors[i].sparse.indices_extensions, data->accessors[i].sparse.indices_extensions_count); - cgltf_free_extensions(data, data->accessors[i].sparse.values_extensions, data->accessors[i].sparse.values_extensions_count); - cgltf_free_extras(data, &data->accessors[i].sparse.extras); - cgltf_free_extras(data, &data->accessors[i].sparse.indices_extras); - cgltf_free_extras(data, &data->accessors[i].sparse.values_extras); - } cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count); cgltf_free_extras(data, &data->accessors[i].extras); } @@ -1900,50 +1896,6 @@ void cgltf_free(cgltf_data* data) { data->memory.free_func(data->memory.user_data, data->materials[i].name); - if(data->materials[i].has_pbr_metallic_roughness) - { - cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.metallic_roughness_texture); - cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.base_color_texture); - } - if(data->materials[i].has_pbr_specular_glossiness) - { - cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.diffuse_texture); - cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.specular_glossiness_texture); - } - if(data->materials[i].has_clearcoat) - { - cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_texture); - cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_roughness_texture); - cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_normal_texture); - } - if(data->materials[i].has_specular) - { - cgltf_free_texture_view(data, &data->materials[i].specular.specular_texture); - cgltf_free_texture_view(data, &data->materials[i].specular.specular_color_texture); - } - if(data->materials[i].has_transmission) - { - cgltf_free_texture_view(data, &data->materials[i].transmission.transmission_texture); - } - if (data->materials[i].has_volume) - { - cgltf_free_texture_view(data, &data->materials[i].volume.thickness_texture); - } - if(data->materials[i].has_sheen) - { - cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_color_texture); - cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_roughness_texture); - } - if(data->materials[i].has_iridescence) - { - cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_texture); - cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_thickness_texture); - } - - cgltf_free_texture_view(data, &data->materials[i].normal_texture); - cgltf_free_texture_view(data, &data->materials[i].occlusion_texture); - cgltf_free_texture_view(data, &data->materials[i].emissive_texture); - cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count); cgltf_free_extras(data, &data->materials[i].extras); } @@ -2198,8 +2150,6 @@ static cgltf_ssize cgltf_component_read_integer(const void* in, cgltf_component_ return *((const uint16_t*) in); case cgltf_component_type_r_32u: return *((const uint32_t*) in); - case cgltf_component_type_r_32f: - return (cgltf_ssize)*((const float*) in); case cgltf_component_type_r_8: return *((const int8_t*) in); case cgltf_component_type_r_8u: @@ -2217,8 +2167,6 @@ static cgltf_size cgltf_component_read_index(const void* in, cgltf_component_typ return *((const uint16_t*) in); case cgltf_component_type_r_32u: return *((const uint32_t*) in); - case cgltf_component_type_r_32f: - return (cgltf_size)((cgltf_ssize)*((const float*) in)); case cgltf_component_type_r_8u: return *((const uint8_t*) in); default: @@ -2356,21 +2304,41 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl cgltf_size element_count = float_count / floats_per_element; // First pass: convert each element in the base accessor. - cgltf_float* dest = out; - cgltf_accessor dense = *accessor; - dense.is_sparse = 0; - for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element) + if (accessor->buffer_view == NULL) + { + memset(out, 0, element_count * floats_per_element * sizeof(cgltf_float)); + } + else { - if (!cgltf_accessor_read_float(&dense, index, dest, floats_per_element)) + const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); + if (element == NULL) { return 0; } + element += accessor->offset; + + if (accessor->component_type == cgltf_component_type_r_32f && accessor->stride == floats_per_element * sizeof(cgltf_float)) + { + memcpy(out, element, element_count * floats_per_element * sizeof(cgltf_float)); + } + else + { + cgltf_float* dest = out; + + for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element, element += accessor->stride) + { + if (!cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, dest, floats_per_element)) + { + return 0; + } + } + } } // Second pass: write out each element in the sparse accessor. if (accessor->is_sparse) { - const cgltf_accessor_sparse* sparse = &dense.sparse; + const cgltf_accessor_sparse* sparse = &accessor->sparse; const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view); const uint8_t* reader_head = cgltf_buffer_view_data(sparse->values_buffer_view); @@ -2384,17 +2352,15 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl reader_head += sparse->values_byte_offset; cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type); - for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride) + for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride, reader_head += accessor->stride) { size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type); float* writer_head = out + writer_index * floats_per_element; - if (!cgltf_element_read_float(reader_head, dense.type, dense.component_type, dense.normalized, writer_head, floats_per_element)) + if (!cgltf_element_read_float(reader_head, accessor->type, accessor->component_type, accessor->normalized, writer_head, floats_per_element)) { return 0; } - - reader_head += dense.stride; } } @@ -2488,6 +2454,143 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size return cgltf_component_read_index(element, accessor->component_type); } +cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object) +{ + assert(object && (cgltf_size)(object - data->meshes) < data->meshes_count); + return (cgltf_size)(object - data->meshes); +} + +cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object) +{ + assert(object && (cgltf_size)(object - data->materials) < data->materials_count); + return (cgltf_size)(object - data->materials); +} + +cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object) +{ + assert(object && (cgltf_size)(object - data->accessors) < data->accessors_count); + return (cgltf_size)(object - data->accessors); +} + +cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object) +{ + assert(object && (cgltf_size)(object - data->buffer_views) < data->buffer_views_count); + return (cgltf_size)(object - data->buffer_views); +} + +cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object) +{ + assert(object && (cgltf_size)(object - data->buffers) < data->buffers_count); + return (cgltf_size)(object - data->buffers); +} + +cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object) +{ + assert(object && (cgltf_size)(object - data->images) < data->images_count); + return (cgltf_size)(object - data->images); +} + +cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object) +{ + assert(object && (cgltf_size)(object - data->textures) < data->textures_count); + return (cgltf_size)(object - data->textures); +} + +cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object) +{ + assert(object && (cgltf_size)(object - data->samplers) < data->samplers_count); + return (cgltf_size)(object - data->samplers); +} + +cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object) +{ + assert(object && (cgltf_size)(object - data->skins) < data->skins_count); + return (cgltf_size)(object - data->skins); +} + +cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object) +{ + assert(object && (cgltf_size)(object - data->cameras) < data->cameras_count); + return (cgltf_size)(object - data->cameras); +} + +cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object) +{ + assert(object && (cgltf_size)(object - data->lights) < data->lights_count); + return (cgltf_size)(object - data->lights); +} + +cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object) +{ + assert(object && (cgltf_size)(object - data->nodes) < data->nodes_count); + return (cgltf_size)(object - data->nodes); +} + +cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object) +{ + assert(object && (cgltf_size)(object - data->scenes) < data->scenes_count); + return (cgltf_size)(object - data->scenes); +} + +cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object) +{ + assert(object && (cgltf_size)(object - data->animations) < data->animations_count); + return (cgltf_size)(object - data->animations); +} + +cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object) +{ + assert(object && (cgltf_size)(object - animation->samplers) < animation->samplers_count); + return (cgltf_size)(object - animation->samplers); +} + +cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object) +{ + assert(object && (cgltf_size)(object - animation->channels) < animation->channels_count); + return (cgltf_size)(object - animation->channels); +} + +cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count) +{ + if (out == NULL) + { + return accessor->count; + } + + index_count = accessor->count < index_count ? accessor->count : index_count; + + if (accessor->is_sparse) + { + return 0; + } + if (accessor->buffer_view == NULL) + { + return 0; + } + const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); + if (element == NULL) + { + return 0; + } + element += accessor->offset; + + if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint)) + { + memcpy(out, element, index_count * sizeof(cgltf_uint)); + } + else + { + cgltf_uint* dest = out; + + for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride) + { + *dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type); + } + } + + return index_count; +} + #define CGLTF_ERROR_JSON -1 #define CGLTF_ERROR_NOMEM -2 #define CGLTF_ERROR_LEGACY -3 @@ -2864,6 +2967,10 @@ static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmnt out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk)); ++i; } + else + { + i = cgltf_skip_json(tokens, i+1); + } if (i < 0) { @@ -2889,11 +2996,9 @@ static int cgltf_parse_json_mesh_gpu_instancing(cgltf_options* options, jsmntok_ { i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->attributes, &out_mesh_gpu_instancing->attributes_count); } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0) + else { - ++i; - out_mesh_gpu_instancing->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk)); - ++i; + i = cgltf_skip_json(tokens, i+1); } if (i < 0) @@ -3291,7 +3396,7 @@ static cgltf_component_type cgltf_json_to_component_type(jsmntok_t const* tok, c } } -static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse) +static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -3338,14 +3443,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) - { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->indices_extras); - } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) - { - i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->indices_extensions_count, &out_sparse->indices_extensions); - } else { i = cgltf_skip_json(tokens, i+1); @@ -3381,14 +3478,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) - { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->values_extras); - } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) - { - i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->values_extensions_count, &out_sparse->values_extensions); - } else { i = cgltf_skip_json(tokens, i+1); @@ -3400,14 +3489,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co } } } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) - { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->extras); - } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) - { - i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->extensions_count, &out_sparse->extensions); - } else { i = cgltf_skip_json(tokens, i+1); @@ -3521,7 +3602,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to else if (cgltf_json_strcmp(tokens + i, json_chunk, "sparse") == 0) { out_accessor->is_sparse = 1; - i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->sparse); + i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->sparse); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { @@ -3593,6 +3674,8 @@ static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, co static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view) { + (void)options; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); out_texture_view->scale = 1.0f; @@ -3629,28 +3712,12 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) - { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture_view->extras); - } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - if(out_texture_view->extensions) - { - return CGLTF_ERROR_JSON; - } - int extensions_size = tokens[i].size; - out_texture_view->extensions_count = 0; - out_texture_view->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); - - if (!out_texture_view->extensions) - { - return CGLTF_ERROR_NOMEM; - } ++i; @@ -3665,7 +3732,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const } else { - i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->extensions[out_texture_view->extensions_count++])); + i = cgltf_skip_json(tokens, i + 1); } if (i < 0) @@ -3719,13 +3786,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt } else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorTexture") == 0) { - i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, - &out_pbr->base_color_texture); + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->base_color_texture); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "metallicRoughnessTexture") == 0) { - i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, - &out_pbr->metallic_roughness_texture); + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->metallic_roughness_texture); } else { @@ -4128,6 +4193,47 @@ static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const* return i; } +static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_anisotropy* out_anisotropy) +{ + 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, "anisotropyStrength") == 0) + { + ++i; + out_anisotropy->anisotropy_strength = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyRotation") == 0) + { + ++i; + out_anisotropy->anisotropy_rotation = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_anisotropy->anisotropy_texture); + } + 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); @@ -4516,6 +4622,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_iridescence = 1; i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_anisotropy") == 0) + { + out_material->has_anisotropy = 1; + i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); @@ -6367,6 +6478,8 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count); CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count); + + CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count); } for (cgltf_size i = 0; i < data->buffer_views_count; ++i) @@ -6411,7 +6524,6 @@ static int cgltf_fixup_pointers(cgltf_data* data) if (data->nodes[i].has_mesh_gpu_instancing) { - CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.buffer_view, data->buffer_views, data->buffer_views_count); for (cgltf_size m = 0; m < data->nodes[i].mesh_gpu_instancing.attributes_count; ++m) { CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.attributes[m].data, data->accessors, data->accessors_count); diff --git a/raylib/src/external/dr_flac.h b/raylib/src/external/dr_flac.h index 0c43eed..14324cf 100644 --- a/raylib/src/external/dr_flac.h +++ b/raylib/src/external/dr_flac.h @@ -1,6 +1,6 @@ /* FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_flac - v0.12.39 - 2022-09-17 +dr_flac - v0.12.42 - 2023-11-02 David Reid - mackron@gmail.com @@ -235,12 +235,12 @@ extern "C" { #define DRFLAC_VERSION_MAJOR 0 #define DRFLAC_VERSION_MINOR 12 -#define DRFLAC_VERSION_REVISION 39 +#define DRFLAC_VERSION_REVISION 42 #define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION) #include <stddef.h> /* For size_t. */ -/* Sized types. */ +/* Sized Types */ typedef signed char drflac_int8; typedef unsigned char drflac_uint8; typedef signed short drflac_int16; @@ -273,7 +273,9 @@ typedef drflac_uint8 drflac_bool8; typedef drflac_uint32 drflac_bool32; #define DRFLAC_TRUE 1 #define DRFLAC_FALSE 0 +/* End Sized Types */ +/* Decorations */ #if !defined(DRFLAC_API) #if defined(DRFLAC_DLL) #if defined(_WIN32) @@ -303,6 +305,7 @@ typedef drflac_uint32 drflac_bool32; #define DRFLAC_PRIVATE static #endif #endif +/* End Decorations */ #if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */ #define DRFLAC_DEPRECATED __declspec(deprecated) @@ -321,6 +324,16 @@ typedef drflac_uint32 drflac_bool32; DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision); DRFLAC_API const char* drflac_version_string(void); +/* Allocation Callbacks */ +typedef struct +{ + void* pUserData; + void* (* onMalloc)(size_t sz, void* pUserData); + void* (* onRealloc)(void* p, size_t sz, void* pUserData); + void (* onFree)(void* p, void* pUserData); +} drflac_allocation_callbacks; +/* End Allocation Callbacks */ + /* As data is read from the client it is placed into an internal buffer for fast access. This controls the size of that buffer. Larger values means more speed, but also more memory. In my testing there is diminishing returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8. @@ -329,11 +342,22 @@ but also more memory. In my testing there is diminishing returns after about 4KB #define DR_FLAC_BUFFER_SIZE 4096 #endif -/* Check if we can enable 64-bit optimizations. */ + +/* Architecture Detection */ #if defined(_WIN64) || defined(_LP64) || defined(__LP64__) #define DRFLAC_64BIT #endif +#if defined(__x86_64__) || defined(_M_X64) + #define DRFLAC_X64 +#elif defined(__i386) || defined(_M_IX86) + #define DRFLAC_X86 +#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) + #define DRFLAC_ARM +#endif +/* End Architecture Detection */ + + #ifdef DRFLAC_64BIT typedef drflac_uint64 drflac_cache_t; #else @@ -562,14 +586,6 @@ will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens. typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata); -typedef struct -{ - void* pUserData; - void* (* onMalloc)(size_t sz, void* pUserData); - void* (* onRealloc)(void* p, size_t sz, void* pUserData); - void (* onFree)(void* p, void* pUserData); -} drflac_allocation_callbacks; - /* Structure for internal use. Only used for decoders opened with drflac_open_memory. */ typedef struct { @@ -1351,6 +1367,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat #include <stdlib.h> #include <string.h> +/* Inline */ #ifdef _MSC_VER #define DRFLAC_INLINE __forceinline #elif defined(__GNUC__) @@ -1377,15 +1394,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat #else #define DRFLAC_INLINE #endif - -/* CPU architecture. */ -#if defined(__x86_64__) || defined(_M_X64) - #define DRFLAC_X64 -#elif defined(__i386) || defined(_M_IX86) - #define DRFLAC_X86 -#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) - #define DRFLAC_ARM -#endif +/* End Inline */ /* Intrinsics Support @@ -1623,6 +1632,7 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void) #define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */ +/* Result Codes */ typedef drflac_int32 drflac_result; #define DRFLAC_SUCCESS 0 #define DRFLAC_ERROR -1 /* A generic error. */ @@ -1678,7 +1688,10 @@ typedef drflac_int32 drflac_result; #define DRFLAC_CANCELLED -51 #define DRFLAC_MEMORY_ALREADY_MAPPED -52 #define DRFLAC_AT_END -53 -#define DRFLAC_CRC_MISMATCH -128 + +#define DRFLAC_CRC_MISMATCH -100 +/* End Result Codes */ + #define DRFLAC_SUBFRAME_CONSTANT 0 #define DRFLAC_SUBFRAME_VERBATIM 1 @@ -1838,7 +1851,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n) #if defined(_MSC_VER) && !defined(__clang__) return _byteswap_ulong(n); #elif defined(__GNUC__) || defined(__clang__) - #if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */ + #if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */ /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */ drflac_uint32 r; __asm__ __volatile__ ( @@ -2802,7 +2815,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x) return r; } - #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */ + #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */ { unsigned int r; __asm__ __volatile__ ( @@ -6479,7 +6492,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d for (;;) { drflac_metadata metadata; drflac_uint8 isLastBlock = 0; - drflac_uint8 blockType; + drflac_uint8 blockType = 0; drflac_uint32 blockSize; if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) { return DRFLAC_FALSE; @@ -8141,6 +8154,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac #include <wchar.h> /* For wcslen(), wcsrtombs() */ #endif +/* Errno */ /* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */ #include <errno.h> static drflac_result drflac_result_from_errno(int e) @@ -8544,7 +8558,9 @@ static drflac_result drflac_result_from_errno(int e) default: return DRFLAC_ERROR; } } +/* End Errno */ +/* fopen */ static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) { #if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -8702,6 +8718,7 @@ static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons return DRFLAC_SUCCESS; } #endif +/* End fopen */ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead) { @@ -11666,6 +11683,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p /* High Level APIs */ +/* SIZE_MAX */ #if defined(SIZE_MAX) #define DRFLAC_SIZE_MAX SIZE_MAX #else @@ -11675,6 +11693,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p #define DRFLAC_SIZE_MAX 0xFFFFFFFF #endif #endif +/* End SIZE_MAX */ /* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */ @@ -12058,6 +12077,16 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat /* REVISION HISTORY ================ +v0.12.42 - 2023-11-02 + - Fix build for ARMv6-M. + - Fix a compilation warning with GCC. + +v0.12.41 - 2023-06-17 + - Fix an incorrect date in revision history. No functional change. + +v0.12.40 - 2023-05-22 + - Minor code restructure. No functional change. + v0.12.39 - 2022-09-17 - Fix compilation with DJGPP. - Fix compilation error with Visual Studio 2019 and the ARM build. @@ -12488,7 +12517,7 @@ For more information, please refer to <http://unlicense.org/> =============================================================================== ALTERNATIVE 2 - MIT No Attribution =============================================================================== -Copyright 2020 David Reid +Copyright 2023 David Reid 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 diff --git a/raylib/src/external/dr_mp3.h b/raylib/src/external/dr_mp3.h index 59876c8..84849ee 100644 --- a/raylib/src/external/dr_mp3.h +++ b/raylib/src/external/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.34 - 2022-09-17 +dr_mp3 - v0.6.38 - 2023-11-02 David Reid - mackron@gmail.com @@ -95,12 +95,12 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 34 +#define DRMP3_VERSION_REVISION 38 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include <stddef.h> /* For size_t. */ -/* Sized types. */ +/* Sized Types */ typedef signed char drmp3_int8; typedef unsigned char drmp3_uint8; typedef signed short drmp3_int16; @@ -133,7 +133,9 @@ typedef drmp3_uint8 drmp3_bool8; typedef drmp3_uint32 drmp3_bool32; #define DRMP3_TRUE 1 #define DRMP3_FALSE 0 +/* End Sized Types */ +/* Decorations */ #if !defined(DRMP3_API) #if defined(DRMP3_DLL) #if defined(_WIN32) @@ -163,7 +165,9 @@ typedef drmp3_uint32 drmp3_bool32; #define DRMP3_PRIVATE static #endif #endif +/* End Decorations */ +/* Result Codes */ typedef drmp3_int32 drmp3_result; #define DRMP3_SUCCESS 0 #define DRMP3_ERROR -1 /* A generic error. */ @@ -219,11 +223,12 @@ typedef drmp3_int32 drmp3_result; #define DRMP3_CANCELLED -51 #define DRMP3_MEMORY_ALREADY_MAPPED -52 #define DRMP3_AT_END -53 - +/* End Result Codes */ #define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 #define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2) +/* Inline */ #ifdef _MSC_VER #define DRMP3_INLINE __forceinline #elif defined(__GNUC__) @@ -250,12 +255,24 @@ typedef drmp3_int32 drmp3_result; #else #define DRMP3_INLINE #endif +/* End Inline */ DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision); DRMP3_API const char* drmp3_version_string(void); +/* Allocation Callbacks */ +typedef struct +{ + void* pUserData; + void* (* onMalloc)(size_t sz, void* pUserData); + void* (* onRealloc)(void* p, size_t sz, void* pUserData); + void (* onFree)(void* p, void* pUserData); +} drmp3_allocation_callbacks; +/* End Allocation Callbacks */ + + /* Low Level Push API ================== @@ -331,14 +348,6 @@ typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek typedef struct { - void* pUserData; - void* (* onMalloc)(size_t sz, void* pUserData); - void* (* onRealloc)(void* p, size_t sz, void* pUserData); - void (* onFree)(void* p, void* pUserData); -} drmp3_allocation_callbacks; - -typedef struct -{ drmp3_uint32 channels; drmp3_uint32 sampleRate; } drmp3_config; @@ -704,7 +713,7 @@ static int drmp3_have_simd(void) #endif -#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) +#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__) #define DRMP3_HAVE_ARMV6 1 static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a) { @@ -2415,6 +2424,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num Main Public API ************************************************************************************************************************************************************/ +/* SIZE_MAX */ #if defined(SIZE_MAX) #define DRMP3_SIZE_MAX SIZE_MAX #else @@ -2424,6 +2434,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num #define DRMP3_SIZE_MAX 0xFFFFFFFF #endif #endif +/* End SIZE_MAX */ /* Options. */ #ifndef DRMP3_SEEK_LEADING_MP3_FRAMES @@ -2690,6 +2701,11 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa DRMP3_ASSERT(pMP3->pData != NULL); DRMP3_ASSERT(pMP3->dataCapacity > 0); + /* Do a runtime check here to try silencing a false-positive from clang-analyzer. */ + if (pMP3->pData == NULL) { + return 0; + } + pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */ /* Consume the data. */ @@ -2931,6 +2947,7 @@ DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t #include <stdio.h> #include <wchar.h> /* For wcslen(), wcsrtombs() */ +/* Errno */ /* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */ #include <errno.h> static drmp3_result drmp3_result_from_errno(int e) @@ -3334,7 +3351,9 @@ static drmp3_result drmp3_result_from_errno(int e) default: return DRMP3_ERROR; } } +/* End Errno */ +/* fopen */ static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) { #if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -3490,7 +3509,7 @@ static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const return DRMP3_SUCCESS; } - +/* End fopen */ static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) @@ -4476,6 +4495,18 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.38 - 2023-11-02 + - Fix build for ARMv6-M. + +v0.6.37 - 2023-07-07 + - Silence a static analysis warning. + +v0.6.36 - 2023-06-17 + - Fix an incorrect date in revision history. No functional change. + +v0.6.35 - 2023-05-22 + - Minor code restructure. No functional change. + v0.6.34 - 2022-09-17 - Fix compilation with DJGPP. - Fix compilation when compiling with x86 with no SSE2. @@ -4777,7 +4808,7 @@ For more information, please refer to <http://unlicense.org/> =============================================================================== ALTERNATIVE 2 - MIT No Attribution =============================================================================== -Copyright 2020 David Reid +Copyright 2023 David Reid 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 diff --git a/raylib/src/external/dr_wav.h b/raylib/src/external/dr_wav.h index 2f885a0..36451b5 100644 --- a/raylib/src/external/dr_wav.h +++ b/raylib/src/external/dr_wav.h @@ -1,6 +1,6 @@ /* WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_wav - v0.13.7 - 2022-09-17 +dr_wav - v0.13.13 - 2023-11-02 David Reid - mackron@gmail.com @@ -79,7 +79,9 @@ dr_wav can also be used to output WAV files. This does not currently support com drwav_uint64 framesWritten = drwav_write_pcm_frames(pWav, frameCount, pSamples); ``` -dr_wav has seamless support the Sony Wave64 format. The decoder will automatically detect it and it should Just Work without any manual intervention. +Note that writing to AIFF or RIFX is not supported. + +dr_wav has support for decoding from a number of different encapsulation formats. See below for details. Build Options @@ -96,23 +98,40 @@ Build Options Disables all functions ending with `_w`. Use this if your compiler does not provide wchar.h. Not required if DR_WAV_NO_STDIO is also defined. +Supported Encapsulations +======================== +- RIFF (Regular WAV) +- RIFX (Big-Endian) +- AIFF (Does not currently support ADPCM) +- RF64 +- W64 + +Note that AIFF and RIFX do not support write mode, nor do they support reading of metadata. + + +Supported Encodings +=================== +- Unsigned 8-bit PCM +- Signed 12-bit PCM +- Signed 16-bit PCM +- Signed 24-bit PCM +- Signed 32-bit PCM +- IEEE 32-bit floating point +- IEEE 64-bit floating point +- A-law and u-law +- Microsoft ADPCM +- IMA ADPCM (DVI, format code 0x11) + +8-bit PCM encodings are always assumed to be unsigned. Signed 8-bit encoding can only be read with `drwav_read_raw()`. + +Note that ADPCM is not currently supported with AIFF. Contributions welcome. + Notes ===== - Samples are always interleaved. - The default read function does not do any data conversion. Use `drwav_read_pcm_frames_f32()`, `drwav_read_pcm_frames_s32()` and `drwav_read_pcm_frames_s16()` - to read and convert audio data to 32-bit floating point, signed 32-bit integer and signed 16-bit integer samples respectively. Tested and supported internal - formats include the following: - - Unsigned 8-bit PCM - - Signed 12-bit PCM - - Signed 16-bit PCM - - Signed 24-bit PCM - - Signed 32-bit PCM - - IEEE 32-bit floating point - - IEEE 64-bit floating point - - A-law and u-law - - Microsoft ADPCM - - IMA ADPCM (DVI, format code 0x11) + to read and convert audio data to 32-bit floating point, signed 32-bit integer and signed 16-bit integer samples respectively. - dr_wav will try to read the WAV file as best it can, even if it's not strictly conformant to the WAV format. */ @@ -128,12 +147,12 @@ extern "C" { #define DRWAV_VERSION_MAJOR 0 #define DRWAV_VERSION_MINOR 13 -#define DRWAV_VERSION_REVISION 7 +#define DRWAV_VERSION_REVISION 13 #define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION) #include <stddef.h> /* For size_t. */ -/* Sized types. */ +/* Sized Types */ typedef signed char drwav_int8; typedef unsigned char drwav_uint8; typedef signed short drwav_int16; @@ -166,7 +185,9 @@ typedef drwav_uint8 drwav_bool8; typedef drwav_uint32 drwav_bool32; #define DRWAV_TRUE 1 #define DRWAV_FALSE 0 +/* End Sized Types */ +/* Decorations */ #if !defined(DRWAV_API) #if defined(DRWAV_DLL) #if defined(_WIN32) @@ -196,7 +217,9 @@ typedef drwav_uint32 drwav_bool32; #define DRWAV_PRIVATE static #endif #endif +/* End Decorations */ +/* Result Codes */ typedef drwav_int32 drwav_result; #define DRWAV_SUCCESS 0 #define DRWAV_ERROR -1 /* A generic error. */ @@ -252,6 +275,7 @@ typedef drwav_int32 drwav_result; #define DRWAV_CANCELLED -51 #define DRWAV_MEMORY_ALREADY_MAPPED -52 #define DRWAV_AT_END -53 +/* End Result Codes */ /* Common data formats. */ #define DR_WAVE_FORMAT_PCM 0x1 @@ -264,10 +288,21 @@ typedef drwav_int32 drwav_result; /* Flags to pass into drwav_init_ex(), etc. */ #define DRWAV_SEQUENTIAL 0x00000001 +#define DRWAV_WITH_METADATA 0x00000002 DRWAV_API void drwav_version(drwav_uint32* pMajor, drwav_uint32* pMinor, drwav_uint32* pRevision); DRWAV_API const char* drwav_version_string(void); +/* Allocation Callbacks */ +typedef struct +{ + void* pUserData; + void* (* onMalloc)(size_t sz, void* pUserData); + void* (* onRealloc)(void* p, size_t sz, void* pUserData); + void (* onFree)(void* p, void* pUserData); +} drwav_allocation_callbacks; +/* End Allocation Callbacks */ + typedef enum { drwav_seek_origin_start, @@ -277,8 +312,10 @@ typedef enum typedef enum { drwav_container_riff, + drwav_container_rifx, drwav_container_w64, - drwav_container_rf64 + drwav_container_rf64, + drwav_container_aiff } drwav_container; typedef struct @@ -409,13 +446,6 @@ The read pointer will be sitting on the first byte after the chunk's header. You */ typedef drwav_uint64 (* drwav_chunk_proc)(void* pChunkUserData, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_chunk_header* pChunkHeader, drwav_container container, const drwav_fmt* pFMT); -typedef struct -{ - void* pUserData; - void* (* onMalloc)(size_t sz, void* pUserData); - void* (* onRealloc)(void* p, size_t sz, void* pUserData); - void (* onFree)(void* p, void* pUserData); -} drwav_allocation_callbacks; /* Structure for internal use. Only used for loaders opened with drwav_init_memory(). */ typedef struct @@ -869,9 +899,6 @@ typedef struct drwav_bool32 isSequentialWrite; - /* A bit-field of drwav_metadata_type values, only bits set in this variable are parsed and saved */ - drwav_metadata_type allowedMetadataTypes; - /* A array of metadata. This is valid after the *init_with_metadata call returns. It will be valid until drwav_uninit() is called. You can take ownership of this data with drwav_take_ownership_of_metadata(). */ drwav_metadata* pMetadata; drwav_uint32 metadataCount; @@ -902,6 +929,13 @@ typedef struct drwav_int32 cachedFrames[16]; /* Samples are stored in this cache during decoding. */ drwav_uint32 cachedFrameCount; } ima; + + /* AIFF specific data. */ + struct + { + drwav_bool8 isLE; /* Will be set to true if the audio data is little-endian encoded. */ + drwav_bool8 isUnsigned; /* Only used for 8-bit samples. When set to true, will be treated as unsigned. */ + } aiff; } drwav; @@ -1347,9 +1381,9 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b); #define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x)))) #define drwav_offset_ptr(p, offset) (((drwav_uint8*)(p)) + (offset)) -#define DRWAV_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */ +#define DRWAV_MAX_SIMD_VECTOR_SIZE 32 -/* CPU architecture. */ +/* Architecture Detection */ #if defined(__x86_64__) || defined(_M_X64) #define DRWAV_X64 #elif defined(__i386) || defined(_M_IX86) @@ -1357,7 +1391,9 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b); #elif defined(__arm__) || defined(_M_ARM) #define DRWAV_ARM #endif +/* End Architecture Detection */ +/* Inline */ #ifdef _MSC_VER #define DRWAV_INLINE __forceinline #elif defined(__GNUC__) @@ -1384,7 +1420,9 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b); #else #define DRWAV_INLINE #endif +/* End Inline */ +/* SIZE_MAX */ #if defined(SIZE_MAX) #define DRWAV_SIZE_MAX SIZE_MAX #else @@ -1394,6 +1432,11 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b); #define DRWAV_SIZE_MAX 0xFFFFFFFF #endif #endif +/* End SIZE_MAX */ + +/* Weird bit manipulation is for C89 compatibility (no direct support for 64-bit integers). */ +#define DRWAV_INT64_MIN ((drwav_int64) ((drwav_uint64)0x80000000 << 32)) +#define DRWAV_INT64_MAX ((drwav_int64)(((drwav_uint64)0x7FFFFFFF << 32) | 0xFFFFFFFF)) #if defined(_MSC_VER) && _MSC_VER >= 1400 #define DRWAV_HAS_BYTESWAP16_INTRINSIC @@ -1603,69 +1646,65 @@ static DRWAV_INLINE void drwav__bswap_samples_s32(drwav_int32* pSamples, drwav_u } -static DRWAV_INLINE float drwav__bswap_f32(float n) +static DRWAV_INLINE drwav_int64 drwav__bswap_s64(drwav_int64 n) { - union { - drwav_uint32 i; - float f; - } x; - x.f = n; - x.i = drwav__bswap32(x.i); - - return x.f; + return (drwav_int64)drwav__bswap64((drwav_uint64)n); } -static DRWAV_INLINE void drwav__bswap_samples_f32(float* pSamples, drwav_uint64 sampleCount) +static DRWAV_INLINE void drwav__bswap_samples_s64(drwav_int64* pSamples, drwav_uint64 sampleCount) { drwav_uint64 iSample; for (iSample = 0; iSample < sampleCount; iSample += 1) { - pSamples[iSample] = drwav__bswap_f32(pSamples[iSample]); + pSamples[iSample] = drwav__bswap_s64(pSamples[iSample]); } } -static DRWAV_INLINE double drwav__bswap_f64(double n) +static DRWAV_INLINE float drwav__bswap_f32(float n) { union { - drwav_uint64 i; - double f; + drwav_uint32 i; + float f; } x; x.f = n; - x.i = drwav__bswap64(x.i); + x.i = drwav__bswap32(x.i); return x.f; } -static DRWAV_INLINE void drwav__bswap_samples_f64(double* pSamples, drwav_uint64 sampleCount) +static DRWAV_INLINE void drwav__bswap_samples_f32(float* pSamples, drwav_uint64 sampleCount) { drwav_uint64 iSample; for (iSample = 0; iSample < sampleCount; iSample += 1) { - pSamples[iSample] = drwav__bswap_f64(pSamples[iSample]); + pSamples[iSample] = drwav__bswap_f32(pSamples[iSample]); } } -static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample) +static DRWAV_INLINE void drwav__bswap_samples(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample) { - /* Assumes integer PCM. Floating point PCM is done in drwav__bswap_samples_ieee(). */ switch (bytesPerSample) { - case 1: /* u8 */ + case 1: { - /* no-op. */ + /* No-op. */ } break; - case 2: /* s16, s12 (loosely packed) */ + case 2: { drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount); } break; - case 3: /* s24 */ + case 3: { drwav__bswap_samples_s24((drwav_uint8*)pSamples, sampleCount); } break; - case 4: /* s32 */ + case 4: { drwav__bswap_samples_s32((drwav_int32*)pSamples, sampleCount); } break; + case 8: + { + drwav__bswap_samples_s64((drwav_int64*)pSamples, sampleCount); + } break; default: { /* Unsupported format. */ @@ -1674,59 +1713,91 @@ static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_uint64 s } } -static DRWAV_INLINE void drwav__bswap_samples_ieee(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample) + + +DRWAV_PRIVATE DRWAV_INLINE drwav_bool32 drwav_is_container_be(drwav_container container) { - switch (bytesPerSample) - { - #if 0 /* Contributions welcome for f16 support. */ - case 2: /* f16 */ - { - drwav__bswap_samples_f16((drwav_float16*)pSamples, sampleCount); - } break; - #endif - case 4: /* f32 */ - { - drwav__bswap_samples_f32((float*)pSamples, sampleCount); - } break; - case 8: /* f64 */ - { - drwav__bswap_samples_f64((double*)pSamples, sampleCount); - } break; - default: - { - /* Unsupported format. */ - DRWAV_ASSERT(DRWAV_FALSE); - } break; + if (container == drwav_container_rifx || container == drwav_container_aiff) { + return DRWAV_TRUE; + } else { + return DRWAV_FALSE; } } -static DRWAV_INLINE void drwav__bswap_samples(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample, drwav_uint16 format) + +DRWAV_PRIVATE DRWAV_INLINE drwav_uint16 drwav_bytes_to_u16_le(const drwav_uint8* data) { - switch (format) - { - case DR_WAVE_FORMAT_PCM: - { - drwav__bswap_samples_pcm(pSamples, sampleCount, bytesPerSample); - } break; + return ((drwav_uint16)data[0] << 0) | ((drwav_uint16)data[1] << 8); +} - case DR_WAVE_FORMAT_IEEE_FLOAT: - { - drwav__bswap_samples_ieee(pSamples, sampleCount, bytesPerSample); - } break; +DRWAV_PRIVATE DRWAV_INLINE drwav_uint16 drwav_bytes_to_u16_be(const drwav_uint8* data) +{ + return ((drwav_uint16)data[1] << 0) | ((drwav_uint16)data[0] << 8); +} - case DR_WAVE_FORMAT_ALAW: - case DR_WAVE_FORMAT_MULAW: - { - drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount); - } break; +DRWAV_PRIVATE DRWAV_INLINE drwav_uint16 drwav_bytes_to_u16_ex(const drwav_uint8* data, drwav_container container) +{ + if (drwav_is_container_be(container)) { + return drwav_bytes_to_u16_be(data); + } else { + return drwav_bytes_to_u16_le(data); + } +} - case DR_WAVE_FORMAT_ADPCM: - case DR_WAVE_FORMAT_DVI_ADPCM: - default: - { - /* Unsupported format. */ - DRWAV_ASSERT(DRWAV_FALSE); - } break; + +DRWAV_PRIVATE DRWAV_INLINE drwav_uint32 drwav_bytes_to_u32_le(const drwav_uint8* data) +{ + return ((drwav_uint32)data[0] << 0) | ((drwav_uint32)data[1] << 8) | ((drwav_uint32)data[2] << 16) | ((drwav_uint32)data[3] << 24); +} + +DRWAV_PRIVATE DRWAV_INLINE drwav_uint32 drwav_bytes_to_u32_be(const drwav_uint8* data) +{ + return ((drwav_uint32)data[3] << 0) | ((drwav_uint32)data[2] << 8) | ((drwav_uint32)data[1] << 16) | ((drwav_uint32)data[0] << 24); +} + +DRWAV_PRIVATE DRWAV_INLINE drwav_uint32 drwav_bytes_to_u32_ex(const drwav_uint8* data, drwav_container container) +{ + if (drwav_is_container_be(container)) { + return drwav_bytes_to_u32_be(data); + } else { + return drwav_bytes_to_u32_le(data); + } +} + + + +DRWAV_PRIVATE drwav_int64 drwav_aiff_extented_to_s64(const drwav_uint8* data) +{ + drwav_uint32 exponent = ((drwav_uint32)data[0] << 8) | data[1]; + drwav_uint64 hi = ((drwav_uint64)data[2] << 24) | ((drwav_uint64)data[3] << 16) | ((drwav_uint64)data[4] << 8) | ((drwav_uint64)data[5] << 0); + drwav_uint64 lo = ((drwav_uint64)data[6] << 24) | ((drwav_uint64)data[7] << 16) | ((drwav_uint64)data[8] << 8) | ((drwav_uint64)data[9] << 0); + drwav_uint64 significand = (hi << 32) | lo; + int sign = exponent >> 15; + + /* Remove sign bit. */ + exponent &= 0x7FFF; + + /* Special cases. */ + if (exponent == 0 && significand == 0) { + return 0; + } else if (exponent == 0x7FFF) { + return sign ? DRWAV_INT64_MIN : DRWAV_INT64_MAX; /* Infinite. */ + } + + exponent -= 16383; + + if (exponent > 63) { + return sign ? DRWAV_INT64_MIN : DRWAV_INT64_MAX; /* Too big for a 64-bit integer. */ + } else if (exponent < 1) { + return 0; /* Number is less than 1, so rounds down to 0. */ + } + + significand >>= (63 - exponent); + + if (sign) { + return -(drwav_int64)significand; + } else { + return (drwav_int64)significand; } } @@ -1850,7 +1921,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_d DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_chunk_header* pHeaderOut) { - if (container == drwav_container_riff || container == drwav_container_rf64) { + if (container == drwav_container_riff || container == drwav_container_rifx || container == drwav_container_rf64 || container == drwav_container_aiff) { drwav_uint8 sizeInBytes[4]; if (onRead(pUserData, pHeaderOut->id.fourcc, 4) != 4) { @@ -1861,10 +1932,11 @@ DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void return DRWAV_INVALID_FILE; } - pHeaderOut->sizeInBytes = drwav_bytes_to_u32(sizeInBytes); + pHeaderOut->sizeInBytes = drwav_bytes_to_u32_ex(sizeInBytes, container); pHeaderOut->paddingSize = drwav__chunk_padding_size_riff(pHeaderOut->sizeInBytes); + *pRunningBytesReadOut += 8; - } else { + } else if (container == drwav_container_w64) { drwav_uint8 sizeInBytes[8]; if (onRead(pUserData, pHeaderOut->id.guid, 16) != 16) { @@ -1878,6 +1950,8 @@ DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes) - 24; /* <-- Subtract 24 because w64 includes the size of the header. */ pHeaderOut->paddingSize = drwav__chunk_padding_size_w64(pHeaderOut->sizeInBytes); *pRunningBytesReadOut += 24; + } else { + return DRWAV_INVALID_FILE; } return DRWAV_SUCCESS; @@ -1931,115 +2005,6 @@ DRWAV_PRIVATE drwav_bool32 drwav__seek_from_start(drwav_seek_proc onSeek, drwav_ } -DRWAV_PRIVATE drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_fmt* fmtOut) -{ - drwav_chunk_header header; - drwav_uint8 fmt[16]; - - if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) { - return DRWAV_FALSE; - } - - - /* Skip non-fmt chunks. */ - while (((container == drwav_container_riff || container == drwav_container_rf64) && !drwav_fourcc_equal(header.id.fourcc, "fmt ")) || (container == drwav_container_w64 && !drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT))) { - if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) { - return DRWAV_FALSE; - } - *pRunningBytesReadOut += header.sizeInBytes + header.paddingSize; - - /* Try the next header. */ - if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) { - return DRWAV_FALSE; - } - } - - - /* Validation. */ - if (container == drwav_container_riff || container == drwav_container_rf64) { - if (!drwav_fourcc_equal(header.id.fourcc, "fmt ")) { - return DRWAV_FALSE; - } - } else { - if (!drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT)) { - return DRWAV_FALSE; - } - } - - - if (onRead(pUserData, fmt, sizeof(fmt)) != sizeof(fmt)) { - return DRWAV_FALSE; - } - *pRunningBytesReadOut += sizeof(fmt); - - fmtOut->formatTag = drwav_bytes_to_u16(fmt + 0); - fmtOut->channels = drwav_bytes_to_u16(fmt + 2); - fmtOut->sampleRate = drwav_bytes_to_u32(fmt + 4); - fmtOut->avgBytesPerSec = drwav_bytes_to_u32(fmt + 8); - fmtOut->blockAlign = drwav_bytes_to_u16(fmt + 12); - fmtOut->bitsPerSample = drwav_bytes_to_u16(fmt + 14); - - fmtOut->extendedSize = 0; - fmtOut->validBitsPerSample = 0; - fmtOut->channelMask = 0; - DRWAV_ZERO_MEMORY(fmtOut->subFormat, sizeof(fmtOut->subFormat)); - - if (header.sizeInBytes > 16) { - drwav_uint8 fmt_cbSize[2]; - int bytesReadSoFar = 0; - - if (onRead(pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) { - return DRWAV_FALSE; /* Expecting more data. */ - } - *pRunningBytesReadOut += sizeof(fmt_cbSize); - - bytesReadSoFar = 18; - - fmtOut->extendedSize = drwav_bytes_to_u16(fmt_cbSize); - if (fmtOut->extendedSize > 0) { - /* Simple validation. */ - if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) { - if (fmtOut->extendedSize != 22) { - return DRWAV_FALSE; - } - } - - if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) { - drwav_uint8 fmtext[22]; - if (onRead(pUserData, fmtext, fmtOut->extendedSize) != fmtOut->extendedSize) { - return DRWAV_FALSE; /* Expecting more data. */ - } - - fmtOut->validBitsPerSample = drwav_bytes_to_u16(fmtext + 0); - fmtOut->channelMask = drwav_bytes_to_u32(fmtext + 2); - drwav_bytes_to_guid(fmtext + 6, fmtOut->subFormat); - } else { - if (!onSeek(pUserData, fmtOut->extendedSize, drwav_seek_origin_current)) { - return DRWAV_FALSE; - } - } - *pRunningBytesReadOut += fmtOut->extendedSize; - - bytesReadSoFar += fmtOut->extendedSize; - } - - /* Seek past any leftover bytes. For w64 the leftover will be defined based on the chunk size. */ - if (!onSeek(pUserData, (int)(header.sizeInBytes - bytesReadSoFar), drwav_seek_origin_current)) { - return DRWAV_FALSE; - } - *pRunningBytesReadOut += (header.sizeInBytes - bytesReadSoFar); - } - - if (header.paddingSize > 0) { - if (!onSeek(pUserData, header.paddingSize, drwav_seek_origin_current)) { - return DRWAV_FALSE; - } - *pRunningBytesReadOut += header.paddingSize; - } - - return DRWAV_TRUE; -} - DRWAV_PRIVATE size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, void* pBufferOut, size_t bytesToRead, drwav_uint64* pCursor) { @@ -2164,7 +2129,7 @@ DRWAV_PRIVATE drwav_result drwav__metadata_alloc(drwav__metadata_parser* pParser /* We don't need to worry about specifying an alignment here because malloc always returns something - of suitable alignment. This also means than pParser->pMetadata is all that we need to store in order + of suitable alignment. This also means pParser->pMetadata is all that we need to store in order for us to free when we are done. */ pParser->pMetadata = (drwav_metadata*)drwav__metadata_get_memory(pParser, sizeof(drwav_metadata) * pParser->metadataCount, 1); @@ -2187,12 +2152,18 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_pars { drwav_uint8 smplHeaderData[DRWAV_SMPL_BYTES]; drwav_uint64 totalBytesRead = 0; - size_t bytesJustRead = drwav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead); + size_t bytesJustRead; + + if (pMetadata == NULL) { + return 0; + } + + bytesJustRead = drwav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead); DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read); DRWAV_ASSERT(pChunkHeader != NULL); - if (bytesJustRead == sizeof(smplHeaderData)) { + if (pMetadata != NULL && bytesJustRead == sizeof(smplHeaderData)) { drwav_uint32 iSampleLoop; pMetadata->type = drwav_metadata_type_smpl; @@ -2245,7 +2216,13 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parse { drwav_uint8 cueHeaderSectionData[DRWAV_CUE_BYTES]; drwav_uint64 totalBytesRead = 0; - size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueHeaderSectionData, sizeof(cueHeaderSectionData), &totalBytesRead); + size_t bytesJustRead; + + if (pMetadata == NULL) { + return 0; + } + + bytesJustRead = drwav__metadata_parser_read(pParser, cueHeaderSectionData, sizeof(cueHeaderSectionData), &totalBytesRead); DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read); @@ -2292,7 +2269,13 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parse DRWAV_PRIVATE drwav_uint64 drwav__read_inst_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata) { drwav_uint8 instData[DRWAV_INST_BYTES]; - drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, instData, sizeof(instData), NULL); + drwav_uint64 bytesRead; + + if (pMetadata == NULL) { + return 0; + } + + bytesRead = drwav__metadata_parser_read(pParser, instData, sizeof(instData), NULL); DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read); @@ -2313,7 +2296,13 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_inst_to_metadata_obj(drwav__metadata_pars DRWAV_PRIVATE drwav_uint64 drwav__read_acid_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata) { drwav_uint8 acidData[DRWAV_ACID_BYTES]; - drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, acidData, sizeof(acidData), NULL); + drwav_uint64 bytesRead; + + if (pMetadata == NULL) { + return 0; + } + + bytesRead = drwav__metadata_parser_read(pParser, acidData, sizeof(acidData), NULL); DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read); @@ -2663,7 +2652,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_unknown_chunk(drwav__metadata return 0; } - if (drwav_fourcc_equal(pChunkId, "data") || drwav_fourcc_equal(pChunkId, "fmt") || drwav_fourcc_equal(pChunkId, "fact")) { + if (drwav_fourcc_equal(pChunkId, "data") || drwav_fourcc_equal(pChunkId, "fmt ") || drwav_fourcc_equal(pChunkId, "fact")) { return 0; } @@ -3018,20 +3007,25 @@ DRWAV_PRIVATE drwav_bool32 drwav_preinit(drwav* pWav, drwav_read_proc onRead, dr DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags) { /* This function assumes drwav_preinit() has been called beforehand. */ - + drwav_result result; drwav_uint64 cursor; /* <-- Keeps track of the byte position so we can seek to specific locations. */ drwav_bool32 sequential; drwav_uint8 riff[4]; drwav_fmt fmt; unsigned short translatedFormatTag; - drwav_bool32 foundDataChunk; - drwav_uint64 dataChunkSize = 0; /* <-- Important! Don't explicitly set this to 0 anywhere else. Calculation of the size of the data chunk is performed in different paths depending on the container. */ + drwav_uint64 dataChunkSize = 0; /* <-- Important! Don't explicitly set this to 0 anywhere else. Calculation of the size of the data chunk is performed in different paths depending on the container. */ drwav_uint64 sampleCountFromFactChunk = 0; /* Same as dataChunkSize - make sure this is the only place this is initialized to 0. */ - drwav_uint64 chunkSize; + drwav_uint64 metadataStartPos; drwav__metadata_parser metadataParser; + drwav_bool8 isProcessingMetadata = DRWAV_FALSE; + drwav_bool8 foundChunk_fmt = DRWAV_FALSE; + drwav_bool8 foundChunk_data = DRWAV_FALSE; + drwav_bool8 isAIFCFormType = DRWAV_FALSE; /* Only used with AIFF. */ + drwav_uint64 aiffFrameCount = 0; cursor = 0; sequential = (flags & DRWAV_SEQUENTIAL) != 0; + DRWAV_ZERO_OBJECT(&fmt); /* The first 4 bytes should be the RIFF identifier. */ if (drwav__on_read(pWav->onRead, pWav->pUserData, riff, sizeof(riff), &cursor) != sizeof(riff)) { @@ -3044,6 +3038,8 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on */ if (drwav_fourcc_equal(riff, "RIFF")) { pWav->container = drwav_container_riff; + } else if (drwav_fourcc_equal(riff, "RIFX")) { + pWav->container = drwav_container_rifx; } else if (drwav_fourcc_equal(riff, "riff")) { int i; drwav_uint8 riff2[12]; @@ -3062,28 +3058,31 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on } } else if (drwav_fourcc_equal(riff, "RF64")) { pWav->container = drwav_container_rf64; + } else if (drwav_fourcc_equal(riff, "FORM")) { + pWav->container = drwav_container_aiff; } else { return DRWAV_FALSE; /* Unknown or unsupported container. */ } - if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) { + if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx || pWav->container == drwav_container_rf64) { drwav_uint8 chunkSizeBytes[4]; drwav_uint8 wave[4]; - /* RIFF/WAVE */ if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) { return DRWAV_FALSE; } - if (pWav->container == drwav_container_riff) { - if (drwav_bytes_to_u32(chunkSizeBytes) < 36) { + if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx) { + if (drwav_bytes_to_u32_ex(chunkSizeBytes, pWav->container) < 36) { return DRWAV_FALSE; /* Chunk size should always be at least 36 bytes. */ } - } else { - if (drwav_bytes_to_u32(chunkSizeBytes) != 0xFFFFFFFF) { + } else if (pWav->container == drwav_container_rf64) { + if (drwav_bytes_to_u32_le(chunkSizeBytes) != 0xFFFFFFFF) { return DRWAV_FALSE; /* Chunk size should always be set to -1/0xFFFFFFFF for RF64. The actual size is retrieved later. */ } + } else { + return DRWAV_FALSE; /* Should never hit this. */ } if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) { @@ -3093,11 +3092,10 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on if (!drwav_fourcc_equal(wave, "WAVE")) { return DRWAV_FALSE; /* Expecting "WAVE". */ } - } else { + } else if (pWav->container == drwav_container_w64) { drwav_uint8 chunkSizeBytes[8]; drwav_uint8 wave[16]; - /* W64 */ if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) { return DRWAV_FALSE; } @@ -3113,6 +3111,31 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on if (!drwav_guid_equal(wave, drwavGUID_W64_WAVE)) { return DRWAV_FALSE; } + } else if (pWav->container == drwav_container_aiff) { + drwav_uint8 chunkSizeBytes[4]; + drwav_uint8 aiff[4]; + + if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) { + return DRWAV_FALSE; + } + + if (drwav_bytes_to_u32_be(chunkSizeBytes) < 18) { + return DRWAV_FALSE; + } + + if (drwav__on_read(pWav->onRead, pWav->pUserData, aiff, sizeof(aiff), &cursor) != sizeof(aiff)) { + return DRWAV_FALSE; + } + + if (drwav_fourcc_equal(aiff, "AIFF")) { + isAIFCFormType = DRWAV_FALSE; + } else if (drwav_fourcc_equal(aiff, "AIFC")) { + isAIFCFormType = DRWAV_TRUE; + } else { + return DRWAV_FALSE; /* Expecting "AIFF" or "AIFC". */ + } + } else { + return DRWAV_FALSE; } @@ -3121,7 +3144,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on drwav_uint8 sizeBytes[8]; drwav_uint64 bytesRemainingInChunk; drwav_chunk_header header; - drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header); + result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header); if (result != DRWAV_SUCCESS) { return DRWAV_FALSE; } @@ -3164,88 +3187,52 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on } - /* The next bytes should be the "fmt " chunk. */ - if (!drwav__read_fmt(pWav->onRead, pWav->onSeek, pWav->pUserData, pWav->container, &cursor, &fmt)) { - return DRWAV_FALSE; /* Failed to read the "fmt " chunk. */ - } + metadataStartPos = cursor; - /* Basic validation. */ - if ((fmt.sampleRate == 0 || fmt.sampleRate > DRWAV_MAX_SAMPLE_RATE) || - (fmt.channels == 0 || fmt.channels > DRWAV_MAX_CHANNELS) || - (fmt.bitsPerSample == 0 || fmt.bitsPerSample > DRWAV_MAX_BITS_PER_SAMPLE) || - fmt.blockAlign == 0) { - return DRWAV_FALSE; /* Probably an invalid WAV file. */ - } + /* + Whether or not we are processing metadata controls how we load. We can load more efficiently when + metadata is not being processed, but we also cannot process metadata for Wave64 because I have not + been able to test it. If someone is able to test this and provide a patch I'm happy to enable it. + Seqential mode cannot support metadata because it involves seeking backwards. + */ + isProcessingMetadata = !sequential && ((flags & DRWAV_WITH_METADATA) != 0); - /* Translate the internal format. */ - translatedFormatTag = fmt.formatTag; - if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) { - translatedFormatTag = drwav_bytes_to_u16(fmt.subFormat + 0); + /* Don't allow processing of metadata with untested containers. */ + if (pWav->container != drwav_container_riff && pWav->container != drwav_container_rf64) { + isProcessingMetadata = DRWAV_FALSE; } DRWAV_ZERO_MEMORY(&metadataParser, sizeof(metadataParser)); - - /* Not tested on W64. */ - if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) { - drwav_uint64 cursorForMetadata = cursor; - + if (isProcessingMetadata) { metadataParser.onRead = pWav->onRead; metadataParser.onSeek = pWav->onSeek; metadataParser.pReadSeekUserData = pWav->pUserData; - metadataParser.stage = drwav__metadata_parser_stage_count; - - for (;;) { - drwav_result result; - drwav_uint64 bytesRead; - drwav_uint64 remainingBytes; - drwav_chunk_header header; - - result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursorForMetadata, &header); - if (result != DRWAV_SUCCESS) { - break; - } - - bytesRead = drwav__metadata_process_chunk(&metadataParser, &header, pWav->allowedMetadataTypes); - DRWAV_ASSERT(bytesRead <= header.sizeInBytes); - - remainingBytes = header.sizeInBytes - bytesRead + header.paddingSize; - if (!drwav__seek_forward(pWav->onSeek, remainingBytes, pWav->pUserData)) { - break; - } - cursorForMetadata += remainingBytes; - } - - if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) { - return DRWAV_FALSE; - } - - drwav__metadata_alloc(&metadataParser, &pWav->allocationCallbacks); - metadataParser.stage = drwav__metadata_parser_stage_read; + metadataParser.stage = drwav__metadata_parser_stage_count; } - /* - We need to enumerate over each chunk for two reasons: - 1) The "data" chunk may not be the next one - 2) We may want to report each chunk back to the client - In order to correctly report each chunk back to the client we will need to keep looping until the end of the file. + /* + From here on out, chunks might be in any order. In order to robustly handle metadata we'll need + to loop through every chunk and handle them as we find them. In sequential mode we need to get + out of the loop as soon as we find the data chunk because we won't be able to seek back. */ - foundDataChunk = DRWAV_FALSE; - - /* The next chunk we care about is the "data" chunk. This is not necessarily the next chunk so we'll need to loop. */ - for (;;) { + for (;;) { /* For each chunk... */ drwav_chunk_header header; - drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header); + drwav_uint64 chunkSize; + + result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header); if (result != DRWAV_SUCCESS) { - if (!foundDataChunk) { - return DRWAV_FALSE; - } else { - break; /* Probably at the end of the file. Get out of the loop. */ - } + break; } - /* Tell the client about this chunk. */ + chunkSize = header.sizeInBytes; + + + /* + Always tell the caller about this chunk. We cannot do this in sequential mode because the + callback is allowed to read from the file, in which case we'll need to rewind. + */ if (!sequential && onChunk != NULL) { drwav_uint64 callbackBytesRead = onChunk(pChunkUserData, pWav->onRead, pWav->onSeek, pWav->pUserData, &header, pWav->container, &fmt); @@ -3254,106 +3241,356 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on we called the callback. */ if (callbackBytesRead > 0) { - if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) { + if (drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData) == DRWAV_FALSE) { return DRWAV_FALSE; } } } - if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) { - drwav_uint64 bytesRead = drwav__metadata_process_chunk(&metadataParser, &header, pWav->allowedMetadataTypes); - if (bytesRead > 0) { - if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) { + /* Explicitly handle known chunks first. */ + + /* "fmt " */ + if (((pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx || pWav->container == drwav_container_rf64) && drwav_fourcc_equal(header.id.fourcc, "fmt ")) || + ((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT))) { + drwav_uint8 fmtData[16]; + + foundChunk_fmt = DRWAV_TRUE; + + if (pWav->onRead(pWav->pUserData, fmtData, sizeof(fmtData)) != sizeof(fmtData)) { + return DRWAV_FALSE; + } + cursor += sizeof(fmtData); + + fmt.formatTag = drwav_bytes_to_u16_ex(fmtData + 0, pWav->container); + fmt.channels = drwav_bytes_to_u16_ex(fmtData + 2, pWav->container); + fmt.sampleRate = drwav_bytes_to_u32_ex(fmtData + 4, pWav->container); + fmt.avgBytesPerSec = drwav_bytes_to_u32_ex(fmtData + 8, pWav->container); + fmt.blockAlign = drwav_bytes_to_u16_ex(fmtData + 12, pWav->container); + fmt.bitsPerSample = drwav_bytes_to_u16_ex(fmtData + 14, pWav->container); + + fmt.extendedSize = 0; + fmt.validBitsPerSample = 0; + fmt.channelMask = 0; + DRWAV_ZERO_MEMORY(fmt.subFormat, sizeof(fmt.subFormat)); + + if (header.sizeInBytes > 16) { + drwav_uint8 fmt_cbSize[2]; + int bytesReadSoFar = 0; + + if (pWav->onRead(pWav->pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) { + return DRWAV_FALSE; /* Expecting more data. */ + } + cursor += sizeof(fmt_cbSize); + + bytesReadSoFar = 18; + + fmt.extendedSize = drwav_bytes_to_u16_ex(fmt_cbSize, pWav->container); + if (fmt.extendedSize > 0) { + /* Simple validation. */ + if (fmt.formatTag == DR_WAVE_FORMAT_EXTENSIBLE) { + if (fmt.extendedSize != 22) { + return DRWAV_FALSE; + } + } + + if (fmt.formatTag == DR_WAVE_FORMAT_EXTENSIBLE) { + drwav_uint8 fmtext[22]; + + if (pWav->onRead(pWav->pUserData, fmtext, fmt.extendedSize) != fmt.extendedSize) { + return DRWAV_FALSE; /* Expecting more data. */ + } + + fmt.validBitsPerSample = drwav_bytes_to_u16_ex(fmtext + 0, pWav->container); + fmt.channelMask = drwav_bytes_to_u32_ex(fmtext + 2, pWav->container); + drwav_bytes_to_guid(fmtext + 6, fmt.subFormat); + } else { + if (pWav->onSeek(pWav->pUserData, fmt.extendedSize, drwav_seek_origin_current) == DRWAV_FALSE) { + return DRWAV_FALSE; + } + } + cursor += fmt.extendedSize; + + bytesReadSoFar += fmt.extendedSize; + } + + /* Seek past any leftover bytes. For w64 the leftover will be defined based on the chunk size. */ + if (pWav->onSeek(pWav->pUserData, (int)(header.sizeInBytes - bytesReadSoFar), drwav_seek_origin_current) == DRWAV_FALSE) { return DRWAV_FALSE; } + cursor += (header.sizeInBytes - bytesReadSoFar); } - } + if (header.paddingSize > 0) { + if (drwav__seek_forward(pWav->onSeek, header.paddingSize, pWav->pUserData) == DRWAV_FALSE) { + break; + } + cursor += header.paddingSize; + } - if (!foundDataChunk) { - pWav->dataChunkDataPos = cursor; + /* Go to the next chunk. Don't include this chunk in metadata. */ + continue; } - chunkSize = header.sizeInBytes; - if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) { - if (drwav_fourcc_equal(header.id.fourcc, "data")) { - foundDataChunk = DRWAV_TRUE; - if (pWav->container != drwav_container_rf64) { /* The data chunk size for RF64 will always be set to 0xFFFFFFFF here. It was set to it's true value earlier. */ - dataChunkSize = chunkSize; - } - } - } else { - if (drwav_guid_equal(header.id.guid, drwavGUID_W64_DATA)) { - foundDataChunk = DRWAV_TRUE; + /* "data" */ + if (((pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx || pWav->container == drwav_container_rf64) && drwav_fourcc_equal(header.id.fourcc, "data")) || + ((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_DATA))) { + foundChunk_data = DRWAV_TRUE; + + pWav->dataChunkDataPos = cursor; + + if (pWav->container != drwav_container_rf64) { /* The data chunk size for RF64 will always be set to 0xFFFFFFFF here. It was set to it's true value earlier. */ dataChunkSize = chunkSize; } - } - /* - If at this point we have found the data chunk and we're running in sequential mode, we need to break out of this loop. The reason for - this is that we would otherwise require a backwards seek which sequential mode forbids. - */ - if (foundDataChunk && sequential) { - break; + /* If we're running in sequential mode, or we're not reading metadata, we have enough now that we can get out of the loop. */ + if (sequential || !isProcessingMetadata) { + break; /* No need to keep reading beyond the data chunk. */ + } else { + chunkSize += header.paddingSize; /* <-- Make sure we seek past the padding. */ + if (drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == DRWAV_FALSE) { + break; + } + cursor += chunkSize; + + continue; /* There may be some more metadata to read. */ + } } - /* Optional. Get the total sample count from the FACT chunk. This is useful for compressed formats. */ - if (pWav->container == drwav_container_riff) { - if (drwav_fourcc_equal(header.id.fourcc, "fact")) { - drwav_uint32 sampleCount; + /* "fact". This is optional. Can use this to get the sample count which is useful for compressed formats. For RF64 we retrieved the sample count from the ds64 chunk earlier. */ + if (((pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx || pWav->container == drwav_container_rf64) && drwav_fourcc_equal(header.id.fourcc, "fact")) || + ((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_FACT))) { + if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx) { + drwav_uint8 sampleCount[4]; if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCount, 4, &cursor) != 4) { return DRWAV_FALSE; } - chunkSize -= 4; - if (!foundDataChunk) { - pWav->dataChunkDataPos = cursor; - } + chunkSize -= 4; /* The sample count in the "fact" chunk is either unreliable, or I'm not understanding it properly. For now I am only enabling this for Microsoft ADPCM formats. */ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) { - sampleCountFromFactChunk = sampleCount; + sampleCountFromFactChunk = drwav_bytes_to_u32_ex(sampleCount, pWav->container); } else { sampleCountFromFactChunk = 0; } - } - } else if (pWav->container == drwav_container_w64) { - if (drwav_guid_equal(header.id.guid, drwavGUID_W64_FACT)) { + } else if (pWav->container == drwav_container_w64) { if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCountFromFactChunk, 8, &cursor) != 8) { return DRWAV_FALSE; } + chunkSize -= 8; + } else if (pWav->container == drwav_container_rf64) { + /* We retrieved the sample count from the ds64 chunk earlier so no need to do that here. */ + } + + /* Seek to the next chunk in preparation for the next iteration. */ + chunkSize += header.paddingSize; /* <-- Make sure we seek past the padding. */ + if (drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == DRWAV_FALSE) { + break; + } + cursor += chunkSize; + + continue; + } + - if (!foundDataChunk) { - pWav->dataChunkDataPos = cursor; + /* "COMM". AIFF/AIFC only. */ + if (pWav->container == drwav_container_aiff && drwav_fourcc_equal(header.id.fourcc, "COMM")) { + drwav_uint8 commData[24]; + drwav_uint32 commDataBytesToRead; + drwav_uint16 channels; + drwav_uint32 frameCount; + drwav_uint16 sampleSizeInBits; + drwav_int64 sampleRate; + drwav_uint16 compressionFormat; + + foundChunk_fmt = DRWAV_TRUE; + + if (isAIFCFormType) { + commDataBytesToRead = 24; + if (header.sizeInBytes < commDataBytesToRead) { + return DRWAV_FALSE; /* Invalid COMM chunk. */ + } + } else { + commDataBytesToRead = 18; + if (header.sizeInBytes != commDataBytesToRead) { + return DRWAV_FALSE; /* INVALID COMM chunk. */ } } - } else if (pWav->container == drwav_container_rf64) { - /* We retrieved the sample count from the ds64 chunk earlier so no need to do that here. */ + + if (drwav__on_read(pWav->onRead, pWav->pUserData, commData, commDataBytesToRead, &cursor) != commDataBytesToRead) { + return DRWAV_FALSE; + } + + + channels = drwav_bytes_to_u16_ex (commData + 0, pWav->container); + frameCount = drwav_bytes_to_u32_ex (commData + 2, pWav->container); + sampleSizeInBits = drwav_bytes_to_u16_ex (commData + 6, pWav->container); + sampleRate = drwav_aiff_extented_to_s64(commData + 8); + + if (sampleRate < 0 || sampleRate > 0xFFFFFFFF) { + return DRWAV_FALSE; /* Invalid sample rate. */ + } + + if (isAIFCFormType) { + const drwav_uint8* type = commData + 18; + + if (drwav_fourcc_equal(type, "NONE")) { + compressionFormat = DR_WAVE_FORMAT_PCM; /* PCM, big-endian. */ + } else if (drwav_fourcc_equal(type, "raw ")) { + compressionFormat = DR_WAVE_FORMAT_PCM; + + /* In my testing, it looks like when the "raw " compression type is used, 8-bit samples should be considered unsigned. */ + if (sampleSizeInBits == 8) { + pWav->aiff.isUnsigned = DRWAV_TRUE; + } + } else if (drwav_fourcc_equal(type, "sowt")) { + compressionFormat = DR_WAVE_FORMAT_PCM; /* PCM, little-endian. */ + pWav->aiff.isLE = DRWAV_TRUE; + } else if (drwav_fourcc_equal(type, "fl32") || drwav_fourcc_equal(type, "fl64") || drwav_fourcc_equal(type, "FL32") || drwav_fourcc_equal(type, "FL64")) { + compressionFormat = DR_WAVE_FORMAT_IEEE_FLOAT; + } else if (drwav_fourcc_equal(type, "alaw") || drwav_fourcc_equal(type, "ALAW")) { + compressionFormat = DR_WAVE_FORMAT_ALAW; + } else if (drwav_fourcc_equal(type, "ulaw") || drwav_fourcc_equal(type, "ULAW")) { + compressionFormat = DR_WAVE_FORMAT_MULAW; + } else if (drwav_fourcc_equal(type, "ima4")) { + compressionFormat = DR_WAVE_FORMAT_DVI_ADPCM; + sampleSizeInBits = 4; + + /* + I haven't been able to figure out how to get correct decoding for IMA ADPCM. Until this is figured out + we'll need to abort when we encounter such an encoding. Advice welcome! + */ + return DRWAV_FALSE; + } else { + return DRWAV_FALSE; /* Unknown or unsupported compression format. Need to abort. */ + } + } else { + compressionFormat = DR_WAVE_FORMAT_PCM; /* It's a standard AIFF form which is always compressed. */ + } + + /* With AIFF we want to use the explicitly defined frame count rather than deriving it from the size of the chunk. */ + aiffFrameCount = frameCount; + + /* We should now have enough information to fill out our fmt structure. */ + fmt.formatTag = compressionFormat; + fmt.channels = channels; + fmt.sampleRate = (drwav_uint32)sampleRate; + fmt.bitsPerSample = sampleSizeInBits; + fmt.blockAlign = (drwav_uint16)(fmt.channels * fmt.bitsPerSample / 8); + fmt.avgBytesPerSec = fmt.blockAlign * fmt.sampleRate; + + if (fmt.blockAlign == 0 && compressionFormat == DR_WAVE_FORMAT_DVI_ADPCM) { + fmt.blockAlign = 34 * fmt.channels; + } + + /* + Weird one. I've seen some alaw and ulaw encoded files that for some reason set the bits per sample to 16 when + it should be 8. To get this working I need to explicitly check for this and change it. + */ + if (compressionFormat == DR_WAVE_FORMAT_ALAW || compressionFormat == DR_WAVE_FORMAT_MULAW) { + if (fmt.bitsPerSample > 8) { + fmt.bitsPerSample = 8; + fmt.blockAlign = fmt.channels; + } + } + + /* In AIFF, samples are padded to 8 byte boundaries. We need to round up our bits per sample here. */ + fmt.bitsPerSample += (fmt.bitsPerSample & 7); + + + /* If the form type is AIFC there will be some additional data in the chunk. We need to seek past it. */ + if (isAIFCFormType) { + if (drwav__seek_forward(pWav->onSeek, (chunkSize - commDataBytesToRead), pWav->pUserData) == DRWAV_FALSE) { + return DRWAV_FALSE; + } + cursor += (chunkSize - commDataBytesToRead); + } + + /* Don't fall through or else we'll end up treating this chunk as metadata which is incorrect. */ + continue; } - /* Make sure we seek past the padding. */ - chunkSize += header.paddingSize; - if (!drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData)) { + + /* "SSND". AIFF/AIFC only. This is the AIFF equivalent of the "data" chunk. */ + if (pWav->container == drwav_container_aiff && drwav_fourcc_equal(header.id.fourcc, "SSND")) { + drwav_uint8 offsetAndBlockSizeData[8]; + drwav_uint32 offset; + + foundChunk_data = DRWAV_TRUE; + + if (drwav__on_read(pWav->onRead, pWav->pUserData, offsetAndBlockSizeData, sizeof(offsetAndBlockSizeData), &cursor) != sizeof(offsetAndBlockSizeData)) { + return DRWAV_FALSE; + } + + /* We need to seek forward by the offset. */ + offset = drwav_bytes_to_u32_ex(offsetAndBlockSizeData + 0, pWav->container); + if (drwav__seek_forward(pWav->onSeek, offset, pWav->pUserData) == DRWAV_FALSE) { + return DRWAV_FALSE; + } + cursor += offset; + + pWav->dataChunkDataPos = cursor; + dataChunkSize = chunkSize; + + /* If we're running in sequential mode, or we're not reading metadata, we have enough now that we can get out of the loop. */ + if (sequential || !isProcessingMetadata) { + break; /* No need to keep reading beyond the data chunk. */ + } else { + if (drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == DRWAV_FALSE) { + break; + } + cursor += chunkSize; + + continue; /* There may be some more metadata to read. */ + } + } + + + + /* Getting here means it's not a chunk that we care about internally, but might need to be handled as metadata by the caller. */ + if (isProcessingMetadata) { + drwav_uint64 metadataBytesRead; + + metadataBytesRead = drwav__metadata_process_chunk(&metadataParser, &header, drwav_metadata_type_all_including_unknown); + DRWAV_ASSERT(metadataBytesRead <= header.sizeInBytes); + + /* Go back to the start of the chunk so we can normalize the position of the cursor. */ + if (drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData) == DRWAV_FALSE) { + break; /* Failed to seek. Can't reliable read the remaining chunks. Get out. */ + } + } + + + /* Make sure we skip past the content of this chunk before we go to the next one. */ + chunkSize += header.paddingSize; /* <-- Make sure we seek past the padding. */ + if (drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == DRWAV_FALSE) { break; } cursor += chunkSize; + } - if (!foundDataChunk) { - pWav->dataChunkDataPos = cursor; - } + /* There's some mandatory chunks that must exist. If they were not found in the iteration above we must abort. */ + if (!foundChunk_fmt || !foundChunk_data) { + return DRWAV_FALSE; } - pWav->pMetadata = metadataParser.pMetadata; - pWav->metadataCount = metadataParser.metadataCount; + /* Basic validation. */ + if ((fmt.sampleRate == 0 || fmt.sampleRate > DRWAV_MAX_SAMPLE_RATE ) || + (fmt.channels == 0 || fmt.channels > DRWAV_MAX_CHANNELS ) || + (fmt.bitsPerSample == 0 || fmt.bitsPerSample > DRWAV_MAX_BITS_PER_SAMPLE) || + fmt.blockAlign == 0) { + return DRWAV_FALSE; /* Probably an invalid WAV file. */ + } - /* If we haven't found a data chunk, return an error. */ - if (!foundDataChunk) { - return DRWAV_FALSE; + /* Translate the internal format. */ + translatedFormatTag = fmt.formatTag; + if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) { + translatedFormatTag = drwav_bytes_to_u16_ex(fmt.subFormat + 0, pWav->container); } /* We may have moved passed the data chunk. If so we need to move back. If running in sequential mode we can assume we are already sitting on the data chunk. */ @@ -3365,8 +3602,77 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on } + /* + At this point we should have done the initial parsing of each of our chunks, but we now need to + do a second pass to extract the actual contents of the metadata (the first pass just calculated + the length of the memory allocation). + + We only do this if we've actually got metadata to parse. + */ + if (isProcessingMetadata && metadataParser.metadataCount > 0) { + if (drwav__seek_from_start(pWav->onSeek, metadataStartPos, pWav->pUserData) == DRWAV_FALSE) { + return DRWAV_FALSE; + } + + result = drwav__metadata_alloc(&metadataParser, &pWav->allocationCallbacks); + if (result != DRWAV_SUCCESS) { + return DRWAV_FALSE; + } + + metadataParser.stage = drwav__metadata_parser_stage_read; + + for (;;) { + drwav_chunk_header header; + drwav_uint64 metadataBytesRead; + + result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header); + if (result != DRWAV_SUCCESS) { + break; + } + + metadataBytesRead = drwav__metadata_process_chunk(&metadataParser, &header, drwav_metadata_type_all_including_unknown); + + /* Move to the end of the chunk so we can keep iterating. */ + if (drwav__seek_forward(pWav->onSeek, (header.sizeInBytes + header.paddingSize) - metadataBytesRead, pWav->pUserData) == DRWAV_FALSE) { + drwav_free(metadataParser.pMetadata, &pWav->allocationCallbacks); + return DRWAV_FALSE; + } + } + + /* Getting here means we're finished parsing the metadata. */ + pWav->pMetadata = metadataParser.pMetadata; + pWav->metadataCount = metadataParser.metadataCount; + } + + /* At this point we should be sitting on the first byte of the raw audio data. */ + /* + I've seen a WAV file in the wild where a RIFF-ecapsulated file has the size of it's "RIFF" and + "data" chunks set to 0xFFFFFFFF when the file is definitely not that big. In this case we're + going to have to calculate the size by reading and discarding bytes, and then seeking back. We + cannot do this in sequential mode. We just assume that the rest of the file is audio data. + */ + if (dataChunkSize == 0xFFFFFFFF && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx) && pWav->isSequentialWrite == DRWAV_FALSE) { + dataChunkSize = 0; + + for (;;) { + drwav_uint8 temp[4096]; + size_t bytesRead = pWav->onRead(pWav->pUserData, temp, sizeof(temp)); + dataChunkSize += bytesRead; + + if (bytesRead < sizeof(temp)) { + break; + } + } + } + + if (drwav__seek_from_start(pWav->onSeek, pWav->dataChunkDataPos, pWav->pUserData) == DRWAV_FALSE) { + drwav_free(pWav->pMetadata, &pWav->allocationCallbacks); + return DRWAV_FALSE; + } + + pWav->fmt = fmt; pWav->sampleRate = fmt.sampleRate; pWav->channels = fmt.channels; @@ -3377,9 +3683,12 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on if (sampleCountFromFactChunk != 0) { pWav->totalPCMFrameCount = sampleCountFromFactChunk; + } else if (aiffFrameCount != 0) { + pWav->totalPCMFrameCount = aiffFrameCount; } else { drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); if (bytesPerFrame == 0) { + drwav_free(pWav->pMetadata, &pWav->allocationCallbacks); return DRWAV_FALSE; /* Invalid file. */ } @@ -3419,12 +3728,14 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on /* Some formats only support a certain number of channels. */ if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) { if (pWav->channels > 2) { + drwav_free(pWav->pMetadata, &pWav->allocationCallbacks); return DRWAV_FALSE; } } /* The number of bytes per frame must be known. If not, it's an invalid file and not decodable. */ if (drwav_get_bytes_per_pcm_frame(pWav) == 0) { + drwav_free(pWav->pMetadata, &pWav->allocationCallbacks); return DRWAV_FALSE; } @@ -3470,8 +3781,7 @@ DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav* pWav, drwav_read_proc onR return DRWAV_FALSE; } - pWav->allowedMetadataTypes = drwav_metadata_type_all_including_unknown; /* <-- Needs to be set to tell drwav_init_ex() that we need to process metadata. */ - return drwav_init__internal(pWav, NULL, NULL, flags); + return drwav_init__internal(pWav, NULL, NULL, flags | DRWAV_WITH_METADATA); } DRWAV_API drwav_metadata* drwav_take_ownership_of_metadata(drwav* pWav) @@ -3689,8 +3999,8 @@ DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata* } if (pMetadata->data.smpl.samplerSpecificDataSizeInBytes > 0) { - bytesWritten += drwav__write(pWav, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes); - } + bytesWritten += drwav__write_or_count(pWav, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes); + } } break; case drwav_metadata_type_inst: @@ -4134,6 +4444,8 @@ DRWAV_PRIVATE drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_d runningPos += drwav__write(pWav, "RF64", 4); runningPos += drwav__write_u32ne_to_le(pWav, 0xFFFFFFFF); /* Always 0xFFFFFFFF for RF64. Set to a proper value in the "ds64" chunk. */ runningPos += drwav__write(pWav, "WAVE", 4); + } else { + return DRWAV_FALSE; /* Container not supported for writing. */ } @@ -4267,6 +4579,7 @@ DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pF #ifndef DR_WAV_NO_STDIO +/* Errno */ /* drwav_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */ #include <errno.h> DRWAV_PRIVATE drwav_result drwav_result_from_errno(int e) @@ -4670,7 +4983,9 @@ DRWAV_PRIVATE drwav_result drwav_result_from_errno(int e) default: return DRWAV_ERROR; } } +/* End Errno */ +/* fopen */ DRWAV_PRIVATE drwav_result drwav_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) { #if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -4828,6 +5143,7 @@ DRWAV_PRIVATE drwav_result drwav_wfopen(FILE** ppFile, const wchar_t* pFilePath, return DRWAV_SUCCESS; } #endif +/* End fopen */ DRWAV_PRIVATE size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) @@ -4851,7 +5167,7 @@ DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const } -DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFile, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, drwav_metadata_type allowedMetadataTypes, const drwav_allocation_callbacks* pAllocationCallbacks) +DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFile, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks) { drwav_bool32 result; @@ -4861,8 +5177,6 @@ DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFi return result; } - pWav->allowedMetadataTypes = allowedMetadataTypes; - result = drwav_init__internal(pWav, onChunk, pChunkUserData, flags); if (result != DRWAV_TRUE) { fclose(pFile); @@ -4880,7 +5194,7 @@ DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drw } /* This takes ownership of the FILE* object. */ - return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, drwav_metadata_type_none, pAllocationCallbacks); + return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, pAllocationCallbacks); } #ifndef DR_WAV_NO_WCHAR @@ -4897,7 +5211,7 @@ DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename } /* This takes ownership of the FILE* object. */ - return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, drwav_metadata_type_none, pAllocationCallbacks); + return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, pAllocationCallbacks); } #endif @@ -4909,7 +5223,7 @@ DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav* pWav, const char* fi } /* This takes ownership of the FILE* object. */ - return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags, drwav_metadata_type_all_including_unknown, pAllocationCallbacks); + return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags | DRWAV_WITH_METADATA, pAllocationCallbacks); } #ifndef DR_WAV_NO_WCHAR @@ -4921,7 +5235,7 @@ DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav* pWav, const wchar_ } /* This takes ownership of the FILE* object. */ - return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags, drwav_metadata_type_all_including_unknown, pAllocationCallbacks); + return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags | DRWAV_WITH_METADATA, pAllocationCallbacks); } #endif @@ -5166,9 +5480,7 @@ DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav* pWav, const void* pWav->memoryStream.dataSize = dataSize; pWav->memoryStream.currentReadPos = 0; - pWav->allowedMetadataTypes = drwav_metadata_type_all_including_unknown; - - return drwav_init__internal(pWav, NULL, NULL, flags); + return drwav_init__internal(pWav, NULL, NULL, flags | DRWAV_WITH_METADATA); } @@ -5297,9 +5609,7 @@ DRWAV_API drwav_result drwav_uninit(drwav* pWav) } } } else { - if (pWav->pMetadata != NULL) { - pWav->allocationCallbacks.onFree(pWav->pMetadata, pWav->allocationCallbacks.pUserData); - } + drwav_free(pWav->pMetadata, &pWav->allocationCallbacks); } #ifndef DR_WAV_NO_STDIO @@ -5387,6 +5697,7 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 frames { drwav_uint32 bytesPerFrame; drwav_uint64 bytesToRead; /* Intentionally uint64 instead of size_t so we can do a check that we're not reading too much on 32-bit builds. */ + drwav_uint64 framesRemainingInFile; if (pWav == NULL || framesToRead == 0) { return 0; @@ -5397,6 +5708,11 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 frames return 0; } + framesRemainingInFile = pWav->totalPCMFrameCount - pWav->readCursorInPCMFrames; + if (framesToRead > framesRemainingInFile) { + framesToRead = framesRemainingInFile; + } + bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); if (bytesPerFrame == 0) { return 0; @@ -5429,7 +5745,7 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 frames return 0; /* Could not get the bytes per frame which means bytes per sample cannot be determined and we don't know how to byte swap. */ } - drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, bytesPerFrame/pWav->channels, pWav->translatedFormatTag); + drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, bytesPerFrame/pWav->channels); } return framesRead; @@ -5437,11 +5753,50 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 frames DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut) { + drwav_uint64 framesRead = 0; + + if (drwav_is_container_be(pWav->container)) { + /* + Special case for AIFF. AIFF is a big-endian encoded format, but it supports a format that is + PCM in little-endian encoding. In this case, we fall through this branch and treate it as + little-endian. + */ + if (pWav->container != drwav_container_aiff || pWav->aiff.isLE == DRWAV_FALSE) { + if (drwav__is_little_endian()) { + framesRead = drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut); + } else { + framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut); + } + + goto post_process; + } + } + + /* Getting here means the data should be considered little-endian. */ if (drwav__is_little_endian()) { - return drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut); + framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut); } else { - return drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut); + framesRead = drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut); + } + + /* + Here is where we check if we need to do a signed/unsigned conversion for AIFF. The reason we need to do this + is because dr_wav always assumes an 8-bit sample is unsigned, whereas AIFF can have signed 8-bit formats. + */ + post_process: + { + if (pWav->container == drwav_container_aiff && pWav->bitsPerSample == 8 && pWav->aiff.isUnsigned == DRWAV_FALSE) { + if (pBufferOut != NULL) { + drwav_uint64 iSample; + + for (iSample = 0; iSample < framesRead * pWav->channels; iSample += 1) { + ((drwav_uint8*)pBufferOut)[iSample] += 128; + } + } + } } + + return framesRead; } @@ -5552,7 +5907,7 @@ DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetF } totalSizeInBytes = pWav->totalPCMFrameCount * bytesPerFrame; - DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining); + /*DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);*/ currentBytePos = totalSizeInBytes - pWav->bytesRemaining; targetBytePos = targetFrameIndex * bytesPerFrame; @@ -5714,7 +6069,7 @@ DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 frame } DRWAV_COPY_MEMORY(temp, pRunningData, (size_t)bytesToWriteThisIteration); - drwav__bswap_samples(temp, sampleCount, bytesPerSample, pWav->translatedFormatTag); + drwav__bswap_samples(temp, sampleCount, bytesPerSample); bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp); if (bytesJustWritten == 0) { @@ -5967,7 +6322,7 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uin return totalFramesRead; /* Invalid data. */ } - pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0); + pWav->ima.predictor[0] = (drwav_int16)drwav_bytes_to_u16(header + 0); pWav->ima.stepIndex[0] = drwav_clamp(header[2], 0, (drwav_int32)drwav_countof(stepTable)-1); /* Clamp not necessary because we checked above, but adding here to silence a static analysis warning. */ pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0]; pWav->ima.cachedFrameCount = 1; @@ -6341,6 +6696,23 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_ui drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead); + /* + For some reason libsndfile seems to be returning samples of the opposite sign for a-law, but only + with AIFF files. For WAV files it seems to be the same as dr_wav. This is resulting in dr_wav's + automated tests failing. I'm not sure which is correct, but will assume dr_wav. If we're enforcing + libsndfile compatibility we'll swap the signs here. + */ + #ifdef DR_WAV_LIBSNDFILE_COMPAT + { + if (pWav->container == drwav_container_aiff) { + drwav_uint64 iSample; + for (iSample = 0; iSample < samplesRead; iSample += 1) { + pBufferOut[iSample] = -pBufferOut[iSample]; + } + } + } + #endif + pBufferOut += samplesRead; framesToRead -= framesRead; totalFramesRead += framesRead; @@ -6391,6 +6763,21 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_u drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead); + /* + Just like with alaw, for some reason the signs between libsndfile and dr_wav are opposite. We just need to + swap the sign if we're compiling with libsndfile compatiblity so our automated tests don't fail. + */ + #ifdef DR_WAV_LIBSNDFILE_COMPAT + { + if (pWav->container == drwav_container_aiff) { + drwav_uint64 iSample; + for (iSample = 0; iSample < samplesRead; iSample += 1) { + pBufferOut[iSample] = -pBufferOut[iSample]; + } + } + } + #endif + pBufferOut += samplesRead; framesToRead -= framesRead; totalFramesRead += framesRead; @@ -6543,7 +6930,6 @@ DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, siz } - DRWAV_PRIVATE void drwav__pcm_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample) { unsigned int i; @@ -6777,6 +7163,17 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_ui drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead); + #ifdef DR_WAV_LIBSNDFILE_COMPAT + { + if (pWav->container == drwav_container_aiff) { + drwav_uint64 iSample; + for (iSample = 0; iSample < samplesRead; iSample += 1) { + pBufferOut[iSample] = -pBufferOut[iSample]; + } + } + } + #endif + pBufferOut += samplesRead; framesToRead -= framesRead; totalFramesRead += framesRead; @@ -6823,6 +7220,17 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_u drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead); + #ifdef DR_WAV_LIBSNDFILE_COMPAT + { + if (pWav->container == drwav_container_aiff) { + drwav_uint64 iSample; + for (iSample = 0; iSample < samplesRead; iSample += 1) { + pBufferOut[iSample] = -pBufferOut[iSample]; + } + } + } + #endif + pBufferOut += samplesRead; framesToRead -= framesRead; totalFramesRead += framesRead; @@ -7234,6 +7642,17 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_ui drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead); + #ifdef DR_WAV_LIBSNDFILE_COMPAT + { + if (pWav->container == drwav_container_aiff) { + drwav_uint64 iSample; + for (iSample = 0; iSample < samplesRead; iSample += 1) { + pBufferOut[iSample] = -pBufferOut[iSample]; + } + } + } + #endif + pBufferOut += samplesRead; framesToRead -= framesRead; totalFramesRead += framesRead; @@ -7280,6 +7699,17 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_u drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead); + #ifdef DR_WAV_LIBSNDFILE_COMPAT + { + if (pWav->container == drwav_container_aiff) { + drwav_uint64 iSample; + for (iSample = 0; iSample < samplesRead; iSample += 1) { + pBufferOut[iSample] = -pBufferOut[iSample]; + } + } + } + #endif + pBufferOut += samplesRead; framesToRead -= framesRead; totalFramesRead += framesRead; @@ -7853,7 +8283,7 @@ DRWAV_API drwav_int16 drwav_bytes_to_s16(const drwav_uint8* data) DRWAV_API drwav_uint32 drwav_bytes_to_u32(const drwav_uint8* data) { - return ((drwav_uint32)data[0] << 0) | ((drwav_uint32)data[1] << 8) | ((drwav_uint32)data[2] << 16) | ((drwav_uint32)data[3] << 24); + return drwav_bytes_to_u32_le(data); } DRWAV_API float drwav_bytes_to_f32(const drwav_uint8* data) @@ -7917,6 +8347,29 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b) /* REVISION HISTORY ================ +v0.13.13 - 2023-11-02 + - Fix a warning when compiling with Clang. + +v0.13.12 - 2023-08-07 + - Fix a possible crash in drwav_read_pcm_frames(). + +v0.13.11 - 2023-07-07 + - AIFF compatibility improvements. + +v0.13.10 - 2023-05-29 + - Fix a bug where drwav_init_with_metadata() does not decode any frames after initializtion. + +v0.13.9 - 2023-05-22 + - Add support for AIFF decoding (writing and metadata not supported). + - Add support for RIFX decoding (writing and metadata not supported). + - Fix a bug where metadata is not processed if it's located before the "fmt " chunk. + - Add a workaround for a type of malformed WAV file where the size of the "RIFF" and "data" chunks + are incorrectly set to 0xFFFFFFFF. + +v0.13.8 - 2023-03-25 + - Fix a possible null pointer dereference. + - Fix a crash when loading files with badly formed metadata. + v0.13.7 - 2022-09-17 - Fix compilation with DJGPP. - Add support for disabling wchar_t with DR_WAV_NO_WCHAR. @@ -8331,7 +8784,7 @@ For more information, please refer to <http://unlicense.org/> =============================================================================== ALTERNATIVE 2 - MIT No Attribution =============================================================================== -Copyright 2020 David Reid +Copyright 2023 David Reid 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 diff --git a/raylib/src/external/m3d.h b/raylib/src/external/m3d.h index 3b29927..6abaad1 100644 --- a/raylib/src/external/m3d.h +++ b/raylib/src/external/m3d.h @@ -89,7 +89,7 @@ typedef uint8_t M3D_VOXEL; #define M3D_NUMBONE 4 #endif #ifndef M3D_BONEMAXLEVEL -#define M3D_BONEMAXLEVEL 8 +#define M3D_BONEMAXLEVEL 64 #endif #ifndef _MSC_VER #ifndef _inline @@ -2172,6 +2172,8 @@ M3D_INDEX _m3d_gettx(m3d_t *model, m3dread_t readfilecb, m3dfree_t freecb, char stbi__context s; stbi__result_info ri; + /* failsafe */ + if(!fn || !*fn) return M3D_UNDEF; /* do we have loaded this texture already? */ for(i = 0; i < model->numtexture; i++) if(!strcmp(fn, model->texture[i].name)) return i; @@ -2246,9 +2248,9 @@ void _m3d_getpr(m3d_t *model, _unused m3dread_t readfilecb, _unused m3dfree_t f { #ifdef M3D_PR_INTERP unsigned int i, len = 0; - unsigned char *buff = readfilecb ? (*readfilecb)(fn, &len) : NULL; + unsigned char *buff = readfilecb && fn && *fn ? (*readfilecb)(fn, &len) : NULL; - if(!buff && model->inlined) { + if(!buff && fn && *fn && model->inlined) { for(i = 0; i < model->numinlined; i++) if(!strcmp(fn, model->inlined[i].name)) { buff = model->inlined[i].data; @@ -3439,6 +3441,7 @@ memerr: M3D_LOG("Out of memory"); model->bone[i].numweight = 0; model->bone[i].weight = NULL; } + if(i != model->numbone) { M3D_LOG("Truncated bone chunk"); model->numbone = i; model->numskin = 0; model->errcode = M3D_ERR_BONE; } /* read skin definitions */ if(model->numskin) { model->skin = (m3ds_t*)M3D_MALLOC(model->numskin * sizeof(m3ds_t)); @@ -3471,6 +3474,7 @@ memerr: M3D_LOG("Out of memory"); model->skin[i].weight[j] /= w; } } + if(i != model->numskin) { M3D_LOG("Truncated skin in bone chunk"); model->numskin = i; model->errcode = M3D_ERR_BONE; } } } else /* material */ @@ -4726,14 +4730,14 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size unsigned char *out = NULL, *z = NULL, weights[M3D_NUMBONE < 8 ? 8 : M3D_NUMBONE], *norm = NULL; unsigned int i, j, k, l, n, o, len, chunklen, *length; int maxvox = 0, minvox = 0; - M3D_FLOAT scale = (M3D_FLOAT)0.0, min_x, max_x, min_y, max_y, min_z, max_z; + M3D_FLOAT scale = (M3D_FLOAT)0.0, min_x, max_x, min_y, max_y, min_z, max_z, mw; M3D_INDEX last, *vrtxidx = NULL, *mtrlidx = NULL, *tmapidx = NULL, *skinidx = NULL; #ifdef M3D_VERTEXMAX M3D_INDEX lastp; #endif uint32_t idx, numcmap = 0, *cmap = NULL, numvrtx = 0, maxvrtx = 0, numtmap = 0, maxtmap = 0, numproc = 0; uint32_t numskin = 0, maxskin = 0, numstr = 0, maxt = 0, maxbone = 0, numgrp = 0, maxgrp = 0, *grpidx = NULL; - uint8_t *opa; + uint8_t *opa = NULL; m3dcd_t *cd; m3dc_t *cmd; m3dstr_t *str = NULL; @@ -5072,10 +5076,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size for(i = 0; i < model->numskin; i++) { if(skinidx[i] == M3D_UNDEF) continue; memset(&sk, 0, sizeof(m3dssave_t)); - for(j = 0, min_x = (M3D_FLOAT)0.0; j < M3D_NUMBONE && model->skin[i].boneid[j] != M3D_UNDEF && - model->skin[i].weight[j] > (M3D_FLOAT)0.0; j++) { + for(j = 0, min_x = (M3D_FLOAT)0.0; j < M3D_NUMBONE && model->skin[i].boneid[j] != M3D_UNDEF; j++) { sk.data.boneid[j] = model->skin[i].boneid[j]; - sk.data.weight[j] = model->skin[i].weight[j]; + sk.data.weight[j] = model->skin[i].weight[j] > (M3D_FLOAT)0.0 ? model->skin[i].weight[j] : (M3D_FLOAT)0.01; min_x += sk.data.weight[j]; } if(j > maxbone) maxbone = j; @@ -5191,6 +5194,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx); if(sa) M3D_FREE(sa); if(sd) M3D_FREE(sd); if(out) M3D_FREE(out); + if(opa) free(opa); if(h) M3D_FREE(h); M3D_LOG("Out of memory"); model->errcode = M3D_ERR_ALLOC; @@ -5218,8 +5222,16 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx); if(model->preview.data && model->preview.length) { sl = _m3d_safestr(sn, 0); if(sl) { +/* gcc thinks that "ptr is used after free", well, gcc is simply wrong. */ +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuse-after-free" +#endif ptr -= (uintptr_t)out; len = (unsigned int)((uintptr_t)ptr + (uintptr_t)20 + strlen(sl)); out = (unsigned char*)M3D_REALLOC(out, len); ptr += (uintptr_t)out; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif if(!out) { setlocale(LC_NUMERIC, ol); goto memerr; } ptr += sprintf(ptr, "Preview\r\n%s.png\r\n\r\n", sl); M3D_FREE(sl); sl = NULL; @@ -5228,6 +5240,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx); M3D_FREE(sn); sn = NULL; /* texture map */ if(numtmap && tmap && !(flags & M3D_EXP_NOTXTCRD) && !(flags & M3D_EXP_NOFACE)) { +/* interestingly gcc does not complain about "ptr is used after free" here, although the code is 100% the same */ ptr -= (uintptr_t)out; len = (unsigned int)((uintptr_t)ptr + (uintptr_t)(maxtmap * 32) + (uintptr_t)12); out = (unsigned char*)M3D_REALLOC(out, len); ptr += (uintptr_t)out; if(!out) { setlocale(LC_NUMERIC, ol); goto memerr; } @@ -5846,9 +5859,13 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx); if(skin[i].newidx == last) continue; last = skin[i].newidx; memset(&weights, 0, nb_s); - for(j = 0; j < (uint32_t)nb_s && skin[i].data.boneid[j] != M3D_UNDEF && - skin[i].data.weight[j] > (M3D_FLOAT)0.0; j++) + for(j = k = l = 0, mw = 0.0; j < (uint32_t)nb_s && skin[i].data.boneid[j] != M3D_UNDEF && + skin[i].data.weight[j] > (M3D_FLOAT)0.0; j++) { + if(mw < skin[i].data.weight[j]) { mw = skin[i].data.weight[j]; k = j; } weights[j] = (uint8_t)(skin[i].data.weight[j] * 255); + if(!weights[j]) { weights[j]++; l--; } + } + weights[k] += l; switch(nb_s) { case 1: weights[0] = 255; break; case 2: memcpy(out, weights, 2); out += 2; break; @@ -5941,7 +5958,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx); } /* mesh face */ if(model->numface && face && !(flags & M3D_EXP_NOFACE)) { - chunklen = 8 + si_s + model->numface * (6 * vi_s + 3 * ti_s + si_s + 1); + chunklen = 8 + si_s + model->numface * (9 * vi_s + 3 * ti_s + si_s + 1); h = (m3dhdr_t*)M3D_REALLOC(h, len + chunklen); if(!h) goto memerr; memcpy((uint8_t*)h + len, "MESH", 4); @@ -6268,6 +6285,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx); if(skin) M3D_FREE(skin); if(str) M3D_FREE(str); if(vrtx) M3D_FREE(vrtx); + if(opa) free(opa); if(h) M3D_FREE(h); return out; } diff --git a/raylib/src/external/miniaudio.h b/raylib/src/external/miniaudio.h index 181f452..47332e1 100644 --- a/raylib/src/external/miniaudio.h +++ b/raylib/src/external/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.18 - 2023-08-07 +miniaudio - v0.11.21 - 2023-11-15 David Reid - mackron@gmail.com @@ -87,7 +87,7 @@ device on the stack, but you could allocate it on the heap if that suits your si // Do something here. Probably your program's main loop. - ma_device_uninit(&device); // This will stop the device so no need to do that manually. + ma_device_uninit(&device); return 0; } ``` @@ -1675,7 +1675,7 @@ an example for initializing a data source: // ... - ma_resource_manager_data_source_uninit(pResourceManager, &dataSource); + ma_resource_manager_data_source_uninit(&dataSource); ``` The `flags` parameter specifies how you want to perform loading of the sound file. It can be a @@ -1912,10 +1912,10 @@ once after the other: ```c ma_resource_manager_data_source_init(pResourceManager, "my_file", ..., &myDataBuffer0); // Refcount = 1. Initial load. - ma_resource_manager_data_source_uninit(pResourceManager, &myDataBuffer0); // Refcount = 0. Unloaded. + ma_resource_manager_data_source_uninit(&myDataBuffer0); // Refcount = 0. Unloaded. ma_resource_manager_data_source_init(pResourceManager, "my_file", ..., &myDataBuffer1); // Refcount = 1. Reloaded because previous uninit() unloaded it. - ma_resource_manager_data_source_uninit(pResourceManager, &myDataBuffer1); // Refcount = 0. Unloaded. + ma_resource_manager_data_source_uninit(&myDataBuffer1); // Refcount = 0. Unloaded. ``` A binary search tree (BST) is used for storing data buffers as it has good balance between @@ -2675,9 +2675,16 @@ outputting any audio data. To output audio data, use `ma_encoder_write_pcm_frame example below: ```c - framesWritten = ma_encoder_write_pcm_frames(&encoder, pPCMFramesToWrite, framesToWrite); + ma_uint64 framesWritten; + result = ma_encoder_write_pcm_frames(&encoder, pPCMFramesToWrite, framesToWrite, &framesWritten); + if (result != MA_SUCCESS) { + ... handle error ... + } ``` +The `framesWritten` variable will contain the number of PCM frames that were actually written. This +is optionally and you can pass in `NULL` if you need this. + Encoders must be uninitialized with `ma_encoder_uninit()`. @@ -3409,7 +3416,7 @@ miniaudio supports reading from a buffer of raw audio data via the `ma_audio_buf read from memory that's managed by the application, but can also handle the memory management for you internally. Memory management is flexible and should support most use cases. -Audio buffers are initialised using the standard configuration system used everywhere in miniaudio: +Audio buffers are initialized using the standard configuration system used everywhere in miniaudio: ```c ma_audio_buffer_config config = ma_audio_buffer_config_init( @@ -3716,7 +3723,7 @@ extern "C" { #define MA_VERSION_MAJOR 0 #define MA_VERSION_MINOR 11 -#define MA_VERSION_REVISION 18 +#define MA_VERSION_REVISION 21 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #if defined(_MSC_VER) && !defined(__clang__) @@ -4267,7 +4274,7 @@ typedef enum ma_standard_sample_rate_192000 = 192000, ma_standard_sample_rate_16000 = 16000, /* Extreme lows */ - ma_standard_sample_rate_11025 = 11250, + ma_standard_sample_rate_11025 = 11025, ma_standard_sample_rate_8000 = 8000, ma_standard_sample_rate_352800 = 352800, /* Extreme highs */ @@ -5390,7 +5397,7 @@ MA_API void ma_resampler_uninit(ma_resampler* pResampler, const ma_allocation_ca /* Converts the given input data. -Both the input and output frames must be in the format specified in the config when the resampler was initilized. +Both the input and output frames must be in the format specified in the config when the resampler was initialized. On input, [pFrameCountOut] contains the number of output frames to process. On output it contains the number of output frames that were actually processed, which may be less than the requested amount which will happen if there's not enough input data. You can use @@ -6709,7 +6716,8 @@ typedef enum ma_device_notification_type_stopped, ma_device_notification_type_rerouted, ma_device_notification_type_interruption_began, - ma_device_notification_type_interruption_ended + ma_device_notification_type_interruption_ended, + ma_device_notification_type_unlocked } ma_device_notification_type; typedef struct @@ -7035,7 +7043,7 @@ struct ma_device_config ma_uint32 periods; ma_performance_profile performanceProfile; ma_bool8 noPreSilencedOutputBuffer; /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to silence. */ - ma_bool8 noClip; /* When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. Only applies when the playback sample format is f32. */ + ma_bool8 noClip; /* When set to true, the contents of the output buffer passed into the data callback will not be clipped after returning. Only applies when the playback sample format is f32. */ ma_bool8 noDisableDenormals; /* Do not disable denormals when firing the data callback. */ ma_bool8 noFixedSizedCallback; /* Disables strict fixed-sized data callbacks. Setting this to true will result in the period size being treated only as a hint to the backend. This is an optimization for those who don't need fixed sized callbacks. */ ma_device_data_proc dataCallback; @@ -8619,8 +8627,8 @@ then be set directly on the structure. Below are the members of the `ma_device_c callback will write to every sample in the output buffer, or if you are doing your own clearing. noClip - When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. When set to false (default), the - contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or not the clip. This only + When set to true, the contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or + not to clip. When set to false (default), the contents of the output buffer passed into the data callback will be clipped after returning. This only applies when the playback sample format is f32. noDisableDenormals @@ -9133,8 +9141,6 @@ speakers or received from the microphone which can in turn result in de-syncs. Do not call this in any callback. -This will be called implicitly by `ma_device_uninit()`. - See Also -------- @@ -10171,7 +10177,7 @@ MA_API ma_noise_config ma_noise_config_init(ma_format format, ma_uint32 channels typedef struct { - ma_data_source_vtable ds; + ma_data_source_base ds; ma_noise_config config; ma_lcg lcg; union @@ -10569,7 +10575,7 @@ typedef struct /* Extended processing callback. This callback is used for effects that process input and output at different rates (i.e. they perform resampling). This is similar to the simple version, only - they take two seperate frame counts: one for input, and one for output. + they take two separate frame counts: one for input, and one for output. On input, `pFrameCountOut` is equal to the capacity of the output buffer for each bus, whereas `pFrameCountIn` will be equal to the number of PCM frames in each of the buffers in `ppFramesIn`. @@ -12238,7 +12244,7 @@ static MA_INLINE void ma_zero_memory_default(void* p, size_t sz) #define ma_abs(x) (((x) > 0) ? (x) : -(x)) #define ma_clamp(x, lo, hi) (ma_max(lo, ma_min(x, hi))) #define ma_offset_ptr(p, offset) (((ma_uint8*)(p)) + (offset)) -#define ma_align(x, a) ((x + (a-1)) & ~(a-1)) +#define ma_align(x, a) (((x) + ((a)-1)) & ~((a)-1)) #define ma_align_64(x) ma_align(x, 8) #define ma_buffer_frame_capacity(buffer, channels, format) (sizeof(buffer) / ma_get_bytes_per_sample(format) / (channels)) @@ -13639,7 +13645,7 @@ MA_API ma_result ma_log_postv(ma_log* pLog, ma_uint32 level, const char* pFormat /* First try formatting into our fixed sized stack allocated buffer. If this is too small we'll fallback to a heap allocation. */ length = vsnprintf(pFormattedMessageStack, sizeof(pFormattedMessageStack), pFormat, args); if (length < 0) { - return MA_INVALID_OPERATION; /* An error occured when trying to convert the buffer. */ + return MA_INVALID_OPERATION; /* An error occurred when trying to convert the buffer. */ } if ((size_t)length < sizeof(pFormattedMessageStack)) { @@ -16180,7 +16186,15 @@ static void ma_thread_wait__posix(ma_thread* pThread) static ma_result ma_mutex_init__posix(ma_mutex* pMutex) { - int result = pthread_mutex_init((pthread_mutex_t*)pMutex, NULL); + int result; + + if (pMutex == NULL) { + return MA_INVALID_ARGS; + } + + MA_ZERO_OBJECT(pMutex); + + result = pthread_mutex_init((pthread_mutex_t*)pMutex, NULL); if (result != 0) { return ma_result_from_errno(result); } @@ -17807,7 +17821,7 @@ MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename) #ifdef MA_WIN32 /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/ - #if !defined(MA_WIN32_UWP) + #if !defined(MA_WIN32_UWP) || !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))) handle = (ma_handle)LoadLibraryA(filename); #else /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */ @@ -18452,7 +18466,7 @@ Timing *******************************************************************************/ #if defined(MA_WIN32) && !defined(MA_POSIX) static LARGE_INTEGER g_ma_TimerFrequency; /* <-- Initialized to zero since it's static. */ - void ma_timer_init(ma_timer* pTimer) + static void ma_timer_init(ma_timer* pTimer) { LARGE_INTEGER counter; @@ -18464,7 +18478,7 @@ Timing pTimer->counter = counter.QuadPart; } - double ma_timer_get_time_in_seconds(ma_timer* pTimer) + static double ma_timer_get_time_in_seconds(ma_timer* pTimer) { LARGE_INTEGER counter; if (!QueryPerformanceCounter(&counter)) { @@ -18637,30 +18651,31 @@ static void ma_device__on_notification(ma_device_notification notification) } } -void ma_device__on_notification_started(ma_device* pDevice) +static void ma_device__on_notification_started(ma_device* pDevice) { ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_started)); } -void ma_device__on_notification_stopped(ma_device* pDevice) +static void ma_device__on_notification_stopped(ma_device* pDevice) { ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_stopped)); } -void ma_device__on_notification_rerouted(ma_device* pDevice) +/* Not all platforms support reroute notifications. */ +#if !defined(MA_EMSCRIPTEN) +static void ma_device__on_notification_rerouted(ma_device* pDevice) { ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_rerouted)); } +#endif -void ma_device__on_notification_interruption_began(ma_device* pDevice) -{ - ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began)); -} - -void ma_device__on_notification_interruption_ended(ma_device* pDevice) +#if defined(MA_EMSCRIPTEN) +EMSCRIPTEN_KEEPALIVE +void ma_device__on_notification_unlocked(ma_device* pDevice) { - ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended)); + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_unlocked)); } +#endif static void ma_device__on_data_inner(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount) @@ -19115,10 +19130,10 @@ static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_device_state n #if defined(MA_WIN32) - GUID MA_GUID_KSDATAFORMAT_SUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; - GUID MA_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; - /*GUID MA_GUID_KSDATAFORMAT_SUBTYPE_ALAW = {0x00000006, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/ - /*GUID MA_GUID_KSDATAFORMAT_SUBTYPE_MULAW = {0x00000007, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/ + static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; + static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; + /*static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_ALAW = {0x00000006, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/ + /*static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_MULAW = {0x00000007, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/ #endif @@ -23270,7 +23285,7 @@ static ma_result ma_device_read__wasapi(ma_device* pDevice, void* pFrames, ma_ui /* At this point we should be able to loop back to the start of the loop and try retrieving a data buffer again. */ } else { - /* An error occured and we need to abort. */ + /* An error occurred and we need to abort. */ ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from capture device in preparation for reading from the device. HRESULT = %d. Stopping device.\n", (int)hr); result = ma_result_from_HRESULT(hr); break; @@ -23492,6 +23507,39 @@ static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_context_ MA_ZERO_OBJECT(&pContext->wasapi); + + #if defined(MA_WIN32_UWP) + { + /* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */ + pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll"); + if (pContext->wasapi.hMMDevapi) { + pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync"); + if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) { + ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi); + return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */ + } + } else { + return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */ + } + } + #endif + + /* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */ + pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll"); + if (pContext->wasapi.hAvrt) { + pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA"); + pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics"); + + /* If either function could not be found, disable use of avrt entirely. */ + if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) { + pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL; + pContext->wasapi.AvRevertMmThreadcharacteristics = NULL; + ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt); + pContext->wasapi.hAvrt = NULL; + } + } + + /* Annoyingly, WASAPI does not allow you to release an IAudioClient object from a different thread than the one that retrieved it with GetService(). This can result in a deadlock in two @@ -23535,41 +23583,6 @@ static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_context_ ma_mutex_uninit(&pContext->wasapi.commandLock); return result; } - - #if defined(MA_WIN32_UWP) - { - /* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */ - pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll"); - if (pContext->wasapi.hMMDevapi) { - pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync"); - if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) { - ma_semaphore_uninit(&pContext->wasapi.commandSem); - ma_mutex_uninit(&pContext->wasapi.commandLock); - ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi); - return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */ - } - } else { - ma_semaphore_uninit(&pContext->wasapi.commandSem); - ma_mutex_uninit(&pContext->wasapi.commandLock); - return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */ - } - } - #endif - - /* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */ - pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll"); - if (pContext->wasapi.hAvrt) { - pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA"); - pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics"); - - /* If either function could not be found, disable use of avrt entirely. */ - if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) { - pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL; - pContext->wasapi.AvRevertMmThreadcharacteristics = NULL; - ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt); - pContext->wasapi.hAvrt = NULL; - } - } } @@ -31865,6 +31878,18 @@ size, allocate a block of memory of that size and then call AudioObjectGetProper AudioDeviceID's so just do "dataSize/sizeof(AudioDeviceID)" to know the device count. */ +#if defined(MA_APPLE_MOBILE) +static void ma_device__on_notification_interruption_began(ma_device* pDevice) +{ + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began)); +} + +static void ma_device__on_notification_interruption_ended(ma_device* pDevice) +{ + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended)); +} +#endif + static ma_result ma_result_from_OSStatus(OSStatus status) { switch (status) @@ -32781,9 +32806,9 @@ static ma_result ma_find_best_format__coreaudio(ma_context* pContext, AudioObjec hasSupportedFormat = MA_FALSE; for (iFormat = 0; iFormat < deviceFormatDescriptionCount; ++iFormat) { - ma_format format; - ma_result formatResult = ma_format_from_AudioStreamBasicDescription(&pDeviceFormatDescriptions[iFormat].mFormat, &format); - if (formatResult == MA_SUCCESS && format != ma_format_unknown) { + ma_format formatFromDescription; + ma_result formatResult = ma_format_from_AudioStreamBasicDescription(&pDeviceFormatDescriptions[iFormat].mFormat, &formatFromDescription); + if (formatResult == MA_SUCCESS && formatFromDescription != ma_format_unknown) { hasSupportedFormat = MA_TRUE; bestDeviceFormatSoFar = pDeviceFormatDescriptions[iFormat].mFormat; break; @@ -34834,7 +34859,7 @@ static ma_result ma_context_init__coreaudio(ma_context* pContext, const ma_conte #endif #if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE) - pContext->coreaudio.hCoreFoundation = ma_dlopen(ma_context_get_log(pContext), "CoreFoundation.framework/CoreFoundation"); + pContext->coreaudio.hCoreFoundation = ma_dlopen(ma_context_get_log(pContext), "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"); if (pContext->coreaudio.hCoreFoundation == NULL) { return MA_API_NOT_FOUND; } @@ -34843,7 +34868,7 @@ static ma_result ma_context_init__coreaudio(ma_context* pContext, const ma_conte pContext->coreaudio.CFRelease = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation, "CFRelease"); - pContext->coreaudio.hCoreAudio = ma_dlopen(ma_context_get_log(pContext), "CoreAudio.framework/CoreAudio"); + pContext->coreaudio.hCoreAudio = ma_dlopen(ma_context_get_log(pContext), "/System/Library/Frameworks/CoreAudio.framework/CoreAudio"); if (pContext->coreaudio.hCoreAudio == NULL) { ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation); return MA_API_NOT_FOUND; @@ -34861,7 +34886,7 @@ static ma_result ma_context_init__coreaudio(ma_context* pContext, const ma_conte The way it'll work is that it'll first try AudioUnit, and if the required symbols are not present there we'll fall back to AudioToolbox. */ - pContext->coreaudio.hAudioUnit = ma_dlopen(ma_context_get_log(pContext), "AudioUnit.framework/AudioUnit"); + pContext->coreaudio.hAudioUnit = ma_dlopen(ma_context_get_log(pContext), "/System/Library/Frameworks/AudioUnit.framework/AudioUnit"); if (pContext->coreaudio.hAudioUnit == NULL) { ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio); ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation); @@ -34871,7 +34896,7 @@ static ma_result ma_context_init__coreaudio(ma_context* pContext, const ma_conte if (ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioComponentFindNext") == NULL) { /* Couldn't find the required symbols in AudioUnit, so fall back to AudioToolbox. */ ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit); - pContext->coreaudio.hAudioUnit = ma_dlopen(ma_context_get_log(pContext), "AudioToolbox.framework/AudioToolbox"); + pContext->coreaudio.hAudioUnit = ma_dlopen(ma_context_get_log(pContext), "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox"); if (pContext->coreaudio.hAudioUnit == NULL) { ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio); ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation); @@ -39784,6 +39809,7 @@ static ma_result ma_device_uninit__webaudio(ma_device* pDevice) */ device.webaudio.close(); device.webaudio = undefined; + device.pDevice = undefined; }, pDevice->webaudio.deviceIndex); } #endif @@ -39807,6 +39833,10 @@ static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__webaudio(co */ ma_uint32 periodSizeInFrames; + if (nativeSampleRate == 0) { + nativeSampleRate = MA_DEFAULT_SAMPLE_RATE; + } + if (pDescriptor->periodSizeInFrames == 0) { if (pDescriptor->periodSizeInMilliseconds == 0) { if (performanceProfile == ma_performance_profile_low_latency) { @@ -39956,7 +39986,7 @@ static void ma_audio_worklet_processor_created__webaudio(EMSCRIPTEN_WEBAUDIO_T a /* With the audio worklet initialized we can now attach it to the graph. */ if (pParameters->pConfig->deviceType == ma_device_type_capture || pParameters->pConfig->deviceType == ma_device_type_duplex) { - ma_result attachmentResult = EM_ASM_INT({ + ma_result attachmentResult = (ma_result)EM_ASM_INT({ var getUserMediaResult = 0; var audioWorklet = emscriptenGetAudioObject($0); var audioContext = emscriptenGetAudioObject($1); @@ -39987,7 +40017,7 @@ static void ma_audio_worklet_processor_created__webaudio(EMSCRIPTEN_WEBAUDIO_T a /* If it's playback only we can now attach the worklet node to the graph. This has already been done for the duplex case. */ if (pParameters->pConfig->deviceType == ma_device_type_playback) { - ma_result attachmentResult = EM_ASM_INT({ + ma_result attachmentResult = (ma_result)EM_ASM_INT({ var audioWorklet = emscriptenGetAudioObject($0); var audioContext = emscriptenGetAudioObject($1); audioWorklet.connect(audioContext.destination); @@ -40202,7 +40232,7 @@ static ma_result ma_device_init__webaudio(ma_device* pDevice, const ma_device_co /* First thing we need is an AudioContext. */ var audioContextOptions = {}; - if (deviceType == window.miniaudio.device_type.playback) { + if (deviceType == window.miniaudio.device_type.playback && sampleRate != 0) { audioContextOptions.sampleRate = sampleRate; } @@ -40279,6 +40309,8 @@ static ma_result ma_device_init__webaudio(ma_device* pDevice, const ma_device_co device.scriptNode.connect(device.webaudio.destination); } + device.pDevice = pDevice; + return miniaudio.track_device(device); }, pConfig->deviceType, channels, sampleRate, periodSizeInFrames, pDevice->webaudio.pIntermediaryBuffer, pDevice); @@ -40445,14 +40477,21 @@ static ma_result ma_context_init__webaudio(ma_context* pContext, const ma_contex }; miniaudio.unlock_event_types = (function(){ - return ['touchstart', 'touchend', 'click']; + return ['touchend', 'click']; })(); miniaudio.unlock = function() { for(var i = 0; i < miniaudio.devices.length; ++i) { var device = miniaudio.devices[i]; - if (device != null && device.webaudio != null && device.state === 2 /* ma_device_state_started */) { - device.webaudio.resume(); + if (device != null && + device.webaudio != null && + device.state === window.miniaudio.device_state.started) { + + device.webaudio.resume().then(() => { + Module._ma_device__on_notification_unlocked(device.pDevice); + }, + (error) => {console.error("Failed to resume audiocontext", error); + }); } } miniaudio.unlock_event_types.map(function(event_type) { @@ -40890,6 +40929,11 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData) ma_device__on_notification_stopped(pDevice); } + /* If we stopped because the device has been uninitialized, abort now. */ + if (ma_device_get_state(pDevice) == ma_device_state_uninitialized) { + break; + } + /* A function somewhere is waiting for the device to have stopped for real so we need to signal an event to allow it to continue. */ ma_device__set_state(pDevice, ma_device_state_stopped); ma_event_signal(&pDevice->stopEvent); @@ -42100,10 +42144,23 @@ MA_API void ma_device_uninit(ma_device* pDevice) return; } - /* Make sure the device is stopped first. The backends will probably handle this naturally, but I like to do it explicitly for my own sanity. */ - if (ma_device_is_started(pDevice)) { - ma_device_stop(pDevice); + /* + It's possible for the miniaudio side of the device and the backend to not be in sync due to + system-level situations such as the computer being put into sleep mode and the backend not + notifying miniaudio of the fact the device has stopped. It's possible for this to result in a + deadlock due to miniaudio thinking the device is in a running state, when in fact it's not + running at all. For this reason I am no longer explicitly stopping the device. I don't think + this should affect anyone in practice since uninitializing the backend will naturally stop the + device anyway. + */ + #if 0 + { + /* Make sure the device is stopped first. The backends will probably handle this naturally, but I like to do it explicitly for my own sanity. */ + if (ma_device_is_started(pDevice)) { + ma_device_stop(pDevice); + } } + #endif /* Putting the device into an uninitialized state will make the worker thread return. */ ma_device__set_state(pDevice, ma_device_state_uninitialized); @@ -52835,7 +52892,7 @@ static ma_result ma_channel_map_apply_mono_in_f32(float* MA_RESTRICT pFramesOut, for (iFrame = 0; iFrame < unrolledFrameCount; iFrame += 1) { __m128 in0 = _mm_set1_ps(pFramesIn[iFrame*2 + 0]); __m128 in1 = _mm_set1_ps(pFramesIn[iFrame*2 + 1]); - _mm_storeu_ps(&pFramesOut[iFrame*4 + 0], _mm_shuffle_ps(in1, in0, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_storeu_ps(&pFramesOut[iFrame*4 + 0], _mm_shuffle_ps(in0, in1, _MM_SHUFFLE(0, 0, 0, 0))); } /* Tail. */ @@ -52861,7 +52918,7 @@ static ma_result ma_channel_map_apply_mono_in_f32(float* MA_RESTRICT pFramesOut, __m128 in1 = _mm_set1_ps(pFramesIn[iFrame*2 + 1]); _mm_storeu_ps(&pFramesOut[iFrame*12 + 0], in0); - _mm_storeu_ps(&pFramesOut[iFrame*12 + 4], _mm_shuffle_ps(in1, in0, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_storeu_ps(&pFramesOut[iFrame*12 + 4], _mm_shuffle_ps(in0, in1, _MM_SHUFFLE(0, 0, 0, 0))); _mm_storeu_ps(&pFramesOut[iFrame*12 + 8], in1); } @@ -59701,7 +59758,7 @@ extern "C" { #define MA_DR_WAV_XSTRINGIFY(x) MA_DR_WAV_STRINGIFY(x) #define MA_DR_WAV_VERSION_MAJOR 0 #define MA_DR_WAV_VERSION_MINOR 13 -#define MA_DR_WAV_VERSION_REVISION 12 +#define MA_DR_WAV_VERSION_REVISION 13 #define MA_DR_WAV_VERSION_STRING MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MAJOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MINOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_REVISION) #include <stddef.h> #define MA_DR_WAVE_FORMAT_PCM 0x1 @@ -60121,7 +60178,7 @@ extern "C" { #define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x) #define MA_DR_FLAC_VERSION_MAJOR 0 #define MA_DR_FLAC_VERSION_MINOR 12 -#define MA_DR_FLAC_VERSION_REVISION 41 +#define MA_DR_FLAC_VERSION_REVISION 42 #define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION) #include <stddef.h> #if defined(_MSC_VER) && _MSC_VER >= 1700 @@ -60408,7 +60465,7 @@ extern "C" { #define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x) #define MA_DR_MP3_VERSION_MAJOR 0 #define MA_DR_MP3_VERSION_MINOR 6 -#define MA_DR_MP3_VERSION_REVISION 37 +#define MA_DR_MP3_VERSION_REVISION 38 #define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION) #include <stddef.h> #define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 @@ -64826,7 +64883,7 @@ MA_API ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_co /* Probably no implementation for loading from a file path. Use miniaudio's file IO instead. */ result = ma_decoder_init_vfs(NULL, pFilePath, pConfig, pDecoder); if (result != MA_SUCCESS) { - return MA_SUCCESS; + return result; } } @@ -64976,7 +65033,7 @@ MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decod /* Probably no implementation for loading from a file path. Use miniaudio's file IO instead. */ result = ma_decoder_init_vfs_w(NULL, pFilePath, pConfig, pDecoder); if (result != MA_SUCCESS) { - return MA_SUCCESS; + return result; } } @@ -68744,7 +68801,7 @@ static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_ma async = (flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC) != 0; /* - Fences need to be acquired before doing anything. These must be aquired and released outside of + Fences need to be acquired before doing anything. These must be acquired and released outside of the node to ensure there's no holes where ma_fence_wait() could prematurely return before the data buffer has completed initialization. @@ -72016,7 +72073,7 @@ MA_API ma_result ma_node_init_preallocated(ma_node_graph* pNodeGraph, const ma_n } if (heapLayout.outputBusOffset != MA_SIZE_MAX) { - pNodeBase->pOutputBuses = (ma_node_output_bus*)ma_offset_ptr(pHeap, heapLayout.inputBusOffset); + pNodeBase->pOutputBuses = (ma_node_output_bus*)ma_offset_ptr(pHeap, heapLayout.outputBusOffset); } else { pNodeBase->pOutputBuses = pNodeBase->_outputBuses; } @@ -72507,11 +72564,11 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde /* At this point we know that we are inside our start/stop times. However, we may need to adjust - our frame count and output pointer to accomodate since we could be straddling the time period + our frame count and output pointer to accommodate since we could be straddling the time period that this function is getting called for. It's possible (and likely) that the start time does not line up with the output buffer. We - therefore need to offset it by a number of frames to accomodate. The same thing applies for + therefore need to offset it by a number of frames to accommodate. The same thing applies for the stop time. */ timeOffsetBeg = (globalTimeBeg < startTime) ? (ma_uint32)(globalTimeEnd - startTime) : 0; @@ -74097,7 +74154,7 @@ static void ma_engine_node_process_pcm_frames__general(ma_engine_node* pEngineNo if (fadeStartOffsetInFrames == (ma_int64)(~(ma_uint64)0)) { fadeStartOffsetInFrames = 0; } else { - fadeStartOffsetInFrames -= ma_engine_get_time(pEngineNode->pEngine); + fadeStartOffsetInFrames -= ma_engine_get_time_in_pcm_frames(pEngineNode->pEngine); } ma_fader_set_fade_ex(&pEngineNode->fader, fadeVolumeBeg, fadeVolumeEnd, fadeLengthInFrames, fadeStartOffsetInFrames); @@ -75534,6 +75591,10 @@ MA_API void ma_engine_listener_get_cone(const ma_engine* pEngine, ma_uint32 list *pOuterGain = 0; } + if (pEngine == NULL || listenerIndex >= pEngine->listenerCount) { + return; + } + ma_spatializer_listener_get_cone(&pEngine->listeners[listenerIndex], pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain); } @@ -76103,7 +76164,7 @@ MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint } /* Stopping with a fade out requires us to schedule the stop into the future by the fade length. */ - ma_sound_set_stop_time_with_fade_in_pcm_frames(pSound, ma_engine_get_time(ma_sound_get_engine(pSound)) + fadeLengthInFrames, fadeLengthInFrames); + ma_sound_set_stop_time_with_fade_in_pcm_frames(pSound, ma_engine_get_time_in_pcm_frames(ma_sound_get_engine(pSound)) + fadeLengthInFrames, fadeLengthInFrames); return MA_SUCCESS; } @@ -76476,6 +76537,10 @@ MA_API void ma_sound_get_cone(const ma_sound* pSound, float* pInnerAngleInRadian *pOuterGain = 0; } + if (pSound == NULL) { + return; + } + ma_spatializer_get_cone(&pSound->engineNode.spatializer, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain); } @@ -76757,6 +76822,8 @@ MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor) { + ma_uint64 seekTarget; + if (pSound == NULL) { return MA_INVALID_ARGS; } @@ -76766,7 +76833,13 @@ MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* return MA_INVALID_OPERATION; } - return ma_data_source_get_cursor_in_pcm_frames(pSound->pDataSource, pCursor); + seekTarget = ma_atomic_load_64(&pSound->seekTarget); + if (seekTarget != MA_SEEK_TARGET_NONE) { + *pCursor = seekTarget; + return MA_SUCCESS; + } else { + return ma_data_source_get_cursor_in_pcm_frames(pSound->pDataSource, pCursor); + } } MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength) @@ -76785,16 +76858,28 @@ MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor) { - if (pSound == NULL) { - return MA_INVALID_ARGS; + ma_result result; + ma_uint64 cursorInPCMFrames; + ma_uint32 sampleRate; + + if (pCursor != NULL) { + *pCursor = 0; } - /* The notion of a cursor is only valid for sounds that are backed by a data source. */ - if (pSound->pDataSource == NULL) { - return MA_INVALID_OPERATION; + result = ma_sound_get_cursor_in_pcm_frames(pSound, &cursorInPCMFrames); + if (result != MA_SUCCESS) { + return result; + } + + result = ma_sound_get_data_format(pSound, NULL, NULL, &sampleRate, NULL, 0); + if (result != MA_SUCCESS) { + return result; } - return ma_data_source_get_cursor_in_seconds(pSound->pDataSource, pCursor); + /* VC6 does not support division of unsigned 64-bit integers with floating point numbers. Need to use a signed number. This shouldn't effect anything in practice. */ + *pCursor = (ma_int64)cursorInPCMFrames / (float)sampleRate; + + return MA_SUCCESS; } MA_API ma_result ma_sound_get_length_in_seconds(ma_sound* pSound, float* pLength) @@ -77193,8 +77278,8 @@ code below please report the bug to the respective repository for the relevant p #define ma_dr_wav_clamp(x, lo, hi) (ma_dr_wav_max((lo), ma_dr_wav_min((hi), (x)))) #define ma_dr_wav_offset_ptr(p, offset) (((ma_uint8*)(p)) + (offset)) #define MA_DR_WAV_MAX_SIMD_VECTOR_SIZE 32 -#define MA_DR_WAV_INT64_MIN ((ma_int64)0x80000000 << 32) -#define MA_DR_WAV_INT64_MAX ((((ma_int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF) +#define MA_DR_WAV_INT64_MIN ((ma_int64) ((ma_uint64)0x80000000 << 32)) +#define MA_DR_WAV_INT64_MAX ((ma_int64)(((ma_uint64)0x7FFFFFFF << 32) | 0xFFFFFFFF)) #if defined(_MSC_VER) && _MSC_VER >= 1400 #define MA_DR_WAV_HAS_BYTESWAP16_INTRINSIC #define MA_DR_WAV_HAS_BYTESWAP32_INTRINSIC @@ -82322,7 +82407,7 @@ static MA_INLINE ma_uint32 ma_dr_flac__swap_endian_uint32(ma_uint32 n) #if defined(_MSC_VER) && !defined(__clang__) return _byteswap_ulong(n); #elif defined(__GNUC__) || defined(__clang__) - #if defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(MA_64BIT) + #if defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(__ARM_ARCH_6M__) && !defined(MA_64BIT) ma_uint32 r; __asm__ __volatile__ ( #if defined(MA_64BIT) @@ -83063,7 +83148,7 @@ static MA_INLINE ma_uint32 ma_dr_flac__clz_lzcnt(ma_dr_flac_cache_t x) ); return r; } - #elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(MA_64BIT) + #elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(MA_64BIT) { unsigned int r; __asm__ __volatile__ ( @@ -85804,7 +85889,7 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea for (;;) { ma_dr_flac_metadata metadata; ma_uint8 isLastBlock = 0; - ma_uint8 blockType; + ma_uint8 blockType = 0; ma_uint32 blockSize; if (ma_dr_flac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == MA_FALSE) { return MA_FALSE; @@ -89884,7 +89969,7 @@ static int ma_dr_mp3_have_simd(void) #else #define MA_DR_MP3_HAVE_SIMD 0 #endif -#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) +#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__) #define MA_DR_MP3_HAVE_ARMV6 1 static __inline__ __attribute__((always_inline)) ma_int32 ma_dr_mp3_clip_int16_arm(ma_int32 a) { diff --git a/raylib/src/external/qoa.h b/raylib/src/external/qoa.h index 59d90ad..fc62f47 100644 --- a/raylib/src/external/qoa.h +++ b/raylib/src/external/qoa.h @@ -8,71 +8,96 @@ QOA - The "Quite OK Audio" format for fast, lossy audio compression -- Data Format -A QOA file has an 8 byte file header, followed by a number of frames. Each frame -consists of an 8 byte frame header, the current 8 byte en-/decoder state per -channel and 256 slices per channel. Each slice is 8 bytes wide and encodes 20 -samples of audio data. +QOA encodes pulse-code modulated (PCM) audio data with up to 255 channels, +sample rates from 1 up to 16777215 hertz and a bit depth of 16 bits. -Note that the last frame of a file may contain less than 256 slices per channel. -The last slice (per channel) in the last frame may contain less 20 samples, but -the slice will still be 8 bytes wide, with the unused samples zeroed out. +The compression method employed in QOA is lossy; it discards some information +from the uncompressed PCM data. For many types of audio signals this compression +is "transparent", i.e. the difference from the original file is often not +audible. -The samplerate and number of channels is only stated in the frame headers, but -not in the file header. A decoder may peek into the first frame of the file to -find these values. +QOA encodes 20 samples of 16 bit PCM data into slices of 64 bits. A single +sample therefore requires 3.2 bits of storage space, resulting in a 5x +compression (16 / 3.2). -In a valid QOA file all frames have the same number of channels and the same -samplerate. These restrictions may be relaxed for streaming. This remains to -be decided. +A QOA file consists of an 8 byte file header, followed by a number of frames. +Each frame contains an 8 byte frame header, the current 16 byte en-/decoder +state per channel and 256 slices per channel. Each slice is 8 bytes wide and +encodes 20 samples of audio data. -All values in a QOA file are BIG ENDIAN. Luckily, EVERYTHING in a QOA file, -including the headers, is 64 bit aligned, so it's possible to read files with -just a read_u64() that does the byte swapping if necessary. - -In pseudocode, the file layout is as follows: +All values, including the slices, are big endian. The file layout is as follows: struct { struct { - char magic[4]; // magic bytes 'qoaf' - uint32_t samples; // number of samples per channel in this file - } file_header; // = 64 bits + char magic[4]; // magic bytes "qoaf" + uint32_t samples; // samples per channel in this file + } file_header; struct { struct { - uint8_t num_channels; // number of channels + uint8_t num_channels; // no. of channels uint24_t samplerate; // samplerate in hz - uint16_t fsamples; // sample count per channel in this frame - uint16_t fsize; // frame size (including the frame header) - } frame_header; // = 64 bits + uint16_t fsamples; // samples per channel in this frame + uint16_t fsize; // frame size (includes this header) + } frame_header; struct { - int16_t history[4]; // = 64 bits - int16_t weights[4]; // = 64 bits + int16_t history[4]; // most recent last + int16_t weights[4]; // most recent last } lms_state[num_channels]; - qoa_slice_t slices[256][num_channels]; // = 64 bits each - } frames[samples * channels / qoa_max_framesize()]; -} qoa_file; + qoa_slice_t slices[256][num_channels]; + + } frames[ceil(samples / (256 * 20))]; +} qoa_file_t; -Wheras the 64bit qoa_slice_t is defined as follows: +Each `qoa_slice_t` contains a quantized scalefactor `sf_quant` and 20 quantized +residuals `qrNN`: .- QOA_SLICE -- 64 bits, 20 samples --------------------------/ /------------. | Byte[0] | Byte[1] | Byte[2] \ \ Byte[7] | | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | 7 6 5 / / 2 1 0 | |------------+--------+--------+--------+---------+---------+-\ \--+---------| -| sf_index | r00 | r01 | r02 | r03 | r04 | / / | r19 | +| sf_quant | qr00 | qr01 | qr02 | qr03 | qr04 | / / | qr19 | `-------------------------------------------------------------\ \------------` -`sf_index` defines the scalefactor to use for this slice as an index into the -qoa_scalefactor_tab[16] +Each frame except the last must contain exactly 256 slices per channel. The last +frame may contain between 1 .. 256 (inclusive) slices per channel. The last +slice (for each channel) in the last frame may contain less than 20 samples; the +slice still must be 8 bytes wide, with the unused samples zeroed out. + +Channels are interleaved per slice. E.g. for 2 channel stereo: +slice[0] = L, slice[1] = R, slice[2] = L, slice[3] = R ... + +A valid QOA file or stream must have at least one frame. Each frame must contain +at least one channel and one sample with a samplerate between 1 .. 16777215 +(inclusive). + +If the total number of samples is not known by the encoder, the samples in the +file header may be set to 0x00000000 to indicate that the encoder is +"streaming". In a streaming context, the samplerate and number of channels may +differ from frame to frame. For static files (those with samples set to a +non-zero value), each frame must have the same number of channels and same +samplerate. -`r00`--`r19` are the residuals for the individual samples, divided by the -scalefactor and quantized by the qoa_quant_tab[]. +Note that this implementation of QOA only handles files with a known total +number of samples. -In the decoder, a prediction of the next sample is computed by multiplying the -state (the last four output samples) with the predictor. The residual from the -slice is then dequantized using the qoa_dequant_tab[] and added to the -prediction. The result is clamped to int16 to form the final output sample. +A decoder should support at least 8 channels. The channel layout for channel +counts 1 .. 8 is: + + 1. Mono + 2. L, R + 3. L, R, C + 4. FL, FR, B/SL, B/SR + 5. FL, FR, C, B/SL, B/SR + 6. FL, FR, C, LFE, B/SL, B/SR + 7. FL, FR, C, LFE, B, SL, SR + 8. FL, FR, C, LFE, BL, BR, SL, SR + +QOA predicts each audio sample based on the previously decoded ones using a +"Sign-Sign Least Mean Squares Filter" (LMS). This prediction plus the +dequantized residual forms the final output sample. */ @@ -158,7 +183,7 @@ the higher end. Note that the residual zero is identical to the lowest positive value. This is mostly fine, since the qoa_div() function always rounds away from zero. */ -static int qoa_quant_tab[17] = { +static const int qoa_quant_tab[17] = { 7, 7, 7, 5, 5, 3, 3, 1, /* -8..-1 */ 0, /* 0 */ 0, 2, 2, 4, 4, 6, 6, 6 /* 1.. 8 */ @@ -169,13 +194,13 @@ static int qoa_quant_tab[17] = { less accurate at the higher end. In theory, the highest scalefactor that we would need to encode the highest 16bit residual is (2**16)/8 = 8192. However we rely on the LMS filter to predict samples accurately enough that a maximum -residual of one quarter of the 16 bit range is high sufficient. I.e. with the +residual of one quarter of the 16 bit range is sufficient. I.e. with the scalefactor 2048 times the quant range of 8 we can encode residuals up to 2**14. The scalefactor values are computed as: scalefactor_tab[s] <- round(pow(s + 1, 2.75)) */ -static int qoa_scalefactor_tab[16] = { +static const int qoa_scalefactor_tab[16] = { 1, 7, 21, 45, 84, 138, 211, 304, 421, 562, 731, 928, 1157, 1419, 1715, 2048 }; @@ -188,7 +213,7 @@ do this in .16 fixed point with integers, instead of floats. The reciprocal_tab is computed as: reciprocal_tab[s] <- ((1<<16) + scalefactor_tab[s] - 1) / scalefactor_tab[s] */ -static int qoa_reciprocal_tab[16] = { +static const int qoa_reciprocal_tab[16] = { 65536, 9363, 3121, 1457, 781, 475, 311, 216, 156, 117, 90, 71, 57, 47, 39, 32 }; @@ -200,9 +225,13 @@ Since qoa_div rounds away from the zero, the smallest entries are mapped to 3/4 instead of 1. The dequant_tab assumes the following dequantized values for each of the quant_tab indices and is computed as: float dqt[8] = {0.75, -0.75, 2.5, -2.5, 4.5, -4.5, 7, -7}; -dequant_tab[s][q] <- round(scalefactor_tab[s] * dqt[q]) */ +dequant_tab[s][q] <- round_ties_away_from_zero(scalefactor_tab[s] * dqt[q]) + +The rounding employed here is "to nearest, ties away from zero", i.e. positive +and negative values are treated symmetrically. +*/ -static int qoa_dequant_tab[16][8] = { +static const int qoa_dequant_tab[16][8] = { { 1, -1, 3, -3, 5, -5, 7, -7}, { 5, -5, 18, -18, 32, -32, 49, -49}, { 16, -16, 53, -53, 95, -95, 147, -147}, @@ -270,7 +299,21 @@ static inline int qoa_div(int v, int scalefactor) { } static inline int qoa_clamp(int v, int min, int max) { - return (v < min) ? min : (v > max) ? max : v; + if (v < min) { return min; } + if (v > max) { return max; } + return v; +} + +/* This specialized clamp function for the signed 16 bit range improves decode +performance quite a bit. The extra if() statement works nicely with the CPUs +branch prediction as this branch is rarely taken. */ + +static inline int qoa_clamp_s16(int v) { + if ((unsigned int)(v + 32768) > 65535) { + if (v < -32768) { return -32768; } + if (v > 32767) { return 32767; } + } + return v; } static inline qoa_uint64_t qoa_read_u64(const unsigned char *bytes, unsigned int *p) { @@ -312,6 +355,7 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned unsigned int p = 0; unsigned int slices = (frame_len + QOA_SLICE_LEN - 1) / QOA_SLICE_LEN; unsigned int frame_size = QOA_FRAME_SIZE(channels, slices); + int prev_scalefactor[QOA_MAX_CHANNELS] = {0}; /* Write the frame header */ qoa_write_u64(( @@ -321,8 +365,24 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned (qoa_uint64_t)frame_size ), bytes, &p); - /* Write the current LMS state */ + for (int c = 0; c < channels; c++) { + /* If the weights have grown too large, reset them to 0. This may happen + with certain high-frequency sounds. This is a last resort and will + introduce quite a bit of noise, but should at least prevent pops/clicks */ + int weights_sum = + qoa->lms[c].weights[0] * qoa->lms[c].weights[0] + + qoa->lms[c].weights[1] * qoa->lms[c].weights[1] + + qoa->lms[c].weights[2] * qoa->lms[c].weights[2] + + qoa->lms[c].weights[3] * qoa->lms[c].weights[3]; + if (weights_sum > 0x2fffffff) { + qoa->lms[c].weights[0] = 0; + qoa->lms[c].weights[1] = 0; + qoa->lms[c].weights[2] = 0; + qoa->lms[c].weights[3] = 0; + } + + /* Write the current LMS state */ qoa_uint64_t weights = 0; qoa_uint64_t history = 0; for (int i = 0; i < QOA_LMS_LEN; i++) { @@ -348,8 +408,13 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned qoa_uint64_t best_error = -1; qoa_uint64_t best_slice; qoa_lms_t best_lms; + int best_scalefactor; - for (int scalefactor = 0; scalefactor < 16; scalefactor++) { + for (int sfi = 0; sfi < 16; sfi++) { + /* There is a strong correlation between the scalefactors of + neighboring slices. As an optimization, start testing + the best scalefactor of the previous slice first. */ + int scalefactor = (sfi + prev_scalefactor[c]) % 16; /* We have to reset the LMS state to the last known good one before trying each scalefactor, as each pass updates the LMS @@ -367,7 +432,7 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned int clamped = qoa_clamp(scaled, -8, 8); int quantized = qoa_quant_tab[clamped + 8]; int dequantized = qoa_dequant_tab[scalefactor][quantized]; - int reconstructed = qoa_clamp(predicted + dequantized, -32768, 32767); + int reconstructed = qoa_clamp_s16(predicted + dequantized); long long error = (sample - reconstructed); current_error += error * error; @@ -383,9 +448,12 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned best_error = current_error; best_slice = slice; best_lms = lms; + best_scalefactor = scalefactor; } } + prev_scalefactor[c] = best_scalefactor; + qoa->lms[c] = best_lms; #ifdef QOA_RECORD_TOTAL_ERROR qoa->error += best_error; @@ -553,7 +621,7 @@ unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa int predicted = qoa_lms_predict(&qoa->lms[c]); int quantized = (slice >> 57) & 0x7; int dequantized = qoa_dequant_tab[scalefactor][quantized]; - int reconstructed = qoa_clamp(predicted + dequantized, -32768, 32767); + int reconstructed = qoa_clamp_s16(predicted + dequantized); sample_data[si] = reconstructed; slice <<= 3; diff --git a/raylib/src/external/qoaplay.c b/raylib/src/external/qoaplay.c index 7f937f4..cc4d8c6 100644 --- a/raylib/src/external/qoaplay.c +++ b/raylib/src/external/qoaplay.c @@ -36,7 +36,7 @@ // QOA streaming data descriptor typedef struct { qoa_desc info; // QOA descriptor data - + FILE *file; // QOA file to read, if NULL, using memory buffer -> file_data unsigned char *file_data; // QOA file data on memory unsigned int file_data_size; // QOA file data on memory size @@ -68,7 +68,7 @@ void qoaplay_close(qoaplay_desc *qoa_ctx); void qoaplay_rewind(qoaplay_desc *qoa_ctx); void qoaplay_seek_frame(qoaplay_desc *qoa_ctx, int frame); -unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_samples); +unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_samples, int loop_point); unsigned int qoaplay_decode_frame(qoaplay_desc *qoa_ctx); double qoaplay_get_duration(qoaplay_desc *qoa_ctx); double qoaplay_get_time(qoaplay_desc *qoa_ctx); @@ -107,7 +107,7 @@ qoaplay_desc *qoaplay_open(const char *path) unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2; qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size); memset(qoa_ctx, 0, sizeof(qoaplay_desc)); - + qoa_ctx->file = file; qoa_ctx->file_data = NULL; qoa_ctx->file_data_size = 0; @@ -209,7 +209,7 @@ void qoaplay_rewind(qoaplay_desc *qoa_ctx) } // Decode required QOA frames -unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_samples) +unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_samples, int loop_point) { int src_index = qoa_ctx->sample_data_pos*qoa_ctx->info.channels; int dst_index = 0; @@ -222,7 +222,8 @@ unsigned int qoaplay_decode(qoaplay_desc *qoa_ctx, float *sample_data, int num_s if (!qoaplay_decode_frame(qoa_ctx)) { // Loop to the beginning - qoaplay_rewind(qoa_ctx); + //qoaplay_rewind(qoa_ctx); + qoaplay_seek_frame(qoa_ctx, loop_point); qoaplay_decode_frame(qoa_ctx); } diff --git a/raylib/src/external/qoi.h b/raylib/src/external/qoi.h index 6734ac4..f2800b0 100644 --- a/raylib/src/external/qoi.h +++ b/raylib/src/external/qoi.h @@ -594,7 +594,7 @@ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) { int qoi_write(const char *filename, const void *data, const qoi_desc *desc) { FILE *f = fopen(filename, "wb"); - int size; + int size, err; void *encoded; if (!f) { @@ -608,10 +608,12 @@ int qoi_write(const char *filename, const void *data, const qoi_desc *desc) { } fwrite(encoded, 1, size, f); + fflush(f); + err = ferror(f); fclose(f); QOI_FREE(encoded); - return size; + return err ? 0 : size; } void *qoi_read(const char *filename, qoi_desc *desc, int channels) { @@ -625,11 +627,10 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) { fseek(f, 0, SEEK_END); size = ftell(f); - if (size <= 0) { + if (size <= 0 || fseek(f, 0, SEEK_SET) != 0) { fclose(f); return NULL; } - fseek(f, 0, SEEK_SET); data = QOI_MALLOC(size); if (!data) { @@ -639,8 +640,7 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) { bytes_read = fread(data, 1, size, f); fclose(f); - - pixels = qoi_decode(data, bytes_read, desc, channels); + pixels = (bytes_read != size) ? NULL : qoi_decode(data, bytes_read, desc, channels); QOI_FREE(data); return pixels; } diff --git a/raylib/src/external/rl_gputex.h b/raylib/src/external/rl_gputex.h index fa39fe2..2cbe596 100644 --- a/raylib/src/external/rl_gputex.h +++ b/raylib/src/external/rl_gputex.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* rl_gputex - GPU compressed textures loading and saving +* rl_gputex v1.0 - GPU compressed textures loading and saving * * DESCRIPTION: * @@ -261,11 +261,9 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_ } else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed { - int data_size = 0; - - // Calculate data size, including all mipmaps - if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size*2; - else data_size = header->pitch_or_linear_size; + // NOTE: This forces only 1 mipmap to be loaded which is not really correct but it works + int data_size = (header->pitch_or_linear_size < file_size - 0x80) ? header->pitch_or_linear_size : file_size - 0x80; + *mips = 1; image_data = RL_MALLOC(data_size*sizeof(unsigned char)); diff --git a/raylib/src/external/rprand.h b/raylib/src/external/rprand.h new file mode 100644 index 0000000..c9b460c --- /dev/null +++ b/raylib/src/external/rprand.h @@ -0,0 +1,305 @@ +/********************************************************************************************** +* +* rprand v1.0 - A simple and easy-to-use pseudo-random numbers generator (PRNG) +* +* FEATURES: +* - Pseudo-random values generation, 32 bits: [0..4294967295] +* - Sequence generation avoiding duplicate values +* - Using standard and proven prng algorithm (Xoshiro128**) +* - State initialized with a separate generator (SplitMix64) +* +* LIMITATIONS: +* - No negative numbers, up to the user to manage them +* +* POSSIBLE IMPROVEMENTS: +* - Support 64 bits generation +* +* ADDITIONAL NOTES: +* This library implements two pseudo-random number generation algorithms: +* +* - Xoshiro128** : https://prng.di.unimi.it/xoshiro128starstar.c +* - SplitMix64 : https://prng.di.unimi.it/splitmix64.c +* +* SplitMix64 is used to initialize the Xoshiro128** state, from a provided seed +* +* It's suggested to use SplitMix64 to initialize the state of the generators starting from +* a 64-bit seed, as research has shown that initialization must be performed with a generator +* radically different in nature from the one initialized to avoid correlation on similar seeds. +* +* CONFIGURATION: +* #define RPRAND_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* DEPENDENCIES: none +* +* VERSIONS HISTORY: +* 1.0 (01-Jun-2023) First version +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2023 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. +* +* 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. +* +**********************************************************************************************/ + +#ifndef RPRAND_H +#define RPRAND_H + +#define RPRAND_VERSION "1.0" + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +#if defined(_WIN32) + #if defined(BUILD_LIBTYPE_SHARED) + #define RPRAND __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #elif defined(USE_LIBTYPE_SHARED) + #define RPRAND __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #endif +#endif + +// Function specifiers definition +#ifndef RPRANDAPI + #define RPRANDAPI // Functions defined as 'extern' by default (implicit specifiers) +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// Allow custom memory allocators +#ifndef RPRAND_CALLOC + #define RPRAND_CALLOC(ptr,sz) calloc(ptr,sz) +#endif +#ifndef RPRAND_FREE + #define RPRAND_FREE(ptr) free(ptr) +#endif + +// Simple log system to avoid RPNG_LOG() calls if required +// NOTE: Avoiding those calls, also avoids const strings memory usage +#define RPRAND_SHOW_LOG_INFO +#if defined(RPNG_SHOW_LOG_INFO) + #define RPRAND_LOG(...) printf(__VA_ARGS__) +#else + #define RPRAND_LOG(...) +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +//... + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit +RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included + +RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates +RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence + +#ifdef __cplusplus +} +#endif + +#endif // RPRAND_H + +/*********************************************************************************** +* +* RPRAND IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RPRAND_IMPLEMENTATION) + +#include <stdlib.h> // Required for: calloc(), free(), abs() +#include <stdint.h> // Required for data types: uint32_t, uint64_t + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static uint64_t rprand_seed = 0; // SplitMix64 actual seed +static uint32_t rprand_state[4] = { 0 }; // Xoshiro128** state, nitialized by SplitMix64 + +//---------------------------------------------------------------------------------- +// Module internal functions declaration +//---------------------------------------------------------------------------------- +static uint32_t rprand_xoshiro(void); // Xoshiro128** generator (uses global rprand_state) +static uint64_t rprand_splitmix64(void); // SplitMix64 generator (uses seed to generate rprand_state) + +//---------------------------------------------------------------------------------- +// Module functions definition +//---------------------------------------------------------------------------------- +// Set rprand_state for Xoshiro128** +// NOTE: We use a custom generation algorithm using SplitMix64 +void rprand_set_seed(unsigned long long seed) +{ + rprand_seed = (uint64_t)seed; // Set SplitMix64 seed for further use + + // To generate the Xoshiro128** state, we use SplitMix64 generator first + // We generate 4 pseudo-random 64bit numbers that we combine using their LSB|MSB + rprand_state[0] = (uint32_t)(rprand_splitmix64() & 0xffffffff); + rprand_state[1] = (uint32_t)((rprand_splitmix64() & 0xffffffff00000000) >> 32); + rprand_state[2] = (uint32_t)(rprand_splitmix64() & 0xffffffff); + rprand_state[3] = (uint32_t)((rprand_splitmix64() & 0xffffffff00000000) >> 32); +} + +// Get random value within a range, min and max included +int rprand_get_value(int min, int max) +{ + int value = rprand_xoshiro()%(abs(max - min) + 1) + min; + + return value; +} + +// Load pseudo-random numbers sequence with no duplicates, min and max included +int *rprand_load_sequence(unsigned int count, int min, int max) +{ + int *sequence = NULL; + + if (count > (unsigned int)(abs(max - min) + 1)) + { + RPRAND_LOG("WARNING: Sequence count required is greater than range provided\n"); + //count = (max - min); + return sequence; + } + + sequence = (int *)RPRAND_CALLOC(count, sizeof(int)); + + int value = 0; + bool value_is_dup = false; + + for (unsigned int i = 0; i < count;) + { + value = ((int)rprand_xoshiro()%(abs(max - min) + 1)) + min; + value_is_dup = false; + + for (int j = 0; j < i; j++) + { + if (sequence[j] == value) + { + value_is_dup = true; + break; + } + } + + if (!value_is_dup) + { + sequence[i] = value; + i++; + } + } + + return sequence; +} + +// Unload pseudo-random numbers sequence +void rprand_unload_sequence(int *sequence) +{ + RPRAND_FREE(sequence); + sequence = NULL; +} + +//---------------------------------------------------------------------------------- +// Module internal functions definition +//---------------------------------------------------------------------------------- +static inline uint32_t rprand_rotate_left(const uint32_t x, int k) +{ + return (x << k) | (x >> (32 - k)); +} + +// Xoshiro128** generator info: +// +// Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) +// +// To the extent possible under law, the author has dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// +// See <http://creativecommons.org/publicdomain/zero/1.0/>. +// +// This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid +// generators. It has excellent speed, a state size (128 bits) that is +// large enough for mild parallelism, and it passes all tests we are aware +// of. +// +// Note that version 1.0 had mistakenly s[0] instead of s[1] as state +// word passed to the scrambler. +// +// For generating just single-precision (i.e., 32-bit) floating-point +// numbers, xoshiro128+ is even faster. +// +// The state must be seeded so that it is not everywhere zero. +// +uint32_t rprand_xoshiro(void) +{ + const uint32_t result = rprand_rotate_left(rprand_state[1]*5, 7)*9; + const uint32_t t = rprand_state[1] << 9; + + rprand_state[2] ^= rprand_state[0]; + rprand_state[3] ^= rprand_state[1]; + rprand_state[1] ^= rprand_state[2]; + rprand_state[0] ^= rprand_state[3]; + + rprand_state[2] ^= t; + + rprand_state[3] = rprand_rotate_left(rprand_state[3], 11); + + return result; +} + +// SplitMix64 generator info: +// +// Written in 2015 by Sebastiano Vigna (vigna@acm.org) +// +// To the extent possible under law, the author has dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// +// See <http://creativecommons.org/publicdomain/zero/1.0/>. +// +// +// This is a fixed-increment version of Java 8's SplittableRandom generator +// See http://dx.doi.org/10.1145/2714064.2660195 and +// http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html +// +// It is a very fast generator passing BigCrush, and it can be useful if +// for some reason you absolutely want 64 bits of state. +uint64_t rprand_splitmix64() +{ + uint64_t z = (rprand_seed += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30))*0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27))*0x94d049bb133111eb; + return z ^ (z >> 31); +} + +#endif // RPRAND_IMPLEMENTATION
\ No newline at end of file diff --git a/raylib/src/external/sinfl.h b/raylib/src/external/sinfl.h index 8979fcd..16589c1 100644 --- a/raylib/src/external/sinfl.h +++ b/raylib/src/external/sinfl.h @@ -122,6 +122,7 @@ extern "C" { struct sinfl { const unsigned char *bitptr; + const unsigned char *bitend; // @raysan5: added unsigned long long bitbuf; int bitcnt; @@ -185,9 +186,10 @@ sinfl_read64(const void *p) { } static void sinfl_copy64(unsigned char **dst, unsigned char **src) { - unsigned long long n; - memcpy(&n, *src, 8); - memcpy(*dst, &n, 8); + //unsigned long long n; + //memcpy(&n, *src, 8); + //memcpy(*dst, &n, 8); + memcpy(*dst, *src, 8); // @raysan5 *dst += 8, *src += 8; } static unsigned char* @@ -210,9 +212,22 @@ sinfl_copy128(unsigned char **dst, unsigned char **src) { #endif static void sinfl_refill(struct sinfl *s) { - s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt; - s->bitptr += (63 - s->bitcnt) >> 3; - s->bitcnt |= 56; /* bitcount in range [56,63] */ + if (s->bitend - s->bitptr >= 8) { + // @raysan5: original code, only those 3 lines + s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt; + s->bitptr += (63 - s->bitcnt) >> 3; + s->bitcnt |= 56; /* bitcount in range [56,63] */ + } else { + // @raysan5: added this case when bits remaining < 8 + int bitswant = 63 - s->bitcnt; + int byteswant = bitswant >> 3; + int bytesuse = s->bitend - s->bitptr <= byteswant ? (int)(s->bitend - s->bitptr) : byteswant; + unsigned long long n = 0; + memcpy(&n, s->bitptr, bytesuse); + s->bitbuf |= n << s->bitcnt; + s->bitptr += bytesuse; + s->bitcnt += bytesuse << 3; + } } static int sinfl_peek(struct sinfl *s, int cnt) { @@ -384,6 +399,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) int last = 0; s.bitptr = in; + s.bitend = e; // @raysan5: added while (1) { switch (state) { case hdr: { diff --git a/raylib/src/external/tinyobj_loader_c.h b/raylib/src/external/tinyobj_loader_c.h index 502a55a..55d595a 100644 --- a/raylib/src/external/tinyobj_loader_c.h +++ b/raylib/src/external/tinyobj_loader_c.h @@ -1269,6 +1269,11 @@ int tinyobj_parse_obj(tinyobj_attrib_t *attrib, tinyobj_shape_t **shapes, if (is_line_ending(buf, i, end_idx)) { line_infos[line_no].pos = prev_pos; line_infos[line_no].len = i - prev_pos; + +// ---- QUICK BUG FIX : https://github.com/raysan5/raylib/issues/3473 + if ( i > 0 && buf[i-1] == '\r' ) line_infos[line_no].len--; +// -------- + prev_pos = i + 1; line_no++; } diff --git a/raylib/src/minshell.html b/raylib/src/minshell.html index 2aa7557..38f3672 100644 --- a/raylib/src/minshell.html +++ b/raylib/src/minshell.html @@ -8,24 +8,27 @@ <meta name="title" content="raylib web game"> <meta name="description" content="New raylib web videogame, developed using raylib videogames library"> - <meta name="keywords" content="raylib, games, html5, programming, C, C++, library, learn, videogames"> + <meta name="keywords" content="raylib, programming, examples, html5, C, C++, library, learn, games, videogames"> <meta name="viewport" content="width=device-width"> <!-- Open Graph metatags for sharing --> + <meta property="og:type" content="website" /> <meta property="og:title" content="raylib web game"> <meta property="og:image:type" content="image/png"> - <meta property="og:image" content="https://www.raylib.com/common/img/raylib_logo.png"> - <meta property="og:site_name" content="raylib.com"> + <meta property="og:image" content="https://www.raylib.com/common/raylib_logo.png"> + <meta property="og:image:alt" content="New raylib web videogame, developed using raylib videogames library" /> + <meta property="og:site_name" content="raylib - example"> <meta property="og:url" content="https://www.raylib.com/games.html"> <meta property="og:description" content="New raylib web videogame, developed using raylib videogames library"> <!-- Twitter metatags for sharing --> - <meta name="twitter:card" content="summary"> + <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="@raysan5"> <meta name="twitter:title" content="raylib web game"> <meta name="twitter:image" content="https://www.raylib.com/common/raylib_logo.png"> + <meta name="twitter:image:alt" content="New raylib web videogame, developed using raylib videogames library"> <meta name="twitter:url" content="https://www.raylib.com/games.html"> - <meta name="twitter:description" content="New raylib web game, developed using raylib videogames library"> + <meta name="twitter:description" content="New raylib web videogame, developed using raylib videogames library"> <!-- Favicon --> <link rel="shortcut icon" href="https://www.raylib.com/favicon.ico"> diff --git a/raylib/src/rcore_android.c b/raylib/src/platforms/rcore_android.c index 98ce64a..5d6f7d5 100644 --- a/raylib/src/rcore_android.c +++ b/raylib/src/platforms/rcore_android.c @@ -21,8 +21,8 @@ * Custom flag for rcore on target platform -not used- * * DEPENDENCIES: -* Android NDK - Provides C API to access Android functionality -* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) +* - Android NDK: Provides C API to access Android functionality +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) * * * LICENSE: zlib/libpng @@ -46,8 +46,6 @@ * **********************************************************************************************/ -#include "rcore.h" - #include <android_native_app_glue.h> // Required for: android_app struct and activity management #include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others //#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...) @@ -82,8 +80,8 @@ static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- -static int InitPlatform(void); // Initialize platform (graphics, inputs and more) -static void ClosePlatform(void); // Close platform +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +void ClosePlatform(void); // Close platform static void AndroidCommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs @@ -138,96 +136,6 @@ struct android_app *GetAndroidApp(void) // Module Functions Definition: Window and Graphics Device //---------------------------------------------------------------------------------- -// Initialize window and OpenGL context -// NOTE: data parameter could be used to pass any kind of required data to the initialization -void InitWindow(int width, int height, const char *title) -{ - TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); - - TRACELOG(LOG_INFO, "Supported raylib modules:"); - TRACELOG(LOG_INFO, " > rcore:..... loaded (mandatory)"); - TRACELOG(LOG_INFO, " > rlgl:...... loaded (mandatory)"); -#if defined(SUPPORT_MODULE_RSHAPES) - TRACELOG(LOG_INFO, " > rshapes:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rshapes:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXTURES) - TRACELOG(LOG_INFO, " > rtextures:. loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtextures:. not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXT) - TRACELOG(LOG_INFO, " > rtext:..... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtext:..... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RMODELS) - TRACELOG(LOG_INFO, " > rmodels:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rmodels:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RAUDIO) - TRACELOG(LOG_INFO, " > raudio:.... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); -#endif - - // Initialize window data - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; - CORE.Window.eventWaiting = false; - CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default - if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; - - // Initialize global input state - memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0 - CORE.Input.Keyboard.exitKey = KEY_ESCAPE; - CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; - CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; - CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; - - // Initialize platform - //-------------------------------------------------------------- - InitPlatform(); - //-------------------------------------------------------------- -} - -// Close window and unload OpenGL context -void CloseWindow(void) -{ -#if defined(SUPPORT_GIF_RECORDING) - if (gifRecording) - { - MsfGifResult result = msf_gif_end(&gifState); - msf_gif_free(result); - gifRecording = false; - } -#endif - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - UnloadFontDefault(); // WARNING: Module required: rtext -#endif - - rlglClose(); // De-init rlgl - -#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP) - timeEndPeriod(1); // Restore time period -#endif - - // De-initialize platform - //-------------------------------------------------------------- - ClosePlatform(); - //-------------------------------------------------------------- - -#if defined(SUPPORT_EVENTS_AUTOMATION) - RL_FREE(events); -#endif - - CORE.Window.ready = false; - TRACELOG(LOG_INFO, "Window closed successfully"); -} - // Check if application should close bool WindowShouldClose(void) { @@ -608,8 +516,10 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Initialize platform: graphics, inputs and more -static int InitPlatform(void) +int InitPlatform(void) { + // Initialize display basic configuration + //---------------------------------------------------------------------------- CORE.Window.currentFbo.width = CORE.Window.screen.width; CORE.Window.currentFbo.height = CORE.Window.screen.height; @@ -638,26 +548,32 @@ static int InitPlatform(void) //AConfiguration_getScreenSize(platform.app->config); //AConfiguration_getScreenLong(platform.app->config); + // Set some default window flags + CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false + CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false + CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true + CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false + //---------------------------------------------------------------------------- + // Initialize App command system // NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()... + //---------------------------------------------------------------------------- platform.app->onAppCmd = AndroidCommandCallback; + //---------------------------------------------------------------------------- // Initialize input events system + //---------------------------------------------------------------------------- platform.app->onInputEvent = AndroidInputCallback; + //---------------------------------------------------------------------------- - // Initialize assets manager - InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath); + // Initialize storage system + //---------------------------------------------------------------------------- + InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath); // Initialize assets manager - // Initialize base path for storage - CORE.Storage.basePath = platform.app->activity->internalDataPath; + CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage + //---------------------------------------------------------------------------- - // Set some default window flags - CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false - CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false - - TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully"); + TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Initialized successfully"); // Android ALooper_pollAll() variables int pollResult = 0; @@ -681,7 +597,7 @@ static int InitPlatform(void) } // Close platform -static void ClosePlatform(void) +void ClosePlatform(void) { // Close surface, context and display if (platform.device != EGL_NO_DISPLAY) @@ -869,7 +785,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Initialize graphics device (display device and OpenGL context) InitGraphicsDevice(); - + // Initialize OpenGL context (states and resources) // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); @@ -908,7 +824,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes #endif #endif - + // Initialize random seed SetRandomSeed((unsigned int)time(NULL)); diff --git a/raylib/src/rcore_desktop.c b/raylib/src/platforms/rcore_desktop.c index 4039bbd..05c390f 100644 --- a/raylib/src/rcore_desktop.c +++ b/raylib/src/platforms/rcore_desktop.c @@ -6,7 +6,7 @@ * - Windows (Win32, Win64) * - Linux (X11/Wayland desktop mode) * - FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop) -* - OSX/macOS +* - OSX/macOS (x64, arm64) * * LIMITATIONS: * - Limitation 01 @@ -24,8 +24,8 @@ * Custom flag for rcore on target platform -not used- * * DEPENDENCIES: -* rglfw - Manage graphic device, OpenGL context and inputs (Windows, Linux, OSX, FreeBSD...) -* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) +* - rglfw: Manage graphic device, OpenGL context and inputs (Windows, Linux, OSX, FreeBSD...) +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) * * * LICENSE: zlib/libpng @@ -111,8 +111,8 @@ static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- -static int InitPlatform(void); // Initialize platform (graphics, inputs and more) -static void ClosePlatform(void); // Close platform +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +void ClosePlatform(void); // Close platform // Error callback event static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error @@ -142,162 +142,11 @@ static void JoystickCallback(int jid, int event); // Module Functions Definition: Window and Graphics Device //---------------------------------------------------------------------------------- -// Initialize window and OpenGL context -// NOTE: data parameter could be used to pass any kind of required data to the initialization -void InitWindow(int width, int height, const char *title) -{ - TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); - - TRACELOG(LOG_INFO, "Supported raylib modules:"); - TRACELOG(LOG_INFO, " > rcore:..... loaded (mandatory)"); - TRACELOG(LOG_INFO, " > rlgl:...... loaded (mandatory)"); -#if defined(SUPPORT_MODULE_RSHAPES) - TRACELOG(LOG_INFO, " > rshapes:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rshapes:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXTURES) - TRACELOG(LOG_INFO, " > rtextures:. loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtextures:. not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXT) - TRACELOG(LOG_INFO, " > rtext:..... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtext:..... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RMODELS) - TRACELOG(LOG_INFO, " > rmodels:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rmodels:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RAUDIO) - TRACELOG(LOG_INFO, " > raudio:.... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); -#endif - - // Initialize window data - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; - CORE.Window.eventWaiting = false; - CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default - if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; - - // Initialize global input state - memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0 - CORE.Input.Keyboard.exitKey = KEY_ESCAPE; - CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; - CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; - CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; - - // Initialize platform - //-------------------------------------------------------------- - InitPlatform(); - //-------------------------------------------------------------- - - // Initialize rlgl default data (buffers and shaders) - // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl - rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - - // Setup default viewport - SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - // Load default font - // WARNING: External function: Module required: rtext - LoadFontDefault(); - #if defined(SUPPORT_MODULE_RSHAPES) - // Set font white rectangle for shapes drawing, so shapes and text can be batched together - // WARNING: rshapes module is required, if not available, default internal white rectangle is used - Rectangle rec = GetFontDefault().recs[95]; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) - { - // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering - SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); - } - else - { - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding - SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); - } - #endif -#else - #if defined(SUPPORT_MODULE_RSHAPES) - // Set default texture and rectangle to be used for shapes drawing - // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 - Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; - SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes - #endif -#endif -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) - { - // Set default font texture filter for HighDPI (blurry) - // RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR); - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR); - } -#endif - -#if defined(SUPPORT_EVENTS_AUTOMATION) - events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent)); - CORE.Time.frameCounter = 0; -#endif - - // Initialize random seed - SetRandomSeed((unsigned int)time(NULL)); - - TRACELOG(LOG_INFO, "PLATFORM: DESKTOP: Application initialized successfully"); -} - -// Close window and unload OpenGL context -void CloseWindow(void) -{ -#if defined(SUPPORT_GIF_RECORDING) - if (gifRecording) - { - MsfGifResult result = msf_gif_end(&gifState); - msf_gif_free(result); - gifRecording = false; - } -#endif - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - UnloadFontDefault(); // WARNING: Module required: rtext -#endif - - rlglClose(); // De-init rlgl - - // De-initialize platform - //-------------------------------------------------------------- - ClosePlatform(); - //-------------------------------------------------------------- - -#if defined(SUPPORT_EVENTS_AUTOMATION) - RL_FREE(events); -#endif - - CORE.Window.ready = false; - TRACELOG(LOG_INFO, "Window closed successfully"); -} - // Check if application should close // NOTE: By default, if KEY_ESCAPE pressed or window close icon clicked bool WindowShouldClose(void) { - if (CORE.Window.ready) - { - // While window minimized, stop loop execution - while (IsWindowState(FLAG_WINDOW_MINIMIZED) && !IsWindowState(FLAG_WINDOW_ALWAYS_RUN)) glfwWaitEvents(); - - CORE.Window.shouldClose = glfwWindowShouldClose(platform.handle); - - // Reset close status for next frame - glfwSetWindowShouldClose(platform.handle, GLFW_FALSE); - - return CORE.Window.shouldClose; - } + if (CORE.Window.ready) return CORE.Window.shouldClose; else return true; } @@ -800,12 +649,12 @@ void SetWindowMinSize(int width, int height) { CORE.Window.screenMin.width = width; CORE.Window.screenMin.height = height; - + int minWidth = (CORE.Window.screenMin.width == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMin.width; int minHeight = (CORE.Window.screenMin.height == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMin.height; int maxWidth = (CORE.Window.screenMax.width == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMax.width; int maxHeight = (CORE.Window.screenMax.height == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMax.height; - + glfwSetWindowSizeLimits(platform.handle, minWidth, minHeight, maxWidth, maxHeight); } @@ -814,12 +663,12 @@ void SetWindowMaxSize(int width, int height) { CORE.Window.screenMax.width = width; CORE.Window.screenMax.height = height; - + int minWidth = (CORE.Window.screenMin.width == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMin.width; int minHeight = (CORE.Window.screenMin.height == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMin.height; int maxWidth = (CORE.Window.screenMax.width == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMax.width; int maxHeight = (CORE.Window.screenMax.height == 0)? GLFW_DONT_CARE : (int)CORE.Window.screenMax.height; - + glfwSetWindowSizeLimits(platform.handle, minWidth, minHeight, maxWidth, maxHeight); } @@ -902,13 +751,24 @@ int GetCurrentMonitor(void) } else { - int x = 0; - int y = 0; + // In case the window is between two monitors, we use below logic + // to try to detect the "current monitor" for that window, note that + // this is probably an overengineered solution for a very side case + // trying to match SDL behaviour + + int closestDist = 0x7FFFFFFF; - glfwGetWindowPos(platform.handle, &x, &y); + // Window center position + int wcx = 0; + int wcy = 0; + + glfwGetWindowPos(platform.handle, &wcx, &wcy); + wcx += (int)CORE.Window.screen.width/2; + wcy += (int)CORE.Window.screen.height/2; for (int i = 0; i < monitorCount; i++) { + // Monitor top-left position int mx = 0; int my = 0; @@ -918,17 +778,34 @@ int GetCurrentMonitor(void) if (mode) { - const int width = mode->width; - const int height = mode->height; + const int right = mx + mode->width - 1; + const int bottom = my + mode->height - 1; - if ((x >= mx) && - (x < (mx + width)) && - (y >= my) && - (y < (my + height))) + if ((wcx >= mx) && + (wcx <= right) && + (wcy >= my) && + (wcy <= bottom)) { index = i; break; } + + int xclosest = wcx; + if (wcx < mx) xclosest = mx; + else if (wcx > right) xclosest = right; + + int yclosest = wcy; + if (wcy < my) yclosest = my; + else if (wcy > bottom) yclosest = bottom; + + int dx = wcx - xclosest; + int dy = wcy - yclosest; + int dist = (dx*dx) + (dy*dy); + if (dist < closestDist) + { + index = i; + closestDist = dist; + } } else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor"); } @@ -1229,12 +1106,11 @@ void PollInputEvents(void) // Reset keys/chars pressed registered 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; + // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) // Register previous keys states @@ -1259,7 +1135,7 @@ void PollInputEvents(void) // Reset touch positions //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! // TODO: GLFW does not support multi-touch input just yet @@ -1348,7 +1224,15 @@ void PollInputEvents(void) CORE.Window.resizedLastFrame = false; if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused) - else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) + else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) -> Update keys state + + // While window minimized, stop loop execution + while (IsWindowState(FLAG_WINDOW_MINIMIZED) && !IsWindowState(FLAG_WINDOW_ALWAYS_RUN)) glfwWaitEvents(); + + CORE.Window.shouldClose = glfwWindowShouldClose(platform.handle); + + // Reset close status for next frame + glfwSetWindowShouldClose(platform.handle, GLFW_FALSE); } @@ -1357,7 +1241,7 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Initialize platform: graphics, inputs and more -static int InitPlatform(void) +int InitPlatform(void) { glfwSetErrorCallback(ErrorCallback); /* @@ -1379,6 +1263,8 @@ static int InitPlatform(void) int result = glfwInit(); if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; } + // Initialize graphic device: display/window and graphic context + //---------------------------------------------------------------------------- glfwDefaultWindowHints(); // Set default windows hints //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits //glfwWindowHint(GLFW_GREEN_BITS, 8); // Framebuffer green color component bits @@ -1492,7 +1378,7 @@ static int InitPlatform(void) // Forcing this initialization here avoids doing it on PollInputEvents() called by EndDrawing() after first frame has been just drawn. // The initialization will still happen and possible delays still occur, but before the window is shown, which is a nicer experience. // REF: https://github.com/raysan5/raylib/issues/1554 - if (MAX_GAMEPADS > 0) glfwSetJoystickCallback(NULL); + glfwSetJoystickCallback(NULL); // Find monitor resolution GLFWmonitor *monitor = glfwGetPrimaryMonitor(); @@ -1547,6 +1433,7 @@ static int InitPlatform(void) } } } + TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height); // NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example, @@ -1591,6 +1478,74 @@ static int InitPlatform(void) return -1; } + glfwMakeContextCurrent(platform.handle); + result = glfwGetError(NULL); + + // Check context activation + if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR)) + { + CORE.Window.ready = true; + + glfwSwapInterval(0); // No V-Sync by default + + // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) + // NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need + // to be activated on web platforms since VSync is enforced there. + if (CORE.Window.flags & FLAG_VSYNC_HINT) + { + // WARNING: It seems to hit a critical render path in Intel HD Graphics + glfwSwapInterval(1); + TRACELOG(LOG_INFO, "DISPLAY: Trying to enable VSYNC"); + } + + int fbWidth = CORE.Window.screen.width; + int fbHeight = CORE.Window.screen.height; + + if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + { + // NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling. + // Framebuffer scaling should be activated with: glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE); + #if !defined(__APPLE__) + glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); + + // Screen scaling matrix is required in case desired screen area is different from display area + CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f); + + // Mouse input scaling for the new screen size + SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); + #endif + } + + CORE.Window.render.width = fbWidth; + CORE.Window.render.height = fbHeight; + CORE.Window.currentFbo.width = fbWidth; + CORE.Window.currentFbo.height = fbHeight; + + 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 ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + + // 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); + + // Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + rlLoadExtensions(glfwGetProcAddress); + //---------------------------------------------------------------------------- + + // Initialize input events callbacks + //---------------------------------------------------------------------------- // Set window callback events glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default! glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback); @@ -1607,74 +1562,32 @@ static int InitPlatform(void) glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback); glfwSetJoystickCallback(JoystickCallback); - glfwMakeContextCurrent(platform.handle); - glfwSetInputMode(platform.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM) - glfwSwapInterval(0); // No V-Sync by default - - // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) - // NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need - // to be activated on web platforms since VSync is enforced there. - if (CORE.Window.flags & FLAG_VSYNC_HINT) - { - // WARNING: It seems to hit a critical render path in Intel HD Graphics - glfwSwapInterval(1); - TRACELOG(LOG_INFO, "DISPLAY: Trying to enable VSYNC"); - } - - int fbWidth = CORE.Window.screen.width; - int fbHeight = CORE.Window.screen.height; - - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + // Retrieve gamepad names + for (int i = 0; i < MAX_GAMEPADS; i++) { - // NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling. - // Framebuffer scaling should be activated with: glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE); -#if !defined(__APPLE__) - glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); - - // Screen scaling matrix is required in case desired screen area is different from display area - CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f); - - // Mouse input scaling for the new screen size - SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); -#endif + if (glfwJoystickPresent(i)) strcpy(CORE.Input.Gamepad.name[i], glfwGetJoystickName(i)); } + //---------------------------------------------------------------------------- - CORE.Window.render.width = fbWidth; - CORE.Window.render.height = fbHeight; - CORE.Window.currentFbo.width = fbWidth; - CORE.Window.currentFbo.height = fbHeight; - - 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); - - // Load OpenGL extensions - // NOTE: GL procedures address loader is required to load extensions - rlLoadExtensions(glfwGetProcAddress); + // Initialize timming system + //---------------------------------------------------------------------------- + InitTimer(); + //---------------------------------------------------------------------------- - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + // Initialize storage system + //---------------------------------------------------------------------------- + CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- - CORE.Window.ready = true; // TODO: Proper validation on windows/context creation - - // 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); + TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully"); - // Initialize hi-res timer - InitTimer(); - - // Initialize base path for storage - CORE.Storage.basePath = GetWorkingDirectory(); - return 0; } // Close platform -static void ClosePlatform(void) +void ClosePlatform(void) { glfwDestroyWindow(platform.handle); glfwTerminate(); @@ -1684,7 +1597,6 @@ static void ClosePlatform(void) #endif } - // GLFW3 Error Callback, runs on GLFW3 error static void ErrorCallback(int error, const char *description) { @@ -1800,61 +1712,6 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i // Check the exit key to set close window if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE); - -#if defined(SUPPORT_SCREEN_CAPTURE) - if ((key == GLFW_KEY_F12) && (action == GLFW_PRESS)) - { -#if defined(SUPPORT_GIF_RECORDING) - if (mods & GLFW_MOD_CONTROL) - { - if (gifRecording) - { - gifRecording = false; - - MsfGifResult result = msf_gif_end(&gifState); - - SaveFileData(TextFormat("%s/screenrec%03i.gif", CORE.Storage.basePath, screenshotCounter), result.data, (unsigned int)result.dataSize); - msf_gif_free(result); - - TRACELOG(LOG_INFO, "SYSTEM: Finish animated GIF recording"); - } - else - { - gifRecording = true; - gifFrameCounter = 0; - - Vector2 scale = GetWindowScaleDPI(); - msf_gif_begin(&gifState, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); - screenshotCounter++; - - TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter)); - } - } - else -#endif // SUPPORT_GIF_RECORDING - { - TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); - screenshotCounter++; - } - } -#endif // SUPPORT_SCREEN_CAPTURE - -#if defined(SUPPORT_EVENTS_AUTOMATION) - if ((key == GLFW_KEY_F11) && (action == GLFW_PRESS)) - { - eventsRecording = !eventsRecording; - - // On finish recording, we export events into a file - if (!eventsRecording) ExportAutomationEvents("eventsrec.rep"); - } - else if ((key == GLFW_KEY_F9) && (action == GLFW_PRESS)) - { - LoadAutomationEvents("eventsrec.rep"); - eventsPlaying = true; - - TRACELOG(LOG_WARNING, "eventsPlaying enabled!"); - } -#endif } // GLFW3 Char Key Callback, runs on key down (gets equivalent unicode char value) @@ -1908,7 +1765,6 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int // Gesture data is sent to gestures-system for processing ProcessGestureEvent(gestureEvent); - #endif } diff --git a/raylib/src/platforms/rcore_desktop_sdl.c b/raylib/src/platforms/rcore_desktop_sdl.c new file mode 100644 index 0000000..96e5570 --- /dev/null +++ b/raylib/src/platforms/rcore_desktop_sdl.c @@ -0,0 +1,1391 @@ +/********************************************************************************************** +* +* rcore_desktop_sdl - Functions to manage window, graphics device and inputs +* +* PLATFORM: DESKTOP: SDL +* - Windows (Win32, Win64) +* - Linux (X11/Wayland desktop mode) +* - Others (not tested) +* +* 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: +* - SDL 2 (main library): Windowing and inputs management +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2013-2023 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. +* +* 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. +* +**********************************************************************************************/ + +#include "SDL.h" // SDL base library (window/rendered, input, timming... functionality) +#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct { + SDL_Window *window; + SDL_GLContext glContext; + + SDL_Joystick *gamepad; + SDL_Cursor *cursor; + bool cursorRelative; +} PlatformData; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +extern CoreData CORE; // Global CORE state context + +static PlatformData platform = { 0 }; // Platform specific data + +//---------------------------------------------------------------------------------- +// Local Variables Definition +//---------------------------------------------------------------------------------- +#define SCANCODE_MAPPED_NUM 232 +static const KeyboardKey ScancodeToKey[SCANCODE_MAPPED_NUM] = { + KEY_NULL, // SDL_SCANCODE_UNKNOWN + 0, + 0, + 0, + KEY_A, // SDL_SCANCODE_A + KEY_B, // SDL_SCANCODE_B + KEY_C, // SDL_SCANCODE_C + KEY_D, // SDL_SCANCODE_D + KEY_E, // SDL_SCANCODE_E + KEY_F, // SDL_SCANCODE_F + KEY_G, // SDL_SCANCODE_G + KEY_H, // SDL_SCANCODE_H + KEY_I, // SDL_SCANCODE_I + KEY_J, // SDL_SCANCODE_J + KEY_K, // SDL_SCANCODE_K + KEY_L, // SDL_SCANCODE_L + KEY_M, // SDL_SCANCODE_M + KEY_N, // SDL_SCANCODE_N + KEY_O, // SDL_SCANCODE_O + KEY_P, // SDL_SCANCODE_P + KEY_Q, // SDL_SCANCODE_Q + KEY_R, // SDL_SCANCODE_R + KEY_S, // SDL_SCANCODE_S + KEY_T, // SDL_SCANCODE_T + KEY_U, // SDL_SCANCODE_U + KEY_V, // SDL_SCANCODE_V + KEY_W, // SDL_SCANCODE_W + KEY_X, // SDL_SCANCODE_X + KEY_Y, // SDL_SCANCODE_Y + KEY_Z, // SDL_SCANCODE_Z + KEY_ONE, // SDL_SCANCODE_1 + KEY_TWO, // SDL_SCANCODE_2 + KEY_THREE, // SDL_SCANCODE_3 + KEY_FOUR, // SDL_SCANCODE_4 + KEY_FIVE, // SDL_SCANCODE_5 + KEY_SIX, // SDL_SCANCODE_6 + KEY_SEVEN, // SDL_SCANCODE_7 + KEY_EIGHT, // SDL_SCANCODE_8 + KEY_NINE, // SDL_SCANCODE_9 + KEY_ZERO, // SDL_SCANCODE_0 + KEY_ENTER, // SDL_SCANCODE_RETURN + KEY_ESCAPE, // SDL_SCANCODE_ESCAPE + KEY_BACKSPACE, // SDL_SCANCODE_BACKSPACE + KEY_TAB, // SDL_SCANCODE_TAB + KEY_SPACE, // SDL_SCANCODE_SPACE + KEY_MINUS, // SDL_SCANCODE_MINUS + KEY_EQUAL, // SDL_SCANCODE_EQUALS + KEY_LEFT_BRACKET, // SDL_SCANCODE_LEFTBRACKET + KEY_RIGHT_BRACKET, // SDL_SCANCODE_RIGHTBRACKET + KEY_BACKSLASH, // SDL_SCANCODE_BACKSLASH + 0, // SDL_SCANCODE_NONUSHASH + KEY_SEMICOLON, // SDL_SCANCODE_SEMICOLON + KEY_APOSTROPHE, // SDL_SCANCODE_APOSTROPHE + KEY_GRAVE, // SDL_SCANCODE_GRAVE + KEY_COMMA, // SDL_SCANCODE_COMMA + KEY_PERIOD, // SDL_SCANCODE_PERIOD + KEY_SLASH, // SDL_SCANCODE_SLASH + KEY_CAPS_LOCK, // SDL_SCANCODE_CAPSLOCK + KEY_F1, // SDL_SCANCODE_F1 + KEY_F2, // SDL_SCANCODE_F2 + KEY_F3, // SDL_SCANCODE_F3 + KEY_F4, // SDL_SCANCODE_F4 + KEY_F5, // SDL_SCANCODE_F5 + KEY_F6, // SDL_SCANCODE_F6 + KEY_F7, // SDL_SCANCODE_F7 + KEY_F8, // SDL_SCANCODE_F8 + KEY_F9, // SDL_SCANCODE_F9 + KEY_F10, // SDL_SCANCODE_F10 + KEY_F11, // SDL_SCANCODE_F11 + KEY_F12, // SDL_SCANCODE_F12 + KEY_PRINT_SCREEN, // SDL_SCANCODE_PRINTSCREEN + KEY_SCROLL_LOCK, // SDL_SCANCODE_SCROLLLOCK + KEY_PAUSE, // SDL_SCANCODE_PAUSE + KEY_INSERT, // SDL_SCANCODE_INSERT + KEY_HOME, // SDL_SCANCODE_HOME + KEY_PAGE_UP, // SDL_SCANCODE_PAGEUP + KEY_DELETE, // SDL_SCANCODE_DELETE + KEY_END, // SDL_SCANCODE_END + KEY_PAGE_DOWN, // SDL_SCANCODE_PAGEDOWN + KEY_RIGHT, // SDL_SCANCODE_RIGHT + KEY_LEFT, // SDL_SCANCODE_LEFT + KEY_DOWN, // SDL_SCANCODE_DOWN + KEY_UP, // SDL_SCANCODE_UP + KEY_NUM_LOCK, // SDL_SCANCODE_NUMLOCKCLEAR + KEY_KP_DIVIDE, // SDL_SCANCODE_KP_DIVIDE + KEY_KP_MULTIPLY, // SDL_SCANCODE_KP_MULTIPLY + KEY_KP_SUBTRACT, // SDL_SCANCODE_KP_MINUS + KEY_KP_ADD, // SDL_SCANCODE_KP_PLUS + KEY_KP_ENTER, // SDL_SCANCODE_KP_ENTER + KEY_KP_1, // SDL_SCANCODE_KP_1 + KEY_KP_2, // SDL_SCANCODE_KP_2 + KEY_KP_3, // SDL_SCANCODE_KP_3 + KEY_KP_4, // SDL_SCANCODE_KP_4 + KEY_KP_5, // SDL_SCANCODE_KP_5 + KEY_KP_6, // SDL_SCANCODE_KP_6 + KEY_KP_7, // SDL_SCANCODE_KP_7 + KEY_KP_8, // SDL_SCANCODE_KP_8 + KEY_KP_9, // SDL_SCANCODE_KP_9 + KEY_KP_0, // SDL_SCANCODE_KP_0 + KEY_KP_DECIMAL, // SDL_SCANCODE_KP_PERIOD + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + KEY_LEFT_CONTROL, //SDL_SCANCODE_LCTRL + KEY_LEFT_SHIFT, //SDL_SCANCODE_LSHIFT + KEY_LEFT_ALT, //SDL_SCANCODE_LALT + KEY_LEFT_SUPER, //SDL_SCANCODE_LGUI + KEY_RIGHT_CONTROL, //SDL_SCANCODE_RCTRL + KEY_RIGHT_SHIFT, //SDL_SCANCODE_RSHIFT + KEY_RIGHT_ALT, //SDL_SCANCODE_RALT + KEY_RIGHT_SUPER //SDL_SCANCODE_RGUI +}; + +static const int CursorsLUT[] = { + SDL_SYSTEM_CURSOR_ARROW, // 0 MOUSE_CURSOR_DEFAULT + SDL_SYSTEM_CURSOR_ARROW, // 1 MOUSE_CURSOR_ARROW + SDL_SYSTEM_CURSOR_IBEAM, // 2 MOUSE_CURSOR_IBEAM + SDL_SYSTEM_CURSOR_CROSSHAIR, // 3 MOUSE_CURSOR_CROSSHAIR + SDL_SYSTEM_CURSOR_HAND, // 4 MOUSE_CURSOR_POINTING_HAND + SDL_SYSTEM_CURSOR_SIZEWE, // 5 MOUSE_CURSOR_RESIZE_EW + SDL_SYSTEM_CURSOR_SIZENS, // 6 MOUSE_CURSOR_RESIZE_NS + SDL_SYSTEM_CURSOR_SIZENWSE, // 7 MOUSE_CURSOR_RESIZE_NWSE + SDL_SYSTEM_CURSOR_SIZENESW, // 8 MOUSE_CURSOR_RESIZE_NESW + SDL_SYSTEM_CURSOR_SIZEALL, // 9 MOUSE_CURSOR_RESIZE_ALL + SDL_SYSTEM_CURSOR_NO // 10 MOUSE_CURSOR_NOT_ALLOWED + //SDL_SYSTEM_CURSOR_WAIT, // No equivalent implemented on MouseCursor enum on raylib.h + //SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h +}; + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +void ClosePlatform(void); // Close platform + +static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode); // Help convert SDL scancodes to raylib key + +//---------------------------------------------------------------------------------- +// 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.ready) return CORE.Window.shouldClose; + else return true; +} + +// Toggle fullscreen mode +void ToggleFullscreen(void) +{ + const int monitor = SDL_GetWindowDisplayIndex(platform.window); + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) + { + SDL_SetWindowFullscreen(platform.window, 0); + CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + CORE.Window.fullscreen = false; + } + else + { + SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); + CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + CORE.Window.fullscreen = true; + } + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); +} + +// Toggle borderless windowed mode +void ToggleBorderlessWindowed(void) +{ + const int monitor = SDL_GetWindowDisplayIndex(platform.window); + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) + { + SDL_SetWindowFullscreen(platform.window, 0); + CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + } + else + { + SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP); + CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE; + } + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); +} + +// Set window state: maximized, if resizable +void MaximizeWindow(void) +{ + SDL_MaximizeWindow(platform.window); + CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; +} + +// Set window state: minimized +void MinimizeWindow(void) +{ + SDL_MinimizeWindow(platform.window); + CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; +} + +// Set window state: not minimized/maximized +void RestoreWindow(void) +{ + SDL_ShowWindow(platform.window); +} + +// Set window configuration state using flags +void SetWindowState(unsigned int flags) +{ + CORE.Window.flags |= flags; + + if (flags & FLAG_VSYNC_HINT) + { + SDL_GL_SetSwapInterval(1); + } + if (flags & FLAG_FULLSCREEN_MODE) + { + const int monitor = SDL_GetWindowDisplayIndex(platform.window); + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); + CORE.Window.fullscreen = true; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + } + if (flags & FLAG_WINDOW_RESIZABLE) + { + SDL_SetWindowResizable(platform.window, SDL_TRUE); + } + if (flags & FLAG_WINDOW_UNDECORATED) + { + SDL_SetWindowBordered(platform.window, SDL_FALSE); + } + if (flags & FLAG_WINDOW_HIDDEN) + { + SDL_HideWindow(platform.window); + } + if (flags & FLAG_WINDOW_MINIMIZED) + { + SDL_MinimizeWindow(platform.window); + } + if (flags & FLAG_WINDOW_MAXIMIZED) + { + SDL_MaximizeWindow(platform.window); + } + if (flags & FLAG_WINDOW_UNFOCUSED) + { + // NOTE: To be able to implement this part it seems that we should + // do it ourselves, via `Windows.h`, `X11/Xlib.h` or even `Cocoa.h` + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_TOPMOST) + { + SDL_SetWindowAlwaysOnTop(platform.window, SDL_FALSE); + } + if (flags & FLAG_WINDOW_ALWAYS_RUN) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_TRANSPARENT) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_HIGHDPI) + { + // NOTE: Such a function does not seem to exist + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + { + //SDL_SetWindowGrab(platform.window, SDL_FALSE); + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + { + const int monitor = SDL_GetWindowDisplayIndex(platform.window); + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP); + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + } + if (flags & FLAG_MSAA_4X_HINT) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Enable multisampling buffers + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); // Enable multisampling + } + if (flags & FLAG_INTERLACED_HINT) + { + TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_SDL"); + } +} + +// Clear window configuration state flags +void ClearWindowState(unsigned int flags) +{ + CORE.Window.flags &= ~flags; + + if (flags & FLAG_VSYNC_HINT) + { + SDL_GL_SetSwapInterval(0); + } + if (flags & FLAG_FULLSCREEN_MODE) + { + SDL_SetWindowFullscreen(platform.window, 0); + CORE.Window.fullscreen = false; + } + if (flags & FLAG_WINDOW_RESIZABLE) + { + SDL_SetWindowResizable(platform.window, SDL_FALSE); + } + if (flags & FLAG_WINDOW_UNDECORATED) + { + SDL_SetWindowBordered(platform.window, SDL_TRUE); + } + if (flags & FLAG_WINDOW_HIDDEN) + { + SDL_ShowWindow(platform.window); + } + if (flags & FLAG_WINDOW_MINIMIZED) + { + SDL_RestoreWindow(platform.window); + } + if (flags & FLAG_WINDOW_MAXIMIZED) + { + SDL_RestoreWindow(platform.window); + } + if (flags & FLAG_WINDOW_UNFOCUSED) + { + //SDL_RaiseWindow(platform.window); + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_TOPMOST) + { + SDL_SetWindowAlwaysOnTop(platform.window, SDL_FALSE); + } + if (flags & FLAG_WINDOW_ALWAYS_RUN) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_SDL"); + } + if (flags & FLAG_WINDOW_TRANSPARENT) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); + } + 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_SDL"); + } + 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_SDL"); + } + if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + { + SDL_SetWindowFullscreen(platform.window, 0); + } + if (flags & FLAG_MSAA_4X_HINT) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); // Disable multisampling buffers + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); // Disable multisampling + } + if (flags & FLAG_INTERLACED_HINT) + { + TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_SDL"); + } +} + +// Set icon for window +void SetWindowIcon(Image image) +{ + SDL_Surface* iconSurface = NULL; + + Uint32 rmask, gmask, bmask, amask; + int depth = 0; // Depth in bits + int pitch = 0; // Pixel spacing (pitch) in bytes + + switch (image.format) + { + case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: + rmask = 0xFF, gmask = 0; + bmask = 0, amask = 0; + depth = 8, pitch = image.width; + break; + case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: + rmask = 0xFF, gmask = 0xFF00; + bmask = 0, amask = 0; + depth = 16, pitch = image.width * 2; + break; + case PIXELFORMAT_UNCOMPRESSED_R5G6B5: + rmask = 0xF800, gmask = 0x07E0; + bmask = 0x001F, amask = 0; + depth = 16, pitch = image.width * 2; + break; + case PIXELFORMAT_UNCOMPRESSED_R8G8B8: + rmask = 0xFF0000, gmask = 0x00FF00; + bmask = 0x0000FF, amask = 0; + depth = 24, pitch = image.width * 3; + break; + case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: + rmask = 0xF800, gmask = 0x07C0; + bmask = 0x003E, amask = 0x0001; + depth = 16, pitch = image.width * 2; + break; + case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: + rmask = 0xF000, gmask = 0x0F00; + bmask = 0x00F0, amask = 0x000F; + depth = 16, pitch = image.width * 2; + break; + case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: + rmask = 0xFF000000, gmask = 0x00FF0000; + bmask = 0x0000FF00, amask = 0x000000FF; + depth = 32, pitch = image.width * 4; + break; + case PIXELFORMAT_UNCOMPRESSED_R32: + rmask = 0xFFFFFFFF, gmask = 0; + bmask = 0, amask = 0; + depth = 32, pitch = image.width * 4; + break; + case PIXELFORMAT_UNCOMPRESSED_R32G32B32: + rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF; + bmask = 0xFFFFFFFF, amask = 0; + depth = 96, pitch = image.width * 12; + break; + case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: + rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF; + bmask = 0xFFFFFFFF, amask = 0xFFFFFFFF; + depth = 128, pitch = image.width * 16; + break; + case PIXELFORMAT_UNCOMPRESSED_R16: + rmask = 0xFFFF, gmask = 0; + bmask = 0, amask = 0; + depth = 16, pitch = image.width * 2; + break; + case PIXELFORMAT_UNCOMPRESSED_R16G16B16: + rmask = 0xFFFF, gmask = 0xFFFF; + bmask = 0xFFFF, amask = 0; + depth = 48, pitch = image.width * 6; + break; + case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: + rmask = 0xFFFF, gmask = 0xFFFF; + bmask = 0xFFFF, amask = 0xFFFF; + depth = 64, pitch = image.width * 8; + break; + default: + // Compressed formats are not supported + return; + } + + iconSurface = SDL_CreateRGBSurfaceFrom( + image.data, image.width, image.height, depth, pitch, + rmask, gmask, bmask, amask + ); + + if (iconSurface) + { + SDL_SetWindowIcon(platform.window, iconSurface); + SDL_FreeSurface(iconSurface); + } +} + +// 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) +{ + SDL_SetWindowTitle(platform.window, title); + + CORE.Window.title = title; +} + +// Set window position on screen (windowed mode) +void SetWindowPosition(int x, int y) +{ + SDL_SetWindowPosition(platform.window, x, y); + + CORE.Window.position.x = x; + CORE.Window.position.y = y; +} + +// Set monitor for the current window +void SetWindowMonitor(int monitor) +{ + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + // 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. + const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) ? true : false; + + const int screenWidth = CORE.Window.screen.width; + const int screenHeight = CORE.Window.screen.height; + SDL_Rect usableBounds; + if (SDL_GetDisplayUsableBounds(monitor, &usableBounds) == 0) + { + if (wasFullscreen == 1) ToggleFullscreen(); // Leave fullscreen. + + // If the screen size is larger than the monitor usable area, anchor it on the top left corner, otherwise, center it + if ((screenWidth >= usableBounds.w) || (screenHeight >= usableBounds.h)) + { + // NOTE: + // 1. There's a known issue where if the window larger than the target display bounds, + // when moving the windows to that display, the window could be clipped back + // 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 + // is acceptable behavior by the user. + SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y); + CORE.Window.position.x = usableBounds.x; + CORE.Window.position.y = usableBounds.y; + } + else + { + const int x = usableBounds.x + (usableBounds.w/2) - (screenWidth/2); + const int y = usableBounds.y + (usableBounds.h/2) - (screenHeight/2); + SDL_SetWindowPosition(platform.window, x, y); + CORE.Window.position.x = x; + CORE.Window.position.y = y; + } + + if (wasFullscreen == 1) ToggleFullscreen(); // Re-enter fullscreen + } + else TRACELOG(LOG_WARNING, "SDL: Failed to get selected display usable bounds"); + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); +} + +// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMinSize(int width, int height) +{ + SDL_SetWindowMinimumSize(platform.window, 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) +{ + SDL_SetWindowMaximumSize(platform.window, width, height); + + CORE.Window.screenMax.width = width; + CORE.Window.screenMax.height = height; +} + +// Set window dimensions +void SetWindowSize(int width, int height) +{ + SDL_SetWindowSize(platform.window, width, height); + + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; +} + +// Set window opacity, value opacity is between 0.0 and 1.0 +void SetWindowOpacity(float opacity) +{ + if (opacity >= 1.0f) opacity = 1.0f; + else if (opacity <= 0.0f) opacity = 0.0f; + + SDL_SetWindowOpacity(platform.window, opacity); +} + +// Set window focused +void SetWindowFocused(void) +{ + SDL_RaiseWindow(platform.window); +} + +// Get native window handle +void *GetWindowHandle(void) +{ + return (void *)platform.window; +} + +// Get number of monitors +int GetMonitorCount(void) +{ + int monitorCount = 0; + + monitorCount = SDL_GetNumVideoDisplays(); + + return monitorCount; +} + +// Get number of monitors +int GetCurrentMonitor(void) +{ + int currentMonitor = 0; + + currentMonitor = SDL_GetWindowDisplayIndex(platform.window); + + return currentMonitor; +} + +// Get selected monitor position +Vector2 GetMonitorPosition(int monitor) +{ + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + SDL_Rect displayBounds; + if (SDL_GetDisplayUsableBounds(monitor, &displayBounds) == 0) + { + return (Vector2){ (float)displayBounds.x, (float)displayBounds.y }; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to get selected display usable bounds"); + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + return (Vector2){ 0.0f, 0.0f }; +} + +// Get selected monitor width (currently used by monitor) +int GetMonitorWidth(int monitor) +{ + int width = 0; + + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(monitor, &mode); + width = mode.w; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + + return width; +} + +// Get selected monitor height (currently used by monitor) +int GetMonitorHeight(int monitor) +{ + int height = 0; + + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(monitor, &mode); + height = mode.h; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + + return height; +} + +// Get selected monitor physical width in millimetres +int GetMonitorPhysicalWidth(int monitor) +{ + int width = 0; + + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + float ddpi = 0.0f; + SDL_GetDisplayDPI(monitor, &ddpi, NULL, NULL); + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(monitor, &mode); + // Calculate size on inches, then convert to millimeter + if (ddpi > 0.0f) width = (mode.w/ddpi)*25.4f; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + + return width; +} + +// Get selected monitor physical height in millimetres +int GetMonitorPhysicalHeight(int monitor) +{ + int height = 0; + + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + float ddpi = 0.0f; + SDL_GetDisplayDPI(monitor, &ddpi, NULL, NULL); + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(monitor, &mode); + // Calculate size on inches, then convert to millimeter + if (ddpi > 0.0f) height = (mode.h/ddpi)*25.4f; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + + return height; +} + +// Get selected monitor refresh rate +int GetMonitorRefreshRate(int monitor) +{ + int refresh = 0; + + const int monitorCount = SDL_GetNumVideoDisplays(); + if ((monitor >= 0) && (monitor < monitorCount)) + { + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(monitor, &mode); + refresh = mode.refresh_rate; + } + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + + return refresh; +} + +// Get the human-readable, UTF-8 encoded name of the selected monitor +const char *GetMonitorName(int monitor) +{ + const int monitorCount = SDL_GetNumVideoDisplays(); + + if ((monitor >= 0) && (monitor < monitorCount)) return SDL_GetDisplayName(monitor); + else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); + + return ""; +} + +// Get window position XY on monitor +Vector2 GetWindowPosition(void) +{ + int x = 0; + int y = 0; + + SDL_GetWindowPosition(platform.window, &x, &y); + + return (Vector2){ (float)x, (float)y }; +} + +// Get window scale DPI factor for current monitor +Vector2 GetWindowScaleDPI(void) +{ + Vector2 scale = { 1.0f, 1.0f }; + + // NOTE: SDL_GetWindowDisplayScale was only added on SDL3 + // see https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale + // TODO: Implement the window scale factor calculation manually. + TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform"); + + return scale; +} + +// Set clipboard text content +void SetClipboardText(const char *text) +{ + SDL_SetClipboardText(text); +} + +// Get clipboard text content +// NOTE: returned string must be freed with SDL_free() +const char *GetClipboardText(void) +{ + return SDL_GetClipboardText(); +} + +// Show mouse cursor +void ShowCursor(void) +{ + SDL_ShowCursor(SDL_ENABLE); + + CORE.Input.Mouse.cursorHidden = false; +} + +// Hides mouse cursor +void HideCursor(void) +{ + SDL_ShowCursor(SDL_DISABLE); + + CORE.Input.Mouse.cursorHidden = true; +} + +// Enables cursor (unlock cursor) +void EnableCursor(void) +{ + SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_ShowCursor(SDL_ENABLE); + + platform.cursorRelative = false; + CORE.Input.Mouse.cursorHidden = false; +} + +// Disables cursor (lock cursor) +void DisableCursor(void) +{ + SDL_SetRelativeMouseMode(SDL_TRUE); + + platform.cursorRelative = true; + CORE.Input.Mouse.cursorHidden = true; +} + +// Swap back buffer with front buffer (screen drawing) +void SwapScreenBuffer(void) +{ + SDL_GL_SwapWindow(platform.window); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Misc +//---------------------------------------------------------------------------------- + +// Get elapsed time measure in seconds +double GetTime(void) +{ + unsigned int ms = SDL_GetTicks(); // Elapsed time in milliseconds since SDL_Init() + double time = (double)ms/1000; + 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 + if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + else SDL_OpenURL(url); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Inputs +//---------------------------------------------------------------------------------- + +// Set internal gamepad mappings +int SetGamepadMappings(const char *mappings) +{ + return SDL_GameControllerAddMapping(mappings); +} + +// Set mouse position XY +void SetMousePosition(int x, int 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) +{ + platform.cursor = SDL_CreateSystemCursor(CursorsLUT[cursor]); + SDL_SetCursor(platform.cursor); + + CORE.Input.Mouse.cursor = cursor; +} + +// 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 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; + + // 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; + + // 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; + + // 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 + + // 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 plaform + //----------------------------------------------------------------------------- + /* + // WARNING: Indexes into this array are obtained by using SDL_Scancode values, not SDL_Keycode values + const Uint8 *keys = SDL_GetKeyboardState(NULL); + for (int i = 0; i < 256; ++i) + { + CORE.Input.Keyboard.currentKeyState[i] = keys[i]; + //if (keys[i]) TRACELOG(LOG_WARNING, "Pressed key: %i", i); + } + */ + + CORE.Window.resizedLastFrame = false; + + SDL_Event event = { 0 }; + while (SDL_PollEvent(&event) != 0) + { + // All input events can be processed after polling + switch (event.type) + { + case SDL_QUIT: CORE.Window.shouldClose = true; break; + + case SDL_DROPFILE: // Dropped file + { + 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.drop.file); + SDL_free(event.drop.file); + + 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.drop.file); + SDL_free(event.drop.file); + + 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 SDL_WINDOWEVENT: + { + switch (event.window.event) + { + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_SIZE_CHANGED: + { + const int width = event.window.data1; + const int height = event.window.data2; + SetupViewport(width, height); + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + CORE.Window.currentFbo.width = width; + CORE.Window.currentFbo.height = height; + CORE.Window.resizedLastFrame = true; + } break; + case SDL_WINDOWEVENT_LEAVE: + 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: + case SDL_WINDOWEVENT_RESTORED: + default: break; + } + } break; + + // Keyboard events + case SDL_KEYDOWN: + { + KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode); + if (key != KEY_NULL) 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; + } + } break; + + case SDL_KEYUP: + { + KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode); + if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0; + } break; + + // Check mouse events + case SDL_MOUSEBUTTONDOWN: + { + // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW + // The following conditions align SDL with raylib.h MouseButton enum order + int btn = event.button.button - 1; + if (btn == 2) btn = 1; + else if (btn == 1) btn = 2; + + CORE.Input.Mouse.currentButtonState[btn] = 1; + + touchAction = 1; + gestureUpdate = true; + } break; + case SDL_MOUSEBUTTONUP: + { + // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW + // The following conditions align SDL with raylib.h MouseButton enum order + int btn = event.button.button - 1; + if (btn == 2) btn = 1; + else if (btn == 1) btn = 2; + + CORE.Input.Mouse.currentButtonState[btn] = 0; + + touchAction = 0; + gestureUpdate = true; + } break; + case SDL_MOUSEWHEEL: + { + CORE.Input.Mouse.currentWheelMove.x = (float)event.wheel.x; + CORE.Input.Mouse.currentWheelMove.y = (float)event.wheel.y; + } break; + case SDL_MOUSEMOTION: + { + if (platform.cursorRelative) + { + CORE.Input.Mouse.currentPosition.x = (float)event.motion.xrel; + CORE.Input.Mouse.currentPosition.y = (float)event.motion.yrel; + CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; + } + else + { + CORE.Input.Mouse.currentPosition.x = (float)event.motion.x; + CORE.Input.Mouse.currentPosition.y = (float)event.motion.y; + } + + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + touchAction = 2; + gestureUpdate = true; + } break; + + // Check gamepad events + case SDL_JOYAXISMOTION: + { + // Motion on gamepad 0 + if (event.jaxis.which == 0) + { + // X axis motion + if (event.jaxis.axis == 0) + { + //... + } + // Y axis motion + else if (event.jaxis.axis == 1) + { + //... + } + } + } break; + default: break; + } + +#if defined(SUPPORT_GESTURES_SYSTEM) + if (gestureUpdate) + { + // 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) 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); + } +#endif + } + //----------------------------------------------------------------------------- +} + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- + +// Initialize platform: graphics, inputs and more +int InitPlatform(void) +{ + // Initialize SDL internal global state + int result = SDL_Init(SDL_INIT_EVERYTHING); + if (result < 0) { TRACELOG(LOG_WARNING, "SDL: Failed to initialize SDL"); return -1; } + + // Initialize graphic device: display/window and graphic context + //---------------------------------------------------------------------------- + unsigned int flags = 0; + flags |= SDL_WINDOW_SHOWN; + flags |= SDL_WINDOW_OPENGL; + flags |= SDL_WINDOW_INPUT_FOCUS; + flags |= SDL_WINDOW_MOUSE_FOCUS; + flags |= SDL_WINDOW_MOUSE_CAPTURE; // Window has mouse captured + + // Check window creation flags + if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) + { + CORE.Window.fullscreen = true; + flags |= SDL_WINDOW_FULLSCREEN; + } + + //if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) == 0) flags |= SDL_WINDOW_HIDDEN; + if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= SDL_WINDOW_BORDERLESS; + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) flags |= SDL_WINDOW_RESIZABLE; + if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) flags |= SDL_WINDOW_MINIMIZED; + if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) flags |= SDL_WINDOW_MAXIMIZED; + + if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) + { + flags &= ~SDL_WINDOW_INPUT_FOCUS; + flags &= ~SDL_WINDOW_MOUSE_FOCUS; + } + + if ((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) flags |= SDL_WINDOW_ALWAYS_ON_TOP; + if ((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + + if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) flags |= SDL_WINDOW_ALLOW_HIGHDPI; + + //if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= SDL_WINDOW_TRANSPARENT; // Alternative: SDL_GL_ALPHA_SIZE = 8 + + //if ((CORE.Window.flags & FLAG_FULLSCREEN_DESKTOP) > 0) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + + // NOTE: Some OpenGL context attributes must be set before window creation + + // Check selection OpenGL version + if (rlGetVersion() == RL_OPENGL_21) + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + } + else if (rlGetVersion() == RL_OPENGL_33) + { + 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) + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); +#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); // Enable OpenGL Debug Context +#endif + } + else if (rlGetVersion() == RL_OPENGL_ES_20) // Request OpenGL ES 2.0 context + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + } + else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + } + + if (CORE.Window.flags & FLAG_VSYNC_HINT) + { + SDL_GL_SetSwapInterval(1); + } + + if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); + } + + // Init window + platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags); + + // Init OpenGL context + platform.glContext = SDL_GL_CreateContext(platform.window); + + // Check window and glContext have been initialized succesfully + if ((platform.window != NULL) && (platform.glContext != NULL)) + { + CORE.Window.ready = true; + + SDL_DisplayMode displayMode = { 0 }; + SDL_GetCurrentDisplayMode(GetCurrentMonitor(), &displayMode); + + CORE.Window.display.width = displayMode.w; + CORE.Window.display.height = displayMode.h; + + 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; + } + + // Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + rlLoadExtensions(SDL_GL_GetProcAddress); + //---------------------------------------------------------------------------- + + // Initialize input events system + //---------------------------------------------------------------------------- + if (SDL_NumJoysticks() >= 1) + { + platform.gamepad = SDL_JoystickOpen(0); + //if (platform.gamepadgamepad == NULL) TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); + } + + SDL_EventState(SDL_DROPFILE, SDL_ENABLE); + //---------------------------------------------------------------------------- + + // Initialize timming system + //---------------------------------------------------------------------------- + // NOTE: No need to call InitTimer(), let SDL manage it internally + CORE.Time.previous = GetTime(); // Get time as double + //---------------------------------------------------------------------------- + + // Initialize storage system + //---------------------------------------------------------------------------- + CORE.Storage.basePath = GetWorkingDirectory(); // Define base path for storage + //---------------------------------------------------------------------------- + + TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully"); + + return 0; +} + +// Close platform +void ClosePlatform(void) +{ + SDL_FreeCursor(platform.cursor); // Free cursor + SDL_GL_DeleteContext(platform.glContext); // Deinitialize OpenGL context + SDL_DestroyWindow(platform.window); + SDL_Quit(); // Deinitialize SDL internal global state +} + +// Scancode to keycode mapping +static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode) +{ + if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM) + { + return ScancodeToKey[sdlScancode]; + } + return KEY_NULL; // No equivalent key in Raylib +} +// EOF diff --git a/raylib/src/rcore_drm.c b/raylib/src/platforms/rcore_drm.c index 1fb83c8..bdfc9e0 100644 --- a/raylib/src/rcore_drm.c +++ b/raylib/src/platforms/rcore_drm.c @@ -3,8 +3,8 @@ * rcore_drm - Functions to manage window, graphics device and inputs * * PLATFORM: DRM -* - Raspberry Pi 0-5 -* - Linux native mode (KMS driver) +* - Raspberry Pi 0-5 (DRM/KMS) +* - Linux DRM subsystem (KMS mode) * * LIMITATIONS: * - Most of the window/monitor functions are not implemented (not required) @@ -23,7 +23,8 @@ * running processes orblocking the device if not restored properly. Use with care. * * DEPENDENCIES: -* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) +* - DRM and GLM: System libraries for display initialization and configuration +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) * * * LICENSE: zlib/libpng @@ -121,6 +122,10 @@ typedef struct { Vector2 eventWheelMove; // Registers the event mouse wheel variation // NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab + bool cursorRelative; // Relative cursor mode + int mouseFd; // File descriptor for the evdev mouse/touch/gestures + Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) + int touchSlot; // Hold the touch slot number of the currently being sent multitouch block // Gamepad data pthread_t gamepadThreadId; // Gamepad reading thread id @@ -136,10 +141,43 @@ extern CoreData CORE; // Global CORE state context 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[] = { + 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 +}; + +//---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- -static int InitPlatform(void); // Initialize platform (graphics, inputs and more) -static void ClosePlatform(void); // Close platform +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +void ClosePlatform(void); // Close platform static void InitKeyboard(void); // Initialize raw keyboard system static void RestoreKeyboard(void); // Restore keyboard system @@ -168,150 +206,6 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt // Module Functions Definition: Window and Graphics Device //---------------------------------------------------------------------------------- -// Initialize window and OpenGL context -// NOTE: data parameter could be used to pass any kind of required data to the initialization -void InitWindow(int width, int height, const char *title) -{ - TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); - - TRACELOG(LOG_INFO, "Supported raylib modules:"); - TRACELOG(LOG_INFO, " > rcore:..... loaded (mandatory)"); - TRACELOG(LOG_INFO, " > rlgl:...... loaded (mandatory)"); -#if defined(SUPPORT_MODULE_RSHAPES) - TRACELOG(LOG_INFO, " > rshapes:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rshapes:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXTURES) - TRACELOG(LOG_INFO, " > rtextures:. loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtextures:. not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXT) - TRACELOG(LOG_INFO, " > rtext:..... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtext:..... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RMODELS) - TRACELOG(LOG_INFO, " > rmodels:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rmodels:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RAUDIO) - TRACELOG(LOG_INFO, " > raudio:.... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); -#endif - - // Initialize window data - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; - CORE.Window.eventWaiting = false; - CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default - if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; - - // Initialize global input state - memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0 - CORE.Input.Keyboard.exitKey = KEY_ESCAPE; - CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; - CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; - CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; - - // Initialize platform - //-------------------------------------------------------------- - InitPlatform(); - //-------------------------------------------------------------- - - // Initialize rlgl default data (buffers and shaders) - // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl - rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - - // Setup default viewport - SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - // Load default font - // WARNING: External function: Module required: rtext - LoadFontDefault(); -#if defined(SUPPORT_MODULE_RSHAPES) - // Set font white rectangle for shapes drawing, so shapes and text can be batched together - // WARNING: rshapes module is required, if not available, default internal white rectangle is used - Rectangle rec = GetFontDefault().recs[95]; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) - { - // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering - SetShapesTexture(GetFontDefault().texture, (Rectangle){rec.x + 2, rec.y + 2, 1, 1}); - } - else - { - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding - SetShapesTexture(GetFontDefault().texture, (Rectangle){rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2}); - } -#endif -#else -#if defined(SUPPORT_MODULE_RSHAPES) - // Set default texture and rectangle to be used for shapes drawing - // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 - Texture2D texture = {rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8}; - SetShapesTexture(texture, (Rectangle){0.0f, 0.0f, 1.0f, 1.0f}); // WARNING: Module required: rshapes -#endif -#endif -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) - { - // Set default font texture filter for HighDPI (blurry) - // RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR); - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR); - } -#endif - -#if defined(SUPPORT_EVENTS_AUTOMATION) - events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent)); - CORE.Time.frameCounter = 0; -#endif - - // Initialize random seed - SetRandomSeed((unsigned int)time(NULL)); - - TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully"); -} - -// Close window and unload OpenGL context -void CloseWindow(void) -{ -#if defined(SUPPORT_GIF_RECORDING) - if (gifRecording) - { - MsfGifResult result = msf_gif_end(&gifState); - msf_gif_free(result); - gifRecording = false; - } -#endif - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - UnloadFontDefault(); // WARNING: Module required: rtext -#endif - - rlglClose(); // De-init rlgl - -#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP) - timeEndPeriod(1); // Restore time period -#endif - - // De-initialize platform - //-------------------------------------------------------------- - ClosePlatform(); - //-------------------------------------------------------------- - -#if defined(SUPPORT_EVENTS_AUTOMATION) - RL_FREE(events); -#endif - - CORE.Window.ready = false; - TRACELOG(LOG_INFO, "Window closed successfully"); -} - // Check if application should close // NOTE: By default, if KEY_ESCAPE pressed bool WindowShouldClose(void) @@ -544,6 +438,7 @@ void EnableCursor(void) // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + platform.cursorRelative = false; CORE.Input.Mouse.cursorHidden = false; } @@ -551,8 +446,9 @@ void EnableCursor(void) void DisableCursor(void) { // Set cursor position in the middle - SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + SetMousePosition(0, 0); + platform.cursorRelative = true; CORE.Input.Mouse.cursorHidden = true; } @@ -666,6 +562,10 @@ void PollInputEvents(void) PollKeyboardEvents(); + // 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; + // Register previous mouse states CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove; CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove; @@ -692,6 +592,9 @@ void PollInputEvents(void) // Reset touch positions //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 + 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 @@ -701,15 +604,191 @@ void PollInputEvents(void) // 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 + } + } +} //---------------------------------------------------------------------------------- // Module Internal Functions Definition //---------------------------------------------------------------------------------- // Initialize platform: graphics, inputs and more -static int InitPlatform(void) +int InitPlatform(void) { platform.fd = -1; platform.connector = NULL; @@ -720,6 +799,8 @@ static int InitPlatform(void) platform.prevBO = NULL; platform.prevFB = 0; + // Initialize graphic device: display/window and graphic context + //---------------------------------------------------------------------------- CORE.Window.fullscreen = true; CORE.Window.flags |= FLAG_FULLSCREEN_MODE; @@ -990,7 +1071,6 @@ static int InitPlatform(void) } // Create an EGL window surface - //--------------------------------------------------------------------------------- platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL); if (EGL_NO_SURFACE == platform.surface) { @@ -1008,13 +1088,13 @@ static int InitPlatform(void) // There must be at least one frame displayed before the buffers are swapped //eglSwapInterval(platform.device, 1); - if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE) - { - TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface"); - return -1; - } - else + EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context); + + // Check surface and context activation + if (result != EGL_FALSE) { + 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; @@ -1026,16 +1106,15 @@ static int InitPlatform(void) 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); } - - // Load OpenGL extensions - // NOTE: GL procedures address loader is required to load extensions - rlLoadExtensions(eglGetProcAddress); + else + { + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); + return -1; + } if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); - CORE.Window.ready = true; // TODO: Proper validation on windows/context creation - - // If graphic device is no properly initialized, we end program + // 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); @@ -1045,22 +1124,36 @@ static int InitPlatform(void) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false - // Initialize hi-res timer + // Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + rlLoadExtensions(eglGetProcAddress); + //---------------------------------------------------------------------------- + + // Initialize timming system + //---------------------------------------------------------------------------- + // NOTE: timming system must be initialized before the input events system InitTimer(); + //---------------------------------------------------------------------------- - // Initialize base path for storage + // Initialize input events system + //---------------------------------------------------------------------------- + InitEvdevInput(); // Evdev inputs initialization + InitGamepad(); // Gamepad init + InitKeyboard(); // Keyboard init (stdin) + //---------------------------------------------------------------------------- + + // Initialize storage system + //---------------------------------------------------------------------------- CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- - // Initialize raw input system - InitEvdevInput(); // Evdev inputs initialization - InitGamepad(); // Gamepad init - InitKeyboard(); // Keyboard init (stdin) + TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully"); return 0; } // Close platform -static void ClosePlatform(void) +void ClosePlatform(void) { if (platform.prevFB) { @@ -1149,7 +1242,6 @@ static void ClosePlatform(void) if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL); } - // Initialize Keyboard system (using standard input) static void InitKeyboard(void) { @@ -1457,9 +1549,14 @@ static void ConfigureEvdevDevice(char *device) 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; } // Check for multiple absolute movement support (usually multitouch touchscreens) @@ -1471,9 +1568,14 @@ static void ConfigureEvdevDevice(char *device) 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; } } @@ -1533,15 +1635,20 @@ static void ConfigureEvdevDevice(char *device) 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); - } + //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 @@ -1574,27 +1681,6 @@ static void ConfigureEvdevDevice(char *device) // Poll and process evdev keyboard events static void PollKeyboardEvents(void) { - // 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 - }; - int fd = platform.keyboardFd; if (fd == -1) return; @@ -1638,6 +1724,18 @@ static void PollKeyboardEvents(void) } #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); @@ -1650,6 +1748,7 @@ static void PollKeyboardEvents(void) // Input device events reading thread static void *EventThread(void *arg) { +/* struct input_event event = { 0 }; InputEventWorker *worker = (InputEventWorker *)arg; @@ -1666,8 +1765,16 @@ static void *EventThread(void *arg) { if (event.code == REL_X) { - CORE.Input.Mouse.currentPosition.x += event.value; - CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.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; @@ -1675,8 +1782,16 @@ static void *EventThread(void *arg) if (event.code == REL_Y) { - CORE.Input.Mouse.currentPosition.y += event.value; - CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.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; @@ -1815,7 +1930,7 @@ static void *EventThread(void *arg) } close(worker->fd); - +*/ return NULL; } diff --git a/raylib/src/rcore_template.c b/raylib/src/platforms/rcore_template.c index 4d2db9d..5d4721c 100644 --- a/raylib/src/rcore_template.c +++ b/raylib/src/platforms/rcore_template.c @@ -21,8 +21,8 @@ * Custom flag for rcore on target platform -not used- * * DEPENDENCIES: -* - Dependency 01 -* - Dependency 02 +* - <platform-specific SDK dependency> +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) * * * LICENSE: zlib/libpng @@ -71,8 +71,8 @@ static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- -static int InitPlatform(void); // Initialize platform (graphics, inputs and more) -static bool InitGraphicsDevice(void); // Initialize graphics device +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +bool InitGraphicsDevice(void); // Initialize graphics device //---------------------------------------------------------------------------------- // Module Functions Declaration @@ -83,153 +83,6 @@ static bool InitGraphicsDevice(void); // Initialize graphics device // Module Functions Definition: Window and Graphics Device //---------------------------------------------------------------------------------- -// Initialize window and OpenGL context -// NOTE: data parameter could be used to pass any kind of required data to the initialization -void InitWindow(int width, int height, const char *title) -{ - TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); - - TRACELOG(LOG_INFO, "Supported raylib modules:"); - TRACELOG(LOG_INFO, " > rcore:..... loaded (mandatory)"); - TRACELOG(LOG_INFO, " > rlgl:...... loaded (mandatory)"); -#if defined(SUPPORT_MODULE_RSHAPES) - TRACELOG(LOG_INFO, " > rshapes:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rshapes:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXTURES) - TRACELOG(LOG_INFO, " > rtextures:. loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtextures:. not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXT) - TRACELOG(LOG_INFO, " > rtext:..... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtext:..... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RMODELS) - TRACELOG(LOG_INFO, " > rmodels:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rmodels:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RAUDIO) - TRACELOG(LOG_INFO, " > raudio:.... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); -#endif - - // NOTE: Keep internal pointer to input title string (no copy) - if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; - - // Initialize global input state - memset(&CORE.Input, 0, sizeof(CORE.Input)); - CORE.Input.Keyboard.exitKey = KEY_ESCAPE; - CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; - CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; - CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN - CORE.Window.eventWaiting = false; - - - // TODO: Platform specific init window - //-------------------------------------------------------------- - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; - CORE.Window.currentFbo.width = width; - CORE.Window.currentFbo.height = height; - - // Initialize graphics device - // NOTE: returns true if window and graphic device has been initialized successfully - CORE.Window.ready = InitGraphicsDevice(width, height); - - - - // Initialize OpenGL context (states and resources) - // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl - rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - - // Setup default viewport - // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height - SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - // Load default font - // WARNING: External function: Module required: rtext - LoadFontDefault(); - #if defined(SUPPORT_MODULE_RSHAPES) - // Set font white rectangle for shapes drawing, so shapes and text can be batched together - // WARNING: rshapes module is required, if not available, default internal white rectangle is used - Rectangle rec = GetFontDefault().recs[95]; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) - { - // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering - SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); - } - else - { - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding - SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); - } - #endif -#else - #if defined(SUPPORT_MODULE_RSHAPES) - // Set default texture and rectangle to be used for shapes drawing - // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 - Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; - SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes - #endif -#endif -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) - { - // Set default font texture filter for HighDPI (blurry) - // RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR); - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR); - } -#endif - -#if defined(SUPPORT_EVENTS_AUTOMATION) - events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent)); - CORE.Time.frameCounter = 0; -#endif - - // Initialize random seed - SetRandomSeed((unsigned int)time(NULL)); - - TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Application initialized successfully"); -} - -// Close window and unload OpenGL context -void CloseWindow(void) -{ -#if defined(SUPPORT_GIF_RECORDING) - if (gifRecording) - { - MsfGifResult result = msf_gif_end(&gifState); - msf_gif_free(result); - gifRecording = false; - } -#endif - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - UnloadFontDefault(); // WARNING: Module required: rtext -#endif - - rlglClose(); // De-init rlgl - - // Platform specific close window - //-------------------------------------------------------------- - // TODO. - //-------------------------------------------------------------- - -#if defined(SUPPORT_EVENTS_AUTOMATION) - RL_FREE(events); -#endif - - CORE.Window.ready = false; - TRACELOG(LOG_INFO, "Window closed successfully"); -} - // Check if application should close bool WindowShouldClose(void) { @@ -503,27 +356,7 @@ void OpenURL(const char *url) if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); else { - JNIEnv *env = NULL; - JavaVM *vm = platform.app->activity->vm; - (*vm)->AttachCurrentThread(vm, &env, NULL); - - jstring urlString = (*env)->NewStringUTF(env, url); - jclass uriClass = (*env)->FindClass(env, "android/net/Uri"); - jmethodID uriParse = (*env)->GetStaticMethodID(env, uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;"); - jobject uri = (*env)->CallStaticObjectMethod(env, uriClass, uriParse, urlString); - - jclass intentClass = (*env)->FindClass(env, "android/content/Intent"); - jfieldID actionViewId = (*env)->GetStaticFieldID(env, intentClass, "ACTION_VIEW", "Ljava/lang/String;"); - jobject actionView = (*env)->GetStaticObjectField(env, intentClass, actionViewId); - jmethodID newIntent = (*env)->GetMethodID(env, intentClass, "<init>", "(Ljava/lang/String;Landroid/net/Uri;)V"); - jobject intent = (*env)->AllocObject(env, intentClass); - - (*env)->CallVoidMethod(env, intent, newIntent, actionView, uri); - jclass activityClass = (*env)->FindClass(env, "android/app/Activity"); - jmethodID startActivity = (*env)->GetMethodID(env, activityClass, "startActivity", "(Landroid/content/Intent;)V"); - (*env)->CallVoidMethod(env, platform.app->activity->clazz, startActivity, intent); - - (*vm)->DetachCurrentThread(vm); + // TODO: } } @@ -596,8 +429,14 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Initialize platform: graphics, inputs and more -static int InitPlatform(void) -{ +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 + //---------------------------------------------------------------------------- CORE.Window.fullscreen = true; CORE.Window.flags |= FLAG_FULLSCREEN_MODE; @@ -663,35 +502,27 @@ static int InitPlatform(void) } // Create an EGL window surface - //--------------------------------------------------------------------------------- EGLint displayFormat = 0; // EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry() // As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat); - // At this point we need to manage render size vs screen size - // NOTE: This function use and modify global module variables: - // -> CORE.Window.screen.width/CORE.Window.screen.height - // -> CORE.Window.render.width/CORE.Window.render.height - // -> CORE.Window.screenScale - SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - - ANativeWindow_setBuffersGeometry(platform.app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat); - //ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size + // Android specific call + ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size platform.surface = eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL); // There must be at least one frame displayed before the buffers are swapped - //eglSwapInterval(platform.device, 1); + eglSwapInterval(platform.device, 1); - if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE) - { - TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface"); - return -1; - } - else + EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context); + + // Check surface and context activation + if (result != EGL_FALSE) { + 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; @@ -703,27 +534,56 @@ static int InitPlatform(void) 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; + } + //---------------------------------------------------------------------------- - // Load OpenGL extensions - // NOTE: GL procedures address loader is required to load extensions - rlLoadExtensions(eglGetProcAddress); - - CORE.Window.ready = true; + // If everything work as expected, we can continue + 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; - // 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; } + 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); - // Initialize hi-res timer + // TODO: Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + //---------------------------------------------------------------------------- + rlLoadExtensions(eglGetProcAddress); + //---------------------------------------------------------------------------- + + // TODO: Initialize input events system + // It could imply keyboard, mouse, gamepad, touch... + // Depending on the platform libraries/SDK it could use a callbacks mechanims + // For system events and inputs evens polling on a per-frame basis, use PollInputEvents() + //---------------------------------------------------------------------------- + // ... + //---------------------------------------------------------------------------- + + // TODO: Initialize timming system + //---------------------------------------------------------------------------- InitTimer(); + //---------------------------------------------------------------------------- - // Initialize base path for storage + // TODO: Initialize storage system + //---------------------------------------------------------------------------- CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- + + TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); return 0; } // Close platform -static void ClosePlatform(void) +void ClosePlatform(void) { // TODO: De-initialize graphics, inputs and more } diff --git a/raylib/src/rcore_web.c b/raylib/src/platforms/rcore_web.c index f8e1e5b..d8fa543 100644 --- a/raylib/src/rcore_web.c +++ b/raylib/src/platforms/rcore_web.c @@ -20,8 +20,8 @@ * Custom flag for rcore on target platform -not used- * * DEPENDENCIES: -* emscripten - Allow interaction between browser API and C -* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) +* - emscripten: Allow interaction between browser API and C +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) * * * LICENSE: zlib/libpng @@ -45,9 +45,9 @@ * **********************************************************************************************/ -#define GLFW_INCLUDE_ES2 // GLFW3: Enable OpenGL ES 2.0 (translated to WebGL) -// #define GLFW_INCLUDE_ES3 // GLFW3: Enable OpenGL ES 3.0 (transalted to WebGL2?) -#include "GLFW/glfw3.h" // GLFW3: Windows, OpenGL context and Input management +#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3 + // NOTE: Already provided by rlgl implementation (on glad.h) +#include "GLFW/glfw3.h" // GLFW3: Windows, OpenGL context and Input management #include <emscripten/emscripten.h> // Emscripten functionality for C #include <emscripten/html5.h> // Emscripten HTML5 library @@ -85,8 +85,8 @@ static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- -static int InitPlatform(void); // Initialize platform (graphics, inputs and more) -static void ClosePlatform(void); // Close platform +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +void ClosePlatform(void); // Close platform // Error callback event static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error @@ -94,7 +94,7 @@ static void ErrorCallback(int error, const char *description); // Window callbacks events static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored -static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized +//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 @@ -125,147 +125,6 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE // Module Functions Definition: Window and Graphics Device //---------------------------------------------------------------------------------- -// Initialize window and OpenGL context -// NOTE: data parameter could be used to pass any kind of required data to the initialization -void InitWindow(int width, int height, const char *title) -{ - TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); - - TRACELOG(LOG_INFO, "Supported raylib modules:"); - TRACELOG(LOG_INFO, " > rcore:..... loaded (mandatory)"); - TRACELOG(LOG_INFO, " > rlgl:...... loaded (mandatory)"); -#if defined(SUPPORT_MODULE_RSHAPES) - TRACELOG(LOG_INFO, " > rshapes:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rshapes:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXTURES) - TRACELOG(LOG_INFO, " > rtextures:. loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtextures:. not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RTEXT) - TRACELOG(LOG_INFO, " > rtext:..... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rtext:..... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RMODELS) - TRACELOG(LOG_INFO, " > rmodels:... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > rmodels:... not loaded (optional)"); -#endif -#if defined(SUPPORT_MODULE_RAUDIO) - TRACELOG(LOG_INFO, " > raudio:.... loaded (optional)"); -#else - TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); -#endif - - // Initialize window data - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; - CORE.Window.eventWaiting = false; - CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default - if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; - - // Initialize global input state - memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0 - CORE.Input.Keyboard.exitKey = KEY_ESCAPE; - CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; - CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; - CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; - - // Initialize platform - //-------------------------------------------------------------- - InitPlatform(); - //-------------------------------------------------------------- - - // Initialize OpenGL context (states and resources) - // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl - rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - - // Setup default viewport - // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height - SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - // Load default font - // WARNING: External function: Module required: rtext - LoadFontDefault(); -#if defined(SUPPORT_MODULE_RSHAPES) - // Set font white rectangle for shapes drawing, so shapes and text can be batched together - // WARNING: rshapes module is required, if not available, default internal white rectangle is used - Rectangle rec = GetFontDefault().recs[95]; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) - { - // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering - SetShapesTexture(GetFontDefault().texture, (Rectangle){rec.x + 2, rec.y + 2, 1, 1}); - } - else - { - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding - SetShapesTexture(GetFontDefault().texture, (Rectangle){rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2}); - } -#endif -#else -#if defined(SUPPORT_MODULE_RSHAPES) - // Set default texture and rectangle to be used for shapes drawing - // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 - Texture2D texture = {rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8}; - SetShapesTexture(texture, (Rectangle){0.0f, 0.0f, 1.0f, 1.0f}); // WARNING: Module required: rshapes -#endif -#endif -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) - { - // Set default font texture filter for HighDPI (blurry) - // RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR); - rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR); - } -#endif - -#if defined(SUPPORT_EVENTS_AUTOMATION) - events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent)); - CORE.Time.frameCounter = 0; -#endif - - // Initialize random seed - SetRandomSeed((unsigned int)time(NULL)); - - TRACELOG(LOG_INFO, "PLATFORM: WEB: Application initialized successfully"); -} - -// Close window and unload OpenGL context -void CloseWindow(void) -{ -#if defined(SUPPORT_GIF_RECORDING) - if (gifRecording) - { - MsfGifResult result = msf_gif_end(&gifState); - msf_gif_free(result); - gifRecording = false; - } -#endif - -#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) - UnloadFontDefault(); // WARNING: Module required: rtext -#endif - - rlglClose(); // De-init rlgl - - // De-initialize platform - //-------------------------------------------------------------- - ClosePlatform(); - //-------------------------------------------------------------- - -#if defined(SUPPORT_EVENTS_AUTOMATION) - RL_FREE(events); -#endif - - CORE.Window.ready = false; - TRACELOG(LOG_INFO, "Window closed successfully"); -} - // Check if application should close bool WindowShouldClose(void) { @@ -700,12 +559,11 @@ void PollInputEvents(void) // Reset keys/chars pressed registered 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; + // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) // Register previous keys states @@ -733,7 +591,6 @@ void PollInputEvents(void) // 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 }; - CORE.Window.resizedLastFrame = false; // Gamepad support using emscripten API // NOTE: GLFW3 joystick functionality not available in web @@ -802,15 +659,20 @@ void PollInputEvents(void) CORE.Input.Gamepad.axisCount[i] = gamepadState.numAxes; } } -} + CORE.Window.resizedLastFrame = false; + + // TODO: This code does not seem to do anything?? + //if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused) + //else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) --> WARNING: Where is key input reseted? +} //---------------------------------------------------------------------------------- // Module Internal Functions Definition //---------------------------------------------------------------------------------- // Initialize platform: graphics, inputs and more -static int InitPlatform(void) +int InitPlatform(void) { glfwSetErrorCallback(ErrorCallback); @@ -818,6 +680,8 @@ static int InitPlatform(void) int result = glfwInit(); if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; } + // Initialize graphic device: display/window and graphic context + //---------------------------------------------------------------------------- glfwDefaultWindowHints(); // Set default windows hints // glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits // glfwWindowHint(GLFW_GREEN_BITS, 8); // Framebuffer green color component bits @@ -900,6 +764,7 @@ static int InitPlatform(void) } else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context { + // TODO: It seems WebGL 2.0 context is not set despite being requested glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); @@ -1003,43 +868,45 @@ static int InitPlatform(void) glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback); glfwMakeContextCurrent(platform.handle); + result = true; // TODO: WARNING: glfwGetError(NULL); symbol can not be found in Web - // Load OpenGL extensions - // NOTE: GL procedures address loader is required to load extensions - rlLoadExtensions(glfwGetProcAddress); - - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); - - // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) - // NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need - // to be activated on web platforms since VSync is enforced there. + // Check context activation + if (result == true) //(result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR)) + { + CORE.Window.ready = true; - int fbWidth = CORE.Window.screen.width; - int fbHeight = CORE.Window.screen.height; + int fbWidth = CORE.Window.screen.width; + int fbHeight = CORE.Window.screen.height; - CORE.Window.render.width = fbWidth; - CORE.Window.render.height = fbHeight; - CORE.Window.currentFbo.width = fbWidth; - CORE.Window.currentFbo.height = fbHeight; + CORE.Window.render.width = fbWidth; + CORE.Window.render.height = fbHeight; + CORE.Window.currentFbo.width = fbWidth; + CORE.Window.currentFbo.height = fbHeight; - 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); + 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; + } - CORE.Window.ready = true; // TODO: Proper validation on windows/context creation + if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); // 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); - // Initialize hi-res timer - InitTimer(); - - // Initialize base path for storage - CORE.Storage.basePath = GetWorkingDirectory(); + // Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + rlLoadExtensions(glfwGetProcAddress); + //---------------------------------------------------------------------------- + // Initialize input events callbacks + //---------------------------------------------------------------------------- // Setup callback functions for the DOM events emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback); @@ -1068,12 +935,25 @@ static int InitPlatform(void) // Support gamepad events (not provided by GLFW3 on emscripten) emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback); emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback); + //---------------------------------------------------------------------------- + + // Initialize timming system + //---------------------------------------------------------------------------- + InitTimer(); + //---------------------------------------------------------------------------- + + // Initialize storage system + //---------------------------------------------------------------------------- + CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- + + TRACELOG(LOG_INFO, "PLATFORM: WEB: Initialized successfully"); return 0; } // Close platform -static void ClosePlatform(void) +void ClosePlatform(void) { glfwDestroyWindow(platform.handle); glfwTerminate(); @@ -1122,11 +1002,13 @@ static void WindowIconifyCallback(GLFWwindow *window, int iconified) else CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // The window was restored } +/* // GLFW3 Window Maximize Callback, runs when window is maximized static void WindowMaximizeCallback(GLFWwindow *window, int maximized) { // TODO. } +*/ // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused) @@ -1184,65 +1066,6 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i // Check the exit key to set close window if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE); - -#if defined(SUPPORT_SCREEN_CAPTURE) - if ((key == GLFW_KEY_F12) && (action == GLFW_PRESS)) - { -#if defined(SUPPORT_GIF_RECORDING) - if (mods & GLFW_MOD_CONTROL) - { - if (gifRecording) - { - gifRecording = false; - - MsfGifResult result = msf_gif_end(&gifState); - - SaveFileData(TextFormat("%s/screenrec%03i.gif", CORE.Storage.basePath, screenshotCounter), result.data, (unsigned int)result.dataSize); - msf_gif_free(result); - - // Download file from MEMFS (emscripten memory filesystem) - // saveFileFromMEMFSToDisk() function is defined in raylib/templates/web_shel/shell.html - emscripten_run_script(TextFormat("saveFileFromMEMFSToDisk('%s','%s')", TextFormat("screenrec%03i.gif", screenshotCounter - 1), TextFormat("screenrec%03i.gif", screenshotCounter - 1))); - - TRACELOG(LOG_INFO, "SYSTEM: Finish animated GIF recording"); - } - else - { - gifRecording = true; - gifFrameCounter = 0; - - Vector2 scale = GetWindowScaleDPI(); - msf_gif_begin(&gifState, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); - screenshotCounter++; - - TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter)); - } - } - else -#endif // SUPPORT_GIF_RECORDING - { - TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); - screenshotCounter++; - } - } -#endif // SUPPORT_SCREEN_CAPTURE - -#if defined(SUPPORT_EVENTS_AUTOMATION) - if ((key == GLFW_KEY_F11) && (action == GLFW_PRESS)) - { - eventsRecording = !eventsRecording; - - // On finish recording, we export events into a file - if (!eventsRecording) ExportAutomationEvents("eventsrec.rep"); - } - else if ((key == GLFW_KEY_F9) && (action == GLFW_PRESS)) - { - LoadAutomationEvents("eventsrec.rep"); - eventsPlaying = true; - - TRACELOG(LOG_WARNING, "eventsPlaying enabled!"); - } -#endif } // GLFW3 Char Key Callback, runs on key down (gets equivalent unicode char value) diff --git a/raylib/src/raudio.c b/raylib/src/raudio.c index 8216897..19794f7 100644 --- a/raylib/src/raudio.c +++ b/raylib/src/raudio.c @@ -536,6 +536,14 @@ void SetMasterVolume(float volume) ma_device_set_master_volume(&AUDIO.System.device, volume); } +// Get master volume (listener) +float GetMasterVolume(void) +{ + float volume = 0.0f; + ma_device_get_master_volume(&AUDIO.System.device, &volume); + return volume; +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Audio Buffer management //---------------------------------------------------------------------------------- @@ -920,7 +928,6 @@ Sound LoadSoundFromWave(Wave wave) } // Clone sound from existing sound data, clone does not own wave data -// Wave data must // NOTE: Wave data must be unallocated manually and will be shared across all clones Sound LoadSoundAlias(Sound source) { @@ -928,13 +935,16 @@ Sound LoadSoundAlias(Sound source) if (source.stream.buffer->data != NULL) { - AudioBuffer* audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, source.frameCount, 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 } + audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames; + audioBuffer->volume = source.stream.buffer->volume; audioBuffer->data = source.stream.buffer->data; + sound.frameCount = source.frameCount; sound.stream.sampleRate = AUDIO.System.device.sampleRate; sound.stream.sampleSize = 32; @@ -945,6 +955,7 @@ Sound LoadSoundAlias(Sound source) return sound; } + // Checks if a sound is ready bool IsSoundReady(Sound sound) { @@ -1786,7 +1797,14 @@ void SeekMusicStream(Music music, float position) case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame((drmp3 *)music.ctxData, positionInFrames); break; #endif #if defined(SUPPORT_FILEFORMAT_QOA) - case MUSIC_AUDIO_QOA: qoaplay_seek_frame((qoaplay_desc *)music.ctxData, positionInFrames); break; + case MUSIC_AUDIO_QOA: + { + int qoaFrame = positionInFrames/QOA_FRAME_LEN; + qoaplay_seek_frame((qoaplay_desc *)music.ctxData, qoaFrame); // Seeks to QOA frame, not PCM frame + + // We need to compute QOA frame number and update positionInFrames + positionInFrames = ((qoaplay_desc *)music.ctxData)->sample_position; + } break; #endif #if defined(SUPPORT_FILEFORMAT_FLAC) case MUSIC_AUDIO_FLAC: drflac_seek_to_pcm_frame((drflac *)music.ctxData, positionInFrames); break; @@ -1867,7 +1885,7 @@ void UpdateMusicStream(Music music) frameCountReadTotal += frameCountRead; frameCountStillNeeded -= frameCountRead; if (frameCountStillNeeded == 0) break; - else stb_vorbis_seek_start((stb_vorbis *)music.ctxData); + else SeekMusicStream(music, music.loopPoint); } } break; #endif @@ -1887,18 +1905,10 @@ void UpdateMusicStream(Music music) #if defined(SUPPORT_FILEFORMAT_QOA) case MUSIC_AUDIO_QOA: { - unsigned int frameCountRead = qoaplay_decode((qoaplay_desc *)music.ctxData, (float *)AUDIO.System.pcmBuffer, framesToStream); - frameCountReadTotal += frameCountRead; - /* - while (true) - { - int frameCountRead = (int)qoaplay_decode((qoaplay_desc *)music.ctxData, (float *)((char *)AUDIO.System.pcmBuffer + frameCountReadTotal*frameSize), frameCountStillNeeded); - frameCountReadTotal += frameCountRead; - frameCountStillNeeded -= frameCountRead; - if (frameCountStillNeeded == 0) break; - else qoaplay_rewind((qoaplay_desc *)music.ctxData); - } - */ + int qoaFrame = (int)(music.loopPoint * music.stream.sampleRate)/QOA_FRAME_LEN; + unsigned int frameCountRead = qoaplay_decode((qoaplay_desc *)music.ctxData, (float *)AUDIO.System.pcmBuffer, framesToStream, qoaFrame); + frameCountReadTotal += frameCountRead; + } break; #endif #if defined(SUPPORT_FILEFORMAT_FLAC) @@ -1949,8 +1959,6 @@ void UpdateMusicStream(Music music) StopMusicStream(music); return; } - - SeekMusicStream(music, music.loopPoint); } } diff --git a/raylib/src/raylib.dll.rc b/raylib/src/raylib.dll.rc index c2a42dc..e1455af 100644 --- a/raylib/src/raylib.dll.rc +++ b/raylib/src/raylib.dll.rc @@ -1,8 +1,8 @@ GLFW_ICON ICON "raylib.ico" 1 VERSIONINFO -FILEVERSION 4,5,0,0 -PRODUCTVERSION 4,5,0,0 +FILEVERSION 5,0,0,0 +PRODUCTVERSION 5,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -11,12 +11,12 @@ BEGIN BEGIN //VALUE "CompanyName", "raylib technologies" VALUE "FileDescription", "raylib dynamic library (www.raylib.com)" - VALUE "FileVersion", "4.5.0" + VALUE "FileVersion", "5.0.0" VALUE "InternalName", "raylib.dll" VALUE "LegalCopyright", "(c) 2023 Ramon Santamaria (@raysan5)" VALUE "OriginalFilename", "raylib.dll" VALUE "ProductName", "raylib" - VALUE "ProductVersion", "4.5.0" + VALUE "ProductVersion", "5.0.0" END END BLOCK "VarFileInfo" diff --git a/raylib/src/raylib.dll.rc.data b/raylib/src/raylib.dll.rc.data Binary files differindex 7403bd0..e93edcf 100644 --- a/raylib/src/raylib.dll.rc.data +++ b/raylib/src/raylib.dll.rc.data diff --git a/raylib/src/raylib.h b/raylib/src/raylib.h index edda3c7..be39b61 100644 --- a/raylib/src/raylib.h +++ b/raylib/src/raylib.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* raylib v4.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) +* raylib v5.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) * * FEATURES: * - NO external dependencies, all required libraries included with raylib @@ -81,10 +81,10 @@ #include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback -#define RAYLIB_VERSION_MAJOR 4 -#define RAYLIB_VERSION_MINOR 6 +#define RAYLIB_VERSION_MAJOR 5 +#define RAYLIB_VERSION_MINOR 0 #define RAYLIB_VERSION_PATCH 0 -#define RAYLIB_VERSION "4.6-dev" +#define RAYLIB_VERSION "5.0" // Function specifiers in case library is build/used as a shared library (Windows) // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll @@ -507,6 +507,20 @@ typedef struct FilePathList { char **paths; // Filepaths entries } FilePathList; +// Automation event +typedef struct AutomationEvent { + unsigned int frame; // Event frame + unsigned int type; // Event type (AutomationEventType) + int params[4]; // Event parameters (if required) +} AutomationEvent; + +// Automation event list +typedef struct AutomationEventList { + unsigned int capacity; // Events max entries (MAX_AUTOMATION_EVENTS) + unsigned int count; // Events entries count + AutomationEvent *events; // Events entries +} AutomationEventList; + //---------------------------------------------------------------------------------- // Enumerators Definition //---------------------------------------------------------------------------------- @@ -1054,9 +1068,13 @@ RLAPI void SwapScreenBuffer(void); // Swap back b RLAPI void PollInputEvents(void); // Register all input events RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) -// Misc. functions -RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +// Random values generation functions RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator +RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +RLAPI int *LoadRandomSequence(unsigned int count, int min, int max); // Load random values sequence, no values repeated +RLAPI void UnloadRandomSequence(int *sequence); // Unload random values sequence + +// Misc. functions RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) @@ -1115,6 +1133,16 @@ RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataS RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree() RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree() +// 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 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 +RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set) +RLAPI void StopAutomationEventRecording(void); // Stop recording automation events +RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event + //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) //------------------------------------------------------------------------------------ @@ -1194,20 +1222,17 @@ RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set t RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line -RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) -RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness -RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out -RLAPI void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color); // Draw line using quadratic bezier curves with a control point -RLAPI void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlPos, Vector2 endControlPos, float thick, Color color); // Draw line using cubic bezier curves with 2 control points -RLAPI void DrawLineBSpline(Vector2 *points, int pointCount, float thick, Color color); // Draw a B-Spline line, minimum 4 points -RLAPI void DrawLineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw a Catmull Rom spline line, minimum 4 points -RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence +RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) +RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads) +RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines) +RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline +RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version) RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring @@ -1231,6 +1256,25 @@ RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Col RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters +// Splines drawing functions +RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points +RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points +RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points +RLAPI void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +RLAPI void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points +RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points +RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points +RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point +RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points + +// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] +RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear +RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline +RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom +RLAPI Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier +RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier + // Basic shapes collision detection functions RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles @@ -1539,6 +1583,7 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully RLAPI void SetMasterVolume(float volume); // Set master volume (listener) +RLAPI float GetMasterVolume(void); // Get master volume (listener) // Wave/Sound loading/unloading functions RLAPI Wave LoadWave(const char *fileName); // Load wave data from file diff --git a/raylib/src/raylib.rc b/raylib/src/raylib.rc index 6a95465..8612a95 100644 --- a/raylib/src/raylib.rc +++ b/raylib/src/raylib.rc @@ -1,8 +1,8 @@ GLFW_ICON ICON "raylib.ico" 1 VERSIONINFO -FILEVERSION 4,5,0,0 -PRODUCTVERSION 4,5,0,0 +FILEVERSION 5,0,0,0 +PRODUCTVERSION 5,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -11,12 +11,12 @@ BEGIN BEGIN //VALUE "CompanyName", "raylib technologies" VALUE "FileDescription", "raylib application (www.raylib.com)" - VALUE "FileVersion", "4.5.0" + VALUE "FileVersion", "5.0.0" VALUE "InternalName", "raylib app" VALUE "LegalCopyright", "(c) 2023 Ramon Santamaria (@raysan5)" //VALUE "OriginalFilename", "raylib_app.exe" VALUE "ProductName", "raylib app" - VALUE "ProductVersion", "4.5.0" + VALUE "ProductVersion", "5.0.0" END END BLOCK "VarFileInfo" diff --git a/raylib/src/raylib.rc.data b/raylib/src/raylib.rc.data Binary files differindex 1485d3a..1476a1c 100644 --- a/raylib/src/raylib.rc.data +++ b/raylib/src/raylib.rc.data diff --git a/raylib/src/rcore.c b/raylib/src/rcore.c index f94731f..4539889 100644 --- a/raylib/src/rcore.c +++ b/raylib/src/rcore.c @@ -3,14 +3,22 @@ * rcore - Window/display management, Graphic device/context management and input management * * PLATFORMS SUPPORTED: -* - PLATFORM_DESKTOP: Windows (Win32, Win64) -* - PLATFORM_DESKTOP: Linux (X11 desktop mode) -* - PLATFORM_DESKTOP: FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop) -* - PLATFORM_DESKTOP: OSX/macOS -* - PLATFORM_WEB: HTML5 (WebAssembly) -* - PLATFORM_DRM: Raspberry Pi 0-5 -* - PLATFORM_DRM: Linux native mode (KMS driver) -* - PLATFORM_ANDROID: Android (ARM, ARM64) +* > PLATFORM_DESKTOP (GLFW backend): +* - Windows (Win32, Win64) +* - Linux (X11/Wayland desktop mode) +* - macOS/OSX (x64, arm64) +* - FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop) +* > PLATFORM_DESKTOP_SDL (SDL backend): +* - Windows (Win32, Win64) +* - Linux (X11/Wayland desktop mode) +* - Others (not tested) +* > PLATFORM_WEB: +* - HTML5 (WebAssembly) +* > PLATFORM_DRM: +* - Raspberry Pi 0-5 (DRM/KMS) +* - Linux DRM subsystem (KMS mode) +* > PLATFORM_ANDROID: +* - Android (ARM, ARM64) * * CONFIGURATION: * #define SUPPORT_DEFAULT_FONT (default) @@ -44,8 +52,8 @@ * provided by stb_image and stb_image_write libraries, so, those libraries must be enabled on textures module * for linkage * -* #define SUPPORT_EVENTS_AUTOMATION -* Support automatic generated events, loading and recording of those events when required +* #define SUPPORT_AUTOMATION_EVENTS +* Support automatic events recording and playing, useful for automated testing systems or AI based game playing * * DEPENDENCIES: * raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion) @@ -81,12 +89,19 @@ #include "config.h" // Defines module configuration flags #endif -#include "rcore.h" // Defines types and globals +#include "utils.h" // Required for: TRACELOG() macros + +#include <stdlib.h> // Required for: srand(), rand(), atexit() +#include <stdio.h> // Required for: sprintf() [Used in OpenURL()] +#include <string.h> // Required for: strrchr(), strcmp(), strlen(), memset() +#include <time.h> // Required for: time() [Used in InitTimer()] +#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] #define RLGL_IMPLEMENTATION #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 -#include "raymath.h" // Vector3, Quaternion and Matrix functionality +#define RAYMATH_IMPLEMENTATION +#include "raymath.h" // Vector2, Vector3, Quaternion and Matrix functionality #if defined(SUPPORT_GESTURES_SYSTEM) #define RGESTURES_IMPLEMENTATION @@ -116,6 +131,11 @@ #include "external/sdefl.h" // Deflate (RFC 1951) compressor #endif +#if defined(SUPPORT_RPRAND_GENERATOR) + #define RPRAND_IMPLEMENTATION + #include "external/rprand.h" +#endif + #if defined(__linux__) && !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif @@ -163,6 +183,166 @@ __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigne #endif //---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#ifndef MAX_FILEPATH_CAPACITY + #define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath +#endif +#ifndef MAX_FILEPATH_LENGTH + #if defined(_WIN32) + #define MAX_FILEPATH_LENGTH 256 // On Win32, MAX_PATH = 260 (limits.h) but Windows 10, Version 1607 enables long paths... + #else + #define MAX_FILEPATH_LENGTH 4096 // On Linux, PATH_MAX = 4096 by default (limits.h) + #endif +#endif + +#ifndef MAX_KEYBOARD_KEYS + #define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported +#endif +#ifndef MAX_MOUSE_BUTTONS + #define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported +#endif +#ifndef MAX_GAMEPADS + #define MAX_GAMEPADS 4 // Maximum number of gamepads supported +#endif +#ifndef MAX_GAMEPAD_AXIS + #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) +#endif +#ifndef MAX_GAMEPAD_BUTTONS + #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#endif +#ifndef MAX_TOUCH_POINTS + #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#endif +#ifndef MAX_KEY_PRESSED_QUEUE + #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue +#endif +#ifndef MAX_CHAR_PRESSED_QUEUE + #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue +#endif + +#ifndef MAX_DECOMPRESSION_SIZE + #define MAX_DECOMPRESSION_SIZE 64 // Maximum size allocated for decompression in MB +#endif + +#ifndef MAX_AUTOMATION_EVENTS + #define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record +#endif + +// Flags operation macros +#define FLAG_SET(n, f) ((n) |= (f)) +#define FLAG_CLEAR(n, f) ((n) &= ~(f)) +#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 +//---------------------------------------------------------------------------------- +typedef struct { int x; int y; } Point; +typedef struct { unsigned int width; unsigned int height; } Size; + +// Core global state context data +typedef struct CoreData { + struct { + const char *title; // Window text title const pointer + unsigned int flags; // Configuration flags (bit based), keeps window state + bool ready; // Check if window has been initialized successfully + bool fullscreen; // Check if fullscreen mode is enabled + bool shouldClose; // Check if window set for closing + bool resizedLastFrame; // Check if window has been resized last frame + bool eventWaiting; // Wait for events before ending frame + bool usingFbo; // Using FBO (RenderTexture) for rendering instead of default framebuffer + + Point position; // Window position (required on fullscreen toggle) + Point previousPosition; // Window previous position (required on borderless windowed toggle) + Size display; // Display width and height (monitor, device-screen, LCD, ...) + Size screen; // Screen width and height (used render area) + Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) + Size currentFbo; // Current render width and height (depends on active fbo) + Size render; // Framebuffer width and height (render area, including black bars if required) + Point renderOffset; // Offset from render area (must be divided by 2) + Size screenMin; // Screen minimum width and height (for resizable window) + Size screenMax; // Screen maximum width and height (for resizable window) + Matrix screenScale; // Matrix to scale screen (framebuffer rendering) + + char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) + unsigned int dropFileCount; // Count dropped files strings + + } Window; + struct { + const char *basePath; // Base path for data storage + + } Storage; + 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 + + // 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. + + 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 charPressedQueueCount; // Input characters queue count + + } Keyboard; + struct { + Vector2 offset; // Mouse offset + Vector2 scale; // Mouse scaling + Vector2 currentPosition; // Mouse position on screen + Vector2 previousPosition; // Previous mouse position + + int cursor; // Tracks current mouse cursor + bool cursorHidden; // Track if cursor is hidden + bool cursorOnScreen; // Tracks if cursor is inside client area + + char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state + char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state + Vector2 currentWheelMove; // Registers current mouse wheel variation + Vector2 previousWheelMove; // Registers previous mouse wheel variation + + } Mouse; + struct { + int pointCount; // Number of touch points active + int pointId[MAX_TOUCH_POINTS]; // Point identifiers + Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen + char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state + char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state + + } Touch; + struct { + int lastButtonPressed; // Register last gamepad button pressed + 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 + char previousButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state + float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state + + } Gamepad; + } Input; + struct { + double current; // Current time measure + double previous; // Previous time measure + double update; // Time measure for frame update + double draw; // Time measure for frame draw + double frame; // Time measure for one frame + double target; // Desired time for one frame, if 0 not applied + unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) + unsigned int frameCounter; // Frame counter + + } Time; +} CoreData; + +//---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings @@ -179,9 +359,8 @@ bool gifRecording = false; // GIF recording state MsfGifState gifState = { 0 }; // MSGIF context state #endif -#if defined(SUPPORT_EVENTS_AUTOMATION) -#define MAX_CODE_AUTOMATION_EVENTS 16384 - +#if defined(SUPPORT_AUTOMATION_EVENTS) +// Automation events type typedef enum AutomationEventType { EVENT_NONE = 0, // Input events @@ -208,12 +387,12 @@ typedef enum AutomationEventType { WINDOW_MINIMIZE, // no params WINDOW_RESIZE, // param[0]: width, param[1]: height // Custom events - ACTION_TAKE_SCREENSHOT, - ACTION_SETTARGETFPS + ACTION_TAKE_SCREENSHOT, // no params + ACTION_SETTARGETFPS // param[0]: fps } AutomationEventType; -// Event type -// Used to enable events flags +// Event type to config events flags +// TODO: Not used at the moment typedef enum { EVENT_INPUT_KEYBOARD = 0, EVENT_INPUT_MOUSE = 1, @@ -224,6 +403,7 @@ typedef enum { EVENT_CUSTOM = 32 } EventType; +// Event type name strings, required for export static const char *autoEventTypeName[] = { "EVENT_NONE", "INPUT_KEY_UP", @@ -251,19 +431,19 @@ static const char *autoEventTypeName[] = { "ACTION_SETTARGETFPS" }; +/* // Automation event (24 bytes) -typedef struct AutomationEvent { +// NOTE: Opaque struct, internal to raylib +struct AutomationEvent { unsigned int frame; // Event frame unsigned int type; // Event type (AutomationEventType) int params[4]; // Event parameters (if required) -} AutomationEvent; - -static AutomationEvent *events = NULL; // Events array -static unsigned int eventCount = 0; // Events count -static bool eventsPlaying = false; // Play events -static bool eventsRecording = false; // Record events +}; +*/ -//static short eventsEnabled = 0b0000001111111111; // Events enabled for checking +static AutomationEventList *currentEventList = NULL; // Current automation events list, set by user, keep internal pointer +static bool automationEventRecording = false; // Recording automation events flag +//static short automationEventEnabled = 0b0000001111111111; // TODO: Automation events enabled for recording/playing #endif //----------------------------------------------------------------------------------- @@ -277,18 +457,18 @@ extern void LoadFontDefault(void); // [Module: text] Loads default font on extern void UnloadFontDefault(void); // [Module: text] Unloads default font from GPU memory #endif -static void InitTimer(void); // Initialize timer (hi-resolution if available) -static void SetupFramebuffer(int width, int height); // Setup main framebuffer +extern int InitPlatform(void); // Initialize platform (graphics, inputs and more) +extern void ClosePlatform(void); // Close platform + +static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform()) +static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform()) static void SetupViewport(int width, int height); // Set viewport for a provided width and height static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories recursively from a base path -#if defined(SUPPORT_EVENTS_AUTOMATION) -static void LoadAutomationEvents(const char *fileName); // Load automation events from file -static void ExportAutomationEvents(const char *fileName); // Export recorded automation events into a file -static void RecordAutomationEvent(unsigned int frame); // Record frame events (to internal events array) -static void PlayAutomationEvent(unsigned int frame); // Play frame events (from internal events array) +#if defined(SUPPORT_AUTOMATION_EVENTS) +static void RecordAutomationEvent(void); // Record frame events (to internal events array) #endif #if defined(_WIN32) @@ -297,18 +477,20 @@ void __stdcall Sleep(unsigned long msTimeout); // Required for: Wai #endif #if !defined(SUPPORT_MODULE_RTEXT) -const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' +const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' #endif // !SUPPORT_MODULE_RTEXT // Include platform-specific submodules #if defined(PLATFORM_DESKTOP) - #include "rcore_desktop.c" + #include "platforms/rcore_desktop.c" +#elif defined(PLATFORM_DESKTOP_SDL) + #include "platforms/rcore_desktop_sdl.c" #elif defined(PLATFORM_WEB) - #include "rcore_web.c" + #include "platforms/rcore_web.c" #elif defined(PLATFORM_DRM) - #include "rcore_drm.c" + #include "platforms/rcore_drm.c" #elif defined(PLATFORM_ANDROID) - #include "rcore_android.c" + #include "platforms/rcore_android.c" #else // TODO: Include your custom platform backend! // i.e software rendering backend or console backend! @@ -319,8 +501,6 @@ const char *TextFormat(const char *text, ...); // Formatting of text with //---------------------------------------------------------------------------------- // NOTE: Functions with a platform-specific implementation on rcore_<platform>.c -//void InitWindow(int width, int height, const char *title) -//void CloseWindow(void) //bool WindowShouldClose(void) //void ToggleFullscreen(void) //void ToggleBorderlessWindowed(void) @@ -363,6 +543,154 @@ const char *TextFormat(const char *text, ...); // Formatting of text with //void EnableCursor(void) //void DisableCursor(void) +// Initialize window and OpenGL context +// NOTE: data parameter could be used to pass any kind of required data to the initialization +void InitWindow(int width, int height, const char *title) +{ + TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); + +#if defined(PLATFORM_DESKTOP) + TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)"); +#elif defined(PLATFORM_DESKTOP_SDL) + TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)"); +#elif defined(PLATFORM_WEB) + TRACELOG(LOG_INFO, "Platform backend: WEB (HTML5)"); +#elif defined(PLATFORM_DRM) + TRACELOG(LOG_INFO, "Platform backend: NATIVE DRM"); +#elif defined(PLATFORM_ANDROID) + TRACELOG(LOG_INFO, "Platform backend: ANDROID"); +#else + // TODO: Include your custom platform backend! + // i.e software rendering backend or console backend! + TRACELOG(LOG_INFO, "Platform backend: CUSTOM"); +#endif + + TRACELOG(LOG_INFO, "Supported raylib modules:"); + TRACELOG(LOG_INFO, " > rcore:..... loaded (mandatory)"); + TRACELOG(LOG_INFO, " > rlgl:...... loaded (mandatory)"); +#if defined(SUPPORT_MODULE_RSHAPES) + TRACELOG(LOG_INFO, " > rshapes:... loaded (optional)"); +#else + TRACELOG(LOG_INFO, " > rshapes:... not loaded (optional)"); +#endif +#if defined(SUPPORT_MODULE_RTEXTURES) + TRACELOG(LOG_INFO, " > rtextures:. loaded (optional)"); +#else + TRACELOG(LOG_INFO, " > rtextures:. not loaded (optional)"); +#endif +#if defined(SUPPORT_MODULE_RTEXT) + TRACELOG(LOG_INFO, " > rtext:..... loaded (optional)"); +#else + TRACELOG(LOG_INFO, " > rtext:..... not loaded (optional)"); +#endif +#if defined(SUPPORT_MODULE_RMODELS) + TRACELOG(LOG_INFO, " > rmodels:... loaded (optional)"); +#else + TRACELOG(LOG_INFO, " > rmodels:... not loaded (optional)"); +#endif +#if defined(SUPPORT_MODULE_RAUDIO) + TRACELOG(LOG_INFO, " > raudio:.... loaded (optional)"); +#else + TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); +#endif + + // Initialize window data + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + CORE.Window.eventWaiting = false; + CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default + if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; + + // Initialize global input state + memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0 + CORE.Input.Keyboard.exitKey = KEY_ESCAPE; + CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; + CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; + CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; + + // Initialize platform + //-------------------------------------------------------------- + InitPlatform(); + //-------------------------------------------------------------- + + // Initialize rlgl default data (buffers and shaders) + // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl + rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); + + // Setup default viewport + SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); + +#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) + // Load default font + // WARNING: External function: Module required: rtext + LoadFontDefault(); + #if defined(SUPPORT_MODULE_RSHAPES) + // Set font white rectangle for shapes drawing, so shapes and text can be batched together + // WARNING: rshapes module is required, if not available, default internal white rectangle is used + Rectangle rec = GetFontDefault().recs[95]; + if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + { + // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering + SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); + } + else + { + // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding + SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); + } + #endif +#else + #if defined(SUPPORT_MODULE_RSHAPES) + // Set default texture and rectangle to be used for shapes drawing + // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 + Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; + SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes + #endif +#endif +#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) + if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + { + // Set default font texture filter for HighDPI (blurry) + // RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps + rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR); + rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR); + } +#endif + + CORE.Time.frameCounter = 0; + CORE.Window.shouldClose = false; + + // Initialize random seed + SetRandomSeed((unsigned int)time(NULL)); +} + +// Close window and unload OpenGL context +void CloseWindow(void) +{ +#if defined(SUPPORT_GIF_RECORDING) + if (gifRecording) + { + MsfGifResult result = msf_gif_end(&gifState); + msf_gif_free(result); + gifRecording = false; + } +#endif + +#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) + UnloadFontDefault(); // WARNING: Module required: rtext +#endif + + rlglClose(); // De-init rlgl + + // De-initialize platform + //-------------------------------------------------------------- + ClosePlatform(); + //-------------------------------------------------------------- + + CORE.Window.ready = false; + TRACELOG(LOG_INFO, "Window closed successfully"); +} + // Check if window has been initialized successfully bool IsWindowReady(void) { @@ -426,13 +754,27 @@ int GetScreenHeight(void) // Get current render width which is equal to screen width*dpi scale int GetRenderWidth(void) { - return CORE.Window.render.width; + int width = 0; +#if defined(__APPLE__) + Vector2 scale = GetWindowScaleDPI(); + width = (int)((float)CORE.Window.render.width*scale.x); +#else + width = CORE.Window.render.width; +#endif + return width; } // Get current screen height which is equal to screen height*dpi scale int GetRenderHeight(void) { - return CORE.Window.render.height; + int height = 0; +#if defined(__APPLE__) + Vector2 scale = GetWindowScaleDPI(); + height = (int)((float)CORE.Window.render.height*scale.y); +#else + height = CORE.Window.render.height; +#endif + return height; } // Enable waiting for events on EndDrawing(), no automatic event polling @@ -523,32 +865,8 @@ void EndDrawing(void) } #endif -#if defined(SUPPORT_EVENTS_AUTOMATION) - // Draw record/play indicator - if (eventsRecording) - { - gifFrameCounter++; - - if (((gifFrameCounter/15)%2) == 1) - { - DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON); - DrawText("EVENTS RECORDING", 50, CORE.Window.screen.height - 25, 10, RED); - } - - rlDrawRenderBatchActive(); // Update and draw internal render batch - } - else if (eventsPlaying) - { - gifFrameCounter++; - - if (((gifFrameCounter/15)%2) == 1) - { - DrawCircle(30, CORE.Window.screen.height - 20, 10, LIME); - DrawText("EVENTS PLAYING", 50, CORE.Window.screen.height - 25, 10, GREEN); - } - - rlDrawRenderBatchActive(); // Update and draw internal render batch - } +#if defined(SUPPORT_AUTOMATION_EVENTS) + if (automationEventRecording) RecordAutomationEvent(); // Event recording #endif #if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) @@ -576,16 +894,43 @@ void EndDrawing(void) PollInputEvents(); // Poll user events (before next frame update) #endif -#if defined(SUPPORT_EVENTS_AUTOMATION) - // Events recording and playing logic - if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter); - else if (eventsPlaying) +#if defined(SUPPORT_SCREEN_CAPTURE) + if (IsKeyPressed(KEY_F12)) { - // TODO: When should we play? After/before/replace PollInputEvents()? - if (CORE.Time.frameCounter >= eventCount) eventsPlaying = false; - PlayAutomationEvent(CORE.Time.frameCounter); +#if defined(SUPPORT_GIF_RECORDING) + if (IsKeyDown(KEY_LEFT_CONTROL)) + { + if (gifRecording) + { + gifRecording = false; + + MsfGifResult result = msf_gif_end(&gifState); + + SaveFileData(TextFormat("%s/screenrec%03i.gif", CORE.Storage.basePath, screenshotCounter), result.data, (unsigned int)result.dataSize); + msf_gif_free(result); + + TRACELOG(LOG_INFO, "SYSTEM: Finish animated GIF recording"); + } + else + { + gifRecording = true; + gifFrameCounter = 0; + + Vector2 scale = GetWindowScaleDPI(); + msf_gif_begin(&gifState, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); + screenshotCounter++; + + TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter)); + } + } + else +#endif // SUPPORT_GIF_RECORDING + { + TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); + screenshotCounter++; + } } -#endif +#endif // SUPPORT_SCREEN_CAPTURE CORE.Time.frameCounter++; } @@ -696,6 +1041,7 @@ void BeginTextureMode(RenderTexture2D target) // calculation when using BeginMode3D() CORE.Window.currentFbo.width = target.texture.width; CORE.Window.currentFbo.height = target.texture.height; + CORE.Window.usingFbo = true; } // Ends drawing to render texture @@ -711,6 +1057,7 @@ void EndTextureMode(void) // Reset current fbo to screen size CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.height = CORE.Window.render.height; + CORE.Window.usingFbo = false; } // Begin custom shader mode @@ -747,19 +1094,22 @@ void BeginScissorMode(int x, int y, int width, int height) rlEnableScissorTest(); #if defined(__APPLE__) - Vector2 scale = GetWindowScaleDPI(); - rlScissor((int)(x*scale.x), (int)(GetScreenHeight()*scale.y - (((y + height)*scale.y))), (int)(width*scale.x), (int)(height*scale.y)); + if (!CORE.Window.usingFbo) + { + Vector2 scale = GetWindowScaleDPI(); + rlScissor((int)(x*scale.x), (int)(GetScreenHeight()*scale.y - (((y + height)*scale.y))), (int)(width*scale.x), (int)(height*scale.y)); + } #else - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + if (!CORE.Window.usingFbo && ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)) { Vector2 scale = GetWindowScaleDPI(); rlScissor((int)(x*scale.x), (int)(CORE.Window.currentFbo.height - (y + height)*scale.y), (int)(width*scale.x), (int)(height*scale.y)); } +#endif else { rlScissor(x, CORE.Window.currentFbo.height - (y + height), width, height); } -#endif } // End scissor mode @@ -1233,6 +1583,16 @@ int GetFPS(void) static float average = 0, last = 0; float fpsFrame = GetFrameTime(); + // if we reset the window, reset the FPS info + if (CORE.Time.frameCounter == 0) + { + average = 0; + last = 0; + index = 0; + + for (int i = 0; i < FPS_CAPTURE_FRAMES_COUNT; i++) history[i] = 0; + } + if (fpsFrame == 0) return 0; if ((GetTime() - last) > FPS_STEP) @@ -1261,7 +1621,7 @@ float GetFrameTime(void) //---------------------------------------------------------------------------------- // NOTE: Functions with a platform-specific implementation on rcore_<platform>.c -//void SwapScreenBuffer(void); +//void SwapScreenBuffer(void); //void PollInputEvents(void); // Wait for some time (stop program execution) @@ -1272,7 +1632,7 @@ float GetFrameTime(void) void WaitTime(double seconds) { if (seconds < 0) return; - + #if defined(SUPPORT_BUSY_WAIT_LOOP) || defined(SUPPORT_PARTIALBUSY_WAIT_LOOP) double destinationTime = GetTime() + seconds; #endif @@ -1317,12 +1677,22 @@ void WaitTime(double seconds) // NOTE: Functions with a platform-specific implementation on rcore_<platform>.c //void OpenURL(const char *url) -// Get a random value between min and max (both included) -// WARNING: Ranges higher than RAND_MAX will return invalid results -// More specifically, if (max - min) > INT_MAX there will be an overflow, -// and otherwise if (max - min) > RAND_MAX the random value will incorrectly never exceed a certain threshold + +// Set the seed for the random number generator +void SetRandomSeed(unsigned int seed) +{ +#if defined(SUPPORT_RPRAND_GENERATOR) + rprand_set_seed(seed); +#else + srand(seed); +#endif +} + +// Get a random value between min and max included int GetRandomValue(int min, int max) { + int value = 0; + if (min > max) { int tmp = max; @@ -1330,21 +1700,74 @@ int GetRandomValue(int min, int max) min = tmp; } +#if defined(SUPPORT_RPRAND_GENERATOR) + value = rprand_get_value(min, max); +#else + // WARNING: Ranges higher than RAND_MAX will return invalid results + // More specifically, if (max - min) > INT_MAX there will be an overflow, + // and otherwise if (max - min) > RAND_MAX the random value will incorrectly never exceed a certain threshold + // NOTE: Depending on the library it can be as low as 32767 if ((unsigned int)(max - min) > (unsigned int)RAND_MAX) { TRACELOG(LOG_WARNING, "Invalid GetRandomValue() arguments, range should not be higher than %i", RAND_MAX); } - return (rand()%(abs(max - min) + 1) + min); + value = (rand()%(abs(max - min) + 1) + min); +#endif + return value; } -// Set the seed for the random number generator -void SetRandomSeed(unsigned int seed) +// Load random values sequence, no values repeated, min and max included +int *LoadRandomSequence(unsigned int count, int min, int max) { - srand(seed); + int *values = NULL; + +#if defined(SUPPORT_RPRAND_GENERATOR) + values = rprand_load_sequence(count, min, max); +#else + if (count > ((unsigned int)abs(max - min) + 1)) return values; + + values = (int *)RL_CALLOC(count, sizeof(int)); + + int value = 0; + bool dupValue = false; + + for (int i = 0; i < (int)count;) + { + value = (rand()%(abs(max - min) + 1) + min); + dupValue = false; + + for (int j = 0; j < i; j++) + { + if (values[j] == value) + { + dupValue = true; + break; + } + } + + if (!dupValue) + { + values[i] = value; + i++; + } + } +#endif + return values; } -// Takes a screenshot of current screen (saved a .png) +// Unload random values sequence +void UnloadRandomSequence(int *sequence) +{ +#if defined(SUPPORT_RPRAND_GENERATOR) + rprand_unload_sequence(sequence); +#else + RL_FREE(sequence); +#endif +} + +// Takes a screenshot of current screen +// NOTE: Provided fileName should not contain paths, saving to working directory void TakeScreenshot(const char *fileName) { #if defined(SUPPORT_MODULE_RTEXTURES) @@ -1356,12 +1779,13 @@ void TakeScreenshot(const char *fileName) Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; char path[512] = { 0 }; - strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName)); - + strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, GetFileName(fileName))); + ExportImage(image, path); // WARNING: Module required: rtextures RL_FREE(imgData); - TRACELOG(LOG_INFO, "SYSTEM: [%s] Screenshot taken successfully", path); + if (FileExists(path)) TRACELOG(LOG_INFO, "SYSTEM: [%s] Screenshot taken successfully", path); + else TRACELOG(LOG_WARNING, "SYSTEM: [%s] Screenshot could not be saved", path); #else TRACELOG(LOG_WARNING,"IMAGE: ExportImage() requires module: rtextures"); #endif @@ -1414,10 +1838,10 @@ bool IsFileExtension(const char *fileName, const char *ext) { #if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_TEXT_MANIPULATION) int extCount = 0; - const char **checkExts = TextSplit(ext, ';', &extCount); // WARNING: Module required: rtext + 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 + strncpy(fileExtLower, TextToLower(fileExt), MAX_FILE_EXTENSION_SIZE); // WARNING: Module required: rtext for (int i = 0; i < extCount; i++) { @@ -1972,6 +2396,255 @@ unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize) } //---------------------------------------------------------------------------------- +// Module Functions Definition: Automation Events Recording and Playing +//---------------------------------------------------------------------------------- + +// Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS +AutomationEventList LoadAutomationEventList(const char *fileName) +{ + AutomationEventList list = { 0 }; + + // Allocate and empty automation event list, ready to record new events + list.events = (AutomationEvent *)RL_CALLOC(MAX_AUTOMATION_EVENTS, sizeof(AutomationEvent)); + list.capacity = MAX_AUTOMATION_EVENTS; + +#if defined(SUPPORT_AUTOMATION_EVENTS) + if (fileName == NULL) TRACELOG(LOG_INFO, "AUTOMATION: New empty events list loaded successfully"); + else + { + // Load automation events file (binary) + /* + //int dataSize = 0; + //unsigned char *data = LoadFileData(fileName, &dataSize); + + FILE *raeFile = fopen(fileName, "rb"); + unsigned char fileId[4] = { 0 }; + + fread(fileId, 1, 4, raeFile); + + if ((fileId[0] == 'r') && (fileId[1] == 'A') && (fileId[2] == 'E') && (fileId[1] == ' ')) + { + fread(&eventCount, sizeof(int), 1, raeFile); + TRACELOG(LOG_WARNING, "Events loaded: %i\n", eventCount); + fread(events, sizeof(AutomationEvent), eventCount, raeFile); + } + + fclose(raeFile); + */ + + // Load events file (text) + //unsigned char *buffer = LoadFileText(fileName); + FILE *raeFile = fopen(fileName, "rt"); + + if (raeFile != NULL) + { + unsigned int counter = 0; + char buffer[256] = { 0 }; + char eventDesc[64] = { 0 }; + + fgets(buffer, 256, raeFile); + + while (!feof(raeFile)) + { + switch (buffer[0]) + { + case 'c': sscanf(buffer, "c %i", &list.count); break; + case 'e': + { + sscanf(buffer, "e %d %d %d %d %d %d %[^\n]s", &list.events[counter].frame, &list.events[counter].type, + &list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc); + + counter++; + } break; + default: break; + } + + fgets(buffer, 256, raeFile); + } + + if (counter != list.count) + { + TRACELOG(LOG_WARNING, "AUTOMATION: Events read from file [%i] do not mach event count specified [%i]", counter, list.count); + list.count = counter; + } + + fclose(raeFile); + + TRACELOG(LOG_INFO, "AUTOMATION: Events file loaded successfully"); + } + + TRACELOG(LOG_INFO, "AUTOMATION: Events loaded from file: %i", list.count); + } +#endif + return list; +} + +// Unload automation events list from file +void UnloadAutomationEventList(AutomationEventList *list) +{ +#if defined(SUPPORT_AUTOMATION_EVENTS) + RL_FREE(list->events); + list->events = NULL; + list->count = 0; + list->capacity = 0; +#endif +} + +// Export automation events list as text file +bool ExportAutomationEventList(AutomationEventList list, const char *fileName) +{ + bool success = false; + +#if defined(SUPPORT_AUTOMATION_EVENTS) + // Export events as binary file + // TODO: Save to memory buffer and SaveFileData() + /* + unsigned char fileId[4] = "rAE "; + FILE *raeFile = fopen(fileName, "wb"); + fwrite(fileId, sizeof(unsigned char), 4, raeFile); + fwrite(&eventCount, sizeof(int), 1, raeFile); + fwrite(events, sizeof(AutomationEvent), eventCount, raeFile); + fclose(raeFile); + */ + + // Export events as text + // TODO: Save to memory buffer and SaveFileText() + char *txtData = (char *)RL_CALLOC(256*list.count + 2048, sizeof(char)); // 256 characters per line plus some header + + int byteCount = 0; + byteCount += sprintf(txtData + byteCount, "#\n"); + byteCount += sprintf(txtData + byteCount, "# Automation events exporter v1.0 - raylib automation events list\n"); + byteCount += sprintf(txtData + byteCount, "#\n"); + byteCount += sprintf(txtData + byteCount, "# c <events_count>\n"); + byteCount += sprintf(txtData + byteCount, "# e <frame> <event_type> <param0> <param1> <param2> <param3> // <event_type_name>\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-2024 Ramon Santamaria (@raysan5)\n"); + byteCount += sprintf(txtData + byteCount, "#\n\n"); + + // Add events data + byteCount += sprintf(txtData + byteCount, "c %i\n", list.count); + for (unsigned int i = 0; i < list.count; i++) + { + byteCount += snprintf(txtData + byteCount, 256, "e %i %i %i %i %i %i // Event: %s\n", list.events[i].frame, list.events[i].type, + list.events[i].params[0], list.events[i].params[1], list.events[i].params[2], list.events[i].params[3], autoEventTypeName[list.events[i].type]); + } + + // NOTE: Text data size exported is determined by '\0' (NULL) character + success = SaveFileText(fileName, txtData); + + RL_FREE(txtData); +#endif + + return success; +} + +// Setup automation event list to record to +void SetAutomationEventList(AutomationEventList *list) +{ +#if defined(SUPPORT_AUTOMATION_EVENTS) + currentEventList = list; +#endif +} + +// Set automation event internal base frame to start recording +void SetAutomationEventBaseFrame(int frame) +{ + CORE.Time.frameCounter = frame; +} + +// Start recording automation events (AutomationEventList must be set) +void StartAutomationEventRecording(void) +{ +#if defined(SUPPORT_AUTOMATION_EVENTS) + automationEventRecording = true; +#endif +} + +// Stop recording automation events +void StopAutomationEventRecording(void) +{ +#if defined(SUPPORT_AUTOMATION_EVENTS) + automationEventRecording = false; +#endif +} + +// Play a recorded automation event +void PlayAutomationEvent(AutomationEvent event) +{ +#if defined(SUPPORT_AUTOMATION_EVENTS) + // WARNING: When should event be played? After/before/replace PollInputEvents()? -> Up to the user! + + if (!automationEventRecording) // TODO: Allow recording events while playing? + { + switch (event.type) + { + // Input event + case INPUT_KEY_UP: CORE.Input.Keyboard.currentKeyState[event.params[0]] = false; break; // param[0]: key + case INPUT_KEY_DOWN: { // param[0]: key + CORE.Input.Keyboard.currentKeyState[event.params[0]] = true; + + if (CORE.Input.Keyboard.previousKeyState[event.params[0]] == false) + { + if (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) + { + // Add character to the queue + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = event.params[0]; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + } + } break; + case INPUT_MOUSE_BUTTON_UP: CORE.Input.Mouse.currentButtonState[event.params[0]] = false; break; // param[0]: key + case INPUT_MOUSE_BUTTON_DOWN: CORE.Input.Mouse.currentButtonState[event.params[0]] = true; break; // param[0]: key + case INPUT_MOUSE_POSITION: // param[0]: x, param[1]: y + { + CORE.Input.Mouse.currentPosition.x = (float)event.params[0]; + CORE.Input.Mouse.currentPosition.y = (float)event.params[1]; + } break; + case INPUT_MOUSE_WHEEL_MOTION: // param[0]: x delta, param[1]: y delta + { + CORE.Input.Mouse.currentWheelMove.x = (float)event.params[0]; break; + CORE.Input.Mouse.currentWheelMove.y = (float)event.params[1]; break; + } break; + case INPUT_TOUCH_UP: CORE.Input.Touch.currentTouchState[event.params[0]] = false; break; // param[0]: id + case INPUT_TOUCH_DOWN: CORE.Input.Touch.currentTouchState[event.params[0]] = true; break; // param[0]: id + case INPUT_TOUCH_POSITION: // param[0]: id, param[1]: x, param[2]: y + { + CORE.Input.Touch.position[event.params[0]].x = (float)event.params[1]; + CORE.Input.Touch.position[event.params[0]].y = (float)event.params[2]; + } break; + case INPUT_GAMEPAD_CONNECT: CORE.Input.Gamepad.ready[event.params[0]] = true; break; // param[0]: gamepad + case INPUT_GAMEPAD_DISCONNECT: CORE.Input.Gamepad.ready[event.params[0]] = false; break; // param[0]: gamepad + case INPUT_GAMEPAD_BUTTON_UP: CORE.Input.Gamepad.currentButtonState[event.params[0]][event.params[1]] = false; break; // param[0]: gamepad, param[1]: button + case INPUT_GAMEPAD_BUTTON_DOWN: CORE.Input.Gamepad.currentButtonState[event.params[0]][event.params[1]] = true; break; // param[0]: gamepad, param[1]: button + case INPUT_GAMEPAD_AXIS_MOTION: // param[0]: gamepad, param[1]: axis, param[2]: delta + { + CORE.Input.Gamepad.axisState[event.params[0]][event.params[1]] = ((float)event.params[2]/32768.0f); + } break; + case INPUT_GESTURE: GESTURES.current = event.params[0]; break; // param[0]: gesture (enum Gesture) -> rgestures.h: GESTURES.current + + // Window event + case WINDOW_CLOSE: CORE.Window.shouldClose = true; break; + case WINDOW_MAXIMIZE: MaximizeWindow(); break; + case WINDOW_MINIMIZE: MinimizeWindow(); break; + case WINDOW_RESIZE: SetWindowSize(event.params[0], event.params[1]); break; + + // Custom event + case ACTION_TAKE_SCREENSHOT: + { + TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); + screenshotCounter++; + } break; + case ACTION_SETTARGETFPS: SetTargetFPS(event.params[0]); break; + default: break; + } + } +#endif +} + +//---------------------------------------------------------------------------------- // Module Functions Definition: Input Handling: Keyboard //---------------------------------------------------------------------------------- @@ -2360,7 +3033,8 @@ int GetTouchPointCount(void) //---------------------------------------------------------------------------------- // NOTE: Functions with a platform-specific implementation on rcore_<platform>.c -//static bool InitPlatform(void) +//int InitPlatform(void) +//void ClosePlatform(void) // Initialize hi-resolution timer void InitTimer(void) @@ -2369,7 +3043,7 @@ void InitTimer(void) // 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) +#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 @@ -2396,8 +3070,6 @@ void SetupViewport(int width, int height) // NOTE: We consider render size (scaled) and offset in case black bars are required and // render area does not match full display area (this situation is only applicable on fullscreen mode) #if defined(__APPLE__) - //float xScale = 1.0f, yScale = 1.0f; - //glfwGetWindowContentScale(CORE.Window.handle, &xScale, &yScale); Vector2 scale = GetWindowScaleDPI(); rlViewport(CORE.Window.renderOffset.x/2*scale.x, CORE.Window.renderOffset.y/2*scale.y, (CORE.Window.render.width)*scale.x, (CORE.Window.render.height)*scale.y); #else @@ -2511,7 +3183,11 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const if ((strcmp(dp->d_name, ".") != 0) && (strcmp(dp->d_name, "..") != 0)) { + #if defined(_WIN32) + sprintf(path, "%s\\%s", basePath, dp->d_name); + #else sprintf(path, "%s/%s", basePath, dp->d_name); + #endif if (filter != NULL) { @@ -2550,7 +3226,11 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi if ((strcmp(dp->d_name, ".") != 0) && (strcmp(dp->d_name, "..") != 0)) { // Construct new path from our base path + #if defined(_WIN32) + sprintf(path, "%s\\%s", basePath, dp->d_name); + #else sprintf(path, "%s/%s", basePath, dp->d_name); + #endif if (IsPathFile(path)) { @@ -2583,233 +3263,180 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); } -#if defined(SUPPORT_EVENTS_AUTOMATION) -// NOTE: Loading happens over AutomationEvent *events -// TODO: This system should probably be redesigned -static void LoadAutomationEvents(const char *fileName) -{ - // Load events file (binary) - /* - FILE *repFile = fopen(fileName, "rb"); - unsigned char fileId[4] = { 0 }; - - fread(fileId, 1, 4, repFile); - - if ((fileId[0] == 'r') && (fileId[1] == 'E') && (fileId[2] == 'P') && (fileId[1] == ' ')) - { - fread(&eventCount, sizeof(int), 1, repFile); - TRACELOG(LOG_WARNING, "Events loaded: %i\n", eventCount); - fread(events, sizeof(AutomationEvent), eventCount, repFile); - } - - fclose(repFile); - */ - - // Load events file (text) - FILE *repFile = fopen(fileName, "rt"); - - if (repFile != NULL) - { - unsigned int count = 0; - char buffer[256] = { 0 }; - - fgets(buffer, 256, repFile); - - while (!feof(repFile)) - { - if (buffer[0] == 'c') sscanf(buffer, "c %i", &eventCount); - else if (buffer[0] == 'e') - { - sscanf(buffer, "e %d %d %d %d %d", &events[count].frame, &events[count].type, - &events[count].params[0], &events[count].params[1], &events[count].params[2]); - - count++; - } - - fgets(buffer, 256, repFile); - } - - if (count != eventCount) TRACELOG(LOG_WARNING, "Events count provided is different than count"); - - fclose(repFile); - } - - TRACELOG(LOG_WARNING, "Events loaded: %i", eventCount); -} - -// Export recorded events into a file -static void ExportAutomationEvents(const char *fileName) +#if defined(SUPPORT_AUTOMATION_EVENTS) +// Automation event recording +// NOTE: Recording is by default done at EndDrawing(), after PollInputEvents() +static void RecordAutomationEvent(void) { - unsigned char fileId[4] = "rEP "; - - // Save as binary - /* - FILE *repFile = fopen(fileName, "wb"); - fwrite(fileId, sizeof(unsigned char), 4, repFile); - fwrite(&eventCount, sizeof(int), 1, repFile); - fwrite(events, sizeof(AutomationEvent), eventCount, repFile); - fclose(repFile); - */ - - // Export events as text - FILE *repFile = fopen(fileName, "wt"); - - if (repFile != NULL) - { - fprintf(repFile, "# Automation events list\n"); - fprintf(repFile, "# c <events_count>\n"); - fprintf(repFile, "# e <frame> <event_type> <param0> <param1> <param2> // <event_type_name>\n"); - - fprintf(repFile, "c %i\n", eventCount); - for (int i = 0; i < eventCount; i++) - { - fprintf(repFile, "e %i %i %i %i %i // %s\n", events[i].frame, events[i].type, - events[i].params[0], events[i].params[1], events[i].params[2], autoEventTypeName[events[i].type]); - } + // Checking events in current frame and save them into currentEventList + // TODO: How important is the current frame? Could it be modified? - fclose(repFile); - } -} + if (currentEventList->count == currentEventList->capacity) return; // Security check -// EndDrawing() -> After PollInputEvents() -// Check event in current frame and save into the events[i] array -static void RecordAutomationEvent(unsigned int frame) -{ + // Keyboard input events recording + //------------------------------------------------------------------------------------- for (int key = 0; key < MAX_KEYBOARD_KEYS; key++) { - // INPUT_KEY_UP (only saved once) + // Event type: INPUT_KEY_UP (only saved once) if (CORE.Input.Keyboard.previousKeyState[key] && !CORE.Input.Keyboard.currentKeyState[key]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_KEY_UP; - events[eventCount].params[0] = key; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_KEY_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_KEY_UP; + currentEventList->events[currentEventList->count].params[0] = key; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_KEY_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } - // INPUT_KEY_DOWN + if (currentEventList->count == currentEventList->capacity) return; // Security check + + // Event type: INPUT_KEY_DOWN if (CORE.Input.Keyboard.currentKeyState[key]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_KEY_DOWN; - events[eventCount].params[0] = key; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_KEY_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_KEY_DOWN; + currentEventList->events[currentEventList->count].params[0] = key; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_KEY_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } + + if (currentEventList->count == currentEventList->capacity) return; // Security check } + //------------------------------------------------------------------------------------- + // Mouse input currentEventList->events recording + //------------------------------------------------------------------------------------- for (int button = 0; button < MAX_MOUSE_BUTTONS; button++) { - // INPUT_MOUSE_BUTTON_UP + // Event type: INPUT_MOUSE_BUTTON_UP if (CORE.Input.Mouse.previousButtonState[button] && !CORE.Input.Mouse.currentButtonState[button]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_MOUSE_BUTTON_UP; - events[eventCount].params[0] = button; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_BUTTON_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_MOUSE_BUTTON_UP; + currentEventList->events[currentEventList->count].params[0] = button; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_BUTTON_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } - // INPUT_MOUSE_BUTTON_DOWN + if (currentEventList->count == currentEventList->capacity) return; // Security check + + // Event type: INPUT_MOUSE_BUTTON_DOWN if (CORE.Input.Mouse.currentButtonState[button]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_MOUSE_BUTTON_DOWN; - events[eventCount].params[0] = button; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_BUTTON_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_MOUSE_BUTTON_DOWN; + currentEventList->events[currentEventList->count].params[0] = button; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_BUTTON_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } + + if (currentEventList->count == currentEventList->capacity) return; // Security check } - // INPUT_MOUSE_POSITION (only saved if changed) + // Event type: INPUT_MOUSE_POSITION (only saved if changed) if (((int)CORE.Input.Mouse.currentPosition.x != (int)CORE.Input.Mouse.previousPosition.x) || ((int)CORE.Input.Mouse.currentPosition.y != (int)CORE.Input.Mouse.previousPosition.y)) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_MOUSE_POSITION; - events[eventCount].params[0] = (int)CORE.Input.Mouse.currentPosition.x; - events[eventCount].params[1] = (int)CORE.Input.Mouse.currentPosition.y; - events[eventCount].params[2] = 0; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_MOUSE_POSITION; + currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentPosition.x; + currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentPosition.y; + currentEventList->events[currentEventList->count].params[2] = 0; - TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_POSITION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; + + if (currentEventList->count == currentEventList->capacity) return; // Security check } - // INPUT_MOUSE_WHEEL_MOTION + // Event type: INPUT_MOUSE_WHEEL_MOTION if (((int)CORE.Input.Mouse.currentWheelMove.x != (int)CORE.Input.Mouse.previousWheelMove.x) || ((int)CORE.Input.Mouse.currentWheelMove.y != (int)CORE.Input.Mouse.previousWheelMove.y)) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_MOUSE_WHEEL_MOTION; - events[eventCount].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x; - events[eventCount].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;; - events[eventCount].params[2] = 0; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_MOUSE_WHEEL_MOTION; + currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x; + currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_WHEEL_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; - TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_WHEEL_MOTION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + if (currentEventList->count == currentEventList->capacity) return; // Security check } + //------------------------------------------------------------------------------------- + // Touch input currentEventList->events recording + //------------------------------------------------------------------------------------- for (int id = 0; id < MAX_TOUCH_POINTS; id++) { - // INPUT_TOUCH_UP + // Event type: INPUT_TOUCH_UP if (CORE.Input.Touch.previousTouchState[id] && !CORE.Input.Touch.currentTouchState[id]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_TOUCH_UP; - events[eventCount].params[0] = id; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_TOUCH_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_TOUCH_UP; + currentEventList->events[currentEventList->count].params[0] = id; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } - // INPUT_TOUCH_DOWN + if (currentEventList->count == currentEventList->capacity) return; // Security check + + // Event type: INPUT_TOUCH_DOWN if (CORE.Input.Touch.currentTouchState[id]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_TOUCH_DOWN; - events[eventCount].params[0] = id; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_TOUCH_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_TOUCH_DOWN; + currentEventList->events[currentEventList->count].params[0] = id; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } - // INPUT_TOUCH_POSITION + if (currentEventList->count == currentEventList->capacity) return; // Security check + + // Event type: INPUT_TOUCH_POSITION // TODO: It requires the id! /* if (((int)CORE.Input.Touch.currentPosition[id].x != (int)CORE.Input.Touch.previousPosition[id].x) || ((int)CORE.Input.Touch.currentPosition[id].y != (int)CORE.Input.Touch.previousPosition[id].y)) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_TOUCH_POSITION; - events[eventCount].params[0] = id; - events[eventCount].params[1] = (int)CORE.Input.Touch.currentPosition[id].x; - events[eventCount].params[2] = (int)CORE.Input.Touch.currentPosition[id].y; - - TRACELOG(LOG_INFO, "[%i] INPUT_TOUCH_POSITION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_TOUCH_POSITION; + currentEventList->events[currentEventList->count].params[0] = id; + currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Touch.currentPosition[id].x; + currentEventList->events[currentEventList->count].params[2] = (int)CORE.Input.Touch.currentPosition[id].y; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } */ + + if (currentEventList->count == currentEventList->capacity) return; // Security check } + //------------------------------------------------------------------------------------- + // Gamepad input currentEventList->events recording + //------------------------------------------------------------------------------------- for (int gamepad = 0; gamepad < MAX_GAMEPADS; gamepad++) { - // INPUT_GAMEPAD_CONNECT + // Event type: INPUT_GAMEPAD_CONNECT /* if ((CORE.Input.Gamepad.currentState[gamepad] != CORE.Input.Gamepad.previousState[gamepad]) && (CORE.Input.Gamepad.currentState[gamepad])) // Check if changed to ready @@ -2818,7 +3445,7 @@ static void RecordAutomationEvent(unsigned int frame) } */ - // INPUT_GAMEPAD_DISCONNECT + // Event type: INPUT_GAMEPAD_DISCONNECT /* if ((CORE.Input.Gamepad.currentState[gamepad] != CORE.Input.Gamepad.previousState[gamepad]) && (!CORE.Input.Gamepad.currentState[gamepad])) // Check if changed to not-ready @@ -2829,122 +3456,84 @@ static void RecordAutomationEvent(unsigned int frame) for (int button = 0; button < MAX_GAMEPAD_BUTTONS; button++) { - // INPUT_GAMEPAD_BUTTON_UP + // Event type: INPUT_GAMEPAD_BUTTON_UP if (CORE.Input.Gamepad.previousButtonState[gamepad][button] && !CORE.Input.Gamepad.currentButtonState[gamepad][button]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_GAMEPAD_BUTTON_UP; - events[eventCount].params[0] = gamepad; - events[eventCount].params[1] = button; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_GAMEPAD_BUTTON_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_BUTTON_UP; + currentEventList->events[currentEventList->count].params[0] = gamepad; + currentEventList->events[currentEventList->count].params[1] = button; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GAMEPAD_BUTTON_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } - // INPUT_GAMEPAD_BUTTON_DOWN + if (currentEventList->count == currentEventList->capacity) return; // Security check + + // Event type: INPUT_GAMEPAD_BUTTON_DOWN if (CORE.Input.Gamepad.currentButtonState[gamepad][button]) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_GAMEPAD_BUTTON_DOWN; - events[eventCount].params[0] = gamepad; - events[eventCount].params[1] = button; - events[eventCount].params[2] = 0; - - TRACELOG(LOG_INFO, "[%i] INPUT_GAMEPAD_BUTTON_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_BUTTON_DOWN; + currentEventList->events[currentEventList->count].params[0] = gamepad; + currentEventList->events[currentEventList->count].params[1] = button; + currentEventList->events[currentEventList->count].params[2] = 0; + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GAMEPAD_BUTTON_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } + + if (currentEventList->count == currentEventList->capacity) return; // Security check } for (int axis = 0; axis < MAX_GAMEPAD_AXIS; axis++) { - // INPUT_GAMEPAD_AXIS_MOTION + // Event type: INPUT_GAMEPAD_AXIS_MOTION if (CORE.Input.Gamepad.axisState[gamepad][axis] > 0.1f) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_GAMEPAD_AXIS_MOTION; - events[eventCount].params[0] = gamepad; - events[eventCount].params[1] = axis; - events[eventCount].params[2] = (int)(CORE.Input.Gamepad.axisState[gamepad][axis]*32768.0f); - - TRACELOG(LOG_INFO, "[%i] INPUT_GAMEPAD_AXIS_MOTION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_AXIS_MOTION; + currentEventList->events[currentEventList->count].params[0] = gamepad; + currentEventList->events[currentEventList->count].params[1] = axis; + currentEventList->events[currentEventList->count].params[2] = (int)(CORE.Input.Gamepad.axisState[gamepad][axis]*32768.0f); + + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GAMEPAD_AXIS_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; } + + if (currentEventList->count == currentEventList->capacity) return; // Security check } } + //------------------------------------------------------------------------------------- - // INPUT_GESTURE + // Gestures input currentEventList->events recording + //------------------------------------------------------------------------------------- if (GESTURES.current != GESTURE_NONE) { - events[eventCount].frame = frame; - events[eventCount].type = INPUT_GESTURE; - events[eventCount].params[0] = GESTURES.current; - events[eventCount].params[1] = 0; - events[eventCount].params[2] = 0; + // Event type: INPUT_GESTURE + currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; + currentEventList->events[currentEventList->count].type = INPUT_GESTURE; + currentEventList->events[currentEventList->count].params[0] = GESTURES.current; + currentEventList->events[currentEventList->count].params[1] = 0; + currentEventList->events[currentEventList->count].params[2] = 0; - TRACELOG(LOG_INFO, "[%i] INPUT_GESTURE: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]); - eventCount++; - } -} + TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GESTURE | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); + currentEventList->count++; -// Play automation event -static void PlayAutomationEvent(unsigned int frame) -{ - for (unsigned int i = 0; i < eventCount; i++) - { - if (events[i].frame == frame) - { - switch (events[i].type) - { - // Input events - case INPUT_KEY_UP: CORE.Input.Keyboard.currentKeyState[events[i].params[0]] = false; break; // param[0]: key - case INPUT_KEY_DOWN: CORE.Input.Keyboard.currentKeyState[events[i].params[0]] = true; break; // param[0]: key - case INPUT_MOUSE_BUTTON_UP: CORE.Input.Mouse.currentButtonState[events[i].params[0]] = false; break; // param[0]: key - case INPUT_MOUSE_BUTTON_DOWN: CORE.Input.Mouse.currentButtonState[events[i].params[0]] = true; break; // param[0]: key - case INPUT_MOUSE_POSITION: // param[0]: x, param[1]: y - { - CORE.Input.Mouse.currentPosition.x = (float)events[i].params[0]; - CORE.Input.Mouse.currentPosition.y = (float)events[i].params[1]; - } break; - case INPUT_MOUSE_WHEEL_MOTION: // param[0]: x delta, param[1]: y delta - { - CORE.Input.Mouse.currentWheelMove.x = (float)events[i].params[0]; break; - CORE.Input.Mouse.currentWheelMove.y = (float)events[i].params[1]; break; - } break; - case INPUT_TOUCH_UP: CORE.Input.Touch.currentTouchState[events[i].params[0]] = false; break; // param[0]: id - case INPUT_TOUCH_DOWN: CORE.Input.Touch.currentTouchState[events[i].params[0]] = true; break; // param[0]: id - case INPUT_TOUCH_POSITION: // param[0]: id, param[1]: x, param[2]: y - { - CORE.Input.Touch.position[events[i].params[0]].x = (float)events[i].params[1]; - CORE.Input.Touch.position[events[i].params[0]].y = (float)events[i].params[2]; - } break; - case INPUT_GAMEPAD_CONNECT: CORE.Input.Gamepad.ready[events[i].params[0]] = true; break; // param[0]: gamepad - case INPUT_GAMEPAD_DISCONNECT: CORE.Input.Gamepad.ready[events[i].params[0]] = false; break; // param[0]: gamepad - case INPUT_GAMEPAD_BUTTON_UP: CORE.Input.Gamepad.currentButtonState[events[i].params[0]][events[i].params[1]] = false; break; // param[0]: gamepad, param[1]: button - case INPUT_GAMEPAD_BUTTON_DOWN: CORE.Input.Gamepad.currentButtonState[events[i].params[0]][events[i].params[1]] = true; break; // param[0]: gamepad, param[1]: button - case INPUT_GAMEPAD_AXIS_MOTION: // param[0]: gamepad, param[1]: axis, param[2]: delta - { - CORE.Input.Gamepad.axisState[events[i].params[0]][events[i].params[1]] = ((float)events[i].params[2]/32768.0f); - } break; - case INPUT_GESTURE: GESTURES.current = events[i].params[0]; break; // param[0]: gesture (enum Gesture) -> rgestures.h: GESTURES.current - - // Window events - case WINDOW_CLOSE: CORE.Window.shouldClose = true; break; - case WINDOW_MAXIMIZE: MaximizeWindow(); break; - case WINDOW_MINIMIZE: MinimizeWindow(); break; - case WINDOW_RESIZE: SetWindowSize(events[i].params[0], events[i].params[1]); break; - - // Custom events - case ACTION_TAKE_SCREENSHOT: - { - TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); - screenshotCounter++; - } break; - case ACTION_SETTARGETFPS: SetTargetFPS(events[i].params[0]); break; - default: break; - } - } + if (currentEventList->count == currentEventList->capacity) return; // Security check } + //------------------------------------------------------------------------------------- + + // Window events recording + //------------------------------------------------------------------------------------- + // TODO. + //------------------------------------------------------------------------------------- + + // Custom actions events recording + //------------------------------------------------------------------------------------- + // TODO. + //------------------------------------------------------------------------------------- } #endif diff --git a/raylib/src/rcore.h b/raylib/src/rcore.h deleted file mode 100644 index 1127585..0000000 --- a/raylib/src/rcore.h +++ /dev/null @@ -1,209 +0,0 @@ -/********************************************************************************************** -* -* rcore - Common types and globals (all platforms) -* -* LIMITATIONS: -* - Limitation 01 -* - Limitation 02 -* -* POSSIBLE IMPROVEMENTS: -* - Improvement 01 -* - Improvement 02 -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2013-2023 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. -* -* 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. -* -**********************************************************************************************/ - -#ifndef RCORE_H -#define RCORE_H - -#include "raylib.h" - -#include "utils.h" // Required for: TRACELOG() macros - -#include "rlgl.h" // Required for: graphics layer functionality - -#define RAYMATH_IMPLEMENTATION -#include "raymath.h" // Required for: Vector2/Vector3/Matrix functionality - -#include <stdlib.h> // Required for: srand(), rand(), atexit() -#include <stdio.h> // Required for: sprintf() [Used in OpenURL()] -#include <string.h> // Required for: strrchr(), strcmp(), strlen(), memset() -#include <time.h> // Required for: time() [Used in InitTimer()] -#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -#ifndef MAX_FILEPATH_CAPACITY - #define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath -#endif -#ifndef MAX_FILEPATH_LENGTH - #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) -#endif - -#ifndef MAX_KEYBOARD_KEYS - #define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported -#endif -#ifndef MAX_MOUSE_BUTTONS - #define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported -#endif -#ifndef MAX_GAMEPADS - #define MAX_GAMEPADS 4 // Maximum number of gamepads supported -#endif -#ifndef MAX_GAMEPAD_AXIS - #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) -#endif -#ifndef MAX_GAMEPAD_BUTTONS - #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) -#endif -#ifndef MAX_TOUCH_POINTS - #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported -#endif -#ifndef MAX_KEY_PRESSED_QUEUE - #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue -#endif -#ifndef MAX_CHAR_PRESSED_QUEUE - #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue -#endif - -#ifndef MAX_DECOMPRESSION_SIZE - #define MAX_DECOMPRESSION_SIZE 64 // Maximum size allocated for decompression in MB -#endif - -// Flags operation macros -#define FLAG_SET(n, f) ((n) |= (f)) -#define FLAG_CLEAR(n, f) ((n) &= ~(f)) -#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 -//---------------------------------------------------------------------------------- -typedef struct { int x; int y; } Point; -typedef struct { unsigned int width; unsigned int height; } Size; - -// Core global state context data -typedef struct CoreData { - struct { - const char *title; // Window text title const pointer - unsigned int flags; // Configuration flags (bit based), keeps window state - bool ready; // Check if window has been initialized successfully - bool fullscreen; // Check if fullscreen mode is enabled - bool shouldClose; // Check if window set for closing - bool resizedLastFrame; // Check if window has been resized last frame - bool eventWaiting; // Wait for events before ending frame - - Point position; // Window position (required on fullscreen toggle) - Point previousPosition; // Window previous position (required on borderless windowed toggle) - Size display; // Display width and height (monitor, device-screen, LCD, ...) - Size screen; // Screen width and height (used render area) - Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) - Size currentFbo; // Current render width and height (depends on active fbo) - Size render; // Framebuffer width and height (render area, including black bars if required) - Point renderOffset; // Offset from render area (must be divided by 2) - Size screenMin; // Screen minimum width and height (for resizable window) - Size screenMax; // Screen maximum width and height (for resizable window) - Matrix screenScale; // Matrix to scale screen (framebuffer rendering) - - char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) - unsigned int dropFileCount; // Count dropped files strings - - } Window; - struct { - const char *basePath; // Base path for data storage - - } Storage; - 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 - - // 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. - - 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 charPressedQueueCount; // Input characters queue count - - } Keyboard; - struct { - Vector2 offset; // Mouse offset - Vector2 scale; // Mouse scaling - Vector2 currentPosition; // Mouse position on screen - Vector2 previousPosition; // Previous mouse position - - int cursor; // Tracks current mouse cursor - bool cursorHidden; // Track if cursor is hidden - bool cursorOnScreen; // Tracks if cursor is inside client area - - char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state - char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state - Vector2 currentWheelMove; // Registers current mouse wheel variation - Vector2 previousWheelMove; // Registers previous mouse wheel variation - - } Mouse; - struct { - int pointCount; // Number of touch points active - int pointId[MAX_TOUCH_POINTS]; // Point identifiers - Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen - char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state - char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state - - } Touch; - struct { - int lastButtonPressed; // Register last gamepad button pressed - 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 - char previousButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state - float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state - - } Gamepad; - } Input; - struct { - double current; // Current time measure - double previous; // Previous time measure - double update; // Time measure for frame update - double draw; // Time measure for frame draw - double frame; // Time measure for one frame - double target; // Desired time for one frame, if 0 not applied - unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) - unsigned int frameCounter; // Frame counter - - } Time; -} CoreData; - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -extern CoreData CORE; - -#endif diff --git a/raylib/src/rlgl.h b/raylib/src/rlgl.h index 40e7b47..6cf9c7e 100644 --- a/raylib/src/rlgl.h +++ b/raylib/src/rlgl.h @@ -59,7 +59,7 @@ * #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 * -* When loading a shader, the following vertex attribute and uniform +* 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 @@ -67,6 +67,7 @@ * #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_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 @@ -516,28 +517,28 @@ typedef enum { // Framebuffer attachment type // NOTE: By default up to 8 color channels defined, but it can be more typedef enum { - RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 - RL_ATTACHMENT_COLOR_CHANNEL1, // Framebuffer attachment type: color 1 - RL_ATTACHMENT_COLOR_CHANNEL2, // Framebuffer attachment type: color 2 - RL_ATTACHMENT_COLOR_CHANNEL3, // Framebuffer attachment type: color 3 - RL_ATTACHMENT_COLOR_CHANNEL4, // Framebuffer attachment type: color 4 - RL_ATTACHMENT_COLOR_CHANNEL5, // Framebuffer attachment type: color 5 - RL_ATTACHMENT_COLOR_CHANNEL6, // Framebuffer attachment type: color 6 - RL_ATTACHMENT_COLOR_CHANNEL7, // Framebuffer attachment type: color 7 - RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachment type: depth - RL_ATTACHMENT_STENCIL = 200, // Framebuffer attachment type: stencil + RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 + RL_ATTACHMENT_COLOR_CHANNEL1 = 1, // Framebuffer attachment type: color 1 + RL_ATTACHMENT_COLOR_CHANNEL2 = 2, // Framebuffer attachment type: color 2 + RL_ATTACHMENT_COLOR_CHANNEL3 = 3, // Framebuffer attachment type: color 3 + RL_ATTACHMENT_COLOR_CHANNEL4 = 4, // Framebuffer attachment type: color 4 + RL_ATTACHMENT_COLOR_CHANNEL5 = 5, // Framebuffer attachment type: color 5 + RL_ATTACHMENT_COLOR_CHANNEL6 = 6, // Framebuffer attachment type: color 6 + RL_ATTACHMENT_COLOR_CHANNEL7 = 7, // Framebuffer attachment type: color 7 + RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachment type: depth + RL_ATTACHMENT_STENCIL = 200, // Framebuffer attachment type: stencil } rlFramebufferAttachType; // Framebuffer texture attachment type typedef enum { - RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side - RL_ATTACHMENT_CUBEMAP_NEGATIVE_X, // Framebuffer texture attachment type: cubemap, -X side - RL_ATTACHMENT_CUBEMAP_POSITIVE_Y, // Framebuffer texture attachment type: cubemap, +Y side - RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y, // Framebuffer texture attachment type: cubemap, -Y side - RL_ATTACHMENT_CUBEMAP_POSITIVE_Z, // Framebuffer texture attachment type: cubemap, +Z side - RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z, // Framebuffer texture attachment type: cubemap, -Z side - RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d - RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer + RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_X = 1, // Framebuffer texture attachment type: cubemap, -X side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Y = 2, // Framebuffer texture attachment type: cubemap, +Y side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y = 3, // Framebuffer texture attachment type: cubemap, -Y side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Z = 4, // Framebuffer texture attachment type: cubemap, +Z side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z = 5, // Framebuffer texture attachment type: cubemap, -Z side + RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d + RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer } rlFramebufferAttachTextureType; // Face culling mode @@ -617,6 +618,7 @@ RLAPI void rlDisableShader(void); // Disable shader progra RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo) RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to 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 // General render state RLAPI void rlEnableColorBlend(void); // Enable color blending @@ -632,7 +634,8 @@ 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 rlDisableWireMode(void); // Disable wire 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 RLAPI void rlEnableSmoothLines(void); // Enable line aliasing @@ -797,13 +800,17 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad #define GLAD_FREE RL_FREE #define GLAD_GL_IMPLEMENTATION - #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers + #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers #endif -#if defined(GRAPHICS_API_OPENGL_ES2) +#if defined(GRAPHICS_API_OPENGL_ES3) + #include <GLES3/gl3.h> // OpenGL ES 3.0 library + #define GL_GLEXT_PROTOTYPES + #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library +#elif defined(GRAPHICS_API_OPENGL_ES2) // NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, // in that case, functions are loaded from a custom glad for OpenGL ES 2.0 - #if defined(PLATFORM_DESKTOP) + #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #define GLAD_GLES2_IMPLEMENTATION #include "external/glad_gles2.h" #else @@ -897,8 +904,10 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad #if defined(GRAPHICS_API_OPENGL_ES2) #define glClearDepth glClearDepthf - #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER - #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER + #if !defined(GRAPHICS_API_OPENGL_ES3) + #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER + #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER + #endif #endif // Default shader vertex attribute names to set location points @@ -1037,7 +1046,7 @@ typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions static rlglData RLGL = { 0 }; #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 -#if defined(GRAPHICS_API_OPENGL_ES2) +#if defined(GRAPHICS_API_OPENGL_ES2) && !defined(GRAPHICS_API_OPENGL_ES3) // NOTE: VAO functionality is exposed through extensions (OES) static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; @@ -1056,7 +1065,7 @@ static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; static void rlLoadShaderDefault(void); // Load default shader static void rlUnloadShaderDefault(void); // Unload default shader #if defined(RLGL_SHOW_GL_DETAILS_INFO) -static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name +static const char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name #endif // RLGL_SHOW_GL_DETAILS_INFO #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 @@ -1712,6 +1721,14 @@ void rlDisableFramebuffer(void) #endif } +// Blit active framebuffer to main framebuffer +void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) + glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask, GL_NEAREST); +#endif +} + // Activate multiple draw color buffers // NOTE: One color buffer is always active by default void rlActiveDrawBuffers(int count) @@ -1817,6 +1834,14 @@ void rlEnableWireMode(void) #endif } +void rlEnablePointMode(void) +{ +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) + // NOTE: glPolygonMode() not available on OpenGL ES + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + glEnable(GL_PROGRAM_POINT_SIZE); +#endif +} // Disable wire mode void rlDisableWireMode(void) { @@ -2225,7 +2250,7 @@ void rlLoadExtensions(void *loader) #if defined(GRAPHICS_API_OPENGL_ES3) // Register supported extensions flags - // OpenGL ES 3.0 extensions supported by default + // OpenGL ES 3.0 extensions supported by default (or it should be) RLGL.ExtSupported.vao = true; RLGL.ExtSupported.instancing = true; RLGL.ExtSupported.texNPOT = true; @@ -2236,20 +2261,20 @@ void rlLoadExtensions(void *loader) RLGL.ExtSupported.maxDepthBits = 24; RLGL.ExtSupported.texAnisoFilter = true; RLGL.ExtSupported.texMirrorClamp = true; - // TODO: Make sure that the ones above are actually present by default - // TODO: Check for these... - // RLGL.ExtSupported.texCompDXT - // RLGL.ExtSupported.texCompETC1 - // RLGL.ExtSupported.texCompETC2 - // RLGL.ExtSupported.texCompPVRT - // RLGL.ExtSupported.texCompASTC - // RLGL.ExtSupported.computeShader - // RLGL.ExtSupported.ssbo - // RLGL.ExtSupported.maxAnisotropyLevel + // TODO: Check for additional OpenGL ES 3.0 supported extensions: + //RLGL.ExtSupported.texCompDXT = true; + //RLGL.ExtSupported.texCompETC1 = true; + //RLGL.ExtSupported.texCompETC2 = true; + //RLGL.ExtSupported.texCompPVRT = true; + //RLGL.ExtSupported.texCompASTC = true; + //RLGL.ExtSupported.maxAnisotropyLevel = true; + //RLGL.ExtSupported.computeShader = true; + //RLGL.ExtSupported.ssbo = true; + #elif defined(GRAPHICS_API_OPENGL_ES2) - #if defined(PLATFORM_DESKTOP) - // TODO: Support OpenGL ES 3.0 + #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) + // TODO: Support GLAD loader for OpenGL ES 3.0 if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions"); else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); #endif @@ -3000,7 +3025,8 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipOffset = 0; // Mipmap data offset, only used for tracelog // NOTE: Added pointer math separately from function to avoid UBSAN complaining - unsigned char *dataPtr = (unsigned char *)data; + unsigned char *dataPtr = NULL; + if (data != NULL) dataPtr = (unsigned char *)data; // Load the different mipmap levels for (int i = 0; i < mipmapCount; i++) @@ -3040,7 +3066,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, mipWidth /= 2; mipHeight /= 2; mipOffset += mipSize; // Increment offset position to next mipmap - dataPtr += mipSize; // Increment data pointer to next mipmap + if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap // Security check for NPOT textures if (mipWidth < 1) mipWidth = 1; @@ -4664,7 +4690,7 @@ static void rlUnloadShaderDefault(void) #if defined(RLGL_SHOW_GL_DETAILS_INFO) // Get compressed format official GL identifier name -static char *rlGetCompressedFormatName(int format) +static const char *rlGetCompressedFormatName(int format) { switch (format) { diff --git a/raylib/src/rmodels.c b/raylib/src/rmodels.c index a11ecf7..229d373 100644 --- a/raylib/src/rmodels.c +++ b/raylib/src/rmodels.c @@ -1052,26 +1052,16 @@ Model LoadModel(const char *fileName) // Make sure model transform is set to identity matrix! model.transform = MatrixIdentity(); - if (model.meshCount == 0) + if ((model.meshCount != 0) && (model.meshes != NULL)) { - model.meshCount = 1; - model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); -#if defined(SUPPORT_MESH_GENERATION) - TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load mesh data, default to cube mesh", fileName); - model.meshes[0] = GenMeshCube(1.0f, 1.0f, 1.0f); -#else - TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load mesh data", fileName); -#endif - } - else - { - // Upload vertex data to GPU (static mesh) + // Upload vertex data to GPU (static meshes) for (int i = 0; i < model.meshCount; i++) UploadMesh(&model.meshes[i], false); } + else TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load model mesh(es) data", fileName); if (model.materialCount == 0) { - TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to load material data, default to white material", fileName); + TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to load model material data, default to white material", fileName); model.materialCount = 1; model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); @@ -1171,6 +1161,12 @@ BoundingBox GetModelBoundingBox(Model model) } } + // Apply model.transform to bounding box + // WARNING: Current BoundingBox structure design does not support rotation transformations, + // in those cases is up to the user to calculate the proper box bounds (8 vertices transformed) + bounds.min = Vector3Transform(bounds.min, model.transform); + bounds.max = Vector3Transform(bounds.max, model.transform); + return bounds; } @@ -2146,11 +2142,11 @@ Mesh GenMeshPoly(int sides, float radius) Vector3 *vertices = (Vector3 *)RL_MALLOC(vertexCount*sizeof(Vector3)); float d = 0.0f, dStep = 360.0f/sides; - for (int v = 0; v < vertexCount; v += 3) + for (int v = 0; v < vertexCount - 2; v += 3) { vertices[v] = (Vector3){ 0.0f, 0.0f, 0.0f }; vertices[v + 1] = (Vector3){ sinf(DEG2RAD*d)*radius, 0.0f, cosf(DEG2RAD*d)*radius }; - vertices[v + 2] = (Vector3){sinf(DEG2RAD*(d+dStep))*radius, 0.0f, cosf(DEG2RAD*(d+dStep))*radius }; + vertices[v + 2] = (Vector3){ sinf(DEG2RAD*(d+dStep))*radius, 0.0f, cosf(DEG2RAD*(d+dStep))*radius }; d += dStep; } @@ -2249,7 +2245,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 % (resX - 1) + (face/(resZ - 1)*resX); + int i = face + face / (resX - 1); triangles[t++] = i + resX; triangles[t++] = i + 1; @@ -3935,9 +3931,10 @@ static Model LoadOBJ(const char *fileName) if (fileText != NULL) { unsigned int dataSize = (unsigned int)strlen(fileText); + char currentDir[1024] = { 0 }; - strcpy(currentDir, GetWorkingDirectory()); - const char *workingDir = GetDirectoryPath(fileName); + strcpy(currentDir, GetWorkingDirectory()); // Save current working directory + const char *workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness if (CHDIR(workingDir) != 0) { TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir); @@ -3949,117 +3946,91 @@ static Model LoadOBJ(const char *fileName) if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName); else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes/%i materials", fileName, meshCount, materialCount); - model.meshCount = materialCount; + // WARNING: We are not splitting meshes by materials (previous implementation) + // Depending on the provided OBJ that was not the best option and it just crashed + // so, implementation was simplified to prioritize parsed meshes + model.meshCount = meshCount; - // Init model materials array - if (materialCount > 0) + // Set number of materials available + // 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) { - model.materialCount = materialCount; - model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); - TRACELOG(LOG_INFO, "MODEL: model has %i material meshes", materialCount); - } - else - { - model.meshCount = 1; - TRACELOG(LOG_INFO, "MODEL: No materials, putting all meshes in a default material"); + model.materialCount = 1; + TRACELOG(LOG_INFO, "MODEL: No materials provided, setting one default material for all meshes"); } + // Init model meshes and materials model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); - model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); - - // Count the faces for each material - int *matFaces = RL_CALLOC(model.meshCount, sizeof(int)); + model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); // Material index assigned to each mesh + model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); - // if no materials are present use all faces on one mesh - if (materialCount > 0) + // Process each provided mesh + for (int i = 0; i < model.meshCount; i++) { - for (unsigned int fi = 0; fi < attrib.num_faces; fi++) + // 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, + // 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; + else tris = meshes[i + 1].face_offset; + + model.meshes[i].vertexCount = tris*3; + model.meshes[i].triangleCount = tris; // Face count (triangulated) + model.meshes[i].vertices = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); + model.meshes[i].texcoords = (float *)RL_CALLOC(model.meshes[i].vertexCount*2, sizeof(float)); + model.meshes[i].normals = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); + model.meshMaterial[i] = 0; // By default, assign material 0 to each mesh + + // Process all mesh faces + for (unsigned int face = 0, f = meshes[i].face_offset, v = 0, vt = 0, vn = 0; face < tris; face++, f++, v += 3, vt += 3, vn += 3) { - //tinyobj_vertex_index_t face = attrib.faces[fi]; - int idx = attrib.material_ids[fi]; - matFaces[idx]++; - } + // Get indices for the face + tinyobj_vertex_index_t idx0 = attrib.faces[f*3 + 0]; + tinyobj_vertex_index_t idx1 = attrib.faces[f*3 + 1]; + tinyobj_vertex_index_t idx2 = attrib.faces[f*3 + 2]; - } - else - { - matFaces[0] = attrib.num_faces; - } - - //-------------------------------------- - // Create the material meshes - - // Running counts/indexes for each material mesh as we are - // building them at the same time - int *vCount = RL_CALLOC(model.meshCount, sizeof(int)); - int *vtCount = RL_CALLOC(model.meshCount, sizeof(int)); - int *vnCount = RL_CALLOC(model.meshCount, sizeof(int)); - int *faceCount = RL_CALLOC(model.meshCount, sizeof(int)); - - // Allocate space for each of the material meshes - for (int mi = 0; mi < model.meshCount; mi++) - { - model.meshes[mi].vertexCount = matFaces[mi]*3; - model.meshes[mi].triangleCount = matFaces[mi]; - model.meshes[mi].vertices = (float *)RL_CALLOC(model.meshes[mi].vertexCount*3, sizeof(float)); - model.meshes[mi].texcoords = (float *)RL_CALLOC(model.meshes[mi].vertexCount*2, sizeof(float)); - model.meshes[mi].normals = (float *)RL_CALLOC(model.meshes[mi].vertexCount*3, sizeof(float)); - model.meshMaterial[mi] = mi; - } - - // Scan through the combined sub meshes and pick out each material mesh - for (unsigned int af = 0; af < attrib.num_faces; af++) - { - int mm = attrib.material_ids[af]; // mesh material for this face - if (mm == -1) { mm = 0; } // no material object.. + // Fill vertices buffer (float) using vertex index of the face + for (int n = 0; n < 3; n++) { model.meshes[i].vertices[v*3 + n] = attrib.vertices[idx0.v_idx*3 + n]; } + for (int n = 0; n < 3; n++) { model.meshes[i].vertices[(v + 1)*3 + n] = attrib.vertices[idx1.v_idx*3 + n]; } + for (int n = 0; n < 3; n++) { model.meshes[i].vertices[(v + 2)*3 + n] = attrib.vertices[idx2.v_idx*3 + n]; } - // Get indices for the face - tinyobj_vertex_index_t idx0 = attrib.faces[3*af + 0]; - tinyobj_vertex_index_t idx1 = attrib.faces[3*af + 1]; - tinyobj_vertex_index_t idx2 = attrib.faces[3*af + 2]; + if (attrib.num_texcoords > 0) + { + // Fill texcoords buffer (float) using vertex index of the face + // NOTE: Y-coordinate must be flipped upside-down + model.meshes[i].texcoords[vt*2 + 0] = attrib.texcoords[idx0.vt_idx*2 + 0]; + model.meshes[i].texcoords[vt*2 + 1] = 1.0f - attrib.texcoords[idx0.vt_idx*2 + 1]; - // Fill vertices buffer (float) using vertex index of the face - for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx0.v_idx*3 + v]; } vCount[mm] +=3; - for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx1.v_idx*3 + v]; } vCount[mm] +=3; - for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx2.v_idx*3 + v]; } vCount[mm] +=3; + model.meshes[i].texcoords[(vt + 1)*2 + 0] = attrib.texcoords[idx1.vt_idx*2 + 0]; + model.meshes[i].texcoords[(vt + 1)*2 + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1]; - if (attrib.num_texcoords > 0) - { - // Fill texcoords buffer (float) using vertex index of the face - // NOTE: Y-coordinate must be flipped upside-down to account for - // raylib's upside down textures... - model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx0.vt_idx*2 + 0]; - model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx0.vt_idx*2 + 1]; vtCount[mm] += 2; - model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx1.vt_idx*2 + 0]; - model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1]; vtCount[mm] += 2; - model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx2.vt_idx*2 + 0]; - model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1]; vtCount[mm] += 2; - } + model.meshes[i].texcoords[(vt + 2)*2 + 0] = attrib.texcoords[idx2.vt_idx*2 + 0]; + model.meshes[i].texcoords[(vt + 2)*2 + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1]; + } - if (attrib.num_normals > 0) - { - // Fill normals buffer (float) using vertex index of the face - for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx0.vn_idx*3 + v]; } vnCount[mm] +=3; - for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx1.vn_idx*3 + v]; } vnCount[mm] +=3; - for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx2.vn_idx*3 + v]; } vnCount[mm] +=3; + if (attrib.num_normals > 0) + { + // Fill normals buffer (float) using vertex index of the face + for (int n = 0; n < 3; n++) { model.meshes[i].normals[vn*3 + n] = attrib.normals[idx0.vn_idx*3 + n]; } + for (int n = 0; n < 3; n++) { model.meshes[i].normals[(vn + 1)*3 + n] = attrib.normals[idx1.vn_idx*3 + n]; } + for (int n = 0; n < 3; n++) { model.meshes[i].normals[(vn + 2)*3 + n] = attrib.normals[idx2.vn_idx*3 + n]; } + } } } // Init model materials - ProcessMaterialsOBJ(model.materials, materials, materialCount); + if (materialCount > 0) ProcessMaterialsOBJ(model.materials, materials, materialCount); + else model.materials[0] = LoadMaterialDefault(); // Set default material for the mesh tinyobj_attrib_free(&attrib); - tinyobj_shapes_free(meshes, meshCount); + tinyobj_shapes_free(meshes, model.meshCount); tinyobj_materials_free(materials, materialCount); UnloadFileText(fileText); - RL_FREE(matFaces); - RL_FREE(vCount); - RL_FREE(vtCount); - RL_FREE(vnCount); - RL_FREE(faceCount); - + // Restore current working directory if (CHDIR(currentDir) != 0) { TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", currentDir); diff --git a/raylib/src/rshapes.c b/raylib/src/rshapes.c index f3061f8..bababf8 100644 --- a/raylib/src/rshapes.c +++ b/raylib/src/rshapes.c @@ -65,10 +65,10 @@ // Error rate to calculate how many segments we need to draw a smooth circle, // taken from https://stackoverflow.com/a/2244088 #ifndef SMOOTH_CIRCLE_ERROR_RATE - #define SMOOTH_CIRCLE_ERROR_RATE 0.5f // Circle error rate + #define SMOOTH_CIRCLE_ERROR_RATE 0.5f // Circle error rate #endif -#ifndef SPLINE_LINE_DIVISIONS - #define SPLINE_LINE_DIVISIONS 24 // Spline lines segment divisions +#ifndef SPLINE_SEGMENT_DIVISIONS + #define SPLINE_SEGMENT_DIVISIONS 24 // Spline segment divisions #endif @@ -161,7 +161,7 @@ void DrawPixelV(Vector2 position, Color color) #endif } -// Draw a line +// Draw a line (using gl lines) void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color) { rlBegin(RL_LINES); @@ -171,7 +171,7 @@ void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color colo rlEnd(); } -// Draw a line (Vector version) +// Draw a line (using gl lines) void DrawLineV(Vector2 startPos, Vector2 endPos, Color color) { rlBegin(RL_LINES); @@ -181,88 +181,37 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color) rlEnd(); } -// Draw a line defining thickness -void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color) +// Draw lines sequuence (using gl lines) +void DrawLineStrip(Vector2 *points, int pointCount, Color color) { - Vector2 delta = { endPos.x - startPos.x, endPos.y - startPos.y }; - float length = sqrtf(delta.x*delta.x + delta.y*delta.y); - - if ((length > 0) && (thick > 0)) + if (pointCount >= 2) { - float scale = thick/(2*length); - - Vector2 radius = { -scale*delta.y, scale*delta.x }; - Vector2 strip[4] = { - { startPos.x - radius.x, startPos.y - radius.y }, - { startPos.x + radius.x, startPos.y + radius.y }, - { endPos.x - radius.x, endPos.y - radius.y }, - { endPos.x + radius.x, endPos.y + radius.y } - }; + rlBegin(RL_LINES); + rlColor4ub(color.r, color.g, color.b, color.a); - DrawTriangleStrip(strip, 4, color); + 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 curves in-out +// Draw line using cubic-bezier spline, in-out interpolation, no control points void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color) { Vector2 previous = startPos; Vector2 current = { 0 }; - Vector2 points[2*SPLINE_LINE_DIVISIONS + 2] = { 0 }; + Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; - for (int i = 1; i <= SPLINE_LINE_DIVISIONS; i++) + for (int i = 1; i <= SPLINE_SEGMENT_DIVISIONS; i++) { // Cubic easing in-out // NOTE: Easing is calculated only for y position value - current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)SPLINE_LINE_DIVISIONS); - current.x = previous.x + (endPos.x - startPos.x)/(float)SPLINE_LINE_DIVISIONS; - - float dy = current.y - previous.y; - float dx = current.x - previous.x; - float size = 0.5f*thick/sqrtf(dx*dx+dy*dy); - - if (i == 1) - { - points[0].x = previous.x + dy*size; - points[0].y = previous.y - dx*size; - points[1].x = previous.x - dy*size; - points[1].y = previous.y + dx*size; - } - - points[2*i + 1].x = current.x - dy*size; - points[2*i + 1].y = current.y + dx*size; - points[2*i].x = current.x + dy*size; - points[2*i].y = current.y - dx*size; - - previous = current; - } - - DrawTriangleStrip(points, 2*SPLINE_LINE_DIVISIONS + 2, color); -} - -// Draw line using quadratic bezier curves with a control point -void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color) -{ - const float step = 1.0f/SPLINE_LINE_DIVISIONS; - - Vector2 previous = startPos; - Vector2 current = { 0 }; - float t = 0.0f; - - Vector2 points[2*SPLINE_LINE_DIVISIONS + 2] = { 0 }; - - for (int i = 1; i <= SPLINE_LINE_DIVISIONS; i++) - { - t = step*i; - - float a = powf(1.0f - t, 2); - float b = 2.0f*(1.0f - t)*t; - float c = powf(t, 2); - - // NOTE: The easing functions aren't suitable here because they don't take a control point - current.y = a*startPos.y + b*controlPos.y + c*endPos.y; - current.x = a*startPos.x + b*controlPos.x + c*endPos.x; + current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)SPLINE_SEGMENT_DIVISIONS); + current.x = previous.x + (endPos.x - startPos.x)/(float)SPLINE_SEGMENT_DIVISIONS; float dy = current.y - previous.y; float dx = current.x - previous.x; @@ -284,211 +233,28 @@ void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, fl previous = current; } - DrawTriangleStrip(points, 2*SPLINE_LINE_DIVISIONS + 2, color); -} - -// Draw line using cubic bezier curves with 2 control points -void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlPos, Vector2 endControlPos, float thick, Color color) -{ - const float step = 1.0f/SPLINE_LINE_DIVISIONS; - - Vector2 previous = startPos; - Vector2 current = { 0 }; - float t = 0.0f; - - Vector2 points[2*SPLINE_LINE_DIVISIONS + 2] = { 0 }; - - for (int i = 1; i <= SPLINE_LINE_DIVISIONS; i++) - { - t = step*i; - - float a = powf(1.0f - t, 3); - float b = 3.0f*powf(1.0f - t, 2)*t; - float c = 3.0f*(1.0f - t)*powf(t, 2); - float d = powf(t, 3); - - current.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y; - current.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x; - - float dy = current.y - previous.y; - float dx = current.x - previous.x; - float size = 0.5f*thick/sqrtf(dx*dx+dy*dy); - - if (i == 1) - { - points[0].x = previous.x + dy*size; - points[0].y = previous.y - dx*size; - points[1].x = previous.x - dy*size; - points[1].y = previous.y + dx*size; - } - - points[2*i + 1].x = current.x - dy*size; - points[2*i + 1].y = current.y + dx*size; - points[2*i].x = current.x + dy*size; - points[2*i].y = current.y - dx*size; - - previous = current; - } - - DrawTriangleStrip(points, 2*SPLINE_LINE_DIVISIONS + 2, color); -} - -// Draw a B-Spline line, minimum 4 points -void DrawLineBSpline(Vector2 *points, int pointCount, float thick, Color color) -{ - if (pointCount < 4) return; - - float a[4] = { 0 }; - float b[4] = { 0 }; - float dy = 0.0f; - float dx = 0.0f; - float size = 0.0f; - - Vector2 currentPoint = { 0 }; - Vector2 nextPoint = { 0 }; - Vector2 vertices[2*SPLINE_LINE_DIVISIONS + 2] = { 0 }; - - for (int i = 0; i < (pointCount - 3); i++) - { - float t = 0.0f; - Vector2 p1 = points[i], p2 = points[i + 1], p3 = points[i + 2], p4 = points[i + 3]; - - a[0] = (-p1.x + 3.0f*p2.x - 3.0f*p3.x + p4.x)/6.0f; - a[1] = (3.0f*p1.x - 6.0f*p2.x + 3.0f*p3.x)/6.0f; - a[2] = (-3.0f*p1.x + 3.0f*p3.x)/6.0f; - a[3] = (p1.x + 4.0f*p2.x + p3.x)/6.0f; - - b[0] = (-p1.y + 3.0f*p2.y - 3.0f*p3.y + p4.y)/6.0f; - b[1] = (3.0f*p1.y - 6.0f*p2.y + 3.0f*p3.y)/6.0f; - b[2] = (-3.0f*p1.y + 3.0f*p3.y)/6.0f; - b[3] = (p1.y + 4.0f*p2.y + p3.y)/6.0f; - - currentPoint.x = a[3]; - currentPoint.y = b[3]; - - if (i == 0) DrawCircleV(currentPoint, thick/2.0f, color); // Draw init line circle-cap - - if (i > 0) - { - vertices[0].x = currentPoint.x + dy*size; - vertices[0].y = currentPoint.y - dx*size; - vertices[1].x = currentPoint.x - dy*size; - vertices[1].y = currentPoint.y + dx*size; - } - - for (int j = 1; j <= SPLINE_LINE_DIVISIONS; j++) - { - t = ((float)j)/((float)SPLINE_LINE_DIVISIONS); - - nextPoint.x = a[3] + t*(a[2] + t*(a[1] + t*a[0])); - nextPoint.y = b[3] + t*(b[2] + t*(b[1] + t*b[0])); - - dy = nextPoint.y - currentPoint.y; - dx = nextPoint.x - currentPoint.x; - size = 0.5f*thick/sqrtf(dx*dx+dy*dy); - - if ((i == 0) && (j == 1)) - { - vertices[0].x = currentPoint.x + dy*size; - vertices[0].y = currentPoint.y - dx*size; - vertices[1].x = currentPoint.x - dy*size; - vertices[1].y = currentPoint.y + dx*size; - } - - vertices[2*j + 1].x = nextPoint.x - dy*size; - vertices[2*j + 1].y = nextPoint.y + dx*size; - vertices[2*j].x = nextPoint.x + dy*size; - vertices[2*j].y = nextPoint.y - dx*size; - - currentPoint = nextPoint; - } - - DrawTriangleStrip(vertices, 2*SPLINE_LINE_DIVISIONS + 2, color); - } - - DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap + DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); } -// Draw a Catmull Rom spline line, minimum 4 points -void DrawLineCatmullRom(Vector2 *points, int pointCount, float thick, Color color) +// Draw a line defining thickness +void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color) { - if (pointCount < 4) return; - - float dy = 0.0f; - float dx = 0.0f; - float size = 0.0f; - - Vector2 currentPoint = points[1]; - Vector2 nextPoint = { 0 }; - Vector2 vertices[2*SPLINE_LINE_DIVISIONS + 2] = { 0 }; - - DrawCircleV(currentPoint, thick/2.0f, color); // Draw init line circle-cap + Vector2 delta = { endPos.x - startPos.x, endPos.y - startPos.y }; + float length = sqrtf(delta.x*delta.x + delta.y*delta.y); - for (int i = 0; i < (pointCount - 3); i++) + if ((length > 0) && (thick > 0)) { - float t = 0.0f; - Vector2 p1 = points[i], p2 = points[i + 1], p3 = points[i + 2], p4 = points[i + 3]; - - if (i > 0) - { - vertices[0].x = currentPoint.x + dy*size; - vertices[0].y = currentPoint.y - dx*size; - vertices[1].x = currentPoint.x - dy*size; - vertices[1].y = currentPoint.y + dx*size; - } - - for (int j = 1; j <= SPLINE_LINE_DIVISIONS; j++) - { - t = ((float)j)/((float)SPLINE_LINE_DIVISIONS); - - float q0 = (-1.0f*t*t*t) + (2.0f*t*t) + (-1.0f*t); - float q1 = (3.0f*t*t*t) + (-5.0f*t*t) + 2.0f; - float q2 = (-3.0f*t*t*t) + (4.0f*t*t) + t; - float q3 = t*t*t - t*t; - - nextPoint.x = 0.5f*((p1.x*q0) + (p2.x*q1) + (p3.x*q2) + (p4.x*q3)); - nextPoint.y = 0.5f*((p1.y*q0) + (p2.y*q1) + (p3.y*q2) + (p4.y*q3)); - - dy = nextPoint.y - currentPoint.y; - dx = nextPoint.x - currentPoint.x; - size = (0.5f*thick)/sqrtf(dx*dx + dy*dy); - - if ((i == 0) && (j == 1)) - { - vertices[0].x = currentPoint.x + dy*size; - vertices[0].y = currentPoint.y - dx*size; - vertices[1].x = currentPoint.x - dy*size; - vertices[1].y = currentPoint.y + dx*size; - } - - vertices[2*j + 1].x = nextPoint.x - dy*size; - vertices[2*j + 1].y = nextPoint.y + dx*size; - vertices[2*j].x = nextPoint.x + dy*size; - vertices[2*j].y = nextPoint.y - dx*size; - - currentPoint = nextPoint; - } - - DrawTriangleStrip(vertices, 2*SPLINE_LINE_DIVISIONS + 2, color); - } - - DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap -} + float scale = thick/(2*length); -// Draw lines sequence -void DrawLineStrip(Vector2 *points, int pointCount, Color color) -{ - if (pointCount >= 2) - { - rlBegin(RL_LINES); - rlColor4ub(color.r, color.g, color.b, color.a); + Vector2 radius = { -scale*delta.y, scale*delta.x }; + Vector2 strip[4] = { + { startPos.x - radius.x, startPos.y - radius.y }, + { startPos.x + radius.x, startPos.y + radius.y }, + { endPos.x - radius.x, endPos.y - radius.y }, + { endPos.x + radius.x, endPos.y + radius.y } + }; - 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(); + DrawTriangleStrip(strip, 4, color); } } @@ -671,14 +437,20 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co // Draw circle outline void DrawCircleLines(int centerX, int centerY, float radius, Color color) { + DrawCircleLinesV((Vector2){ (float)centerX, (float)centerY }, radius, color); +} + +// Draw circle outline (Vector version) +void DrawCircleLinesV(Vector2 center, float radius, Color color) +{ rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); // NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360) for (int i = 0; i < 360; i += 10) { - rlVertex2f(centerX + cosf(DEG2RAD*i)*radius, centerY + sinf(DEG2RAD*i)*radius); - rlVertex2f(centerX + cosf(DEG2RAD*(i + 10))*radius, centerY + sinf(DEG2RAD*(i + 10))*radius); + rlVertex2f(center.x + cosf(DEG2RAD*i)*radius, center.y + sinf(DEG2RAD*i)*radius); + rlVertex2f(center.x + cosf(DEG2RAD*(i + 10))*radius, center.y + sinf(DEG2RAD*(i + 10))*radius); } rlEnd(); } @@ -1768,6 +1540,504 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl } //---------------------------------------------------------------------------------- +// Module Functions Definition - Splines functions +//---------------------------------------------------------------------------------- + +// Draw spline: linear, minimum 2 points +void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) +{ + 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 }; + length = sqrtf(delta.x*delta.x + delta.y*delta.y); + + if (length > 0) scale = thick/(2*length); + + Vector2 radius = { -scale*delta.y, scale*delta.x }; + Vector2 strip[4] = { + { points[i].x - radius.x, points[i].y - radius.y }, + { points[i].x + radius.x, points[i].y + radius.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); + } +#if defined(SUPPORT_SPLINE_SEGMENT_CAPS) + +#endif +} + +// Draw spline: B-Spline, minimum 4 points +void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color) +{ + if (pointCount < 4) return; + + float a[4] = { 0 }; + float b[4] = { 0 }; + float dy = 0.0f; + float dx = 0.0f; + float size = 0.0f; + + Vector2 currentPoint = { 0 }; + Vector2 nextPoint = { 0 }; + Vector2 vertices[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; + + for (int i = 0; i < (pointCount - 3); i++) + { + float t = 0.0f; + Vector2 p1 = points[i], p2 = points[i + 1], p3 = points[i + 2], p4 = points[i + 3]; + + a[0] = (-p1.x + 3.0f*p2.x - 3.0f*p3.x + p4.x)/6.0f; + a[1] = (3.0f*p1.x - 6.0f*p2.x + 3.0f*p3.x)/6.0f; + a[2] = (-3.0f*p1.x + 3.0f*p3.x)/6.0f; + a[3] = (p1.x + 4.0f*p2.x + p3.x)/6.0f; + + b[0] = (-p1.y + 3.0f*p2.y - 3.0f*p3.y + p4.y)/6.0f; + b[1] = (3.0f*p1.y - 6.0f*p2.y + 3.0f*p3.y)/6.0f; + b[2] = (-3.0f*p1.y + 3.0f*p3.y)/6.0f; + b[3] = (p1.y + 4.0f*p2.y + p3.y)/6.0f; + + currentPoint.x = a[3]; + currentPoint.y = b[3]; + + if (i == 0) DrawCircleV(currentPoint, thick/2.0f, color); // Draw init line circle-cap + + if (i > 0) + { + vertices[0].x = currentPoint.x + dy*size; + vertices[0].y = currentPoint.y - dx*size; + vertices[1].x = currentPoint.x - dy*size; + vertices[1].y = currentPoint.y + dx*size; + } + + for (int j = 1; j <= SPLINE_SEGMENT_DIVISIONS; j++) + { + t = ((float)j)/((float)SPLINE_SEGMENT_DIVISIONS); + + nextPoint.x = a[3] + t*(a[2] + t*(a[1] + t*a[0])); + nextPoint.y = b[3] + t*(b[2] + t*(b[1] + t*b[0])); + + dy = nextPoint.y - currentPoint.y; + dx = nextPoint.x - currentPoint.x; + size = 0.5f*thick/sqrtf(dx*dx+dy*dy); + + if ((i == 0) && (j == 1)) + { + vertices[0].x = currentPoint.x + dy*size; + vertices[0].y = currentPoint.y - dx*size; + vertices[1].x = currentPoint.x - dy*size; + vertices[1].y = currentPoint.y + dx*size; + } + + vertices[2*j + 1].x = nextPoint.x - dy*size; + vertices[2*j + 1].y = nextPoint.y + dx*size; + vertices[2*j].x = nextPoint.x + dy*size; + vertices[2*j].y = nextPoint.y - dx*size; + + currentPoint = nextPoint; + } + + DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); + } + + DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap +} + +// Draw spline: Catmull-Rom, minimum 4 points +void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color) +{ + if (pointCount < 4) return; + + float dy = 0.0f; + float dx = 0.0f; + float size = 0.0f; + + Vector2 currentPoint = points[1]; + Vector2 nextPoint = { 0 }; + Vector2 vertices[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; + + DrawCircleV(currentPoint, thick/2.0f, color); // Draw init line circle-cap + + for (int i = 0; i < (pointCount - 3); i++) + { + float t = 0.0f; + Vector2 p1 = points[i], p2 = points[i + 1], p3 = points[i + 2], p4 = points[i + 3]; + + if (i > 0) + { + vertices[0].x = currentPoint.x + dy*size; + vertices[0].y = currentPoint.y - dx*size; + vertices[1].x = currentPoint.x - dy*size; + vertices[1].y = currentPoint.y + dx*size; + } + + for (int j = 1; j <= SPLINE_SEGMENT_DIVISIONS; j++) + { + t = ((float)j)/((float)SPLINE_SEGMENT_DIVISIONS); + + float q0 = (-1.0f*t*t*t) + (2.0f*t*t) + (-1.0f*t); + float q1 = (3.0f*t*t*t) + (-5.0f*t*t) + 2.0f; + float q2 = (-3.0f*t*t*t) + (4.0f*t*t) + t; + float q3 = t*t*t - t*t; + + nextPoint.x = 0.5f*((p1.x*q0) + (p2.x*q1) + (p3.x*q2) + (p4.x*q3)); + nextPoint.y = 0.5f*((p1.y*q0) + (p2.y*q1) + (p3.y*q2) + (p4.y*q3)); + + dy = nextPoint.y - currentPoint.y; + dx = nextPoint.x - currentPoint.x; + size = (0.5f*thick)/sqrtf(dx*dx + dy*dy); + + if ((i == 0) && (j == 1)) + { + vertices[0].x = currentPoint.x + dy*size; + vertices[0].y = currentPoint.y - dx*size; + vertices[1].x = currentPoint.x - dy*size; + vertices[1].y = currentPoint.y + dx*size; + } + + vertices[2*j + 1].x = nextPoint.x - dy*size; + vertices[2*j + 1].y = nextPoint.y + dx*size; + vertices[2*j].x = nextPoint.x + dy*size; + vertices[2*j].y = nextPoint.y - dx*size; + + currentPoint = nextPoint; + } + + DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); + } + + DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap +} + +// Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +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); + } +} + +// Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +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); + } +} + +// Draw spline segment: Linear, 2 points +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); + + if ((length > 0) && (thick > 0)) + { + float scale = thick/(2*length); + + Vector2 radius = { -scale*delta.y, scale*delta.x }; + Vector2 strip[4] = { + { p1.x - radius.x, p1.y - radius.y }, + { p1.x + radius.x, p1.y + radius.y }, + { p2.x - radius.x, p2.y - radius.y }, + { p2.x + radius.x, p2.y + radius.y } + }; + + DrawTriangleStrip(strip, 4, color); + } +} + +// Draw spline segment: B-Spline, 4 points +void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color) +{ + const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS; + + 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 }; + + a[0] = (-p1.x + 3*p2.x - 3*p3.x + p4.x)/6.0f; + a[1] = (3*p1.x - 6*p2.x + 3*p3.x)/6.0f; + a[2] = (-3*p1.x + 3*p3.x)/6.0f; + a[3] = (p1.x + 4*p2.x + p3.x)/6.0f; + + b[0] = (-p1.y + 3*p2.y - 3*p3.y + p4.y)/6.0f; + b[1] = (3*p1.y - 6*p2.y + 3*p3.y)/6.0f; + b[2] = (-3*p1.y + 3*p3.y)/6.0f; + b[3] = (p1.y + 4*p2.y + p3.y)/6.0f; + + currentPoint.x = a[3]; + currentPoint.y = b[3]; + + for (int i = 0; i <= SPLINE_SEGMENT_DIVISIONS; i++) + { + t = step*(float)i; + + nextPoint.x = a[3] + t*(a[2] + t*(a[1] + t*a[0])); + nextPoint.y = b[3] + t*(b[2] + t*(b[1] + t*b[0])); + + float dy = nextPoint.y - currentPoint.y; + float dx = nextPoint.x - currentPoint.x; + float size = (0.5f*thick)/sqrtf(dx*dx + dy*dy); + + if (i == 1) + { + points[0].x = currentPoint.x + dy*size; + points[0].y = currentPoint.y - dx*size; + points[1].x = currentPoint.x - dy*size; + points[1].y = currentPoint.y + dx*size; + } + + points[2*i + 1].x = nextPoint.x - dy*size; + points[2*i + 1].y = nextPoint.y + dx*size; + points[2*i].x = nextPoint.x + dy*size; + points[2*i].y = nextPoint.y - dx*size; + + currentPoint = nextPoint; + } + + DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS+2, color); +} + +// Draw spline segment: Catmull-Rom, 4 points +void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color) +{ + const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS; + + 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++) + { + t = step*(float)i; + + float q0 = (-1*t*t*t) + (2*t*t) + (-1*t); + float q1 = (3*t*t*t) + (-5*t*t) + 2; + float q2 = (-3*t*t*t) + (4*t*t) + t; + float q3 = t*t*t - t*t; + + nextPoint.x = 0.5f*((p1.x*q0) + (p2.x*q1) + (p3.x*q2) + (p4.x*q3)); + nextPoint.y = 0.5f*((p1.y*q0) + (p2.y*q1) + (p3.y*q2) + (p4.y*q3)); + + float dy = nextPoint.y - currentPoint.y; + float dx = nextPoint.x - currentPoint.x; + float size = (0.5f*thick)/sqrtf(dx*dx + dy*dy); + + if (i == 1) + { + points[0].x = currentPoint.x + dy*size; + points[0].y = currentPoint.y - dx*size; + points[1].x = currentPoint.x - dy*size; + points[1].y = currentPoint.y + dx*size; + } + + points[2*i + 1].x = nextPoint.x - dy*size; + points[2*i + 1].y = nextPoint.y + dx*size; + points[2*i].x = nextPoint.x + dy*size; + points[2*i].y = nextPoint.y - dx*size; + + currentPoint = nextPoint; + } + + DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); +} + +// Draw spline segment: Quadratic Bezier, 2 points, 1 control point +void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color) +{ + const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS; + + Vector2 previous = p1; + Vector2 current = { 0 }; + float t = 0.0f; + + Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; + + for (int i = 1; i <= SPLINE_SEGMENT_DIVISIONS; i++) + { + t = step*(float)i; + + float a = powf(1.0f - t, 2); + float b = 2.0f*(1.0f - t)*t; + float c = powf(t, 2); + + // NOTE: The easing functions aren't suitable here because they don't take a control point + current.y = a*p1.y + b*c2.y + c*p3.y; + current.x = a*p1.x + b*c2.x + c*p3.x; + + float dy = current.y - previous.y; + float dx = current.x - previous.x; + float size = 0.5f*thick/sqrtf(dx*dx+dy*dy); + + if (i == 1) + { + points[0].x = previous.x + dy*size; + points[0].y = previous.y - dx*size; + points[1].x = previous.x - dy*size; + points[1].y = previous.y + dx*size; + } + + points[2*i + 1].x = current.x - dy*size; + points[2*i + 1].y = current.y + dx*size; + points[2*i].x = current.x + dy*size; + points[2*i].y = current.y - dx*size; + + previous = current; + } + + DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); +} + +// Draw spline segment: Cubic Bezier, 2 points, 2 control points +void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color) +{ + const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS; + + Vector2 previous = p1; + Vector2 current = { 0 }; + float t = 0.0f; + + Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 }; + + for (int i = 1; i <= SPLINE_SEGMENT_DIVISIONS; i++) + { + t = step*(float)i; + + float a = powf(1.0f - t, 3); + float b = 3.0f*powf(1.0f - t, 2)*t; + float c = 3.0f*(1.0f - t)*powf(t, 2); + float d = powf(t, 3); + + current.y = a*p1.y + b*c2.y + c*c3.y + d*p4.y; + current.x = a*p1.x + b*c2.x + c*c3.x + d*p4.x; + + float dy = current.y - previous.y; + float dx = current.x - previous.x; + float size = 0.5f*thick/sqrtf(dx*dx+dy*dy); + + if (i == 1) + { + points[0].x = previous.x + dy*size; + points[0].y = previous.y - dx*size; + points[1].x = previous.x - dy*size; + points[1].y = previous.y + dx*size; + } + + points[2*i + 1].x = current.x - dy*size; + points[2*i + 1].y = current.y + dx*size; + points[2*i].x = current.x + dy*size; + points[2*i].y = current.y - dx*size; + + previous = current; + } + + DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); +} + +// Get spline point for a given t [0.0f .. 1.0f], Linear +Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t) +{ + Vector2 point = { 0 }; + + point.x = startPos.x*(1.0f - t) + endPos.x*t; + point.y = startPos.y*(1.0f - t) + endPos.y*t; + + return point; +} + +// Get spline point for a given t [0.0f .. 1.0f], B-Spline +Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t) +{ + Vector2 point = { 0 }; + + float a[4] = { 0 }; + float b[4] = { 0 }; + + a[0] = (-p1.x + 3*p2.x - 3*p3.x + p4.x)/6.0f; + a[1] = (3*p1.x - 6*p2.x + 3*p3.x)/6.0f; + a[2] = (-3*p1.x + 3*p3.x)/6.0f; + a[3] = (p1.x + 4*p2.x + p3.x)/6.0f; + + b[0] = (-p1.y + 3*p2.y - 3*p3.y + p4.y)/6.0f; + b[1] = (3*p1.y - 6*p2.y + 3*p3.y)/6.0f; + b[2] = (-3*p1.y + 3*p3.y)/6.0f; + b[3] = (p1.y + 4*p2.y + p3.y)/6.0f; + + point.x = a[3] + t*(a[2] + t*(a[1] + t*a[0])); + point.y = b[3] + t*(b[2] + t*(b[1] + t*b[0])); + + return point; +} + +// Get spline point for a given t [0.0f .. 1.0f], Catmull-Rom +Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t) +{ + Vector2 point = { 0 }; + + float q0 = (-1*t*t*t) + (2*t*t) + (-1*t); + float q1 = (3*t*t*t) + (-5*t*t) + 2; + float q2 = (-3*t*t*t) + (4*t*t) + t; + float q3 = t*t*t - t*t; + + point.x = 0.5f*((p1.x*q0) + (p2.x*q1) + (p3.x*q2) + (p4.x*q3)); + point.y = 0.5f*((p1.y*q0) + (p2.y*q1) + (p3.y*q2) + (p4.y*q3)); + + return point; +} + +// Get spline point for a given t [0.0f .. 1.0f], Quadratic Bezier +Vector2 GetSplinePointBezierQuad(Vector2 startPos, Vector2 controlPos, Vector2 endPos, float t) +{ + Vector2 point = { 0 }; + + float a = powf(1.0f - t, 2); + float b = 2.0f*(1.0f - t)*t; + float c = powf(t, 2); + + point.y = a*startPos.y + b*controlPos.y + c*endPos.y; + point.x = a*startPos.x + b*controlPos.x + c*endPos.x; + + return point; +} + +// Get spline point for a given t [0.0f .. 1.0f], Cubic Bezier +Vector2 GetSplinePointBezierCubic(Vector2 startPos, Vector2 startControlPos, Vector2 endControlPos, Vector2 endPos, float t) +{ + Vector2 point = { 0 }; + + float a = powf(1.0f - t, 3); + float b = 3.0f*powf(1.0f - t, 2)*t; + float c = 3.0f*(1.0f - t)*powf(t, 2); + float d = powf(t, 3); + + point.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y; + point.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x; + + return point; +} + +//---------------------------------------------------------------------------------- // Module Functions Definition - Collision Detection functions //---------------------------------------------------------------------------------- diff --git a/raylib/src/rtext.c b/raylib/src/rtext.c index 2ce21e5..dd7c83f 100644 --- a/raylib/src/rtext.c +++ b/raylib/src/rtext.c @@ -322,7 +322,7 @@ Font LoadFont(const char *fileName) #define FONT_TTF_DEFAULT_FIRST_CHAR 32 // TTF font generation default first char for image sprite font (32-Space) #endif #ifndef FONT_TTF_DEFAULT_CHARS_PADDING - #define FONT_TTF_DEFAULT_CHARS_PADDING 10 // TTF font generation default chars padding + #define FONT_TTF_DEFAULT_CHARS_PADDING 4 // TTF font generation default chars padding #endif Font font = { 0 }; @@ -716,7 +716,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp totalWidth += glyphs[i].image.width + 4*padding; } -#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE +//#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE #if defined(SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE) int rowCount = 0; int imageSize = 64; // Define minimum starting value to avoid unnecessary calculation steps for very small images @@ -1344,10 +1344,12 @@ Rectangle GetGlyphAtlasRec(Font font, int codepoint) // Get text length in bytes, check for \0 character unsigned int TextLength(const char *text) { - unsigned int length = 0; //strlen(text) + unsigned int length = 0; if (text != NULL) { + // NOTE: Alternative: use strlen(text) + while (*text++) length++; } @@ -1415,6 +1417,8 @@ int TextCopy(char *dst, const char *src) if ((src != NULL) && (dst != NULL)) { + // NOTE: Alternative: use strcpy(dst, src) + while (*src != '\0') { *dst = *src; @@ -1460,6 +1464,8 @@ const char *TextSubtext(const char *text, int position, int length) if (length >= textLength) length = textLength; + // NOTE: Alternative: memcpy(buffer, text + position, length) + for (int c = 0 ; c < length ; c++) { *(buffer + c) = *(text + position); @@ -1996,7 +2002,6 @@ int GetCodepointPrevious(const char *text, int *codepointSize) // Module specific Functions Definition //---------------------------------------------------------------------------------- #if defined(SUPPORT_FILEFORMAT_FNT) - // Read a line from memory // REQUIRES: memcpy() // NOTE: Returns the number of bytes read @@ -2026,7 +2031,9 @@ static Font LoadBMFont(const char *fileName) int imHeight = 0; char imFileName[129] = { 0 }; - int base = 0; // Useless data + int base = 0; // Useless data + int readBytes = 0; // Data bytes read + int readVars = 0; // Variables filled by sscanf() char *fileText = LoadFileText(fileName); @@ -2035,32 +2042,30 @@ static Font LoadBMFont(const char *fileName) char *fileTextPtr = fileText; // NOTE: We skip first line, it contains no useful information - int lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); - fileTextPtr += (lineBytes + 1); + readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); + fileTextPtr += (readBytes + 1); // Read line data - lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); + readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); searchPoint = strstr(buffer, "lineHeight"); - sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &imWidth, &imHeight); - fileTextPtr += (lineBytes + 1); + readVars = sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &imWidth, &imHeight); + fileTextPtr += (readBytes + 1); + + if (readVars < 4) { UnloadFileText(fileText); return font; } // Some data not available, file malformed - TRACELOGD("FONT: [%s] Loaded font info:", fileName); - TRACELOGD(" > Base size: %i", fontSize); - TRACELOGD(" > Texture scale: %ix%i", imWidth, imHeight); - - lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); + readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); searchPoint = strstr(buffer, "file"); - sscanf(searchPoint, "file=\"%128[^\"]\"", imFileName); - fileTextPtr += (lineBytes + 1); + readVars = sscanf(searchPoint, "file=\"%128[^\"]\"", imFileName); + fileTextPtr += (readBytes + 1); - TRACELOGD(" > Texture filename: %s", imFileName); + if (readVars < 1) { UnloadFileText(fileText); return font; } // No fileName read - lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); + readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); searchPoint = strstr(buffer, "count"); - sscanf(searchPoint, "count=%i", &glyphCount); - fileTextPtr += (lineBytes + 1); + readVars = sscanf(searchPoint, "count=%i", &glyphCount); + fileTextPtr += (readBytes + 1); - TRACELOGD(" > Chars count: %i", glyphCount); + if (readVars < 1) { UnloadFileText(fileText); return font; } // No glyphCount read // Compose correct path using route of .fnt file (fileName) and imFileName char *imPath = NULL; @@ -2118,22 +2123,26 @@ static Font LoadBMFont(const char *fileName) for (int i = 0; i < glyphCount; i++) { - lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); - sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%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); - fileTextPtr += (lineBytes + 1); - - // Get character rectangle in the font atlas texture - font.recs[i] = (Rectangle){ (float)charX, (float)charY, (float)charWidth, (float)charHeight }; + fileTextPtr += (readBytes + 1); + + if (readVars == 8) // 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 }; - // Save data properly in sprite font - font.glyphs[i].value = charId; - font.glyphs[i].offsetX = charOffsetX; - font.glyphs[i].offsetY = charOffsetY; - font.glyphs[i].advanceX = charAdvanceX; + // Save data properly in sprite font + font.glyphs[i].value = charId; + font.glyphs[i].offsetX = charOffsetX; + 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 imFont data + font.glyphs[i].image = ImageFromImage(imFont, font.recs[i]); + } + else TRACELOG(LOG_WARNING, "FONT: [%s] Some characters data not correctly provided", fileName); } UnloadImage(imFont); diff --git a/raylib/src/rtextures.c b/raylib/src/rtextures.c index bf1b35e..98586db 100644 --- a/raylib/src/rtextures.c +++ b/raylib/src/rtextures.c @@ -347,7 +347,7 @@ Image LoadImageSvg(const char *fileNameOrString, int width, int height) (fileNameOrString[2] == 'v') && (fileNameOrString[3] == 'g')) { - fileData = fileNameOrString; + fileData = (unsigned char *)fileNameOrString; isSvgStringValid = true; } } @@ -1288,8 +1288,6 @@ void ImageFormat(Image *image, int newFormat) image->data = NULL; image->format = newFormat; - int k = 0; - switch (image->format) { case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: @@ -1306,7 +1304,7 @@ void ImageFormat(Image *image, int newFormat) { image->data = (unsigned char *)RL_MALLOC(image->width*image->height*2*sizeof(unsigned char)); - for (int i = 0; i < image->width*image->height*2; i += 2, k++) + for (int i = 0, k = 0; i < image->width*image->height*2; i += 2, k++) { ((unsigned char *)image->data)[i] = (unsigned char)((pixels[k].x*0.299f + (float)pixels[k].y*0.587f + (float)pixels[k].z*0.114f)*255.0f); ((unsigned char *)image->data)[i + 1] = (unsigned char)(pixels[k].w*255.0f); diff --git a/raylib/src/shell.html b/raylib/src/shell.html index b373394..6effbca 100644 --- a/raylib/src/shell.html +++ b/raylib/src/shell.html @@ -8,24 +8,27 @@ <meta name="title" content="raylib web game"> <meta name="description" content="New raylib web videogame, developed using raylib videogames library"> - <meta name="keywords" content="raylib, games, html5, programming, C, C++, library, learn, videogames"> + <meta name="keywords" content="raylib, programming, examples, html5, C, C++, library, learn, games, videogames"> <meta name="viewport" content="width=device-width"> <!-- Open Graph metatags for sharing --> + <meta property="og:type" content="website" /> <meta property="og:title" content="raylib web game"> <meta property="og:image:type" content="image/png"> - <meta property="og:image" content="https://www.raylib.com/common/img/raylib_logo.png"> - <meta property="og:site_name" content="raylib.com"> + <meta property="og:image:alt" content="New raylib web videogame, developed using raylib videogames library" /> + <meta property="og:image" content="https://www.raylib.com/common/raylib_logo.png"> + <meta property="og:site_name" content="raylib - example"> <meta property="og:url" content="https://www.raylib.com/games.html"> <meta property="og:description" content="New raylib web videogame, developed using raylib videogames library"> <!-- Twitter metatags for sharing --> - <meta name="twitter:card" content="summary"> + <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="@raysan5"> <meta name="twitter:title" content="raylib web game"> <meta name="twitter:image" content="https://www.raylib.com/common/raylib_logo.png"> + <meta name="twitter:image:alt" content="New raylib web videogame, developed using raylib videogames library"> <meta name="twitter:url" content="https://www.raylib.com/games.html"> - <meta name="twitter:description" content="New raylib web game, developed using raylib videogames library"> + <meta name="twitter:description" content="New raylib web videogame, developed using raylib videogames library"> <!-- Favicon --> <link rel="shortcut icon" href="https://www.raylib.com/favicon.ico"> @@ -157,6 +160,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB cursor: pointer; width: 140px; height: 50px; + margin-left: 10px; } input[type=button]:hover { @@ -173,8 +177,9 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB <div class="emscripten" id="status">Downloading...</div> <span id='controls'> + <span><input type="button" value="📜 SOURCE CODE" onclick="location.href='https://github.com/raysan5/raylib';"/></span> <span><input type="button" value="🖵 FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span> - <span><input type="button" id="btn-audio" value="🔇 SUSPEND" onclick="toggleAudio()"></span> + <span><input type="button" id="btn-audio" value="🔇 MUTE" onclick="toggleAudio()"></span> </span> <div class="emscripten"> @@ -319,7 +324,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB else if (ctx.state == "running") ctx.suspend(); }); - if (resumed) audioBtn.value = "🔇 SUSPEND"; + if (resumed) audioBtn.value = "🔇 MUTE"; else audioBtn.value = "🔈 RESUME"; } </script> diff --git a/src/gunner/controller.c b/src/gunner/controller.c index 4e56a27..1ac76ff 100644 --- a/src/gunner/controller.c +++ b/src/gunner/controller.c @@ -1,86 +1,14 @@ -// Keyboard things - -b32 is_key_pressed(i32 btn) -{ - return IsKeyPressed(btn); -} - -b32 is_key_held(i32 btn) -{ - return IsKeyDown(btn); -} - -b32 is_key_released(i32 btn) -{ - return IsKeyReleased(btn); -} - -// Mouse things - -b32 is_mouse_pressed(i32 btn) -{ - return IsMouseButtonPressed(btn); -} - -b32 is_mouse_held(i32 btn) -{ - return IsMouseButtonDown(btn); -} - -b32 is_mouse_released(i32 btn) -{ - return IsMouseButtonReleased(btn); -} - -void set_mouse_scale(f32 x, f32 y) -{ - SetMouseScale(x, y); -} - -vec2 get_mouse_pos(void) -{ - Vector2 pos = GetMousePosition(); - return (vec2){FP_TO_FIXED(pos.x), FP_TO_FIXED(pos.y)}; -} - -fx32 get_wheel_movement(void) -{ - return FP_TO_FIXED(GetMouseWheelMove()); -} - -// Gamepad things - -b32 is_button_pressed(i32 btn) -{ - return IsGamepadButtonPressed(0, btn); -} - -b32 is_button_held(i32 btn) -{ - return IsGamepadButtonDown(0, btn); -} - -b32 is_button_released(i32 btn) -{ - return IsGamepadButtonReleased(0, btn); -} - -i32 last_button_press(void) -{ - return GetGamepadButtonPressed(); -} - // Movement things -vec2 get_dir_input(void) +Vector2 get_dir_input(void) { - fx32 cont_x = FP_TO_FIXED(GetGamepadAxisMovement(0, 0)); - fx32 cont_y = FP_TO_FIXED(GetGamepadAxisMovement(0, 1)); + f32 cont_x = GetGamepadAxisMovement(0, 0); + f32 cont_y = GetGamepadAxisMovement(0, 1); - fx32 key_w = IsKeyDown(KEY_W) ? FIXED_POINT_ONE : 0; - fx32 key_s = IsKeyDown(KEY_S) ? FIXED_POINT_ONE : 0; - fx32 key_a = IsKeyDown(KEY_A) ? FIXED_POINT_ONE : 0; - fx32 key_d = IsKeyDown(KEY_D) ? FIXED_POINT_ONE : 0; + f32 key_w = IsKeyDown(KEY_W) ? 1.f: 0.f; + f32 key_s = IsKeyDown(KEY_S) ? 1.f: 0.f; + f32 key_a = IsKeyDown(KEY_A) ? 1.f: 0.f; + f32 key_d = IsKeyDown(KEY_D) ? 1.f: 0.f; // Either Gamepad or Keyboard control, not both! if(key_w != 0 || key_s != 0 || key_a != 0 || key_d != 0){ @@ -88,5 +16,5 @@ vec2 get_dir_input(void) cont_y = key_s - key_w; } - return (vec2){cont_x, cont_y}; + return (Vector2){cont_x, cont_y}; } diff --git a/src/gunner/text.c b/src/gunner/text.c index 0812ff1..d7f1e23 100644 --- a/src/gunner/text.c +++ b/src/gunner/text.c @@ -94,10 +94,18 @@ i32 load_font(const char* path) return current_idx; } -void draw_text_font(i32 idx, const char* text, vec2 pos, i32 size, Color col) +void draw_text_font(i32 idx, const char* text, Vector2 pos, f32 size, Color col) { - Vector2 position = (Vector2){FROM_FIXED(pos.x), FROM_FIXED(pos.y)}; - DrawTextEx(font_slots[idx], text, position, (f32)size, 1.0f, col); + DrawTextEx(font_slots[idx], text, pos, size, 0.5f, col); +} + +void draw_text_font_centered(i32 idx, const char* text, f32 y_offset, f32 size, Color col) +{ + Vector2 vec = MeasureTextEx(font_slots[idx], text, size, 0.5f); + Vector2 final_pos = (Vector2){(320.0f - vec.x) / 2.f, y_offset}; + + DrawTextEx(font_slots[idx], text, final_pos, size, 0.5f, col); + DrawLineV((Vector2){final_pos.x, y_offset + vec.y - 2.f}, (Vector2){final_pos.x + vec.x, y_offset + vec.y - 2.f}, col); } void unload_font(i32 idx) @@ -1,4 +1,5 @@ #include <raylib.h> +#include <rlgl.h> #include <stdlib.h> #include <stdio.h> @@ -33,7 +34,28 @@ int main() init_tex_sys(); init_shader_sys(); - i32 idx = load_font("assets/berry-rotunda.ttf"); + i32 idx = load_font("assets/fonts/berry-rotunda.fnt"); + + //load_music("assets/wicked_glee.ogg"); + //set_music_loop_point(15.73f); + + //play_music(); + + Model amanita = LoadModel("assets/models/amanita.m3d"); + + + RenderTexture2D tex = LoadRenderTexture(320, 240); + + Camera camera = { 0 }; + camera.position = (Vector3){ 0.5f, .5f, 1.5f }; // Camera position + camera.target = (Vector3){ 0.0f, .5f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera mode type + + Shader psx = LoadShader("assets/shaders/ps1vert.vs", "assets/shaders/ps1frag.fs"); + + amanita.materials[1].shader = psx; while(!WindowShouldClose()){ float dt = GetFrameTime(); @@ -46,12 +68,30 @@ int main() ClearBackground(WHITE); BeginDrawing(); + BeginTextureMode(tex); + ClearBackground(WHITE); + + BeginMode3D(camera); + + rlDisableBackfaceCulling(); + DrawModel(amanita, (Vector3){0.f, 0.f, 0.f}, 1.0f, WHITE); + rlEnableBackfaceCulling(); + EndMode3D(); + + draw_text_font_centered(idx, "Amanita", 4.f, 18, BLACK); + EndTextureMode(); - draw_text_font(idx, "Uneven Prankster Presents", (vec2){TO_FIXED(4), TO_FIXED(4)}, 16, BLACK); + DrawTexturePro(tex.texture, (Rectangle){0, 0, 320, -240}, (Rectangle){0, 0, 640, 480}, (Vector2){0, 0}, 0.f, WHITE); EndDrawing(); } + UnloadRenderTexture(tex); + + UnloadShader(psx); + + UnloadModel(amanita); + unload_all_fonts(); unload_active_audio(); unload_current_music(); |
