/* Refresh a canvas. */ void video_canvas_refresh(video_canvas_t *canvas, unsigned int xs, unsigned int ys, unsigned int xi, unsigned int yi, unsigned int w, unsigned int h) { #if 0 log_debug("XS%i YS%i XI%i YI%i W%i H%i PS%i", xs, ys, xi, yi, w, h, canvas->draw_buffer->draw_buffer_width); #endif if (console_mode || video_disabled_mode) { return; } if (canvas->videoconfig->doublesizex) { xi *= (canvas->videoconfig->doublesizex + 1); w *= (canvas->videoconfig->doublesizex + 1); } if (canvas->videoconfig->doublesizey) { yi *= (canvas->videoconfig->doublesizey + 1); h *= (canvas->videoconfig->doublesizey + 1); } #ifdef HAVE_FULLSCREEN if (canvas->video_fullscreen_refresh_func) { canvas->video_fullscreen_refresh_func(canvas, xs, ys, xi, yi, w, h); return; } #endif if (xi + w > canvas->gdk_image->width || yi + h > canvas->gdk_image->height) { #ifdef DEBUG log_debug("Attempt to draw outside canvas!\nXI%i YI%i W%i H%i CW%i CH%i\n", xi, yi, w, h, canvas->gdk_image->width, canvas->gdk_image->height); #endif return; } #ifdef HAVE_HWSCALE if (canvas->videoconfig->hwscale) { video_canvas_render(canvas, canvas->hwscale_image, w, h, xs, ys, xi, yi, canvas->gdk_image->width * 4, 32); gtk_widget_queue_draw(canvas->emuwindow); } else #endif { video_canvas_render(canvas, canvas->gdk_image->mem, w, h, xs, ys, xi, yi, canvas->gdk_image->bpl, canvas->gdk_image->bits_per_pixel); gtk_widget_queue_draw_area(canvas->emuwindow, xi, yi, w, h); } }
int video_canvas_refresh_dx9(video_canvas_t *canvas, unsigned int xs, unsigned int ys, unsigned int xi, unsigned int yi, unsigned int w, unsigned int h) { HRESULT stretchresult; LPDIRECT3DSURFACE9 d3dbackbuffer = NULL; D3DLOCKED_RECT lockedrect; if (canvas->videoconfig->doublesizex) { xi *= (canvas->videoconfig->doublesizex + 1); w *= (canvas->videoconfig->doublesizex + 1); } if (canvas->videoconfig->doublesizey) { yi *= (canvas->videoconfig->doublesizey + 1); h *= (canvas->videoconfig->doublesizey + 1); } if (S_OK != video_canvas_prepare_for_update(canvas)) { return -1; } if (S_OK != IDirect3DDevice9_Clear(canvas->d3ddev, 0, NULL, D3DCLEAR_TARGET, 0, 0, 0) || S_OK != IDirect3DDevice9_BeginScene(canvas->d3ddev) || S_OK != IDirect3DDevice9_GetBackBuffer(canvas->d3ddev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dbackbuffer) || S_OK != IDirect3DSurface9_LockRect(canvas->d3dsurface, &lockedrect, NULL, 0)) { log_debug("video_dx9: Failed to prepare for rendering!"); return -1; } video_canvas_render(canvas, lockedrect.pBits, w, h, xs, ys, xi, yi, lockedrect.Pitch, 32); //video_save_screen ("c:\\temp\\screens\\", w, h, 32, lockedrect.pBits); if (S_OK != IDirect3DSurface9_UnlockRect(canvas->d3dsurface)) { log_debug("video_dx9: Failed to unlock surface!"); return -1; } do { stretchresult = IDirect3DDevice9_StretchRect(canvas->d3ddev, canvas->d3dsurface, NULL, d3dbackbuffer, canvas->dest_rect_ptr, d3dpreffilter); if (d3dpreffilter == D3DTEXF_NONE) { break; } if (stretchresult != S_OK) { /* Some adapters don't support filtering */ d3dpreffilter = D3DTEXF_NONE; log_debug("video_dx9: Disabled StretchRect filtering!"); } } while (stretchresult != S_OK); if (stretchresult != S_OK) { log_debug("video_dx9: StretchRect failed even without filtering!"); } if (S_OK != IDirect3DSurface9_Release(d3dbackbuffer) || S_OK != IDirect3DDevice9_EndScene(canvas->d3ddev)) { log_debug("video_dx9: EndScene failed!"); return -1; } if (S_OK != IDirect3DDevice9_Present(canvas->d3ddev, NULL, NULL, NULL, NULL)) { log_debug("video_dx9: Refresh failed to present the scene!"); return -1; } return 0; }
/* Refresh a canvas. */ void video_canvas_refresh(video_canvas_t *canvas, unsigned int xs, unsigned int ys, unsigned int xi, unsigned int yi, unsigned int w, unsigned int h) { Display *display; if (console_mode || vsid_mode) { return; } #ifdef HAVE_XVIDEO if (canvas->videoconfig->hwscale && canvas->xv_image) { int doublesize = canvas->videoconfig->doublesizex && canvas->videoconfig->doublesizey; #if defined(__QNX__) || defined(MINIX_SUPPORT) XShmSegmentInfo* shminfo = NULL; #else XShmSegmentInfo* shminfo = use_mitshm ? &canvas->xshm_info : NULL; #endif Window root; int x, y; unsigned int border_width, depth; unsigned int canvas_height; double local_aspect_ratio; display = x11ui_get_display_ptr(); render_yuv_image(doublesize, canvas->viewport, video_resources.delayloop_emulation, video_resources.pal_blur * 64 / 1000, video_resources.pal_scanlineshade * 1024 / 1000, canvas->xv_format, &canvas->yuv_image, canvas->draw_buffer->draw_buffer, canvas->draw_buffer->draw_buffer_width, canvas->videoconfig, xs, ys, w, h, xi, yi); /* * render_yuv_image() doesn't handle 1x2 drawing modes. * So it mistakenly fills only half the canvas vertically. * However, that is what we can use the hardware scaling for! */ canvas_height = canvas->height; if (trueaspect) { local_aspect_ratio = canvas->geometry->pixel_aspect_ratio; } else if (keepaspect) { local_aspect_ratio = aspect_ratio; } else { local_aspect_ratio = 0.0; } if (!doublesize && canvas->videoconfig->doublesizey) { canvas_height /= 2; local_aspect_ratio /= 2; } XGetGeometry(display, canvas->drawable, &root, &x, &y, &canvas->xv_geometry.w, &canvas->xv_geometry.h, &border_width, &depth); /* Xv does subpixel scaling. Since coordinates are in integers we refresh the entire image to get it right. */ display_yuv_image(display, canvas->xv_port, canvas->drawable, _video_gc, canvas->xv_image, shminfo, 0, 0, canvas->width, canvas_height, &canvas->xv_geometry, local_aspect_ratio); if (_video_use_xsync) { XSync(display, False); } return; } #endif if (canvas->videoconfig->doublesizex) { xi *= 2; w *= 2; } if (canvas->videoconfig->doublesizey) { yi *= 2; h *= 2; } #ifdef HAVE_FULLSCREEN if (canvas->video_fullscreen_refresh_func) { canvas->video_fullscreen_refresh_func(canvas, xs, ys, xi, yi, w, h); return; } #endif if (xi + w > canvas->width || yi + h > canvas->height) { log_debug("Attempt to draw outside canvas!\nXI%i YI%i W%i H%i CW%i CH%i\n", xi, yi, w, h, canvas->width, canvas->height); return; /* this makes `-fullscreen -80col' work XXX fix me some day */ } if ((int)xs >= 0) { /* some render routines don't like negative xs */ video_canvas_render(canvas, (BYTE *)canvas->x_image->data, w, h, xs, ys, xi, yi, canvas->x_image->bytes_per_line, canvas->x_image->bits_per_pixel); } /* This could be optimized away. */ display = x11ui_get_display_ptr(); _refresh_func(display, canvas->drawable, _video_gc, canvas->x_image, xi, yi, xi, yi, w, h, False, NULL, canvas); if (_video_use_xsync) { XSync(display, False); } }