Update for N-Gage - Audio is now double buffered (#15516)

[N-Gage] Audio is now double buffered to avoid stuttering and glitches. Some audio platform specific variables were exposed through SDL_Hints. Same method was used to display FPS. N-gage functions to obtain the current buffer and screen pitch were added to the render.

Adds hints:

SDL_AUDIO_NGAGE_LATENCY
SDL_AUDIO_NGAGE_SCHEDULER_TICK
SDL_AUDIO_NGAGE_PROCESS_TICK
SDL_AUDIO_NGAGE_PROCESS_PRIORITY
SDL_RENDER_SHOW_FPS

Adds functions to get current buffer address and pitch:

void *NGAGE_GetBackbufferAddress(void);
int NGAGE_GetBackbufferPitch(void);

---------
Co-authored-by: Michael Fitzmayer <mail@michael-fitzmayer.de>
Co-authored-by: Eddy Jansson <eloj@users.noreply.github.com>
This commit is contained in:
misscelan
2026-05-06 16:39:23 +02:00
committed by GitHub
parent 1ac0ae9224
commit 37089cf0a8
7 changed files with 323 additions and 215 deletions

View File

@@ -149,6 +149,23 @@ void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target)
}
}
static void SDLCALL NGAGE_ShowFPSChanged(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
CRenderer *renderer = (CRenderer *)userdata;
renderer->SetShowFPS(SDL_GetStringBoolean(newValue, false));
}
void *NGAGE_GetBackbufferAddress(void)
{
return gRenderer->GetCurrentBitmap()->DataAddress();
}
int NGAGE_GetBackbufferPitch(void)
{
return CFbsBitmap::ScanLineLength(NGAGE_SCREEN_WIDTH, EColor4K) / 2;
}
#ifdef __cplusplus
}
#endif
@@ -166,6 +183,8 @@ CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSessio
CRenderer::~CRenderer()
{
SDL_RemoveHintCallback(SDL_HINT_RENDER_NGAGE_SHOW_FPS, NGAGE_ShowFPSChanged, this);
delete iRenderer;
iRenderer = 0;
@@ -266,6 +285,8 @@ void CRenderer::ConstructL()
}
iDirectScreen->ScreenDevice()->SetAutoUpdate(ETrue);
}
SDL_AddHintCallback(SDL_HINT_RENDER_NGAGE_SHOW_FPS, NGAGE_ShowFPSChanged, this);
}
void CRenderer::Restart(RDirectScreenAccess::TTerminationReasons aReason)
@@ -336,6 +357,8 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
return false;
}
NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal;
if (!phdata || !phdata->bitmap) {
return false;
@@ -346,7 +369,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
int sw = srcrect->w;
int sh = srcrect->h;
// Fast path: render target texture with no color mod.
// BitBlt directly from its bitmap — DataAddress() is unreliable
// for bitmaps that have been drawn into via a CFbsBitGc.
@@ -359,7 +382,8 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
SDL_GetTextureBlendMode(texture, &blend);
bool no_color_key = (blend != SDL_BLENDMODE_BLEND);
if (phdata->gc && no_color_mod && no_scale && no_color_key) {
if (phdata->gc && no_color_mod && no_scale && no_color_key)
{
CFbsBitGc *gc = GetCurrentGc();
if (gc) {
TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(sw, sh));
@@ -369,6 +393,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
return true;
}
// Fast path: color-key with no color mod and no scale.
// Blit directly from the source bitmap into the destination, skipping transparent pixels.
if (no_color_mod && no_scale && !no_color_key && phdata->has_color_key) {
@@ -414,6 +439,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
return false;
}
}
TSize scratch_size = iScratchBitmap->SizeInPixels();
if (scratch_size.iWidth < sw || scratch_size.iHeight < sh) {
iScratchBitmap->Reset();
@@ -438,6 +464,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec
void *source = iPixelBufferA;
void *dest = iPixelBufferB;
if (!no_color_mod) {
ApplyColorMod(dest, source, src_pitch, sw, sh, texture->color);
void *tmp = source;
@@ -934,13 +961,15 @@ void CRenderer::HandleEvent(const TWsEvent &aWsEvent)
timestamp = SDL_GetPerformanceCounter();
SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), true);
/*
commented out so it works with hints
if (aWsEvent.Key()->iScanCode == EStdKeyHash) {
if (iShowFPS) {
iShowFPS = EFalse;
} else {
iShowFPS = ETrue;
}
}
}*/
break;
case EEventKeyUp: /* Key events */

View File

@@ -25,6 +25,10 @@
#define NGAGE_SCREEN_WIDTH 176
#define NGAGE_SCREEN_HEIGHT 208
#ifndef SDL_HINT_RENDER_NGAGE_SHOW_FPS
#define SDL_HINT_RENDER_NGAGE_SHOW_FPS "SDL_RENDER_NGAGE_SHOW_FPS"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -108,6 +112,8 @@ void NGAGE_SetDrawColor(const Uint32 color);
void NGAGE_PumpEventsInternal(void);
void NGAGE_SuspendScreenSaverInternal(bool suspend);
void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target);
void *NGAGE_GetBackbufferAddress(void);
int NGAGE_GetBackbufferPitch(void);
#ifdef __cplusplus
}

View File

@@ -46,6 +46,7 @@ class CRenderer : public MDirectScreenAccess
void SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight);
void UpdateFPS();
void SuspendScreenSaver(TBool aSuspend);
void SetShowFPS(TBool aShow) { iShowFPS = aShow; }
// Render target management.
void SetRenderTarget(NGAGE_TextureData *aTarget);