+3
-1
examples/renderer/18-debug-text/debug-text.c
+3
-1
examples/renderer/18-debug-text/debug-text.c
···
46
46
/* This function runs once per frame, and is the heart of the program. */
47
47
SDL_AppResult SDL_AppIterate(void *appstate)
48
48
{
49
+
const int charsize = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
50
+
49
51
/* as you can see from this, rendering draws over whatever was drawn before it. */
50
52
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
51
53
SDL_RenderClear(renderer); /* start with a blank canvas. */
···
63
65
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
64
66
SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣");
65
67
66
-
SDL_RenderDebugTextF(renderer, 0, 0, "This program has been running for %" SDL_PRIu64 " seconds.", SDL_GetTicks() / 1000);
68
+
SDL_RenderDebugTextFormat(renderer, (float) ((WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000);
67
69
68
70
SDL_RenderPresent(renderer); /* put it all on the screen! */
69
71
+7
-36
include/SDL3/SDL_render.h
+7
-36
include/SDL3/SDL_render.h
···
2530
2530
*
2531
2531
* \since This function is available since SDL 3.1.6.
2532
2532
*
2533
-
* \sa SDL_RenderDebugTextF
2534
-
* \sa SDL_RenderDebugTextV
2533
+
* \sa SDL_RenderDebugTextFormat
2535
2534
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
2536
2535
*/
2537
2536
extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, float x, float y, const char *str);
···
2539
2538
/**
2540
2539
* Draw debug text to an SDL_Renderer.
2541
2540
*
2542
-
* This function will render a printf() style format string to a renderer. Note
2543
-
* that this is a convinence function for debugging, with severe limitations,
2544
-
* and is not intended to be used for production apps and games.
2541
+
* This function will render a printf()-style format string to a renderer.
2542
+
* Note that this is a convinence function for debugging, with severe
2543
+
* limitations, and is not intended to be used for production apps and games.
2545
2544
*
2546
2545
* For the full list of limitations and other useful information,
2547
2546
* see SDL_RenderDebugText.
···
2550
2549
* \param x the x coordinate where the top-left corner of the text will draw.
2551
2550
* \param y the y coordinate where the top-left corner of the text will draw.
2552
2551
* \param fmt the format string to draw.
2553
-
* \param ... format arguments
2552
+
* \param ... additional parameters matching % tokens in the `fmt` string, if
2553
+
* any.
2554
2554
* \returns true on success or false on failure; call SDL_GetError() for more
2555
2555
* information.
2556
2556
*
···
2559
2559
* \since This function is available since SDL 3.1.7.
2560
2560
*
2561
2561
* \sa SDL_RenderDebugText
2562
-
* \sa SDL_RenderDebugTextV
2563
2562
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
2564
2563
*/
2565
-
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);
2566
-
2567
-
/**
2568
-
* Draw debug text to an SDL_Renderer.
2569
-
*
2570
-
* This function will render a printf() style format string to a renderer. Note
2571
-
* that this is a convinence function for debugging, with severe limitations,
2572
-
* and is not intended to be used for production apps and games.
2573
-
*
2574
-
* For the full list of limitations and other useful information,
2575
-
* see SDL_RenderDebugText.
2576
-
*
2577
-
* \param renderer the renderer which should draw the text.
2578
-
* \param x the x coordinate where the top-left corner of the text will draw.
2579
-
* \param y the y coordinate where the top-left corner of the text will draw.
2580
-
* \param fmt the format string to draw.
2581
-
* \param ap a variable argument lists representing the format arguments
2582
-
* \returns true on success or false on failure; call SDL_GetError() for more
2583
-
* information.
2584
-
*
2585
-
* \threadsafety This function should only be called on the main thread.
2586
-
*
2587
-
* \since This function is available since SDL 3.1.7.
2588
-
*
2589
-
* \sa SDL_RenderDebugText
2590
-
* \sa SDL_RenderDebugTextF
2591
-
* \sa SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE
2592
-
*/
2593
-
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);
2564
+
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);
2594
2565
2595
2566
/* Ends C function definitions when using C++ */
2596
2567
#ifdef __cplusplus
+18
-4
src/dynapi/SDL_dynapi.c
+18
-4
src/dynapi/SDL_dynapi.c
···
149
149
va_end(ap); \
150
150
return result; \
151
151
} \
152
-
_static bool SDLCALL SDL_RenderDebugTextF##name(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
152
+
_static bool SDLCALL SDL_RenderDebugTextFormat##name(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
153
153
{ \
154
-
bool result; \
154
+
char buf[128], *str = buf; \
155
+
int result; \
155
156
va_list ap; \
156
157
initcall; \
157
158
va_start(ap, fmt); \
158
-
result = jump_table.SDL_RenderDebugTextV(renderer, x, y, fmt, ap); \
159
+
result = jump_table.SDL_vsnprintf(buf, sizeof(buf), fmt, ap); \
159
160
va_end(ap); \
160
-
return result; \
161
+
if (result >= 0 && (size_t)result >= sizeof(buf)) { \
162
+
str = NULL; \
163
+
va_start(ap, fmt); \
164
+
result = jump_table.SDL_vasprintf(&str, fmt, ap); \
165
+
va_end(ap); \
166
+
} \
167
+
bool retval = false; \
168
+
if (result >= 0) { \
169
+
retval = jump_table.SDL_RenderDebugTextFormat(renderer, x, y, "%s", str); \
170
+
} \
171
+
if (str != buf) { \
172
+
jump_table.SDL_free(str); \
173
+
} \
174
+
return retval; \
161
175
} \
162
176
_static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
163
177
{ \
+1
-2
src/dynapi/SDL_dynapi.sym
+1
-2
src/dynapi/SDL_dynapi.sym
···
1207
1207
SDL_SetGPUAllowedFramesInFlight;
1208
1208
SDL_RenderTextureAffine;
1209
1209
SDL_WaitAndAcquireGPUSwapchainTexture;
1210
-
SDL_RenderDebugTextF;
1211
-
SDL_RenderDebugTextV;
1210
+
SDL_RenderDebugTextFormat;
1212
1211
# extra symbols go here (don't modify this line)
1213
1212
local: *;
1214
1213
};
+1
-2
src/dynapi/SDL_dynapi_overrides.h
+1
-2
src/dynapi/SDL_dynapi_overrides.h
···
1232
1232
#define SDL_SetGPUAllowedFramesInFlight SDL_SetGPUAllowedFramesInFlight_REAL
1233
1233
#define SDL_RenderTextureAffine SDL_RenderTextureAffine_REAL
1234
1234
#define SDL_WaitAndAcquireGPUSwapchainTexture SDL_WaitAndAcquireGPUSwapchainTexture_REAL
1235
-
#define SDL_RenderDebugTextF SDL_RenderDebugTextF_REAL
1236
-
#define SDL_RenderDebugTextV SDL_RenderDebugTextV_REAL
1235
+
#define SDL_RenderDebugTextFormat SDL_RenderDebugTextFormat_REAL
+1
-2
src/dynapi/SDL_dynapi_procs.h
+1
-2
src/dynapi/SDL_dynapi_procs.h
···
1239
1239
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)
1240
1240
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)
1241
1241
#ifndef SDL_DYNAPI_PROC_NO_VARARGS
1242
-
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)
1242
+
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)
1243
1243
#endif
1244
-
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)
+15
-32
src/render/SDL_render.c
+15
-32
src/render/SDL_render.c
···
5590
5590
return result;
5591
5591
}
5592
5592
5593
-
bool SDL_RenderDebugTextF(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
5593
+
bool SDL_RenderDebugTextFormat(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
5594
5594
{
5595
5595
va_list ap;
5596
-
5597
5596
va_start(ap, fmt);
5598
-
bool result = SDL_RenderDebugTextV(renderer, x, y, fmt, ap);
5599
-
va_end(ap);
5600
5597
5601
-
return result;
5602
-
}
5603
-
5604
-
bool SDL_RenderDebugTextV(SDL_Renderer *renderer, float x, float y, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
5605
-
{
5606
-
// 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...
5607
-
CHECK_RENDERER_MAGIC(renderer, false);
5608
-
5609
-
va_list apc;
5610
-
va_copy(apc, ap); // vsnprintf mangles ap, so copy it so it can be used again later
5611
-
int len = SDL_vsnprintf(NULL, 0, fmt, apc);
5612
-
va_end(apc);
5613
-
5614
-
if (len < 0) {
5615
-
return SDL_SetError("Failed to format debug text");
5598
+
// fast path to avoid unnecessary allocation and copy. If you're going through the dynapi, there's a good chance
5599
+
// you _always_ hit this path, since it probably had to process varargs before calling into the jumptable.
5600
+
if (SDL_strcmp(fmt, "%s") == 0) {
5601
+
const char *str = va_arg(ap, const char *);
5602
+
va_end(ap);
5603
+
return SDL_RenderDebugText(renderer, x, y, str);
5616
5604
}
5617
5605
5618
-
char *buf = SDL_malloc(len + 1);
5619
-
if (buf == NULL) {
5620
-
return SDL_OutOfMemory();
5621
-
}
5606
+
char *str = NULL;
5607
+
const int rc = SDL_vasprintf(&str, fmt, ap);
5608
+
va_end(ap);
5622
5609
5623
-
len = SDL_vsnprintf(buf, len + 1, fmt, ap);
5624
-
if (len < 0) {
5625
-
SDL_free(buf);
5626
-
return SDL_SetError("Failed to format debug text");
5610
+
if (rc == -1) {
5611
+
return false;
5627
5612
}
5628
5613
5629
-
bool result = SDL_RenderDebugText(renderer, x, y, buf);
5630
-
5631
-
SDL_free(buf);
5632
-
5633
-
return result;
5614
+
const bool retval = SDL_RenderDebugText(renderer, x, y, str);
5615
+
SDL_free(str);
5616
+
return retval;
5634
5617
}