diff options
Diffstat (limited to 'plugins/gxvideo/draw.c')
| -rw-r--r-- | plugins/gxvideo/draw.c | 757 |
1 files changed, 757 insertions, 0 deletions
diff --git a/plugins/gxvideo/draw.c b/plugins/gxvideo/draw.c new file mode 100644 index 00000000..c8d6c7e0 --- /dev/null +++ b/plugins/gxvideo/draw.c @@ -0,0 +1,757 @@ +/* + * Copyright (C) 2010 Benoit Gschwind + * Inspired by original author : Pete Bernert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <sys/shm.h> +#include <X11/cursorfont.h> + +#include "globals.h" +#include "swap.h" + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +enum { + GXV_YUV_PORT = 0, GXV_RGB_PORT = 1, GXV_MAX_PORT = 2, +}; + +gxv_blit_t available_port[GXV_MAX_PORT]; + +/* Convert RGB to YUV */ +inline uint32_t rgb_to_yuv(uint8_t R, uint8_t G, uint8_t B) { + uint8_t Y, U, V; + Y = abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13; + Y = MIN(Y, 235); + U = abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13; + U = MIN(U, 240); + V = abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13; + V = MIN(V, 240); + return Y << 24 | V << 16 | Y << 8 | U; +} + +inline uint32_t rgb_to_yuv2(uint8_t R0, uint8_t G0, uint8_t B0, uint8_t R1, + uint8_t G1, uint8_t B1) { + int32_t Y0, U0, V0; + int32_t Y1, U1, V1; + int32_t U, V; + Y0 = abs(R0 * 2104 + G0 * 4130 + B0 * 802 + 4096 + 131072) >> 13; + Y0 = MIN(Y0, 235); + U0 = abs(R0 * -1214 + G0 * -2384 + B0 * 3598 + 4096 + 1048576) >> 13; + U0 = MIN(U0, 240); + V0 = abs(R0 * 3598 + G0 * -3013 + B0 * -585 + 4096 + 1048576) >> 13; + V0 = MIN(V0, 240); + Y1 = abs(R1 * 2104 + G1 * 4130 + B1 * 802 + 4096 + 131072) >> 13; + Y1 = MIN(Y1, 235); + U1 = abs(R1 * -1214 + G1 * -2384 + B1 * 3598 + 4096 + 1048576) >> 13; + U1 = MIN(U1, 240); + V1 = abs(R1 * 3598 + G1 * -3013 + B1 * -585 + 4096 + 1048576) >> 13; + V1 = MIN(V1, 240); + U = (U0 + U1) / 2; + V = (V0 + V1) / 2; + return Y1 << 24 | V << 16 | Y0 << 8 | U; +} + +#define colorMask8 0x00FEFEFE +#define lowPixelMask8 0x00010101 +#define qcolorMask8 0x00FCFCFC +#define qlowpixelMask8 0x00030303 + +static Atom xv_intern_atom_if_exists(Display *display, char const * atom_name) { + XvAttribute * attributes; + int attrib_count, i; + Atom xv_atom = None; + + attributes = XvQueryPortAttributes(display, g_draw.xv_port, &attrib_count); + if (attributes != NULL) { + for (i = 0; i < attrib_count; ++i) { + if (strcmp(attributes[i].name, atom_name) == 0) { + xv_atom = XInternAtom(display, atom_name, False); + break; // found what we want, break out + } + } + XFree(attributes); + } + + return xv_atom; +} + +// close display + +void DestroyDisplay(void) { + if (g_draw.display) { + XFreeColormap(g_draw.display, g_draw.colormap); + if (g_draw.hGC) { + XFreeGC(g_draw.display, g_draw.hGC); + g_draw.hGC = 0; + } + if (g_draw.Ximage) { + XDestroyImage(g_draw.Ximage); + g_draw.Ximage = 0; + } + if (g_draw.XCimage) { + XFree(g_draw.XCimage); + g_draw.XCimage = 0; + } + if (g_draw.XFimage) { + XDestroyImage(g_draw.XFimage); + g_draw.XFimage = 0; + } + + XShmDetach(g_draw.display, &g_draw.shminfo); + shmdt(g_draw.shminfo.shmaddr); + shmctl(g_draw.shminfo.shmid, IPC_RMID, NULL); + + Atom atom_vsync = xv_intern_atom_if_exists(g_draw.display, + "XV_SYNC_TO_VBLANK"); + if (atom_vsync != None) { + XvSetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync, + g_draw.xv_vsync); + } + + XSync(g_draw.display, False); + + XCloseDisplay(g_draw.display); + } +} + +// Create display + +void create_display(void) { + //fprintf(stderr, "Entering %s\n", __FUNCTION__); + XSetWindowAttributes winattr; + int myscreen; + Screen * screen; + XEvent event; + XSizeHints hints; + XWMHints wm_hints; + MotifWmHints mwmhints; + Atom mwmatom; + + Atom delwindow; + + XGCValues gcv; + int i; + + int ret, j, p; + int formats; + unsigned int p_num_adaptors = 0, p_num_ports = 0; + + XvAdaptorInfo *ai; + XvImageFormatValues *fo; + + // Open display + g_draw.display = XOpenDisplay(NULL); + + if (!g_draw.display) { + fprintf(stderr, "Failed to open display!!!\n"); + DestroyDisplay(); + return; + } + + myscreen = DefaultScreen(g_draw.display); + + // desktop fullscreen switch + if (g_cfg.FullScreen) + g_draw.fx = 1; + + screen = DefaultScreenOfDisplay(g_draw.display); + + g_draw.root_window_id = RootWindow(g_draw.display, myscreen); + + //Look for an Xvideo RGB port + ret = XvQueryAdaptors(g_draw.display, g_draw.root_window_id, + &p_num_adaptors, &ai); + if (ret != Success) { + if (ret == XvBadExtension) + fprintf(stderr, "XvBadExtension returned at XvQueryExtension.\n"); + else if (ret == XvBadAlloc) + fprintf(stderr, "XvBadAlloc returned at XvQueryExtension.\n"); + else + fprintf(stderr, "other error happaned at XvQueryAdaptors.\n"); + exit(EXIT_FAILURE); + } + + g_draw.depth = DefaultDepth(g_draw.display, myscreen); + + g_draw.xv_id = -1; + g_draw.xv_port = -1; + g_draw.xv = -1; + + for (i = 0; i < p_num_adaptors; i++) { + p_num_ports = ai[i].base_id + ai[i].num_ports; + for (p = ai[i].base_id; p < p_num_ports; p++) { + fo = XvListImageFormats(g_draw.display, p, &formats); + for (j = 0; j < formats; ++j) { + + if (fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 + && fo[j].format == XvPacked && strncmp("UYVY", + fo[j].component_order, 4) == 0) { + g_draw.xv_port = p; + g_draw.xv_id = fo[j].id; + + g_draw.xv = GXV_YUV_PORT; + j = formats; + p = p_num_ports; + i = p_num_adaptors; + break; + } + + if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32) { + g_draw.xv_port = p; + g_draw.xv_id = fo[j].id; + printf("RGB mode found. id: %x\n", g_draw.xv_id); + g_draw.xv = GXV_RGB_PORT; + //break out of loops + j = formats; + p = p_num_ports; + i = p_num_adaptors; + } + } + + if (fo) + XFree(fo); + } + } + + if (p_num_adaptors > 0) + XvFreeAdaptorInfo(ai); + + if (g_draw.xv < 0) { + fprintf(stderr, "RGB & YUV not found. Quitting.\n"); + exit(EXIT_FAILURE); + } + + Atom atom_vsync = xv_intern_atom_if_exists(g_draw.display, + "XV_SYNC_TO_VBLANK"); + if (atom_vsync != None) { + XvGetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync, + &g_draw.xv_vsync); + XvSetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync, 0); + } + + g_draw.myvisual = 0; + + if (XMatchVisualInfo(g_draw.display, myscreen, g_draw.depth, TrueColor, + &g_draw.vi)) + g_draw.myvisual = &g_draw.vi; + + if (!g_draw.myvisual) { + fprintf(stderr, "Failed to obtain visual!\n"); + DestroyDisplay(); + return; + } + + if (!g_cfg.FullScreen) + g_draw.cursor = XCreateFontCursor(g_draw.display, XC_trek); + else { + g_draw.cursor = None; + } + + g_draw.colormap = XCreateColormap(g_draw.display, g_draw.root_window_id, + g_draw.myvisual->visual, AllocNone); + + winattr.background_pixel = BlackPixelOfScreen(screen); + winattr.border_pixel = WhitePixelOfScreen(screen); + winattr.bit_gravity = ForgetGravity; + winattr.win_gravity = NorthWestGravity; + winattr.backing_store = NotUseful; + + winattr.override_redirect = False; + winattr.save_under = False; + winattr.event_mask = 0; + winattr.do_not_propagate_mask = 0; + winattr.colormap = g_draw.colormap; + winattr.cursor = None; + + g_draw.window = XCreateWindow(g_draw.display, g_draw.root_window_id, 0, 0, + g_cfg.ResX, g_cfg.ResY, 0, g_draw.myvisual->depth, InputOutput, + g_draw.myvisual->visual, CWBorderPixel | CWBackPixel | CWEventMask + | CWDontPropagate | CWColormap | CWCursor, &winattr); + + if (!g_draw.window) { + fprintf(stderr, "Failed in XCreateWindow()!!!\n"); + DestroyDisplay(); + return; + } + + delwindow = XInternAtom(g_draw.display, "WM_DELETE_WINDOW", 0); + XSetWMProtocols(g_draw.display, g_draw.window, &delwindow, 1); + + hints.flags = USPosition | USSize; + hints.base_width = g_cfg.ResX; + hints.base_height = g_cfg.ResY; + + wm_hints.input = 1; + wm_hints.flags = InputHint; + + XSetWMHints(g_draw.display, g_draw.window, &wm_hints); + XSetWMNormalHints(g_draw.display, g_draw.window, &hints); + //if (pCaptionText) + // XStoreName(draw_ctx.display, draw_ctx.window, pCaptionText); + //else + XStoreName(g_draw.display, g_draw.window, "GXVideo GPU"); + + XDefineCursor(g_draw.display, g_draw.window, g_draw.cursor); + + // hack to get rid of window title bar + if (g_draw.fx) { + mwmhints.flags = MWM_HINTS_DECORATIONS; + mwmhints.decorations = 0; + mwmatom = XInternAtom(g_draw.display, "_MOTIF_WM_HINTS", 0); + XChangeProperty(g_draw.display, g_draw.window, mwmatom, mwmatom, 32, + PropModeReplace, (unsigned char *) &mwmhints, 4); + } + + // key stuff + XSelectInput(g_draw.display, g_draw.window, FocusChangeMask | ExposureMask + | KeyPressMask | KeyReleaseMask); + + XMapRaised(g_draw.display, g_draw.window); + XClearWindow(g_draw.display, g_draw.window); + XWindowEvent(g_draw.display, g_draw.window, ExposureMask, &event); + + if (g_draw.fx) { + XResizeWindow(g_draw.display, g_draw.window, screen->width, + screen->height); + + hints.min_width = hints.max_width = hints.base_width = screen->width; + hints.min_height = hints.max_height = hints.base_height + = screen->height; + + XSetWMNormalHints(g_draw.display, g_draw.window, &hints); + + // set the window layer for GNOME + { + XEvent xev; + + memset(&xev, 0, sizeof(xev)); + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = 1; + xev.xclient.message_type = XInternAtom(g_draw.display, + "_NET_WM_STATE", 0); + xev.xclient.window = g_draw.window; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = XInternAtom(g_draw.display, + "_NET_WM_STATE_FULLSCREEN", 0); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent(g_draw.display, g_draw.root_window_id, 0, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); + } + } + + gcv.graphics_exposures = False; + gcv.foreground = WhitePixelOfScreen(screen); + gcv.background = BlackPixelOfScreen(screen); + g_draw.hGC = XCreateGC(g_draw.display, g_draw.window, GCGraphicsExposures + |GCForeground | GCBackground, &gcv); + if (!g_draw.hGC) { + fprintf(stderr, "No gfx context!!!\n"); + DestroyDisplay(); + } + + g_draw.Xpixels = (char *) malloc(600 * 15 * 4); + + uint32_t color; + if (g_draw.xv == GXV_YUV_PORT) + color = rgb_to_yuv(0x00, 0x00, 0xff); + else + color = 0x0000ff; + + for (i = 0; i < 600 * 15; ++i) + ((uint32_t *) g_draw.Xpixels)[i] = color; + + g_draw.XFimage = XCreateImage(g_draw.display, g_draw.myvisual->visual, + g_draw.depth, ZPixmap, 0, (char *) g_draw.Xpixels, 600, 15, + g_draw.depth > 16 ? 32 : 16, 0); + + /* fix the green back ground in YUV mode */ + if (g_draw.xv == GXV_YUV_PORT) + color = rgb_to_yuv(0x00, 0x00, 0x00); + else + color = 0; + + g_draw.Xpixels = (char *) malloc(8 * 8 * 4); + for (i = 0; i < 8 * 8; ++i) + ((uint32_t *) g_draw.Xpixels)[i] = color; + + g_draw.XCimage = XvCreateImage(g_draw.display, g_draw.xv_port, + g_draw.xv_id, (char *) g_draw.Xpixels, 8, 8); + + /* + Allocate max that could be needed: + Big(est?) PSX res: 640x512 + 32bpp (times 4) + 2xsai func= 3xwidth,3xheight + = approx 11.8mb + */ + g_draw.shminfo.shmid + = shmget(IPC_PRIVATE, 1024 * 512 * 4, IPC_CREAT | 0777); + g_draw.shminfo.shmaddr = shmat(g_draw.shminfo.shmid, 0, 0); + g_draw.shminfo.readOnly = 0; + + if (!XShmAttach(g_draw.display, &g_draw.shminfo)) { + printf("XShmAttach failed !\n"); + exit(-1); + } + + uint32_t *pShmaddr = (uint32_t *) g_draw.shminfo.shmaddr; + for (i = 0; i < 1024 * 512; ++i) + pShmaddr[i] = color; + + //fprintf(stderr, "Return %s\n", __FUNCTION__); + return; +} + +int rgb_check_port(XvImageFormatValues const * fo) { + if (fo->type == XvRGB && fo->bits_per_pixel == 32) { + g_draw.xv_id = fo->id; + return 1; + } + return 0; +} + +void rgb_blit_16(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) { + //fprintf(stderr, "BlitToYUV\n"); + int16_t * src_pxl; + int8_t * dst_pxl; + int32_t startxy; + int32_t _x, _y; + + startxy = 0; + dst_pxl = buff; + for (_y = y; _y < h; ++_y) { + src_pxl = &g_gpu.psx_vram.s16[startxy]; + for (_x = x; _x < w; ++_x) { + dst_pxl[0] = ((*src_pxl) << 3) & 0xf8; + dst_pxl[1] = ((*src_pxl) >> 2) & 0xf8; + dst_pxl[2] = ((*src_pxl) >> 7) & 0xf8; + dst_pxl += 3; + src_pxl += 1; + } + startxy += 2048; + } +} + +void rgb_blit_24(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) { + //fprintf(stderr, "BlitToYUV\n"); + int8_t * src_pxl; + int8_t * dst_pxl; + int32_t startxy; + int32_t _x, _y; + + dst_pxl = buff; + startxy = 0; + for (_y = y; _y < h; ++_y) { + src_pxl = &g_gpu.psx_vram.s8[startxy]; + for (_x = x; _x < w; ++_x) { + dst_pxl[0] = src_pxl[0]; + dst_pxl[1] = src_pxl[1]; + dst_pxl[2] = src_pxl[2]; + dst_pxl += 3; + src_pxl += 3; + } + startxy += 2048; + } +} + +int yuyv_check_port(XvImageFormatValues * fo) { + if (fo->type == XvYUV && fo->bits_per_pixel == 16 && fo->format == XvPacked + && strncmp("UYVY", fo->component_order, 4) == 0) { + g_draw.xv_id = fo->id; + return 1; + } + return 0; +} + +void yuyv_blit_24(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) { + //fprintf(stderr, "yuyv_blit_24 %d %d %d %d\n", x, y, w, h); + uint8_t * src_pxl; + int8_t R0, G0, B0; + int8_t R1, G1, B1; + uint32_t * dst_pxl; + int32_t _x, _y; + + /* x and w should be multiple of 2 to be align */ + x = x & 0xfffffffe; + w = (w + 1) & 0xfffffffe; + + dst_pxl = (uint32_t *) (buff); + for (_y = y; _y < (y + h); _y += 1) { + src_pxl = &g_gpu.psx_vram.u8[x * 3 + (_y * 2048)]; + for (_x = 0; _x < (w / 2); ++_x) { + R0 = src_pxl[0]; + G0 = src_pxl[1]; + B0 = src_pxl[2]; + R1 = src_pxl[3]; + G1 = src_pxl[4]; + B1 = src_pxl[5]; + *dst_pxl++ = rgb_to_yuv2(R0, G0, B0, R1, G1, B1); + src_pxl += 6; + } + } +} + +void yuyv_blit_16(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) { + //fprintf(stderr, "yuyv_blit_16 %d %d %d %d\n", x, y, w, h); + int8_t R0, G0, B0; + int8_t R1, G1, B1; + uint32_t * dst_pxl; + int32_t _x, _y; + int32_t s; + uint16_t * src_pxl; + + /* x must be a multiple of 2 */ + /* x and w must be a multiple of 2 */ + x = x & 0xfffffffe; + w = (w + 1) & 0xfffffffe; + + dst_pxl = (uint32_t *) (buff); + for (_y = y; _y < (y + h); _y += 1) { + src_pxl = &g_gpu.psx_vram.u16[x + (_y * 1024)]; + for (_x = 0; _x < (w / 2); ++_x) { + s = GETLE16(src_pxl++); + R0 = (s << 3) & 0xf8; + G0 = (s >> 2) & 0xf8; + B0 = (s >> 7) & 0xf8; + s = GETLE16(src_pxl++); + R1 = (s << 3) & 0xf8; + G1 = (s >> 2) & 0xf8; + B1 = (s >> 7) & 0xf8; + *dst_pxl++ = rgb_to_yuv2(R0, G0, B0, R1, G1, B1); + } + } +} + +/** + * compute the position and the size of output screen + * The aspect of the psx output mode is preserved. + * Note: dest dx,dy,dw,dh are both input and output variables + */ +inline void maintain_aspect(uint32_t * dx, uint32_t * dy, uint32_t * dw, + uint32_t * dh, int32_t w, int32_t h) { + + double ratio_x = ((double) *dw) / ((double) w); + double ratio_y = ((double) *dh) / ((double) h); + + double ratio; + if (ratio_x < ratio_y) { + ratio = ratio_x; + } else { + ratio = ratio_y; + } + + uint32_t tw = (uint32_t) floor(w * ratio); + uint32_t th = (uint32_t) floor(h * ratio); + + *dx += (uint32_t) floor((*dw - tw) / 2.0); + *dy += (uint32_t) floor((*dh - th) / 2.0); + *dw = tw; + *dh = th; +} + +void do_buffer_swap(void) { + //Screen *screen; + Window _dw; + XvImage *xvi; + unsigned int dstx, dsty; + unsigned int _d, _w, _h; //don't care about _d + + dstx = 0; + dsty = 0; + + XSync(g_draw.display, False); + + XGetGeometry(g_draw.display, g_draw.window, &_dw, (int *) &_d, (int *) &_d, + &_w, &_h, &_d, &_d); + + if (g_cfg.ShowFPS) { + dsty += 15; + _h -= 15; + compute_fps(); + snprintf(g_draw.msg, 511, "FPS : %f", g_draw.fps); + XDrawImageString(g_draw.display, g_draw.window, g_draw.hGC, 0, 12, + g_draw.msg, strlen(g_draw.msg)); + } + + uint32_t _x_, _y_, _w_, _h_; + + /* if video mode is valid */ + if (g_gpu.dsp.mode.x) { + + if (g_gpu.status_reg & STATUS_RGB24) { + _x_ = (g_gpu.dsp.position.x * 2) / 3; + } else { + _x_ = g_gpu.dsp.position.x; + } + _y_ = g_gpu.dsp.position.y; + _w_ = (g_gpu.dsp.range.x1 - g_gpu.dsp.range.x0) / g_gpu.dsp.mode.x; + _h_ = (g_gpu.dsp.range.y1 - g_gpu.dsp.range.y0) * g_gpu.dsp.mode.y; + + if (g_gpu.status_reg & STATUS_RGB24) { + available_port[g_draw.xv].blit_24_bits( + (int8_t *) g_draw.shminfo.shmaddr, _x_, _y_, _w_, _h_); + } else { + available_port[GXV_YUV_PORT].blit_16_bits( + (int8_t *) g_draw.shminfo.shmaddr, _x_, _y_, _w_, _h_); + } + + xvi = XvShmCreateImage(g_draw.display, g_draw.xv_port, g_draw.xv_id, 0, + _w_, _h_, &g_draw.shminfo); + + xvi->data = g_draw.shminfo.shmaddr; + + //screen = DefaultScreenOfDisplay(g_draw.display); + //screennum = DefaultScreen(display); + + // if (g_cfg.FullScreen) { + // _w = screen->width; + // _h = screen->height; + // } + + if (g_cfg.Maintain43) + maintain_aspect(&dstx, &dsty, &_w, &_h, _w_, (g_gpu.dsp.range.y1 + - g_gpu.dsp.range.y0)); + + // int _i; + // int32_t * dst_pxl; + // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[2048 * _y_]; + // for (_i = _x_ / 2; _i < (_x_ + _w_) / 2; ++_i) + // dst_pxl[_i] = rgb_to_yuv2(255, 0, 0, 255, 0, 0); + // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[2048 * (_y_ + _h_)]; + // for (_i = _x_ / 2; _i < (_x_ + _w_) / 2; ++_i) + // dst_pxl[_i] = rgb_to_yuv2(255, 0, 0, 255, 0, 0); + // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[4 * (_x_ / 2)]; + // for (_i = _y_; _i < (_y_ + _h_); ++_i) + // dst_pxl[_i * 512] = rgb_to_yuv2(255, 0, 0, 255, 0, 0); + // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[4 * ((_x_ + _w_) / 2)]; + // for (_i = _y_; _i < (_y_ + _h_); ++_i) + // dst_pxl[_i * 512] = rgb_to_yuv2(255, 0, 0, 255, 0, 0); + + //fprintf(stderr, "From %d,%d,%d,%d\n", _x_, _y_, _w_, _h_); + XvShmPutImage(g_draw.display, g_draw.xv_port, g_draw.window, + g_draw.hGC, xvi, 0, 0, _w_, _h_, + //0, 0, 1024, 512, + /* dst */ + dstx, dsty, _w, _h, 1); + XFree(xvi); + } +} + +void do_clear_screen_buffer(void) // CLEAR DX BUFFER +{ + XClearWindow(g_draw.display, g_draw.window); +} + +void Xcleanup() // X CLEANUP +{ + //CloseMenu(); +} + +/** + * Call on GPUopen + * Return the current display. + **/ +unsigned long init_display() { + + available_port[GXV_YUV_PORT].blit_24_bits = yuyv_blit_24; + available_port[GXV_YUV_PORT].blit_16_bits = yuyv_blit_16; + + available_port[GXV_RGB_PORT].blit_24_bits = rgb_blit_24; + available_port[GXV_RGB_PORT].blit_16_bits = rgb_blit_16; + + create_display(); // x stuff + g_draw.bIsFirstFrame = 0; + return (unsigned long) g_draw.display; +} + +void CloseDisplay(void) { + Xcleanup(); // cleanup dx + DestroyDisplay(); +} + +void CreatePic(unsigned char * pMem) { + unsigned char * p = (unsigned char *) malloc(128 * 96 * 4); + unsigned char * ps; + //int x, y; + + ps = p; + + // if (iDesktopCol == 16) { + // unsigned short s; + // for (y = 0; y < 96; y++) { + // for (x = 0; x < 128; x++) { + // s = (*(pMem + 0)) >> 3; + // s |= ((*(pMem + 1)) & 0xfc) << 3; + // s |= ((*(pMem + 2)) & 0xf8) << 8; + // pMem += 3; + // *((unsigned short *) (ps + y * 256 + x * 2)) = s; + // } + // } + // } else if (iDesktopCol == 15) { + // unsigned short s; + // for (y = 0; y < 96; y++) { + // for (x = 0; x < 128; x++) { + // s = (*(pMem + 0)) >> 3; + // s |= ((*(pMem + 1)) & 0xfc) << 2; + // s |= ((*(pMem + 2)) & 0xf8) << 7; + // pMem += 3; + // *((unsigned short *) (ps + y * 256 + x * 2)) = s; + // } + // } + // } else if (iDesktopCol == 32) { + // uint32_t l; + // for (y = 0; y < 96; y++) { + // for (x = 0; x < 128; x++) { + // l = *(pMem + 0); + // l |= (*(pMem + 1)) << 8; + // l |= (*(pMem + 2)) << 16; + // pMem += 3; + // *((uint32_t *) (ps + y * 512 + x * 4)) = l; + // } + // } + // } + + g_draw.XPimage = XCreateImage(g_draw.display, g_draw.myvisual->visual, + g_draw.depth, ZPixmap, 0, (char *) p, 128, 96, + g_draw.depth > 16 ? 32 : 16, 0); +} + +void DestroyPic(void) { + if (g_draw.XPimage) { /* + XPutImage(display,window,hGC, XCimage, + 0, 0, 0, 0, iResX, iResY);*/ + XDestroyImage(g_draw.XPimage); + g_draw.XPimage = 0; + } +} + +void ShowGpuPic(void) { +} + +void ShowTextGpuPic(void) { +} |
