Guest User

sdl3fix

a guest
Aug 11th, 2026
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.61 KB | Source Code | 0 0
  1. /* nuklear - public domain */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include <math.h>
  8. #include <assert.h>
  9. #include <limits.h>
  10. #include <time.h>
  11.  
  12. #include <SDL3/SDL.h>
  13.  
  14. /* This demo uses "main callbacks" which are new in SDL3
  15. * Those provide highly portable entry point and event loop for the app
  16. * see: https://wiki.libsdl.org/SDL3/README-main-functions
  17. * */
  18. #define SDL_MAIN_USE_CALLBACKS
  19. #include <SDL3/SDL_main.h>
  20.  
  21. /* ===============================================================
  22. *
  23. * CONFIG
  24. *
  25. * ===============================================================*/
  26.  
  27. /* optional: sdl3_renderer does not need any of these defines
  28. * (but some examples might need them, so be careful) */
  29. #define NK_INCLUDE_STANDARD_VARARGS
  30. #define NK_INCLUDE_STANDARD_IO
  31.  
  32. /* note that sdl3_renderer comes with nk_sdl_style_set_debug_font()
  33. * so you may wish to use that instead of font baking */
  34. #define NK_INCLUDE_FONT_BAKING
  35. #define NK_INCLUDE_DEFAULT_FONT
  36.  
  37. /* note that sdl3_renderer comes with nk_sdl_allocator()
  38. * and you probably want to use that allocator instead of the default ones */
  39. /*#define NK_INCLUDE_DEFAULT_ALLOCATOR*/
  40.  
  41. /* mandatory: sdl3_renderer depends on those defines */
  42. #define NK_INCLUDE_COMMAND_USERDATA
  43. #define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
  44.  
  45.  
  46. /* We can re-use the types provided by SDL which are extremely portable,
  47. * so there is no need for Nuklear to detect those on its own */
  48. /*#define NK_INCLUDE_FIXED_TYPES*/
  49. #ifndef NK_INCLUDE_FIXED_TYPES
  50. #define NK_INT8 Sint8
  51. #define NK_UINT8 Uint8
  52. #define NK_INT16 Sint16
  53. #define NK_UINT16 Uint16
  54. #define NK_INT32 Sint32
  55. #define NK_UINT32 Uint32
  56. /* SDL guarantees 'uintptr_t' typedef */
  57. #define NK_SIZE_TYPE uintptr_t
  58. #define NK_POINTER_TYPE uintptr_t
  59. #endif
  60.  
  61. /* We can reuse the `bool` symbol because SDL3 guarantees its existence */
  62. /*#define NK_INCLUDE_STANDARD_BOOL*/
  63. #ifndef NK_INCLUDE_STANDARD_BOOL
  64. #define NK_BOOL bool
  65. #endif
  66.  
  67. /* We can re-use various portable libc functions provided by SDL */
  68. #define NK_ASSERT(condition) SDL_assert(condition)
  69. #define NK_STATIC_ASSERT(exp) SDL_COMPILE_TIME_ASSERT(, exp)
  70. #define NK_MEMSET(dst, c, len) SDL_memset(dst, c, len)
  71. #define NK_MEMCPY(dst, src, len) SDL_memcpy(dst, src, len)
  72. #define NK_VSNPRINTF(s, n, f, a) SDL_vsnprintf(s, n, f, a)
  73. #define NK_STRTOD(str, endptr) SDL_strtod(str, endptr)
  74.  
  75. /* SDL3 does not provide "dtoa" (only integer versions)
  76. * but we can emulate it with SDL_snprintf */
  77. static char* nk_sdl_dtoa(char *str, double d);
  78. #define NK_DTOA(str, d) nk_sdl_dtoa(str, d)
  79.  
  80. /* SDL can also provide us with math functions, but beware that Nuklear's own
  81. * implementation can be slightly faster at the cost of some precision */
  82. #define NK_INV_SQRT(f) (1.0f / SDL_sqrtf(f))
  83. #define NK_SIN(f) SDL_sinf(f)
  84. #define NK_COS(f) SDL_cosf(f)
  85.  
  86. /* HACK: Nuklear pulls two stb libraries in order to use font baking
  87. * those libraries pull in some libc headers internally, creating a linkage dependency,
  88. * so you’ll most likely want to use SDL symbols instead */
  89. #define STBTT_ifloor(x) ((int)SDL_floor(x))
  90. #define STBTT_iceil(x) ((int)SDL_ceil(x))
  91. #define STBTT_sqrt(x) SDL_sqrt(x)
  92. #define STBTT_pow(x,y) SDL_pow(x,y)
  93. #define STBTT_fmod(x,y) SDL_fmod(x,y)
  94. #define STBTT_cos(x) SDL_cosf(x)
  95. #define STBTT_acos(x) SDL_acos(x)
  96. #define STBTT_fabs(x) SDL_fabs(x)
  97. #define STBTT_assert(x) SDL_assert(x)
  98. #define STBTT_strlen(x) SDL_strlen(x)
  99. #define STBTT_memcpy SDL_memcpy
  100. #define STBTT_memset SDL_memset
  101. #define stbtt_uint8 Uint8
  102. #define stbtt_int8 Sint8
  103. #define stbtt_uint16 Uint16
  104. #define stbtt_int16 Sint16
  105. #define stbtt_uint32 Uint32
  106. #define stbtt_int32 Sint32
  107. #define STBRP_SORT SDL_qsort
  108. #define STBRP_ASSERT SDL_assert
  109. /* There is no need to define STBTT_malloc/STBTT_free macros
  110. * Nuklear will define those to user-provided nk_allocator */
  111.  
  112.  
  113. #define NK_IMPLEMENTATION
  114. #include "../../nuklear.h"
  115. #define NK_SDL3_RENDERER_IMPLEMENTATION
  116. #include "nuklear_sdl3_renderer.h"
  117.  
  118. #define WINDOW_WIDTH 1200
  119. #define WINDOW_HEIGHT 800
  120.  
  121. /* ===============================================================
  122. *
  123. * EXAMPLE
  124. *
  125. * ===============================================================*/
  126. /* These are some code examples to provide a small overview of what can be
  127. * done with this library. To try out an example uncomment the defines */
  128. /*#define INCLUDE_ALL */
  129. /*#define INCLUDE_STYLE */
  130. /*#define INCLUDE_CALCULATOR */
  131. /*#define INCLUDE_CANVAS */
  132. #define INCLUDE_OVERVIEW
  133. /*#define INCLUDE_CONFIGURATOR */
  134. /*#define INCLUDE_NODE_EDITOR */
  135.  
  136. #ifdef INCLUDE_ALL
  137. #define INCLUDE_STYLE
  138. #define INCLUDE_CALCULATOR
  139. #define INCLUDE_CANVAS
  140. #define INCLUDE_OVERVIEW
  141. #define INCLUDE_CONFIGURATOR
  142. #define INCLUDE_NODE_EDITOR
  143. #endif
  144.  
  145. #ifdef INCLUDE_STYLE
  146. #include "../../demo/common/style.c"
  147. #endif
  148. #ifdef INCLUDE_CALCULATOR
  149. #include "../../demo/common/calculator.c"
  150. #endif
  151. #ifdef INCLUDE_CANVAS
  152. #include "../../demo/common/canvas.c"
  153. #endif
  154. #ifdef INCLUDE_OVERVIEW
  155. #include "../../demo/common/overview.c"
  156. #endif
  157. #ifdef INCLUDE_CONFIGURATOR
  158. #include "../../demo/common/style_configurator.c"
  159. #endif
  160. #ifdef INCLUDE_NODE_EDITOR
  161. #include "../../demo/common/node_editor.c"
  162. #endif
  163.  
  164. /* ===============================================================
  165. *
  166. * DEMO
  167. *
  168. * ===============================================================*/
  169. int height = 800;
  170. int width = 1200;
  171. int tempheight;
  172. int tempwidth;
  173. nk_bool show_app_about = nk_false;
  174. nk_bool Show_Search_Menu = nk_false;
  175. char abouttext[1000];
  176. int SearchBox_Write_buffer;
  177. char SearchBox_Total_buffer[40];
  178.  
  179. struct nk_sdl_app {
  180. SDL_Window* window;
  181. SDL_Renderer* renderer;
  182. struct nk_context * ctx;
  183. struct nk_colorf bg;
  184. enum nk_anti_aliasing AA;
  185. };
  186.  
  187. static SDL_AppResult
  188. nk_sdl_fail()
  189. {
  190. SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "Error: %s", SDL_GetError());
  191. return SDL_APP_FAILURE;
  192. }
  193.  
  194. SDL_AppResult
  195. SDL_AppInit(void** appstate, int argc, char* argv[])
  196. {
  197. struct nk_sdl_app* app;
  198. struct nk_context* ctx;
  199. float font_scale;
  200. NK_UNUSED(argc);
  201. NK_UNUSED(argv);
  202.  
  203. if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
  204. return nk_sdl_fail();
  205. }
  206.  
  207. app = SDL_malloc(sizeof(*app));
  208. if (app == NULL) {
  209. return nk_sdl_fail();
  210. }
  211.  
  212. if (!SDL_CreateWindowAndRenderer("Nuklear: SDL3 Renderer", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &app->window, &app->renderer)) {
  213. SDL_free(app);
  214. return nk_sdl_fail();
  215. }
  216. *appstate = app;
  217.  
  218. if (!SDL_SetRenderVSync(app->renderer, 1)) {
  219. SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "SDL_SetRenderVSync failed: %s", SDL_GetError());
  220. }
  221.  
  222. app->bg.r = 0.10f;
  223. app->bg.g = 0.18f;
  224. app->bg.b = 0.24f;
  225. app->bg.a = 1.0f;
  226.  
  227.  
  228. font_scale = 1;
  229. {
  230. /* This scaling logic was kept simple for the demo purpose.
  231. * On some platforms, this might not be the exact scale
  232. * that you want to use. For more information, see:
  233. * https://wiki.libsdl.org/SDL3/README-highdpi */
  234. const float scale = SDL_GetWindowDisplayScale(app->window);
  235. SDL_SetRenderScale(app->renderer, scale, scale);
  236. font_scale = scale;
  237. }
  238.  
  239. ctx = nk_sdl_init(app->window, app->renderer, nk_sdl_allocator());
  240. app->ctx = ctx;
  241.  
  242. #if 0
  243. {
  244. /* If you don't want to use advanced Nuklear font baking API
  245. * you can use simple ASCII debug font provided by SDL
  246. * just change the `#if 0` above to `#if 1` */
  247. nk_sdl_style_set_debug_font(ctx);
  248.  
  249. /* Note that since debug font is extremely small (only 8x8 pixels),
  250. * scaling it does not make much sense. The font would appear blurry. */
  251. NK_UNUSED(font_scale);
  252.  
  253. /* You may wish to change a few style options, here are few recommendations: */
  254. ctx->style.button.rounding = 0.0f;
  255. ctx->style.menu_button.rounding = 0.0f;
  256. ctx->style.property.rounding = 0.0f;
  257. ctx->style.property.border = 0.0f;
  258. ctx->style.option.border = -1.0f;
  259. ctx->style.checkbox.border = -1.0f;
  260. ctx->style.property.dec_button.border = -2.0f;
  261. ctx->style.property.inc_button.border = -2.0f;
  262. ctx->style.tab.tab_minimize_button.border = -2.0f;
  263. ctx->style.tab.tab_maximize_button.border = -2.0f;
  264. ctx->style.tab.node_minimize_button.border = -2.0f;
  265. ctx->style.tab.node_maximize_button.border = -2.0f;
  266. ctx->style.checkbox.spacing = 5.0f;
  267.  
  268. /* It's better to disable anti-aliasing when using small fonts */
  269. app->AA = NK_ANTI_ALIASING_OFF;
  270. }
  271. #else
  272. {
  273. struct nk_font_atlas *atlas;
  274. struct nk_font_config config = nk_font_config(0);
  275. struct nk_font *font;
  276.  
  277. /* set up the font atlas and add desired font; note that font sizes are
  278. * multiplied by font_scale to produce better results at higher DPIs */
  279. atlas = nk_sdl_font_stash_begin(ctx);
  280. font = nk_font_atlas_add_default(atlas, 13 * font_scale, &config);
  281. /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14 * font_scale, &config);*/
  282. /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16 * font_scale, &config);*/
  283. /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13 * font_scale, &config);*/
  284. /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12 * font_scale, &config);*/
  285. /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10 * font_scale, &config);*/
  286. /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13 * font_scale, &config);*/
  287. nk_sdl_font_stash_end(ctx);
  288.  
  289. /* this hack makes the font appear to be scaled down to the desired
  290. * size and is only necessary when font_scale > 1 */
  291. font->handle.height /= font_scale;
  292. /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
  293. nk_style_set_font(ctx, &font->handle);
  294.  
  295. app->AA = NK_ANTI_ALIASING_ON;
  296. }
  297. #endif
  298.  
  299. nk_input_begin(ctx);
  300.  
  301. return SDL_APP_CONTINUE;
  302. }
  303.  
  304. SDL_AppResult
  305. SDL_AppEvent(void *appstate, SDL_Event* event)
  306. {
  307. struct nk_sdl_app* app = (struct nk_sdl_app*)appstate;
  308.  
  309. switch (event->type) {
  310. case SDL_EVENT_QUIT:
  311. return SDL_APP_SUCCESS;
  312. case SDL_EVENT_KEY_DOWN:
  313. if (event->key.key == SDLK_Q && event->key.mod & SDL_KMOD_CTRL) {
  314. return SDL_APP_SUCCESS;
  315. }
  316. break;
  317. case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
  318. /* You may wish to rescale the renderer and Nuklear during this event.
  319. * Without this the UI and Font could appear too small or too big.
  320. * This is not handled by the demo in order to keep it simple,
  321. * but you may wish to re-bake the Font whenever this happens. */
  322. SDL_Log("Unhandled scale event! Nuklear may appear blurry");
  323. return SDL_APP_CONTINUE;
  324. }
  325.  
  326. /* Remember to always rescale the event coordinates,
  327. * if your renderer uses custom scale. */
  328. SDL_ConvertEventToRenderCoordinates(app->renderer, event);
  329.  
  330. nk_sdl_handle_event(app->ctx, event);
  331.  
  332. if ( event->key.key == SDLK_ESCAPE || event->key.key == SDLK_Q ) {
  333. Show_Search_Menu = nk_false;
  334. }
  335. if ( event->key.key == SDLK_A && event->key.repeat == 0) {
  336. show_app_about = nk_false;
  337. }
  338. if ( event->key.key == SDLK_SLASH ) {
  339. Show_Search_Menu = nk_true;
  340. }
  341.  
  342. return SDL_APP_CONTINUE;
  343. }
  344.  
  345. SDL_AppResult
  346. SDL_AppIterate(void *appstate)
  347. {
  348. struct nk_sdl_app* app = (struct nk_sdl_app*)appstate;
  349. struct nk_context* ctx = app->ctx;
  350.  
  351. #ifdef INCLUDE_CONFIGURATOR
  352. static struct nk_color color_table[NK_COLOR_COUNT];
  353. NK_MEMCPY(color_table, nk_default_color_style, sizeof(color_table));
  354. #endif
  355.  
  356. nk_input_end(ctx);
  357.  
  358. /* GUI */
  359. if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
  360. NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
  361. NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
  362. {
  363. enum {EASY, HARD};
  364. static int op = EASY;
  365. static int property = 20;
  366.  
  367. nk_layout_row_static(ctx, 30, 80, 1);
  368. if (nk_button_label(ctx, "button")) {
  369. SDL_Log("button pressed");
  370. }
  371. nk_layout_row_dynamic(ctx, 30, 2);
  372. if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
  373. if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
  374. nk_layout_row_dynamic(ctx, 25, 1);
  375. nk_property_int(ctx, "Compression:", 0, &property, 1000, 1, 1);
  376.  
  377. nk_layout_row_dynamic(ctx, 20, 1);
  378. nk_label(ctx, "background:", NK_TEXT_LEFT);
  379. nk_layout_row_dynamic(ctx, 25, 1);
  380. if (nk_combo_begin_color(ctx, nk_rgb_cf(app->bg), nk_vec2(nk_widget_width(ctx),400))) {
  381. nk_layout_row_dynamic(ctx, 120, 1);
  382. app->bg = nk_color_picker(ctx, app->bg, NK_RGBA);
  383. nk_layout_row_dynamic(ctx, 25, 1);
  384. app->bg.r = nk_propertyf(ctx, "#R:", 0, app->bg.r, 1.0f, 0.01f,0.005f);
  385. app->bg.g = nk_propertyf(ctx, "#G:", 0, app->bg.g, 1.0f, 0.01f,0.005f);
  386. app->bg.b = nk_propertyf(ctx, "#B:", 0, app->bg.b, 1.0f, 0.01f,0.005f);
  387. app->bg.a = nk_propertyf(ctx, "#A:", 0, app->bg.a, 1.0f, 0.01f,0.005f);
  388. nk_combo_end(ctx);
  389. }
  390. }
  391. nk_end(ctx);
  392. if (nk_begin(ctx, "ic.wiki", nk_rect(10, 10, 300, 300), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE) ) {
  393. /*
  394. nk_layout_row_static(ctx, (height/40.), (width/20), 1);
  395. if ( nk_button_label(ctx, "About") ) {
  396. show_app_about = nk_true;
  397. fprintf(stdout, "nk_true: %d\n", show_app_about);
  398. SDL_Log("button pressed");
  399. }
  400. */
  401. nk_layout_row_begin(ctx, NK_STATIC, 30, 2);
  402. nk_layout_row_push(ctx, 120);
  403. nk_label(ctx, "Popup:", NK_TEXT_LEFT);
  404. nk_layout_row_push(ctx, 50);
  405. if (nk_button_label(ctx, "Popup"))
  406. show_app_about = 1;
  407. nk_layout_row_end(ctx);
  408. if (show_app_about)
  409. {
  410. if (nk_popup_begin(ctx, NK_POPUP_DYNAMIC, "About", 0, nk_rect( (100) , (100) , (300), (200) )))
  411. {
  412. nk_layout_row_dynamic(ctx, 10, 1);
  413. if (nk_tree_push(ctx, NK_TREE_NODE, "Manifest", NK_MAXIMIZED)) {
  414. nk_layout_row_static(ctx, 100, 200, 1);
  415. nk_label_wrap(ctx, "\176 ic.wiki is a site made by me to compare (hopefully) all of ic in the world in a flat fashion; tired to dumpster dive in to hundreds of nothingness pdf pages");
  416. nk_label_wrap(ctx, "\176 The full dataset can be downloaded below:");
  417. if ( nk_button_label(ctx, "https://ic.wiki/public/dataset-latest.csv.zstd") ) {
  418. }
  419. nk_tree_pop(ctx);
  420. }
  421. if (nk_tree_push(ctx, NK_TREE_NODE, "Open Source License & Credits", NK_MINIMIZED))
  422. {
  423. if (nk_tree_push(ctx, NK_TREE_NODE, "Powering Site", NK_MINIMIZED)) {
  424. if ( nk_button_label(ctx, "SDL3\54 Zlib\54 Sam Lantinga\54 1997-2026") ) {
  425. }
  426. if ( nk_button_label(ctx, "Nuklear ui\54 MIT\54 Micha Mettke\54 2017") ) {
  427. }
  428. if ( nk_button_label(ctx, "Emscripten\54 MIT University of Illinois NCSA Open Source License\54 Emscripten authors 2010-2014") ) {
  429. }
  430. if ( nk_button_label(ctx, "SQLite\54 Open License") ) {
  431. }
  432. nk_tree_pop(ctx);
  433. }
  434. if (nk_tree_push(ctx, NK_TREE_NODE, "Curation of Dataset", NK_MINIMIZED)) {
  435. if ( nk_button_label(ctx, "LibreOffice Calc") ) {
  436. }
  437. nk_tree_pop(ctx);
  438. }
  439. nk_tree_pop(ctx);
  440. }
  441. nk_popup_end(ctx);
  442. } else show_app_about = nk_false;
  443. }
  444. }
  445. nk_end(ctx);
  446. /*
  447. if ( Show_Search_Menu ) {
  448. if (nk_popup_begin(ctx, NK_POPUP_DYNAMIC, "Search",
  449. NK_WINDOW_CLOSABLE|NK_WINDOW_SCALABLE|NK_WINDOW_MOVABLE,
  450. nk_rect( (width / 20) , (height / 20) , (width / 4), (height / 4) ))) {
  451. nk_layout_row_static(ctx, ( height / 5.2 ), ( width / 4.2 ) , 1);
  452. nk_edit_string(ctx, NK_EDIT_BOX, SearchBox_Total_buffer, &SearchBox_Write_buffer, 512, nk_filter_default);
  453. nk_popup_end(ctx);
  454. }else Show_Search_Menu = nk_false;
  455. } */
  456.  
  457. /* -------------- EXAMPLES ---------------- */
  458. #ifdef INCLUDE_CALCULATOR
  459. calculator(ctx);
  460. #endif
  461. #ifdef INCLUDE_CANVAS
  462. canvas(ctx);
  463. #endif
  464. #ifdef INCLUDE_OVERVIEW
  465. overview(ctx);
  466. #endif
  467. #ifdef INCLUDE_CONFIGURATOR
  468. style_configurator(ctx, color_table);
  469. #endif
  470. #ifdef INCLUDE_NODE_EDITOR
  471. node_editor(ctx);
  472. #endif
  473. /* ----------------------------------------- */
  474.  
  475. SDL_SetRenderDrawColorFloat(app->renderer, app->bg.r, app->bg.g, app->bg.b, app->bg.a);
  476. SDL_RenderClear(app->renderer);
  477.  
  478. nk_sdl_render(ctx, app->AA);
  479. nk_sdl_update_TextInput(ctx);
  480.  
  481. /* show if TextInput is active for debug purpose. Feel free to remove this. */
  482. SDL_SetRenderDrawColor(app->renderer, 0xFF, 0xFF, 0xFF, 0xFF);
  483. SDL_RenderDebugTextFormat(app->renderer, 10, 10, "TextInputActive? %s",
  484. SDL_TextInputActive(app->window) ? "Yes" : "No");
  485.  
  486. SDL_RenderPresent(app->renderer);
  487.  
  488. nk_input_begin(ctx);
  489. return SDL_APP_CONTINUE;
  490. }
  491.  
  492. void
  493. SDL_AppQuit(void* appstate, SDL_AppResult result)
  494. {
  495. struct nk_sdl_app* app = (struct nk_sdl_app*)appstate;
  496. NK_UNUSED(result);
  497.  
  498. if (app) {
  499. nk_input_end(app->ctx);
  500. nk_sdl_shutdown(app->ctx);
  501. SDL_DestroyRenderer(app->renderer);
  502. SDL_DestroyWindow(app->window);
  503. SDL_free(app);
  504. }
  505. }
  506.  
  507. static char*
  508. nk_sdl_dtoa(char *str, double d)
  509. {
  510. NK_ASSERT(str);
  511. if (!str) return NULL;
  512. (void)SDL_snprintf(str, 99999, "%.17g", d);
  513. return str;
  514. }
  515.  
  516.  
Advertisement
Add Comment
Please, Sign In to add comment