SDL: Make sure to round color values when converting to Uint8

From dacfaa91b422e4c69d41cb029050270325cea093 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 31 Jan 2024 23:31:19 -0800
Subject: [PATCH] Make sure to round color values when converting  to Uint8

---
 src/render/ps2/SDL_render_ps2.c     | 16 +++----
 src/render/psp/SDL_render_psp.c     | 72 ++++++++++++++---------------
 src/render/software/SDL_render_sw.c | 64 ++++++++++++-------------
 3 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c
index d4abc69407cb..0440be4e7b95 100644
--- a/src/render/ps2/SDL_render_ps2.c
+++ b/src/render/ps2/SDL_render_ps2.c
@@ -105,20 +105,20 @@ static int PixelFormatToPS2PSM(Uint32 format)
 
 static gs_rgbaq float_color_to_RGBAQ(const SDL_FColor *color)
 {
-    uint8_t colorR = (uint8_t)(color->r * 255.0f);
-    uint8_t colorG = (uint8_t)(color->g * 255.0f);
-    uint8_t colorB = (uint8_t)(color->b * 255.0f);
-    uint8_t colorA = (uint8_t)(color->a * 255.0f);
+    uint8_t colorR = (uint8_t)SDL_roundf(color->r * 255.0f);
+    uint8_t colorG = (uint8_t)SDL_roundf(color->g * 255.0f);
+    uint8_t colorB = (uint8_t)SDL_roundf(color->b * 255.0f);
+    uint8_t colorA = (uint8_t)SDL_roundf(color->a * 255.0f);
 
     return color_to_RGBAQ(colorR, colorG, colorB, colorA, 0x00);
 }
 
 static uint64_t float_GS_SETREG_RGBAQ(const SDL_FColor *color)
 {
-    uint8_t colorR = (uint8_t)(color->r * 255.0f);
-    uint8_t colorG = (uint8_t)(color->g * 255.0f);
-    uint8_t colorB = (uint8_t)(color->b * 255.0f);
-    uint8_t colorA = (uint8_t)(color->a * 255.0f);
+    uint8_t colorR = (uint8_t)SDL_roundf(color->r * 255.0f);
+    uint8_t colorG = (uint8_t)SDL_roundf(color->g * 255.0f);
+    uint8_t colorB = (uint8_t)SDL_roundf(color->b * 255.0f);
+    uint8_t colorA = (uint8_t)SDL_roundf(color->a * 255.0f);
 
     return GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00);
 }
diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c
index 0fa89d46fe1a..97ed45b5da3c 100644
--- a/src/render/psp/SDL_render_psp.c
+++ b/src/render/psp/SDL_render_psp.c
@@ -683,10 +683,10 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             verts->y = xy_[1] * scale_y;
             verts->z = 0;
 
-            verts->col.r = (Uint8)(col_->r * 255.0f);
-            verts->col.g = (Uint8)(col_->g * 255.0f);
-            verts->col.b = (Uint8)(col_->b * 255.0f);
-            verts->col.a = (Uint8)(col_->a * 255.0f);
+            verts->col.r = (Uint8)SDL_roundf(col_->r * 255.0f);
+            verts->col.g = (Uint8)SDL_roundf(col_->g * 255.0f);
+            verts->col.b = (Uint8)SDL_roundf(col_->b * 255.0f);
+            verts->col.a = (Uint8)SDL_roundf(col_->a * 255.0f);
 
             verts++;
         }
@@ -722,10 +722,10 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             verts->y = xy_[1] * scale_y;
             verts->z = 0;
 
-            verts->col.r = (Uint8)(col_->r * 255.0f);
-            verts->col.g = (Uint8)(col_->g * 255.0f);
-            verts->col.b = (Uint8)(col_->b * 255.0f);
-            verts->col.a = (Uint8)(col_->a * 255.0f);
+            verts->col.r = (Uint8)SDL_roundf(col_->r * 255.0f);
+            verts->col.g = (Uint8)SDL_roundf(col_->g * 255.0f);
+            verts->col.b = (Uint8)SDL_roundf(col_->b * 255.0f);
+            verts->col.a = (Uint8)SDL_roundf(col_->a * 255.0f);
 
             verts->u = uv_[0] * psp_texture->textureWidth;
             verts->v = uv_[1] * psp_texture->textureHeight;
@@ -1080,10 +1080,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const Uint8 r = (Uint8)(cmd->data.color.color.r * 255.0f);
-            const Uint8 g = (Uint8)(cmd->data.color.color.g * 255.0f);
-            const Uint8 b = (Uint8)(cmd->data.color.color.b * 255.0f);
-            const Uint8 a = (Uint8)(cmd->data.color.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.color.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.color.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.color.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.color.color.a * 255.0f);
             sceGuClearColor(GU_RGBA(r, g, b, a));
             sceGuClearStencil(a);
             sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT);
@@ -1094,10 +1094,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
-            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
-            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = NULL,
@@ -1113,10 +1113,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
-            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
-            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = NULL,
@@ -1132,10 +1132,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
-            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
-            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = NULL,
@@ -1151,10 +1151,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first);
-            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
-            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = cmd->data.draw.texture,
@@ -1169,10 +1169,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         case SDL_RENDERCMD_COPY_EX:
         {
             const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first);
-            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
-            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = cmd->data.draw.texture,
@@ -1195,10 +1195,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
                 sceGuEnable(GU_TEXTURE_2D);
             } else {
                 const VertTCV *verts = (VertTCV *)(gpumem + cmd->data.draw.first);
-                const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
-                const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
-                const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
-                const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
+                const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
+                const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+                const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+                const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
                 PSP_BlendState state = {
                     .color = GU_RGBA(r, g, b, a),
                     .texture = NULL,
diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c
index 3de58e81b6e1..300f71a3c0e7 100644
--- a/src/render/software/SDL_render_sw.c
+++ b/src/render/software/SDL_render_sw.c
@@ -106,10 +106,10 @@ static int SW_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
         return SDL_SetError("Cannot create surface");
     }
     texture->driverdata = surface;
-    r = (Uint8)((float)texture->color.r * 255.0f);
-    g = (Uint8)((float)texture->color.g * 255.0f);
-    b = (Uint8)((float)texture->color.b * 255.0f);
-    a = (Uint8)((float)texture->color.a * 255.0f);
+    r = (Uint8)SDL_roundf(texture->color.r * 255.0f);
+    g = (Uint8)SDL_roundf(texture->color.g * 255.0f);
+    b = (Uint8)SDL_roundf(texture->color.b * 255.0f);
+    a = (Uint8)SDL_roundf(texture->color.a * 255.0f);
     SDL_SetSurfaceColorMod(texture->driverdata, r, g, b);
     SDL_SetSurfaceAlphaMod(texture->driverdata, a);
     SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
@@ -582,10 +582,10 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
             ptr->dst.y = (int)(xy_[1] * scale_y);
             trianglepoint_2_fixedpoint(&ptr->dst);
 
-            ptr->color.r = (Uint8)((float)col_.r * 255.0f);
-            ptr->color.g = (Uint8)((float)col_.g * 255.0f);
-            ptr->color.b = (Uint8)((float)col_.b * 255.0f);
-            ptr->color.a = (Uint8)((float)col_.a * 255.0f);
+            ptr->color.r = (Uint8)SDL_roundf(col_.r * 255.0f);
+            ptr->color.g = (Uint8)SDL_roundf(col_.g * 255.0f);
+            ptr->color.b = (Uint8)SDL_roundf(col_.b * 255.0f);
+            ptr->color.a = (Uint8)SDL_roundf(col_.a * 255.0f);
 
             ptr++;
         }
@@ -613,10 +613,10 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
             ptr->dst.y = (int)(xy_[1] * scale_y);
             trianglepoint_2_fixedpoint(&ptr->dst);
 
-            ptr->color.r = (Uint8)((float)col_.r * 255.0f);
-            ptr->color.g = (Uint8)((float)col_.g * 255.0f);
-            ptr->color.b = (Uint8)((float)col_.b * 255.0f);
-            ptr->color.a = (Uint8)((float)col_.a * 255.0f);
+            ptr->color.r = (Uint8)SDL_roundf(col_.r * 255.0f);
+            ptr->color.g = (Uint8)SDL_roundf(col_.g * 255.0f);
+            ptr->color.b = (Uint8)SDL_roundf(col_.b * 255.0f);
+            ptr->color.a = (Uint8)SDL_roundf(col_.a * 255.0f);
 
             ptr++;
         }
@@ -626,10 +626,10 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
 
 static void PrepTextureForCopy(const SDL_RenderCommand *cmd)
 {
-    const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
-    const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
-    const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
-    const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
+    const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+    const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+    const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+    const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
     const SDL_BlendMode blend = cmd->data.draw.blend;
     SDL_Texture *texture = cmd->data.draw.texture;
     SDL_Surface *surface = (SDL_Surface *)texture->driverdata;
@@ -711,10 +711,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const Uint8 r = (Uint8)((float)cmd->data.color.color.r * 255.0f);
-            const Uint8 g = (Uint8)((float)cmd->data.color.color.g * 255.0f);
-            const Uint8 b = (Uint8)((float)cmd->data.color.color.b * 255.0f);
-            const Uint8 a = (Uint8)((float)cmd->data.color.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.color.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.color.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.color.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.color.color.a * 255.0f);
             /* By definition the clear ignores the clip rect */
             SDL_SetSurfaceClipRect(surface, NULL);
             SDL_FillSurfaceRect(surface, NULL, SDL_MapRGBA(surface->format, r, g, b, a));
@@ -724,10 +724,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_DRAW_POINTS:
         {
-            const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
-            const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
             const int count = (int)cmd->data.draw.count;
             SDL_Point *verts = (SDL_Point *)(((Uint8 *)vertices) + cmd->data.draw.first);
             const SDL_BlendMode blend = cmd->data.draw.blend;
@@ -752,10 +752,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_DRAW_LINES:
         {
-            const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
-            const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
             const int count = (int)cmd->data.draw.count;
             SDL_Point *verts = (SDL_Point *)(((Uint8 *)vertices) + cmd->data.draw.first);
             const SDL_BlendMode blend = cmd->data.draw.blend;
@@ -780,10 +780,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_FILL_RECTS:
         {
-            const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
-            const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
-            const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
-            const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)SDL_roundf(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)SDL_roundf(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)SDL_roundf(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)SDL_roundf(cmd->data.draw.color.a * 255.0f);
             const int count = (int)cmd->data.draw.count;
             SDL_Rect *verts = (SDL_Rect *)(((Uint8 *)vertices) + cmd->data.draw.first);
             const SDL_BlendMode blend = cmd->data.draw.blend;