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 }