Ejemplo n.º 1
0
/**
 * netplay_impl_magic:
 *
 * Not really a hash, but should be enough to differentiate 
 * implementations from each other.
 *
 * Subtle differences in the implementation will not be possible to spot.
 * The alternative would have been checking serialization sizes, but it 
 * was troublesome for cross platform compat.
 **/
uint32_t netplay_impl_magic(void)
{
   size_t i, len;
   retro_ctx_api_info_t api_info;
   unsigned api;
   uint32_t res                        = 0;
   rarch_system_info_t *info           = NULL;
   const char *lib                     = NULL;
   const char *ver                     = PACKAGE_VERSION;

   core_api_version(&api_info);

   api                                 = api_info.version;

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info);

   res |= api;

   if (info)
   {
      lib = info->info.library_name;

      len = strlen(lib);
      for (i = 0; i < len; i++)
         res ^= lib[i] << (i & 0xf);

      lib = info->info.library_version;
      len = strlen(lib);

      for (i = 0; i < len; i++)
         res ^= lib[i] << (i & 0xf);
   }

   len = strlen(ver);
   for (i = 0; i < len; i++)
      res ^= ver[i] << ((i & 0xf) + 16);

   res ^= NETPLAY_PROTOCOL_VERSION << 24;

   return res;
}
Ejemplo n.º 2
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;
}