Esempio n. 1
0
static bool gfx_ctx_init(void)
{
   struct android_app *android_app = (struct android_app*)g_android;
   const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_NONE
   };
   EGLint num_config;
   EGLint egl_version_major, egl_version_minor;
   EGLint format;

   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };

   RARCH_LOG("Initializing context\n");

   if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
   {
      RARCH_ERR("eglGetDisplay failed.\n");
      goto error;
   }

   if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor))
   {
      RARCH_ERR("eglInitialize failed.\n");
      goto error;
   }

   RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor);

   if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &num_config))
   {
      RARCH_ERR("eglChooseConfig failed.\n");
      goto error;
   }

   int var = eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &format);

   if (!var)
   {
      RARCH_ERR("eglGetConfigAttrib failed: %d.\n", var);
      goto error;
   }

   ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format);

   if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, android_app->window, 0)))
   {
      RARCH_ERR("eglCreateWindowSurface failed.\n");
      goto error;
   }

   if (!(g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, 0, context_attributes)))
   {
      RARCH_ERR("eglCreateContext failed.\n");
      goto error;
   }

   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
   {
      RARCH_ERR("eglMakeCurrent failed.\n");
      goto error;
   }

   ALooper *looper = ALooper_forThread();
   if (!looper)
      ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);

   return true;

error:
   RARCH_ERR("EGL error: %d.\n", eglGetError());
   gfx_ctx_destroy();
   return false;
}
Esempio n. 2
0
static void *gdi_gfx_init(const video_info_t *video,
      const input_driver_t **input, void **input_data)
{
   unsigned full_x, full_y;
   gfx_ctx_input_t inp;
   gfx_ctx_mode_t mode;
   const gfx_ctx_driver_t *ctx_driver   = NULL;
   unsigned win_width = 0, win_height   = 0;
   unsigned temp_width = 0, temp_height = 0;
   settings_t *settings                 = config_get_ptr();
   gdi_t *gdi                           = (gdi_t*)calloc(1, sizeof(*gdi));

   *input                               = NULL;
   *input_data                          = NULL;

   gdi_video_width                      = video->width;
   gdi_video_height                     = video->height;
   gdi_rgb32                            = video->rgb32;

   gdi_video_bits                       = video->rgb32 ? 32 : 16;

   if (video->rgb32)
      gdi_video_pitch = video->width * 4;
   else
      gdi_video_pitch = video->width * 2;

   gdi_gfx_create();

   ctx_driver = video_context_driver_init_first(gdi,
         settings->video.context_driver,
         GFX_CTX_GDI_API, 1, 0, false);
   if (!ctx_driver)
      goto error;

   video_context_driver_set((const gfx_ctx_driver_t*)ctx_driver);

   RARCH_LOG("Found GDI context: %s\n", ctx_driver->ident);

   video_context_driver_get_video_size(&mode);

   full_x      = mode.width;
   full_y      = mode.height;
   mode.width  = 0;
   mode.height = 0;

   RARCH_LOG("Detecting screen resolution %ux%u.\n", full_x, full_y);

   win_width   = video->width;
   win_height  = video->height;

   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      win_width  = full_x;
      win_height = full_y;
   }

   mode.width      = win_width;
   mode.height     = win_height;
   mode.fullscreen = video->fullscreen;

   if (!video_context_driver_set_video_mode(&mode))
      goto error;

   mode.width     = 0;
   mode.height    = 0;

   video_context_driver_get_video_size(&mode);

   temp_width     = mode.width;
   temp_height    = mode.height;
   mode.width     = 0;
   mode.height    = 0;

   /* Get real known video size, which might have been altered by context. */

   if (temp_width != 0 && temp_height != 0)
      video_driver_set_size(&temp_width, &temp_height);

   video_driver_get_size(&temp_width, &temp_height);

   RARCH_LOG("GDI: Using resolution %ux%u\n", temp_width, temp_height);

   inp.input      = input;
   inp.input_data = input_data;

   video_context_driver_input_driver(&inp);

   if (settings->video.font_enable)
      font_driver_init_osd(NULL, false, FONT_DRIVER_RENDER_GDI);

   RARCH_LOG("[GDI]: Init complete.\n");

   return gdi;

error:
   video_context_driver_destroy();
   if (gdi)
      free(gdi);
   return NULL;
}
Esempio n. 3
0
/**
 * recording_init:
 *
 * Initializes recording.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool recording_init(void)
{
   char recording_file[PATH_MAX_LENGTH] = {0};
   struct ffemu_params params           = {0};
   global_t *global                     = global_get_ptr();
   driver_t *driver                     = driver_get_ptr();
   settings_t *settings                 = config_get_ptr();
   struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
   const struct retro_hw_render_callback *hw_render = 
      (const struct retro_hw_render_callback*)video_driver_callback();
   bool *recording_enabled              = recording_is_enabled();

   if (!*recording_enabled)
      return false;

   if (global->inited.core.type == CORE_TYPE_DUMMY)
   {
      RARCH_WARN("%s\n", msg_hash_to_str(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED));
      return false;
   }

   if (!settings->video.gpu_record && hw_render->context_type)
   {
      RARCH_WARN("%s.\n", msg_hash_to_str(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING));
      return false;
   }

   RARCH_LOG("%s: FPS: %.4f, Sample rate: %.4f\n",
         msg_hash_to_str(MSG_CUSTOM_TIMING_GIVEN),
         (float)av_info->timing.fps,
         (float)av_info->timing.sample_rate);

   strlcpy(recording_file, global->record.path, sizeof(recording_file));

   if (global->record.use_output_dir)
      fill_pathname_join(recording_file,
            global->record.output_dir,
            global->record.path, sizeof(recording_file));

   params.out_width  = av_info->geometry.base_width;
   params.out_height = av_info->geometry.base_height;
   params.fb_width   = av_info->geometry.max_width;
   params.fb_height  = av_info->geometry.max_height;
   params.channels   = 2;
   params.filename   = recording_file;
   params.fps        = av_info->timing.fps;
   params.samplerate = av_info->timing.sample_rate;
   params.pix_fmt    = (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_XRGB8888) ?
      FFEMU_PIX_ARGB8888 : FFEMU_PIX_RGB565;
   params.config     = NULL;
   
   if (*global->record.config)
      params.config = global->record.config;

   if (settings->video.gpu_record && driver->video->read_viewport)
   {
      struct video_viewport vp = {0};

      video_driver_viewport_info(&vp);

      if (!vp.width || !vp.height)
      {
         RARCH_ERR("Failed to get viewport information from video driver. "
               "Cannot start recording ...\n");
         return false;
      }

      params.out_width  = vp.width;
      params.out_height = vp.height;
      params.fb_width   = next_pow2(vp.width);
      params.fb_height  = next_pow2(vp.height);

      if (settings->video.force_aspect &&
            (video_driver_get_aspect_ratio() > 0.0f))
         params.aspect_ratio  = video_driver_get_aspect_ratio();
      else
         params.aspect_ratio  = (float)vp.width / vp.height;

      params.pix_fmt             = FFEMU_PIX_BGR24;
      global->record.gpu_width   = vp.width;
      global->record.gpu_height  = vp.height;

      RARCH_LOG("%s %u x %u\n", msg_hash_to_str(MSG_DETECTED_VIEWPORT_OF),
            vp.width, vp.height);

      global->record.gpu_buffer = (uint8_t*)malloc(vp.width * vp.height * 3);
      if (!global->record.gpu_buffer)
         return false;
   }
   else
   {
      if (global->record.width || global->record.height)
      {
         params.out_width  = global->record.width;
         params.out_height = global->record.height;
      }

      if (settings->video.force_aspect &&
            (video_driver_get_aspect_ratio() > 0.0f))
         params.aspect_ratio = video_driver_get_aspect_ratio();
      else
         params.aspect_ratio = (float)params.out_width / params.out_height;

      if (settings->video.post_filter_record && video_driver_frame_filter_alive())
      {
         unsigned max_width  = 0;
         unsigned max_height = 0;

         if (video_driver_frame_filter_is_32bit())
            params.pix_fmt = FFEMU_PIX_ARGB8888;
         else
            params.pix_fmt =  FFEMU_PIX_RGB565;

         rarch_softfilter_get_max_output_size(
               video_driver_frame_filter_get_ptr(),
               &max_width, &max_height);
         params.fb_width  = next_pow2(max_width);
         params.fb_height = next_pow2(max_height);
      }
   }

   RARCH_LOG("%s %s @ %ux%u. (FB size: %ux%u pix_fmt: %u)\n",
         msg_hash_to_str(MSG_RECORDING_TO),
         global->record.path,
         params.out_width, params.out_height,
         params.fb_width, params.fb_height,
         (unsigned)params.pix_fmt);

   if (!record_driver_init_first(&driver->recording, &driver->recording_data, &params))
   {
      RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_START_RECORDING));
      event_command(EVENT_CMD_GPU_RECORD_DEINIT);

      return false;
   }

   return true;
}
Esempio n. 4
0
static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size)
{
   LIBXML_TEST_VERSION;

   xmlParserCtxtPtr ctx = xmlNewParserCtxt();
   if (!ctx)
   {
      RARCH_ERR("Failed to load libxml2 context.\n");
      return false;
   }

   RARCH_LOG("Loading XML shader: %s\n", path);
   xmlDocPtr doc = xmlCtxtReadFile(ctx, path, NULL, 0);
   xmlNodePtr head = NULL;
   xmlNodePtr cur = NULL;
   unsigned num = 0;

   if (!doc)
   {
      RARCH_ERR("Failed to parse XML file: %s\n", path);
      goto error;
   }

   if (ctx->valid == 0)
   {
      RARCH_ERR("Cannot validate XML shader: %s\n", path);
      goto error;
   }

   head = xmlDocGetRootElement(doc);

   for (cur = head; cur; cur = cur->next)
   {
      if (cur->type != XML_ELEMENT_NODE)
         continue;
      if (strcmp((const char*)cur->name, "shader") != 0)
         continue;

      char attr[64];
      xml_get_prop(attr, sizeof(attr), cur, "language");
      if (strcmp(attr, "GLSL") != 0)
         continue;

      xml_get_prop(attr, sizeof(attr), cur, "style");
      glsl_modern = strcmp(attr, "GLES2") == 0;

      if (glsl_modern)
         RARCH_LOG("[GL]: Shader reports a GLES2 style shader.\n");
      break;
   }

   if (!cur) // We couldn't find any GLSL shader :(
      goto error;

   memset(prog, 0, sizeof(struct shader_program) * size);

   // Iterate to check if we find fragment and/or vertex shaders.
   for (cur = cur->children; cur && num < size; cur = cur->next)
   {
      if (cur->type != XML_ELEMENT_NODE)
         continue;

      char *content = xml_get_content(cur);
      if (!content)
         continue;

      if (strcmp((const char*)cur->name, "vertex") == 0)
      {
         if (prog[num].vertex)
         {
            RARCH_ERR("Cannot have more than one vertex shader in a program.\n");
            free(content);
            goto error;
         }

         content = xml_replace_if_file(content, path, cur, "src");
         if (!content)
         {
            RARCH_ERR("Shader source file was provided, but failed to read.\n");
            goto error;
         }

         prog[num].vertex = content;
      }
      else if (strcmp((const char*)cur->name, "fragment") == 0)
      {
         if (glsl_modern && !prog[num].vertex)
         {
            RARCH_ERR("Modern GLSL was chosen and vertex shader was not provided. This is an error.\n");
            free(content);
            goto error;
         }

         content = xml_replace_if_file(content, path, cur, "src");
         if (!content)
         {
            RARCH_ERR("Shader source file was provided, but failed to read.\n");
            goto error;
         }

         prog[num].fragment = content;
         if (!get_xml_attrs(&prog[num], cur))
         {
            RARCH_ERR("XML shader attributes do not comply with specifications.\n");
            goto error;
         }
         num++;
      }
      else if (strcmp((const char*)cur->name, "texture") == 0)
      {
         free(content);
         if (!get_texture_image(path, cur))
         {
            RARCH_ERR("Texture image failed to load.\n");
            goto error;
         }
      }
      else if (strcmp((const char*)cur->name, "import") == 0)
      {
         free(content);
         if (!get_import_value(cur))
         {
            RARCH_ERR("Import value is invalid.\n");
            goto error;
         }
      }
#ifdef HAVE_PYTHON
      else if (strcmp((const char*)cur->name, "script") == 0)
      {
         free(content);
         if (!get_script(path, cur))
         {
            RARCH_ERR("Script is invalid.\n");
            goto error;
         }
      }
#endif
   }

   if (num == 0)
   {
      RARCH_ERR("Couldn't find vertex shader nor fragment shader in XML file.\n");
      goto error;
   }

   xmlFreeDoc(doc);
   xmlFreeParserCtxt(ctx);
   return num;

error:
   RARCH_ERR("Failed to load XML shader ...\n");
   if (doc)
      xmlFreeDoc(doc);
   xmlFreeParserCtxt(ctx);
   return 0;
}
Esempio n. 5
0
static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
   HRESULT ret;

   if (driver.video_data)
   {
      xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data;
      // Reinitialize textures as we might have changed pixel formats.
      xdk_d3d_reinit_textures(d3d, video);
      return driver.video_data;
   }

   //we'll just use driver.video_data throughout here because it needs to
   //exist when we delegate initing to the context file
   driver.video_data = (xdk_d3d_video_t*)calloc(1, sizeof(xdk_d3d_video_t));
   if (!driver.video_data)
      return NULL;

   xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data;

   d3d->vsync = video->vsync;
   d3d->tex_w = RARCH_SCALE_BASE * video->input_scale;
   d3d->tex_h = RARCH_SCALE_BASE * video->input_scale;

#if defined(_XBOX1)
   d3d->ctx_driver = gfx_ctx_init_first(GFX_CTX_DIRECT3D8_API, 8, 0);
#elif defined(_XBOX360)
   d3d->ctx_driver = gfx_ctx_init_first(GFX_CTX_DIRECT3D9_API, 9, 0);
#endif
   if (d3d->ctx_driver)
   {
      D3DPRESENT_PARAMETERS d3dpp;
      xdk_d3d_generate_pp(&d3dpp, video);

      ret = d3d->d3d_device->CreateDevice(0, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING,
            &d3dpp, &d3d->d3d_render_device);

      if (ret != S_OK)
         RARCH_ERR("Failed at CreateDevice.\n");
      RD3DDevice_Clear(d3d->d3d_render_device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
   }
   else
   {
      free(d3d);
      return NULL;
   }

   RARCH_LOG("Found D3D context: %s\n", d3d->ctx_driver->ident);

   xdk_d3d_init_textures(d3d, video);

#if defined(_XBOX1)
   // use an orthogonal matrix for the projection matrix
   D3DXMATRIX mat;
   D3DXMatrixOrthoOffCenterLH(&mat, 0,  d3d->win_width ,  d3d->win_height , 0, 0.0f, 1.0f);

   d3d->d3d_render_device->SetTransform(D3DTS_PROJECTION, &mat);

   // use an identity matrix for the world and view matrices
   D3DXMatrixIdentity(&mat);
   d3d->d3d_render_device->SetTransform(D3DTS_WORLD, &mat);
   d3d->d3d_render_device->SetTransform(D3DTS_VIEW, &mat);

   ret = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), 
         D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &d3d->vertex_buf);

   if (ret != S_OK)
   {
      RARCH_ERR("[xdk_d3d_init::] Failed at CreateVertexBuffer.\n");
      return NULL;
   }

   const DrawVerticeFormats init_verts[] = {
      { -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
      {  1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
      { -1.0f,  1.0f, 1.0f, 0.0f, 0.0f },
      {  1.0f,  1.0f, 1.0f, 1.0f, 0.0f },
   };

   BYTE *verts_ptr;
   RD3DVertexBuffer_Lock(d3d->vertex_buf, 0, 0, &verts_ptr, 0);
   memcpy(verts_ptr, init_verts, sizeof(init_verts));
   RD3DVertexBuffer_Unlock(d3d->vertex_buf);

   RD3DDevice_SetVertexShader(d3d->d3d_render_device, D3DFVF_XYZ | D3DFVF_TEX1);
#elif defined(_XBOX360)
   ret = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), 
         0, 0, 0, &d3d->vertex_buf, NULL);

   if (ret != S_OK)
   {
      RARCH_ERR("[xdk_d3d_init::] Failed at CreateVertexBuffer.\n");
      return NULL;
   }

   static const DrawVerticeFormats init_verts[] = {
      { -1.0f, -1.0f, 0.0f, 1.0f },
      {  1.0f, -1.0f, 1.0f, 1.0f },
      { -1.0f,  1.0f, 0.0f, 0.0f },
      {  1.0f,  1.0f, 1.0f, 0.0f },
   };

   void *verts_ptr;
   RD3DVertexBuffer_Lock(d3d->vertex_buf, 0, 0, &verts_ptr, 0);
   memcpy(verts_ptr, init_verts, sizeof(init_verts));
   RD3DVertexBuffer_Unlock(d3d->vertex_buf);

   static const D3DVERTEXELEMENT VertexElements[] =
   {
      { 0, 0 * sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
      { 0, 2 * sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
      D3DDECL_END()
   };

   ret = d3d->d3d_render_device->CreateVertexDeclaration(VertexElements, &d3d->v_decl);

   if (ret != S_OK)
   {
      RARCH_ERR("[xdk_d3d_init::] Failed at CreateVertexDeclaration.\n");
   }
#endif

   d3d->ctx_driver->get_video_size(&d3d->win_width, &d3d->win_height);
   RARCH_LOG("Detecting screen resolution: %ux%u.\n", d3d->win_width, d3d->win_height);

   d3d->ctx_driver->swap_interval(d3d->vsync ? 1 : 0);

#ifdef HAVE_HLSL
   if (!hlsl_shader_init())
   {
      RARCH_ERR("Shader init failed.\n");
      d3d->ctx_driver->destroy();
      free(d3d);
      return NULL;
   }

   RARCH_LOG("D3D: Loaded %u program(s).\n", d3d->shader->num_shaders());
#endif

#if 0 /* ifdef HAVE_FBO */
   xdk_d3d_init_fbo(d3d);
#endif

   xdk_d3d_set_rotation(d3d, g_extern.console.screen.orientation);

   //really returns driver.video_data to driver.video_data - see comment above
   return d3d;
}
Esempio n. 6
0
static bool environment_cb(unsigned cmd, void *data)
{
   switch (cmd)
   {
      case RETRO_ENVIRONMENT_GET_OVERSCAN:
         *(bool*)data = !g_settings.video.crop_overscan;
         RARCH_LOG("Environ GET_OVERSCAN: %u\n", (unsigned)!g_settings.video.crop_overscan);
         break;

      case RETRO_ENVIRONMENT_GET_CAN_DUPE:
         *(bool*)data = true;
         RARCH_LOG("Environ GET_CAN_DUPE: true\n");
         break;

      case RETRO_ENVIRONMENT_GET_VARIABLE:
      {
         struct retro_variable *var = (struct retro_variable*)data;
         RARCH_LOG("Environ GET_VARIABLE %s:\n", var->key);

         if (g_extern.system.core_options)
            core_option_get(g_extern.system.core_options, var);
         else
            var->value = NULL;

         RARCH_LOG("\t%s\n", var->value ? var->value : "N/A");
         break;
      }

      case RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE:
         *(bool*)data = g_extern.system.core_options ?
            core_option_updated(g_extern.system.core_options) : false;
         break;

      case RETRO_ENVIRONMENT_SET_VARIABLES:
      {
         RARCH_LOG("Environ SET_VARIABLES.\n");

         if (g_extern.system.core_options)
         {
            core_option_flush(g_extern.system.core_options);
            core_option_free(g_extern.system.core_options);
         }

         const struct retro_variable *vars = (const struct retro_variable*)data;

         const char *options_path = g_settings.core_options_path;
         char buf[PATH_MAX];
         if (!*options_path && *g_extern.config_path)
         {
            fill_pathname_resolve_relative(buf, g_extern.config_path, ".retroarch-core-options.cfg", sizeof(buf));
            options_path = buf;
         }
         g_extern.system.core_options = core_option_new(options_path, vars);

         break;
      }

      case RETRO_ENVIRONMENT_SET_MESSAGE:
      {
         const struct retro_message *msg = (const struct retro_message*)data;
         RARCH_LOG("Environ SET_MESSAGE: %s\n", msg->msg);
         if (g_extern.msg_queue)
            msg_queue_push(g_extern.msg_queue, msg->msg, 1, msg->frames);
         break;
      }

      case RETRO_ENVIRONMENT_SET_ROTATION:
      {
         unsigned rotation = *(const unsigned*)data;
         RARCH_LOG("Environ SET_ROTATION: %u\n", rotation);
         if (!g_settings.video.allow_rotate)
            break;

         g_extern.system.rotation = rotation;

         if (driver.video && driver.video->set_rotation)
         {
            if (driver.video_data)
               video_set_rotation_func(rotation);
         }
         else
            return false;
         break;
      }

      case RETRO_ENVIRONMENT_SHUTDOWN:
         RARCH_LOG("Environ SHUTDOWN.\n");
         g_extern.system.shutdown = true;
         break;

      case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
         g_extern.system.performance_level = *(const unsigned*)data;
         RARCH_LOG("Environ PERFORMANCE_LEVEL: %u.\n", g_extern.system.performance_level);
         break;

      case RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY:
         *(const char **)data = *g_settings.system_directory ? g_settings.system_directory : NULL;
         RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n", g_settings.system_directory);
         break;

      case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT:
      {
         enum retro_pixel_format pix_fmt = *(const enum retro_pixel_format*)data;
         switch (pix_fmt)
         {
            case RETRO_PIXEL_FORMAT_0RGB1555:
               RARCH_LOG("Environ SET_PIXEL_FORMAT: 0RGB1555.\n");
               break;

            case RETRO_PIXEL_FORMAT_RGB565:
               RARCH_LOG("Environ SET_PIXEL_FORMAT: RGB565.\n");
               break;
            case RETRO_PIXEL_FORMAT_XRGB8888:
               RARCH_LOG("Environ SET_PIXEL_FORMAT: XRGB8888.\n");
               break;
            default:
               return false;
         }
         
         g_extern.system.pix_fmt = pix_fmt;
         break;
      }

      case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS:
      {
         memset(g_extern.system.input_desc_btn, 0, sizeof(g_extern.system.input_desc_btn));

         const struct retro_input_descriptor *desc = (const struct retro_input_descriptor*)data;
         for (; desc->description; desc++)
         {
            if (desc->port >= MAX_PLAYERS)
               continue;

            if (desc->device != RETRO_DEVICE_JOYPAD) // Ignore all others for now.
               continue;

            if (desc->id >= RARCH_FIRST_CUSTOM_BIND)
               continue;

            g_extern.system.input_desc_btn[desc->port][desc->id] = desc->description;
         }

         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",
         };

         RARCH_LOG("Environ SET_INPUT_DESCRIPTORS:\n");
         for (unsigned p = 0; p < MAX_PLAYERS; p++)
         {
            for (unsigned id = 0; id < RARCH_FIRST_CUSTOM_BIND; id++)
            {
               const char *desc = g_extern.system.input_desc_btn[p][id];
               if (desc)
               {
                  RARCH_LOG("\tRetroPad, Player %u, Button \"%s\" => \"%s\"\n",
                        p + 1, libretro_btn_desc[id], desc);
               }
            }
         }

         break;
      }
      
      case RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK:
      {
         RARCH_LOG("Environ SET_KEYBOARD_CALLBACK.\n");
         const struct retro_keyboard_callback *info = (const struct retro_keyboard_callback*)data;
         g_extern.system.key_event = info->callback;
         break;
      }

      case RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE:
         RARCH_LOG("Environ SET_DISK_CONTROL_INTERFACE.\n");
         g_extern.system.disk_control = *(const struct retro_disk_control_callback*)data;
         break;

      case RETRO_ENVIRONMENT_SET_HW_RENDER:
      {
         RARCH_LOG("Environ SET_HW_RENDER.\n");
         struct retro_hw_render_callback *cb = (struct retro_hw_render_callback*)data;
         switch (cb->context_type)
         {
            case RETRO_HW_CONTEXT_NONE:
               RARCH_LOG("Requesting no HW context.\n");
               break;

#if defined(HAVE_OPENGLES2)
            case RETRO_HW_CONTEXT_OPENGLES2:
               RARCH_LOG("Requesting OpenGLES2 context.\n");
               driver.video = &video_gl;
               break;

            case RETRO_HW_CONTEXT_OPENGL:
               RARCH_ERR("Requesting OpenGL context, but RetroArch is compiled against OpenGLES2. Cannot use HW context.\n");
               return false;
#elif defined(HAVE_OPENGL)
            case RETRO_HW_CONTEXT_OPENGLES2:
               RARCH_ERR("Requesting OpenGLES2 context, but RetroArch is compiled against OpenGL. Cannot use HW context.\n");
               return false;

            case RETRO_HW_CONTEXT_OPENGL:
               RARCH_LOG("Requesting OpenGL context.\n");
               driver.video = &video_gl;
               break;
#endif

            default:
               RARCH_LOG("Requesting unknown context.\n");
               return false;
         }
         cb->get_current_framebuffer = driver_get_current_framebuffer;
         cb->get_proc_address = driver_get_proc_address;
         memcpy(&g_extern.system.hw_render_callback, cb, sizeof(*cb));
         break;
      }

      case RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME:
      {
         bool state = *(const bool*)data;
         RARCH_LOG("Environ SET_SUPPORT_NO_GAME: %s.\n", state ? "yes" : "no");
         g_extern.system.no_game = state;
         break;
      }

      default:
         RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
         return false;
   }

   return true;
}
Esempio n. 7
0
static bool get_xml_attrs(struct shader_program *prog, xmlNodePtr ptr)
{
   prog->scale_x = 1.0;
   prog->scale_y = 1.0;
   prog->type_x = prog->type_y = RARCH_SCALE_INPUT;
   prog->valid_scale = false;

   // Check if shader forces a certain texture filtering.
   char attr[64];
   if (xml_get_prop(attr, sizeof(attr), ptr, "filter"))
   {
      if (strcmp(attr, "nearest") == 0)
      {
         prog->filter = RARCH_GL_NEAREST;
         RARCH_LOG("XML: Shader forces GL_NEAREST.\n");
      }
      else if (strcmp(attr, "linear") == 0)
      {
         prog->filter = RARCH_GL_LINEAR;
         RARCH_LOG("XML: Shader forces GL_LINEAR.\n");
      }
      else
         RARCH_WARN("XML: Invalid property for filter.\n");
   }
   else
      prog->filter = RARCH_GL_NOFORCE;

   // Check for scaling attributes *lots of code <_<*
   char attr_scale[64], attr_scale_x[64], attr_scale_y[64];
   char attr_size[64], attr_size_x[64], attr_size_y[64];
   char attr_outscale[64], attr_outscale_x[64], attr_outscale_y[64];

   xml_get_prop(attr_scale, sizeof(attr_scale), ptr, "scale");
   xml_get_prop(attr_scale_x, sizeof(attr_scale_x), ptr, "scale_x");
   xml_get_prop(attr_scale_y, sizeof(attr_scale_y), ptr, "scale_y");
   xml_get_prop(attr_size, sizeof(attr_size), ptr, "size");
   xml_get_prop(attr_size_x, sizeof(attr_size_x), ptr, "size_x");
   xml_get_prop(attr_size_y, sizeof(attr_size_y), ptr, "size_y");
   xml_get_prop(attr_outscale, sizeof(attr_outscale), ptr, "outscale");
   xml_get_prop(attr_outscale_x, sizeof(attr_outscale_x), ptr, "outscale_x");
   xml_get_prop(attr_outscale_y, sizeof(attr_outscale_y), ptr, "outscale_y");

   unsigned x_attr_cnt = 0, y_attr_cnt = 0;

   if (*attr_scale)
   {
      float scale = strtod(attr_scale, NULL);
      prog->scale_x = scale;
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_x = prog->type_y = RARCH_SCALE_INPUT;
      RARCH_LOG("Got scale attr: %.1f\n", scale);
      x_attr_cnt++;
      y_attr_cnt++;
   }

   if (*attr_scale_x)
   {
      float scale = strtod(attr_scale_x, NULL);
      prog->scale_x = scale;
      prog->valid_scale = true;
      prog->type_x = RARCH_SCALE_INPUT;
      RARCH_LOG("Got scale_x attr: %.1f\n", scale);
      x_attr_cnt++;
   }

   if (*attr_scale_y)
   {
      float scale = strtod(attr_scale_y, NULL);
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_y = RARCH_SCALE_INPUT;
      RARCH_LOG("Got scale_y attr: %.1f\n", scale);
      y_attr_cnt++;
   }
   
   if (*attr_size)
   {
      prog->abs_x = prog->abs_y = strtoul(attr_size, NULL, 0);
      prog->valid_scale = true;
      prog->type_x = prog->type_y = RARCH_SCALE_ABSOLUTE;
      RARCH_LOG("Got size attr: %u\n", prog->abs_x);
      x_attr_cnt++;
      y_attr_cnt++;
   }

   if (*attr_size_x)
   {
      prog->abs_x = strtoul(attr_size_x, NULL, 0);
      prog->valid_scale = true;
      prog->type_x = RARCH_SCALE_ABSOLUTE;
      RARCH_LOG("Got size_x attr: %u\n", prog->abs_x);
      x_attr_cnt++;
   }

   if (*attr_size_y)
   {
      prog->abs_y = strtoul(attr_size_y, NULL, 0);
      prog->valid_scale = true;
      prog->type_y = RARCH_SCALE_ABSOLUTE;
      RARCH_LOG("Got size_y attr: %u\n", prog->abs_y);
      y_attr_cnt++;
   }

   if (*attr_outscale)
   {
      float scale = strtod(attr_outscale, NULL);
      prog->scale_x = scale;
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_x = prog->type_y = RARCH_SCALE_VIEWPORT;
      RARCH_LOG("Got outscale attr: %.1f\n", scale);
      x_attr_cnt++;
      y_attr_cnt++;
   }

   if (*attr_outscale_x)
   {
      float scale = strtod(attr_outscale_x, NULL);
      prog->scale_x = scale;
      prog->valid_scale = true;
      prog->type_x = RARCH_SCALE_VIEWPORT;
      RARCH_LOG("Got outscale_x attr: %.1f\n", scale);
      x_attr_cnt++;
   }

   if (*attr_outscale_y)
   {
      float scale = strtod(attr_outscale_y, NULL);
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_y = RARCH_SCALE_VIEWPORT;
      RARCH_LOG("Got outscale_y attr: %.1f\n", scale);
      y_attr_cnt++;
   }

   if (x_attr_cnt > 1)
      return false;
   if (y_attr_cnt > 1)
      return false;

   return true;
}
Esempio n. 8
0
static bool gfx_ctx_ps3_init(void *data)
{
   gfx_ctx_ps3_data_t *ps3 = (gfx_ctx_ps3_data_t*)
      calloc(1, sizeof(gfx_ctx_ps3_data_t));

   (void)data;

   if (!ps3)
      return false;

#if defined(HAVE_PSGL)
   PSGLinitOptions options = {
      .enable = PSGL_INIT_MAX_SPUS | PSGL_INIT_INITIALIZE_SPUS,
      .maxSPUs = 1,
      .initializeSPUs = GL_FALSE,
   };

   /* Initialize 6 SPUs but reserve 1 SPU as a raw SPU for PSGL. */
   sys_spu_initialize(6, 1);
   psglInit(&options);

   PSGLdeviceParameters params;

   params.enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT |
      PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT |
      PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE;
   params.colorFormat = GL_ARGB_SCE;
   params.depthFormat = GL_NONE;
   params.multisamplingMode = GL_MULTISAMPLING_NONE_SCE;

   if (g_extern.console.screen.resolutions.current.id)
   {
      params.enable |= PSGL_DEVICE_PARAMETERS_WIDTH_HEIGHT;
      params.width = gfx_ctx_ps3_get_resolution_width(g_extern.console.screen.resolutions.current.id);
      params.height = gfx_ctx_ps3_get_resolution_height(g_extern.console.screen.resolutions.current.id);
      g_extern.console.screen.pal_enable = false;

      if (params.width == 720 && params.height == 576)
      {
         RARCH_LOG("[PSGL Context]: 720x576 resolution detected, setting MODE_VIDEO_PAL_ENABLE.\n");
         g_extern.console.screen.pal_enable = true;
      }
   }

   if (g_extern.console.screen.pal60_enable)
   {
      RARCH_LOG("[PSGL Context]: Setting temporal PAL60 mode.\n");
      params.enable |= PSGL_DEVICE_PARAMETERS_RESC_PAL_TEMPORAL_MODE;
      params.enable |= PSGL_DEVICE_PARAMETERS_RESC_RATIO_MODE;
      params.rescPalTemporalMode = RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE;
      params.rescRatioMode = RESC_RATIO_MODE_FULLSCREEN;
   }

   ps3->gl_device = psglCreateDeviceExtended(&params);
   ps3->gl_context = psglCreateContext();

   psglMakeCurrent(ps3->gl_context, ps3->gl_device);
   psglResetCurrentContext();
#endif

   g_extern.console.screen.pal_enable = 
      cellVideoOutGetResolutionAvailability(
            CELL_VIDEO_OUT_PRIMARY, CELL_VIDEO_OUT_RESOLUTION_576,
            CELL_VIDEO_OUT_ASPECT_AUTO, 0);

   gfx_ctx_ps3_get_available_resolutions();

   driver.video_context_data = ps3;

   return true;
}

static bool gfx_ctx_ps3_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   (void)data;
   return true;
}
Esempio n. 9
0
bool load_state(const char *path)
{
   unsigned i;
   void *buf = NULL;
   ssize_t size = read_file(path, &buf);

   RARCH_LOG("Loading state: \"%s\".\n", path);

   if (size < 0)
   {
      RARCH_ERR("Failed to load state from \"%s\".\n", path);
      return false;
   }

   bool ret = true;
   RARCH_LOG("State size: %u bytes.\n", (unsigned)size);

   struct sram_block *blocks = NULL;
   unsigned num_blocks = 0;

   if (g_settings.block_sram_overwrite && g_extern.savefiles
         && g_extern.savefiles->size)
   {
      RARCH_LOG("Blocking SRAM overwrite.\n");
      blocks = (struct sram_block*)
         calloc(g_extern.savefiles->size, sizeof(*blocks));

      if (blocks)
      {
         num_blocks = g_extern.savefiles->size;
         for (i = 0; i < num_blocks; i++)
            blocks[i].type = g_extern.savefiles->elems[i].attr.i;
      }
   }

   for (i = 0; i < num_blocks; i++)
      blocks[i].size = pretro_get_memory_size(blocks[i].type);

   for (i = 0; i < num_blocks; i++)
      if (blocks[i].size)
         blocks[i].data = malloc(blocks[i].size);

   /* Backup current SRAM which is overwritten by unserialize. */
   for (i = 0; i < num_blocks; i++)
   {
      if (blocks[i].data)
      {
         const void *ptr = pretro_get_memory_data(blocks[i].type);
         if (ptr)
            memcpy(blocks[i].data, ptr, blocks[i].size);
      }
   }

   ret = pretro_unserialize(buf, size);

   /* Flush back. */
   for (i = 0; i < num_blocks; i++)
   {
      if (blocks[i].data)
      {
         void *ptr = pretro_get_memory_data(blocks[i].type);
         if (ptr)
            memcpy(ptr, blocks[i].data, blocks[i].size);
      }
   }

   for (i = 0; i < num_blocks; i++)
      free(blocks[i].data);
   free(blocks);
   return ret;
}
Esempio n. 10
0
static bool gfx_ctx_qnx_init(void *data)
{
   EGLint num_config;
   EGLint egl_version_major, egl_version_minor;
   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
   const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_NONE
   };
   int angle, size[2];
   int usage, format = SCREEN_FORMAT_RGBX8888;

   /* Create a screen context that will be used to 
    * create an EGL surface to receive libscreen events */

   RARCH_LOG("Initializing screen context...\n");
   if (!screen_ctx)
   {
      screen_create_context(&screen_ctx, 0);

      if (screen_request_events(screen_ctx) != BPS_SUCCESS)
      {
         RARCH_ERR("screen_request_events failed.\n");
         goto screen_error;
      }

      if (navigator_request_events(0) != BPS_SUCCESS)
      {
         RARCH_ERR("navigator_request_events failed.\n");
         goto screen_error;
      }

      if (navigator_rotation_lock(false) != BPS_SUCCESS)
      {
         RARCH_ERR("navigator_location_lock failed.\n");
         goto screen_error;
      }
   }

   usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;

   RARCH_LOG("Initializing context\n");

   if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
   {
      RARCH_ERR("eglGetDisplay failed.\n");
      goto error;
   }

   if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor))
   {
      RARCH_ERR("eglInitialize failed.\n");
      goto error;
   }

   if (!eglBindAPI(EGL_OPENGL_ES_API))
   {
      RARCH_ERR("eglBindAPI failed.\n");
      goto error;
   }

   RARCH_LOG("[BLACKBERRY QNX/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor);

   if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &num_config))
      goto error;

   g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes);

   if (g_egl_ctx == EGL_NO_CONTEXT)
      goto error;

   if (g_use_hw_ctx)
   {
      g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_config, g_egl_ctx,
            context_attributes);
      RARCH_LOG("[Android/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);

      if (g_egl_hw_ctx == EGL_NO_CONTEXT)
         goto error;
   }

   if(!screen_win)
   {
      if (screen_create_window(&screen_win, screen_ctx))
      {
	     RARCH_ERR("screen_create_window failed:.\n");
	     goto error;
      }
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_FORMAT] failed.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_USAGE] failed.\n");
      goto error;
   }

   if (screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp))
   {
      RARCH_ERR("screen_get_window_property_pv [SCREEN_PROPERTY_DISPLAY] failed.\n");
      goto error;
   }

   int screen_resolution[2];

   if (screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution))
   {
      RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_SIZE] failed.\n");
      goto error;
   }

#ifndef HAVE_BB10
   angle = atoi(getenv("ORIENTATION"));

   screen_display_mode_t screen_mode;
   if (screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode))
   {
      RARCH_ERR("screen_get_display_property_pv [SCREEN_PROPERTY_MODE] failed.\n");
      goto error;
   }

   if (screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size))
   {
      RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_BUFFER_SIZE] failed.\n");
      goto error;
   }

   int buffer_size[2] = {size[0], size[1]};

   if ((angle == 0) || (angle == 180))
   {
      if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
            ((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
      {
         buffer_size[1] = size[0];
         buffer_size[0] = size[1];
      }
   }
   else if ((angle == 90) || (angle == 270))
   {
      if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
            ((screen_mode.width < screen_mode.height && size[0] < size[1])))
      {
         buffer_size[1] = size[0];
         buffer_size[0] = size[1];
      }
   }
   else
   {
      RARCH_ERR("Navigator returned an unexpected orientation angle.\n");
      goto error;
   }


   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_BUFFER_SIZE] failed.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_ROTATION] failed.\n");
      goto error;
   }
#endif

   if (screen_create_window_buffers(screen_win, WINDOW_BUFFERS))
   {
      RARCH_ERR("screen_create_window_buffers failed.\n");
      goto error;
   }

   if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, screen_win, 0)))
   {
      RARCH_ERR("eglCreateWindowSurface failed.\n");
      goto error;
   }


   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
   {
      RARCH_ERR("eglMakeCurrent failed.\n");
      goto error;
   }

   return true;

error:
   RARCH_ERR("EGL error: %d.\n", eglGetError());
   gfx_ctx_qnx_destroy(data);
screen_error:
   screen_stop_events(screen_ctx);
   return false;
}
Esempio n. 11
0
static void handle_screen_event(void *data, bps_event_t *event)
{
   int type;
   qnx_input_t *qnx = (qnx_input_t*)data;

   screen_event_t screen_event = screen_event_get_event(event);
   screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &type);

   switch(type)
   {
      case SCREEN_EVENT_MTOUCH_TOUCH:
      case SCREEN_EVENT_MTOUCH_RELEASE:
      case SCREEN_EVENT_MTOUCH_MOVE:
         process_touch_event(data, screen_event, type);
         break;
      case SCREEN_EVENT_KEYBOARD:
         process_keyboard_event(data, screen_event, type);
         break;
#ifdef HAVE_BB10
      case SCREEN_EVENT_GAMEPAD:
      case SCREEN_EVENT_JOYSTICK:
         process_gamepad_event(data, screen_event, type);
         break;
      case SCREEN_EVENT_DEVICE:
         {
            // A device was attached or removed.
            screen_device_t device;
            int attached, type, i;

            screen_get_event_property_pv(screen_event,
                  SCREEN_PROPERTY_DEVICE, (void**)&device);
            screen_get_event_property_iv(screen_event,
                  SCREEN_PROPERTY_ATTACHED, &attached);

            if (attached)
               screen_get_device_property_iv(device,
                     SCREEN_PROPERTY_TYPE, &type);

            if (attached && (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK || type == SCREEN_EVENT_KEYBOARD))
            {
               for (i = 0; i < MAX_PADS; ++i)
               {
                  if (!qnx->devices[i].handle)
                  {
                     qnx->devices[i].handle = device;
                     loadController(data, &qnx->devices[i]);
                     break;
                  }
               }
            }
            else
            {
               for (i = 0; i < MAX_PADS; ++i)
               {
                  if (device == qnx->devices[i].handle)
                  {
                     RARCH_LOG("Device %s: Disconnected.\n", qnx->devices[i].id);
                     initController(data, &qnx->devices[i]);
                     break;
                  }
               }
            }
         }
         break;
#endif
      default:
         break;
   }
}
Esempio n. 12
0
rarch_resampler_t *resampler_new(void)
{
   RARCH_LOG("Hermite resampler [C]\n");
   return (rarch_resampler_t*)calloc(1, sizeof(rarch_resampler_t));
}
Esempio n. 13
0
static bool winxinput_joypad_init(void)
{
   unsigned i, autoconf_pad;
   g_winxinput_dll = NULL;

   // Find the correct path to load the DLL from.
   // Usually this will be from the system directory,
   // but occasionally a user may wish to use a third-party
   // wrapper DLL (such as x360ce); support these by checking
   // the working directory first.

   // No need to check for existance as we will be checking LoadLibrary's
   // success anyway.

   const char *version = "1.4";
   g_winxinput_dll = LoadLibrary("xinput1_4.dll"); // Using dylib_* complicates building joyconfig.
   if (!g_winxinput_dll)
   {
      g_winxinput_dll = LoadLibrary("xinput1_3.dll");
      version = "1.3";
   }

   if (!g_winxinput_dll)
   {
      RARCH_ERR("Failed to load XInput, ensure DirectX and controller drivers are up to date.\n");
      return false;
   }

   RARCH_LOG("Found XInput v%s.\n", version);

   // If we get here then an xinput DLL is correctly loaded.
   // First try to load ordinal 100 (XInputGetStateEx).
   g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (const char*)100);
   g_winxinput_guide_button_supported = true;

   if (!g_XInputGetStateEx)
   {
      // no ordinal 100. (Presumably a wrapper.) Load the ordinary
      // XInputGetState, at the cost of losing guide button support.
      g_winxinput_guide_button_supported = false;
      g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState");
      if (!g_XInputGetStateEx)
      {
         RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
         FreeLibrary(g_winxinput_dll);
         return false; // DLL was loaded but did not contain the correct function.
      }
      RARCH_WARN("XInput: No guide button support.\n");
   }

   g_XInputSetState = (XInputSetState_t) GetProcAddress(g_winxinput_dll, "XInputSetState");
   if (!g_XInputSetState)
   {
      RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
      FreeLibrary(g_winxinput_dll);
      return false; // DLL was loaded but did not contain the correct function.
   }

   // Zero out the states
   for (i = 0; i < 4; ++i)
      memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state));

   // Do a dummy poll to check which controllers are connected.
   XINPUT_STATE dummy_state;
   for (i = 0; i < 4; ++i)
   {
      g_winxinput_states[i].connected = !(g_XInputGetStateEx(i, &dummy_state) == ERROR_DEVICE_NOT_CONNECTED);
      if (g_winxinput_states[i].connected)
         RARCH_LOG("Found XInput controller, player #%u\n", i);
   }

   if ((!g_winxinput_states[0].connected) &&
         (!g_winxinput_states[1].connected) &&
         (!g_winxinput_states[2].connected) &&
         (!g_winxinput_states[3].connected))
      return false;

   g_xinput_block_pads = true;

   // We're going to have to be buddies with dinput if we want to be able
   // to use XI and non-XI controllers together.
   if (!dinput_joypad.init())
   {
      g_xinput_block_pads = false;
      return false;
   }

   for (autoconf_pad = 0; autoconf_pad < MAX_PLAYERS; autoconf_pad++)
   {
      if (pad_index_to_xplayer_index(autoconf_pad) > -1)
      {
         strlcpy(g_settings.input.device_names[autoconf_pad], winxinput_joypad_name(autoconf_pad), sizeof(g_settings.input.device_names[autoconf_pad]));
         input_config_autoconfigure_joypad(autoconf_pad, winxinput_joypad_name(autoconf_pad), winxinput_joypad.ident);
      }
   }

   return true;

}
Esempio n. 14
0
static void *alsa_thread_init(const char *device,
      unsigned rate, unsigned latency)
{
   alsa_thread_t *alsa = (alsa_thread_t*)calloc(1, sizeof(alsa_thread_t));

   snd_pcm_hw_params_t *params = NULL;
   snd_pcm_sw_params_t *sw_params = NULL;

   const char *alsa_dev = device ? device : "default";

   unsigned latency_usec = latency * 1000 / 2;

   unsigned channels = 2;
   unsigned periods = 4;
   snd_pcm_uframes_t buffer_size;
   snd_pcm_format_t format;

   if (!alsa)
      return NULL;

   TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0));

   TRY_ALSA(snd_pcm_hw_params_malloc(&params));
   alsa->has_float = alsathread_find_float_format(alsa->pcm, params);
   format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;

   TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
   TRY_ALSA(snd_pcm_hw_params_set_access(
            alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
   TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format));
   TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels));
   TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));

   TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(
            alsa->pcm, params, &latency_usec, NULL));
   TRY_ALSA(snd_pcm_hw_params_set_periods_near(
            alsa->pcm, params, &periods, NULL));

   TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));

   /* Shouldn't have to bother with this, 
    * but some drivers are apparently broken. */
   if (snd_pcm_hw_params_get_period_size(params, &alsa->period_frames, NULL))
      snd_pcm_hw_params_get_period_size_min(
            params, &alsa->period_frames, NULL);
   RARCH_LOG("ALSA: Period size: %d frames\n", (int)alsa->period_frames);
   if (snd_pcm_hw_params_get_buffer_size(params, &buffer_size))
      snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size);
   RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size);

   alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size);
   alsa->period_size = snd_pcm_frames_to_bytes(alsa->pcm, alsa->period_frames);

   TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
   TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
   TRY_ALSA(snd_pcm_sw_params_set_start_threshold(
            alsa->pcm, sw_params, buffer_size / 2));
   TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params));

   snd_pcm_hw_params_free(params);
   snd_pcm_sw_params_free(sw_params);

   alsa->fifo_lock = slock_new();
   alsa->cond_lock = slock_new();
   alsa->cond = scond_new();
   alsa->buffer = fifo_new(alsa->buffer_size);
   if (!alsa->fifo_lock || !alsa->cond_lock || !alsa->cond || !alsa->buffer)
      goto error;

   alsa->worker_thread = sthread_create(alsa_worker_thread, alsa);
   if (!alsa->worker_thread)
   {
      RARCH_ERR("error initializing worker thread");
      goto error;
   }

   return alsa;

error:
   RARCH_ERR("ALSA: Failed to initialize...\n");
   if (params)
      snd_pcm_hw_params_free(params);

   if (sw_params)
      snd_pcm_sw_params_free(sw_params);

   alsa_thread_free(alsa);

   return NULL;
}
Esempio n. 15
0
static bool create_softfilter_graph(rarch_softfilter_t *filt,
      enum retro_pixel_format in_pixel_format,
      unsigned max_width, unsigned max_height,
      softfilter_simd_mask_t cpu_features,
      unsigned threads)
{
   unsigned input_fmts, input_fmt, output_fmts, i = 0;
   struct config_file_userdata userdata;
   char key[64], name[64];

   (void)i;

   key[0] = name[0] = '\0';

   snprintf(key, sizeof(key), "filter");

   if (!config_get_array(filt->conf, key, name, sizeof(name)))
   {
      RARCH_ERR("Could not find 'filter' array in config.\n");
      return false;
   }

   if (filt->num_plugs == 0)
   {
      RARCH_ERR("No filter plugs found. Exiting...\n");
      return false;
   }

   filt->impl = softfilter_find_implementation(filt, name);
   if (!filt->impl)
   {
      RARCH_ERR("Could not find implementation.\n");
      return false;
   }

   userdata.conf = filt->conf;
   /* Index-specific configs take priority over ident-specific. */
   userdata.prefix[0] = key;
   userdata.prefix[1] = filt->impl->short_ident;

   /* Simple assumptions. */
   filt->pix_fmt = in_pixel_format;
   input_fmts = filt->impl->query_input_formats();

   switch (in_pixel_format)
   {
      case RETRO_PIXEL_FORMAT_XRGB8888:
         input_fmt = SOFTFILTER_FMT_XRGB8888;
         break;
      case RETRO_PIXEL_FORMAT_RGB565:
         input_fmt = SOFTFILTER_FMT_RGB565;
         break;
      default:
         return false;
   }

   if (!(input_fmt & input_fmts))
   {
      RARCH_ERR("Softfilter does not support input format.\n");
      return false;
   }

   output_fmts = filt->impl->query_output_formats(input_fmt);
   /* If we have a match of input/output formats, use that. */
   if (output_fmts & input_fmt)
      filt->out_pix_fmt = in_pixel_format;
   else if (output_fmts & SOFTFILTER_FMT_XRGB8888)
      filt->out_pix_fmt = RETRO_PIXEL_FORMAT_XRGB8888;
   else if (output_fmts & SOFTFILTER_FMT_RGB565)
      filt->out_pix_fmt = RETRO_PIXEL_FORMAT_RGB565;
   else
   {
      RARCH_ERR("Did not find suitable output format for softfilter.\n");
      return false;
   }

   filt->max_width = max_width;
   filt->max_height = max_height;

   filt->impl_data = filt->impl->create(
         &softfilter_config, input_fmt, input_fmt, max_width, max_height,
         threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads :
         cpu_features_get_core_amount(), cpu_features,
         &userdata);
   if (!filt->impl_data)
   {
      RARCH_ERR("Failed to create softfilter state.\n");
      return false;
   }

   threads = filt->impl->query_num_threads(filt->impl_data);
   if (!threads)
   {
      RARCH_ERR("Invalid number of threads.\n");
      return false;
   }

   filt->threads = threads;
   RARCH_LOG("Using %u threads for softfilter.\n", threads);

   filt->packets = (struct softfilter_work_packet*)
      calloc(threads, sizeof(*filt->packets));
   if (!filt->packets)
   {
      RARCH_ERR("Failed to allocate softfilter packets.\n");
      return false;
   }

#ifdef HAVE_THREADS
   filt->thread_data = (struct filter_thread_data*)
      calloc(threads, sizeof(*filt->thread_data));
   if (!filt->thread_data)
      return false;

   for (i = 0; i < threads; i++)
   {
      filt->thread_data[i].userdata = filt->impl_data;
      filt->thread_data[i].done = true;

      filt->thread_data[i].lock = slock_new();
      if (!filt->thread_data[i].lock)
         return false;
      filt->thread_data[i].cond = scond_new();
      if (!filt->thread_data[i].cond)
         return false;
      filt->thread_data[i].thread = sthread_create(
            filter_thread_loop, &filt->thread_data[i]);
      if (!filt->thread_data[i].thread)
         return false;
   }
#endif

   return true;
}
Esempio n. 16
0
static bool load_content(const struct retro_subsystem_info *special,
      const struct string_list *content)
{
   unsigned i;
   bool ret = true;

   struct string_list* additional_path_allocs = string_list_new();

   struct retro_game_info *info = (struct retro_game_info*)
      calloc(content->size, sizeof(*info));

   if (!info)
      return false;

   for (i = 0; i < content->size; i++)
   {
      const char *path = content->elems[i].data;
      int attr = content->elems[i].attr.i;

      bool need_fullpath = attr & 2;
      bool require_content = attr & 4;

      if (require_content && !*path)
      {
         RARCH_LOG("libretro core requires content, but nothing was provided.\n");
         ret = false;
         goto end;
      }

      info[i].path = *path ? path : NULL;
      if (!need_fullpath && *path)
      {
         /* Load the content into memory. */
         RARCH_LOG("Loading content file: %s.\n", path);

         /* First content file is significant, attempt to do patching,
          * CRC checking, etc. */
         long size = i == 0 ?
            read_content_file(path, (void**)&info[i].data) :
            read_file(path, (void**)&info[i].data);

         if (size < 0)
         {
            RARCH_ERR("Could not read content file \"%s\".\n", path);
            ret = false;
            goto end;
         }

         info[i].size = size;
      }
      else
      {
         RARCH_LOG("Content loading skipped. Implementation will"
               " load it on its own.\n");
         if (need_fullpath && path_contains_compressed_file(path))
         {
            RARCH_LOG("Compressed file in case of need_fullpath."
                  "Now extracting to temporary directory.\n");

            if ((!strcmp(g_settings.extraction_directory,"")) ||
                 !path_is_directory(g_settings.extraction_directory))
            {
               RARCH_ERR("Tried extracting to extraction directory, but "
                      "extraction directory was not set or found. Exiting.\n");
               rarch_assert(false);
            }

            char new_path[PATH_MAX];
            union string_list_elem_attr attr;
            attr.i = 0;
            fill_pathname_join(new_path,g_settings.extraction_directory,
                  path_basename(path),sizeof(new_path));
            read_compressed_file(path,NULL,new_path);
            string_list_append(additional_path_allocs,new_path,attr);
            info[i].path =
                  additional_path_allocs->elems
                     [additional_path_allocs->size -1 ].data;

            /* g_extern.temporary_content is initialized in init_content_file
             * The following part takes care of cleanup of the unzipped files
             * after exit.
             */
            rarch_assert(g_extern.temporary_content != NULL);
            string_list_append(g_extern.temporary_content,
                  new_path, attr);
         }
      }
   }

   if (special)
      ret = pretro_load_game_special(special->id, info, content->size);
   else
      ret = pretro_load_game(*content->elems[0].data ? info : NULL);

   if (!ret)
      RARCH_ERR("Failed to load game.\n");

end:
   for (i = 0; i < content->size; i++)
      free((void*)info[i].data);

   string_list_free(additional_path_allocs);
   free(info);
   return ret;
}
Esempio n. 17
0
static void load_symbols(bool is_dummy)
{
   if (is_dummy)
   {
      SYM_DUMMY(retro_init);
      SYM_DUMMY(retro_deinit);

      SYM_DUMMY(retro_api_version);
      SYM_DUMMY(retro_get_system_info);
      SYM_DUMMY(retro_get_system_av_info);

      SYM_DUMMY(retro_set_environment);
      SYM_DUMMY(retro_set_video_refresh);
      SYM_DUMMY(retro_set_audio_sample);
      SYM_DUMMY(retro_set_audio_sample_batch);
      SYM_DUMMY(retro_set_input_poll);
      SYM_DUMMY(retro_set_input_state);

      SYM_DUMMY(retro_set_controller_port_device);

      SYM_DUMMY(retro_reset);
      SYM_DUMMY(retro_run);

      SYM_DUMMY(retro_serialize_size);
      SYM_DUMMY(retro_serialize);
      SYM_DUMMY(retro_unserialize);

      SYM_DUMMY(retro_cheat_reset);
      SYM_DUMMY(retro_cheat_set);

      SYM_DUMMY(retro_load_game);
      SYM_DUMMY(retro_load_game_special);

      SYM_DUMMY(retro_unload_game);
      SYM_DUMMY(retro_get_region);
      SYM_DUMMY(retro_get_memory_data);
      SYM_DUMMY(retro_get_memory_size);
   }
   else
   {
#ifdef HAVE_DYNAMIC
      if (path_is_directory(g_settings.libretro))
      {
         char libretro_core_buffer[PATH_MAX];
         if (!find_first_libretro(libretro_core_buffer, sizeof(libretro_core_buffer),
                  g_settings.libretro, g_extern.fullpath))
         {
            RARCH_ERR("libretro_path is a directory, but no valid libretro implementation was found.\n");
            rarch_fail(1, "load_dynamic()");
         }

         strlcpy(g_settings.libretro, libretro_core_buffer, sizeof(g_settings.libretro));
      }

      // Need to use absolute path for this setting. It can be saved to ROM history,
      // and a relative path would break in that scenario.
      path_resolve_realpath(g_settings.libretro, sizeof(g_settings.libretro));

      RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", g_settings.libretro);
      lib_handle = dylib_load(g_settings.libretro);
      if (!lib_handle)
      {
         RARCH_ERR("Failed to open dynamic library: \"%s\"\n", g_settings.libretro);
         rarch_fail(1, "load_dynamic()");
      }
#endif

      SYM(retro_init);
      SYM(retro_deinit);

      SYM(retro_api_version);
      SYM(retro_get_system_info);
      SYM(retro_get_system_av_info);

      SYM(retro_set_environment);
      SYM(retro_set_video_refresh);
      SYM(retro_set_audio_sample);
      SYM(retro_set_audio_sample_batch);
      SYM(retro_set_input_poll);
      SYM(retro_set_input_state);

      SYM(retro_set_controller_port_device);

      SYM(retro_reset);
      SYM(retro_run);

      SYM(retro_serialize_size);
      SYM(retro_serialize);
      SYM(retro_unserialize);

      SYM(retro_cheat_reset);
      SYM(retro_cheat_set);

      SYM(retro_load_game);
      SYM(retro_load_game_special);

      SYM(retro_unload_game);
      SYM(retro_get_region);
      SYM(retro_get_memory_data);
      SYM(retro_get_memory_size);
   }
}
Esempio n. 18
0
static void frontend_ps3_get_environment_settings(int *argc, char *argv[],
      void *args, void *params_data)
{
#ifndef IS_SALAMANDER
   bool original_verbose = verbosity_is_enabled();
   verbosity_enable();
#endif

   (void)args;
#ifndef IS_SALAMANDER
#if defined(HAVE_LOGGER)
   logger_init();
#elif defined(HAVE_FILE_LOGGER)
   retro_main_log_file_init("/retroarch-log.txt");
#endif
#endif

   int ret;
   unsigned int get_type;
   unsigned int get_attributes;
   CellGameContentSize size;
   char dirName[CELL_GAME_DIRNAME_SIZE]  = {0};

#ifdef HAVE_MULTIMAN
   /* not launched from external launcher, set default path */
   // second param is multiMAN SELF file
   if(path_file_exists(argv[2]) && *argc > 1
         && (!strcmp(argv[2], EMULATOR_CONTENT_DIR)))
   {
      multiman_detected = true;
      RARCH_LOG("Started from multiMAN, auto-game start enabled.\n");
   }
   else
#endif
#ifndef IS_SALAMANDER
      if (*argc > 1 && !string_is_empty(argv[1]))
      {
         static char path[PATH_MAX_LENGTH];
         *path = '\0';
         struct rarch_main_wrap *args = (struct rarch_main_wrap*)params_data;

         if (args)
         {
            strlcpy(path, argv[1], sizeof(path));

            args->touched        = true;
            args->no_content     = false;
            args->verbose        = false;
            args->config_path    = NULL;
            args->sram_path      = NULL;
            args->state_path     = NULL;
            args->content_path   = path;
            args->libretro_path  = NULL;

            RARCH_LOG("argv[0]: %s\n", argv[0]);
            RARCH_LOG("argv[1]: %s\n", argv[1]);
            RARCH_LOG("argv[2]: %s\n", argv[2]);

            RARCH_LOG("Auto-start game %s.\n", argv[1]);
         }
      }
      else
         RARCH_WARN("Started from Salamander, auto-game start disabled.\n");
#endif

   memset(&size, 0x00, sizeof(CellGameContentSize));

   ret = cellGameBootCheck(&get_type, &get_attributes, &size, dirName);
   if(ret < 0)
   {
      RARCH_ERR("cellGameBootCheck() Error: 0x%x.\n", ret);
   }
   else
   {
      char content_info_path[PATH_MAX_LENGTH] = {0};

      RARCH_LOG("cellGameBootCheck() OK.\n");
      RARCH_LOG("Directory name: [%s].\n", dirName);
      RARCH_LOG(" HDD Free Size (in KB) = [%d] Size (in KB) = [%d] System Size (in KB) = [%d].\n",
            size.hddFreeSizeKB, size.sizeKB, size.sysSizeKB);

      switch(get_type)
      {
         case CELL_GAME_GAMETYPE_DISC:
            RARCH_LOG("RetroArch was launched on Optical Disc Drive.\n");
            break;
         case CELL_GAME_GAMETYPE_HDD:
            RARCH_LOG("RetroArch was launched on HDD.\n");
            break;
      }

      if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) 
            == CELL_GAME_ATTRIBUTE_APP_HOME)
         RARCH_LOG("RetroArch was launched from host machine (APP_HOME).\n");

      ret = cellGameContentPermit(content_info_path, g_defaults.dir.port);

#ifdef HAVE_MULTIMAN
      if (multiman_detected)
      {
         fill_pathname_join(content_info_path, "/dev_hdd0/game/",
               EMULATOR_CONTENT_DIR, sizeof(content_info_path));
         fill_pathname_join(g_defaults.dir.port, content_info_path,
               "USRDIR", sizeof(g_defaults.dir.port));
      }
#endif

      if(ret < 0)
         RARCH_ERR("cellGameContentPermit() Error: 0x%x\n", ret);
      else
      {
         RARCH_LOG("cellGameContentPermit() OK.\n");
         RARCH_LOG("content_info_path : [%s].\n", content_info_path);
         RARCH_LOG("usrDirPath : [%s].\n", g_defaults.dir.port);
      }

      strlcpy(g_defaults.dir.content_history,
            g_defaults.dir.port, sizeof(g_defaults.dir.content_history));
      fill_pathname_join(g_defaults.dir.core, g_defaults.dir.port,
            "cores", sizeof(g_defaults.dir.core));
      fill_pathname_join(g_defaults.dir.core_info, g_defaults.dir.port,
            "cores", sizeof(g_defaults.dir.core_info));
      fill_pathname_join(g_defaults.dir.savestate, g_defaults.dir.core,
            "savestates", sizeof(g_defaults.dir.savestate));
      fill_pathname_join(g_defaults.dir.sram, g_defaults.dir.core,
            "savefiles", sizeof(g_defaults.dir.sram));
      fill_pathname_join(g_defaults.dir.system, g_defaults.dir.core,
            "system", sizeof(g_defaults.dir.system));
      fill_pathname_join(g_defaults.dir.shader,  g_defaults.dir.core,
            "shaders_cg", sizeof(g_defaults.dir.shader));
      fill_pathname_join(g_defaults.path.config, g_defaults.dir.port,
            file_path_str(FILE_PATH_MAIN_CONFIG),  sizeof(g_defaults.path.config));
      fill_pathname_join(g_defaults.dir.overlay, g_defaults.dir.core,
            "overlays", sizeof(g_defaults.dir.overlay));
      fill_pathname_join(g_defaults.dir.assets,   g_defaults.dir.core,
            "assets", sizeof(g_defaults.dir.assets));
      fill_pathname_join(g_defaults.dir.cursor,   g_defaults.dir.core,
            "database/cursors", sizeof(g_defaults.dir.cursor));
      fill_pathname_join(g_defaults.dir.database,   g_defaults.dir.core,
            "database/rdb", sizeof(g_defaults.dir.database));
      fill_pathname_join(g_defaults.dir.playlist,   g_defaults.dir.core,
            "playlists", sizeof(g_defaults.dir.playlist));
   }

#ifndef IS_SALAMANDER
   if (original_verbose)
      verbosity_enable();
   else
      verbosity_disable();
#endif
}
Esempio n. 19
0
bool gl_glsl_init(const char *path)
{
#if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__)
   // Load shader functions.
   LOAD_GL_SYM(CreateProgram);
   LOAD_GL_SYM(UseProgram);
   LOAD_GL_SYM(CreateShader);
   LOAD_GL_SYM(DeleteShader);
   LOAD_GL_SYM(ShaderSource);
   LOAD_GL_SYM(CompileShader);
   LOAD_GL_SYM(AttachShader);
   LOAD_GL_SYM(DetachShader);
   LOAD_GL_SYM(LinkProgram);
   LOAD_GL_SYM(GetUniformLocation);
   LOAD_GL_SYM(Uniform1i);
   LOAD_GL_SYM(Uniform1f);
   LOAD_GL_SYM(Uniform2fv);
   LOAD_GL_SYM(Uniform4fv);
   LOAD_GL_SYM(UniformMatrix4fv);
   LOAD_GL_SYM(GetShaderiv);
   LOAD_GL_SYM(GetShaderInfoLog);
   LOAD_GL_SYM(GetProgramiv);
   LOAD_GL_SYM(GetProgramInfoLog);
   LOAD_GL_SYM(DeleteProgram);
   LOAD_GL_SYM(GetAttachedShaders);
   LOAD_GL_SYM(GetAttribLocation);
   LOAD_GL_SYM(EnableVertexAttribArray);
   LOAD_GL_SYM(DisableVertexAttribArray);
   LOAD_GL_SYM(VertexAttribPointer);

   RARCH_LOG("Checking GLSL shader support ...\n");
   bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader
      && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader
      && pglDetachShader && pglLinkProgram && pglGetUniformLocation
      && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv
      && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog 
      && pglDeleteProgram && pglGetAttachedShaders
      && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray
      && pglVertexAttribPointer;

   if (!shader_support)
   {
      RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
      return false;
   }
#endif

   unsigned num_progs = 0;
   struct shader_program progs[RARCH_GLSL_MAX_SHADERS] = {{0}};
#ifdef HAVE_XML
   if (path)
   {
      num_progs = get_xml_shaders(path, progs, RARCH_GLSL_MAX_SHADERS - 1);

      if (num_progs == 0)
      {
         RARCH_ERR("Couldn't find any valid shaders in XML file.\n");
         return false;
      }
   }
   else
#endif
   {
      RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
      num_progs = 1;
      progs[0].vertex   = strdup(stock_vertex_modern);
      progs[0].fragment = strdup(stock_fragment_modern);
      glsl_modern       = true;
   }

#ifdef HAVE_OPENGLES2
   if (!glsl_modern)
   {
      RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
      return false;
   }
#endif

   struct shader_program stock_prog = {0};
   stock_prog.vertex   = strdup(glsl_modern ? stock_vertex_modern   : stock_vertex_legacy);
   stock_prog.fragment = strdup(glsl_modern ? stock_fragment_modern : stock_fragment_legacy);

   if (!compile_programs(&gl_program[0], &stock_prog, 1))
   {
      RARCH_ERR("GLSL stock programs failed to compile.\n");
      return false;
   }

   for (unsigned i = 0; i < num_progs; i++)
   {
      gl_filter_type[i + 1]   = progs[i].filter;
      gl_scale[i + 1].type_x  = progs[i].type_x;
      gl_scale[i + 1].type_y  = progs[i].type_y;
      gl_scale[i + 1].scale_x = progs[i].scale_x;
      gl_scale[i + 1].scale_y = progs[i].scale_y;
      gl_scale[i + 1].abs_x   = progs[i].abs_x;
      gl_scale[i + 1].abs_y   = progs[i].abs_y;
      gl_scale[i + 1].valid   = progs[i].valid_scale;
   }

   if (!compile_programs(&gl_program[1], progs, num_progs))
      return false;

#ifdef HAVE_XML
   // RetroArch custom two-pass with two different files.
   if (num_progs == 1 && *g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
   {
      unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs, 1);
      if (secondary_progs == 1)
      {
         compile_programs(&gl_program[2], progs, 1);
         num_progs++;
      }
      else
      {
         RARCH_ERR("Did not find exactly one valid shader in secondary shader file.\n");
         return false;
      }
   }
#endif

   for (unsigned i = 0; i <= num_progs; i++)
      find_uniforms(gl_program[i], &gl_uniforms[i]);

#ifdef GLSL_DEBUG
   if (!gl_check_error())
      RARCH_WARN("Detected GL error in GLSL.\n");
#endif

#ifdef HAVE_XML
   if (gl_tracker_info_cnt > 0)
   {
      struct state_tracker_info info = {0};
      info.wram      = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
      info.info      = gl_tracker_info;
      info.info_elem = gl_tracker_info_cnt;

#ifdef HAVE_PYTHON
      info.script = gl_script_program;
      info.script_class   = *gl_tracker_script_class ? gl_tracker_script_class : NULL;
      info.script_is_file = false;
#endif

      gl_state_tracker = state_tracker_init(&info);
      if (!gl_state_tracker)
         RARCH_WARN("Failed to init state tracker.\n");
   }
#endif
   
   glsl_enable                      = true;
   gl_num_programs                  = num_progs;
   gl_program[gl_num_programs + 1]  = gl_program[0];
   gl_uniforms[gl_num_programs + 1] = gl_uniforms[0];

   gl_glsl_reset_attrib();

   return true;
}
Esempio n. 20
0
static void patch_rom(uint8_t **buf, ssize_t *size)
{
   uint8_t *ret_buf = *buf;
   ssize_t ret_size = *size;

   const char *patch_desc = NULL;
   const char *patch_path = NULL;
   patch_error_t err = PATCH_UNKNOWN;
   patch_func_t func = NULL;

   ssize_t patch_size = 0;
   void *patch_data = NULL;
   bool success = false;

   if (g_extern.ups_pref + g_extern.bps_pref + g_extern.ips_pref > 1)
   {
      RARCH_WARN("Several patches are explicitly defined, ignoring all ...\n");
      return;
   }

   bool allow_bps = !g_extern.ups_pref && !g_extern.ips_pref;
   bool allow_ups = !g_extern.bps_pref && !g_extern.ips_pref;
   bool allow_ips = !g_extern.ups_pref && !g_extern.bps_pref;

   if (allow_ups && *g_extern.ups_name && (patch_size = read_file(g_extern.ups_name, &patch_data)) >= 0)
   {
      patch_desc = "UPS";
      patch_path = g_extern.ups_name;
      func = ups_apply_patch;
   }
   else if (allow_bps && *g_extern.bps_name && (patch_size = read_file(g_extern.bps_name, &patch_data)) >= 0)
   {
      patch_desc = "BPS";
      patch_path = g_extern.bps_name;
      func = bps_apply_patch;
   }
   else if (allow_ips && *g_extern.ips_name && (patch_size = read_file(g_extern.ips_name, &patch_data)) >= 0)
   {
      patch_desc = "IPS";
      patch_path = g_extern.ips_name;
      func = ips_apply_patch;
   }
   else
   {
      RARCH_LOG("Did not find a valid ROM patch.\n");
      return;
   }

   RARCH_LOG("Found %s file in \"%s\", attempting to patch ...\n", patch_desc, patch_path);

   size_t target_size = ret_size * 4; // Just to be sure ...
   uint8_t *patched_rom = (uint8_t*)malloc(target_size);
   if (!patched_rom)
   {
      RARCH_ERR("Failed to allocate memory for patched ROM ...\n");
      goto error;
   }

   err = func((const uint8_t*)patch_data, patch_size, ret_buf, ret_size, patched_rom, &target_size);
   if (err == PATCH_SUCCESS)
   {
      RARCH_LOG("ROM patched successfully (%s).\n", patch_desc);
      success = true;
   }
   else
      RARCH_ERR("Failed to patch %s: Error #%u\n", patch_desc, (unsigned)err);

   if (success)
   {
      free(ret_buf);
      *buf = patched_rom;
      *size = target_size;
   }

   if (patch_data)
      free(patch_data);

   return;

error:
   *buf = ret_buf;
   *size = ret_size;
   if (patch_data)
      free(patch_data);
}
Esempio n. 21
0
static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
{
   if (gl_teximage_cnt >= MAX_TEXTURES)
   {
      RARCH_WARN("Too many texture images. Ignoring ...\n");
      return true;
   }

   bool linear = true;
   char filename[PATH_MAX];
   char filter[64];
   char id[64];
   xml_get_prop(filename, sizeof(filename), ptr, "file");
   xml_get_prop(filter, sizeof(filter), ptr, "filter");
   xml_get_prop(id, sizeof(id), ptr, "id");
   struct texture_image img;

   if (!*id)
   {
      RARCH_ERR("Could not find ID in texture.\n");
      return false;
   }

   if (!*filename)
   {
      RARCH_ERR("Could not find filename in texture.\n");
      return false;
   }

   if (strcmp(filter, "nearest") == 0)
      linear = false;

   char tex_path[PATH_MAX];
   fill_pathname_resolve_relative(tex_path, shader_path, (const char*)filename, sizeof(tex_path));

   RARCH_LOG("Loading texture image from: \"%s\" ...\n", tex_path);
   if (!texture_image_load(tex_path, &img))
   {
      RARCH_ERR("Failed to load texture image from: \"%s\"\n", tex_path);
      return false;
   }

   strlcpy(gl_teximage_uniforms[gl_teximage_cnt], (const char*)id, sizeof(gl_teximage_uniforms[0]));

   glGenTextures(1, &gl_teximage[gl_teximage_cnt]);

   pglActiveTexture(GL_TEXTURE0 + gl_teximage_cnt + 1);
   glBindTexture(GL_TEXTURE_2D, gl_teximage[gl_teximage_cnt]);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, BORDER_FUNC);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, BORDER_FUNC);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);

   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
   glTexImage2D(GL_TEXTURE_2D,
         0, RARCH_GL_INTERNAL_FORMAT32,
         img.width, img.height, 0, RARCH_GL_TEXTURE_TYPE32, RARCH_GL_FORMAT32, img.pixels);

   pglActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, 0);
   free(img.pixels);

   gl_teximage_cnt++;

   return true;
}
Esempio n. 22
0
static ssize_t read_rom_file(FILE *file, void **buf)
{
   ssize_t ret = 0;
   uint8_t *ret_buf = NULL;

   if (file == NULL) // stdin
   {
#if defined(_WIN32) && !defined(_XBOX)
      _setmode(0, O_BINARY);
#endif

      RARCH_LOG("Reading ROM from stdin ...\n");
      size_t buf_size = 0xfffff; // Some initial guesstimate.
      size_t buf_ptr = 0;
      uint8_t *rom_buf = (uint8_t*)malloc(buf_size);
      if (rom_buf == NULL)
      {
         RARCH_ERR("Couldn't allocate memory.\n");
         return -1;
      }

      for (;;)
      {
         size_t ret = fread(rom_buf + buf_ptr, 1, buf_size - buf_ptr, stdin);
         buf_ptr += ret;

         // We've reached the end
         if (buf_ptr < buf_size)
            break;

         rom_buf = (uint8_t*)realloc(rom_buf, buf_size * 2);
         if (rom_buf == NULL)
         {
            RARCH_ERR("Couldn't allocate memory.\n");
            return -1;
         }

         buf_size *= 2;
      }

      ret_buf = rom_buf;
      ret = buf_ptr;
   }
   else
   {
      fseek(file, 0, SEEK_END);
      ret = ftell(file);
      rewind(file);

      void *rom_buf = malloc(ret);
      if (rom_buf == NULL)
      {
         RARCH_ERR("Couldn't allocate memory.\n");
         return -1;
      }

      if (fread(rom_buf, 1, ret, file) < (size_t)ret)
      {
         RARCH_ERR("Didn't read whole file.\n");
         free(rom_buf);
         return -1;
      }

      ret_buf = (uint8_t*)rom_buf;
   }

   if (!g_extern.block_patch)
   {
      // Attempt to apply a patch.
      patch_rom(&ret_buf, &ret);
   }
   
   g_extern.cart_crc = crc32_calculate(ret_buf, ret);
   sha256_hash(g_extern.sha256, ret_buf, ret);
   RARCH_LOG("CRC32: 0x%x, SHA256: %s\n",
         (unsigned)g_extern.cart_crc, g_extern.sha256);
   *buf = ret_buf;
   return ret;
}
Esempio n. 23
0
static void frontend_ctr_get_environment_settings(int *argc, char *argv[],
      void *args, void *params_data)
{
   (void)args;

#ifndef IS_SALAMANDER
#if defined(HAVE_LOGGER)
   logger_init();
#elif defined(HAVE_FILE_LOGGER)
   global_t *global  = global_get_ptr();
   global->log_file = fopen("sdmc:/retroarch/retroarch-log.txt", "w");
#endif
#endif

   fill_pathname_basedir(g_defaults.dir.port, elf_path_cst, sizeof(g_defaults.dir.port));
   RARCH_LOG("port dir: [%s]\n", g_defaults.dir.port);

   fill_pathname_join(g_defaults.dir.core_assets, g_defaults.dir.port,
         "downloads", sizeof(g_defaults.dir.core_assets));
   fill_pathname_join(g_defaults.dir.assets, g_defaults.dir.port,
         "media", sizeof(g_defaults.dir.assets));
   fill_pathname_join(g_defaults.dir.core, g_defaults.dir.port,
         "cores", sizeof(g_defaults.dir.core));
   fill_pathname_join(g_defaults.dir.core_info, g_defaults.dir.port,
         "cores", sizeof(g_defaults.dir.core_info));
   fill_pathname_join(g_defaults.dir.savestate, g_defaults.dir.core,
         "savestates", sizeof(g_defaults.dir.savestate));
   fill_pathname_join(g_defaults.dir.sram, g_defaults.dir.core,
         "savefiles", sizeof(g_defaults.dir.sram));
   fill_pathname_join(g_defaults.dir.system, g_defaults.dir.core,
         "system", sizeof(g_defaults.dir.system));
   fill_pathname_join(g_defaults.dir.playlist, g_defaults.dir.core,
         "playlists", sizeof(g_defaults.dir.playlist));
   fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.port,
         "remaps", sizeof(g_defaults.dir.remap));
   fill_pathname_join(g_defaults.path.config, g_defaults.dir.port,
         "retroarch.cfg", sizeof(g_defaults.path.config));

#ifndef IS_SALAMANDER
#if 0
   if (argv[1] && (argv[1][0] != '\0'))
   {
      static char path[PATH_MAX_LENGTH];
      struct rarch_main_wrap *args = NULL;

      *path = '\0';
      args = (struct rarch_main_wrap*)params_data;

      if (args)
      {
         strlcpy(path, argv[1], sizeof(path));

         args->touched        = true;
         args->no_content     = false;
         args->verbose        = false;
         args->config_path    = NULL;
         args->sram_path      = NULL;
         args->state_path     = NULL;
         args->content_path   = path;
         args->libretro_path  = NULL;

         RARCH_LOG("argv[0]: %s\n", argv[0]);
         RARCH_LOG("argv[1]: %s\n", argv[1]);
         RARCH_LOG("argv[2]: %s\n", argv[2]);

         RARCH_LOG("Auto-start game %s.\n", argv[1]);
      }
   }
#endif
#endif
}
Esempio n. 24
0
bool load_state(const char *path)
{
   RARCH_LOG("Loading state: \"%s\".\n", path);
   void *buf = NULL;
   ssize_t size = read_file(path, &buf);

   if (size < 0)
   {
      RARCH_ERR("Failed to load state from \"%s\".\n", path);
      return false;
   }

   bool ret = true;
   RARCH_LOG("State size: %u bytes.\n", (unsigned)size);

   void *block_buf[2] = {NULL, NULL};
   int block_type[2] = {-1, -1};
   size_t block_size[2] = {0};

   if (g_settings.block_sram_overwrite)
   {
      RARCH_LOG("Blocking SRAM overwrite.\n");
      switch (g_extern.game_type)
      {
         case RARCH_CART_NORMAL:
            block_type[0] = RETRO_MEMORY_SAVE_RAM;
            block_type[1] = RETRO_MEMORY_RTC;
            break;

         case RARCH_CART_BSX:
         case RARCH_CART_BSX_SLOTTED:
            block_type[0] = RETRO_MEMORY_SNES_BSX_RAM;
            block_type[1] = RETRO_MEMORY_SNES_BSX_PRAM;
            break;

         case RARCH_CART_SUFAMI:
            block_type[0] = RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM;
            block_type[1] = RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM;
            break;

         case RARCH_CART_SGB:
            block_type[0] = RETRO_MEMORY_SNES_GAME_BOY_RAM;
            block_type[1] = RETRO_MEMORY_SNES_GAME_BOY_RTC;
            break;
      }
   }

   for (unsigned i = 0; i < 2; i++)
      if (block_type[i] != -1)
         block_size[i] = pretro_get_memory_size(block_type[i]);

   for (unsigned i = 0; i < 2; i++)
      if (block_size[i])
         block_buf[i] = malloc(block_size[i]);

   // Backup current SRAM which is overwritten by unserialize.
   for (unsigned i = 0; i < 2; i++)
   {
      if (block_buf[i])
      {
         const void *ptr = pretro_get_memory_data(block_type[i]);
         if (ptr)
            memcpy(block_buf[i], ptr, block_size[i]);
      }
   }

   ret = pretro_unserialize(buf, size);

   // Flush back :D
   for (unsigned i = 0; i < 2 && ret; i++)
   {
      if (block_buf[i])
      {
         void *ptr = pretro_get_memory_data(block_type[i]);
         if (ptr)
            memcpy(ptr, block_buf[i], block_size[i]);
      }
   }

   for (unsigned i = 0; i < 2; i++)
      if (block_buf[i])
         free(block_buf[i]);

   free(buf);
   return ret;
}
Esempio n. 25
0
py_state_t *py_state_new(const char *script,
      unsigned is_file, const char *pyclass)
{
   py_state_t *handle;
   PyObject *hook;

   RARCH_LOG("Initializing Python runtime ...\n");
   PyImport_AppendInittab("rarch", &PyInit_Retro);
   Py_Initialize();
   RARCH_LOG("Initialized Python runtime.\n");

   handle = (py_state_t*)calloc(1, sizeof(*handle));
   hook = NULL;

   handle->main = PyImport_AddModule("__main__");
   if (!handle->main)
      goto error;
   Py_INCREF(handle->main);

   if (is_file)
   {
      /* Have to hack around the fact that the FILE struct
       * isn't standardized across environments.
       * PyRun_SimpleFile() breaks on Windows because it's
       * compiled with MSVC. */
      ssize_t len;
      char *script_ = NULL;
      bool ret      = filestream_read_file
         (script, (void**)&script_, &len);

      if (!ret || len < 0)
      {
         RARCH_ERR("Python: Failed to read script\n");
         free(script_);
         goto error;
      }

      PyRun_SimpleString(script_);
      free(script_);
   }
   else
   {
      char *script_ = align_program(script);
      if (script_)
      {
         PyRun_SimpleString(script_);
         free(script_);
      }
   }

   RARCH_LOG("Python: Script loaded.\n");
   handle->dict = PyModule_GetDict(handle->main);
   if (!handle->dict)
   {
      RARCH_ERR("Python: PyModule_GetDict() failed.\n");
      goto error;
   }
   Py_INCREF(handle->dict);

   hook = PyDict_GetItemString(handle->dict, pyclass);
   if (!hook)
   {
      RARCH_ERR("Python: PyDict_GetItemString() failed.\n");
      goto error;
   }

   handle->inst = PyObject_CallFunction(hook, NULL);
   if (!handle->inst)
   {
      RARCH_ERR("Python: PyObject_CallFunction() failed.\n");
      goto error;
   }
   Py_INCREF(handle->inst);

   return handle;

error:
   PyErr_Print();
   PyErr_Clear();
   py_state_free(handle);
   return NULL;
}
Esempio n. 26
0
static bool load_roms(unsigned rom_type, const char **rom_paths, size_t roms)
{
   bool ret = true;

   if (roms == 0)
      return false;

   if (roms > MAX_ROMS)
      return false;

   void *rom_buf[MAX_ROMS] = {NULL};
   ssize_t rom_len[MAX_ROMS] = {0};
   struct retro_game_info info[MAX_ROMS] = {{NULL}};
   char *xml_buf = load_xml_map(g_extern.xml_name);

   FILE *rom_file = NULL;
   if (rom_paths[0])
   {
      RARCH_LOG("Loading ROM file: %s.\n", rom_paths[0]);
      rom_file = fopen(rom_paths[0], "rb");
   }

   if (!g_extern.system.info.need_fullpath)
   {
      if ((rom_len[0] = read_rom_file(rom_file, &rom_buf[0])) == -1)
      {
         RARCH_ERR("Could not read ROM file.\n");
         ret = false;
         goto end;
      }

      RARCH_LOG("ROM size: %u bytes.\n", (unsigned)rom_len[0]);
   }
   else
   {
      if (!rom_file)
      {
         RARCH_ERR("Implementation requires a full path to be set, cannot load ROM from stdin. Aborting ...\n");
         ret = false;
         goto end;
      }

      RARCH_LOG("ROM loading skipped. Implementation will load it on its own.\n");
   }

   info[0].path = rom_paths[0];
   info[0].data = rom_buf[0];
   info[0].size = rom_len[0];
   info[0].meta = xml_buf;

   for (size_t i = 1; i < roms; i++)
   {
      if (rom_paths[i] &&
            !g_extern.system.info.need_fullpath &&
            (rom_len[i] = read_file(rom_paths[i], &rom_buf[i])) == -1)
      {
         RARCH_ERR("Could not read ROM file: \"%s\".\n", rom_paths[i]);
         ret = false;
         goto end;
      }
      
      info[i].path = rom_paths[i];
      info[i].data = rom_buf[i];
      info[i].size = rom_len[i];
   }

   if (rom_type == 0)
      ret = pretro_load_game(&info[0]);
   else
      ret = pretro_load_game_special(rom_type, info, roms);

   if (!ret)
      RARCH_ERR("Failed to load game.\n");

end:
   for (unsigned i = 0; i < MAX_ROMS; i++)
      free(rom_buf[i]);
   free(xml_buf);
   if (rom_file)
      fclose(rom_file);

   return ret;
}
Esempio n. 27
0
static void *audio_ext_init(const char *device, unsigned rate, unsigned latency)
{
   if (!(*g_settings.audio.external_driver))
   {
      RARCH_ERR("Please define an external audio driver.\n");
      return NULL;
   }

   audio_ext_t *ext = (audio_ext_t*)calloc(1, sizeof(*ext));
   if (!ext)
      return NULL;

   rarch_audio_driver_info_t info = {0};
   const rarch_audio_driver_t *(*plugin_load)(void) = NULL;

   ext->lib = dylib_load(g_settings.audio.external_driver);
   if (!ext->lib)
   {
      RARCH_ERR("Failed to load external library \"%s\"\n", g_settings.audio.external_driver);
      goto error;
   }

   plugin_load = (const rarch_audio_driver_t *(*)(void))dylib_proc(ext->lib, "rarch_audio_driver_init");

   if (!plugin_load)
   {
      RARCH_ERR("Failed to find symbol \"rarch_audio_driver_init\" in plugin.\n");
      goto error;
   }

   ext->driver = plugin_load();
   if (!ext->driver)
   {
      RARCH_ERR("Received invalid driver from plugin.\n");
      goto error;
   }

   RARCH_LOG("Loaded external audio driver: \"%s\"\n", ext->driver->ident ? ext->driver->ident : "Unknown");

   if (ext->driver->api_version != RARCH_AUDIO_API_VERSION)
   {
      RARCH_ERR("API mismatch in external audio plugin. RetroArch: %d, Plugin: %d ...\n", RARCH_AUDIO_API_VERSION, ext->driver->api_version);
      goto error;
   }

   info.device = device;
   info.sample_rate = rate;
   info.latency = latency;

   ext->handle = ext->driver->init(&info);
   if (!ext->handle)
   {
      RARCH_ERR("Failed to init audio driver.\n");
      goto error;
   }

   if (ext->driver->sample_rate)
      g_settings.audio.out_rate = ext->driver->sample_rate(ext->handle);

   if (!g_settings.audio.sync)
      ext->driver->set_nonblock_state(ext->handle, RARCH_TRUE);

   return ext;

error:
   audio_ext_free(ext);
   return NULL;
}
Esempio n. 28
0
static void* rmenu_xui_init(void)
{
   HRESULT hr;
   TypefaceDescriptor typeface = {0};

   menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu));

   if (!menu)
      return NULL;

   d3d_video_t *d3d= (d3d_video_t*)driver.video_data;

   if (d3d->resolution_hd_enable)
      RARCH_LOG("HD menus enabled.\n");

   D3DPRESENT_PARAMETERS d3dpp;
   video_info_t video_info = {0};

   video_info.vsync = g_settings.video.vsync;
   video_info.force_aspect = false;
   video_info.smooth = g_settings.video.smooth;
   video_info.input_scale = 2;
   video_info.fullscreen = true;
   video_info.rgb32 = false;

   d3d_make_d3dpp(d3d, &video_info, &d3dpp);

   hr = app.InitShared(d3d->dev, &d3dpp, XuiPNGTextureLoader);

   if (FAILED(hr))
   {
      RARCH_ERR("Failed initializing XUI application.\n");
      goto error;
   }

   /* Register font */
   typeface.szTypeface = L"Arial Unicode MS";
   typeface.szLocator = L"file://game:/media/rarch.ttf";
   typeface.szReserved1 = NULL;

   hr = XuiRegisterTypeface( &typeface, TRUE );
   if (FAILED(hr))
   {
      RARCH_ERR("Failed to register default typeface.\n");
      goto error;
   }

   hr = XuiLoadVisualFromBinary(
         L"file://game:/media/rarch_scene_skin.xur", NULL);
   if (FAILED(hr))
   {
      RARCH_ERR("Failed to load skin.\n");
      goto error;
   }

   hr = XuiSceneCreate(d3d->resolution_hd_enable ?
         L"file://game:/media/hd/" : L"file://game:/media/sd/",
         L"rarch_main.xur", NULL, &root_menu);
   if (FAILED(hr))
   {
      RARCH_ERR("Failed to create scene 'rarch_main.xur'.\n");
      goto error;
   }

   current_menu = root_menu;
   hr = XuiSceneNavigateFirst(app.GetRootObj(),
         current_menu, XUSER_INDEX_FOCUS);
   if (FAILED(hr))
   {
      RARCH_ERR("XuiSceneNavigateFirst failed.\n");
      goto error;
   }

   if (driver.video_data && driver.video_poke
         && driver.video_poke->set_texture_enable)
      driver.video_poke->set_texture_frame(driver.video_data, NULL,
            true, 0, 0, 1.0f);

   xui_msg_queue = msg_queue_new(16);

   return menu;

error:
   free(menu);
   return NULL;
}
Esempio n. 29
0
/* Initializes and loads a content file for the currently
 * selected libretro core. */
bool content_init(void)
{
   content_information_ctx_t content_ctx;

   bool ret                                   = true;
   char *error_string                         = NULL;
   rarch_system_info_t *sys_info              = NULL;
   settings_t *settings                       = config_get_ptr();
   temporary_content                          = string_list_new();

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &sys_info);

   content_ctx.temporary_content              = temporary_content;
   content_ctx.history_list_enable            = false;
   content_ctx.directory_system               = NULL;
   content_ctx.directory_cache                = NULL;
   content_ctx.valid_extensions               = NULL;
   content_ctx.block_extract                  = false;
   content_ctx.need_fullpath                  = false;
   content_ctx.set_supports_no_game_enable    = false;

   content_ctx.subsystem.data                 = NULL;
   content_ctx.subsystem.size                 = 0;
   
   if (sys_info)
   {
      content_ctx.history_list_enable         = settings->history_list_enable;
      content_ctx.set_supports_no_game_enable = settings->set_supports_no_game_enable;

      if (!string_is_empty(settings->directory.system))
         content_ctx.directory_system         = strdup(settings->directory.system);
      if (!string_is_empty(settings->directory.cache))
         content_ctx.directory_cache          = strdup(settings->directory.cache);
      if (!string_is_empty(sys_info->info.valid_extensions))
         content_ctx.valid_extensions         = strdup(sys_info->info.valid_extensions);

      content_ctx.block_extract               = sys_info->info.block_extract;
      content_ctx.need_fullpath               = sys_info->info.need_fullpath;

      content_ctx.subsystem.data              = sys_info->subsystem.data;
      content_ctx.subsystem.size              = sys_info->subsystem.size;
   }

   if (     !temporary_content 
         || !content_file_init(&content_ctx, error_string))
   {
      content_deinit();

      ret = false;
      goto end;
   }

   _content_is_inited = true;

end:
   if (content_ctx.directory_system)
      free(content_ctx.directory_system);
   if (content_ctx.directory_cache)
      free(content_ctx.directory_cache);
   if (content_ctx.valid_extensions)
      free(content_ctx.valid_extensions);

   if (error_string)
   {
      if (ret)
      {
         RARCH_LOG("%s\n", error_string);
      }
      else
      {
         RARCH_ERR("%s\n", error_string);
      }
      runloop_msg_queue_push(error_string, 2, ret ? 1 : 180, true);
      free(error_string);
   }

   return ret;
}
Esempio n. 30
0
static void gfx_ctx_set_swap_interval(unsigned interval)
{
   RARCH_LOG("gfx_ctx_set_swap_interval(%d).\n", interval);
   eglSwapInterval(g_egl_dpy, interval);
}