Ejemplo n.º 1
0
static bool xdk_d3d_frame(void *data, const void *frame,
      unsigned width, unsigned height, unsigned pitch, const char *msg)
{
   if (!frame)
      return true;

   xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data;
   bool menu_enabled = g_console.menu_enable;
   bool fps_enable = g_console.fps_info_enable;

   if (d3d->last_width != width || d3d->last_height != height) //240*160
   {

      D3DLOCKED_RECT d3dlr;

      d3d->lpTexture->LockRect(0, &d3dlr, NULL, 0);
      memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch);
      d3d->lpTexture->UnlockRect(0);

      float tex_w = width;  // / 512.0f;
      float tex_h = height; // / 512.0f;

      DrawVerticeFormats verts[] = {
         { -1.0f, -1.0f, 1.0f, 0.0f,  tex_h },
         {  1.0f, -1.0f, 1.0f, tex_w, tex_h },
         { -1.0f,  1.0f, 1.0f, 0.0f,  0.0f },
         {  1.0f,  1.0f, 1.0f, tex_w, 0.0f },
      };

      // Align texels and vertices (D3D9 quirk).
      for (unsigned i = 0; i < 4; i++)
      {
         verts[i].x -= 0.5f / 512.0f;
         verts[i].y += 0.5f / 512.0f;
      }

      BYTE *verts_ptr;
      d3d->vertex_buf->Lock(0, 0, &verts_ptr, 0);
      memcpy(verts_ptr, verts, sizeof(verts));
      d3d->vertex_buf->Unlock();

      d3d->last_width = width;
      d3d->last_height = height;
   }

   if (d3d->should_resize)
      xdk_d3d_set_viewport(false);

   d3d->frame_count++;

   d3d->d3d_render_device->SetTexture(0, d3d->lpTexture);

   D3DLOCKED_RECT d3dlr;

   d3d->lpTexture->LockRect(0, &d3dlr, NULL, 0);
   for (unsigned y = 0; y < height; y++)
   {
      const uint8_t *in = (const uint8_t*)frame + y * pitch;
      uint8_t *out = (uint8_t*)d3dlr.pBits + y * d3dlr.Pitch;
      memcpy(out, in, width * sizeof(uint16_t));
   }
   d3d->lpTexture->UnlockRect(0);


   d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_MINFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
   d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_MAGFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
   d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
   d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);

   D3DXMATRIX p_out;
   D3DXMatrixIdentity(&p_out);
   d3d->d3d_render_device->SetTransform(D3DTS_WORLD, &p_out);
   d3d->d3d_render_device->SetTransform(D3DTS_VIEW, &p_out);
   d3d->d3d_render_device->SetTransform(D3DTS_PROJECTION, &p_out);

   d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
   d3d->d3d_render_device->SetStreamSource(0, d3d->vertex_buf, sizeof(DrawVerticeFormats));
   d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);

   d3d->d3d_render_device->BeginScene();
   d3d->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
   d3d->d3d_render_device->EndScene();

   if(fps_enable)
   {
      static MEMORYSTATUS stat;
      GlobalMemoryStatus(&stat);
      d3d->d3d_render_device->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &d3d->pFrontBuffer);
      d3d->d3d_render_device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &d3d->pBackBuffer);

      //Output memory usage

      char buf[128], buf2[128], buf_fps_last[128];
      bool ret = false;
      sprintf(buf, "%.2f MB free / %.2f MB total", stat.dwAvailPhys/(1024.0f*1024.0f), stat.dwTotalPhys/(1024.0f*1024.0f));
      rarch_convert_char_to_wchar(strw_buffer, buf, sizeof(strw_buffer));
      d3d->debug_font->TextOut(d3d->pFrontBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 50 );
      d3d->debug_font->TextOut(d3d->pBackBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 50 );

      if(ret = gfx_window_title(buf2, sizeof(buf2)) || sizeof(buf_fps_last))
      {
         if(ret)
	 {
            sprintf(buf_fps_last, buf2);
	    rarch_convert_char_to_wchar(strw_buffer, buf2, sizeof(strw_buffer));
	 }
         else if(buf_fps_last)
            rarch_convert_char_to_wchar(strw_buffer, buf_fps_last, sizeof(strw_buffer));

	 d3d->debug_font->TextOut(d3d->pFrontBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 70 );
	 d3d->debug_font->TextOut(d3d->pBackBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 70 );
	 d3d->pFrontBuffer->Release();
	 d3d->pBackBuffer->Release();
      }
   }

   if(!d3d->block_swap)
      gfx_ctx_swap_buffers();

   return true;
}
Ejemplo n.º 2
0
static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
#ifdef _WIN32
   gfx_set_dwm();
#endif

   if (!sdlwrap_init())
      return NULL;

   const SDL_VideoInfo *video_info = SDL_GetVideoInfo();
   rarch_assert(video_info);
   unsigned full_x = video_info->current_w;
   unsigned full_y = video_info->current_h;
   RARCH_LOG("Detecting desktop resolution %ux%u.\n", full_x, full_y);

   sdlwrap_set_swap_interval(video->vsync ? 1 : 0, false);

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

   if (!sdlwrap_set_video_mode(win_width, win_height,
            g_settings.video.force_16bit ? 15 : 0, video->fullscreen))
      return NULL;

   gfx_window_title_reset();
   char buf[128];
   if (gfx_window_title(buf, sizeof(buf)))
      sdlwrap_wm_set_caption(buf);

   // Remove that ugly mouse :D
   SDL_ShowCursor(SDL_DISABLE);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32)
   // Win32 GL lib doesn't have some functions needed for XML shaders.
   // Need to load dynamically :(
   if (!load_gl_proc())
   {
      sdlwrap_destroy();
      return NULL;
   }
#endif

   gl_t *gl = (gl_t*)calloc(1, sizeof(gl_t));
   if (!gl)
   {
      sdlwrap_destroy();
      return NULL;
   }

   gl->vsync = video->vsync;
   gl->fullscreen = video->fullscreen;
   
   gl->full_x = full_x;
   gl->full_y = full_y;
   gl->win_width = win_width;
   gl->win_height = win_height;

   RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);

   if (!gl_shader_init())
   {
      RARCH_ERR("Shader init failed.\n");
      sdlwrap_destroy();
      free(gl);
      return NULL;
   }

   RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num());

#ifdef HAVE_FBO
   // Set up render to texture.
   gl_init_fbo(gl, RARCH_SCALE_BASE * video->input_scale,
         RARCH_SCALE_BASE * video->input_scale);
#endif
   
   gl->keep_aspect = video->force_aspect;

   // Apparently need to set viewport for passes when we aren't using FBOs.
   gl_shader_use(0);
   set_viewport(gl, gl->win_width, gl->win_height, false, true);
   gl_shader_use(1);
   set_viewport(gl, gl->win_width, gl->win_height, false, true);

   bool force_smooth;
   if (gl_shader_filter_type(1, &force_smooth))
      gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST;
   else
      gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST;

   gl->texture_type = GL_BGRA;
   gl->texture_fmt = video->rgb32 ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_SHORT_1_5_5_5_REV;
   gl->base_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t);

   glEnable(GL_TEXTURE_2D);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_DITHER);
   glClearColor(0, 0, 0, 1);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glGenTextures(TEXTURES, gl->texture);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      glBindTexture(GL_TEXTURE_2D, gl->texture[i]);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter);
   }

   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glEnableClientState(GL_COLOR_ARRAY);
   glVertexPointer(2, GL_FLOAT, 0, vertexes_flipped);

   memcpy(gl->tex_coords, tex_coords, sizeof(tex_coords));
   glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords);

   glColorPointer(4, GL_FLOAT, 0, white_color);

   set_lut_texture_coords(tex_coords);

   gl->tex_w = RARCH_SCALE_BASE * video->input_scale;
   gl->tex_h = RARCH_SCALE_BASE * video->input_scale;

   // Empty buffer that we use to clear out the texture with on res change.
   gl->empty_buf = calloc(gl->tex_w * gl->tex_h, gl->base_size);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
      glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);
      glTexImage2D(GL_TEXTURE_2D,
            0, GL_RGBA, gl->tex_w, gl->tex_h, 0, gl->texture_type,
            gl->texture_fmt, gl->empty_buf ? gl->empty_buf : NULL);
   }
   glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->last_width[i] = gl->tex_w;
      gl->last_height[i] = gl->tex_h;
   }

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->prev_info[i].tex = gl->texture[(gl->tex_index - (i + 1)) & TEXTURES_MASK];
      gl->prev_info[i].input_size[0] = gl->tex_w;
      gl->prev_info[i].tex_size[0] = gl->tex_w;
      gl->prev_info[i].input_size[1] = gl->tex_h;
      gl->prev_info[i].tex_size[1] = gl->tex_h;
      memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords)); 
   }

   // Hook up SDL input driver to get SDL_QUIT events and RESIZE.
   sdl_input_t *sdl_input = (sdl_input_t*)input_sdl.init();
   if (sdl_input)
   {
      *input = &input_sdl;
      *input_data = sdl_input;
   }
   else
      *input = NULL;

   gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size);
      
   if (!gl_check_error())
   {
      sdlwrap_destroy();
      free(gl);
      return NULL;
   }

   return gl;
}
Ejemplo n.º 3
0
static bool setup_video(ext_t *ext, const video_info_t *video, const input_driver_t **input, void **input_data)
{
   RARCH_LOG("Loaded driver: \"%s\"\n", ext->driver->ident ? ext->driver->ident : "Unknown");

   if (RARCH_GRAPHICS_API_VERSION != ext->driver->api_version)
   {
      RARCH_ERR("API version mismatch detected.\n");
      RARCH_ERR("Required API version: %d, Library version: %d\n", RARCH_GRAPHICS_API_VERSION, ext->driver->api_version);
      return false;
   }

   const char *cg_shader  = NULL;
   const char *xml_shader = NULL;

   enum rarch_shader_type type = g_settings.video.shader_type;

   if ((type == RARCH_SHADER_CG || type == RARCH_SHADER_AUTO) && *g_settings.video.cg_shader_path)
      cg_shader = g_settings.video.cg_shader_path;
   else if ((type == RARCH_SHADER_BSNES || type == RARCH_SHADER_AUTO) && *g_settings.video.bsnes_shader_path)
      xml_shader = g_settings.video.bsnes_shader_path;

   int font_color_r = g_settings.video.msg_color_r * 255;
   int font_color_g = g_settings.video.msg_color_g * 255;
   int font_color_b = g_settings.video.msg_color_b * 255;
   font_color_r = font_color_r > 255 ? 255 : (font_color_r < 0 ? 0 : font_color_r);
   font_color_g = font_color_g > 255 ? 255 : (font_color_g < 0 ? 0 : font_color_g);
   font_color_b = font_color_b > 255 ? 255 : (font_color_b < 0 ? 0 : font_color_b);

   const char *font = NULL;
   if (g_settings.video.font_enable)
   {
#ifdef HAVE_FREETYPE
      if (*g_settings.video.font_path)
         font = g_settings.video.font_path;
      else
         font = font_renderer_get_default_font();
#else
      font = *g_settings.video.font_path ?
         g_settings.video.font_path : NULL;
#endif
   }

   char title_buf[128];
   gfx_window_title_reset();
   gfx_window_title(title_buf, sizeof(title_buf));

   rarch_video_info_t info = {0};
   info.width              = video->width;
   info.height             = video->height;
   info.fullscreen         = video->fullscreen;
   info.vsync              = video->vsync;
   info.force_aspect       = video->force_aspect;
   info.aspect_ratio       = g_settings.video.aspect_ratio;
   info.smooth             = video->smooth;
   info.input_scale        = video->input_scale;
   info.color_format       = video->rgb32 ? RARCH_COLOR_FORMAT_ARGB8888 : RARCH_COLOR_FORMAT_XRGB1555;
   info.xml_shader         = xml_shader;
   info.cg_shader          = cg_shader;
   info.ttf_font           = font;
   info.ttf_font_size      = g_settings.video.font_size;
   info.ttf_font_color     = (font_color_r << 16) | (font_color_g << 8) | (font_color_b << 0);
   info.title_hint         = title_buf;

#ifdef HAVE_PYTHON
   info.python_state_new  = py_state_new;
   info.python_state_get  = py_state_get;
   info.python_state_free = py_state_free;
#endif

   const rarch_input_driver_t *input_driver = NULL;
   ext->handle = ext->driver->init(&info, &input_driver);
   if (!ext->handle)
      return false;

   *input = input_driver ? &input_ext : NULL;
   if (input_driver)
      *input_data = setup_input(ext, input_driver);
   else
      *input_data = NULL;

   return true;
}
Ejemplo n.º 4
0
static bool gl_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
{
   gl_t *gl = (gl_t*)data;

   gl_shader_use(1);
   gl->frame_count++;

   glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);

#ifdef HAVE_FBO
   // Render to texture in first pass.
   if (gl->fbo_inited)
   {
      // Recompute FBO geometry.
      // When width/height changes or window sizes change, we have to recalcuate geometry of our FBO.
      gl_compute_fbo_geometry(gl, width, height, gl->vp_out_width, gl->vp_out_height);
      gl_start_frame_fbo(gl);
   }
#endif

   if (gl->should_resize)
   {
      gl->should_resize = false;
      sdlwrap_set_resize(gl->win_width, gl->win_height);

      // On resize, we might have to recreate our FBOs due to "Viewport" scale, and set a new viewport.
      gl_update_resize(gl);
   }

   gl_update_input_size(gl, width, height, pitch);

   gl_copy_frame(gl, frame, width, height, pitch);

   struct gl_tex_info tex_info = {0};
   tex_info.tex           = gl->texture[gl->tex_index];
   tex_info.input_size[0] = width;
   tex_info.input_size[1] = height;
   tex_info.tex_size[0]   = gl->tex_w;
   tex_info.tex_size[1]   = gl->tex_h;

   memcpy(tex_info.coord, gl->tex_coords, sizeof(gl->tex_coords));

   glClear(GL_COLOR_BUFFER_BIT);
   gl_shader_set_params(width, height,
         gl->tex_w, gl->tex_h,
         gl->vp_width, gl->vp_height,
         gl->frame_count, 
         &tex_info, gl->prev_info, NULL, 0);

   glDrawArrays(GL_QUADS, 0, 4);

#ifdef HAVE_FBO
   if (gl->fbo_inited)
      gl_frame_fbo(gl, &tex_info);
#endif

   gl_next_texture_index(gl, &tex_info);

   if (msg)
      gl_render_msg(gl, msg);

   char buf[128];
   if (gfx_window_title(buf, sizeof(buf)))
      sdlwrap_wm_set_caption(buf);

   sdlwrap_swap_buffers();

   return true;
}