Пример #1
0
/* fix-me: incomplete, lacks error checking */
int action_right_input_desc(unsigned type, const char *label,
   bool wraparound)
{
   rarch_system_info_t *system           = runloop_get_system_info();
   settings_t *settings                  = config_get_ptr();
   unsigned btn_idx, user_idx, remap_idx;

   if (!settings || !system)
      return 0;

   user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
   btn_idx  = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;

   if (settings->uints.input_remap_ids[user_idx][btn_idx] < RARCH_CUSTOM_BIND_LIST_END - 1)
      settings->uints.input_remap_ids[user_idx][btn_idx]++;
   else if (settings->uints.input_remap_ids[user_idx][btn_idx] == RARCH_CUSTOM_BIND_LIST_END - 1)
      settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_UNMAPPED;
   else
      settings->uints.input_remap_ids[user_idx][btn_idx] = 0;

   remap_idx = settings->uints.input_remap_ids[user_idx][btn_idx];

   /* skip the not used buttons (unless they are at the end by calling the right desc function recursively
      also skip all the axes until analog remapping is implemented */
   if (remap_idx != RARCH_UNMAPPED)
   {
      if ((string_is_empty(system->input_desc_btn[user_idx][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END))
         action_right_input_desc(type, label, wraparound);
   }

   return 0;
}
Пример #2
0
/* Sets 's' to the name of the current core 
 * (shown at the top of the UI). */
int menu_entries_get_core_title(char *s, size_t len)
{
   const char *core_name          = NULL;
   const char *core_version       = NULL;
   rarch_system_info_t      *info      = runloop_get_system_info();
   struct retro_system_info    *system = &info->info;

   if (system)
   {
      core_name    = system->library_name;
      core_version = system->library_version;
   }

   if (string_is_empty(core_name) && info)
      core_name = info->info.library_name;
   if (string_is_empty(core_name))
      core_name = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE);

   if (!core_version && info)
      core_version = info->info.library_version;
   if (!core_version)
      core_version = "";

   snprintf(s, len, "%s - %s %s", PACKAGE_VERSION,
         core_name, core_version);

   return 0;
}
Пример #3
0
static void netplay_announce(void)
{
   char buf [2048];
   char url [2048]               = "http://newlobby.libretro.com/add/";
   char *username                = NULL;
   char *corename                = NULL;
   char *gamename                = NULL;
   char *coreversion             = NULL;
   char *frontend_ident          = NULL;
   settings_t *settings          = config_get_ptr();
   rarch_system_info_t *system   = runloop_get_system_info();
   uint32_t content_crc          = content_get_crc();
   char frontend_architecture[PATH_MAX_LENGTH];

   netplay_get_architecture(frontend_architecture, sizeof(frontend_architecture));

   net_http_urlencode(&username, settings->paths.username);
   net_http_urlencode(&corename, system->info.library_name);
   net_http_urlencode(&gamename,
      !string_is_empty(path_basename(path_get(RARCH_PATH_BASENAME))) ?
      path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A");
   net_http_urlencode(&coreversion, system->info.library_version);
   net_http_urlencode(&frontend_ident, frontend_architecture);

   buf[0] = '\0';

   snprintf(buf, sizeof(buf), "username=%s&core_name=%s&core_version=%s&"
      "game_name=%s&game_crc=%08X&port=%d&mitm_server=%s"
      "&has_password=%d&has_spectate_password=%d&force_mitm=%d&retroarch_version=%s&frontend=%s",
      username, corename, coreversion, gamename, content_crc,
      settings->uints.netplay_port,
      settings->arrays.netplay_mitm_server,
      *settings->paths.netplay_password ? 1 : 0,
      *settings->paths.netplay_spectate_password ? 1 : 0,
      settings->bools.netplay_use_mitm_server,
      PACKAGE_VERSION, frontend_architecture);
#if 0
   RARCH_LOG("[netplay] announcement URL: %s\n", buf);
#endif
   task_push_http_post_transfer(url, buf, true, NULL, netplay_announce_cb, NULL);

   if (username)
      free(username);
   if (corename)
      free(corename);
   if (gamename)
      free(gamename);
   if (coreversion)
      free(coreversion);
   if (frontend_ident)
      free(frontend_ident);
}
Пример #4
0
/* Sets 's' to the name of the current core
 * (shown at the top of the UI). */
int menu_entries_get_core_title(char *s, size_t len)
{
   const char *core_name          = NULL;
   const char *core_version       = NULL;
   rarch_system_info_t      *info      = runloop_get_system_info();
   struct retro_system_info    *system = &info->info;
#if _MSC_VER == 1200
   const char *extra_version = " msvc6";
#elif _MSC_VER == 1300
   const char *extra_version = " msvc2002";
#elif _MSC_VER == 1310
   const char *extra_version = " msvc2003";
#elif _MSC_VER == 1400
   const char *extra_version = " msvc2005";
#elif _MSC_VER == 1500
   const char *extra_version = " msvc2008";
#elif _MSC_VER == 1600
   const char *extra_version = " msvc2010";
#elif _MSC_VER == 1700
   const char *extra_version = " msvc2012";
#elif _MSC_VER == 1800
   const char *extra_version = " msvc2013";
#elif _MSC_VER == 1900
   const char *extra_version = " msvc2015";
#elif _MSC_VER >= 1910 && _MSC_VER < 2000
   const char *extra_version = " msvc2017";
#else
   const char *extra_version = "";
#endif

   if (system)
   {
      core_name    = system->library_name;
      core_version = system->library_version;
   }

   if (string_is_empty(core_name) && info)
      core_name = info->info.library_name;
   if (string_is_empty(core_name))
      core_name = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE);

   if (!core_version && info)
      core_version = info->info.library_version;
   if (!core_version)
      core_version = "";

   snprintf(s, len, "%s%s - %s %s", PACKAGE_VERSION, extra_version,
         core_name, core_version);

   return 0;
}
Пример #5
0
static int httpserver_handle_get_mmaps(struct mg_connection* conn, void* cbdata)
{
   unsigned id;
   const struct          mg_request_info* req = mg_get_request_info(conn);
   const                          char* comma = "";
   const struct retro_memory_map* mmaps       = NULL;
   const struct retro_memory_descriptor* mmap = NULL;
   rarch_system_info_t *system                = runloop_get_system_info();

   if (strcmp(req->request_method, "GET"))
      return httpserver_error(conn, 405, "Unimplemented method in %s: %s", __FUNCTION__, req->request_method);

   mmaps = &system->mmaps;
   mmap  = mmaps->descriptors;

   mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n");
   mg_printf(conn, "[");

   for (id = 0; id < mmaps->num_descriptors; id++, mmap++)
   {
      mg_printf(conn,
            "%s{"
            "\"id\":%u,"
            "\"flags\":" STRING_REP_UINT64 ","
            "\"ptr\":\"%" PRIXPTR "\","
            "\"offset\":" STRING_REP_UINT64 ","
            "\"start\":" STRING_REP_UINT64 ","
            "\"select\":" STRING_REP_UINT64 ","
            "\"disconnect\":" STRING_REP_UINT64 ","
            "\"len\":" STRING_REP_UINT64 ","
            "\"addrspace\":\"%s\""
            "}",
            comma,
            id,
            mmap->flags,
            (uintptr_t)mmap->ptr,
            mmap->offset,
            mmap->start,
            mmap->select,
            mmap->disconnect,
            mmap->len,
            mmap->addrspace ? mmap->addrspace : ""
               );

      comma = ",";
   }

   mg_printf(conn, "]");
   return 1;
}
Пример #6
0
static void menu_action_setting_disp_set_label_input_desc(
      file_list_t* list,
      unsigned *w, unsigned type, unsigned i,
      const char *label,
      char *s, size_t len,
      const char *entry_label,
      const char *path,
      char *s2, size_t len2)
{
   rarch_system_info_t *system           = runloop_get_system_info();
   settings_t *settings                  = config_get_ptr();
   const char* descriptor                = NULL;
   char buf[256];

   unsigned btn_idx, user_idx, remap_idx;

   if (!settings)
      return;

   user_idx  = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
   btn_idx   = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
   remap_idx =
      settings->uints.input_remap_ids[user_idx][btn_idx];

   if (!system)
      return;

   if (remap_idx != RARCH_UNMAPPED)
      descriptor = system->input_desc_btn[user_idx][remap_idx];

   if (!string_is_empty(descriptor) && remap_idx < RARCH_FIRST_CUSTOM_BIND)
      strlcpy(s, descriptor, len);
   else if (!string_is_empty(descriptor) && remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx % 2 == 0)
   {
      snprintf(buf, sizeof(buf), "%s %c", descriptor, '+');
      strlcpy(s, buf, len);
   }
   else if (!string_is_empty(descriptor) && remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx % 2 != 0)
   {
      snprintf(buf, sizeof(buf), "%s %c", descriptor, '-');
      strlcpy(s, buf, len);
   }
   else
      strlcpy(s, "---", len);

   *w = 19;
   strlcpy(s2, path, len2);
}
Пример #7
0
int menu_entries_get_core_name(char *s, size_t len)
{
   rarch_system_info_t      *info      = runloop_get_system_info();
   struct retro_system_info    *system = &info->info;
   const char *core_name               = NULL;

   if (system)
      core_name    = system->library_name;

   if (string_is_empty(core_name) && info)
      core_name = info->info.library_name;
   if (string_is_empty(core_name))
      core_name = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE);

   snprintf(s, len, "%s", core_name);

   return 0;
}
Пример #8
0
static void menu_action_setting_disp_set_label_menu_disk_index(
      file_list_t* list,
      unsigned *w, unsigned type, unsigned i,
      const char *label,
      char *s, size_t len,
      const char *entry_label,
      const char *path,
      char *s2, size_t len2)
{
   unsigned images = 0, current                = 0;
   struct retro_disk_control_callback *control = NULL;
   rarch_system_info_t *system                 = runloop_get_system_info();

   if (!system)
      return;

   control = &system->disk_control_cb;

   if (!control)
      return;

   *w = 19;
   *s = '\0';
   strlcpy(s2, path, len2);

   if (!control->get_num_images)
      return;
   if (!control->get_image_index)
      return;

   images  = control->get_num_images();
   current = control->get_image_index();

   if (current >= images)
      strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_DISK), len);
   else
      snprintf(s, len, "%u", current + 1);
}
Пример #9
0
/**
 * netplay_lan_ad_server
 *
 * Respond to any LAN ad queries that the netplay server has received.
 */
bool netplay_lan_ad_server(netplay_t *netplay)
{
   fd_set fds;
   struct timeval tmp_tv = {0};
   struct sockaddr their_addr;
   socklen_t addr_size;
   rarch_system_info_t *info = NULL;

   if (lan_ad_server_fd < 0 && !init_lan_ad_server_socket(netplay, RARCH_DEFAULT_PORT))
       return false;

   /* Check for any ad queries */
   while (1)
   {
      FD_ZERO(&fds);
      FD_SET(lan_ad_server_fd, &fds);
      if (socket_select(lan_ad_server_fd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
         break;
      if (!FD_ISSET(lan_ad_server_fd, &fds))
         break;

      /* Somebody queried, so check that it's valid */
      addr_size = sizeof(their_addr);

      if (recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer,
            sizeof(struct ad_packet), 0, &their_addr, &addr_size) >=
            (ssize_t) (2*sizeof(uint32_t)))
      {
         char s[NETPLAY_HOST_STR_LEN];
         uint32_t content_crc         = 0;

         /* Make sure it's a valid query */
         if (memcmp((void *) &ad_packet_buffer, "RANQ", 4))
            continue;

         /* For this version */
         if (ntohl(ad_packet_buffer.protocol_version) !=
               NETPLAY_PROTOCOL_VERSION)
            continue;

         info              = runloop_get_system_info();

         /* Now build our response */
         content_crc = content_get_crc();

         memset(&ad_packet_buffer, 0, sizeof(struct ad_packet));
         memcpy(&ad_packet_buffer, "RANS", 4);

         ad_packet_buffer.protocol_version =
            htonl(NETPLAY_PROTOCOL_VERSION);
         ad_packet_buffer.port = htonl(netplay->tcp_port);
         strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION,
            NETPLAY_HOST_STR_LEN);
         strlcpy(ad_packet_buffer.content, !string_is_empty(
                  path_basename(path_get(RARCH_PATH_BASENAME))) 
               ? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A",
               NETPLAY_HOST_LONGSTR_LEN);
         strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN);

         if (info)
         {
            strlcpy(ad_packet_buffer.core, info->info.library_name,
               NETPLAY_HOST_STR_LEN);
            strlcpy(ad_packet_buffer.core_version, info->info.library_version,
               NETPLAY_HOST_STR_LEN);
         }

         snprintf(s, sizeof(s), "%d", content_crc);
         strlcpy(ad_packet_buffer.content_crc, s,
            NETPLAY_HOST_STR_LEN);

         /* And send it */
         sendto(lan_ad_server_fd, (const char*)&ad_packet_buffer,
            sizeof(struct ad_packet), 0, &their_addr, addr_size);
      }
   }

   return true;
}
Пример #10
0
static int httpserver_handle_get_mmap(struct mg_connection* conn, void* cbdata)
{
   size_t start, length;
   unsigned id;
   uLong buflen;
   const struct mg_request_info         * req = mg_get_request_info(conn);
   const char                         * comma = "";
   const struct retro_memory_map* mmaps       = NULL;
   const struct retro_memory_descriptor* mmap = NULL;
   const char* param                          = NULL;
   Bytef* buffer                              = NULL;
   rarch_system_info_t *system                = runloop_get_system_info();

   if (strcmp(req->request_method, "GET"))
      return httpserver_error(conn, 405, "Unimplemented method in %s: %s", __FUNCTION__, req->request_method);

   if (sscanf(req->request_uri, "/" MEMORY_MAP "/%u", &id) != 1)
      return httpserver_error(conn, 500, "Malformed request in %s: %s", __FUNCTION__, req->request_uri);

   mmaps = &system->mmaps;

   if (id >= mmaps->num_descriptors)
      return httpserver_error(conn, 404, "Invalid memory map id in %s: %u", __FUNCTION__, id);

   mmap   = mmaps->descriptors + id;
   start  = 0;
   length = mmap->len;

   if (req->query_string != NULL)
   {
      param = strstr(req->query_string, "start=");

      if (param != NULL)
         start = atoll(param + 6);

      param = strstr(req->query_string, "length=");

      if (param != NULL)
         length = atoll(param + 7);
   }

   if (start >= mmap->len)
      start = mmap->len - 1;

   if (length > mmap->len - start)
      length = mmap->len - start;

   buflen = compressBound(length);
   buffer = (Bytef*)malloc(((buflen + 3) / 4) * 5);

   if (buffer == NULL)
      return httpserver_error(conn, 500, "Out of memory in %s", __FUNCTION__);

   if (compress2(buffer, &buflen, (Bytef*)mmap->ptr + start, length, Z_BEST_COMPRESSION) != Z_OK)
   {
      free((void*)buffer);
      return httpserver_error(conn, 500, "Error during compression in %s", __FUNCTION__);
   }

   buffer[buflen] = 0;
   buffer[buflen + 1] = 0;
   buffer[buflen + 2] = 0;
   httpserver_z85_encode_inplace(buffer, (buflen + 3) & ~3);

   mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n");
   mg_printf(conn,
         "{"
         "\"start\":" STRING_REP_ULONG ","
         "\"length\":" STRING_REP_ULONG ","
         "\"compression\":\"deflate\","
         "\"compressedLength\":" STRING_REP_ULONG ","
         "\"encoding\":\"Z85\","
         "\"data\":\"%s\""
         "}",
         start,
         length,
         (size_t)buflen,
         (char*)buffer
         );

   free((void*)buffer);
   return 1;
}
Пример #11
0
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(&region);

   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;
}
Пример #12
0
int setting_action_left_libretro_device_type(
      void *data, bool wraparound)
{
   retro_ctx_controller_info_t pad;
   unsigned current_device, current_idx, i, devices[128],
            types = 0, port = 0;
   const struct retro_controller_info *desc = NULL;
   rarch_setting_t *setting    = (rarch_setting_t*)data;
   rarch_system_info_t *system = NULL;

   if (!setting)
      return -1;

   port = setting->index_offset;

   devices[types++] = RETRO_DEVICE_NONE;
   devices[types++] = RETRO_DEVICE_JOYPAD;

   system           = runloop_get_system_info();

   if (system)
   {
      /* Only push RETRO_DEVICE_ANALOG as default if we use an
       * older core which doesn't use SET_CONTROLLER_INFO. */
      if (!system->ports.size)
         devices[types++] = RETRO_DEVICE_ANALOG;

      if (port < system->ports.size)
         desc = &system->ports.data[port];
   }

   if (desc)
   {
      for (i = 0; i < desc->num_types; i++)
      {
         unsigned id = desc->types[i].id;
         if (types < ARRAY_SIZE(devices) &&
               id != RETRO_DEVICE_NONE &&
               id != RETRO_DEVICE_JOYPAD)
            devices[types++] = id;
      }
   }

   current_device = input_config_get_device(port);
   current_idx    = 0;
   for (i = 0; i < types; i++)
   {
      if (current_device != devices[i])
         continue;

      current_idx = i;
      break;
   }

   current_device = devices
      [(current_idx + types - 1) % types];

   input_config_set_device(port, current_device);

   pad.port   = port;
   pad.device = current_device;

   core_set_controller_port_device(&pad);

   return 0;
}