Skip to content

Commit 2ef7944

Browse files
committed
[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.
1 parent d86fb8a commit 2ef7944

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

src/render/ngage/SDL_render_ngage.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ void NGAGE_DestroyTextureData(NGAGE_TextureData *data)
6969
if (data) {
7070
delete data->bitmap;
7171
data->bitmap = NULL;
72+
delete data->mask;
73+
data->mask = NULL;
7274
}
7375
}
7476

@@ -350,7 +352,29 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
350352
if (phdata->bitmap) {
351353
TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h));
352354
TPoint aDest(dstrect->x, dstrect->y);
353-
iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource);
355+
356+
w = phdata->surface->w;
357+
pitch = phdata->surface->pitch;
358+
Uint16 *src = (Uint16 *)phdata->surface->pixels;
359+
Uint16 *mask = (Uint16 *)phdata->mask->DataAddress();
360+
361+
for (int y = 0; y < srcrect->h; ++y) {
362+
int src_y = srcrect->y + y;
363+
if (src_y < 0 || src_y >= phdata->surface->h) {
364+
continue;
365+
}
366+
for (int x = 0; x < srcrect->w; ++x) {
367+
int src_x = srcrect->x + x;
368+
if (src_x < 0 || src_x >= phdata->surface->w) {
369+
continue;
370+
}
371+
Uint16 pixel = src[src_y * (pitch / 2) + src_x];
372+
Uint8 alpha = (pixel & 0xF000) >> 12;
373+
mask[src_y * w + src_x] = (alpha == 0) ? 0x0000 : 0xFFFF;
374+
}
375+
}
376+
377+
iRenderer->Gc()->BitBltMasked(aDest, phdata->bitmap, aSource, phdata->mask, EFalse);
354378
}
355379

356380
return true;
@@ -416,7 +440,29 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE
416440
if (phdata->bitmap) {
417441
TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h));
418442
TPoint aDest(copydata->dstrect.x, copydata->dstrect.y);
419-
iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource);
443+
444+
w = phdata->surface->w;
445+
pitch = phdata->surface->pitch;
446+
Uint16 *src = (Uint16 *)phdata->surface->pixels;
447+
Uint16 *mask = (Uint16 *)phdata->mask->DataAddress();
448+
449+
for (int y = 0; y < copydata->srcrect.h; ++y) {
450+
int src_y = copydata->srcrect.y + y;
451+
if (src_y < 0 || src_y >= phdata->surface->h) {
452+
continue;
453+
}
454+
for (int x = 0; x < copydata->srcrect.w; ++x) {
455+
int src_x = copydata->srcrect.x + x;
456+
if (src_x < 0 || src_x >= phdata->surface->w) {
457+
continue;
458+
}
459+
Uint16 pixel = src[src_y * (pitch / 2) + src_x];
460+
Uint8 alpha = (pixel & 0xF000) >> 12;
461+
mask[src_y * w + src_x] = (alpha == 0) ? 0x0000 : 0xFFFF;
462+
}
463+
}
464+
465+
iRenderer->Gc()->BitBltMasked(aDest, phdata->bitmap, aSource, phdata->mask, EFalse);
420466
}
421467

422468
return true;
@@ -440,6 +486,18 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW
440486
return false;
441487
}
442488

489+
aTextureData->mask = new CFbsBitmap();
490+
if (!aTextureData->mask) {
491+
return false;
492+
}
493+
494+
error = aTextureData->mask->Create(TSize(aWidth, aHeight), EColor4K);
495+
if (error != KErrNone) {
496+
delete aTextureData->mask;
497+
aTextureData->mask = NULL;
498+
return false;
499+
}
500+
443501
return true;
444502
}
445503

src/render/ngage/SDL_render_ngage_c.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ typedef struct CFbsBitmap CFbsBitmap;
5858
typedef struct NGAGE_TextureData
5959
{
6060
CFbsBitmap *bitmap;
61+
CFbsBitmap *mask;
6162
SDL_Surface *surface;
6263

6364
} NGAGE_TextureData;

0 commit comments

Comments
 (0)