mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-12-23 03:00:56 +00:00
642 lines
16 KiB
Diff
642 lines
16 KiB
Diff
|
From 8e6ada7bc33e3cc4e1c17821ea171bf0815a505d Mon Sep 17 00:00:00 2001
|
||
|
From: Alam Arias <Alam.GBC@gmail.com>
|
||
|
Date: Tue, 1 Dec 2009 19:31:57 -0500
|
||
|
Subject: [PATCH] SDL GC hack
|
||
|
|
||
|
---
|
||
|
configure.in | 17 ++
|
||
|
include/SDL_config.h.in | 1 +
|
||
|
src/video/fbcon/SDL_fbgc.c | 471 +++++++++++++++++++++++++++++++++++++++++
|
||
|
src/video/fbcon/SDL_fbgc.h | 35 +++
|
||
|
src/video/fbcon/SDL_fbvideo.c | 10 +
|
||
|
src/video/fbcon/SDL_fbvideo.h | 11 +
|
||
|
6 files changed, 545 insertions(+), 0 deletions(-)
|
||
|
create mode 100644 src/video/fbcon/SDL_fbgc.c
|
||
|
create mode 100644 src/video/fbcon/SDL_fbgc.h
|
||
|
|
||
|
diff --git a/configure.in b/configure.in
|
||
|
index a7e9b18..a8961ba 100644
|
||
|
--- a/configure.in
|
||
|
+++ b/configure.in
|
||
|
@@ -1227,6 +1227,22 @@ AC_HELP_STRING([--enable-video-fbcon], [use framebuffer console video driver [[d
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
+dnl See if we're running on Linux for the Nintendo GameCube/Wii
|
||
|
+dnl FIXME, perform a real test here...
|
||
|
+CheckGC()
|
||
|
+{
|
||
|
+ AC_ARG_ENABLE(video-gc,
|
||
|
+AC_HELP_STRING([--enable-video-gc], [enable GameCube video support in FB [[default=no]]]),
|
||
|
+ , enable_video_gc=no)
|
||
|
+ if test x$enable_video = xyes -a x$enable_video_gc = xyes -a x$video_fbcon = xyes; then
|
||
|
+ video_gc=yes
|
||
|
+ AC_MSG_RESULT($video_gc)
|
||
|
+ if test x$video_gc = xyes; then
|
||
|
+ AC_DEFINE(SDL_VIDEO_DRIVER_GC)
|
||
|
+ fi
|
||
|
+ fi
|
||
|
+}
|
||
|
+
|
||
|
dnl Find DirectFB
|
||
|
CheckDirectFB()
|
||
|
{
|
||
|
@@ -2322,6 +2338,7 @@ case "$host" in
|
||
|
CheckX11
|
||
|
CheckNANOX
|
||
|
CheckFBCON
|
||
|
+ CheckGC
|
||
|
CheckDirectFB
|
||
|
CheckPS2GS
|
||
|
CheckPS3
|
||
|
diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in
|
||
|
index 58593ca..e523e9b 100644
|
||
|
--- a/include/SDL_config.h.in
|
||
|
+++ b/include/SDL_config.h.in
|
||
|
@@ -262,6 +262,7 @@
|
||
|
#undef SDL_VIDEO_DRIVER_DUMMY
|
||
|
#undef SDL_VIDEO_DRIVER_FBCON
|
||
|
#undef SDL_VIDEO_DRIVER_GAPI
|
||
|
+#undef SDL_VIDEO_DRIVER_GC
|
||
|
#undef SDL_VIDEO_DRIVER_GEM
|
||
|
#undef SDL_VIDEO_DRIVER_GGI
|
||
|
#undef SDL_VIDEO_DRIVER_IPOD
|
||
|
diff --git a/src/video/fbcon/SDL_fbgc.c b/src/video/fbcon/SDL_fbgc.c
|
||
|
new file mode 100644
|
||
|
index 0000000..b3b72bb
|
||
|
--- /dev/null
|
||
|
+++ b/src/video/fbcon/SDL_fbgc.c
|
||
|
@@ -0,0 +1,471 @@
|
||
|
+/*
|
||
|
+ SDL - Simple DirectMedia Layer
|
||
|
+ Copyright (C) 1997-2009 Sam Lantinga
|
||
|
+
|
||
|
+ This library is free software; you can redistribute it and/or
|
||
|
+ modify it under the terms of the GNU Lesser General Public
|
||
|
+ License as published by the Free Software Foundation; either
|
||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||
|
+
|
||
|
+ This library 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
|
||
|
+ Lesser General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Lesser General Public
|
||
|
+ License along with this library; if not, write to the Free Software
|
||
|
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
+
|
||
|
+ Sam Lantinga
|
||
|
+ slouken@libsdl.org
|
||
|
+*/
|
||
|
+#include "SDL_config.h"
|
||
|
+
|
||
|
+#ifdef SDL_VIDEO_DRIVER_GC
|
||
|
+#include <errno.h>
|
||
|
+#include "SDL_video.h"
|
||
|
+#include "../SDL_blit.h"
|
||
|
+#include "SDL_fbgc.h"
|
||
|
+
|
||
|
+static Uint32 r_Yr[256];
|
||
|
+static Uint32 g_Yg_[256];
|
||
|
+static Uint32 b_Yb[256];
|
||
|
+static Uint32 r_Ur[256];
|
||
|
+static Uint32 g_Ug_[256];
|
||
|
+static Uint32 b_Ub[256];
|
||
|
+/* static Uint32 r_Vr[256]; // space and cache optimisation */
|
||
|
+#define r_Vr b_Ub
|
||
|
+static Uint32 g_Vg_[256];
|
||
|
+static Uint32 b_Vb[256];
|
||
|
+
|
||
|
+static Uint8 RGB16toY[1 << 16];
|
||
|
+static Uint8 RGB16toU[1 << 16];
|
||
|
+static Uint8 RGB16toV[1 << 16];
|
||
|
+
|
||
|
+#ifndef FBIOFLIPHACK
|
||
|
+#define FBIOFLIPHACK 0x4623 /* gc-linux */
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifndef GC_BLACK
|
||
|
+#define GC_BLACK 0x00800080
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifdef GC_DEBUG
|
||
|
+# define GC_DPRINTF(fmt, args...) \
|
||
|
+ fprintf(stderr,"DDD|%s: " fmt, __FUNCTION__ , ## args)
|
||
|
+#else
|
||
|
+# define GC_DPRINTF(fmt, args...)
|
||
|
+#endif
|
||
|
+
|
||
|
+SDL_bool GC_Test(_THIS)
|
||
|
+{
|
||
|
+ int fliptest;
|
||
|
+ if (ioctl(console_fd, FBIOFLIPHACK, &fliptest))
|
||
|
+ return SDL_TRUE;
|
||
|
+ return SDL_FALSE;
|
||
|
+}
|
||
|
+
|
||
|
+SDL_bool GC_Available(void)
|
||
|
+{
|
||
|
+ if (access("/sys/bus/of_platform/drivers/gcn-vifb", 0) == 0)
|
||
|
+ return SDL_TRUE;
|
||
|
+
|
||
|
+ return SDL_FALSE;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ *
|
||
|
+ * Color space handling.
|
||
|
+ */
|
||
|
+
|
||
|
+#define RGB2YUV_SHIFT 16
|
||
|
+#define RGB2YUV_LUMA 16
|
||
|
+#define RGB2YUV_CHROMA 128
|
||
|
+
|
||
|
+#define Yr ((int)( 0.299*(1<<RGB2YUV_SHIFT)))
|
||
|
+#define Yg ((int)( 0.587*(1<<RGB2YUV_SHIFT)))
|
||
|
+#define Yb ((int)( 0.114*(1<<RGB2YUV_SHIFT)))
|
||
|
+
|
||
|
+#define Ur ((int)(-0.169*(1<<RGB2YUV_SHIFT)))
|
||
|
+#define Ug ((int)(-0.331*(1<<RGB2YUV_SHIFT)))
|
||
|
+#define Ub ((int)( 0.500*(1<<RGB2YUV_SHIFT)))
|
||
|
+
|
||
|
+#define Vr ((int)( 0.500*(1<<RGB2YUV_SHIFT))) /* same as Ub */
|
||
|
+#define Vg ((int)(-0.419*(1<<RGB2YUV_SHIFT)))
|
||
|
+#define Vb ((int)(-0.081*(1<<RGB2YUV_SHIFT)))
|
||
|
+
|
||
|
+#define clamp(x, y, z) ((z < x) ? x : ((z > y) ? y : z))
|
||
|
+
|
||
|
+static void GC_InitRGB2YUVTables(void)
|
||
|
+{
|
||
|
+ unsigned int i;
|
||
|
+ unsigned int r, g, b;
|
||
|
+
|
||
|
+ for (i = 0; i < 256; i++) {
|
||
|
+ r_Yr[i] = Yr * i;
|
||
|
+ g_Yg_[i] = Yg * i + (RGB2YUV_LUMA << RGB2YUV_SHIFT);
|
||
|
+ b_Yb[i] = Yb * i;
|
||
|
+ r_Ur[i] = Ur * i;
|
||
|
+ g_Ug_[i] = Ug * i + (RGB2YUV_CHROMA << RGB2YUV_SHIFT);
|
||
|
+ b_Ub[i] = Ub * i;
|
||
|
+ r_Vr[i] = Vr * i;
|
||
|
+ g_Vg_[i] = Vg * i + (RGB2YUV_CHROMA << RGB2YUV_SHIFT);
|
||
|
+ b_Vb[i] = Vb * i;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < 1 << 16; i++) {
|
||
|
+ /* RGB565 */
|
||
|
+ r = ((i >> 8) & 0xf8);
|
||
|
+ g = ((i >> 3) & 0xfc);
|
||
|
+ b = ((i << 3) & 0xf8);
|
||
|
+ /* extend to 8bit */
|
||
|
+ r |= (r >> 5);
|
||
|
+ g |= (g >> 6);
|
||
|
+ b |= (b >> 5);
|
||
|
+
|
||
|
+ RGB16toY[i] =
|
||
|
+ clamp(16, 235,
|
||
|
+ (r_Yr[r] + g_Yg_[g] + b_Yb[b]) >> RGB2YUV_SHIFT);
|
||
|
+ RGB16toU[i] =
|
||
|
+ clamp(16, 240,
|
||
|
+ (r_Ur[r] + g_Ug_[g] + b_Ub[b]) >> RGB2YUV_SHIFT);
|
||
|
+ RGB16toV[i] =
|
||
|
+ clamp(16, 240,
|
||
|
+ (r_Vr[r] + g_Vg_[g] + b_Vb[b]) >> RGB2YUV_SHIFT);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static inline Uint32 rgbrgb16toyuy2(Uint16 rgb1, Uint16 rgb2)
|
||
|
+{
|
||
|
+ register int Y1, Cb, Y2, Cr;
|
||
|
+ Uint16 rgb;
|
||
|
+
|
||
|
+ /* fast path, thanks to bohdy */
|
||
|
+ if (!(rgb1 | rgb2)) {
|
||
|
+ return GC_BLACK; /* black, black */
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rgb1 == rgb2) {
|
||
|
+ /* fast path, thanks to isobel */
|
||
|
+ Y1 = Y2 = RGB16toY[rgb1];
|
||
|
+ Cb = RGB16toU[rgb1];
|
||
|
+ Cr = RGB16toV[rgb1];
|
||
|
+ } else {
|
||
|
+ Y1 = RGB16toY[rgb1];
|
||
|
+ Y2 = RGB16toY[rgb2];
|
||
|
+
|
||
|
+ /* RGB565 average */
|
||
|
+ rgb = ((rgb1 >> 1) & 0xFBEF) + ((rgb2 >> 1) & 0xFBEF) +
|
||
|
+ ((rgb1 & rgb2) & 0x0821);
|
||
|
+
|
||
|
+ Cb = RGB16toU[rgb];
|
||
|
+ Cr = RGB16toV[rgb];
|
||
|
+ }
|
||
|
+
|
||
|
+ return (((char)Y1) << 24) | (((char)Cb) << 16) | (((char)Y2) << 8)
|
||
|
+ | (((char)Cr) << 0);
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ *
|
||
|
+ * Blitters.
|
||
|
+ */
|
||
|
+static void GC_UpdateRectRGB16(_THIS, SDL_Rect * rect, int pitch)
|
||
|
+{
|
||
|
+ int width, height, left, i, mod, mod32;
|
||
|
+ Uint8 *src, *dst;
|
||
|
+ Uint32 *src32, *dst32;
|
||
|
+ Uint16 *rgb;
|
||
|
+
|
||
|
+ /* XXX case width < 2 needs special treatment */
|
||
|
+
|
||
|
+ /* in pixel units */
|
||
|
+ left = rect->x & ~1; /* 2 pixel align */
|
||
|
+ width = (rect->w + 1) & ~1; /* 2 pixel align in excess */
|
||
|
+ height = rect->h;
|
||
|
+
|
||
|
+ /* in bytes, src and dest are 16bpp */
|
||
|
+ src = shadow_mem + (rect->y * pitch) + left * 2;
|
||
|
+ dst = flip_address[back_page] + page_offset +
|
||
|
+ (rect->y * pitch) + left * 2;
|
||
|
+ mod = pitch - width * 2;
|
||
|
+
|
||
|
+ src32 = (Uint32 *) src;
|
||
|
+ dst32 = (Uint32 *) dst;
|
||
|
+ mod32 = mod / 4;
|
||
|
+
|
||
|
+ while (height--) {
|
||
|
+ i = width / 2;
|
||
|
+
|
||
|
+ while (i--) {
|
||
|
+ rgb = (Uint16 *) src32;
|
||
|
+ *dst32++ = rgbrgb16toyuy2(rgb[0], rgb[1]);
|
||
|
+ src32++;
|
||
|
+ }
|
||
|
+ src32 += mod32;
|
||
|
+ dst32 += mod32;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void GC_Init(_THIS, SDL_PixelFormat *vformat)
|
||
|
+{
|
||
|
+ GC_InitRGB2YUVTables();
|
||
|
+
|
||
|
+ /* 16 bits per pixel */
|
||
|
+ vformat->BitsPerPixel = 16;
|
||
|
+ vformat->BytesPerPixel = 2;
|
||
|
+ /* RGB565 */
|
||
|
+ vformat->Rmask = 0x0000f800;
|
||
|
+ vformat->Gmask = 0x000007e0;
|
||
|
+ vformat->Bmask = 0x0000001f;
|
||
|
+
|
||
|
+ shadow_fb = 1;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ *
|
||
|
+ * Video mode handling.
|
||
|
+ */
|
||
|
+
|
||
|
+/* only 640x480 16bpp is currently supported */
|
||
|
+const static SDL_Rect RECT_640x480 = { 0, 0, 640, 480 };
|
||
|
+const static SDL_Rect *vid_modes[] = {
|
||
|
+ &RECT_640x480,
|
||
|
+ NULL
|
||
|
+};
|
||
|
+
|
||
|
+static SDL_Rect **GC_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
|
||
|
+{
|
||
|
+ switch (format->BitsPerPixel) {
|
||
|
+ case 16:
|
||
|
+ return (SDL_Rect **) vid_modes;
|
||
|
+ default:
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+SDL_Surface *GC_SetVideoMode(_THIS, SDL_Surface * current,
|
||
|
+ int width, int height, int bpp, Uint32 flags)
|
||
|
+{
|
||
|
+ struct fb_fix_screeninfo finfo;
|
||
|
+ struct fb_var_screeninfo vinfo;
|
||
|
+ int i;
|
||
|
+ Uint32 Rmask;
|
||
|
+ Uint32 Gmask;
|
||
|
+ Uint32 Bmask;
|
||
|
+ Uint32 *p, *q;
|
||
|
+ Uint32 yres;
|
||
|
+
|
||
|
+ GC_DPRINTF("Setting %dx%d %dbpp %smode\n", width, height, bpp,
|
||
|
+ (flags & SDL_DOUBLEBUF)?"(doublebuf) ":"");
|
||
|
+
|
||
|
+ /* Set the terminal into graphics mode */
|
||
|
+ if (FB_EnterGraphicsMode(this) < 0) {
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Restore the original palette */
|
||
|
+ //FB_RestorePalette(this);
|
||
|
+
|
||
|
+ /* Set the video mode and get the final screen format */
|
||
|
+ if (ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
|
||
|
+ SDL_SetError("Couldn't get console screen info");
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
+
|
||
|
+ yres = vinfo.yres;
|
||
|
+
|
||
|
+ /* hack to center 640x480 resolution on PAL cubes */
|
||
|
+ if (vinfo.xres == 640 && vinfo.yres == 576) {
|
||
|
+ page_offset = ((576 - 480) / 2) * 640 * ((bpp + 7) / 8);
|
||
|
+ } else {
|
||
|
+ page_offset = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* clear all video memory */
|
||
|
+ p = (Uint32 *)mapped_mem;
|
||
|
+ q = (Uint32 *)(mapped_mem + mapped_memlen);
|
||
|
+ while (p < q)
|
||
|
+ *p++ = GC_BLACK;
|
||
|
+
|
||
|
+ if ((vinfo.xres != width) || (vinfo.yres != height) ||
|
||
|
+ (vinfo.bits_per_pixel != bpp)) {
|
||
|
+ vinfo.activate = FB_ACTIVATE_NOW;
|
||
|
+ vinfo.accel_flags = 0;
|
||
|
+ vinfo.bits_per_pixel = bpp;
|
||
|
+ vinfo.xres = width;
|
||
|
+ vinfo.xres_virtual = width;
|
||
|
+ /* do not modify yres*, we use a fake 640x480 mode in PAL */
|
||
|
+ //vinfo.yres = height;
|
||
|
+ //vinfo.yres_virtual = 2*height;
|
||
|
+ vinfo.xoffset = 0;
|
||
|
+ vinfo.yoffset = 0;
|
||
|
+ vinfo.red.length = vinfo.red.offset = 0;
|
||
|
+ vinfo.green.length = vinfo.green.offset = 0;
|
||
|
+ vinfo.blue.length = vinfo.blue.offset = 0;
|
||
|
+ vinfo.transp.length = vinfo.transp.offset = 0;
|
||
|
+
|
||
|
+ if (ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) {
|
||
|
+ SDL_SetError("Couldn't set console screen info");
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ int maxheight;
|
||
|
+
|
||
|
+ /* Figure out how much video memory is available */
|
||
|
+ maxheight = 2*yres;
|
||
|
+ if (vinfo.yres_virtual > maxheight) {
|
||
|
+ vinfo.yres_virtual = maxheight;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ cache_vinfo = vinfo;
|
||
|
+
|
||
|
+ Rmask = 0;
|
||
|
+ for (i = 0; i < vinfo.red.length; ++i) {
|
||
|
+ Rmask <<= 1;
|
||
|
+ Rmask |= (0x00000001 << vinfo.red.offset);
|
||
|
+ }
|
||
|
+ Gmask = 0;
|
||
|
+ for (i = 0; i < vinfo.green.length; ++i) {
|
||
|
+ Gmask <<= 1;
|
||
|
+ Gmask |= (0x00000001 << vinfo.green.offset);
|
||
|
+ }
|
||
|
+ Bmask = 0;
|
||
|
+ for (i = 0; i < vinfo.blue.length; ++i) {
|
||
|
+ Bmask <<= 1;
|
||
|
+ Bmask |= (0x00000001 << vinfo.blue.offset);
|
||
|
+ }
|
||
|
+ if (!SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0)) {
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Get the fixed information about the console hardware.
|
||
|
+ This is necessary since finfo.line_length changes.
|
||
|
+ */
|
||
|
+ if (ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
|
||
|
+ SDL_SetError("Couldn't get console hardware info");
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Save hardware palette, if needed */
|
||
|
+ //FB_SavePalette(this, &finfo, &vinfo);
|
||
|
+
|
||
|
+ /* Set up the new mode framebuffer */
|
||
|
+ current->flags = SDL_FULLSCREEN;
|
||
|
+ current->w = width;
|
||
|
+ current->h = height;
|
||
|
+ current->pitch = width * ((bpp + 7) / 8);
|
||
|
+ current->pixels = shadow_mem;
|
||
|
+
|
||
|
+ flip_address[0] = mapped_mem;
|
||
|
+ flip_address[1] = mapped_mem + current->pitch * yres;
|
||
|
+
|
||
|
+ back_page = 1;
|
||
|
+ if (flags & SDL_DOUBLEBUF) {
|
||
|
+ current->flags |= SDL_DOUBLEBUF;
|
||
|
+ flip_pending = 1;
|
||
|
+ } else {
|
||
|
+ flip_pending = 0;
|
||
|
+ /* make page 0 both the visible and back page */
|
||
|
+ back_page = ioctl(console_fd, FBIOFLIPHACK, &back_page);
|
||
|
+ if (back_page < 0)
|
||
|
+ back_page = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Set the update rectangle function */
|
||
|
+ switch (bpp) {
|
||
|
+ case 16:
|
||
|
+ GC_DPRINTF("Using 16bpp blitter\n");
|
||
|
+ this->hidden->UpdateRect = GC_UpdateRectRGB16;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ GC_DPRINTF("Using NO blitter\n");
|
||
|
+ this->hidden->UpdateRect = NULL;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Handle OpenGL support */
|
||
|
+#ifdef HAVE_OPENGL
|
||
|
+ if (flags & SDL_OPENGL) {
|
||
|
+ if (GC_GL_CreateWindow(this, width, height) == 0) {
|
||
|
+ current->flags |= (SDL_OPENGL | SDL_FULLSCREEN);
|
||
|
+ } else {
|
||
|
+ current = NULL;
|
||
|
+ }
|
||
|
+ }
|
||
|
+#endif /* HAVE_OPENGL */
|
||
|
+
|
||
|
+ /* We're done */
|
||
|
+ return (current);
|
||
|
+}
|
||
|
+
|
||
|
+static int GC_FlipHWSurface(_THIS, SDL_Surface * surface)
|
||
|
+{
|
||
|
+ if (flip_pending) {
|
||
|
+ /* SDL_UpdateRect was not called */
|
||
|
+ SDL_UpdateRect(this->screen, 0, 0, 0, 0);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* flip video page as soon as possible */
|
||
|
+ ioctl(console_fd, FBIOFLIPHACK, NULL);
|
||
|
+ flip_pending = 1;
|
||
|
+
|
||
|
+ return (0);
|
||
|
+}
|
||
|
+
|
||
|
+static void GC_WaitForFlipCompletion(_THIS)
|
||
|
+{
|
||
|
+ int visible_page;
|
||
|
+ int result;
|
||
|
+
|
||
|
+ if (flip_pending) {
|
||
|
+ flip_pending = 0;
|
||
|
+ back_page ^= 1;
|
||
|
+ visible_page = back_page;
|
||
|
+ while (visible_page == back_page) {
|
||
|
+ /* wait until back_page is not visible */
|
||
|
+ result = ioctl(console_fd, FBIOFLIPHACK, &back_page);
|
||
|
+ if (result < 0) {
|
||
|
+ if ((errno == EINTR) || (errno == EAGAIN))
|
||
|
+ continue;
|
||
|
+ return; /* ioctl unsupported ... */
|
||
|
+ }
|
||
|
+ visible_page = result;
|
||
|
+ }
|
||
|
+ /*
|
||
|
+ * At this point the back_page is not visible. We can safely
|
||
|
+ * write to it without tearing.
|
||
|
+ */
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void GC_UpdateRects(_THIS, int numrects, SDL_Rect * rects)
|
||
|
+{
|
||
|
+ SDL_Surface *screen;
|
||
|
+ int pitch;
|
||
|
+
|
||
|
+ /* external yuy2 fb is 16bpp */
|
||
|
+
|
||
|
+ screen = this->screen;
|
||
|
+ pitch = screen->pitch; /* this is the pitch of the shadow buffer */
|
||
|
+
|
||
|
+ if (this->hidden->UpdateRect) {
|
||
|
+ GC_WaitForFlipCompletion(this);
|
||
|
+ while (numrects--) {
|
||
|
+ if (rects->w <= 0 || rects->h <= 0)
|
||
|
+ continue;
|
||
|
+ this->hidden->UpdateRect(this, rects, pitch);
|
||
|
+ rects++;
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void GC_CreateDevice(SDL_VideoDevice *this)
|
||
|
+{
|
||
|
+ this->ListModes = GC_ListModes;
|
||
|
+ this->SetVideoMode = GC_SetVideoMode;
|
||
|
+ this->FlipHWSurface = GC_FlipHWSurface;
|
||
|
+ this->UpdateRects = GC_UpdateRects;
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
diff --git a/src/video/fbcon/SDL_fbgc.h b/src/video/fbcon/SDL_fbgc.h
|
||
|
new file mode 100644
|
||
|
index 0000000..534a73e
|
||
|
--- /dev/null
|
||
|
+++ b/src/video/fbcon/SDL_fbgc.h
|
||
|
@@ -0,0 +1,35 @@
|
||
|
+/*
|
||
|
+ SDL - Simple DirectMedia Layer
|
||
|
+ Copyright (C) 1997-2009 Sam Lantinga
|
||
|
+
|
||
|
+ This library is free software; you can redistribute it and/or
|
||
|
+ modify it under the terms of the GNU Lesser General Public
|
||
|
+ License as published by the Free Software Foundation; either
|
||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||
|
+
|
||
|
+ This library 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
|
||
|
+ Lesser General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Lesser General Public
|
||
|
+ License along with this library; if not, write to the Free Software
|
||
|
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
+
|
||
|
+ Sam Lantinga
|
||
|
+ slouken@libsdl.org
|
||
|
+*/
|
||
|
+#include "SDL_config.h"
|
||
|
+
|
||
|
+
|
||
|
+#ifdef SDL_VIDEO_DRIVER_GC
|
||
|
+/* Gamecube/Wii hardware setup for the SDL framebuffer console driver */
|
||
|
+
|
||
|
+#include "SDL_fbvideo.h"
|
||
|
+
|
||
|
+extern SDL_bool GC_Available(void);
|
||
|
+extern void GC_CreateDevice(SDL_VideoDevice *this);
|
||
|
+
|
||
|
+extern SDL_bool GC_Test(_THIS);
|
||
|
+extern void GC_Init(_THIS, SDL_PixelFormat *vformat);
|
||
|
+#endif
|
||
|
diff --git a/src/video/fbcon/SDL_fbvideo.c b/src/video/fbcon/SDL_fbvideo.c
|
||
|
index 81a89da..328790e 100644
|
||
|
--- a/src/video/fbcon/SDL_fbvideo.c
|
||
|
+++ b/src/video/fbcon/SDL_fbvideo.c
|
||
|
@@ -272,6 +272,11 @@ static SDL_VideoDevice *FB_CreateDevice(int devindex)
|
||
|
|
||
|
this->free = FB_DeleteDevice;
|
||
|
|
||
|
+#ifdef SDL_VIDEO_DRIVER_GC
|
||
|
+ if (GC_Available(this))
|
||
|
+ GC_CreateDevice(this);
|
||
|
+#endif
|
||
|
+
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
@@ -784,6 +789,11 @@ static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+#ifdef SDL_VIDEO_DRIVER_GC
|
||
|
+ if (GC_Test(this))
|
||
|
+ GC_Init(this, vformat);
|
||
|
+#endif
|
||
|
+
|
||
|
if (shadow_fb) {
|
||
|
shadow_mem = (char *)SDL_malloc(mapped_memlen);
|
||
|
if (shadow_mem == NULL) {
|
||
|
diff --git a/src/video/fbcon/SDL_fbvideo.h b/src/video/fbcon/SDL_fbvideo.h
|
||
|
index 03b9e94..74d1460 100644
|
||
|
--- a/src/video/fbcon/SDL_fbvideo.h
|
||
|
+++ b/src/video/fbcon/SDL_fbvideo.h
|
||
|
@@ -106,6 +106,12 @@ struct SDL_PrivateVideoData {
|
||
|
|
||
|
void (*wait_vbl)(_THIS);
|
||
|
void (*wait_idle)(_THIS);
|
||
|
+#ifdef SDL_VIDEO_DRIVER_GC
|
||
|
+ void (*UpdateRect) (_THIS, SDL_Rect * rect, int pitch);
|
||
|
+ int back_page;
|
||
|
+ int page_offset;
|
||
|
+ int flip_pending;
|
||
|
+#endif
|
||
|
};
|
||
|
/* Old variable names */
|
||
|
#define console_fd (this->hidden->console_fd)
|
||
|
@@ -147,6 +153,11 @@ struct SDL_PrivateVideoData {
|
||
|
#define screen_palette (this->hidden->screen_palette)
|
||
|
#define wait_vbl (this->hidden->wait_vbl)
|
||
|
#define wait_idle (this->hidden->wait_idle)
|
||
|
+#ifdef SDL_VIDEO_DRIVER_GC
|
||
|
+#define back_page (this->hidden->back_page)
|
||
|
+#define page_offset (this->hidden->page_offset)
|
||
|
+#define flip_pending (this->hidden->flip_pending)
|
||
|
+#endif
|
||
|
|
||
|
/* Accelerator types that are supported by the driver, but are not
|
||
|
necessarily in the kernel headers on the system we compile on.
|
||
|
--
|
||
|
1.6.5
|
||
|
|