|
@@ -59,57 +59,33 @@ bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData
|
|
|
return gRenderer->CopyEx(renderer, texture, copydata);
|
|
return gRenderer->CopyEx(renderer, texture, copydata);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height)
|
|
|
|
|
|
|
+bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height, const int access)
|
|
|
{
|
|
{
|
|
|
- return gRenderer->CreateTextureData(data, width, height);
|
|
|
|
|
|
|
+ return gRenderer->CreateTextureData(data, width, height, access);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void NGAGE_DestroyTextureData(NGAGE_TextureData *data)
|
|
void NGAGE_DestroyTextureData(NGAGE_TextureData *data)
|
|
|
{
|
|
{
|
|
|
if (data) {
|
|
if (data) {
|
|
|
|
|
+ if (data->gc) {
|
|
|
|
|
+ delete data->gc;
|
|
|
|
|
+ data->gc = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (data->device) {
|
|
|
|
|
+ delete data->device;
|
|
|
|
|
+ data->device = NULL;
|
|
|
|
|
+ }
|
|
|
delete data->bitmap;
|
|
delete data->bitmap;
|
|
|
data->bitmap = NULL;
|
|
data->bitmap = NULL;
|
|
|
-
|
|
|
|
|
- // Free cardinal rotation cache.
|
|
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
|
|
- if (data->cardinalRotations[i]) {
|
|
|
|
|
- delete data->cardinalRotations[i];
|
|
|
|
|
- data->cardinalRotations[i] = NULL;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data)
|
|
void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data)
|
|
|
{
|
|
{
|
|
|
- if (data) {
|
|
|
|
|
- return data->bitmap->DataAddress();
|
|
|
|
|
- }
|
|
|
|
|
- return NULL;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-int NGAGE_GetBitmapPitch(NGAGE_TextureData *data)
|
|
|
|
|
-{
|
|
|
|
|
- if (data) {
|
|
|
|
|
- return data->cachedPitch;
|
|
|
|
|
- }
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-int NGAGE_GetBitmapWidth(NGAGE_TextureData *data)
|
|
|
|
|
-{
|
|
|
|
|
- if (data) {
|
|
|
|
|
- return data->cachedWidth;
|
|
|
|
|
- }
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-int NGAGE_GetBitmapHeight(NGAGE_TextureData *data)
|
|
|
|
|
-{
|
|
|
|
|
- if (data) {
|
|
|
|
|
- return data->cachedHeight;
|
|
|
|
|
|
|
+ if (!data || !data->bitmap) {
|
|
|
|
|
+ return NULL;
|
|
|
}
|
|
}
|
|
|
- return 0;
|
|
|
|
|
|
|
+ return data->bitmap->DataAddress();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count)
|
|
void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count)
|
|
@@ -139,7 +115,9 @@ void NGAGE_SetClipRect(const SDL_Rect *rect)
|
|
|
|
|
|
|
|
void NGAGE_SetDrawColor(const Uint32 color)
|
|
void NGAGE_SetDrawColor(const Uint32 color)
|
|
|
{
|
|
{
|
|
|
- gRenderer->SetDrawColor(color);
|
|
|
|
|
|
|
+ if (gRenderer) {
|
|
|
|
|
+ gRenderer->SetDrawColor(color);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void NGAGE_PumpEventsInternal()
|
|
void NGAGE_PumpEventsInternal()
|
|
@@ -152,19 +130,17 @@ void NGAGE_SuspendScreenSaverInternal(bool suspend)
|
|
|
gRenderer->SuspendScreenSaver(suspend);
|
|
gRenderer->SuspendScreenSaver(suspend);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target)
|
|
|
|
|
+{
|
|
|
|
|
+ if (gRenderer) {
|
|
|
|
|
+ gRenderer->SetRenderTarget(target);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
#ifdef __cplusplus
|
|
#ifdef __cplusplus
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
-// Pre-calculated fixed-point angle constants for cardinal rotation checks.
|
|
|
|
|
-// These avoid repeated Real2Fix conversions in CopyEx hot path.
|
|
|
|
|
-static const TFixed kAngleZero = 0;
|
|
|
|
|
-static const TFixed kAnglePi_2 = Real2Fix(M_PI / 2.0); // 90 degrees
|
|
|
|
|
-static const TFixed kAnglePi = Real2Fix(M_PI); // 180 degrees
|
|
|
|
|
-static const TFixed kAnglePi3_2 = Real2Fix(3.0 * M_PI / 2.0); // 270 degrees
|
|
|
|
|
-static const TFixed kAnglePi2 = Real2Fix(2.0 * M_PI); // 360 degrees
|
|
|
|
|
-static const TFixed kAngleTolerance = 100; // Tolerance for angle comparison
|
|
|
|
|
-
|
|
|
|
|
CRenderer *CRenderer::NewL()
|
|
CRenderer *CRenderer::NewL()
|
|
|
{
|
|
{
|
|
|
CRenderer *self = new (ELeave) CRenderer();
|
|
CRenderer *self = new (ELeave) CRenderer();
|
|
@@ -174,32 +150,16 @@ CRenderer *CRenderer::NewL()
|
|
|
return self;
|
|
return self;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0), iLastClearColor(0xFFFFFFFF)
|
|
|
|
|
-{
|
|
|
|
|
-}
|
|
|
|
|
|
|
+CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iCurrentRenderTarget(0), iPixelBufferA(0), iPixelBufferB(0), iPixelBufferSize(0), iPointsBuffer(0), iPointsBufferSize(0) {}
|
|
|
|
|
|
|
|
CRenderer::~CRenderer()
|
|
CRenderer::~CRenderer()
|
|
|
{
|
|
{
|
|
|
delete iRenderer;
|
|
delete iRenderer;
|
|
|
iRenderer = 0;
|
|
iRenderer = 0;
|
|
|
|
|
|
|
|
- // Free work buffers.
|
|
|
|
|
- SDL_free(iWorkBuffer1);
|
|
|
|
|
- SDL_free(iWorkBuffer2);
|
|
|
|
|
- iWorkBuffer1 = 0;
|
|
|
|
|
- iWorkBuffer2 = 0;
|
|
|
|
|
- iWorkBufferSize = 0;
|
|
|
|
|
-
|
|
|
|
|
- // Free temp render bitmap.
|
|
|
|
|
- delete iTempRenderBitmap;
|
|
|
|
|
- iTempRenderBitmap = 0;
|
|
|
|
|
- iTempRenderBitmapWidth = 0;
|
|
|
|
|
- iTempRenderBitmapHeight = 0;
|
|
|
|
|
-
|
|
|
|
|
- // Free line points buffer.
|
|
|
|
|
- delete[] iLinePointsBuffer;
|
|
|
|
|
- iLinePointsBuffer = 0;
|
|
|
|
|
- iLinePointsBufferCapacity = 0;
|
|
|
|
|
|
|
+ SDL_free(iPixelBufferA);
|
|
|
|
|
+ SDL_free(iPixelBufferB);
|
|
|
|
|
+ delete[] iPointsBuffer;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::ConstructL()
|
|
void CRenderer::ConstructL()
|
|
@@ -312,186 +272,11 @@ void CRenderer::AbortNow(RDirectScreenAccess::TTerminationReasons aReason)
|
|
|
|
|
|
|
|
void CRenderer::Clear(TUint32 iColor)
|
|
void CRenderer::Clear(TUint32 iColor)
|
|
|
{
|
|
{
|
|
|
- if (iRenderer && iRenderer->Gc()) {
|
|
|
|
|
- // Skip redundant SetBrushColor if color hasn't changed.
|
|
|
|
|
- if (iColor != iLastClearColor) {
|
|
|
|
|
- iRenderer->Gc()->SetBrushColor(iColor);
|
|
|
|
|
- iLastClearColor = iColor;
|
|
|
|
|
- }
|
|
|
|
|
- iRenderer->Gc()->Clear();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool CRenderer::EnsureWorkBufferCapacity(TInt aRequiredSize)
|
|
|
|
|
-{
|
|
|
|
|
- if (aRequiredSize <= iWorkBufferSize) {
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
|
|
+ gc->SetBrushColor(iColor);
|
|
|
|
|
+ gc->Clear();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // Free old buffers.
|
|
|
|
|
- SDL_free(iWorkBuffer1);
|
|
|
|
|
- SDL_free(iWorkBuffer2);
|
|
|
|
|
-
|
|
|
|
|
- // Allocate new buffers.
|
|
|
|
|
- iWorkBuffer1 = SDL_calloc(1, aRequiredSize);
|
|
|
|
|
- if (!iWorkBuffer1) {
|
|
|
|
|
- iWorkBuffer2 = 0;
|
|
|
|
|
- iWorkBufferSize = 0;
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- iWorkBuffer2 = SDL_calloc(1, aRequiredSize);
|
|
|
|
|
- if (!iWorkBuffer2) {
|
|
|
|
|
- SDL_free(iWorkBuffer1);
|
|
|
|
|
- iWorkBuffer1 = 0;
|
|
|
|
|
- iWorkBufferSize = 0;
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- iWorkBufferSize = aRequiredSize;
|
|
|
|
|
- return true;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool CRenderer::EnsureLinePointsCapacity(TInt aRequiredCount)
|
|
|
|
|
-{
|
|
|
|
|
- if (aRequiredCount <= iLinePointsBufferCapacity) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Free old buffer.
|
|
|
|
|
- delete[] iLinePointsBuffer;
|
|
|
|
|
-
|
|
|
|
|
- // Allocate new buffer.
|
|
|
|
|
- iLinePointsBuffer = new TPoint[aRequiredCount];
|
|
|
|
|
- if (!iLinePointsBuffer) {
|
|
|
|
|
- iLinePointsBufferCapacity = 0;
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- iLinePointsBufferCapacity = aRequiredCount;
|
|
|
|
|
- return true;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool CRenderer::EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight)
|
|
|
|
|
-{
|
|
|
|
|
- if (iTempRenderBitmap &&
|
|
|
|
|
- iTempRenderBitmapWidth >= aWidth &&
|
|
|
|
|
- iTempRenderBitmapHeight >= aHeight) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Delete old bitmap.
|
|
|
|
|
- delete iTempRenderBitmap;
|
|
|
|
|
- iTempRenderBitmap = 0;
|
|
|
|
|
-
|
|
|
|
|
- // Create new bitmap.
|
|
|
|
|
- iTempRenderBitmap = new CFbsBitmap();
|
|
|
|
|
- if (!iTempRenderBitmap) {
|
|
|
|
|
- iTempRenderBitmapWidth = 0;
|
|
|
|
|
- iTempRenderBitmapHeight = 0;
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- TInt error = iTempRenderBitmap->Create(TSize(aWidth, aHeight), EColor4K);
|
|
|
|
|
- if (error != KErrNone) {
|
|
|
|
|
- delete iTempRenderBitmap;
|
|
|
|
|
- iTempRenderBitmap = 0;
|
|
|
|
|
- iTempRenderBitmapWidth = 0;
|
|
|
|
|
- iTempRenderBitmapHeight = 0;
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- iTempRenderBitmapWidth = aWidth;
|
|
|
|
|
- iTempRenderBitmapHeight = aHeight;
|
|
|
|
|
- return true;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void CRenderer::BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf)
|
|
|
|
|
-{
|
|
|
|
|
- // Build lookup tables for R, G, B channels.
|
|
|
|
|
- for (int i = 0; i < 256; i++) {
|
|
|
|
|
- TFixed val = i << 16; // Convert to fixed-point
|
|
|
|
|
- iColorModLUT[i] = (TUint8)SDL_min(Fix2Int(FixMul(val, rf)), 255); // R
|
|
|
|
|
- iColorModLUT[i + 256] = (TUint8)SDL_min(Fix2Int(FixMul(val, gf)), 255); // G
|
|
|
|
|
- iColorModLUT[i + 512] = (TUint8)SDL_min(Fix2Int(FixMul(val, bf)), 255); // B
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Remember the last color to avoid rebuilding unnecessarily.
|
|
|
|
|
- iLastColorR = rf;
|
|
|
|
|
- iLastColorG = gf;
|
|
|
|
|
- iLastColorB = bf;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-CFbsBitmap *CRenderer::GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex)
|
|
|
|
|
-{
|
|
|
|
|
- // Check if already cached.
|
|
|
|
|
- if (aTextureData->cardinalRotations[aAngleIndex]) {
|
|
|
|
|
- return aTextureData->cardinalRotations[aAngleIndex];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Create rotated bitmap.
|
|
|
|
|
- CFbsBitmap *rotated = new CFbsBitmap();
|
|
|
|
|
- if (!rotated) {
|
|
|
|
|
- return NULL;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- TInt w = aTextureData->cachedWidth;
|
|
|
|
|
- TInt h = aTextureData->cachedHeight;
|
|
|
|
|
- TSize size(w, h);
|
|
|
|
|
-
|
|
|
|
|
- // For 90 and 270 degree rotations, swap width/height.
|
|
|
|
|
- if (aAngleIndex == 1 || aAngleIndex == 3) {
|
|
|
|
|
- size = TSize(h, w);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- TInt error = rotated->Create(size, EColor4K);
|
|
|
|
|
- if (error != KErrNone) {
|
|
|
|
|
- delete rotated;
|
|
|
|
|
- return NULL;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Rotate the bitmap data.
|
|
|
|
|
- TUint16 *src = (TUint16 *)aTextureData->cachedDataAddress;
|
|
|
|
|
- TUint16 *dst = (TUint16 *)rotated->DataAddress();
|
|
|
|
|
- TInt srcPitch = aTextureData->cachedPitch >> 1;
|
|
|
|
|
- TInt dstPitch = rotated->ScanLineLength(size.iWidth, rotated->DisplayMode()) >> 1;
|
|
|
|
|
-
|
|
|
|
|
- for (int y = 0; y < h; ++y) {
|
|
|
|
|
- for (int x = 0; x < w; ++x) {
|
|
|
|
|
- TUint16 pixel = src[y * srcPitch + x];
|
|
|
|
|
- int dstX = 0;
|
|
|
|
|
- int dstY = 0;
|
|
|
|
|
-
|
|
|
|
|
- switch (aAngleIndex) {
|
|
|
|
|
- case 0: // 0 degrees
|
|
|
|
|
- dstX = x;
|
|
|
|
|
- dstY = y;
|
|
|
|
|
- break;
|
|
|
|
|
- case 1: // 90 degrees
|
|
|
|
|
- dstX = h - 1 - y;
|
|
|
|
|
- dstY = x;
|
|
|
|
|
- break;
|
|
|
|
|
- case 2: // 180 degrees
|
|
|
|
|
- dstX = w - 1 - x;
|
|
|
|
|
- dstY = h - 1 - y;
|
|
|
|
|
- break;
|
|
|
|
|
- case 3: // 270 degrees
|
|
|
|
|
- dstX = y;
|
|
|
|
|
- dstY = w - 1 - x;
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- // Should never happen, but initialize to avoid warnings
|
|
|
|
|
- dstX = x;
|
|
|
|
|
- dstY = y;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- dst[dstY * dstPitch + dstX] = pixel;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- aTextureData->cardinalRotations[aAngleIndex] = rotated;
|
|
|
|
|
- return rotated;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
#ifdef __cplusplus
|
|
@@ -508,9 +293,13 @@ Uint32 NGAGE_ConvertColor(float r, float g, float b, float a, float color_scale)
|
|
|
TFixed bf = Real2Fix(b);
|
|
TFixed bf = Real2Fix(b);
|
|
|
TFixed af = Real2Fix(a);
|
|
TFixed af = Real2Fix(a);
|
|
|
|
|
|
|
|
- rf = SDL_clamp(FixMul(rf, scalef), 0, ff);
|
|
|
|
|
- gf = SDL_clamp(FixMul(gf, scalef), 0, ff);
|
|
|
|
|
- bf = SDL_clamp(FixMul(bf, scalef), 0, ff);
|
|
|
|
|
|
|
+ rf = FixMul(rf, scalef);
|
|
|
|
|
+ gf = FixMul(gf, scalef);
|
|
|
|
|
+ bf = FixMul(bf, scalef);
|
|
|
|
|
+
|
|
|
|
|
+ rf = SDL_clamp(rf, 0, ff);
|
|
|
|
|
+ gf = SDL_clamp(gf, 0, ff);
|
|
|
|
|
+ bf = SDL_clamp(bf, 0, ff);
|
|
|
af = SDL_clamp(af, 0, ff);
|
|
af = SDL_clamp(af, 0, ff);
|
|
|
|
|
|
|
|
rf = FixMul(rf, ff) >> 16;
|
|
rf = FixMul(rf, ff) >> 16;
|
|
@@ -537,80 +326,69 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
SDL_FColor *c = &texture->color;
|
|
SDL_FColor *c = &texture->color;
|
|
|
-
|
|
|
|
|
- // Fast path 1: No transformations needed; direct BitBlt.
|
|
|
|
|
- if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) {
|
|
|
|
|
- // Only check render scale if color mod passes.
|
|
|
|
|
- float sx;
|
|
|
|
|
- float sy;
|
|
|
|
|
- SDL_GetRenderScale(renderer, &sx, &sy);
|
|
|
|
|
- if (sx == 1.f && sy == 1.f) {
|
|
|
|
|
- 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);
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Slow path: Transformations needed.
|
|
|
|
|
- float sx;
|
|
|
|
|
- float sy;
|
|
|
|
|
- SDL_GetRenderScale(renderer, &sx, &sy);
|
|
|
|
|
- int w = phdata->cachedWidth;
|
|
|
|
|
- int h = phdata->cachedHeight;
|
|
|
|
|
- int pitch = phdata->cachedPitch;
|
|
|
|
|
- void *source = phdata->cachedDataAddress;
|
|
|
|
|
|
|
+ int w = texture->w;
|
|
|
|
|
+ int h = texture->h;
|
|
|
|
|
+ const int bytes_per_pixel = 2;
|
|
|
|
|
+ int pitch = w * bytes_per_pixel;
|
|
|
|
|
+ void *source = phdata->bitmap->DataAddress();
|
|
|
void *dest;
|
|
void *dest;
|
|
|
|
|
|
|
|
if (!source) {
|
|
if (!source) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Ensure work buffers have sufficient capacity.
|
|
|
|
|
- TInt bufferSize = pitch * h;
|
|
|
|
|
- if (!EnsureWorkBufferCapacity(bufferSize)) {
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ TInt required_size = pitch * h;
|
|
|
|
|
+ if (required_size > iPixelBufferSize) {
|
|
|
|
|
+ void *new_buffer_a = SDL_realloc(iPixelBufferA, required_size);
|
|
|
|
|
+ if (!new_buffer_a) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ iPixelBufferA = new_buffer_a;
|
|
|
|
|
+
|
|
|
|
|
+ void *new_buffer_b = SDL_realloc(iPixelBufferB, required_size);
|
|
|
|
|
+ if (!new_buffer_b) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ iPixelBufferB = new_buffer_b;
|
|
|
|
|
+
|
|
|
|
|
+ iPixelBufferSize = required_size;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- dest = iWorkBuffer1;
|
|
|
|
|
|
|
+ dest = iPixelBufferA;
|
|
|
|
|
|
|
|
if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) {
|
|
if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) {
|
|
|
- TFixed rf = Real2Fix(c->r);
|
|
|
|
|
- TFixed gf = Real2Fix(c->g);
|
|
|
|
|
- TFixed bf = Real2Fix(c->b);
|
|
|
|
|
|
|
+ ApplyColorMod(dest, source, pitch, w, h, texture->color);
|
|
|
|
|
|
|
|
- // Build LUT if color changed.
|
|
|
|
|
- if (rf != iLastColorR || gf != iLastColorG || bf != iLastColorB) {
|
|
|
|
|
- BuildColorModLUT(rf, gf, bf);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT);
|
|
|
|
|
source = dest;
|
|
source = dest;
|
|
|
- dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ float sx;
|
|
|
|
|
+ float sy;
|
|
|
|
|
+ SDL_GetRenderScale(renderer, &sx, &sy);
|
|
|
|
|
+
|
|
|
if (sx != 1.f || sy != 1.f) {
|
|
if (sx != 1.f || sy != 1.f) {
|
|
|
TFixed scale_x = Real2Fix(sx);
|
|
TFixed scale_x = Real2Fix(sx);
|
|
|
TFixed scale_y = Real2Fix(sy);
|
|
TFixed scale_y = Real2Fix(sy);
|
|
|
TFixed center_x = Int2Fix(w / 2);
|
|
TFixed center_x = Int2Fix(w / 2);
|
|
|
TFixed center_y = Int2Fix(h / 2);
|
|
TFixed center_y = Int2Fix(h / 2);
|
|
|
|
|
|
|
|
|
|
+ dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA;
|
|
|
|
|
+
|
|
|
ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y);
|
|
ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y);
|
|
|
- source = dest;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // Use temp bitmap to avoid destroying source texture.
|
|
|
|
|
- if (!EnsureTempBitmapCapacity(w, h)) {
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ source = dest;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Copy transformed data to temp bitmap.
|
|
|
|
|
- Mem::Copy(iTempRenderBitmap->DataAddress(), source, pitch * h);
|
|
|
|
|
|
|
+ Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h);
|
|
|
|
|
|
|
|
- // Render from temp bitmap, preserving original texture.
|
|
|
|
|
- TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h));
|
|
|
|
|
- TPoint aDest(dstrect->x, dstrect->y);
|
|
|
|
|
- iRenderer->Gc()->BitBlt(aDest, iTempRenderBitmap, aSource);
|
|
|
|
|
|
|
+ if (phdata->bitmap) {
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
|
|
+ TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h));
|
|
|
|
|
+ TPoint aDest(dstrect->x, dstrect->y);
|
|
|
|
|
+ gc->BitBlt(aDest, phdata->bitmap, aSource);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
@@ -623,118 +401,74 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
SDL_FColor *c = &texture->color;
|
|
SDL_FColor *c = &texture->color;
|
|
|
|
|
+ int w = texture->w;
|
|
|
|
|
+ int h = texture->h;
|
|
|
|
|
+ const int bytes_per_pixel = 2;
|
|
|
|
|
+ int pitch = w * bytes_per_pixel;
|
|
|
|
|
+ void *source = phdata->bitmap->DataAddress();
|
|
|
|
|
+ void *dest;
|
|
|
|
|
|
|
|
- // Pre-calculate common checks.
|
|
|
|
|
- const bool isNoFlip = (!copydata->flip);
|
|
|
|
|
- const bool isNoRotation = (copydata->angle == 0);
|
|
|
|
|
- const bool isNoColorMod = (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f);
|
|
|
|
|
- const bool isIdentityScale = (copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1));
|
|
|
|
|
-
|
|
|
|
|
- // Fast path 1: No transformations needed; direct BitBlt.
|
|
|
|
|
- if (isNoFlip && isNoRotation && isNoColorMod && isIdentityScale) {
|
|
|
|
|
- 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);
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ if (!source) {
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Fast path 2: Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°).
|
|
|
|
|
- if (isNoFlip && isIdentityScale && isNoColorMod && !isNoRotation) {
|
|
|
|
|
- TFixed angle = copydata->angle;
|
|
|
|
|
- TInt angleIndex = -1;
|
|
|
|
|
-
|
|
|
|
|
- // Check cardinal angles with tolerance - optimized for early exit.
|
|
|
|
|
- if (SDL_abs(angle - kAngleZero) < kAngleTolerance) {
|
|
|
|
|
- angleIndex = 0; // 0°
|
|
|
|
|
- } else if (SDL_abs(angle - kAnglePi_2) < kAngleTolerance) {
|
|
|
|
|
- angleIndex = 1; // 90°
|
|
|
|
|
- } else if (SDL_abs(angle - kAnglePi) < kAngleTolerance) {
|
|
|
|
|
- angleIndex = 2; // 180°
|
|
|
|
|
- } else if (SDL_abs(angle - kAnglePi3_2) < kAngleTolerance) {
|
|
|
|
|
- angleIndex = 3; // 270°
|
|
|
|
|
- } else if (SDL_abs(angle - kAnglePi2) < kAngleTolerance) {
|
|
|
|
|
- angleIndex = 0; // 360° = 0°
|
|
|
|
|
|
|
+ TInt required_size = pitch * h;
|
|
|
|
|
+ if (required_size > iPixelBufferSize) {
|
|
|
|
|
+ void *new_buffer_a = SDL_realloc(iPixelBufferA, required_size);
|
|
|
|
|
+ if (!new_buffer_a) {
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
+ iPixelBufferA = new_buffer_a;
|
|
|
|
|
|
|
|
- if (angleIndex >= 0) {
|
|
|
|
|
- CFbsBitmap *cached = GetCardinalRotation(phdata, angleIndex);
|
|
|
|
|
- if (cached) {
|
|
|
|
|
- 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, cached, aSource);
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ void *new_buffer_b = SDL_realloc(iPixelBufferB, required_size);
|
|
|
|
|
+ if (!new_buffer_b) {
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
+ iPixelBufferB = new_buffer_b;
|
|
|
|
|
|
|
|
- // Slow path: Transformations needed.
|
|
|
|
|
- int w = phdata->cachedWidth;
|
|
|
|
|
- int h = phdata->cachedHeight;
|
|
|
|
|
- int pitch = phdata->cachedPitch;
|
|
|
|
|
- void *source = phdata->cachedDataAddress;
|
|
|
|
|
- void *dest;
|
|
|
|
|
-
|
|
|
|
|
- if (!source) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Ensure work buffers have sufficient capacity.
|
|
|
|
|
- TInt bufferSize = pitch * h;
|
|
|
|
|
- if (!EnsureWorkBufferCapacity(bufferSize)) {
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ iPixelBufferSize = required_size;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- dest = iWorkBuffer1;
|
|
|
|
|
|
|
+ dest = iPixelBufferA;
|
|
|
|
|
|
|
|
if (copydata->flip) {
|
|
if (copydata->flip) {
|
|
|
ApplyFlip(dest, source, pitch, w, h, copydata->flip);
|
|
ApplyFlip(dest, source, pitch, w, h, copydata->flip);
|
|
|
source = dest;
|
|
source = dest;
|
|
|
- dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!isIdentityScale) {
|
|
|
|
|
|
|
+ if (copydata->scale_x != 1.f || copydata->scale_y != 1.f) {
|
|
|
|
|
+ dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA;
|
|
|
ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y);
|
|
ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y);
|
|
|
source = dest;
|
|
source = dest;
|
|
|
- dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (copydata->angle) {
|
|
if (copydata->angle) {
|
|
|
|
|
+ dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA;
|
|
|
ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle);
|
|
ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle);
|
|
|
source = dest;
|
|
source = dest;
|
|
|
- dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!isNoColorMod) {
|
|
|
|
|
- TFixed rf = Real2Fix(c->r);
|
|
|
|
|
- TFixed gf = Real2Fix(c->g);
|
|
|
|
|
- TFixed bf = Real2Fix(c->b);
|
|
|
|
|
-
|
|
|
|
|
- // Build LUT if color changed.
|
|
|
|
|
- if (rf != iLastColorR || gf != iLastColorG || bf != iLastColorB) {
|
|
|
|
|
- BuildColorModLUT(rf, gf, bf);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT);
|
|
|
|
|
|
|
+ if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) {
|
|
|
|
|
+ dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA;
|
|
|
|
|
+ ApplyColorMod(dest, source, pitch, w, h, texture->color);
|
|
|
source = dest;
|
|
source = dest;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Use temp bitmap to avoid destroying source texture.
|
|
|
|
|
- if (!EnsureTempBitmapCapacity(w, h)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Copy transformed data to temp bitmap.
|
|
|
|
|
- Mem::Copy(iTempRenderBitmap->DataAddress(), source, pitch * h);
|
|
|
|
|
|
|
+ Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h);
|
|
|
|
|
|
|
|
- // Render from temp bitmap, preserving original texture.
|
|
|
|
|
- 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, iTempRenderBitmap, aSource);
|
|
|
|
|
|
|
+ if (phdata->bitmap) {
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
|
|
+ TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h));
|
|
|
|
|
+ TPoint aDest(copydata->dstrect.x, copydata->dstrect.y);
|
|
|
|
|
+ gc->BitBlt(aDest, phdata->bitmap, aSource);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight)
|
|
|
|
|
|
|
+bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight, const TInt aAccess)
|
|
|
{
|
|
{
|
|
|
if (!aTextureData) {
|
|
if (!aTextureData) {
|
|
|
return false;
|
|
return false;
|
|
@@ -752,101 +486,88 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Cache texture properties to avoid repeated API calls.
|
|
|
|
|
- TSize bitmapSize = aTextureData->bitmap->SizeInPixels();
|
|
|
|
|
- aTextureData->cachedWidth = bitmapSize.iWidth;
|
|
|
|
|
- aTextureData->cachedHeight = bitmapSize.iHeight;
|
|
|
|
|
- aTextureData->cachedPitch = aTextureData->bitmap->ScanLineLength(aWidth, aTextureData->bitmap->DisplayMode());
|
|
|
|
|
- aTextureData->cachedDataAddress = aTextureData->bitmap->DataAddress();
|
|
|
|
|
|
|
+ if (aAccess == SDL_TEXTUREACCESS_TARGET) {
|
|
|
|
|
+ TRAPD(err1, aTextureData->device = CFbsBitmapDevice::NewL(aTextureData->bitmap));
|
|
|
|
|
+ if (err1 != KErrNone || !aTextureData->device) {
|
|
|
|
|
+ delete aTextureData->bitmap;
|
|
|
|
|
+ aTextureData->bitmap = NULL;
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // Initialize cardinal rotation cache to NULL.
|
|
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
|
|
- aTextureData->cardinalRotations[i] = NULL;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ TRAPD(err2, aTextureData->gc = CFbsBitGc::NewL());
|
|
|
|
|
+ if (err2 != KErrNone || !aTextureData->gc) {
|
|
|
|
|
+ delete aTextureData->device;
|
|
|
|
|
+ aTextureData->device = NULL;
|
|
|
|
|
+ delete aTextureData->bitmap;
|
|
|
|
|
+ aTextureData->bitmap = NULL;
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // Initialize dirty tracking.
|
|
|
|
|
- aTextureData->isDirty = true; // New textures start dirty.
|
|
|
|
|
- aTextureData->dirtyRect.x = 0;
|
|
|
|
|
- aTextureData->dirtyRect.y = 0;
|
|
|
|
|
- aTextureData->dirtyRect.w = aWidth;
|
|
|
|
|
- aTextureData->dirtyRect.h = aHeight;
|
|
|
|
|
|
|
+ aTextureData->gc->Activate(aTextureData->device);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ aTextureData->gc = NULL;
|
|
|
|
|
+ aTextureData->device = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount)
|
|
void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount)
|
|
|
{
|
|
{
|
|
|
- if (iRenderer && iRenderer->Gc()) {
|
|
|
|
|
- // Ensure reusable buffer has sufficient capacity.
|
|
|
|
|
- if (!EnsureLinePointsCapacity(aCount)) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
|
|
+ gc->SetPenStyle(CGraphicsContext::ESolidPen);
|
|
|
|
|
|
|
|
- // Fill points from vertex data.
|
|
|
|
|
- for (TInt i = 0; i < aCount; i++) {
|
|
|
|
|
- iLinePointsBuffer[i] = TPoint(aVerts[i].x, aVerts[i].y);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // Draw lines as pairs of points (start, end)
|
|
|
|
|
+ for (TInt i = 0; i < aCount - 1; i += 2) {
|
|
|
|
|
+ TPoint start(aVerts[i].x, aVerts[i].y);
|
|
|
|
|
+ TPoint end(aVerts[i + 1].x, aVerts[i + 1].y);
|
|
|
|
|
|
|
|
- // Pack color once - all vertices use the same color in polyline.
|
|
|
|
|
- Uint8 ca = aVerts->color.a;
|
|
|
|
|
- Uint8 cr = aVerts->color.r;
|
|
|
|
|
- Uint8 cg = aVerts->color.g;
|
|
|
|
|
- Uint8 cb = aVerts->color.b;
|
|
|
|
|
- TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr;
|
|
|
|
|
|
|
+ TRgb color = TRgb(aVerts[i].color.r, aVerts[i].color.g, aVerts[i].color.b);
|
|
|
|
|
|
|
|
- iRenderer->Gc()->SetPenColor(aColor);
|
|
|
|
|
- iRenderer->Gc()->DrawPolyLineNoEndPoint(iLinePointsBuffer, aCount);
|
|
|
|
|
|
|
+ gc->SetPenColor(color);
|
|
|
|
|
+ gc->DrawLine(start, end);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount)
|
|
void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount)
|
|
|
{
|
|
{
|
|
|
- if (iRenderer && iRenderer->Gc()) {
|
|
|
|
|
- // Batch points by color to minimize SetPenColor calls.
|
|
|
|
|
- TUint32 currentColor = 0;
|
|
|
|
|
- bool colorSet = false;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
for (TInt i = 0; i < aCount; i++, aVerts++) {
|
|
for (TInt i = 0; i < aCount; i++, aVerts++) {
|
|
|
- TUint32 aColor = (TUint32(aVerts->color.a) << 24) | (TUint32(aVerts->color.b) << 16) |
|
|
|
|
|
- (TUint32(aVerts->color.g) << 8) | TUint32(aVerts->color.r);
|
|
|
|
|
-
|
|
|
|
|
- // Only set pen color when it changes.
|
|
|
|
|
- if (!colorSet || aColor != currentColor) {
|
|
|
|
|
- iRenderer->Gc()->SetPenColor(aColor);
|
|
|
|
|
- currentColor = aColor;
|
|
|
|
|
- colorSet = true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ TUint32 aColor = (((TUint8)aVerts->color.a << 24) |
|
|
|
|
|
+ ((TUint8)aVerts->color.b << 16) |
|
|
|
|
|
+ ((TUint8)aVerts->color.g << 8) |
|
|
|
|
|
+ (TUint8)aVerts->color.r);
|
|
|
|
|
|
|
|
- iRenderer->Gc()->Plot(TPoint(aVerts->x, aVerts->y));
|
|
|
|
|
|
|
+ gc->SetPenColor(aColor);
|
|
|
|
|
+ gc->Plot(TPoint(aVerts->x, aVerts->y));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount)
|
|
void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount)
|
|
|
{
|
|
{
|
|
|
- if (iRenderer && iRenderer->Gc()) {
|
|
|
|
|
- // Batch rectangles by color to minimize SetPenColor/SetBrushColor calls.
|
|
|
|
|
- TUint32 currentColor = 0;
|
|
|
|
|
- bool colorSet = false;
|
|
|
|
|
-
|
|
|
|
|
- // Process rectangles (each rect uses 2 vertices: position and size).
|
|
|
|
|
- for (TInt i = 0; i < aCount; i += 2) {
|
|
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
|
|
+ for (TInt i = 0; i < aCount; i++, aVerts++) {
|
|
|
TPoint pos(aVerts[i].x, aVerts[i].y);
|
|
TPoint pos(aVerts[i].x, aVerts[i].y);
|
|
|
- TSize size(aVerts[i + 1].x, aVerts[i + 1].y);
|
|
|
|
|
|
|
+ TSize size(
|
|
|
|
|
+ aVerts[i + 1].x,
|
|
|
|
|
+ aVerts[i + 1].y);
|
|
|
TRect rect(pos, size);
|
|
TRect rect(pos, size);
|
|
|
|
|
|
|
|
- TUint32 aColor = (TUint32(aVerts[i].color.a) << 24) | (TUint32(aVerts[i].color.b) << 16) |
|
|
|
|
|
- (TUint32(aVerts[i].color.g) << 8) | TUint32(aVerts[i].color.r);
|
|
|
|
|
-
|
|
|
|
|
- // Only set colors when they change.
|
|
|
|
|
- if (!colorSet || aColor != currentColor) {
|
|
|
|
|
- iRenderer->Gc()->SetPenColor(aColor);
|
|
|
|
|
- iRenderer->Gc()->SetBrushColor(aColor);
|
|
|
|
|
- currentColor = aColor;
|
|
|
|
|
- colorSet = true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ TUint32 aColor = (((TUint8)aVerts->color.a << 24) |
|
|
|
|
|
+ ((TUint8)aVerts->color.b << 16) |
|
|
|
|
|
+ ((TUint8)aVerts->color.g << 8) |
|
|
|
|
|
+ (TUint8)aVerts->color.r);
|
|
|
|
|
|
|
|
- iRenderer->Gc()->DrawRect(rect);
|
|
|
|
|
|
|
+ gc->SetPenColor(aColor);
|
|
|
|
|
+ gc->SetBrushColor(aColor);
|
|
|
|
|
+ gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
|
|
|
|
+ gc->SetPenStyle(CGraphicsContext::ENullPen);
|
|
|
|
|
+ gc->DrawRect(rect);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -862,65 +583,64 @@ void CRenderer::Flip()
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ iRenderer->Gc()->UseFont(iFont);
|
|
|
|
|
+
|
|
|
if (iShowFPS && iRenderer->Gc()) {
|
|
if (iShowFPS && iRenderer->Gc()) {
|
|
|
UpdateFPS();
|
|
UpdateFPS();
|
|
|
|
|
|
|
|
- iRenderer->Gc()->UseFont(iFont);
|
|
|
|
|
-
|
|
|
|
|
TBuf<64> info;
|
|
TBuf<64> info;
|
|
|
|
|
|
|
|
iRenderer->Gc()->SetPenStyle(CGraphicsContext::ESolidPen);
|
|
iRenderer->Gc()->SetPenStyle(CGraphicsContext::ESolidPen);
|
|
|
- iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
|
|
|
|
- iRenderer->Gc()->SetBrushColor(KRgbBlack);
|
|
|
|
|
|
|
+ iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ENullBrush);
|
|
|
iRenderer->Gc()->SetPenColor(KRgbCyan);
|
|
iRenderer->Gc()->SetPenColor(KRgbCyan);
|
|
|
|
|
|
|
|
- // Draw FPS background and text.
|
|
|
|
|
TRect aTextRect(TPoint(3, 203 - iFont->HeightInPixels()), TSize(45, iFont->HeightInPixels() + 2));
|
|
TRect aTextRect(TPoint(3, 203 - iFont->HeightInPixels()), TSize(45, iFont->HeightInPixels() + 2));
|
|
|
|
|
+ iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
|
|
|
|
+ iRenderer->Gc()->SetBrushColor(KRgbBlack);
|
|
|
iRenderer->Gc()->DrawRect(aTextRect);
|
|
iRenderer->Gc()->DrawRect(aTextRect);
|
|
|
|
|
|
|
|
|
|
+ // Draw messages.
|
|
|
info.Format(_L("FPS: %d"), iFPS);
|
|
info.Format(_L("FPS: %d"), iFPS);
|
|
|
iRenderer->Gc()->DrawText(info, TPoint(5, 203));
|
|
iRenderer->Gc()->DrawText(info, TPoint(5, 203));
|
|
|
-
|
|
|
|
|
- iRenderer->Gc()->DiscardFont();
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // This is a workaround that helps regulating the FPS.
|
|
|
|
|
+ iRenderer->Gc()->DrawText(_L(""), TPoint(0, 0));
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+ iRenderer->Gc()->DiscardFont();
|
|
|
iRenderer->Flip(iDirectScreen);
|
|
iRenderer->Flip(iDirectScreen);
|
|
|
|
|
|
|
|
- // Keep the backlight on when screen saver is suspended.
|
|
|
|
|
|
|
+ // Keep the backlight on.
|
|
|
if (iSuspendScreenSaver) {
|
|
if (iSuspendScreenSaver) {
|
|
|
User::ResetInactivityTime();
|
|
User::ResetInactivityTime();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // Yield to other threads and active objects briefly.
|
|
|
|
|
|
|
+ // Suspend the current thread for a short while.
|
|
|
|
|
+ // Give some time to other threads and active objects.
|
|
|
User::After(0);
|
|
User::After(0);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::SetDrawColor(TUint32 iColor)
|
|
void CRenderer::SetDrawColor(TUint32 iColor)
|
|
|
{
|
|
{
|
|
|
- if (iRenderer && iRenderer->Gc()) {
|
|
|
|
|
- // Skip redundant calls if color hasn't changed.
|
|
|
|
|
- if (iColor == iLastDrawColor) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- iRenderer->Gc()->SetPenColor(iColor);
|
|
|
|
|
- iRenderer->Gc()->SetBrushColor(iColor);
|
|
|
|
|
- iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
|
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
|
|
+ gc->SetPenColor(iColor);
|
|
|
|
|
+ gc->SetBrushColor(iColor);
|
|
|
|
|
+ gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ if (iRenderer) {
|
|
|
TRAPD(err, iRenderer->SetCurrentColor(iColor));
|
|
TRAPD(err, iRenderer->SetCurrentColor(iColor));
|
|
|
if (err != KErrNone) {
|
|
if (err != KErrNone) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- iLastDrawColor = iColor;
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight)
|
|
void CRenderer::SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight)
|
|
|
{
|
|
{
|
|
|
- if (iRenderer && iRenderer->Gc()) {
|
|
|
|
|
|
|
+ CFbsBitGc *gc = GetCurrentGc();
|
|
|
|
|
+ if (gc) {
|
|
|
TRect viewportRect(aX, aY, aX + aWidth, aY + aHeight);
|
|
TRect viewportRect(aX, aY, aX + aWidth, aY + aHeight);
|
|
|
- iRenderer->Gc()->SetClippingRect(viewportRect);
|
|
|
|
|
|
|
+ gc->SetClippingRect(viewportRect);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -928,17 +648,10 @@ void CRenderer::UpdateFPS()
|
|
|
{
|
|
{
|
|
|
static TTime lastTime;
|
|
static TTime lastTime;
|
|
|
static TInt frameCount = 0;
|
|
static TInt frameCount = 0;
|
|
|
- static TBool initialized = EFalse;
|
|
|
|
|
TTime currentTime;
|
|
TTime currentTime;
|
|
|
- const TUint KOneSecond = 1000000; // 1s in microseconds.
|
|
|
|
|
|
|
+ const TUint KOneSecond = 1000000; // 1s in ms.
|
|
|
|
|
|
|
|
currentTime.HomeTime();
|
|
currentTime.HomeTime();
|
|
|
-
|
|
|
|
|
- if (!initialized) {
|
|
|
|
|
- lastTime = currentTime;
|
|
|
|
|
- initialized = ETrue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
++frameCount;
|
|
++frameCount;
|
|
|
|
|
|
|
|
TTimeIntervalMicroSeconds timeDiff = currentTime.MicroSecondsFrom(lastTime);
|
|
TTimeIntervalMicroSeconds timeDiff = currentTime.MicroSecondsFrom(lastTime);
|
|
@@ -958,6 +671,19 @@ void CRenderer::SuspendScreenSaver(TBool aSuspend)
|
|
|
iSuspendScreenSaver = aSuspend;
|
|
iSuspendScreenSaver = aSuspend;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void CRenderer::SetRenderTarget(NGAGE_TextureData *aTarget)
|
|
|
|
|
+{
|
|
|
|
|
+ iCurrentRenderTarget = aTarget;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+CFbsBitGc *CRenderer::GetCurrentGc()
|
|
|
|
|
+{
|
|
|
|
|
+ if (iCurrentRenderTarget && iCurrentRenderTarget->gc) {
|
|
|
|
|
+ return iCurrentRenderTarget->gc;
|
|
|
|
|
+ }
|
|
|
|
|
+ return iRenderer ? iRenderer->Gc() : NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static SDL_Scancode ConvertScancode(int key)
|
|
static SDL_Scancode ConvertScancode(int key)
|
|
|
{
|
|
{
|
|
|
SDL_Keycode keycode;
|
|
SDL_Keycode keycode;
|
|
@@ -1058,8 +784,8 @@ void CRenderer::HandleEvent(const TWsEvent &aWsEvent)
|
|
|
case EEventKeyUp: /* Key events */
|
|
case EEventKeyUp: /* Key events */
|
|
|
timestamp = SDL_GetPerformanceCounter();
|
|
timestamp = SDL_GetPerformanceCounter();
|
|
|
SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), false);
|
|
SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), false);
|
|
|
- break;
|
|
|
|
|
|
|
|
|
|
|
|
+ break;
|
|
|
case EEventFocusGained:
|
|
case EEventFocusGained:
|
|
|
DisableKeyBlocking();
|
|
DisableKeyBlocking();
|
|
|
if (!iDirectScreen->IsActive()) {
|
|
if (!iDirectScreen->IsActive()) {
|