Mercurial > repos > blastem
comparison nuklear_ui/blastem_nuklear.c @ 1492:bdeb2a1d0385 nuklear_ui
Add shader selector to video settings
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 01 Dec 2017 23:16:07 -0800 |
parents | e890971f3757 |
children | 24f44f26b74d |
comparison
equal
deleted
inserted
replaced
1491:e890971f3757 | 1492:bdeb2a1d0385 |
---|---|
274 sprintf(buffer, "%d", val); | 274 sprintf(buffer, "%d", val); |
275 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); | 275 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); |
276 } | 276 } |
277 } | 277 } |
278 | 278 |
279 typedef struct { | |
280 char *fragment; | |
281 char *vertex; | |
282 } shader_prog; | |
283 | |
284 shader_prog *get_shader_progs(dir_entry *entries, size_t num_entries, shader_prog *progs, uint32_t *num_existing, uint32_t *storage) | |
285 { | |
286 uint32_t num_progs = *num_existing; | |
287 uint32_t prog_storage = *storage; | |
288 uint32_t starting = num_progs; | |
289 | |
290 for (uint32_t i = 0; i < num_entries; i++) { | |
291 if (entries[i].is_dir) { | |
292 continue; | |
293 } | |
294 char *no_ext = basename_no_extension(entries[i].name); | |
295 uint32_t len = strlen(no_ext); | |
296 if (no_ext[len-1] == 'f' && no_ext[len-2] == '.') { | |
297 uint8_t dupe = 0;; | |
298 for (uint32_t j = 0; j < starting; j++) { | |
299 if (!strcmp(entries[i].name, progs[j].fragment)) { | |
300 dupe = 1; | |
301 break; | |
302 } | |
303 } | |
304 if (!dupe) { | |
305 if (num_progs == prog_storage) { | |
306 prog_storage *= 2; | |
307 progs = realloc(progs, sizeof(progs) * prog_storage); | |
308 } | |
309 progs[num_progs].vertex = NULL; | |
310 progs[num_progs++].fragment = strdup(entries[i].name); | |
311 } | |
312 } | |
313 free(no_ext); | |
314 } | |
315 | |
316 for (uint32_t i = 0; i < num_entries; i++) { | |
317 if (entries[i].is_dir) { | |
318 continue; | |
319 } | |
320 char *no_ext = basename_no_extension(entries[i].name); | |
321 uint32_t len = strlen(no_ext); | |
322 if (no_ext[len-1] == 'v' && no_ext[len-2] == '.') { | |
323 for (uint32_t j = 0; j < num_progs; j++) { | |
324 if (!strncmp(no_ext, progs[j].fragment, len-1) && progs[j].fragment[len-1] == 'f' && progs[j].fragment[len] == '.') { | |
325 progs[j].vertex = strdup(entries[i].name); | |
326 } | |
327 } | |
328 } | |
329 free(no_ext); | |
330 } | |
331 free_dir_list(entries, num_entries); | |
332 *num_existing = num_progs; | |
333 *storage = prog_storage; | |
334 return progs; | |
335 } | |
336 | |
337 shader_prog *get_shader_list(uint32_t *num_out) | |
338 { | |
339 char *shader_dir = path_append(get_config_dir(), "shaders"); | |
340 size_t num_entries; | |
341 dir_entry *entries = get_dir_list(shader_dir, &num_entries); | |
342 free(shader_dir); | |
343 shader_prog *progs; | |
344 uint32_t num_progs = 0, prog_storage; | |
345 if (num_entries) { | |
346 progs = calloc(num_entries, sizeof(shader_prog)); | |
347 prog_storage = num_entries; | |
348 progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage); | |
349 } else { | |
350 progs = NULL; | |
351 prog_storage = 0; | |
352 } | |
353 shader_dir = path_append(get_exe_dir(), "shaders"); | |
354 entries = get_dir_list(shader_dir, &num_entries); | |
355 progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage); | |
356 *num_out = num_progs; | |
357 return progs; | |
358 } | |
359 | |
279 void view_video_settings(struct nk_context *context) | 360 void view_video_settings(struct nk_context *context) |
280 { | 361 { |
362 static shader_prog *progs; | |
363 static char **prog_names; | |
364 static uint32_t num_progs; | |
365 static uint32_t selected_prog; | |
366 if(!progs) { | |
367 progs = get_shader_list(&num_progs); | |
368 prog_names = calloc(num_progs, sizeof(char*)); | |
369 for (uint32_t i = 0; i < num_progs; i++) | |
370 { | |
371 prog_names[i] = basename_no_extension(progs[i].fragment);; | |
372 uint32_t len = strlen(prog_names[i]); | |
373 if (len > 2) { | |
374 prog_names[i][len-2] = 0; | |
375 } | |
376 if (!progs[i].vertex) { | |
377 progs[i].vertex = strdup("default.v.glsl"); | |
378 } | |
379 if (!strcmp( | |
380 progs[i].fragment, | |
381 tern_find_path_default(config, "video\0fragment_shader\0", (tern_val){.ptrval = "default.f.glsl"}, TVAL_PTR).ptrval | |
382 )) { | |
383 selected_prog = i; | |
384 } | |
385 } | |
386 } | |
281 uint32_t width = render_width(); | 387 uint32_t width = render_width(); |
282 uint32_t height = render_height(); | 388 uint32_t height = render_height(); |
283 if (nk_begin(context, "Video Settings", nk_rect(0, 0, width, height), 0)) { | 389 if (nk_begin(context, "Video Settings", nk_rect(0, 0, width, height), 0)) { |
284 nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); | 390 nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); |
285 settings_toggle(context, "Fullscreen", "video\0fullscreen\0", 0); | 391 settings_toggle(context, "Fullscreen", "video\0fullscreen\0", 0); |
286 settings_toggle(context, "Open GL", "video\0gl\0", 1); | 392 settings_toggle(context, "Open GL", "video\0gl\0", 1); |
287 settings_toggle(context, "Scanlines", "video\0scanlines\0", 0); | 393 settings_toggle(context, "Scanlines", "video\0scanlines\0", 0); |
288 settings_int_input(context, "Windowed Width", "video\0width\0", "640"); | 394 settings_int_input(context, "Windowed Width", "video\0width\0", "640"); |
395 nk_label(context, "Shader", NK_TEXT_LEFT); | |
396 uint32_t next_selected = nk_combo(context, (const char **)prog_names, num_progs, selected_prog, 30, nk_vec2(300, 300)); | |
397 if (next_selected != selected_prog) { | |
398 selected_prog = next_selected; | |
399 config = tern_insert_path(config, "video\0fragment_shader\0", (tern_val){.ptrval = strdup(progs[next_selected].fragment)}, TVAL_PTR); | |
400 config = tern_insert_path(config, "video\0vertex_shader\0", (tern_val){.ptrval = strdup(progs[next_selected].vertex)}, TVAL_PTR); | |
401 } | |
289 settings_int_property(context, "NTSC Overscan", "Top", "video\0ntsc\0overscan\0top\0", 2, 0, 32); | 402 settings_int_property(context, "NTSC Overscan", "Top", "video\0ntsc\0overscan\0top\0", 2, 0, 32); |
290 settings_int_property(context, "", "Bottom", "video\0ntsc\0overscan\0bottom\0", 17, 0, 32); | 403 settings_int_property(context, "", "Bottom", "video\0ntsc\0overscan\0bottom\0", 17, 0, 32); |
291 settings_int_property(context, "", "Left", "video\0ntsc\0overscan\0left\0", 13, 0, 32); | 404 settings_int_property(context, "", "Left", "video\0ntsc\0overscan\0left\0", 13, 0, 32); |
292 settings_int_property(context, "", "Right", "video\0ntsc\0overscan\0right\0", 14, 0, 32); | 405 settings_int_property(context, "", "Right", "video\0ntsc\0overscan\0right\0", 14, 0, 32); |
293 settings_int_property(context, "PAL Overscan", "Top", "video\0pal\0overscan\0top\0", 2, 0, 32); | 406 settings_int_property(context, "PAL Overscan", "Top", "video\0pal\0overscan\0top\0", 2, 0, 32); |
294 settings_int_property(context, "", "Bottom", "video\0pal\0overscan\0bottom\0", 17, 0, 32); | 407 settings_int_property(context, "", "Bottom", "video\0pal\0overscan\0bottom\0", 17, 0, 32); |
295 settings_int_property(context, "", "Left", "video\0pal\0overscan\0left\0", 13, 0, 32); | 408 settings_int_property(context, "", "Left", "video\0pal\0overscan\0left\0", 13, 0, 32); |
296 settings_int_property(context, "", "Right", "video\0pal\0overscan\0right\0", 14, 0, 32); | 409 settings_int_property(context, "", "Right", "video\0pal\0overscan\0right\0", 14, 0, 32); |
410 | |
297 if (nk_button_label(context, "Back")) { | 411 if (nk_button_label(context, "Back")) { |
298 pop_view(); | 412 pop_view(); |
299 } | 413 } |
300 nk_end(context); | 414 nk_end(context); |
301 } | 415 } |