فهرست منبع

[Nokia N-Gage] Fix alpha transparency in 4K color mode using BitBltMasked

Previously, all transparent pixels were rendered as opaque due to the limitations of the 4K color mode. Replaced Gc()->BitBlt() with Gc()->BitBltMasked() and updated the mask during copy operations to correctly respect the alpha channel of textures, while maintaining good performance.
Michael Fitzmayer 10 ماه پیش
والد
کامیت
2ef7944170
2فایلهای تغییر یافته به همراه61 افزوده شده و 2 حذف شده
  1. 60 2
      src/render/ngage/SDL_render_ngage.cpp
  2. 1 0
      src/render/ngage/SDL_render_ngage_c.h

+ 60 - 2
src/render/ngage/SDL_render_ngage.cpp

@@ -69,6 +69,8 @@ void NGAGE_DestroyTextureData(NGAGE_TextureData *data)
     if (data) {
         delete data->bitmap;
         data->bitmap = NULL;
+        delete data->mask;
+        data->mask = NULL;
     }
 }
 
@@ -350,7 +352,29 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
     if (phdata->bitmap) {
         TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h));
         TPoint aDest(dstrect->x, dstrect->y);
-        iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource);
+
+        w = phdata->surface->w;
+        pitch = phdata->surface->pitch;
+        Uint16 *src = (Uint16 *)phdata->surface->pixels;
+        Uint16 *mask = (Uint16 *)phdata->mask->DataAddress();
+
+        for (int y = 0; y < srcrect->h; ++y) {
+            int src_y = srcrect->y + y;
+            if (src_y < 0 || src_y >= phdata->surface->h) {
+                continue;
+            }
+            for (int x = 0; x < srcrect->w; ++x) {
+                int src_x = srcrect->x + x;
+                if (src_x < 0 || src_x >= phdata->surface->w) {
+                    continue;
+                }
+                Uint16 pixel = src[src_y * (pitch / 2) + src_x];
+                Uint8 alpha = (pixel & 0xF000) >> 12;
+                mask[src_y * w + src_x] = (alpha == 0) ? 0x0000 : 0xFFFF;
+            }
+        }
+
+        iRenderer->Gc()->BitBltMasked(aDest, phdata->bitmap, aSource, phdata->mask, EFalse);
     }
 
     return true;
@@ -416,7 +440,29 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE
     if (phdata->bitmap) {
         TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h));
         TPoint aDest(copydata->dstrect.x, copydata->dstrect.y);
-        iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource);
+
+        w = phdata->surface->w;
+        pitch = phdata->surface->pitch;
+        Uint16 *src = (Uint16 *)phdata->surface->pixels;
+        Uint16 *mask = (Uint16 *)phdata->mask->DataAddress();
+
+        for (int y = 0; y < copydata->srcrect.h; ++y) {
+            int src_y = copydata->srcrect.y + y;
+            if (src_y < 0 || src_y >= phdata->surface->h) {
+                continue;
+            }
+            for (int x = 0; x < copydata->srcrect.w; ++x) {
+                int src_x = copydata->srcrect.x + x;
+                if (src_x < 0 || src_x >= phdata->surface->w) {
+                    continue;
+                }
+                Uint16 pixel = src[src_y * (pitch / 2) + src_x];
+                Uint8 alpha = (pixel & 0xF000) >> 12;
+                mask[src_y * w + src_x] = (alpha == 0) ? 0x0000 : 0xFFFF;
+            }
+        }
+
+        iRenderer->Gc()->BitBltMasked(aDest, phdata->bitmap, aSource, phdata->mask, EFalse);
     }
 
     return true;
@@ -440,6 +486,18 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW
         return false;
     }
 
+    aTextureData->mask = new CFbsBitmap();
+    if (!aTextureData->mask) {
+        return false;
+    }
+
+    error = aTextureData->mask->Create(TSize(aWidth, aHeight), EColor4K);
+    if (error != KErrNone) {
+        delete aTextureData->mask;
+        aTextureData->mask = NULL;
+        return false;
+    }
+
     return true;
 }
 

+ 1 - 0
src/render/ngage/SDL_render_ngage_c.h

@@ -58,6 +58,7 @@ typedef struct CFbsBitmap CFbsBitmap;
 typedef struct NGAGE_TextureData
 {
     CFbsBitmap *bitmap;
+    CFbsBitmap *mask;
     SDL_Surface *surface;
 
 } NGAGE_TextureData;