Mercurial > sdl-ios-xcode
changeset 3678:8e961ef35d4b
Fixed bug #930
The PS2 video driver is obsolete and not going to be updated unless someone wants to maintain it.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 18 Jan 2010 14:27:30 +0000 |
parents | cec9ea711294 |
children | ce290de32f2a |
files | configure.in include/SDL_config.h.in src/video/SDL_sysvideo.h src/video/SDL_video.c src/video/ps2gs/SDL_gsevents.c src/video/ps2gs/SDL_gsevents_c.h src/video/ps2gs/SDL_gskeys.h src/video/ps2gs/SDL_gsmouse.c src/video/ps2gs/SDL_gsmouse_c.h src/video/ps2gs/SDL_gsvideo.c src/video/ps2gs/SDL_gsvideo.h src/video/ps2gs/SDL_gsyuv.c src/video/ps2gs/SDL_gsyuv_c.h |
diffstat | 13 files changed, 0 insertions(+), 2808 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Mon Jan 18 14:16:47 2010 +0000 +++ b/configure.in Mon Jan 18 14:27:30 2010 +0000 @@ -1438,31 +1438,6 @@ fi } -dnl See if we're running on PlayStation 2 hardware -CheckPS2GS() -{ - AC_ARG_ENABLE(video-ps2gs, -AC_HELP_STRING([--enable-video-ps2gs], [use PlayStation 2 GS video driver [[default=no]]]), - , enable_video_ps2gs=no) - if test x$enable_video = xyes -a x$enable_video_ps2gs = xyes; then - AC_MSG_CHECKING(for PlayStation 2 GS support) - video_ps2gs=no - AC_TRY_COMPILE([ - #include <linux/ps2/dev.h> - #include <linux/ps2/gs.h> - ],[ - ],[ - video_ps2gs=yes - ]) - AC_MSG_RESULT($video_ps2gs) - if test x$video_ps2gs = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_PS2GS) - SOURCES="$SOURCES $srcdir/src/video/ps2gs/*.c" - have_video=yes - fi - fi -} - dnl See if we're running on PlayStation 3 Cell hardware CheckPS3() { @@ -2233,7 +2208,6 @@ CheckFBCON CheckDirectFB CheckFusionSound - CheckPS2GS CheckPS3 CheckSVGA CheckOpenGLX11
--- a/include/SDL_config.h.in Mon Jan 18 14:16:47 2010 +0000 +++ b/include/SDL_config.h.in Mon Jan 18 14:27:30 2010 +0000 @@ -262,7 +262,6 @@ #undef SDL_VIDEO_DRIVER_NDS #undef SDL_VIDEO_DRIVER_PHOTON #undef SDL_VIDEO_DRIVER_QNXGF -#undef SDL_VIDEO_DRIVER_PS2GS #undef SDL_VIDEO_DRIVER_PS3 #undef SDL_VIDEO_DRIVER_RISCOS #undef SDL_VIDEO_DRIVER_SVGALIB
--- a/src/video/SDL_sysvideo.h Mon Jan 18 14:16:47 2010 +0000 +++ b/src/video/SDL_sysvideo.h Mon Jan 18 14:27:30 2010 +0000 @@ -373,9 +373,6 @@ #if SDL_VIDEO_DRIVER_DIRECTFB extern VideoBootStrap DirectFB_bootstrap; #endif -#if SDL_VIDEO_DRIVER_PS2GS -extern VideoBootStrap PS2GS_bootstrap; -#endif #if SDL_VIDEO_DRIVER_PS3 extern VideoBootStrap PS3_bootstrap; #endif
--- a/src/video/SDL_video.c Mon Jan 18 14:16:47 2010 +0000 +++ b/src/video/SDL_video.c Mon Jan 18 14:27:30 2010 +0000 @@ -61,9 +61,6 @@ #if SDL_VIDEO_DRIVER_DIRECTFB &DirectFB_bootstrap, #endif -#if SDL_VIDEO_DRIVER_PS2GS - &PS2GS_bootstrap, -#endif #if SDL_VIDEO_DRIVER_PS3 &PS3_bootstrap, #endif
--- a/src/video/ps2gs/SDL_gsevents.c Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1103 +0,0 @@ -/* - 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" - -/* Handle the event stream, converting console events into SDL events */ - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <limits.h> - -/* For parsing /proc */ -#include <dirent.h> -#include <ctype.h> - -#include <linux/vt.h> -#include <linux/kd.h> -#include <linux/keyboard.h> - -#include "SDL_mutex.h" -#include "../SDL_sysvideo.h" -#include "../../events/SDL_sysevents.h" -#include "../../events/SDL_events_c.h" -#include "SDL_gsvideo.h" -#include "SDL_gsevents_c.h" -#include "SDL_gskeys.h" - -#ifndef GPM_NODE_FIFO -#define GPM_NODE_FIFO "/dev/gpmdata" -#endif - -/* The translation tables from a console scancode to a SDL keysym */ -#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) -static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; -static SDLKey keymap[128]; -static Uint16 keymap_temp[128]; /* only used at startup */ -static SDL_keysym *TranslateKey(int scancode, SDL_keysym * keysym); - -/* Ugh, we have to duplicate the kernel's keysym mapping code... - Oh, it's not so bad. :-) - - FIXME: Add keyboard LED handling code - */ -static void -GS_vgainitkeymaps(int fd) -{ - struct kbentry entry; - int map, i; - - /* Don't do anything if we are passed a closed keyboard */ - if (fd < 0) { - return; - } - - /* Load all the keysym mappings */ - for (map = 0; map < NUM_VGAKEYMAPS; ++map) { - SDL_memset(vga_keymap[map], 0, NR_KEYS * sizeof(Uint16)); - for (i = 0; i < NR_KEYS; ++i) { - entry.kb_table = map; - entry.kb_index = i; - if (ioctl(fd, KDGKBENT, &entry) == 0) { - /* fill keytemp. This replaces SDL_fbkeys.h */ - if ((map == 0) && (i < 128)) { - keymap_temp[i] = entry.kb_value; - } - /* The "Enter" key is a special case */ - if (entry.kb_value == K_ENTER) { - entry.kb_value = K(KT_ASCII, 13); - } - /* Handle numpad specially as well */ - if (KTYP(entry.kb_value) == KT_PAD) { - switch (entry.kb_value) { - case K_P0: - case K_P1: - case K_P2: - case K_P3: - case K_P4: - case K_P5: - case K_P6: - case K_P7: - case K_P8: - case K_P9: - vga_keymap[map][i] = entry.kb_value; - vga_keymap[map][i] += '0'; - break; - case K_PPLUS: - vga_keymap[map][i] = K(KT_ASCII, '+'); - break; - case K_PMINUS: - vga_keymap[map][i] = K(KT_ASCII, '-'); - break; - case K_PSTAR: - vga_keymap[map][i] = K(KT_ASCII, '*'); - break; - case K_PSLASH: - vga_keymap[map][i] = K(KT_ASCII, '/'); - break; - case K_PENTER: - vga_keymap[map][i] = K(KT_ASCII, '\r'); - break; - case K_PCOMMA: - vga_keymap[map][i] = K(KT_ASCII, ','); - break; - case K_PDOT: - vga_keymap[map][i] = K(KT_ASCII, '.'); - break; - default: - break; - } - } - /* Do the normal key translation */ - if ((KTYP(entry.kb_value) == KT_LATIN) || - (KTYP(entry.kb_value) == KT_ASCII) || - (KTYP(entry.kb_value) == KT_LETTER)) { - vga_keymap[map][i] = entry.kb_value; - } - } - } - } -} - -int -GS_InGraphicsMode(_THIS) -{ - return ((keyboard_fd >= 0) && (saved_kbd_mode >= 0)); -} - -int -GS_EnterGraphicsMode(_THIS) -{ - struct termios keyboard_termios; - - /* Set medium-raw keyboard mode */ - if ((keyboard_fd >= 0) && !GS_InGraphicsMode(this)) { - - /* Switch to the correct virtual terminal */ - if (current_vt > 0) { - struct vt_stat vtstate; - - if (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) { - saved_vt = vtstate.v_active; - } - if (ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0) { - ioctl(keyboard_fd, VT_WAITACTIVE, current_vt); - } - } - - /* Set the terminal input mode */ - if (tcgetattr(keyboard_fd, &saved_kbd_termios) < 0) { - SDL_SetError("Unable to get terminal attributes"); - if (keyboard_fd > 0) { - close(keyboard_fd); - } - keyboard_fd = -1; - return (-1); - } - if (ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0) { - SDL_SetError("Unable to get current keyboard mode"); - if (keyboard_fd > 0) { - close(keyboard_fd); - } - keyboard_fd = -1; - return (-1); - } - keyboard_termios = saved_kbd_termios; - keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); - keyboard_termios.c_iflag &= - ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); - keyboard_termios.c_cc[VMIN] = 0; - keyboard_termios.c_cc[VTIME] = 0; - if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) { - GS_CloseKeyboard(this); - SDL_SetError("Unable to set terminal attributes"); - return (-1); - } - /* This will fail if we aren't root or this isn't our tty */ - if (ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0) { - GS_CloseKeyboard(this); - SDL_SetError("Unable to set keyboard in raw mode"); - return (-1); - } - if (ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0) { - GS_CloseKeyboard(this); - SDL_SetError("Unable to set keyboard in graphics mode"); - return (-1); - } - } - return (keyboard_fd); -} - -void -GS_LeaveGraphicsMode(_THIS) -{ - if (GS_InGraphicsMode(this)) { - ioctl(keyboard_fd, KDSETMODE, KD_TEXT); - ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); - tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); - saved_kbd_mode = -1; - - /* Head back over to the original virtual terminal */ - if (saved_vt > 0) { - ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); - } - } -} - -void -GS_CloseKeyboard(_THIS) -{ - if (keyboard_fd >= 0) { - GS_LeaveGraphicsMode(this); - if (keyboard_fd > 0) { - close(keyboard_fd); - } - } - keyboard_fd = -1; -} - -int -GS_OpenKeyboard(_THIS) -{ - /* Open only if not already opened */ - if (keyboard_fd < 0) { - char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; - char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; - int i, tty0_fd; - - /* Try to query for a free virtual terminal */ - tty0_fd = -1; - for (i = 0; tty0[i] && (tty0_fd < 0); ++i) { - tty0_fd = open(tty0[i], O_WRONLY, 0); - } - if (tty0_fd < 0) { - tty0_fd = dup(0); /* Maybe stdin is a VT? */ - } - ioctl(tty0_fd, VT_OPENQRY, ¤t_vt); - close(tty0_fd); - if ((geteuid() == 0) && (current_vt > 0)) { - for (i = 0; vcs[i] && (keyboard_fd < 0); ++i) { - char vtpath[12]; - - SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], - current_vt); - keyboard_fd = open(vtpath, O_RDWR, 0); -#ifdef DEBUG_KEYBOARD - fprintf(stderr, "vtpath = %s, fd = %d\n", - vtpath, keyboard_fd); -#endif /* DEBUG_KEYBOARD */ - - /* This needs to be our controlling tty - so that the kernel ioctl() calls work - */ - if (keyboard_fd >= 0) { - tty0_fd = open("/dev/tty", O_RDWR, 0); - if (tty0_fd >= 0) { - ioctl(tty0_fd, TIOCNOTTY, 0); - close(tty0_fd); - } - } - } - } - if (keyboard_fd < 0) { - /* Last resort, maybe our tty is a usable VT */ - current_vt = 0; - keyboard_fd = open("/dev/tty", O_RDWR); - } -#ifdef DEBUG_KEYBOARD - fprintf(stderr, "Current VT: %d\n", current_vt); -#endif - saved_kbd_mode = -1; - - /* Make sure that our input is a console terminal */ - { - int dummy; - if (ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0) { - close(keyboard_fd); - keyboard_fd = -1; - SDL_SetError("Unable to open a console terminal"); - } - } - - /* Set up keymap */ - GS_vgainitkeymaps(keyboard_fd); - } - return (keyboard_fd); -} - -static enum -{ - MOUSE_NONE = -1, - MOUSE_GPM, /* Note: GPM uses the MSC protocol */ - MOUSE_PS2, - MOUSE_IMPS2, - MOUSE_MS, - MOUSE_BM, - NUM_MOUSE_DRVS -} mouse_drv = MOUSE_NONE; - -void -GS_CloseMouse(_THIS) -{ - if (mouse_fd > 0) { - close(mouse_fd); - } - mouse_fd = -1; -} - -/* Returns processes listed in /proc with the desired name */ -static int -find_pid(DIR * proc, const char *wanted_name) -{ - struct dirent *entry; - int pid; - - /* First scan proc for the gpm process */ - pid = 0; - while ((pid == 0) && ((entry = readdir(proc)) != NULL)) { - if (isdigit(entry->d_name[0])) { - FILE *status; - char path[PATH_MAX]; - char name[PATH_MAX]; - - SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", - entry->d_name); - status = fopen(path, "r"); - if (status) { - name[0] = '\0'; - fscanf(status, "Name: %s", name); - if (SDL_strcmp(name, wanted_name) == 0) { - pid = atoi(entry->d_name); - } - fclose(status); - } - } - } - return pid; -} - -/* Returns true if /dev/gpmdata is being written to by gpm */ -static int -gpm_available(void) -{ - int available; - DIR *proc; - int pid; - int cmdline, len, arglen; - char path[PATH_MAX]; - char args[PATH_MAX], *arg; - - /* Don't bother looking if the fifo isn't there */ - if (access(GPM_NODE_FIFO, F_OK) < 0) { - return (0); - } - - available = 0; - proc = opendir("/proc"); - if (proc) { - while ((pid = find_pid(proc, "gpm")) > 0) { - SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid); - cmdline = open(path, O_RDONLY, 0); - if (cmdline >= 0) { - len = read(cmdline, args, sizeof(args)); - arg = args; - while (len > 0) { - if (SDL_strcmp(arg, "-R") == 0) { - available = 1; - } - arglen = SDL_strlen(arg) + 1; - len -= arglen; - arg += arglen; - } - close(cmdline); - } - } - closedir(proc); - } - return available; -} - - -/* rcg06112001 Set up IMPS/2 mode, if possible. This gives - * us access to the mousewheel, etc. Returns zero if - * writes to device failed, but you still need to query the - * device to see which mode it's actually in. - */ -static int -set_imps2_mode(int fd) -{ - /* If you wanted to control the mouse mode (and we do :) ) ... - Set IMPS/2 protocol: - {0xf3,200,0xf3,100,0xf3,80} - Reset mouse device: - {0xFF} - */ - Uint8 set_imps2[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; - Uint8 reset = 0xff; - fd_set fdset; - struct timeval tv; - int retval = 0; - - if (write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2)) { - if (write(fd, &reset, sizeof(reset)) == sizeof(reset)) { - retval = 1; - } - } - - /* Get rid of any chatter from the above */ - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - tv.tv_sec = 0; - tv.tv_usec = 0; - while (select(fd + 1, &fdset, 0, 0, &tv) > 0) { - char temp[32]; - read(fd, temp, sizeof(temp)); - } - - return retval; -} - - -/* Returns true if the mouse uses the IMPS/2 protocol */ -static int -detect_imps2(int fd) -{ - int imps2; - - imps2 = 0; - - if (SDL_getenv("SDL_MOUSEDEV_IMPS2")) { - imps2 = 1; - } - if (!imps2) { - Uint8 query_ps2 = 0xF2; - fd_set fdset; - struct timeval tv; - - /* Get rid of any mouse motion noise */ - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - tv.tv_sec = 0; - tv.tv_usec = 0; - while (select(fd + 1, &fdset, 0, 0, &tv) > 0) { - char temp[32]; - read(fd, temp, sizeof(temp)); - } - - /* Query for the type of mouse protocol */ - if (write(fd, &query_ps2, sizeof(query_ps2)) == sizeof(query_ps2)) { - Uint8 ch = 0; - - /* Get the mouse protocol response */ - do { - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - tv.tv_sec = 1; - tv.tv_usec = 0; - if (select(fd + 1, &fdset, 0, 0, &tv) < 1) { - break; - } - } while ((read(fd, &ch, sizeof(ch)) == sizeof(ch)) && - ((ch == 0xFA) || (ch == 0xAA))); - - /* Experimental values (Logitech wheelmouse) */ -#ifdef DEBUG_MOUSE - fprintf(stderr, "Last mouse mode: 0x%x\n", ch); -#endif - if (ch == 3) { - imps2 = 1; - } - } - } - return imps2; -} - -int -GS_OpenMouse(_THIS) -{ - int i; - const char *mousedev; - const char *mousedrv; - - mousedrv = SDL_getenv("SDL_MOUSEDRV"); - mousedev = SDL_getenv("SDL_MOUSEDEV"); - mouse_fd = -1; - - /* STD MICE */ - - if (mousedev == NULL) { - /* FIXME someday... allow multiple mice in this driver */ - char *ps2mice[] = { - "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL - }; - /* First try to use GPM in repeater mode */ - if (mouse_fd < 0) { - if (gpm_available()) { - mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); - if (mouse_fd >= 0) { -#ifdef DEBUG_MOUSE - fprintf(stderr, "Using GPM mouse\n"); -#endif - mouse_drv = MOUSE_GPM; - } - } - } - /* Now try to use a modern PS/2 mouse */ - for (i = 0; (mouse_fd < 0) && ps2mice[i]; ++i) { - mouse_fd = open(ps2mice[i], O_RDWR, 0); - if (mouse_fd < 0) { - mouse_fd = open(ps2mice[i], O_RDONLY, 0); - } - if (mouse_fd >= 0) { - /* rcg06112001 Attempt to set IMPS/2 mode */ - if (i == 0) { - set_imps2_mode(mouse_fd); - } - if (detect_imps2(mouse_fd)) { -#ifdef DEBUG_MOUSE - fprintf(stderr, "Using IMPS2 mouse\n"); -#endif - mouse_drv = MOUSE_IMPS2; - } else { - mouse_drv = MOUSE_PS2; -#ifdef DEBUG_MOUSE - fprintf(stderr, "Using PS2 mouse\n"); -#endif - } - } - } - /* Next try to use a PPC ADB port mouse */ - if (mouse_fd < 0) { - mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); - if (mouse_fd >= 0) { -#ifdef DEBUG_MOUSE - fprintf(stderr, "Using ADB mouse\n"); -#endif - mouse_drv = MOUSE_BM; - } - } - } - /* Default to a serial Microsoft mouse */ - if (mouse_fd < 0) { - if (mousedev == NULL) { - mousedev = "/dev/mouse"; - } - mouse_fd = open(mousedev, O_RDONLY, 0); - if (mouse_fd >= 0) { - struct termios mouse_termios; - - /* Set the sampling speed to 1200 baud */ - tcgetattr(mouse_fd, &mouse_termios); - mouse_termios.c_iflag = IGNBRK | IGNPAR; - mouse_termios.c_oflag = 0; - mouse_termios.c_lflag = 0; - mouse_termios.c_line = 0; - mouse_termios.c_cc[VTIME] = 0; - mouse_termios.c_cc[VMIN] = 1; - mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; - mouse_termios.c_cflag |= CS8; - mouse_termios.c_cflag |= B1200; - tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios); -#ifdef DEBUG_MOUSE - fprintf(stderr, "Using Microsoft mouse on %s\n", mousedev); -#endif - mouse_drv = MOUSE_MS; - } - } - if (mouse_fd < 0) { - mouse_drv = MOUSE_NONE; - } - return (mouse_fd); -} - -static int posted = 0; - -void -GS_vgamousecallback(int button, int dx, int dy) -{ - int button_1, button_3; - int button_state; - int state_changed; - int i; - Uint8 state; - - if (dx || dy) { - posted += SDL_PrivateMouseMotion(0, 1, dx, dy); - } - - /* Swap button 1 and 3 */ - button_1 = (button & 0x04) >> 2; - button_3 = (button & 0x01) << 2; - button &= ~0x05; - button |= (button_1 | button_3); - - /* See what changed */ - button_state = SDL_GetMouseState(NULL, NULL); - state_changed = button_state ^ button; - for (i = 0; i < 8; ++i) { - if (state_changed & (1 << i)) { - if (button & (1 << i)) { - state = SDL_PRESSED; - } else { - state = SDL_RELEASED; - } - posted += SDL_PrivateMouseButton(state, i + 1, 0, 0); - } - } -} - -/* For now, use GPM, PS/2, and MS protocols - Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) - */ -static void -handle_mouse(_THIS) -{ - static int start = 0; - static unsigned char mousebuf[BUFSIZ]; - int i, nread; - int button = 0; - int dx = 0, dy = 0; - int packetsize = 0; - - /* Figure out the mouse packet size */ - switch (mouse_drv) { - case MOUSE_NONE: - /* Ack! */ - read(mouse_fd, mousebuf, BUFSIZ); - return; - case MOUSE_GPM: - packetsize = 5; - break; - case MOUSE_IMPS2: - packetsize = 4; - break; - case MOUSE_PS2: - case MOUSE_MS: - case MOUSE_BM: - packetsize = 3; - break; - case NUM_MOUSE_DRVS: - /* Uh oh.. */ - packetsize = 0; - break; - } - - /* Read as many packets as possible */ - nread = read(mouse_fd, &mousebuf[start], BUFSIZ - start); - if (nread < 0) { - return; - } - nread += start; -#ifdef DEBUG_MOUSE - fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start); -#endif - for (i = 0; i < (nread - (packetsize - 1)); i += packetsize) { - switch (mouse_drv) { - case MOUSE_NONE: - break; - case MOUSE_GPM: - /* GPM protocol has 0x80 in high byte */ - if ((mousebuf[i] & 0xF8) != 0x80) { - /* Go to next byte */ - i -= (packetsize - 1); - continue; - } - /* Get current mouse state */ - button = (~mousebuf[i]) & 0x07; - dx = (signed char) (mousebuf[i + 1]) + - (signed char) (mousebuf[i + 3]); - dy = -((signed char) (mousebuf[i + 2]) + - (signed char) (mousebuf[i + 4])); - break; - case MOUSE_PS2: - /* PS/2 protocol has nothing in high byte */ - if ((mousebuf[i] & 0xC0) != 0) { - /* Go to next byte */ - i -= (packetsize - 1); - continue; - } - /* Get current mouse state */ - button = (mousebuf[i] & 0x04) >> 1 | /*Middle */ - (mousebuf[i] & 0x02) >> 1 | /*Right */ - (mousebuf[i] & 0x01) << 2; /*Left */ - dx = (mousebuf[i] & 0x10) ? - mousebuf[i + 1] - 256 : mousebuf[i + 1]; - dy = (mousebuf[i] & 0x20) ? - -(mousebuf[i + 2] - 256) : -mousebuf[i + 2]; - break; - case MOUSE_IMPS2: - /* Get current mouse state */ - button = (mousebuf[i] & 0x04) >> 1 | /*Middle */ - (mousebuf[i] & 0x02) >> 1 | /*Right */ - (mousebuf[i] & 0x01) << 2 | /*Left */ - (mousebuf[i] & 0x40) >> 3 | /* 4 */ - (mousebuf[i] & 0x80) >> 3; /* 5 */ - dx = (mousebuf[i] & 0x10) ? - mousebuf[i + 1] - 256 : mousebuf[i + 1]; - dy = (mousebuf[i] & 0x20) ? - -(mousebuf[i + 2] - 256) : -mousebuf[i + 2]; - switch (mousebuf[i + 3] & 0x0F) { - case 0x0E: /* DX = +1 */ - case 0x02: /* DX = -1 */ - break; - case 0x0F: /* DY = +1 (map button 4) */ - FB_vgamousecallback(button | (1 << 3), 1, 0, 0); - break; - case 0x01: /* DY = -1 (map button 5) */ - FB_vgamousecallback(button | (1 << 4), 1, 0, 0); - break; - } - break; - case MOUSE_MS: - /* Microsoft protocol has 0x40 in high byte */ - if ((mousebuf[i] & 0x40) != 0x40) { - /* Go to next byte */ - i -= (packetsize - 1); - continue; - } - /* Get current mouse state */ - button = ((mousebuf[i] & 0x20) >> 3) | - ((mousebuf[i] & 0x10) >> 4); - dx = (signed char) (((mousebuf[i] & 0x03) << 6) | - (mousebuf[i + 1] & 0x3F)); - dy = (signed char) (((mousebuf[i] & 0x0C) << 4) | - (mousebuf[i + 2] & 0x3F)); - break; - case MOUSE_BM: - /* BusMouse protocol has 0xF8 in high byte */ - if ((mousebuf[i] & 0xF8) != 0x80) { - /* Go to next byte */ - i -= (packetsize - 1); - continue; - } - /* Get current mouse state */ - button = (~mousebuf[i]) & 0x07; - dx = (signed char) mousebuf[i + 1]; - dy = -(signed char) mousebuf[i + 2]; - break; - case NUM_MOUSE_DRVS: - /* Uh oh.. */ - dx = 0; - dy = 0; - break; - } - GS_vgamousecallback(button, dx, dy); - } - if (i < nread) { - SDL_memcpy(mousebuf, &mousebuf[i], (nread - i)); - start = (nread - i); - } else { - start = 0; - } - return; -} - -static void -handle_keyboard(_THIS) -{ - unsigned char keybuf[BUFSIZ]; - int i, nread; - int pressed; - int scancode; - SDL_keysym keysym; - - nread = read(keyboard_fd, keybuf, BUFSIZ); - for (i = 0; i < nread; ++i) { - scancode = keybuf[i] & 0x7F; - if (keybuf[i] & 0x80) { - pressed = SDL_RELEASED; - } else { - pressed = SDL_PRESSED; - } - TranslateKey(scancode, &keysym); - posted += SDL_PrivateKeyboard(pressed, &keysym); - } -} - -void -GS_PumpEvents(_THIS) -{ - fd_set fdset; - int max_fd; - static struct timeval zero; - - do { - posted = 0; - - FD_ZERO(&fdset); - max_fd = 0; - if (keyboard_fd >= 0) { - FD_SET(keyboard_fd, &fdset); - if (max_fd < keyboard_fd) { - max_fd = keyboard_fd; - } - } - if (mouse_fd >= 0) { - FD_SET(mouse_fd, &fdset); - if (max_fd < mouse_fd) { - max_fd = mouse_fd; - } - } - if (select(max_fd + 1, &fdset, NULL, NULL, &zero) > 0) { - if (keyboard_fd >= 0) { - if (FD_ISSET(keyboard_fd, &fdset)) { - handle_keyboard(this); - } - } - if (mouse_fd >= 0) { - if (FD_ISSET(mouse_fd, &fdset)) { - handle_mouse(this); - } - } - } - } while (posted); -} - -void -GS_InitOSKeymap(_THIS) -{ - int i; - - /* Initialize the Linux key translation table */ - - /* First get the ascii keys and others not well handled */ - for (i = 0; i < SDL_arraysize(keymap); ++i) { - switch (i) { - /* These aren't handled by the x86 kernel keymapping (?) */ - case SCANCODE_PRINTSCREEN: - keymap[i] = SDLK_PRINT; - break; - case SCANCODE_BREAK: - keymap[i] = SDLK_BREAK; - break; - case SCANCODE_BREAK_ALTERNATIVE: - keymap[i] = SDLK_PAUSE; - break; - case SCANCODE_LEFTSHIFT: - keymap[i] = SDLK_LSHIFT; - break; - case SCANCODE_RIGHTSHIFT: - keymap[i] = SDLK_RSHIFT; - break; - case SCANCODE_LEFTCONTROL: - keymap[i] = SDLK_LCTRL; - break; - case SCANCODE_RIGHTCONTROL: - keymap[i] = SDLK_RCTRL; - break; - case SCANCODE_RIGHTWIN: - keymap[i] = SDLK_RSUPER; - break; - case SCANCODE_LEFTWIN: - keymap[i] = SDLK_LSUPER; - break; - case 127: - keymap[i] = SDLK_MENU; - break; - /* this should take care of all standard ascii keys */ - default: - keymap[i] = KVAL(vga_keymap[0][i]); - break; - } - } - for (i = 0; i < SDL_arraysize(keymap); ++i) { - switch (keymap_temp[i]) { - case K_F1: - keymap[i] = SDLK_F1; - break; - case K_F2: - keymap[i] = SDLK_F2; - break; - case K_F3: - keymap[i] = SDLK_F3; - break; - case K_F4: - keymap[i] = SDLK_F4; - break; - case K_F5: - keymap[i] = SDLK_F5; - break; - case K_F6: - keymap[i] = SDLK_F6; - break; - case K_F7: - keymap[i] = SDLK_F7; - break; - case K_F8: - keymap[i] = SDLK_F8; - break; - case K_F9: - keymap[i] = SDLK_F9; - break; - case K_F10: - keymap[i] = SDLK_F10; - break; - case K_F11: - keymap[i] = SDLK_F11; - break; - case K_F12: - keymap[i] = SDLK_F12; - break; - - case K_DOWN: - keymap[i] = SDLK_DOWN; - break; - case K_LEFT: - keymap[i] = SDLK_LEFT; - break; - case K_RIGHT: - keymap[i] = SDLK_RIGHT; - break; - case K_UP: - keymap[i] = SDLK_UP; - break; - - case K_P0: - keymap[i] = SDLK_KP0; - break; - case K_P1: - keymap[i] = SDLK_KP1; - break; - case K_P2: - keymap[i] = SDLK_KP2; - break; - case K_P3: - keymap[i] = SDLK_KP3; - break; - case K_P4: - keymap[i] = SDLK_KP4; - break; - case K_P5: - keymap[i] = SDLK_KP5; - break; - case K_P6: - keymap[i] = SDLK_KP6; - break; - case K_P7: - keymap[i] = SDLK_KP7; - break; - case K_P8: - keymap[i] = SDLK_KP8; - break; - case K_P9: - keymap[i] = SDLK_KP9; - break; - case K_PPLUS: - keymap[i] = SDLK_KP_PLUS; - break; - case K_PMINUS: - keymap[i] = SDLK_KP_MINUS; - break; - case K_PSTAR: - keymap[i] = SDLK_KP_MULTIPLY; - break; - case K_PSLASH: - keymap[i] = SDLK_KP_DIVIDE; - break; - case K_PENTER: - keymap[i] = SDLK_KP_ENTER; - break; - case K_PDOT: - keymap[i] = SDLK_KP_PERIOD; - break; - - case K_SHIFT: - if (keymap[i] != SDLK_RSHIFT) - keymap[i] = SDLK_LSHIFT; - break; - case K_SHIFTL: - keymap[i] = SDLK_LSHIFT; - break; - case K_SHIFTR: - keymap[i] = SDLK_RSHIFT; - break; - case K_CTRL: - if (keymap[i] != SDLK_RCTRL) - keymap[i] = SDLK_LCTRL; - break; - case K_CTRLL: - keymap[i] = SDLK_LCTRL; - break; - case K_CTRLR: - keymap[i] = SDLK_RCTRL; - break; - case K_ALT: - keymap[i] = SDLK_LALT; - break; - case K_ALTGR: - keymap[i] = SDLK_RALT; - break; - - case K_INSERT: - keymap[i] = SDLK_INSERT; - break; - case K_REMOVE: - keymap[i] = SDLK_DELETE; - break; - case K_PGUP: - keymap[i] = SDLK_PAGEUP; - break; - case K_PGDN: - keymap[i] = SDLK_PAGEDOWN; - break; - case K_FIND: - keymap[i] = SDLK_HOME; - break; - case K_SELECT: - keymap[i] = SDLK_END; - break; - - case K_NUM: - keymap[i] = SDLK_NUMLOCK; - break; - case K_CAPS: - keymap[i] = SDLK_CAPSLOCK; - break; - - case K_F13: - keymap[i] = SDLK_PRINT; - break; - case K_HOLD: - keymap[i] = SDLK_SCROLLOCK; - break; - case K_PAUSE: - keymap[i] = SDLK_PAUSE; - break; - - case 127: - keymap[i] = SDLK_BACKSPACE; - break; - - default: - break; - } - } -} - -static SDL_keysym * -TranslateKey(int scancode, SDL_keysym * keysym) -{ - /* Set the keysym information */ - keysym->scancode = scancode; - keysym->sym = keymap[scancode]; - keysym->mod = KMOD_NONE; - - /* If UNICODE is on, get the UNICODE value for the key */ - keysym->unicode = 0; - if (SDL_TranslateUNICODE) { - int map; - SDLMod modstate; - - modstate = SDL_GetModState(); - map = 0; - if (modstate & KMOD_SHIFT) { - map |= (1 << KG_SHIFT); - } - if (modstate & KMOD_CTRL) { - map |= (1 << KG_CTRL); - } - if (modstate & KMOD_ALT) { - map |= (1 << KG_ALT); - } - if (modstate & KMOD_MODE) { - map |= (1 << KG_ALTGR); - } - if (KTYP(vga_keymap[map][scancode]) == KT_LETTER) { - if (modstate & KMOD_CAPS) { - map ^= (1 << KG_SHIFT); - } - } - if (KTYP(vga_keymap[map][scancode]) == KT_PAD) { - if (modstate & KMOD_NUM) { - keysym->unicode = KVAL(vga_keymap[map][scancode]); - } - } else { - keysym->unicode = KVAL(vga_keymap[map][scancode]); - } - } - return (keysym); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsevents_c.h Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - 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" - -#include "SDL_gsvideo.h" - -/* Variables and functions exported by SDL_sysevents.c to other parts - of the native video subsystem (SDL_sysvideo.c) -*/ -extern int GS_OpenKeyboard(_THIS); -extern void GS_CloseKeyboard(_THIS); -extern int GS_OpenMouse(_THIS); -extern void GS_CloseMouse(_THIS); -extern int GS_EnterGraphicsMode(_THIS); -extern int GS_InGraphicsMode(_THIS); -extern void GS_LeaveGraphicsMode(_THIS); - -extern void GS_InitOSKeymap(_THIS); -extern void GS_PumpEvents(_THIS); -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gskeys.h Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ - -/* Scancodes for the Linux framebuffer console - - Taken with thanks from SVGAlib 1.4.0 -*/ - -#define SCANCODE_ESCAPE 1 - -#define SCANCODE_1 2 -#define SCANCODE_2 3 -#define SCANCODE_3 4 -#define SCANCODE_4 5 -#define SCANCODE_5 6 -#define SCANCODE_6 7 -#define SCANCODE_7 8 -#define SCANCODE_8 9 -#define SCANCODE_9 10 -#define SCANCODE_0 11 - -#define SCANCODE_MINUS 12 -#define SCANCODE_EQUAL 13 - -#define SCANCODE_BACKSPACE 14 -#define SCANCODE_TAB 15 - -#define SCANCODE_Q 16 -#define SCANCODE_W 17 -#define SCANCODE_E 18 -#define SCANCODE_R 19 -#define SCANCODE_T 20 -#define SCANCODE_Y 21 -#define SCANCODE_U 22 -#define SCANCODE_I 23 -#define SCANCODE_O 24 -#define SCANCODE_P 25 -#define SCANCODE_BRACKET_LEFT 26 -#define SCANCODE_BRACKET_RIGHT 27 - -#define SCANCODE_ENTER 28 - -#define SCANCODE_LEFTCONTROL 29 - -#define SCANCODE_A 30 -#define SCANCODE_S 31 -#define SCANCODE_D 32 -#define SCANCODE_F 33 -#define SCANCODE_G 34 -#define SCANCODE_H 35 -#define SCANCODE_J 36 -#define SCANCODE_K 37 -#define SCANCODE_L 38 -#define SCANCODE_SEMICOLON 39 -#define SCANCODE_APOSTROPHE 40 -#define SCANCODE_GRAVE 41 - -#define SCANCODE_LEFTSHIFT 42 -#define SCANCODE_BACKSLASH 43 - -#define SCANCODE_Z 44 -#define SCANCODE_X 45 -#define SCANCODE_C 46 -#define SCANCODE_V 47 -#define SCANCODE_B 48 -#define SCANCODE_N 49 -#define SCANCODE_M 50 -#define SCANCODE_COMMA 51 -#define SCANCODE_PERIOD 52 -#define SCANCODE_SLASH 53 - -#define SCANCODE_RIGHTSHIFT 54 -#define SCANCODE_KEYPADMULTIPLY 55 - -#define SCANCODE_LEFTALT 56 -#define SCANCODE_SPACE 57 -#define SCANCODE_CAPSLOCK 58 - -#define SCANCODE_F1 59 -#define SCANCODE_F2 60 -#define SCANCODE_F3 61 -#define SCANCODE_F4 62 -#define SCANCODE_F5 63 -#define SCANCODE_F6 64 -#define SCANCODE_F7 65 -#define SCANCODE_F8 66 -#define SCANCODE_F9 67 -#define SCANCODE_F10 68 - -#define SCANCODE_NUMLOCK 69 -#define SCANCODE_SCROLLLOCK 70 - -#define SCANCODE_KEYPAD7 71 -#define SCANCODE_CURSORUPLEFT 71 -#define SCANCODE_KEYPAD8 72 -#define SCANCODE_CURSORUP 72 -#define SCANCODE_KEYPAD9 73 -#define SCANCODE_CURSORUPRIGHT 73 -#define SCANCODE_KEYPADMINUS 74 -#define SCANCODE_KEYPAD4 75 -#define SCANCODE_CURSORLEFT 75 -#define SCANCODE_KEYPAD5 76 -#define SCANCODE_KEYPAD6 77 -#define SCANCODE_CURSORRIGHT 77 -#define SCANCODE_KEYPADPLUS 78 -#define SCANCODE_KEYPAD1 79 -#define SCANCODE_CURSORDOWNLEFT 79 -#define SCANCODE_KEYPAD2 80 -#define SCANCODE_CURSORDOWN 80 -#define SCANCODE_KEYPAD3 81 -#define SCANCODE_CURSORDOWNRIGHT 81 -#define SCANCODE_KEYPAD0 82 -#define SCANCODE_KEYPADPERIOD 83 - -#define SCANCODE_LESS 86 - -#define SCANCODE_F11 87 -#define SCANCODE_F12 88 - -#define SCANCODE_KEYPADENTER 96 -#define SCANCODE_RIGHTCONTROL 97 -#define SCANCODE_CONTROL 97 -#define SCANCODE_KEYPADDIVIDE 98 -#define SCANCODE_PRINTSCREEN 99 -#define SCANCODE_RIGHTALT 100 -#define SCANCODE_BREAK 101 /* Beware: is 119 */ -#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */ - -#define SCANCODE_HOME 102 -#define SCANCODE_CURSORBLOCKUP 103 /* Cursor key block */ -#define SCANCODE_PAGEUP 104 -#define SCANCODE_CURSORBLOCKLEFT 105 /* Cursor key block */ -#define SCANCODE_CURSORBLOCKRIGHT 106 /* Cursor key block */ -#define SCANCODE_END 107 -#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */ -#define SCANCODE_PAGEDOWN 109 -#define SCANCODE_INSERT 110 -#define SCANCODE_REMOVE 111 - -#define SCANCODE_RIGHTWIN 126 -#define SCANCODE_LEFTWIN 125 -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsmouse.c Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/* - 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" - -#include <sys/ioctl.h> - -#include "SDL_mouse.h" -#include "../../events/SDL_events_c.h" -#include "../SDL_cursor_c.h" -#include "SDL_gsvideo.h" -#include "SDL_gsmouse_c.h" - - -/* The implementation dependent data for the window manager cursor */ -struct WMcursor -{ - int unused; -}; - -/* There isn't any implementation dependent data */ -void -GS_FreeWMCursor(_THIS, WMcursor * cursor) -{ - return; -} - -/* There isn't any implementation dependent data */ -WMcursor * -GS_CreateWMCursor(_THIS, - Uint8 * data, Uint8 * mask, int w, int h, int hot_x, - int hot_y) -{ - return ((WMcursor *) 0x01); -} - -static void -GS_MoveCursor(_THIS, SDL_Cursor * cursor, int x, int y) -{ - SDL_Surface *screen; - struct ps2_image image; - SDL_Rect area; - int mouse_y1, mouse_y2; - void *saved_pixels; - int screen_updated; - - /* Lock so we don't interrupt an update with mouse motion */ - SDL_LockCursor(); - - /* Make sure any pending DMA has completed */ - if (dma_pending) { - ioctl(console_fd, PS2IOC_SENDQCT, 1); - dma_pending = 0; - } - - /* Remove the cursor image from the DMA area */ - screen = this->screen; - saved_pixels = screen->pixels; - screen->pixels = mapped_mem + screen->offset; - screen_updated = 0; - if (cursor_drawn) { - SDL_EraseCursorNoLock(screen); - cursor_drawn = 0; - screen_updated = 1; - } - - /* Save the current mouse area */ - SDL_MouseRect(&area); - mouse_y1 = area.y; - mouse_y2 = area.y + area.h; - - /* Only draw the new cursor if there was one passed in */ - if (cursor) { - /* Set the new location */ - cursor->area.x = (x - cursor->hot_x); - cursor->area.y = (y - cursor->hot_y); - - /* Draw the cursor at the new location */ - if ((SDL_cursorstate & CURSOR_VISIBLE) && screen->pixels) { - SDL_DrawCursorNoLock(screen); - cursor_drawn = 1; - screen_updated = 1; - } - } - screen->pixels = saved_pixels; - - /* Update the affected area of the screen */ - if (screen_updated) { - SDL_MouseRect(&area); - if (area.y < mouse_y1) { - mouse_y1 = area.y; - } - if ((area.y + area.h) > mouse_y2) { - mouse_y2 = area.y + area.h; - } - image = screen_image; - image.y += screen->offset / screen->pitch + mouse_y1; - image.h = mouse_y2 - mouse_y1; - image.ptr = mapped_mem + (image.y - screen_image.y) * screen->pitch; - ioctl(console_fd, PS2IOC_LOADIMAGE, &image); - - /* Need to scale offscreen image to TV output */ - if (image.y > 0) { - scaleimage_nonblock(console_fd, tex_tags_mem, scale_tags_mem); - } - } - - /* We're finished */ - SDL_UnlockCursor(); -} - -void -GS_MoveWMCursor(_THIS, int x, int y) -{ - GS_MoveCursor(this, SDL_cursor, x, y); -} - -int -GS_ShowWMCursor(_THIS, WMcursor * wmcursor) -{ - SDL_Cursor *cursor; - int x, y; - - /* Draw the cursor at the appropriate location */ - SDL_GetMouseState(&x, &y); - if (wmcursor) { - cursor = SDL_cursor; - } else { - cursor = NULL; - } - GS_MoveCursor(this, cursor, x, y); - return (1); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsmouse_c.h Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - 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" - -#include "SDL_gsvideo.h" - -/* This is the maximum size of the cursor sprite */ -#define CURSOR_W 32 -#define CURSOR_H 32 -#define CURSOR_W_POW 5 /* 32 = 2^5 */ -#define CURSOR_H_POW 5 /* 32 = 2^5 */ - -/* Functions to be exported */ -extern void GS_FreeWMCursor(_THIS, WMcursor * cursor); -extern WMcursor *GS_CreateWMCursor(_THIS, - Uint8 * data, Uint8 * mask, int w, int h, - int hot_x, int hot_y); -extern void GS_MoveWMCursor(_THIS, int x, int y); -extern int GS_ShowWMCursor(_THIS, WMcursor * cursor); -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsvideo.c Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,693 +0,0 @@ -/* - 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" - -/* Framebuffer console based SDL video driver implementation. -*/ - -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> - -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" -#include "../SDL_cursor_c.h" -#include "SDL_gsvideo.h" -#include "SDL_gsmouse_c.h" -#include "SDL_gsevents_c.h" -#include "SDL_gsyuv_c.h" - - -/* Initialization/Query functions */ -static int GS_VideoInit(_THIS, SDL_PixelFormat * vformat); -static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags); -static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface * current, int width, - int height, int bpp, Uint32 flags); -static int GS_SetColors(_THIS, int firstcolor, int ncolors, - SDL_Color * colors); -static void GS_VideoQuit(_THIS); - -/* Hardware surface functions */ -static int GS_AllocHWSurface(_THIS, SDL_Surface * surface); -static int GS_LockHWSurface(_THIS, SDL_Surface * surface); -static void GS_UnlockHWSurface(_THIS, SDL_Surface * surface); -static void GS_FreeHWSurface(_THIS, SDL_Surface * surface); - -/* GS driver bootstrap functions */ - -static int -GS_Available(void) -{ - int console, memory; - - console = open(PS2_DEV_GS, O_RDWR, 0); - if (console >= 0) { - close(console); - } - memory = open(PS2_DEV_MEM, O_RDWR, 0); - if (memory >= 0) { - close(memory); - } - return ((console >= 0) && (memory >= 0)); -} - -static void -GS_DeleteDevice(SDL_VideoDevice * device) -{ - SDL_free(device->hidden); - SDL_free(device); -} - -static SDL_VideoDevice * -GS_CreateDevice(int devindex) -{ - SDL_VideoDevice *this; - - /* Initialize all variables that we clean on shutdown */ - this = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); - if (this) { - SDL_memset(this, 0, (sizeof *this)); - this->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof *this->hidden)); - } - if ((this == NULL) || (this->hidden == NULL)) { - SDL_OutOfMemory(); - if (this) { - SDL_free(this); - } - return (0); - } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - mouse_fd = -1; - keyboard_fd = -1; - - /* Set the function pointers */ - this->VideoInit = GS_VideoInit; - this->ListModes = GS_ListModes; - this->SetVideoMode = GS_SetVideoMode; - this->CreateYUVOverlay = GS_CreateYUVOverlay; - this->SetColors = GS_SetColors; - this->UpdateRects = NULL; - this->VideoQuit = GS_VideoQuit; - this->AllocHWSurface = GS_AllocHWSurface; - this->CheckHWBlit = NULL; - this->FillHWRect = NULL; - this->SetHWColorKey = NULL; - this->SetHWAlpha = NULL; - this->LockHWSurface = GS_LockHWSurface; - this->UnlockHWSurface = GS_UnlockHWSurface; - this->FlipHWSurface = NULL; - this->FreeHWSurface = GS_FreeHWSurface; - this->SetIcon = NULL; - this->SetCaption = NULL; - this->GetWMInfo = NULL; - this->FreeWMCursor = GS_FreeWMCursor; - this->CreateWMCursor = GS_CreateWMCursor; - this->ShowWMCursor = GS_ShowWMCursor; - this->MoveWMCursor = GS_MoveWMCursor; - this->InitOSKeymap = GS_InitOSKeymap; - this->PumpEvents = GS_PumpEvents; - - this->free = GS_DeleteDevice; - - return this; -} - -VideoBootStrap PS2GS_bootstrap = { - "ps2gs", "PlayStation 2 Graphics Synthesizer", - GS_Available, GS_CreateDevice -}; - -/* These are the pixel formats for the 32, 24, and 16 bit video modes */ -static struct -{ - int bpp; - Uint32 r; - Uint32 g; - Uint32 b; -} GS_pixelmasks[] = { - { - 32, 0x000000FF, /* RGB little-endian */ - 0x0000FF00, 0x00FF0000}, { - 24, 0x000000FF, /* RGB little-endian */ - 0x0000FF00, 0x00FF0000}, { - 16, 0x0000001f, /* RGB little-endian */ -0x000003e0, 0x00007c00},}; - -/* This is a mapping from SDL bytes-per-pixel to GS pixel format */ -static int GS_formatmap[] = { - -1, /* 0 bpp, not a legal value */ - -1, /* 8 bpp, not supported (yet?) */ - PS2_GS_PSMCT16, /* 16 bpp */ - PS2_GS_PSMCT24, /* 24 bpp */ - PS2_GS_PSMCT32 /* 32 bpp */ -}; - -static unsigned long long head_tags[] __attribute__ ((aligned(16))) = { - 4 | (1LL << 60), /* GIFtag */ - 0x0e, /* A+D */ - 0, /* 2 */ - PS2_GS_BITBLTBUF, 0, /* 4 */ - PS2_GS_TRXPOS, 0, /* 6 */ - PS2_GS_TRXREG, 0, /* 8 */ -PS2_GS_TRXDIR}; - -#define MAXIMG (32767 * 16) -#define MAXTAGS 8 - -static inline int -loadimage_nonblock(int fd, struct ps2_image *image, int size, - unsigned long long *hm, unsigned long long *im) -{ - struct ps2_plist plist; - struct ps2_packet packet[1 + MAXTAGS * 2]; - int isize; - int pnum, it, eop; - char *data; - - /* initialize the variables */ - data = (char *) image->ptr; - pnum = it = eop = 0; - plist.packet = packet; - - /* make BITBLT packet */ - packet[pnum].ptr = hm; - packet[pnum].len = sizeof(head_tags); - pnum++; - hm[2] = ((unsigned long long) image->fbp << 32) | - ((unsigned long long) image->fbw << 48) | - ((unsigned long long) image->psm << 56); - hm[4] = ((unsigned long long) image->x << 32) | - ((unsigned long long) image->y << 48); - hm[6] = (unsigned long long) image->w | - ((unsigned long long) image->h << 32); - - /* make image mode tags */ - while (!eop) { - isize = size > MAXIMG ? MAXIMG : size; - size -= isize; - eop = (size == 0); - - packet[pnum].ptr = &im[it]; - packet[pnum].len = sizeof(unsigned long long) * 2; - pnum++; - im[it++] = (isize >> 4) | (eop ? (1 << 15) : 0) | (2LL << 58); - im[it++] = 0; - - packet[pnum].ptr = (void *) data; - packet[pnum].len = isize; - pnum++; - data += isize; - } - plist.num = pnum; - - return ioctl(fd, PS2IOC_SENDL, &plist); -} - -static unsigned long long tex_tags[] __attribute__ ((aligned(16))) = { - 3 | (1LL << 60), /* GIFtag */ - 0x0e, /* A+D */ - 0, /* 2 */ -PS2_GS_TEX0_1, (1 << 5) + (1 << 6), PS2_GS_TEX1_1, 0, PS2_GS_TEXFLUSH}; - -static unsigned long long scale_tags[] __attribute__ ((aligned(16))) = { - 5 | (1LL << 60), /* GIFtag */ - 0x0e, /* A+D */ - 6 + (1 << 4) + (1 << 8), PS2_GS_PRIM, ((unsigned long long) 0 * 16) + (((unsigned long long) 0 * 16) << 16), PS2_GS_UV, ((unsigned long long) 0 * 16) + (((unsigned long long) 0 * 16) << 16), PS2_GS_XYZ2, 0, /* 8 */ - PS2_GS_UV, 0, /* 10 */ -PS2_GS_XYZ2}; - - -int -scaleimage_nonblock(int fd, unsigned long long *tm, unsigned long long *sm) -{ - struct ps2_plist plist; - struct ps2_packet packet[2]; - - /* initialize the variables */ - plist.num = 2; - plist.packet = packet; - - packet[0].ptr = tm; - packet[0].len = sizeof(tex_tags); - packet[1].ptr = sm; - packet[1].len = sizeof(scale_tags); - - return ioctl(fd, PS2IOC_SENDL, &plist); -} - -static int -power_of_2(int value) -{ - int shift; - - for (shift = 0; (1 << shift) < value; ++shift) { - /* Keep looking */ ; - } - return (shift); -} - -static int -GS_VideoInit(_THIS, SDL_PixelFormat * vformat) -{ - struct ps2_screeninfo vinfo; - - /* Initialize the library */ - console_fd = open(PS2_DEV_GS, O_RDWR, 0); - if (console_fd < 0) { - SDL_SetError("Unable to open %s", PS2_DEV_GS); - return (-1); - } - memory_fd = open(PS2_DEV_MEM, O_RDWR, 0); - if (memory_fd < 0) { - close(console_fd); - console_fd = -1; - SDL_SetError("Unable to open %s", PS2_DEV_MEM); - return (-1); - } - - if (ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0) { - close(memory_fd); - close(console_fd); - console_fd = -1; - SDL_SetError("Couldn't get console pixel format"); - return (-1); - } - - /* Determine the current screen size */ - this->info.current_w = vinfo.w; - this->info.current_h = vinfo.h; - - /* Determine the current screen depth */ - switch (vinfo.psm) { - /* Supported pixel formats */ - case PS2_GS_PSMCT32: - case PS2_GS_PSMCT24: - case PS2_GS_PSMCT16: - break; - default: - GS_VideoQuit(this); - SDL_SetError("Unknown console pixel format: %d", vinfo.psm); - return (-1); - } - vformat->BitsPerPixel = GS_pixelmasks[vinfo.psm].bpp; - vformat->Rmask = GS_pixelmasks[vinfo.psm].r; - vformat->Gmask = GS_pixelmasks[vinfo.psm].g; - vformat->Bmask = GS_pixelmasks[vinfo.psm].b; - saved_vinfo = vinfo; - - /* Enable mouse and keyboard support */ - if (GS_OpenKeyboard(this) < 0) { - GS_VideoQuit(this); - SDL_SetError("Unable to open keyboard"); - return (-1); - } - if (GS_OpenMouse(this) < 0) { - const char *sdl_nomouse; - - sdl_nomouse = SDL_getenv("SDL_NOMOUSE"); - if (!sdl_nomouse) { - GS_VideoQuit(this); - SDL_SetError("Unable to open mouse"); - return (-1); - } - } - - /* We're done! */ - return (0); -} - -static SDL_Rect ** -GS_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags) -{ - static SDL_Rect GS_vesa_mode_list[] = { - {0, 0, 1280, 1024}, - {0, 0, 1024, 768}, - {0, 0, 800, 600}, - {0, 0, 640, 480} - }; - static SDL_Rect *GS_vesa_modes[] = { - &GS_vesa_mode_list[0], - &GS_vesa_mode_list[1], - &GS_vesa_mode_list[2], - &GS_vesa_mode_list[3], - NULL - }; - static SDL_Rect GS_tvout_stretch; - static SDL_Rect GS_tvout_mode; - static SDL_Rect *GS_tvout_modes[3]; - SDL_Rect **modes = NULL; - - switch (format->BitsPerPixel) { - case 16: - case 24: - case 32: - if (saved_vinfo.mode == PS2_GS_VESA) { - modes = GS_vesa_modes; - } else { - int i, j = 0; - -// FIXME - what's wrong with the stretch code at 16 bpp? - if (format->BitsPerPixel != 32) - break; - /* Add a mode that we could possibly stretch to */ - for (i = 0; GS_vesa_modes[i]; ++i) { - if ((GS_vesa_modes[i]->w == saved_vinfo.w) && - (GS_vesa_modes[i]->h != saved_vinfo.h)) { - GS_tvout_stretch.w = GS_vesa_modes[i]->w; - GS_tvout_stretch.h = GS_vesa_modes[i]->h; - GS_tvout_modes[j++] = &GS_tvout_stretch; - break; - } - } - /* Add the current TV video mode */ - GS_tvout_mode.w = saved_vinfo.w; - GS_tvout_mode.h = saved_vinfo.h; - GS_tvout_modes[j++] = &GS_tvout_mode; - GS_tvout_modes[j++] = NULL; - - /* Return the created list of modes */ - modes = GS_tvout_modes; - } - break; - default: - break; - } - return (modes); -} - -/* Various screen update functions available */ -static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect * rects); - -static SDL_Surface * -GS_SetVideoMode(_THIS, SDL_Surface * current, - int width, int height, int bpp, Uint32 flags) -{ - struct ps2_screeninfo vinfo; - - /* Set the terminal into graphics mode */ - if (GS_EnterGraphicsMode(this) < 0) { - return (NULL); - } - - /* Set the video mode and get the final screen format */ - if (ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0) { - SDL_SetError("Couldn't get console screen info"); - return (NULL); - } - if ((vinfo.w != width) || (vinfo.h != height) || - (GS_pixelmasks[vinfo.psm].bpp != bpp)) { - /* If we're not in VESA mode, we have to scale resolution */ - if (saved_vinfo.mode == PS2_GS_VESA) { - switch (width) { - case 640: - vinfo.res = PS2_GS_640x480; - break; - case 800: - vinfo.res = PS2_GS_800x600; - break; - case 1024: - vinfo.res = PS2_GS_1024x768; - break; - case 1280: - vinfo.res = PS2_GS_1280x1024; - break; - default: - SDL_SetError("Unsupported resolution: %dx%d\n", - width, height); - return (NULL); - } - vinfo.res |= (PS2_GS_75Hz << 8); - vinfo.w = width; - vinfo.h = height; - } - vinfo.fbp = 0; - vinfo.psm = GS_formatmap[bpp / 8]; - if (vinfo.psm < 0) { - SDL_SetError("Unsupported depth: %d bpp\n", bpp); - return (NULL); - } - if (ioctl(console_fd, PS2IOC_SSCREENINFO, &vinfo) < 0) { - SDL_SetError("Couldn't set console screen info"); - return (NULL); - } - - /* Unmap the previous DMA buffer */ - if (mapped_mem) { - munmap(mapped_mem, mapped_len); - mapped_mem = NULL; - } - } - if (!SDL_ReallocFormat(current, GS_pixelmasks[vinfo.psm].bpp, - GS_pixelmasks[vinfo.psm].r, - GS_pixelmasks[vinfo.psm].g, - GS_pixelmasks[vinfo.psm].b, 0)) { - return (NULL); - } - - /* Set up the new mode framebuffer */ - current->flags = SDL_FULLSCREEN; - current->w = width; - current->h = height; - current->pitch = SDL_CalculatePitch(current); - - /* Memory map the DMA area for block memory transfer */ - if (!mapped_mem) { - pixels_len = height * current->pitch; - mapped_len = pixels_len + - /* Screen update DMA command area */ - sizeof(head_tags) + ((2 * MAXTAGS) * 16); - if (saved_vinfo.mode != PS2_GS_VESA) { - mapped_len += sizeof(tex_tags) + sizeof(scale_tags); - } - mapped_mem = mmap(0, mapped_len, PROT_READ | PROT_WRITE, - MAP_SHARED, memory_fd, 0); - if (mapped_mem == MAP_FAILED) { - SDL_SetError("Unable to map %d bytes for DMA", mapped_len); - mapped_mem = NULL; - return (NULL); - } - - /* Set up the entire screen for DMA transfer */ - screen_image.ptr = mapped_mem; - screen_image.fbp = 0; - screen_image.fbw = (vinfo.w + 63) / 64; - screen_image.psm = vinfo.psm; - screen_image.x = 0; - if (vinfo.h == height) { - screen_image.y = 0; - } else { - /* Put image offscreen and scale to screen height */ - screen_image.y = vinfo.h; - } - screen_image.w = current->w; - screen_image.h = current->h; - - /* get screen image data size (qword aligned) */ - screen_image_size = (screen_image.w * screen_image.h); - switch (screen_image.psm) { - case PS2_GS_PSMCT32: - screen_image_size *= 4; - break; - case PS2_GS_PSMCT24: - screen_image_size *= 3; - break; - case PS2_GS_PSMCT16: - screen_image_size *= 2; - break; - } - screen_image_size = (screen_image_size + 15) & ~15; - - /* Set up the memory for screen update DMA commands */ - head_tags_mem = (unsigned long long *) (mapped_mem + pixels_len); - image_tags_mem = (unsigned long long *) - ((caddr_t) head_tags_mem + sizeof(head_tags)); - SDL_memcpy(head_tags_mem, head_tags, sizeof(head_tags)); - if (saved_vinfo.mode != PS2_GS_VESA) { - tex_tags_mem = (unsigned long long *) - ((caddr_t) image_tags_mem + ((2 * MAXTAGS) * 16)); - scale_tags_mem = (unsigned long long *) - ((caddr_t) tex_tags_mem + sizeof(tex_tags)); - SDL_memcpy(tex_tags_mem, tex_tags, sizeof(tex_tags)); - tex_tags_mem[2] = - (vinfo.h * vinfo.w) / 64 + - ((unsigned long long) screen_image.fbw << 14) + - ((unsigned long long) screen_image.psm << 20) + - ((unsigned long long) power_of_2(screen_image.w) << 26) + - ((unsigned long long) power_of_2(screen_image.h) << 30) + - ((unsigned long long) 1 << 34) + - ((unsigned long long) 1 << 35); - SDL_memcpy(scale_tags_mem, scale_tags, sizeof(scale_tags)); - scale_tags_mem[8] = - ((unsigned long long) screen_image.w * 16) + - (((unsigned long long) screen_image.h * 16) << 16); - scale_tags_mem[10] = - ((unsigned long long) vinfo.w * 16) + - (((unsigned long long) vinfo.h * 16) << 16); - } - } - current->pixels = NULL; - if (SDL_getenv("SDL_FULLSCREEN_UPDATE")) { - /* Correct semantics */ - current->flags |= SDL_ASYNCBLIT; - } else { - /* We lie here - the screen memory isn't really the visible - display memory and still requires an update, but this - has the desired effect for most applications. - */ - current->flags |= SDL_HWSURFACE; - } - - /* Set the update rectangle function */ - this->UpdateRects = GS_DMAFullUpdate; - - /* We're done */ - return (current); -} - -/* We don't support hardware surfaces yet */ -static int -GS_AllocHWSurface(_THIS, SDL_Surface * surface) -{ - return (-1); -} - -static void -GS_FreeHWSurface(_THIS, SDL_Surface * surface) -{ - return; -} - -static int -GS_LockHWSurface(_THIS, SDL_Surface * surface) -{ - if (surface == this->screen) { - /* Since mouse motion affects 'pixels', lock it */ - SDL_LockCursor(); - - /* Make sure any pending DMA has completed */ - if (dma_pending) { - ioctl(console_fd, PS2IOC_SENDQCT, 1); - dma_pending = 0; - } - - /* If the cursor is drawn on the DMA area, remove it */ - if (cursor_drawn) { - surface->pixels = mapped_mem + surface->offset; - SDL_EraseCursorNoLock(this->screen); - cursor_drawn = 0; - } - - /* Set the surface pixels to the base of the DMA area */ - surface->pixels = mapped_mem; - - /* We're finished! */ - SDL_UnlockCursor(); - } - return (0); -} - -static void -GS_UnlockHWSurface(_THIS, SDL_Surface * surface) -{ - if (surface == this->screen) { - /* Since mouse motion affects 'pixels', lock it */ - SDL_LockCursor(); - surface->pixels = NULL; - SDL_UnlockCursor(); - } -} - -static void -GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect * rects) -{ - /* Lock so we aren't interrupted by a mouse update */ - SDL_LockCursor(); - - /* Make sure any pending DMA has completed */ - if (dma_pending) { - ioctl(console_fd, PS2IOC_SENDQCT, 1); - dma_pending = 0; - } - - /* If the mouse is visible, draw it on the DMA area */ - if ((SDL_cursorstate & CURSOR_VISIBLE) && !cursor_drawn) { - this->screen->pixels = mapped_mem + this->screen->offset; - SDL_DrawCursorNoLock(this->screen); - this->screen->pixels = NULL; - cursor_drawn = 1; - } - - /* Put the image onto the screen */ - loadimage_nonblock(console_fd, - &screen_image, screen_image_size, - head_tags_mem, image_tags_mem); - if (screen_image.y > 0) { - /* Need to scale offscreen image to TV output */ - ioctl(console_fd, PS2IOC_SENDQCT, 1); - dma_pending = 0; - scaleimage_nonblock(console_fd, tex_tags_mem, scale_tags_mem); - } else { - dma_pending = 1; - } - - /* We're finished! */ - SDL_UnlockCursor(); -} - -static int -GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) -{ - return (0); -} - -static void -GS_VideoQuit(_THIS) -{ - /* Close console and input file descriptors */ - if (console_fd > 0) { - /* Unmap the video framebuffer */ - if (mapped_mem) { - /* Unmap the video framebuffer */ - munmap(mapped_mem, mapped_len); - mapped_mem = NULL; - } - close(memory_fd); - - /* Restore the original video mode */ - if (GS_InGraphicsMode(this)) { - ioctl(console_fd, PS2IOC_SSCREENINFO, &saved_vinfo); - } - - /* We're all done with the graphics device */ - close(console_fd); - console_fd = -1; - } - GS_CloseMouse(this); - GS_CloseKeyboard(this); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsvideo.h Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - 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" - -#ifndef _SDL_gsvideo_h -#define _SDL_gsvideo_h - -#include <sys/types.h> -#include <termios.h> -#include <linux/ps2/dev.h> -#include <linux/ps2/gs.h> - -#include "SDL_mouse.h" -#include "SDL_mutex.h" -#include "../SDL_sysvideo.h" - -/* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *this - - -/* Private display data */ -struct SDL_PrivateVideoData -{ - /* Gotta love that simple PS2 graphics interface. :) */ - int console_fd; - int memory_fd; - struct ps2_screeninfo saved_vinfo; - - /* Ye olde linux keyboard code */ - int current_vt; - int saved_vt; - int keyboard_fd; - int saved_kbd_mode; - struct termios saved_kbd_termios; - - /* Ye olde linux mouse code */ - int mouse_fd; - int cursor_drawn; - - /* The memory mapped DMA area and associated variables */ - caddr_t mapped_mem; - int pixels_len; - int mapped_len; - struct ps2_image screen_image; - int screen_image_size; - unsigned long long *head_tags_mem; - unsigned long long *image_tags_mem; - unsigned long long *tex_tags_mem; - unsigned long long *scale_tags_mem; - int dma_pending; -}; -/* Old variable names */ -#define console_fd (this->hidden->console_fd) -#define memory_fd (this->hidden->memory_fd) -#define saved_vinfo (this->hidden->saved_vinfo) -#define current_vt (this->hidden->current_vt) -#define saved_vt (this->hidden->saved_vt) -#define keyboard_fd (this->hidden->keyboard_fd) -#define saved_kbd_mode (this->hidden->saved_kbd_mode) -#define saved_kbd_termios (this->hidden->saved_kbd_termios) -#define mouse_fd (this->hidden->mouse_fd) -#define cursor_drawn (this->hidden->cursor_drawn) -#define mapped_mem (this->hidden->mapped_mem) -#define pixels_len (this->hidden->pixels_len) -#define mapped_len (this->hidden->mapped_len) -#define screen_image (this->hidden->screen_image) -#define screen_image_size (this->hidden->screen_image_size) -#define head_tags_mem (this->hidden->head_tags_mem) -#define image_tags_mem (this->hidden->image_tags_mem) -#define tex_tags_mem (this->hidden->tex_tags_mem) -#define scale_tags_mem (this->hidden->scale_tags_mem) -#define dma_pending (this->hidden->dma_pending) - -/* Shared between the mouse and video code for screen update scaling */ -extern int scaleimage_nonblock(int fd, - unsigned long long *tm, - unsigned long long *sm); -#endif /* _SDL_gsvideo_h */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsyuv.c Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,471 +0,0 @@ -/* - 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" - -/* This is the Playstation 2 implementation of YUV video overlays */ - -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <asm/page.h> /* For definition of PAGE_SIZE */ - -#include "SDL_video.h" -#include "SDL_gsyuv_c.h" -#include "../SDL_yuvfuncs.h" - -/* The maximum number of 16x16 pixel block converted at once */ -#define MAX_MACROBLOCKS 1024 /* 2^10 macroblocks at once */ - -/* The functions used to manipulate video overlays */ -static struct private_yuvhwfuncs gs_yuvfuncs = { - GS_LockYUVOverlay, - GS_UnlockYUVOverlay, - GS_DisplayYUVOverlay, - GS_FreeYUVOverlay -}; - -struct private_yuvhwdata -{ - int ipu_fd; - Uint8 *pixels; - int macroblocks; - int dma_len; - caddr_t dma_mem; - caddr_t ipu_imem; - caddr_t ipu_omem; - caddr_t dma_tags; - unsigned long long *stretch_x1y1; - unsigned long long *stretch_x2y2; - struct ps2_plist plist; - - /* These are just so we don't have to allocate them separately */ - Uint16 pitches[3]; - Uint8 *planes[3]; -}; - -static int -power_of_2(int value) -{ - int shift; - - for (shift = 0; (1 << shift) < value; ++shift) { - /* Keep looking */ ; - } - return (shift); -} - -SDL_Overlay * -GS_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, - SDL_Surface * display) -{ - SDL_Overlay *overlay; - struct private_yuvhwdata *hwdata; - int map_offset; - unsigned long long *tags; - caddr_t base; - int bpp; - int fbp, fbw, psm; - int x, y, w, h; - int pnum; - struct ps2_packet *packet; - struct ps2_packet tex_packet; - - /* We can only decode blocks of 16x16 pixels */ - if ((width & 15) || (height & 15)) { - SDL_SetError("Overlay width/height must be multiples of 16"); - return (NULL); - } - /* Make sure the image isn't too large for a single DMA transfer */ - if (((width / 16) * (height / 16)) > MAX_MACROBLOCKS) { - SDL_SetError("Overlay too large (maximum size: %d pixels)", - MAX_MACROBLOCKS * 16 * 16); - return (NULL); - } - - /* Double-check the requested format. For simplicity, we'll only - support planar YUV formats. - */ - switch (format) { - case SDL_YV12_OVERLAY: - case SDL_IYUV_OVERLAY: - /* Supported planar YUV format */ - break; - default: - SDL_SetError("Unsupported YUV format"); - return (NULL); - } - - /* Create the overlay structure */ - overlay = (SDL_Overlay *) SDL_malloc(sizeof *overlay); - if (overlay == NULL) { - SDL_OutOfMemory(); - return (NULL); - } - SDL_memset(overlay, 0, (sizeof *overlay)); - - /* Fill in the basic members */ - overlay->format = format; - overlay->w = width; - overlay->h = height; - - /* Set up the YUV surface function structure */ - overlay->hwfuncs = &gs_yuvfuncs; - overlay->hw_overlay = 1; - - /* Create the pixel data */ - hwdata = (struct private_yuvhwdata *) SDL_malloc(sizeof *hwdata); - overlay->hwdata = hwdata; - if (hwdata == NULL) { - SDL_FreeYUVOverlay(overlay); - SDL_OutOfMemory(); - return (NULL); - } - hwdata->ipu_fd = -1; - hwdata->pixels = (Uint8 *) SDL_malloc(width * height * 2); - if (hwdata->pixels == NULL) { - SDL_FreeYUVOverlay(overlay); - SDL_OutOfMemory(); - return (NULL); - } - hwdata->macroblocks = (width / 16) * (height / 16); - - /* Find the pitch and offset values for the overlay */ - overlay->pitches = hwdata->pitches; - overlay->pixels = hwdata->planes; - switch (format) { - case SDL_YV12_OVERLAY: - case SDL_IYUV_OVERLAY: - overlay->pitches[0] = overlay->w; - overlay->pitches[1] = overlay->pitches[0] / 2; - overlay->pitches[2] = overlay->pitches[0] / 2; - overlay->pixels[0] = hwdata->pixels; - overlay->pixels[1] = overlay->pixels[0] + - overlay->pitches[0] * overlay->h; - overlay->pixels[2] = overlay->pixels[1] + - overlay->pitches[1] * overlay->h / 2; - overlay->planes = 3; - break; - default: - /* We should never get here (caught above) */ - break; - } - - /* Theoretically we could support several concurrent decode - streams queueing up on the same file descriptor, but for - simplicity we'll support only one. Opening the IPU more - than once will fail with EBUSY. - */ - hwdata->ipu_fd = open("/dev/ps2ipu", O_RDWR); - if (hwdata->ipu_fd < 0) { - SDL_FreeYUVOverlay(overlay); - SDL_SetError("Playstation 2 IPU busy"); - return (NULL); - } - - /* Allocate a DMA area for pixel conversion */ - bpp = this->screen->format->BytesPerPixel; - map_offset = (mapped_len + (sysconf(_SC_PAGESIZE) - 1)) & ~(sysconf(_SC_PAGESIZE) - 1); - hwdata->dma_len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8) + - width * height * bpp + - hwdata->macroblocks * (16 * sizeof(long long)) + - 12 * sizeof(long long); - hwdata->dma_mem = mmap(0, hwdata->dma_len, PROT_READ | PROT_WRITE, - MAP_SHARED, memory_fd, map_offset); - if (hwdata->dma_mem == MAP_FAILED) { - hwdata->ipu_imem = (caddr_t) 0; - SDL_FreeYUVOverlay(overlay); - SDL_SetError("Unable to map %d bytes for DMA", hwdata->dma_len); - return (NULL); - } - hwdata->ipu_imem = hwdata->dma_mem; - hwdata->ipu_omem = hwdata->ipu_imem + - hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8); - hwdata->dma_tags = hwdata->ipu_omem + width * height * bpp; - - /* Allocate memory for the DMA packets */ - hwdata->plist.num = hwdata->macroblocks * 4 + 1; - hwdata->plist.packet = - (struct ps2_packet *) SDL_malloc(hwdata->plist.num * - sizeof(struct ps2_packet)); - if (!hwdata->plist.packet) { - SDL_FreeYUVOverlay(overlay); - SDL_OutOfMemory(); - return (NULL); - } - pnum = 0; - packet = hwdata->plist.packet; - - /* Set up the tags to send the image to the screen */ - tags = (unsigned long long *) hwdata->dma_tags; - base = hwdata->ipu_omem; - fbp = screen_image.fbp; - fbw = screen_image.fbw; - psm = screen_image.psm; - y = screen_image.y + screen_image.h; /* Offscreen video memory */ - for (h = height / 16; h; --h) { - x = 0; /* Visible video memory */ - for (w = width / 16; w; --w) { - /* The head tag */ - packet[pnum].ptr = &tags[0]; - packet[pnum].len = 10 * sizeof(*tags); - ++pnum; - tags[0] = 4 | (1LL << 60); /* GIFtag */ - tags[1] = 0x0e; /* A+D */ - tags[2] = ((unsigned long long) fbp << 32) | - ((unsigned long long) fbw << 48) | - ((unsigned long long) psm << 56); - tags[3] = PS2_GS_BITBLTBUF; - tags[4] = ((unsigned long long) x << 32) | - ((unsigned long long) y << 48); - tags[5] = PS2_GS_TRXPOS; - tags[6] = (unsigned long long) 16 | - ((unsigned long long) 16 << 32); - tags[7] = PS2_GS_TRXREG; - tags[8] = 0; - tags[9] = PS2_GS_TRXDIR; - /* Now the actual image data */ - packet[pnum].ptr = &tags[10]; - packet[pnum].len = 2 * sizeof(*tags); - ++pnum; - tags[10] = ((16 * 16 * bpp) >> 4) | (2LL << 58); - tags[11] = 0; - packet[pnum].ptr = (void *) base; - packet[pnum].len = 16 * 16 * bpp; - ++pnum; - packet[pnum].ptr = &tags[12]; - packet[pnum].len = 2 * sizeof(*tags); - ++pnum; - tags[12] = (0 >> 4) | (1 << 15) | (2LL << 58); - tags[13] = 0; - - tags += 16; - base += 16 * 16 * bpp; - - x += 16; - } - y += 16; - } - - /* Set up the texture memory area for the video */ - tex_packet.ptr = tags; - tex_packet.len = 8 * sizeof(*tags); - tags[0] = 3 | (1LL << 60); /* GIFtag */ - tags[1] = 0x0e; /* A+D */ - tags[2] = ((screen_image.y + screen_image.h) * screen_image.w) / 64 + - ((unsigned long long) fbw << 14) + - ((unsigned long long) psm << 20) + - ((unsigned long long) power_of_2(width) << 26) + - ((unsigned long long) power_of_2(height) << 30) + - ((unsigned long long) 1 << 34) + ((unsigned long long) 1 << 35); - tags[3] = PS2_GS_TEX0_1; - tags[4] = (1 << 5) + (1 << 6); - tags[5] = PS2_GS_TEX1_1; - tags[6] = 0; - tags[7] = PS2_GS_TEXFLUSH; - ioctl(console_fd, PS2IOC_SEND, &tex_packet); - - /* Set up the tags for scaling the image */ - packet[pnum].ptr = tags; - packet[pnum].len = 12 * sizeof(*tags); - ++pnum; - tags[0] = 5 | (1LL << 60); /* GIFtag */ - tags[1] = 0x0e; /* A+D */ - tags[2] = 6 + (1 << 4) + (1 << 8); - tags[3] = PS2_GS_PRIM; - tags[4] = ((unsigned long long) 0 * 16) + - (((unsigned long long) 0 * 16) << 16); - tags[5] = PS2_GS_UV; - tags[6] = 0; /* X1, Y1 */ - tags[7] = PS2_GS_XYZ2; - hwdata->stretch_x1y1 = &tags[6]; - tags[8] = ((unsigned long long) overlay->w * 16) + - (((unsigned long long) overlay->h * 16) << 16); - tags[9] = PS2_GS_UV; - tags[10] = 0; /* X2, Y2 */ - tags[11] = PS2_GS_XYZ2; - hwdata->stretch_x2y2 = &tags[10]; - - /* We're all done.. */ - return (overlay); -} - -int -GS_LockYUVOverlay(_THIS, SDL_Overlay * overlay) -{ - return (0); -} - -void -GS_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay) -{ - return; -} - -int -GS_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src, - SDL_Rect * dst) -{ - struct private_yuvhwdata *hwdata; - __u32 cmd; - struct ps2_packet packet; - int h, w, i; - Uint32 *lum, *Cr, *Cb; - int lum_pitch; - int crb_pitch; - Uint32 *lum_src, *Cr_src, *Cb_src; - Uint32 *srcp, *dstp; - unsigned int x, y; - SDL_Surface *screen; - - /* Find out where the various portions of the image are */ - hwdata = overlay->hwdata; - switch (overlay->format) { - case SDL_YV12_OVERLAY: - lum = (Uint32 *) overlay->pixels[0]; - Cr = (Uint32 *) overlay->pixels[1]; - Cb = (Uint32 *) overlay->pixels[2]; - break; - case SDL_IYUV_OVERLAY: - lum = (Uint32 *) overlay->pixels[0]; - Cr = (Uint32 *) overlay->pixels[2]; - Cb = (Uint32 *) overlay->pixels[1]; - default: - SDL_SetError("Unsupported YUV format in blit (?)"); - return (-1); - } - dstp = (Uint32 *) hwdata->ipu_imem; - lum_pitch = overlay->w / 4; - crb_pitch = (overlay->w / 2) / 4; - - /* Copy blocks of 16x16 pixels to the DMA area */ - for (h = overlay->h / 16; h; --h) { - lum_src = lum; - Cr_src = Cr; - Cb_src = Cb; - for (w = overlay->w / 16; w; --w) { - srcp = lum_src; - for (i = 0; i < 16; ++i) { - dstp[0] = srcp[0]; - dstp[1] = srcp[1]; - dstp[2] = srcp[2]; - dstp[3] = srcp[3]; - srcp += lum_pitch; - dstp += 4; - } - srcp = Cb_src; - for (i = 0; i < 8; ++i) { - dstp[0] = srcp[0]; - dstp[1] = srcp[1]; - srcp += crb_pitch; - dstp += 2; - } - srcp = Cr_src; - for (i = 0; i < 8; ++i) { - dstp[0] = srcp[0]; - dstp[1] = srcp[1]; - srcp += crb_pitch; - dstp += 2; - } - lum_src += 16 / 4; - Cb_src += 8 / 4; - Cr_src += 8 / 4; - } - lum += lum_pitch * 16; - Cr += crb_pitch * 8; - Cb += crb_pitch * 8; - } - - /* Send the macroblock data to the IPU */ -#ifdef DEBUG_YUV - fprintf(stderr, "Sending data to IPU..\n"); -#endif - packet.ptr = hwdata->ipu_imem; - packet.len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8); - ioctl(hwdata->ipu_fd, PS2IOC_SENDA, &packet); - - /* Trigger the DMA to the IPU for conversion */ -#ifdef DEBUG_YUV - fprintf(stderr, "Trigging conversion command\n"); -#endif - cmd = (7 << 28) + hwdata->macroblocks; - if (screen_image.psm == PS2_GS_PSMCT16) { - cmd += (1 << 27) + /* Output RGB 555 */ - (1 << 26); /* Dither output */ - } - ioctl(hwdata->ipu_fd, PS2IOC_SIPUCMD, &cmd); - - /* Retrieve the converted image from the IPU */ -#ifdef DEBUG_YUV - fprintf(stderr, "Retrieving data from IPU..\n"); -#endif - packet.ptr = hwdata->ipu_omem; - packet.len = overlay->w * overlay->h * - this->screen->format->BytesPerPixel; - ioctl(hwdata->ipu_fd, PS2IOC_RECV, &packet); - -#ifdef DEBUG_YUV - fprintf(stderr, "Copying image to screen..\n"); -#endif - /* Wait for previous DMA to complete */ - ioctl(console_fd, PS2IOC_SENDQCT, 1); - - /* Send the current image to the screen and scale it */ - screen = this->screen; - x = (unsigned int) dst->x; - y = (unsigned int) dst->y; - if (screen->offset) { - x += (screen->offset % screen->pitch) / screen->format->BytesPerPixel; - y += (screen->offset / screen->pitch); - } - y += screen_image.y; - *hwdata->stretch_x1y1 = (x * 16) + ((y * 16) << 16); - x += (unsigned int) dst->w; - y += (unsigned int) dst->h; - *hwdata->stretch_x2y2 = (x * 16) + ((y * 16) << 16); - return ioctl(console_fd, PS2IOC_SENDL, &hwdata->plist); -} - -void -GS_FreeYUVOverlay(_THIS, SDL_Overlay * overlay) -{ - struct private_yuvhwdata *hwdata; - - hwdata = overlay->hwdata; - if (hwdata) { - if (hwdata->ipu_fd >= 0) { - close(hwdata->ipu_fd); - } - if (hwdata->dma_mem) { - munmap(hwdata->dma_mem, hwdata->dma_len); - } - if (hwdata->plist.packet) { - SDL_free(hwdata->plist.packet); - } - if (hwdata->pixels) { - SDL_free(hwdata->pixels); - } - SDL_free(hwdata); - } -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/ps2gs/SDL_gsyuv_c.h Mon Jan 18 14:16:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - 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" - -/* This is the Playstation 2 implementation of YUV video overlays */ - -#include "SDL_video.h" -#include "SDL_gsvideo.h" - -extern SDL_Overlay *GS_CreateYUVOverlay(_THIS, int width, int height, - Uint32 format, SDL_Surface * display); - -extern int GS_LockYUVOverlay(_THIS, SDL_Overlay * overlay); - -extern void GS_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay); - -extern int GS_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src, - SDL_Rect * dst); - -extern void GS_FreeYUVOverlay(_THIS, SDL_Overlay * overlay); -/* vi: set ts=4 sw=4 expandtab: */