static int httpserver_handle_basic_info(struct mg_connection* conn, void* cbdata) { static const char *libretro_btn_desc[] = { "B (bottom)", "Y (left)", "Select", "Start", "D-Pad Up", "D-Pad Down", "D-Pad Left", "D-Pad Right", "A (right)", "X (up)", "L", "R", "L2", "R2", "L3", "R3", }; unsigned p, q, r; retro_ctx_api_info_t api; retro_ctx_region_info_t region; retro_ctx_memory_info_t sram; retro_ctx_memory_info_t rtc; retro_ctx_memory_info_t sysram; retro_ctx_memory_info_t vram; char core_path[PATH_MAX_LENGTH] = {0}; const char* pixel_format = NULL; const struct retro_subsystem_info* subsys = NULL; const struct retro_subsystem_rom_info* rom = NULL; const struct retro_subsystem_memory_info* mem = NULL; const struct retro_controller_description* ctrl = NULL; const char* comma = NULL; const struct core_option* opts = NULL; const struct retro_system_av_info* av_info = NULL; const core_option_manager_t* core_opts = NULL; const struct mg_request_info * req = mg_get_request_info(conn); const settings_t * settings = config_get_ptr(); rarch_system_info_t *system = runloop_get_system_info(); if (string_is_empty(system->info.library_name)) return httpserver_error(conn, 500, "Core not initialized in %s", __FUNCTION__); if (!core_is_game_loaded()) return httpserver_error(conn, 500, "Game not loaded in %s", __FUNCTION__); json_string_encode(core_path, sizeof(core_path), config_get_active_core_path()); core_api_version(&api); core_get_region(®ion); switch (video_driver_get_pixel_format()) { case RETRO_PIXEL_FORMAT_0RGB1555: pixel_format = "RETRO_PIXEL_FORMAT_0RGB1555"; break; case RETRO_PIXEL_FORMAT_XRGB8888: pixel_format = "RETRO_PIXEL_FORMAT_XRGB8888"; break; case RETRO_PIXEL_FORMAT_RGB565: pixel_format = "RETRO_PIXEL_FORMAT_RGB565"; break; default: pixel_format = "?"; break; } sram.id = RETRO_MEMORY_SAVE_RAM; core_get_memory(&sram); rtc.id = RETRO_MEMORY_RTC; core_get_memory(&rtc); sysram.id = RETRO_MEMORY_SYSTEM_RAM; core_get_memory(&sysram); vram.id = RETRO_MEMORY_VIDEO_RAM; core_get_memory(&vram); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" "{" "\"corePath\":\"%s\"," "\"apiVersion\":%u," "\"systemInfo\":" "{" "\"libraryName\":\"%s\"," "\"libraryVersion\":\"%s\"," "\"validExtensions\":\"%s\"," "\"needsFullpath\":%s," "\"blockExtract\":%s" "}," "\"region\":\"%s\"," "\"pixelFormat\":\"%s\"," "\"rotation\":%u," "\"performaceLevel\":%u," "\"supportsNoGame\":%s," #ifdef HAVE_CHEEVOS "\"frontendSupportsAchievements\":true," "\"coreSupportsAchievements\":%s," #else "\"frontendSupportsAchievements\":false," "\"coreSupportsAchievements\":null," #endif "\"saveRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "}," "\"rtcRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "}," "\"systemRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "}," "\"videoRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "},", core_path, api.version, system->info.library_name, system->info.library_version, system->info.valid_extensions, system->info.need_fullpath ? "true" : "false", system->info.block_extract ? "true" : "false", region.region ? "RETRO_REGION_PAL" : "RETRO_REGION_NTSC", pixel_format, system->rotation, system->performance_level, content_does_not_need_content() ? "true" : "false", #ifdef HAVE_CHEEVOS cheevos_get_support_cheevos() ? "true" : "false", #endif (uintptr_t)sram.data, sram.size, (uintptr_t)rtc.data, rtc.size, (uintptr_t)sysram.data, sysram.size, (uintptr_t)vram.data, vram.size ); mg_printf(conn, "\"subSystems\":["); subsys = system->subsystem.data; for (p = 0; p < system->subsystem.size; p++, subsys++) { mg_printf(conn, "%s{\"id\":%u,\"description\":\"%s\",\"identifier\":\"%s\",\"roms\":[", p == 0 ? "" : ",", subsys->id, subsys->desc, subsys->ident); rom = subsys->roms; for (q = 0; q < subsys->num_roms; q++, rom++) { mg_printf(conn, "%s{" "\"description\":\"%s\"," "\"extensions\":\"%s\"," "\"needsFullpath\":%s," "\"blockExtract\":%s," "\"required\":%s," "\"memory\":[", q == 0 ? "" : ",", rom->desc, rom->valid_extensions, rom->need_fullpath ? "true" : "false", rom->block_extract ? "true" : "false", rom->required ? "true" : "false" ); mem = rom->memory; comma = ""; for (r = 0; r < rom->num_memory; r++, mem++) { mg_printf(conn, "%s{\"extension\":\"%s\",\"type\":%u}", comma, mem->extension, mem->type); comma = ","; } mg_printf(conn, "]}"); } mg_printf(conn, "]}"); } av_info = video_viewport_get_system_av_info(); mg_printf(conn, "],\"avInfo\":{" "\"geometry\":{" "\"baseWidth\":%u," "\"baseHeight\":%u," "\"maxWidth\":%u," "\"maxHeight\":%u," "\"aspectRatio\":%f" "}," "\"timing\":{" "\"fps\":%f," "\"sampleRate\":%f" "}" "},", av_info->geometry.base_width, av_info->geometry.base_height, av_info->geometry.max_width, av_info->geometry.max_height, av_info->geometry.aspect_ratio, av_info->timing.fps, av_info->timing.sample_rate ); mg_printf(conn, "\"ports\":["); comma = ""; for (p = 0; p < system->ports.size; p++) { ctrl = system->ports.data[p].types; for (q = 0; q < system->ports.data[p].num_types; q++, ctrl++) { mg_printf(conn, "%s{\"id\":%u,\"description\":\"%s\"}", comma, ctrl->id, ctrl->desc); comma = ","; } } mg_printf(conn, "],\"inputDescriptors\":["); comma = ""; if (core_has_set_input_descriptor()) { for (p = 0; p < settings->input.max_users; p++) { for (q = 0; q < RARCH_FIRST_CUSTOM_BIND; q++) { const char* description = system->input_desc_btn[p][q]; if (description) { mg_printf(conn, "%s{\"player\":%u,\"button\":\"%s\",\"description\":\"%s\"}", comma, p + 1, libretro_btn_desc[q], description ); comma = ","; } } } } mg_printf(conn, "],\"coreOptions\":["); rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, (void*)&core_opts); opts = core_opts->opts; for (p = 0; p < core_opts->size; p++, opts++) { mg_printf(conn, "%s{\"key\":\"%s\",\"description\":\"%s\",\"values\":[", p == 0 ? "" : ",", opts->key, opts->desc); comma = ""; for (q = 0; q < opts->vals->size; q++) { mg_printf(conn, "%s\"%s\"", comma, opts->vals->elems[q].data); comma = ","; } mg_printf(conn, "]}"); } mg_printf(conn, "]}"); return 1; }
/* Get the count of the files dropped */ static int win32_drag_query_file(HWND hwnd, WPARAM wparam) { char szFilename[1024] = {0}; if (DragQueryFile((HDROP)wparam, 0xFFFFFFFF, NULL, 0)) { /*poll list of current cores */ size_t list_size; content_ctx_info_t content_info = {0}; core_info_list_t *core_info_list = NULL; const core_info_t *core_info = NULL; DragQueryFile((HDROP)wparam, 0, szFilename, 1024); core_info_get_list(&core_info_list); if (!core_info_list) return 0; core_info_list_get_supported_cores(core_info_list, (const char*)szFilename, &core_info, &list_size); runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH,szFilename); if (!string_is_empty(config_get_active_core_path())) { unsigned i; core_info_t *current_core = NULL; core_info_get_current_core(¤t_core); /*we already have path for libretro core */ for (i = 0; i < list_size; i++) { const core_info_t *info = (const core_info_t*)&core_info[i]; if(!string_is_equal(info->systemname, current_core->systemname)) break; if(string_is_equal(config_get_active_core_path(), info->path)) { /* Our previous core supports the current rom */ content_ctx_info_t content_info = {0}; task_push_content_load_default( NULL, NULL, &content_info, CORE_TYPE_PLAIN, CONTENT_MODE_LOAD_CONTENT_WITH_CURRENT_CORE_FROM_COMPANION_UI, NULL, NULL); return 0; } } } /* Poll for cores for current rom since none exist. */ if(list_size ==1) { /*pick core that only exists and is bound to work. Ish. */ const core_info_t *info = (const core_info_t*)&core_info[0]; if (info) task_push_content_load_default( info->path, NULL, &content_info, CORE_TYPE_PLAIN, CONTENT_MODE_LOAD_CONTENT_WITH_NEW_CORE_FROM_COMPANION_UI, NULL, NULL); } else { /* Pick one core that could be compatible, ew */ if(DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PICKCORE), hwnd,PickCoreProc,(LPARAM)NULL)==IDOK) { task_push_content_load_default( NULL, NULL, &content_info, CORE_TYPE_PLAIN, CONTENT_MODE_LOAD_CONTENT_WITH_CURRENT_CORE_FROM_COMPANION_UI, NULL, NULL); } } } return 0; }