Пример #1
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)
{
#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);
    }
}
Пример #2
0
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;
}
Пример #3
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);
    }
}