From 7f6239f849602f9201b703856510907bd794711f Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 02:38:36 +0100 Subject: [PATCH 01/89] Prettified a comment --- src/raymath.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 86d2c8eb842f..87254186d700 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -1062,12 +1062,11 @@ RMAPI int Vector3Equals(Vector3 p, Vector3 q) return result; } -// Compute the direction of a refracted ray where v specifies the -// normalized direction of the incoming ray, n specifies the -// normalized normal vector of the interface of two optical media, -// and r specifies the ratio of the refractive index of the medium -// from where the ray comes to the refractive index of the medium -// on the other side of the surface +// Compute the direction of a refracted ray +// v: normalized direction of the incoming ray +// n: normalized normal vector of the interface of two optical media +// r: ratio of the refractive index of the medium from where the ray comes +// to the refractive index of the medium on the other side of the surface RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) { Vector3 result = { 0 }; From feaaf95db467e6367208605131f23b7088549401 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 02:40:29 +0100 Subject: [PATCH 02/89] fixed broken indentation caused by another commit. the commit renamed a bool to int and broke indentation: 233cf3970c9148c4963cfdea20e49e761104f9de --- src/raymath.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 87254186d700..00cf645c4828 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -1056,8 +1056,8 @@ RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max) RMAPI int Vector3Equals(Vector3 p, Vector3 q) { int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && - ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))); + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && + ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))); return result; } From 03567d2b2ede5607845e143777af8dbf13dde0b5 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 02:43:19 +0100 Subject: [PATCH 03/89] Changed 0.001 and 0.00001 to EPSILON This commit is untested. I don't know what consequences this has. Since the commits that added these numbers were before epsilon was added, I have assumed that epsilon could replace them. --- src/raymath.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 00cf645c4828..892fad6cbb4d 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -1826,7 +1826,7 @@ RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) float halfTheta = acosf(cosHalfTheta); float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta); - if (fabsf(sinHalfTheta) < 0.001f) + if (fabsf(sinHalfTheta) < EPSILON) { result.x = (q1.x*0.5f + q2.x*0.5f); result.y = (q1.y*0.5f + q2.y*0.5f); @@ -2039,7 +2039,7 @@ RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle float resAngle = 2.0f*acosf(q.w); float den = sqrtf(1.0f - q.w*q.w); - if (den > 0.0001f) + if (den > EPSILON) { resAxis.x = q.x/den; resAxis.y = q.y/den; From c21d7b70a909668b8168693f2df81ee98a13f33e Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 02:53:26 +0100 Subject: [PATCH 04/89] Prettied up indentation in a few places --- src/raymath.h | 182 +++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 892fad6cbb4d..d2e2a22efe23 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -757,8 +757,8 @@ RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat) float y = v.y; float z = v.z; - result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; - result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; + result.x = mat.m0*x + mat.m4*y + mat.m8 *z + mat.m12; + result.y = mat.m1*x + mat.m5*y + mat.m9 *z + mat.m13; result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14; return result; @@ -769,9 +769,9 @@ RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q) { Vector3 result = { 0 }; - result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); - result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); - result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); + result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); + result.y = v.x*( 2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); + result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z) + v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); return result; } @@ -914,28 +914,28 @@ RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it Matrix matViewProj = { // MatrixMultiply(view, projection); - view.m0*projection.m0 + view.m1*projection.m4 + view.m2*projection.m8 + view.m3*projection.m12, - view.m0*projection.m1 + view.m1*projection.m5 + view.m2*projection.m9 + view.m3*projection.m13, - view.m0*projection.m2 + view.m1*projection.m6 + view.m2*projection.m10 + view.m3*projection.m14, - view.m0*projection.m3 + view.m1*projection.m7 + view.m2*projection.m11 + view.m3*projection.m15, - view.m4*projection.m0 + view.m5*projection.m4 + view.m6*projection.m8 + view.m7*projection.m12, - view.m4*projection.m1 + view.m5*projection.m5 + view.m6*projection.m9 + view.m7*projection.m13, - view.m4*projection.m2 + view.m5*projection.m6 + view.m6*projection.m10 + view.m7*projection.m14, - view.m4*projection.m3 + view.m5*projection.m7 + view.m6*projection.m11 + view.m7*projection.m15, - view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, - view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, - view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, - view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, - view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, - view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, + view.m0*projection.m0 + view.m1*projection.m4 + view.m2 *projection.m8 + view.m3*projection.m12, + view.m0*projection.m1 + view.m1*projection.m5 + view.m2 *projection.m9 + view.m3*projection.m13, + view.m0*projection.m2 + view.m1*projection.m6 + view.m2 *projection.m10 + view.m3*projection.m14, + view.m0*projection.m3 + view.m1*projection.m7 + view.m2 *projection.m11 + view.m3*projection.m15, + view.m4*projection.m0 + view.m5*projection.m4 + view.m6 *projection.m8 + view.m7*projection.m12, + view.m4*projection.m1 + view.m5*projection.m5 + view.m6 *projection.m9 + view.m7*projection.m13, + view.m4*projection.m2 + view.m5*projection.m6 + view.m6 *projection.m10 + view.m7*projection.m14, + view.m4*projection.m3 + view.m5*projection.m7 + view.m6 *projection.m11 + view.m7*projection.m15, + view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, + view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, + view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, + view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, + view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, + view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14, view.m12*projection.m3 + view.m13*projection.m7 + view.m14*projection.m11 + view.m15*projection.m15 }; // Calculate inverted matrix -> MatrixInvert(matViewProj); // Cache the matrix values (speed optimization) - float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3; - float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7; - float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11; + float a00 = matViewProj.m0 , a01 = matViewProj.m1 , a02 = matViewProj.m2 , a03 = matViewProj.m3; + float a10 = matViewProj.m4 , a11 = matViewProj.m5 , a12 = matViewProj.m6 , a13 = matViewProj.m7; + float a20 = matViewProj.m8 , a21 = matViewProj.m9 , a22 = matViewProj.m10, a23 = matViewProj.m11; float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15; float b00 = a00*a11 - a01*a10; @@ -955,22 +955,22 @@ RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); Matrix matViewProjInv = { - (a11*b11 - a12*b10 + a13*b09)*invDet, + ( a11*b11 - a12*b10 + a13*b09)*invDet, (-a01*b11 + a02*b10 - a03*b09)*invDet, - (a31*b05 - a32*b04 + a33*b03)*invDet, + ( a31*b05 - a32*b04 + a33*b03)*invDet, (-a21*b05 + a22*b04 - a23*b03)*invDet, (-a10*b11 + a12*b08 - a13*b07)*invDet, - (a00*b11 - a02*b08 + a03*b07)*invDet, + ( a00*b11 - a02*b08 + a03*b07)*invDet, (-a30*b05 + a32*b02 - a33*b01)*invDet, - (a20*b05 - a22*b02 + a23*b01)*invDet, - (a10*b10 - a11*b08 + a13*b06)*invDet, + ( a20*b05 - a22*b02 + a23*b01)*invDet, + ( a10*b10 - a11*b08 + a13*b06)*invDet, (-a00*b10 + a01*b08 - a03*b06)*invDet, - (a30*b04 - a31*b02 + a33*b00)*invDet, + ( a30*b04 - a31*b02 + a33*b00)*invDet, (-a20*b04 + a21*b02 - a23*b00)*invDet, (-a10*b09 + a11*b07 - a12*b06)*invDet, - (a00*b09 - a01*b07 + a02*b06)*invDet, + ( a00*b09 - a01*b07 + a02*b06)*invDet, (-a30*b03 + a31*b01 - a32*b00)*invDet, - (a20*b03 - a21*b01 + a22*b00)*invDet }; + ( a20*b03 - a21*b01 + a22*b00)*invDet }; // Create quaternion from source point Quaternion quat = { source.x, source.y, source.z, 1.0f }; @@ -1125,16 +1125,16 @@ RMAPI Matrix MatrixTranspose(Matrix mat) { Matrix result = { 0 }; - result.m0 = mat.m0; - result.m1 = mat.m4; - result.m2 = mat.m8; - result.m3 = mat.m12; - result.m4 = mat.m1; - result.m5 = mat.m5; - result.m6 = mat.m9; - result.m7 = mat.m13; - result.m8 = mat.m2; - result.m9 = mat.m6; + result.m0 = mat.m0; + result.m1 = mat.m4; + result.m2 = mat.m8; + result.m3 = mat.m12; + result.m4 = mat.m1; + result.m5 = mat.m5; + result.m6 = mat.m9; + result.m7 = mat.m13; + result.m8 = mat.m2; + result.m9 = mat.m6; result.m10 = mat.m10; result.m11 = mat.m14; result.m12 = mat.m3; @@ -1151,9 +1151,9 @@ RMAPI Matrix MatrixInvert(Matrix mat) Matrix result = { 0 }; // Cache the matrix values (speed optimization) - float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; - float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; - float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a00 = mat.m0 , a01 = mat.m1 , a02 = mat.m2 , a03 = mat.m3; + float a10 = mat.m4 , a11 = mat.m5 , a12 = mat.m6 , a13 = mat.m7; + float a20 = mat.m8 , a21 = mat.m9 , a22 = mat.m10, a23 = mat.m11; float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; float b00 = a00*a11 - a01*a10; @@ -1172,22 +1172,22 @@ RMAPI Matrix MatrixInvert(Matrix mat) // Calculate the invert determinant (inlined to avoid double-caching) float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); - result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; - result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; - result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; - result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; - result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; - result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; - result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; - result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; - result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; - result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; - result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; + result.m0 = ( a11*b11 - a12*b10 + a13*b09)*invDet; + result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; + result.m2 = ( a31*b05 - a32*b04 + a33*b03)*invDet; + result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; + result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; + result.m5 = ( a00*b11 - a02*b08 + a03*b07)*invDet; + result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; + result.m7 = ( a20*b05 - a22*b02 + a23*b01)*invDet; + result.m8 = ( a10*b10 - a11*b08 + a13*b06)*invDet; + result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; + result.m10 = ( a30*b04 - a31*b02 + a33*b00)*invDet; result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; - result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; + result.m13 = ( a00*b09 - a01*b07 + a02*b06)*invDet; result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; - result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; + result.m15 = ( a20*b03 - a21*b01 + a22*b00)*invDet; return result; } @@ -1208,16 +1208,16 @@ RMAPI Matrix MatrixAdd(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0 + right.m0; - result.m1 = left.m1 + right.m1; - result.m2 = left.m2 + right.m2; - result.m3 = left.m3 + right.m3; - result.m4 = left.m4 + right.m4; - result.m5 = left.m5 + right.m5; - result.m6 = left.m6 + right.m6; - result.m7 = left.m7 + right.m7; - result.m8 = left.m8 + right.m8; - result.m9 = left.m9 + right.m9; + result.m0 = left.m0 + right.m0; + result.m1 = left.m1 + right.m1; + result.m2 = left.m2 + right.m2; + result.m3 = left.m3 + right.m3; + result.m4 = left.m4 + right.m4; + result.m5 = left.m5 + right.m5; + result.m6 = left.m6 + right.m6; + result.m7 = left.m7 + right.m7; + result.m8 = left.m8 + right.m8; + result.m9 = left.m9 + right.m9; result.m10 = left.m10 + right.m10; result.m11 = left.m11 + right.m11; result.m12 = left.m12 + right.m12; @@ -1233,16 +1233,16 @@ RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0 - right.m0; - result.m1 = left.m1 - right.m1; - result.m2 = left.m2 - right.m2; - result.m3 = left.m3 - right.m3; - result.m4 = left.m4 - right.m4; - result.m5 = left.m5 - right.m5; - result.m6 = left.m6 - right.m6; - result.m7 = left.m7 - right.m7; - result.m8 = left.m8 - right.m8; - result.m9 = left.m9 - right.m9; + result.m0 = left.m0 - right.m0; + result.m1 = left.m1 - right.m1; + result.m2 = left.m2 - right.m2; + result.m3 = left.m3 - right.m3; + result.m4 = left.m4 - right.m4; + result.m5 = left.m5 - right.m5; + result.m6 = left.m6 - right.m6; + result.m7 = left.m7 - right.m7; + result.m8 = left.m8 - right.m8; + result.m9 = left.m9 - right.m9; result.m10 = left.m10 - right.m10; result.m11 = left.m11 - right.m11; result.m12 = left.m12 - right.m12; @@ -1259,20 +1259,20 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; - result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; - result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; - result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; - result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; - result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; - result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; - result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; - result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; - result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; - result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; - result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; - result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; - result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; + result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2 *right.m8 + left.m3 *right.m12; + result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2 *right.m9 + left.m3 *right.m13; + result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2 *right.m10 + left.m3 *right.m14; + result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2 *right.m11 + left.m3 *right.m15; + result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6 *right.m8 + left.m7 *right.m12; + result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6 *right.m9 + left.m7 *right.m13; + result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6 *right.m10 + left.m7 *right.m14; + result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6 *right.m11 + left.m7 *right.m15; + result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; + result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; + result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; + result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; + result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; + result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; @@ -2122,7 +2122,7 @@ RMAPI int QuaternionEquals(Quaternion p, Quaternion q) ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))) || - (((fabsf(p.x + q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && + (((fabsf(p.x + q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && ((fabsf(p.y + q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && ((fabsf(p.z + q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && ((fabsf(p.w + q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))); From f85f9d4c4fceaae48efcfe798a83b381cb277caa Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 02:55:52 +0100 Subject: [PATCH 05/89] removed spacing around *, standardizing it. --- src/raymath.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index d2e2a22efe23..8e303ac22f53 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -785,7 +785,7 @@ RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) Vector3 result = v; // Vector3Normalize(axis); - float length = sqrtf(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z); + float length = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); if (length == 0.0f) length = 1.0f; float ilength = 1.0f / length; axis.x *= ilength; @@ -794,19 +794,19 @@ RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) angle /= 2.0f; float a = sinf(angle); - float b = axis.x * a; - float c = axis.y * a; - float d = axis.z * a; + float b = axis.x*a; + float c = axis.y*a; + float d = axis.z*a; a = cosf(angle); Vector3 w = { b, c, d }; // Vector3CrossProduct(w, v) - Vector3 wv = { w.y * v.z - w.z * v.y, w.z * v.x - w.x * v.z, w.x * v.y - w.y * v.x }; + Vector3 wv = { w.y*v.z - w.z*v.y, w.z*v.x - w.x*v.z, w.x*v.y - w.y*v.x }; // Vector3CrossProduct(w, wv) - Vector3 wwv = { w.y * wv.z - w.z * wv.y, w.z * wv.x - w.x * wv.z, w.x * wv.y - w.y * wv.x }; + Vector3 wwv = { w.y*wv.z - w.z*wv.y, w.z*wv.x - w.x*wv.z, w.x*wv.y - w.y*wv.x }; - // Vector3Scale(wv, 2 * a) + // Vector3Scale(wv, 2*a) a *= 2; wv.x *= a; wv.y *= a; @@ -1906,34 +1906,34 @@ RMAPI Quaternion QuaternionFromMatrix(Matrix mat) biggestIndex = 3; } - float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f) * 0.5f; + float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f)*0.5f; float mult = 0.25f / biggestVal; switch (biggestIndex) { case 0: result.w = biggestVal; - result.x = (mat.m6 - mat.m9) * mult; - result.y = (mat.m8 - mat.m2) * mult; - result.z = (mat.m1 - mat.m4) * mult; + result.x = (mat.m6 - mat.m9)*mult; + result.y = (mat.m8 - mat.m2)*mult; + result.z = (mat.m1 - mat.m4)*mult; break; case 1: result.x = biggestVal; - result.w = (mat.m6 - mat.m9) * mult; - result.y = (mat.m1 + mat.m4) * mult; - result.z = (mat.m8 + mat.m2) * mult; + result.w = (mat.m6 - mat.m9)*mult; + result.y = (mat.m1 + mat.m4)*mult; + result.z = (mat.m8 + mat.m2)*mult; break; case 2: result.y = biggestVal; - result.w = (mat.m8 - mat.m2) * mult; - result.x = (mat.m1 + mat.m4) * mult; - result.z = (mat.m6 + mat.m9) * mult; + result.w = (mat.m8 - mat.m2)*mult; + result.x = (mat.m1 + mat.m4)*mult; + result.z = (mat.m6 + mat.m9)*mult; break; case 3: result.z = biggestVal; - result.w = (mat.m1 - mat.m4) * mult; - result.x = (mat.m8 + mat.m2) * mult; - result.y = (mat.m6 + mat.m9) * mult; + result.w = (mat.m1 - mat.m4)*mult; + result.x = (mat.m8 + mat.m2)*mult; + result.y = (mat.m6 + mat.m9)*mult; break; } From 10993c593945d202aaa315c0cf55be07be6474e6 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 03:25:15 +0100 Subject: [PATCH 06/89] I may have gotten overboard with indentation --- src/raymath.h | 176 +++++++++++++++++++++++++------------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 8e303ac22f53..b35db2e05497 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -506,7 +506,7 @@ RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) RMAPI int Vector2Equals(Vector2 p, Vector2 q) { int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); return result; } @@ -914,18 +914,18 @@ RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it Matrix matViewProj = { // MatrixMultiply(view, projection); - view.m0*projection.m0 + view.m1*projection.m4 + view.m2 *projection.m8 + view.m3*projection.m12, - view.m0*projection.m1 + view.m1*projection.m5 + view.m2 *projection.m9 + view.m3*projection.m13, - view.m0*projection.m2 + view.m1*projection.m6 + view.m2 *projection.m10 + view.m3*projection.m14, - view.m0*projection.m3 + view.m1*projection.m7 + view.m2 *projection.m11 + view.m3*projection.m15, - view.m4*projection.m0 + view.m5*projection.m4 + view.m6 *projection.m8 + view.m7*projection.m12, - view.m4*projection.m1 + view.m5*projection.m5 + view.m6 *projection.m9 + view.m7*projection.m13, - view.m4*projection.m2 + view.m5*projection.m6 + view.m6 *projection.m10 + view.m7*projection.m14, - view.m4*projection.m3 + view.m5*projection.m7 + view.m6 *projection.m11 + view.m7*projection.m15, - view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, - view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, - view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, - view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, + view.m0 *projection.m0 + view.m1 *projection.m4 + view.m2 *projection.m8 + view.m3*projection.m12, + view.m0 *projection.m1 + view.m1 *projection.m5 + view.m2 *projection.m9 + view.m3*projection.m13, + view.m0 *projection.m2 + view.m1 *projection.m6 + view.m2 *projection.m10 + view.m3*projection.m14, + view.m0 *projection.m3 + view.m1 *projection.m7 + view.m2 *projection.m11 + view.m3*projection.m15, + view.m4 *projection.m0 + view.m5 *projection.m4 + view.m6 *projection.m8 + view.m7*projection.m12, + view.m4 *projection.m1 + view.m5 *projection.m5 + view.m6 *projection.m9 + view.m7*projection.m13, + view.m4 *projection.m2 + view.m5 *projection.m6 + view.m6 *projection.m10 + view.m7*projection.m14, + view.m4 *projection.m3 + view.m5 *projection.m7 + view.m6 *projection.m11 + view.m7*projection.m15, + view.m8 *projection.m0 + view.m9 *projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, + view.m8 *projection.m1 + view.m9 *projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, + view.m8 *projection.m2 + view.m9 *projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, + view.m8 *projection.m3 + view.m9 *projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14, @@ -1097,9 +1097,9 @@ RMAPI float MatrixDeterminant(Matrix mat) float result = 0.0f; // Cache the matrix values (speed optimization) - float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; - float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; - float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a00 = mat.m0 , a01 = mat.m1 , a02 = mat.m2 , a03 = mat.m3; + float a10 = mat.m4 , a11 = mat.m5 , a12 = mat.m6 , a13 = mat.m7; + float a20 = mat.m8 , a21 = mat.m9 , a22 = mat.m10, a23 = mat.m11; float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 + @@ -1259,18 +1259,18 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2 *right.m8 + left.m3 *right.m12; - result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2 *right.m9 + left.m3 *right.m13; - result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2 *right.m10 + left.m3 *right.m14; - result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2 *right.m11 + left.m3 *right.m15; - result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6 *right.m8 + left.m7 *right.m12; - result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6 *right.m9 + left.m7 *right.m13; - result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6 *right.m10 + left.m7 *right.m14; - result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6 *right.m11 + left.m7 *right.m15; - result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; - result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; - result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; - result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; + result.m0 = left.m0 *right.m0 + left.m1 *right.m4 + left.m2 *right.m8 + left.m3 *right.m12; + result.m1 = left.m0 *right.m1 + left.m1 *right.m5 + left.m2 *right.m9 + left.m3 *right.m13; + result.m2 = left.m0 *right.m2 + left.m1 *right.m6 + left.m2 *right.m10 + left.m3 *right.m14; + result.m3 = left.m0 *right.m3 + left.m1 *right.m7 + left.m2 *right.m11 + left.m3 *right.m15; + result.m4 = left.m4 *right.m0 + left.m5 *right.m4 + left.m6 *right.m8 + left.m7 *right.m12; + result.m5 = left.m4 *right.m1 + left.m5 *right.m5 + left.m6 *right.m9 + left.m7 *right.m13; + result.m6 = left.m4 *right.m2 + left.m5 *right.m6 + left.m6 *right.m10 + left.m7 *right.m14; + result.m7 = left.m4 *right.m3 + left.m5 *right.m7 + left.m6 *right.m11 + left.m7 *right.m15; + result.m8 = left.m8 *right.m0 + left.m9 *right.m4 + left.m10*right.m8 + left.m11*right.m12; + result.m9 = left.m8 *right.m1 + left.m9 *right.m5 + left.m10*right.m9 + left.m11*right.m13; + result.m10 = left.m8 *right.m2 + left.m9 *right.m6 + left.m10*right.m10 + left.m11*right.m14; + result.m11 = left.m8 *right.m3 + left.m9 *right.m7 + left.m10*right.m11 + left.m11*right.m15; result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; @@ -1312,18 +1312,18 @@ RMAPI Matrix MatrixRotate(Vector3 axis, float angle) float cosres = cosf(angle); float t = 1.0f - cosres; - result.m0 = x*x*t + cosres; - result.m1 = y*x*t + z*sinres; - result.m2 = z*x*t - y*sinres; - result.m3 = 0.0f; + result.m0 = x*x*t + cosres; + result.m1 = y*x*t + z*sinres; + result.m2 = z*x*t - y*sinres; + result.m3 = 0.0f; - result.m4 = x*y*t - z*sinres; - result.m5 = y*y*t + cosres; - result.m6 = z*y*t + x*sinres; - result.m7 = 0.0f; + result.m4 = x*y*t - z*sinres; + result.m5 = y*y*t + cosres; + result.m6 = z*y*t + x*sinres; + result.m7 = 0.0f; - result.m8 = x*z*t + y*sinres; - result.m9 = y*z*t - x*sinres; + result.m8 = x*z*t + y*sinres; + result.m9 = y*z*t - x*sinres; result.m10 = z*z*t + cosres; result.m11 = 0.0f; @@ -1347,10 +1347,10 @@ RMAPI Matrix MatrixRotateX(float angle) float cosres = cosf(angle); float sinres = sinf(angle); - result.m5 = cosres; - result.m6 = sinres; - result.m9 = -sinres; - result.m10 = cosres; + result.m5 = cosres; + result.m6 = sinres; + result.m9 = -sinres; + result.m10 = cosres; return result; } @@ -1367,10 +1367,10 @@ RMAPI Matrix MatrixRotateY(float angle) float cosres = cosf(angle); float sinres = sinf(angle); - result.m0 = cosres; - result.m2 = -sinres; - result.m8 = sinres; - result.m10 = cosres; + result.m0 = cosres; + result.m2 = -sinres; + result.m8 = sinres; + result.m10 = cosres; return result; } @@ -1387,10 +1387,10 @@ RMAPI Matrix MatrixRotateZ(float angle) float cosres = cosf(angle); float sinres = sinf(angle); - result.m0 = cosres; - result.m1 = sinres; + result.m0 = cosres; + result.m1 = sinres; result.m4 = -sinres; - result.m5 = cosres; + result.m5 = cosres; return result; } @@ -1440,23 +1440,23 @@ RMAPI Matrix MatrixRotateZYX(Vector3 angle) float cx = cosf(angle.x); float sx = sinf(angle.x); - result.m0 = cz*cy; - result.m4 = cz*sy*sx - cx*sz; - result.m8 = sz*sx + cz*cx*sy; + result.m0 = cz*cy; + result.m4 = cz*sy*sx - cx*sz; + result.m8 = sz*sx + cz*cx*sy; result.m12 = 0; - result.m1 = cy*sz; - result.m5 = cz*cx + sz*sy*sx; - result.m9 = cx*sz*sy - cz*sx; + result.m1 = cy*sz; + result.m5 = cz*cx + sz*sy*sx; + result.m9 = cx*sz*sy - cz*sx; result.m13 = 0; - result.m2 = -sy; - result.m6 = cy*sx; + result.m2 = -sy; + result.m6 = cy*sx; result.m10 = cy*cx; result.m14 = 0; - result.m3 = 0; - result.m7 = 0; + result.m3 = 0; + result.m7 = 0; result.m11 = 0; result.m15 = 1; @@ -1466,9 +1466,9 @@ RMAPI Matrix MatrixRotateZYX(Vector3 angle) // Get scaling matrix RMAPI Matrix MatrixScale(float x, float y, float z) { - Matrix result = { x, 0.0f, 0.0f, 0.0f, - 0.0f, y, 0.0f, 0.0f, - 0.0f, 0.0f, z, 0.0f, + Matrix result = { x , 0.0f, 0.0f, 0.0f, + 0.0f, y , 0.0f, 0.0f, + 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; return result; @@ -1493,9 +1493,9 @@ RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, result.m6 = 0.0f; result.m7 = 0.0f; - result.m8 = ((float)right + (float)left)/rl; - result.m9 = ((float)top + (float)bottom)/tb; - result.m10 = -((float)far + (float)near)/fn; + result.m8 = ((float)right + (float)left )/rl; + result.m9 = ((float)top + (float)bottom)/tb; + result.m10 = -((float)far + (float)near )/fn; result.m11 = -1.0f; result.m12 = 0.0f; @@ -1518,14 +1518,14 @@ RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, dou double left = -right; // MatrixFrustum(-right, right, -top, top, near, far); - float rl = (float)(right - left); - float tb = (float)(top - bottom); + float rl = (float)(right - left ); + float tb = (float)(top - bottom ); float fn = (float)(farPlane - nearPlane); - result.m0 = ((float)nearPlane*2.0f)/rl; - result.m5 = ((float)nearPlane*2.0f)/tb; - result.m8 = ((float)right + (float)left)/rl; - result.m9 = ((float)top + (float)bottom)/tb; + result.m0 = ((float)nearPlane*2.0f)/rl; + result.m5 = ((float)nearPlane*2.0f)/tb; + result.m8 = ((float)right + (float)left )/rl; + result.m9 = ((float)top + (float)bottom )/tb; result.m10 = -((float)farPlane + (float)nearPlane)/fn; result.m11 = -1.0f; result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn; @@ -1538,8 +1538,8 @@ RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, d { Matrix result = { 0 }; - float rl = (float)(right - left); - float tb = (float)(top - bottom); + float rl = (float)(right - left ); + float tb = (float)(top - bottom ); float fn = (float)(farPlane - nearPlane); result.m0 = 2.0f/rl; @@ -1554,8 +1554,8 @@ RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, d result.m9 = 0.0f; result.m10 = -2.0f/fn; result.m11 = 0.0f; - result.m12 = -((float)left + (float)right)/rl; - result.m13 = -((float)top + (float)bottom)/tb; + result.m12 = -((float)left + (float)right )/rl; + result.m13 = -((float)top + (float)bottom )/tb; result.m14 = -((float)farPlane + (float)nearPlane)/fn; result.m15 = 1.0f; @@ -1881,9 +1881,9 @@ RMAPI Quaternion QuaternionFromMatrix(Matrix mat) { Quaternion result = { 0 }; - float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; - float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; - float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; + float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; + float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; + float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5; int biggestIndex = 0; @@ -1958,16 +1958,16 @@ RMAPI Matrix QuaternionToMatrix(Quaternion q) float bd = q.w*q.y; float cd = q.w*q.z; - result.m0 = 1 - 2*(b2 + c2); - result.m1 = 2*(ab + cd); - result.m2 = 2*(ac - bd); + result.m0 = 1 - 2*(b2 + c2); + result.m1 = 2*(ab + cd); + result.m2 = 2*(ac - bd); - result.m4 = 2*(ab - cd); - result.m5 = 1 - 2*(a2 + c2); - result.m6 = 2*(bc + ad); + result.m4 = 2*(ab - cd); + result.m5 = 1 - 2*(a2 + c2); + result.m6 = 2*(bc + ad); - result.m8 = 2*(ac + bd); - result.m9 = 2*(bc - ad); + result.m8 = 2*(ac + bd); + result.m9 = 2*(bc - ad); result.m10 = 1 - 2*(a2 + b2); return result; @@ -2107,8 +2107,8 @@ RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat) { Quaternion result = { 0 }; - result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w; - result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w; + result.x = mat.m0*q.x + mat.m4*q.y + mat.m8 *q.z + mat.m12*q.w; + result.y = mat.m1*q.x + mat.m5*q.y + mat.m9 *q.z + mat.m13*q.w; result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w; result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w; From 7b4d83ff0ec749730533ab07305f2344e6a5c54a Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 13 Aug 2023 03:26:55 +0100 Subject: [PATCH 07/89] removed a few useless parenthesis --- src/raymath.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index b35db2e05497..5d08862e71e2 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -281,7 +281,7 @@ RMAPI float Vector2Length(Vector2 v) // Calculate vector square length RMAPI float Vector2LengthSqr(Vector2 v) { - float result = (v.x*v.x) + (v.y*v.y); + float result = v.x*v.x + v.y*v.y; return result; } @@ -289,7 +289,7 @@ RMAPI float Vector2LengthSqr(Vector2 v) // Calculate two vectors dot product RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2) { - float result = (v1.x*v2.x + v1.y*v2.y); + float result = v1.x*v2.x + v1.y*v2.y; return result; } @@ -305,7 +305,7 @@ RMAPI float Vector2Distance(Vector2 v1, Vector2 v2) // Calculate square distance between two vectors RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) { - float result = ((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); + float result = (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y); return result; } From 35028b3d216ebe06c0e86ec821a33259a2dc8fd1 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 14 Aug 2023 21:10:24 +0200 Subject: [PATCH 08/89] Added fortran-raylib --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index 00672d9bf791..48cf0e64bfbc 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -24,6 +24,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | rayex | 3.7 | [elixir](https://elixir-lang.org/) | Apache-2.0 | https://github.com/shiryel/rayex | | raylib-factor | 4.0 | [Factor](https://factorcode.org/) | BSD | https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor | | raylib-freebasic | **4.5** | [FreeBASIC](https://www.freebasic.net/) | MIT | https://github.com/WIITD/raylib-freebasic | +| fortran-raylib | **4.5** | [Fortran](https://www.fortran.com/) | 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-guile | **auto** | [Guile](https://www.gnu.org/software/guile/) | Zlib | https://github.com/petelliott/raylib-guile | From 92bf6e8bad905913989aebf9ef253647dc0907d3 Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:55:13 -0300 Subject: [PATCH 09/89] Fix examples/others/rlgl_standalone.c compilation issue (#3242) --- examples/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/Makefile b/examples/Makefile index ff5098948c12..9d0b7341b0f8 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -261,6 +261,11 @@ ifeq ($(PLATFORM),PLATFORM_DRM) INCLUDE_PATHS += -I/usr/include/libdrm endif +# Include GLFW required for examples/others/rlgl_standalone.c +ifeq ($(USE_EXTERNAL_GLFW),FALSE) +all others: INCLUDE_PATHS += -I$(RAYLIB_PATH)/src/external/glfw/include +endif + # Define library paths containing required libs: LDFLAGS #------------------------------------------------------------------------------------------------ LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src From 45a099c0f0348a15ec789107a44fab7110bc8c23 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 15 Aug 2023 00:04:07 +0200 Subject: [PATCH 10/89] Update BINDINGS.md --- BINDINGS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BINDINGS.md b/BINDINGS.md index 48cf0e64bfbc..d4bd8fc21b98 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -24,7 +24,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | rayex | 3.7 | [elixir](https://elixir-lang.org/) | Apache-2.0 | https://github.com/shiryel/rayex | | raylib-factor | 4.0 | [Factor](https://factorcode.org/) | BSD | https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor | | raylib-freebasic | **4.5** | [FreeBASIC](https://www.freebasic.net/) | MIT | https://github.com/WIITD/raylib-freebasic | -| fortran-raylib | **4.5** | [Fortran](https://www.fortran.com/) | ISC | https://github.com/interkosmos/fortran-raylib | +| 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-guile | **auto** | [Guile](https://www.gnu.org/software/guile/) | Zlib | https://github.com/petelliott/raylib-guile | From 565790e6d48d0685258446113abf59dec9475890 Mon Sep 17 00:00:00 2001 From: ashn <60763262+ashn-dot-dev@users.noreply.github.com> Date: Mon, 14 Aug 2023 18:09:27 -0400 Subject: [PATCH 11/89] Ignore unused return value of GetCodepointNext in GetCodepointCount (#3241) * Ignore unused return value of GetCodepointNext in GetCodepointCount Removes the last warning from non-external libraries when compiling with the default build configuration on x64 Linux. * Remove unnecessary void cast in GetCodepointCount --- src/rtext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtext.c b/src/rtext.c index a66c58101b62..3fb2b8861b85 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1766,7 +1766,7 @@ int GetCodepointCount(const char *text) while (*ptr != '\0') { int next = 0; - int letter = GetCodepointNext(ptr, &next); + GetCodepointNext(ptr, &next); ptr += next; From 7e2c474c50d00c92cf69a7c6091ca6be6cd01adc Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Aug 2023 15:05:52 +0200 Subject: [PATCH 12/89] Fix #3246 --- src/rlgl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rlgl.h b/src/rlgl.h index 3756e5ac7493..9ca099acf9cb 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -2945,6 +2945,7 @@ bool rlCheckRenderBatchLimit(int vCount) unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) { unsigned int id = 0; + if (data == NULL) return id; glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding From 90afcda9dcfa6a5ba9db9051cf4a1ef4824d2bc1 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 19 Aug 2023 20:09:43 +0200 Subject: [PATCH 13/89] Revert "Fix #3246" This reverts commit e4dcbd518091a5854a517ea4cfc3f7e2d29de1a7. --- src/rlgl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rlgl.h b/src/rlgl.h index 9ca099acf9cb..3756e5ac7493 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -2945,7 +2945,6 @@ bool rlCheckRenderBatchLimit(int vCount) unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) { unsigned int id = 0; - if (data == NULL) return id; glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding From d3ebf8c09ba18525d76fbdce5ef7defb88fae3c6 Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Sat, 19 Aug 2023 08:43:00 -0300 Subject: [PATCH 14/89] Fix text_unicode.c example crashing (#3250) * Fix text_unicode.c example crashing * Adjust the text_unicode.c example crashing fix --- examples/text/text_unicode.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/text/text_unicode.c b/examples/text/text_unicode.c index eb2a7843c1f3..b25e3273bf68 100644 --- a/examples/text/text_unicode.c +++ b/examples/text/text_unicode.c @@ -187,12 +187,11 @@ int main(void) // Add a new set of emojis when SPACE is pressed if (IsKeyPressed(KEY_SPACE)) RandomizeEmoji(); - // Set the selected emoji and copy its text to clipboard + // Set the selected emoji if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (hovered != -1) && (hovered != selected)) { selected = hovered; selectedPos = hoveredPos; - SetClipboardText(messages[emoji[selected].message].text); } Vector2 mouse = GetMousePosition(); @@ -267,7 +266,7 @@ int main(void) a = b; b = tmp; } - + if (msgRect.x + msgRect.width > screenWidth) msgRect.x -= (msgRect.x + msgRect.width) - screenWidth + 10; // Draw chat bubble @@ -287,11 +286,11 @@ int main(void) DrawText(info, (int)pos.x, (int)pos.y, 10, RAYWHITE); } //------------------------------------------------------------------------------ - + // Draw the info text DrawText("These emojis have something to tell you, click each to find out!", (screenWidth - 650)/2, screenHeight - 40, 20, GRAY); DrawText("Each emoji is a unicode character from a font, not a texture... Press [SPACEBAR] to refresh", (screenWidth - 484)/2, screenHeight - 16, 10, GRAY); - + EndDrawing(); //---------------------------------------------------------------------------------- } @@ -342,7 +341,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop - float textOffsetY = 0; // Offset between lines (on line break '\n') + float textOffsetY = 0.0f; // Offset between lines (on line break '\n') float textOffsetX = 0.0f; // Offset X to next character to draw float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor @@ -465,4 +464,4 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, textOffsetX += glyphWidth; } -} \ No newline at end of file +} From 934cd6fa4d30e5491f79bbde51bfe5080a5df1f3 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 20 Aug 2023 21:36:36 +0200 Subject: [PATCH 15/89] tweaks --- src/rshapes.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/rshapes.c b/src/rshapes.c index ea45aefc4ace..f3061f8b3435 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -498,6 +498,13 @@ void DrawCircle(int centerX, int centerY, float radius, Color color) DrawCircleV((Vector2){ (float)centerX, (float)centerY }, radius, color); } +// Draw a color-filled circle (Vector version) +// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues +void DrawCircleV(Vector2 center, float radius, Color color) +{ + DrawCircleSector(center, radius, 0, 360, 36, color); +} + // Draw a piece of a circle void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color) { @@ -530,6 +537,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA rlSetTexture(texShapes.id); rlBegin(RL_QUADS); + // NOTE: Every QUAD actually represents two segments for (int i = 0; i < segments/2; i++) { @@ -539,7 +547,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA rlVertex2f(center.x, center.y); rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); - rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2))*radius); + rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2.0f))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2.0f))*radius); rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); @@ -547,11 +555,11 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); - angle += (stepLength*2); + angle += (stepLength*2.0f); } // NOTE: In case number of segments is odd, we add one last piece to the cake - if (segments%2) + if ((segments%2) == 1) { rlColor4ub(color.r, color.g, color.b, color.a); @@ -567,6 +575,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); rlVertex2f(center.x, center.y); } + rlEnd(); rlSetTexture(0); @@ -659,13 +668,6 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co rlEnd(); } -// Draw a color-filled circle (Vector version) -// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues -void DrawCircleV(Vector2 center, float radius, Color color) -{ - DrawCircleSector(center, radius, 0, 360, 36, color); -} - // Draw circle outline void DrawCircleLines(int centerX, int centerY, float radius, Color color) { From 62c20dfba60009a47043b2d402613036c56bd965 Mon Sep 17 00:00:00 2001 From: "actondev (Christos)" Date: Sun, 20 Aug 2023 21:27:39 +0200 Subject: [PATCH 16/89] add build.zig options for individual modules (#3254) --- src/build.zig | 58 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/build.zig b/src/build.zig index 9aab4812a536..27250f5ff060 100644 --- a/src/build.zig +++ b/src/build.zig @@ -6,7 +6,6 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built "-std=gnu99", "-D_GNU_SOURCE", "-DGL_SILENCE_DEPRECATION=199309L", - "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 }; const raylib = b.addStaticLibrary(.{ @@ -22,15 +21,38 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built } raylib.addCSourceFiles(&.{ - srcdir ++ "/raudio.c", srcdir ++ "/rcore.c", - srcdir ++ "/rmodels.c", - srcdir ++ "/rshapes.c", - srcdir ++ "/rtext.c", - srcdir ++ "/rtextures.c", srcdir ++ "/utils.c", }, raylib_flags); + if (options.raudio) { + raylib.addCSourceFiles(&.{ + srcdir ++ "/raudio.c", + }, raylib_flags); + } + if (options.rmodels) { + raylib.addCSourceFiles(&.{ + srcdir ++ "/rmodels.c", + }, &[_][]const u8{ + "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 + } ++ raylib_flags); + } + if (options.rshapes) { + raylib.addCSourceFiles(&.{ + srcdir ++ "/rshapes.c", + }, raylib_flags); + } + if (options.rtext) { + raylib.addCSourceFiles(&.{ + srcdir ++ "/rtext.c", + }, raylib_flags); + } + if (options.rtextures) { + raylib.addCSourceFiles(&.{ + srcdir ++ "/rtextures.c", + }, raylib_flags); + } + var gen_step = std.build.Step.WriteFile.create(b); raylib.step.dependOn(&gen_step.step); @@ -137,6 +159,11 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built } pub const Options = struct { + raudio: bool = true, + rmodels: bool = true, + rshapes: bool = true, + rtext: bool = true, + rtextures: bool = true, raygui: bool = false, platform_drm: bool = false, }; @@ -152,19 +179,24 @@ pub fn build(b: *std.Build) void { // set a preferred release mode, allowing the user to decide how to optimize. const optimize = b.standardOptimizeOption(.{}); - const raygui = b.option(bool, "raygui", "Compile with raygui support"); - const platform_drm = b.option(bool, "platform_drm", "Compile raylib in native mode (no X11)"); + const defaults = Options{}; + const options = Options{ + .platform_drm = b.option(bool, "platform_drm", "Compile raylib in native mode (no X11)") orelse defaults.platform_drm, + .raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio, + .rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels, + .rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext, + .rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures, + .rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes, + .raygui = b.option(bool, "raygui", "Compile with raygui support") orelse defaults.raygui, + }; - const lib = addRaylib(b, target, optimize, .{ - .raygui = raygui orelse false, - .platform_drm = platform_drm orelse false, - }); + const lib = addRaylib(b, target, optimize, options); lib.installHeader("src/raylib.h", "raylib.h"); lib.installHeader("src/raymath.h", "raymath.h"); lib.installHeader("src/rlgl.h", "rlgl.h"); - if (raygui orelse false) { + if (options.raygui) { lib.installHeader("../raygui/src/raygui.h", "raygui.h"); } From 952ebb501ab80444053c5930b57682add16970ab Mon Sep 17 00:00:00 2001 From: "actondev (Christos)" Date: Sun, 20 Aug 2023 23:53:20 +0200 Subject: [PATCH 17/89] Add `IsKeyPressedRepeat` (desktop only) (#3245) Since the key pressed are handle by comparing current vs previous state (ie frame), a special way is needed to handle key repeats. --- src/raylib.h | 1 + src/rcore.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index abc8371bcb1d..d932e3a34881 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1115,6 +1115,7 @@ RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize // 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 diff --git a/src/rcore.c b/src/rcore.c index 7d8811b05b33..52a58d6d6e28 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -438,6 +438,8 @@ typedef struct CoreData { 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 @@ -3755,6 +3757,13 @@ bool IsKeyPressed(int key) return pressed; } +// Check if a key has been pressed again (only PLATFORM_DESKTOP) +bool IsKeyPressedRepeat(int key) +{ + if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) return true; + else return true; +} + // Check if a key is being pressed (key held down) bool IsKeyDown(int key) { @@ -5170,6 +5179,8 @@ 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; #if !(defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) // Reset last gamepad button/axis registered state @@ -5179,7 +5190,11 @@ void PollInputEvents(void) #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) // Register previous keys states - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + 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; + } PollKeyboardEvents(); @@ -5586,7 +5601,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // to work properly with our implementation (IsKeyDown/IsKeyUp checks) if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; - else CORE.Input.Keyboard.currentKeyState[key] = 1; + else if(action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1; + else if(action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1; #if !defined(PLATFORM_WEB) // WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys @@ -6357,7 +6373,11 @@ static void ProcessKeyboard(void) bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call // Reset pressed keys array (it will be filled below) - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) + { + CORE.Input.Keyboard.currentKeyState[i] = 0; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } // Fill all read bytes (looking for keys) for (int i = 0; i < bufferByteCount; i++) From 7190face1b976fedfb03b289b1a141bacd8e9341 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 21 Aug 2023 00:34:35 +0200 Subject: [PATCH 18/89] Reviewed `IsKeyPressedRepeat()` #3248 --- src/rcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 52a58d6d6e28..1cae7f582ce1 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3761,7 +3761,7 @@ bool IsKeyPressed(int key) bool IsKeyPressedRepeat(int key) { if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) return true; - else return true; + else return false; } // Check if a key is being pressed (key held down) From acc4ecb48a24d1b2818bb9fc17649459330a7c6a Mon Sep 17 00:00:00 2001 From: vitopigno <103512727+VitusVeit@users.noreply.github.com> Date: Mon, 21 Aug 2023 00:36:00 +0200 Subject: [PATCH 19/89] Update rcore.c (#3255) --- src/rcore.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 1cae7f582ce1..10303fe945e6 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -4470,13 +4470,16 @@ static bool InitGraphicsDevice(int width, int height) #endif // 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 + // 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 !defined(PLATFORM_WEB) 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"); } +#endif int fbWidth = CORE.Window.screen.width; int fbHeight = CORE.Window.screen.height; From 87c9ed4109ed77374d181c2ab5e2ae050b4bbffa Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Sat, 26 Aug 2023 09:35:53 -0300 Subject: [PATCH 20/89] Match CMakeOptions.txt options default values (#3258) --- CMakeOptions.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index cc57a851f25c..5cb73bbdd353 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -38,13 +38,13 @@ cmake_dependent_option(SUPPORT_MODULE_RAUDIO "Include module: raudio" ON CUSTOMI 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_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" OFF CUSTOMIZE_BUILD OFF) +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) cmake_dependent_option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_WINMM_HIGHRES_TIMER "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions" OFF CUSTOMIZE_BUILD OFF) +cmake_dependent_option(SUPPORT_WINMM_HIGHRES_TIMER "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_CUSTOM_FRAME_CONTROL "Enabling this flag allows manual control of the frame processes, use at your own risk" OFF CUSTOMIZE_BUILD OFF) @@ -58,14 +58,14 @@ cmake_dependent_option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editin cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_PNM "Support loading PNM as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON CUSTOMIZE_BUILD ON) -cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_FILEFORMAT_PNM "Support loading PNM as textures" ${OFF} CUSTOMIZE_BUILD OFF) +cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ${OFF} CUSTOMIZE_BUILD OFF) +cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_QOI "Support loading QOI as textures" ${OFF} CUSTOMIZE_BUILD OFF) +cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_FILEFORMAT_QOI "Support loading QOI as textures" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF) From 97602089932fc72fdbe09193a524dfa4f1f64e90 Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Sat, 26 Aug 2023 09:40:30 -0300 Subject: [PATCH 21/89] Fix SetClipboardText for web (#3257) --- src/rcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 10303fe945e6..8413df2a00ac 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2150,7 +2150,7 @@ void SetClipboardText(const char *text) #if defined(PLATFORM_WEB) // Security check to (partially) avoid malicious code if (strchr(text, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided Clipboard could be potentially malicious, avoid [\'] character"); - else emscripten_run_script(TextFormat("navigator.clipboard.writeText('%s')", text)); + else EM_ASM( { navigator.clipboard.writeText(UTF8ToString($0)); }, text); #endif } From 81ec5f0a21e3c0d381bb22e5660538c2057f02a4 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Sat, 26 Aug 2023 05:43:14 -0700 Subject: [PATCH 22/89] [Image] Validate that ImageDrawRectangleRec is drawing entirely inside the image (#3264) * Add a function to clone a sound and share data with another sound. * rename items based on feedback * PR Feedback, use custom unload for sound alias, not variant of normal sound unloading * sound_multi example * Validate that image rect drawing is inside the image so we don't overflow a buffer * remove files that should not have been added. * remove changes that should not have been * revert * adsfasdfsdfsdf --- src/rtextures.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/rtextures.c b/src/rtextures.c index 4b697f777808..f32a45d1ef7d 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3284,6 +3284,20 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) if (rec.width < 0) rec.width = 0; if (rec.height < 0) rec.height = 0; + // clamp the size the the image bounds + if (rec.x + rec.width >= dst->width) + rec.width = dst->width - rec.x; + + if (rec.y + rec.height >= dst->height) + rec.height = dst->height - rec.y; + + // check if the rect is even inside the image + if (rec.x > dst->width || rec.y > dst->height) + return; + + if (rec.x + rec.width < 0 || rec.y + rec.height < 0) + return; + int sy = (int)rec.y; int sx = (int)rec.x; From 8744f45a1d7fedc6787a59d07a7ca9675fb85067 Mon Sep 17 00:00:00 2001 From: Ethan Simpson Date: Sun, 27 Aug 2023 00:44:52 +1200 Subject: [PATCH 23/89] Add Vector3 Projecting and Rejection to Raymath (#3263) * Update raymath.h * formatting --- src/raymath.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/raymath.h b/src/raymath.h index 5d08862e71e2..1d03d946170a 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -713,6 +713,32 @@ RMAPI Vector3 Vector3Normalize(Vector3 v) return result; } +//Calculate the projection of the vector v1 on to v2 +RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) +{ + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); + + float mag = v1dv2/v2dv2; + + Vector3 result = { v2.x*mag , v2.y*mag, v2.z*mag }; + + return result; +} + +//Calculate the rejection of the vector v1 on to v2 +RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) +{ + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); + + float mag = v1dv2/v2dv2; + + Vector3 result = { v1.x - (v2.x*mag) , v1.y - (v2.y*mag), v1.z - (v2.z*mag) }; + + return result; +} + // Orthonormalize provided vectors // Makes vectors normalized and orthogonal to each other // Gram-Schmidt function implementation From 22707987eba0c6d8b0994b88990553a54c10b944 Mon Sep 17 00:00:00 2001 From: Nickolas McDonald <43690021+n77y@users.noreply.github.com> Date: Sat, 26 Aug 2023 08:48:28 -0400 Subject: [PATCH 24/89] [Feature] IsKey... safety checks and more (#3256) * [Feature] Add GetKeyRepeat * Update rcore.c * Simpler design, only one repeat per frame * Update config.h * Update rcore.c * Add KEYBOARD_KEYS_MASK * Update config.h * reversions * Update rcore.c * Update rcore.c * change docs * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c * Update raylib.h * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c * Update rcore.c --- src/rcore.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 8413df2a00ac..cb3dfe82a819 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3750,6 +3750,7 @@ void OpenURL(const char *url) // Check if a key has been pressed once bool IsKeyPressed(int key) { + if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; bool pressed = false; if ((CORE.Input.Keyboard.previousKeyState[key] == 0) && (CORE.Input.Keyboard.currentKeyState[key] == 1)) pressed = true; @@ -3760,6 +3761,7 @@ bool IsKeyPressed(int key) // Check if a key has been pressed again (only PLATFORM_DESKTOP) bool IsKeyPressedRepeat(int key) { + if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) return true; else return false; } @@ -3767,6 +3769,7 @@ bool IsKeyPressedRepeat(int key) // Check if a key is being pressed (key held down) bool IsKeyDown(int key) { + if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; if (CORE.Input.Keyboard.currentKeyState[key] == 1) return true; else return false; } @@ -3774,6 +3777,7 @@ bool IsKeyDown(int key) // Check if a key has been released once bool IsKeyReleased(int key) { + if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; bool released = false; if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true; @@ -3784,6 +3788,7 @@ bool IsKeyReleased(int key) // Check if a key is NOT being pressed (key not held down) bool IsKeyUp(int key) { + if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; if (CORE.Input.Keyboard.currentKeyState[key] == 0) return true; else return false; } @@ -5226,7 +5231,11 @@ void PollInputEvents(void) // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) // Register previous keys states - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + 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]; @@ -5408,7 +5417,11 @@ void PollInputEvents(void) #if defined(PLATFORM_ANDROID) // Register previous keys states // NOTE: Android supports up to 260 keys - for (int i = 0; i < 260; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + for (int i = 0; i < 260; i++) + { + CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } // Android ALooper_pollAll() variables int pollResult = 0; @@ -6073,6 +6086,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; CORE.Input.Keyboard.keyPressedQueueCount++; } + else if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_MULTIPLE) CORE.Input.Keyboard.keyRepeatInFrame[keycode] = 1; else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up if (keycode == AKEYCODE_POWER) @@ -6496,7 +6510,11 @@ static void InitEvdevInput(void) } // Reset keyboard key state - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) + { + CORE.Input.Keyboard.currentKeyState[i] = 0; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } // Open the linux directory of "/dev/input" directory = opendir(DEFAULT_EVDEV_PATH); From 1814fd660d3cb1b3793d35a7cf76225a9625c9ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Ri=C4=8Dko?= Date: Sat, 26 Aug 2023 18:55:57 +0200 Subject: [PATCH 25/89] Fix bug where default shaders was not linking. (#3261) --- src/rlgl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rlgl.h b/src/rlgl.h index 3756e5ac7493..f274931e21b5 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -4550,6 +4550,7 @@ static void rlLoadShaderDefault(void) #endif #if defined(GRAPHICS_API_OPENGL_ES2) "#version 100 \n" + "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers) "attribute vec3 vertexPosition; \n" "attribute vec2 vertexTexCoord; \n" "attribute vec4 vertexColor; \n" From bfd9c4ef3cbe98d68dd268abfb6bd5f0aefc9ddf Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 27 Aug 2023 00:30:56 +0200 Subject: [PATCH 26/89] Formating review --- src/raymath.h | 13 +++++++++++-- src/rtextures.c | 18 ++++++------------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 1d03d946170a..4b377925f2c2 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -15,6 +15,7 @@ * - Functions use always a "result" variable for return * - Functions are always defined inline * - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) +* - No compound literals used to make sure libray is compatible with C++ * * CONFIGURATION: * #define RAYMATH_IMPLEMENTATION @@ -716,12 +717,16 @@ RMAPI Vector3 Vector3Normalize(Vector3 v) //Calculate the projection of the vector v1 on to v2 RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) { + Vector3 result = { 0 }; + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); float mag = v1dv2/v2dv2; - Vector3 result = { v2.x*mag , v2.y*mag, v2.z*mag }; + result.x = v2.x*mag; + result.y = v2.y*mag; + result.z = v2.z*mag; return result; } @@ -729,12 +734,16 @@ RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) //Calculate the rejection of the vector v1 on to v2 RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) { + Vector3 result = { 0 }; + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); float mag = v1dv2/v2dv2; - Vector3 result = { v1.x - (v2.x*mag) , v1.y - (v2.y*mag), v1.z - (v2.z*mag) }; + result.x = v1.x - (v2.x*mag); + result.y = v1.y - (v2.y*mag); + result.z = v1.z - (v2.z*mag); return result; } diff --git a/src/rtextures.c b/src/rtextures.c index f32a45d1ef7d..b88aeb1549b6 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3284,19 +3284,13 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) if (rec.width < 0) rec.width = 0; if (rec.height < 0) rec.height = 0; - // clamp the size the the image bounds - if (rec.x + rec.width >= dst->width) - rec.width = dst->width - rec.x; + // Clamp the size the the image bounds + if ((rec.x + rec.width) >= dst->width) rec.width = dst->width - rec.x; + if ((rec.y + rec.height) >= dst->height) rec.height = dst->height - rec.y; - if (rec.y + rec.height >= dst->height) - rec.height = dst->height - rec.y; - - // check if the rect is even inside the image - if (rec.x > dst->width || rec.y > dst->height) - return; - - if (rec.x + rec.width < 0 || rec.y + rec.height < 0) - return; + // Check if the rect is even inside the image + if ((rec.x > dst->width) || (rec.y > dst->height)) return; + if (((rec.x + rec.width) < 0) || (rec.y + rec.height < 0)) return; int sy = (int)rec.y; int sx = (int)rec.x; From 2931ba97b981cd65bd9f9703f8df49f9e186a7b8 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Sun, 27 Aug 2023 10:42:45 -0300 Subject: [PATCH 27/89] Add missing cmake options (#3267) --- CMakeOptions.txt | 4 ++++ cmake/CompileDefinitions.cmake | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 5cb73bbdd353..83faa5637814 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -46,6 +46,7 @@ cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing syn cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_WINMM_HIGHRES_TIMER "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_EVENTS_AUTOMATION "Support automatic generated events, loading and recording of those events when required" OFF CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_CUSTOM_FRAME_CONTROL "Enabling this flag allows manual control of the frame processes, use at your own risk" OFF CUSTOMIZE_BUILD OFF) # rshapes.c @@ -58,6 +59,7 @@ cmake_dependent_option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editin cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_FILEFORMAT_PIC "Support loading PIC as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PNM "Support loading PNM as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ${OFF} CUSTOMIZE_BUILD OFF) @@ -83,6 +85,7 @@ cmake_dependent_option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" cmake_dependent_option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_VOX "Support loading VOX file format" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_FILEFORMAT_M3D "Support loading M3D file format" ON CUSTOMIZE_BUILD ON) # raudio.c cmake_dependent_option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON CUSTOMIZE_BUILD ON) @@ -90,6 +93,7 @@ cmake_dependent_option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" O cmake_dependent_option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_FILEFORMAT_QOA "Support loading QOA for sound" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF} CUSTOMIZE_BUILD OFF) # utils.c diff --git a/cmake/CompileDefinitions.cmake b/cmake/CompileDefinitions.cmake index 689f98ac4176..1458e2f3ca27 100644 --- a/cmake/CompileDefinitions.cmake +++ b/cmake/CompileDefinitions.cmake @@ -28,6 +28,7 @@ if (${CUSTOMIZE_BUILD}) define_if("raylib" SUPPORT_EVENTS_WAITING) define_if("raylib" SUPPORT_WINMM_HIGHRES_TIMER) define_if("raylib" SUPPORT_COMPRESSION_API) + define_if("raylib" SUPPORT_EVENTS_AUTOMATION) define_if("raylib" SUPPORT_CUSTOM_FRAME_CONTROL) define_if("raylib" SUPPORT_QUADS_DRAW_MODE) define_if("raylib" SUPPORT_IMAGE_EXPORT) @@ -36,6 +37,7 @@ if (${CUSTOMIZE_BUILD}) define_if("raylib" SUPPORT_FILEFORMAT_PNG) define_if("raylib" SUPPORT_FILEFORMAT_DDS) define_if("raylib" SUPPORT_FILEFORMAT_HDR) + define_if("raylib" SUPPORT_FILEFORMAT_PIC) define_if("raylib" SUPPORT_FILEFORMAT_PNM) define_if("raylib" SUPPORT_FILEFORMAT_KTX) define_if("raylib" SUPPORT_FILEFORMAT_ASTC) @@ -56,11 +58,13 @@ if (${CUSTOMIZE_BUILD}) define_if("raylib" SUPPORT_FILEFORMAT_IQM) define_if("raylib" SUPPORT_FILEFORMAT_GLTF) define_if("raylib" SUPPORT_FILEFORMAT_VOX) + define_if("raylib" SUPPORT_FILEFORMAT_M3D) define_if("raylib" SUPPORT_FILEFORMAT_WAV) define_if("raylib" SUPPORT_FILEFORMAT_OGG) define_if("raylib" SUPPORT_FILEFORMAT_XM) define_if("raylib" SUPPORT_FILEFORMAT_MOD) define_if("raylib" SUPPORT_FILEFORMAT_MP3) + define_if("raylib" SUPPORT_FILEFORMAT_QOA) define_if("raylib" SUPPORT_FILEFORMAT_FLAC) define_if("raylib" SUPPORT_STANDARD_FILEIO) define_if("raylib" SUPPORT_TRACELOG) From fb0184a1353e6ff13ad5c1b373442910747e7a74 Mon Sep 17 00:00:00 2001 From: iacore <74560659+iacore@users.noreply.github.com> Date: Sun, 27 Aug 2023 13:43:39 +0000 Subject: [PATCH 28/89] Fix CMake extraneous -lglfw (#3266) Closes #3265. The problem: LIBS_PRIVATE is a list of library names (used by pkg-config), but the shared library of the same name doesn't always exist. --- cmake/InstallConfigurations.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/InstallConfigurations.cmake b/cmake/InstallConfigurations.cmake index 6a89ad55c97f..6c606e565d94 100644 --- a/cmake/InstallConfigurations.cmake +++ b/cmake/InstallConfigurations.cmake @@ -9,8 +9,7 @@ install( # PKG_CONFIG_LIBS_PRIVATE is used in raylib.pc.in if (NOT BUILD_SHARED_LIBS) include(LibraryPathToLinkerFlags) - library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}") - set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS}) + set(PKG_CONFIG_LIBS_PRIVATE ${GLFW_PKG_LIBS}) string(REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}") elseif (BUILD_SHARED_LIBS) set(PKG_CONFIG_LIBS_EXTRA "") From 7ed0fdb6e9dad32c226616fdb4ee0389fc10b754 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Sun, 27 Aug 2023 16:14:20 -0300 Subject: [PATCH 29/89] Fix example/models/models_loading_gltf.c controls (#3268) --- examples/models/models_loading_gltf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/models/models_loading_gltf.c b/examples/models/models_loading_gltf.c index d5ebff237231..28847316af20 100644 --- a/examples/models/models_loading_gltf.c +++ b/examples/models/models_loading_gltf.c @@ -4,9 +4,9 @@ * * LIMITATIONS: * - Only supports 1 armature per file, and skips loading it if there are multiple armatures -* - Only supports linear interpolation (default method in Blender when checked +* - Only supports linear interpolation (default method in Blender when checked * "Always Sample Animations" when exporting a GLTF file) -* - Only supports translation/rotation/scale animation channel.path, +* - Only supports translation/rotation/scale animation channel.path, * weights not considered (i.e. morph targets) * * Example originally created with raylib 3.7, last time updated with raylib 4.2 @@ -42,7 +42,7 @@ int main(void) // Load gltf model Model model = LoadModel("resources/models/gltf/robot.glb"); - + // Load gltf model animations unsigned int animsCount = 0; unsigned int animIndex = 0; @@ -63,9 +63,9 @@ int main(void) //---------------------------------------------------------------------------------- UpdateCamera(&camera, CAMERA_THIRD_PERSON); // Select current animation - if (IsKeyPressed(KEY_UP)) animIndex = (animIndex + 1)%animsCount; - else if (IsKeyPressed(KEY_DOWN)) animIndex = (animIndex + animsCount - 1)%animsCount; - + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount; + else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount; + // Update model animation ModelAnimation anim = modelAnimations[animIndex]; animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount; @@ -85,7 +85,7 @@ int main(void) EndMode3D(); - DrawText("Use the UP/DOWN arrow keys to switch animation", 10, 10, 20, GRAY); + DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY); DrawText(TextFormat("Animation: %s", anim.name), 10, GetScreenHeight() - 20, 10, DARKGRAY); EndDrawing(); From 10408524f095d689e1b077c4cdc19f85f20c1eae Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Sun, 27 Aug 2023 16:15:02 -0300 Subject: [PATCH 30/89] Fix example/models/models_loading_m3d.c controls (#3269) --- examples/models/models_loading_m3d.c | 35 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/models/models_loading_m3d.c b/examples/models/models_loading_m3d.c index b9674b6f626d..1e56d51ca595 100644 --- a/examples/models/models_loading_m3d.c +++ b/examples/models/models_loading_m3d.c @@ -40,7 +40,7 @@ int main(void) camera.projection = CAMERA_PERSPECTIVE; // Camera projection type Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - + char modelFileName[128] = "resources/models/m3d/cesium_man.m3d"; bool drawMesh = 1; bool drawSkeleton = 1; @@ -72,27 +72,27 @@ int main(void) if (IsKeyDown(KEY_SPACE) || IsKeyPressed(KEY_N)) { animFrameCounter++; - + if (animFrameCounter >= anims[animId].frameCount) animFrameCounter = 0; - + UpdateModelAnimation(model, anims[animId], animFrameCounter); animPlaying = true; } - - // Select animation by pressing A - if (IsKeyPressed(KEY_A)) + + // Select animation by pressing C + if (IsKeyPressed(KEY_C)) { animFrameCounter = 0; animId++; - + if (animId >= animsCount) animId = 0; UpdateModelAnimation(model, anims[animId], 0); animPlaying = true; } } - + // Toggle skeleton drawing - if (IsKeyPressed(KEY_S)) drawSkeleton ^= 1; + if (IsKeyPressed(KEY_B)) drawSkeleton ^= 1; // Toggle mesh drawing if (IsKeyPressed(KEY_M)) drawMesh ^= 1; @@ -112,19 +112,19 @@ int main(void) // Draw the animated skeleton if (drawSkeleton) { - // Loop to (boneCount - 1) because the last one is a special "no bone" bone, + // Loop to (boneCount - 1) because the last one is a special "no bone" bone, // needed to workaround buggy models // without a -1, we would always draw a cube at the origin for (int i = 0; i < model.boneCount - 1; i++) { - // By default the model is loaded in bind-pose by LoadModel(). - // But if UpdateModelAnimation() has been called at least once + // By default the model is loaded in bind-pose by LoadModel(). + // But if UpdateModelAnimation() has been called at least once // then the model is already in animation pose, so we need the animated skeleton if (!animPlaying || !animsCount) { // Display the bind-pose skeleton DrawCube(model.bindPose[i].translation, 0.04f, 0.04f, 0.04f, RED); - + if (model.bones[i].parent >= 0) { DrawLine3D(model.bindPose[i].translation, @@ -135,7 +135,7 @@ int main(void) { // Display the frame-pose skeleton DrawCube(anims[animId].framePoses[animFrameCounter][i].translation, 0.05f, 0.05f, 0.05f, RED); - + if (anims[animId].bones[i].parent >= 0) { DrawLine3D(anims[animId].framePoses[animFrameCounter][i].translation, @@ -149,9 +149,10 @@ int main(void) EndMode3D(); - DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, GetScreenHeight() - 60, 10, MAROON); - DrawText("PRESS A to CYCLE THROUGH ANIMATIONS", 10, GetScreenHeight() - 40, 10, DARKGRAY); - DrawText("PRESS M to toggle MESH, S to toggle SKELETON DRAWING", 10, GetScreenHeight() - 20, 10, DARKGRAY); + DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, GetScreenHeight() - 80, 10, MAROON); + DrawText("PRESS N to STEP ONE ANIMATION FRAME", 10, GetScreenHeight() - 60, 10, DARKGRAY); + DrawText("PRESS C to CYCLE THROUGH ANIMATIONS", 10, GetScreenHeight() - 40, 10, DARKGRAY); + DrawText("PRESS M to toggle MESH, B to toggle SKELETON DRAWING", 10, GetScreenHeight() - 20, 10, DARKGRAY); DrawText("(c) CesiumMan model by KhronosGroup", GetScreenWidth() - 210, GetScreenHeight() - 20, 10, GRAY); EndDrawing(); From c0038158f53c47cba8e699e7c5c57c25c8dae509 Mon Sep 17 00:00:00 2001 From: Ethan Conneely Date: Mon, 28 Aug 2023 21:49:45 +0100 Subject: [PATCH 31/89] Remove e from secondes (#3270) --- examples/shaders/resources/shaders/glsl100/wave.fs | 6 +++--- examples/shaders/resources/shaders/glsl330/wave.fs | 6 +++--- examples/shaders/shaders_texture_waves.c | 2 +- src/rcore.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/shaders/resources/shaders/glsl100/wave.fs b/examples/shaders/resources/shaders/glsl100/wave.fs index 50c4e02f3018..cd4ba9de43d3 100644 --- a/examples/shaders/resources/shaders/glsl100/wave.fs +++ b/examples/shaders/resources/shaders/glsl100/wave.fs @@ -10,7 +10,7 @@ varying vec4 fragColor; uniform sampler2D texture0; uniform vec4 colDiffuse; -uniform float secondes; +uniform float seconds; uniform vec2 size; @@ -29,8 +29,8 @@ void main() { float boxTop = 0.0; vec2 p = fragTexCoord; - p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; - p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; + p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (seconds * speedX)) * ampX * pixelWidth; + p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (seconds * speedY)) * ampY * pixelHeight; gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor; } diff --git a/examples/shaders/resources/shaders/glsl330/wave.fs b/examples/shaders/resources/shaders/glsl330/wave.fs index 43efee2347d1..1f22bee09f51 100644 --- a/examples/shaders/resources/shaders/glsl330/wave.fs +++ b/examples/shaders/resources/shaders/glsl330/wave.fs @@ -11,7 +11,7 @@ uniform vec4 colDiffuse; // Output fragment color out vec4 finalColor; -uniform float secondes; +uniform float seconds; uniform vec2 size; @@ -30,8 +30,8 @@ void main() { float boxTop = 0.0; vec2 p = fragTexCoord; - p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; - p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; + p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (seconds * speedX)) * ampX * pixelWidth; + p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (seconds * speedY)) * ampY * pixelHeight; finalColor = texture(texture0, p)*colDiffuse*fragColor; } diff --git a/examples/shaders/shaders_texture_waves.c b/examples/shaders/shaders_texture_waves.c index a087ec4d0e87..27ad1f6e4722 100644 --- a/examples/shaders/shaders_texture_waves.c +++ b/examples/shaders/shaders_texture_waves.c @@ -46,7 +46,7 @@ int main(void) // Load shader and setup location points and values Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/wave.fs", GLSL_VERSION)); - int secondsLoc = GetShaderLocation(shader, "secondes"); + int secondsLoc = GetShaderLocation(shader, "seconds"); int freqXLoc = GetShaderLocation(shader, "freqX"); int freqYLoc = GetShaderLocation(shader, "freqY"); int ampXLoc = GetShaderLocation(shader, "ampX"); diff --git a/src/rcore.c b/src/rcore.c index cb3dfe82a819..6e5d94964c84 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2999,7 +2999,7 @@ int GetFPS(void) #if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) #define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures - #define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes + #define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 milliseconds #define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT) static int index = 0; From 7fd3a02e8828310f5f165ac94302ff60c6e7ba7e Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Tue, 29 Aug 2023 14:04:27 -0300 Subject: [PATCH 32/89] Fix example/audio/audio_module_player.c help instructions and small bug (#3272) * Fix example/audio/audio_module_player.c help instructions and small bug * Update example/audio/audio_module_player.png screenshot --- examples/audio/audio_module_playing.c | 11 ++++++++++- examples/audio/audio_module_playing.png | Bin 47970 -> 45137 bytes 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/audio/audio_module_playing.c b/examples/audio/audio_module_playing.c index b8482aa572d3..bf5530fdcbc9 100644 --- a/examples/audio/audio_module_playing.c +++ b/examples/audio/audio_module_playing.c @@ -79,6 +79,7 @@ int main(void) { StopMusicStream(music); PlayMusicStream(music); + pause = false; } // Pause/Resume music playing @@ -134,6 +135,14 @@ int main(void) DrawRectangle(20, screenHeight - 20 - 12, (int)timePlayed, 12, MAROON); DrawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, GRAY); + // Draw help instructions + DrawRectangle(20, 20, 425, 145, WHITE); + DrawRectangleLines(20, 20, 425, 145, GRAY); + DrawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, BLACK); + DrawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, BLACK); + DrawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, BLACK); + DrawText(TextFormat("SPEED: %f", pitch), 40, 130, 20, MAROON); + EndDrawing(); //---------------------------------------------------------------------------------- } @@ -148,4 +157,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/examples/audio/audio_module_playing.png b/examples/audio/audio_module_playing.png index 8bde9879d4aa7c8f57c9bb334888b0fd52c1102e..63003e0472eccf6c7861ffee50dad0215c88cab0 100644 GIT binary patch literal 45137 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 Date: Tue, 29 Aug 2023 19:25:44 +0200 Subject: [PATCH 33/89] Use type name instead of valid specifier long long --> long long int --- src/rcore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 6e5d94964c84..210100fbfc8d 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -506,7 +506,7 @@ typedef struct CoreData { double frame; // Time measure for one frame double target; // Desired time for one frame, if 0 not applied #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) - unsigned long long base; // Base time measure for hi-res timer + unsigned long long int base; // Base time measure for hi-res timer #endif unsigned int frameCounter; // Frame counter } Time; @@ -3495,10 +3495,10 @@ bool ChangeDirectory(const char *dir) // Check if a given path point to a file bool IsPathFile(const char *path) { - struct stat pathStat = { 0 }; - stat(path, &pathStat); + struct stat result = { 0 }; + stat(path, &result); - return S_ISREG(pathStat.st_mode); + return S_ISREG(result.st_mode); } // Check if a file has been dropped into window From c197cac34c87ead5ef7243b58d86c124e122d1c9 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 29 Aug 2023 19:26:15 +0200 Subject: [PATCH 34/89] REVIEWED: `GetFileLength()`, added comment #3262 --- src/rcore.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 210100fbfc8d..2c53eb5e660d 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3192,13 +3192,24 @@ bool DirectoryExists(const char *dirPath) int GetFileLength(const char *fileName) { int size = 0; + + // NOTE: On Unix-like systems, it can by used the POSIX system call: stat(), + // but depending on the platform that call could not be available + //struct stat result = { 0 }; + //stat(fileName, &result); + //return result.st_size; FILE *file = fopen(fileName, "rb"); if (file != NULL) { fseek(file, 0L, SEEK_END); - size = (int)ftell(file); + long int fileSize = ftell(file); + + // Check for size overflow (INT_MAX) + if (fileSize > 2147483647) TRACELOG(LOG_WARNING, "[%s] File size overflows expected limit, do not use GetFileLength()", fileName); + else size = (int)fileSize; + fclose(file); } From 5c51b0b10946925af4a32029c7777ec82b5bcb91 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Tue, 29 Aug 2023 14:28:03 -0300 Subject: [PATCH 35/89] Update examples/models/models_loading_gltf.png;m3d.png screenshots (#3273) --- examples/models/models_loading_gltf.png | Bin 25896 -> 26632 bytes examples/models/models_loading_m3d.png | Bin 23682 -> 25881 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/models/models_loading_gltf.png b/examples/models/models_loading_gltf.png index 34748a22e587a86dc297238c939fbbe148fb5153..ce2a85284077b0cce9fbfb8b63f326ca48013be8 100644 GIT binary patch literal 26632 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 literal 25896 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 diff --git a/examples/models/models_loading_m3d.png b/examples/models/models_loading_m3d.png index 2214b8e0152194319b3cb88f763d85df9019e5a0..9220419ad1c9124b887dc019f0ecdf776eac1f31 100644 GIT binary patch literal 25881 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 l%o%Vu0{0rQ56G!+dTcYHd8`V{|m|TrIG*u literal 23682 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 Date: Wed, 30 Aug 2023 17:39:44 -0300 Subject: [PATCH 36/89] Remove a duplicated screenshot and add missing one (#3275) --- examples/audio/audio_sound_multi.png | Bin 0 -> 15106 bytes .../core/core_2d_camera_smooth_pixelperfect.png | Bin 15832 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/audio/audio_sound_multi.png delete mode 100644 examples/core/core_2d_camera_smooth_pixelperfect.png diff --git a/examples/audio/audio_sound_multi.png b/examples/audio/audio_sound_multi.png new file mode 100644 index 0000000000000000000000000000000000000000..d60138d0782e24f41049582c0554db33e293f090 GIT binary patch literal 15106 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ1{4ubUVDOp!Rn-^i(^PdT=Jh^Utia^ z1sX^(Emp)qlyEREyBHwH+jvnx0xQ8-)p{U5u-U`G)Ii)2=qSoXt^+2 zE{v87qvgVAxqxl_bF_3EPxC0)NIeA)ku!@kEtZ{d@rpT~vFZd#-q)a! zYQ{T?4zDz3u3Pu6gTt@raO#fN$|64v{$IA98zA-W$gb(vzVU?oIQVF4$nT3+FI&sG zc~zQ3e7>7;*9v5IgEfm=x`SKracs#3B*t*pDWQZd#RNF!%^;}gkfBnzWSzQNdCSy0 zA7pZVwM9K!7;Yt(`Lp%P%!wC2rEIw+2_C(Fsc2xuY&47A%{jq@1sm}~jA^m4!s5aXUP5#}vo)pV-6gl*`xitbF=B z!wzDF4a5p5cOtCl;9xBJUNOOHlV3)Qz}=NsjOO2Qad^jJyz`;w`@Lo@Z^44ZJZ%?sRwkf&NpSg$yRV(}|4*>`?2uV? zXliTwD<9@vyAvNW3#*$LJLK71&N`OAWfH`@yo_H2z@`f0o5$#I zUJ<2fEM+fecP-XpJ+OI@bk*lXCVI;Ycj`ja%( zsNa+0Ue1sE==x@!K+@ypYd@Kv^&J#CKjoZ6Z`drbC#JL?c)@cbLknm<_9>SI(HsVK ze}8@bpHb0|T(_YnRt8&05}k{4TIPZ-i<>nhwP8z)5YOF$L>Z0=Do}Pb!6m0?@CV|A zP@K*jbpj{?M?+yW6ktuX(X=p{7Dm$oa#c2(BSv$?XpR`o5uncMXef+^0$MTvb4Tll z(K-TFIEYM(c>tI%2erK$M9H)@bQCS~`xF qj-#dHXz7S36A`S@(h*uZGRzZIR1w_UTm{_Q%HZkh=d#Wzp$P!(&(8<| literal 0 HcmV?d00001 diff --git a/examples/core/core_2d_camera_smooth_pixelperfect.png b/examples/core/core_2d_camera_smooth_pixelperfect.png deleted file mode 100644 index ba8d89b7c1e7d68f069a4c25488a2e0a8a698d22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15832 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 Date: Wed, 30 Aug 2023 17:40:24 -0300 Subject: [PATCH 37/89] Add examples/shaders/shaders_lightmap.c to Makefiles (#3276) --- examples/Makefile | 1 + examples/Makefile.Web | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/Makefile b/examples/Makefile index 9d0b7341b0f8..7028a95424f6 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -529,6 +529,7 @@ SHADERS = \ shaders/shaders_simple_mask \ shaders/shaders_spotlight \ shaders/shaders_hot_reloading \ + shaders/shaders_lightmap \ shaders/shaders_mesh_instancing \ shaders/shaders_multi_sample2d \ shaders/shaders_write_depth \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index e65351e07dea..4574e928ec62 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -504,6 +504,7 @@ SHADERS = \ shaders/shaders_simple_mask \ shaders/shaders_spotlight \ shaders/shaders_hot_reloading \ + shaders/shaders_lightmap \ shaders/shaders_mesh_instancing \ shaders/shaders_multi_sample2d \ shaders/shaders_write_depth \ From 3b84ec7d93e415bc63e6ad60bda0e155510c83d3 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Wed, 30 Aug 2023 17:40:49 -0300 Subject: [PATCH 38/89] Fix examples/others/easings_testbed.c help instructions and small tweak (#3277) --- examples/others/easings_testbed.c | 22 +++++++++++----------- examples/others/easings_testbed.png | Bin 17338 -> 17443 bytes 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/others/easings_testbed.c b/examples/others/easings_testbed.c index 227efd231ef0..45f0efd0b556 100644 --- a/examples/others/easings_testbed.c +++ b/examples/others/easings_testbed.c @@ -108,7 +108,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [easings] example - easings testbed"); - Vector2 ballPosition = { 100.0f, 200.0f }; + Vector2 ballPosition = { 100.0f, 100.0f }; float t = 0.0f; // Current time (in any unit measure, but same unit as duration) float d = 300.0f; // Total time it should take to complete (duration) @@ -180,8 +180,8 @@ int main(void) // Movement computation if (!paused && ((boundedT && t < d) || !boundedT)) { - ballPosition.x = Easings[easingX].func(t, 100.0f, 700.0f - 100.0f, d); - ballPosition.y = Easings[easingY].func(t, 100.0f, 400.0f - 100.0f, d); + ballPosition.x = Easings[easingX].func(t, 100.0f, 700.0f - 170.0f, d); + ballPosition.y = Easings[easingY].func(t, 100.0f, 400.0f - 170.0f, d); t += 1.0f; } //---------------------------------------------------------------------------------- @@ -193,15 +193,15 @@ int main(void) ClearBackground(RAYWHITE); // Draw information text - DrawText(TextFormat("Easing x: %s", Easings[easingX].name), 0, FONT_SIZE*2, FONT_SIZE, LIGHTGRAY); - DrawText(TextFormat("Easing y: %s", Easings[easingY].name), 0, FONT_SIZE*3, FONT_SIZE, LIGHTGRAY); - DrawText(TextFormat("t (%c) = %.2f d = %.2f", (boundedT == true)? 'b' : 'u', t, d), 0, FONT_SIZE*4, FONT_SIZE, LIGHTGRAY); + DrawText(TextFormat("Easing x: %s", Easings[easingX].name), 20, FONT_SIZE, FONT_SIZE, LIGHTGRAY); + DrawText(TextFormat("Easing y: %s", Easings[easingY].name), 20, FONT_SIZE*2, FONT_SIZE, LIGHTGRAY); + DrawText(TextFormat("t (%c) = %.2f d = %.2f", (boundedT == true)? 'b' : 'u', t, d), 20, FONT_SIZE*3, FONT_SIZE, LIGHTGRAY); // Draw instructions text - DrawText("Use ENTER to play or pause movement, use SPACE to restart", 0, GetScreenHeight() - FONT_SIZE*2, FONT_SIZE, LIGHTGRAY); - DrawText("Use D and W or A and S keys to change duration", 0, GetScreenHeight() - FONT_SIZE*3, FONT_SIZE, LIGHTGRAY); - DrawText("Use LEFT or RIGHT keys to choose easing for the x axis", 0, GetScreenHeight() - FONT_SIZE*4, FONT_SIZE, LIGHTGRAY); - DrawText("Use UP or DOWN keys to choose easing for the y axis", 0, GetScreenHeight() - FONT_SIZE*5, FONT_SIZE, LIGHTGRAY); + DrawText("Use ENTER to play or pause movement, use SPACE to restart", 20, GetScreenHeight() - FONT_SIZE*2, FONT_SIZE, LIGHTGRAY); + DrawText("Use Q and W or A and S keys to change duration", 20, GetScreenHeight() - FONT_SIZE*3, FONT_SIZE, LIGHTGRAY); + DrawText("Use LEFT or RIGHT keys to choose easing for the x axis", 20, GetScreenHeight() - FONT_SIZE*4, FONT_SIZE, LIGHTGRAY); + DrawText("Use UP or DOWN keys to choose easing for the y axis", 20, GetScreenHeight() - FONT_SIZE*5, FONT_SIZE, LIGHTGRAY); // Draw ball DrawCircleV(ballPosition, 16.0f, MAROON); @@ -226,4 +226,4 @@ static float NoEase(float t, float b, float c, float d) d += burn; return b; -} \ No newline at end of file +} diff --git a/examples/others/easings_testbed.png b/examples/others/easings_testbed.png index fb0538531057f5e78e25186ba6023d4956f1db0c..05f63acdda92d4497df752a7768e01c7fbcb781e 100644 GIT binary patch literal 17443 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 TZV3GO2gKT9xA`qoeCWRc4{Unk literal 17338 zcmeHPdpMM7{~z=+GJ~RW$Y52rM9N5EkkcqRtf+R@G8D$4lE$G?n8iqq(-vw%D&0HUG@TGc(Wqy}yUg_i%rn zNpyC^B3G-dhQVOS{dU$aFqnh}3?}w7ToSml;TWR<2D2jXx8CO(;c;w!c4{n|@{PWV zI9*e~3lT0>z;Z?*$t-y#$QLnEd^JJpIGT|}sV2aw5HI@FFbi9S8t6BHFO8lna!hiZ4T{KpA)6%2V=FIt{Dmaav^t+^>AKrC{Q!k&{p-Z(1{(COB=jmk1)XTbf;9DwC3eyDptS*LXn4K&@$4UL zMiJsKuz4*^L^;!fgZM}BLQW>8uIkdOkErG*Xc=QRf~p?zg3vOkd7i2*iyi7XNR9B; z2E4sY9Y;)aT5&sZ@m6ab!Zl*JeMEAe_1GNB0*|fmM9Jgmcu3vx^x3An>VnxnWZrzm zO$+v(mPD{o;sGx&1=>nvCxuG9rr=FP5eHx)`_y-(JomciitCJ86fpkPZcG^@1FDFZM2B_fo#+g(01KM$l7%EC$Fm8$fjyhX_%pzV~zt zwV)Kr@p;$8W)rH15e`@nT&uXWdTU{?COU+b+IJrltRCII-I|8LUu+r)N&fQYa%fU+{ z*WBi8FhOCPCRW(Ng6|0EokAQzV@`2Hgt@d;%5@ zr?vn=mb}8aOGUg`RXpt1>6n~WQ|B>s5o=Dy_RKRVfFZyUpZNQGCUk!a+Kw?m_z)@N zwyn-rZmuidy#GYua z#hWw-l>G7=;pN^Hpc9MXi#QCi?y`t6AI7@wFBbc&78lC&KeLoLV`Bnr7kfuEyJ zuh7P4M75X#T7U|H83@Qy?tF9X7G@5*S}Ln<_lg}Y`*n|)vV+9(KPx^}y9397M9aR!5|6-AP9JfB?<;nFo=TT z|4A_5m62m)Y4T-b$4%b`MfvYoahgxf*DufpQ_&%emti#hbYPIFkvP^bUZZ`X-3=(=q)XX=Pm^RCcEv zfP=>lD?6N}f{9mKGbJozb5IwQ6ItJ;vRoirim&6q^q-XsHGx~2A_=cRmUb25EH~&< z#PT^x-&_x66FkuP1I3t%u-@f=T@M1S*?$(Hs6cE|XHN3Ph=l(%;U@HU#Ju^1U6#P= z6&TL_Ew%1*ma7BQI&_4d{|l5_oq-`8pjKmOIsRQ{6BOCp8)-^epOkcW3U()g(jo4! z5;e@sR^~cX!I-Nk&dV)aW9VQ4CxXCXTHBr?|Gic_jpugaT%Z(yC|jBvvIul1_zm{y zTNiEUYAGy5$RKs)ja%Z9cVd&0YYBfIW0ojGjV~I(BGIB0I~vqLs6WQcf&7##FSL{$ z>Y>6HyvA!8HXjvIZ}YwVe_Ha3MBo9eNDCq@EFWNrd_m+3B47Bwd0i9{qKFVhgeW4u zJdYRQf(RExxFEs>5iUTTT#C?9gpML~{4b+p%+SP86W()VboBLSlkX|iJebK~2Q zP&6ia_kG|Tcn}~Lti8)}{gRsX@3|z8ny6gtMWxk;`g9v9g42?Ej_;rARR5p zD+L)miu3hOXgtUz^k@TIh=FkQ5HPB2Sfc6+yRSy1WE>kKHOTo!X`80MyWzca6uceT~t`yVtu39dd9- zwt~qmtJ{%wQ@`7J&RsNnZFA?n2KqI2jJW?q^qN3a*(aN^c}K>4tWLBX@vP0=MPj09 zy8M%Kx6oNE0jk(VKZ^_B53HVC!|+AfAxl|l={4z1!AV!s#tyh^g#aww(5g*_+0+a&Q<_ZH zyMMvKZ?K>~_hyS-^TS%*Y(&QF8jSn%&<*)RvxLgMI0e8g?}3RgK$&3+dx8Qmi*K|>?ap_PljTEQY8`Is)Hg22o zFPY2k=E7x8aYLqer5Qa>$+%881h_wlMgCrggzXjJ9~TFjN;Rnr)s*{&<@8!{Xx|3Z zYv=b{Fs{iTb^MCC{u(=2t23H;K(6A&Gs8(M#@hH-T${U}@+cb^1LU3swSW<-^JApz zS)-#(-yZPOAI|Et)7@a#d}_FVU(rTNrC-iKI1>pD+%4w#0{I9Nh))JYzT=JW#YW?* zeZK12lR}vWw)3aFhM_w3jp}Rxh4mh#8x4l}-=S#5_@M8C+zTFwx9mB+*ay8zNy&Dy z<`2hz&_5W^?7=rBBl%1d7SzE3C=I|g8Ab`?Eb$)20T|yx=rjP^alN-wtx`~-Z)#-Y z>QYU64o2}xpXW~3lj2)KlXm6?=N^t2TYJ{Z{K;$oitOD6uJcBu(bhlixnTzq9)DE6 zJvEI#HIP(L&pP}OAV{0>V+@LPwoLxQ*Jb@+!$C+C&juH(pVZQ+YuQunf-W`c|1m(X za<6Y*T?gSBV4c{#s~U7O{fD$I4IalfKcN?22YgNCDSc}IK(bZmQ^JCH$yGqvVeuCN zAoRlQz7I4vp0IF#mBM|mt~avkye;)r#OAOq39gfgx`}PgHsNw*lukTI$1Qn1D9#eZuG2ZAF{~IuA6nrZ0Hzjo0P~Op?3B=F+%)vn!IpB z<}RP&bxgh92q9X^J|~VNm-ucqkgfr%`%Co{;hmfPk|)XHyBw(HGSg zDbANoe%NU|LB=@TN|344!qpW-aMQLE&sQB!X15#Huc1}$dzjrhbG)QwIEncnI;Y9W zyFDiEUP5rQb*jqA!KzCxbJ(V4R_6=>?z}{j>ky`>x61OpVmJj; z+HT2kxN~4!V8t_oVgnl{?X>D$18Xf^PXO^RvxyY@Px$No^uwfEJkS}*>RG^MYZelJ zxdB2?$hf+$5%xO|-~?@n5$h%_$U)TECe=j4yL262JI2Y~HDNPuSj9eYw&Z=S;p@m-ZhFSkN|HAh_wtPEVZ4nRsXSQ>OFT zef}6*#(eyp8})8Z&N_<5)9pg+3kR-kFDaxO%$%xwDJGo1xkIu+i z-orJ%n@oTPhw>G`P2K}m?W%AIWbCbS+OM{c{wwY@?*2@E`3z87Wnk!mkDfPOwlbXe znvw512rr&V?hejzGp_Z~yLU}JAibKoEgR2K4H{A``(%H6k#Zn{+QLmLpWv@W0+aX~ zft*+#wSS=NzULxXQ-J9MVGaL-=B1pJRHG(N|FD~8`C0U@rNQ9h8VJ!8j{&r_`5ZSm zqU(uOE#?^&U~6CdtW}F9eqrD#1Qf|Ej4+-oueIkrOhGK>?5&s1KXNi@Y5D&s*IO$?oH9)SE&u z&UE9SJJDxI%-zZd`75G6>*EW1E=9b{DMxLiH9G_{+%jgf!Ud4>H1!KJa3zL$~Se{A@}1=K>`F9x|+ z>~$v_9HQB@=PJWor@%SsAvxj<>wN{nadt2xoO{v9a^|x0LgC>VQ+9h-aNy;(J2&Iw zRY|j`pee+Y#vK6(5|vY1HN&apHCU?{6knK@&#Qm&7a)w{J2B1BP4R7Tbg`K>T0Ex7 zjGK0Vlmt&3^YF$R+ab-pKRJv?(AlPzoC3Fq+=Ly#!*yZCTAfj(_zlGibhj!?b+7t# zRM83ZvUVxPEAzII^mf{boQ@4;wl@-yQl#`_`qQc3nXj3UEB#=52Y`t81)&QXin4KtjE(7wj!Y7}=37WWKR$+79e?wFSC zd~EkFttQuF3rpv*WR&#~7TSAd4>q5v)KS(&-Z}_TFf=i6i zdAf#{xG8+_dNt+K^L z!|0MLQh6CS@~Tt;c&QwTZC6GFWEKuDRQs6SJ7>q3NH`iUfALg6Jkax=!4(ExovE8W zQ^Yo4%NlX#opdL+GP(#uvfvK`pb?;I28AIh{|Q5&V*w%|9u^dr)Sl)U@F={bN+#1h zffk89)BPT}3vmza!RI(@;NuSQZ{Uu!rarqfIHjNwaEsNN`rW>}u!ovIr_{EkXCQ?# zo_hZiuJE3>6-?n5O&vv3$K}rOzu*hNPjEyg9OJxM^)v9B9I*X1j@I`q@jv_vB8v5! From f26cb1ff71990bbea075d8aa8323cff991daff9b Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Wed, 30 Aug 2023 17:42:01 -0300 Subject: [PATCH 39/89] Fix examples/shaders/shaders_texture_outline.c help instructions (#3278) --- examples/shaders/shaders_texture_outline.c | 18 +++++++++--------- examples/shaders/shaders_texture_outline.png | Bin 264137 -> 264739 bytes 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/shaders/shaders_texture_outline.c b/examples/shaders/shaders_texture_outline.c index a28ab80e424c..09f625bb53fa 100644 --- a/examples/shaders/shaders_texture_outline.c +++ b/examples/shaders/shaders_texture_outline.c @@ -37,18 +37,18 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shaders] example - Apply an outline to a texture"); Texture2D texture = LoadTexture("resources/fudesumi.png"); - + Shader shdrOutline = LoadShader(0, TextFormat("resources/shaders/glsl%i/outline.fs", GLSL_VERSION)); float outlineSize = 2.0f; - float outlineColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; // Normalized RED color + float outlineColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; // Normalized RED color float textureSize[2] = { (float)texture.width, (float)texture.height }; - + // Get shader locations int outlineSizeLoc = GetShaderLocation(shdrOutline, "outlineSize"); int outlineColorLoc = GetShaderLocation(shdrOutline, "outlineColor"); int textureSizeLoc = GetShaderLocation(shdrOutline, "textureSize"); - + // Set shader values (they can be changed later) SetShaderValue(shdrOutline, outlineSizeLoc, &outlineSize, SHADER_UNIFORM_FLOAT); SetShaderValue(shdrOutline, outlineColorLoc, outlineColor, SHADER_UNIFORM_VEC4); @@ -64,7 +64,7 @@ int main(void) //---------------------------------------------------------------------------------- outlineSize += GetMouseWheelMove(); if (outlineSize < 1.0f) outlineSize = 1.0f; - + SetShaderValue(shdrOutline, outlineSizeLoc, &outlineSize, SHADER_UNIFORM_FLOAT); //---------------------------------------------------------------------------------- @@ -75,13 +75,13 @@ int main(void) ClearBackground(RAYWHITE); BeginShaderMode(shdrOutline); - + DrawTexture(texture, GetScreenWidth()/2 - texture.width/2, -30, WHITE); - + EndShaderMode(); DrawText("Shader-based\ntexture\noutline", 10, 10, 20, GRAY); - + DrawText("Scroll mouse wheel to\nchange outline size", 10, 72, 20, GRAY); DrawText(TextFormat("Outline size: %i px", (int)outlineSize), 10, 120, 20, MAROON); DrawFPS(710, 10); @@ -99,4 +99,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/examples/shaders/shaders_texture_outline.png b/examples/shaders/shaders_texture_outline.png index 85c69b1808f756ca6969b53669d850293c53e799..badd388a5167830275b20fb07e75c95b449edb11 100644 GIT binary patch delta 240586 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

Mzx#iqzyz}QX7=)GsKx|Z5g8VIlc0YU`9vj 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�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 z zj19{q$m-f8T=4I$EdZ?SU&zD9nptpSyA!VkmZRc?Yq)*v+!d^Csa`XpKX6eFHUwWYe> zTcSy@n)xBd4$St7X>(rrZK9<1co-sCh4KXMs+9Ad>6mERk~2u*e@)(AJ14yY$6PZB zJxngXh#jpkyPq6F+qWN_ZU9Z{$pYT;*-1b_+vdP9vBN!8u+Dpd0f22OH#Wocr|{mB zsLvwRpk?7y1=LuK&pLA^l6iumki-w)pM!#1N}}Lm3H_m*AWw7;$~xzgC~x-#^a)hR zsZwr%jWR%g{7h3fYvsP)N;6G@bT-cCap9;*6V_E#;GM3O8#YbE##kys*@8+!cSe|@ zutA88O1n6=v;k&ZTqQL_JNGY2da%5zD+a98AbIBiCn7JsL}{jwvQH5=LWziZKnM@= zD+yI_4owFt*JV3ct{M+y7j;?ph^(=nhdoo7&76Y!R^h%i*`?g3S<=Qk(684R193zq~3cx{IspqR+pD#fpec@fZti`A~J=FS=; zf?bz|2BBt*DI1|@9OhOC#yHv^iV3C1QR}{&o6|jaCU?Gsy}$m@?X(WUS(P!qF5xWs z=)Hqzy?Eqyoq$TP{~_1M99Yy8e3KD*K*fPjc`T*^)(NEyc*=VHp<=Tg(;bdEq9lb2 zJ8^@i2?Wcs>@b@ep?t+LFV8)y<-~K!Hcz>6->CIAqDBmRkIaCuO4RyPNOKndQO0N} z&LNYpwwej-SL6#<1q)Uk7IY}WBJ|I`{9z*hI#XI*t#G-(KQ+vUkfxWeV0jk)P?TJZ zjkcg?6O%pPCT9%OI3aX;5;Q`9jaFecJUDrBRv3G2Vc`c4j!C|hTCP!}FTV4<`sg%y z39H#I{t_zOktC7b2XrenK-ys0l~@gZ=nP-m*dmlwomZIDH835G;uN6ge-iXSrA0ky zjb43^cm|B<+hlv-<_buQnfknvh$4_^U@5+Ix_D?$6D_-o4e2v$2~Q+I*>S$4Sxs z$Ku{-Y4VhgDZ}IgFQduXMkhlQ5s$ohtrl7bUn8{*q>e<-$RAvWKf-rd??dV}j)FxgH{OW; zxQI7OQpOIVi{r~{PFxKUKHU*Sp+4@ww!)@b3~gP}GDCkoe^wnK3bil^U6YfVYJ;WC z)F!y45mh|}Gkw_R^#emgKupNeNyx5ya$+x;uKA(spf;x<{ZH`0q;MNv)4z?$ve2_< z&S>!p3)LhyCa;Sx-lzA-db*1_pft}O82ScH3(}!*J3j>ng~sk?E%KC9Sn#S!r1GAw zy+UF%AXPfZm!hJQ1zDfhgzhp$yGjL%2?N8G^^z@gNM|zO{k{LC+EdgswZWQS&UAGK zAP!_bE@)z0sJ`sE7L!;(;LgAIWAY>fY+tiHA~wH<3Y8-eiMbBz067XUU$E>b-M6z$ zrzi)qa2c`QDxoIWj&2dUI}cm7o`6Q4QMJVua}_No9D}4dH`_b=Wi%EDOR<7N=Cv<{3i*}(_~y_ED8!x3b^rS8 zS)6SCns}1KuTZHIF|tI6iq{;fAOaDQ{<3AC#TQ?D=37@wCSUDByx7T|4Kf9*vDZl= zZS&-0CnAElh+9kPH2O`?f)MKyQ!99RXN_vE*3^+5Fq&Bqa-AY-{Cjaei$a|Ii@cJn zuGn1gR3?9kntc?3wa}37^lt>ar*Os}jzWbQL0+H#(UK+SUXtpR;83a{Y(u@Hp!r;S ziA;^Ur6v3Ig}51h56HF13prU>hf#UpYuu^T_RDS&?|7!!m?2*mbGztX+$ILVDO}FxfLcz$!*wC zKk5+&SlTt<53InTQ`@5G8sAE4^@}53zm_|kAWe&jq|?k$f#zw(R~?(k^NgLRE?#|V zN$zA|{`?-oF}@IRD#n!V3iC#9LZG!<_&a!u@iZm`$(PQdRvdbGWSwue+;6r2$F)#0~U1suY&!M7j}7D z&LM)OPjy~*F7;9Jr3c(gN4QhJai$M0q_uzlIzj-4mQUOe6}mqhwy?zQyn;D`;|06X z&qed4Rd9%JWn0$LAhC}ql%=xlLVGoRm`%J6N)_0RA=ei zYbNZcgnpH6Yex=ZW~N>_BO&601`EQ>9+bK7A*}rxb0(1Kij8_KGxHgoN#6R2hhJwJ zgahl)h%z#oJ=<&ob*?L_h01w2Ekz=qVklY@YT|20(6N@B@2Tdcfqie{8t{`x6lB6~ z+I`O%E+qk8`P`|-ij&i+J;S*)p=S+AGMt%p6O2DpX1@LzPpPQv1omDDCVSgr5Tw27 zr$C}4`lCat39txUyZ*xYvusq)s^XgjBHhadql1hy_ba&7fPWug2qQ+=j- zbdvMun6yQP;_82D%9vTSmg+BAKxOpx7ee>*50&5#cx061s=9^XOW)~Qyj3i}fo(gM z*5$3}z2b-DjXSv8I+$PE{Lz$E0-T&`j5{gEkA*;I7x7I=rluSNI^AG1*Yc$ll)&Ei z>6Z8_2Jo^kaV=f2)5hz4Fi98s#amRATABd1y>{XsIX0fk;}C(io}KCeefT?Lal2-0DhYY-z@ zY>EOK&^cF@Tt6xfJXzh4L#8-j#zto_6?%oIW&fIk3SQ%nxbc36R5JyO%afCn#fy62 zpOQS;DkyLg*`wOjYz+-SQIt7tKKvvus|Pl1&gC{#S#zeKd9FB2yWV!JN*Yi`$UkYb zG^Y>Z#0IAn%It<76AIle?Myj9yxN^g zjJv#(=$N#WdWsTyZ3%V60*qqlSFGha=!k%4qa?Zn>{2c`P@ez5T-3Dwy`{PNIje6{ zJC$b;M$6GSiW$@BVL}^%7;*G-p~0d0lo(f>ElY|mZvC!OwrPY=qB1^V1!_*>7zIRf z2M^{y@(Fo1*Hp$;$~wQs-3{n2|gC4?*1v8Xu*EdnvC#@;W zc}9+4isxC5X=$ z3z`)SR+&uHr z&i_UNcbu3%lb?crPgEATYhS)lbdDT(-bJ0BQjk0-zaqYvOg|Tcii#IZ#OEIi)eLKF z#gSJZk2#nLFX?jM|8S1wP|LNwik6%`wUdui(@cKB#HtH!x^r)CrR%?!Qs}NiCyfE6 zjgp-jOsulS=cK6xBV;oLPBlaWC5Phqi`s%*5=%V|i0jAur^D;tRP*m5*wDZ!6d4#d zP*MO5=Ea73M1pPK0_A426k%05v)|NdZ-yD5cl&cU(Hr9E4^>MZ8HVPP4UY*4DT^sH zl+qW2{r4Q1ip9Gy-d`tGtdEZC2Af{{14sFbP`DnSU8@MML|qO(iIaaI#Tb1lDKSkB zcamc5-l;{#+uC9sSq~oz1W?T)AxqehL)Akjm02CjW_BBcNwK+{9I-;UYTur%7l>Ph zmAV&%o~f5lDe?Y#V8MHMV+AiI!;n`FSz#SD*MX>dks;=q(WV)|g_(~uhO@d7;R*q% zZ3ph9e7!+}SH8RqXEak&Z5{aQW5WJykewu~ZYh zgX1m$x|Qq`O0YhvBDtPQOI){ zlmSz>v}8&`tX#2XU7Z0`Nb%aelQ}c_T?I57?bQI=g>$L{b#pySi90nK>!OzW-VZe^ z-g3s=@T@$o9&55u717zh4(d!We%(|{ecdEi8z7ALe!<>H?we^R+g(c`Z{m!roA{yd z=*HPb$R?HiHQX!b^qDiTEgd6P`ID}`%eN{*o_$Lk0e(h8BuPZC=TOUTKtcdyESmkY zWfzE-E?p8Q>Sh7WkL9t>YC!5l^1rj-7>yV+J6y~)y85zY8$IA>^Jhhs1_Mec6yx+2 z3g06o4!3avWZs@VHDZD>qM!?NBbt&vV@m3U-|fU}ytfD|9e|(YPUmxxmA_g|dGtr} ziI97eM$(;3Te_9wUyYq_Bqe za~9lhA0a+Q6a1Cb`Usz9A)9L1wj=m1>!rCS0u$wJSE_J5Re)tXiBK<d=!Q7C)oA~YzSCiQIV+q|){rTE{53qnM6)zu#k2fRV2q`3X?KhL4P+b6H?@IAMei-v?|AKDk4&e}vTUUoE zXppF|F{&!Sy{@iKnt9+TDm?oMMVCzN;BFXGK9VobrcmuFD0+3$WXqu|&tmczkhO|F zRKe#fhbqa3_S<>s>enms4{#gqGHFDr^aM7i>_J90!i6_d?3|Hu z%|3ZnuVq=QoW(>_o)u9*(GcB;5;-V)`8b8`3h`&+k9QJAReC;WE2+Z%sHc)a$-@`e z(R9vp>6;=~z?ks7xazIKK-KNrKh3;q@BjI%ogKjRkM5%K&+t#kNr8&L$H@Zz{|On} zk{+adhh~DD>cFP8RAfUpUB6AxT0}o5Mx|Gs2Z-s-I4m|`RyAmnvI6rgN68QhYcCS< zwKdS{o4$-D6pkiyJiKb=7hZlO`V4yz&0rUyXRRNC47g3A1C3ylPqfLEPgrNQTk%@f zdDy%L%4KnV!e*A2=|V50<39{)9{lCXJ?Eu|EMIk)88|~~`zSKTml1IOHLm?!Z6g*> zZOsj8fwoI3IPqYn4ItM^MqPjMBGLgk*F~RD;kJ(g3c~kpZ|YIf)wlGhLEif}lnUb= zIYpyd!lLje92z}8e^}h0%y7>Kn16bLX!T^8xM7aEcMJC`lRm$i-i*~g(9m2Bk6I^d zdhiG1-J+)_rr-c{H9I zJbM`u}2$2U!91Z%zAQI=H(N1B*a{oC$x2>7~-xA^HiGly` ziD4xUaMt=ST%>5JnYi4Sp66j}ZpT|y$D+qLE=^MInCFaqH`s3yVDGy)o5CNu!%Ol= zXpMGTGIICqT$aUPBXqnnx!+YtBZ{^?_lf`=C2{@YCsce_e&0F~sA+hGb7)3;?{yJk z95N`^Ub1`KGs#k3Obm2$h45$z$2~vkCwFD66*|5a8T}JF_lRfzL$`F{3<_JzO8|M; zM$J|-d1oZv#M~}nL4)0QcQsqZuFvI!oAZJr+mi71G$z(Ghgyf>Y23CGDzpd?^NJL? zQpn;V^kHSv^k|^Cc0gUcxQ4pn=TBF?!^+_$Zpc}o!Ma7>$N?^HBYSi}>c}>LR=&nn z5^xr0g}4z=(-oe;q9Y;L(f3djlhX$H`I-+5aGi_=d7a+~2RrK(D|)m*c~1M5{E^NR zm=G0eUVAS2SFYv*uy3xDe4eEt^*de?#j+GHeeF_z&9)s%YAPY^Cl}$Gnk+v`5?nA( zV0*XwdF5cHMI0Mhapgt<#YpgxUhqe@5DU`}S|3n$K#^^iq{P^J2ScnAr`Ag@)cY~5 z7V+UT{ZI@`Ral@bx?drvmHu_q3Jmj3Fk?A3<%vJsXBiEZ^$3B^vE-opw=#n_<2APG)8~)!#hkP)3 z!~e|p26Qlj=DKs&Rw8-PLtev6aHpvcu0r9UdRgDMca{CZ)?6Hgemqii*i*10(5qX)V{gAtQsIyNrKa;QmDzdl67zE%_asbKzcCWjh9Dlx#-hbS`O^-66J}X3z8) z)eNtiCtI{F=ibzRh0&~%3W9kGOh{M05jV1iu_z%`>_>lcztRaEL|vc2ciD4p2VS@PzrP<(*u# zujdPL<@X<;5RHH)i>|INduh;$MH1a?@e?|zsVW7r73~fUt(8ngh?FZFIj!1NT$(n> zQ*XS&Z4h-QN}D9htj|tLCSp_Fh36LDJ1#Pna4{}G5Px%q6G0{BzhdL;jAz%ezFj(1 zW^HXpU&3|}2FZ!I(ao??_#6(c2$E>B{E*_-HHyQN9Ggh-s(nB)6)bFc!1*pKCx7_x z;Z)7{;jq=i6TImoV77$`Il7yysAX3R4SL_|=c5K4Wh{^Dec><7b;Q>Aw)RBieCM(jXl#wR~VQ!Trg0zJp>ON@hCRLlHlOhN~7 zNiA4lhc8x-vM@a+tFlgh-OQ+>q?^R2Ezx*CxR=%ewlEjS@3N`*lnF^d=0%sir}5Sb%%`fnn-PP(TM1#JfC8nun`omRWwp<#oVD zJiw7q?(*`}Ec?|12f7?4T>+;WXE>P}NY_#L$RrI4F@1(g5l8r}3YdaSjXcfn)`IEi zqc4ZJn)QdcG@5vEIo)AEN7t4QS!D~i0NziDK=_D*uZ}p0q=1M^GixjZ`YR{kRKf22FGv; zl)U;w-!yg*4++`5NwdrD4BR~{&s)z*WtG*_5rR>!_DQ@7egoLk>hjSmm25z6`Eo$A8Knl&^#?()L$K{l zhB$RS=u4y@1cI=1Pnn=w>YH?8Hko3hPQL@l%$H~Bb)2b8PVh#MKzShn{y@oFW0AJL zxM@U)nAaZ^e(pRjnhUEWWiL7z72LN&v)?DO0TST(P@-NuB&I zU-)!q8CQF`nnXw4SiI)ooY1p9T0AT>P#deD@QY-9r-?Wtlh3E}Zlv1OJekO*c;?#? zhWY7GtGRp$ZBcgkmpy8hNc|nv7yT%Ii5e7xi+cU;dCFOePn9%?Wfv`1m@!sfZeG9t zK-Q&w|6ObPoc|eir2lht8PLGo)6}H&-SbQPIGdK8?f-j$Yz=_5h-X*_5U)V(sNF+v zS|3-t7JOx(^4yt9=0l@jcc-7C*{R|z9s3R_JqRSlleUxfo>A?VVFgE z6m}L?ll5v@6wl&LbPH7Yg2^c$aN4S=8HJLB*MwN5$uoh=bll#Yf3-m!9 zzFY})wKZY7THuWeXO(rn3K9*(&5BW%@WUIZniWr^y4S8MI!vjTEqr_5@`+ed#Ah@G zigdL2d5k(e6zNV63pol`$|yy?)UQuO!K)p#dR^uj3Main6fA}y*&->?k@FB}*1=br zplGoRb2*n2^*hybfpjonO0M|pm%Lb_3jn7^R^$_x`P?A}_z1Us7rIkAxCQFsYZR=N z#K~39R}q1IW5fzSJcwd>4eq>yHRl3}OVe5}?7;bozwIlr-A{k$=_5ovWr{CCm!sj? z2^wqm{dvHvD>~P==rqp%oPF$Je7h7z-1Ha2Oo_zJ8v0&Sh z?W3`PvQqzb&YF@NXzbJ#$DZ#~)_Poq_ksA*7yrGh-YC|GYW%AZSAYYY#oubuh&zpp zh@E~_$$xP!9sJS$!EAVD?y}yR4}h^<1Aj1qy)~kz#skF<{y+h=szPkbNP=8>=c0qi zZv%(PjptM;cba~o9OJaV-j~bRwONauu+El^qSb$X%p#9=qsmuyUpbVx%c`NfuW*0f_YOq9 zY|OAu!)YN>`gH07)+&b)ZwI2t^oJ`1_6lM}Oz8=XZ!!{81;;4TT}7`k*;-tiATbNS z7H3qAiO$?7Ye^ zMJdEg^E%_dpJ5Qo#?sEFk0yKZju#U*TY^Jz#7u2Q^~-*ADytO8hxW(1tl3czfl}swmmJ3psxpIk(p25ta26#b*b}WZ=KB~>8#8IHv3fqwna8wCem!+=oYN&6Ft|@$u2XDo3t%w<;@2|-DvGO#isi- z3{C6Zq3khen&g8oyn#lI^~g)W9Je)({t(kBv|TN1xROJCs3@piS8NN;Z9%|`+1{Er z?Ps?8T02d`y3f`8EILg>>Lc$-#V)IdKhybSO?=TW zV&5nzHmng`y#c)=eQe;qJwaF86k3OClLeIG$XV(p8T2g|YGQGWpJR_Z5MtK~_L#r(`Ey{@>1^q=2UPVXfHk-wo9akT^eBu^3c!dxi-Pf_WASJQ& zRupqdU`QT(l3rkaf~Jq`Bj75u48+2_wY% z1ipi)NkV-rhqcucG!5_dXkJVBbW_erZr-Qr0=XElBtckH za9@&FfA7n){o;>rzi_Q4c{ZE*U(h3bdA$yf`)eTQ161V4FBtJI)=#+c5lNWdNp<$@ z<>ch`WxWwIk}a$Z!!@tC^ErZC(>=`oE!+31usihCSzF%i7r(u;j(E?v>JSvYn_30jiKCeX8agkn9e;17?XBk7Tt>^?&%y#A4eSCHxZi-Af#Aq2qQ zO6?gumqsLAsX#{2Z!-j+BQKGPSoi@Vbqty|!8*?SrT(yOHpe{~G_}rM!wWY`1G$gt zFrWjirs+zVb??m0g~lbI!3xEmCxd>^7KyK{0P!k1@qLa)oGz>gVU^G@CM0mD$ve%B z0#zJ4kXCVVkz82c?ywwb&rkrHy2~43ql*}$hbU&-InE`<;(S_+t=@|#APsS@-S1fv zq2-liV#1uWeLvJr*0RX8!;E!?hfMKydDABLgAcIRAxAR0U6!igEW_Mf@|qyiy_3@g#ervfI${^ zj8M>ay|}m@vbiO%YEF&L5CJx01X?4wzEe=?*x6Yj=FI;XvYm1BgOie&A-fbSw1#S% zJ`&docipGoyukJJz&5>e1BoCjQxRg)i#ctdICaKd zkuFdExKT^B57%LD`5YSYzaxuaq4BT$g7a06^`+emMJDd7N7R_TYQY@`e)%OeMr>C6 z@~`DY1|y01ZcniA`nqvqzp*2;y;7=$9eDoi-X|0ax9=xp?sOjAStcD&zz!tah}O%5 zKE;<^l`AlU?zv(%)H0@1AuB3R<1fMD%G=|=6D?h~5^sDkCnn@K61Nvt1eGNXDc1xt z`@c4zR_RZ63M+N?-s=SaYYR+6&l3Dt9Vb?mu83ILF$&~F=b!Rlai!v>zXfNfs7vq< z)f_Tiq5Vo#QnG91#`b-byIm(=nuh;agXoKaFnpsdcs;Imkz~k*u7)Z|JXv#H%tvyw zkdyFkId(=-u0A*lzz~OVp=y}YX)(AZ?lu$+g9I8U^4hxgO8%m;AQM}B@wq~$75u?e zA(A|NDVkNn9fP=`%u_O)kVN`dZYNf*^-9$eCu9Y+ZpdkhM-M(noue1X$jX`_^~*Xb* zbs@{W3HFGR+UX2gpSr$9uo6|w~v#xQQnJj7mF*vPwZK@R0{I1o0-Pmb1(3Klg4`l$?U57td}cCYOK`7;0{a$BL$v9#6T zW%o2zmplc9yAr-%zrIo!?@ZTbfR`}?1I$6pnfbou&Uz+}&fm^y5^aR`x_8he;Y9Ct z@vuhdx4-`c(y>)o-kS^mmw~xWCL;!n&nG~;7=&lHIg9Nj*1K=ykdX*xpklCc=vbWx zAs*3V-mH237FV$*SF=5R*Y2G`tjN+s{9U_)%i_n(YFZ6i$fvmOCG>bRxem-Tn}iAq9Wc*gBu{capcZ>od_T23x=_Nuv}&OUSD(gPgNh}DvQ{|2hc z+71%{I{TGJmQH058@AgqxbT+&aSNlChzu?h_nz>N4dQ5g6#%%rLSp;)Di=wpMJO&G zw%G=IFJU#d5N*+Zoem1Tjw38|EN;vWPd91x>aOjUn9ZW2Lk|WEc z?0}=^=n?hRuc{?F?GYkzU?6J`w^MHEd!26Tv||#0c5J3A#4p#=K@Ko)w)(i_z-_V# z(k}$bG3KUa{jl+;WdzG%KXkEHqFiQ$t7w!9l{&KOevoE%n|a;Dw5`EJJLzDijc(n( z4YgjCVbf3t_I3r>AlaCw4=PvarJ4XgsuoWDN)#1aClS@0JVGmv5 zV~wjP2Taz2X>^4I25bzX4I36BFH{h-!yT}`71ICniTjsG`yoGelrV=qaPWbsx{> zxL|PwAj_lY%eZy5$yqsvk{h3MtR6X!oB}+tg~k_+G7c-$KrF3kfn(K+{hOOPlhRbi z2{GhMB{#AaIvWH5@G*v;`Y< zO9NXv@lvMHp5ybO9_cPV*C`7>A@yxf5^o7W0eO1Ysw89N06qdaZU!UHhZzXC$k{6G zQTcjEj4$NB#1RdQ#gP?KVZ4(AHhatr>LQJ68YTfcGLAbPZ->Ni*qn!S53PJ=EVonf z$;JW&yCLkL5_r+Yj&&aTsf&cVGL}d=OF6>FT~flQcO;u?`D=uz*Xo9f`%x~q#$@kL zp8A%6^Np#;cG}(j^Ur2L6+iXeftB@U0{BL*t$a!L@R%fL5TnU^bgiEYR^59cz*Qbo zQad>x(#Z6}>$FpE-rDHx^dF|FL>|8J##;MdS2gUNB0Rmyovg(ncP!X~R(Y;)6{u!y zA@ZAQ(zm@qiQ-fXEIZJ+_^RxOJjfe^1Kbd)5cYAx9!b9q*^+doju63aJRqlP+`6X2 zJ(gS4TE#Wk$<=6<>NNzBDPjxkoo$NO8L{aL(CBi==<$jni3+99wXRo8tPeNpAfBPdG+c>HLgoX z!u{bGL%>A$$jI4jV@TY{$zJvhKl;~6Iqw+6=NWF$jXr0ubbwy4w*Jj?w0aba7O;tt zB#=U_RHViOW}9eR7t@xp1ofgszJ3yg41%%p&-i>;!&9s%x6=>2L;J${76UWBUar`f z(<|MK?(8CbkjDTuu#C@Yylo}%QW9NzS(sS4eCv@xVjf3ZbfTp@*;Y}oUvITwFCAP) zH(>!Tq@)J+zFpf={T!tl%XLO6W@I~x*@u8uJIdC|)Zqn(ruT{C`Xe%Fu~9NV<|i2$ z7AR`g+Y5j(+(Jf7I9g<^c!nfY?*Rw2@I@CUQye6bDCndit`;@lBp^ zIMW|wRPduAaA6~mhEIKMa%J{!POfgP`K|h60|4gw$)E&LnAeLV7!%V@lFfGVnv3~S zu^}Z;vqrM<5iO&F|1PN3ssG?h%KyceY?0|i3S+Lr6^}V82|b!G&fHtJjQAU71u@e< z3G7qX5*@kfkE*vP2LuJtM-4e2?#55)U@Td=WZ^j{M0Cr|13XcQK#i#s;D!F8dI+dk z0>p%FDQlt8Id$mq6`JIGiMh-;*7f04g@}4X`?h$gvg@bhtU!Eb5HFKa@Oab?8`>L} zk*z2~1P8^n)N2Gx>siTkR~+0qDkN zr7WRP#W`)&EJ4$JNpCKLrY%q;7#{P5!WmTwvvMHLRi2-()n}~kf=CJ}BBL2CAFu=I zP~v-w5{(3{RrH1jbZrX}kh(2W1)1uhQo8}efZ*Ugh-h`9rDaU&X3fWDFSfeVSeTGh zdJp^oKW?@547Y$6SQ_;|!!`i)pkRt<)FRpVpQ&5UpdM5{#xrmzWGJy!jUV(J9XU=} zTKmd$-@Y77R_!8uWHk9Y#b5JYwL&PfM$KB2x^g{ezWd-3E-wo@siaafp+3fqhn|`H zJoy2X-0_yh_t%)bYEk-fk1(7eLp$~nE%2WxbSH*$tU|FL!IuY3BxblZ+!Ee=WNyxx zUa^1=BR^BHJ3KV}qo2ra)(~c5SXu?L5w_O#{sQIr_T&8kU7(^e(@k=#<0^Oh!$war zOcPIupA9>!c+!-ftmiBw$t0-C`@onlWut!R0PN1(fzfNc_0uhX$ z+n9tcI`t-KRnn6G%-o2<>q2EDwEqmA4boj8opE}3S>SV-+*BxsKd&pcjM2`@7RWmp zC;POD=#ieMqc_J5gSBntk7Uq(Z+a&T-b1%SU-PEw0o0=t-_3))k(7!Me30dUjGrhq zDp5Z$HCEa|_H>AQDOs8iM=S-2cZ9c;R*O{?*NKdc#p?-<^7>dwWIUp{$3=W7Md*nk z8DQ73T+%6Q$A+U~BwkIRvpLKY*(TOrv4Eo3F~gH2;-@jgu>LP!{FPLe!=ua5xN6ad zx35dWKRE#V`wGFiQEDtoh3=1fh0?;!0*@ERu_ z&>r)e)|=bOK2BDuC6Sj}ARA*x zIs9X49Z{F-?gwHJg?6nQGdjNsjmtMYf;CH z>Y);nRGJpPiyLcB7Q}C3J`&!*2>dbM*kbkn!X5FVaowDb3{>Qa z?6cQbDQm%eUx$sFedowZ!&|6~_tu#p^>5dTS0{*dE`$r8I?(4g&_7pk6e2~(5ca(~ z-4|~k#tJXqpf_9rs$XHMgnzpKPynVVLhj-oid^44jXg`EpWL_1e1dU}=|6wJ&@ zdhAP7eh}Kfoor#v1CvFT|0uGng(X~U77B@W_vKbjDOl6s%L;IT(@SEPq2d&6C7oNK z7mWCWO!qrSM@o!uRf|M6>N~aMV!gs}V)CdQT#!?X>BG+Jh!gd|uOoHIR(#_}_EsC1 zA)^>oVJ5>1exCiS4Xg*AQitp(Ht;UBg8?rjx?9%hU#li+oF<%$JA3*xq}i3NXA1(5 z-oN7pan=VgR+AX3RpB4di#=`E4T$ejBSC_gJI$4mV5aqG7y#KlCz4Wh?B?rPUq75k zT`;5}qIBCC>pe(&lB!E8ic;tGgo!Y-m)vF;jD$O+maCU8AaNl`v1YZRT}=0Cv z>C?R6GjwmdYs+&R8tbuhQ?db`s@oPycvY1+fm8qso~%~PO&PYDtg4T&c_r&^GIxi^ zr5;C?Nz3)@F^Udk)h~tTG)vdJE3%3A3?)umymFGTF^{^TkS#iiOVtvMvNZ?O3(i%$ zUN6Lb{bx6kRATjM>@Hj-SZ_}yv191c6BaQ+mr9OiWB=j0glPobI-R4 zNTVsKY_Z3c-+tSG?b~GGM&(YmaT){gF~M|lX@oYQ3J>@yic@2~Zpx~L2m%WjhsSF2 zwiBPK8~GbzFE=fXufh&&S`UjirxmUGM{Mc6bRi4d4Y#13Jd@cOEk zL=WQCH4#K}Vf3gjH!lf%8Q0*?DNexIj{pr!pd93dRRFO#<+d`UDH)KY4~mf^$08w< z3-gM{=#dLSIOBVB&!KW?`>xIT49~5c9`We|#P?xU!Ct#m5p>#@URS&JwVb)?3vW}O z%8AQ8!dLOcx@N}!(T?STCFcA~2ZTl5eCPV!3(;9$B@;9`157)B}<5>V{4mFA!kiEyBz7UTHUJ9|2Z?wne6s1&q|$R*!1yTN#Is(JxlPT$bfVl?g`Y zUvI2Nu+Gk@>FF}!(;-tJv`Kj!PERzg;&ze%qVvFA{22m^KpY5J&Abc{`LEU*n%lu& z&$a{v5Cw|$u41zn0&v+tU8?_Uy|w;}5dX)u2;V*>y!Fc;rk)jX$Z*0n?DqK`k&nQS zF=~FS>(N;_s;aivU^~Uv4t)iA9|#XEt`h)XvEA)Gd^l2yVRfjKs9?NrysT-$`^MnP zH;qm7qo5zM7{ZqG3HYH>)`pa3oYrPH-cGAT)j$dQu$w>`-6L_^5Sm2@`jm3%j3Lib z$r0DRDe3cPmDJgx7PI>F3G>jkXH4^-0uK1_T|F$2I4>_#&Vdha(lz&1=qOb@^7ZG! zn`3;%In0pf@)skFld(iIZ#-~9t=&H$Bz^Ml5GCb4T=#S1Cf4`b6RBNwqo%<9whU#v z;;eX?k5=%0PhQCihYYX-yGbymJAO5#{%MjEu`SZ?Oo zEDQKOS=@SOiIH_1zbYL?MZ2C@bNm+;HC1Z1Go5wc^+3@wj5)rFV(24W!tM4ZTfklP z2EC*wRa|!< z&r0D02<-J7IXw~#d+Ue2;y14yyDJWf;h10XGc(Mmf#fCWBFWd*VEsy<^sCg4ve|Qd z+XmkG`)0hXEE4bLO+wiOGRWd~W(-?-#ldO4s257H&`0cK6$aExYz6Ak-S6Lrh$u$c z;HLMlrJ9^38~~u*zJHXAfKOZz_dS_`D^pD&S)Y-o4Xdyg;~tfmVzW*=@UC1jsEHNV z9yT%p=^<_1xj1iPT-*n7!-6q1eR8<_#6OBI=CiUgGB_1R&Ao5Y{kf|Ou#OqF@XE4a ztLjAgjGPdgYhuNllfiLSU064RIfR=nBMTp2;03D+r=vOEu^GhdS5EM1R3CUjumeF5 zHuN1wf&Ca;_D1G_WvvhzRpopT3hYO(p zD%a^@b5lPEH5YH*Bcs-wqG4*Zz|yvu(a_RTBg9u+%Tlr4g}eL%GWvTCdu%sv^0{YE zGN_1n)Eh3KVxx&B;}w**(SM#q!CK843(Yved>Pi_xs21 z&mNEaN008Ab3UK<`}KN0m0UiJbr+43xuR*$0@tKQ+22rH7eR-jg0@1 z90BQnP;S$xu7+Nd;&8>^@a>6J${pPOgI|1zi>2vtzZpsM>6r6&M~@`WZRe`;gH}ll z449EU%Ce=iL5%YRY6KU}KOx7$*2Jo`9)fFlqx>W zi;|;b&F*GLzpxTpsb^@QhO4-^>uJmb2l|;9t;z`E*;{acMY1)QDqo zbX-#9l;*x^(qpw*L-F0JYC5i>p8few5;;Y654oLt;}ltRImAenl#3rIMbBE!&XR)8 zf`4fY?{;2$0c8)n`s^z)Zul%`dW7Wl_4^}o#336H*Vuve28+Bl|J=w&kp}hEi0!+t z{fRLnl`860IU71JKfg`&EqwTbJ^0Kk9RQ*DIsJqNCL40_sL^>Z%EtHAzH174%pVqV zp%cyS2d8wBm z!JU66nAd=MF^~dZIhvVir2yrqM35SZsU75(BvCxUY0Xy~_OokuF6Lf*-hB?qNh zZfwhQU5Jbt=mzs%HShkf;~W03O}+J3)@=R}Y+O6`1NF>Vb1&;|yllbW?fK5MLk}%6ly1X&OTN)$kgw^z>E76)ULpyHwE1%clfNRo($>+90sFFwnEVAD*4chwst! z4|eD`Z|9qtBaka!}dDS!O0vDn9>q3U1ks2D}+R(bb*dham_T)t-a>w7h(k)12tcX%ycV zND=5VPH-eP7Ls069)RxcCk%W^7b84 z3drXE(2U=0B({aiOJ(}9P7VJevfdb@=}*W{{E;(zzUo1uI{!LHBW>va7=FGnG`x)9wo^3MlzMDoB;Die-wwE8T^4@Z`>Z{a)J&K#w__FcktB?Qt zG=%0fOatEFw=VkM&yW`a4 zym;W*sZAYov$A2-r$wz#j}j3NtYjqe(3n4of0a!Am^S2im1l5IDDlN~L)n?jU?km0 z>~ZXH=c094b6znUNe?va)~f9J?nzk_f_D4^ukaNrx0<@{?^UenvK^LgqNP`?18O+W;Kr1BMojd_)d3lJkdZ{2hXaD?{zUb%ZA+g(y8?+{**s6>(v>RlH*bsR?y^Sp7-H=}V-V4wg*pdGuI{#SX4u-u z!hdqjc+Nu7p^~n@$ z*UJPq)-PPh;n0T%DlV&`vidbpSqJ4_Btcl@1Fz!xF}D)R8nacXoEa=UAPCJb;s&|d zR^X@j`qcX&A(y1RVHDn6@+}c2Quq$pvK58WAwD^kac};-ukbz>w$>*L$s<4B{fF+P z#%r#m1gk(Oa)u#X5MjE+It-eH`zx>+Icyhdb4W?6#`NF7;NyQqWADN1gsX!C?~_F7 zI#LPz5H)T}w8)DzJ*Gr*XvB;=#B)T%SnDDE?L6E=BQP&d+>Ba0n^vmuLt1$7t~bx( zWq72obctkuu=?9O$_MJgvmHnvq7mo|o!PBRz>{zdtvp(^UD!NQp zs|IlQtF%cRk~r-&ipqQml$ zjNrNQ*JPtx=gH^SULps9g>E2kd;ui%1RKAd;B2W&yi01i1FmX&#@#0@&QxNmYPK3| zZdSSrzu@cw+2*U`WZ~`ik&f|Wsx>E^{ipysWy?Fem1obb;_HkhV{NMbUb>|L%JFFy ztM$@6^3^5vq~ep5^M6R8Y^hiIW&zQ;?80+}6(1+ucaYJ@9jNvf-dO_AX}M_Ay*aPp zNcboZD4?d9W!UtJ6l;2N4F);sL8V=@Z(}n*1Zz{=xN|tpGFMAB-`>6E+vg_K=XRhi zdUpLR7fM*gTq1Qpd0q7#S#g`CF)QK=rRGu6IQ0rILq8MeC%_%J#njhq{SqSby^?ha zSL3&PNqQpImaBnn&+?-f0A_W!AnE|kY~6D7@>nd* zBH%#{dvs=3dWPQzl&=zYKhw$`1d9BhBX(R3sQnwHq%7H265E*)#!OEroAZc-smu#c zf|FTz%n1@bS|rDOni$UwkXR+sPzJQiF4M8M-@VMTMsdD;EdNB8!$jPw+VGR23FLt1 z90a~N^`WWlKfbqZVi&2z+i1GWR&TFWx2YXnCP-oid!4vR8vWeuokImeh*KbK3~4kU zIU6DgcE0^UBnXnb#cnfrj3*7~Mw6j5#;{GyLaFuA&7W*Ab z|92a!`pbXG#Touw$kLthLqU&TiZbH6Cl^U~kx72}A=^In!X3wF`EcCLWyTy^o2cs= z^)`|?L;p~%(gMTM+?fwt!1VCZwmaYS)VvA<73ipeIjErdNsX+p%aRzw{EV~Hky9K) z$T}y9`p1%n`fY*dJd(UNu9|!!>k_8&{sT71jh4K+BRcV6#$^DA-qL7{aZhyBy;%3; zIsrB8rA)j1Psrgs@5EY3^D;@vB8h@qan(zF{w$NBdyN!rO3ZKk(KEX>{dtqS)yhNt zP|i8Ru5Gm#v`4|#$_5eIj94>#i>F8h!@O-j3{$?*C*nK=en2ftkH96YqdQ!-<#8={ z&8T)jO*3)||E42_pH*tar^o_NI#Ysd^_&h1yT135$T@`-VG{}!tNmB4Jr0*9BBhbY z{Os63E)z08`4QLYmfblC9a(V`QRpP4&hHkz{u`Ua|FA`;jazw_r$s)7+fmz9;JPdd z-yza{--hazcz|1#t##&#i*l~?gnR%yeTDH++DMb6n&cEh<9{aOp3xjQhG0-QPtrM0 z5~a+FRsH*}o~e07ib`(yNnGc0q`hO7atMNNo>nf=n7;*J12bZQ3ShWxg6b&8IhRPY ziR_DdtOqoix~D%WU9t6O7@Y8O&Q{JW`|%N}0j@&h?FPOe;Kp5$0uPkMAtR|U&aTaui*t?K#v)a(ttA3yP8T;z?i?swkOdXgpQs3xlr(PsBd&3f0? zTC?o&b}!&|LtH=Ev{u3TobFO9h0%RhsBiY6AD@(K{=6SVUHIEUTG|AMHsqE<>hKxO z@%Sx}ntVv>N+JeDoX>y?%?NGI7!+89cT!X;wIX+1X8=QQdl7C&|AEOjKE%lVK>4+J zqOj5t8!dBp5hdtJzrh)b?uz3hs933d1C5-d2pKE z-lqzkJa|aBWHY>r>vZDlGTB6sWaHx2-V8Awu_3l>N7|In)1c^Wq$BTlGQFl@_NIF` zZs?S0EHE|2SA6|VJGrUuw22>;nY6b!_Xk6tBvI)VE!wV*seJGRL2@#gEW3QjNOxRr zorxRY5D}`jw2UL&4@WwF8?xo= zu!A!HE(61hPf9|g-(eTrL6AlM9rnUAv}K2dK%JSyP3<_Ox`Lo=GhKxXbRzE9LP&69 zRl@%IeQ8%Sn%r&Bh;3)C5NIi=QjAX|#*mH)iwy+?BKDk*87&^^o`ZPZhI4yAr5-f^)l}6z0LDBEac3b?NSwg3&syz=>u53 zBLmh`&*@Od%^35S&&AzsN$Fd$@SPj6Tq6VK=hyQ%+6_y94d}+vC0?YBTv89EdE>Hx zyY8juG()I_|H?<1|CWzjewB}Em3X%?-M<#y3d;EUsOZ`=cK?@6=`PCqiT)&9i5|)B z9_7I?Txo?Ocxk^+s@-Trl&;w#m)lsQw_2eOcB&wO(rydwVa!d8X|)#5DV_-hlTa;u zV>XoI15n(D9+Wv&8UGNSOpv9AvcRW*%>-e9oIEvptgG`|Ecw1cAON&?+wh6({bjss z3;EeM@HKxs-=^B3b)}5N(3y~lI>`AC#g2K_z*cH!jN3@s^F8%! zu!nCQ?kFSDQ}D@>o=+#r)ctq{7QS`^Pz#qGNanp(|U!Z6%n>5$} z@0w5uym#cx9!63W(`SHDS4u_mpM1qigTuneZz%n&T3jTt0QWlM+O@?eu~%z6>7-In2Fu=c>L<+O;v&L$wU=vv#dIXJDyr*lW81R)FMFm}FheSBGKL#2L1{ zjaZDpVEjvkBM zs7BuFtyAyct|`)?&o1ooRbYkSYDr@a=RA&KphL-s@TkDQAqSosqa0f1RJK8--_go5 zBASsx3c}TX&+*u~J=4SQ_0g`}$`v)8##=$X_ffsm&Z*0U3;nAU6(1+Yn zL)&uq_Hz# zophVfyK$n%OsedR88}h`FDK11K^k?z3AhAEZ0@G1BxYojF$gY2xx`{d>qr~JTL;>U`7ATu4Puum9S9CbBYihBOm1P5>!}?4t=Ay z4H=bnh_mtK-|GKoB?Dr@dlalr5NrSE&jJlxEKgT5iPi-$59J^^j@*C#K{`>DsQB5* z*<(Dlb_oF#x>OzuZ+C)Eq!&(6KKISA!rrjuG4a4+>^|r2KGY!}4BB$xgg6Z#DjJ;ATb*7K zz$Jzv;p`&d@C8l0d8v9!j<-)sp-!`y1wbF8$jQ<)O|CN8dk4)nkHCLWtR|P@OHI;9 zT+W9Kx~y|PV7Ew!NfELJ*}3aP`|0Ysng-cuua7i+(wq64wBZ9L!+k*-($KM&=oqUN zNS9FyjkH}0Gb zrVt@{vE7U;D4o!3c}OfFxFr{Si4S=i`2yup}9dnbOoygFd*zE|q8DmV>avMqoPgw?-Z8`A({N0ip}la)7K` zcaB#V!N@=N5PNo|ByS$u&amahB&l;6-mwZFnDWEW#6NSM3C)H%`7>uwM zOW*L{k|S@qhJuq@Y78^O%siB6p^G#OpfPn3#P>H;?T}J^{T3Ma!3&P6uz`i+jG^af z{3>cNkC?v*{xVB)x};rUrxb5z8K&WMgfTKU$+sO(gPTQV;Ld0I+;k>YdHAZMr#9eh3 zfDqHB+jH{i8jwE-TD>bX$3vBKy=S@fLnfbBnnd{>56R=hTm%w zxss~pIN%82%2B5i0)s`SPIyO0>dHBzp~6bC%Ret~{QbxOc}!Re^nX17%YQvV0!>_0 z;&Ank!<#pRm(7it^B1#^suUZ;d+bt$Hn46;Y-a_bvuz|F1`hN0t5wU}rrl*{OeMvR ztWe9ou&eGE?c@h;jL+if zT(3ljAafF8`4pG1m|?Q!4kRQ+yRc7J?Jz96uFt9FYV{=St98M%>M>N z|1s>aobR-pzTe}*EqB~gcbr297dE({?6g2T!OmY#GRc~6K_2sj89es2CthJ=8?*574f!3ykYAQo!TI z_;p)dfFAU)^yoH|!pcxbl8ftCXLjycYZ=}wf!MlaC$?w@CO$;yQ2u!RQav3c1v=J@ zZ7Rw>YxUphPY1{PmtDN@-vw!{5_~rHgLEn;H75E~Z@54pBn^#B5P+Jd`~qm6T2=#T z7nV)7K%`r!D8 zw6G!(d!I5{3zPb_UqLA@f1_0Fj}8Y#3|A%iNra zTed6~>$;_YcEgh6+K%TNNiJ=GIB_4Pm0g!o`c{W9O>lswSz>YJ1z|Ol5owI&$pz70 zCEevzCfCFR=d+0mzzcG@=&~07(F3KL$z?gzF}=rC?6GFA^tr)@)B;2( z_yT&_QE-eB>A>j1MMtV;X{%&9PPJ~Dl63%X^LZUOQuRG+$dGcNhB(wI@wjO=pmDn5 zd<}VHg%$YDMEDeO`KU(>G1@JoAqr(lxPSp_WAE<`*(rzY-u(h3$)aU$Y66#^JNkM{ z_7?bxVauIq#qt9)(}^--g1GQxGj!a~)WeoHu00zG<)0z+Gg6(L&CG6+L5g65C_-{Q zw2(U&I-zG#RP>JxL1P<9;PN?>kocod3o9{FO2Urv*?nI$izq)BtTa!blw*%C9HR zX9zvktvkabC4c>qNc88=O`g^!j~lq)h8Lkxmm=_ne@>Ii)@7d7bV(o^n3D#BA#=-+ z;4b3*{NT&ncj8xjB+UD%sd{YlSwB!FQ(U%886lbIB4s1Wu1oseGBl?rOK(%AWT(u%za2ihD@61+gsRT5w(|=Q` z453cy0M7ggyd3lR^8q8lBVy~EE%fd-xe$H+?lI>_LDw>N8wEhugb;h>uK8s%896zm zDp#sxXpNR~VI9a3$8XTv9alzJ}BoQ8ofK9m3 zBU~DTh|UnRoWY?*)XR<{t7A#tosTCm`m$y4&^FKPvfm!XB3FdM3}veJFs%TgER{4j zM?lNJd))ODosfzgp)bgLi1LvSqSa%O=*IwEPVQBZ;6eJRK?0YXeB=~zU<)IkAQ|ij z2#i`6Nr7sstB#nazUp`ZS9ffos!u50c1|uQx-|4tY91C=(#jY_sbbcqCdT zVmv!L9ZSx_wqN$a7O`&grrj5!Uj*7z%MYlUoE(3~)~fYyRR3i+#n5`-?%$!Z_mze* z*Y|}jtocXZnQF(YYgl#c!v8%=MB=CZ{{Hk=C^&=&Z$`ql+!cCRM-@Ts!Iqr^X@eV% z)cWB%a3juDm*OGdDVwFVuJ|dnM^@`2@d91 zUjW?)M^L7f3@A-(VN0hDZ;+;_!OYM(C)v5*RTilcN&CauUV5c=U+RAP?HWGQ-TCis zFt{PZM>ELxo+(~i)GRAkE#;xhLb6D=C6~TS z-Jdk?-djFTEiO*W3^chWNkbDnryc1#M#*E>_K+8ZEFfcJ%Vi-o&&lWem81`U$NDcG z^3bQP?k<3nzjV!#nt0kPM|rV<@@efj5p=U#;cE+TMsde2g3}*l@Tnf*248sPF&;=y zR0j~c$7KHu#BL|9pNabZg?j*B$vCQ5;!b*Ci`#LEaDD@9-h>w`x*{&OYV#&*Z zWbjimPk*ZclhkX?m8qVQS0s~R%RuZeLhtD$Y|)`pJlr?OFIXL+F>PV<}-r$rF_d z_ijV>H%kZcD~j%k2)?$9GQ zha_XKz_eTPSGy=Q!2ykQ@8KnN=7Ob?_cITDr469sYQ4re6^JHf;hTntwrlXf@wY2dF+|V`2G^bRba7Pe*2a%kVc!*17`rMn7XMF$6n6Hth*pJRa2?J#hwoyCGdueAj+tHNvn81Fw4poUR z5(Czfj&EArx@#e0KjW^6piBy0>HDT-Bg)84FSIXthGe2B*;gsbT`B=1@x&qA_;3Yj zXm}oexC%Z1o^P^*$bMq>mdic_gWHcUc$ReG1Kg!QPs84Qk8u{gQ-ntnN|<)o8$$C4 z3~GP5gz~S5-7?%p%K7L?e!}(z7gws<2sJpVx_#A8Ut4xsuf{oCI)*sY)$?wWNno+r zf__QUJ!e0Oepv@*5;9Gh)e-GV^nNkoy!iY~2R6GPid@K>0Rs7x>m6cj^p@L4h`DY_ zS}}jkHRh8kyt=v`p0_+(YsG&DCqOg)NwpyTY7ngku9g(lu=T@S-k6;j6}F-Fq5QMT zfITBOUXr?8&!djTP+2K4Ls;)!`$8BoF&46tOL8&M^1Pd%LWDv!4-*9ke$d@0?BORx ze&WNXlJsHjYPFi3o7X`c?PojFLrpCB_gB{nd!t|{_0qp_c7Gyq1tPj7|H1Xe6QzF% zt)t-;VX2y|gIXNE8`~J?PFaSyTk0ai-VxGuYHWJ~t7{X}c%rlBEfyZWj+~l2K(3zA zllF!TV7hhNQE%#goaOEwT)Ocx@x^+jykNNLoE2kuYsQe`B;~5dP$a%720gS;&Px$W zqTwCfv1AlnOwaD-IV~!@_}tAnF@O=QP$Ru8F+QpoR1?qWlxy*m4S+S_lRHZ@7a2cdw5y4&T?s#qWjOP*PA5Fx6Pf2 zr62`;pC~T>e6?f0_~YZ3*V2}H0M6p}ym)qkJi2Jn-%VkO*7y94FwP3wa_Bx-nM{V;~?9YZvzbnP-I&dknTZ)p6W|CEV`#z}= z1rHg(o_Tp#^ysG&Jy=TY+-9!WE*}{-EQ85AE)n+H@txeiCVU99dUGm7Fu#|Oz&JT~4dogkd4H&p5)LuOvjDA|;CM`y)%Ees zezNGqXQhqCp5XslIIZ-|Q(itXLDcF_6zHO-jmd(eN4c`o3AsSkeqH!77LMU&s1>-K z^U%G;(_b7MoRSW1NId5Vu^7K3^?)1W4LXAZ3jRf!@q4tuEv)aOr@*Zze7pFOq1e}AwIyqfcAr+fzjx33 zhlx^^&*JTBJ&ShK9yPpT$X)oH;4()0bh{ACREIkAZc~mU=|OVp5NF#OEun$#oxoHgSaF`cTkGak(u~8?R_|1iKh#iI(=_Xasc^Gb3RdIM+ ztwR)vT55;jhlhchqzh?u%S6vUmx=khb?zz2k!V8-P#b{g<Ko0sTq;vzo+&1aR@w}%?N+$RRp?=3q9g@mi;(!#w?&rj;J7$EUX~!&M_9&> z#B_k;!qH~P#OQ=pu07g@nHS}QcaJo)$$Bw~i9*GB0 ztJP$CUEGB(#!vuee-q4;aor=!CRQ^A+X13RYJ5)a<>b|O*I3+0YBgh)juKF8O!oy#g=regx`Yt0!<# zE8}3{JCvLn?G%}&!p-CByr!#)pDORUIY+z^PU?(N?YBbD8qLl=SEw-Q(Js3)P5BGK z?WeLdN~!G2&Y6@wEz4@x*q}o<=FR^|FpQj@ncNGgZ#oN!0CNH!#XDS__l@v{N2rdx zx*Kj>xO0!nzwE*V^R?lNLN!3F6*x@scRYrIu$O-+|pN4hhV zs27jolXX}4LoI4N8mzPlNF$4FQ#g&Cq(>{d`=y@a-L?CbTZ1cP zbGArv=q06ro~5`*w{1XwCw&(0Ps&56v9Ua#I|(?;?ZguS_n#i+C61VzxT;3`}S0xaqB_CagyJ z!8@eo9BF+5I)uRa>V)!(y77~A0Fv4hkb(=GA~~5WU(qkU@3{>stHig45SO0`z93wI z7HLJVU~88RWMx#X-h@l8u*V1 zUwS?NNbVmV^ULyI(DtLYZi&oRXA*zgZhx;ADG z%3s;%Y{a3X%B`S{A!SS-VdSrj5a|dh9C$5vRo|E2JFrEo>#^{q(r0c!7FI}#i|o;6 z>$^^rZDtoqbrII~`No&&2uo3YYOo!|4ezQ3h&CjF15xX#TpeI zWTl`Y?pN@b*mMQ;J&GIjfR+=VqKPP)Jw}LLM_exQxL@pkaD-Mi(@*e9xw(Xk^r^4# zzdXOie-6s~tu;YLD>+++^H!VE!%gac6kH z{;7ZkRO9K*DTtpp?t?OJ07KiWM8p-^><2W5%soDomx za0q6Em4ch{BJx0A=j7ZU!7nHGlM`E7Xc5rwiu41XXQrp9os$#CEuQL_^M9RXRt5aa zQknfVS$koG)uuTv9d{R~>}8~qKSCC_am$rFR2==gCoDN@k@9I;OFAhgM)>X!*dHDk``S-oiI=_C44pE^VDQv)AQKcg=qb?n7;JgmY+F;XKG z82S2wLbba#@+zOln5~|Cj>m1IKLksRDm%8K*3Hv|z2B=N)-mk*EL7P=`w4fRW{HR}8ABQrE?VtU#HkWCFc zGUd;q2S;Wp97`pn&;9^24che-LtH$!_@6}du6;EF%ksBKVm?bLR(U4ReRc;)ueD)I0Wec47c_gLL08*j?xRSxC0NNh66{D4=1qGwyx zH^Y*P2155_*cP{Hzc4--KFn=nowWOpF6a8MxFq>kqrYb!)3YB1zR!BPPY~U>RS(lh zD|=AJOF|x}-ao=WGnbL*NiXu|=^PcktM>5u8}kWr^RPd)KMtfOe0Sikdk>|dI%&59 z9|eQflOrP^_BS@{0paf1g~PmQ<(Li*RH2`r&jp+GsD5Yh-4T-GG}N8}>-_Z@XK-D) zA4NNAYrhwEJ)3nP=M-?mWQkVH3DrC!CMm%mEUFi#%uSsRes@t9xBx)GqfJpzFpRx> z8LX{UjZ-Xr4Ezy1^UtXrYgP5bz1wSWaVE-~#eMD*@fLy>IXBa18oNAD$+)Y-1+xI% zM;-~NlM_(S?-SR9|g7;P+*D_@2@(JDRUpv5wr* zI;RqF2pHt#GqcJA3)8uR@K8~%lK-}SVEZfz-!{4tbDSXMuE0&Il&mAiud}i`g*ueT zi7^RsMW-#ff1IqU+I%$l?NRPK^5@16X?iQjWJ~r|^;QHwNda%5!6x2Q%e8=q7;qvN zw*R`24jLE!a|OZUjen7|)Q^)raW)|Gi&$QnX?O{pzlhWKtIsUWKzb~I-K8h|cM&Ho zKMw$K`A!Rgz>Rel*TWU)74OHb4HZAqm%nmaAZ4ewABi$?$>z$vRJ9n5R8blJ0DFE< z56u_Oc{7WUBLk&oS`@214(juvpb}6LNoDRm%2thx=VPf6YZ-P9;?POLIqy=Q?Yh|_ zKkL@kceWgT7X=5M()nNM;{DM!N%n~S{o`7G|6OSG{{7zH`kxC8Y_F2Z&zHOER#-B{7CtR9{CbvG1b21=4wx0*3$ zJArNw9bwdQvklx;D(bUIV9D8XgK)x$Z&CB`@U*q~TNTjTiRN_x;Jca8314FRaF81? zL{-CqH=e$%t`(0zL5Ro!uC;Xc2CPks$=5A~bxZZW^tF-5eu2rs;(MEMvFu1vV3X>3 zIGFLp#hNj!F-fwgbSUx?mSQkY?yN+ z%=hBnA6MPe^9{0mg6vwU&^`@2jqDv9+fTkQ9uVSxRwF`eCE$ksge*elw#b2)l(~-) z6NCzMc$w^4qU2hVY#pxeQ#>*AA@B4uj1VAD8IY><0`rz5?g13ky({0H)~!fxqMO7tCah@!r76c=jYJfNSG>XBNTsdAi2*H61mTKddmG`%lF{A2i+q=W zUjBJT4AJ}|F4~MV2tMp?j4w(pG@f}8?x<1X%GK+?(;v|*|137O4j^`p?2|Wm6G@AF zWn>)+2{`K6FWzZLug#Mf;q*kg6lQCx6EA>^fgUZhC=GGktx#@z1>xY%9w|2EOTNBk zo3vU6HHt}`eHVX^_{7@%-&@Lf0sh>o?tcqtcKFpQu;l7qE7xS;{guRNNJj3^ttB_p zQIuY`Yu3=|6uGlVW@w`Uop+rebd1aN%gA3zvhPNYn7$67Z&>QDh~{0Jw;GS+i74FW%_m za1aOvT-k=6s7~^8OU?P~Z~HS5(EE7RJtCltd=UKhi10B5B<|(CZ#Y8F@7d z&RJS4x4t=wggd(A*ZdHY7^q8@YyzRVP403q&IUOIV_M6XiSND3YKnkD;Qk%Hy?~EX zY*9okheJHgR^s#tW@b;C=tdUgCxUeMz5+GC7-&%-=?5owcP>kx-0Nq%c`Q2e+?|j3 zn%;Mo;PT7kp!Z)M%Tj=U97X*8`51|I+!>{CD}V~@`h6tPuoxi>F|0g=r)EikDH9jE zl-WT@-?J%vkiJZ1AZfgi5NJ24;4Vh5h89??Z|5AUqi0ry_DVe)% z`-YPI4LfyfHc40gc-74M`I+PXgp7D9SZ&?9)#3Q6U;QCK6A-B5KA`uVzWJSl-i+$D z7Vp3XcrHLX!v4H?71RNeMuc53`-*mnntsWEg53dlPeJMvP^MyDX!-EyuyRaGsuNCh zqR%0w6G)IP-m0mqLl+2p7?y$eh-GVLl_yvMt+TqKhW7!O50UF}Vu!@~wrIP$ET4w$ zd{$L=mr*B1FZ7!KU?ir44$|4szuxUX=CNsen#b1P@U82@Kxy=|(w>2!htsEmCqMa+ zvy__2qF3BjGP$@0rZtcbYR2_gAY~fWP>idyY8H^nk@z(q{g}p@ zrDg-VvReug?zMP0$jS0nvrkMyr)4CwGuPhE$V97oHvAc~7K9s4%8?FuLMK zMx)sz)UcS?Ts27CXnhi=ecac#u_L8?g zQegjVq+fcKU3wX*4U0(CJ4x7alF)yJH-p<4bYZwobbY}KHnr?+cuk`%`Geb|5dYJ` zK+(kvpZHct$n=OwkKPaoCB{pHVZ3Hy?VxnKuD_QdOOf+{=HLLNh_E`z+z&Ybd2m09 zR817TeC+`z*79;Fld*j+trLd90#To45GZZ-lY6X<)sF`>}Vg+R!2RYEB{+FQa9KqZj73qiW+?oGZh(GIFS#n}5-68n}j_N3=}D zwke9|0>fQgy_GNjyC6J0_L$wwqR9)a zsjiCsdBj`xV(Y~i9jWe1kIP+oc>&UslL!Cwvre9vGIV(dxwUKcwN^@=O}Wb!@9$gn zjVpKri*kvrixUNh{4)qoNC#3G)OZ&w)`P}GFw-`Pf1t^VNF#727qB)tFOvnT%M8?{ z>9K)K?&U4>9ltG5%^QRo4zY0#W_-UgT)|S}#&2WqP13(<$5_qaW8$>t^&p8cz?1<$ zw#C~`so<8uzKbK`HgJPqPk0$<5;mvd8oNi&R0xgmsk4 ziRdx}lv0)!sYQVp9hMP2m;Qd8YL>I4_7OLe?l5s}LO&xG{p^1Q7`gf=s!tB z$>`!J{dw%}^J=A^@ph4f{x+*rKdU5yOY@dZ0IJrwP9^hqTG&E7H9POYb8+zJ6(9qy z!aqM>gI`7m95LyVph`J!h{cN!VdT^Ny>YX}y97xd`uNrj68S}+`;2KXroI{%jLlou z_tF0rm8RePZ1_EHeNUSf`@RNC%QWu+I-RqPr~d%V=V~gq-lkoHUr#;rZlcCKntejY z8mnanW$qD(Y`$%X>~IBt-$VGz1atLzG;=h$cLu=@;FqcR3JSjWeO z_&-Rb6v*c{6-GKj1L7BL-1h9VYyUfI-Te2gh5dKd@(<0{=A@afHr5b#CHSs6+NCD8 z9+WaE9l9eKaH-j+$#0S5Sl<0@{Ih#`x)o&k#c31Z+L)RNhnBZg`P@gNUl)qHSwL!S znGc^37&;}BITyyY)4ekMz=3M!WL2%dKDW3~tz!g@CX>wbaf8R84=UBrb_?*#ne}_-Z)M0GJaM>0A(c6U-0?1ON3+clv~Z@ z-X<#J{=HE+w}#CKW<}ua~xAp`UaF`8?g)T z+P2dY49cHjqyf95nF^=_#*bhy@>j1WrK#DP8<~e92fP3#(Xa3^H0;zBD)Cn*6cK)- z1rsCpt_P2yCu6)bbld%IJ=x|`A^FCs?`H9^A=k?!+y-Ux^&FXHVAiAu5eh10H)hH;;rCFf_;F;`M-Z#Nwt6fxB=SJTD9u(qJ;~2)Alh{n`s_DQ>CK}Wt@H3lca@E(Cx86okBeYve{hn(zjVorV;}y{ zy<_C$nPjra2j`Jb6dYP@{M}G&SWSMsTi?zH+T$Xht-+Ubb9h`*-);%O-i%a8!nf70 zzHrrJk4OGOdyqY9fr!zp4D*K{i9@d-eIMn=&(pfx%epkgX=VD@o4Eh8O}9OTIZ&uUa5KXYm(yZJhCvDYtps3|krVH~-B*}#CM$wZ6omWajT zE#SDfvgT|UFT#;g#N_38&B+au>&;oQ3M@I1b=j#e;)kI`d3kWYwtpl(ZfR=}@uwQ% zluE@bgT6Sa&BM3YiEgl_E^?Xw2i9pvDoFp^kRz>LEUMEFoIZ;N4n;g7WWOH6)^B$x7S|PU@R+ z=8PTtOu-4*ZZA~My*%$89(=;|%WjeGS?j-n;ap_TjB7Hd5RNDDZ{BpNSuahQr??L$ z5~Q!n#JOM^ayD1Z1|WWPkY>_(9;)A7IP(XWOU=LBkd_e*4?IIxOv7K3873N3#>MZ-?YjxlA4z}J zA<^-qNkl7$-d^p`tJ)k?(AE6^sCxH6sPaGl|C~8 zyx*_a^Z9uE5I5z(K_~+Zu=9jAWtDq}^t~nbTtyAv-YMN>2s65rsZGT zJz^yr$YV1~hrZMQFYl>N=chpL|4cPdZ8*^TYfaY!YJ&4l>_;l8i0b&Q$D2%}(SUj3 z#4LHAmqpnw(yL7Ed*?yZ02!y5e5P2Ro}g5l89TBGpR+K-VhQ7vML>}q_K2g^lR+C` zw|6iIOt}%YY|pe}S{EmK#p*+C9gy|kgk~Sm$?P}}pPPnS%p z{`$e?8ZBiVUcA;TbzIZ^;rcV-LtTFYNyZe}#MZI}%A3XtU zkn7_!$6+z=IBbNbjs7JP2MER6VPI2=IJL5&VyI=2(a-SHDA!A*&nnE6F(HLeoa7|7ji}pVrMe#?ff7y{{S()_t5s7 znw7;I_Bsh;cCHtf*~Fz#F{d`!NFFBo>J??_Rc|fP)+-SeUtdroxnZX6`B?u}9xEkO zA6YmxGjpim>;m&exFYr%xrj7A_K6~UG3`uGGOl`}?D?um)@^B}J}l^Fv~wO9Mr)IO zP<_Qyxg_1gJi>cPy=VK@;IeE++}1gnv{&W?a8@`(TjhB7W05nj$7-P6-@#6H4+waghRk^+Ih|mArS;gZ~TAm4hIc#64nmF16BI*gO z_T#4zn=S9iHs;7?#kfX0GnD3DR?~B9t1m1#Tk6`ThCn3p+M878BpV40lNGFEk_*2NtmWz3bI|MIoQ?R-+*K1l58$H%Co*%vhHv2*O6z@n1GaAr|BpouBB}JE0R|EUb`)C5_Vsu zKHEeRnaxcA#-(fJZRDkA6<+%H`2&9ifPAEqfUIwZeWd5lpX44!L{an3l0SK zYM#=s8NJ03djo=>$K0~WeE_t#Qs~Gxy8qCw3bDdswCaJ*=z#_pk<>_lOMayhSP% zYYKjOp-UpA$Gf{z*RNl%I9bNg;>k})KoaRMk@FSNE2Z+OQk84IgS#>jUs;A*rz+MO zD6R#?cRz@Pj&%ZVTSm>3wPF}7WS!qJ7q zL{d%-hRM5VncKNLMaR-ab2uJw!oZi8EG++P2VlZ3saY#Ic^%)zHBi}`gELMHhZDh} zg1Yjt3K3vo46KA1lxN7R`WZuk!|d3O(~y^~pkq#DPm5Xy3Vmny&Gl-ZWh0LxfohJq zbe)-n1x0&*V7qX{6UAH^Wga?Zc~GE?gi^viSk>!{*Ah zi{+aa0{`q(#6`u=p)Ihn+QJ#7#3~&6!Y~>HmUt5Uh znjcEE+up_gMXkbg+u+KC$vN`t&U9^KuU7uo?@Q91TL<9yd8&uFM*r-a_A`;t&do8r za6;;^OkNusz|hzWC!=*cuH#IBAel zV#OyKSDY8-oz8>j(TYBdt61}`%v@)@&-}u*eT-Op5x_`YgIhiiz`Es!j!0T4U|$U1 zOVO#AeN;Ej4M{nd}x>7~t!Mwbhm9o$gQPxX8ecPq3zSQ1xxQObG=Z4SoX zxa#E%w#$=7cBUBs^I%t-jU62#?6jy+|2M=Evh-(I_RP;g3#b^aQDoKamtU95&6oWx zyc)3zu?c{8`1HPeM`}fX#YSkc+rMA|va~l(0SNBxQm@?FviY|4`AyuFdu9s_x`Z*a zu_H6~Gck~MglLq4gY9zT?kXtY5MeNbM=&`sIqHR!j@vG%*REn1C(=Zx7Se)@9QUcF zoy*uzTvXZ!z2N>x0oVUGospxi*?w4o=%2pu)dU(#96j&KX3DWZeM|im(wb z$9R5FFMQjAWRj^|?|e~4*m#bV@H(vT(^|=gNRF*gJX(pW)PXy@B5uX%^=WX*H5MW; zN221LrRLvRDf?Z)2+(SZlP~9{1PZV-I@b_qUy*B!?I$-ce0>V`g3P^&<+Jf+*SbZMP1*P z;&yN0q{_i6w609wMRejYSlb3aagHP-vRFz~#igIh1-j3FT&b3yqq(R<*x5_-WQbxj zDNU}O`AcppIphrKUP-fDuG3jYIX3cVNeL7`awYLY+XsZSJe1(RJnGZ{KWive}vsm%|$nH3ky(%&tmgS7n-2Fzu_PA@Nxr* zZjzi^g+Kl!_K|Vh&AWRib;sseZCTDB`}A$ysAQP&Av)p64?W{J9KT6>L$6{s~MoOn`>8nAIvq~B~Ng3QlzTwT&FLAGw9 zgLVddkvr3F3UqiMDkkq#Q_BQGv?z^?S}p+ozADfy;ZlpFK1MdZn9xl}5QB1z*Q1!V%HHlhf1)^hT%T z?)|Lkls?DV#J(PKbF%^PATMm|hP9B(Yx3|&vu`}3U1)5(T0UdS+t@=Yx^?F7cou>v z=RRzbW%L}sND4W!=gX_bXpQE{8GiaM#6?t(c28uJ}dIB@V zI(qF|su&wJI}7T(xYLI6-DPaLp&>|q+=-Z=eM-Sc_#9UQ$^FHqZ$Z*gyiWrEg6`=5 zNO0m+!|_+5Nlwvwr9m~uI)RZ>4UJ-|WYdG3q63i8*Yy53koC~SnC|T*KC#4=ZtmybwwPKfPeDPV8^Sw_m>NW@T<$F!phe&zQp>s2}q@*ZE>t_2gOD z5xJ;U`Ju27sZhOjM*7qDw8x>^CF3)QAYoSAdgS&?(xZ&UAGN5%3?ADUh&iH{{Yy(9 zcm!GBO|#ZTn$y$}aia$*NiBTh=6opd>~1JVeW2?>Gk>zm2~2a0M3q+-dRN}lmA!FG z1`nT`OzyPZOPS!il`Q{OiDJ%YG&P4rZ{Sy&X(@luOYW#?1OVf7_%6!1t-^lMIC9gZ zQumglm#J&X8vU*>JM#U_`W#R~nBz~|lm;goxvV&wvE zIZtvqLGrp2U21!b*m?>c-2?zTpQ!}#bJ#7u$x8D2Z3q2qa0l+YYzP{SD7!TTxfL~0 z}8zCSDyOFSRa>~7wdP8W;+$Ay5mvf06Er4a1yMpJskeK9YURjK2TB&AXHIClFI zDN4O$%{cg4RQkhxkLJlsTua_)%<3gLF;Iwk9$%raSU84)Rq@FJa1%^Qk}ps8$D3R5 z;@w`Ulp^u+V%P)isv^YoIo!fV?583z>EYvW#UkU1whZ-qu??Y-S(%^oa@>9;WqmpAsJI zl_@m(-Tl6)I~b)-WY?@*LoBGEd5)_Mv>QUBnJME_q8hQ4UMwh^R%;GufVn6 zrp(*a{<1Wjr>4oYzW%?9VbDS7d8~W(y8ouH&|Nb?{4qLO`f`rIa(JsE;dmWRX2w3Z zOVnIEmS`4fuE#T1QIIiuXy4jj+7|_>xW&)CyzEm_Qu4VWYl)TPMx8+*4G3+|5*hZ1 z4_t=b(DzBo%e!%MpV+pWaaQ8{A?-chczp(_ym0N$^SBel+{KfUExgofGKpWg=Fxx_MY$|ttr2MX>k01KoD{8rZ z`>TIfkz4CcbTjXBpGmgtGs4&X!KtH)`pJd2Nw0RpAnW_7xAy~7R5bq)?;1*}T(-t{ zmVj%jjMa<0;vt&1~qJs>Z%9)2ss=(#p)0jaxKedSZf9)^-zptVWGgG8;=$*Q9Y{OaD6~Fw;v(8TH zRcvJdhbaly3Y9OsXQIs3kvkOGp07r+O~qxC9L}-Eu1(UN{^RJ)519beI07k~K*%D>(OoWJ|Q< z#7;o?P_i0|ZJ0BGT2cIrfH?OGIgG%II#>|6$3*aDI;^kua2bDs;_fuA#TQNFJKvz2 zvbE3}_KGZ(YH768lzBk$*nDtueCD0A;0oa$a2Kwn`^^l!WC6?{3fbJ9c&PknuKZqg z-V`N>AKQzZipyc=OW>X{GJ%qn%g*^YpfU8dy*u0 z_Tt5x4GhmN)f2@JB^;z1dve@c(GdUa%o)MZQEmR+IgJe`srxMgq5<(OW6=m@XT)H6 zd1MeeNs>+d8Nj%N)fqAmgLT!&tA&vBRTQ~PqBn$aMq!KR^s~Znfu=N!(&133u161r zbG~c=H#OAE?q|I9(SJMfga2LCv|&$hRXd>Y*>o08!`GEP#ID-!p!~Ht!}y2B_R_SG z1=72B5%JRLNX$q!K}%WbQc~RWaP$Nh5^x{B4zr@(!dJpxgu#=732Fj`RKnHXHYRc^ z5;>`hTs0)=b|t!6pHEFuoQ^EPQ1&kphK}MN8Xoz39_~Akw(|@5&4!xhW>Ob_=38R` zIWVTzn9l&&kVwen1KDZh-{!i5l`?(zrON>lA2$KwEZ?2Gl62wvR=)RfAq-HeGE`|o z3yd_nWc)r%e#_d%#))r1Y6~KNwS@OXfNy7=>9K~DihhbM;>^E>YW2+mqw&t_nmaPK z!`zFAV?N>4Yp5%LFq`})O&c(b%ALj>mO42pn|mdfe^cn)K5Hg6O>+fCF>-y5B$%kf z+8b<8PtINP7T@&c@Zpr)R5`WY1KhM8rGJ9ol%!5iELPZ8vM}R^t%_-;3Y(ncUyIeL zX43kBoGFg{6OKd`Tfw@6`Oang98j{z9hbk^7q)>ZT zcOqR^nq~aS8Ya1Hm%_L!OMX-Ta4gxD}_? zHZE+&IA?shP647bhXEC)6+2^Y4@fQ?H{3Y^VWRg{X33%0>P>_l?&9ORNPG#oxd;OY zVX>82EwQgXLY}Zd-uzAyOprg5oX0m+aLZW|6B>|YfSn*H!IqJBxKf%^Fjqs#Y8`;V ziY;DJ?+2dS_v>zOb|U9>7MQBJCyfEib9!RRelD-Yb@xZAh@c$X0@lIrKT>e?T{PEV zDd?102v?sz!JDj;SU#-bD;ko?p|Jw4O->Ya<2VxF33({>+PUFT5#dmC1U8a{Wh+R_ zHS3KfuUifY@05u~PI6phP;B%L6yuHg4yTSy753;U50(aSMv4u>z)^RO-1<8R*j=h4kg%kJKaN`26`szr(O+S7hrk+WeMSXzh zf4|&Xw7h{ih-FyX>8NuW6*j%^?H10~zt|_IwD6|LuER{ex}kEIr;KayR@|(i0dOQ3 zLCug8Xk!F_9(@(mGH>G&7dxVN4n$_WZ|iE|&+5}g6zEg@|ML|GZdw1*Mh1S~ww9Zj zQrsPeJ^0r$P5Fgx^`?!Wj}ZZ`UNNnOjXZ64M&@DlgkR_QX(#%Z-oHqbZi5~n=vYJv~ShndwIH=Zon}BGv@m0;g4Jwik&DnR!E-qfJ#GK%OIJ&{?9AG!t z3-7!U4Wx(l#Hbf2Xeu#GkD;D?idrS@qixiZIVF+GUazQ+kYh2yb3NVtx(xEv(s*wo z&w5;4ojbi?>CzCYsb>jTlP&|H$eNK*B@};|5}xbQ@2OK3CYhXt9}5Z0SmmG9qp4i5 zf9YW;s#TNsZv68P2aoIaC(CbD*m~tLvO~t3@b9CDs04D8maE;nq?1yDht*#nLse6hR$Jl2bvjb6 zQKI?%%2VLorpn!tqB3pl;xyjnjOp>uXeOo%(iCxOYNDOBls$2HaucK#jU=t+7FtB> zqYM0c_39~`bJfoshQB`8t5$ie=m!&#MFEK6MSOltefalT(w9Cqiw<9^j5vMfaoOm| z4s!3-=Zc9jp~cNlQ1d-%<)Y2!!m@fSm4U(sv@m-=>`c@(KSGXbx=D!$Y@5R*+FPC0 zrvo0s$v-QNkZzeTk9}6SHTTbAQ4g&QjU>G8Wp6zAzqerEf3(AMKkc)Ug~UtPevS?B zs;tj<7Bz#0BLMZHly9jVwqd4#(zQ`mFomWwRRsb04f1Xbm0FVP0QQ16j{DIQ41Gp_H;8PfMW zp`M;U?sJ1$X4a%0_gk21ShF1-Z-iWbJMpU-_IB)`CB6=w#GSW24-Cwc4IyI2 zjB5M|u2m`A{99%Q*Z*t|S4}W6hvn=BCW91aA33r9W}QR{6)h)wqH<^+;j zop6J7X|7&Cz@*?uU;_c;tbeC#0Mga}HJWTwUH!P#kAB{=r z1IQbthIEk!>c62#sM+4|mNYT$tW3@C21R<}m4=t`p==}Nj~JyWiNhITLNNxk!S)(n z|2y`^egAt@bN@@}JpAubbs++nSuvaAW@;+45?X}+fSljm9vNkWoR}jrpa)xv#;4yd zk&P@VrzZ^t%j6%fLX}q8#;CylHJZMim4`QOYkMC|_y0g*I92s-(IMTg;IbD;JoF?T zw00A%c2GON5+h$Q$l~mY$Wj4uygoPsf9WCYoQa+qMk>3#12J*W_hSasD?Wcv@6$rV z1J4+25zI`m1^PrsjTQ}~aB}xmxPJj>^{%uK2eoZ3qS_0-eQApfrxoUV7uGq;GENWi{vZP2Jk^f}ySo7+Ie}-q z6i_Tyfc?$fxDn!pG^m60S&prC-JP5qBc-~BI{g}Ou&2Gzi^{5+isqk+j&$q&QjUYGZP?YM>jnc&Z+(IPT2W?;M${+c4OljvP zZw1CXNu$|a%-A~c6=**m8&^X^{`x^~$I;;_51F@4>NmL4ewq++IyYIN$s8L}9?C=4Qr>gLyXa0NGr>7as9MzW1{u zsH8YOUb*=Qmri#A3%9_D9-a3<>N=u__+`v1W3$Ljn<(5uIhRaU?M2B+isN1vRbFhtwO#DCyH6Zu50JaGt?L?<2K$B_W4mQ_wDUa{{=$Ah z&|8Z6mZXWFL(C*FZuQjU-%@DumuSYe0K5m0Q4yDM^e9ts)6`Owsl$>z?`1Lit=i~L z{VuJL>*v!X!5^~(*JdZ4Avk*DM2{CB$84legT_QVbBIlMv-?-(5;Dy*n{1^T@kNnw4iHyF$j40dk4`!}lMXnN%QLMahP7xBzJpl-?gb z2>#Cj-e>=ELHfSe*>Y~5fS9r!3R2qllu~N++$riwn*%(>+bATt@@&o3ebX`Rl*%8Q zSOV8q-Cotg@}+4wbLcu&sJovWIF&XNjbw~!q5kHoG?!guqMVv0t*K5ybJIqBC^ALcPScg&_2RZZZM zQSnK$!6$pj$3>LD6V@dsp@$Ng20&nRtE=1FH5W8UB!B$6#zc4498$dBh6lTlIBg4l z*l$C%N2xi(!}L%zwS~8^rd6qx$aXKQ`=;5>n4$WwM8WT1ySqOwqH-El*u5(=V>LW# z$VeTb+29pkhJ5f?(RaMMxVHUgj1kx{FaI}refe|pdSodlWaBw*L=7Rm7{9#!g;2;Z zmx2gI?D11knY{|$!bJ;ta%i!iP<-pa7GAirO($YZ>)r*!HW$@oM$Pi<(>16fL=wFURcnqjGtVhyqqdYcO1K9DKAo!xB;13dnsh8 zoa-9c3nvVb&Bq>D%6Fo~k6!+~A+ymmXt`w4$Ta^dmu=ca&63|=hEIYu@&(RL%I0&F zjo;^!+&^em-Yn9+bpyF*AlNsjJ&H`OCl9g|AEFf>)~Zw@H(;4q$;nrk)xG`x{X1}l zoD+3Y&pm)h?j^fyC?Q?QlBM)p4WU%&d#!(qm|}R3&CE0^dQ%MtHF$Ip*EO%)Cgei^c|M<)e)Ddml#Oz$So|o~~R_Te(kvGJay}LAy?VKTXwkCdR*iK%dNN`ByWxO-z zKc*%+*OL`p`M)XrFIw|+=G5z$@n-hv>ele%Ta3u_FHJ7>Ia>Z-;YEk8@!y;C>i>Cj zLjA+@JbA!!E1$DtM>+*xGj^2I60Oj^GAi7!!!dtFVG#x&po*BtAj3Z%@rt3!KVg?& zweQ_QD%vuUc7+P*&$YU%(V1dn)(RDEfx6VDb)`!tC}nJ6`+X&=;W|zp9_+@qtmK&S zd=<`R>k{U;94ST41w%>81i~+0&VwnA;zM|hOX|l3qJs-*vh&?uHDV-9yup5{jm<%; z(-FkvUvVAdS@KjJ0EL%4u*lVf8FcZkN_aNm5=)#}37eqy-p(IHhTp+%rY1QHd+};2 zBkmQsS%R$>2yGulVt0=-Dz{Fkyp+aA6dk5c3KK@I7pL6FR>;if8f&)4sl^U0>38r3 z*JpV@r6ip8xzqG~I%yq}!0vOj4vhKGaMFT07Q>|rd&ct3nwK5q2As?2=^Cx3vatR1 zG@-?oyl(^=G^U=lLEf|B8E%q3k7g-LHa#yA<(X~vJ=^o40Z=M2Ume8YlD*55@AjE9 z`&#&Kn}W&CzWbHdAL`Y0Z)Z`Lso<7e%$62KZi(GB0B zM<2l8gAg)Cxx2@xLJYde>J=dxQlmp!E=Q;v9b{Vlfhm+$aZqz>RPb#v*X`kcZm4ad)~C)q;!)jA4BvSD z8)ON>8uLmmEg5K&Ovb3d%Bc}}p4+x0Py8Fy9~TP`Dy7?^h{`|=k`ws{#2b*+Fa7a6x_O%vQh z4JzsgZ6)L|moe5eIDE?(#cNuvZP)R)#KLT%{VKzDp;S3-ATvZ7zpK8Mxuti4zyW%)l}cajcI7 zMflR)xZ3MS+Fcbh=X(s4f*^UEwqBw>F(uMf^L=!@JWgHEp)a>muGmmt_q#pEb*}1y z;~1T%e7s$s?@Ozgt*L)FzPoA*wgYX;SPZZZTHA69!L;39K5Zb`&*ptEd+ZdOzKr1V zJ;(B2{&h$e%6Ql|R6(0MN>^0+H1b5B({&r$-`gQ>C!#dM#%`PVUbI@(v2uZd{tQR$E z{ZUV+-dlfHNZi{0e8Kc~k*i4o(qwvy+Ehk_1^#BrR_zTyMPX2pAQ%aaE)!^h1E z3k!QZl!EP1y?@+5H`Xe3_fehxcNW$Xn(6#}UZVbcUJ}$&NH)h@$#I>Z_6qF!2+TEh z2*+2Mwp#bzwTlmPx5YN;q(pgnr!V%BmGZWbVV*BsVMOWtowqDVePimL&)+trYYx&G zK-A;=T)4ekHIvb~8xBq#62mX_DI=D2bS!Vip>NkTJZKJmy{7X%0x&MfpN;?q*BY;=_qwD@-Q%7+Yc^;qN;p?{37yN3+V&2fv4#)%Y)5Wn3Y}OD2g; zHfo}_wBc#dz*TOJ0Pw-suCc)ew}W$8_~jk9*BVjJ;VUNuoI8E+{$<_Rq?h|*l9^l3 z3>%KQL#K}ko%bJI%P+Uj93nV>U@vtIkd%$l3O?M_`4DAC3H@!MdcUL|636YD1}BQT z1g(}WVbbWixiP+=h<6B%z1Fc!@hR{){^7R}{M~_3Xz;aiNebQkK(~17Blu5L7TC&PecG{lo2i04GbsX9ETc-7eX#{%9QN>9+!;Ss88Nq#ielD% zH$bn#&&cslcw4M2{zUY_5vv(C7H|`dh&b4khC7kV3F7K94s$ZMst%;6`l~^x@w39i zoVP@=D5x~IgO5E zKBApm$~YxTzXTz;tqCe$`G)Iv+{(UYIj)@p(c%va|4QR~FDvrCX`mXDrD ztRB?>)cQtJ*AqDLYBs0{t(a4SsGVCxIFxfl%|hnIGhHZ-sD~X^UUkk50{+2%^cyA)RDN`NLxt89?u#0M$n{YzfQ``_oF^N1C!O%GY^}nAkVtMTKWD@mHfGc zqqS9@svgydQ$W1wHY#jfhl%&vmF$87c!Ys*9Yr+g!tN9T7G;3&`eq+cg%;myfQ`}Q zKvN2wX81s&jl{;2r0*arMvc~fxrw&KH7F)s{nZ+HaRs-~T$!a__8eNm&`dm`uXNcg zzbwk4%0FzNDi{W3`xM_VSA)>FHN5z{*`(iD(=R7En;Aa!S|9!8+L|dQnC{jGhWrJY zy1&4$W3@C`@+S3IePY{Pc#jIRkRA=D2n!@r_mZD6_LM3`)1e z*GZh9(dA9VE{|gMkbQ@WB(_1p_U^CBGin^n!tvd12FlDZeZ}?9_nAx(z8wvyF}kE( zusCICng%ZLCu$nwJ=y*Hr_R)@TA#@!3VP<23?(zADLQSt^hjM)+UJ7>@E@qA`vc7@ zVLP5LNVg5ELhZ7Cf>D94=ih6^KI&ks>(8+u&H&5_-wfCO?woZqS;y_YJ@}FRr-ytQ zu9Y9?ONW;;IM$zYyk?eeuoP~*BC$~;iYy#32T68~fnvvp?$jADX(+RIIjq{!J~ZZx zXxh4!fs2QdCfxv4FpMgvG+se5#2t^PQB{7AfjJu-h!XC$;%-a)$AajgqJ74AdMRkm zg2cJ^@Hz$c=q!MbRKz`cP0P)%-n&-{)>69i$B8f(Cd;2Ka*`M(DH8PgqH)%Ha-zIS zvpz~QB97dqO>WM_VpdC-QWV<1UgBY1mZupgqdTr7T+22R-0~T!HIv~ ztEw^)IVv4*8Q`0Gxs8AE?%WnNojQIz95OD~bhXz=Tx7N|;%2i8)~W8QrCDJ%{j}H@ z@0!gP>F|TPg3jd&4N&Rv0^Ql6xSeX0wP@>943>1oG{SUuUY?nUZlJWxZaRjCJZ94P zj;f&zyb#1~qw7>Z_yir>xqPQS*^Kvk?`XC$Rpa}2ss?_th*xOQp1v>lTED!d!AG&? zww}f6D1gJ+aD^c_9`2%)AgPLHoZ*8LT7vIwPoJ$NpPWiT$!EK2a^Gwb)=fV-bIQ($ za_@ZjOPjKj!M3Zh+mPn9Oe`^(#{e z3)ZgZr3$n{zAvQx$W>F$YS@oIFm*3ZPRlye_w$bGZTcUK`_s?$+^=e;IqoY7G49%M z0IGgZv+|Ty@KZh0>bfqW*}K|Rg}-;;0*YE;!Se;RoiO&6gWG@YjProd*qw5EWg!@QN=Dt#9!^~Gp9&Nh8&A^@DD78 zBQftmv6NIr?%{>9crt97`s1s!pb$Ml0K{G%N)k8|nMg_al?%kqFF1A4t1ig*%*#=MyaW@05gaaGLLr)NAob}0)+WN;e#&LyVMI8t-wmz z2<2P6+`pk4rDg>^oBzneU-A0Ic_hFH373~PJ=S7^X<90&a#cZo52P$QdKBMun=95x z+v!7T9>KB*9qJoz5zlpSy1ddX$3?DIlKouHq-823&c3EBcZhxR9W=LZ2&b~!YKeL9 zfK({X=8k@WrqMc$em>?ZkX(+F*hRtVb8Ptmh@W-eBde_npG0}rEHlNzYP_07^$P2Z zX-`(_$oB9u2yNpB3)@K-x#cFw1D)aZ_4T}k*1tsfk-GlbMHWPCFyx52^8~(=h_XzxRGoRg8jk z#a4Z_cKXY(R0n)w-%DY6j@^(HyYnZ?@=)Ji;rJ7*N}v1R2;`5SkJmyo%zduSLaQbv z)8&>GI%pzeYiXtHWhYUG4iwT~9japUHN2u@mA~t6GBX8&M8|GLlFIlcxW2U$aP-z^t z_IXbRD-CE-{imy_QLMtR*r=VVdzW;)jyN2U?6{!@4* zs`Q-A1NpRduE1Hi^jJcBoEDJSv>moP^D#n)G@yc#7t$FwKN|Y@#L@{{g8y9>xL`Yh zUmOzZP66{QPd@Ad6Slu zL`5&`Kg!YmKr)#VXKUW5eE)6(&y&X!X!l>bLAvsqh9CHCBCS%P_ZZIz5@~aw^o~Tu zt-3JWU1R9Ifg(LAea(N-Byi#ZZx}J}*n;Oj=d}f9{8>^W+Q?{EBAbU_Y8dUi=$=ij>a57N61sG7k&(nk-f{IJoNAQc+5GqAr`am$S*mw)X>r^3hJIL`Eh)~lLt z=Y{KO=0U9n4XthZDF48a2jo7UK+iT&+wVmIbdUTJ>yvtPPzcG>e=rj1wVbk6?e z9OG;iI18=&JBZF3J!I!_(WaX4bq*lWri#O!!&}x>sBh*3=5qamGHW>5ny%$TIYRZ% zzJAWcXGaM)FPsFNi_^i92FpMfksAv)JrwsjCIZ-|JYjLTaLmYG;noYXL6g6p#ayea z_WcW$+0Qc))7wB*{P0#(_#jwYGUdzj{qAO$8xIerj7u)pnvySZCr;<*GrEw`(`wqf zsvP|XKR>4C&Og5e)~SAe3%t;AdG+j}!ZFz? z_NB*OMzo(OZO)A}C%NxDO}f>l*4_bRIhCoPs^M1J7r=`gW4(`X?{ioXSUhCR|M*U` z4A$7juYy-+x>E-JkxporoB?56Nbstarbs=^lFwghO2MK{#a90SFSX>ceUxkxRX$l1 zSeMD@Op7MA^6a>71`4vH^f>iX9G2fG4>kw{(ZN$?Wpi7nuyb!S83aJFZo4@KyWgT$ z41cj5(*~hpbCbmiVO=}HZKE=nRWdK?<6Ez(7x96;2M^_uQsN)GDXsqn^Z1AGloZq*=sI4vf>j+&_>JuLRkQOGyf4H=+DZUlar0(ajnVOm$t%=`?ET#KC&85uBL}Gk6;($NOW}>C) z1>l$UERHmg;kRnl79FH;Cn;n^tWoeoK?oHbjzbs6k^!D1`hD%wV(NNa(>`P4yG?V> zwidyo{rJ=+xYBW#=-MLLeja5bp?#6&x;ZiO*>59qp(}e=C}tQ8vz_TNoLV56s&`fh zbpo(ExNP`|hXCj6(W8r(zxv-EWkiQw2s2g{|9k@IX8e?y6!OcFq}jW;sKRyfq<<6j z)?6?8M?oLKRzC`S>_SF}ujYY#HvbILzI9ByGi7Gdxk3hS%OY&LtRN4g^$GI=%~kJu zy8&;fu`Ebf+y|qphy2MQ7J0Rz|B%rnC?PeKDs-oSvn(c>`}&7Us0EHo^$FMO z@boBm(=%Dkjiz0q8=z`iFeXXjQK1pcha5nV79pICAitpE5m57O>XOR={JnInjwD-o47oO?#7Uk7eLm3yd{|AH?|O$7}5v4B>I72 z8cs(MO=kNdbhDy^)^}~Q;&PmSR_^6^j=G5g>;*TD4N;zrBYWZ=VY~J*&f5I8M8!6` zn{c@2!l{)C=#_%^bN{_Q4?>TD&i;t}EIG`~q z(&b05oFlFHH7t`PAlh0YeFQ%xmB}|(9e#P99txoWNo=@FD}gGl`(({e*XS6s!aX?D zn>YV&PK&%-Evp5~y3+ddHGN74c*&l%848xt_LcdUB}Yl8e*EGsK0ga_<99r_P*5L% zf)Nm0-mQ;Oe7_psJ(D(Q$HPETU|8gH$IL)yso}XW%=olHe3fW)qdUU9^|EvFk@9_G zJm}(lZ8fy2rhDGpWj{syYx{&asRQ%`e8_?Cg4Co_VA=l9keCIs2>ZP_$M}9C6Ni;> z_f6=tDcAXl=vx{)#B)+>DOJ~oS!{FU1e%DA)OfJJF+3msM1{zCk_Ac{0 zu6gOa?$&h^XuH$a+?SFrk@4@;ZGM0#WRGRPC*4J6`$&pYNZ8h2XSWBxhr1G0qs?sc zCL5D3Ka0b5@(I4=~FK2sQut*U;k_spHMeW_o z7=WHH`4eIx6q>WlOVJQC8Jfa#8U3gy(o;T8OyU_5b_ye6p_YA>z8e#2)!ntWSNQ#J z>Rn^Lgr+#M>dQoK~q+Vnj)3 z2y@);)pdP7-|z2tyZ!$0pZ&4-d#~5?@Oa!GH@$^U7+I__dqZJ{cKrjvm1KYB<0`TB zDx)fmcT2EkjerUhtx-I!Wd{%ELN6Hs+_G129__)pX-=FN?y_s`Nsu;ag47%h_vxp# znD;eMp(n->`2Zb|iN^jER1aGIFgr$7Bp$uDr_#TK=&~Ach99 zIL)1_i2aBa|Jjh05_UHK6SYNBg-;jW`dA`7=X?)=gGm;LKGgB>%|y^&fcmR8e-PGJm^IqguKwmE$2XRsPV5SD2wWd zZTgWDUjxKNVzJU&)hv_!Usypw(!XSl)U=9WkmK$X2FOF`J)`sB3(+ge?VU1 z=NHub<9BQhAMd;QWaI>}qfOBCBkU8H{JdY7%4;j+$7egxCSs`R=p!!@d%N~z=c zYG~vw2OKt(h(Pc}!`BF~mhcC4CD|dq$fi7~2gtsNJ1X#gZ{P!KA#2rIUwPz0_G}%Y z+@I;_3_?Q!>We12b6m%W(6R&d6(kX-=$3&`RAy+)+Z)Muf4!% zaZEb2V9lmE5-NOc4+#8p{!>4ycA2V+Dx5L$FFjWU5J+Jy^CBOY~P*Wb(V z{@#G;gT5z%?H-IPM(_{9VGq;X7JQ$P(8-p43vizij-zlx6F2)j2W>I}F7&m_@~;De zU;hUO#j^mk1po01lzR+%M=b9#v?F25+>E|FHsx|oK!c?U$oP*2xct81%Vz;6bFIkV zLb*3{@S#T5Uw3uAne;OZk-_*)th2XQW1s&@WSnLi?tb1stJYW5> z8OgPZBl^8hGSq)mU(Z+_{XIxd2=fT02XSj&|Iumm^3=98bjCtxu#>#O>m#oiPu zp|oIHF8h_RPR9gnmiHw$3$i12@O(~VolVToSrC86Q0Kdp0%P7>0Dt=T%I8u4&A*s5 z{J96iB%#@-wFng6C;SS>vXfrJmddZ5(#IxJEU^VShxK#0i7%HAI!8>rdB+MRH@ET` zk_U%v1v^U=R4BAmSMDeIhzRxTXYgrrY_V%pZj><=y3j{^3Lv5C?*VzcIw^E6u~a9I z74<@K>+N^pczl5^*HgMGdlX3T3;l&qOa4izbP9yBrYb^vuJ8~6%2QiLz)m4!*m4}n@fOypQ7bCcGQ^U6`yBPd255%? z;eINsBz>s@va;yD)PXV<>loV;=Jn3%Mwn9`v}rlL6Bb&YgkC;OXgrN}>9za@8=0Zx ztUk=q^iv9G8xq~MK*$7;OrZ+5KcIphq4~yL@p0w#C;z9+`uv|<<-dDXT!cF7_NQC? zs(I=ID&GHYWQx2pK9YPIonrZ&n0Vq{*5g|9&U_CLsIoUmxY+_PbcS^gxb071!z_ro zzu-eJR^a^XRb>7AP95|#>qqlWudQc~{5D{p)G*;nU{nAsRNEVU54Zo-f z3T3OYV_`n%)DrHMN{}w&s1!IGOJ5bR(=}E-*u}lHu}WW~N}nPOGUjHpx;^KWq&8~2 zBVyk`ePnC*wD*ab@P4JKr7IS+FVW}OPy0Y3%fyHS9I~RNvQpjYPu}DC1jYEh$2r~A zM_k-%FqhYDM9DC>8fIbARdB5xia{YE3m&s)k} z&moF>ve5h>`IZ7 zFqt|xB9~&-&HY1zWEwaIA6sm&$nh?!f7Sg2`6aPJq8*}r`;}JC%E@L-t{v2vCAhy{(0O9`;xI81sPjT+a|NryrG>M3RYXM4_ z#+R}xK(?HlH?QRFHB+v*YU`zR|A8A1$#-pq`nAy6=GPax2r*_Au;scb<%E9C+i);o zpajeJ9qACRQM$&B;rVB4ydun@z|Tl;UJX$(e9N@C(i$<0A4=`i(7qQpmegr1cR8k* zVR2elFu2*c)~{Ym0m@r$T`q0>AU!jI8fi=YrQ+E=yd$GaBJ#2rAr=LxjY?g|GuS!A z0TaybmxP^t@P{_?0qrBOCF`U^irbxDwImbv8Hc+)3N+*{@xX8&6x8-)e#jhL%Ocz% zrFbKfY?Tm$ikQZ3aMd7*&-DHuL z-Wewde%Ca#V2_Ym)DyHr^MTj(lAvV+CcOSLWYGvEg4Ltzg?k+pwp{yLYGM*c6?j(- zNLjO1f}j=LA^fIEr@w3psu6e-SLLr3YFqqMoFJJx~{I`sqccDekUfWt_H`O?;rpMnNuEAa84&k z8}sKDIYdLZ+-6W+j#Vq?miV*&^uq9uw}$8K+i^W{`hUBq2mk%NpMkRZs)@1}$U=`C zK1|-`<_5g|+;a~1nqIvQQpzWY{UKIXjvFg$CFOkp-*#7{Cd+C$A&3VLjXdlC$&pTM zb0=#cfm&T2ufEXPexaHC)9WTS%QKk;Rg7$wRvwa;S>sUGjfBKJs}Jp*xKb^4WdWssy*)yN$}XlHT0MESov5>a~Vh1=pooDGrid8FZa& z2cL&RM$~a&PHj(y%Bymq<8%myOJ0z5MM+-}Gi4}MwRu(Vjf(|~wdJ!W-iB(T_!e0y z5RN+Bvvs*}arLvS)f9w6?vM{+85TR}Et=DS9)KV5!dTs1nioiav!|@NptoU}m;@3( zOG0GUi_U;3@U1gAixtz&NzF8)`7Z9g9PA+ zKYH`lk-NZ*&Hmt98@9tvZvO>T_g;{nD^g|kwfBfv{^YGdUw+><)a!+Re)L6x#lp!N zrCt=IV9Dp0%je{)(OpeHL)Ta4xTv*!XW@4u=%9D?ny12nZPB~{Ku#F)G2&m%{%4Uh zY-_GxbMAXT$T>Q6c$=AAa~*np$2+0L~mZ)f*j4rxTSo6%*daTzG6wAX}A8hRhrr( zqa67WSf#N$2-g=SurC2D6zv^O$EaE6`%D$7-%uD7fimT4caT>yc1+;B zq`+gow_)23sOf;f3A7bRF2KWDP0vui<_W;7W^19m;g1?qWg8j$t(7**qIns@1Y#bs zJf)AdD0J3Zkj{sK{ki_;T5Y>9eXW2KW$9NAvI1P*X+8K3cLz(Z{5)L(j=6=(L+fp& zPU7%f`fZ^@#}W`Rsc6#SgG7$D8r2l*IC6gR0a z2dJOO`N}6}C{ei;X zoxE_W6R=DtZh2MGxv6}4{_LJ!KZ19S`o)MP2*`YR**#1rX{q~OIC>6u!?kvyeP-n( zJFV-UsYczCaak(XBs zKK}Qhc|nBMd>7eY2+$*iafr>4++8Ic;f6}?Gz)z^PwL^4e|3i0CQ#Gbe45BE1h8Wa zc{e9yi&Kc^++jbw%w~a1Jgg=s7jRvdkrrs}eE$UZl1yfLe=>5R?85F8;s-Tm;3RXI zZ@PCMNY66nhZB=2eW7vFDtyW9eg}|EitEb~TnZP4^NE)MfqM->a_sz^YLL*3&wn*C z`hliQp_Po_!4~-FYUykzCM@U@u4zFVw%v*vxd?2RqbBu2I-tPP_Z)(}vA3?Sj+`Xe z|LNP?X7X7uR-eS2eWFJQivvVdpE?<4CDNmHITG!x1NQh2y4b$0RpG~ic|1X5g78DN zy7Mxf=j@7ZD9E7y7Rhq-6uLdDeXh|y!lt_X9nzoiSVqM8JQeAUj29>p?v9Poa2(c3l>&O&CF0GzNCeEG29QX`Qd8yF~6`7YZZ|m z`3*XV!1+Z(41U*Zcg6W7@(P;L$N+t?AmoBg$mdRDW$$iz{MilYBUe{Y{Y#x!%-YbR2&P@PWUW@@bm4O{?qb5bEGXkfD-V z#ohAL}qBFUhk^vaP-w5u2|-+hr;aNj1-%?3QYNK zwgCsweLiQ6+X8&l2}q)zT*8B@uNSwfVP;<`NxhZd-n592ZQP zv|fF9m4x|-= zN~XJ()!-F2E{Azve2rV7W6%I2mS}}FGx@SIYrIt!L$cg5!*DVbCQCTAZh6QGosf&O`VrA5&n4-`36`3^^drdI@T$4D)M}J@Co_|6 z9%s$|3tHZfcA;}FjIwNNDiH)Ebir|VR_5u#<#9s}fk5E2+Pt;!7jJV+pry=Eo`Q#e zEZXIL6JPAry`(?{Y~YYqu%rwyIXkb`7t)1c*v8{7aX(T3K}_Pdelw20)FLFDq+8-n z&~o?Au*QxDa6MloG|1Rqy@DWT?#TzMrugRxQSqqR$!85}5Bj3Knh;>0G zkjzF6VB+TkTI1EaB2vV6nv901O~<;pPKU^fD_^Q^y%SVHPC*l_INcR_2MJmWC9WB{ zybXn@t&z4H!N*acYi4)XZNHYCdv%RgU!Ik9IdbfZzbJ9JyQ31t`CuRHC_Ue4sPt*? zj5bfsFLA6vo&ewf#q!5hem&U1n8gkb!OHjJ$^N6IAIK?a(|0Cs&F{v1+cGU}k*C4b z6q7GUIkF0x50VBS|En_u;{1>NNM!x5{OD_>9Zq~qLogOwvTfU5)v!gxo9o%Rx&B`g zKaqFO9w49lyqPT38EIw-Vq!4Pc&WWTLX5y&PEFKwxq#WZ^9P=vskrs9gTY_q;iJK~@sQUKQT3G^pn@c8{ON&S;!Ht`)`IYscCLxn23k z%?Ji!adC%Y2TV{Vb5<{FT`XzB1~$%(s~JOh;c#&|sVzQn5q!2zjaxolg_tj~wk_ZW zF9Hc7>=-XATY3U1pf_S`3!G*nzDLGL(vs6NMd$P3xZ%tFbHozfW+ za+LxCmRT(;_MXg1z-RZUNFTMK%R5wfqpM}A-dw<^OWgfA*~gR62V&eA2?+`0 zYV^eqhwyemW7+Z1UqpE2W{x*VX4q03H8DqQ{xHloYK067;s*jS6Iw2YH7pap1Th)=I7cU1`>6 z&!b+R(1HG}T+=aY#eY6z-B1#pQ#FV0Tw)lppT2f^zU@pv9ho5Z=P$l0O(Cz3{{uhx z)E_@cfha5`9IQhT)Zh28(70`FmFR$+;$Go;-4C@*5gjZ~kj-E&cz{pb>H% zSQp(h+LR8~MJeuz)~preRwouwm}*Z`L|(eL^d8+aeW%Up_cEJleEaR`$$?<8gY+?u zELlD+t#i!RnS@K8b}f%s@p>Yb#TaYjH%Bn|MH5FAc#%Up9PHvc6T~MP3TGNL+MZU) zo<*n~NHq=$8oGec%DRgih$|>en1`JqvT&rGcX0q@YMH-x zb*fTr^@aOH=V6w6f6~%t30b{3zet=jM0%g3qJ2CFg>7|zn<&g0Ls;)^C#Wu&T6Vhd zp0QEZeJMFmKjhu(U>?5;l&E`Mm25v!jeYlyMh)yesS)~t2=g-mdYRZi z->o5Vb*38gEgkv+GAaK$={x6iZ&by}=oSx>>gR^%r>ZRFKc&XcC%Vxc6IGeC>DUT5 zBvY?Y|Lyx$D^(V!Uh-{GQ-RBCi5r&xOz}2m4?X9EirlWy0_lUfe)t6yuva;DUN z=ths$fxLKZP6Hn3V;KNO&)P-WF&}R;HKH#!VyICA6C>Q(NAy5e$PZR||0(ErCmS)% z+eiMBd!rj6M64miU2)Le`yKmyhNU*Kr77yvNblm^YPSCTYOl8m%f4Y>N*hO6LjT#Z z0U}}b7ZKFu{HU z0JbASt;xTfVPcg%i11T8vmQ`gRvdxGi(Gb9#<%wHEW*OXk1v?l%p9d<5Kfk~0{5ux zs-@`Ywl;JrvhexSst96+=OC26@;T&ey1Cqi+{QuDE`9lT9}NC1_zwW;4X847G4Oys z2`o%ZB;Q6G8K_*I_f7trA z)`Ibt1ZOr{w}>hClbfj!`SpEO7bt3z8Gzy&BgtXu33KTQZ9sN6V#*M|(`v;d8&~-I zYrcBcw!6j5=iudYP+XBCpFps)9s15`^^(}T<{hQ@YU9B4zjT3iG)p5+vlUruPJD1% z<3S9*)D){Tb+*+KYiH0h#Gjp}>@^c;7Pe4|w~|}VVL$E}rtq)nfYHVFU8mgKcN<4( zSi`z`&KNT{pbDx-9&tg2YcOYa)_q+gNJgu_#l2}F1U;ye3ELp5&4Lp#@sXqad^|{; zie6D7702qd?~!&Cj=(L7^v)pfxu1dryK|Duw!?gFh#zzsYC8ijyE+AvG2V&Q*l+n( z-0_9%QjHcJsIyZ3b%_tXI_L;D+q2d6fOqg&-MFomNP#K-$AlNJoG2Ty4((KSN z5%X{}^TsoY)q3+JS)Id ze^aY%|F2N>wux04G0^T17gHVYsw$L4MiW&_#@W*x7HxlGg`4wlsNp7R9JVR0JRVSxyU2wt z-#9fKf~3PO4C+`#Ehpgu9eQh*Y&wcpH4c;4Zqbz9*e?C>(*I_nn}u=U>UA#wsk}bj zlA#hLL0l)kB+~#4hdJ@nJpR<+vYJ$;17n!7nh_{`IuMU-iU$Cz-bI>#V`an*3g+!5 zBFQfrQc{#VbiA{saXA9~X25H^j^E44|1?Z|zXXoyrC&8#F4aNK89bGlpBFwzE8x-~ z%u#Nu;4#B9NcJQ#S2z`7C%Ae2sBhUbC3jP*8+1IcKr4b(ze#bw=$EpxnqSOGrXP>) z#g?C&{rGSX`K?fd#~R)yC$Y+d_{vUXi3lIzrAxBnxWa>1k55mp0Des)*EYcZ1UXry zwl+JT|I1kf%PaPO_>S{nZ{6^t{=wX+iu6p&CyeQPo*%D~yy+5Th`NMN*GzXYSbcXYP)6At{qJz+) z`CMo2h9od!lEf~qShcsCvzMi%0X>jr-4#0P!sh$D!l| zb!Qj8Op4H2hA`PwybZIMOtRZdJ8)a1D%d4+OO2N#wxL@d%~pMH<_VfN3f@02*m6&? zu7{HcW5-A#pRw;htIxVHvEAsU5Nobi47PDn;6#zWqx(2OZ5U$T6s}wi7yBD^KiE@Q zX{&)@epnAe^wzK6EP1R8BG(@+r<)it6e;P4rokoDM&3+%KMuW@RD4(X6Wn!z2;s|3 z6dp4jiVyXPi7V&}5=-gak5uJ)NBR9KaAhk$ci* z%h-2N&sM}tR#<>|Tg&fEN_*l9R!&IIotU@HCpb+ggdM*D(P>x1*^&9I(KvTJr?ED;*J}4y9k7ftU#OcU$Z@4RcQ; zkT*%&F$RONrq@4Mi)O6R&3cLpL@E|u*0cLmg$c8@1)M0d+{1|Ch9beuA|N)Kpi1u{`+cQzzC^6WhoZc%H@@ z4NQ@aSI_IUkMu@9F}uxVFP9RO?PoaXi>dMN9Do*dUN4>14aw9GF?9@_4|j3b5^;7P zgsmL4nsr+jJH))5O<}Yp^@^4<+?SrgF7I`V$23lHgZLoWc6J|sYSxs0mLNOy)6XIH z@bf(H=AE1lMBDwGR`0bnhN}}ApxtFEJ-$9JM2u*Gz@%gLLa5E(KTtK?L#jEV=ye1k zj5f@u{y|Gc4p!2tr|7S`qVL6cFSY9TVUj(Mcdv)Whg}w>fRo02?Uzrq5?GTAu_+%8;s#|1LsLoodJ%jS%U>D=}z8BN|U)2Yb{n5w27W5?cKTWf?%DX|iRoE}g zWx>6x+$1-1U`t<+i3*ACr#Olhu=HV0fvsAvWctAPg}3Bslz$$wNQ#3tKCQeuo+tQG zjx{b?igOtXEf)MYi$y5HDmwOhEZ5^z&%ZBJ$*Z?d*+gLc=)bYQFp_LjT}h9;vycuz z@|eLmEB9Rz>6L~(ScmjV{!BI$6^_@95{-VTOd;!c%m$ahSt-2f36XI8yQMhSWtxn% z3e!7<_Gd)~XQXMwf+w@IvhW0EN%{J@{56Srd5c6PNQM+aC6@`5A?nXM|~mY zn@0ZRsSJF0XnTA2gA^gL6`4?JxGa9=wJW)5Bk+U2<;d;~&FS(bC$#k|*D)o3NoJO6 zkL<{xU!4kM*Ed(dpYRK46*NL0&KpGM6)2j_TKpxRWH@dyBgB%_y=V`C(E2Rk_EN=u zJ>{^Yw;CUXy>glD3@?405C(lAHYK|p87 z^Mz4hx|rB60Y}lh4q^QZ>dN?MsK&;c;~g6Y#kYYXIqj(dwbXV|5FP&!8Vue zLH(R@50s?=Sne_go-5zZzw@V%F6AGaKEmf9|MI?^8|dwcc0ZOL=KX zDkG|trCW20rKX2fOjaoeMqb6`2>4UkltogDDjU|MIYb+t_ZE*H{hD9VlSv|#vHh4o3K-gn#_^=&5>Id zgKIJ5*c@f;9x+GFW>&kof7*ixnSXXb&Uh!Zeu6u%x{N3ta|{W1lx)T6j@L4iovV~y zsdb}FR4O*iV=!6;`U?^+MbAu+GWjmcNO1R}U1lm{?TAY3`($zPkjaKKylk>^BW2?( zXS#L=LHir+{gbooebRmY(oBYA797E|(km|~1V#%1__5`buD*T{q9EjG5jGPkW*28V z*e9fnvuATFYy?5!+-!a2OFNGS1>p%kRP#-hh{*UMd|Fy3duCmNwfyT*T}@5F@LPTH zs$I(n-p9eATVLP6o-c#4D9|L!&{+b)B3J0i`SW;RBn;P?Dwz^cHM^M+Vofj{+IKP~ zSeOO9-~NM!yfMMP0MfT>h$5CZ>;7^MSS4P7ZD`lVI50D!4lb@8Wbuy~FGwpD?ClV0 z>hqfy!ueZ9^yprb)otW26DlAT+$V$9Oj%;XsoNdw4DEX|7ewTe8f@pFJw8j(8E=-r z-0uV-TIJ~y2T{FE73bZ7Q)fyei#nHJ+*prH_1J<8m=~|wL)QJD+1;XlXLrvIgW26W zjdG&j^E%jYVdAkbq=>J-*VH7DU*8=jZ=Svl@J8;Q0Fo3wF+4znd&6k*1qA(qR{%Dc zTnS}qmi`!auGz)A*}Yu3^;SB$pS<*17f5l&qWiX~-M;-n=We*by^g$=*8P%yu0gXu zPB3;zU{EEkSF_DMtfh7tns`foZf%EJ@hZOpemi0dIj<@>hj_!r#e1-JT{OQ!+)e|6 zopy0b5~Fv4TrhEF55j20O@QWe5EmYoG|rW7xWqN0naMypw5G50)k$vHBr*HG;E*>+ z*f?eQvmCmDBDj^OHC^Fh+ROWxOcm|Tgzz}Ir9#{o`7;(wHrxAxL;yRzJ;hu8;zlPl z5G*&r#`kZ5_yNrQT+LP$Ff;541qQ@D>GvESmRMYyGKsF>n%4mUTJ7<%%cW~7bp^r+c| zD*e7-x!=tgbceRszXd8iqQI1kZbW|~xSK>+UDYdTAs1J!OZOmPcOVC>5}Zur-UY~3efel}*CWWF2+l+)BFWrnN^4^spD|BsD zITR1&pZjF_j;2kLX_^s!&335Wu@S|zJ1C(N+9%TpQ~R~#C}*d9H&Pi5j;#Hq`%Sn6 zFa02Oqxec(WZRLmf^74{ibBhXo1L8EMABxN#!3)e^tb+j6(PB`dz5wK9BEZF*!~kk zMAN~FL*3Gaft3RPCk@lI@}(N(Cwn+A*z>-Zdu4yi>kYIBM7U1lbrEyE=nf@^XBW} zIC08kQI^XyRFc(T<%@>%Zo=;@L0#exTOdE)UJ8(O?+sRwvaF{Y>zg8mK5Z9=OK(U} z=if5Adl+=%mDq#2uU`277uMngFcwxm?z||PEad&qCP^E6cKf{`?P(=6c;Q=LA2~H? z+_vR-zQ8haifB|tJnF(t4VUl#OPZOI-mHOLh}f9R&pnU^M7mLq%0EYXU!P<}MX>^@ z*E-L%;l%wqD&m7_PS7GXae$~IR&-7cebNVCT55FbI#0!g%Yr*z@=%PfDxNHlv{0sz zBCgMCk>HI;)A-g2etor;uYE1io)wp*(ek%i&0a~BJTj@z)cy#X1`IUty9)375~+sU z1hWkO2XMnU^mvj3DakmFSRlRhr`viwC)`)rw_=EXdB`mIg zqejsf=Kvj@))=$ZHRZE3^0|b?!T7Kr#L)xXA~LYje|F&i8^h^^0?`=dg#27tLBMGS zL+;E^LsvTQMV zS6<M*axov{%1Ni=Z^tmiWm*%Kgig^YZE$CbO$9&+r5%br-d8&36dLPhdXHwPDt3 z45EVYHlhVcG>jKk_p3PsABD}dDEb$ZnS!4T(y!Fwxrnkp{UKOBPhH_@Zus$BFC;0P zKX-rDS|iC>RQJxMwz6l^`PEO^HBU9kR}jEpGLp=Ab=bBMqPZ7WysIkO8j6Yl#!cUF zCH`P>*ne{GS`(|ErH2bBJ(819FU4-^@WHp&RC`4Qi$u3ja{@{6m5V( z12WHAlMpkwIFM7l79hx+&1-I-*+U=W%uw2cO3&vA+aP7O0iZksyNjCc3G8DSBgj0@j7B{g`(iDkP9!DuS^crd17S z1Ga7duzn$9mZfy@@kqZy!WtuLX{;-qJ5Yg;3l{n)UR_oUx<^^GLte#m<|+V%FOXY* zgWE^XEI2zVnARF*-2RPfgP-G&LYA%h+lE_%jT_dBn0Otdz$Yr6>Gyh&THQ9QKvA9+F~L+8s+By1Mf(>R##saL2H%0 zDT~(Y_uYXgmMV&#o@E67agi=|QYmLwin{*V5)lq~1);vMh4qoGf9%D4Og*BTQAce< zo+;rHQ2XvQd5G4H1v zYsrTK6Lty|O@zQ&Bm2QwmP`F`I^@Koywk;ma;pbtRhquHW(THd%DS)3xs_IeOS^;# zIgAJUjVd~z$csy4THb5$HcJwc7f42>?=%$M#2Q#(W4wR=VWq29>*i&$^EcIG*$J5M z&N}{=k*Z}8K~{(?lf0C+Q!!1{(4QrE z6cP9W1cu8=k#NX`N5vQEs=#FcV<0z{$LpDywM?8+CkwFAX+G?jJj`RwoI7rV2&g-9 z7GkooV-!AlKwq(uqN=swwI%>d=YH>}+F%v*OdnD4dD0ae!9&GUn0cqe&6ZBvL665c z`}l4|7@ybtZ5y&K!a8mSzv46_>c_H08{J|#84MF6ymwYY5Qj_gwcy>vwLt!>e?Saw zY(xdtnJvwvMSKDF<$B0YqZl&kUoN>SjpYc!pc`40lH>r)p>4pM4l1NZzSS($s55H? zL?7wdRcGzR9uB5aX`1QdRP0*B7{^;`TEoWn3#uZY>nmP-AYV7q{$GElBe*v---J8| z_lAivHg|0B*P*KT6~_p+$F>pRU*pA-yFo-GG#(>^&)VQEZ|uc423ZN2kM;;Dl}W%0 zn0%zjDsah6u=musu+w&lzN&Snd?|(*altO+Gu*-@rrs4H;U>hiWObtPV^W`?z@S`O zH@&BKUjlMf|E16ncYr6d>P`OOaIeF*oIgZx`7{L9F5+?Y3hIA^AQ_#N+~BIOn)dK$ zRUVaU(;)o}Y48i|cjG`lrC%8LrN>`_%P|;b#_2l1QQgy^kf3(YU8p?I=9wBkxJc}> zASj<9USQxMYpfKS_DT0`m-cLtQpup6K{R@!^1Xlh!-?ZPNx>v;G#YR z%NvK0SsN5=WYT)^%_>1PxtCV3gFV6vN^mkqGg-ir`S1#S6V8w_AG@^^Hbn^b^Gf1D zTCFZ0A*$xyQ>&|{g3!lHJ!Bi_`iFRF1U}RMDK*H^gPMNPzOE9ELQ{O* zCcVBFjCy4Iec2>#>>S0-vIIlIl^u}%-)^aXs@tR%k%FNKlxvpY*WK7ZfAf4mtCKJ& zgo`(v3pTYW0*||Bi$ma59q+y;BX7ylG$10v4;Bml;ifqeEU#c2!?+-VvzpxU z4t^o+g&G$DbE%))Z!Ui^9lW>29bHeybIBYx2frH1-ayRJYp(IrWY=Fw#cPOxMkf(#F(0O& zSGYdk6O&_SAiGabpmGeY?3$L#c93_|2z|Xa6O4H!w<9|Jg=yK>g$=tV{$YN#Q^S*! zBENtNuDo%Z)Nv!fQ&4{pl>!?A0ch&yv=H&7XLTLp#`<0{#px(gSK5;8EU`Of2U}e% zS`K_Y%DMc=OmYO{b+F>av)$>Iwm!eqTdhsFWPo*Um)3WIfQv5S%NYvqIHpJDjPBdT zQK{&T(sZ48*W(w3RZU^VasR7JbYozz+p@1~9s!+agofbF=`-+muHaZ_*`M>2$yXne zQE0CiNqHSZKfmb)<3}EVfIRK5ZV?!yGyvy4M^Q+5P+7?sD-YP$I^>=q)NwpdE)zp7 zbmH!I;(?RyKc<5*+5E(~di#7Gtpl|PHpg&uxCi9%wrjSo<%Il+i^>~_RXB~FMF}gr zAA~7xg9VOOR5ZqANflcJQrH)PEZMrI~m^6+=jj{?Y{4ru*xkBRnMbD>~X zpy1{nA%GrMd(I{<9e|c!WB7lzO89VB0!*@REb}2Xv5y*Y{Sp)v{0t$;vrRYx{VCz4 zQ^IM=fkh&xO$7n|{-~w<@*9-&L|-xd&-U+hZp^W1tObI7Cq!%>iR>-_ z@OZUW8<(aPF8KtMu2tEz7N9_hzz>*1*&YO~VCBd8Dc)Yt@&wQCdkIa~l9M%Tl-Tb9 zkkL>*zU?CUa@BE)3y*tolvYz1vix>7P3aLKO>z`;YLO7_8GP|WLWVb5U&xE)&`qv1 zSHesbl!Myx&qua-Ag%KkuZ__JlmFVuahAbnwMh{}${>62&Yq;S`cIJno8lL!Q6LzL zFDP=GChzDXY&xnoF%J*|hiS~Vb53S#vtB+A`pf~TOOz;|_d&#E&IW{q?;kmY(;H$2 zuv6Wn0^4D#V^I~=#UzEr|INI&cfTB;E){7s!6O|9f9LJA#k8A_=kCJDacv zrajYx=Ya+#L8tBX$$!-JtM$@&D0n$Hb_F-R(>j59GeL1KRQ}S?`?_KA0*w}KQUigT zRy{M$`bSUG*qr!ooE0U~fcf7wLr0bazQV+Ojy#35*1@#E^a$)YRkf_ThK(uzX!wBE z#R(bfX2H{!!uaX9sMGTziY)R^k#_BTf;q%?H$&#IAO0x$3y7 zq5=Xas$yJA@~=7m(111MP%AuOvId!1HRdR|q$@P|kSjDwu;iZjj2=}gcFa+xHm68T z`0~#Zb@B}#MN^epO)l8CO1VQ59HYGh#$?I9&0xO%*)5(pa9?{)SAdGvSAzLnIF^nE zEoH|V0GYWHo`XyiSZ7G@Z_{>OBfQ^A>x%+}H}t6rJAj#B#{D(lvc0 ztUCB)n?3CZh-)@p7%*N+K=k<5~Yq37S8lG67fFBdcyQ9i_W>8IQ75om^c5q zV;X_l=$eUAk8jiDpsP#xy8IyOs`|yEsbFNxR9uNTG8zJL;0`Ti#6!$OildiM#KS

TJlax)dWtK!?c|Sc;vuE(b%?W%;h0wNcw|Ib3`Qxb~P*?pa!xTf!?QM{9fV@ zXaGXteD*;%iht`+r6izC8s`7gcVmx=jxUyqT~uilNv^=i*4va7_sEI=H?H{bj3uo4 zd|3LpfRUy~0Z?=Q+}^eR-ZlDd5M*EHX1hW?JO9w#HDLc3gK!1@q|#5g_FCdo)6gr< zy51}Ew-BA?Fu>LrFbNvOp|wdWO3MmpSvqX_30wE^x;~4(AfwVY3jf@ezh6seetfKB z0tKzuAv3^SCzhFi(pSyW2)r*R^+LZOi!}S<1R1{a$1Jw}?GrSun(^F9+iAGzt`f7R zt7<>a3CV`bcF*d|@9`|;aHSx-wo>sfU#)mNAN@BF`@DaC0p4JIngeAg%rXL**TkPESf zVDiRHL$J(1sd)Owr)GLkj=Gk2AP>qJ!tBQ`k9JE%u>Tg z`|cm6^8iwy)s@tGYKwFq&=x#AA#z#>n2R9W9p(#X8Cpff--g#Rlj9(KBHmhiw6nW6(Jv1Q9Z7gAMP>?l?>(9e5A4}8f zzE?^qKT;HpFVKT)>4Kz#;Jn(+;+*iuWN*g51Xq)ri)O{6E)HDW4DaWPE*T3iZMe@) z^>!b-FF3xDOCAtn?)?H@+zNrk`e``p56nAJ8v}zJRdKV~a!TJlPJA%1mVdY$$VMfh z7WM3=n&(Qu=6}B-98hGwPbOpA`P9oFG2cHz(I75^>8Dt{`8N8ONl1&}`$f#|;ir^- z`e7?~&-DRegnZT`vgtcuT5NewCEid7vv2N`{DMMFMD%sK?sK*JbJJ2hy-A)Z# z);#T~q)VXN7aFWi3KzW`Dh(DmTxQ`1i9?(J*r(Xb!?2t%XNoFOLFx3@B{0h>POo$Y zJqHeVPdYX=ZdF1{{2#kCLjIsl|9H~%atY|EG?LJP-)|}Ic4)K-4DMd5Mr%fMO?+66 zlN8@RtW(um?UFiV;Kp0>sI#$cZ^$ByGi#~jw>aJsLW>6BkbRQf>CCE{X0|;@J1a1S z4xAL(L$;!EE|35(KZyv>@@5)Q^6muqfL+2EM_>RjMUEwh5ZX>xdc0AM4x0IwTG7-F zA`msZ<8{oG8#QDbwP#0I$77x0zh~H0@~i&e-(|2~{J{l=yx|J$0&|7*>=e$HDAu-}CbjSqTWAwP#@7pRcs8PI|!-KU0 zjqqplU0w>_e-Tw?6iG|S`#U8 zz(!s%t?57{p3IOpaCgOb4tottlrZOw<{VxCFS+niV6v6=KKa})dsW!1VaGVNX-$Q5 zF8y&fDU5D84vGqe%67Gh>%c((WN`|-klq9 zZ|Ma>f*qPHPcWS8i4NGnTVbV5G-z_hsocsl>&rn~SMcL+-TPiV1NMa&e zmiay1`@P@a@Atod@SNxQEbsU0Jp;ue7@a;3y|!bwazB2oi*4&l7{LF9YdT)_T|IFe zQ=a_4R0qYsi9!Di@C44jmU=J(Qd_iG!rdl3JYK+62)ui24;q#2`b%&LI9Y_H&;FbmG z$}dSbld_5B*Qef-N%A!%SD#+M=5KAl8ebqfhJRFkUGJ$3$JM<_lam&IM7+c^+!B3U zk$%5#iWVZ!sSEj5p`fU%Jl<2YRP%6p2%C$h*AN>Il^q^a2NIYL25#>>mDt*C=MK^A z+Y&Zp)tb~6re!B4E*N9Jn%DsyA%xle;3izxE4*B(=5~@=Lo&WjdE2FRVK>fLv!U^6 z4Qnp;MArUN|rDv9n3R?aKaY@O5Q zz||~!tROsr2ApPa(MXIaWM+!|zPdX3d_(G!zx=FQ$3^k(f`QP3L&^N)6DI)oy)IlX zf~7tzuI#c}Re*Hc1jZhp8m3iyC_V>&NK3o?Y2v@i{MbL0xp@ny%#%#PcEHl(&_KZK ztU+>MK!}AZQ*;V{{!dZ8fOoR|B6e!;1|1&~5+gX1quJ^NH?GI*D;;=ZgVI%s&Dy<> z4GX{e$|B_t56Neu{C3XzxxqgG?J23w`VHP7^8BKz)Vs!6wz8RT& zHGLDi!fQtL$KA;7XRS@GYoOg0oTP}~$ak0Wy(RhhPrC}9(3gv1w@po+=uH5TI%^Ty zXC5z;A~KLFDi4rI%18^p2z<*YNb{EX6M9;Dg)dFVg?{Y2eH_C27otCsTC!BVRn_iS5XyLR!U9~O|LnNst7Iaq*RVP zR$4^L%E}q1DBsVqOR_|nCMJ^qIBkFWn19fk&CQJzA+?^H1UhukDu1uvM<$+ zLh4_I`aH%xaU?6xZ<6P0`K@D?z*BhHFx;PIi}|dc)aXx0n4VyQ1eZeXsO^-xReq_Y z;F;~7Uajb8Hd-~LFB~Pzc98DcE`7t0CmIO3#9pq zq|ziRd03@Vma&a|DnF2#_Eot?En9ZFbGn*LZNk#oVIP-`NU`6Yd~?Nq%HZh@4^d{=c_L0zff9yuBNUx3#IF6NZj-jSw{X9_od85&th-4}V2dbk{{fz9xRmsG}}qh4Jn zE8@jmMnkyR$}cmimYea>?mScS+j&}B4n0Y0=_Ow|auL%+`az&IsR?-d&8v1D)LtsW+=s@!2|;TdkOVv%)KW z3$GTTia(H|wz>tsqMo-deZwe+Ubda=iJ+U{vuc0A+vIlQ_Qg0h!t+LEc$wC=%eGdt47weZ?-9kqSwMXZc%Rp| zBBnWgsw&^gq^Pw#4p9Y|0{766V~M=6?QAwLG+J7$%K|odb1lgsWgtWTg4G*U3#J3g zWl<05jMmDm$vbQoK*(J2U~xIsnX_!|*jQ$oXi!6Rf%4XHNT;+$V>V(_1zfU}@sK$4 zlz7@jj?;4)dlhvp=#@ZPD>Z=}qmhUY<@x)w_NyNc)eG_JA-NV4qFg|DW7I4?@bSeR zGzc%!@KV9n?|+cW#y{N9IIc&_lxS5u=`&h8e%g01_&eG2K&``th|*U6GUDA^0;Hlu$Q8>2qWjE+&_8 zYORac%ok?Z1$<;HFH+WMPnCRkYN6b1#?0;pCHlcJp5@T+tGo9vR>q6VA$&I{Y*5pW zT0)?dz}pCM3%e@yBN*R-7bVU(F2Ux1qAw8O65|8k=rsUu{W-wdVJb8!9rKuMTUvTU zrTk{wKQVg2v}JuJobb|cJ*list#uZH?~g(a+MXvFfl~cTO=bOc^kkS{b*66IGQHmO zTm4gsEv4d;zW`mvhJH!ES2XJBvClzOk7>FN=>D7zu7IMQu-J7_qu7{2p#iY}MI&PP zyk(%IwOoPA%Co}RBRd4k4f0akbl`1vPoei0E1|C}_Oh(NOErswuj2Z-y*D)rhk+z_ zN*v{b?VBd=Rud0+z|p4#_~)ui*BneA!LRN>(cLV=f=i8ED(zw3$4SZRQ3(jhb1LSq zyr=TG_N&0yN?Y@7zgE5*t`UW-NUKdmH9SMW{5lhXok1S(;@9!&i<5$ ze0)uHE<@<%gasVb^BKSXGLNItAu85qja6qIfL{mmV=u6QSd8iZh6t{Rt@*?lJuu7Z zXQ3gYa%fDC_o4=rsYSPavH9Ez>B#_Lg;rtbI{<~bC^Bs3SF!Hq^5S{dY(>t&3W_xY zF^xTlg52YQ_3+3Xp0T!<_7s_U6xxzR%&?Z40{T_qnFBvQ#d7hA5dz8EkB))j^BC80q^#@7qfRHhn zE%N3iiQtlU=DkkHY1Is|G@*O?^+l@m3S$o-kgJf2UE?#u`eL^1+gujbh{3tGqLbrh z7YZbr&lS5k*eC8PEK|u<;10{z$ON{E1i( zxH#i9F+D_VFd|*uFExwi#{(ksXp--1oI?@sexZ2aCDfRVdXDiOPgjs*{94w3s`O5q z;Ttx}Je}*Tq@I>xT_*SD9oKm~fj0C`rKaeD&=P##@E!d#Fg*1(M^kuSnhG%N8n0wMz@EH0a)8>DL(CIMN3{*(isYi zB)Ac>>cBPIq0S~MRkh)JDL{IgrEbqU#Rj*WM<~~y&si%`K->O;FPwsoXo0)KWxQo^ za>Wc3YBq!Wwn?#YPX+3Il{a0^#7JOOfqV4~ZL~W~jM-NKeZ`G#!X_Kuh>ESMuunW` zwxf?Uo;NCf36j?3yN*bkQi`3*19uXRa%GPfd55VqjZ%3_rDquJup`newl-OA zvJn5^lUp5CQ2Wh7zOC0-^7EJsLDef1H(55qi|fnMEvs!5MLhZbIs^rNAQG8(aJVvy zNsR?_Sk6H$(niIKG+9+AQ@OtEud4r@&;9n#eC}m8n9p6(E-gLC5#wLz-CpH%9Tb zMK-OSR`*)~w)3MT+FP+EPGNU(5c4!I)X~~vgEy!oHRhrYl}VWvm6@6%gRv|_JFq|c zMZ54XP4_)|rOT-;*Wu{(fw-&yk+Yf2_Q%AgdqUefuM=X!FRbB8{qZ}z!Q0T%Q#!ku z#KPgqWd9#WTo;SZ{|QAO2QF*}scIM6*f%vf#+*L~Z4tL=4Kc&G8hGUeb$Pp{e;mId zrB(Aw0^r(U=+vbkBfvaF^;>&4Kwd0 z%Ze#|y;EraezM8qdW=Qrmq$V?d-y?5Dl4hwON?jV>)^-wvw;@L7JZ=>N7QGRV}@^4 zQ{o)WFTA9z6j2p?v_myj%c@axX@Q)ck;^W9W9lxhwvf8Zcby1dRj50WR(R}S-MNSi z)IzYE^}yh)1uxbj0o^C<**RXV)JnLspwOcc6B@>C?)lSKGP&8FKoqT9WcI@L#)FBh zrbVF3^HWn=`lBD-J~qEfJ#NRO6Otd$6Vc2q@arjXo4!}6G;^tNzV>(ZQU_*B5M&j4 zs&i+kJWCN$Iz6DT(DbyXBG~d7ovqnSU-7_=GwscELb4&Tu@b5{PJW+Z*@dTW4 zbxv2$&bZMJOR9AhLzaG_E4;n4MJG-em(^*s1i?#QRcapeth2K?f5Y^0w^Xz1sGF7| zadupzj?7G{U-Zpn9;v*HMqePEzg?QHbBnaNu7Rs?S;mU@;GNt9az|!N4H_h8Y7kVU zX-~KJz`c7{sTSRV2zD}BCZGsdl~H1v4;QTh-crHNBLUE{mMXHf<0S1(nkMyKGa$L3 zKA%o!&cfH~6c!KleYGILPq$Oo;r^y~q26Bvc{KU{M=a`vrEv67-T?Hq8cNl*cju>| z7p_ZB_DJKM1z)2j@A%&LdC1Tpdbw}Ah_g|Vt!3VuM#p!h;p!?0*iJZXx!$&sZf)VbDnID-k`*$yqw$-UKRDm%rtOz1_X$%zss zs9#PUmXf#ZAq5<|`>EZVv^U5^`E}ApRD59!EjGD`uJgTsxg5xcefM&9@YnY^-o49+ zYHRbX9|aZ5KQ8x@e=Vv1l(g!i#Vgabae?@)ywu+zFkIgvYg5=1^JID zSt$O5($9=UUjS;0;q-QuU_`A3fp=%$cq7j0b+{y5&bMEF^|H_EbR)JyhM|k__5bTQN(@WNC zCiC-hGq6ViiO6&V`>*ZCVEY>*#D}l(_VM37y^D~2^p|F-+ZD6zFrRx#dwoeqG{at@ zc>6C^&}TK#=s4>0EB?sqP(?#+yyEKs%c0ba=%C~Jz6N?^)>T~#={2cD#u-x4Kq-|D#s* z6^n}u*Amg?E-dAFgrXN2aa8m!D6Aw8nH2t|ZgBY3xvm|Ot{wq!xcka>zE)3JnGtBm z_Q-gCgj|iZ_T$F=wgSlYSz?@)C0SWutTYez^cps?pVeGTamHm*%5IWcSY)eW-21oF zw1;aL_fm01yK{A3K&p)1PiWQ#I4hMOqQ{H%0u5y-72UTM`58gEw-g99zQ89VJ>Ft| z9JKL`Dov5CBfkTp84A#DP(!h&QrnioL%M~!@P%#A16s=|Xzwi&$OzffHMcpDJvUk# zyF8pGnZHWvLkwQ}%7!GjQmQT)Gr-=uB0k!H)t$6lG!vR+ z6pBy=){6$-LslYOUhEUXU89m*wE+0VRpL1Fl z4|5X6N6D@nXsC9RKx|aB>4;9-8i-MiTdJGY$z5weK6U_hVM@b-lVe;FkwXsNjdbD9 zxRGxzT`4h=c~J*-Yb?Fu62`w%;shANB>7dqUE%VzHhhKU977quK@+eA-cG_k5tzMF z^Sl-?`BK3zu-$%j#2U94C8wYOk@~RtOF%be%AWd{tMJFq z%~CQHwyo4u2sl&2l?1oQC`V!5hSPbt>aXvZbmw~=yTZP23RQH1>`0>PXN?x>46gqu zHs&yunpQ5>L-^CUTX{V=2Y=qls%`N;oPdf62^{&wp{wMoN)>d?$(Co&H~f$rV5E3t zA+-urt`JGJNL(97Jk8M}u7+uU26oR=Z&mI}$?HyTbDwHPU(rK=+6{yUF7qr0fI)-S zwWsG&aoDsL5YUBP*H7pMj1_0{6Gm%*Jaa&WP?hsnt^!d^MS`p;kuxma862c3l>f4g zE2^c72khV_`Fzgo-oI$?(r6U2zXhqF=lx^`HKM%?|6zQ1cCil1*K(BR(<=E^ zg{d2zRP&xC(S1a}G(e7S=UD_)0vNdGn5lJ8^5_a)-eW)q1RgLq0wJza-^d+F7`kBk z-0!UEvsJmB#&HMVBXxHkVLC$j^-Ul^GHxR!jLV^PsRc-`%huiJbwU>=1aNFJ9lKGU zIGtj2jM679A6EjH*mitNJ^rg9ZuL@8+fxlYN~uxbaMpI}c6Zed)XE(H-e#_v>yhKk z)}_R+6AE}>1w5hCbyz-aiu`;z(`ykys7}jYfH^I?wO?d4EjEIbOj}NkTJ|aUnE1nL zZKvX)k2JIDK~)1)q4|~9EGyn`SBH1piqF^x4J_>p7Cot=mP>s0mxYq(wr#wR8Qhl>M^ryerF36X&by0)uYw+rDAWmXZ^^3 z?_JBk@15x92uDp+yY(JBjP<8xMc9riWyY8lo}8oRA?Q&j?K}vl2z7q}K2FlSIv45X zwH4E7zzILWr`G2 z1X}BDgw-x#m&ZFQwljEHWBg2(ZIW*m&bV=sQrbeYU)HQ)^7qQGVFJnyzsvNfD&6s@ z>niD|O(3p{)ExGX>d#5m+gy~Yw5?+tU;JY+s2q~oB{5V2; zsAJUf1>T!R{yG7DT`jV&GqqTwJ&pgmf1La#SkvUNiu}d~mlfoWV2U5$I;g>cE!z`-zY5#@gZzwPrm*fV$bapm>c&s3bN5^EyPtT2yvG_Ef$mq!6sk(NBbGa?{5Yn z8jSx1Kv6&ZyD<34vBsIQ$_~36UmS}MHTqx~N4M+V9#lFpq+6ZluRz|$D(Yq~b|6@> zo^&scA(V0rG`E>W@OAl<|rq&1J%9VE#kO{13_OzA*a zlb$?HAkxyg#uV)%_25ik%B)GPHZu?nkThyDb!4Bin_zwJ$0WI^HYuBNAaaEJqMuwx z^~29@f#GArI3z0)khqxc2_b&#&f!g#)K@~z=5$vvIBU@wsQnph zL}`kzZOl7wNbNkt(COF1OsBaO#z@?uzp8I;qx|Tm#J?j3mh~8~hOzw1WTvjw6 zr;W5HlEKNaksTPvw`J@IN@~k*R__;jDGz{Q^bpbdT+-ec@f)|UejtmB31kObZ+e^Y|UWt}vPymwhB!2~}1ahgVQwA~0CJM#kq zu*behOcRdRFTdKIuQ*sQd{Up&NfRP?2MYWB45|Hy?Rtv6-^wYDth!S85nys@xw-Vy zsCUs>QStWQvBzsVM4vN3&!7vvpO0_o(QilKYi|(j#4@DVbYR&;RWD^1$xW4gQb;|?gMS{4bX+`Q>V3eLX9P8$cCAnOHK5{^~}P$ ziIKZmhEap$8ZFP13KicNKwtFj|Db+ZE*jl~0*b?qG5&{m9xlglTS6#vu?~%{%d=>dp zE|&9`=#U8LKTmcKN+(?tmo;0Et}c|XQZE#bOpXC6d6ZsoG=Pf*ztWgx!BVO1XWO=s ztc!l>w7PdlXy=L>82NzHa>u^sdHuRWwssTK z>h*s+Grv@<*F^Fc0mQ0^T?rK!ld!jM@QU_k`3;TIWurz+A}yjoP!T_aUC5D6%ZU=92C{x0_?)yeR_I03-*Lj-wgG) zc0HrsyRlL9Ud3z$qjjS=3DiwAQGDKU6I(rlt=>d^9f$-wDf^7$ROhZhv}&e+wRzzp zkZFK~cJK@kp^)wMwD$kuY4!hW!jb8k zSy_<+M~7y|MGXLPLn!^`pCgs`0h2@qCSR12Z$I=8J)A?9UBVmOAirM&JMX8I1bAzg zt|vq-0^68|$P7XJ`WeF0Gy*KR|Bf!XRQ`?_6@n7x(}nF1rPM z2Px4Kb|DAXhwj?4#jcKJochBD*fD1*NryrdkvF#6Y`0?vKCHo}dv(MwCWfiMWAnGL z9w%VY;|rUbsG9-5cD#lywhW%!q&h(6KeuE*4B3jX$XQ zrl^0hQ2pW}kbu&Fm!_YyWHPJo#@Ya7nJ*eYGRmob0v3PmxQtiG#;#6*9I~z?mLDlr?&6<^Qacr!uXxNH!cx9QY~N0* z9N3qlkLiqp;?g$x#%J()o*SB#faw;Z#X8u0Yw4?{y-h?vv4Q zI^TlB=KV(fiu^_pY}_EtmRwZqVu64v-JJ39(n@2Ag>RrJg1<7q5gIWrhXys_Am!S5 zA$3J22M;bJCCc-00x_ket%tj|3>}vtB>Ol+=YI2Oc{{D{hq-KzJmoj9Yj~%HgtuSd z@D>&M-VT23DKup6Ow!nWG@heaJ=$ArDLX;FQ^5t8gHYV~zCW=g_8ro#T{!y~S*_ zxdyid_i%ysMDG@Pp0V_>p|tUHnjE-?<=OhSiW%(wd4zZ*bV9dYjGDA!p83@ z&U^IiJy>(+V$j-Vd_W}5;LUV~o`nMO2)|_3p?F4PRgxaoC&5Kg>M@zK6Pn5L_p-+( z()eF^#r9IoAJV2ugw#8O1FGB-H*+b&MDDKsrl+~ndYl@rcKphfpw;vHFrQ}!1lP39 zukY`15Z}J)T>5f^=3HGxcwYi++1Y=>jc-w3ZD4<9G^mZ~2dAW-J9)0t9T7Iyo~yr4 zcb=ZjXy_WJx5J@s;IU0ats%lmgS@y=Vgf8>3q5fyb>zJed9P6@d5G_w!^?TZ=U5wI zK6sZXv3u$8H)83Vsh6~rLCl0&xDI;z-D+-w)J@D zuNcQ@g(!xc9Y`ip)=BZSpjYFUe#vVEZ zZiOe7y0frrS2h2x>i_cY{({=UTlemV7IGuc@)@P8)*y`1n}2~lTdJ}01>djdql+-3 zahIUBONZSi-mspYjB@s|kq+{}w1kx3>aeBofBO;IKcQL%AekL#C8YB`s<10_mSIoN zISUzjb=eeD^IYQAtt3zR!d2V1+tR)Eb0GaB@fa-upT1H2_NDaHF8Ps2kePto)S>SF zI1?I2D{J{`rYs8Ir&V`-DQmy{{oE-mMJp`X#2(M0wq?O@bt6aKx~0@-MTi?ojhU!H z!7A*pP;13u7C?!G=@Em;hQj4WQSnO)&8lkD7|&DvekNQ8?^@0v5D!*{9}N_E=*0zC zc~R|$aYI=J1Z6u-aUsUfaOX7hPy%EHN3@deN-K*=*drTW{KE5>^bM1;8hpXDeLA)2 zS9DCo7JwM2&%Ktin(|5-kJNi~tABM4+!xb2LzllO(Z@dhmYT6`N8$ccL27^N6G5z1PN$o2^yA1o zregly3Xxl?M@9wvyf-eZ9eyK4+)Sht=na~uDR;kk8{15kbSy=$ZN6g`{Q|t!?tys6 zGvZ8zDAXRkQc=jZ7~hu_i>rZKz*}&5lP!$%Xz@ZLX+2Ri>E^`Ox4^l~ zlWwNT^Ch>j=><%YH<}3f2IHdrd1Pk7g!(Zz`O^b_&QsJVikB5qc!uyhAFRGX`+cN6 zMN30X0NP@vvNTA57HqA%sqN(!rh4wENRim2-J}{dYv)xX)q)b$T(-hbu#`{~=d(rBTO@fP-f zM-55A1pnVz>p=A-j~$lmQs8gx&%(Da-EUG?uHKIl^4;o%22OLs=hbV5w{ZCBmc&t4 zo_?JuWLY9^OpIpMqRwOiHOB`!>4(pHIt4rSW@CE;m0qrXMo}dTY03owt*0JJ-At>n zHfx*7u&gue~7PH4|bHItb@P6D`S_U-nVBiHF}|*RSZ*?yE=CW z;j(1|kDx(w0dzlzVVd(ol{BbCEx|d%1F56B(Lz#2DS|hAEJ>%=EbtE{gs{Cd3twg} zuxi9eWj%QFnfH}&goch9b@{3LBnQa^s_7|D)b&Etqc*cB_`(CEEnA*cQQxtf)!ZLw z%)Z5n5L*iqhG%rE2c| zv`M-q-jp!j%HSE+EfoRObNrG-T&N?@V(8n$k^h})_sZ?1tjyHA-bzZ?llC-u6cKS_y*D+~Vi6-Zz9D-wDr~2LZLTS}V z*oOpytNIt5aN)&S!i}?{P8%(FUXHWTe@rQhQaTAge+U)qI7Kw6FoJWZ@3`;B4NPys z8pju1xcp1IDE6H+jg3uO4-P50BP$eUo)J;kmTCn05 ze`%n4VUX6_5-U?{s{6(BHL2~art{t7w7B0M6co_K zzyEG2PD!y77oBz$-%KNjWfBMvB+g*K|8d)d=;R`6MZ1o+<{mUD#HgTPIRhleNgT!1 zmkD9au=UIre~;5D4jaFU+l4y3^c&G zX6YpjT!CU`=zgVU>kXn6On5@6OORV?_I{{RDXs`roj^A4VkVz9mbrjdg6ntaNWtdi zwfGl&g0Iq6hzpH0!4ED!rGGY9fgi|1i6$p<+a%T%CT-=7tcPJbt+X_iX*S69@al}f zrq{2MuAasa@$7-J$vPo5u3=<}qThhaHY!>AhS3fUKe~=Wc*7Up9^JqBC!=QGJkR>! z{}u_eKxw6Z*!~h&B(OALzv?`EDPs%1Reb{QnmOE-<49eNZG2~_aF=+*MsVy8eHL#G zl^O#QEluLc%RA2Gs(7z%p$0utPt8)~l-8a_c6JGHxV8v0Bx)N<-+#_^37upK!^v z^c-c#IQa5Ng-T}36fngBRnYDl9I!kuvZfFGHHZk;1{T!HO-Xj8Mz{cG|27C4Ra z4*^Ho1MCegMsQg>bKXAKCTd;F-%oOuwTkj&E3sW${*Y6;c*pZZR;rjV@vPYy(ocI> zhMm`9Ds#08_!hx#1fzXU9e2j;JyMRbJpN3biw{Gd#w#MPPiDBojz_ZYZ^F4CS255L zta;>mld6bcid_rlmysT>lAIyVF2~-ONgs)xqOsr60e|@GF?g?nyw{8TW~9$eNb0uf zRSWS1$;DA(b%19bm_0*o3}>^;$R>l7UsGk8-K?#c?&eig#m7qwe^%Zvep|!=HCnq9 z#5;SqQ6BF0EdYkTPjR{$>ETthdTRi)<3U`gee_@tYZ)5P+|Vk2D>{jiZwPZ0#J$oT;61JErv)JJtuClY=+tswDtTuNohyrR)*Xk?r@;b_?^YXU!`sEiW0+H#3LSLsL zDc(nb#?4FEohvT^W`2`{~$8wq&VnfK+GV=d0c#Ib!u_S(|zlw2vyzq>Bco zpyYQFxTSUIFQ1q21YHXWM9rfgm>1#lS3hAeiJ_G^evVqzOt^V_X?7rT{IoUCQOUjob z<|ku@{x(sBzdOqbrRVNSW~@q%qpwHF4*t-X=Wg8Cw#UToNA;M`lEUIJtHt#KElY~v z^H-d*HB5{`|Iv(qfMfnYkj&lDz#Y6_Eg>~<)l*vT3NNQav-@9oU@3RSi-ZSflR0tB zT3`9l4MbI0OqV`pR$M|fm#3&?$Fx0r6Tz!ytT55`6jaYDyLn8<_5{3ThS2A9^q4w` z#rg%dasLQJWY9Oh_Z=R{Ha|FYx^wEm7wls+7f`HxYysvQXtinn?5fNd{=fmq!JQ%P z@qxFNNnKX*EVey{trx=27T>5tU7Tc}90ZPHOvgqG@by#ml(vnO_GnwJpO%oE7jb}_LP?j)vgR+$!Fy1_K` zUf(BYJA^pl%dVST^~bgD{!ZQ(q8gnh12eT@omqpzTg`NZb>TN4{0S(Zk#x#MFR6JZ zFA(Z{pGYdO&WCk>Y=56Y1to@^2`+Tj!=~~b=VJ%S%Asc!)R?v5RNGf;sR6Fx)Cx3J z3)OnH1K+eKfoSy@_v4hY({LrJUxp4$#F1V9*67*`ymu0(u#SdJa!YmLA!3;ZwReHs z&dNlQhy!R=s~3~-dvUdfkD(+EKZq=builAef<42fDL6tKsN1I?>qkH8)gGS8ha*ip zxysGEsnYmgd3l#qGA*)GA|1=y)vCvAO-Yc?KO*%}E4@6#yyM%&wQoe77a{b`^f+|) zE8eQ({K;DyO;D&77w7V#udSad{j~WBW|lf3;{48@j%a8Ud4Fs5tRMRCxwQLt z5^?9>=dyL7zqI}pC5P@cd)+$fD!FuYB-;`U0D8TVtLv_!C+B^W`0BU}UK8%tcUaXqogK?-$Exs{LG zHHxm{hpgbG9~q&T>Mm5wSoO}FuE4&uToL8%TW7t7)Y;=mzvbjCsvf^`OkF(J%&giE zzbV~#r)-gBumEoV3Lls>Qv_zR6~v^BeC{r7f=P73D1ui8TlPY*4M_b1Rwo(0dJvXz zX8k6pQPA8n4X<9@t=0iG|CcEm{4e)l=ATj>%1as{mR|qf^XFFJ|5mHZ9&7oV-X7pu zEik?P9NJ^P@6o7U+`I2wlJPIr%5qrw`R7%w_-g0by4xcS$nc7pwDtsKmjY+~MM2m{ zP?7VN1SQ2R<8>dvWgSwZ41+FLdYB^hc~ZX#>_4}BZb1Q`=!mFpJ2-Li-( zJyQ&3-f~Mk4XBH3lyTcU1!DE6iH_#&6$~B+y6Ap5D2@{FocPuo*SA2_l9c}R@4q&N zKzUb*57z-SLDYR{u35o1it{wN|CmauTX0^q>L+ggE+s!Y2yIA&-XPM;Aj&8R$3XnZ z#K?d_Zi<~^t;wnC)XqMW1q*F^3B*%p?YcxcXa_!Pn|e7ydld>5@bj$YL)P*a4st3X ztb*LT{?_zL8;`OIlE)Q-U9$#ENj95}XfMI~cQ#G#kGsfE+xxX0#>Y7D?8A-$gyalRpkEg98zbfKjr+0o zClS5Z!(>;Tg#ti=UrFW)yYUHa*42n|Xo-B*;*i3O%1({&adG-9qVfGnxOM*#FF4{h z`RZjA)?{sH7QEl6Zh$GDp2rmRl|wds!WC}oCEO~igrFX{g&cqs5&IVGhsSOvO#GlF z++_F0h05O1E6>cs+)NbeF0$xwOv`e?-a;HLP(rl+4X-`}w;$5_ogunBL-o*}y5Mk9 zg#UVPND~A$HR{$fZlbjVNu%$|@U%s2wh%XLzQD$fJQM*B2I%0epEQu0Uf9CEb>f55 z>VCH$-gm5C@Y59Z&y9C!_CKP@?>`rx_5>c-YJMLJ)ov?MAE=^WA7i6y9xw_BB7Jq7 z;qUcL6@sI-I!7}0h(X8C&;cQ9)#>VQ3sqX-^JWMRe%b!0g@q`+jA;ECS`u98_`5iS zkLArVCz%K=l8jrOhMoEnVG$2hWPC$5Qcxhh;h(r5PSsnGu5c)e@qdH@YgF z)`1&$6~Av^Z4KKW?`t-9{%$YGg_Hjp?vq?F&GIf|k`RMeA?Ol*zdfw9t|4=#9JxzCclt4U@ITax_ikhD?JjCyy> zAc?h-IZ~iwd8Oxy6yxXdiq&MBHT^Dw48>=9g~jl3#768uQ6mX$G z7&;8YfqjI2=F~XlbAjkbY{eyxPKAhL4(tfMbb%yKN}m{=)G8H8- z@d*Y!yg`_KOTt(J(z0}-!XRCIxFSHmrLbaCx5GsLC!*;7qbHrN8!?vK8|b{Ylgm{=y&uDruiuV`EV_Ux;Tzoi z3N?7_1tvvLt-Tx#mEUa?N%K=G(y&{#h-a9tK@p8$zn1#tXae4$g|~7b$rszfvsA$y zDe3oC^>9l?(-+~A8qJcY<br2aD>Z2#XdD4*?3w&#UV31}nCY>e&jmv1H z4EIt4R4dG%uH*+syqEL5RSK>g> zQn+OC#uT!1{1`LAQfVVCyD4Ggd!E!Q#|7m4Uq{=Xrtp!Y#!Dw*C$kNsOXnu>$G+_> z-F^$_auddO-aCSNce>-VXeLCH2NdUTUo6-t-}^%;T72wxtf|gLU{OGegRfg`>G@cY zV<`S*{xEJj`D6LY@nE#`f4NAQTDzP+f=ZP zxQEYGzOKFi+gHQR+3F<==}`@f!tUXslJv+j-67ppG$eQm-@d$2E1>8JIbg@g_cx1E zHen2H`6_Z)mtjf2`l~v!RSs^+5&&fPtNnnN0l~EwI-n-nW;Fiw9ZmLb!`WS4biplx zP5F*w`;HidEXNTMhBH*Gf+64gK$a`(J^!`A^YB3f5?~m7aSl z{d3t3HP_!qCbp4Q+bX_2!aTX(%@Vr=pSz zW~vSXvo-v{S*5vN+GY3g_Rh3E89I6hbbt@gT-Omw0^D(}`6705H>}Y4UD~7>UZEa_ zcjj_!@V(s!>W*!Y>lV#;yqXpdPNPrBE;3l7e7;d@)vn~bWtZYtu#hppD0_$y!Avwy zQ+cY)%WROv6>Lo;t|h6XnHjtrG9LI?{taHMJDE zE;sQ2d*Fbe)FB9r?*gx?IeNqBI?4bJrl`M_3-s4zL*M@S7*1}mcM(G=8f_*o)w!Aa zlyijuxF=-nOn=j_qR$w-VBS&PIj6)=ecM8z>n;=MH*@+=llyiZ;I1%^Q=8xC+8>E~ z?APZHg7(9@r&iLZA&q&o)MnRzTI;xEkCXf|!v8?37l2a;ZIESOc?Zr=X(qD%o)yT0 zr>E8i-BT{VTC?dlkb#jTkt%!ant>`>>sD49#3xYPDFBG%u!JIBOVSfifP~raPFwpD9N>=; z$EbP|TGnphSZZR`Odni*2%FgFdq`Q3|8f{>@@4y7V2{`O_Yhy^G|kP~S`gjs4Dbx? z$;T84bCMM`EL5|@>+ST*9M}%F`%in+kQxx(yE6QRfFUP{w1TyD@s9 zP!CX?v)|4B{N%!`dO=5IRHfE6fFlqQh);;II?Vqw)KVenAuxKF_bU%5pKT{PT?%Cw zWynn^%GjRBFFg_ATylkC*#^Z{MQD>;hjBu5Y~WQ;0X1gM-l3B4KAAXZC5T~BT8>x{ z15n}F9|&Kb&J^3BEw*)p58wMOtW)TfPds!Ez3@nUM%a9iJg_=-)Jlvt%4WXUWQ^fk zKHMS(6a%z`64w88NXpTiO+0cG9M}_C|G$+NQ1AZJ!ma?XE(LGt&V2y-^W!To?-A@= z@usV)De&_=>f;~Zq=gewpNl5E=N=`6v#6S@dh&R8B(mIETc&OtSW9ayOW!(xe| z)6qeC@6>J8@VD6e^{? z0cbPvLl!$8`}jxp@jQ+{=}d;FM}(yJ%XY$Uwj5fWxymM_2JY9lwOZKEw5Jlv56pQ8 zjXLbBJf*iEifrF9AL+PAiC{lk%r(>;T17;X` z>Kv-~f2O5NNIsFkaW)JF33pUoo%b&iI&>WBx0AjqnqYl!Xd}kp$h|?`^&tnJa~Cz$ zGHF4X^opkk<%P$oFR&G&)bTV-Z{KQZ@qR(x6eq6^%l|>@f~GijDM<<)^Z{9~z%ZS-u%9|0P#|qL;D&ws_6`l8iW5EA5x|+lbdt8b1U%Rh zl_a3RNsy?Qu9toeS#s$)z$!N#OjA-SIjMdLGuN8k<{hMDPIuHQTk(nV-Cs55d`{kP z)e-aAj{3F*F`dcJaM@?F_oGZAY;J4dy!Akn?O5ABa9kO^9)LHIt00$XVQVa`|9z$t z*R{;Ei6yQ_52jhSD&!bR(veVr_%q|2g zw`tn%Oq+SnnIlrDbLj_xz9e(A;D=QPV-ix$Nn_{_bU1LB~;S=C1R5J z{c9pO7<&H$@`%$b4*+fYGkCoScw#Rlj+q@n^F9!UuZD){KZ@g(ef&2{)$#ADCiT~< zCJirkPXMTxl)>-SX7x}3u9`Y{{o^l%clPdRWK;kl>B z^yJadiJKGDKWX;VD#64`Z1ejp$wM8s{>5LaFv*&yA|Hz=ApQFcwV{(^IfO1_V%hHD zE)8k{9=>6{HVElFZPRp$Dv$YlrW&#=Bg|8)CfG2LduTYM|An! zfvx`~E9$keh<9LYNTc?w!&}`5$|Bp6!?E^*4`xqXKqIE%jHiNU)GR!i^&thLk-6Il zfFh*-{Qx_^?QFHnZY;nN{t)#7CwMN>(X_sSFH~*2p)hIhD;<+ZLgXCkp7e?goX8<=7WlmO+-o(@3e`*)rP{$)Z}+;MX$+dOzLlove$+gUt9 z=a9c)()+EWI`{4!h3>5BeSLhGdPGEXQ06_=HFc=f7lqsf0&}kZPtJNC?KZ8^PRdSA z{zGe3U-R@#I)_x=y0$1^qmsVDi2v{b!PdwadOaS-M82i3?FRjNV!?Y$r#BHf?9C}; zw;#`}98cfauB4~HM}pKRiTv)*bSYZ6C<`|gJitn^8zGNv4-ube4ZW}3VclonIt`3P z!&tr?J$%$*MnfZvOKkBOA=2wr;jXi$N}6GH&V??U9|AAzFA@nM``=d5G4LTInc#GT z{v=v7H41hqLO=F|@u8rvbLxCndhN*t)T76;bc2iDKM#zGsh6R&@?}@{zV${t{Uc;^ z^uR*aSe-Jmbmbo8fJuBtVu0Kh^C{qrDT(Th&ZtE9&92aEjY!+0Dp>QU<+RX^B-%uktXmWqNpuuK9q)LbI<{tH(lHlTcvyQx zt(&V#I46f)QO#TP>za5&Kg=^Gj33+b2%p%~tLHCR4qk94FujN3{tc2Rd~tp|=l)Hh z-bX5v6X?w->0<%zNwlpncPeQbSOntNy-DDPsq}hEMwyLvWrrSGu@k*=^p`OKSeOyD za-+NWWnD&G*why3sPm>p#^FEp%IKsHNG)*;+?t85wSaQe?6b~`RMe64ZkI^cQgV2k z`$P!W*GVH>_Ev3Mx$L{L_vo`N)X<6=Y6iG4ui$=BkGoHC5u4D@S$!m_i_Q|ow>XBj zOrN4x5tNlP!et&&e;OS6g%(cZOnUW^COSJU+LxTpnbaFDE-2kw_oCiw)3nP zFYjl+cd_5LF@9toxVGO32sD@L%FwjG8rU;ReH#K-_z8|4<0!f2^QXVkGc1z5GnSQI z-V(C1(m+F#FM9ob&y9`M%sVMdh0i`UQLp1P%C+T2ee-_bEnR1isQSE~q46nCw{nXP zsucXOoznIEA~C4GvEc=4^R53qpfHUHTAQP1=$)q?t*p}&Iz;j2m@>ZCK3y9A>LC;zJxWgi;_Y&-rr+fJ7=l`aC&}! zu^R?b{g0xl1$%%tCG|C3`tlwi8cOp?xL?VfL!V4+*EUjW$Agbo&C=XL2 z;*aX1EGbQ`&w0Nra48(M;~!&0g2YHr3l?9)4J-v;tqmm(ABOtjLj0fYkqx4w0Cur_ z_Q7B@vP!3KG>v#F6qaGEpdtZK#5wf6s0lAKqI)Wf*P%) z4HPll@SVQ*mA3DTNNIYG=n?tXbTqX(&*m}ox&!=U!!t#;lr>%gojOjf(dpbXf~Lpp z{!FblU~j&Mba>EC&dK^+YNwC0ba~+YT}0XM=PF42-BsXsj|2vvY~Xq?HTxhiyk?BI zUuTIHiou0eJMc^1j)TN}^uO&&!ux**4sAf)qMA;i^J@EJq`t!orFtV$GKr!ng2*&r7+z;xMRS{Zuq#C|c8ero?j48$7XFv2k z(diKt{_ipyZkX1fId_Fp64Z?z(q|uJTKOOw&3i$VgL(w_4_1=x(dzAc3|0Q-W!wf` zh*y^`*Si)8Wt_Nh#;dv_kH|WWDADhT$KA7#<5>0cr%KU*rNZeOqGaQc#{lr2%Q0MFFUwMCEfn<>r34)b8@3A$z%-(>9IOcNTDVAF>*IP_|oNIGe6)VN#Z7l}yw#C4Kv|LV1wO z0j|?RNag+nG$XKtr*F8>=?@JlnG#kAL0BWfxh8)IZp@^bUFcR!zmw|B2Yo`YnWL%arbiaph)ct*?&y0Vj>U2_Q z%TqMGv*ZpQ?i3<0be1d-ifD!RzKYjXZm@0brLJ_2lVmv5DzRbGX z79h$wIN>6b318r^@1=OTgu|y60R@%^?oaE}1jk>~gsJw8x_`qiPmV$XM^3sX8X0BX zz+a!wSQYwXqESurYVh8@p@#^;i>@!MgFU8>L#(NnE3d6UHWA7)sji$T1GOr~o2U*{xxAk|C3huU%gGQ$Y zp8keNc8`nN7pkhbNr*{Jo`JQ)RXN#( zanHqsui7wcUE~RR+e&D$@hsg#WeD{U_xxDQI$w>yPcAdH-~0|_FQOFif9pvM@HWj! z$47R&W{jGz+2%{WS&R%(Ldkm=;pDCjBf917`#yg1qiUpHW{eYD3abuUHcFW<8h+8} z2s;_r@L9q=OZkkTaPIqY0KOrN8fo0vSA!EmmXg&e#yv`vlPZqrA{95XA~@&eb0DWM zP6L)2l{1CP+14kq!7}#FUa!p6CKCsl*4m`A^mRXex-82i@D#P{7H3h#&h{Fn+usuT z59rF5#(q9{G^lT}9V}Ga9XG#3{0Cnq1$t7SR4FHhWX=UaWQ> z(q(``Q@~1;uqSwYNu0uhEA-4X+cT3tU(Fw1E--Bp`Hl68j7WVxvaea*?5S8~FWL6>Mpub}{>)cWA@`;1AfG}Z&m zXF1Yn6$^h(Vg@@;D}`izllVTR1<7jC50Tp@k)3yL6&NmFFST%QYM=vdeE7k<4`@ng zNofMNT;8uN)aJb)S)6Rcj(xchxbacacoqj)cysm>k)}RrR83ItIhnbC4y);f`FUh5^MfJj53gTrR0%QqALj&7*gF}GY zR$-E<6;&Um!J7&-ltm5iT7e!1?LeM=$;w#!jU%JrkNh~a_zQf#AoKK14n>8X>p--* zNixfc5oLSGzL(MQvu|C_qxOR-ahai?euRKE&XL2HG;1}b_CEW{HW^E(ht+t@bm))` zA=2ydAM5QIuI~S*3i=Jpy7FuFPBOv1X2L#8q zNgn6C2m$SNXI;7Q?ov)@t-^x^`mJ2@{R6s;3&q1F5M^`Am~jPF$qZg6S1Qjvs>YAD zFt%|~ET5=ttUJUgrsN@M#D%Ddd6HnWzp9Q`_G~!8W-rn3K@+`_D<+i)`oC@{7k+?O z@Y4VKYlrrjXw!`b{FIn$sA?j5&%!2(G3Svn(6q*~T~nq$JJe2T=r9gG+OC@oO^p1$ z=RpH^UPF`E-v1Qjx)xV0le!7jc$!MewqCh6 z1+)d2)eGW&L-scCjP`#e^Ty#N5@tW-#NhO=B7lJl#oADVoZTmMs}{YC3p5|s5Z8{V zwMmg5Y>oqJNf+eNju72F@UZ8YO0+*B2sqDZ!=}Mf?)7=W;f1wh_lI%d>#}=F#20u| zg$9@#WUQ{COTD#K`0#tqW6#=y(pQ$o3-)q@!$bK$``v4wAOD~`LrF%>3NMAx6+7t08GX>CQ?@l&DGl13*61TnA*1&b`K!$t^h9U?nAHi0u3s1h1uG>p)pdE0Rn2c8&1i8{|kT8-|nYwZ+|v z1AKPdYU&OAp&7eaD$>}VO~U+=(*!zQf>wKcgV6h)zc=#M#QRcK6sNwXS>as;lq*={ zh5fXP!Bj%6{hbki&>z_NMd99o8CDs&iPRBAaME!6Ni#YytGwyp56VFUn?_?04+U$7 zYiFg$%%wGdqIs&B#2B>QNHTht1p;M11s9cCK}O~$0q)i>8-sQRrH=2aBo)Pzl^pz~ zRvJ;x)K~r6!wH3f_!3t2X~Qi;t*;R0C zy|uJ{7c9N~_dL8fSPmUONN$&VtvbSqR)}L;N4MeJL-%F|+-$qRR=i`rU?kyd?S>5a z#V?U?(IGQRf$kkbk*2vy!7LaS+2`c31o0-i=X`-5$eM_3fV9^l-+ zD}048 zZM#auxn`X3c6ZgxI2fafP5MnE8oA}DaV;F7jRYI{NXh%NaEtLM;#}Fv@J_C$& z&YJh4CIwx5B0?-2$|8V-S0VWqS*Dxt{2K9_H&U_zuDQdj>q?#T}oV@CdmK5xqk~3C;_X_vQ#eJlpzmcIozm_ zo$IdKg@B3lIr+vgJ8=4pE#D~Z-;fZT9PWGj^soNI{$=Hu%0{qIzG?fR=5r$3?<}5x zVjsy2e-W)ghfDc3{eeXlwGgAK8Yt2fR7vt`v9)xEpU7X?nD;&3*!5^VG+3VMQ_U%K zZrf@iTKnyT#Fl(mxS~>!n@lkBCsZsjtlW?WJ=mqB=yN8K{a0Ta79kujIW!szD)7sw zQe|cp(WRQrrXnF#QiKV3Xw`AVZ9cLX-e!N|>F6}tyRHhJegh%zt zGy5IIV=omuP1Wwk7$2F7#QpPjuBNV!K`BFdOM-)2xRld6a8X&t4TU(h&tB%{NNHFD zqXZ0wH?Nmp`1A~o ziqU8d73^Qd$NFFY9!vnh>ixd!w?4$Vdj~DNJ#6Vg;(PTxR@CuBmb@izmKqypB)+|M z{0#?Ouk?tfw*N_=JWT;1_O%L_fA!Cooy|N?tE_7E^4w`p*&v!CxpR5}etBVPP&0L) zauGEYUvq_NUe)t4LK+qcQl`7hknHWLdYbYJre{Px#Hev0+2f;1zm^yZxC8+6Ob4UY z)L+d|Sm=#alzkHkw?hLvT<`(HZN zSHN}wm9m2eMn(;5haO$kEn=ayvYD?eWXXP13t6F`3_fHZsA?J8s895V?FtUg<#X1b z$*&GRkq4D+SJa#nwUcCKyK{*J_Ht3&l)mfq$j90Q@U`RzW@>Gp(Bd{&z~wJJ{FV#5 zrA;rW&uZp@kCx9}TUpwIebUGDU}+IuTYCF0Gcg5r*-KAPJ)&|ZAasbdpZJWO|2XD7 zp=Fu9LlSA|0^z+JI`>1B6t9I;K|P9b9~zcRqZ@5RW+9i(F38c%Q_3c~q8+!OAs#zX z4e%VnVcJi|7HZ2po)G%Cr$$_vlSh(XL<F`_ zq;imxRND1<)Gb3@+ia2e)I}hHH?(cZfS%))`ILh0C6GZ>D1-d(W4egsGl6B9O@dSD zG85jXzO|tDorh-=EzxPZr=e1rr`#s)12P!(8~8O_`Q(=(AEd;aIKZ1pcizlV;Ye;M zMEQ{BH#}{j2Hzp?w6$kP+OnInDT@i6|dx|u2S*bz|nM6jc+jaaDr8>vMk3_Te@le4ZP(l zNmjGcS^6A{!Ahf=siI_WIfI?w$|+>aj8wTlq4N$npZct z4GG9i9J0Y0zCHd4J&01%%>9UKJTJQxuDe|lF);q-jr~S=!jG9~Q2EjT&)> z)XF;Axi{RsDo+z~yt?JAx)$Sd&od8157Xzo#?^ML9JRMl*lPzeoQE&Sn|EY9!5^+U zh#j!kJ^!=s)&Le9>P6K+g0<62 zO5rxx;6W8B=-qQ=gS9t_d!hYo_^!`($d@#fC2*;1dE>vn;PNnpD(j-|8tTs@2F_U!g8eit; zq`)P`#IsAF=OWu`n~TEzt8#?ut^5PZJ6{q5D%6QB7}iPXh^7^th1Qg^T|8>@Y)=w1 z(fvfe!0+uw#@RskO?dcjk<$zl6}k+-fNy{E3p)Fm0+-Yh?wrzT6Ngh;l4S724+|*3 z4_U_j|!&`jVV(R;p3#h49T}X<$rOByw|5Mc03wOoS zJTD(TWmx{SNU_pfA=b4fB;)FE6@(t2n^o5CA+(ggr*v`DNtOLuhF&c|9yc7@>oppk1+QsiFF^z`R}bfvpCY=Up8qIS zW-0MYNKyBc`w&?(#r73osj>T|Hrv^-od$6Uk67T(_PaedoB6Pxwb~e*#M={*)qcQ& zY%21%)0dSyf!Tyr%wjvlEJDN*Tn+uCt7qQ{ey|G-S2b*lhRFy3Xsd<&pXbD#S$sI@ z-w$vu%H7M0wa0wioLUi~ zNE#d!0mmLT+CG=6w!2@U`55zI2vL7YG+JN)(D0qoa0`+0H?V>TV8@GzJ0!8zfngL6 zOE}smwc1i7NeQYFV}s5DcJAFIuOpv%{7WFc*O@jhJB+1Z8wsu$ig zxJYn}8Gq^W29}_>pM@3w)fej9R03$S*M|vUhXit)SUL2bu=CPwIDmu-_ZJy?9(c}t zI-b|vCp=Caoc9roFO=R^g;0Oum)Ehdrd;-3as^4<6M(0_3v%zyre!gOZYiSh4aS12 zYJ#CJgkO=rmBAn!XMne4pHVOu8p!4^4!k<-V!LK$7Jkr92AiM4q8~aP(is>OD7B45 z7PC;0{db7pYrQV&EuG(QXj{>(FA4o^L(ZjYoLsQ9hiLr)Zf{ZqdNx;PgXox!xcCAq}IXnPmhH@Yy; z0N(Js9W&Sdmj&iG!K;OQgO99U-Gntm8J7GgriTe;1r0#W}0npCNc$QaQ7p zGm)tP$J8XeRSgyYuDb0^;*gc_`RhpP7Quv2lvvMbd-`+u(-WRfzvk_iN<05EM(6)) zSPK6|tDy=UaP;y9{H_~S312%MD2-KK&lRe_KN}+O)c90>c8I##d+Ehf~1Q z>HHD7SuF<**{@L1C+wN9y;=5WpoQN>JpZ{s<*G5hrH}3BlH#4$#Z0hgTquO2&SyY( zw!^({b%0WBH>%N?tTKoxz>%y;Y{juuAm_?_hH|Fq>}d{LCEO=UNKPWs#s3g1ZqOst zOS+Z2_;XX1veu$1@t<3A^zRCakgc7_t~0{sY2xn_isd6o&b+gk&(1nnRPSf-?ed*@ zhHguX^;+$E*#o4fL>DDt?#X0=%>vk|WzMcL>1V1yx7_#Jvv(-_t9u3JuH@)_m0$n<#e-LrU@hync37iheD@l1y3p<50#tE5{!dF{I~SgHc{g%{%NK* zFNG=_kL#Q%`j%%C$@MBYp_~hUv)iQNG5!XM8a|wNoG~M~8YCDG!Q67ipN>&W+SQY8 z_lET8z7tiF^K~IhVM`P~s%f!cCUYP&&LihlBank-%TZhXSN{m&g1Ds?RN1>9)uq>Q zFHXRbylTJSs3_m{NdRIj-4QBUu!$vrts6(Kkp{C46Z49;dT%*d|KGk@#vlLo&A$I9 zCPp~MAGmwh4q#jx*I`Y!T`y=k`Wm!fGe+gx2moJxZ0DS?Oj@m@{ur@7t46RMmO|FE zgvEy;C)MivTOGXoZ*SX{dgEmTHqOjJ-E~A}NZ))@?ld^GpU^$<0Xk?aP@)4(dtc2G ziNZ9xOb+gCe#8oB)--VSsvreE$p)A^e{+!Rk(_vh`{?$?ddObhW;?BB-wr{U<}P+M zos=@!ySKymZ^bF8H#2nU=av$jF3!OdS?oPaBLS2g3HnVwpyI8_tIGO-7A>{#e-yp* z85oWfq#LaTZ!{Z8*mlnNLMSHl4P@Q)lR9W2==FqS_Q_@AOKX>MGuQfW%7z>rMt^>z zAn-yXnS!%E@0vjghpxOKN6sk?{xCO#ta!ggI#{PHeOWGgeVP4|Ua>of(S~bjeBPdu zD-BhZrgyUEbjm5PBU($^nUF&1IzrPsk`)cuf7m zZdKFDDa)2`CdEc7^XLi|&r!lqQ#q+JP3B^%_!u;s zW|^~1GSa#C*)ytLCf&BgmuJu4b<{y2_BKHGr{-E*?7Rzm9?60__sUheibv>`EQQ$X z|DdPWpr7Oy9?=?~zLD!n{cdp&t9ta1H|IW4u=K=XM$RU!LxzW933tklLnoV=e#-@h zzyx%XZ6n=_U*G0Iy^Jr|l#Xl61rvG!cBV0ue*VxMH>jHq2z z^2)re{|{LNrkr$lK3nBrMB~|VDho6HM|?Su!66Ma6WrB0@uDNw{#F2DJDodv zfz_i(Me(N1tI`CzNdXGH5JE{06tswZhgcRvXdS_JC(Zr}yBI$pqZKM~Um6mm8L<-I zrO}gy^Xb5A>(QlDs7*Nb_hV?!&^@Bjfz3!|y51DgQ9_Qd5|}Hh)T#X~@~?j@V)Dg2 z;`=K!4=u%C=L(&~>Ca2SwB&MJbC3sh=OWPN4v&yyd9ocxys~eRzrBT?YgY#>CZ;Qj ztAGAzFb1H$V`y&-=J$>5ped5U&rkcp0WBvrd$y@+^^!iQz)E3~YEl&j`eHo^Rm8mA z$(K^`$qI=rCqgviGnbi>(!VWaPW;~Oy>>~&~U_h|GqKuUnI_*B~& z-EwT&iM_X(+?hadR&J9d{hR~2jOn8w+GzF(b?4QuGHPR|s01yke`emoO)uM|e`#(@ zkb!FfyXlQ5(S3KccL_ZD9fZS|bM=JFzek3KX6(RqUBgX0rMt%qfUwWm;&^h(#Nlo& zF&wMLZ}IjbJ7umwbDBdeq{@`GM#P-DEf}X;k$N-^%K#Rw>o#D3Bq7pDAmeoSDq|V<$4JQhf|N# zPGGp3IaT&(rPT3lx z_j(n2WI45BW#ND2tZLb#7J8<&7eZo9u}* zGohGMtel|VA=*;QNeT>8=u{&PkcSH=m3PcwxvqlFiIG}!=}K0WZUkY4Wci8QYOElM z%76C&DfE9-lbZzwArBirF2d{kH%Je;L@j*tS|_G@&2qr@mJU)Z;gYbLdZ0%>M|a&q zD#+M|W(Kz?1Q)+hIC6>w)W^qux`3^mNLMKk1jsew-jx%1^>AF4y)p0R(x^A2*0Y3k zS&Y<^mNOe7_`XHj?}w%c>FdcZdYrvT2cKrtiXaQk!B)tPEB$((#XVpa6=cVG4KDqI z{aOmkU;fd_ zaO8T7Kmk>$=}o(tAq};#(dw9s#k!Y{Wo4{>@SVz!zW1@voj2i$vWZ<{#*S4y+*-FpjLw!ek52r;Q0-5 zuLuwqY#2=aG0$zW6x@!zBVB-`>VAP~jDO~SFOhjP^iQfwrO@4!nsa%x?QGyxcB!pU z;AkT(JYrk>()>8Xi-jgfl#6a2Qy)$p{@@Trh)iuMet)axe_#D1g)F05_j8AS1%lIm zv0JpcJx9~YPP=OAbU(kye3)z8_FxkBe1Md{fL#lDU*5YQDF_)+?0SJGlSRrO&fq%x zdBQgUu{@R(mg*$aWw5UZU2^Q%9af?is8Pz2p!(UI1Qym|DXKT;pFXXo=F2qe%T`@$ zLPNr({i~!~N(Dm%rwq<@21i9zbWsQQxg|bi3)GyjTU4B8W$RZK-&V77neshIyH#;& zWL5{hFl|;5ez#^T@&ztsgs7%4H`)&14bbTgxtQXb|{qLai?3 zpQ9`~vi!szZ^{D>RBktGDOOYJ_&Pf9gMy@_7$HlRC}xC!GU<728X{o{*AEc^X_%(U z4a+caq7I#gY9~y2>p!~l5V$gc!Z7Vh+vW)!ZG*U}xhq$CUs-*S)cG(JtvujxByku@ghh_YU!I$1 z^n`@iW7Zj@#p#-)&l~o087m1rG)@0RZ1go&8lM$)|9f$wQQWNt(ptNWxk7i{GQo;> zi2f=d*qLa@{L6o4_L*aMIX`J4kMG7OZ-+jjA~NmRL+9i<*+kgUCiOKbDWb=Cvc)j1 z6P1Z@6pe}`{_a0BeSEw2Mu!`})nI4(v0NQyKJIsi5lUM=Nt;huC0sNwND7^T6T0lv zfa1aW?LXnR93_nusRUS(ebX1JB^=tmvi`ZTqUSCQMel=ui&O!-H3o;q=#2Pl_4 zG$mE$o>#QLqp~v&^Rccrp9f`HROi=mrtQu!f!kogQc;FQA0xy_noPG>4+0^a*VPHj z2n)_uf3{7{+mZ}rpME?G9BV3-UsB;VHZo0VwFpgZ$-!2H2|lOhZMRF+zl(|@RD2nZ zO(V+uw~D<+N2+9xOi@98e09_9Id3;+mB93AOmJ0LqoZ?#uh*7WW2*fAvy*9xIrXiC z`ddui(|_of5>?tB!|oZl&+H26+8ZHQ-h%7bp23khKBZ;5-8@u@! z#antea9urWrvNs_Jt9~6BukDIkQEcZ{G{qJRm*K#&t%1t)%a&!HKMyA{pg#4w%ot#D8Om0fB6qHcRcV8!01DMS&+-a! zFZv@BuRW{FkPH2th0W2Nj#)YLsCdp>f0mjhfejedXX$pigcF%@-%S$wv1jTMHeoWZ z43+D03;$?qRoZ?_H_n;V`Cy7(s1}O-m2N-vV;3` zFR3NXV|Mg}3Dx!J0orba8aF6TLA{8zPhg7A*T4SrJca(ZW9|Vu!4{+<;)>OwEm{Pl zuRj%B0T)myT97>U0aL4L6mt5=}{}S_4%y^zzE!e5%f=q zx4hyUTP^WalU;LVKN7v%?IY_|G=(oh&q#ZkO9}c_L3j%VEvdF7cg7HQeZ*R(BQvbO zZ6n7o>zWltv;RDy9!~g{K-h1^e$JfqBu0U-Tq9E0MH+}>uRmm)dYm~&Svo?AQ`gbw zA(Tt>xD)ziPf10K4@?Y!C$rdGJd(P zXYyQ)?0Y|Ii5MCABj9u05W|fjBz5TUB9<8d-Y})p5*qj&&z>bdeIy@01;Wc5ddF*M zKw*?vo2J1pSWFiSEJ>YX)k=fqNk}kT;fTBJ1~`;Wsg+;-{PLjduxyc{&*bfaWq}1jZY5hb1YtBAs=4W1Y;O}R;?RmA8M{X<<4j=BZ*c-dlvxuWm zZne8a+p99FbkCT;@4CO|foAD-t0&TH7GTfkF}q5SZ=+<+TlmIO+ALAzHjFXEW9W%J z+v+8x=%~_}pXvX6H71jF^={tKoxvJjjgHPlDmb6s76|R>n46`??bN;4L+JXenoy`V zLvIhvZaWHTWyY)F6>O3z-&6VCO{HkoOs}QLBWX&r7QOW8H+lEa%<;+>Lg?iMtmQ9T zJR)GO_Uc*&cwyj%pxkTAoLH5T_vbZY2wLq@3~xDwYg_i!@1w<=O@bkbn)2p&_?-sP zjicyTF{NKYI(k;|+KA%dM)n>*aIcN6YX%cVOD4JU5B*DWCtT z9FlVhEtQAh06cZ^h157N27_y;lEY#ThDh??SND|3>6;jGVr<>l!P>%vsjMtYJ#dT6oX}HkGH&F?3JNRMej_N{OaqByIZ@VS3oV*aM z@U8`lTC^KcFvz-biQFc*s(Tw~C)CBJJQneI2N}eqGYG}0P~2O@Mt0i41oB6MA(~A6 z>_0gv#EK;e-X7%a<+{q0ut%7$19O54>sW0$RU+;v*lBtT!a>)l2kMd>nd$* zXS6*|4x6MrO8RUkzWuji<%ex0+H4eSN}tSe&S8=FTpS{|)a~$7Z~zNxI|V|XQL0}1 zi>f)U>&Q>j+7TCH-N%H)XyAX^#7?e}_$i}Am!b~{8oZ3JRK8({xvcl03Lchl3Y!o) zo_DR6!h`%thOeEBkXIp~od8Ow=ong(8GOzhcTf^-I*N*EN-!MVuL)Pm35B;Y|D4n@ z=AlXYS=;o5@ZuLU)0Eha5L{VXjkQK%&Dof{HTO{<%zhN%gOrCd$JqV)gEZufQ7`JR z%=?_K_7T9J=I@o>C^~gcp*Hh8?%(*&U(`%&N`FZ*HlB6}j`T7rUflD)OY$$$!LKD= z2YB6inaGx}R2;=JoOh@jxt8JJgngQ&Zs9apmn ze5D)$oqsP?p!Sjv-A@oTd9zhwBn#JYfj;wdgv8!5&{R1t$g0GonG`1<{!j&=tFLth z+NpU~H;K;ZD0x4)8oONeQ&u2Oe6h9nI5?}7RA(}Cq z*_raRmCKq3UT20#6Fr&vGrEi}!owMfand9IVf{mag{;Cc6haGEIal;2BEoDDZ>~!TPq@&QQ+u>Yx^Fdp-xrgY;g+i*B8O2h_0;|%stqzNjmF)B$svnM$5%usSH%o z#;+o_u9O~jjbX{d`1Fd>Zn~v#;IBOH`9^|%`BeexSBmeNxsVcuSl4cYob@<{3X)lx zc$0#W^f4q^{WO6KYnF`|w3-lXo)Vq+unSLDNsvV)cEkZ3YtH$T)b(36aYx%7Y>zR; z8boa(IQj26rr+_$3bnhq@b8?Jm_P_So|Ee=OuKL_SDxcH_$z|8biO2+B0`q<+D)S0 zEkzV|f*ITS&K$)!QYrSs!vteS5?1{D8h*4Zr+Dacxhwp(?l8VoD_Xe7XH!nLjuz5& zX0f8d$Y&@!rxbG6V9JFv6Li;ya0lh0S-pyf%2$_K7ilm}k`cS!Us?^}>~O&IGv?hR z#SN&r_q8tMt{A4EoY27=wwIQloi=9PnI zJhkY}IGp$9DP+@mnqCZJn; z3;bWK{vd<8_0cg~F`+j9ly0mW7@A(7PGIJTm(ETKL!188p?cuIeVfBNMsXS;iiznn zD57MIBl9|`NumXDDD{v(rF;p!YhEhDgUjCTjv&agOj2D$+Hw!uzvnm;N3lrjIWK=P z(XbxzWD++jV6VtG-c=L!(=*zsIU0A^z34_c?C4Odptz`UwfVfG^YSU`c(fei-!2Ai_x@LKi=)6=#|hcm=C)aQ4Dh(YH2mqm<*v^Eygczkao&z} z-uytX^+nzNSI<-D1tn1{!4^Jw9@JTOknXyOw%H4ED_3Y`bJM$&YiOO81U;v8f3_`l zJepj1`n#N7>(Y1Prl*`Q{b|vHjdESNJ;7Xr?X9aL40I|IX2Dj5 zd~Pvu@!o^_92+;f(TH)l)M<_}Gfs?Sl zQ1o~~i7B+DE8Sp^tX-Ac@MW>gZ0vlMNhSo^X#$sg;m0E(Ia;{!{gu+ z;jm54zIq_N7I=&Lbd*Xd}hupmSKpPvCT-9vM(X)ObeARs(U4g zv8&KjV#;!6jIG6%vSb^rDwX2aRF=aKvW-$nVuVOyB3qXEo%_AN`!Dd!Ip_I&-tX5d zjI%DUOQK|n@tBw3Pgnw7e|DDL=xSQ{x5gg(i&rlAGAg_lSmCqzjp%Yzp;zY|CTKWe!$18RF3Z4m)J>A+xb`I=^)wE7nfso1)H`7GgW)^08?AJ>sa-3z?$fW&+k;Se)8Mm^NXZ&Y49;>B**y?1^&B(C8P~! z0wHDT1UJHRhGzsY(Pj!9zFkO$f|%Uf+UA)E!!t{B(`4qLMChjVfpUfNL0e_@+G)A+ zPf=S@DY)FdPf<~zm)UmPDQ?hZ(X9(&npGS8(vjV(&y{V{5U#1hQ)4?AUb;&r)DmNH zk-~4TM_i|!Rft@KK&d7=JXGn8Z%Dr|+q#D|iYT<@P+pSja- zK6g}*nHiVP?r03PxBMTIs&N}VQsH;#Wmq(!sfdaV)wRtB7VNx{5!A7)%*5qwMCR~Q zLBZS(Lksp0*C~M zZ2*q7s5)M-O17iMO;Xz-l*8NHp|1rc_&rd^TdosOk@i|7+nXAUjIdS`4*S8n>2Bf@ z;e?_XXBA3~!BEXLGVA|r8IW&jN^BRpN`z|J1b#*LZbH78U0rsA|9{cOs0GDp`TBla z#0z|<2J`&q^Vc_E1;ttQ>mDSS`TOg+?i>ETj7O8E~)HWvd`xR8t zizd8Hspi!vb(Cnymh;@&kt0`;y`~fi*f2bHX!L5D$c_3Tid34hld%z0i4L>b-M2bQ#?6*VvU?nHqP1w24G+Qzr4-3{N&?uyx9Kwbz z9qFg3=c0ASLT>3A(t%Zv=$aRF;#y)A?Zu_K0jnX@t$%%YOzcA3qMfD5GF#YL7G%B| z3>9;zx@b>(rLtbhtbd1XYQle8i{Jmg^1wI$d*@M5ldS5@9g&v5E?pu$toz+bxe(cN zAHit7NWmHN0bvjW5Bfcb7rZ(Zj19GAA$yjDxb%ty*K*Vur+Ajto$V@e!ucjpqCozf zic)Az-A2an*6}I>fzC0Zq9jn!)Mg@X(NEUzsx>W>cnmjGUJYQToVQ}URlr7>{^k0n zCgh_Tt+ads{t9y4W3&2YGrZw|W<{{%N|k;9o?c+QTfzJD7VouH(wEJ8Jrp_gv)W>C5| z*3cK#BwHp=I2H*bzcbh9%14jf_t%HXLH-bimc>?-)aV!WJs+_+*_psXcyWX_XwW_8r`DKMScyuCU!n z4Lux`e9e@-iYC^$bq2xCc42UiCXQo_shok&Cn_Z#%^sEtd;5d z#wRR)?1S=U1bL3q?rO0%BomNrBlj|*7GC9N<9n_K!jz8lKULun+obX?^|DIBbG^&! zd3P?5VnNBF0PfkB#j$iI!Q1jE*5d8X%O&-+gp7KP)bN{&Fv1(dYDP$#6ZeSBSP}Ju z;ItusZF!pLfXZ!STQ+i3SH){u)oWxAGpg&|fP~rd!T~la$pB*8Ae`b&Yl=FNmR3G7XpQn zTf@TBg}n8wSB^i0dLVeUig%13Fz;}>FB^E79V)OZ}T@Hsm9?+*j!jo+m>&RMh~ygPs0 z(_nI-B9{e_v9)+SV6@nRF@RTKCM z0t#jPP@nIj+D~%}zR&>l9db>`BD$YDbw|G*E;2e{`Xpp+cCaMlkLm(}AU2cGS9wM? zwE1yv2}zOljql=8RH$VSm|efOoVoW^$E9!G>6DMrqP*R5U~ zk`-OwC2~h!U+6;QAKh_*6iQ-&<7@n!FwGspCd{9z8$m_XT`9k!qH>5@u6s;3h3C=5ys;#v>Y1 zEu&xx7rS^+7z$hZoRSF4XQ)(Toy`zM%kUNB>zoVLR#-M3=a%N( zfYIl3Si5ti$eDMA(kEDc9UWZlhI$0pmxuTAT39CBoRzq?_yzsSYW&Hz%qI9dfZ=Q# zYO!R?&_O8<3Z->PrtkpMboJ8*N8u~;vIG34`bNaHt6zX(W|L$!fQ{Tbf)mwdi18`D zVmeHC7XQRs&z@ORP}nZdIDwwbJCfNt%`WI%DlJH)#j6`7btHXzOR6eu1LNa?+-Gs9 z;$Y0gBD+Dk%9LzzpauKFBuVmA7p5#5+vf;OT;XK61SdpJ(TY0mcR898VXfpw+QMDL z_9B_ykMQi+tP3+)AwpT@%u-EZ8SJ@Pespqnm!laG2(b*ixk#ceESsQgEy}6(T$gRM zU`{YW%(l^_;%gJvfy8mI1aEx$sRT%&(vz5uw6%i)^}(PIxjqhG(VUF|JBXPwl zYbXTK(f4;sk@Jc;DDw8k=8>@Vt3&IlBvvHGyf@ zVFKJ1WyY^u8J-*Z>4?;T32kDOWkV8aAG(y;(aR+fTFxI-69z=nDvi0zO7Yu69RC4! z%ZGkNL|){jr*G!mys5W+U~LuO0TpC}+@kWp_uci3g}%R$8Gbr9v%tr?Zp3nS3VceY zjv_nIY+FyLMh&vm1wxf^Rv^QT1uu1&9>a!=oZ+=$H~fh@aUc`f9||L3zK|HxR{Z%G zI8gXw%`dfQUEm_N|1@8+UtgsB;wDBhnu|4YWCUs`_H!$6XH;mvatFEE2jI|uu2jMe z)cZcpuftGy#|h{c;w4(XCmCz_aR_^@tE=NR!o~+tWsHsto8B5iZ=RE95KwxZ@9o#x z1)=m7n5|&5$Ft-?8PT#*!z6! zY&ov^eUhg0=Xh+V9{a6>XQ8B>x#Wcdu5{f*Rcn3J3&K}j_tm>0CB!Q`nQ)>71D9F9 zp{v}as-NMi{#+M|%av|K>44vGqQBKzDiy?8*X6v4RID7a6a$oJ<9`IeIx8949-@il zH(zK0Ty4I*yk>5)ZP{4x=~L-3`YJh6qI|G^NbF9 zyb}E$b@>lgxAd9jB5;DRyK$tRDWWBfzLzVI4fW3>YY&wY`v_z9@|(dB!FGxXWn zHF+zfz^g^7x-?H82^IoV+W9e~hMc5J8#oKA%lK#P+#e@V3oPy>rdD|X;(;zaKU`b{ zc|>ZFqGuPbA3|ECvUShEt-voRe-98UH-3T_hs;Gek%DiY+(Vabp^qtlL_3%Tk}jCBa(dYFlB_Qi zy1$GF?s79I)q1W|zb^%OO&yu^BU)ISMdp4a2-OXR9|=|N$h*k=pVGaheu+k6Kj4*Z z=+Zj^9aykth+D0MKObc-`xA*i3GGOyhUW{8#7l}6q-_FM9b4&s@J2vR{?^IYxz8Z& zNU2@Xf>@ko0vua!%z&Sp)8LwvPrSqn6FK-s6uP8p#c16yZgFn`N*k|Z{jA3n?h8!u zkEf5JA}>wBJ*h8da-7DkY?pqjx`Uv|eiDi~NQEVo=`Yu0FZo7r3p1V)7dP5^WRf5s zeLX^b`bTV&J*cNaYkNjjcXr1RK20O1{zMJCz|&RiL~1{3V149NQ%JH{ycUq573v2` zbYy21Ol#VEFvfsxfIaSPiEU3VE}JVso+LJbfWb+G8Sgev2~9itU()}(L0O5znJ zlY56=E=-#94TZ^5gWQ*z)ac_ZR|~*Wk@k%5R=1d=>3Iafn=eTlQmzQX+T`PVPO|>S zJ!i!@Z z+I{KH>C(I|sjrV@p!{d*R*%eEBt>T4=z-YyFCPzM1wY>}IL7-~&rGT_TYGSDnax_} z%y_-+KeKF71Pa9AWKmYh#*VXjLz_fQA6a^czrLuUK1i1gw-P1V-Jk-|G$O-1UZljl zX(=)}?*etUN(yyOiQ){Pqnje=cgR(R(mg-vm?&?WIT`*jD(Q&KoZQ!tP4aqEH0K$! z`r8exqY@SzO>Ck4V|0XPowWCxGs?_uN($#f5|H4Vd0cd;urjA2AJ!NB>=S3@xSMiy zH8oIZv(2#4sw#;uH28a|IWDnO?Ns-FeSnc^8pY3@{{#I0}w!T`O{Iu+oI!-Bc?U%hk4TVFdOvYN0m6 zDUu2p<8}t7P+Z-rTVh`Bu)y|n5W$NCp`KQYz#LAmS0gQVDf^u5Fj4K5c#9agD3Y~! zLa<4a?j;5!;)~3v!Jr*+C`N@Mo6v8F_&9PYR$YE19w|~e846%}QvVTb8ipXZ9;RmI z()Q6VuyMS0>BuX_p-N~Atp@2rO?ly1kRIwGp)M^-vs8mYZh*m;ScBWztfI!|UCUHO z_D?NLb>h_A_XRu``z}OSo^Ajyq)bGo>N21kQ6-2FN07Q~3^S$v!FTIz33a+LJgJX8 zFhtHis@f4jpAi8Ic;dRK4fyo=76))ookM{js132gkt#Ha~ zLVt*61AP-_LhY0(E608{1oJ~J#1Em~d;FHpD+YvNxh2G>H zB2p_gbA3T%Njl~@p5=D^cgkoyOv0{ekWhb#IHO2WPHQ-4jK}LW2Y{N==FqaH$W?l; zVeH%o$MH*&0I;X|tK)S7AMvSB)~rvCxwIiP>h8+71IY&kHy(<&x2fIj^GeQuT-QQJ z{~fO~x6^-ZXz1?w=aieEYmvDsM=%3Y?Xq@nt}6Fu#>rHl^(Ia!An6ZQ0cP!(s_>8Y zd(ggabvTwA24cRL*az*>N7(=~vmZ{t9oR$i?!$AEjI$jsbiUa(nX0?_Y#O4Mw;uT= zEqBnYYAUv|qPr!L_PtTELVbblLbm)|{YoUq(>!;Xqp)4*(9-H0&6Z*L!fbTGgHdj9 zqgX6(X(!Uc6(m$GE=x}BHQ6>r^g}+4q{Y}$v1On zfU|k(k#3k!dxuari4l*VVtnk19sUvP*)2Cr)Ega2(|ve!5q0O@1zNOt!zRa;`}MdkBs{)CfQ5WvaSX_{)4lVEl z-~S~XUt0FXH{FIyVI7@?P|QXiYf(XDvDy8lbk+NkQL+Nxm`*@egSg1Y5+;{ux(2I@ zxNp5|8w))oBCK^4Ue*3?hNLV;%tSr}cU}JeOB{B_#iSukhGR>i{xqroCXYD6mU%x7 zZOYAsT-(1m`x2=!DmHB0%#SzHKuh0>C;lc#jf*zk(n^9i+XNkB6mcASApF#?HG8a| ztf0t73`IZg#}vEI3;9;q0Bt|)LHnb^ro_E??k|}aEebcsmW^BDM!7O0g<+XD9@Cap zsb~Kn@SXu12@Q^{397k|5RhV>)IwkSz5rdseJGB5WwI)?$4YB!ViiE4dCnBHv!^YZ+1|YdI+cUSynGjyw0rWZ+$+fL&m$7T+lsOx!6p_)xo5_qGrO4^TD<(L8_i_nQ z%CbMmlkV3cl=u8%oHCA8vMBh_x4N-g!?a!HyhSK3r?7ZupET~V7 z660AKy@6{5qc<)%LP2|kt9p9{*QM^I%J-Kp;c5#IPrB#Hi!Ddw4!dV&_-$ZVeg${X zDSO(zB0j%ngw0PPFNP~s4JRC7J8!OwfolQtMa}qFD5}g%bkkH6bc(8+kj_hLkA-bV zh?tb))A9bjK>v7A5T$`4IVr&kew@hu30$lBjr% zx=|F+8bC^&R-%W^PcyIhQ=7U_#*J?41E@H&J3| zTAh=dluJz2&i-Z(Ifyzl;ln_G#5%hQZmBpht70t_{rY4Kqrw8tcERmIcpUd@!EuFd zjq#qxd2Pn_S#-6dfBdyH?rM^3X;KzDg1;egyG;S;hzgH;D*3Cv+S=g+}3i@f_Eo~m$or}kHI=eMr-k=sXKT_HL?V!6}eSS?*V5a7Gb;q(?u`NDqRk) zz(hDXN=?R2;(VOWO6^*~#QXCI-Y@usFwcZsIGk<3mU(LhU3fX$ej2Opw;mhrr-?lz zOb%ew5Y&){pCeN=X@l1^6?#8XEf)}i2z%k1?1$_1p$4uCM4y=kSJ4`puNx4bDv>_N zni^B9ZmagMBt-9`s>>|~#lq0&(i^v7jz!4g{0|&I8WgT!1j*qZ!u^K5*G{{qBo-CP z*i}n8jN*ErC0xEdGJG9YJ>~aEvsLn4|1Wxv_3>ea)tmtrT1Kd2-^W(2WdFwR`+Yiv zsZZs7WO=!_kv(UZ#kuwCdY>Z<$!FJQRDtp2lkPkQiXSene1yLkQ4@kV)4R9vIjcz4 z3F{|McEv`}?O;=|98CtAhJsG-6;tj=(9-pS{TFA&WM1yg_oyVWZq3B==pM6;)@5d? zfb$4#As(7qrlSWkCRAA;MArneU}kS7@Qtz%&dNBBkcRsDxE2H$zdA2k zK}Hd2>gT7a%Zn`CP|US96N{bWW{F;Ha11r=1KV8XAY1n^TV*VL;yUDNs0`?JaZDC} z8Pau&)f3s^HPFBKD?1f@@7Ye=>fLn42Ly(@5wPk{>QNr5_O&(yhC{W z3FV`*S~F##UR6#^%6xiH>oTHz8S(u%-QezTf=`*`R_*VOmmS>W*D@^h8xY^FP_b%j z_3yT)e+>#me7;h9feaM^>T7RXM_oA z!5KDk&9}aOZ3ZVvcWTBYt?w1kgZ+bh&yJ~cY#32HRID31@m{B8?~Sw5GM+)wQ~Rw3 z0!?z>2BpR?$TGVc4`bnEq}90Wd2J|;TzF{%z9~Aw)a3f#D(&pC$>|r7=aHw5Zv~GD z**Tdev>%v3H%LNVKPkO^`~2CJ6e~LQcs)(^_#x=o8FSWQ5_g}gp#7iK&e2AsY7ez8 z!A6ZM{gW!QB~!)7RTe8NtRbhSRp5omt&Zcn9Vel~pLCB{H&-Be4r(8-a;2r*9vya` z^#rBVvbGeMu;EIrht9WQyt5Ys%r!m4iO6&aZsBuXVm5$#ji}pUfE)g znrdQ?3e(>EL$VvK7;fo2qOwRM$5%)yc?6Lz)WLN{62<(W@Zvb@md$vhz9ro_c({Xr z*MC?O(1OtTsE_Iqlgie#%7#&REddOyd~zSQlh*VJ>pIR@-dWk)9g#XasdCc5qz6*hX z4G}hR#*1T6?VKhZ9sKO0BmSvR4)}>obAk{ZU)eJV*z@V6)3Wm#x6@?Y5_F>1A_gbB z8qpf9DL2ENKxPOhOWsDSp{0ct%K}2D&~|`?2V(ayrIKc@Ucxe0=5~CYf+;;g>}&Ak zx^vg_5*?1-_{=uJDHp-5WT?h23<~n)!eD&hhhM^17g6$Q?5?r(RlnZIF<)Gf7VY0b zqTdsha!aCcUpY>Fi{Tihz0k_8gVgAnrA^v1yy-($QC0q-lu0( zcx#`)uV=BOh@;8r7sp6z2)C@I#W{P??ZDt<*x_RuhP2#c%dS+bhFoR^9A_z*6r>+| z(83)Rm$s$sXOl!YwKVnc-vBPt39dKmndc+|omLzW; zV#|1mzQ(#|qJ|fwD^5e`utP@3PXBV=T5)N^{sfu|&q`Qd2^TElw7DPG8*z7Xv&)0w zkQlzVwIT;SP%XPx*_<^I4dljNRk;YK*<(z?l^x7?+`k6HHJr1wSuPJV`QI=Cw=tG_ z`ROTe3J-(s>L#J|9>(Uqu1JDG=E>6m0&M3zYbB{)eh^pqZU&t^`?cAM_~!H9#9t#x z@Lg;j^(~^kJu~PaH%_s_6&v`3lZAXQNl%!1Oh=Q6hzSPEMtkor-6q-$Zlx+rv=^ym z$Mn-}SmhKyk(s!}nqOp1Dx#zI*DE_EP+U7uU*&^^bYT3=wkV;~Sy7QD)q(exFhQxG zB?pS-a(915k@aCy(}z8p{c{8(?CH(^UO*%Tb4(f7j5EjH#0;GDqyAvBVm9ODXrVZC zZsupW9Pmwm;zdsBSjhfAbsggV|Dsh5z67bDF2U*D-tL?u@MD$0%p#9l6sMG|ndu?k zJ+2gE$o0!Iy`gD&F-V4(W{@JNSnlUY6E-Aw0TF8LjPcmKy5B8!%gnP_{bfT z3ng_FWf_!eH{3<#l4Nv*9n3*?LChg`rHb%VNj~L9V{Xs@${(Z^yrTW_{4au|xdAW` z`S9jOzA)@~i%5le@3Mrl0w?PQWs&&C4YH+Cbpzu7jmPa$pBIo3i^%9-tLUgdsmted ziq1Aw0HIEmMT#6nhQd;~@X{+~cuzl0^l+tnmw@7IzuylC_$f#>t;Ecce}c|*#T7p} zgJzCI+`NVW`DcXjtmv>~c-4(TB!7Y$osR6JYA#R9G6wnjbbhBAQ@T!;ag=1g&?B&U znP4<$Cw0j-rEv$AR&~R>4zOKPU==wZ6t3y-lk`Zoi2eh+ThjM=Q3!_*C|nN%c`Da0!bO z6_Ym!+1P{ZWoj?WoWlL6ENItMWy~uy;(ll&&$Dg!a68wzo5QNxc1P}w2Q*Kq-lJ!( z$kXM3H@aky&XcHimKZV4Q`M}r$gDBswy%-z!eHj9;6Utk^9B+5s1EuI^JdUBu{-EG zyK|QbH;S2Qqs*t)s`~I2##vm7myesIA4{DJ&Y=rUM1h>sZdqwQ;j-HtGF! zY}=aiNsTgj;CM1S9lz7t3}*Kzh)^(sRw0S%{39XVcy(97Nshx$=b-?%<&NRr+W;#&)bDxCulT{6CTg(KD73}B#_8L*e*2=k5kP?HszZ|s&9SGWsFKWEf%6Xr7FTcz2aWKFP+2b zNH)a-hzl>JPoBg-glcTZ2ap|}O~8U9xTVmxHFNxWy&R&t4(O@CeLg39tex}5HnmIQ za4vcx45*YJzkO~zksMfwGx*8>y}{ifEDCArf@ssk3uKfsUpeqT%j_M2uXU&0L(o+R zf&Nx@XSwIS^CsSB=d*@d;pBL~S~)ZvL1Hx0pE>~It-kRt-wxyw*yuiX_V{&)o6cU!7%_2pwvb zguHB3+I#@Ih%Uqw!CAB{k^fP_IIb8teX9wJFdZlz_4)*OnTID*3@Ha_i;%rh2Jy!B-N$_EO;8Y7LF~k7TD%HTE3W6mVj}K zt=#)?rtbKLHo=>?tF#%kBfkbl_KjHQldiyz9zyMk-#Bin2F5@VI5HK(e#gp@?|+ZN zdYLY=qiOGbDYIBqC%ro6AGA$25~dgCRwHwdoJ83wN3-vQj84b3BPR0x?%QR$g6X_s zcXlp~EkpF+=3hQdU6SRhD}$_}yv+*xuqXcFsM z-V0Ow-sM>t>x)lcKF*?@o;!v$70&1<`(deVl5jjRs`5~s20tW*m4e|R7aWfK{&h+7 zgL4YaZC~aPA@aTKm9L&`bD2W5a^a`neyap`TlFe$IkOC80jyt5KHSuTcyUtWy)wI- za&c&)KH-uueaopaw52hs;3N{3*{a{dU;BveP)cwee3LU8;-32@z%zbDo`2^A2z^Fp z!Y?$~NXbsw%0T8Co>1%!!Sgze4Tj8W7^(9`r+2^%@kosdkqp1Mt)#fsjr zwmo>8@PNjy*K#q=^kYQ&%Q;f!ZzH_8G)OwsNh0!8?ncpuR}R9<_d|BwnUzElCYgwS z@_!@)>>vMLriS5XFkfy_)^6acvUMQy$7eU}uwxzDIc5#e;Q!7oJ;j$vj-oe#VO6Jf zFFb-N7#iGe!A0oPgQD*AefCm?M@=KoG?Dg*xyQvc)d!ej`+zd^MBSNXQ~v657m@lb zkK=4lyKx_qe+O3hxr`%p$9r@#?G~@ouvpQ$8@`ZydmZduHx}+IrOZ2ye}n(0>)mgl zt8~#-BT}^v8og*gz-Sfq1H>UquFNT)+9TV3uLK(2m(MEbcLSNY>b>0(P2}L0(dLCa zU+&829f73#Q!~ovl^J!f|4ui;{!tZll(NNfM-mY=8AOUwd%+hr>$D0h18n)m+&Vm4 z*G(OqEh=4}P)!bT6q~1_PMpoXDi1{8q^3O!F&;GCb#g64pg8IeGH1T%^Au1M%!EFW zTY>KQEkcAmltmh24f+=n>*bjHJxoOpGYKcCx~VW+D=l&m6}96wav{5&N0_{Xu$p@2 zxyvMP*D2G<*kAdj^S!5&$HX7my19?d!v6daC^1-Zl|8-Wa*2ZIIQ1E0)bs>fjKy4d zJCqaDiJXPy8kOL4rM~mKxt$B%!uEW9#$fgn6k+>?0vnDT*%n5KZx)2%j71wa3tpXe z=cp_Ca-B@d*30Iv2B5mUSC$D|Rjwf;6^*q5Z)`17Kt}8^zaB-S%S4SlP67q*Ez7<) z;EU!GIt*YdHOos#nd5e%$7dQG1+hxO+OW4K?fBYb5Qq0=-3eyf7;q(%Kx*^~`m3=e z{m#`QnaFjHRXC*CFY+V>Cp>=&q}+MUZU;J?R8VfO_oD_z;-#4PG{z--oo=S%^z2!< z9dvc6OAm(eqHi*JpGfp=;-SN~Q0s)_DcwY**%;F8gdixS0#=Bx`oN#FAs!U<^*e{7p6zl(odbKNE?R3NpQ7r$_xmhLC*@sNfrrI zuQisfHV8$rZ76&93f?CE6I}Ru`c#Fv2*~wk2fI>S9#do#GPlBLKpvVEvvcB+ZvgLZ z`K2%9&ZBQz_8!bHDbr$AT+!3Y@1Gtod4WUH?}_ zpYW}aiEZREmcLW@$2;MHvOsOpj-*8*3>IR{lkITDB-GNhY=y$u_4Z~Fj)@f73Js)s z-N#$3^%-A*NVk>^!hy7$;V#m)tBb^jThB=Y@GPfoPU1n|I=)287}aqKn7Z0Mz{{eM!nMSV z7E9r(2K4r&K|=$v(f4{(wZqJ;`JV-OW`Sh;cDd<$^>ROMN==rTa;z@!gKeorbR<%6 zG^`zJQ)b`sK@KNNGph`(tjZ4HhB$q1;cx%kn-eHGP)=QOeCZ@!*zu`ML4vMDJuBI> z8&0>gfJ!9L65Fz`1|%i2%#mk{kHK5!v!PSxQ}B=e3DDZ83stGaHwZ?U$Is}@i(H2Y12WhvtwEn+H{Q&K{bkh!>x|=tK$LD6ZDi{$o9b&&)>i_E+*`H_cj~Zat@hNZKQ;wTF~KZv@hjwc{b4SHz?X~ep*4v-^=UZjs*5$cgSeqF8t$Q(V3or#g$Q2&h2CrQ}Uf8omT@) zB`y6NvgiB_;*I(DpAC}e1?jXjLs{W|6~QRGL)XV7jJK9vD#y#^uVen2I4kU~`A&}W zA4f&)3GQEQXOyrxY%;U%;tgxt?Zr0A{2(Fz;1v4~9yhQC-{JdiAqvBh&*iJ^#?1RR z9gC5YhQHSMO&ct8*n(4arFlsMwecN{O`9*&uLpVM__*xVBf^1uJA`JHAFYhc0?!>c zwI1JXR)Neg{fe}lSc1QGs_iC)TG5)7`!3w_k(25nq7P}d73f#-0 z#O-VOv$3Quv*XiV!Cgtg8v{Y`ul>F^6W~T5+CNd7JO1pc z9f%*m5CZ=EO`lr7ZX^X?g?hKjNtYF4jcCX-VXzXd-nbf$J|aYG*u3UEmP=`^k=Kq> zn@t$tNk1O8Xm#t-#1_7}OKK=PGtlRUQ0%D$>u?Qu~ocqz;|_HS!nM-p>PTN)H)s zBeb*=#(Dc9gk^IFx+&?B^rFQJt*PzUtbpdj? zVyVE^^B(g%F@!?-~D`gOsAeV74N0Dlo)8b@%kUtw+lvG(GH>xpaw(SDky zynOPILuPdgU$1jL{D|+*yF=O{SxaX}W zSkt;K#&bz}N=i=H-c(2Ub7F!{oi{UuNe-&3VbJJFt}L!)ouIpwTO~cw$UwlI;|BFB z4t~zF+j2r_?VLz=%CaN%9Ep@Kx2#XpJO;(kh?+|Y@?P0u&chG>$@h@Y3&_l)L8ZBy zIYl`{{?p^eq~H=}W5w4AX)rnbnXkE8?4ky95pqs$BgdQcV>PHh@#9@?R4^fUAIk?F z;T;l)@WsQ5XXG^*o2i3p zlX#a{p{(=uf8Y2>PzggMZ3;D(XbEo?uWmot+uS|O{NH#Cp9B8enQ4MAc{-Y03Ge&0 z1fI84mExYx*B6G=7~88bFgInlFzW@58e`6KzWW*#Voog0ZPAQ5ybHcbxVT)T?cAA! zw7w#pyN>p9ON$tN4q>_?H($9H2z&+X=+C+pl!>+9a&^ny(}0CjI!ka ze14kbfXWEL6rIC-GN&w-Bn=7PmEey-%M?pcExyBj>kx`B?GTI|ydaT$OIn54-ycqj zDrPpwjq9~?Tf|v@9qFq0gD30)$BS#P`YjB(K=Q`~l|2Ws0O)Yi|c+_|z63ptJBu8hZ3M^9H6 zsCFW3)lb1<;LW>IOjvfm$=1i8q4QF_J4-_36hr*qq0o#x)wD{0cfuZVQtEW>m>`1Ak-@m6PFmM5cl}iaomIGINP?tqQ`N`vFPwKq7fp*R0sCmRiIRb z+<-{Gf>*{~o~*bvPoH8MiZ`+mj^?2H=`l)M}Fi|W}d=9g< zSow_rk*3D!VcSxuv-Qm>sFcF`-1R713b$j78|2mBuZHKgNn=tUe=dXBS!Y zq#VTC^%vr$;bU_!%XJR*c|j!C_RX2%$eDj%jWv9CG?dOj51jSe2Oeq_b#!Ode1OHXQf^dt}R2cx_o@T*oeQ5uAGIR#IoOf_?b*Ea06mchQ+e z^YOYw!}IFZ)smrP3q3n(nwK1Qi_un=vuX*tSTRwp83ko`B_AGQgv|uPQdt8o<(lsx zV%FvFB<<}Dr5rr_=^p%DA1`?6@$q5_R3)+JAlKF+j|)CH=RSk|Q3Tgw-G3(;o=v#< z48&K&sdK9(o`W1rwYRi|Ez0XflSI+qh`T_vN1oPw1R7zU8p9oO+fxQ?;KY{Axmpx`nWBCwT9V8frS7+$=am&ule=@*jnS zs=NJHu%P_Asbj(!hD+O6s@50861>8REsVIAsufzNl&$Z}%XqgLOIKUVY?Pe=@3k~t z#E-F;*VTS_XUbC9Y|LJ7Va#}brKZN7A0q6o>W5xBWHz0b(byt9b@Q2R6qKu7|LY{e zs{RAQS>ygkG|5%nrb{HlYgOx!Si*g#uYLXDoc!roiAgL|oHW!nb^?CyUM_)N?to*U zluPH-#z2veM6gavFuhmiTe%RF4+$0-epBOa`2nd4;Cz96Z*ZhYk}7yxMYX!a3El%U zNzyf!|2Ws7l04`coMHq_SDV>Y=uy1V2?|3WNZNg#&;`nt z8YLqaaCD*_xR|Kv;he};WmbQ;5`NZbX6H(EI*2a})qeo-W@caTN=h&AI!@PwY2Udr z^N)OLaD!JHWO|IXv|n@YK5XIMdeF`-r_@8hWF9NsHo4Fm>urOsZkO-rW}m^*EJBz1 zjOcx5Q>wbX2~1FNHoPjkHu;#xlBBl>^E#JRf9pDoSP!57F3XrVmg;2}pIcMh?!(pK zJWEmoLLaRg*`fc>$d~n2sVp0@ZfQ>Sh1GeanL_ho3G#(ovV3jUHDupe`nIq?5pe6g zV-Ga~6GBJiBDXA7YGb*@|;2YPYL{F3fs9zB!nS7{`tjQWfUI|5BjK}8XA znl(7N?~cHXqQ-1;m#0G#6|~&NB~&viQ#ZH%H%bK*S({c| z{iR&3mXuHXb8lWLt{0leMZC$4`y~-prBo3RrNVraVi_4M5j=Q8XdruvSiOFof3Fmb zc%PgmW6#jHH~;)UrrtBGiS&KnPcmshLMQ?WEkRVU(5s;(pnxj^YcG^ggrFc%QKFzT zLm;4{#IjV;sHnKMsH`F)4n>L5qOyvJ5EK*@Aqq+-|JmK|=Xd}uVh76aMOhD2H6V32<;t&7ttzzb@VMvQX|zVK_jl)YD@J~4 zS{?FaK^>^r7>Do@tXo1~)o64`Vxlm6SgjFNO+3u$nQ`r~8?SZ`GV1&9AzST(5|K9s z3(tv2uUXN68AfG??@2B`NJaHcn4Hp$r zf{_a;&u4BiD|;*%!oYg)7)a^Y6{AN@{|X=OSPL}AaqiW)Or{uPIFq+Aq5*O)Ys*P- zwK?5FF1iS%c+%1M{z2K+HLS%PBZFOz+-6cs_fA~A6{>Bqbr9aR9_-V!uFRkY)R~w}~JV>J1(`DZsyK2xrh`yjq-Sm1`d3I_(|RfTOPfoXGUwGr$6ra*_|`dpU<%5w&!irQUk_^3V{d(;SRiZudcToD&-n8^ zP?E#rcC<0(F(@tQXBe`qb`hb$Sh|V zVU)c_EO$p%<82?~Y;|#V6H(BTzflz#$>kI8-Y!voIsEICylJJq^`bzBoI{!!9!ps} zJ1!ozgFiy-xPmg2W(Lw2hXXc!0p26p&KwOOR8**IJf0hPJw{M6>EpXl9;!^i2rpr( z(lu)uG*Lw19y&Lz$Q^EM%wR84dd)?)274kO((l93(ox`TmiCHa*{aVv9<@#u6pExj zGDsS%ZT+`X-RpU^`3K-%g;3mvnpu3rD$UZnq3aQ5sYWrg*G$8o z7Wak}7?Ng}2rq5^pvw|8m?f{751pk=uP-R+6 z*r9%3Xo8QZa1Oz57XM_v_|D6?ah3F3`s6gmho%Z#yF>MPi!Xw5(MydN43O>1FVqvl z{+zea;+efkrRfJdm3w3%uvE5W>1ynm{84h%vFS?KqW&kCNAEllOE1G0F>HO(pCUIb zn(Wh}0Ktb!ZNL57?412lWD7;R<%`5e3JyB7f8^UQ*>dYp@3X(s&>sEi9&|<)@?f%2 zPVsa(qEXpS`eP6X1Wl`tGddKwByZv#*AD0){+$D^b1_h}_&u#}t&QS)gY>}$&Yii{ z)t;1<&>iNzWJp+yve?~XG?p%R1J$2OGtfzJb8_t>gg7=kfH1&Ro+2x;UCE;D7@GLyDDFH zN3;VRijTL~??v6d_UJ2!&8|=HQi+NKev$)=B#6kS1fRxO>dB2Dd}l;Wu|qwK(fDM= z8XU^t)Q!Pxhpzg6nRhJ$~gTMnJ*2I9P5t5YtOa+KOQj_J!a6R^jtJ# zf}&(ms6%^kF;as~T99pnt({+R3kNuWz`zNI3X6E+vX^~6mFGwg0Q_BV^Y(KXyAQlr zj&r5-LQ^90v*-PLUu8eN8f|A;G-CWVL(=C5C2t#`CYdYF?XwSe^RCB7`cL>P9O~Up zo~(@!Y9_+$qJ{R=({)Xf&V6UOjfz82Ep>Z|)UEr(YNS6r61?TuzCPc6&PDKzQ`v@Z zQGr*y>y_VjJVq=0l+iXH;sQmYet8V?q!y`beT+PN(u&|3q}m4M0Pc%*;EKccIk=EN zaqq^pH|G;O|BwKS`>a7%HN)^D<3C znxCQjO~{mHe36*P7UhAyvn1_1shklZwDMIUlDbxgjjxAF-os7nc;5+C%nyKIqC522 zTr@>rZiGBYI1L$DXV|`&&U1G9zH!AN3!pMc_P*nHv30zQ7@tZdhFY559n^efg}Jym zbbL1Z#thbG6|SfL2W^+|9|425p?tPjtpp5NZukr~M)er3j%$XM?S*_!)>uArqTkgbS8!1{f zudTtJ7^n3^7a@EfeaA)`KFW4pY%Sb^DKQ{S^m+-1!o=k1@lFxN7oTU0st|I1{Gj;cu*1-&)~Y%y=|&Lj%QogT4dMOw;b(# zXSG0iX{QEJk#$6=jZ$?Kdpg*wU>QB9Wa5~fJ?Q7T0T5dJh2B-D$GsA zYR(-pg~D1YPgs|$oY9a8C)Lasl5A%&_o%>spk2dybXH_CArrf$=R>-Nw{vsmuTlLK zr0y-sFsP_Fd?*W>(q}i~le3AUW|i&^CH4APR=&l*Ie|;DN^H~UK#|&|x{7Prhw*lz zGu0rgUVJBnkqM_}$~AU6rehaP&W^c_TlfA`zw_wuVQ^9pP7^}1Ikvi636~C_oG^6G zuc;!FiNUr>UAO(F50D(DZsIL^Od1k!*?|<L4Ai{I7{CI9o;3SYYA1>%80ij?GDdodL;94(sYx=|_Rak3+q81vA z+BM*BTRFLx9g)AF{OgeM>zh64Jj|`Am6aUo&VK?ly(I02KMmI)$W1k6q$U97qJpQhg-n5keaW1!6ARNEpwo0+J%0?R1D|n zvc2;7Q!@ljpemRn9pF;w5a*8J%?>4 z^LOd6k+sUfjc$ZOW9iWyl7~u>A*WRTqZ;v}KzeG67NNrNR^+2u_$b;B=Z-kDwn~FF zEX#F|c>svSvliU!WIQjRH4Kzyc&{FIL9w^Or`>I{EIWDBoBI661N}d2b$YhL#~^y+%0a*mdZSRBUlJ` zg-+$pNuP@2)a`P(*n;&<>QCn1UA8RqZ12Q~8$~)pQ>(ej(Ij&}&8ljhl(oZv@_D^| zz#*(#luy=B9(2g!Y{q;|&+f|B+T#||#KnI5{#@v{;x<+g<4%%sC;qUw%eSh}4tYf9 zC3z`sJA#U4g4{IJQm1c$qQ<~bapoi#q@2G=dNOBr7KoTjK8@`qc8B0LZyRB<6ScM_ z!(H;`={#)8YQ6IB8s6*aRhgQ5HO$L*HW56xjp+;Qr~|XKP{7!E%{)Y{;XXB&==oFg zb|1cdAJ(P?_jyXy>jdPq*dbaqd(5i4&D;4P&{{Z+nN%C7SlD%Z%rvua<@#W3e1|Dq z;1|8J!3`ekXuoya@tV*6OpDfaqT08=nOCpZG#dfMZyywO$1JI59NYisVKQrx?f@D@*6_^lK-NbQUDjA7&7zMT2%q~ zY6r8fG$>QcGI4#j?(;F|F=KVPG*hcm|1su}kp!I>Kh*0;)IVPh*``g=?&M*Gk?8EF zbbdAEyu5LHo^5UPzhANR|Hj1H0e%I}RKOOzYVLfVYJ7m;asx!Q>1aUp*su@M_{?!S z+vPp$s0(UsY}dvfB_09B_E+zp!FI`_GEZ;U-1H3ZtY6{Qry&D=m{dCaVbG~NA=+z1 z{;_Z)EA{C?VH>aPO0D1%!AKU3woYBlTLc9Ct=^ytLm`U1Ni#w;+*`B%jJI=P2Y290H)!+a1jJC%%Vx%mhe zVh)5)TH`!*wfdOj-)~4jLv!~55FJI!metN%xRk$JzE%0WwS&z>XSm0x$V0EkD4q^X zRMU<1n(36aSq!vOxc||tL&lgRG`1FVxsa817>bgU4;%Wc{F64ue;WqN#zi+C`+l~r zPkX4YU1K0^wOZ1Wp>4{Gn{2{tvvz{hSdzatDo>Wr`o2*}K!V-M$-IiqC{zJXdLrI? zif3lz?>|sY(FZEEMrrIWTColAZ4BGui@4SJwUAI{XnK~BaG$}z`Ntc#EG6#V$`y+? zL^_?WR-b`UXqN2WT{L@Vi0{g0=|b+u zzwY(af&srY0k@GJVz>U>$Bo)&`X^}NlY|hCe8yG~LhEx3+^^0Xc;tX|O)=N&pupHW z+&j9Jc0|o=bxsE-qUtGT9jW;K@95U{`++HOVEu*5y#Hbql>bJw+31MY7?+}fov*xo z=EByklpBBlEttxME(iZ)FLmg{B?n34NZo_fZHbnh7IGUs#lV8HEMn(POjWbQs4@uO zt|W#p8mGDc){Og72EBF64IQ!AFBC3i%$t`5e7EdX0w!l#b@B%x6 zV({VlhfNSVFQ8l;3&wIEt>%FT&?`*-04uG!Hv@QDxn{>8E zp_(g4Ny|sY^8@~Y+2eMxiwHtaEvULEl1lIkNW{1S=`2X>=S8>n2P3~i<+*5lk?KZC z0CGfw>*_N#Dnf^YVZ%P?tP(Oh0((#;=>MN$#*s&w39z1~ZSo)vWkS1~!HzQW=BJo5 zRg*Lq@o}u~UL6napCI<#HJWF}hUqtJWXcd!&@r&kZ{xoKG2-(70*>$h!E<5W`676s zMc3n&62>U(cAn#_s2T7PP~+T>a>67k^b=V`Dah3WIG`GAC%O&H zx%L4$b~0?eVaL;GHmo6Z@Q;753BE9m<)RuU2Kt$$OVr3e7w%`Bw}C zbIhF600)EjRw}xu!1^?yjYg65Rp`2mjqG!iFSF|o-Nr0#lL zSD6h$WjrSh*J53_sUh|iSu8GTzF%doV!lw(O|h;jVwGwr#5-iGrIxdBT$R*voaZ(Z z57`VvLpE;HZ8-xf`?|Qzbh@-Oc$vs7-)fd?wH?`u`I(VF0#8pEb)F-p%8+w}Jqz0p zp}V)>BOuPEcRz9P6!t-r(&Q~DnqsMIFK5DWdeCAl3MXyjre2)RH0Pq^H=Ti9=E{S* zmQl9i#nNCi!IM4<0V972lT`T$)7jXXlh0$7GIFeihP2zSH2>7>ei#jDi98mg?Zi6^ ztj{_+*!y}cQd_((o6b&I&vClQgztn)cRv7eQ1-e&jGYCZG0Sj&`P4fne)PYHi}b&= z_t?L;sH!ZChwS^5zVLi|a&j_p{lIFggS-z?f^gI6nb`nk|Jp%h)dk7V)tq=ZAF)60 z8p&BH;T-+*kz#Qn_YT_0z=mF6>~r!cq$Z``!kJ7;gXOExb%=5k0Pf!P|I z1T^s_AZeyJ+kxXLmmW#94TLmIDAj5-(|%*Trt_Z^wu@H9WjuNyb(JD2qZ!SwYKiVn z$(9ZY`oe8m<`(b>s9LG{IY&7n7E`3H0kTp@Kj~3DfWP9!Jtl~(gu7O4Ww07uMd_r^ zXEN#xQx0{zDVIwmzr5ysYJCTl>a7%6tdryH4f}gz}L|0{^2|toh{ypiE#S@m@ zlNQXjN=x=tiL++ub~NM8ke1x6b+#TtF0XO0M}E1=?EQiZC$&Bo_{I&;8FXdoy0SBF zv5xrLpG}KTAfNHCLe#V`D994Wb&5yY5f!s4!L<5F)_0$1Lv6keKUog)LyTVKt)9~l zM!TmCo7J!3S^1i~U;REsvlM_j^7Z~iSKj`a?_;!%aH)p3B9?5ueOAD&-{c?Th2O7hn_KvLE?#>mg*>RfP5tfLgoX`ohhS)}- z2^){A)IOf`SW!gROl-C4`&hlZ~Uk1L}#TLO9DKi4s*X5b{sEOOE1Wz z3>~zb|D%~u4&$CkU(K_O#TOUkp}eC(a?13Qa(&G)9*8qk z=rMDKIVMllejz@%ubBI&pGWJivsOC{9TkgqxP1EXfq3==p=vp*WHMhS3YyAmFM_hn z%ImS{vh57S-)K4xyIvP1pCwJ2v@h+&Os>)snmTx9$d)&-42r#^o-F96={-` zGCD+4`fn3d1NHO@Q;n3tB?A(mAeRm-0*T4Q>?}0q17Tf8VY5&{y-CGa{QgY4Ktef| z#y+QUyq#mLu79=Bf%DN%`kB};MY|8;%ZyH~Eh=P{o>B*H=3PDrPgW27$a%+2;bR*5(PwEgdq~v#%*eh_96{ZguX`D%ULw;l&<w9R{P zovGiye~6bS1XJXzY>4u#SgDvLa6iou!WlA_s@+Q2sn?-rgMNrzhhs7yWEBy1M{f)b zJKg(Gq7!zMD)^koFk;q^E?o?b6$*fYEw?b>x9AL86rF5m788pPr!-P_>Q=rRWePVb znc_!}xCKPqaM<`r3AX*s#E+jO^c(WWLZVn*z7xC4L-v#ORR~Q}zwjZp*FRF)81X)6 ztQ11ozNyf$KEfW~*%&(TomoDDty2~mNQ*&baH9`VzIDGEEgqa-iF5n*n*~@(aoreF zJBjZ)DN1i^Oi=1RBmOy8>8_@JNkkn61%B{*T!q^wTE$Du7b(QvBHct4Fbyslwky=6 zgh5f>5@KmSF=*Qhq~y`MixZ4%6%CBF(BfAKwQUVLCG zy;~!D0a>^x+e$}%jV3p%MlAP;R$W8^Rt0}1VbA0ecGVGW}h%{qf@X$b$|tz{8H^ zA=PIp-e`tSv-X?Hg5An?Yd<4OmQl3z?Tv0P(=qgy1iJ#2CpCt0rn67!N?X2fh&T|% zCkzqZr;qELIm-dakrys78ZMUo-$REW*~oz2wSTvU=vg$Tql4Q)@!GVeUMeXh-+Q~7 zUTIe*Z$A~Ksp^}ntrRD0jQQ-dpM*ulrM4Qd>4qlqj;$GSE;TrlAJVNs$~Y~4gMqUM zA%DxnBw<@t3k0_vkY8A+K#4(Lu#AtJ22xiPWS9aAL11hb6tXHBZ#OkTs&Y7{;cAK7 zW{NFHm?7+8(~<4V=GFzmoo{F;w?WO4{VX+%TJ6~pC`K~Q zw;MCep1^wQQrdN5h+;GAX3p3d8Ri?wZW9XRvv8WHcxM)rOHoUm%w^s*{yfu^XZhBk zksYA_Vrx?K;lm=w?CIrS<~<}`x;$cc)@j^C?)2YNyU0yNIH0zmhAV!5B73q}Ul^xx z`!!@xX@pPDBiSQrtjAH-EK@nC!C%I7y{aPJE-~$@t$3b~Y0V*vJeX2{m$?F7Qx;u! zCSFiBn>~Dwm}-g`qp6v@XPv;h4ex53v5(CxJsmh>u)Xitr|IlHzn=@|OGrQ`Wf4y%i@MS1D~i!wX(ezP5R89mj{&T(W7c zS7~&-sYI(T^{KoFY)d+nJ4JQT?+eDI`&kJDEA|KwbJl>KX=(qS`i^? z*&8rLbK5So*C>4ss*#dW5Sol6Wwg5z zm|L3hiOxqb$?2a65sS!YdNF$yLMZhxbj&4=aAvZBSe=TmxG6RhrfOO?2k{DF*FQyZ z1RlB>a2_~i6Ru38*}do&;gAQLi7|!~TAoKKA8%|xjy?{l0i%_l;y~c6^%L?AnK~Zb z(|*Er|At@NjQ2XIIY(Qntr6(MA6aT8&}Wyg!F@@G>hvotOuF_(K@Hd?U7Q4BMVq+v z4?_A^PoU!G6w`YP>36hv0N*{$P&-MN+r<9DRbK$C$7tS`*flxrk zvJbl9U4{I)l9tS0?h3>9p4G5PIO)HU@Q;%c6zc6v&DOyY5a?q>g&PC zS@C-gd%)LO5JEWhvIggI%&iBEDgXOLv{E>sXZ|r{Yb@RQ#EJhMT+08-?%V$NoMCJ( zPHKc5&Pu%h`TlOoCZwgI2O8S|y*}c^GLFqvuDP(0&N;fxke`jMo}G$kmhJh$5UL+< z7}#}5t!UL4m?H(%tVRHi)8aIpm-qxY%WqtylYH%Uaan_SS` z@_XGPmBK>2e$8&NtkPFp-`MJ;!n)nh7&~b1n;*lySxq#r*X%N+6dbVtOu!uiI0<%r zHtQE$hnqm<1}bZI#dqSiI=Jx#Y-Y~2@FrSVV0q&*6oncOyPg-to#0GGa8ffN_72%9 zM0(7ae-~(15t1Ncl;Q_NVWXPF;RHT4Mss3yOs`!g&P;2heu`24@G@5p8d}NfvjX)g zN)IpI(X`NNM~CPI;2w#NbrKZU*a1%#ZKBtjd4*cx=R~l)O%|8`xvbeAGOj^yEe5%Y zK%i)ZA-pnaW_2$uP zi_rJ52M(%M{q|b*@p)=L8^DeRTwds}>OTGtNHiU%ssuO5sA6h#SdtcMm61Qum2tgHTvP0#PwA z9l`_jtH-dFr!-Q^tOw3e6j|xlmPm*mgAG^J3V%)hrWf(b<>^Z5E478&8MUbO7{|5T zF(cWJ3uN}b(hFn7^{1{S%x_jEylmau>|4`6^#%v1}K zluy);(0C!&Oy9CB|K|qf3#VZ7Gu$FS`Xey=!B;C255S1z6uUkH`$9-C^Po_@iA4Vn zIlFGLR3S=H@=U5MsHy$~iP*&^`T~%)xRA6NM>;V>dRVA)J4mzh1ZfM-#fZ-;cStvL z-!4$Sa1xKCcH38Dk{XEMuXIkpySfKN)tW1GWX%HEo$H9hGjjNEk8|wx?|;DGGI(_a zQUw0iTg+Lh&5$}-=rDcR6%<7^c2g($7W37!>>*PW=J}urI~Z$C-i4mQ4(b&*oRZiS)$0zG!_`*D|XIU zsLtqgtacMHfi9ETyg3%R6xkX5*chL(JJ=CBVO%D*HHM>tCjk1Hv(O#;5O}OR7Vt1$ z5*QHBL+BRYG-0;=A9?WqheJR?@{kx46RdrB<_p?s&BWT-;NNvnw~dO18spGOM07kM zl_d!{%ZQp!PidG_M%u?PtaQR9@v4%|_Q8xJ#8NKoN(h{xp#H2Dc7{9ET5|z1RM$|Q|?ftAk zcVXSEI{V(&TLI__X0?y%qjew~w-A4yFy|C1ylf0WOM{`t`1{QET!3=c%^!(RbQpLJk~6sYdh{XxYl&1;iCEj1_ne$`22BP!y>QJC}yWa-IB-}$JpV{ z#?biqCY>{(PXzs);Y7)UsO!t*OQ-^dq2Tl1k9yExp^kcH62N97q$_yM(DM%YtL=j=qu zP3OLAdnbIci}fM%lTkw9wc1t$^VJfNLIO@5m8$xQ&laxy;aF+B!ioP(!*TGD>Qt|Rz!1{!kdl^SUkT%&P1?H* z^&65{ZuR*Fa2faBWhc&uLfuV3$3tadEM`xf)N3&@upr|Qb|2QL^0}IM++1O4h?Y+4 zO*o}t>vrxCZ$KDFQ_)k~P4LDbanl=cV2L(=Y>xG{)m*1w<%Od#5%q@7t(uk`A-6r8 zX+@sM$u;*r8VC{$g&1sc&2uX*a*n#^Jvy?UHSre)kme9kkP{F_X+J)N8RXXxtL$i% zuSFWgH@UM93N#i09$*vXux*n0+&$A}fHP%%aCVwnt&o^?a$wiB^jSyQY(Szj$>n_y z*6q4z$yz@)_A6D;5NVop$lxyGfVF+hrgY(x9&9rREB-uUBtAVuVwfjvb13U~bxaI< zr4?q_P^bF37>%qEB~#of4l6*F!KR|^#T&&a%?>*#m;gNz9Im}d6ZH-p+D_SZ`@M30 zm~{SXR_d(i%r!!l#!Sy^P)Th7VYh3d{IzhLBge^DYAHSrkkM{ICANf+KE04{ih8l; zIq=t>E$U^KE!P_Ahm5a0g3#l;_A{+(B|I3pz{KQQ0#MQQ%}X^GxreN&t$BE`MFn&u zOwd5~ADZn&fLRQsAqWvn(-JAOB%5rk*uhD#+k>V`nftr)%I5QWdO7`Zv6sB}mZ8F- zRpDYL($XfSzL!2&TL>MEQ5<9_96jQc*8mR>rw(_yf35-Nx%RDYOZcAS(RSR*}D`3O{VJX^?LJI;%-(cJ*M2zQ%2(Cfq5 z{rCKR^l{ki#^RebjvH}rSRNhl${Pn~u;Dcm%*yyo82*E?>n54sLmJRF2+clfG9V0B zF8H|^Ilur@VI%#F=^w_z&lm8r`X}UKjf}|>-MiN`UrnJ+XLDn6szaT}5mmno^9_?I6n68%poh4LQ1LAjTn{dW@4um@68#Z4&ctt!41dN-Hs zNpxKvl4tQj6-Ct0h$1Q|Wd2$P_)($eKh#w@&f_(a(L8kLYiwtF3lvJJ1_AdMG*d!$ zQXsMP_Rqf0+lf&;(U$i^;V1}g*^ae@mL~&2XIljn_wBsD67<7-zHU%zc#aJ_&BF{+ zt|XqWv%lz+hpia>;v*QD@Ih&Ik9_E?%Td^Ztypx7a3gPa=97mA#r9lT8&{~|*U~Pc zyha;qis$R2F%!V;bH*vcg{p`>h69H-s~N~0!=NB!egdNXgr=0+sjBS+jrhHj`oLQ1 zz?0p4eS@xYz(xM%%|?b~tPNt@K7yO%*PsiH#YVQs%n$7W5J=JZN5v|^vs z-OM`JuPGv{h-u&^<;MdH${6#a^k0kJUgL^*T>B>Mo@ECy1r~=iK$%k|{WqsULThGNwfb1CvGDZG z3Nj5Sx1b#c0#9=iV=~`rB*fOoInMfd7^_Cr%=ZUn`z2lAz^*^liZevZ*w-4K52gc} zC+#_ZXIQPDt*ygGIa$|2KeYHOivBpvsz26r6XoKWyx=;miiCTgV#0~UFUw$Ud#G8) z$=`^F*Nfl+l`VR?WcHD})haKu9F9LNIh4%05tS*VUn2%W+Ae8YXawM?7eOe*IlZWn z9x*he_;b1cZ(4wIo6+&pDU?!wxl!wdHt6rw{T__Z-q6pBNZW5V1QY z76nwUg*;Qo(2_*snKP7Mw{D@CW2TFe`qCF+uvU98S$D=^li8op*U|7To9T0sk{CB| zAx0h#4|;*9`P}qYZ`=28CcX;=nd)IscA2|H!O$7ojoyCpi8DYe5p96V)4XLaDO_S* z19#O<`V)bEm{VD;_U2BKCTNJ3&7D7Big!lAN73qd#VCl)`^x~ZU3qx#+9-uYm*>8# zpHQFmAQ=VKEz()3^?MR-lc>5+^Zc>nSpRx(Z}PO7R`R(%pDRg+2Wst+>BF8=wa`4x z=#0Tx>S^Mw)r6t>xYjt+gX36tON}>$+Fx>HSg$7H;8yrWmruD5LxR&yDbO?ujW|Tw zrPk)JnT%IbN2N6u%@>vPv()EqKyiZc*?D{cCmr+72N!YgG3FPWFaBt&8t(~n0(TRQ zD$;zqfr1scWx2<0{Z~*Z`)}1>{O_t?G#Bp-Qzxu;p;x59chyfr6Svi=^eWwODR*23 z`W7kJ>B~N7y?i6pJ*YUbK$Y;jTKB?R>0T=TlySuhy7S2&1J75gmiV$%I1m4_2YGq;QP&CCZn)pDSeUCJ4WpC`}AYxk2GsOd~g#KY4M8;gegomDrqqK!F1HZb-u*B zd5!TtZFIZ&@F9(=F7oPXQHflN-AVMXbRT$?lH&v4yCVXJtg&L);KhJL;1E-F#!%+~ z!(D5>hUb-_;l35uxIk6Zq?xL``|IQ+B^xSm*?}4QylH5lLDu>BkEqMn&FZ(t=!?fR zcTvBdW_48B~JtJ`r-5Z>Gs#5k_ z5mmDWr_4-bMU=JKkjXa|uBPCFPs#;6P$+i(qONxl{Yrr1bdcHj%#S2~%{VPdZkbIg zv#f`1cj>m@LP5D&&iT>8?-QhYtn$+SC?)uLqc7sIfs^Ko)}TW`=f)7tWPnD#6RIj|4*}C{of;1`oBjC4_Vp2BU8cUJCA&Nd6|-q92rH!AN2^< zlW-(E`y@8yCSjn4*e6Eo%!Yj#f1!W!7?At*rP^<^ixS@CFF$_fAFIR5GpPKCq&$c> zQby<(W}#CgI0rC!UPdIA>(BLwA=Xos#2v8@Vbp8yTKAr^yI?quH>no&4&NN6s3DU! zH7H_Rns#%PVK0^Vq$T1K^2Vl3*h_;#;x=Texho&E{Xw@i1$%vql=?cacCGn;2<@RW1AsVVw$ zK>Mi@5OvG?gIO+*;FYg`VFF6G!%bk=G}O!g^}$N?rsXRIzIW59EOKc}=*|&mzuJoz zD7r==_VjSiHtE<9;HM{8@lMYwUhIKvvMTgK5q3FL_QPifCw7UAy1OZD=kB%WAI{F> zH}$iUUV*AtPV>;;bmmaH8~OHq+58Rm4h@Nb;ai9O^Fv{^{a-ojoy&E#+2A?qKdcs2 z!xC3l<-56xT4AVY)=Kb3M}EMtSP!Mh$81w)j42VrdE92eMC+R~t16HpIYzXsIEnS3 zYF#7TD1>3`?Ys=#&fnq6tRifmxsJ){NV>G-0Ym4`R%In-A7Gp-tC_GT_{3J+7x0A;!i2}usMUrr3%ZRd-Ioi5AbpH%(sooat4s0*x(mF-L z#va&dhjOL8+KJ;@ius$fp_#jXMJQMs7e8w`m)wl|_6S>gdk@on>baKZv$x~Z`%aP5 zv^+P_Qm|J41IJZZ*t30>7Q3TmY7}t1iY#wa^l?zhYCJZeH&zJ5LBdVH|c zKMf&t8zKt17Y*$7=Zy(jc9Bt;HyTN1_nuKUYXLiyEaQ!+?ylgfE3h6^JkEN=*jQ`% ze#4EfD9pP!+l343Fq<=e4x@$CIkIz_n^!k9wBncg8@XrVzd#r(JxP8Tmu;$|z7C|u zs#dHDyuMWRc{!qe%u6uhHT?a9;ARiO^-Cty_B8GFxvjwF%UB>sx>n5Ij*fW-q_F#RdY=$qD;Gl zv!taj4AGUba~iQzjdjxZTEcp-cDNop&t^HqUZXzO=mA%N8H3nw>o6|GMGT9hI~5-V zp)qFdt1vbffSx?;U1B@I_gfB>S?j@-2FJuMYaZnGN#d5!EfOUU?aw0oj#(>N7nsS& zRe0iP9O6Kb0xX-E%ei$H5jw8c!6aXb-22|4zH0kTIt729jxXYvG5p12XcCIsO?>Q8 zuEsisziz?Mp6pl;8!<1a4{(gu1K1PT81f642Ks#Gg z&$6_@bkWW~5xgH=Cw`sm4Q=^@bx*`zFMa#gq7ilBOqCwe*j1-Lz1GTKzIt(CB>Lf= zOA9PS-lC>+6Y!%{Y!Mit|E)|4B28~IFPx_@gRR0W(gqd?+QdF82wLeA;WTPEWq-=5 z!%?_#u|whKKu7CmTJ~hkTc{w&5jXbG-cf+wV#q)4IP$Ola2oe$a%%rbcWh3$7hi7U z94DMReyn!*eS%nf-i1qxbI-@RLw9&AGEG$`aAFi3edT2tggHU%-HCN!wm;|L zQVr1wp`$d|h+mA&WLQ{ba6Qoo1ViS$|>%Dp=yZM{Fqwfa( zOgsqnRG@nh6oPtN_cW}_*8f3!vDEi2+)mC~Xe238(aWJkD zJ4nV@3F+>zc^_^ltv6QOY&iq8bz$=Y#v3u(V?LaE&dOU2@MYKwXa03c-+hh7x62OD z2BQq^p^VMiv`AtO3E={N0DEF1uw&ryYTT1g%apYS?~zTbH}YUM2rgb^{jBl-Zo??< z!@d*CSjGSE3vCfT6At(>%h{&$73-lX-6RRfJL51-Y{fuBw|RsewgfZ3#Vom2&1s$c z->E;ElLa4$?a^?>W*)ULQgLM9J(T9v0GD({nS+=x!!iT2Rp3r{`sGWGVJ?mtC8z`H zYMtLYQSabiml5yAc%pp8Mzk1F(gvzAdza7;I>~m*oMf`yj zJkL-1z*|JNH*G!pNTci2tXcXBi}IMC9~$k5Xmg=GP~_rYJ5~by(y`}mxx&%BZDsQ6 za2!50TG|pL1E*L{_G*NhLM=OajdRq!R70O0%k*BRk(Z4w%EIg-Vnba+;|jx=jnV~; zG|#=iJnDxdk^ZfSwt>Fj$svQvyexunjTfJW7Z%Y4?WPrAKS{;!8%BthDvT|04PYTI zHU-3t7FWvlp75AJOlykg@{(@~;?TJX;-HQ<7*O>U@Y+=aKSasFz%CF zYTj^CQ!!&qDDKd#Z^7+ab~x){PCNWcnZ1|DGo#5@vpOFfo7s%DOmWYB(nJTDa3{!=Y76KQD#jIR#xCo|hMbU(z$3r>BEx5u|a z)g;?mwwC8MqjpdSBX*lNgci0uQ4C1hZjPC$)JzY#h<=%w72QLE@$y}=zZA7Vp^xs; z0vIJu;vBiu{Ii_hL)iG=!P^unV-UK0+v4&O5yDs-&a?V|M(O{Pp#S4Qr@~wV+#=-R zoXd*f{9S|_4mg+S$eR6)2r=<-M#wIlIaiDQCNNM!yK;_{kN^*hc#zF2$W;eEdirK0 z2+eGp`b0Z?Hu-WH3VD@=8tX`BSay2)zvn&&iLLEj2PPT9u0;ddlAFjw7H4`yt6q(Q zjp&@zJ+j-_cprDv{juQTLG{VrC+`X<;?7-^pu{lBUr5PoY9{*UFyhS{$5uZyZI{n# zcF$X?p+zagErSxRbGz7`NA)sJNJd*sv+h&C;nAvyPDKzB@oc z{H@&rz+?SsO0%Ms45XA#`N+_MAm_l$1kE~u91kX$YF!GeC9T?( zAyZ7pBiOf|trX91sGj-|*IfAZfwk(?y;LM6om6>$+SoqA2UGviiO(e4^Ec9ePyHKW zgJIINHPD@T(jx%3^d!16UBgr+F&g1?e^X_sT!u3t2gx?4`ZXEq;Z>@Vua=40E4@*oZpZwg%J;EPY$M zuW~6}xbJ>w{%gcPy!Kl}hd7+4MXVq#Gpy_j_*74-Jllf_saw7L?R4-8NN)M=i?(Bc zVP)dr$h{s4$hC5SU2~m$i`PppF@h{*&zs5BZ9u#6R?<-N($sznpj;Fcb*Uc1UccT< z=)2BJwSN3{GRg%@A3u$~JNjj@48TRi{bIUywvj(4aZS>5Lv1&k7^nR14ipS?fG{vI zHe=`+rf6Ns)&^D1gqNSKeMH2H-=z45L{-gkA0$}5rs54()fYLTrPN-j(|#c-*SPlyWm#U~xuU*>pS)O0vyPp|c8XexNAKp#xKo1^OKp zm~i&Eeqmb#Cf@ue5b~>vG$;wf?x=XA(U6Qb(S_JIgfH8n8$dq^Z2j#3zSTct2tPs7 z+Dxa+Bgq*^=kIRX9EACZOe516D>fz^QU4HL)C>3%$q8$Z=JTSti!4 z+KCTezH+i6s4mmX-+~VR*5NjZl+O* zb&7H_o!8OHildNtvQEg^Dn}tFQxXwFg`Dj3JdWP4?+@Sqz-2vpJ|2(z<954VCF+;7 z$fvzjXATg(>upWjhhl|t)~c)lx-Fx7hSaqJd+0Dc<>&c6aQ01Z$(6> z``|jbxjzvmYBeW2k?pt!#6MZpn{fkcgQHB@9^VYbzyZ~EG&HHV$U#K=gidTpMXSz@ zPkA^VfR7vua9)xnF46%^+Tv>%r544hv}fq(H9(HxYUPqZctg#yPB+gh&ws^0|2n#5 zYX23_RS-ot@*O#6EZ5{XU>{0ixtG?@bhOuAdYxZ#N>6)m(-OoRJePtzZ+dIpd_X8d zhfR}q%mDj@XgycaQ%zg=vwQu3?aa*UHif+L6VhcxW^Hej(VWHy;`E0ufY>Ypf!MQn+V&?4MJJ3f2NI!=Q)%_W1>s$r5o=ud=Xe+13EN$;3T5_v&z%%&>k zCpfy<`|458H}`kiC_QA`RuSSdqtH~}Ick?}M*ML!9z`PQ0eAQ+8~H#U~C-k;o&#*l@=tO`v$1wS2l!W>)A`5I?sQVepwdA!c zo!H=w$LfV!tXlj`P@&TimZ?Ta7}6;C1W;HWNo|ct0az)=b*0@tve8Va6c52HJ3ig;L0c=frcG=)_g$cmsP-xiM(c z>WFfns`S&pKgAoMvOvAPn1%X=L(kybobX8khJn}38;lh?1!s6E(iPz(E}iP%hkpcXV`8RY(?@%v1f|3jg>nzE0JX z$Mm{G$m@yVHNh>G zn1a=PyO68-ta6vo;*Vzy(k(I1<#{tEUb^hWPs;4w=-nSv{}(kiP~N7`H5=k+r89J9hx@KS3d>{g^HZED>Ec&H^HH< zcKKDbb=xeVk~&}w+|g4W4&eIX$1Hgba~Z2F+ciBUi4ZoF7QIqh)W3o4u?b(*uV&3l*w!3=^M_l-tO6s9W~^X(gIv{VDrl9?%g zNM~bQ3`HxGLl~uhwg-_n^9~gA_8-KRM-uJEYw?>&i1LA7q~Y|Q=lYXs7%Ix{bYcDC zC>6}-4foZGlwC!r;2#YW2k=_DU&8*6V8;0IJ0EcS{|-(ROaXjaKFeg9#T|@@CRlqN zRv=Z^*kEF;fCq3cE=IVQ<;dmsK%irc3igru5S0zs4W98l4P|<`GARnfn@D>^!YB^Y@Zh2Y#6WS(AGez23#9^UM-E%9#6M#isRvTmC<%D)XShXe@R z*oJLVxM7(}RlAtVdGc!(!9X%f5#72{z>QC>R1rzRoFjhCVsxGnYa6uP7s*laiGm=) z9>=sOe~{P)(2#Stwl^*@N)XRY_sd!NIhr~fvnHu28_Z~sq*ne^=oG9fy)pZ+0 zHRbtsJgMcy7>~c2d|W|p$k5OjVL7#1b_=ihi`7)`0Ch^EnOq&@d3xW~41FQ$6Mt## zPoQ~DCB*v$rdvx5iLf0}x;d2&S9(i3bYjMoimXIM3#3t)h9EyHu-Ej2wo$SsT%__R z2;aYKtHJ;t4d;#-BP9d}0#QDyV=tJ69r4LJUCQV^zeu?XUqBmT!~s*;bGTQERh8We z1$6b=E~y-F((2EC0=Hzi$a@U^Wp`)lc}IIXFV@<*94W(6|Jz5?et+~H{r>3LW0&&w zDr!vb{&1*1lFKwKpP8OH>3~oILE)jF!oR+MgAi0 zI8>9VDK^{_!_85CdZ1rP^5BKHKyzjWe93)$k#FzD*Im{AOd0piw+uf&i5Ln_v5{@J z{2l&bUjeSnE1yRx&qza;+bJhVW;_0}M)Ckww%BAcUA~`YgQz83T{+X~Or^5T$_<_l zvd*ahnMR%H2_qFXKS6E3H4V6LBSY_$XGlFG%}ViR{EO@?p+-v3m28c7sD+m-r7nfB zQq_B)!{48G!}p)ir**=`pBrRf;u_?ihY>u^b;yu)!JK9Vi?nHtR$vJ&JZ>gYbRSMFSg0wX`Lt3;@ zu4=1CO$|C{*#fR$aX2B-G`LppALOl3HkiEk(Mrj|7p))#4$jtznLX&oZG1fn`0IW` zkla1!+~Wvu@%xab;G}~GtqNx!)WJ28i}4=y^TPc{>a&yvpV>&)cd?#|7l1r(!xPbw z+~!PfTkWm|iS9?Sw=;BSHEF-{#CaoDz9LgiC8k)7NHgG$5U6}`)Xb~D10Dk2JV5VU zGDBUwK~$!4MuF&w3l2FS`m|C~+h|>4V1Y*#v$u=mtNZ|+SY8CxS)&d{<~``!uTvzchV(74F)ZDaSN;pj)ujKF}Qf@QCRqX%uaULvy1Fw2M z%_3Jr^RMI!-;T(@dT1}+u&iS-(sEnpEPk!pnW9$l&%6hasXAdTb^=}RDjoRC@uo6i zFOC1=ykg!bwg7+X)frZX_V_02kVtWblK}dt@4m8)$;VH@lF6N zY1jv9nl^`VI6uhzi-SAyCM&}PCO-Z)j(BYwi){ym%z#zUqVkk1T-R6wT%ClaFC z4~-bhWBR7x?cGki*&U2RRW}B;Hl@AKyp__<9Tl9q%}36&-X1ad5h^>~ z@IV?FLL9ieM;CmCV!1jf<3svzpK>Ct%|75|pNFP6;^i|`yw#P055(bfj9td_jPgKc z;|YcjnSVheZNmU&k~wt~Ws^Ctu>SsLoiLHzWs~;l-L}BIzK##~L6=tdFz#R&CP`$R zbcylCX##gn{GF7vw98*nd)7%b2iIfwn{%KGK*G84UWF`JLk@z#)l!wW_+cRzGwdR_ zvpHlFC%bmm58N6GA(ZWh`MknvQm>JYdz$kKS+MphC=G4rgy|$*#&<2pTx^)Zbcq&p zQb29sa;^lG|2M{ISdV?B-i;Ogu(R$=t?s^0Gksklc*}#6uiqT`ug8}ufRVC9q}|Z( z4Dna>>8wX!Bj5;3AQf=|i2;TRaIv?z{#;C=DZ_US1L=!iZ!fM9o=#+!g6&F}m2DN= zSsLfG_r@PwpXAQFAq}X`NmN}sCQaj(@hei>FlOZD95ysDG4;LGoxY!hTP5H1%CkmB zU*>>s7Nvl&WxWu(t|iv2Yf{^G_<0lD(C~si@-a|w^kuxwGi)B+?9~a|In-!iGO=pD z;2Vj~um3BToY-FI{9GMdP%-oC8(})!JHSh$3q6Bu)R=j2-@ZDlVgNZdsRrZaX-lNB z()d9)vvByDU%fWM>W=S3g&aO#to_W$+yqno{*wW_0@}W9XtCfHJ(qU1V#4-&bd1er z?^|@NE}f1g&qd|!*!^6+?_Ps&`@5IYcTa@8OGM7CCG53YF&Df;vWkt3n~K6_d3!;G zQUqjo@kv9t#8nKvx_o2H0Z4R&#yFyphfLFgf;xCf*XJVCPqTK#m_G<}oSC6`9Zz2@ zA(eGNYM1`rOUdIE{w;~|F(aVIRFma$JxO6SwRY+p_rfXOC@Ks$ww4t>4aDNS)NELh z+(Q8{6Q6&Ng#cJ6cSZC1!bn)j?e7!H47;O^!R;~)$>7AbJ%)?xdg*2DIELt=o61d6@be{5WtWfSX>nc~-_bmu&DiK}GC10ot@~;8vE~ITH%2Bl?SchRkf7Z(NIZFbyCtDTZnKefktf;guU8O4A zoDTcoFfys3zyCOsCXSXkiqWK2*i9k}R}B&C}gC%f+9o3UcFUd6=y(AuXz2<2C= z88}KVU$%Iq{xMqB{!8wTKY>kqxF;gpAOmF`>0KM58|bjYD|*;g9Y?mi1$Z&638u z5HhbII_0Ah=B!8JR07Nm5+NnWEVyN+74-qD_CS5nVIdN(+^wCkeFlOCn?D<^ZGQm< z4IA7tsmpAeLFFsk4|^m8BT4XDl&$i+6_{4n2We{ND1k<~d2N$C=QO2C->QCHQSBz* zg0R}658!*m>xXzGS58qVMnkBNTf~8)5?r{~EC!Bp(*$CV8OGr8kI;oYjR(tdkK(_2 zZ2F?-+L+c>fjblhF&c0CY2hes%Q)mmAxEFf87Y>oAujQ z8d=4dt~ytk&s1_O{fXin=oo{9LR12m?4PHG30%Y(|36x;tXqtbpM%(7LXLFwr0>PBG;#f!pzmMeVCTJ zVn5*j>0-@*tK^5veex^YE^_43W8_ry*t+T2FFKMN*1eR?yq^z@52*_+9q=a*)kR>6 z0$sI!-oqq?qBgzCf*qmu<}2`+uRs_H7O#1B6Y!NDn4(Tcsv|3|3c5FodbjpgzX&)p z0vn;g8Xx~qi2l7fs8v*A(IShhZ$_H%E%F~OgVl@bo4ZB3LLi2DHMdVOKJS8uBJ2_J z-wMIITQ1}+_dehXlzAh=(>VRRxw+aAnM#Qf?I|*}WGm|iv1|@+SBiB~(=Kx=#8oBX z9`4jFw-{Df z13P0u>z<>4Ij%4j=RB%oXZ~}F6nXr0aj(?Halz}t&iP~UnfTqjgcGbn`Q4q9TOK@trp-mOO#htr+J!3=0HsxU<{}^mw&_2=# z4Yn!ue>a!9t4o_y&3d^C?ndr1Kc&G$Nv zPnNpWTGmIbA3y52G`;rO`=qiq!~gC`AAjGG>VDsm+_BZk$tC5leKx1}S;`$dr>O3{ zXr}Cp^mO#Uf9LTau?sU*@k_NjO#e={a%uZ4wqRpDE)?P>ske{k+1eDBR4pwidFYxQ zHu~LGP}u?s8peuf)2QejElUoivl4YN(XQ>hm;6xol)OF%wv*1pwbb`KlgU>HFktvc zSK$?Y2Y1$pyPUZnaClc-Ih_~w;>}rb^rtgu++zy*ho)lVitzV}6|-mi{`ue!dg>Q| zSus-v5InLO-E*?<_D$@F7&WD0R2=t1r?Z25YO^9EYZqUqi=me!Y91DSj=2CI)e3yqQbsRBk9vbOJsy!XVKk5=Vw5T)fH*xiJ|i~+ zaGYp)CRcTQBA@$aE%@MHO`G19NpsXwS!HuBDUMan8P^4@Yt#V~_6vgD_RA$pBr?|C z7vdjsI(~!uTG_xswR%BvzzvYIgdDR)sf!$iGGG!f-a^?|1}o@uxl!AJ<&fqb`p;tY zI~Klh4x7K5TU3?ab~B3Gx{lE#7$JnAlI$5v#4UuYP9&A!K|dv6j}P|pB@I_i-0pGU z8|FZ*fpu9vE+EgAc|(O!dRVsptDkV!23fY@p#6T?iZ}(s=ZB|@pJ-RmHn{9_*wSY4 z!nBv%PiOk8hxgTBEqwb1NG)$CS=N$fDaG_6H~pam8i0_cr;gE<>}y~=$C!{+(;!!CjYf432$j3@L|fbcfUG453lkAj zZFc=HLObZiz_&9Nnj}Ed4Q2VLN*K#z;rZlaP!{3Ew3VLTDK&G5snCjrlsNlb6I5Me z&S@q46V`m#DXRDr?%?JwiUq&jT>&N;x-yKO6ez~B0eZ*33>gkGN> znsg9k?zhgyp$Ub^wPVQS=-TJFQ@$n!l63`r4K`RMNlitbwKb;%d2jTh%PG z+Ib87zbBcE$Ka!ZGBfuWe4lkf6lkx9+=7QQ=X^$pVcZt-Tr}6}W!fQo_1Bn=r|6T+}(kVkq$}xrJ>w_W&N{KsaTM^5CjJpn6vjXkX?BA6+T> zbb@(rhEPz8c|PmFlJu-uoylCxNg4lH>R)>#R=x3tXvfl+&S(Ub``{uE{qeAnR<9~P zNidGRx#{LCGi-{~X#=!|{`;5wh(PsB)`2}b5`0yHkjk;6*Hc?=r-7*#mw;+;zK113 zx+q{&=)fI!Aai)bb8{orubOEixE~c*?)aRt<5|o$0d5h{9NdF!GCi%X40qQ!?APUSP3n*T3UCVl~(0uj?<^6Q4ElfhINrj~eFQ znF?;>9t4bf5&|c;7KW7{9$x9STcF9u$jt(!yN)4z=!ofw@n!56+b7bLE?B&!V$LN*1tTO;!>$JWc|an_O>NS4g1D@7tDbde^;dyGY&7YVnoxY9pDv+yQiS&_bXTQ`pzVp6OY6B7w=vD>G{D7n%|GTb0<^x5G&B6!#{}sejJQVWk})b@ z^{e9pU@D2LwiT6hW&tr}e$xn#LigNJtE8zrnqW@oS+mNkW~K|nT8~A8cbbH1>LzzS zU<QKWMZQv@UqU}KIW^^;oa^Ebj;4>=B zR2KU}Rkl0m4SZ7RpVj3Q4tMl|Y*&O3mAI~r`&c@R%IVcYkM6D@hMY+vIqt=es-v4_ zzzGC7qreRKiZsA@UTORoqI2tjy$J0>=)yZU)CKf5MCbOu*BP!=NY@a z1=``c265P@FuaSNC0=bqlzer@$VdS^YaT>N1#%=u6{9O5enq~kWX>rWOqx;Hq@zwf z4UalOA4vops`MzC^!iuh7#A%3gv9l|-_G?t(Gq%CDdg~>?Aq7s&KtM;=JYk@QW;aF zv?`98^D-631!83xiQ`ePDDK_Zv;`lR4P_E8=W8z0wK$7DCg@b9Ye>_)>c8V3Y&clxFH&F&_zQQ)ieRjXF$51IyKrywH(Q>1Bi6PO~K8UFRxOBs94aa~)Fr5Q_om5cJJ|5dj- zem@fR{1>h<*1)`h&)%vwwmfQ!Gkp99CPeT<{`w$Pj~`HgpjZQvKR;-8rAa|?$nULkiuexI-xz;#EVfda)IP{F`d#T4}Zs7-|swSO(GKY7* z5K(ZqE6x3yG3N`7^t|GIK>nHY82qcmpLS zm_(PxM#&b=eStMb7V`DT{k+E4o{(Ev?aPl7nA|h-^DmpE)pLekk4~VyT*Z=-Lz8%5 zc4{o>t*Q$xE0E`~C7w`uo)j~1b>$S-w}ZPt`1WmDLEtpbM&nHkf@QJw{xbZW4p`ut z0#it#cRVcvvQlI*@%5UO) z3hTK03I(rO!LsY$YZSp`*!Lk)>arAn4iKHKkrjG-Pp?A4FTho7iiT0b@x}E9O-=QB z65gdjo`I8mhcTpJ-ayfKF30uZ)W0(x*hx;CTO(}cXc43FGu(KcY;=$cO5GQk?D4>+ z(11H<$4Q;R$KqzWO^FOZ=k?4q$^DUzcAQAffS53*M3lfYY+QA4yS&y?+rZBtH0z}yZ2*2IMM@1kX~D$wAY+89=9xaY-NRZ%RMMb=umZPV}b z#FgL6_sjp5ujubyhpbb5ap!Sy&o)S3hjG47FO%eqdDKq*!QJL3#OrHvwqUQ44|McG zvhn-E{2c3)6c#-ZGgehzH*vhSHdM8X=af95#;>@w2yoFOa`GF;dZC@%f$9k4YH!Zb zPCusQsD}xuLr|e&luv)7ZwlpA<2+^2&yk4C0AX~w)>ny~%F$R-FJJ%g4fv`v9K4SI z0}edXPJtaZC=?B}u+bIrH-A+wiN~*8rYtC~K^#QR==b-#Q7!!`Vbiz~zm%D|B6Pwt zE0<2oL8F7mPH$+3&R`4`=C~1kZWpl48R-0g4(HoxIq(L~- zuS*${cJ8djG^c`M)tlNtJKCWvp!llM&;4z&OH31nDSf9QQ}yVmPvI;=VwdUNnwRP& z_nKMNqeicHKgT(yJzc${uuszH0Uq395P@3n%Cj<@%cbrHoDd==#4~u-3WhOngW2~c z5DW3ysv>hUR(a$3oZP;V<}aY=>>EboU8GdTKuUj&4`9_eJbv(R18F`u=!Z@B9A(jL z;deWYopt5AariZ3=(aH4hz8T5G0ky^Dh~-$$M+jXq$j z4NMzqL;nVZ(dh1IOlN`G0V4YhHZKmbpf89H+STv^RX3%DfWOvxf+wfC5xRNE3&OT+ z+)snK%x;C!ms-<(>OH{h=c(cvvoK{zpiFcK8ft1d#>P$z$#d ztZ5bJP#w+%+vNmeWQX4O1bdlrBsd3efHGXgz?^*8T3%=z>nGH#C`y@WkX^a;T!yL& zSk$3$UxmmkJyY<%WAAkOf5+aHzn5vgI_JwL{>LrWGNpwZ{yWJ_Qb?=cF>fx_=ix!2uezDJtSW+ktV8|nsRzG&}9|+_AB65DnldOXgWNv zBb~63fh6%H>%L_R>-HaYV(3@B7yAn_Rp0uI$42@b#3oQ8weMU3oQ%O+kI^KZrpuVC z+KaPA?DKtJkd$+RM3RJ5ly*Sm9)unsHz@A~BCX71`3qi^Y|&fsQm%of)V9K>H9}8sNSmv|s1lsN-zH}(<+A_X!=dP>&Tg~+uDCpp!Lx&_WuK&GOA(L7p;03`? zY|6E*qga5wm^rG2>*+tb%CDerVRj1X_n#5^PQjL|*YMTbl*7_{&Z%uujLt8|tFaD# zah3P~6`fK;_Qaf`lvm)$_dW64sLM*GPI0l!Q{{idPkfOsY9ANMHbCY>EL8CpT&E7^fZk2|gu>&h*K?)On{!CZ zN~Gp|`YVC`)IBD!qUJ9v$;EFvFB%M`;F6wVY{qJxGhQbaXwmYo%a0 zR84CS-h+xh%Jm`87jTJ77l7Q$575!f7Mu1Dh_2)Z*Ev)K;6zuxgW}hRP2~$3-T^*~ z%0o_}%bGwkLBaJJGJ=L<*4ci)=iUOB#5b{yFLoC#3qOFEmrq6CLr3G%DdpUxK<}`~e5C(i3%IU6Jn%GMU2K zp%I{|zj!Rm?B%A~xh$n{xxos?B-6K*aSw$I42#iSXatwN9k;;?wtJP;7L03Hu}*I5 zdUWzs-|OM~;6>O=ZDDRcgEsB)HH%pO<&{!Cnb$Ri?zl-((OVO6@fYckZe+f8I3By$ zt-i61F(EqjWr|yv?L$qai80;ZK}X3ric|b@FY>S7id6QkMN6ay%%xcb7q%|J?)}8b z%XoR=@?2FmpaU6LivH`}34)cfTDV!JL%&ZDniynsr^8d-k;kv_NMU7eM5qAWCl(Mc zCLXyjWXTa~^*1kV+5S65VC5%nan7Z%h0l$kW@~XYyX;)FtPj<*3tiPdI&t0yyr_Fd zw#<4&AAYK&4+rMwIl(u!Fmg^@{x2=5vb{FWr!L3r^?1*BJACSNZT z&<1ZFr+xS9trZ4T6&RPqx*;0IB+5rVNY*8WaCJ5SIosw5T^!;_6Ib_|L!3wW^z>&3 zzLDJQPwBv*HJncjxFV!jZm9;Q?2L#8fc+~g-q;$H<)^ebXMCdl0^erUvYQZ3sggTJ zkk@(2j|aovMmNKVd#thu(O5v!ZQqhrXX0PhwkIP}tx@fI6- z#c7S|bWHeFfy>Pr)TPg;2Dy%|mc7rD(UJQpe}iK$O`QfN?pc*J9q z4+2IKLb{={FkC3?w)qZx_HGNtg^|Ri>lX8TM$$$PB$Gz4-Gs_vTXEn4&CFh)BOKmf zT#w}VW#k^f<(Un321B#B~{ou1VgSa|_Hh^ATlb?mmUN6=(UAgKik#nEGiNc1vPe(43?%Iz) z{Vr#z^H2V5%hzGYA3t^6m0x<^*6VP(jqtuoXto5~d2WGP7A>=u6ffH8L4Nejo!}b& zlf)OCG2(d9a_=5Q=nD!(jz+PtGnCjsbPZ!$!TGHK80WV;;7kx+v&3rtdQygCYF@}MXQh^v z<Ua{J|&F&&bubDbYgh z0sLqKFTvPIbC+mdTR872ds{4e3VOHW+1~XaJ`#_8)TH8?f!-O88(;b=1>YW@CCyg3 z8Hk2gBq7i6zI#fm$i%uH74EeOe^nFzby2Nzh^PhN6oUu=&~CWynUb2n*jF@*r1XEZ zNCU|h4LoO?I;3Pmk_}8m!}%m2G!eg#A`3M!7H!4x=qoXzPh#G{QPk+xWEIzy#3;4F z`hEs0`pU@9eR$KWYW2qic>LOXjAvIbSk$<>ZeJOO~)ou8n!n$TyW~c`?T^V^< z8TNmaiYzqKvcA)~(QHSa-m8j=3NGDHAI#Ue)YA4|UdGR-koYSdsQk~zAx-dg zZm5miAhktIDAV8jL+xDIIIcY5+t8h0(DuX$&fBbDKTwifW^&*y_lY$3p3@7tW_c2j zGVJgclI`AELk77o(GaExlQ>#;2)}_v$fUH7BgErh=(h0)%rPCMQj`nw`)bHG*7|`+ zqRmQHWQe>h5@Sr$ah%3^jE5k1LlVMWd$>g2lde$o<&u`Pa=G96x$g4{lAEfE{Rk-* zrl;vFXZ~6vYk37tUyl_(l~rq+3}o*^a(B-_m9{R0`U8a-{SQUS3+@wT84@C;qq6<+ zYZQe3RC}bxVsWPlF+Ofm7!Ofnh&SnbZZByY^yCn{W5I9-h$pZ+O~=JTxH>PGxTYJvd$U zL?u{^7(mcs2j~NO`-bA0l!$3W!Bc((?HsId!EnF&jane zK5Q@jz}Jy|0)K>jsCBiR0w)E|MWf#4Qj&oJWpDYTJ**TP+q_&j87bPJ!7Wkv4I9)1 z-&gGw4C%DeN4$sU+EF>U?AN6%N6ruh0Tx{C1XfBEs9eIl*F~E;_lKn6HQXmAW?>i& z<~v-WC$CvVGfHwqIGf5+PYdayJCGv3#Knuz_<#|Y7RMs!)hfMLzVriSxfe6`1f}68 z38biV_12w&JS-njTqV7QiahR-ZK&Yhs+wOj#%F)){1DrH`~^ z84P%Lcs^8dhwf?dBA96$e6aKJ($ z`hlFi*kLawH*O8e=Sy$ZJS?9luqVF{{RL*I74PCqPEhz{xu@GfKpAh1mD_Tg^oRDYGW+gy=D^L5mw0Ae@7zYnJ8uIyEJFCGc zHDrL{{0n<|7f*VM{%IZ0TaoSq+$f!J(Q6XYTH#YNv=Ke;^cw_AOV7kd zM9CL2cEWPocjv?9Q}3c_y1ZeRA&XL$|6A8+7b(XSgBW{$>yNbfj2@?4teG_*u&091oET}*Lxv97=EfOAHOcf znTbyRV!RxiPS&+eLF&6Tp5NC}6N2LwIr^adHwN{7WeIt|we?8tw@9I%x zF*9}+@qYXuoRiO?s=mM0ZReFgj8c`{*zp8m7tmEM#KkRLezy18H4r3dBxMAp&NKzE z`~Hxe{X!+LTFrrTu?slC`8+d-$}cNZXJ7bA_F88Q0h;JIS0QmcbV@LlU2 z<-Oqkyru-?3dhl7J-bmwsh_bSe=PsL*jcl#-f&C&E@c?-ie)F4ki(jN*m_C_*6JQG;^{sYUfX6N z3w*%!S%lVW@}Mlt&p$_1#*(Uhbsx@>-;l9Io1bAuI@kwokyn(&^Tto&R!Wx3uI;UU z^iUQ7F;(59J(>tlOFCY;(*wbX)vn$%WP=%-Ww_%`erllO^;QH62(2~r!N1no1P%LQ zrua(qOy&KwD!`EU3&(jS%u`>^|GQ){|L%jueBO04{=G^i{*5cPd&+F=dk)>if_qs3F1{Evj4_r2CyufID z2-A(=;1yA_ZlgQ!wfGVEZPSH&PA?HO>2|>@&#i)2SA587MumC!1OENh-QZ8p36Nk_ zgM66Y5IkD6q4vBCtiz`0K7<<$EKTqFicd1FRZd4gj5(oUql#8r83X9uR!|WRkv;w@ z(6*MvLiGyOh~E{A2Q{MET?}%0hhbe5rZt`W1|K=W)#xfgUE3{v@WfB*>&beY%P+Tp zkLrldb}){_GJJ34iS}_!S=-vqe~B)i`e@$YwgU>t0NPHct(;JJReFk?^u6nQIC36N zc6Gj9Bh|je1%J6$h_fxFn?1S-+9fItykP-gqzF>ri zsh6jqqpi{X8d0(Vtq57a2F~hRAHhDB=Tm|4X;h#b4tpg3%nqA;6bN2=jEY}gGhSc} zzZWpqa5MU>r#T_h6z|Ldld^H_aKRj4U!+L0S~2%Si*xaxt?Vy+w4E-gGpb36vJu~0 z#YW|B-;bVhO_`UU3CoS*1L~Lydbu1vV2)Y&Blj8~h=hQYPAz21+jjYWpTM-f z=O;c7uikFldC5)!8Ff1a;Z*KSkHr@b-_)3>4RyDr%m~f{z-Xm^cGg z?9PUdtiET%y-I=(FxU3CfDK|em`Zd*_>EBuZMV_RAU!>8^3yRiyZo8veS)a$%leKc{>+p<(XkpvDkKH>;?KbX>^}HCo zJdQ{s+MPs);_-I#R1OKZs#T%LG}OpctqwS&abUai9V)tG=L9L`tTQmZpp#i4%Exb% zH4$P=`yHk?sCy4K#7RH@82}iSrl{Kl_#oi&XiuaZco26%P1#S$Zm*Jx?|#|P)*5c$ zO3~`{H2A2Yh>aS;P3?mhP&1!B%1cQXUu&@VBU;YmUr4UE^Quz~Ec1Vl!uBg=S=H*U z@A(~Su*EX2OgQjNuKU5K$L7wyBuD*xX;Ys`#Key;;6s*^s*dWHt;&Fu%gc|=P^Vk4 z-mEKHW$~XreTheIajtkP|6k9Ite4}v=&Tm_=_pOo*?fa?$Fhu^IyXnG{tKx3S%`kq z&AoFUZFTS0q+Zu+)FIae#cVU`$zqaSXA{PbTK0z6b^$QZn4OC;F7r!Pcq8y;vyVk=+B zJFm6Q^;YWaEBU~uB*CeSQQE56JwSB$0=+6#k`-l_AakkNte`<=4- zX$RRIrNP4vN14j92Y-8l_j^-uiRF&mABs;vQNNuST?IXW>l7LRvwau4(TwhHXT93${Sq|LJ*RmJ05Z(;; zNV!WEl|HJ>8;W3Yt?vKIao#0Icri%i{9-RU(SXc4HB$qMo?44$-4^)E+ZY!ayN_u& zudW5%@18;)tJ3z7qw&3(6I2ecK&?MuCWDmO3b^sTkpnylM4Q67s&&q9voZrqSxjt^ z8~X5^hd3IwX_kZ}+kxAq50)(wZe=#!S;{L^OWmL?(1Vxl)DCw=s!<jecV7NuaJ4mmEMUGx!B58Ceri?UyrkwkX zP=57f$Fh+3Vlm+VBOKfF1SWNHn;^XYd=%EcEPpfi(=20Z0iBq>boDfuF$-Mfe*fx4 zqQvrE_S*v1swqU*cR`eWUbJP(t2X)&+G7azFG@~@?w73%z0Y+>s7d*8ni(pfR*|r6 zrz0@gX@C87f?nVTWfnUNuiTlB8iQDj5976{eGj}we{q{R z41M&t1aW%J6N+(YfTp?;x{ffBNb}ANZ)22#cXKjRy zC(#g7T8o0SAb0~VX3`<{5jHVo<+L2@y=FPFYi5QtPUQ%2qYUp=UzCp@v)qvz zdIG_M411)QVk4=V)Ak9#)l*+oqFb^qH2wF9lsNvkYc~AeHIatl_`5Cm_ijhvIFFKh zEwtHof?#)!6+H$s=02^`HS;)$FDes-MaUBtpllo5-t(3-6NA-9Z z!Hv%Y3Wi@w-S)fj|E@5VdwNPC<#nRQ_Eh@Z0y31^V&M1z{nZAA2!fshez0J^d)Atg zU0B)7HsBQF2d8`EcY4^+<`F!4Hq)#-}ao1JQ+D{j+0P1jg@mY6cwSvtE0o5RbrJ`IXpM3Q8}z5Doph%y(%G|z5M>@|I)+b`FK3;x7+n9=Vmy>6eyQIG(%mV zlVB4sxIwa3>5sp6<5W0(%yohVH7qAj)`QRKguam*HJNz(QuNg;u?#=whm7o1+f+tp7b6%^r@AXto|ldp#YBB|h_TN+->-wZh57i4{KE|jfd@b&Sh~-d+ zDRI|5r+Vo`4;8ohgsEWR8M};3Bc^e@`Z?JX@)nrq#M)%o5f?o{>-6gM{V+lFmLaA6d8xJN8hmVhHumG(l08P#*}=mV(qbmMgfP6 z^1sNqQKszVAUf4W(u)xni~Ve35cYhonuf*(E0cYB_(#{lghMnyx+y#gC-&8kx#*@L zP3eV%ZP0q9%3xdUPA~kl=>uu8+l4yoikJjcA&ear+ftpt#%ukn6~#P8%_}_@gTIP!nR1 z6F^>w;o0^jM05l4xZTf=WcPRdlMBYd?;f%DuON=zUrT&{czJZi$pJL?=KWQO9;1^2 z^nR@YD;K!KMjEU$D$30?9`Yz+7u$F2e80Ms7_|CGoWv_05k}YtOHQ*FLCL#JnTPe0 z1^o3O^tx`kK}j(Zo|DVPUB8n!&F3I?nYktZ`1oRA3+O7=5cZ~_{9#DaY*`}< zEkTCWZOaxvq*~$heAY|u zX&Fgx*-6d>!=_Ar zMCK%7e(Wu(i5u{OGXG&8Q73dO4<4Vk<)Ve6*Q&0n+8q`6L{E0oQ{)DuXW{r)evS8P z&#V6k3%GLr6B+Q#$o(BsaUIIonrDFeRRABX7&n>+{AS5`b|MtwNdrbyN3 zL~|2@$S2wIA)0sH4xO5Nzq`X!~Or9|ytut;L)?FioNDBs*ul40mfU zJM`5uux>Y83F8y^D*`keD!8C802%N9>E5gz8r6-rey}t0ze$!ZMzjv=RMv6s6`aKF@^KCa$>nf%&foKeUhRvSdn2C0X;7)6>LA=#e=zv7Q`bcQx?9`Nn z=&v4c(v#SpdV!@(p<>*FSF_!y0=ji}*g|MBMd~a?=6?PYgbM744N;CMs!}L8&2iM| zphPIN9hG9DT@YUJO}fJl?v3x47hw#V`J4iB!2*716L?a zNg;-3oK8UY<$@K!yM;b5gmWj9qkCuM`3>;Qn|TnoZ@FY^*FE}r$ep&Zt4ba!`O=RH zMm5z+CkB#v-;(<5uD_Vau?8u6qKo6j#Iy-x`;z9-?pIR$0V-wP@N0!O1Mz)nN)5EC-IG_zIOf(ePkSp0jPwROUn5j_ zKgFGca>PjCb;PT4Co0ee*z+9{YB$xELUKuDkl?mU`8&+IF{92DFP4y-n6ZdYa-;vf zE`p|klu8n8oCc4&GX@OHSDsV<=o1!pD#43xfTrMP+Q|z$iRV{nmZzxPAgsu&ylZ$P z_dMFZt0r@B=O&mU2;87(hrW#+eA{J%(7v3Fb70kAVGhxg%v8FeC5^D(%4mcZ@CZt3 z;Hwc%traXsrRb8FSjT;!A)RI(aO3$Gr%_Yp z7tf&+KIoO&D(Obza@Qh>>(k-bK4~ki8{4ANoz)C3O@B0Bb7H^V4``6A&kyVospr-Q=yz@nJmA=PAuL@Wsq!bi%e91x1R& z(6$=sjEivKhm7i~-?zpBp?wCNIJ)TaY5PX6m~+!MOx_4B=9EF_wgp06HH6U6GNWf- zAygQJO7eu0XJ)a2=+iSRWX8M;G;i;YXtEp)XAvrggV}@xrxnb2RcTYWcygUM6eX9X zPY3agCtlX|0}zo+L%x$&8ruS9;C z1!nH}i!nl8o8X|a$7bayv8Ifg85typuW);snovdG7x3ReTMxf*AfAyibCw9pfa9yu z&@;<8ey4!eA9QCMIf+5_B~Q6~FQhxKA~(xL|1deMtW{8+MtVwZ=8!k1Xa2iGo#kqV zt`5$+W;vz^i+5J{S?<_%3qQzxyKplEs+lQCK_5kMvJD+oDV&TqL#ux|&3VUv-OeTd zyPa$9{EgJv)kPxma|V_O-7#%7qB^pP1zukzI!r9a+K;mJa^&&_r4PO`Jk%MmG^5O_ zv``jKShXCNw@rW$aGavfZ1I9?K@XbJYYy~Nl@g-{fa zK#_d)L44a^iwb{*g&~nXa@t}TrtKtxn~6J)>-z^4tL))*96=g;pF!-udW9r*+$_E- zTem|AZE)uYKBZ-O07MIz`}1iv(Hb?ga>I)PD&;z7G!NA}nMoh_nmwCf+iz}d&6D>9 z+cNFsXltznq`_t*v25Cn3)Qy8#VN%}EzvRWCNApqv31lj@$I-LsvjH?NYdrgq}dZI z+09}k3IO94dsF>Mf2=)DTB&Mmt*nVZz54PF>;e~`$uoswiWM^P&wn8J?ztJAw`^RG z8bNn>_j#Q#){M+T)HoAQTzN~A`1V3N3HQ!AphnSbJiT;klXYpEHDfGPX zn%!GDn(4Y<#I2*CICTYIlw_>2O7PNAZ8tUDzcc+fjXq_gX5Wdz@p~c3)?tW5M!=dr zv+O)aJF5Gjd!ed0*htMNp#nzWf9B{x$UeZFdtT`ws9YKQjaJHqVP?M!j{_tI#)8jh z1uEYml3J+Zx9jY;%PTI{pn50U*@{4urQ+-pFBedOkXQB~oQuQ1p0q!x z@h@GDbktv7%TTU-s5f|K2ENI3Vw>->-hBYusl{E0=y`^nZR)3>sB0MF+@E6BW`- z%o@m;*nH07v|fdhf%dlAz*zX-gEeR&%~~mV3HxaQ)FD4b$(PR|a3WQju*zNnS@QDL zq}D3P5m3<8z}at#km6{hG?ZSloP7=6%U)P1OOdxTeyabhcsIW3rnqAZ@y0(7MA`GJ zSJX;Lo#H{{nXrkz@F(IJIfHgluV#mqt}w4-_Rmup`(?;31t|=%R%&UTz&Y%;K(tX8 z>)Qe=RYxze5U4DTUAAHegj@kD8^pb8s%~#*8VQn(7lbNZg5-Vdv?Xld4Q)wytuSiI zmX`{@Tz40~V*f8|eP)BcTMH9i(Q;VUb_jHmIfDYzBaq-Lc5(ivUS&(B7V(PU9rF6a zpsHkvn-tdls96Hd>QvS8`=x34ie^;71S$z6B34{bSfBwROal9F=;2QGPm_(97$@!0 zpM>qLb*N{L^#`@2pSf`Ma2Aa8@vQ`0Z5f^5!bUV>dxLRfjud*g(w4GH_`|ah_JEN8I(0H~Y zNHPjF+AxCom@g&fFgs15+v2BEr_$Do7sDk^iD29)P3g>=3%`~k@t3Z6@c*(0o@^^q zg)vz%++aG?Vd}-;P7s)12ENX;gMGA@xN&94Ck-Uhmlr1aq7z<$?;cE<`gj=UCV8}K zN6-<*SI-N`i*R+*eu*2To=iO;d34_hjJ9^e$E`fE?E1smMp(hsP&2_B8)ITMn?sNk z>V_a-s;ZQ^dg(xyku=jOW~c63v(wqpo__P_<331Q&t(x)NUvAiyMu6Wj~#l(0C}Lc z>6Kx}_nyGGUfl&ca&IPlw(h3cuzl{&vJ)ZsbaoBtz`G?Q288EwRT380P??E{?;ruM zG?X8lh@=o~;?q#MfUJo*tSgNgKG#m1Hb`z_&UR=ZzxE;QjV0P$0q%M%-c>)Wn0vC5B+x?Z)-Ag6^R3_h?=aW!ks6mk_GSoaT%u$T_@Q&8$#+UPlv*qFs*v?7w zO-9(N2N*>2Deu1+$%y7$W-Bs7PN|RWQ3r{ZeyiS!Z&e7bXk zAXQ&LQZpO;ygR_3Gw6P;qxJ7o#5i=Gxf|ASJKTWrQRaV8-=!VUc$(91^ctG9$iJx8 zEQIwsNJL4E!pJ8f{Pu6CsYMx&KyXGu7v^g1RW?dTj@e~mY=%=*uRogy19QH%x946M zWeJjt|3_XCf}A%b{+m<(Z+WU52%qqm+&HeiOT6uNmPCEGw-a0w4G$#^bhc1!~a z-7ERugY`smxm*?0@z!=URprz1;&@uP>CLls5Esdx9o4X;3g&pXHvMUE%5KlpeuJ5)aL0_+a-Aw_(?L|o%@f!!=zOL~9r!z(on zgC_X(>ete#fBbPyA40%G+M1MGgRNnTXA4^>Hyy6J@AtgkPnAA;C6~U`mvfSnd#QU! zKDJV{ztxL1X0OPQ-0iFm*mZiTAHC+rv_CyT8`{$afqcDh z?gnn9@8ts19pdaBd1#>@Utc4Fh8I4C6?Xx{*6ewd+Hdj_9Qn&~hR=PNx>{-)ATC(O zKgi!JJsw0x2Y6?wcRz~eSuM;Hx+2;X{k{nbvZ^8D9t|;C5z3NCQ6o!)VMo~6SpcZV zvi0hoUQcb{kKR(OtkWoO#13Xal59Dc#gE(t%8eVR)359|4pg0Z4c!uBjnq)1jY4-9 zGTCkI8rZ-_ytG!Zd5xLbE?j6E1h#X^c3rWv1NVJxtJ!*D*`P%Z0(z3x*=o!DyT*fLS}Hv%aq zm?dHk7{&}=#t79_50H-vJ*}~eO0Grk1AUWJujyM7jg64;Ls8RP;X?gQ)#wPk3CoEv zGzllcrn~)vF*CoT^thw2>FNc4TBIX1pyeq+3PDFEy0DMJ-D5u3X-<5F*OPD52Ew>? zG~xL+p!;HN4czz&7OZ;J#t_sXKuhyF!GqOxWYZd@z^mAOe@x|}6E;}6K+@asQQBga zE?-GkuY2L|MwOM!vT9&_R4}cy=fQZ7=aGf_86)B#dqyZl&D>hV*}KV?5O{$zKKsTo zl<1TARR;3qSRdB;qO-8SW1l%LzAPRbE~p3Z_b9XPTs~rVFYskHr?BuM=bR4ftD_W8`{4<~TQp}{ zrzZOt;zMat<;(ZPW}FSRA2p_0i#KcIGL`t{SbK$(b1uR%2$^Gk#RHkVQET*fJUWRk zbMIEX<~>Ik?uQLfBl?TD`B(Jw#qODT*`Zy}bU-8y-$bAJ%yzbF5gTvu+7yz3et8pZ zr)Y_{R}X83VjLH_iLVi)h1!&Z*h(PM?qttpDLYOz)i%_TYeh=$Nh+21F8uuLQ}JS~ z^P`=#1ZvIvAI>6F3v-i7zNz#plDa7a?lYoE#`3CTLH{^{cTtl} z{3YNV7aw`CJKjyf-mie<7nD}7HhNpJ=mZ089l2Z*9gPaY&dQc-kc1RT*GfC-sswiF( znF$~6kdO#sOR&^<_Gja6q$T}!O`4(PUL%yqD-NMiQ)Z`&&^ytU3v(KVY1iR*fBc1t z7rcKW6zsb?n=ohBeUAp;yqJqLR0X$IDk5RZ=XnYVnl>h^cdozyjR`Exf8PymF4+e@ zNjwWy7tz9FpmuRY=JAVBO$TYP_ycs!eVbo;O-o0nySI;0r#KI5SiNAtdhptxr*!x{ z0)nvv|Gs~XWF2&(HXvxI0fqDsbXWw8iO65Ft*$8XHTXDV%r0=PU6h!Xq%F!#bV2f+ zKrVFHi3K`#)z_1kRk|DAlG}(6`@(IXXp)VY0x0_2b`&(^O|?$T66WXeZX0=!Amc}(wacH61y)=QPo78rN%Vl>mh;% zW!IQ7(e6y#o4)F8>qiGf|4U9L{ntpjE&Vm(G{8Wd1rvs$8pe7?>C$#gZ$O%I3TRUr zs^Dgb%!zpeU&jDsIGIQM9SFg6gLx-@M=nH6WLTGz;~8C)?qakW-h0JTqUd^bL!eZO z6w)%b$Ht!WF`(E+bxsYTxtA(eiD=@hslk%5W0JIGiIS@)4JENSb8{UQkDZ-ei0-Hf z4OjTC6^bg-ROpsZOel-m{bAF6eGrvxzh~;Goo%bFm;5v27M+Ef+mEnIXzNY`WO@(-wfNj&XSJ zwZ7_5>Tmq@M)DG>zC08;Y=m-_l^7>wQasxEm=DXA;}4|!Sy5^ekCOvW=~}6skoI1b zgW`fqa!FSwNzg;)pNuk-`0AKMjC?j??!qQWF+*Vua`s6xVy;IOOSE{l|E3%~sYe0W26Bto#2hoJ6|Uj@e(t zd%h~#-o0ZzsBY9t33NTCSGjlw0djl7HT6=k+;(BuoM(Zg7WaJHWLtVp8KdWgoVcEF zp5{@Hply7^qh@~$&_uf>rIzN>UW^~ITZ-)rcS!2flta=)x^DO2ZTsJy(;?~l>qk4P zx@I>Qg%p(>ZrIBM%sJ+cXlQ?IHG9FQN;cal?Vk$aWx$_zB^g3M;szPVA)D*>n=`t5 zu*$%3YFlVjgP2gcGWY9JvS#w0ix(s*+m0OJbzQy6ki9qRBl#X*Niyt~V=67KUFKw8 zE93<6vpHMYmpRF|Wbv zDUZND_MMX?AW!WsQZeJ&$5M|{HZ40wjd50@-aA$<8u3Tk0e5!?X7$%hJpePTs}cS; zrzmb(Ct*gB88_^pC`X69SKL>m;F7N0k(tq5T?3;&2vk2-svvFV7k36|qfHjGW(iDl z;69-E{VKg1cf~Wo56)X|N6$v%d!X4ztD1}z`O-x~(UVyS->Zzdj>EK_eTbTIa-TlR zc1g(+*9T@vzWYdm>ung(J{lEIH}Ahv+&}w03B2d)D

$ueU;V`e22L2u2kzab_M1 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ⅇuDal7kq+3z9 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 S_5}!ht#|iYb7wU>@&5r6549%% delta 240155 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

Vna_0JF@gcVt_T)oBB(b@^c-!AE=l4Rk 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 a27o_@|3UK1k7EGz2X*Oe{M(h4{Qm%Ab|a1e From 5a6fbcf1245991035da99db2bfccde706421ec12 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Wed, 30 Aug 2023 17:43:19 -0300 Subject: [PATCH 40/89] Fix examples/shapes/shapes_collision_area.c help instructions (#3279) --- examples/shapes/shapes_collision_area.c | 5 ++++- examples/shapes/shapes_collision_area.png | Bin 15319 -> 15595 bytes 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/shapes/shapes_collision_area.c b/examples/shapes/shapes_collision_area.c index 34d04811d48b..752d4e79ad23 100644 --- a/examples/shapes/shapes_collision_area.c +++ b/examples/shapes/shapes_collision_area.c @@ -99,6 +99,9 @@ int main(void) DrawText(TextFormat("Collision Area: %i", (int)boxCollision.width*(int)boxCollision.height), GetScreenWidth()/2 - 100, screenUpperLimit + 10, 20, BLACK); } + // Draw help instructions + DrawText("Press SPACE to PAUSE/RESUME", 20, screenHeight - 35, 20, LIGHTGRAY); + DrawFPS(10, 10); EndDrawing(); @@ -111,4 +114,4 @@ int main(void) //---------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/examples/shapes/shapes_collision_area.png b/examples/shapes/shapes_collision_area.png index 760e1bc1d94f9f11f21993fa5193a9ec8850ba2e..049e6fb00213631953a26d5457e9768e64f77a77 100644 GIT binary patch literal 15595 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ1{4ubUVDOp!Df@Ei(^PdTyo8_%zyI} zMS9u}WN=_77-XFqGEJtqJ13a1xM3w4;uH;TF-rPoFIF^=V!}r7ES8;c(FKPjP{SLi zgc7zClfZsl&bXk<;%2R|xHA{08}cA-$iZekL=5Nz6WmVt193tqm7UNa!W4Af->Bh3 z#sWm}UQh%3Ml&0aZw@%E@eNvP-x2g{&1~j1eIZ|4c+{`i%&=Utt2yeI+vRuA=sMuk za3%0d`mARYJ_%be`Fm+BdfohybK2^FYLC$VJiV=Ve6@=?fBJVFDUk4ehzOf0tp{H4 zoXFsk;%&SrAc2Kg5Y4e+LY8n&T4O}*jw_R`7Bg<{5Bc4Bwf(g1lUwGq+MvmSA?}|; zx>-Rh$GVx5(ofmxjrIS&nI9YUm>6Wom#B_~{*VvIeNELL>b zE|4I}`x@b-Mqb9CbRM_I-CG1C?mjl0l>|$H1rQH($zX9i*grrIOt4{g%6QMV_Pfu7 zZ2O(nek*EcUC+2B2i5UVj_Js}f3E9i$`|=_O8c%v1kM&th%-&`ICH@*&4?%G3?{q^ zj+)!l`i?K@?ZWB%-9I0JMhnk3fdyae1fzcEm#C$f@b^N~^#cxw$rgA_mat{bHrWW% z!O(u-g{JS9UIr)g?fvt-%%W7F$%rA>8JuTYVJb25FEG!nsN)jbb-MkPT<68TvWs^X zfYMt-l%m6%l>rh@pMRa4V%a#M_J#7FBdgrQ+wF>-b?YC^5>&cg6Vup{t(H>amSyrD znjeU=PNGrS;lKOgYFx=0Sc1F|WLj*ju=r&TE;S7VGja(q74e?&zd&(T#F5|4A4t#(VDShheF<&5NU;xOnoDE9>L; zPkL%P!}i55Pf_)2MKRC#LiSwHp2Hr!%lW&x&c9Axey^*Kz1BDD*7i)B0WIVlGC6wA z0W--$)R;iz8Bm;nDhOyMD^hgGNNc_#SmVXqaA&62jJ;D{Ee~bk+g7lw)JfH(*)gN7 z>Bf&G<-cTfAHfRf4G;rn;VYm)Zh)qXL~*7a-|_@LX>9%0GhugnLtHgqhUmjDx3nE| zZ2I2KmC(HdGq|7)?6Olt8Z0QxbY$JbR;|sJmCw8L zq1i6;lr093YC%)cz>3*u)-^<(1+x}fSiBGe7as72NQMYgi`y3V*Du32JXmmDGvY|! zAO5Y9Oi7Q+m&`RYi+TX7^g)3sg{`86RaU5B!Cd?6;)@QmOwX>cYBx9kgHmMsUs0Ut zi&ZMebq=eA6HBw+hDvBISDLshyzNH8!f$fYL64JHyl0fsm4bS>Aq)}#+t9p?-~t1n z=YZfMnwJXTG9Gt`Nz_3cx(aVh0h@eB$S;^iod78wfR*iNM1YzcqoFVw3gF(-Xj%YO zTce>c8VayJ*l1c9O$(!G0nvdPEgeVOj);NPVNp8jEKY=tuqrY!q1Yh`)20Qq|qH@rKa@dlBdc^(N!#5S4EvKgIy0?w9>&cT7^j7LL( z)}a7gl)&)#`uh0){cYbds#HYgyr9hDmJVDnaub&thPzG)TYxck12LzG5b;r|w0i(?5&x62S+H|3c9*7R=$XKMsb#V@XQaf@a|7=G9i z(*MUfMgZ#nAMiW4Xd1t#tfy*e%ETz;iAVa@JlfPBX3TzNp5jH>wC}rkz7@!?C}BOl zf62L;178;Io*hx_(aZ03xIOBr$l5!$QQ>{adldtCz#F?ttdUD{gp;5<+g>I5zB!?! zSo*@4amgzA%*<(bCceM8$JWNF;nqk0cX6E;znGxu{{q>ScooGm%GP<==u@i-R5a4T8*o0E?Li=Bo)79-cKbHVW)M~C(r6L zPo0-BwcqXaHRymRcq4)Y4`f+AA4-Bm-Y5lH{~y1Tsx-Lq8<;({ZX9 lo!|f!ZKI(;Y$z}=6s6|I&Rdh)1l+{T;OXk;vd$@?2>_Q(o@D?4 literal 15319 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ1{4ubUVDOp!Fryji(^PdTyo8_%zyI} zMS9u}WN=_77-XFqGEJtqJ13a1xM3w4;uH;TF-rPoFIF^=V!}r7ES8;c(FKPjP{SLi zgc7zClfZsl&bXk<;%2R|xHA{08}cA-$iZekL=5Nz6WmVt193tqm7UNa!W4Af->Bh3 z#sWm}UQh%3Ml&0aZw@%E@eNvP-x2g{&1~j1eIZ|4c+{`i%&=Utt2yeI+vRuA=sMuk za3%0d`mARYJ_%be`Fm+BdfohybK2^FYLC$VJiV=Ve6@=?fBJVFDUk4ehzOf0tp{H4 zoXFsk;%&SrAc2Kg5Y4e+LY8n&T4O}*jw_R`7Bg<{5Bc4Bwf(g1lUwGq+MvmSA?}|; zx>-Rh$GVx5(ofmxjrIS&nI9YUm>6Wom#B_~{*VvIeNELL>b zE|4I}`x@b-Mqb9CbRM_I-CG1C?mjl0l>|$H1rQH($zX9i*grrIOt4{g%6QMV_Pfu7 zZ2O(nek*EcUC+2B2i5UVj_Js}f3E9i$`|=_O8c%v1kM&th%-&`ICH@*&4?%G3?{q^ zj+)!l`i?K@?ZWB%-9I0JMhnk3fdyae1fzcEm#C$f@b^N~^#cxw$rgA_mat{bHrWW% z!O(u-g{JS9UIr)g?fvt-%%W7F$%rA>8JuTYVJb25FEG!nsN)jbb-MkPT<68TvWs^X zfYMt-l%m6%l>rh@pMRa4V%a#M_J#7FBdgrQ+wF>-b?YC^5>&cg6Vup{t(H>amSyrD znjeU=PNGrS;lKOgYFx=0Sc1F|WLj*ju=r&TE;S7VGja(q74e?&zd&(T#F5|4A4t#(VDShheF<&5NU;xOnoDE9>L; zPkL%P!}i55Pf_)2MKRC#LiSwHp2Hr!%lW&x&c9C4<4@&do(TlmM;XD2iUMHH0hYsC z@CMjiV2uu`O`Y{vIL_uwuxj$pWSC%mnQ8O%pubzX4jdFax5aP8l5-Ukr0sTmxoCa2 zPplSJhz2McSTP&T`UWemF|yhVF>oe?R_Hfc8P@HUZn5!NYpZ;uFJ*E6j>)^j8$y0( zh(3JsYxa$bg(flXn|~qF1ySWF!UM``EHCzcn|DW2G@@m~tGKM+{da6Rm;9O?Q9gOs z^QKE5)TbD_eb4C;n+J8iLmWrXIbazw2Q{H0iWE?i1=XLhGKf*Cm0_V^QB?nh;8(gq z=`ts__TQMeH4=PSUF>wRTZ;RoWuv@$#q;`kf13?+qD-iPZP}2Zc#9_}7?cZIUi{CffO!)UPjD84Eu?uh z7nTI!GO%n-u!Wbf1?UYnoC&He9^%kfcpOTgm>G2fsF^Yv3ZtPgnkkXXr_mfSnj=PY z#AuE{A0Qho7e>p4(Q;w5To|F{0>kNy2ymB=XTQLMUB_&t)`Gjw7ETXlU%P&B1EP~E zaX>%<)T^z7jSgURe@BP(Kr<(!p)eW>unDTsv@n_$M$-avMKPKqMsoxebA-;~iB`zT zYYQLavD3er)hAs4yKrapzH2>U>lg3Lf{ucNW}Ai9T-;)atOL0BjofN=n@ss z7%ZeH8eJs=3X0KC7!8Hd9DzJ0J(?p%bHr$l7|jvL9hT7?F`6SrbHr$lK=d9EtkL$u tXz4gwI*yi(qopIFOhmBgP&zU&oM#T?66lzs0o<_5;OXk;vd$@?2>@k)q Date: Fri, 1 Sep 2023 23:23:01 +0200 Subject: [PATCH 41/89] RENAMED: LoadFont*() parameter names for consistency and coherence --- src/raylib.h | 12 ++++----- src/rtext.c | 72 ++++++++++++++++++++++++++-------------------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index d932e3a34881..9043a11e9edd 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1371,13 +1371,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 @@ -1387,7 +1387,7 @@ 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 diff --git a/src/rtext.c b/src/rtext.c index 3fb2b8861b85..9017c8b26926 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -358,7 +358,7 @@ Font LoadFont(const char *fileName) // Load Font from TTF font file with generation parameters // NOTE: You can pass an array with desired characters, those characters should be available in the font // if array is NULL, default char set is selected 32..126 -Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount) +Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount) { Font font = { 0 }; @@ -369,7 +369,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCou if (fileData != NULL) { // Loading font from memory data - font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, glyphCount); + font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, codepoints, codepointCount); UnloadFileData(fileData); } @@ -504,7 +504,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar) } // Load font from memory buffer, fileType refers to extension: i.e. ".ttf" -Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount) +Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount) { Font font = { 0 }; @@ -516,9 +516,9 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int TextIsEqual(fileExtLower, ".otf")) { font.baseSize = fontSize; - font.glyphCount = (glyphCount > 0)? glyphCount : 95; + font.glyphCount = (codepointCount > 0)? codepointCount : 95; font.glyphPadding = 0; - font.glyphs = LoadFontData(fileData, dataSize, font.baseSize, fontChars, font.glyphCount, FONT_DEFAULT); + font.glyphs = LoadFontData(fileData, dataSize, font.baseSize, codepoints, font.glyphCount, FONT_DEFAULT); if (font.glyphs != NULL) { @@ -562,7 +562,7 @@ bool IsFontReady(Font font) // Load font data for further use // NOTE: Requires TTF font memory data and can generate SDF data -GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount, int type) +GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type) { // NOTE: Using some SDF generation default values, // trades off precision with ability to handle *smaller* sizes @@ -600,25 +600,25 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap); // In case no chars count provided, default to 95 - glyphCount = (glyphCount > 0)? glyphCount : 95; + codepointCount = (codepointCount > 0)? codepointCount : 95; // Fill fontChars in case not provided externally // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) - if (fontChars == NULL) + if (codepoints == NULL) { - fontChars = (int *)RL_MALLOC(glyphCount*sizeof(int)); - for (int i = 0; i < glyphCount; i++) fontChars[i] = i + 32; + codepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); + for (int i = 0; i < codepointCount; i++) codepoints[i] = i + 32; genFontChars = true; } - chars = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo)); + chars = (GlyphInfo *)RL_MALLOC(codepointCount*sizeof(GlyphInfo)); // NOTE: Using simple packaging, one char after another - for (int i = 0; i < glyphCount; i++) + for (int i = 0; i < codepointCount; i++) { int chw = 0, chh = 0; // Character width and height (on generation) - int ch = fontChars[i]; // Character value to get info for + int ch = codepoints[i]; // Character value to get info for chars[i].value = ch; // Render a unicode codepoint to a bitmap @@ -678,7 +678,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz } else TRACELOG(LOG_WARNING, "FONT: Failed to process TTF font data"); - if (genFontChars) RL_FREE(fontChars); + if (genFontChars) RL_FREE(codepoints); } #endif @@ -688,17 +688,17 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Generate image font atlas using chars info // NOTE: Packing method: 0-Default, 1-Skyline #if defined(SUPPORT_FILEFORMAT_TTF) -Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphCount, int fontSize, int padding, int packMethod) +Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod) { Image atlas = { 0 }; - if (chars == NULL) + if (glyphs == NULL) { TRACELOG(LOG_WARNING, "FONT: Provided chars info not valid, returning empty image atlas"); return atlas; } - *charRecs = NULL; + *glyphRecs = NULL; // In case no chars count provided we suppose default of 95 glyphCount = (glyphCount > 0)? glyphCount : 95; @@ -712,8 +712,8 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC for (int i = 0; i < glyphCount; i++) { - if (chars[i].image.width > maxGlyphWidth) maxGlyphWidth = chars[i].image.width; - totalWidth += chars[i].image.width + 4*padding; + if (glyphs[i].image.width > maxGlyphWidth) maxGlyphWidth = glyphs[i].image.width; + totalWidth += glyphs[i].image.width + 4*padding; } //#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE @@ -764,7 +764,7 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC for (int i = 0; i < glyphCount; i++) { // Check remaining space for glyph - if (offsetX >= (atlas.width - chars[i].image.width - 2*padding)) + if (offsetX >= (atlas.width - glyphs[i].image.width - 2*padding)) { offsetX = padding; @@ -789,22 +789,22 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC } // Copy pixel data from fc.data to atlas - for (int y = 0; y < chars[i].image.height; y++) + for (int y = 0; y < glyphs[i].image.height; y++) { - for (int x = 0; x < chars[i].image.width; x++) + for (int x = 0; x < glyphs[i].image.width; x++) { - ((unsigned char *)atlas.data)[(offsetY + y)*atlas.width + (offsetX + x)] = ((unsigned char *)chars[i].image.data)[y*chars[i].image.width + x]; + ((unsigned char *)atlas.data)[(offsetY + y)*atlas.width + (offsetX + x)] = ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; } } // Fill chars rectangles in atlas info recs[i].x = (float)offsetX; recs[i].y = (float)offsetY; - recs[i].width = (float)chars[i].image.width; - recs[i].height = (float)chars[i].image.height; + recs[i].width = (float)glyphs[i].image.width; + recs[i].height = (float)glyphs[i].image.height; // Move atlas position X for next character drawing - offsetX += (chars[i].image.width + 2*padding); + offsetX += (glyphs[i].image.width + 2*padding); } } else if (packMethod == 1) // Use Skyline rect packing algorithm (stb_pack_rect) @@ -819,8 +819,8 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC for (int i = 0; i < glyphCount; i++) { rects[i].id = i; - rects[i].w = chars[i].image.width + 2*padding; - rects[i].h = chars[i].image.height + 2*padding; + rects[i].w = glyphs[i].image.width + 2*padding; + rects[i].h = glyphs[i].image.height + 2*padding; } // Package rectangles into atlas @@ -831,17 +831,17 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC // It returns char rectangles in atlas recs[i].x = rects[i].x + (float)padding; recs[i].y = rects[i].y + (float)padding; - recs[i].width = (float)chars[i].image.width; - recs[i].height = (float)chars[i].image.height; + recs[i].width = (float)glyphs[i].image.width; + recs[i].height = (float)glyphs[i].image.height; if (rects[i].was_packed) { // Copy pixel data from fc.data to atlas - for (int y = 0; y < chars[i].image.height; y++) + for (int y = 0; y < glyphs[i].image.height; y++) { - for (int x = 0; x < chars[i].image.width; x++) + for (int x = 0; x < glyphs[i].image.width; x++) { - ((unsigned char *)atlas.data)[(rects[i].y + padding + y)*atlas.width + (rects[i].x + padding + x)] = ((unsigned char *)chars[i].image.data)[y*chars[i].image.width + x]; + ((unsigned char *)atlas.data)[(rects[i].y + padding + y)*atlas.width + (rects[i].x + padding + x)] = ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; } } } @@ -879,7 +879,7 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC atlas.data = dataGrayAlpha; atlas.format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA; - *charRecs = recs; + *glyphRecs = recs; return atlas; } @@ -1176,14 +1176,14 @@ void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSiz } // Draw multiple character (codepoints) -void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 position, float fontSize, float spacing, Color tint) +void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint) { int textOffsetY = 0; // Offset between lines (on linebreak '\n') float textOffsetX = 0.0f; // Offset X to next character to draw float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor - for (int i = 0; i < count; i++) + for (int i = 0; i < codepointCount; i++) { int index = GetGlyphIndex(font, codepoints[i]); From fc0c51d0c7d0ff4e916759a37d461ee1effb0596 Mon Sep 17 00:00:00 2001 From: Johannes Barthelmes <615914+jbarthelmes@users.noreply.github.com> Date: Sat, 2 Sep 2023 11:41:33 +0200 Subject: [PATCH 42/89] Fix uninitialized thread-locals in stbi #3282 (#3283) --- src/rtextures.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rtextures.c b/src/rtextures.c index b88aeb1549b6..a97cb0b378b7 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -147,6 +147,8 @@ #define STBI_FREE RL_FREE #define STBI_REALLOC RL_REALLOC + #define STBI_NO_THREAD_LOCALS + #define STB_IMAGE_IMPLEMENTATION #include "external/stb_image.h" // Required for: stbi_load_from_file() // NOTE: Used to read image data (multiple formats support) From 650fbab3418752de1cce26dfee7d9e715f15bffc Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 2 Sep 2023 11:48:19 +0200 Subject: [PATCH 43/89] REVIEWED: Added `SetTextLineSpacing()` to multiline examples --- examples/text/text_codepoints_loading.c | 2 ++ examples/text/text_font_loading.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/text/text_codepoints_loading.c b/examples/text/text_codepoints_loading.c index 1f3db0cf3d93..376b4972ac67 100644 --- a/examples/text/text_codepoints_loading.c +++ b/examples/text/text_codepoints_loading.c @@ -52,6 +52,8 @@ int main(void) // Set bilinear scale filter for better font scaling SetTextureFilter(font.texture, TEXTURE_FILTER_BILINEAR); + SetTextLineSpacing(54); // Set line spacing for multiline text (when line breaks are included '\n') + // Free codepoints, atlas has already been generated free(codepointsNoDups); diff --git a/examples/text/text_font_loading.c b/examples/text/text_font_loading.c index 2ded64f09f20..a3ff988e9bc0 100644 --- a/examples/text/text_font_loading.c +++ b/examples/text/text_font_loading.c @@ -47,6 +47,8 @@ int main(void) // NOTE: We define a font base size of 32 pixels tall and up-to 250 characters Font fontTtf = LoadFontEx("resources/pixantiqua.ttf", 32, 0, 250); + SetTextLineSpacing(48); // Set line spacing for multiline text (when line breaks are included '\n') + bool useTtf = false; SetTargetFPS(60); // Set our game to run at 60 frames-per-second From 98a02e13ea101777881de79eef2d49f602a65864 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 2 Sep 2023 12:05:34 +0200 Subject: [PATCH 44/89] REVIEWED: Data size type consistency between functions #3168 --- src/raudio.c | 22 ++++++++++---------- src/raylib.h | 8 ++++---- src/rmodels.c | 54 +++++++++++++++++++++++++------------------------ src/rtext.c | 6 +++--- src/rtextures.c | 10 ++++----- src/utils.c | 32 ++++++++++++++--------------- 6 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 9d1683a1fa0f..4627cdf5c63a 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -413,8 +413,8 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension static const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes the dot: .png) -static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read) -static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write) +static unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) +static bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write) static bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated #endif @@ -732,11 +732,11 @@ Wave LoadWave(const char *fileName) Wave wave = { 0 }; // Loading file to memory - unsigned int fileSize = 0; - unsigned char *fileData = LoadFileData(fileName, &fileSize); + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); // Loading wave from memory data - if (fileData != NULL) wave = LoadWaveFromMemory(GetFileExtension(fileName), fileData, fileSize); + if (fileData != NULL) wave = LoadWaveFromMemory(GetFileExtension(fileName), fileData, dataSize); RL_FREE(fileData); @@ -2619,10 +2619,10 @@ static const char *GetFileExtension(const char *fileName) } // Load data from file into a buffer -static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead) +static unsigned char *LoadFileData(const char *fileName, int *dataSize) { unsigned char *data = NULL; - *bytesRead = 0; + *dataSize = 0; if (fileName != NULL) { @@ -2642,7 +2642,7 @@ static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] unsigned int count = (unsigned int)fread(data, sizeof(unsigned char), size, file); - *bytesRead = count; + *dataSize = count; if (count != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded", fileName); else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName); @@ -2659,7 +2659,7 @@ static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead } // Save data to file from buffer -static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite) +static bool SaveFileData(const char *fileName, void *data, int dataSize) { if (fileName != NULL) { @@ -2667,10 +2667,10 @@ static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToW if (file != NULL) { - unsigned int count = (unsigned int)fwrite(data, sizeof(unsigned char), bytesToWrite, file); + unsigned int count = (unsigned int)fwrite(data, sizeof(unsigned char), dataSize, file); if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName); - else if (count != bytesToWrite) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); + else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName); fclose(file); diff --git a/src/raylib.h b/src/raylib.h index 9043a11e9edd..084fb4dc04ca 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1075,10 +1075,10 @@ 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 @@ -1506,7 +1506,7 @@ 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 diff --git a/src/rmodels.c b/src/rmodels.c index ebb454e4ae56..66de97273d55 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -151,18 +151,18 @@ static Model LoadOBJ(const char *fileName); // Load OBJ mesh data #endif #if defined(SUPPORT_FILEFORMAT_IQM) static Model LoadIQM(const char *fileName); // Load IQM mesh data -static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, unsigned int *animCount); // Load IQM animation data +static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCount); // Load IQM animation data #endif #if defined(SUPPORT_FILEFORMAT_GLTF) static Model LoadGLTF(const char *fileName); // Load GLTF mesh data -static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, unsigned int *animCount); // Load GLTF animation data +static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCount); // Load GLTF animation data #endif #if defined(SUPPORT_FILEFORMAT_VOX) static Model LoadVOX(const char *filename); // Load VOX mesh data #endif #if defined(SUPPORT_FILEFORMAT_M3D) static Model LoadM3D(const char *filename); // Load M3D mesh data -static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, unsigned int *animCount); // Load M3D animation data +static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCount); // Load M3D animation data #endif #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL) static void ProcessMaterialsOBJ(Material *rayMaterials, tinyobj_material_t *materials, int materialCount); // Process obj materials @@ -1979,7 +1979,7 @@ void SetModelMeshMaterial(Model *model, int meshId, int materialId) } // Load model animations from file -ModelAnimation *LoadModelAnimations(const char *fileName, unsigned int *animCount) +ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount) { ModelAnimation *animations = NULL; @@ -4081,8 +4081,8 @@ static Model LoadIQM(const char *fileName) #define MESH_NAME_LENGTH 32 // Mesh name string length #define MATERIAL_NAME_LENGTH 32 // Material name string length - unsigned int fileSize = 0; - unsigned char *fileData = LoadFileData(fileName, &fileSize); + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); unsigned char *fileDataPtr = fileData; // IQM file structs @@ -4090,7 +4090,7 @@ static Model LoadIQM(const char *fileName) typedef struct IQMHeader { char magic[16]; unsigned int version; - unsigned int filesize; + unsigned int dataSize; unsigned int flags; unsigned int num_text, ofs_text; unsigned int num_meshes, ofs_meshes; @@ -4443,19 +4443,19 @@ static Model LoadIQM(const char *fileName) } // Load IQM animation data -static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, unsigned int *animCount) +static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCount) { #define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number #define IQM_VERSION 2 // only IQM version 2 supported - unsigned int fileSize = 0; - unsigned char *fileData = LoadFileData(fileName, &fileSize); + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); unsigned char *fileDataPtr = fileData; typedef struct IQMHeader { char magic[16]; unsigned int version; - unsigned int filesize; + unsigned int dataSize; unsigned int flags; unsigned int num_text, ofs_text; unsigned int num_meshes, ofs_meshes; @@ -4815,7 +4815,7 @@ static Model LoadGLTF(const char *fileName) Model model = { 0 }; // glTF file loading - unsigned int dataSize = 0; + int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); if (fileData == NULL) return model; @@ -5295,10 +5295,10 @@ static bool GetPoseAtTimeGLTF(cgltf_accessor *input, cgltf_accessor *output, flo #define GLTF_ANIMDELAY 17 // Animation frames delay, (~1000 ms/60 FPS = 16.666666* ms) -static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, unsigned int *animCount) +static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCount) { // glTF file loading - unsigned int dataSize = 0; + int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); ModelAnimation *animations = NULL; @@ -5466,11 +5466,11 @@ static Model LoadVOX(const char *fileName) int nbvertices = 0; int meshescount = 0; - unsigned int fileSize = 0; - unsigned char *fileData = NULL; - + // Read vox file into buffer - fileData = LoadFileData(fileName, &fileSize); + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + if (fileData == 0) { TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load VOX file", fileName); @@ -5479,7 +5479,7 @@ static Model LoadVOX(const char *fileName) // Read and build voxarray description VoxArray3D voxarray = { 0 }; - int ret = Vox_LoadFromMemory(fileData, fileSize, &voxarray); + int ret = Vox_LoadFromMemory(fileData, dataSize, &voxarray); if (ret != VOX_SUCCESS) { @@ -5574,9 +5574,10 @@ static Model LoadM3D(const char *fileName) m3d_t *m3d = NULL; m3dp_t *prop = NULL; - unsigned int bytesRead = 0; - unsigned char *fileData = LoadFileData(fileName, &bytesRead); int i, j, k, l, n, mi = -2, vcolor = 0; + + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); if (fileData != NULL) { @@ -5878,16 +5879,17 @@ static Model LoadM3D(const char *fileName) #define M3D_ANIMDELAY 17 // Animation frames delay, (~1000 ms/60 FPS = 16.666666* ms) // Load M3D animation data -static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, unsigned int *animCount) +static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCount) { - m3d_t *m3d = NULL; - unsigned int bytesRead = 0; - unsigned char *fileData = LoadFileData(fileName, &bytesRead); ModelAnimation *animations = NULL; + + m3d_t *m3d = NULL; int i = 0, j = 0; - *animCount = 0; + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + if (fileData != NULL) { m3d = m3d_load(fileData, m3d_loaderhook, m3d_freehook, NULL); diff --git a/src/rtext.c b/src/rtext.c index 9017c8b26926..facf24c24122 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -363,13 +363,13 @@ Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepoi Font font = { 0 }; // Loading file to memory - unsigned int fileSize = 0; - unsigned char *fileData = LoadFileData(fileName, &fileSize); + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); if (fileData != NULL) { // Loading font from memory data - font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, codepoints, codepointCount); + font = LoadFontFromMemory(GetFileExtension(fileName), fileData, dataSize, fontSize, codepoints, codepointCount); UnloadFileData(fileData); } diff --git a/src/rtextures.c b/src/rtextures.c index a97cb0b378b7..566371112a46 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -271,11 +271,11 @@ Image LoadImage(const char *fileName) #endif // Loading file to memory - unsigned int fileSize = 0; - unsigned char *fileData = LoadFileData(fileName, &fileSize); + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); // Loading image from memory data - if (fileData != NULL) image = LoadImageFromMemory(GetFileExtension(fileName), fileData, fileSize); + if (fileData != NULL) image = LoadImageFromMemory(GetFileExtension(fileName), fileData, dataSize); RL_FREE(fileData); @@ -287,7 +287,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int { Image image = { 0 }; - unsigned int dataSize = 0; + int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); if (fileData != NULL) @@ -323,7 +323,7 @@ Image LoadImageAnim(const char *fileName, int *frames) #if defined(SUPPORT_FILEFORMAT_GIF) if (IsFileExtension(fileName, ".gif")) { - unsigned int dataSize = 0; + int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); if (fileData != NULL) diff --git a/src/utils.c b/src/utils.c index ac57a2157d31..27747b7571ce 100644 --- a/src/utils.c +++ b/src/utils.c @@ -180,16 +180,16 @@ void MemFree(void *ptr) } // Load data from file into a buffer -unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead) +unsigned char *LoadFileData(const char *fileName, int *dataSize) { unsigned char *data = NULL; - *bytesRead = 0; + *dataSize = 0; if (fileName != NULL) { if (loadFileData) { - data = loadFileData(fileName, bytesRead); + data = loadFileData(fileName, dataSize); return data; } #if defined(SUPPORT_STANDARD_FILEIO) @@ -211,7 +211,7 @@ unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead) { // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] unsigned int count = (unsigned int)fread(data, sizeof(unsigned char), size, file); - *bytesRead = count; + *dataSize = count; if (count != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded", fileName); else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName); @@ -239,7 +239,7 @@ void UnloadFileData(unsigned char *data) } // Save data to file from buffer -bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite) +bool SaveFileData(const char *fileName, void *data, int dataSize) { bool success = false; @@ -247,17 +247,17 @@ bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite) { if (saveFileData) { - return saveFileData(fileName, data, bytesToWrite); + return saveFileData(fileName, data, dataSize); } #if defined(SUPPORT_STANDARD_FILEIO) FILE *file = fopen(fileName, "wb"); if (file != NULL) { - unsigned int count = (unsigned int)fwrite(data, sizeof(unsigned char), bytesToWrite, file); + unsigned int count = (unsigned int)fwrite(data, sizeof(unsigned char), dataSize, file); if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName); - else if (count != bytesToWrite) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); + else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName); int result = fclose(file); @@ -274,7 +274,7 @@ bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite) } // Export data to code (.h), returns true on success -bool ExportDataAsCode(const unsigned char *data, unsigned int size, const char *fileName) +bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName) { bool success = false; @@ -284,7 +284,7 @@ bool ExportDataAsCode(const unsigned char *data, unsigned int size, const char * // NOTE: Text data buffer size is estimated considering raw data size in bytes // and requiring 6 char bytes for every byte: "0x00, " - char *txtData = (char *)RL_CALLOC(size*6 + 2000, sizeof(char)); + char *txtData = (char *)RL_CALLOC(dataSize*6 + 2000, sizeof(char)); int byteCount = 0; byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n"); @@ -303,11 +303,11 @@ bool ExportDataAsCode(const unsigned char *data, unsigned int size, const char * strcpy(varFileName, GetFileNameWithoutExt(fileName)); for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } - byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, size); + byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize); byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%s_DATA_SIZE] = { ", varFileName, varFileName); - for (unsigned int i = 0; i < size - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]); - byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[size - 1]); + for (int i = 0; i < (dataSize - 1); i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]); + byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]); // NOTE: Text data size exported is determined by '\0' (NULL) character success = SaveFileText(fileName, txtData); @@ -465,12 +465,12 @@ FILE *android_fopen(const char *fileName, const char *mode) // Module specific Functions Definition //---------------------------------------------------------------------------------- #if defined(PLATFORM_ANDROID) -static int android_read(void *cookie, char *buf, int size) +static int android_read(void *cookie, char *data, int dataSize) { - return AAsset_read((AAsset *)cookie, buf, size); + return AAsset_read((AAsset *)cookie, data, dataSize); } -static int android_write(void *cookie, const char *buf, int size) +static int android_write(void *cookie, const char *data, int dataSize) { TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK"); From b0986cbabb7590449e599f79a86575b3df852676 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 2 Sep 2023 12:54:36 +0200 Subject: [PATCH 45/89] Some tweaks --- src/raylib.h | 2 +- src/rcore.c | 2 +- src/rmodels.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 084fb4dc04ca..6f67d839e455 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1509,7 +1509,7 @@ RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); 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 diff --git a/src/rcore.c b/src/rcore.c index 2c53eb5e660d..912f85c0dad2 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -601,7 +601,7 @@ static const char *autoEventTypeName[] = { "ACTION_SETTARGETFPS" }; -// Automation Event (24 bytes) +// Automation event (24 bytes) typedef struct AutomationEvent { unsigned int frame; // Event frame unsigned int type; // Event type (AutomationEventType) diff --git a/src/rmodels.c b/src/rmodels.c index 66de97273d55..5a6d98ac67a7 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2099,9 +2099,9 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) } // Unload animation array data -void UnloadModelAnimations(ModelAnimation *animations, unsigned int count) +void UnloadModelAnimations(ModelAnimation *animations, int animCount) { - for (unsigned int i = 0; i < count; i++) UnloadModelAnimation(animations[i]); + for (int i = 0; i < animCount; i++) UnloadModelAnimation(animations[i]); RL_FREE(animations); } From d79ec5c431c6d0cc36a8164a6148063aa807f819 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 2 Sep 2023 12:58:47 +0200 Subject: [PATCH 46/89] Use internal default allocators, instead of user-exposed ones --- src/rmodels.c | 4 ++-- src/rtext.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index 5a6d98ac67a7..9616f0ceb380 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1904,7 +1904,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount) int result = tinyobj_parse_mtl_file(&mats, &count, fileName); if (result != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to parse materials file", fileName); - materials = MemAlloc(count*sizeof(Material)); + materials = RL_MALLOC(count*sizeof(Material)); ProcessMaterialsOBJ(materials, mats, count); tinyobj_materials_free(mats, count); @@ -4704,7 +4704,7 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat if (result == cgltf_result_success) { image = LoadImageFromMemory(".png", (unsigned char *)data, outSize); - MemFree(data); + RL_FREE(data); } } } diff --git a/src/rtext.c b/src/rtext.c index facf24c24122..5ca97d06d868 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -975,7 +975,7 @@ bool ExportFontAsCode(Font font, const char *fileName) byteCount += sprintf(txtData + byteCount, "static unsigned char fontData_%s[COMPRESSED_DATA_SIZE_FONT_%s] = { ", fileNamePascal, TextToUpper(fileNamePascal)); for (int i = 0; i < compDataSize - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%02x,\n " : "0x%02x, "), compData[i]); byteCount += sprintf(txtData + byteCount, "0x%02x };\n\n", compData[compDataSize - 1]); - MemFree(compData); + RL_FREE(compData); #else // Save font image data (uncompressed) byteCount += sprintf(txtData + byteCount, "// Font image pixels data\n"); From 6527f61d0222143787cf430e2b2c4d93c1d5d628 Mon Sep 17 00:00:00 2001 From: bXi Date: Sat, 2 Sep 2023 07:00:18 -0400 Subject: [PATCH 47/89] Added rudimentary SVG support. (#2738) * Added rudimentary SVG support. Added 2 functions ImageLoadSvg and ImageLoadSvgWithSize. * Added an example on how to use ImageLoadSvgWithSize and adjusted Makefiles accordingly. * Added actual correct example file. * Reviewed the code to keep the raylib coding conventions in mind. Moved the LoadImageSvg() code into LoadImage() guarded by SUPPORT_FILEFORMAT_SVG. Renamed LoadImageSvgWithSize() to LoadImageSvg(). Added a LoadImageSvgFromString() function to parse the loaded SVG into an actual image. This does the bulk of the work. * Fixed typo. --------- Co-authored-by: Ray --- examples/Makefile | 3 +- examples/Makefile.Web | 3 +- examples/textures/resources/test.svg | 1 + examples/textures/textures_svg_loading.c | 72 + examples/textures/textures_svg_loading.png | Bin 0 -> 13850 bytes src/config.h | 30 +- src/external/nanosvg.h | 3053 ++++++++++++++++++++ src/external/nanosvgrast.h | 1458 ++++++++++ src/raylib.h | 2 + src/rtextures.c | 95 + 10 files changed, 4700 insertions(+), 17 deletions(-) create mode 100644 examples/textures/resources/test.svg create mode 100644 examples/textures/textures_svg_loading.c create mode 100644 examples/textures/textures_svg_loading.png create mode 100644 src/external/nanosvg.h create mode 100644 src/external/nanosvgrast.h diff --git a/examples/Makefile b/examples/Makefile index 7028a95424f6..4ba4f1720edb 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -475,7 +475,8 @@ TEXTURES = \ textures/textures_draw_tiled \ textures/textures_polygon \ textures/textures_gif_player \ - textures/textures_fog_of_war + textures/textures_fog_of_war \ + textures/textures_svg_loading TEXT = \ text/text_raylib_fonts \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 4574e928ec62..ccb4550f9970 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -450,7 +450,8 @@ TEXTURES = \ textures/textures_draw_tiled \ textures/textures_polygon \ textures/textures_gif_player \ - textures/textures_fog_of_war + textures/textures_fog_of_war \ + textures/textures_svg_loading TEXT = \ text/text_raylib_fonts \ diff --git a/examples/textures/resources/test.svg b/examples/textures/resources/test.svg new file mode 100644 index 000000000000..3d9bbb1133e2 --- /dev/null +++ b/examples/textures/resources/test.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/textures/textures_svg_loading.c b/examples/textures/textures_svg_loading.c new file mode 100644 index 000000000000..434ec7602faf --- /dev/null +++ b/examples/textures/textures_svg_loading.c @@ -0,0 +1,72 @@ +/******************************************************************************************* +* +* raylib [textures] example - SVG loading and texture creation +* +* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) +* +* Example originally created with raylib 4.2, last time updated with raylib 4.2 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2022 Dennis Meinen (@bixxy#4258 on Discord) +* +********************************************************************************************/ + +#include "raylib.h" + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - svg loading"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + + Image image = LoadImageSvg("resources/test.svg", 400, 350); // Loaded in CPU memory (RAM) + Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM) + UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM + + 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 + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE); + + //Red border to illustrate how the SVG is centered within the specified dimensions + DrawRectangleLines((screenWidth / 2 - texture.width / 2) - 1, (screenHeight / 2 - texture.height / 2) - 1, texture.width + 2, texture.height + 2, RED); + + DrawText("this IS a texture loaded from an SVG file!", 300, 410, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(texture); // Texture unloading + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/textures/textures_svg_loading.png b/examples/textures/textures_svg_loading.png new file mode 100644 index 0000000000000000000000000000000000000000..fa98605fa8508a068537defae8a8fc960a6a6c08 GIT binary patch literal 13850 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, image->height); + // Use... + for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { + for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { + for (int i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); + } + } + } + // Delete + nsvgDelete(image); +*/ + +enum NSVGpaintType { + NSVG_PAINT_NONE = 0, + NSVG_PAINT_COLOR = 1, + NSVG_PAINT_LINEAR_GRADIENT = 2, + NSVG_PAINT_RADIAL_GRADIENT = 3 +}; + +enum NSVGspreadType { + NSVG_SPREAD_PAD = 0, + NSVG_SPREAD_REFLECT = 1, + NSVG_SPREAD_REPEAT = 2 +}; + +enum NSVGlineJoin { + NSVG_JOIN_MITER = 0, + NSVG_JOIN_ROUND = 1, + NSVG_JOIN_BEVEL = 2 +}; + +enum NSVGlineCap { + NSVG_CAP_BUTT = 0, + NSVG_CAP_ROUND = 1, + NSVG_CAP_SQUARE = 2 +}; + +enum NSVGfillRule { + NSVG_FILLRULE_NONZERO = 0, + NSVG_FILLRULE_EVENODD = 1 +}; + +enum NSVGflags { + NSVG_FLAGS_VISIBLE = 0x01 +}; + +typedef struct NSVGgradientStop { + unsigned int color; + float offset; +} NSVGgradientStop; + +typedef struct NSVGgradient { + float xform[6]; + char spread; + float fx, fy; + int nstops; + NSVGgradientStop stops[1]; +} NSVGgradient; + +typedef struct NSVGpaint { + char type; + union { + unsigned int color; + NSVGgradient* gradient; + }; +} NSVGpaint; + +typedef struct NSVGpath +{ + float* pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... + int npts; // Total number of bezier points. + char closed; // Flag indicating if shapes should be treated as closed. + float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. + struct NSVGpath* next; // Pointer to next path, or NULL if last element. +} NSVGpath; + +typedef struct NSVGshape +{ + char id[64]; // Optional 'id' attr of the shape or its group + NSVGpaint fill; // Fill paint + NSVGpaint stroke; // Stroke paint + float opacity; // Opacity of the shape. + float strokeWidth; // Stroke width (scaled). + float strokeDashOffset; // Stroke dash offset (scaled). + float strokeDashArray[8]; // Stroke dash array (scaled). + char strokeDashCount; // Number of dash values in dash array. + char strokeLineJoin; // Stroke join type. + char strokeLineCap; // Stroke cap type. + float miterLimit; // Miter limit + char fillRule; // Fill rule, see NSVGfillRule. + unsigned char flags; // Logical or of NSVG_FLAGS_* flags + float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. + NSVGpath* paths; // Linked list of paths in the image. + struct NSVGshape* next; // Pointer to next shape, or NULL if last element. +} NSVGshape; + +typedef struct NSVGimage +{ + float width; // Width of the image. + float height; // Height of the image. + NSVGshape* shapes; // Linked list of shapes in the image. +} NSVGimage; + +// Parses SVG file from a file, returns SVG image as paths. +NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); + +// Parses SVG file from a null terminated string, returns SVG image as paths. +// Important note: changes the string. +NSVGimage* nsvgParse(char* input, const char* units, float dpi); + +// Duplicates a path. +NSVGpath* nsvgDuplicatePath(NSVGpath* p); + +// Deletes an image. +void nsvgDelete(NSVGimage* image); + +#ifndef NANOSVG_CPLUSPLUS +#ifdef __cplusplus +} +#endif +#endif + +#ifdef NANOSVG_IMPLEMENTATION + +#include +#include +#include +#include + +#define NSVG_PI (3.14159265358979323846264338327f) +#define NSVG_KAPPA90 (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs. + +#define NSVG_ALIGN_MIN 0 +#define NSVG_ALIGN_MID 1 +#define NSVG_ALIGN_MAX 2 +#define NSVG_ALIGN_NONE 0 +#define NSVG_ALIGN_MEET 1 +#define NSVG_ALIGN_SLICE 2 + +#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0) +#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16)) + +#ifdef _MSC_VER + #pragma warning (disable: 4996) // Switch off security warnings + #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings + #ifdef __cplusplus + #define NSVG_INLINE inline + #else + #define NSVG_INLINE + #endif +#else + #define NSVG_INLINE inline +#endif + + +static int nsvg__isspace(char c) +{ + return strchr(" \t\n\v\f\r", c) != 0; +} + +static int nsvg__isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; } +static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; } + + +// Simple XML parser + +#define NSVG_XML_TAG 1 +#define NSVG_XML_CONTENT 2 +#define NSVG_XML_MAX_ATTRIBS 256 + +static void nsvg__parseContent(char* s, + void (*contentCb)(void* ud, const char* s), + void* ud) +{ + // Trim start white spaces + while (*s && nsvg__isspace(*s)) s++; + if (!*s) return; + + if (contentCb) + (*contentCb)(ud, s); +} + +static void nsvg__parseElement(char* s, + void (*startelCb)(void* ud, const char* el, const char** attr), + void (*endelCb)(void* ud, const char* el), + void* ud) +{ + const char* attr[NSVG_XML_MAX_ATTRIBS]; + int nattr = 0; + char* name; + int start = 0; + int end = 0; + char quote; + + // Skip white space after the '<' + while (*s && nsvg__isspace(*s)) s++; + + // Check if the tag is end tag + if (*s == '/') { + s++; + end = 1; + } else { + start = 1; + } + + // Skip comments, data and preprocessor stuff. + if (!*s || *s == '?' || *s == '!') + return; + + // Get tag name + name = s; + while (*s && !nsvg__isspace(*s)) s++; + if (*s) { *s++ = '\0'; } + + // Get attribs + while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) { + char* name = NULL; + char* value = NULL; + + // Skip white space before the attrib name + while (*s && nsvg__isspace(*s)) s++; + if (!*s) break; + if (*s == '/') { + end = 1; + break; + } + name = s; + // Find end of the attrib name. + while (*s && !nsvg__isspace(*s) && *s != '=') s++; + if (*s) { *s++ = '\0'; } + // Skip until the beginning of the value. + while (*s && *s != '\"' && *s != '\'') s++; + if (!*s) break; + quote = *s; + s++; + // Store value and find the end of it. + value = s; + while (*s && *s != quote) s++; + if (*s) { *s++ = '\0'; } + + // Store only well formed attributes + if (name && value) { + attr[nattr++] = name; + attr[nattr++] = value; + } + } + + // List terminator + attr[nattr++] = 0; + attr[nattr++] = 0; + + // Call callbacks. + if (start && startelCb) + (*startelCb)(ud, name, attr); + if (end && endelCb) + (*endelCb)(ud, name); +} + +int nsvg__parseXML(char* input, + void (*startelCb)(void* ud, const char* el, const char** attr), + void (*endelCb)(void* ud, const char* el), + void (*contentCb)(void* ud, const char* s), + void* ud) +{ + char* s = input; + char* mark = s; + int state = NSVG_XML_CONTENT; + while (*s) { + if (*s == '<' && state == NSVG_XML_CONTENT) { + // Start of a tag + *s++ = '\0'; + nsvg__parseContent(mark, contentCb, ud); + mark = s; + state = NSVG_XML_TAG; + } else if (*s == '>' && state == NSVG_XML_TAG) { + // Start of a content or new tag. + *s++ = '\0'; + nsvg__parseElement(mark, startelCb, endelCb, ud); + mark = s; + state = NSVG_XML_CONTENT; + } else { + s++; + } + } + + return 1; +} + + +/* Simple SVG parser. */ + +#define NSVG_MAX_ATTR 128 + +enum NSVGgradientUnits { + NSVG_USER_SPACE = 0, + NSVG_OBJECT_SPACE = 1 +}; + +#define NSVG_MAX_DASHES 8 + +enum NSVGunits { + NSVG_UNITS_USER, + NSVG_UNITS_PX, + NSVG_UNITS_PT, + NSVG_UNITS_PC, + NSVG_UNITS_MM, + NSVG_UNITS_CM, + NSVG_UNITS_IN, + NSVG_UNITS_PERCENT, + NSVG_UNITS_EM, + NSVG_UNITS_EX +}; + +typedef struct NSVGcoordinate { + float value; + int units; +} NSVGcoordinate; + +typedef struct NSVGlinearData { + NSVGcoordinate x1, y1, x2, y2; +} NSVGlinearData; + +typedef struct NSVGradialData { + NSVGcoordinate cx, cy, r, fx, fy; +} NSVGradialData; + +typedef struct NSVGgradientData +{ + char id[64]; + char ref[64]; + char type; + union { + NSVGlinearData linear; + NSVGradialData radial; + }; + char spread; + char units; + float xform[6]; + int nstops; + NSVGgradientStop* stops; + struct NSVGgradientData* next; +} NSVGgradientData; + +typedef struct NSVGattrib +{ + char id[64]; + float xform[6]; + unsigned int fillColor; + unsigned int strokeColor; + float opacity; + float fillOpacity; + float strokeOpacity; + char fillGradient[64]; + char strokeGradient[64]; + float strokeWidth; + float strokeDashOffset; + float strokeDashArray[NSVG_MAX_DASHES]; + int strokeDashCount; + char strokeLineJoin; + char strokeLineCap; + float miterLimit; + char fillRule; + float fontSize; + unsigned int stopColor; + float stopOpacity; + float stopOffset; + char hasFill; + char hasStroke; + char visible; +} NSVGattrib; + +typedef struct NSVGparser +{ + NSVGattrib attr[NSVG_MAX_ATTR]; + int attrHead; + float* pts; + int npts; + int cpts; + NSVGpath* plist; + NSVGimage* image; + NSVGgradientData* gradients; + NSVGshape* shapesTail; + float viewMinx, viewMiny, viewWidth, viewHeight; + int alignX, alignY, alignType; + float dpi; + char pathFlag; + char defsFlag; +} NSVGparser; + +static void nsvg__xformIdentity(float* t) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetTranslation(float* t, float tx, float ty) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = tx; t[5] = ty; +} + +static void nsvg__xformSetScale(float* t, float sx, float sy) +{ + t[0] = sx; t[1] = 0.0f; + t[2] = 0.0f; t[3] = sy; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetSkewX(float* t, float a) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = tanf(a); t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetSkewY(float* t, float a) +{ + t[0] = 1.0f; t[1] = tanf(a); + t[2] = 0.0f; t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetRotation(float* t, float a) +{ + float cs = cosf(a), sn = sinf(a); + t[0] = cs; t[1] = sn; + t[2] = -sn; t[3] = cs; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformMultiply(float* t, float* s) +{ + float t0 = t[0] * s[0] + t[1] * s[2]; + float t2 = t[2] * s[0] + t[3] * s[2]; + float t4 = t[4] * s[0] + t[5] * s[2] + s[4]; + t[1] = t[0] * s[1] + t[1] * s[3]; + t[3] = t[2] * s[1] + t[3] * s[3]; + t[5] = t[4] * s[1] + t[5] * s[3] + s[5]; + t[0] = t0; + t[2] = t2; + t[4] = t4; +} + +static void nsvg__xformInverse(float* inv, float* t) +{ + double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; + if (det > -1e-6 && det < 1e-6) { + nsvg__xformIdentity(t); + return; + } + invdet = 1.0 / det; + inv[0] = (float)(t[3] * invdet); + inv[2] = (float)(-t[2] * invdet); + inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); + inv[1] = (float)(-t[1] * invdet); + inv[3] = (float)(t[0] * invdet); + inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet); +} + +static void nsvg__xformPremultiply(float* t, float* s) +{ + float s2[6]; + memcpy(s2, s, sizeof(float)*6); + nsvg__xformMultiply(s2, t); + memcpy(t, s2, sizeof(float)*6); +} + +static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t) +{ + *dx = x*t[0] + y*t[2] + t[4]; + *dy = x*t[1] + y*t[3] + t[5]; +} + +static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t) +{ + *dx = x*t[0] + y*t[2]; + *dy = x*t[1] + y*t[3]; +} + +#define NSVG_EPSILON (1e-12) + +static int nsvg__ptInBounds(float* pt, float* bounds) +{ + return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3]; +} + + +static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) +{ + double it = 1.0-t; + return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3; +} + +static void nsvg__curveBounds(float* bounds, float* curve) +{ + int i, j, count; + double roots[2], a, b, c, b2ac, t, v; + float* v0 = &curve[0]; + float* v1 = &curve[2]; + float* v2 = &curve[4]; + float* v3 = &curve[6]; + + // Start the bounding box by end points + bounds[0] = nsvg__minf(v0[0], v3[0]); + bounds[1] = nsvg__minf(v0[1], v3[1]); + bounds[2] = nsvg__maxf(v0[0], v3[0]); + bounds[3] = nsvg__maxf(v0[1], v3[1]); + + // Bezier curve fits inside the convex hull of it's control points. + // If control points are inside the bounds, we're done. + if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds)) + return; + + // Add bezier curve inflection points in X and Y. + for (i = 0; i < 2; i++) { + a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i]; + b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i]; + c = 3.0 * v1[i] - 3.0 * v0[i]; + count = 0; + if (fabs(a) < NSVG_EPSILON) { + if (fabs(b) > NSVG_EPSILON) { + t = -c / b; + if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) + roots[count++] = t; + } + } else { + b2ac = b*b - 4.0*c*a; + if (b2ac > NSVG_EPSILON) { + t = (-b + sqrt(b2ac)) / (2.0 * a); + if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) + roots[count++] = t; + t = (-b - sqrt(b2ac)) / (2.0 * a); + if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) + roots[count++] = t; + } + } + for (j = 0; j < count; j++) { + v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]); + bounds[0+i] = nsvg__minf(bounds[0+i], (float)v); + bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v); + } + } +} + +static NSVGparser* nsvg__createParser(void) +{ + NSVGparser* p; + p = (NSVGparser*)malloc(sizeof(NSVGparser)); + if (p == NULL) goto error; + memset(p, 0, sizeof(NSVGparser)); + + p->image = (NSVGimage*)malloc(sizeof(NSVGimage)); + if (p->image == NULL) goto error; + memset(p->image, 0, sizeof(NSVGimage)); + + // Init style + nsvg__xformIdentity(p->attr[0].xform); + memset(p->attr[0].id, 0, sizeof p->attr[0].id); + p->attr[0].fillColor = NSVG_RGB(0,0,0); + p->attr[0].strokeColor = NSVG_RGB(0,0,0); + p->attr[0].opacity = 1; + p->attr[0].fillOpacity = 1; + p->attr[0].strokeOpacity = 1; + p->attr[0].stopOpacity = 1; + p->attr[0].strokeWidth = 1; + p->attr[0].strokeLineJoin = NSVG_JOIN_MITER; + p->attr[0].strokeLineCap = NSVG_CAP_BUTT; + p->attr[0].miterLimit = 4; + p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; + p->attr[0].hasFill = 1; + p->attr[0].visible = 1; + + return p; + +error: + if (p) { + if (p->image) free(p->image); + free(p); + } + return NULL; +} + +static void nsvg__deletePaths(NSVGpath* path) +{ + while (path) { + NSVGpath *next = path->next; + if (path->pts != NULL) + free(path->pts); + free(path); + path = next; + } +} + +static void nsvg__deletePaint(NSVGpaint* paint) +{ + if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT) + free(paint->gradient); +} + +static void nsvg__deleteGradientData(NSVGgradientData* grad) +{ + NSVGgradientData* next; + while (grad != NULL) { + next = grad->next; + free(grad->stops); + free(grad); + grad = next; + } +} + +static void nsvg__deleteParser(NSVGparser* p) +{ + if (p != NULL) { + nsvg__deletePaths(p->plist); + nsvg__deleteGradientData(p->gradients); + nsvgDelete(p->image); + free(p->pts); + free(p); + } +} + +static void nsvg__resetPath(NSVGparser* p) +{ + p->npts = 0; +} + +static void nsvg__addPoint(NSVGparser* p, float x, float y) +{ + if (p->npts+1 > p->cpts) { + p->cpts = p->cpts ? p->cpts*2 : 8; + p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float)); + if (!p->pts) return; + } + p->pts[p->npts*2+0] = x; + p->pts[p->npts*2+1] = y; + p->npts++; +} + +static void nsvg__moveTo(NSVGparser* p, float x, float y) +{ + if (p->npts > 0) { + p->pts[(p->npts-1)*2+0] = x; + p->pts[(p->npts-1)*2+1] = y; + } else { + nsvg__addPoint(p, x, y); + } +} + +static void nsvg__lineTo(NSVGparser* p, float x, float y) +{ + float px,py, dx,dy; + if (p->npts > 0) { + px = p->pts[(p->npts-1)*2+0]; + py = p->pts[(p->npts-1)*2+1]; + dx = x - px; + dy = y - py; + nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f); + nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f); + nsvg__addPoint(p, x, y); + } +} + +static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) +{ + if (p->npts > 0) { + nsvg__addPoint(p, cpx1, cpy1); + nsvg__addPoint(p, cpx2, cpy2); + nsvg__addPoint(p, x, y); + } +} + +static NSVGattrib* nsvg__getAttr(NSVGparser* p) +{ + return &p->attr[p->attrHead]; +} + +static void nsvg__pushAttr(NSVGparser* p) +{ + if (p->attrHead < NSVG_MAX_ATTR-1) { + p->attrHead++; + memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib)); + } +} + +static void nsvg__popAttr(NSVGparser* p) +{ + if (p->attrHead > 0) + p->attrHead--; +} + +static float nsvg__actualOrigX(NSVGparser* p) +{ + return p->viewMinx; +} + +static float nsvg__actualOrigY(NSVGparser* p) +{ + return p->viewMiny; +} + +static float nsvg__actualWidth(NSVGparser* p) +{ + return p->viewWidth; +} + +static float nsvg__actualHeight(NSVGparser* p) +{ + return p->viewHeight; +} + +static float nsvg__actualLength(NSVGparser* p) +{ + float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); + return sqrtf(w*w + h*h) / sqrtf(2.0f); +} + +static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length) +{ + NSVGattrib* attr = nsvg__getAttr(p); + switch (c.units) { + case NSVG_UNITS_USER: return c.value; + case NSVG_UNITS_PX: return c.value; + case NSVG_UNITS_PT: return c.value / 72.0f * p->dpi; + case NSVG_UNITS_PC: return c.value / 6.0f * p->dpi; + case NSVG_UNITS_MM: return c.value / 25.4f * p->dpi; + case NSVG_UNITS_CM: return c.value / 2.54f * p->dpi; + case NSVG_UNITS_IN: return c.value * p->dpi; + case NSVG_UNITS_EM: return c.value * attr->fontSize; + case NSVG_UNITS_EX: return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. + case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; + default: return c.value; + } + return c.value; +} + +static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) +{ + NSVGgradientData* grad = p->gradients; + if (id == NULL || *id == '\0') + return NULL; + while (grad != NULL) { + if (strcmp(grad->id, id) == 0) + return grad; + grad = grad->next; + } + return NULL; +} + +static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType) +{ + NSVGattrib* attr = nsvg__getAttr(p); + NSVGgradientData* data = NULL; + NSVGgradientData* ref = NULL; + NSVGgradientStop* stops = NULL; + NSVGgradient* grad; + float ox, oy, sw, sh, sl; + int nstops = 0; + int refIter; + + data = nsvg__findGradientData(p, id); + if (data == NULL) return NULL; + + // TODO: use ref to fill in all unset values too. + ref = data; + refIter = 0; + while (ref != NULL) { + NSVGgradientData* nextRef = NULL; + if (stops == NULL && ref->stops != NULL) { + stops = ref->stops; + nstops = ref->nstops; + break; + } + nextRef = nsvg__findGradientData(p, ref->ref); + if (nextRef == ref) break; // prevent infite loops on malformed data + ref = nextRef; + refIter++; + if (refIter > 32) break; // prevent infite loops on malformed data + } + if (stops == NULL) return NULL; + + grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1)); + if (grad == NULL) return NULL; + + // The shape width and height. + if (data->units == NSVG_OBJECT_SPACE) { + ox = localBounds[0]; + oy = localBounds[1]; + sw = localBounds[2] - localBounds[0]; + sh = localBounds[3] - localBounds[1]; + } else { + ox = nsvg__actualOrigX(p); + oy = nsvg__actualOrigY(p); + sw = nsvg__actualWidth(p); + sh = nsvg__actualHeight(p); + } + sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f); + + if (data->type == NSVG_PAINT_LINEAR_GRADIENT) { + float x1, y1, x2, y2, dx, dy; + x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw); + y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh); + x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw); + y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh); + // Calculate transform aligned to the line + dx = x2 - x1; + dy = y2 - y1; + grad->xform[0] = dy; grad->xform[1] = -dx; + grad->xform[2] = dx; grad->xform[3] = dy; + grad->xform[4] = x1; grad->xform[5] = y1; + } else { + float cx, cy, fx, fy, r; + cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw); + cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh); + fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw); + fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh); + r = nsvg__convertToPixels(p, data->radial.r, 0, sl); + // Calculate transform aligned to the circle + grad->xform[0] = r; grad->xform[1] = 0; + grad->xform[2] = 0; grad->xform[3] = r; + grad->xform[4] = cx; grad->xform[5] = cy; + grad->fx = fx / r; + grad->fy = fy / r; + } + + nsvg__xformMultiply(grad->xform, data->xform); + nsvg__xformMultiply(grad->xform, attr->xform); + + grad->spread = data->spread; + memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop)); + grad->nstops = nstops; + + *paintType = data->type; + + return grad; +} + +static float nsvg__getAverageScale(float* t) +{ + float sx = sqrtf(t[0]*t[0] + t[2]*t[2]); + float sy = sqrtf(t[1]*t[1] + t[3]*t[3]); + return (sx + sy) * 0.5f; +} + +static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform) +{ + NSVGpath* path; + float curve[4*2], curveBounds[4]; + int i, first = 1; + for (path = shape->paths; path != NULL; path = path->next) { + nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform); + for (i = 0; i < path->npts-1; i += 3) { + nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform); + nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform); + nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform); + nsvg__curveBounds(curveBounds, curve); + if (first) { + bounds[0] = curveBounds[0]; + bounds[1] = curveBounds[1]; + bounds[2] = curveBounds[2]; + bounds[3] = curveBounds[3]; + first = 0; + } else { + bounds[0] = nsvg__minf(bounds[0], curveBounds[0]); + bounds[1] = nsvg__minf(bounds[1], curveBounds[1]); + bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]); + bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]); + } + curve[0] = curve[6]; + curve[1] = curve[7]; + } + } +} + +static void nsvg__addShape(NSVGparser* p) +{ + NSVGattrib* attr = nsvg__getAttr(p); + float scale = 1.0f; + NSVGshape* shape; + NSVGpath* path; + int i; + + if (p->plist == NULL) + return; + + shape = (NSVGshape*)malloc(sizeof(NSVGshape)); + if (shape == NULL) goto error; + memset(shape, 0, sizeof(NSVGshape)); + + memcpy(shape->id, attr->id, sizeof shape->id); + scale = nsvg__getAverageScale(attr->xform); + shape->strokeWidth = attr->strokeWidth * scale; + shape->strokeDashOffset = attr->strokeDashOffset * scale; + shape->strokeDashCount = (char)attr->strokeDashCount; + for (i = 0; i < attr->strokeDashCount; i++) + shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale; + shape->strokeLineJoin = attr->strokeLineJoin; + shape->strokeLineCap = attr->strokeLineCap; + shape->miterLimit = attr->miterLimit; + shape->fillRule = attr->fillRule; + shape->opacity = attr->opacity; + + shape->paths = p->plist; + p->plist = NULL; + + // Calculate shape bounds + shape->bounds[0] = shape->paths->bounds[0]; + shape->bounds[1] = shape->paths->bounds[1]; + shape->bounds[2] = shape->paths->bounds[2]; + shape->bounds[3] = shape->paths->bounds[3]; + for (path = shape->paths->next; path != NULL; path = path->next) { + shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]); + shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]); + shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]); + shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]); + } + + // Set fill + if (attr->hasFill == 0) { + shape->fill.type = NSVG_PAINT_NONE; + } else if (attr->hasFill == 1) { + shape->fill.type = NSVG_PAINT_COLOR; + shape->fill.color = attr->fillColor; + shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24; + } else if (attr->hasFill == 2) { + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type); + if (shape->fill.gradient == NULL) { + shape->fill.type = NSVG_PAINT_NONE; + } + } + + // Set stroke + if (attr->hasStroke == 0) { + shape->stroke.type = NSVG_PAINT_NONE; + } else if (attr->hasStroke == 1) { + shape->stroke.type = NSVG_PAINT_COLOR; + shape->stroke.color = attr->strokeColor; + shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24; + } else if (attr->hasStroke == 2) { + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type); + if (shape->stroke.gradient == NULL) + shape->stroke.type = NSVG_PAINT_NONE; + } + + // Set flags + shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); + + // Add to tail + if (p->image->shapes == NULL) + p->image->shapes = shape; + else + p->shapesTail->next = shape; + p->shapesTail = shape; + + return; + +error: + if (shape) free(shape); +} + +static void nsvg__addPath(NSVGparser* p, char closed) +{ + NSVGattrib* attr = nsvg__getAttr(p); + NSVGpath* path = NULL; + float bounds[4]; + float* curve; + int i; + + if (p->npts < 4) + return; + + if (closed) + nsvg__lineTo(p, p->pts[0], p->pts[1]); + + // Expect 1 + N*3 points (N = number of cubic bezier segments). + if ((p->npts % 3) != 1) + return; + + path = (NSVGpath*)malloc(sizeof(NSVGpath)); + if (path == NULL) goto error; + memset(path, 0, sizeof(NSVGpath)); + + path->pts = (float*)malloc(p->npts*2*sizeof(float)); + if (path->pts == NULL) goto error; + path->closed = closed; + path->npts = p->npts; + + // Transform path. + for (i = 0; i < p->npts; ++i) + nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform); + + // Find bounds + for (i = 0; i < path->npts-1; i += 3) { + curve = &path->pts[i*2]; + nsvg__curveBounds(bounds, curve); + if (i == 0) { + path->bounds[0] = bounds[0]; + path->bounds[1] = bounds[1]; + path->bounds[2] = bounds[2]; + path->bounds[3] = bounds[3]; + } else { + path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]); + path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]); + path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]); + path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]); + } + } + + path->next = p->plist; + p->plist = path; + + return; + +error: + if (path != NULL) { + if (path->pts != NULL) free(path->pts); + free(path); + } +} + +// We roll our own string to float because the std library one uses locale and messes things up. +static double nsvg__atof(const char* s) +{ + char* cur = (char*)s; + char* end = NULL; + double res = 0.0, sign = 1.0; + long long intPart = 0, fracPart = 0; + char hasIntPart = 0, hasFracPart = 0; + + // Parse optional sign + if (*cur == '+') { + cur++; + } else if (*cur == '-') { + sign = -1; + cur++; + } + + // Parse integer part + if (nsvg__isdigit(*cur)) { + // Parse digit sequence + intPart = strtoll(cur, &end, 10); + if (cur != end) { + res = (double)intPart; + hasIntPart = 1; + cur = end; + } + } + + // Parse fractional part. + if (*cur == '.') { + cur++; // Skip '.' + if (nsvg__isdigit(*cur)) { + // Parse digit sequence + fracPart = strtoll(cur, &end, 10); + if (cur != end) { + res += (double)fracPart / pow(10.0, (double)(end - cur)); + hasFracPart = 1; + cur = end; + } + } + } + + // A valid number should have integer or fractional part. + if (!hasIntPart && !hasFracPart) + return 0.0; + + // Parse optional exponent + if (*cur == 'e' || *cur == 'E') { + long expPart = 0; + cur++; // skip 'E' + expPart = strtol(cur, &end, 10); // Parse digit sequence with sign + if (cur != end) { + res *= pow(10.0, (double)expPart); + } + } + + return res * sign; +} + + +static const char* nsvg__parseNumber(const char* s, char* it, const int size) +{ + const int last = size-1; + int i = 0; + + // sign + if (*s == '-' || *s == '+') { + if (i < last) it[i++] = *s; + s++; + } + // integer part + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + if (*s == '.') { + // decimal point + if (i < last) it[i++] = *s; + s++; + // fraction part + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + } + // exponent + if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) { + if (i < last) it[i++] = *s; + s++; + if (*s == '-' || *s == '+') { + if (i < last) it[i++] = *s; + s++; + } + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + } + it[i] = '\0'; + + return s; +} + +static const char* nsvg__getNextPathItem(const char* s, char* it) +{ + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) s++; + if (!*s) return s; + if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { + s = nsvg__parseNumber(s, it, 64); + } else { + // Parse command + it[0] = *s++; + it[1] = '\0'; + return s; + } + + return s; +} + +static unsigned int nsvg__parseColorHex(const char* str) +{ + unsigned int r=0, g=0, b=0; + if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 ) // 2 digit hex + return NSVG_RGB(r, g, b); + if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 ) // 1 digit hex, e.g. #abc -> 0xccbbaa + return NSVG_RGB(r*17, g*17, b*17); // same effect as (r<<4|r), (g<<4|g), .. + return NSVG_RGB(128, 128, 128); +} + +// Parse rgb color. The pointer 'str' must point at "rgb(" (4+ characters). +// This function returns gray (rgb(128, 128, 128) == '#808080') on parse errors +// for backwards compatibility. Note: other image viewers return black instead. + +static unsigned int nsvg__parseColorRGB(const char* str) +{ + int i; + unsigned int rgbi[3]; + float rgbf[3]; + // try decimal integers first + if (sscanf(str, "rgb(%u, %u, %u)", &rgbi[0], &rgbi[1], &rgbi[2]) != 3) { + // integers failed, try percent values (float, locale independent) + const char delimiter[3] = {',', ',', ')'}; + str += 4; // skip "rgb(" + for (i = 0; i < 3; i++) { + while (*str && (nsvg__isspace(*str))) str++; // skip leading spaces + if (*str == '+') str++; // skip '+' (don't allow '-') + if (!*str) break; + rgbf[i] = nsvg__atof(str); + + // Note 1: it would be great if nsvg__atof() returned how many + // bytes it consumed but it doesn't. We need to skip the number, + // the '%' character, spaces, and the delimiter ',' or ')'. + + // Note 2: The following code does not allow values like "33.%", + // i.e. a decimal point w/o fractional part, but this is consistent + // with other image viewers, e.g. firefox, chrome, eog, gimp. + + while (*str && nsvg__isdigit(*str)) str++; // skip integer part + if (*str == '.') { + str++; + if (!nsvg__isdigit(*str)) break; // error: no digit after '.' + while (*str && nsvg__isdigit(*str)) str++; // skip fractional part + } + if (*str == '%') str++; else break; + while (nsvg__isspace(*str)) str++; + if (*str == delimiter[i]) str++; + else break; + } + if (i == 3) { + rgbi[0] = roundf(rgbf[0] * 2.55f); + rgbi[1] = roundf(rgbf[1] * 2.55f); + rgbi[2] = roundf(rgbf[2] * 2.55f); + } else { + rgbi[0] = rgbi[1] = rgbi[2] = 128; + } + } + // clip values as the CSS spec requires + for (i = 0; i < 3; i++) { + if (rgbi[i] > 255) rgbi[i] = 255; + } + return NSVG_RGB(rgbi[0], rgbi[1], rgbi[2]); +} + +typedef struct NSVGNamedColor { + const char* name; + unsigned int color; +} NSVGNamedColor; + +NSVGNamedColor nsvg__colors[] = { + + { "red", NSVG_RGB(255, 0, 0) }, + { "green", NSVG_RGB( 0, 128, 0) }, + { "blue", NSVG_RGB( 0, 0, 255) }, + { "yellow", NSVG_RGB(255, 255, 0) }, + { "cyan", NSVG_RGB( 0, 255, 255) }, + { "magenta", NSVG_RGB(255, 0, 255) }, + { "black", NSVG_RGB( 0, 0, 0) }, + { "grey", NSVG_RGB(128, 128, 128) }, + { "gray", NSVG_RGB(128, 128, 128) }, + { "white", NSVG_RGB(255, 255, 255) }, + +#ifdef NANOSVG_ALL_COLOR_KEYWORDS + { "aliceblue", NSVG_RGB(240, 248, 255) }, + { "antiquewhite", NSVG_RGB(250, 235, 215) }, + { "aqua", NSVG_RGB( 0, 255, 255) }, + { "aquamarine", NSVG_RGB(127, 255, 212) }, + { "azure", NSVG_RGB(240, 255, 255) }, + { "beige", NSVG_RGB(245, 245, 220) }, + { "bisque", NSVG_RGB(255, 228, 196) }, + { "blanchedalmond", NSVG_RGB(255, 235, 205) }, + { "blueviolet", NSVG_RGB(138, 43, 226) }, + { "brown", NSVG_RGB(165, 42, 42) }, + { "burlywood", NSVG_RGB(222, 184, 135) }, + { "cadetblue", NSVG_RGB( 95, 158, 160) }, + { "chartreuse", NSVG_RGB(127, 255, 0) }, + { "chocolate", NSVG_RGB(210, 105, 30) }, + { "coral", NSVG_RGB(255, 127, 80) }, + { "cornflowerblue", NSVG_RGB(100, 149, 237) }, + { "cornsilk", NSVG_RGB(255, 248, 220) }, + { "crimson", NSVG_RGB(220, 20, 60) }, + { "darkblue", NSVG_RGB( 0, 0, 139) }, + { "darkcyan", NSVG_RGB( 0, 139, 139) }, + { "darkgoldenrod", NSVG_RGB(184, 134, 11) }, + { "darkgray", NSVG_RGB(169, 169, 169) }, + { "darkgreen", NSVG_RGB( 0, 100, 0) }, + { "darkgrey", NSVG_RGB(169, 169, 169) }, + { "darkkhaki", NSVG_RGB(189, 183, 107) }, + { "darkmagenta", NSVG_RGB(139, 0, 139) }, + { "darkolivegreen", NSVG_RGB( 85, 107, 47) }, + { "darkorange", NSVG_RGB(255, 140, 0) }, + { "darkorchid", NSVG_RGB(153, 50, 204) }, + { "darkred", NSVG_RGB(139, 0, 0) }, + { "darksalmon", NSVG_RGB(233, 150, 122) }, + { "darkseagreen", NSVG_RGB(143, 188, 143) }, + { "darkslateblue", NSVG_RGB( 72, 61, 139) }, + { "darkslategray", NSVG_RGB( 47, 79, 79) }, + { "darkslategrey", NSVG_RGB( 47, 79, 79) }, + { "darkturquoise", NSVG_RGB( 0, 206, 209) }, + { "darkviolet", NSVG_RGB(148, 0, 211) }, + { "deeppink", NSVG_RGB(255, 20, 147) }, + { "deepskyblue", NSVG_RGB( 0, 191, 255) }, + { "dimgray", NSVG_RGB(105, 105, 105) }, + { "dimgrey", NSVG_RGB(105, 105, 105) }, + { "dodgerblue", NSVG_RGB( 30, 144, 255) }, + { "firebrick", NSVG_RGB(178, 34, 34) }, + { "floralwhite", NSVG_RGB(255, 250, 240) }, + { "forestgreen", NSVG_RGB( 34, 139, 34) }, + { "fuchsia", NSVG_RGB(255, 0, 255) }, + { "gainsboro", NSVG_RGB(220, 220, 220) }, + { "ghostwhite", NSVG_RGB(248, 248, 255) }, + { "gold", NSVG_RGB(255, 215, 0) }, + { "goldenrod", NSVG_RGB(218, 165, 32) }, + { "greenyellow", NSVG_RGB(173, 255, 47) }, + { "honeydew", NSVG_RGB(240, 255, 240) }, + { "hotpink", NSVG_RGB(255, 105, 180) }, + { "indianred", NSVG_RGB(205, 92, 92) }, + { "indigo", NSVG_RGB( 75, 0, 130) }, + { "ivory", NSVG_RGB(255, 255, 240) }, + { "khaki", NSVG_RGB(240, 230, 140) }, + { "lavender", NSVG_RGB(230, 230, 250) }, + { "lavenderblush", NSVG_RGB(255, 240, 245) }, + { "lawngreen", NSVG_RGB(124, 252, 0) }, + { "lemonchiffon", NSVG_RGB(255, 250, 205) }, + { "lightblue", NSVG_RGB(173, 216, 230) }, + { "lightcoral", NSVG_RGB(240, 128, 128) }, + { "lightcyan", NSVG_RGB(224, 255, 255) }, + { "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) }, + { "lightgray", NSVG_RGB(211, 211, 211) }, + { "lightgreen", NSVG_RGB(144, 238, 144) }, + { "lightgrey", NSVG_RGB(211, 211, 211) }, + { "lightpink", NSVG_RGB(255, 182, 193) }, + { "lightsalmon", NSVG_RGB(255, 160, 122) }, + { "lightseagreen", NSVG_RGB( 32, 178, 170) }, + { "lightskyblue", NSVG_RGB(135, 206, 250) }, + { "lightslategray", NSVG_RGB(119, 136, 153) }, + { "lightslategrey", NSVG_RGB(119, 136, 153) }, + { "lightsteelblue", NSVG_RGB(176, 196, 222) }, + { "lightyellow", NSVG_RGB(255, 255, 224) }, + { "lime", NSVG_RGB( 0, 255, 0) }, + { "limegreen", NSVG_RGB( 50, 205, 50) }, + { "linen", NSVG_RGB(250, 240, 230) }, + { "maroon", NSVG_RGB(128, 0, 0) }, + { "mediumaquamarine", NSVG_RGB(102, 205, 170) }, + { "mediumblue", NSVG_RGB( 0, 0, 205) }, + { "mediumorchid", NSVG_RGB(186, 85, 211) }, + { "mediumpurple", NSVG_RGB(147, 112, 219) }, + { "mediumseagreen", NSVG_RGB( 60, 179, 113) }, + { "mediumslateblue", NSVG_RGB(123, 104, 238) }, + { "mediumspringgreen", NSVG_RGB( 0, 250, 154) }, + { "mediumturquoise", NSVG_RGB( 72, 209, 204) }, + { "mediumvioletred", NSVG_RGB(199, 21, 133) }, + { "midnightblue", NSVG_RGB( 25, 25, 112) }, + { "mintcream", NSVG_RGB(245, 255, 250) }, + { "mistyrose", NSVG_RGB(255, 228, 225) }, + { "moccasin", NSVG_RGB(255, 228, 181) }, + { "navajowhite", NSVG_RGB(255, 222, 173) }, + { "navy", NSVG_RGB( 0, 0, 128) }, + { "oldlace", NSVG_RGB(253, 245, 230) }, + { "olive", NSVG_RGB(128, 128, 0) }, + { "olivedrab", NSVG_RGB(107, 142, 35) }, + { "orange", NSVG_RGB(255, 165, 0) }, + { "orangered", NSVG_RGB(255, 69, 0) }, + { "orchid", NSVG_RGB(218, 112, 214) }, + { "palegoldenrod", NSVG_RGB(238, 232, 170) }, + { "palegreen", NSVG_RGB(152, 251, 152) }, + { "paleturquoise", NSVG_RGB(175, 238, 238) }, + { "palevioletred", NSVG_RGB(219, 112, 147) }, + { "papayawhip", NSVG_RGB(255, 239, 213) }, + { "peachpuff", NSVG_RGB(255, 218, 185) }, + { "peru", NSVG_RGB(205, 133, 63) }, + { "pink", NSVG_RGB(255, 192, 203) }, + { "plum", NSVG_RGB(221, 160, 221) }, + { "powderblue", NSVG_RGB(176, 224, 230) }, + { "purple", NSVG_RGB(128, 0, 128) }, + { "rosybrown", NSVG_RGB(188, 143, 143) }, + { "royalblue", NSVG_RGB( 65, 105, 225) }, + { "saddlebrown", NSVG_RGB(139, 69, 19) }, + { "salmon", NSVG_RGB(250, 128, 114) }, + { "sandybrown", NSVG_RGB(244, 164, 96) }, + { "seagreen", NSVG_RGB( 46, 139, 87) }, + { "seashell", NSVG_RGB(255, 245, 238) }, + { "sienna", NSVG_RGB(160, 82, 45) }, + { "silver", NSVG_RGB(192, 192, 192) }, + { "skyblue", NSVG_RGB(135, 206, 235) }, + { "slateblue", NSVG_RGB(106, 90, 205) }, + { "slategray", NSVG_RGB(112, 128, 144) }, + { "slategrey", NSVG_RGB(112, 128, 144) }, + { "snow", NSVG_RGB(255, 250, 250) }, + { "springgreen", NSVG_RGB( 0, 255, 127) }, + { "steelblue", NSVG_RGB( 70, 130, 180) }, + { "tan", NSVG_RGB(210, 180, 140) }, + { "teal", NSVG_RGB( 0, 128, 128) }, + { "thistle", NSVG_RGB(216, 191, 216) }, + { "tomato", NSVG_RGB(255, 99, 71) }, + { "turquoise", NSVG_RGB( 64, 224, 208) }, + { "violet", NSVG_RGB(238, 130, 238) }, + { "wheat", NSVG_RGB(245, 222, 179) }, + { "whitesmoke", NSVG_RGB(245, 245, 245) }, + { "yellowgreen", NSVG_RGB(154, 205, 50) }, +#endif +}; + +static unsigned int nsvg__parseColorName(const char* str) +{ + int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor); + + for (i = 0; i < ncolors; i++) { + if (strcmp(nsvg__colors[i].name, str) == 0) { + return nsvg__colors[i].color; + } + } + + return NSVG_RGB(128, 128, 128); +} + +static unsigned int nsvg__parseColor(const char* str) +{ + size_t len = 0; + while(*str == ' ') ++str; + len = strlen(str); + if (len >= 1 && *str == '#') + return nsvg__parseColorHex(str); + else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(') + return nsvg__parseColorRGB(str); + return nsvg__parseColorName(str); +} + +static float nsvg__parseOpacity(const char* str) +{ + float val = nsvg__atof(str); + if (val < 0.0f) val = 0.0f; + if (val > 1.0f) val = 1.0f; + return val; +} + +static float nsvg__parseMiterLimit(const char* str) +{ + float val = nsvg__atof(str); + if (val < 0.0f) val = 0.0f; + return val; +} + +static int nsvg__parseUnits(const char* units) +{ + if (units[0] == 'p' && units[1] == 'x') + return NSVG_UNITS_PX; + else if (units[0] == 'p' && units[1] == 't') + return NSVG_UNITS_PT; + else if (units[0] == 'p' && units[1] == 'c') + return NSVG_UNITS_PC; + else if (units[0] == 'm' && units[1] == 'm') + return NSVG_UNITS_MM; + else if (units[0] == 'c' && units[1] == 'm') + return NSVG_UNITS_CM; + else if (units[0] == 'i' && units[1] == 'n') + return NSVG_UNITS_IN; + else if (units[0] == '%') + return NSVG_UNITS_PERCENT; + else if (units[0] == 'e' && units[1] == 'm') + return NSVG_UNITS_EM; + else if (units[0] == 'e' && units[1] == 'x') + return NSVG_UNITS_EX; + return NSVG_UNITS_USER; +} + +static int nsvg__isCoordinate(const char* s) +{ + // optional sign + if (*s == '-' || *s == '+') + s++; + // must have at least one digit, or start by a dot + return (nsvg__isdigit(*s) || *s == '.'); +} + +static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str) +{ + NSVGcoordinate coord = {0, NSVG_UNITS_USER}; + char buf[64]; + coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64)); + coord.value = nsvg__atof(buf); + return coord; +} + +static NSVGcoordinate nsvg__coord(float v, int units) +{ + NSVGcoordinate coord = {v, units}; + return coord; +} + +static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length) +{ + NSVGcoordinate coord = nsvg__parseCoordinateRaw(str); + return nsvg__convertToPixels(p, coord, orig, length); +} + +static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na) +{ + const char* end; + const char* ptr; + char it[64]; + + *na = 0; + ptr = str; + while (*ptr && *ptr != '(') ++ptr; + if (*ptr == 0) + return 1; + end = ptr; + while (*end && *end != ')') ++end; + if (*end == 0) + return 1; + + while (ptr < end) { + if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) { + if (*na >= maxNa) return 0; + ptr = nsvg__parseNumber(ptr, it, 64); + args[(*na)++] = (float)nsvg__atof(it); + } else { + ++ptr; + } + } + return (int)(end - str); +} + + +static int nsvg__parseMatrix(float* xform, const char* str) +{ + float t[6]; + int na = 0; + int len = nsvg__parseTransformArgs(str, t, 6, &na); + if (na != 6) return len; + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseTranslate(float* xform, const char* str) +{ + float args[2]; + float t[6]; + int na = 0; + int len = nsvg__parseTransformArgs(str, args, 2, &na); + if (na == 1) args[1] = 0.0; + + nsvg__xformSetTranslation(t, args[0], args[1]); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseScale(float* xform, const char* str) +{ + float args[2]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 2, &na); + if (na == 1) args[1] = args[0]; + nsvg__xformSetScale(t, args[0], args[1]); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseSkewX(float* xform, const char* str) +{ + float args[1]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 1, &na); + nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseSkewY(float* xform, const char* str) +{ + float args[1]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 1, &na); + nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseRotate(float* xform, const char* str) +{ + float args[3]; + int na = 0; + float m[6]; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 3, &na); + if (na == 1) + args[1] = args[2] = 0.0f; + nsvg__xformIdentity(m); + + if (na > 1) { + nsvg__xformSetTranslation(t, -args[1], -args[2]); + nsvg__xformMultiply(m, t); + } + + nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI); + nsvg__xformMultiply(m, t); + + if (na > 1) { + nsvg__xformSetTranslation(t, args[1], args[2]); + nsvg__xformMultiply(m, t); + } + + memcpy(xform, m, sizeof(float)*6); + + return len; +} + +static void nsvg__parseTransform(float* xform, const char* str) +{ + float t[6]; + int len; + nsvg__xformIdentity(xform); + while (*str) + { + if (strncmp(str, "matrix", 6) == 0) + len = nsvg__parseMatrix(t, str); + else if (strncmp(str, "translate", 9) == 0) + len = nsvg__parseTranslate(t, str); + else if (strncmp(str, "scale", 5) == 0) + len = nsvg__parseScale(t, str); + else if (strncmp(str, "rotate", 6) == 0) + len = nsvg__parseRotate(t, str); + else if (strncmp(str, "skewX", 5) == 0) + len = nsvg__parseSkewX(t, str); + else if (strncmp(str, "skewY", 5) == 0) + len = nsvg__parseSkewY(t, str); + else{ + ++str; + continue; + } + if (len != 0) { + str += len; + } else { + ++str; + continue; + } + + nsvg__xformPremultiply(xform, t); + } +} + +static void nsvg__parseUrl(char* id, const char* str) +{ + int i = 0; + str += 4; // "url("; + if (*str && *str == '#') + str++; + while (i < 63 && *str && *str != ')') { + id[i] = *str++; + i++; + } + id[i] = '\0'; +} + +static char nsvg__parseLineCap(const char* str) +{ + if (strcmp(str, "butt") == 0) + return NSVG_CAP_BUTT; + else if (strcmp(str, "round") == 0) + return NSVG_CAP_ROUND; + else if (strcmp(str, "square") == 0) + return NSVG_CAP_SQUARE; + // TODO: handle inherit. + return NSVG_CAP_BUTT; +} + +static char nsvg__parseLineJoin(const char* str) +{ + if (strcmp(str, "miter") == 0) + return NSVG_JOIN_MITER; + else if (strcmp(str, "round") == 0) + return NSVG_JOIN_ROUND; + else if (strcmp(str, "bevel") == 0) + return NSVG_JOIN_BEVEL; + // TODO: handle inherit. + return NSVG_JOIN_MITER; +} + +static char nsvg__parseFillRule(const char* str) +{ + if (strcmp(str, "nonzero") == 0) + return NSVG_FILLRULE_NONZERO; + else if (strcmp(str, "evenodd") == 0) + return NSVG_FILLRULE_EVENODD; + // TODO: handle inherit. + return NSVG_FILLRULE_NONZERO; +} + +static const char* nsvg__getNextDashItem(const char* s, char* it) +{ + int n = 0; + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) s++; + // Advance until whitespace, comma or end. + while (*s && (!nsvg__isspace(*s) && *s != ',')) { + if (n < 63) + it[n++] = *s; + s++; + } + it[n++] = '\0'; + return s; +} + +static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray) +{ + char item[64]; + int count = 0, i; + float sum = 0.0f; + + // Handle "none" + if (str[0] == 'n') + return 0; + + // Parse dashes + while (*str) { + str = nsvg__getNextDashItem(str, item); + if (!*item) break; + if (count < NSVG_MAX_DASHES) + strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p))); + } + + for (i = 0; i < count; i++) + sum += strokeDashArray[i]; + if (sum <= 1e-6f) + count = 0; + + return count; +} + +static void nsvg__parseStyle(NSVGparser* p, const char* str); + +static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value) +{ + float xform[6]; + NSVGattrib* attr = nsvg__getAttr(p); + if (!attr) return 0; + + if (strcmp(name, "style") == 0) { + nsvg__parseStyle(p, value); + } else if (strcmp(name, "display") == 0) { + if (strcmp(value, "none") == 0) + attr->visible = 0; + // Don't reset ->visible on display:inline, one display:none hides the whole subtree + + } else if (strcmp(name, "fill") == 0) { + if (strcmp(value, "none") == 0) { + attr->hasFill = 0; + } else if (strncmp(value, "url(", 4) == 0) { + attr->hasFill = 2; + nsvg__parseUrl(attr->fillGradient, value); + } else { + attr->hasFill = 1; + attr->fillColor = nsvg__parseColor(value); + } + } else if (strcmp(name, "opacity") == 0) { + attr->opacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "fill-opacity") == 0) { + attr->fillOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "stroke") == 0) { + if (strcmp(value, "none") == 0) { + attr->hasStroke = 0; + } else if (strncmp(value, "url(", 4) == 0) { + attr->hasStroke = 2; + nsvg__parseUrl(attr->strokeGradient, value); + } else { + attr->hasStroke = 1; + attr->strokeColor = nsvg__parseColor(value); + } + } else if (strcmp(name, "stroke-width") == 0) { + attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "stroke-dasharray") == 0) { + attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray); + } else if (strcmp(name, "stroke-dashoffset") == 0) { + attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "stroke-opacity") == 0) { + attr->strokeOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "stroke-linecap") == 0) { + attr->strokeLineCap = nsvg__parseLineCap(value); + } else if (strcmp(name, "stroke-linejoin") == 0) { + attr->strokeLineJoin = nsvg__parseLineJoin(value); + } else if (strcmp(name, "stroke-miterlimit") == 0) { + attr->miterLimit = nsvg__parseMiterLimit(value); + } else if (strcmp(name, "fill-rule") == 0) { + attr->fillRule = nsvg__parseFillRule(value); + } else if (strcmp(name, "font-size") == 0) { + attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "transform") == 0) { + nsvg__parseTransform(xform, value); + nsvg__xformPremultiply(attr->xform, xform); + } else if (strcmp(name, "stop-color") == 0) { + attr->stopColor = nsvg__parseColor(value); + } else if (strcmp(name, "stop-opacity") == 0) { + attr->stopOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "offset") == 0) { + attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f); + } else if (strcmp(name, "id") == 0) { + strncpy(attr->id, value, 63); + attr->id[63] = '\0'; + } else { + return 0; + } + return 1; +} + +static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end) +{ + const char* str; + const char* val; + char name[512]; + char value[512]; + int n; + + str = start; + while (str < end && *str != ':') ++str; + + val = str; + + // Right Trim + while (str > start && (*str == ':' || nsvg__isspace(*str))) --str; + ++str; + + n = (int)(str - start); + if (n > 511) n = 511; + if (n) memcpy(name, start, n); + name[n] = 0; + + while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val; + + n = (int)(end - val); + if (n > 511) n = 511; + if (n) memcpy(value, val, n); + value[n] = 0; + + return nsvg__parseAttr(p, name, value); +} + +static void nsvg__parseStyle(NSVGparser* p, const char* str) +{ + const char* start; + const char* end; + + while (*str) { + // Left Trim + while(*str && nsvg__isspace(*str)) ++str; + start = str; + while(*str && *str != ';') ++str; + end = str; + + // Right Trim + while (end > start && (*end == ';' || nsvg__isspace(*end))) --end; + ++end; + + nsvg__parseNameValue(p, start, end); + if (*str) ++str; + } +} + +static void nsvg__parseAttribs(NSVGparser* p, const char** attr) +{ + int i; + for (i = 0; attr[i]; i += 2) + { + if (strcmp(attr[i], "style") == 0) + nsvg__parseStyle(p, attr[i + 1]); + else + nsvg__parseAttr(p, attr[i], attr[i + 1]); + } +} + +static int nsvg__getArgsPerElement(char cmd) +{ + switch (cmd) { + case 'v': + case 'V': + case 'h': + case 'H': + return 1; + case 'm': + case 'M': + case 'l': + case 'L': + case 't': + case 'T': + return 2; + case 'q': + case 'Q': + case 's': + case 'S': + return 4; + case 'c': + case 'C': + return 6; + case 'a': + case 'A': + return 7; + case 'z': + case 'Z': + return 0; + } + return -1; +} + +static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) { + *cpx += args[0]; + *cpy += args[1]; + } else { + *cpx = args[0]; + *cpy = args[1]; + } + nsvg__moveTo(p, *cpx, *cpy); +} + +static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) { + *cpx += args[0]; + *cpy += args[1]; + } else { + *cpx = args[0]; + *cpy = args[1]; + } + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) + *cpx += args[0]; + else + *cpx = args[0]; + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) + *cpy += args[0]; + else + *cpy = args[0]; + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x2, y2, cx1, cy1, cx2, cy2; + + if (rel) { + cx1 = *cpx + args[0]; + cy1 = *cpy + args[1]; + cx2 = *cpx + args[2]; + cy2 = *cpy + args[3]; + x2 = *cpx + args[4]; + y2 = *cpy + args[5]; + } else { + cx1 = args[0]; + cy1 = args[1]; + cx2 = args[2]; + cy2 = args[3]; + x2 = args[4]; + y2 = args[5]; + } + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx2; + *cpy2 = cy2; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x1, y1, x2, y2, cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + cx2 = *cpx + args[0]; + cy2 = *cpy + args[1]; + x2 = *cpx + args[2]; + y2 = *cpy + args[3]; + } else { + cx2 = args[0]; + cy2 = args[1]; + x2 = args[2]; + y2 = args[3]; + } + + cx1 = 2*x1 - *cpx2; + cy1 = 2*y1 - *cpy2; + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx2; + *cpy2 = cy2; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x1, y1, x2, y2, cx, cy; + float cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + cx = *cpx + args[0]; + cy = *cpy + args[1]; + x2 = *cpx + args[2]; + y2 = *cpy + args[3]; + } else { + cx = args[0]; + cy = args[1]; + x2 = args[2]; + y2 = args[3]; + } + + // Convert to cubic bezier + cx1 = x1 + 2.0f/3.0f*(cx - x1); + cy1 = y1 + 2.0f/3.0f*(cy - y1); + cx2 = x2 + 2.0f/3.0f*(cx - x2); + cy2 = y2 + 2.0f/3.0f*(cy - y2); + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx; + *cpy2 = cy; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x1, y1, x2, y2, cx, cy; + float cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + x2 = *cpx + args[0]; + y2 = *cpy + args[1]; + } else { + x2 = args[0]; + y2 = args[1]; + } + + cx = 2*x1 - *cpx2; + cy = 2*y1 - *cpy2; + + // Convert to cubix bezier + cx1 = x1 + 2.0f/3.0f*(cx - x1); + cy1 = y1 + 2.0f/3.0f*(cy - y1); + cx2 = x2 + 2.0f/3.0f*(cx - x2); + cy2 = y2 + 2.0f/3.0f*(cy - y2); + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx; + *cpy2 = cy; + *cpx = x2; + *cpy = y2; +} + +static float nsvg__sqr(float x) { return x*x; } +static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); } + +static float nsvg__vecrat(float ux, float uy, float vx, float vy) +{ + return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy)); +} + +static float nsvg__vecang(float ux, float uy, float vx, float vy) +{ + float r = nsvg__vecrat(ux,uy, vx,vy); + if (r < -1.0f) r = -1.0f; + if (r > 1.0f) r = 1.0f; + return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r); +} + +static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + // Ported from canvg (https://code.google.com/p/canvg/) + float rx, ry, rotx; + float x1, y1, x2, y2, cx, cy, dx, dy, d; + float x1p, y1p, cxp, cyp, s, sa, sb; + float ux, uy, vx, vy, a1, da; + float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6]; + float sinrx, cosrx; + int fa, fs; + int i, ndivs; + float hda, kappa; + + rx = fabsf(args[0]); // y radius + ry = fabsf(args[1]); // x radius + rotx = args[2] / 180.0f * NSVG_PI; // x rotation angle + fa = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc + fs = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction + x1 = *cpx; // start point + y1 = *cpy; + if (rel) { // end point + x2 = *cpx + args[5]; + y2 = *cpy + args[6]; + } else { + x2 = args[5]; + y2 = args[6]; + } + + dx = x1 - x2; + dy = y1 - y2; + d = sqrtf(dx*dx + dy*dy); + if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) { + // The arc degenerates to a line + nsvg__lineTo(p, x2, y2); + *cpx = x2; + *cpy = y2; + return; + } + + sinrx = sinf(rotx); + cosrx = cosf(rotx); + + // Convert to center point parameterization. + // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + // 1) Compute x1', y1' + x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; + y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f; + d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry); + if (d > 1) { + d = sqrtf(d); + rx *= d; + ry *= d; + } + // 2) Compute cx', cy' + s = 0.0f; + sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p); + sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p); + if (sa < 0.0f) sa = 0.0f; + if (sb > 0.0f) + s = sqrtf(sa / sb); + if (fa == fs) + s = -s; + cxp = s * rx * y1p / ry; + cyp = s * -ry * x1p / rx; + + // 3) Compute cx,cy from cx',cy' + cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp; + cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp; + + // 4) Calculate theta1, and delta theta. + ux = (x1p - cxp) / rx; + uy = (y1p - cyp) / ry; + vx = (-x1p - cxp) / rx; + vy = (-y1p - cyp) / ry; + a1 = nsvg__vecang(1.0f,0.0f, ux,uy); // Initial angle + da = nsvg__vecang(ux,uy, vx,vy); // Delta angle + +// if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI; +// if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; + + if (fs == 0 && da > 0) + da -= 2 * NSVG_PI; + else if (fs == 1 && da < 0) + da += 2 * NSVG_PI; + + // Approximate the arc using cubic spline segments. + t[0] = cosrx; t[1] = sinrx; + t[2] = -sinrx; t[3] = cosrx; + t[4] = cx; t[5] = cy; + + // Split arc into max 90 degree segments. + // The loop assumes an iteration per end point (including start and end), this +1. + ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f); + hda = (da / (float)ndivs) / 2.0f; + // Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite) + if ((hda < 1e-3f) && (hda > -1e-3f)) + hda *= 0.5f; + else + hda = (1.0f - cosf(hda)) / sinf(hda); + kappa = fabsf(4.0f / 3.0f * hda); + if (da < 0.0f) + kappa = -kappa; + + for (i = 0; i <= ndivs; i++) { + a = a1 + da * ((float)i/(float)ndivs); + dx = cosf(a); + dy = sinf(a); + nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position + nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent + if (i > 0) + nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y); + px = x; + py = y; + ptanx = tanx; + ptany = tany; + } + + *cpx = x2; + *cpy = y2; +} + +static void nsvg__parsePath(NSVGparser* p, const char** attr) +{ + const char* s = NULL; + char cmd = '\0'; + float args[10]; + int nargs; + int rargs = 0; + char initPoint; + float cpx, cpy, cpx2, cpy2; + const char* tmp[4]; + char closedFlag; + int i; + char item[64]; + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "d") == 0) { + s = attr[i + 1]; + } else { + tmp[0] = attr[i]; + tmp[1] = attr[i + 1]; + tmp[2] = 0; + tmp[3] = 0; + nsvg__parseAttribs(p, tmp); + } + } + + if (s) { + nsvg__resetPath(p); + cpx = 0; cpy = 0; + cpx2 = 0; cpy2 = 0; + initPoint = 0; + closedFlag = 0; + nargs = 0; + + while (*s) { + s = nsvg__getNextPathItem(s, item); + if (!*item) break; + if (cmd != '\0' && nsvg__isCoordinate(item)) { + if (nargs < 10) + args[nargs++] = (float)nsvg__atof(item); + if (nargs >= rargs) { + switch (cmd) { + case 'm': + case 'M': + nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); + // Moveto can be followed by multiple coordinate pairs, + // which should be treated as linetos. + cmd = (cmd == 'm') ? 'l' : 'L'; + rargs = nsvg__getArgsPerElement(cmd); + cpx2 = cpx; cpy2 = cpy; + initPoint = 1; + break; + case 'l': + case 'L': + nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + case 'H': + case 'h': + nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + case 'V': + case 'v': + nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + case 'C': + case 'c': + nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0); + break; + case 'S': + case 's': + nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0); + break; + case 'Q': + case 'q': + nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0); + break; + case 'T': + case 't': + nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0); + break; + case 'A': + case 'a': + nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + default: + if (nargs >= 2) { + cpx = args[nargs-2]; + cpy = args[nargs-1]; + cpx2 = cpx; cpy2 = cpy; + } + break; + } + nargs = 0; + } + } else { + cmd = item[0]; + if (cmd == 'M' || cmd == 'm') { + // Commit path. + if (p->npts > 0) + nsvg__addPath(p, closedFlag); + // Start new subpath. + nsvg__resetPath(p); + closedFlag = 0; + nargs = 0; + } else if (initPoint == 0) { + // Do not allow other commands until initial point has been set (moveTo called once). + cmd = '\0'; + } + if (cmd == 'Z' || cmd == 'z') { + closedFlag = 1; + // Commit path. + if (p->npts > 0) { + // Move current point to first point + cpx = p->pts[0]; + cpy = p->pts[1]; + cpx2 = cpx; cpy2 = cpy; + nsvg__addPath(p, closedFlag); + } + // Start new subpath. + nsvg__resetPath(p); + nsvg__moveTo(p, cpx, cpy); + closedFlag = 0; + nargs = 0; + } + rargs = nsvg__getArgsPerElement(cmd); + if (rargs == -1) { + // Command not recognized + cmd = '\0'; + rargs = 0; + } + } + } + // Commit path. + if (p->npts) + nsvg__addPath(p, closedFlag); + } + + nsvg__addShape(p); +} + +static void nsvg__parseRect(NSVGparser* p, const char** attr) +{ + float x = 0.0f; + float y = 0.0f; + float w = 0.0f; + float h = 0.0f; + float rx = -1.0f; // marks not set + float ry = -1.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)); + if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); + } + } + + if (rx < 0.0f && ry > 0.0f) rx = ry; + if (ry < 0.0f && rx > 0.0f) ry = rx; + if (rx < 0.0f) rx = 0.0f; + if (ry < 0.0f) ry = 0.0f; + if (rx > w/2.0f) rx = w/2.0f; + if (ry > h/2.0f) ry = h/2.0f; + + if (w != 0.0f && h != 0.0f) { + nsvg__resetPath(p); + + if (rx < 0.00001f || ry < 0.0001f) { + nsvg__moveTo(p, x, y); + nsvg__lineTo(p, x+w, y); + nsvg__lineTo(p, x+w, y+h); + nsvg__lineTo(p, x, y+h); + } else { + // Rounded rectangle + nsvg__moveTo(p, x+rx, y); + nsvg__lineTo(p, x+w-rx, y); + nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry); + nsvg__lineTo(p, x+w, y+h-ry); + nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h); + nsvg__lineTo(p, x+rx, y+h); + nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry); + nsvg__lineTo(p, x, y+ry); + nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y); + } + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseCircle(NSVGparser* p, const char** attr) +{ + float cx = 0.0f; + float cy = 0.0f; + float r = 0.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p))); + } + } + + if (r > 0.0f) { + nsvg__resetPath(p); + + nsvg__moveTo(p, cx+r, cy); + nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r); + nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy); + nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r); + nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy); + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseEllipse(NSVGparser* p, const char** attr) +{ + float cx = 0.0f; + float cy = 0.0f; + float rx = 0.0f; + float ry = 0.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); + } + } + + if (rx > 0.0f && ry > 0.0f) { + + nsvg__resetPath(p); + + nsvg__moveTo(p, cx+rx, cy); + nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry); + nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy); + nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry); + nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy); + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseLine(NSVGparser* p, const char** attr) +{ + float x1 = 0.0; + float y1 = 0.0; + float x2 = 0.0; + float y2 = 0.0; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + } + } + + nsvg__resetPath(p); + + nsvg__moveTo(p, x1, y1); + nsvg__lineTo(p, x2, y2); + + nsvg__addPath(p, 0); + + nsvg__addShape(p); +} + +static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag) +{ + int i; + const char* s; + float args[2]; + int nargs, npts = 0; + char item[64]; + + nsvg__resetPath(p); + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "points") == 0) { + s = attr[i + 1]; + nargs = 0; + while (*s) { + s = nsvg__getNextPathItem(s, item); + args[nargs++] = (float)nsvg__atof(item); + if (nargs >= 2) { + if (npts == 0) + nsvg__moveTo(p, args[0], args[1]); + else + nsvg__lineTo(p, args[0], args[1]); + nargs = 0; + npts++; + } + } + } + } + } + + nsvg__addPath(p, (char)closeFlag); + + nsvg__addShape(p); +} + +static void nsvg__parseSVG(NSVGparser* p, const char** attr) +{ + int i; + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "width") == 0) { + p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); + } else if (strcmp(attr[i], "height") == 0) { + p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); + } else if (strcmp(attr[i], "viewBox") == 0) { + const char *s = attr[i + 1]; + char buf[64]; + s = nsvg__parseNumber(s, buf, 64); + p->viewMinx = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; + if (!*s) return; + s = nsvg__parseNumber(s, buf, 64); + p->viewMiny = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; + if (!*s) return; + s = nsvg__parseNumber(s, buf, 64); + p->viewWidth = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; + if (!*s) return; + s = nsvg__parseNumber(s, buf, 64); + p->viewHeight = nsvg__atof(buf); + } else if (strcmp(attr[i], "preserveAspectRatio") == 0) { + if (strstr(attr[i + 1], "none") != 0) { + // No uniform scaling + p->alignType = NSVG_ALIGN_NONE; + } else { + // Parse X align + if (strstr(attr[i + 1], "xMin") != 0) + p->alignX = NSVG_ALIGN_MIN; + else if (strstr(attr[i + 1], "xMid") != 0) + p->alignX = NSVG_ALIGN_MID; + else if (strstr(attr[i + 1], "xMax") != 0) + p->alignX = NSVG_ALIGN_MAX; + // Parse X align + if (strstr(attr[i + 1], "yMin") != 0) + p->alignY = NSVG_ALIGN_MIN; + else if (strstr(attr[i + 1], "yMid") != 0) + p->alignY = NSVG_ALIGN_MID; + else if (strstr(attr[i + 1], "yMax") != 0) + p->alignY = NSVG_ALIGN_MAX; + // Parse meet/slice + p->alignType = NSVG_ALIGN_MEET; + if (strstr(attr[i + 1], "slice") != 0) + p->alignType = NSVG_ALIGN_SLICE; + } + } + } + } +} + +static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type) +{ + int i; + NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData)); + if (grad == NULL) return; + memset(grad, 0, sizeof(NSVGgradientData)); + grad->units = NSVG_OBJECT_SPACE; + grad->type = type; + if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) { + grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT); + grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) { + grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + } + + nsvg__xformIdentity(grad->xform); + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "id") == 0) { + strncpy(grad->id, attr[i+1], 63); + grad->id[63] = '\0'; + } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "gradientUnits") == 0) { + if (strcmp(attr[i+1], "objectBoundingBox") == 0) + grad->units = NSVG_OBJECT_SPACE; + else + grad->units = NSVG_USER_SPACE; + } else if (strcmp(attr[i], "gradientTransform") == 0) { + nsvg__parseTransform(grad->xform, attr[i + 1]); + } else if (strcmp(attr[i], "cx") == 0) { + grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "cy") == 0) { + grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "r") == 0) { + grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "fx") == 0) { + grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "fy") == 0) { + grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "x1") == 0) { + grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "y1") == 0) { + grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "x2") == 0) { + grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "y2") == 0) { + grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "spreadMethod") == 0) { + if (strcmp(attr[i+1], "pad") == 0) + grad->spread = NSVG_SPREAD_PAD; + else if (strcmp(attr[i+1], "reflect") == 0) + grad->spread = NSVG_SPREAD_REFLECT; + else if (strcmp(attr[i+1], "repeat") == 0) + grad->spread = NSVG_SPREAD_REPEAT; + } else if (strcmp(attr[i], "xlink:href") == 0) { + const char *href = attr[i+1]; + strncpy(grad->ref, href+1, 62); + grad->ref[62] = '\0'; + } + } + } + + grad->next = p->gradients; + p->gradients = grad; +} + +static void nsvg__parseGradientStop(NSVGparser* p, const char** attr) +{ + NSVGattrib* curAttr = nsvg__getAttr(p); + NSVGgradientData* grad; + NSVGgradientStop* stop; + int i, idx; + + curAttr->stopOffset = 0; + curAttr->stopColor = 0; + curAttr->stopOpacity = 1.0f; + + for (i = 0; attr[i]; i += 2) { + nsvg__parseAttr(p, attr[i], attr[i + 1]); + } + + // Add stop to the last gradient. + grad = p->gradients; + if (grad == NULL) return; + + grad->nstops++; + grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops); + if (grad->stops == NULL) return; + + // Insert + idx = grad->nstops-1; + for (i = 0; i < grad->nstops-1; i++) { + if (curAttr->stopOffset < grad->stops[i].offset) { + idx = i; + break; + } + } + if (idx != grad->nstops-1) { + for (i = grad->nstops-1; i > idx; i--) + grad->stops[i] = grad->stops[i-1]; + } + + stop = &grad->stops[idx]; + stop->color = curAttr->stopColor; + stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24; + stop->offset = curAttr->stopOffset; +} + +static void nsvg__startElement(void* ud, const char* el, const char** attr) +{ + NSVGparser* p = (NSVGparser*)ud; + + if (p->defsFlag) { + // Skip everything but gradients in defs + if (strcmp(el, "linearGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); + } else if (strcmp(el, "radialGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); + } else if (strcmp(el, "stop") == 0) { + nsvg__parseGradientStop(p, attr); + } + return; + } + + if (strcmp(el, "g") == 0) { + nsvg__pushAttr(p); + nsvg__parseAttribs(p, attr); + } else if (strcmp(el, "path") == 0) { + if (p->pathFlag) // Do not allow nested paths. + return; + nsvg__pushAttr(p); + nsvg__parsePath(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "rect") == 0) { + nsvg__pushAttr(p); + nsvg__parseRect(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "circle") == 0) { + nsvg__pushAttr(p); + nsvg__parseCircle(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "ellipse") == 0) { + nsvg__pushAttr(p); + nsvg__parseEllipse(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "line") == 0) { + nsvg__pushAttr(p); + nsvg__parseLine(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "polyline") == 0) { + nsvg__pushAttr(p); + nsvg__parsePoly(p, attr, 0); + nsvg__popAttr(p); + } else if (strcmp(el, "polygon") == 0) { + nsvg__pushAttr(p); + nsvg__parsePoly(p, attr, 1); + nsvg__popAttr(p); + } else if (strcmp(el, "linearGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); + } else if (strcmp(el, "radialGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); + } else if (strcmp(el, "stop") == 0) { + nsvg__parseGradientStop(p, attr); + } else if (strcmp(el, "defs") == 0) { + p->defsFlag = 1; + } else if (strcmp(el, "svg") == 0) { + nsvg__parseSVG(p, attr); + } +} + +static void nsvg__endElement(void* ud, const char* el) +{ + NSVGparser* p = (NSVGparser*)ud; + + if (strcmp(el, "g") == 0) { + nsvg__popAttr(p); + } else if (strcmp(el, "path") == 0) { + p->pathFlag = 0; + } else if (strcmp(el, "defs") == 0) { + p->defsFlag = 0; + } +} + +static void nsvg__content(void* ud, const char* s) +{ + NSVG_NOTUSED(ud); + NSVG_NOTUSED(s); + // empty +} + +static void nsvg__imageBounds(NSVGparser* p, float* bounds) +{ + NSVGshape* shape; + shape = p->image->shapes; + if (shape == NULL) { + bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0; + return; + } + bounds[0] = shape->bounds[0]; + bounds[1] = shape->bounds[1]; + bounds[2] = shape->bounds[2]; + bounds[3] = shape->bounds[3]; + for (shape = shape->next; shape != NULL; shape = shape->next) { + bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]); + bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]); + bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]); + bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]); + } +} + +static float nsvg__viewAlign(float content, float container, int type) +{ + if (type == NSVG_ALIGN_MIN) + return 0; + else if (type == NSVG_ALIGN_MAX) + return container - content; + // mid + return (container - content) * 0.5f; +} + +static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy) +{ + float t[6]; + nsvg__xformSetTranslation(t, tx, ty); + nsvg__xformMultiply (grad->xform, t); + + nsvg__xformSetScale(t, sx, sy); + nsvg__xformMultiply (grad->xform, t); +} + +static void nsvg__scaleToViewbox(NSVGparser* p, const char* units) +{ + NSVGshape* shape; + NSVGpath* path; + float tx, ty, sx, sy, us, bounds[4], t[6], avgs; + int i; + float* pt; + + // Guess image size if not set completely. + nsvg__imageBounds(p, bounds); + + if (p->viewWidth == 0) { + if (p->image->width > 0) { + p->viewWidth = p->image->width; + } else { + p->viewMinx = bounds[0]; + p->viewWidth = bounds[2] - bounds[0]; + } + } + if (p->viewHeight == 0) { + if (p->image->height > 0) { + p->viewHeight = p->image->height; + } else { + p->viewMiny = bounds[1]; + p->viewHeight = bounds[3] - bounds[1]; + } + } + if (p->image->width == 0) + p->image->width = p->viewWidth; + if (p->image->height == 0) + p->image->height = p->viewHeight; + + tx = -p->viewMinx; + ty = -p->viewMiny; + sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0; + sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0; + // Unit scaling + us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f); + + // Fix aspect ratio + if (p->alignType == NSVG_ALIGN_MEET) { + // fit whole image into viewbox + sx = sy = nsvg__minf(sx, sy); + tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; + ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; + } else if (p->alignType == NSVG_ALIGN_SLICE) { + // fill whole viewbox with image + sx = sy = nsvg__maxf(sx, sy); + tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; + ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; + } + + // Transform + sx *= us; + sy *= us; + avgs = (sx+sy) / 2.0f; + for (shape = p->image->shapes; shape != NULL; shape = shape->next) { + shape->bounds[0] = (shape->bounds[0] + tx) * sx; + shape->bounds[1] = (shape->bounds[1] + ty) * sy; + shape->bounds[2] = (shape->bounds[2] + tx) * sx; + shape->bounds[3] = (shape->bounds[3] + ty) * sy; + for (path = shape->paths; path != NULL; path = path->next) { + path->bounds[0] = (path->bounds[0] + tx) * sx; + path->bounds[1] = (path->bounds[1] + ty) * sy; + path->bounds[2] = (path->bounds[2] + tx) * sx; + path->bounds[3] = (path->bounds[3] + ty) * sy; + for (i =0; i < path->npts; i++) { + pt = &path->pts[i*2]; + pt[0] = (pt[0] + tx) * sx; + pt[1] = (pt[1] + ty) * sy; + } + } + + if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) { + nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy); + memcpy(t, shape->fill.gradient->xform, sizeof(float)*6); + nsvg__xformInverse(shape->fill.gradient->xform, t); + } + if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) { + nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy); + memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6); + nsvg__xformInverse(shape->stroke.gradient->xform, t); + } + + shape->strokeWidth *= avgs; + shape->strokeDashOffset *= avgs; + for (i = 0; i < shape->strokeDashCount; i++) + shape->strokeDashArray[i] *= avgs; + } +} + +NSVGimage* nsvgParse(char* input, const char* units, float dpi) +{ + NSVGparser* p; + NSVGimage* ret = 0; + + p = nsvg__createParser(); + if (p == NULL) { + return NULL; + } + p->dpi = dpi; + + nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p); + + // Scale to viewBox + nsvg__scaleToViewbox(p, units); + + ret = p->image; + p->image = NULL; + + nsvg__deleteParser(p); + + return ret; +} + +NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi) +{ + FILE* fp = NULL; + size_t size; + char* data = NULL; + NSVGimage* image = NULL; + + fp = fopen(filename, "rb"); + if (!fp) goto error; + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + data = (char*)malloc(size+1); + if (data == NULL) goto error; + if (fread(data, 1, size, fp) != size) goto error; + data[size] = '\0'; // Must be null terminated. + fclose(fp); + image = nsvgParse(data, units, dpi); + free(data); + + return image; + +error: + if (fp) fclose(fp); + if (data) free(data); + if (image) nsvgDelete(image); + return NULL; +} + +NSVGpath* nsvgDuplicatePath(NSVGpath* p) +{ + NSVGpath* res = NULL; + + if (p == NULL) + return NULL; + + res = (NSVGpath*)malloc(sizeof(NSVGpath)); + if (res == NULL) goto error; + memset(res, 0, sizeof(NSVGpath)); + + res->pts = (float*)malloc(p->npts*2*sizeof(float)); + if (res->pts == NULL) goto error; + memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2); + res->npts = p->npts; + + memcpy(res->bounds, p->bounds, sizeof(p->bounds)); + + res->closed = p->closed; + + return res; + +error: + if (res != NULL) { + free(res->pts); + free(res); + } + return NULL; +} + +void nsvgDelete(NSVGimage* image) +{ + NSVGshape *snext, *shape; + if (image == NULL) return; + shape = image->shapes; + while (shape != NULL) { + snext = shape->next; + nsvg__deletePaths(shape->paths); + nsvg__deletePaint(&shape->fill); + nsvg__deletePaint(&shape->stroke); + free(shape); + shape = snext; + } + free(image); +} + +#endif // NANOSVG_IMPLEMENTATION + +#endif // NANOSVG_H diff --git a/src/external/nanosvgrast.h b/src/external/nanosvgrast.h new file mode 100644 index 000000000000..6e23acb7b04f --- /dev/null +++ b/src/external/nanosvgrast.h @@ -0,0 +1,1458 @@ +/* + * Copyright (c) 2013-14 Mikko Mononen memon@inside.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 + * 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. + * + * The polygon rasterization is heavily based on stb_truetype rasterizer + * by Sean Barrett - http://nothings.org/ + * + */ + +#ifndef NANOSVGRAST_H +#define NANOSVGRAST_H + +#include "nanosvg.h" + +#ifndef NANOSVGRAST_CPLUSPLUS +#ifdef __cplusplus +extern "C" { +#endif +#endif + +typedef struct NSVGrasterizer NSVGrasterizer; + +/* Example Usage: + // Load SVG + NSVGimage* image; + image = nsvgParseFromFile("test.svg", "px", 96); + + // Create rasterizer (can be used to render multiple images). + struct NSVGrasterizer* rast = nsvgCreateRasterizer(); + // Allocate memory for image + unsigned char* img = malloc(w*h*4); + // Rasterize + nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4); +*/ + +// Allocated rasterizer context. +NSVGrasterizer* nsvgCreateRasterizer(void); + +// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha) +// r - pointer to rasterizer context +// image - pointer to image to rasterize +// tx,ty - image offset (applied after scaling) +// scale - image scale +// dst - pointer to destination image data, 4 bytes per pixel (RGBA) +// w - width of the image to render +// h - height of the image to render +// stride - number of bytes per scaleline in the destination buffer +void nsvgRasterize(NSVGrasterizer* r, + NSVGimage* image, float tx, float ty, float scale, + unsigned char* dst, int w, int h, int stride); + +// Deletes rasterizer context. +void nsvgDeleteRasterizer(NSVGrasterizer*); + + +#ifndef NANOSVGRAST_CPLUSPLUS +#ifdef __cplusplus +} +#endif +#endif + +#ifdef NANOSVGRAST_IMPLEMENTATION + +#include +#include +#include + +#define NSVG__SUBSAMPLES 5 +#define NSVG__FIXSHIFT 10 +#define NSVG__FIX (1 << NSVG__FIXSHIFT) +#define NSVG__FIXMASK (NSVG__FIX-1) +#define NSVG__MEMPAGE_SIZE 1024 + +typedef struct NSVGedge { + float x0,y0, x1,y1; + int dir; + struct NSVGedge* next; +} NSVGedge; + +typedef struct NSVGpoint { + float x, y; + float dx, dy; + float len; + float dmx, dmy; + unsigned char flags; +} NSVGpoint; + +typedef struct NSVGactiveEdge { + int x,dx; + float ey; + int dir; + struct NSVGactiveEdge *next; +} NSVGactiveEdge; + +typedef struct NSVGmemPage { + unsigned char mem[NSVG__MEMPAGE_SIZE]; + int size; + struct NSVGmemPage* next; +} NSVGmemPage; + +typedef struct NSVGcachedPaint { + char type; + char spread; + float xform[6]; + unsigned int colors[256]; +} NSVGcachedPaint; + +struct NSVGrasterizer +{ + float px, py; + + float tessTol; + float distTol; + + NSVGedge* edges; + int nedges; + int cedges; + + NSVGpoint* points; + int npoints; + int cpoints; + + NSVGpoint* points2; + int npoints2; + int cpoints2; + + NSVGactiveEdge* freelist; + NSVGmemPage* pages; + NSVGmemPage* curpage; + + unsigned char* scanline; + int cscanline; + + unsigned char* bitmap; + int width, height, stride; +}; + +NSVGrasterizer* nsvgCreateRasterizer(void) +{ + NSVGrasterizer* r = (NSVGrasterizer*)malloc(sizeof(NSVGrasterizer)); + if (r == NULL) goto error; + memset(r, 0, sizeof(NSVGrasterizer)); + + r->tessTol = 0.25f; + r->distTol = 0.01f; + + return r; + +error: + nsvgDeleteRasterizer(r); + return NULL; +} + +void nsvgDeleteRasterizer(NSVGrasterizer* r) +{ + NSVGmemPage* p; + + if (r == NULL) return; + + p = r->pages; + while (p != NULL) { + NSVGmemPage* next = p->next; + free(p); + p = next; + } + + if (r->edges) free(r->edges); + if (r->points) free(r->points); + if (r->points2) free(r->points2); + if (r->scanline) free(r->scanline); + + free(r); +} + +static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur) +{ + NSVGmemPage *newp; + + // If using existing chain, return the next page in chain + if (cur != NULL && cur->next != NULL) { + return cur->next; + } + + // Alloc new page + newp = (NSVGmemPage*)malloc(sizeof(NSVGmemPage)); + if (newp == NULL) return NULL; + memset(newp, 0, sizeof(NSVGmemPage)); + + // Add to linked list + if (cur != NULL) + cur->next = newp; + else + r->pages = newp; + + return newp; +} + +static void nsvg__resetPool(NSVGrasterizer* r) +{ + NSVGmemPage* p = r->pages; + while (p != NULL) { + p->size = 0; + p = p->next; + } + r->curpage = r->pages; +} + +static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size) +{ + unsigned char* buf; + if (size > NSVG__MEMPAGE_SIZE) return NULL; + if (r->curpage == NULL || r->curpage->size+size > NSVG__MEMPAGE_SIZE) { + r->curpage = nsvg__nextPage(r, r->curpage); + } + buf = &r->curpage->mem[r->curpage->size]; + r->curpage->size += size; + return buf; +} + +static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol) +{ + float dx = x2 - x1; + float dy = y2 - y1; + return dx*dx + dy*dy < tol*tol; +} + +static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags) +{ + NSVGpoint* pt; + + if (r->npoints > 0) { + pt = &r->points[r->npoints-1]; + if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) { + pt->flags = (unsigned char)(pt->flags | flags); + return; + } + } + + if (r->npoints+1 > r->cpoints) { + r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; + r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); + if (r->points == NULL) return; + } + + pt = &r->points[r->npoints]; + pt->x = x; + pt->y = y; + pt->flags = (unsigned char)flags; + r->npoints++; +} + +static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt) +{ + if (r->npoints+1 > r->cpoints) { + r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; + r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); + if (r->points == NULL) return; + } + r->points[r->npoints] = pt; + r->npoints++; +} + +static void nsvg__duplicatePoints(NSVGrasterizer* r) +{ + if (r->npoints > r->cpoints2) { + r->cpoints2 = r->npoints; + r->points2 = (NSVGpoint*)realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2); + if (r->points2 == NULL) return; + } + + memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints); + r->npoints2 = r->npoints; +} + +static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1) +{ + NSVGedge* e; + + // Skip horizontal edges + if (y0 == y1) + return; + + if (r->nedges+1 > r->cedges) { + r->cedges = r->cedges > 0 ? r->cedges * 2 : 64; + r->edges = (NSVGedge*)realloc(r->edges, sizeof(NSVGedge) * r->cedges); + if (r->edges == NULL) return; + } + + e = &r->edges[r->nedges]; + r->nedges++; + + if (y0 < y1) { + e->x0 = x0; + e->y0 = y0; + e->x1 = x1; + e->y1 = y1; + e->dir = 1; + } else { + e->x0 = x1; + e->y0 = y1; + e->x1 = x0; + e->y1 = y0; + e->dir = -1; + } +} + +static float nsvg__normalize(float *x, float* y) +{ + float d = sqrtf((*x)*(*x) + (*y)*(*y)); + if (d > 1e-6f) { + float id = 1.0f / d; + *x *= id; + *y *= id; + } + return d; +} + +static float nsvg__absf(float x) { return x < 0 ? -x : x; } + +static void nsvg__flattenCubicBez(NSVGrasterizer* r, + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + int level, int type) +{ + float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; + float dx,dy,d2,d3; + + if (level > 10) return; + + x12 = (x1+x2)*0.5f; + y12 = (y1+y2)*0.5f; + x23 = (x2+x3)*0.5f; + y23 = (y2+y3)*0.5f; + x34 = (x3+x4)*0.5f; + y34 = (y3+y4)*0.5f; + x123 = (x12+x23)*0.5f; + y123 = (y12+y23)*0.5f; + + dx = x4 - x1; + dy = y4 - y1; + d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx)); + d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx)); + + if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) { + nsvg__addPathPoint(r, x4, y4, type); + return; + } + + x234 = (x23+x34)*0.5f; + y234 = (y23+y34)*0.5f; + x1234 = (x123+x234)*0.5f; + y1234 = (y123+y234)*0.5f; + + nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); + nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); +} + +static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale) +{ + int i, j; + NSVGpath* path; + + for (path = shape->paths; path != NULL; path = path->next) { + r->npoints = 0; + // Flatten path + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); + for (i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0); + } + // Close path + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); + // Build edges + for (i = 0, j = r->npoints-1; i < r->npoints; j = i++) + nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y); + } +} + +enum NSVGpointFlags +{ + NSVG_PT_CORNER = 0x01, + NSVG_PT_BEVEL = 0x02, + NSVG_PT_LEFT = 0x04 +}; + +static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + float len = nsvg__normalize(&dx, &dy); + float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) +{ + float w = lineWidth * 0.5f; + float px = p->x, py = p->y; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + + nsvg__addEdge(r, lx, ly, rx, ry); + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) +{ + float w = lineWidth * 0.5f; + float px = p->x - dx*w, py = p->y - dy*w; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + + nsvg__addEdge(r, lx, ly, rx, ry); + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +#ifndef NSVG_PI +#define NSVG_PI (3.14159265358979323846264338327f) +#endif + +static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect) +{ + int i; + float w = lineWidth * 0.5f; + float px = p->x, py = p->y; + float dlx = dy, dly = -dx; + float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0; + + for (i = 0; i < ncap; i++) { + float a = (float)i/(float)(ncap-1)*NSVG_PI; + float ax = cosf(a) * w, ay = sinf(a) * w; + float x = px - dlx*ax - dx*ay; + float y = py - dly*ax - dy*ay; + + if (i > 0) + nsvg__addEdge(r, prevx, prevy, x, y); + + prevx = x; + prevy = y; + + if (i == 0) { + lx = x; ly = y; + } else if (i == ncap-1) { + rx = x; ry = y; + } + } + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w); + float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w); + float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w); + float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w); + + nsvg__addEdge(r, lx0, ly0, left->x, left->y); + nsvg__addEdge(r, lx1, ly1, lx0, ly0); + + nsvg__addEdge(r, right->x, right->y, rx0, ry0); + nsvg__addEdge(r, rx0, ry0, rx1, ry1); + + left->x = lx1; left->y = ly1; + right->x = rx1; right->y = ry1; +} + +static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float lx0, rx0, lx1, rx1; + float ly0, ry0, ly1, ry1; + + if (p1->flags & NSVG_PT_LEFT) { + lx0 = lx1 = p1->x - p1->dmx * w; + ly0 = ly1 = p1->y - p1->dmy * w; + nsvg__addEdge(r, lx1, ly1, left->x, left->y); + + rx0 = p1->x + (dlx0 * w); + ry0 = p1->y + (dly0 * w); + rx1 = p1->x + (dlx1 * w); + ry1 = p1->y + (dly1 * w); + nsvg__addEdge(r, right->x, right->y, rx0, ry0); + nsvg__addEdge(r, rx0, ry0, rx1, ry1); + } else { + lx0 = p1->x - (dlx0 * w); + ly0 = p1->y - (dly0 * w); + lx1 = p1->x - (dlx1 * w); + ly1 = p1->y - (dly1 * w); + nsvg__addEdge(r, lx0, ly0, left->x, left->y); + nsvg__addEdge(r, lx1, ly1, lx0, ly0); + + rx0 = rx1 = p1->x + p1->dmx * w; + ry0 = ry1 = p1->y + p1->dmy * w; + nsvg__addEdge(r, right->x, right->y, rx1, ry1); + } + + left->x = lx1; left->y = ly1; + right->x = rx1; right->y = ry1; +} + +static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap) +{ + int i, n; + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float a0 = atan2f(dly0, dlx0); + float a1 = atan2f(dly1, dlx1); + float da = a1 - a0; + float lx, ly, rx, ry; + + if (da < NSVG_PI) da += NSVG_PI*2; + if (da > NSVG_PI) da -= NSVG_PI*2; + + n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * (float)ncap); + if (n < 2) n = 2; + if (n > ncap) n = ncap; + + lx = left->x; + ly = left->y; + rx = right->x; + ry = right->y; + + for (i = 0; i < n; i++) { + float u = (float)i/(float)(n-1); + float a = a0 + u*da; + float ax = cosf(a) * w, ay = sinf(a) * w; + float lx1 = p1->x - ax, ly1 = p1->y - ay; + float rx1 = p1->x + ax, ry1 = p1->y + ay; + + nsvg__addEdge(r, lx1, ly1, lx, ly); + nsvg__addEdge(r, rx, ry, rx1, ry1); + + lx = lx1; ly = ly1; + rx = rx1; ry = ry1; + } + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w); + float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w); + + nsvg__addEdge(r, lx, ly, left->x, left->y); + nsvg__addEdge(r, right->x, right->y, rx, ry); + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static int nsvg__curveDivs(float r, float arc, float tol) +{ + float da = acosf(r / (r + tol)) * 2.0f; + int divs = (int)ceilf(arc / da); + if (divs < 2) divs = 2; + return divs; +} + +static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth) +{ + int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol); // Calculate divisions per half circle. + NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0}; + NSVGpoint* p0, *p1; + int j, s, e; + + // Build stroke edges + if (closed) { + // Looping + p0 = &points[npoints-1]; + p1 = &points[0]; + s = 0; + e = npoints; + } else { + // Add cap + p0 = &points[0]; + p1 = &points[1]; + s = 1; + e = npoints-1; + } + + if (closed) { + nsvg__initClosed(&left, &right, p0, p1, lineWidth); + firstLeft = left; + firstRight = right; + } else { + // Add cap + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + nsvg__normalize(&dx, &dy); + if (lineCap == NSVG_CAP_BUTT) + nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0); + else if (lineCap == NSVG_CAP_SQUARE) + nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0); + else if (lineCap == NSVG_CAP_ROUND) + nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0); + } + + for (j = s; j < e; ++j) { + if (p1->flags & NSVG_PT_CORNER) { + if (lineJoin == NSVG_JOIN_ROUND) + nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap); + else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL)) + nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth); + else + nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth); + } else { + nsvg__straightJoin(r, &left, &right, p1, lineWidth); + } + p0 = p1++; + } + + if (closed) { + // Loop it + nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y); + nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y); + } else { + // Add cap + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + nsvg__normalize(&dx, &dy); + if (lineCap == NSVG_CAP_BUTT) + nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); + else if (lineCap == NSVG_CAP_SQUARE) + nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); + else if (lineCap == NSVG_CAP_ROUND) + nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1); + } +} + +static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin) +{ + int i, j; + NSVGpoint* p0, *p1; + + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + for (i = 0; i < r->npoints; i++) { + // Calculate segment direction and length + p0->dx = p1->x - p0->x; + p0->dy = p1->y - p0->y; + p0->len = nsvg__normalize(&p0->dx, &p0->dy); + // Advance + p0 = p1++; + } + + // calculate joins + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + for (j = 0; j < r->npoints; j++) { + float dlx0, dly0, dlx1, dly1, dmr2, cross; + dlx0 = p0->dy; + dly0 = -p0->dx; + dlx1 = p1->dy; + dly1 = -p1->dx; + // Calculate extrusions + p1->dmx = (dlx0 + dlx1) * 0.5f; + p1->dmy = (dly0 + dly1) * 0.5f; + dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy; + if (dmr2 > 0.000001f) { + float s2 = 1.0f / dmr2; + if (s2 > 600.0f) { + s2 = 600.0f; + } + p1->dmx *= s2; + p1->dmy *= s2; + } + + // Clear flags, but keep the corner. + p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0; + + // Keep track of left turns. + cross = p1->dx * p0->dy - p0->dx * p1->dy; + if (cross > 0.0f) + p1->flags |= NSVG_PT_LEFT; + + // Check to see if the corner needs to be beveled. + if (p1->flags & NSVG_PT_CORNER) { + if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) { + p1->flags |= NSVG_PT_BEVEL; + } + } + + p0 = p1++; + } +} + +static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale) +{ + int i, j, closed; + NSVGpath* path; + NSVGpoint* p0, *p1; + float miterLimit = shape->miterLimit; + int lineJoin = shape->strokeLineJoin; + int lineCap = shape->strokeLineCap; + float lineWidth = shape->strokeWidth * scale; + + for (path = shape->paths; path != NULL; path = path->next) { + // Flatten path + r->npoints = 0; + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER); + for (i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER); + } + if (r->npoints < 2) + continue; + + closed = path->closed; + + // If the first and last points are the same, remove the last, mark as closed path. + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) { + r->npoints--; + p0 = &r->points[r->npoints-1]; + closed = 1; + } + + if (shape->strokeDashCount > 0) { + int idash = 0, dashState = 1; + float totalDist = 0, dashLen, allDashLen, dashOffset; + NSVGpoint cur; + + if (closed) + nsvg__appendPathPoint(r, r->points[0]); + + // Duplicate points -> points2. + nsvg__duplicatePoints(r); + + r->npoints = 0; + cur = r->points2[0]; + nsvg__appendPathPoint(r, cur); + + // Figure out dash offset. + allDashLen = 0; + for (j = 0; j < shape->strokeDashCount; j++) + allDashLen += shape->strokeDashArray[j]; + if (shape->strokeDashCount & 1) + allDashLen *= 2.0f; + // Find location inside pattern + dashOffset = fmodf(shape->strokeDashOffset, allDashLen); + if (dashOffset < 0.0f) + dashOffset += allDashLen; + + while (dashOffset > shape->strokeDashArray[idash]) { + dashOffset -= shape->strokeDashArray[idash]; + idash = (idash + 1) % shape->strokeDashCount; + } + dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale; + + for (j = 1; j < r->npoints2; ) { + float dx = r->points2[j].x - cur.x; + float dy = r->points2[j].y - cur.y; + float dist = sqrtf(dx*dx + dy*dy); + + if ((totalDist + dist) > dashLen) { + // Calculate intermediate point + float d = (dashLen - totalDist) / dist; + float x = cur.x + dx * d; + float y = cur.y + dy * d; + nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER); + + // Stroke + if (r->npoints > 1 && dashState) { + nsvg__prepareStroke(r, miterLimit, lineJoin); + nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); + } + // Advance dash pattern + dashState = !dashState; + idash = (idash+1) % shape->strokeDashCount; + dashLen = shape->strokeDashArray[idash] * scale; + // Restart + cur.x = x; + cur.y = y; + cur.flags = NSVG_PT_CORNER; + totalDist = 0.0f; + r->npoints = 0; + nsvg__appendPathPoint(r, cur); + } else { + totalDist += dist; + cur = r->points2[j]; + nsvg__appendPathPoint(r, cur); + j++; + } + } + // Stroke any leftover path + if (r->npoints > 1 && dashState) + nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); + } else { + nsvg__prepareStroke(r, miterLimit, lineJoin); + nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth); + } + } +} + +static int nsvg__cmpEdge(const void *p, const void *q) +{ + const NSVGedge* a = (const NSVGedge*)p; + const NSVGedge* b = (const NSVGedge*)q; + + if (a->y0 < b->y0) return -1; + if (a->y0 > b->y0) return 1; + return 0; +} + + +static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint) +{ + NSVGactiveEdge* z; + + if (r->freelist != NULL) { + // Restore from freelist. + z = r->freelist; + r->freelist = z->next; + } else { + // Alloc new edge. + z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge)); + if (z == NULL) return NULL; + } + + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); +// STBTT_assert(e->y0 <= start_point); + // round dx down to avoid going too far + if (dxdy < 0) + z->dx = (int)(-floorf(NSVG__FIX * -dxdy)); + else + z->dx = (int)floorf(NSVG__FIX * dxdy); + z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); +// z->x -= off_x * FIX; + z->ey = e->y1; + z->next = 0; + z->dir = e->dir; + + return z; +} + +static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z) +{ + z->next = r->freelist; + r->freelist = z; +} + +static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax) +{ + int i = x0 >> NSVG__FIXSHIFT; + int j = x1 >> NSVG__FIXSHIFT; + if (i < *xmin) *xmin = i; + if (j > *xmax) *xmax = j; + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT)); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT)); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT)); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = (unsigned char)(scanline[i] + maxWeight); + } + } +} + +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule) +{ + // non-zero winding fill + int x0 = 0, w = 0; + + if (fillRule == NSVG_FILLRULE_NONZERO) { + // Non-zero + while (e != NULL) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->dir; + } else { + int x1 = e->x; w += e->dir; + // if we went to zero, we need to draw + if (w == 0) + nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); + } + e = e->next; + } + } else if (fillRule == NSVG_FILLRULE_EVENODD) { + // Even-odd + while (e != NULL) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w = 1; + } else { + int x1 = e->x; w = 0; + nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); + } + e = e->next; + } + } +} + +static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } + +static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + return ((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24); +} + +static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u) +{ + int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); + int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8; + int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8; + int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8; + int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8; + return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); +} + +static unsigned int nsvg__applyOpacity(unsigned int c, float u) +{ + int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); + int r = (c) & 0xff; + int g = (c>>8) & 0xff; + int b = (c>>16) & 0xff; + int a = (((c>>24) & 0xff)*iu) >> 8; + return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); +} + +static inline int nsvg__div255(int x) +{ + return ((x+1) * 257) >> 16; +} + +static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y, + float tx, float ty, float scale, NSVGcachedPaint* cache) +{ + + if (cache->type == NSVG_PAINT_COLOR) { + int i, cr, cg, cb, ca; + cr = cache->colors[0] & 0xff; + cg = (cache->colors[0] >> 8) & 0xff; + cb = (cache->colors[0] >> 16) & 0xff; + ca = (cache->colors[0] >> 24) & 0xff; + + for (i = 0; i < count; i++) { + int r,g,b; + int a = nsvg__div255((int)cover[0] * ca); + int ia = 255 - a; + // Premultiply + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); + + // Blend over + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); + + dst[0] = (unsigned char)r; + dst[1] = (unsigned char)g; + dst[2] = (unsigned char)b; + dst[3] = (unsigned char)a; + + cover++; + dst += 4; + } + } else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) { + // TODO: spread modes. + // TODO: plenty of opportunities to optimize. + float fx, fy, dx, gy; + float* t = cache->xform; + int i, cr, cg, cb, ca; + unsigned int c; + + fx = ((float)x - tx) / scale; + fy = ((float)y - ty) / scale; + dx = 1.0f / scale; + + for (i = 0; i < count; i++) { + int r,g,b,a,ia; + gy = fx*t[1] + fy*t[3] + t[5]; + c = cache->colors[(int)nsvg__clampf(gy*255.0f, 0, 255.0f)]; + cr = (c) & 0xff; + cg = (c >> 8) & 0xff; + cb = (c >> 16) & 0xff; + ca = (c >> 24) & 0xff; + + a = nsvg__div255((int)cover[0] * ca); + ia = 255 - a; + + // Premultiply + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); + + // Blend over + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); + + dst[0] = (unsigned char)r; + dst[1] = (unsigned char)g; + dst[2] = (unsigned char)b; + dst[3] = (unsigned char)a; + + cover++; + dst += 4; + fx += dx; + } + } else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) { + // TODO: spread modes. + // TODO: plenty of opportunities to optimize. + // TODO: focus (fx,fy) + float fx, fy, dx, gx, gy, gd; + float* t = cache->xform; + int i, cr, cg, cb, ca; + unsigned int c; + + fx = ((float)x - tx) / scale; + fy = ((float)y - ty) / scale; + dx = 1.0f / scale; + + for (i = 0; i < count; i++) { + int r,g,b,a,ia; + gx = fx*t[0] + fy*t[2] + t[4]; + gy = fx*t[1] + fy*t[3] + t[5]; + gd = sqrtf(gx*gx + gy*gy); + c = cache->colors[(int)nsvg__clampf(gd*255.0f, 0, 255.0f)]; + cr = (c) & 0xff; + cg = (c >> 8) & 0xff; + cb = (c >> 16) & 0xff; + ca = (c >> 24) & 0xff; + + a = nsvg__div255((int)cover[0] * ca); + ia = 255 - a; + + // Premultiply + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); + + // Blend over + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); + + dst[0] = (unsigned char)r; + dst[1] = (unsigned char)g; + dst[2] = (unsigned char)b; + dst[3] = (unsigned char)a; + + cover++; + dst += 4; + fx += dx; + } + } +} + +static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule) +{ + NSVGactiveEdge *active = NULL; + int y, s; + int e = 0; + int maxWeight = (255 / NSVG__SUBSAMPLES); // weight per vertical scanline + int xmin, xmax; + + for (y = 0; y < r->height; y++) { + memset(r->scanline, 0, r->width); + xmin = r->width; + xmax = 0; + for (s = 0; s < NSVG__SUBSAMPLES; ++s) { + // find center of pixel for this scanline + float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f; + NSVGactiveEdge **step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) { + NSVGactiveEdge *z = *step; + if (z->ey <= scany) { + *step = z->next; // delete from list +// NSVG__assert(z->valid); + nsvg__freeActive(r, z); + } else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for (;;) { + int changed = 0; + step = &active; + while (*step && (*step)->next) { + if ((*step)->x > (*step)->next->x) { + NSVGactiveEdge* t = *step; + NSVGactiveEdge* q = t->next; + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e < r->nedges && r->edges[e].y0 <= scany) { + if (r->edges[e].y1 > scany) { + NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany); + if (z == NULL) break; + // find insertion point + if (active == NULL) { + active = z; + } else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + NSVGactiveEdge* p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + e++; + } + + // now process all active edges in non-zero fashion + if (active != NULL) + nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule); + } + // Blit + if (xmin < 0) xmin = 0; + if (xmax > r->width-1) xmax = r->width-1; + if (xmin <= xmax) { + nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache); + } + } + +} + +static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride) +{ + int x,y; + + // Unpremultiply + for (y = 0; y < h; y++) { + unsigned char *row = &image[y*stride]; + for (x = 0; x < w; x++) { + int r = row[0], g = row[1], b = row[2], a = row[3]; + if (a != 0) { + row[0] = (unsigned char)(r*255/a); + row[1] = (unsigned char)(g*255/a); + row[2] = (unsigned char)(b*255/a); + } + row += 4; + } + } + + // Defringe + for (y = 0; y < h; y++) { + unsigned char *row = &image[y*stride]; + for (x = 0; x < w; x++) { + int r = 0, g = 0, b = 0, a = row[3], n = 0; + if (a == 0) { + if (x-1 > 0 && row[-1] != 0) { + r += row[-4]; + g += row[-3]; + b += row[-2]; + n++; + } + if (x+1 < w && row[7] != 0) { + r += row[4]; + g += row[5]; + b += row[6]; + n++; + } + if (y-1 > 0 && row[-stride+3] != 0) { + r += row[-stride]; + g += row[-stride+1]; + b += row[-stride+2]; + n++; + } + if (y+1 < h && row[stride+3] != 0) { + r += row[stride]; + g += row[stride+1]; + b += row[stride+2]; + n++; + } + if (n > 0) { + row[0] = (unsigned char)(r/n); + row[1] = (unsigned char)(g/n); + row[2] = (unsigned char)(b/n); + } + } + row += 4; + } + } +} + + +static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity) +{ + int i, j; + NSVGgradient* grad; + + cache->type = paint->type; + + if (paint->type == NSVG_PAINT_COLOR) { + cache->colors[0] = nsvg__applyOpacity(paint->color, opacity); + return; + } + + grad = paint->gradient; + + cache->spread = grad->spread; + memcpy(cache->xform, grad->xform, sizeof(float)*6); + + if (grad->nstops == 0) { + for (i = 0; i < 256; i++) + cache->colors[i] = 0; + } if (grad->nstops == 1) { + for (i = 0; i < 256; i++) + cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity); + } else { + unsigned int ca, cb = 0; + float ua, ub, du, u; + int ia, ib, count; + + ca = nsvg__applyOpacity(grad->stops[0].color, opacity); + ua = nsvg__clampf(grad->stops[0].offset, 0, 1); + ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1); + ia = (int)(ua * 255.0f); + ib = (int)(ub * 255.0f); + for (i = 0; i < ia; i++) { + cache->colors[i] = ca; + } + + for (i = 0; i < grad->nstops-1; i++) { + ca = nsvg__applyOpacity(grad->stops[i].color, opacity); + cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity); + ua = nsvg__clampf(grad->stops[i].offset, 0, 1); + ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1); + ia = (int)(ua * 255.0f); + ib = (int)(ub * 255.0f); + count = ib - ia; + if (count <= 0) continue; + u = 0; + du = 1.0f / (float)count; + for (j = 0; j < count; j++) { + cache->colors[ia+j] = nsvg__lerpRGBA(ca,cb,u); + u += du; + } + } + + for (i = ib; i < 256; i++) + cache->colors[i] = cb; + } + +} + +/* +static void dumpEdges(NSVGrasterizer* r, const char* name) +{ + float xmin = 0, xmax = 0, ymin = 0, ymax = 0; + NSVGedge *e = NULL; + int i; + if (r->nedges == 0) return; + FILE* fp = fopen(name, "w"); + if (fp == NULL) return; + + xmin = xmax = r->edges[0].x0; + ymin = ymax = r->edges[0].y0; + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + xmin = nsvg__minf(xmin, e->x0); + xmin = nsvg__minf(xmin, e->x1); + xmax = nsvg__maxf(xmax, e->x0); + xmax = nsvg__maxf(xmax, e->x1); + ymin = nsvg__minf(ymin, e->y0); + ymin = nsvg__minf(ymin, e->y1); + ymax = nsvg__maxf(ymax, e->y0); + ymax = nsvg__maxf(ymax, e->y1); + } + + fprintf(fp, "", xmin, ymin, (xmax - xmin), (ymax - ymin)); + + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + fprintf(fp ,"", e->x0,e->y0, e->x1,e->y1); + } + + for (i = 0; i < r->npoints; i++) { + if (i+1 < r->npoints) + fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y); + fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0"); + } + + fprintf(fp, ""); + fclose(fp); +} +*/ + +void nsvgRasterize(NSVGrasterizer* r, + NSVGimage* image, float tx, float ty, float scale, + unsigned char* dst, int w, int h, int stride) +{ + NSVGshape *shape = NULL; + NSVGedge *e = NULL; + NSVGcachedPaint cache; + int i; + + r->bitmap = dst; + r->width = w; + r->height = h; + r->stride = stride; + + if (w > r->cscanline) { + r->cscanline = w; + r->scanline = (unsigned char*)realloc(r->scanline, w); + if (r->scanline == NULL) return; + } + + for (i = 0; i < h; i++) + memset(&dst[i*stride], 0, w*4); + + for (shape = image->shapes; shape != NULL; shape = shape->next) { + if (!(shape->flags & NSVG_FLAGS_VISIBLE)) + continue; + + if (shape->fill.type != NSVG_PAINT_NONE) { + nsvg__resetPool(r); + r->freelist = NULL; + r->nedges = 0; + + nsvg__flattenShape(r, shape, scale); + + // Scale and translate edges + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + e->x0 = tx + e->x0; + e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; + e->x1 = tx + e->x1; + e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; + } + + // Rasterize edges + if (r->nedges != 0) + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + nsvg__initPaint(&cache, &shape->fill, shape->opacity); + + nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule); + } + if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) { + nsvg__resetPool(r); + r->freelist = NULL; + r->nedges = 0; + + nsvg__flattenShapeStroke(r, shape, scale); + +// dumpEdges(r, "edge.svg"); + + // Scale and translate edges + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + e->x0 = tx + e->x0; + e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; + e->x1 = tx + e->x1; + e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; + } + + // Rasterize edges + if (r->nedges != 0) + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + nsvg__initPaint(&cache, &shape->stroke, shape->opacity); + + nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO); + } + } + + nsvg__unpremultiplyAlpha(dst, w, h, stride); + + r->bitmap = NULL; + r->width = 0; + r->height = 0; + r->stride = 0; +} + +#endif // NANOSVGRAST_IMPLEMENTATION + +#endif // NANOSVGRAST_H diff --git a/src/raylib.h b/src/raylib.h index 6f67d839e455..198c6c497a7a 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1245,6 +1245,8 @@ 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 *fileName, int width, int height); // Load image from SVG file data with specified size +RLAPI Image LoadImageSvgFromString(const char *string, int width, int height); // Load an image from a SVG string with custom 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 diff --git a/src/rtextures.c b/src/rtextures.c index 566371112a46..09202ef7736d 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -215,6 +215,14 @@ #define STB_IMAGE_RESIZE_IMPLEMENTATION #include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() [ImageResize()] +#if defined(SUPPORT_FILEFORMAT_SVG) + #define NANOSVG_IMPLEMENTATION // Expands implementation + #include "external/nanosvg.h" + + #define NANOSVGRAST_IMPLEMENTATION + #include "external/nanosvgrast.h" +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -310,6 +318,72 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int return image; } +// Load an image from SVG file data with a custom size +Image LoadImageSvg(const char *fileName, int width, int height) +{ + Image image = { 0 }; + + unsigned int dataSize = 0; + unsigned char *string = LoadFileData(fileName, &dataSize); + + if (string != NULL) + { + image = LoadImageSvgFromString(string, width, height); + RL_FREE(string); + } + + return image; +} + +// Load an image from a SVG string with custom size +Image LoadImageSvgFromString(const char *string, int width, int height) +{ + Image image = { 0 }; + + if (string != NULL) + { + struct NSVGimage *svgImage = nsvgParse(string, "px", 96.0f); + + // Allocate memory for image + unsigned char *img = malloc(width*height*4); + + // Calculate scales for both the width and the height + const float scaleWidth = width/svgImage->width; + const float scaleHeight = height/svgImage->height; + + // Set the largest of the 2 scales to be the scale to use + const float scale = (scaleHeight > scaleWidth) ? scaleWidth : scaleHeight; + + int offsetX = 0; + int offsetY = 0; + + if (scaleHeight > scaleWidth) + { + offsetY = (height - svgImage->height*scale) / 2; + } + else + { + offsetX = (width - svgImage->width*scale) / 2; + } + + // Rasterize + struct NSVGrasterizer* rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4); + + // Populate image struct with all data + image.data = img; + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + + // Delete + nsvgDelete(svgImage); + } + + return image; +} + // Load animated image data // - Image.data buffer includes all frames: [image#0][image#1][image#2][...] // - Number of frames is returned through 'frames' parameter @@ -470,6 +544,27 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i { image.data = rl_load_astc_from_memory(fileData, dataSize, &image.width, &image.height, &image.format, &image.mipmaps); } +#endif +#if defined(SUPPORT_FILEFORMAT_SVG) + else if (strcmp(fileType, ".svg") == 0) + { + if (fileData != NULL) + { + // Creating a duplicate svg to read sizes from due to nsvgParse modifiying the string buffer. + unsigned char *duplicate = (unsigned char*)RL_MALLOC(dataSize); + memcpy(duplicate, fileData, dataSize); + struct NSVGimage *svgImage = nsvgParse(duplicate, "px", 96.0f); + RL_FREE(duplicate); + + const int width = (int)svgImage->width; + const int height = (int)svgImage->height; + // Delete + nsvgDelete(svgImage); + + + image = LoadImageSvgFromString(fileData, width, height); + } + } #endif else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported"); From 7016f32d4ef3e59847e418a95402400d61f86ecf Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 2 Sep 2023 13:16:44 +0200 Subject: [PATCH 48/89] REVIEWED: `LoadImageSvg()` --- src/raylib.h | 3 +- src/rtextures.c | 134 +++++++++++++++++++++++------------------------- 2 files changed, 65 insertions(+), 72 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 198c6c497a7a..4f3e353807c4 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1245,8 +1245,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 *fileName, int width, int height); // Load image from SVG file data with specified size -RLAPI Image LoadImageSvgFromString(const char *string, int width, int height); // Load an image from a SVG string with custom size +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 diff --git a/src/rtextures.c b/src/rtextures.c index 09202ef7736d..6b7875b08d7d 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -318,67 +318,60 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int return image; } -// Load an image from SVG file data with a custom size -Image LoadImageSvg(const char *fileName, int width, int height) +// Load an image from a SVG file or string with custom size +Image LoadImageSvg(const char *fileNameOrString, int width, int height) { Image image = { 0 }; - - unsigned int dataSize = 0; - unsigned char *string = LoadFileData(fileName, &dataSize); - - if (string != NULL) + bool isSvgStringValid = false; + + // TODO: Validate fileName or string + if (fileNameOrString != NULL) { - image = LoadImageSvgFromString(string, width, height); - RL_FREE(string); - } + if (FileExists(fileNameOrString)) + { + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileNameOrString, &dataSize); + isSvgStringValid = true; + } + else + { + // TODO: Validate it's a valid SVG string + isSvgStringValid = true; + } - return image; -} + if (isSvgStringValid != NULL) + { + struct NSVGimage *svgImage = nsvgParse(fileNameOrString, "px", 96.0f); + + unsigned char *img = RL_MALLOC(width*height*4); -// Load an image from a SVG string with custom size -Image LoadImageSvgFromString(const char *string, int width, int height) -{ - Image image = { 0 }; + // Calculate scales for both the width and the height + const float scaleWidth = width/svgImage->width; + const float scaleHeight = height/svgImage->height; - if (string != NULL) - { - struct NSVGimage *svgImage = nsvgParse(string, "px", 96.0f); + // Set the largest of the 2 scales to be the scale to use + const float scale = (scaleHeight > scaleWidth)? scaleWidth : scaleHeight; - // Allocate memory for image - unsigned char *img = malloc(width*height*4); + int offsetX = 0; + int offsetY = 0; - // Calculate scales for both the width and the height - const float scaleWidth = width/svgImage->width; - const float scaleHeight = height/svgImage->height; + if (scaleHeight > scaleWidth) offsetY = (height - svgImage->height*scale) / 2; + else offsetX = (width - svgImage->width*scale) / 2; - // Set the largest of the 2 scales to be the scale to use - const float scale = (scaleHeight > scaleWidth) ? scaleWidth : scaleHeight; + // Rasterize + struct NSVGrasterizer *rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4); - int offsetX = 0; - int offsetY = 0; + // Populate image struct with all data + image.data = img; + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; - if (scaleHeight > scaleWidth) - { - offsetY = (height - svgImage->height*scale) / 2; - } - else - { - offsetX = (width - svgImage->width*scale) / 2; + // Free used memory + nsvgDelete(svgImage); } - - // Rasterize - struct NSVGrasterizer* rast = nsvgCreateRasterizer(); - nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4); - - // Populate image struct with all data - image.data = img; - image.width = width; - image.height = height; - image.mipmaps = 1; - image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; - - // Delete - nsvgDelete(svgImage); } return image; @@ -515,6 +508,28 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i image.mipmaps = 1; } #endif +#if defined(SUPPORT_FILEFORMAT_SVG) + else if ((strcmp(fileType, ".svg") == 0) || (strcmp(fileType, ".SVG") == 0)) + { + // TODO: Validate fileData as valid SVG string data + + struct NSVGimage *svgImage = nsvgParse(fileData, "px", 96.0f); + unsigned char *img = RL_MALLOC(svgImage->width*svgImage->height*4); + + // Rasterize + struct NSVGrasterizer *rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, svgImage, 0, 0, 1.0f, img, svgImage->width, svgImage->height, svgImage->width*4); + + // Populate image struct with all data + image.data = img; + image.width = svgImage->width; + image.height = svgImage->height; + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + + nsvgDelete(svgImage); + } +#endif #if defined(SUPPORT_FILEFORMAT_DDS) else if ((strcmp(fileType, ".dds") == 0) || (strcmp(fileType, ".DDS") == 0)) { @@ -544,27 +559,6 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i { image.data = rl_load_astc_from_memory(fileData, dataSize, &image.width, &image.height, &image.format, &image.mipmaps); } -#endif -#if defined(SUPPORT_FILEFORMAT_SVG) - else if (strcmp(fileType, ".svg") == 0) - { - if (fileData != NULL) - { - // Creating a duplicate svg to read sizes from due to nsvgParse modifiying the string buffer. - unsigned char *duplicate = (unsigned char*)RL_MALLOC(dataSize); - memcpy(duplicate, fileData, dataSize); - struct NSVGimage *svgImage = nsvgParse(duplicate, "px", 96.0f); - RL_FREE(duplicate); - - const int width = (int)svgImage->width; - const int height = (int)svgImage->height; - // Delete - nsvgDelete(svgImage); - - - image = LoadImageSvgFromString(fileData, width, height); - } - } #endif else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported"); From 0a5c476b0a46f9aaddf0ebef72fa536898bc6da8 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 2 Sep 2023 19:20:56 +0200 Subject: [PATCH 49/89] REVIEWED: `LoadImageSvg()` --- src/rtextures.c | 81 +++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/src/rtextures.c b/src/rtextures.c index 6b7875b08d7d..3092071fdb5d 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -324,24 +324,35 @@ Image LoadImageSvg(const char *fileNameOrString, int width, int height) Image image = { 0 }; bool isSvgStringValid = false; - // TODO: Validate fileName or string + // Validate fileName or string if (fileNameOrString != NULL) { + int dataSize = 0; + unsigned char *fileData = NULL; + if (FileExists(fileNameOrString)) { - int dataSize = 0; - unsigned char *fileData = LoadFileData(fileNameOrString, &dataSize); + fileData = LoadFileData(fileNameOrString, &dataSize); isSvgStringValid = true; } else { - // TODO: Validate it's a valid SVG string - isSvgStringValid = true; + // Validate fileData as valid SVG string data + // + if ((fileNameOrString != NULL) && + (fileNameOrString[0] == '<') && + (fileNameOrString[1] == 's') && + (fileNameOrString[2] == 'v') && + (fileNameOrString[3] == 'g')) + { + fileData = fileNameOrString; + isSvgStringValid = true; + } } - if (isSvgStringValid != NULL) + if (isSvgStringValid) { - struct NSVGimage *svgImage = nsvgParse(fileNameOrString, "px", 96.0f); + struct NSVGimage *svgImage = nsvgParse(fileData, "px", 96.0f); unsigned char *img = RL_MALLOC(width*height*4); @@ -372,6 +383,8 @@ Image LoadImageSvg(const char *fileNameOrString, int width, int height) // Free used memory nsvgDelete(svgImage); } + + if (isSvgStringValid && (fileData != fileNameOrString)) UnloadFileData(fileData); } return image; @@ -500,34 +513,44 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i #if defined(SUPPORT_FILEFORMAT_QOI) else if ((strcmp(fileType, ".qoi") == 0) || (strcmp(fileType, ".QOI") == 0)) { - qoi_desc desc = { 0 }; - image.data = qoi_decode(fileData, dataSize, &desc, 4); - image.width = desc.width; - image.height = desc.height; - image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; - image.mipmaps = 1; + if (fileData != NULL) + { + qoi_desc desc = { 0 }; + image.data = qoi_decode(fileData, dataSize, &desc, 4); + image.width = desc.width; + image.height = desc.height; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + image.mipmaps = 1; + } } #endif #if defined(SUPPORT_FILEFORMAT_SVG) else if ((strcmp(fileType, ".svg") == 0) || (strcmp(fileType, ".SVG") == 0)) { - // TODO: Validate fileData as valid SVG string data - - struct NSVGimage *svgImage = nsvgParse(fileData, "px", 96.0f); - unsigned char *img = RL_MALLOC(svgImage->width*svgImage->height*4); - - // Rasterize - struct NSVGrasterizer *rast = nsvgCreateRasterizer(); - nsvgRasterize(rast, svgImage, 0, 0, 1.0f, img, svgImage->width, svgImage->height, svgImage->width*4); - - // Populate image struct with all data - image.data = img; - image.width = svgImage->width; - image.height = svgImage->height; - image.mipmaps = 1; - image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + // Validate fileData as valid SVG string data + // + if ((fileData != NULL) && + (fileData[0] == '<') && + (fileData[1] == 's') && + (fileData[2] == 'v') && + (fileData[3] == 'g')) + { + struct NSVGimage *svgImage = nsvgParse(fileData, "px", 96.0f); + unsigned char *img = RL_MALLOC(svgImage->width*svgImage->height*4); + + // Rasterize + struct NSVGrasterizer *rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, svgImage, 0, 0, 1.0f, img, svgImage->width, svgImage->height, svgImage->width*4); + + // Populate image struct with all data + image.data = img; + image.width = svgImage->width; + image.height = svgImage->height; + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; - nsvgDelete(svgImage); + nsvgDelete(svgImage); + } } #endif #if defined(SUPPORT_FILEFORMAT_DDS) From fda2d0f5060424ed936de8e5e08dec5a274e34ff Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Sat, 2 Sep 2023 17:38:10 -0300 Subject: [PATCH 50/89] Add SUPPORT_FILEFORMAT_SVG to cmake (#3284) --- CMakeOptions.txt | 1 + cmake/CompileDefinitions.cmake | 1 + 2 files changed, 2 insertions(+) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 83faa5637814..260522340b63 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -71,6 +71,7 @@ cmake_dependent_option(SUPPORT_FILEFORMAT_QOI "Support loading QOI as textures" cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF) +cmake_dependent_option(SUPPORT_FILEFORMAT_SVG "Support loading SVG as textures" ON CUSTOMIZE_BUILD ON) # rtext.c cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON) diff --git a/cmake/CompileDefinitions.cmake b/cmake/CompileDefinitions.cmake index 1458e2f3ca27..68c53d7a1282 100644 --- a/cmake/CompileDefinitions.cmake +++ b/cmake/CompileDefinitions.cmake @@ -49,6 +49,7 @@ if (${CUSTOMIZE_BUILD}) define_if("raylib" SUPPORT_FILEFORMAT_PSD) define_if("raylib" SUPPORT_FILEFORMAT_PKM) define_if("raylib" SUPPORT_FILEFORMAT_PVR) + define_if("raylib" SUPPORT_FILEFORMAT_SVG) define_if("raylib" SUPPORT_FILEFORMAT_FNT) define_if("raylib" SUPPORT_FILEFORMAT_TTF) define_if("raylib" SUPPORT_TEXT_MANIPULATION) From e330f7d17d7f792a8810e85c803f30152eee3d54 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Sat, 2 Sep 2023 17:50:59 -0300 Subject: [PATCH 51/89] Fix examples/textures/textures_fog_of_war.c help instructions (#3285) --- examples/textures/textures_fog_of_war.c | 3 ++- examples/textures/textures_fog_of_war.png | Bin 38477 -> 37736 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/textures/textures_fog_of_war.c b/examples/textures/textures_fog_of_war.c index 433f364a651b..516055aebeb5 100644 --- a/examples/textures/textures_fog_of_war.c +++ b/examples/textures/textures_fog_of_war.c @@ -134,7 +134,8 @@ int main(void) (Vector2){ 0, 0 }, 0.0f, WHITE); // Draw player current tile - DrawText(TextFormat("Current tile: [%i,%i]", playerTileX, playerTileY), 10, 10, 20, LIME); + DrawText(TextFormat("Current tile: [%i,%i]", playerTileX, playerTileY), 10, 10, 20, RAYWHITE); + DrawText("ARROW KEYS to move", 10, screenHeight-25, 20, RAYWHITE); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/textures/textures_fog_of_war.png b/examples/textures/textures_fog_of_war.png index 6a91316ee53a91cc63262e31e3b1bf615c6220de..01563c3906f256433bc11af25d2a2a95517bd22b 100644 GIT binary patch literal 37736 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 O&$r*q2{_}&PyRpTk3qHo literal 38477 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 Date: Sun, 3 Sep 2023 06:03:00 -0300 Subject: [PATCH 52/89] Fix examples/textures/textures_image_rotate.c help instructions (#3286) --- examples/textures/textures_image_rotate.c | 4 +++- examples/textures/textures_image_rotate.png | Bin 24060 -> 35476 bytes 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/textures/textures_image_rotate.c b/examples/textures/textures_image_rotate.c index a590e1e0afaf..e5c735732f03 100644 --- a/examples/textures/textures_image_rotate.c +++ b/examples/textures/textures_image_rotate.c @@ -64,6 +64,8 @@ int main(void) DrawTexture(textures[currentTexture], screenWidth/2 - textures[currentTexture].width/2, screenHeight/2 - textures[currentTexture].height/2, WHITE); + DrawText("Press LEFT MOUSE BUTTON to rotate the image clockwise", 250, 420, 10, DARKGRAY); + EndDrawing(); //---------------------------------------------------------------------------------- } @@ -76,4 +78,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/examples/textures/textures_image_rotate.png b/examples/textures/textures_image_rotate.png index 64bbc54e496f4587e2609a58cea3ceee637123d1..862612e5ababd8a7c0034d173983f0f5c2931311 100644 GIT binary patch literal 35476 zcmeFZdpy(q|3AK&!{#`LoDZAH;R=m83v+0Q5M8BG%^{~G

    -PYomGl#oMQSGlHC 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 leEhsT8j7@l^pb#uA|Qewy(v{dKsuo+Eh0^N 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 From b29284eb37c9cc7837101a4578f79cdb3c11c56e Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 4 Sep 2023 18:43:03 +0200 Subject: [PATCH 53/89] Update rtextures.c --- src/rtextures.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rtextures.c b/src/rtextures.c index 3092071fdb5d..4e2fdbd9139d 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -324,6 +324,7 @@ Image LoadImageSvg(const char *fileNameOrString, int width, int height) Image image = { 0 }; bool isSvgStringValid = false; +#if defined(SUPPORT_FILEFORMAT_SVG) // Validate fileName or string if (fileNameOrString != NULL) { @@ -386,6 +387,9 @@ Image LoadImageSvg(const char *fileNameOrString, int width, int height) if (isSvgStringValid && (fileData != fileNameOrString)) UnloadFileData(fileData); } +#else + TRACELOG(LOG_WARNING, "SVG image support not enabled, image can not be loaded"); +#endif return image; } From a0922a2a92de773e3a23bac5892f944b912d42fc Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 4 Sep 2023 18:43:25 +0200 Subject: [PATCH 54/89] Fix #3247 --- src/rcore.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 912f85c0dad2..67907c367c93 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -887,9 +887,19 @@ void InitWindow(int width, int height, const char *title) // 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]; - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering - SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // WARNING: Module required: rshapes + 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) From 3ec569f2879dac0dff86b8262f6171eb64fee1ab Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 4 Sep 2023 18:51:44 +0200 Subject: [PATCH 55/89] Update config.h --- src/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.h b/src/config.h index 2c7d5e2d021d..3708376101ec 100644 --- a/src/config.h +++ b/src/config.h @@ -156,7 +156,7 @@ //#define SUPPORT_FILEFORMAT_ASTC 1 //#define SUPPORT_FILEFORMAT_PKM 1 //#define SUPPORT_FILEFORMAT_PVR 1 -#define SUPPORT_FILEFORMAT_SVG 1 +//#define SUPPORT_FILEFORMAT_SVG 1 // Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) #define SUPPORT_IMAGE_EXPORT 1 From 224f0af429a0f86122e60071a004e059ca8c7fc6 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 5 Sep 2023 20:04:21 +0200 Subject: [PATCH 56/89] Fix #3293 --- src/rtext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtext.c b/src/rtext.c index 5ca97d06d868..04d7a2a14265 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1075,7 +1075,7 @@ void DrawFPS(int posX, int posY) if ((fps < 30) && (fps >= 15)) color = ORANGE; // Warning FPS else if (fps < 15) color = RED; // Low FPS - DrawText(TextFormat("%2i FPS", GetFPS()), posX, posY, 20, color); + DrawText(TextFormat("%2i FPS", fps), posX, posY, 20, color); } // Draw text (using default font) From 4ed1caebe20a076d485d310018a34e2cd4a89bb5 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 5 Sep 2023 05:02:25 -0400 Subject: [PATCH 57/89] Disable UBSAN in zig builds. (#3292) Zig debug builds automatically enable ubsan. As the fix for #1891 had to be reverted, debug builds using zig will crash like so: ``` Illegal instruction at address 0x3237d2 raylib/src/rlgl.h:3690:91: 0x3237d2 in rlDrawVertexArrayElements (/home/rcorre/src/raylib-zig-template/raylib/src/rcore.c) glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)buffer + offset); ``` This disables UBSAN when using zig to build raylib. --- src/build.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/build.zig b/src/build.zig index 27250f5ff060..09d954bf5a9b 100644 --- a/src/build.zig +++ b/src/build.zig @@ -6,6 +6,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built "-std=gnu99", "-D_GNU_SOURCE", "-DGL_SILENCE_DEPRECATION=199309L", + "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 }; const raylib = b.addStaticLibrary(.{ From c440a5ea469c45b9b8695bf0460ee970a48b069d Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Tue, 5 Sep 2023 18:03:32 +0900 Subject: [PATCH 58/89] Update README.md (#3290) specially -> especially --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90de36ca5532..bff6980b0982 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **raylib is a simple and easy-to-use library to enjoy videogames programming.** -raylib is highly inspired by Borland BGI graphics lib and by XNA framework and it's specially well suited for prototyping, tooling, graphical applications, embedded systems and education. +raylib is highly inspired by Borland BGI graphics lib and by XNA framework and it's especially well suited for prototyping, tooling, graphical applications, embedded systems and education. *NOTE for ADVENTURERS: raylib is a programming library to enjoy videogames programming; no fancy interface, no visual helpers, no debug button... just coding in the most pure spartan-programmers way.* From 8a6c1b72b78749fd13722b167c3d420da235c021 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Tue, 5 Sep 2023 06:03:59 -0300 Subject: [PATCH 59/89] Update cmake SUPPORT_FILEFORMAT_SVG default value (#3291) --- CMakeOptions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 260522340b63..799530951e9b 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -71,7 +71,7 @@ cmake_dependent_option(SUPPORT_FILEFORMAT_QOI "Support loading QOI as textures" cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF) cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF) -cmake_dependent_option(SUPPORT_FILEFORMAT_SVG "Support loading SVG as textures" ON CUSTOMIZE_BUILD ON) +cmake_dependent_option(SUPPORT_FILEFORMAT_SVG "Support loading SVG as textures" ${OFF} CUSTOMIZE_BUILD OFF) # rtext.c cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON) From 3d9263062d8dac605c0c780a6eaf7e1e13ab12a1 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 6 Sep 2023 23:16:31 +0200 Subject: [PATCH 60/89] Mouse offset and scaling must be considered also on web! --- src/rcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 67907c367c93..138d3e4ad334 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -4051,7 +4051,7 @@ Vector2 GetMousePosition(void) { Vector2 position = { 0 }; -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) +#if defined(PLATFORM_ANDROID) //|| defined(PLATFORM_WEB) position = GetTouchPosition(0); #else position.x = (CORE.Input.Mouse.currentPosition.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x; From c0e525079ce4efb47aef1d233bc1f9362f022a9e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 6 Sep 2023 23:33:29 +0200 Subject: [PATCH 61/89] Update rcore.c --- src/rcore.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 138d3e4ad334..c930382396f5 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -49,9 +49,6 @@ * #define SUPPORT_MOUSE_GESTURES * Mouse gestures are directly mapped like touches and processed by gestures system. * -* #define SUPPORT_TOUCH_AS_MOUSE -* Touch input and mouse input are shared. Mouse functions also return touch information. -* * #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only) * Reconfigure standard input to receive key inputs, works with SSH connection. * WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other From 7026ede3c0b87bb6871c0f5b281936fbaef62730 Mon Sep 17 00:00:00 2001 From: SuperUserNameMan Date: Thu, 7 Sep 2023 17:35:02 +0200 Subject: [PATCH 62/89] Update Makefile : clean raygui.c & physac.c (#3296) --- src/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index e9b68cd930c7..ed75949384a7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -827,7 +827,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* + 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 ifeq ($(PLATFORM),PLATFORM_ANDROID) rm -fv $(NATIVE_APP_GLUE)/android_native_app_glue.o endif @@ -839,4 +839,6 @@ clean_shell_cmd: cd $(RAYLIB_RELEASE_PATH) & \ del lib$(RAYLIB_LIB_NAME).a /s & \ del lib$(RAYLIB_LIB_NAME)dll.a /s & \ - del $(RAYLIB_LIB_NAME).dll /s + del $(RAYLIB_LIB_NAME).dll /s & \ + del raygui.c /s & \ + del physac.c /s From 445f024106c125545bef9e4dc075b6fb392eeefd Mon Sep 17 00:00:00 2001 From: MichaelFiber <42419558+michaelfiber@users.noreply.github.com> Date: Thu, 7 Sep 2023 11:42:28 -0400 Subject: [PATCH 63/89] Remove PLATFORM_RPI (#3232) * Remove PLATFORM_RPI * remove build artifacts --------- Co-authored-by: MichaelFiber Co-authored-by: Ray --- cmake/LibraryConfigurations.cmake | 13 -- examples/Makefile | 50 +------ examples/Makefile.Web | 50 +------ examples/core/core_basic_window_web.c | 2 +- examples/core/core_input_gamepad.c | 9 +- examples/core/core_vr_simulator.c | 2 +- examples/models/models_skybox.c | 2 +- examples/others/raylib_opengl_interop.c | 2 +- examples/shaders/shaders_basic_lighting.c | 2 +- examples/shaders/shaders_custom_uniform.c | 2 +- examples/shaders/shaders_eratosthenes.c | 2 +- examples/shaders/shaders_fog.c | 2 +- examples/shaders/shaders_hot_reloading.c | 2 +- examples/shaders/shaders_hybrid_render.c | 2 +- examples/shaders/shaders_julia_set.c | 2 +- examples/shaders/shaders_lightmap.c | 2 +- examples/shaders/shaders_mesh_instancing.c | 2 +- examples/shaders/shaders_model_shader.c | 2 +- examples/shaders/shaders_multi_sample2d.c | 2 +- examples/shaders/shaders_palette_switch.c | 2 +- examples/shaders/shaders_postprocessing.c | 2 +- examples/shaders/shaders_raymarching.c | 2 +- examples/shaders/shaders_shapes_textures.c | 2 +- examples/shaders/shaders_simple_mask.c | 2 +- examples/shaders/shaders_spotlight.c | 2 +- examples/shaders/shaders_texture_drawing.c | 2 +- examples/shaders/shaders_texture_outline.c | 2 +- examples/shaders/shaders_texture_waves.c | 2 +- examples/shaders/shaders_write_depth.c | 2 +- examples/text/text_font_sdf.c | 2 +- projects/CMake/core_basic_window.c | 2 +- projects/VSCode/Makefile | 2 +- src/Makefile | 55 +------- src/rcore.c | 150 +++++---------------- src/rlgl.h | 2 +- 35 files changed, 70 insertions(+), 315 deletions(-) diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index d12df3a000b1..1debfeb421ff 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -73,19 +73,6 @@ elseif (${PLATFORM} MATCHES "Android") find_library(OPENGL_LIBRARY OpenGL) set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c) -elseif (${PLATFORM} MATCHES "Raspberry Pi") - set(PLATFORM_CPP "PLATFORM_RPI") - set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") - - add_definitions(-D_DEFAULT_SOURCE) - - find_library(GLESV2 brcmGLESv2 HINTS /opt/vc/lib) - find_library(EGL brcmEGL HINTS /opt/vc/lib) - find_library(BCMHOST bcm_host HINTS /opt/vc/lib) - include_directories(/opt/vc/include /opt/vc/include/interface/vmcs_host/linux /opt/vc/include/interface/vcos/pthreads) - link_directories(/opt/vc/lib) - set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl) - elseif ("${PLATFORM}" MATCHES "DRM") set(PLATFORM_CPP "PLATFORM_DRM") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") diff --git a/examples/Makefile b/examples/Makefile index 4ba4f1720edb..338fe168cab0 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -25,7 +25,7 @@ # Define required environment variables #------------------------------------------------------------------------------------------------ -# Define target platform: PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB +# Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB PLATFORM ?= PLATFORM_DESKTOP # Define required raylib variables @@ -58,15 +58,6 @@ BUILD_WEB_HEAP_SIZE ?= 134217728 BUILD_WEB_RESOURCES ?= TRUE BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources -# Use cross-compiler for PLATFORM_RPI -ifeq ($(PLATFORM),PLATFORM_RPI) - USE_RPI_CROSS_COMPILER ?= FALSE - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry - RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot - endif -endif - # Determine PLATFORM_OS in case PLATFORM_DESKTOP or PLATFORM_WEB selected ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! @@ -95,12 +86,6 @@ ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB)) endif endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - UNAMEOS = $(shell uname) - ifeq ($(UNAMEOS),Linux) - PLATFORM_OS = LINUX - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) UNAMEOS = $(shell uname) ifeq ($(UNAMEOS),Linux) @@ -118,9 +103,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif # Default path for raylib on Raspberry Pi -ifeq ($(PLATFORM),PLATFORM_RPI) - RAYLIB_PATH ?= /home/pi/raylib -endif ifeq ($(PLATFORM),PLATFORM_DRM) RAYLIB_PATH ?= /home/pi/raylib endif @@ -154,13 +136,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) CC = clang endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - # Define RPI cross-compiler - #CC = armv6j-hardfloat-linux-gnueabi-gcc - CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc - endif -endif ifeq ($(PLATFORM),PLATFORM_WEB) # HTML5 emscripten compiler # WARNING: To compile to HTML5, code must be redesigned @@ -231,9 +206,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - CFLAGS += -std=gnu99 -endif ifeq ($(PLATFORM),PLATFORM_DRM) CFLAGS += -std=gnu99 -DEGL_NO_X11 endif @@ -252,11 +224,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vmcs_host/linux - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vcos/pthreads -endif ifeq ($(PLATFORM),PLATFORM_DRM) INCLUDE_PATHS += -I/usr/include/libdrm endif @@ -328,9 +295,6 @@ ifeq ($(PLATFORM),PLATFORM_WEB) # logic to a self contained function: UpdateDrawFrame(), check core_basic_window_web.c for reference. endif -ifeq ($(PLATFORM),PLATFORM_RPI) - LDFLAGS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -endif # Define libraries required on linking: LDLIBS # NOTE: To link libraries (lib.so or lib.a), use -l @@ -381,14 +345,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDLIBS += -lglfw endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - # Libraries for Raspberry Pi compiling - # NOTE: Required packages: libasound2-dev (ALSA) - LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl -latomic - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - LDLIBS += -lvchiq_arm -lvcos - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) # Libraries for DRM compiling # NOTE: Required packages: libasound2-dev (ALSA) @@ -593,10 +549,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) rm -f *.o endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - find . -type f -executable -delete - rm -fv *.o -endif ifeq ($(PLATFORM),PLATFORM_DRM) find . -type f -executable -delete rm -fv *.o diff --git a/examples/Makefile.Web b/examples/Makefile.Web index ccb4550f9970..518fab9181f9 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -25,7 +25,7 @@ # Define required environment variables #------------------------------------------------------------------------------------------------ -# Define target platform: PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB +# Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB PLATFORM ?= PLATFORM_WEB # Define required raylib variables @@ -51,15 +51,6 @@ USE_EXTERNAL_GLFW ?= FALSE # NOTE: This variable is only used for PLATFORM_OS: LINUX USE_WAYLAND_DISPLAY ?= FALSE -# Use cross-compiler for PLATFORM_RPI -ifeq ($(PLATFORM),PLATFORM_RPI) - USE_RPI_CROSS_COMPILER ?= FALSE - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry - RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot - endif -endif - # Determine PLATFORM_OS in case PLATFORM_DESKTOP or PLATFORM_WEB selected ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! @@ -88,12 +79,6 @@ ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB)) endif endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - UNAMEOS = $(shell uname) - ifeq ($(UNAMEOS),Linux) - PLATFORM_OS = LINUX - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) UNAMEOS = $(shell uname) ifeq ($(UNAMEOS),Linux) @@ -111,9 +96,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif # Default path for raylib on Raspberry Pi -ifeq ($(PLATFORM),PLATFORM_RPI) - RAYLIB_PATH ?= /home/pi/raylib -endif ifeq ($(PLATFORM),PLATFORM_DRM) RAYLIB_PATH ?= /home/pi/raylib endif @@ -147,13 +129,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) CC = clang endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - # Define RPI cross-compiler - #CC = armv6j-hardfloat-linux-gnueabi-gcc - CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc - endif -endif ifeq ($(PLATFORM),PLATFORM_WEB) # HTML5 emscripten compiler # WARNING: To compile to HTML5, code must be redesigned @@ -224,9 +199,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - CFLAGS += -std=gnu99 -endif ifeq ($(PLATFORM),PLATFORM_DRM) CFLAGS += -std=gnu99 -DEGL_NO_X11 endif @@ -245,11 +217,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vmcs_host/linux - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vcos/pthreads -endif ifeq ($(PLATFORM),PLATFORM_DRM) INCLUDE_PATHS += -I/usr/include/libdrm endif @@ -304,9 +271,6 @@ ifeq ($(PLATFORM),PLATFORM_WEB) LDFLAGS += --shell-file $(RAYLIB_PATH)/src/shell.html EXT = .html endif -ifeq ($(PLATFORM),PLATFORM_RPI) - LDFLAGS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -endif # Define libraries required on linking: LDLIBS # NOTE: To link libraries (lib.so or lib.a), use -l @@ -357,14 +321,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDLIBS += -lglfw endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - # Libraries for Raspberry Pi compiling - # NOTE: Required packages: libasound2-dev (ALSA) - LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl -latomic - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - LDLIBS += -lvchiq_arm -lvcos - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) # Libraries for DRM compiling # NOTE: Required packages: libasound2-dev (ALSA) @@ -1067,10 +1023,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) rm -f *.o endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - find . -type f -executable -delete - rm -fv *.o -endif ifeq ($(PLATFORM),PLATFORM_DRM) find . -type f -executable -delete rm -fv *.o diff --git a/examples/core/core_basic_window_web.c b/examples/core/core_basic_window_web.c index 7d83254a1cb0..e0e1f9fb1183 100644 --- a/examples/core/core_basic_window_web.c +++ b/examples/core/core_basic_window_web.c @@ -2,7 +2,7 @@ * * raylib [core] example - Basic window (adapted for HTML5 platform) * -* NOTE: This example is prepared to compile for PLATFORM_WEB, PLATFORM_DESKTOP and PLATFORM_RPI +* NOTE: This example is prepared to compile for PLATFORM_WEB, and PLATFORM_DESKTOP * As you will notice, code structure is slightly diferent to the other examples... * To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning * diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index 1eb516e852a9..c28ff1f9eb3d 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -21,13 +21,8 @@ // NOTE: Gamepad name ID depends on drivers and OS #define XBOX360_LEGACY_NAME_ID "Xbox Controller" -#if defined(PLATFORM_RPI) - #define XBOX360_NAME_ID "Microsoft X-Box 360 pad" - #define PS3_NAME_ID "PLAYSTATION(R)3 Controller" -#else - #define XBOX360_NAME_ID "Xbox 360 Controller" - #define PS3_NAME_ID "PLAYSTATION(R)3 Controller" -#endif +#define XBOX360_NAME_ID "Xbox 360 Controller" +#define PS3_NAME_ID "PLAYSTATION(R)3 Controller" //------------------------------------------------------------------------------------ // Program main entry point diff --git a/examples/core/core_vr_simulator.c b/examples/core/core_vr_simulator.c index bc69cc69850c..fc2dee6b9f3f 100644 --- a/examples/core/core_vr_simulator.c +++ b/examples/core/core_vr_simulator.c @@ -15,7 +15,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c index 34616de59ca6..7a500e04d6f9 100644 --- a/examples/models/models_skybox.c +++ b/examples/models/models_skybox.c @@ -18,7 +18,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/others/raylib_opengl_interop.c b/examples/others/raylib_opengl_interop.c index bcdbbbdd5b4e..09b548c60b56 100644 --- a/examples/others/raylib_opengl_interop.c +++ b/examples/others/raylib_opengl_interop.c @@ -42,7 +42,7 @@ #endif #define GLSL_VERSION 330 #endif -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_basic_lighting.c b/examples/shaders/shaders_basic_lighting.c index 61cec2e808ec..3fbe60b83f7e 100644 --- a/examples/shaders/shaders_basic_lighting.c +++ b/examples/shaders/shaders_basic_lighting.c @@ -27,7 +27,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_custom_uniform.c b/examples/shaders/shaders_custom_uniform.c index eaeca5e517a0..0a1a76428b94 100644 --- a/examples/shaders/shaders_custom_uniform.c +++ b/examples/shaders/shaders_custom_uniform.c @@ -22,7 +22,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_eratosthenes.c b/examples/shaders/shaders_eratosthenes.c index a481f3008b00..005a97aeae49 100644 --- a/examples/shaders/shaders_eratosthenes.c +++ b/examples/shaders/shaders_eratosthenes.c @@ -29,7 +29,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_fog.c b/examples/shaders/shaders_fog.c index 24a1c106835a..cd36936d6b09 100644 --- a/examples/shaders/shaders_fog.c +++ b/examples/shaders/shaders_fog.c @@ -27,7 +27,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_hot_reloading.c b/examples/shaders/shaders_hot_reloading.c index 395d44cfe587..2b1175e4b673 100644 --- a/examples/shaders/shaders_hot_reloading.c +++ b/examples/shaders/shaders_hot_reloading.c @@ -21,7 +21,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_hybrid_render.c b/examples/shaders/shaders_hybrid_render.c index f07917fb08cf..53e14b884279 100644 --- a/examples/shaders/shaders_hybrid_render.c +++ b/examples/shaders/shaders_hybrid_render.c @@ -20,7 +20,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_julia_set.c b/examples/shaders/shaders_julia_set.c index ee1988058e16..aebb287a1c8b 100644 --- a/examples/shaders/shaders_julia_set.c +++ b/examples/shaders/shaders_julia_set.c @@ -22,7 +22,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_lightmap.c b/examples/shaders/shaders_lightmap.c index b636c8b282e0..c5ed6094c826 100644 --- a/examples/shaders/shaders_lightmap.c +++ b/examples/shaders/shaders_lightmap.c @@ -25,7 +25,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_mesh_instancing.c b/examples/shaders/shaders_mesh_instancing.c index 7789f2cb0ff2..7d603a6bfdfd 100644 --- a/examples/shaders/shaders_mesh_instancing.c +++ b/examples/shaders/shaders_mesh_instancing.c @@ -24,7 +24,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_model_shader.c b/examples/shaders/shaders_model_shader.c index e84ecbfbe6de..739a33b7ee02 100644 --- a/examples/shaders/shaders_model_shader.c +++ b/examples/shaders/shaders_model_shader.c @@ -22,7 +22,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_multi_sample2d.c b/examples/shaders/shaders_multi_sample2d.c index d6f8803b799a..f7c369bc462c 100644 --- a/examples/shaders/shaders_multi_sample2d.c +++ b/examples/shaders/shaders_multi_sample2d.c @@ -22,7 +22,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_palette_switch.c b/examples/shaders/shaders_palette_switch.c index bb1eda4e0835..6b108b0927ab 100644 --- a/examples/shaders/shaders_palette_switch.c +++ b/examples/shaders/shaders_palette_switch.c @@ -24,7 +24,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_postprocessing.c b/examples/shaders/shaders_postprocessing.c index 7f6bd00920a1..1a7c621e5e5b 100644 --- a/examples/shaders/shaders_postprocessing.c +++ b/examples/shaders/shaders_postprocessing.c @@ -22,7 +22,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_raymarching.c b/examples/shaders/shaders_raymarching.c index 7b34a5233fde..e9b7755ada2d 100644 --- a/examples/shaders/shaders_raymarching.c +++ b/examples/shaders/shaders_raymarching.c @@ -18,7 +18,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB -> Not supported at this moment +#else // PLATFORM_ANDROID, PLATFORM_WEB -> Not supported at this moment #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_shapes_textures.c b/examples/shaders/shaders_shapes_textures.c index d3ec8daf0414..cca4959ed4ff 100644 --- a/examples/shaders/shaders_shapes_textures.c +++ b/examples/shaders/shaders_shapes_textures.c @@ -22,7 +22,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_simple_mask.c b/examples/shaders/shaders_simple_mask.c index 6283ccbccbe0..7ed315b0aa5f 100644 --- a/examples/shaders/shaders_simple_mask.c +++ b/examples/shaders/shaders_simple_mask.c @@ -25,7 +25,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_spotlight.c b/examples/shaders/shaders_spotlight.c index c96c983d0afb..067f9622dd94 100644 --- a/examples/shaders/shaders_spotlight.c +++ b/examples/shaders/shaders_spotlight.c @@ -34,7 +34,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_texture_drawing.c b/examples/shaders/shaders_texture_drawing.c index 006168d57e52..43ffa21ef2c4 100644 --- a/examples/shaders/shaders_texture_drawing.c +++ b/examples/shaders/shaders_texture_drawing.c @@ -19,7 +19,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_texture_outline.c b/examples/shaders/shaders_texture_outline.c index 09f625bb53fa..83f2820e75d8 100644 --- a/examples/shaders/shaders_texture_outline.c +++ b/examples/shaders/shaders_texture_outline.c @@ -20,7 +20,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_texture_waves.c b/examples/shaders/shaders_texture_waves.c index 27ad1f6e4722..5bdaada44627 100644 --- a/examples/shaders/shaders_texture_waves.c +++ b/examples/shaders/shaders_texture_waves.c @@ -24,7 +24,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/shaders/shaders_write_depth.c b/examples/shaders/shaders_write_depth.c index 048e297ad28b..d9e40d0dd525 100644 --- a/examples/shaders/shaders_write_depth.c +++ b/examples/shaders/shaders_write_depth.c @@ -19,7 +19,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/examples/text/text_font_sdf.c b/examples/text/text_font_sdf.c index 6a223ae5c0db..cba47b438481 100644 --- a/examples/text/text_font_sdf.c +++ b/examples/text/text_font_sdf.c @@ -15,7 +15,7 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 -#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +#else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif diff --git a/projects/CMake/core_basic_window.c b/projects/CMake/core_basic_window.c index 0e55429672ca..86709f7a97b4 100644 --- a/projects/CMake/core_basic_window.c +++ b/projects/CMake/core_basic_window.c @@ -2,7 +2,7 @@ * * raylib [core] example - Basic window (adapted for HTML5 platform) * -* This example is prepared to compile for PLATFORM_WEB, PLATFORM_DESKTOP and PLATFORM_RPI +* This example is prepared to compile for PLATFORM_WEB and PLATFORM_DESKTOP * As you will notice, code structure is slightly different to the other examples... * To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning * diff --git a/projects/VSCode/Makefile b/projects/VSCode/Makefile index 9ab042e8f821..a2a26f092353 100644 --- a/projects/VSCode/Makefile +++ b/projects/VSCode/Makefile @@ -32,7 +32,7 @@ RAYLIB_PATH ?= ..\.. COMPILER_PATH ?= C:/raylib/w64devkit/bin # Define default options -# One of PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +# One of PLATFORM_DESKTOP, PLATFORM_ANDROID, PLATFORM_WEB PLATFORM ?= PLATFORM_DESKTOP # Locations of your newly installed library and associated headers. See ../src/Makefile diff --git a/src/Makefile b/src/Makefile index ed75949384a7..63cbe2a41f1a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,6 @@ # PLATFORM_DESKTOP: OSX/macOS (arm64, x86_64) # PLATFORM_DESKTOP: FreeBSD, OpenBSD, NetBSD, DragonFly # PLATFORM_ANDROID: Android (arm, i686, arm64, x86_64) -# PLATFORM_RPI: Raspberry Pi (deprecated - RPI OS Buster only) # PLATFORM_DRM: Linux native mode, including Raspberry Pi (RPI OS Bullseye) # PLATFORM_WEB: HTML5 (Chrome, Firefox) # @@ -41,7 +40,7 @@ # Define required environment variables #------------------------------------------------------------------------------------------------ -# Define target platform: PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB +# Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB PLATFORM ?= PLATFORM_DESKTOP # Define required raylib variables @@ -94,14 +93,6 @@ USE_EXTERNAL_GLFW ?= FALSE # NOTE: This variable is only used for PLATFORM_OS: LINUX USE_WAYLAND_DISPLAY ?= FALSE -# Use cross-compiler for PLATFORM_RPI -USE_RPI_CROSS_COMPILER ?= FALSE -ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry - RPI_TOOLCHAIN_NAME ?= arm-linux-gnueabihf - RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/$(RPI_TOOLCHAIN_NAME)/sysroot -endif - # Determine if the file has root access (only required to install raylib) # "whoami" prints the name of the user that calls him (so, if it is the root user, "whoami" prints "root") ROOT = $(shell whoami) @@ -144,15 +135,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - UNAMEOS = $(shell uname) - ifeq ($(UNAMEOS),Linux) - PLATFORM_OS = LINUX - endif - ifndef PLATFORM_SHELL - PLATFORM_SHELL = sh - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) UNAMEOS = $(shell uname) ifeq ($(UNAMEOS),Linux) @@ -235,10 +217,7 @@ 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_RPI) - # On RPI OpenGL ES 2.0 must be used - GRAPHICS = GRAPHICS_API_OPENGL_ES2 -endif + ifeq ($(PLATFORM),PLATFORM_DRM) # On DRM OpenGL ES 2.0 must be used GRAPHICS = GRAPHICS_API_OPENGL_ES2 @@ -269,14 +248,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) CC = clang endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) - # Define RPI cross-compiler - #CC = armv6j-hardfloat-linux-gnueabi-gcc - CC = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-gcc - AR = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-ar - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) # Define RPI cross-compiler @@ -452,11 +423,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) INCLUDE_PATHS += -I/usr/local/include endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vmcs_host/linux - INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include/interface/vcos/pthreads -endif ifeq ($(PLATFORM),PLATFORM_DRM) INCLUDE_PATHS += -I/usr/include/libdrm ifeq ($(USE_RPI_CROSSCOMPILER), TRUE) @@ -506,9 +472,6 @@ 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_RPI) - LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -endif ifeq ($(PLATFORM),PLATFORM_DRM) LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) ifeq ($(USE_RPI_CROSSCOMPILER), TRUE) @@ -557,12 +520,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDLIBS = -lglfw endif endif -ifeq ($(PLATFORM),PLATFORM_RPI) - LDLIBS = -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl - ifeq ($(RAYLIB_MODULE_AUDIO),TRUE) - LDLIBS += -latomic - endif -endif ifeq ($(PLATFORM),PLATFORM_DRM) LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl ifeq ($(RAYLIB_MODULE_AUDIO),TRUE) @@ -647,14 +604,6 @@ else cd $(RAYLIB_RELEASE_PATH) && ln -fs lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so lib$(RAYLIB_LIB_NAME).so endif endif - ifeq ($(PLATFORM),PLATFORM_RPI) - # Compile raylib shared library version $(RAYLIB_VERSION). - # WARNING: you should type "make clean" before doing this target - $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION) $(OBJS) $(LDFLAGS) $(LDLIBS) - @echo "raylib shared library generated (lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION)) in $(RAYLIB_RELEASE_PATH)!" - cd $(RAYLIB_RELEASE_PATH) && ln -fsv lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION) lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) - cd $(RAYLIB_RELEASE_PATH) && ln -fsv lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) lib$(RAYLIB_LIB_NAME).so - endif ifeq ($(PLATFORM),PLATFORM_DRM) # Compile raylib shared library version $(RAYLIB_VERSION). # WARNING: you should type "make clean" before doing this target diff --git a/src/rcore.c b/src/rcore.c index c930382396f5..fcb222bb36eb 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -8,7 +8,6 @@ * - PLATFORM_DESKTOP: FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop) * - PLATFORM_DESKTOP: OSX/macOS * - PLATFORM_ANDROID: Android (ARM, ARM64) -* - PLATFORM_RPI: Raspberry Pi 0,1,2,3 (Raspbian, native mode) * - PLATFORM_DRM: Linux native mode, including Raspberry Pi 4 with V3D fkms driver * - PLATFORM_WEB: HTML5 with WebAssembly * @@ -21,12 +20,6 @@ * Windowing and input system configured for Android device, app activity managed internally in this module. * NOTE: OpenGL ES 2.0 is required and graphic device is managed by EGL * -* #define PLATFORM_RPI (deprecated - RPI OS Buster only) -* Windowing and input system configured for Raspberry Pi in native mode (no XWindow required), -* graphic device is managed by EGL and inputs are processed is raw mode, reading from /dev/input/ -* WARNING: This platform is deprecated, since RPI OS Bullseye, the old Dispmanx libraries are not -* supported and you must be using PLATFORM_DRM -* * #define PLATFORM_DRM * Windowing and input system configured for DRM native mode (RPI4 and other devices) * graphic device is managed by EGL and inputs are processed is raw mode, reading from /dev/input/ @@ -260,7 +253,7 @@ //#include // OpenGL ES 2.0 library (not required in this module, only in rlgl) #endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) #include // POSIX file control definitions - open(), creat(), fcntl() #include // POSIX standard function definitions - read(), close(), STDIN_FILENO #include // POSIX terminal control definitions - tcgetattr(), tcsetattr() @@ -272,9 +265,6 @@ #include // Linux: Keycodes constants definition (KEY_A, ...) #include // Linux: Joystick support library -#if defined(PLATFORM_RPI) - #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions -#endif #if defined(PLATFORM_DRM) #include // Generic Buffer Management (native platform for EGL on DRM) #include // Direct Rendering Manager user-level library interface @@ -299,7 +289,7 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) #define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event number #define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...) @@ -351,7 +341,7 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) typedef struct { pthread_t threadId; // Event reading thread id int fd; // File descriptor to the device it is assigned to @@ -375,10 +365,7 @@ typedef struct CoreData { #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) GLFWwindow *handle; // GLFW window handle (graphic device) #endif -#if defined(PLATFORM_RPI) - EGL_DISPMANX_WINDOW_T handle; // Native window handle (graphic device) -#endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) #if defined(PLATFORM_DRM) int fd; // File descriptor for /dev/dri/... drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector @@ -428,7 +415,7 @@ typedef struct CoreData { const char *basePath; // Base path for data storage } Storage; struct { -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event" #endif struct { @@ -444,7 +431,7 @@ typedef struct CoreData { int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) int charPressedQueueCount; // Input characters queue count -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) int defaultMode; // Default keyboard mode #if defined(SUPPORT_SSH_KEYBOARD_RPI) bool evtMode; // Keyboard in event mode @@ -468,7 +455,7 @@ typedef struct CoreData { char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state Vector2 currentWheelMove; // Registers current mouse wheel variation Vector2 previousWheelMove; // Registers previous mouse wheel variation -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) 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 @@ -489,7 +476,7 @@ typedef struct CoreData { 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 -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) pthread_t threadId; // Gamepad reading thread id int streamId[MAX_GAMEPADS]; // Gamepad device file descriptor #endif @@ -502,7 +489,7 @@ typedef struct CoreData { 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 -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) unsigned long long int base; // Base time measure for hi-res timer #endif unsigned int frameCounter; // Frame counter @@ -667,7 +654,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); #endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) static void InitKeyboard(void); // Initialize raw keyboard system static void RestoreKeyboard(void); // Restore keyboard system #if defined(SUPPORT_SSH_KEYBOARD_RPI) @@ -682,13 +669,11 @@ static void *EventThread(void *arg); // Input device events r static void InitGamepad(void); // Initialize raw gamepad input static void *GamepadThread(void *arg); // Mouse reading thread -#if defined(PLATFORM_DRM) static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list -#endif -#endif // PLATFORM_RPI || PLATFORM_DRM +#endif // PLATFORM_DRM #if defined(SUPPORT_EVENTS_AUTOMATION) static void LoadAutomationEvents(const char *fileName); // Load automation events from file @@ -857,7 +842,7 @@ void InitWindow(int width, int height, const char *title) } } #endif -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_DRM) // Initialize graphics device (display device and OpenGL context) // NOTE: returns true if window and graphic device has been initialized successfully CORE.Window.ready = InitGraphicsDevice(width, height); @@ -916,7 +901,7 @@ void InitWindow(int width, int height, const char *title) } #endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) // Initialize raw input system InitEvdevInput(); // Evdev inputs initialization InitGamepad(); // Gamepad init @@ -958,7 +943,7 @@ void InitWindow(int width, int height, const char *title) CORE.Time.frameCounter = 0; #endif -#endif // PLATFORM_DESKTOP || PLATFORM_WEB || PLATFORM_RPI || PLATFORM_DRM +#endif // PLATFORM_DESKTOP || PLATFORM_WEB || PLATFORM_DRM } // Close window and unload OpenGL context @@ -988,7 +973,7 @@ void CloseWindow(void) timeEndPeriod(1); // Restore time period #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) +#if defined(PLATFORM_ANDROID) // Close surface, context and display if (CORE.Window.device != EGL_NO_DISPLAY) { @@ -1076,7 +1061,7 @@ void CloseWindow(void) } #endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) // Wait for mouse and gamepad threads to finish before closing // NOTE: Those threads should already have finished at this point // because they are controlled by CORE.Window.shouldClose variable @@ -1138,7 +1123,7 @@ bool WindowShouldClose(void) else return true; #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) if (CORE.Window.ready) return CORE.Window.shouldClose; else return true; #endif @@ -1324,7 +1309,7 @@ void ToggleFullscreen(void) CORE.Window.fullscreen = !CORE.Window.fullscreen; // Toggle fullscreen flag #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) TRACELOG(LOG_WARNING, "SYSTEM: Failed to toggle to windowed mode"); #endif } @@ -3047,7 +3032,7 @@ double GetTime(void) time = glfwGetTime(); // Elapsed time since glfwInit() #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) struct timespec ts = { 0 }; clock_gettime(CLOCK_MONOTONIC, &ts); unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; @@ -3883,7 +3868,7 @@ const char *GetGamepadName(int gamepad) if (CORE.Input.Gamepad.ready[gamepad]) return glfwGetJoystickName(gamepad); else return NULL; #endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]); return CORE.Input.Gamepad.name[gamepad]; #endif @@ -3896,7 +3881,7 @@ const char *GetGamepadName(int gamepad) // Get gamepad axis count int GetGamepadAxisCount(int gamepad) { -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) int axisCount = 0; if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount); CORE.Input.Gamepad.axisCount = axisCount; @@ -4138,7 +4123,7 @@ int GetTouchX(void) { #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) return (int)CORE.Input.Touch.position[0].x; -#else // PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_DRM +#else // PLATFORM_DESKTOP, PLATFORM_DRM return GetMouseX(); #endif } @@ -4148,7 +4133,7 @@ int GetTouchY(void) { #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) return (int)CORE.Input.Touch.position[0].y; -#else // PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_DRM +#else // PLATFORM_DESKTOP, PLATFORM_DRM return GetMouseY(); #endif } @@ -4165,7 +4150,7 @@ Vector2 GetTouchPosition(int index) // https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages if (index == 0) position = GetMousePosition(); #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) || defined(PLATFORM_DRM) if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index]; else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS); #endif @@ -4537,21 +4522,10 @@ static bool InitGraphicsDevice(int width, int height) #endif // PLATFORM_DESKTOP || PLATFORM_WEB -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) CORE.Window.fullscreen = true; CORE.Window.flags |= FLAG_FULLSCREEN_MODE; -#if defined(PLATFORM_RPI) - bcm_host_init(); - - DISPMANX_ELEMENT_HANDLE_T dispmanElement = { 0 }; - DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = { 0 }; - DISPMANX_UPDATE_HANDLE_T dispmanUpdate = { 0 }; - - VC_RECT_T dstRect = { 0 }; - VC_RECT_T srcRect = { 0 }; -#endif - #if defined(PLATFORM_DRM) CORE.Window.fd = -1; CORE.Window.connector = NULL; @@ -4748,7 +4722,7 @@ static bool InitGraphicsDevice(int width, int height) EGL_NONE }; -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) EGLint numConfigs = 0; // Get an EGL device connection @@ -4863,58 +4837,6 @@ static bool InitGraphicsDevice(int width, int height) CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, CORE.Android.app->window, NULL); #endif // PLATFORM_ANDROID -#if defined(PLATFORM_RPI) - graphics_get_display_size(0, &CORE.Window.display.width, &CORE.Window.display.height); - - // Screen size security check - if (CORE.Window.screen.width <= 0) CORE.Window.screen.width = CORE.Window.display.width; - if (CORE.Window.screen.height <= 0) CORE.Window.screen.height = CORE.Window.display.height; - - // 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); - - dstRect.x = 0; - dstRect.y = 0; - dstRect.width = CORE.Window.display.width; - dstRect.height = CORE.Window.display.height; - - srcRect.x = 0; - srcRect.y = 0; - srcRect.width = CORE.Window.render.width << 16; - srcRect.height = CORE.Window.render.height << 16; - - // NOTE: RPI dispmanx windowing system takes care of source rectangle scaling to destination rectangle by hardware (no cost) - // Take care that renderWidth/renderHeight fit on displayWidth/displayHeight aspect ratio - - VC_DISPMANX_ALPHA_T alpha = { 0 }; - alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; - //alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE; // TODO: Allow transparent framebuffer! -> FLAG_WINDOW_TRANSPARENT - alpha.opacity = 255; // Set transparency level for framebuffer, requires EGLAttrib: EGL_TRANSPARENT_TYPE - alpha.mask = 0; - - dispmanDisplay = vc_dispmanx_display_open(0); // LCD - dispmanUpdate = vc_dispmanx_update_start(0); - - dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay, 0/*layer*/, &dstRect, 0/*src*/, - &srcRect, DISPMANX_PROTECTION_NONE, &alpha, 0/*clamp*/, DISPMANX_NO_ROTATE); - - CORE.Window.handle.element = dispmanElement; - CORE.Window.handle.width = CORE.Window.render.width; - CORE.Window.handle.height = CORE.Window.render.height; - vc_dispmanx_update_submit_sync(dispmanUpdate); - - CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, &CORE.Window.handle, NULL); - - const unsigned char *const renderer = glGetString(GL_RENDERER); - if (renderer) TRACELOG(LOG_INFO, "DISPLAY: Renderer name is: %s", renderer); - else TRACELOG(LOG_WARNING, "DISPLAY: Failed to get renderer name"); - //--------------------------------------------------------------------------------- -#endif // PLATFORM_RPI - #if defined(PLATFORM_DRM) CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, (EGLNativeWindowType)CORE.Window.gbmSurface, NULL); if (EGL_NO_SURFACE == CORE.Window.surface) @@ -4952,7 +4874,7 @@ static bool InitGraphicsDevice(int width, int 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); } -#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM +#endif // PLATFORM_ANDROID || PLATFORM_DRM // Load OpenGL extensions // NOTE: GL procedures address loader is required to load extensions @@ -5096,7 +5018,7 @@ static void InitTimer(void) timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms) #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) struct timespec now = { 0 }; if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success @@ -5160,7 +5082,7 @@ void SwapScreenBuffer(void) glfwSwapBuffers(CORE.Window.handle); #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM) eglSwapBuffers(CORE.Window.device, CORE.Window.surface); #if defined(PLATFORM_DRM) @@ -5190,7 +5112,7 @@ void SwapScreenBuffer(void) CORE.Window.prevBO = bo; #endif // PLATFORM_DRM -#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM +#endif // PLATFORM_ANDROID || PLATFORM_DRM } // Register all input events @@ -5208,13 +5130,11 @@ void PollInputEvents(void) // Reset key repeats for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; -#if !(defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) // Reset last gamepad button/axis registered state CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN CORE.Input.Gamepad.axisCount = 0; -#endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) // Register previous keys states for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) { @@ -5461,7 +5381,7 @@ void PollInputEvents(void) } #endif -#if (defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) && defined(SUPPORT_SSH_KEYBOARD_RPI) +#if defined(PLATFORM_DRM) && 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 @@ -6336,7 +6256,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent } #endif -#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) +#if defined(PLATFORM_DRM) // Initialize Keyboard system (using standard input) static void InitKeyboard(void) { @@ -6977,7 +6897,7 @@ static void *EventThread(void *arg) if (CORE.Input.Touch.position[2].x >= 0) CORE.Input.Touch.pointCount++; if (CORE.Input.Touch.position[3].x >= 0) CORE.Input.Touch.pointCount++; -#if defined(SUPPORT_GESTURES_SYSTEM) // PLATFORM_RPI, PLATFORM_DRM +#if defined(SUPPORT_GESTURES_SYSTEM) // PLATFORM_DRM if (gestureUpdate) { GestureEvent gestureEvent = { 0 }; @@ -7094,7 +7014,7 @@ static void *GamepadThread(void *arg) return NULL; } -#endif // PLATFORM_RPI || PLATFORM_DRM +#endif // PLATFORM_DRM #if defined(PLATFORM_DRM) // Search matching DRM mode in connector's mode list diff --git a/src/rlgl.h b/src/rlgl.h index f274931e21b5..dee4d501fe9a 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -815,7 +815,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi // provided headers (despite being defined in official Khronos GLES2 headers) - #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) + #if defined(PLATFORM_DRM) typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); From 140f624c924839ad055f2e1eef8021536310af21 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 7 Sep 2023 18:00:10 +0200 Subject: [PATCH 64/89] Review to avoid UBSAN complaining #1891 --- src/rlgl.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index dee4d501fe9a..6dee60f95e2a 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3687,7 +3687,11 @@ void rlDrawVertexArray(int offset, int count) // Draw vertex array elements void rlDrawVertexArrayElements(int offset, int count, const void *buffer) { - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)buffer + offset); + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned short *bufferPtr = (unsigned short *)buffer; + if (offset > 0) bufferPtr += offset; + + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr); } // Draw vertex array instanced @@ -3702,7 +3706,11 @@ void rlDrawVertexArrayInstanced(int offset, int count, int instances) void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)buffer + offset, instances); + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned short *bufferPtr = (unsigned short *)buffer; + if (offset > 0) bufferPtr += offset; + + glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr, instances); #endif } From bcdd5997ac874f1f90906e99485b16446a7ab41b Mon Sep 17 00:00:00 2001 From: Dan Vu Date: Fri, 8 Sep 2023 11:13:00 +0200 Subject: [PATCH 65/89] added raylib-raku to bindings (#3299) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index d4bd8fc21b98..bdd5e2558125 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -77,6 +77,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | raylib-sunder | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD | https://github.com/ashn-dot-dev/raylib-sunder | | rayed-bqn | **auto** | [BQN](https://mlochbaum.github.io/BQN/) | MIT | https://github.com/Brian-ED/rayed-bqn | | rayjs | 4.6-dev | [QuickJS](https://bellard.org/quickjs/) | MIT | https://github.com/mode777/rayjs | +| raylib-raku | **auto** | [Raku](https://www.raku.org/) | Artistic License 2.0 | https://github.com/vushu/raylib-raku | ### Utility Wrapers These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's pardigm. From 38b69508919163f64fb8e8d004a78cfab11ca318 Mon Sep 17 00:00:00 2001 From: Gabriel dos Santos Sanches Date: Fri, 8 Sep 2023 12:22:12 +0200 Subject: [PATCH 66/89] examples: core: adds 2D camera two player split screen (#3298) --- examples/Makefile | 1 + examples/Makefile.Web | 1 + examples/README.md | 1 + examples/core/core_camera_2d_split_screen.c | 137 +++++++ examples/core/core_camera_2d_split_screen.png | Bin 0 -> 20010 bytes .../core_camera_2d_split_screen.vcxproj | 387 ++++++++++++++++++ 6 files changed, 527 insertions(+) create mode 100644 examples/core/core_camera_2d_split_screen.c create mode 100644 examples/core/core_camera_2d_split_screen.png create mode 100644 projects/VS2022/examples/core_camera_2d_split_screen.vcxproj diff --git a/examples/Makefile b/examples/Makefile index 338fe168cab0..911743938573 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -386,6 +386,7 @@ CORE = \ core/core_window_letterbox \ core/core_window_should_close \ core/core_split_screen \ + core/core_camera_2d_split_screen \ core/core_smooth_pixelperfect \ core/core_custom_frame_control diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 518fab9181f9..44ace4ee41f9 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -361,6 +361,7 @@ CORE = \ core/core_window_letterbox \ core/core_window_should_close \ core/core_split_screen \ + core/core_camera_2d_split_screen \ core/core_smooth_pixelperfect \ core/core_custom_frame_control \ core/core_loading_thread diff --git a/examples/README.md b/examples/README.md index 8399d677dfb9..35acaa25a38c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -54,6 +54,7 @@ Examples using raylib core platform functionality like window creation, inputs, | 28 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | core_smooth_pixelperfect | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) | | 29 | [core_split_screen](core/core_split_screen.c) | core_split_screen | ⭐️⭐️⭐️⭐️ | 3.7 | **4.0** | [Jeffery Myers](https://github.com/JeffM2501) | | 30 | [core_window_should_close](core/core_window_should_close.c) | core_window_should_close | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | +| 31 | [core_camera_2d_split_screen](core/core_camera_2d_split_screen.c) | core_camera_2d_split_screen | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Jeffery Myers](https://github.com/JeffM2501) | ### category: shapes diff --git a/examples/core/core_camera_2d_split_screen.c b/examples/core/core_camera_2d_split_screen.c new file mode 100644 index 000000000000..5f50595695a9 --- /dev/null +++ b/examples/core/core_camera_2d_split_screen.c @@ -0,0 +1,137 @@ +/******************************************************************************************* +* +* raylib [core] example - split screen +* +* Addapted from the Split Screen example (https://github.com/raysan5/raylib/blob/master/examples/core/core_split_screen.c) +* +* Example originally created with raylib 4.5, last time updated with raylib 4.5 +* +* Example contributed by Jeffery Myers (@JeffM2501) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2021-2023 Jeffery Myers (@JeffM2501) +* +********************************************************************************************/ + +#include "raylib.h" + +#include + +#define PLAYER_SIZE 40 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 440; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - camera 2D split screen"); + + Rectangle player1 = { 200, 200, PLAYER_SIZE, PLAYER_SIZE }; + Rectangle player2 = { 250, 200, PLAYER_SIZE, PLAYER_SIZE }; + + Camera2D camera1 = { 0 }; + camera1.target = (Vector2){ player1.x, player1.y }; + camera1.offset = (Vector2){ 200.0f, 200.0f }; + camera1.rotation = 0.0f; + camera1.zoom = 1.0f; + + Camera2D camera2 = { 0 }; + camera2.target = (Vector2){ player2.x, player2.y }; + camera2.offset = (Vector2){ 200.0f, 200.0f }; + camera2.rotation = 0.0f; + camera2.zoom = 1.0f; + + RenderTexture screenCamera1 = LoadRenderTexture(screenWidth / 2, screenHeight); + RenderTexture screenCamera2 = LoadRenderTexture(screenWidth / 2, screenHeight); + + // Build a flipped rectangle the size of the split view to use for drawing later + Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenCamera1.texture.width, (float)-screenCamera1.texture.height }; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + void DrawScene(void) { + for (int i = 0; i < screenWidth/PLAYER_SIZE + 1; i++) + { + DrawLineV((Vector2){PLAYER_SIZE*i, 0}, (Vector2){PLAYER_SIZE*i, screenHeight}, LIGHTGRAY); + } + + for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++) + { + DrawLineV((Vector2){0, PLAYER_SIZE*i}, (Vector2){screenWidth, PLAYER_SIZE*i}, LIGHTGRAY); + } + + for (int i = 0; i < screenWidth/PLAYER_SIZE; i++) + { + for (int j = 0; j < screenHeight/PLAYER_SIZE; j++) + { + char coordinate_str[8]; + snprintf(coordinate_str, sizeof(coordinate_str), "%d,%d", i, j); + DrawText(coordinate_str, 10 + PLAYER_SIZE*i, 10 + PLAYER_SIZE*j, 10, LIGHTGRAY); + } + } + + DrawRectangleRec(player1, RED); + DrawRectangleRec(player2, BLUE); + } + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsKeyDown(KEY_S)) player1.y += 3; + else if (IsKeyDown(KEY_W)) player1.y -= 3; + if (IsKeyDown(KEY_D)) player1.x += 3; + else if (IsKeyDown(KEY_A)) player1.x -= 3; + + if (IsKeyDown(KEY_UP)) player2.y += 3; + else if (IsKeyDown(KEY_DOWN)) player2.y -= 3; + if (IsKeyDown(KEY_RIGHT)) player2.x += 3; + else if (IsKeyDown(KEY_LEFT)) player2.x -= 3; + + camera1.target = (Vector2){ player1.x, player1.y }; + camera2.target = (Vector2){ player2.x, player2.y }; + + // Draw + //---------------------------------------------------------------------------------- + BeginTextureMode(screenCamera1); + ClearBackground(RAYWHITE); + BeginMode2D(camera1); + DrawScene(); + EndMode2D(); + DrawText("PLAYER1 W/S/A/D to move", 10, 10, 15, RED); + EndTextureMode(); + + BeginTextureMode(screenCamera2); + ClearBackground(RAYWHITE); + BeginMode2D(camera2); + DrawScene(); + EndMode2D(); + DrawText("PLAYER2 UP/DOWN/LEFT/RIGHT to move", 10, 10, 15, BLUE); + EndTextureMode(); + + // Draw both views render textures to the screen side by side + BeginDrawing(); + ClearBackground(BLACK); + DrawTextureRec(screenCamera1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE); + DrawTextureRec(screenCamera2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE); + EndDrawing(); + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadRenderTexture(screenCamera1); // Unload render texture + UnloadRenderTexture(screenCamera2); // Unload render texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/core/core_camera_2d_split_screen.png b/examples/core/core_camera_2d_split_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..ed5aaa58bfc2bb8124098d2b5c583961414bc218 GIT binary patch literal 20010 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 literal 0 HcmV?d00001 diff --git a/projects/VS2022/examples/core_camera_2d_split_screen.vcxproj b/projects/VS2022/examples/core_camera_2d_split_screen.vcxproj new file mode 100644 index 000000000000..1efc58a654d7 --- /dev/null +++ b/projects/VS2022/examples/core_camera_2d_split_screen.vcxproj @@ -0,0 +1,387 @@ + + + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {946A1700-C7AA-46F0-AEF2-67C98B5722AC} + Win32Proj + core_camera_2d_split_screen + 10.0 + core_camera_2d_split_screen + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + 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) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + 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) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + 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) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + 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) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + 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) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + 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) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + 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) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + 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) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + From 8c2932b45d02f9ce8774dc76098c9f4a6231eb02 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 8 Sep 2023 13:27:13 +0200 Subject: [PATCH 67/89] Reviewed examples for consistency --- examples/Makefile | 4 +- examples/Makefile.Web | 13 +- examples/README.md | 42 ++--- examples/core/core_2d_camera_split_screen.c | 167 ++++++++++++++++++ examples/core/core_2d_camera_split_screen.png | Bin 0 -> 21543 bytes examples/core/core_3d_camera_free.c | 2 +- ...screen.c => core_3d_camera_split_screen.c} | 87 +++++---- examples/core/core_3d_camera_split_screen.png | Bin 0 -> 16165 bytes examples/core/core_camera_2d_split_screen.c | 137 -------------- examples/core/core_camera_2d_split_screen.png | Bin 20010 -> 0 bytes examples/core/core_split_screen.png | Bin 21609 -> 0 bytes examples/shapes/shapes_bouncing_ball.c | 6 +- examples/shapes/shapes_lines_bezier.c | 24 ++- examples/shapes/shapes_lines_splines.c | 155 ++++++++++++++++ ...oj => core_2d_camera_split_screen.vcxproj} | 8 +- ...oj => core_3d_camera_split_screen.vcxproj} | 8 +- projects/VS2022/raylib.sln | 57 ++++-- 17 files changed, 481 insertions(+), 229 deletions(-) create mode 100644 examples/core/core_2d_camera_split_screen.c create mode 100644 examples/core/core_2d_camera_split_screen.png rename examples/core/{core_split_screen.c => core_3d_camera_split_screen.c} (68%) create mode 100644 examples/core/core_3d_camera_split_screen.png delete mode 100644 examples/core/core_camera_2d_split_screen.c delete mode 100644 examples/core/core_camera_2d_split_screen.png delete mode 100644 examples/core/core_split_screen.png create mode 100644 examples/shapes/shapes_lines_splines.c rename projects/VS2022/examples/{core_split_screen.vcxproj => core_2d_camera_split_screen.vcxproj} (98%) rename projects/VS2022/examples/{core_camera_2d_split_screen.vcxproj => core_3d_camera_split_screen.vcxproj} (99%) diff --git a/examples/Makefile b/examples/Makefile index 911743938573..cd079c312e1c 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -370,9 +370,11 @@ CORE = \ core/core_2d_camera \ core/core_2d_camera_platformer \ core/core_2d_camera_mouse_zoom \ + 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_split_screen \ core/core_3d_picking \ core/core_world_screen \ core/core_custom_logging \ @@ -385,8 +387,6 @@ CORE = \ core/core_window_flags \ core/core_window_letterbox \ core/core_window_should_close \ - core/core_split_screen \ - core/core_camera_2d_split_screen \ core/core_smooth_pixelperfect \ core/core_custom_frame_control diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 44ace4ee41f9..267e02396ff9 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -346,9 +346,11 @@ CORE = \ core/core_2d_camera \ core/core_2d_camera_platformer \ core/core_2d_camera_mouse_zoom \ + 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_split_screen \ core/core_3d_picking \ core/core_world_screen \ core/core_custom_logging \ @@ -360,8 +362,6 @@ CORE = \ core/core_window_flags \ core/core_window_letterbox \ core/core_window_should_close \ - core/core_split_screen \ - core/core_camera_2d_split_screen \ core/core_smooth_pixelperfect \ core/core_custom_frame_control \ core/core_loading_thread @@ -529,6 +529,9 @@ core/core_2d_camera_platformer: core/core_2d_camera_platformer.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_2d_camera_split_screen: core/core_2d_camera_split_screen.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) core/core_3d_camera_mode: core/core_3d_camera_mode.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -538,6 +541,9 @@ core/core_3d_camera_free: core/core_3d_camera_free.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_3d_camera_split_screen: core/core_3d_camera_split_screen.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) core/core_3d_picking: core/core_3d_picking.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -570,9 +576,6 @@ 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_split_screen: core/core_split_screen.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) diff --git a/examples/README.md b/examples/README.md index 35acaa25a38c..82e4b782521d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -34,27 +34,27 @@ Examples using raylib core platform functionality like window creation, inputs, | 08 | [core_2d_camera](core/core_2d_camera.c) | core_2d_camera | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) | | 09 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | core_2d_camera_mouse_zoom | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) | | 10 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | core_2d_camera_platformer | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) | -| 11 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | core_3d_camera_mode | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | -| 12 | [core_3d_camera_free](core/core_3d_camera_free.c) | core_3d_camera_free | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | -| 13 | [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | core_3d_camera_first_person | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | -| 14 | [core_3d_picking](core/core_3d_picking.c) | core_3d_picking | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | -| 15 | [core_world_screen](core/core_world_screen.c) | core_world_screen | ⭐️⭐️☆☆ | 1.3 | 1.4 | [Ray](https://github.com/raysan5) | -| 16 | [core_custom_logging](core/core_custom_logging.c) | core_custom_logging | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) | -| 17 | [core_window_flags](core/core_window_flags.c) | core_window_flags | ⭐️⭐️⭐️☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) | -| 18 | [core_window_letterbox](core/core_window_letterbox.c) | core_window_letterbox | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) | -| 19 | [core_window_should_close](core/core_window_should_close.c) | core_window_should_close | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | -| 20 | [core_drop_files](core/core_drop_files.c) | core_drop_files | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | -| 21 | [core_random_values](core/core_random_values.c) | core_random_values | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) | -| 22 | [core_storage_values](core/core_storage_values.c) | core_storage_values | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) | -| 23 | [core_vr_simulator](core/core_vr_simulator.c) | core_vr_simulator | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | -| 24 | [core_loading_thread](core/core_loading_thread.c) | core_loading_thread | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) | -| 25 | [core_scissor_test](core/core_scissor_test.c) | core_scissor_test | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) | -| 26 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | core_basic_screen_manager | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | -| 27 | [core_custom_frame_control](core/core_custom_frame_control.c) | core_custom_frame_control | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | -| 28 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | core_smooth_pixelperfect | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) | -| 29 | [core_split_screen](core/core_split_screen.c) | core_split_screen | ⭐️⭐️⭐️⭐️ | 3.7 | **4.0** | [Jeffery Myers](https://github.com/JeffM2501) | -| 30 | [core_window_should_close](core/core_window_should_close.c) | core_window_should_close | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | -| 31 | [core_camera_2d_split_screen](core/core_camera_2d_split_screen.c) | core_camera_2d_split_screen | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Jeffery Myers](https://github.com/JeffM2501) | +| 11 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | core_2d_camera_split_screen | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) | +| 12 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | core_3d_camera_mode | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | +| 13 | [core_3d_camera_free](core/core_3d_camera_free.c) | core_3d_camera_free | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | +| 14 | [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | core_3d_camera_first_person | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | +| 15 | [core_3d_camera:split_screen](core/core_3d_camera_split_screen.c) | core_3d_camera_split_screen | ⭐️⭐️⭐️⭐️ | 3.7 | **4.0** | [Jeffery Myers](https://github.com/JeffM2501) | +| 16 | [core_3d_picking](core/core_3d_picking.c) | core_3d_picking | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | +| 17 | [core_world_screen](core/core_world_screen.c) | core_world_screen | ⭐️⭐️☆☆ | 1.3 | 1.4 | [Ray](https://github.com/raysan5) | +| 18 | [core_custom_logging](core/core_custom_logging.c) | core_custom_logging | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) | +| 19 | [core_window_flags](core/core_window_flags.c) | core_window_flags | ⭐️⭐️⭐️☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) | +| 20 | [core_window_letterbox](core/core_window_letterbox.c) | core_window_letterbox | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) | +| 21 | [core_window_should_close](core/core_window_should_close.c) | core_window_should_close | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | +| 22 | [core_drop_files](core/core_drop_files.c) | core_drop_files | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | +| 23 | [core_random_values](core/core_random_values.c) | core_random_values | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) | +| 24 | [core_storage_values](core/core_storage_values.c) | core_storage_values | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) | +| 25 | [core_vr_simulator](core/core_vr_simulator.c) | core_vr_simulator | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | +| 26 | [core_loading_thread](core/core_loading_thread.c) | core_loading_thread | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) | +| 27 | [core_scissor_test](core/core_scissor_test.c) | core_scissor_test | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) | +| 28 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | core_basic_screen_manager | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | +| 29 | [core_custom_frame_control](core/core_custom_frame_control.c) | core_custom_frame_control | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | +| 30 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | core_smooth_pixelperfect | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) | +| 31 | [core_window_should_close](core/core_window_should_close.c) | core_window_should_close | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | ### category: shapes diff --git a/examples/core/core_2d_camera_split_screen.c b/examples/core/core_2d_camera_split_screen.c new file mode 100644 index 000000000000..57a0dfd3a88e --- /dev/null +++ b/examples/core/core_2d_camera_split_screen.c @@ -0,0 +1,167 @@ +/******************************************************************************************* +* +* raylib [core] example - 2d camera split screen +* +* Addapted from the core_3d_camera_split_screen example: +* https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_split_screen.c +* +* Example originally created with raylib 4.5, last time updated with raylib 4.5 +* +* Example contributed by Gabriel dos Santos Sanches (@gabrielssanches) 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 Gabriel dos Santos Sanches (@gabrielssanches) +* +********************************************************************************************/ + +#include "raylib.h" + +#define PLAYER_SIZE 40 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 440; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera split screen"); + + Rectangle player1 = { 200, 200, PLAYER_SIZE, PLAYER_SIZE }; + Rectangle player2 = { 250, 200, PLAYER_SIZE, PLAYER_SIZE }; + + Camera2D camera1 = { 0 }; + camera1.target = (Vector2){ player1.x, player1.y }; + camera1.offset = (Vector2){ 200.0f, 200.0f }; + camera1.rotation = 0.0f; + camera1.zoom = 1.0f; + + Camera2D camera2 = { 0 }; + camera2.target = (Vector2){ player2.x, player2.y }; + camera2.offset = (Vector2){ 200.0f, 200.0f }; + camera2.rotation = 0.0f; + camera2.zoom = 1.0f; + + RenderTexture screenCamera1 = LoadRenderTexture(screenWidth/2, screenHeight); + RenderTexture screenCamera2 = LoadRenderTexture(screenWidth/2, screenHeight); + + // Build a flipped rectangle the size of the split view to use for drawing later + Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenCamera1.texture.width, (float)-screenCamera1.texture.height }; + + 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 + //---------------------------------------------------------------------------------- + if (IsKeyDown(KEY_S)) player1.y += 3.0f; + else if (IsKeyDown(KEY_W)) player1.y -= 3.0f; + if (IsKeyDown(KEY_D)) player1.x += 3.0f; + else if (IsKeyDown(KEY_A)) player1.x -= 3.0f; + + if (IsKeyDown(KEY_UP)) player2.y -= 3.0f; + else if (IsKeyDown(KEY_DOWN)) player2.y += 3.0f; + if (IsKeyDown(KEY_RIGHT)) player2.x += 3.0f; + else if (IsKeyDown(KEY_LEFT)) player2.x -= 3.0f; + + camera1.target = (Vector2){ player1.x, player1.y }; + camera2.target = (Vector2){ player2.x, player2.y }; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginTextureMode(screenCamera1); + ClearBackground(RAYWHITE); + + BeginMode2D(camera1); + + // 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); + } + + for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++) + { + DrawLineV((Vector2){0, PLAYER_SIZE*i}, (Vector2){screenWidth, PLAYER_SIZE*i}, LIGHTGRAY); + } + + for (int i = 0; i < screenWidth/PLAYER_SIZE; i++) + { + for (int j = 0; j < screenHeight/PLAYER_SIZE; j++) + { + DrawText(TextFormat("[%i,%i]", i, j), 10 + PLAYER_SIZE*i, 15 + PLAYER_SIZE*j, 10, LIGHTGRAY); + } + } + + DrawRectangleRec(player1, RED); + DrawRectangleRec(player2, BLUE); + EndMode2D(); + + DrawRectangle(0, 0, GetScreenWidth()/2, 30, Fade(RAYWHITE, 0.6f)); + DrawText("PLAYER1: W/S/A/D to move", 10, 10, 10, MAROON); + + EndTextureMode(); + + BeginTextureMode(screenCamera2); + ClearBackground(RAYWHITE); + + BeginMode2D(camera2); + + // 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); + } + + for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++) + { + DrawLineV((Vector2){0, PLAYER_SIZE*i}, (Vector2){screenWidth, PLAYER_SIZE*i}, LIGHTGRAY); + } + + for (int i = 0; i < screenWidth/PLAYER_SIZE; i++) + { + for (int j = 0; j < screenHeight/PLAYER_SIZE; j++) + { + DrawText(TextFormat("[%i,%i]", i, j), 10 + PLAYER_SIZE*i, 15 + PLAYER_SIZE*j, 10, LIGHTGRAY); + } + } + + DrawRectangleRec(player1, RED); + DrawRectangleRec(player2, BLUE); + + EndMode2D(); + + DrawRectangle(0, 0, GetScreenWidth()/2, 30, Fade(RAYWHITE, 0.6f)); + DrawText("PLAYER2: UP/DOWN/LEFT/RIGHT to move", 10, 10, 10, DARKBLUE); + + EndTextureMode(); + + // Draw both views render textures to the screen side by side + BeginDrawing(); + ClearBackground(BLACK); + + DrawTextureRec(screenCamera1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE); + DrawTextureRec(screenCamera2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE); + + DrawRectangle(GetScreenWidth()/2 - 2, 0, 4, GetScreenHeight(), LIGHTGRAY); + EndDrawing(); + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadRenderTexture(screenCamera1); // Unload render texture + UnloadRenderTexture(screenCamera2); // Unload render texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/core/core_2d_camera_split_screen.png b/examples/core/core_2d_camera_split_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..a441e39298f2b7962e187f6b5918915a8babff20 GIT binary patch literal 21543 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 F{~tJM=}Z6s literal 0 HcmV?d00001 diff --git a/examples/core/core_3d_camera_free.c b/examples/core/core_3d_camera_free.c index 59bd158a214e..78200a642d65 100644 --- a/examples/core/core_3d_camera_free.c +++ b/examples/core/core_3d_camera_free.c @@ -72,7 +72,7 @@ int main(void) 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("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, DARKGRAY); DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, DARKGRAY); EndDrawing(); diff --git a/examples/core/core_split_screen.c b/examples/core/core_3d_camera_split_screen.c similarity index 68% rename from examples/core/core_split_screen.c rename to examples/core/core_3d_camera_split_screen.c index 50cfcf7ac613..d625e1c0e8f5 100644 --- a/examples/core/core_split_screen.c +++ b/examples/core/core_3d_camera_split_screen.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - split screen +* raylib [core] example - 3d cmaera split screen * * Example originally created with raylib 3.7, last time updated with raylib 4.0 * @@ -15,32 +15,6 @@ #include "raylib.h" -Camera cameraPlayer1 = { 0 }; -Camera cameraPlayer2 = { 0 }; - -// Scene drawing -void DrawScene(void) -{ - int count = 5; - float spacing = 4; - - // Grid of cube trees on a plane to make a "world" - DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 50, 50 }, BEIGE); // Simple world plane - - for (float x = -count*spacing; x <= count*spacing; x += spacing) - { - for (float z = -count*spacing; z <= count*spacing; z += spacing) - { - DrawCube((Vector3) { x, 1.5f, z }, 1, 1, 1, LIME); - DrawCube((Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN); - } - } - - // Draw a cube at each player's position - DrawCube(cameraPlayer1.position, 1, 1, 1, RED); - DrawCube(cameraPlayer2.position, 1, 1, 1, BLUE); -} - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -51,9 +25,10 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [core] example - split screen"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera split screen"); // Setup player 1 camera and screen + Camera cameraPlayer1 = { 0 }; cameraPlayer1.fovy = 45.0f; cameraPlayer1.up.y = 1.0f; cameraPlayer1.target.y = 1.0f; @@ -63,6 +38,7 @@ int main(void) RenderTexture screenPlayer1 = LoadRenderTexture(screenWidth/2, screenHeight); // Setup player two camera and screen + Camera cameraPlayer2 = { 0 }; cameraPlayer2.fovy = 45.0f; cameraPlayer2.up.y = 1.0f; cameraPlayer2.target.y = 3.0f; @@ -73,6 +49,10 @@ int main(void) // Build a flipped rectangle the size of the split view to use for drawing later Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenPlayer1.texture.width, (float)-screenPlayer1.texture.height }; + + // Grid data + int count = 5; + float spacing = 4; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -116,26 +96,69 @@ int main(void) // Draw Player1 view to the render texture BeginTextureMode(screenPlayer1); ClearBackground(SKYBLUE); + BeginMode3D(cameraPlayer1); - DrawScene(); + + // Draw scene: grid of cube trees on a plane to make a "world" + DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 50, 50 }, BEIGE); // Simple world plane + + for (float x = -count*spacing; x <= count*spacing; x += spacing) + { + for (float z = -count*spacing; z <= count*spacing; z += spacing) + { + DrawCube((Vector3) { x, 1.5f, z }, 1, 1, 1, LIME); + DrawCube((Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN); + } + } + + // Draw a cube at each player's position + DrawCube(cameraPlayer1.position, 1, 1, 1, RED); + DrawCube(cameraPlayer2.position, 1, 1, 1, BLUE); + EndMode3D(); - DrawText("PLAYER1 W/S to move", 10, 10, 20, RED); + + DrawRectangle(0, 0, GetScreenWidth()/2, 40, Fade(RAYWHITE, 0.8f)); + DrawText("PLAYER1: W/S to move", 10, 10, 20, MAROON); + EndTextureMode(); // Draw Player2 view to the render texture BeginTextureMode(screenPlayer2); ClearBackground(SKYBLUE); + BeginMode3D(cameraPlayer2); - DrawScene(); + + // Draw scene: grid of cube trees on a plane to make a "world" + DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 50, 50 }, BEIGE); // Simple world plane + + for (float x = -count*spacing; x <= count*spacing; x += spacing) + { + for (float z = -count*spacing; z <= count*spacing; z += spacing) + { + DrawCube((Vector3) { x, 1.5f, z }, 1, 1, 1, LIME); + DrawCube((Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN); + } + } + + // Draw a cube at each player's position + DrawCube(cameraPlayer1.position, 1, 1, 1, RED); + DrawCube(cameraPlayer2.position, 1, 1, 1, BLUE); + EndMode3D(); - DrawText("PLAYER2 UP/DOWN to move", 10, 10, 20, BLUE); + + DrawRectangle(0, 0, GetScreenWidth()/2, 40, Fade(RAYWHITE, 0.8f)); + DrawText("PLAYER2: UP/DOWN to move", 10, 10, 20, DARKBLUE); + EndTextureMode(); // Draw both views render textures to the screen side by side BeginDrawing(); ClearBackground(BLACK); + DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE); DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE); + + DrawRectangle(GetScreenWidth()/2 - 2, 0, 4, GetScreenHeight(), LIGHTGRAY); EndDrawing(); } diff --git a/examples/core/core_3d_camera_split_screen.png b/examples/core/core_3d_camera_split_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..bc323d6adbb22a04677a9435398234601dd45429 GIT binary patch literal 16165 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 D;+@s` literal 0 HcmV?d00001 diff --git a/examples/core/core_camera_2d_split_screen.c b/examples/core/core_camera_2d_split_screen.c deleted file mode 100644 index 5f50595695a9..000000000000 --- a/examples/core/core_camera_2d_split_screen.c +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************************* -* -* raylib [core] example - split screen -* -* Addapted from the Split Screen example (https://github.com/raysan5/raylib/blob/master/examples/core/core_split_screen.c) -* -* Example originally created with raylib 4.5, last time updated with raylib 4.5 -* -* Example contributed by Jeffery Myers (@JeffM2501) and reviewed by Ramon Santamaria (@raysan5) -* -* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, -* BSD-like license that allows static linking with closed source software -* -* Copyright (c) 2021-2023 Jeffery Myers (@JeffM2501) -* -********************************************************************************************/ - -#include "raylib.h" - -#include - -#define PLAYER_SIZE 40 - -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ -int main(void) -{ - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 440; - - InitWindow(screenWidth, screenHeight, "raylib [core] example - camera 2D split screen"); - - Rectangle player1 = { 200, 200, PLAYER_SIZE, PLAYER_SIZE }; - Rectangle player2 = { 250, 200, PLAYER_SIZE, PLAYER_SIZE }; - - Camera2D camera1 = { 0 }; - camera1.target = (Vector2){ player1.x, player1.y }; - camera1.offset = (Vector2){ 200.0f, 200.0f }; - camera1.rotation = 0.0f; - camera1.zoom = 1.0f; - - Camera2D camera2 = { 0 }; - camera2.target = (Vector2){ player2.x, player2.y }; - camera2.offset = (Vector2){ 200.0f, 200.0f }; - camera2.rotation = 0.0f; - camera2.zoom = 1.0f; - - RenderTexture screenCamera1 = LoadRenderTexture(screenWidth / 2, screenHeight); - RenderTexture screenCamera2 = LoadRenderTexture(screenWidth / 2, screenHeight); - - // Build a flipped rectangle the size of the split view to use for drawing later - Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenCamera1.texture.width, (float)-screenCamera1.texture.height }; - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- - void DrawScene(void) { - for (int i = 0; i < screenWidth/PLAYER_SIZE + 1; i++) - { - DrawLineV((Vector2){PLAYER_SIZE*i, 0}, (Vector2){PLAYER_SIZE*i, screenHeight}, LIGHTGRAY); - } - - for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++) - { - DrawLineV((Vector2){0, PLAYER_SIZE*i}, (Vector2){screenWidth, PLAYER_SIZE*i}, LIGHTGRAY); - } - - for (int i = 0; i < screenWidth/PLAYER_SIZE; i++) - { - for (int j = 0; j < screenHeight/PLAYER_SIZE; j++) - { - char coordinate_str[8]; - snprintf(coordinate_str, sizeof(coordinate_str), "%d,%d", i, j); - DrawText(coordinate_str, 10 + PLAYER_SIZE*i, 10 + PLAYER_SIZE*j, 10, LIGHTGRAY); - } - } - - DrawRectangleRec(player1, RED); - DrawRectangleRec(player2, BLUE); - } - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - if (IsKeyDown(KEY_S)) player1.y += 3; - else if (IsKeyDown(KEY_W)) player1.y -= 3; - if (IsKeyDown(KEY_D)) player1.x += 3; - else if (IsKeyDown(KEY_A)) player1.x -= 3; - - if (IsKeyDown(KEY_UP)) player2.y += 3; - else if (IsKeyDown(KEY_DOWN)) player2.y -= 3; - if (IsKeyDown(KEY_RIGHT)) player2.x += 3; - else if (IsKeyDown(KEY_LEFT)) player2.x -= 3; - - camera1.target = (Vector2){ player1.x, player1.y }; - camera2.target = (Vector2){ player2.x, player2.y }; - - // Draw - //---------------------------------------------------------------------------------- - BeginTextureMode(screenCamera1); - ClearBackground(RAYWHITE); - BeginMode2D(camera1); - DrawScene(); - EndMode2D(); - DrawText("PLAYER1 W/S/A/D to move", 10, 10, 15, RED); - EndTextureMode(); - - BeginTextureMode(screenCamera2); - ClearBackground(RAYWHITE); - BeginMode2D(camera2); - DrawScene(); - EndMode2D(); - DrawText("PLAYER2 UP/DOWN/LEFT/RIGHT to move", 10, 10, 15, BLUE); - EndTextureMode(); - - // Draw both views render textures to the screen side by side - BeginDrawing(); - ClearBackground(BLACK); - DrawTextureRec(screenCamera1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE); - DrawTextureRec(screenCamera2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE); - EndDrawing(); - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - UnloadRenderTexture(screenCamera1); // Unload render texture - UnloadRenderTexture(screenCamera2); // Unload render texture - - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -} diff --git a/examples/core/core_camera_2d_split_screen.png b/examples/core/core_camera_2d_split_screen.png deleted file mode 100644 index ed5aaa58bfc2bb8124098d2b5c583961414bc218..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20010 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 diff --git a/examples/core/core_split_screen.png b/examples/core/core_split_screen.png deleted file mode 100644 index eace9027b0710f3a743641e6ca7d4930295d5603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21609 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 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/projects/VS2022/examples/core_split_screen.vcxproj b/projects/VS2022/examples/core_2d_camera_split_screen.vcxproj similarity index 98% rename from projects/VS2022/examples/core_split_screen.vcxproj rename to projects/VS2022/examples/core_2d_camera_split_screen.vcxproj index 1005e2eaf95e..98ddc9ed3fef 100644 --- a/projects/VS2022/examples/core_split_screen.vcxproj +++ b/projects/VS2022/examples/core_2d_camera_split_screen.vcxproj @@ -35,11 +35,11 @@ - {946A1700-C7AA-46F0-AEF2-67C98B5722AC} + {CC62F7DB-D089-4677-8575-CAB7A7815C43} Win32Proj - core_split_screen + core_2d_camera_split_screen 10.0 - core_split_screen + core_2d_camera_split_screen @@ -374,7 +374,7 @@ - + diff --git a/projects/VS2022/examples/core_camera_2d_split_screen.vcxproj b/projects/VS2022/examples/core_3d_camera_split_screen.vcxproj similarity index 99% rename from projects/VS2022/examples/core_camera_2d_split_screen.vcxproj rename to projects/VS2022/examples/core_3d_camera_split_screen.vcxproj index 1efc58a654d7..f39ccc205c82 100644 --- a/projects/VS2022/examples/core_camera_2d_split_screen.vcxproj +++ b/projects/VS2022/examples/core_3d_camera_split_screen.vcxproj @@ -37,9 +37,9 @@ {946A1700-C7AA-46F0-AEF2-67C98B5722AC} Win32Proj - core_camera_2d_split_screen + core_3d_camera_split_screen 10.0 - core_camera_2d_split_screen + core_3d_camera_split_screen @@ -374,7 +374,7 @@ - + @@ -384,4 +384,4 @@ - + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 1736375544fe..007f796f9095 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -33,6 +33,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_free", "exam EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_mode", "examples\core_3d_camera_mode.vcxproj", "{6D1CA2F1-7FCA-4249-9220-075C2DF4F965}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_split_screen", "examples\core_3d_camera_split_screen.vcxproj", "{946A1700-C7AA-46F0-AEF2-67C98B5722AC}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_picking", "examples\core_3d_picking.vcxproj", "{FD193822-3D5C-4161-A147-884C2ABDE483}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_logging", "examples\core_custom_logging.vcxproj", "{20AD0AC9-9159-4744-99CC-6AC5779D6B87}" @@ -233,8 +235,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "easings_testbed", "examples EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_standalone", "examples\rlgl_standalone.vcxproj", "{C8765523-58F8-4C8E-9914-693396F6F0FF}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_split_screen", "examples\core_split_screen.vcxproj", "{946A1700-C7AA-46F0-AEF2-67C98B5722AC}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_vox", "examples\models_loading_vox.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_gltf", "examples\models_loading_gltf.vcxproj", "{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}" @@ -271,6 +271,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_hybrid_render", "ex EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_multi", "examples\audio_sound_multi.vcxproj", "{F81C5819-85B4-4D2E-B6DC-104A7634461B}" 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|x64 = Debug.DLL|x64 @@ -507,6 +509,22 @@ Global {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x64.Build.0 = Release|x64 {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x86.ActiveCfg = Release|Win32 {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x86.Build.0 = Release|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.ActiveCfg = Debug|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.Build.0 = Debug|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.ActiveCfg = Debug|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.Build.0 = Debug|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.ActiveCfg = Release|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.Build.0 = Release|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.ActiveCfg = Release|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.Build.0 = Release|Win32 {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 @@ -1975,22 +1993,6 @@ Global {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.Build.0 = Release|x64 {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.ActiveCfg = Release|Win32 {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.Build.0 = Release|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.ActiveCfg = Debug|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.Build.0 = Debug|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.ActiveCfg = Debug|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.Build.0 = Debug|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.ActiveCfg = Release|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.Build.0 = Release|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.ActiveCfg = Release|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.Build.0 = Release|Win32 {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 @@ -2279,6 +2281,22 @@ Global {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x64.Build.0 = Release|x64 {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x86.ActiveCfg = Release|Win32 {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x86.Build.0 = Release|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x64.ActiveCfg = Debug|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x64.Build.0 = Debug|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x86.ActiveCfg = Debug|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x86.Build.0 = Debug|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x64.ActiveCfg = Release|x64 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2297,6 +2315,7 @@ Global {557138B0-7BE2-4392-B2E2-B45734031A62} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {9EED87BB-527F-4D05-9384-6D16CFD627A8} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {6D1CA2F1-7FCA-4249-9220-075C2DF4F965} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {946A1700-C7AA-46F0-AEF2-67C98B5722AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {FD193822-3D5C-4161-A147-884C2ABDE483} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {20AD0AC9-9159-4744-99CC-6AC5779D6B87} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {0199E349-0701-40BC-8A7F-06A54FFA3E7C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} @@ -2397,7 +2416,6 @@ Global {FDE6080B-E203-4066-910D-AD0302566008} = {E9D708A5-9C1F-4B84-A795-C5F191801762} {E1B6D565-9D7C-46B7-9202-ECF54974DE50} = {E9D708A5-9C1F-4B84-A795-C5F191801762} {C8765523-58F8-4C8E-9914-693396F6F0FF} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {946A1700-C7AA-46F0-AEF2-67C98B5722AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {2F1B955B-275E-4D8E-8864-06FEC44D7912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {F2DB2E59-76BF-4D81-859A-AFC289C046C0} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} @@ -2416,6 +2434,7 @@ Global {70B35F59-AFC2-4D8F-8833-5314D2047A81} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From 3c1331f954aa83820c48f766aa815ef6fd7ac103 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 8 Sep 2023 20:01:19 +0200 Subject: [PATCH 68/89] Update rtext.c --- src/rtext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtext.c b/src/rtext.c index 04d7a2a14265..146fc68f4e65 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -788,7 +788,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp } } - // Copy pixel data from fc.data to atlas + // Copy pixel data from glyph image to atlas for (int y = 0; y < glyphs[i].image.height; y++) { for (int x = 0; x < glyphs[i].image.width; x++) From f8e05e39810c1c810d12e2682341b8dc3bf76da1 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 8 Sep 2023 20:01:52 +0200 Subject: [PATCH 69/89] Some code restructuring for input functions, consistency review --- src/rcore.c | 100 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index fcb222bb36eb..2f112aee56f8 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -389,15 +389,15 @@ typedef struct CoreData { bool resizedLastFrame; // Check if window has been resized last frame bool eventWaiting; // Wait for events before ending frame - Point position; // Window position on screen (required on fullscreen toggle) + 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) Matrix screenScale; // Matrix to scale screen (framebuffer rendering) - Point previousPosition; // Previous screen position (required on borderless windowed toggle) - Size previousScreen; // Previous screen size (required on borderless windowed toggle) char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) unsigned int dropFileCount; // Count dropped files strings @@ -3753,10 +3753,12 @@ void OpenURL(const char *url) // Check if a key has been pressed once bool IsKeyPressed(int key) { - if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; bool pressed = false; - if ((CORE.Input.Keyboard.previousKeyState[key] == 0) && (CORE.Input.Keyboard.currentKeyState[key] == 1)) pressed = true; + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) + { + if ((CORE.Input.Keyboard.previousKeyState[key] == 0) && (CORE.Input.Keyboard.currentKeyState[key] == 1)) pressed = true; + } return pressed; } @@ -3764,26 +3766,38 @@ bool IsKeyPressed(int key) // Check if a key has been pressed again (only PLATFORM_DESKTOP) bool IsKeyPressedRepeat(int key) { - if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; - if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) return true; - else return false; + bool repeat = false; + + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) + { + if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) repeat = true; + } + + return repeat; } // Check if a key is being pressed (key held down) bool IsKeyDown(int key) { - if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; - if (CORE.Input.Keyboard.currentKeyState[key] == 1) return true; - else return false; + bool down = false; + + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) + { + if (CORE.Input.Keyboard.currentKeyState[key] == 1) down = true; + } + + return down; } // Check if a key has been released once bool IsKeyReleased(int key) { - if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; bool released = false; - - if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true; + + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) + { + if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true; + } return released; } @@ -3791,9 +3805,14 @@ bool IsKeyReleased(int key) // Check if a key is NOT being pressed (key not held down) bool IsKeyUp(int key) { - if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return false; - if (CORE.Input.Keyboard.currentKeyState[key] == 0) return true; - else return false; + bool up = false; + + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) + { + if (CORE.Input.Keyboard.currentKeyState[key] == 0) up = true; + } + + return up; } // Get the last key pressed @@ -3806,7 +3825,7 @@ int GetKeyPressed(void) // Get character from the queue head value = CORE.Input.Keyboard.keyPressedQueue[0]; - // Shift elements 1 step toward the head. + // Shift elements 1 step toward the head for (int i = 0; i < (CORE.Input.Keyboard.keyPressedQueueCount - 1); i++) CORE.Input.Keyboard.keyPressedQueue[i] = CORE.Input.Keyboard.keyPressedQueue[i + 1]; @@ -3828,7 +3847,7 @@ int GetCharPressed(void) // Get character from the queue head value = CORE.Input.Keyboard.charPressedQueue[0]; - // Shift elements 1 step toward the head. + // Shift elements 1 step toward the head for (int i = 0; i < (CORE.Input.Keyboard.charPressedQueueCount - 1); i++) CORE.Input.Keyboard.charPressedQueue[i] = CORE.Input.Keyboard.charPressedQueue[i + 1]; @@ -3864,18 +3883,23 @@ bool IsGamepadAvailable(int gamepad) // Get gamepad internal name id const char *GetGamepadName(int gamepad) { + const char *name = NULL; + #if defined(PLATFORM_DESKTOP) - if (CORE.Input.Gamepad.ready[gamepad]) return glfwGetJoystickName(gamepad); - else return NULL; + if (CORE.Input.Gamepad.ready[gamepad]) name = glfwGetJoystickName(gamepad); #endif #if defined(PLATFORM_DRM) - if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]); - return CORE.Input.Gamepad.name[gamepad]; + if (CORE.Input.Gamepad.ready[gamepad]) + { + ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]); + name = CORE.Input.Gamepad.name[gamepad]; + } #endif #if defined(PLATFORM_WEB) - return CORE.Input.Gamepad.name[gamepad]; + name = CORE.Input.Gamepad.name[gamepad]; #endif - return NULL; + + return name; } // Get gamepad axis count @@ -3915,12 +3939,12 @@ bool IsGamepadButtonPressed(int gamepad, int button) // Check if a gamepad button is being pressed bool IsGamepadButtonDown(int gamepad, int button) { - bool result = false; + bool down = false; if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) result = true; + (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) down = true; - return result; + return down; } // Check if a gamepad button has NOT been pressed once @@ -3937,12 +3961,12 @@ bool IsGamepadButtonReleased(int gamepad, int button) // Check if a gamepad button is NOT being pressed bool IsGamepadButtonUp(int gamepad, int button) { - bool result = false; + bool up = false; if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) result = true; + (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) up = true; - return result; + return up; } // Get the last gamepad button pressed @@ -3983,7 +4007,7 @@ bool IsMouseButtonDown(int button) if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true; - // Map touches to mouse buttons checking + // NOTE: Touches are considered like mouse buttons if (CORE.Input.Touch.currentTouchState[button] == 1) down = true; return down; @@ -4005,7 +4029,14 @@ bool IsMouseButtonReleased(int button) // Check if a mouse button is NOT being pressed bool IsMouseButtonUp(int button) { - return !IsMouseButtonDown(button); + bool up = false; + + if (CORE.Input.Mouse.currentButtonState[button] == 0) up = true; + + // NOTE: Touches are considered like mouse buttons + if (CORE.Input.Touch.currentTouchState[button] == 0) up = true; + + return up; } // Get mouse position X @@ -4032,10 +4063,13 @@ int GetMouseY(void) Vector2 GetMousePosition(void) { Vector2 position = { 0 }; + + // TODO: Review touch position on PLATFORM_WEB #if defined(PLATFORM_ANDROID) //|| defined(PLATFORM_WEB) position = GetTouchPosition(0); #else + // NOTE: On PLATFORM_WEB, even on canvas scaling, mouse position is proportionally returned position.x = (CORE.Input.Mouse.currentPosition.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x; position.y = (CORE.Input.Mouse.currentPosition.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y; #endif From e6b645ff2af7fbf49680c40039496006c1f4a329 Mon Sep 17 00:00:00 2001 From: MichaelFiber <42419558+michaelfiber@users.noreply.github.com> Date: Sat, 9 Sep 2023 03:47:07 -0400 Subject: [PATCH 70/89] Remove unneeded #if (#3301) Co-authored-by: MichaelFiber --- src/rcore.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 2f112aee56f8..8df087f8345a 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -265,11 +265,9 @@ #include // Linux: Keycodes constants definition (KEY_A, ...) #include // Linux: Joystick support library -#if defined(PLATFORM_DRM) #include // Generic Buffer Management (native platform for EGL on DRM) #include // Direct Rendering Manager user-level library interface #include // Direct Rendering Manager mode setting (KMS) interface -#endif #include "EGL/egl.h" // Native platform windowing system interface #include "EGL/eglext.h" // EGL extensions From f927b99b63acb4b4db2fca669b4d832dfd6059fa Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Sat, 9 Sep 2023 11:32:28 -0400 Subject: [PATCH 71/89] Revert "Disable UBSAN in zig builds. (#3292)" (#3303) This reverts commit a316f9e7fc7f8e06852a40544e57f89018672ee4. Issue #1891 was fixed again, so this is no longer needed. --- src/build.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/build.zig b/src/build.zig index 09d954bf5a9b..27250f5ff060 100644 --- a/src/build.zig +++ b/src/build.zig @@ -6,7 +6,6 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built "-std=gnu99", "-D_GNU_SOURCE", "-DGL_SILENCE_DEPRECATION=199309L", - "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 }; const raylib = b.addStaticLibrary(.{ From 19cbdbb4e7c595ac41d661dc7729aac5ff8e081f Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Mon, 11 Sep 2023 13:00:30 -0400 Subject: [PATCH 72/89] rtextures: Fix ImageDraw() source clipping when drawing beyond top left (#3306) --- src/rtextures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtextures.c b/src/rtextures.c index 4e2fdbd9139d..c86ebac39f37 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3481,7 +3481,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // Destination rectangle out-of-bounds security checks if (dstRec.x < 0) { - srcRec.x = -dstRec.x; + srcRec.x -= dstRec.x; srcRec.width += dstRec.x; dstRec.x = 0; } @@ -3489,7 +3489,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color if (dstRec.y < 0) { - srcRec.y = -dstRec.y; + srcRec.y -= dstRec.y; srcRec.height += dstRec.y; dstRec.y = 0; } From 2917c522c6e7e4ebe7740765e941946a6024efe4 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 11 Sep 2023 19:01:24 +0200 Subject: [PATCH 73/89] REVIEWED: `TextToPascal()` issue when first char is uppercase --- src/rtext.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rtext.c b/src/rtext.c index 146fc68f4e65..fb8440131ea6 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1676,6 +1676,7 @@ const char *TextToPascal(const char *text) { // Upper case first character if ((text[0] >= 'a') && (text[0] <= 'z')) buffer[0] = text[0] - 32; + else buffer[0] = text[0]; // Check for next separator to upper case another character for (int i = 1, j = 1; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[j] != '\0'); i++, j++) From 330e7010f487f0697ab81a68139e1b0d83b8ea9c Mon Sep 17 00:00:00 2001 From: Peter0x44 Date: Mon, 11 Sep 2023 17:03:33 +0000 Subject: [PATCH 74/89] Implement FLAG_WINDOW_RESIZABLE for web (#3305) Fixes #3231 --- src/rcore.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 8df087f8345a..beb611040f44 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -914,9 +914,9 @@ void InitWindow(int width, int height, const char *title) // Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas) //emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); // Check Resize event (note this is done on the window since most browsers don't support this on #canvas) - //emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); + emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); // Trigger this once to get initial window sizing - //EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); + EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); // Support keyboard events -> Not used, GLFW.JS takes care of that //emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); @@ -6165,8 +6165,8 @@ static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUi return 1; // The event was consumed by the callback handler } -EM_JS(int, GetCanvasWidth, (), { return canvas.clientWidth; }); -EM_JS(int, GetCanvasHeight, (), { return canvas.clientHeight; }); +EM_JS(int, GetWindowInnerWidth, (), { return window.innerWidth; }); +EM_JS(int, GetWindowInnerHeight, (), { return window.innerHeight; }); // Register DOM element resize event static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData) @@ -6176,8 +6176,8 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * // This event is called whenever the window changes sizes, // so the size of the canvas object is explicitly retrieved below - int width = GetCanvasWidth(); - int height = GetCanvasHeight(); + int width = GetWindowInnerWidth(); + int height = GetWindowInnerHeight(); emscripten_set_canvas_element_size("#canvas",width,height); SetupViewport(width, height); // Reset viewport and projection matrix for new size From 45c385304bbddc5f09e0fdb26cbe50428e60593b Mon Sep 17 00:00:00 2001 From: Kenta <106167071+Its-Kenta@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:19:43 +0100 Subject: [PATCH 75/89] Update BINDINGS.md (#3307) Fix Kaylib binding. Reroute to a new repository. Binding renamed. --- BINDINGS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BINDINGS.md b/BINDINGS.md index bdd5e2558125..c26fa873e4ca 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -37,7 +37,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | 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 | -| kaylib | **4.5**| [Kotlin/native](https://kotlinlang.org) | Zlib | https://codeberg.org/Soutaisei/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 | | nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib | From e98bca66f6d22d76a4535b3ad91ab78606fb0db8 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 12 Sep 2023 15:11:16 +0200 Subject: [PATCH 76/89] Update webassembly.yml --- .github/workflows/webassembly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/webassembly.yml b/.github/workflows/webassembly.yml index b50cd8c4675b..9374cb9ebb64 100644 --- a/.github/workflows/webassembly.yml +++ b/.github/workflows/webassembly.yml @@ -27,7 +27,7 @@ jobs: uses: actions/checkout@master - name: Setup emsdk - uses: mymindstorm/setup-emsdk@v11 + uses: mymindstorm/setup-emsdk@v12 with: version: 3.1.30 actions-cache-folder: 'emsdk-cache' From 3ba12dfa31bc7fc63c53589e4783a61d45ac523c Mon Sep 17 00:00:00 2001 From: bohonghuang <1281299809@qq.com> Date: Wed, 13 Sep 2023 22:35:37 +0800 Subject: [PATCH 77/89] Add claw-raylib to BINDINGS.md (#3310) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index c26fa873e4ca..28e2c542e40e 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -12,6 +12,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | Raylib-CsLo | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/NotNotTech/Raylib-CsLo | | cl-raylib | 4.0 | [Common Lisp](https://common-lisp.net/) | MIT | https://github.com/longlene/cl-raylib | | claylib/wrap | **4.5** | [Common Lisp](https://common-lisp.net/) | Zlib | https://github.com/defun-games/claylib | +| claw-raylib | **auto** | [Common Lisp](https://common-lisp.net/) | Apache-2.0 | https://github.com/bohonghuang/claw-raylib | | chez-raylib | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme/) | GPLv3 | https://github.com/Yunoinsky/chez-raylib | | raylib-cr | **4.6-dev (5e1a81)** | [Crystal](https://crystal-lang.org/) | Apache-2.0 | https://github.com/sol-vin/raylib-cr | | ray-cyber | 4.5 | [Cyber](https://cyberscript.dev) | MIT | https://github.com/fubark/ray-cyber | From ab1c437aa1ca7479349de9bd8001da282bbf8550 Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Wed, 13 Sep 2023 11:37:11 -0300 Subject: [PATCH 78/89] Add SetWindowMaxSize for desktop and web (#3309) * Add SetWindowMaxSize for desktop and web * Remove SizeInt and respective adjustments --- src/raylib.h | 1 + src/rcore.c | 72 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 4f3e353807c4..94e79a5f7077 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -961,6 +961,7 @@ RLAPI void SetWindowTitle(const char *title); // Set title f 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 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) diff --git a/src/rcore.c b/src/rcore.c index beb611040f44..771a8380db82 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -395,9 +395,11 @@ typedef struct CoreData { 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 windowMin; // Window minimum width and height (for resizable window) + Size windowMax; // Window 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) + char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) unsigned int dropFileCount; // Count dropped files strings } Window; @@ -1787,9 +1789,36 @@ void SetWindowMonitor(int monitor) // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) void SetWindowMinSize(int width, int height) { + CORE.Window.windowMin.width = width; + CORE.Window.windowMin.height = height; #if defined(PLATFORM_DESKTOP) - const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - glfwSetWindowSizeLimits(CORE.Window.handle, width, height, mode->width, mode->height); + int minWidth = (CORE.Window.windowMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.width; + int minHeight = (CORE.Window.windowMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.height; + int maxWidth = (CORE.Window.windowMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.width; + int maxHeight = (CORE.Window.windowMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.height; + glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight); +#endif +#if defined(PLATFORM_WEB) + // Trigger the resize event once to update the window minimum width and height + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); +#endif +} + +// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMaxSize(int width, int height) +{ + CORE.Window.windowMax.width = width; + CORE.Window.windowMax.height = height; +#if defined(PLATFORM_DESKTOP) + int minWidth = (CORE.Window.windowMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.width; + int minHeight = (CORE.Window.windowMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.height; + int maxWidth = (CORE.Window.windowMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.width; + int maxHeight = (CORE.Window.windowMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.height; + glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight); +#endif +#if defined(PLATFORM_WEB) + // Trigger the resize event once to update the window maximum width and height + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); #endif } @@ -3182,7 +3211,7 @@ bool DirectoryExists(const char *dirPath) int GetFileLength(const char *fileName) { int size = 0; - + // NOTE: On Unix-like systems, it can by used the POSIX system call: stat(), // but depending on the platform that call could not be available //struct stat result = { 0 }; @@ -3195,11 +3224,11 @@ int GetFileLength(const char *fileName) { fseek(file, 0L, SEEK_END); long int fileSize = ftell(file); - + // Check for size overflow (INT_MAX) if (fileSize > 2147483647) TRACELOG(LOG_WARNING, "[%s] File size overflows expected limit, do not use GetFileLength()", fileName); else size = (int)fileSize; - + fclose(file); } @@ -3765,12 +3794,12 @@ bool IsKeyPressed(int key) bool IsKeyPressedRepeat(int key) { bool repeat = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) repeat = true; } - + return repeat; } @@ -3778,12 +3807,12 @@ bool IsKeyPressedRepeat(int key) bool IsKeyDown(int key) { bool down = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if (CORE.Input.Keyboard.currentKeyState[key] == 1) down = true; } - + return down; } @@ -3791,7 +3820,7 @@ bool IsKeyDown(int key) bool IsKeyReleased(int key) { bool released = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true; @@ -3804,12 +3833,12 @@ bool IsKeyReleased(int key) bool IsKeyUp(int key) { bool up = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if (CORE.Input.Keyboard.currentKeyState[key] == 0) up = true; } - + return up; } @@ -3887,7 +3916,7 @@ const char *GetGamepadName(int gamepad) if (CORE.Input.Gamepad.ready[gamepad]) name = glfwGetJoystickName(gamepad); #endif #if defined(PLATFORM_DRM) - if (CORE.Input.Gamepad.ready[gamepad]) + if (CORE.Input.Gamepad.ready[gamepad]) { ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]); name = CORE.Input.Gamepad.name[gamepad]; @@ -4061,7 +4090,7 @@ int GetMouseY(void) Vector2 GetMousePosition(void) { Vector2 position = { 0 }; - + // TODO: Review touch position on PLATFORM_WEB #if defined(PLATFORM_ANDROID) //|| defined(PLATFORM_WEB) @@ -4220,6 +4249,12 @@ static bool InitGraphicsDevice(int width, int height) CORE.Window.screen.height = height; // User desired height CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default + // Set the window minimum and maximum default values to 0 + CORE.Window.windowMin.width = 0; + CORE.Window.windowMin.height = 0; + CORE.Window.windowMax.width = 0; + CORE.Window.windowMax.height = 0; + // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars... // ...in top-down or left-right to match display aspect ratio (no weird scaling) @@ -6178,6 +6213,13 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * // so the size of the canvas object is explicitly retrieved below int width = GetWindowInnerWidth(); int height = GetWindowInnerHeight(); + + if (width < CORE.Window.windowMin.width) width = CORE.Window.windowMin.width; + else if (width > CORE.Window.windowMax.width && CORE.Window.windowMax.width > 0) width = CORE.Window.windowMax.width; + + if (height < CORE.Window.windowMin.height) height = CORE.Window.windowMin.height; + else if (height > CORE.Window.windowMax.height && CORE.Window.windowMax.height > 0) height = CORE.Window.windowMax.height; + emscripten_set_canvas_element_size("#canvas",width,height); SetupViewport(width, height); // Reset viewport and projection matrix for new size From 20424f1543c09515ff6fa90e5e19e93d5ddc408e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 13 Sep 2023 17:05:22 +0200 Subject: [PATCH 79/89] Update rtextures.c --- src/rtextures.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rtextures.c b/src/rtextures.c index c86ebac39f37..a6741ee2a02b 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -322,9 +322,10 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int Image LoadImageSvg(const char *fileNameOrString, int width, int height) { Image image = { 0 }; + +#if defined(SUPPORT_FILEFORMAT_SVG) bool isSvgStringValid = false; -#if defined(SUPPORT_FILEFORMAT_SVG) // Validate fileName or string if (fileNameOrString != NULL) { From 41ce1bf0af62cdbdc94f9d5d76349355fca4cd5e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 13 Sep 2023 17:05:38 +0200 Subject: [PATCH 80/89] Reviewed parameters for consistency --- src/raylib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 94e79a5f7077..07b64aeb6dce 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -918,8 +918,8 @@ typedef enum { // Callbacks to hook some internal functions // WARNING: These callbacks are intended for advance users typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages -typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, unsigned int *bytesRead); // FileIO: Load binary data -typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, unsigned int bytesToWrite); // FileIO: Save binary data +typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data +typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data From 605032ce0fd47c0a3fc2a63ecd8456532fabda4a Mon Sep 17 00:00:00 2001 From: ubkp <118854183+ubkp@users.noreply.github.com> Date: Thu, 14 Sep 2023 06:57:23 -0300 Subject: [PATCH 81/89] Rename windowM* to screenM* (#3312) --- src/rcore.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 771a8380db82..0d3c6e12ae66 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -395,8 +395,8 @@ typedef struct CoreData { 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 windowMin; // Window minimum width and height (for resizable window) - Size windowMax; // Window maximum width and height (for resizable window) + 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) @@ -1789,13 +1789,13 @@ void SetWindowMonitor(int monitor) // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) void SetWindowMinSize(int width, int height) { - CORE.Window.windowMin.width = width; - CORE.Window.windowMin.height = height; + CORE.Window.screenMin.width = width; + CORE.Window.screenMin.height = height; #if defined(PLATFORM_DESKTOP) - int minWidth = (CORE.Window.windowMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.width; - int minHeight = (CORE.Window.windowMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.height; - int maxWidth = (CORE.Window.windowMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.width; - int maxHeight = (CORE.Window.windowMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.height; + int minWidth = (CORE.Window.screenMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.screenMin.width; + int minHeight = (CORE.Window.screenMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.screenMin.height; + int maxWidth = (CORE.Window.screenMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.screenMax.width; + int maxHeight = (CORE.Window.screenMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.screenMax.height; glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight); #endif #if defined(PLATFORM_WEB) @@ -1807,13 +1807,13 @@ void SetWindowMinSize(int width, int height) // Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) void SetWindowMaxSize(int width, int height) { - CORE.Window.windowMax.width = width; - CORE.Window.windowMax.height = height; + CORE.Window.screenMax.width = width; + CORE.Window.screenMax.height = height; #if defined(PLATFORM_DESKTOP) - int minWidth = (CORE.Window.windowMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.width; - int minHeight = (CORE.Window.windowMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.height; - int maxWidth = (CORE.Window.windowMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.width; - int maxHeight = (CORE.Window.windowMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.height; + int minWidth = (CORE.Window.screenMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.screenMin.width; + int minHeight = (CORE.Window.screenMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.screenMin.height; + int maxWidth = (CORE.Window.screenMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.screenMax.width; + int maxHeight = (CORE.Window.screenMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.screenMax.height; glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight); #endif #if defined(PLATFORM_WEB) @@ -4249,11 +4249,11 @@ static bool InitGraphicsDevice(int width, int height) CORE.Window.screen.height = height; // User desired height CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default - // Set the window minimum and maximum default values to 0 - CORE.Window.windowMin.width = 0; - CORE.Window.windowMin.height = 0; - CORE.Window.windowMax.width = 0; - CORE.Window.windowMax.height = 0; + // Set the screen minimum and maximum default values to 0 + CORE.Window.screenMin.width = 0; + CORE.Window.screenMin.height = 0; + CORE.Window.screenMax.width = 0; + CORE.Window.screenMax.height = 0; // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars... // ...in top-down or left-right to match display aspect ratio (no weird scaling) @@ -6214,11 +6214,11 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * int width = GetWindowInnerWidth(); int height = GetWindowInnerHeight(); - if (width < CORE.Window.windowMin.width) width = CORE.Window.windowMin.width; - else if (width > CORE.Window.windowMax.width && CORE.Window.windowMax.width > 0) width = CORE.Window.windowMax.width; + if (width < CORE.Window.screenMin.width) width = CORE.Window.screenMin.width; + else if (width > CORE.Window.screenMax.width && CORE.Window.screenMax.width > 0) width = CORE.Window.screenMax.width; - if (height < CORE.Window.windowMin.height) height = CORE.Window.windowMin.height; - else if (height > CORE.Window.windowMax.height && CORE.Window.windowMax.height > 0) height = CORE.Window.windowMax.height; + if (height < CORE.Window.screenMin.height) height = CORE.Window.screenMin.height; + else if (height > CORE.Window.screenMax.height && CORE.Window.screenMax.height > 0) height = CORE.Window.screenMax.height; emscripten_set_canvas_element_size("#canvas",width,height); From 60af3768a1d725d4890b381d47af76763c4554f1 Mon Sep 17 00:00:00 2001 From: turborium <45082001+turborium@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:32:50 +0400 Subject: [PATCH 82/89] Update BINDINGS.md (#3317) Update TurboRaylib bindings --- BINDINGS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BINDINGS.md b/BINDINGS.md index 28e2c542e40e..b02bba8aba8c 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -50,7 +50,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | raylib-odin | **4.5** | [Odin](https://odin-lang.org/) | BSD-3Clause | https://github.com/odin-lang/Odin/tree/master/vendor/raylib | | raylib_odin_bindings | 4.0-dev | [Odin](https://odin-lang.org/) | MIT | https://github.com/Deathbat2190/raylib_odin_bindings | | raylib-ocaml | 4.2 | [OCaml](https://ocaml.org/) | MIT | https://github.com/tjammer/raylib-ocaml | -| TurboRaylib | 4.2 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT | https://github.com/turborium/TurboRaylib | +| TurboRaylib | **4.5** | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT | https://github.com/turborium/TurboRaylib | | Ray4Laz | **4.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/GuvaCode/Ray4Laz | | Raylib.4.0.Pascal | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/sysrpl/Raylib.4.0.Pascal | | pyraylib | 3.7 | [Python](https://www.python.org/) | Zlib | https://github.com/Ho011/pyraylib | From 049d745cee32016e3e351e131156f4da9e1548d3 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 15 Sep 2023 17:04:07 +0200 Subject: [PATCH 83/89] Update rmodels.c --- src/rmodels.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rmodels.c b/src/rmodels.c index 9616f0ceb380..1f8568625691 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -5564,7 +5564,7 @@ static Model LoadVOX(const char *fileName) #if defined(SUPPORT_FILEFORMAT_M3D) // Hook LoadFileData()/UnloadFileData() calls to M3D loaders -unsigned char *m3d_loaderhook(char *fn, unsigned int *len) { return LoadFileData((const char *)fn, len); } +unsigned char *m3d_loaderhook(char *fn, unsigned int *len) { return LoadFileData((const char *)fn, (int *)len); } void m3d_freehook(void *data) { UnloadFileData((unsigned char *)data); } // Load M3D mesh data From c6802c735d9c2369105bf392d8071860764510cb Mon Sep 17 00:00:00 2001 From: Wilson Silva Date: Sun, 17 Sep 2023 00:56:38 +0700 Subject: [PATCH 84/89] Update BINDINGS.md with vaiorabbit/raylib-bindings (#3318) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index b02bba8aba8c..0eec1dc24f05 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -114,6 +114,7 @@ These are older raylib bindings that are more than 2 versions old or have not be | raylib-pas | 3.0 | [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) | https://github.com/tazdij/raylib-pas | | raylib-pascal | 2.0 | [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) | https://github.com/drezgames/raylib-pascal | | Graphics-Raylib | 1.4 | [Perl](https://www.perl.org/) | https://github.com/athreef/Graphics-Raylib | +| raylib-bindings | 4.5 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/vaiorabbit/raylib-bindings | | raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby | | raylib-ruby-ffi | 2.0 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/D3nX/raylib-ruby-ffi | | raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby | From 6139721d85015b0ea59542b0bac244e7f0a3b6f4 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sat, 16 Sep 2023 21:57:26 +0100 Subject: [PATCH 85/89] fixed spelling mistake --- parser/output/raylib_api.json | 2 +- parser/output/raylib_api.txt | 2 +- projects/Notepad++/raylib_npp_parser/raylib_npp.xml | 2 +- src/raylib.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/parser/output/raylib_api.json b/parser/output/raylib_api.json index b42f03a832d3..c53b1b31399c 100644 --- a/parser/output/raylib_api.json +++ b/parser/output/raylib_api.json @@ -4333,7 +4333,7 @@ }, { "name": "GetApplicationDirectory", - "description": "Get the directory if the running application (uses static string)", + "description": "Get the directory of the running application (uses static string)", "returnType": "const char *" }, { diff --git a/parser/output/raylib_api.txt b/parser/output/raylib_api.txt index 0d0ccccf19a9..13714bc49ad2 100644 --- a/parser/output/raylib_api.txt +++ b/parser/output/raylib_api.txt @@ -1641,7 +1641,7 @@ Function 126: GetWorkingDirectory() (0 input parameters) Function 127: GetApplicationDirectory() (0 input parameters) Name: GetApplicationDirectory Return type: const char * - Description: Get the directory if the running application (uses static string) + Description: Get the directory of the running application (uses static string) No input parameters Function 128: ChangeDirectory() (1 input parameters) Name: ChangeDirectory diff --git a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml index 883183cef071..12624addd41a 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +++ b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml @@ -603,7 +603,7 @@ - + diff --git a/src/raylib.h b/src/raylib.h index 07b64aeb6dce..98e5c48a0191 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1093,7 +1093,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 From 86f0cd8e63d3106739440b3db7b87d0e9e2f4613 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 17 Sep 2023 12:42:50 +0100 Subject: [PATCH 86/89] put back parenthesis --- src/raymath.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 4b377925f2c2..66853a8fd655 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -282,7 +282,7 @@ RMAPI float Vector2Length(Vector2 v) // Calculate vector square length RMAPI float Vector2LengthSqr(Vector2 v) { - float result = v.x*v.x + v.y*v.y; + float result = (v.x*v.x) + (v.y*v.y); return result; } @@ -290,7 +290,7 @@ RMAPI float Vector2LengthSqr(Vector2 v) // Calculate two vectors dot product RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2) { - float result = v1.x*v2.x + v1.y*v2.y; + float result = (v1.x*v2.x + v1.y*v2.y); return result; } @@ -306,7 +306,7 @@ RMAPI float Vector2Distance(Vector2 v1, Vector2 v2) // Calculate square distance between two vectors RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) { - float result = (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y); + float result = ((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); return result; } From 1aea876269f5f0364a2adf61a7d09c2e6160cff5 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 17 Sep 2023 12:58:58 +0100 Subject: [PATCH 87/89] reverted major allignment changes --- src/raymath.h | 300 +++++++++++++++++++++++++------------------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 66853a8fd655..e6740a1c48c7 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -792,8 +792,8 @@ RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat) float y = v.y; float z = v.z; - result.x = mat.m0*x + mat.m4*y + mat.m8 *z + mat.m12; - result.y = mat.m1*x + mat.m5*y + mat.m9 *z + mat.m13; + result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; + result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14; return result; @@ -804,9 +804,9 @@ RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q) { Vector3 result = { 0 }; - result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); - result.y = v.x*( 2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); - result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z) + v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); + result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); + result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); + result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); return result; } @@ -949,28 +949,28 @@ RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it Matrix matViewProj = { // MatrixMultiply(view, projection); - view.m0 *projection.m0 + view.m1 *projection.m4 + view.m2 *projection.m8 + view.m3*projection.m12, - view.m0 *projection.m1 + view.m1 *projection.m5 + view.m2 *projection.m9 + view.m3*projection.m13, - view.m0 *projection.m2 + view.m1 *projection.m6 + view.m2 *projection.m10 + view.m3*projection.m14, - view.m0 *projection.m3 + view.m1 *projection.m7 + view.m2 *projection.m11 + view.m3*projection.m15, - view.m4 *projection.m0 + view.m5 *projection.m4 + view.m6 *projection.m8 + view.m7*projection.m12, - view.m4 *projection.m1 + view.m5 *projection.m5 + view.m6 *projection.m9 + view.m7*projection.m13, - view.m4 *projection.m2 + view.m5 *projection.m6 + view.m6 *projection.m10 + view.m7*projection.m14, - view.m4 *projection.m3 + view.m5 *projection.m7 + view.m6 *projection.m11 + view.m7*projection.m15, - view.m8 *projection.m0 + view.m9 *projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, - view.m8 *projection.m1 + view.m9 *projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, - view.m8 *projection.m2 + view.m9 *projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, - view.m8 *projection.m3 + view.m9 *projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, - view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, - view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, + view.m0*projection.m0 + view.m1*projection.m4 + view.m2*projection.m8 + view.m3*projection.m12, + view.m0*projection.m1 + view.m1*projection.m5 + view.m2*projection.m9 + view.m3*projection.m13, + view.m0*projection.m2 + view.m1*projection.m6 + view.m2*projection.m10 + view.m3*projection.m14, + view.m0*projection.m3 + view.m1*projection.m7 + view.m2*projection.m11 + view.m3*projection.m15, + view.m4*projection.m0 + view.m5*projection.m4 + view.m6*projection.m8 + view.m7*projection.m12, + view.m4*projection.m1 + view.m5*projection.m5 + view.m6*projection.m9 + view.m7*projection.m13, + view.m4*projection.m2 + view.m5*projection.m6 + view.m6*projection.m10 + view.m7*projection.m14, + view.m4*projection.m3 + view.m5*projection.m7 + view.m6*projection.m11 + view.m7*projection.m15, + view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, + view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, + view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, + view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, + view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, + view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14, view.m12*projection.m3 + view.m13*projection.m7 + view.m14*projection.m11 + view.m15*projection.m15 }; // Calculate inverted matrix -> MatrixInvert(matViewProj); // Cache the matrix values (speed optimization) - float a00 = matViewProj.m0 , a01 = matViewProj.m1 , a02 = matViewProj.m2 , a03 = matViewProj.m3; - float a10 = matViewProj.m4 , a11 = matViewProj.m5 , a12 = matViewProj.m6 , a13 = matViewProj.m7; - float a20 = matViewProj.m8 , a21 = matViewProj.m9 , a22 = matViewProj.m10, a23 = matViewProj.m11; + float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3; + float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7; + float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11; float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15; float b00 = a00*a11 - a01*a10; @@ -990,22 +990,22 @@ RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); Matrix matViewProjInv = { - ( a11*b11 - a12*b10 + a13*b09)*invDet, + (a11*b11 - a12*b10 + a13*b09)*invDet, (-a01*b11 + a02*b10 - a03*b09)*invDet, - ( a31*b05 - a32*b04 + a33*b03)*invDet, + (a31*b05 - a32*b04 + a33*b03)*invDet, (-a21*b05 + a22*b04 - a23*b03)*invDet, (-a10*b11 + a12*b08 - a13*b07)*invDet, - ( a00*b11 - a02*b08 + a03*b07)*invDet, + (a00*b11 - a02*b08 + a03*b07)*invDet, (-a30*b05 + a32*b02 - a33*b01)*invDet, - ( a20*b05 - a22*b02 + a23*b01)*invDet, - ( a10*b10 - a11*b08 + a13*b06)*invDet, + (a20*b05 - a22*b02 + a23*b01)*invDet, + (a10*b10 - a11*b08 + a13*b06)*invDet, (-a00*b10 + a01*b08 - a03*b06)*invDet, - ( a30*b04 - a31*b02 + a33*b00)*invDet, + (a30*b04 - a31*b02 + a33*b00)*invDet, (-a20*b04 + a21*b02 - a23*b00)*invDet, (-a10*b09 + a11*b07 - a12*b06)*invDet, - ( a00*b09 - a01*b07 + a02*b06)*invDet, + (a00*b09 - a01*b07 + a02*b06)*invDet, (-a30*b03 + a31*b01 - a32*b00)*invDet, - ( a20*b03 - a21*b01 + a22*b00)*invDet }; + (a20*b03 - a21*b01 + a22*b00)*invDet }; // Create quaternion from source point Quaternion quat = { source.x, source.y, source.z, 1.0f }; @@ -1132,9 +1132,9 @@ RMAPI float MatrixDeterminant(Matrix mat) float result = 0.0f; // Cache the matrix values (speed optimization) - float a00 = mat.m0 , a01 = mat.m1 , a02 = mat.m2 , a03 = mat.m3; - float a10 = mat.m4 , a11 = mat.m5 , a12 = mat.m6 , a13 = mat.m7; - float a20 = mat.m8 , a21 = mat.m9 , a22 = mat.m10, a23 = mat.m11; + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 + @@ -1160,16 +1160,16 @@ RMAPI Matrix MatrixTranspose(Matrix mat) { Matrix result = { 0 }; - result.m0 = mat.m0; - result.m1 = mat.m4; - result.m2 = mat.m8; - result.m3 = mat.m12; - result.m4 = mat.m1; - result.m5 = mat.m5; - result.m6 = mat.m9; - result.m7 = mat.m13; - result.m8 = mat.m2; - result.m9 = mat.m6; + result.m0 = mat.m0; + result.m1 = mat.m4; + result.m2 = mat.m8; + result.m3 = mat.m12; + result.m4 = mat.m1; + result.m5 = mat.m5; + result.m6 = mat.m9; + result.m7 = mat.m13; + result.m8 = mat.m2; + result.m9 = mat.m6; result.m10 = mat.m10; result.m11 = mat.m14; result.m12 = mat.m3; @@ -1186,9 +1186,9 @@ RMAPI Matrix MatrixInvert(Matrix mat) Matrix result = { 0 }; // Cache the matrix values (speed optimization) - float a00 = mat.m0 , a01 = mat.m1 , a02 = mat.m2 , a03 = mat.m3; - float a10 = mat.m4 , a11 = mat.m5 , a12 = mat.m6 , a13 = mat.m7; - float a20 = mat.m8 , a21 = mat.m9 , a22 = mat.m10, a23 = mat.m11; + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; float b00 = a00*a11 - a01*a10; @@ -1207,22 +1207,22 @@ RMAPI Matrix MatrixInvert(Matrix mat) // Calculate the invert determinant (inlined to avoid double-caching) float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); - result.m0 = ( a11*b11 - a12*b10 + a13*b09)*invDet; - result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; - result.m2 = ( a31*b05 - a32*b04 + a33*b03)*invDet; - result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; - result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; - result.m5 = ( a00*b11 - a02*b08 + a03*b07)*invDet; - result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; - result.m7 = ( a20*b05 - a22*b02 + a23*b01)*invDet; - result.m8 = ( a10*b10 - a11*b08 + a13*b06)*invDet; - result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; - result.m10 = ( a30*b04 - a31*b02 + a33*b00)*invDet; + result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; + result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; + result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; + result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; + result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; + result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; + result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; + result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; + result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; + result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; + result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; - result.m13 = ( a00*b09 - a01*b07 + a02*b06)*invDet; + result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; - result.m15 = ( a20*b03 - a21*b01 + a22*b00)*invDet; + result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; return result; } @@ -1243,16 +1243,16 @@ RMAPI Matrix MatrixAdd(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0 + right.m0; - result.m1 = left.m1 + right.m1; - result.m2 = left.m2 + right.m2; - result.m3 = left.m3 + right.m3; - result.m4 = left.m4 + right.m4; - result.m5 = left.m5 + right.m5; - result.m6 = left.m6 + right.m6; - result.m7 = left.m7 + right.m7; - result.m8 = left.m8 + right.m8; - result.m9 = left.m9 + right.m9; + result.m0 = left.m0 + right.m0; + result.m1 = left.m1 + right.m1; + result.m2 = left.m2 + right.m2; + result.m3 = left.m3 + right.m3; + result.m4 = left.m4 + right.m4; + result.m5 = left.m5 + right.m5; + result.m6 = left.m6 + right.m6; + result.m7 = left.m7 + right.m7; + result.m8 = left.m8 + right.m8; + result.m9 = left.m9 + right.m9; result.m10 = left.m10 + right.m10; result.m11 = left.m11 + right.m11; result.m12 = left.m12 + right.m12; @@ -1268,16 +1268,16 @@ RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0 - right.m0; - result.m1 = left.m1 - right.m1; - result.m2 = left.m2 - right.m2; - result.m3 = left.m3 - right.m3; - result.m4 = left.m4 - right.m4; - result.m5 = left.m5 - right.m5; - result.m6 = left.m6 - right.m6; - result.m7 = left.m7 - right.m7; - result.m8 = left.m8 - right.m8; - result.m9 = left.m9 - right.m9; + result.m0 = left.m0 - right.m0; + result.m1 = left.m1 - right.m1; + result.m2 = left.m2 - right.m2; + result.m3 = left.m3 - right.m3; + result.m4 = left.m4 - right.m4; + result.m5 = left.m5 - right.m5; + result.m6 = left.m6 - right.m6; + result.m7 = left.m7 - right.m7; + result.m8 = left.m8 - right.m8; + result.m9 = left.m9 - right.m9; result.m10 = left.m10 - right.m10; result.m11 = left.m11 - right.m11; result.m12 = left.m12 - right.m12; @@ -1294,20 +1294,20 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) { Matrix result = { 0 }; - result.m0 = left.m0 *right.m0 + left.m1 *right.m4 + left.m2 *right.m8 + left.m3 *right.m12; - result.m1 = left.m0 *right.m1 + left.m1 *right.m5 + left.m2 *right.m9 + left.m3 *right.m13; - result.m2 = left.m0 *right.m2 + left.m1 *right.m6 + left.m2 *right.m10 + left.m3 *right.m14; - result.m3 = left.m0 *right.m3 + left.m1 *right.m7 + left.m2 *right.m11 + left.m3 *right.m15; - result.m4 = left.m4 *right.m0 + left.m5 *right.m4 + left.m6 *right.m8 + left.m7 *right.m12; - result.m5 = left.m4 *right.m1 + left.m5 *right.m5 + left.m6 *right.m9 + left.m7 *right.m13; - result.m6 = left.m4 *right.m2 + left.m5 *right.m6 + left.m6 *right.m10 + left.m7 *right.m14; - result.m7 = left.m4 *right.m3 + left.m5 *right.m7 + left.m6 *right.m11 + left.m7 *right.m15; - result.m8 = left.m8 *right.m0 + left.m9 *right.m4 + left.m10*right.m8 + left.m11*right.m12; - result.m9 = left.m8 *right.m1 + left.m9 *right.m5 + left.m10*right.m9 + left.m11*right.m13; - result.m10 = left.m8 *right.m2 + left.m9 *right.m6 + left.m10*right.m10 + left.m11*right.m14; - result.m11 = left.m8 *right.m3 + left.m9 *right.m7 + left.m10*right.m11 + left.m11*right.m15; - result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; - result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; + result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; + result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; + result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; + result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; + result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; + result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; + result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; + result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; + result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; + result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; + result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; + result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; + result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; + result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; @@ -1347,18 +1347,18 @@ RMAPI Matrix MatrixRotate(Vector3 axis, float angle) float cosres = cosf(angle); float t = 1.0f - cosres; - result.m0 = x*x*t + cosres; - result.m1 = y*x*t + z*sinres; - result.m2 = z*x*t - y*sinres; - result.m3 = 0.0f; + result.m0 = x*x*t + cosres; + result.m1 = y*x*t + z*sinres; + result.m2 = z*x*t - y*sinres; + result.m3 = 0.0f; - result.m4 = x*y*t - z*sinres; - result.m5 = y*y*t + cosres; - result.m6 = z*y*t + x*sinres; - result.m7 = 0.0f; + result.m4 = x*y*t - z*sinres; + result.m5 = y*y*t + cosres; + result.m6 = z*y*t + x*sinres; + result.m7 = 0.0f; - result.m8 = x*z*t + y*sinres; - result.m9 = y*z*t - x*sinres; + result.m8 = x*z*t + y*sinres; + result.m9 = y*z*t - x*sinres; result.m10 = z*z*t + cosres; result.m11 = 0.0f; @@ -1382,10 +1382,10 @@ RMAPI Matrix MatrixRotateX(float angle) float cosres = cosf(angle); float sinres = sinf(angle); - result.m5 = cosres; - result.m6 = sinres; - result.m9 = -sinres; - result.m10 = cosres; + result.m5 = cosres; + result.m6 = sinres; + result.m9 = -sinres; + result.m10 = cosres; return result; } @@ -1402,10 +1402,10 @@ RMAPI Matrix MatrixRotateY(float angle) float cosres = cosf(angle); float sinres = sinf(angle); - result.m0 = cosres; - result.m2 = -sinres; - result.m8 = sinres; - result.m10 = cosres; + result.m0 = cosres; + result.m2 = -sinres; + result.m8 = sinres; + result.m10 = cosres; return result; } @@ -1422,10 +1422,10 @@ RMAPI Matrix MatrixRotateZ(float angle) float cosres = cosf(angle); float sinres = sinf(angle); - result.m0 = cosres; - result.m1 = sinres; + result.m0 = cosres; + result.m1 = sinres; result.m4 = -sinres; - result.m5 = cosres; + result.m5 = cosres; return result; } @@ -1475,23 +1475,23 @@ RMAPI Matrix MatrixRotateZYX(Vector3 angle) float cx = cosf(angle.x); float sx = sinf(angle.x); - result.m0 = cz*cy; - result.m4 = cz*sy*sx - cx*sz; - result.m8 = sz*sx + cz*cx*sy; + result.m0 = cz*cy; + result.m4 = cz*sy*sx - cx*sz; + result.m8 = sz*sx + cz*cx*sy; result.m12 = 0; - result.m1 = cy*sz; - result.m5 = cz*cx + sz*sy*sx; - result.m9 = cx*sz*sy - cz*sx; + result.m1 = cy*sz; + result.m5 = cz*cx + sz*sy*sx; + result.m9 = cx*sz*sy - cz*sx; result.m13 = 0; - result.m2 = -sy; - result.m6 = cy*sx; + result.m2 = -sy; + result.m6 = cy*sx; result.m10 = cy*cx; result.m14 = 0; - result.m3 = 0; - result.m7 = 0; + result.m3 = 0; + result.m7 = 0; result.m11 = 0; result.m15 = 1; @@ -1501,9 +1501,9 @@ RMAPI Matrix MatrixRotateZYX(Vector3 angle) // Get scaling matrix RMAPI Matrix MatrixScale(float x, float y, float z) { - Matrix result = { x , 0.0f, 0.0f, 0.0f, - 0.0f, y , 0.0f, 0.0f, - 0.0f, 0.0f, z, 0.0f, + Matrix result = { x, 0.0f, 0.0f, 0.0f, + 0.0f, y, 0.0f, 0.0f, + 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; return result; @@ -1528,9 +1528,9 @@ RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, result.m6 = 0.0f; result.m7 = 0.0f; - result.m8 = ((float)right + (float)left )/rl; - result.m9 = ((float)top + (float)bottom)/tb; - result.m10 = -((float)far + (float)near )/fn; + result.m8 = ((float)right + (float)left)/rl; + result.m9 = ((float)top + (float)bottom)/tb; + result.m10 = -((float)far + (float)near)/fn; result.m11 = -1.0f; result.m12 = 0.0f; @@ -1553,14 +1553,14 @@ RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, dou double left = -right; // MatrixFrustum(-right, right, -top, top, near, far); - float rl = (float)(right - left ); - float tb = (float)(top - bottom ); + float rl = (float)(right - left); + float tb = (float)(top - bottom); float fn = (float)(farPlane - nearPlane); - result.m0 = ((float)nearPlane*2.0f)/rl; - result.m5 = ((float)nearPlane*2.0f)/tb; - result.m8 = ((float)right + (float)left )/rl; - result.m9 = ((float)top + (float)bottom )/tb; + result.m0 = ((float)nearPlane*2.0f)/rl; + result.m5 = ((float)nearPlane*2.0f)/tb; + result.m8 = ((float)right + (float)left)/rl; + result.m9 = ((float)top + (float)bottom)/tb; result.m10 = -((float)farPlane + (float)nearPlane)/fn; result.m11 = -1.0f; result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn; @@ -1573,8 +1573,8 @@ RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, d { Matrix result = { 0 }; - float rl = (float)(right - left ); - float tb = (float)(top - bottom ); + float rl = (float)(right - left); + float tb = (float)(top - bottom); float fn = (float)(farPlane - nearPlane); result.m0 = 2.0f/rl; @@ -1589,8 +1589,8 @@ RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, d result.m9 = 0.0f; result.m10 = -2.0f/fn; result.m11 = 0.0f; - result.m12 = -((float)left + (float)right )/rl; - result.m13 = -((float)top + (float)bottom )/tb; + result.m12 = -((float)left + (float)right)/rl; + result.m13 = -((float)top + (float)bottom)/tb; result.m14 = -((float)farPlane + (float)nearPlane)/fn; result.m15 = 1.0f; @@ -1993,16 +1993,16 @@ RMAPI Matrix QuaternionToMatrix(Quaternion q) float bd = q.w*q.y; float cd = q.w*q.z; - result.m0 = 1 - 2*(b2 + c2); - result.m1 = 2*(ab + cd); - result.m2 = 2*(ac - bd); + result.m0 = 1 - 2*(b2 + c2); + result.m1 = 2*(ab + cd); + result.m2 = 2*(ac - bd); - result.m4 = 2*(ab - cd); - result.m5 = 1 - 2*(a2 + c2); - result.m6 = 2*(bc + ad); + result.m4 = 2*(ab - cd); + result.m5 = 1 - 2*(a2 + c2); + result.m6 = 2*(bc + ad); - result.m8 = 2*(ac + bd); - result.m9 = 2*(bc - ad); + result.m8 = 2*(ac + bd); + result.m9 = 2*(bc - ad); result.m10 = 1 - 2*(a2 + b2); return result; @@ -2142,8 +2142,8 @@ RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat) { Quaternion result = { 0 }; - result.x = mat.m0*q.x + mat.m4*q.y + mat.m8 *q.z + mat.m12*q.w; - result.y = mat.m1*q.x + mat.m5*q.y + mat.m9 *q.z + mat.m13*q.w; + result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w; + result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w; result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w; result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w; From 6d6ab7e6f57291c3efab20dae8039f5d059a620b Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 17 Sep 2023 13:37:05 +0100 Subject: [PATCH 88/89] reverted parser output changes --- parser/output/raylib_api.json | 2 +- parser/output/raylib_api.txt | 2 +- projects/Notepad++/raylib_npp_parser/raylib_npp.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/parser/output/raylib_api.json b/parser/output/raylib_api.json index c53b1b31399c..b42f03a832d3 100644 --- a/parser/output/raylib_api.json +++ b/parser/output/raylib_api.json @@ -4333,7 +4333,7 @@ }, { "name": "GetApplicationDirectory", - "description": "Get the directory of the running application (uses static string)", + "description": "Get the directory if the running application (uses static string)", "returnType": "const char *" }, { diff --git a/parser/output/raylib_api.txt b/parser/output/raylib_api.txt index 13714bc49ad2..0d0ccccf19a9 100644 --- a/parser/output/raylib_api.txt +++ b/parser/output/raylib_api.txt @@ -1641,7 +1641,7 @@ Function 126: GetWorkingDirectory() (0 input parameters) Function 127: GetApplicationDirectory() (0 input parameters) Name: GetApplicationDirectory Return type: const char * - Description: Get the directory of the running application (uses static string) + Description: Get the directory if the running application (uses static string) No input parameters Function 128: ChangeDirectory() (1 input parameters) Name: ChangeDirectory diff --git a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml index 12624addd41a..883183cef071 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +++ b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml @@ -603,7 +603,7 @@ - + From fda8e51ff786c2b09e1e4734f80a2f27ef81be74 Mon Sep 17 00:00:00 2001 From: Brian-E Date: Sun, 17 Sep 2023 15:19:52 +0100 Subject: [PATCH 89/89] reverted one more indentation change --- src/raymath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raymath.h b/src/raymath.h index e6740a1c48c7..48bae01a9557 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -507,7 +507,7 @@ RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) RMAPI int Vector2Equals(Vector2 p, Vector2 q) { int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); return result; }