mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-20 19:58:33 +00:00
render: Updates to format-string versions of SDL_RenderDebugText.
- Removes SDL_RenderDebugTextV - Changes SDL_RenderDebugTextF to SDL_RenderDebugTextFormat and tweaks it to work in a world without SDL_RenderDebugTextV. - Tweaked rendering position of formatted text in the example program.
This commit is contained in:
parent
6abebca943
commit
4d4a2786bb
7 changed files with 50 additions and 83 deletions
examples/renderer/18-debug-text
include/SDL3
src
|
@ -46,6 +46,8 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||||
/* This function runs once per frame, and is the heart of the program. */
|
/* This function runs once per frame, and is the heart of the program. */
|
||||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||||
{
|
{
|
||||||
|
const int charsize = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
|
||||||
|
|
||||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||||
|
@ -63,7 +65,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
|
||||||
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
|
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
|
||||||
SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣");
|
SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣");
|
||||||
|
|
||||||
SDL_RenderDebugTextF(renderer, 0, 0, "This program has been running for %" SDL_PRIu64 " seconds.", SDL_GetTicks() / 1000);
|
SDL_RenderDebugTextFormat(renderer, (float) ((WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000);
|
||||||
|
|
||||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||||
|
|
||||||
|
|
|
@ -2530,8 +2530,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderVSync(SDL_Renderer *renderer, int
|
||||||
*
|
*
|
||||||
* \since This function is available since SDL 3.1.6.
|
* \since This function is available since SDL 3.1.6.
|
||||||
*
|
*
|
||||||
* \sa SDL_RenderDebugTextF
|
* \sa SDL_RenderDebugTextFormat
|
||||||
* \sa SDL_RenderDebugTextV
|
|
||||||
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
|
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
|
||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, float x, float y, const char *str);
|
extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, float x, float y, const char *str);
|
||||||
|
@ -2539,9 +2538,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
|
||||||
/**
|
/**
|
||||||
* Draw debug text to an SDL_Renderer.
|
* Draw debug text to an SDL_Renderer.
|
||||||
*
|
*
|
||||||
* This function will render a printf() style format string to a renderer. Note
|
* This function will render a printf()-style format string to a renderer.
|
||||||
* that this is a convinence function for debugging, with severe limitations,
|
* Note that this is a convinence function for debugging, with severe
|
||||||
* and is not intended to be used for production apps and games.
|
* limitations, and is not intended to be used for production apps and games.
|
||||||
*
|
*
|
||||||
* For the full list of limitations and other useful information,
|
* For the full list of limitations and other useful information,
|
||||||
* see SDL_RenderDebugText.
|
* see SDL_RenderDebugText.
|
||||||
|
@ -2550,7 +2549,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
|
||||||
* \param x the x coordinate where the top-left corner of the text will draw.
|
* \param x the x coordinate where the top-left corner of the text will draw.
|
||||||
* \param y the y coordinate where the top-left corner of the text will draw.
|
* \param y the y coordinate where the top-left corner of the text will draw.
|
||||||
* \param fmt the format string to draw.
|
* \param fmt the format string to draw.
|
||||||
* \param ... format arguments
|
* \param ... additional parameters matching % tokens in the `fmt` string, if
|
||||||
|
* any.
|
||||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
* information.
|
* information.
|
||||||
*
|
*
|
||||||
|
@ -2559,38 +2559,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
|
||||||
* \since This function is available since SDL 3.1.7.
|
* \since This function is available since SDL 3.1.7.
|
||||||
*
|
*
|
||||||
* \sa SDL_RenderDebugText
|
* \sa SDL_RenderDebugText
|
||||||
* \sa SDL_RenderDebugTextV
|
|
||||||
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
|
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
|
||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugTextF(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(4);
|
extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugTextFormat(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(4);
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw debug text to an SDL_Renderer.
|
|
||||||
*
|
|
||||||
* This function will render a printf() style format string to a renderer. Note
|
|
||||||
* that this is a convinence function for debugging, with severe limitations,
|
|
||||||
* and is not intended to be used for production apps and games.
|
|
||||||
*
|
|
||||||
* For the full list of limitations and other useful information,
|
|
||||||
* see SDL_RenderDebugText.
|
|
||||||
*
|
|
||||||
* \param renderer the renderer which should draw the text.
|
|
||||||
* \param x the x coordinate where the top-left corner of the text will draw.
|
|
||||||
* \param y the y coordinate where the top-left corner of the text will draw.
|
|
||||||
* \param fmt the format string to draw.
|
|
||||||
* \param ap a variable argument lists representing the format arguments
|
|
||||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* \threadsafety This function should only be called on the main thread.
|
|
||||||
*
|
|
||||||
* \since This function is available since SDL 3.1.7.
|
|
||||||
*
|
|
||||||
* \sa SDL_RenderDebugText
|
|
||||||
* \sa SDL_RenderDebugTextF
|
|
||||||
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
|
|
||||||
*/
|
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugTextV(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(4);
|
|
||||||
|
|
||||||
/* Ends C function definitions when using C++ */
|
/* Ends C function definitions when using C++ */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -149,15 +149,29 @@ static void SDL_InitDynamicAPI(void);
|
||||||
va_end(ap); \
|
va_end(ap); \
|
||||||
return result; \
|
return result; \
|
||||||
} \
|
} \
|
||||||
_static bool SDLCALL SDL_RenderDebugTextF##name(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
_static bool SDLCALL SDL_RenderDebugTextFormat##name(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
||||||
{ \
|
{ \
|
||||||
bool result; \
|
char buf[128], *str = buf; \
|
||||||
|
int result; \
|
||||||
va_list ap; \
|
va_list ap; \
|
||||||
initcall; \
|
initcall; \
|
||||||
va_start(ap, fmt); \
|
va_start(ap, fmt); \
|
||||||
result = jump_table.SDL_RenderDebugTextV(renderer, x, y, fmt, ap); \
|
result = jump_table.SDL_vsnprintf(buf, sizeof(buf), fmt, ap); \
|
||||||
va_end(ap); \
|
va_end(ap); \
|
||||||
return result; \
|
if (result >= 0 && (size_t)result >= sizeof(buf)) { \
|
||||||
|
str = NULL; \
|
||||||
|
va_start(ap, fmt); \
|
||||||
|
result = jump_table.SDL_vasprintf(&str, fmt, ap); \
|
||||||
|
va_end(ap); \
|
||||||
|
} \
|
||||||
|
bool retval = false; \
|
||||||
|
if (result >= 0) { \
|
||||||
|
retval = jump_table.SDL_RenderDebugTextFormat(renderer, x, y, "%s", str); \
|
||||||
|
} \
|
||||||
|
if (str != buf) { \
|
||||||
|
jump_table.SDL_free(str); \
|
||||||
|
} \
|
||||||
|
return retval; \
|
||||||
} \
|
} \
|
||||||
_static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
_static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -1207,8 +1207,7 @@ SDL3_0.0.0 {
|
||||||
SDL_SetGPUAllowedFramesInFlight;
|
SDL_SetGPUAllowedFramesInFlight;
|
||||||
SDL_RenderTextureAffine;
|
SDL_RenderTextureAffine;
|
||||||
SDL_WaitAndAcquireGPUSwapchainTexture;
|
SDL_WaitAndAcquireGPUSwapchainTexture;
|
||||||
SDL_RenderDebugTextF;
|
SDL_RenderDebugTextFormat;
|
||||||
SDL_RenderDebugTextV;
|
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1232,5 +1232,4 @@
|
||||||
#define SDL_SetGPUAllowedFramesInFlight SDL_SetGPUAllowedFramesInFlight_REAL
|
#define SDL_SetGPUAllowedFramesInFlight SDL_SetGPUAllowedFramesInFlight_REAL
|
||||||
#define SDL_RenderTextureAffine SDL_RenderTextureAffine_REAL
|
#define SDL_RenderTextureAffine SDL_RenderTextureAffine_REAL
|
||||||
#define SDL_WaitAndAcquireGPUSwapchainTexture SDL_WaitAndAcquireGPUSwapchainTexture_REAL
|
#define SDL_WaitAndAcquireGPUSwapchainTexture SDL_WaitAndAcquireGPUSwapchainTexture_REAL
|
||||||
#define SDL_RenderDebugTextF SDL_RenderDebugTextF_REAL
|
#define SDL_RenderDebugTextFormat SDL_RenderDebugTextFormat_REAL
|
||||||
#define SDL_RenderDebugTextV SDL_RenderDebugTextV_REAL
|
|
||||||
|
|
|
@ -1239,6 +1239,5 @@ SDL_DYNAPI_PROC(bool,SDL_SetGPUAllowedFramesInFlight,(SDL_GPUDevice *a,Uint32 b)
|
||||||
SDL_DYNAPI_PROC(bool,SDL_RenderTextureAffine,(SDL_Renderer *a,SDL_Texture *b,const SDL_FRect *c,const SDL_FPoint *d,const SDL_FPoint *e,const SDL_FPoint *f),(a,b,c,d,e,f),return)
|
SDL_DYNAPI_PROC(bool,SDL_RenderTextureAffine,(SDL_Renderer *a,SDL_Texture *b,const SDL_FRect *c,const SDL_FPoint *d,const SDL_FPoint *e,const SDL_FPoint *f),(a,b,c,d,e,f),return)
|
||||||
SDL_DYNAPI_PROC(bool,SDL_WaitAndAcquireGPUSwapchainTexture,(SDL_GPUCommandBuffer *a,SDL_Window *b,SDL_GPUTexture **c,Uint32 *d,Uint32 *e),(a,b,c,d,e),return)
|
SDL_DYNAPI_PROC(bool,SDL_WaitAndAcquireGPUSwapchainTexture,(SDL_GPUCommandBuffer *a,SDL_Window *b,SDL_GPUTexture **c,Uint32 *d,Uint32 *e),(a,b,c,d,e),return)
|
||||||
#ifndef SDL_DYNAPI_PROC_NO_VARARGS
|
#ifndef SDL_DYNAPI_PROC_NO_VARARGS
|
||||||
SDL_DYNAPI_PROC(bool,SDL_RenderDebugTextF,(SDL_Renderer *a,float b,float c,SDL_PRINTF_FORMAT_STRING const char *d,...),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(bool,SDL_RenderDebugTextFormat,(SDL_Renderer *a,float b,float c,SDL_PRINTF_FORMAT_STRING const char *d,...),(a,b,c,d),return)
|
||||||
#endif
|
#endif
|
||||||
SDL_DYNAPI_PROC(bool,SDL_RenderDebugTextV,(SDL_Renderer *a,float b,float c,SDL_PRINTF_FORMAT_STRING const char *d,va_list e),(a,b,c,d,e),return)
|
|
||||||
|
|
|
@ -5590,45 +5590,28 @@ bool SDL_RenderDebugText(SDL_Renderer *renderer, float x, float y, const char *s
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDL_RenderDebugTextF(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
bool SDL_RenderDebugTextFormat(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
bool result = SDL_RenderDebugTextV(renderer, x, y, fmt, ap);
|
|
||||||
|
// fast path to avoid unnecessary allocation and copy. If you're going through the dynapi, there's a good chance
|
||||||
|
// you _always_ hit this path, since it probably had to process varargs before calling into the jumptable.
|
||||||
|
if (SDL_strcmp(fmt, "%s") == 0) {
|
||||||
|
const char *str = va_arg(ap, const char *);
|
||||||
|
va_end(ap);
|
||||||
|
return SDL_RenderDebugText(renderer, x, y, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str = NULL;
|
||||||
|
const int rc = SDL_vasprintf(&str, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return result;
|
if (rc == -1) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
bool SDL_RenderDebugTextV(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
|
|
||||||
{
|
const bool retval = SDL_RenderDebugText(renderer, x, y, str);
|
||||||
// Probably for the best to check this here, so we don't do a bunch of string formatting before realizing the renderer isn't even valid...
|
SDL_free(str);
|
||||||
CHECK_RENDERER_MAGIC(renderer, false);
|
return retval;
|
||||||
|
|
||||||
va_list apc;
|
|
||||||
va_copy(apc, ap); // vsnprintf mangles ap, so copy it so it can be used again later
|
|
||||||
int len = SDL_vsnprintf(NULL, 0, fmt, apc);
|
|
||||||
va_end(apc);
|
|
||||||
|
|
||||||
if (len < 0) {
|
|
||||||
return SDL_SetError("Failed to format debug text");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *buf = SDL_malloc(len + 1);
|
|
||||||
if (buf == NULL) {
|
|
||||||
return SDL_OutOfMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
len = SDL_vsnprintf(buf, len + 1, fmt, ap);
|
|
||||||
if (len < 0) {
|
|
||||||
SDL_free(buf);
|
|
||||||
return SDL_SetError("Failed to format debug text");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result = SDL_RenderDebugText(renderer, x, y, buf);
|
|
||||||
|
|
||||||
SDL_free(buf);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue