diff --git a/build.zig b/build.zig index c780a65cd..239b10f9e 100644 --- a/build.zig +++ b/build.zig @@ -155,8 +155,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. ); } - // Sets a flag indicating the use of a custom `config.h` if (options.config.len > 0) { + // Sets a flag indicating the use of a custom `config.h` + try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS"); // Splits a space-separated list of config flags into multiple flags // // Note: This means certain flags like `-x c++` won't be processed properly. diff --git a/examples/core/core_2d_camera.c b/examples/core/core_2d_camera.c index b752a9640..7e5a14a70 100644 --- a/examples/core/core_2d_camera.c +++ b/examples/core/core_2d_camera.c @@ -125,8 +125,8 @@ int main(void) DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f)); DrawRectangleLines( 10, 10, 250, 113, BLUE); - DrawText("Free 2d camera controls:", 20, 20, 10, BLACK); - DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY); + DrawText("Free 2D camera controls:", 20, 20, 10, BLACK); + DrawText("- Right/Left to move player", 40, 40, 10, DARKGRAY); DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY); DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY); DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY); diff --git a/examples/core/core_2d_camera.png b/examples/core/core_2d_camera.png index d2f9e634f..a0fdabb49 100644 Binary files a/examples/core/core_2d_camera.png and b/examples/core/core_2d_camera.png differ diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 025216e39..80fb02c4f 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -2217,7 +2217,7 @@ static inline bool sw_triangle_face_culling(void) const float *h2 = RLSW.vertexBuffer[2].homogeneous; // Compute a value proportional to the signed area in the projected 2D plane, - // calculated directly using homogeneous coordinates BEFORE division by w. + // calculated directly using homogeneous coordinates BEFORE division by w // This is the determinant of the matrix formed by the (x, y, w) components // of the vertices, which correctly captures the winding order in homogeneous // space and its relationship to the projected 2D winding order, even with @@ -2235,13 +2235,13 @@ static inline bool sw_triangle_face_culling(void) // Discard the triangle if its winding order (determined by the sign // of the homogeneous area/determinant) matches the culled direction // A positive hSgnArea typically corresponds to a counter-clockwise - // winding in the projected space when all w > 0. + // winding in the projected space when all w > 0 // This test is robust for points with w > 0 or w < 0, correctly // capturing the change in orientation when crossing the w=0 plane // The culling logic remains the same based on the signed area/determinant // A value of 0 for hSgnArea means the points are collinear in (x, y, w) - // space, which corresponds to a degenerate triangle projection. + // space, which corresponds to a degenerate triangle projection // Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false) // and should be handled by the clipper if necessary return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise" @@ -2602,7 +2602,7 @@ static inline bool sw_quad_face_culling(void) // space, which corresponds to a degenerate triangle projection // Such quads might also be degenerate or non-planar. They are typically // not culled by this test (0 < 0 is false, 0 > 0 is false) - // and should be handled by the clipper if necessary. + // and should be handled by the clipper if necessary return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise" } diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 8bd4b3a69..d6ed11c2f 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -894,7 +894,8 @@ Vector2 GetMonitorPosition(int monitor) if ((monitor >= 0) && (monitor < monitorCount)) { - int x, y; + int x = 0; + int y = 0; glfwGetMonitorPos(monitors[monitor], &x, &y); return (Vector2){ (float)x, (float)y }; diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index 5a3947561..1b7a55fd8 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -428,7 +428,7 @@ void SetMouseCursor(int cursor) TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); } -// Get physical key name. +// Get physical key name const char *GetKeyName(int key) { TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index dc779d0fb..934f778c3 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -78,6 +78,11 @@ typedef struct { int unmaximizedHeight; // Internal var to store the unmaximized window (canvas) height char canvasId[64]; // Keep current canvas id where wasm app is running + // NOTE: Useful when trying to run multiple wasms in different canvases in same webpage + +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) + unsigned int *pixels; // Pointer to pixel data buffer (RGBA 32bit format) +#endif } PlatformData; //---------------------------------------------------------------------------------- @@ -264,7 +269,8 @@ void ToggleFullscreen(void) }; emscripten_enter_soft_fullscreen(platform.canvasId, &strategy); - int width, height; + int width = 0; + int height = 0; emscripten_get_canvas_element_size(platform.canvasId, &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); @@ -883,7 +889,32 @@ void DisableCursor(void) // Swap back buffer with front buffer (screen drawing) void SwapScreenBuffer(void) { +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) + // Update framebuffer + rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, platform.pixels); + + // Copy framebuffer data into canvas + EM_ASM({ + const width = $0; + const height = $1; + const ptr = $2; + + // Get canvas and 2d context created + const canvas = Module.canvas; + const ctx = canvas.getContext('2d'); + + if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) { + Module.__img = ctx.createImageData(width, height); + } + + const src = HEAPU8.subarray(ptr, ptr + width*height*4); // RGBA (4 bytes) + Module.__img.data.set(src); + ctx.putImageData(Module.__img, 0, 0); + + }, CORE.Window.screen.width, CORE.Window.screen.height, platform.pixels); +#else glfwSwapBuffers(platform.handle); +#endif } //---------------------------------------------------------------------------------- @@ -974,7 +1005,7 @@ void SetMouseCursor(int cursor) } } -// Get physical key name. +// Get physical key name const char *GetKeyName(int key) { TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); @@ -1214,7 +1245,21 @@ int InitPlatform(void) // Init fullscreen toggle required var: platform.ourFullscreen = false; - + +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) + // Avoid creating a WebGL canvas, avoid calling glfwCreateWindow() + emscripten_set_canvas_element_size(platform.canvasId, CORE.Window.screen.width, CORE.Window.screen.height); + EM_ASM({ + const canvas = document.getElementById("canvas"); + Module.canvas = canvas; + }); + + // Load memory framebuffer with desired screen size + // NOTE: Despite using a software framebuffer for blitting, GLFW still creates a WebGL canvas, + // but it is not being used, on SwapScreenBuffer() the pure software renderer is used + // TODO: Consider requesting another type of canvas, not a WebGL one --> Replace GLFW-web by Emscripten? + platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(unsigned int)); +#else if (CORE.Window.fullscreen) { // remember center for switchinging from fullscreen to window @@ -1289,6 +1334,7 @@ int InitPlatform(void) TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window"); return -1; } +#endif // WARNING: glfwCreateWindow() title doesn't work with emscripten emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " "); diff --git a/src/rcore.c b/src/rcore.c index 24ebb6dec..19228cc8e 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -117,7 +117,7 @@ #include // Required for: time() [Used in InitTimer()] #include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] -#if defined(PLATFORM_MEMORY) +#if defined(PLATFORM_MEMORY) || defined(PLATFORM_WEB) #define SW_GL_FRAMEBUFFER_COPY_BGRA false #endif #define RLGL_IMPLEMENTATION diff --git a/src/rmodels.c b/src/rmodels.c index 1502e46af..2347ca0e6 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -3655,7 +3655,7 @@ void GenMeshTangents(Mesh *mesh) for (int t = 0; t < mesh->triangleCount; t++) { // Get triangle vertex indices - int i0, i1, i2; + int i0 = 0, i1 = 0, i2 = 0; if (mesh->indices != NULL) { @@ -4150,7 +4150,9 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform) // Test against all triangles in mesh for (int i = 0; i < triangleCount; i++) { - Vector3 a, b, c; + Vector3 a = { 0 }; + Vector3 b = { 0 }; + Vector3 c = { 0 }; Vector3 *vertdata = (Vector3 *)mesh.vertices; if (mesh.indices) @@ -4193,8 +4195,10 @@ RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3 RayCollision collision = { 0 }; Vector3 edge1 = { 0 }; Vector3 edge2 = { 0 }; - Vector3 p, q, tv; - float det, invDet, u, v, t; + Vector3 p = { 0 }; + Vector3 q = { 0 }; + Vector3 tv = { 0 }; + float det = 0.0f, invDet = 0.0f, u = 0.0f, v = 0.0f, t = 0.0f; // Find vectors for two edges sharing V1 edge1 = Vector3Subtract(p2, p1); diff --git a/src/rtext.c b/src/rtext.c index 0efd7504b..f04f9ade4 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -649,7 +649,9 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Calculate font basic metrics // NOTE: ascent is equivalent to font baseline - int ascent, descent, lineGap; + int ascent = 0; + int descent = 0; + int lineGap = 0; stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap); // In case no chars count provided, default to 95 @@ -2483,7 +2485,15 @@ static Font LoadBMFont(const char *fileName) font.glyphs = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo)); font.recs = (Rectangle *)RL_MALLOC(glyphCount*sizeof(Rectangle)); - int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX, pageID; + int charId = 0; + int charX = 0; + int charY = 0; + int charWidth = 0; + int charHeight = 0; + int charOffsetX = 0; + int charOffsetY = 0; + int charAdvanceX = 0; + int pageID = 0; for (int i = 0; i < glyphCount; i++) { diff --git a/src/rtextures.c b/src/rtextures.c index 02a9ff1a5..4208b40bd 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -1727,7 +1727,8 @@ void ImageResizeNN(Image *image, int newWidth, int newHeight) int xRatio = (int)((image->width << 16)/newWidth) + 1; int yRatio = (int)((image->height << 16)/newHeight) + 1; - int x2, y2; + int x2 = 0; + int y2 = 0; for (int y = 0; y < newHeight; y++) { for (int x = 0; x < newWidth; x++) @@ -2488,8 +2489,13 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) Color oldPixel = WHITE; Color newPixel = WHITE; - int rError, gError, bError; - unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition + int rError = 0; + int gError = 0; + int bError = 0; + unsigned short rPixel = 0; // Used for 16bit pixel composition + unsigned short gPixel = 0; + unsigned short bPixel = 0; + unsigned short aPixel = 0; #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -4006,7 +4012,9 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend() // [ ] TODO: Support 16bit and 32bit (float) channels drawing - Color colSrc, colDst, blend; + Color colSrc = { 0 }; + Color colDst = { 0 }; + Color blend = { 0 }; bool blendRequired = true; // Fast path: Avoid blend if source has no alpha to blend @@ -4681,17 +4689,23 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, bottomBorder = patchHeight - topBorder; } - Vector2 vertA, vertB, vertC, vertD; - vertA.x = 0.0f; // outer left - vertA.y = 0.0f; // outer top - vertB.x = leftBorder; // inner left - vertB.y = topBorder; // inner top - vertC.x = patchWidth - rightBorder; // inner right - vertC.y = patchHeight - bottomBorder; // inner bottom - vertD.x = patchWidth; // outer right - vertD.y = patchHeight; // outer bottom - - Vector2 coordA, coordB, coordC, coordD; + Vector2 vertA = { 0 }; + Vector2 vertB = { 0 }; + Vector2 vertC = { 0 }; + Vector2 vertD = { 0 }; + vertA.x = 0.0f; // Outer left + vertA.y = 0.0f; // Outer top + vertB.x = leftBorder; // Inner left + vertB.y = topBorder; // Inner top + vertC.x = patchWidth - rightBorder; // Inner right + vertC.y = patchHeight - bottomBorder; // Inner bottom + vertD.x = patchWidth; // Outer right + vertD.y = patchHeight; // Outer bottom + + Vector2 coordA = { 0 }; + Vector2 coordB = { 0 }; + Vector2 coordC = { 0 }; + Vector2 coordD = { 0 }; coordA.x = nPatchInfo.source.x/width; coordA.y = nPatchInfo.source.y/height; coordB.x = (nPatchInfo.source.x + leftBorder)/width; @@ -4907,7 +4921,9 @@ Vector3 ColorToHSV(Color color) { Vector3 hsv = { 0 }; Vector3 rgb = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; - float min, max, delta; + float min = 0.0f; + float max = 0.0f; + float delta = 0.0f; min = rgb.x < rgb.y? rgb.x : rgb.y; min = min < rgb.z? min : rgb.z;