Nueva versión de Wiilinux (debian-etch-4.0+whiite-0.1)

1, 2, 3, 4, 5
Y no sería posible modificar el arranque para que, en vez de montar una particion Ext2 directamente, monte la Fat32 (en algun sitio que no sea la raiz) y que monte una partición ext2 en loop, es decir, en un archivo dentro de esta?

Para los que no lo sepais, para crear una solo es necesario hacer:
dd if=/dev/zero of=particion bs=1M count=512
para crear un archivo en blanco de 512mb,
mkfs.ext2 particion
para darle fomato ext2, y..

mount -o loop particion /mnt/punto-de-montaje
para montarla.
nuvalo escribió:¿Para qué quieres hacerlo? Si es por ahorrarte una partición ext2, se puede resolver con un ramdisk en el kernel, que se encargue de hacer todo eso. A la larga sí que sería posible hacerlo, pero ahora mismo esto son solo tests, así que si quieres hacerlo por tu cuenta puedes echarle un vistazo al supertux que hay en sourceforge de gc-linux, o al sdlmame.


No se si me has entendido bien.. yo no digo de poner algunas librerias en la fat32, me refiero a meter todo el filesystem dentro del archivo, y que este archivo se monte en la raiz. Es decir:
-> Arranca ramdisk -> monta SD, la particion Fat32 en /sd -> monta el filesystem en ext2, que se encuentra en /sd/linuxfs por ejemplo, en la raiz -> arrancar desde ese filesystem.
Todas las librerias obviamente irian dentro de ese filesystem en loop, esto lo hacen otras distros como Puppy Linux o la XDSL (DSL de Xbox), aunque no se si requiere el uso de unionfs o no. Luego les echaré un vistazo al sdlmame/supertux a ver si es eso a lo que me refería.

Voy a ver si me pillo un teclado USB (o un adaptador PS2->USB), y me pongo a trastear (y tambien intento hacer funcionar mi wifi USB, cosa que creo no será dificil ya que el modulo para las zydas, zd1211rw, viene en el kernel y funciona sin firmware).
nuvalo escribió:
No se si me has entendido bien.. yo no digo de poner algunas librerias en la fat32, me refiero a meter todo el filesystem dentro del archivo, y que este archivo se monte en la raiz


Que te decía que sí, que se hizo con el sdlmame y con el supertux. Antes me fui un poco por las ramas, perdona por extenderme. Simplemente te creas un archivo tocho, lo formateas a ext2 y metes toda la distribución. Después usas un ramdisk para montar ese archivo y hacer un chroot a él. De hecho también puedes usar archivos de tipo squashfs si quieres comprimir un poco, aunque no es muy buena idea.

Y bueno, actualizando esto un poco: Por fin funcionan las X con colores buenos y fluxbox. No se que narices le pasa pero no me deja arrancarlo directamente, así que tengo que hacerlo a mano por consola. Bueno, menos es nada, ya se solucionará. Ahora ya va el wiimote.

Sobre la wireless, espero que tengas más suerte que yo. El driver de la mía (una ralink usb, rt73) lo he conseguido compilar, pero me da un pete al hacer ifconfig up. En la debian me da un error al cargar el firmware, y en la T2SDE me da un error a secas de "fichero no encontrado", aunque no sale el error del kernel.

Un saludo, y si necesitas algo más te hecho una mano

nuvalo, podrias ser tan amable de poner un video mostrando como hiciste para ponerle colores?? O simplemente mostrando que ya tiene colores?? xD, me muero por verloo
nuvalo escribió:
nuvalo, podrias ser tan amable de poner un video mostrando como hiciste para ponerle colores?? O simplemente mostrando que ya tiene colores?? xD, me muero por verloo


A ver si esta tarde tengo un rato y lo subo. Tampoco es que se vea mucho, no tengo ninguna aplicación que resalte instalada, pero puedo mostrar las ventanas y un wallpaper con colores.

MUchas gracias, espero con ansias
Bien bien, las X rulando bajo WiiLinux, enhorabuena nuvalo.

Que el framebuffer trabaje con YUV tiene sus incovenientes (como en el video, cargar las X con el driver fbdev) pero tambien tiene sus ventajas como a la hora de reproducir video XD (practicamente cualquier video que decodifiques obtienes fotogramas en YUV asi que no necesitamos hacer conversion de formato :P).
sorry I don't speak spanish so i used a translator. I have read this topic and saw that you have a gui working with correct colors in wii linux and I was wondering if when you get it working correctly if you could upload the file system for me and other people that would like to use it that don't have the network adapter for thier wii.

lo siento no hablo español así que utilicé un traductor. He leído este tema y vi que usted tiene una gui de trabajo con los colores correctos en wii linux y me pregunto si cuando usted la consigue funciona correctamente si se puede cargar el sistema de archivos para mí y otras personas que quieran utilizarla que don 't tiene el adaptador de red para su wii.
@Link_of_Hyrule: he is still working on it. The proper coloured gui it's being a little tricky at the moment, and stuff doesn't work as he wants yet. Don't worry, if nuvalo gets along with this (he will ;)) you'll probably get his release. Just be patient.
ok sound awesome :) you guy seem to have more working then we do over at wiibrew forums so thats good to hear hopefully he gets it working soon :P
nuvalo escribió: (...)


Eres un fiera tío.
nuvalo escribió:Bueno, por fin he resuelto el tema de las X. Al final conseguí hacer un driver para las X de siempre (xorg) que hiciera el trabajo de pasar la imagen de rgb a yuv2. El resultado es que ya están las X, a una velocidad decente. Lo cierto es que el mplayer no va tan bien como en la distribución del mfe, pero creo que he metido demasiadas cosas, intentaré limpiar lo que no sirva (ya tengo casi 2GB ocupados ) y ya me centraré con el wiimote. Un problema que hay ahora mismo es que la barra de sensores no está activa, pero se puede solucionar fácilmente. En cuanto tenga un rato pongo un video.

. I have read this topic and saw that you have a gui working with correct colors in wii linux and I was wondering if when you get it working correctly if you could upload the file system for me and other people that would like to use it that don't have the network adapter for thier wii.

I wil release everything when i have all my goals working (good colours, network, wiimote). I have done some changes, as the first version with right colours (Xsdl) was very slow. The next step is wiimote and a gui better than fluxbox.

Muchas gracias, espero con ancias ver tus avances xD.. Suena emocionante tener linux en la wii jejeje
Si, si! queremos vidrios y foticas! yo soy tetalmente una ameba en este asunto, pero me encanta ver los avances que haceis los cracks, qué envidia me dais a veces [+risas]
si tiene interfaz grafica!!!!! esto avanza muy bien, nuvalo sigue asi y haz una distro WiiLinux!!
nuvalo eres un crack sigue asi XD
Si es que donde no se pueda meter linux... :D.

PD:Bueno NetBSD funciona hasta en tostadoras asi que ya casi no me sorprende nada XD.
nuvalo escribió:Bueno, por fin pude hacer el video. Aquí se puede ver el boot, xdm, fluxbox y mplayer. Como veis, aun hay algunos fallos con el xserver, sobre todo al mover o repintar el fondo. Ese error no aparece en las ventanas activas, y si se pasa el ratón se actualiza las zonas "olvidadas". Sobre la linea verde que se ve al final... es cosa de mi capturadora de video, en mi televisión de tubo se ve perfectamente. Y aun no está activo el wiimote, estoy usando un ratón usb. En este video también podréis observar el mplayer en ventanas, y mi lucha con la consola porque no veía que comando estaba escribiendo....

http://www.youtube.com/watch?v=2pvHvcq8qJ8

Disfrutadlo, un saludo

Ufff, vamos, me muero de ganas por tenerlo en mi wii !! Animo nuvalo!
Cuanto trabajo #nuvalo, enhorabuena y ánimo. Yo también tengo ganas de tenerlo en la Wii, eso sí, esperamos como agua de mayo un mejor driver usb.

:D
nuvalo, ya sé que es adelantarme a los acontecimientos, pero me intriga saber de qué ventajas se dispondrán cuando los twiizers publiquen el cargador ése que pretenden colocar antes de boot2.

Según contó marcan en la conferencia, con eso se le dará vía libre a wiilinux para que prescinda del ios y dijo que los drivers para los componentes hardware están casi todos, o todos ya disponibles.

El caso es que lo único que se me ocurre es que se dispondrán de 12 megas más que son los que ocupa el ios en ram, pero aparte de eso... pues lo que te digo, que no sé si supondrá alguna ventaja con respecto a trabajar estando ios como capa intermedia ein?
En realidad, creo que no tiene nada que ver una cosa con la otra. Lo que permite la modificación del boot2 es cargar un ios distinto al encender la consola, bien sea uno propio, uno hackeado para que no tenga la restricción de acceso a los 12 MB (han quitado la restricción para poder leer la información de ahí, pero no es muy buena idea modificarlos) o uno que te recupere de un brick. Sin embargo, los drivers que hay actualmente en wii-linux están escritos sobre el ios (hacen llamadas a él), así que habría que reescribirlos.

Lo que sí permite es la carga de un ios que virtualmente haga "lo que nos de la gana". Para eso, habría que escribirlo/modificarlo, pero la gran ventaja es que si se trabaja con él nos pondría a nuestra disposición la lectura de dvd, por ejemplo. Ahora mismo wii-linux no está pensado para sustituir o pasar del ios , más que nada porque sus drivers le necesitan. En un futuro quien sabe, quizás se saque un ios-linux o un SO programado específicamente para sustituir al ios, o... qui lo sa.

Vamos, que el estado actual de wii-linux es dependiente del ios. Si el ios te deja hacer cosas a bajo nivel pues más libertad para linux.
Gracias por la respuesta. Lo preguntaba en relación a lo que se comentó en la conferecia de la euskal que me sonó a que el equipo detrás de wiilinux ya estaba a la espectativa de este siguiente avance.

Vamos, que yo andaba pensando precisamente en linux como sistema que sustituya al ios. Esperaremos pues.

Lo dicho gracias nuvalo también por la aclaración :)
realbrucest escribió:Gracias por la respuesta. Lo preguntaba en relación a lo que se comentó en la conferecia de la euskal que me sonó a que el equipo detrás de wiilinux ya estaba a la espectativa de este siguiente avance.

Vamos, que yo andaba pensando precisamente en linux como sistema que sustituya al ios. Esperaremos pues.

Lo dicho gracias nuvalo también por la aclaración :)


En realidad Linux no va a sustituir al IOS, sería una locura... el Starlet no tiene acceso ni a la pantalla ni al sonido. Lo que los Twiizers están planeando es hacer una especie de IOS proxy, es decir, un IOS que simplemente dirija los datos entre el PPC y las demás cosas. De esta forma se podrán utilizar drivers "normales" en Linux... y ya existen drivers funcionales (en PC) para buena parte del sistema: tanto la wifi como el Bluetooth son Bradcom, el módulo USB parece ser bastante normal y el lector se sabe como funciona... De esta forma, la Wii se convertiría en un Mac G3 [qmparto]

El IOS proxy se ejecutaría como opción en el menú de recuperación... ya me estoy imaginando "GRUB: Wii recovery mode" XD
iacaca escribió:En realidad Linux no va a sustituir al IOS, sería una locura... el Starlet no tiene acceso ni a la pantalla ni al sonido. Lo que los Twiizers están planeando es hacer una especie de IOS proxy, es decir, un IOS que simplemente dirija los datos entre el PPC y las demás cosas. De esta forma se podrán utilizar drivers "normales" en Linux... y ya existen drivers funcionales (en PC) para buena parte del sistema: tanto la wifi como el Bluetooth son Bradcom, el módulo USB parece ser bastante normal y el lector se sabe como funciona... De esta forma, la Wii se convertiría en un Mac G3 [qmparto]

El IOS proxy se ejecutaría como opción en el menú de recuperación... ya me estoy imaginando "GRUB: Wii recovery mode" XD


Diossss [babas] [babas] [babas] [babas] [babas] [babas]
Nuvalo, que tal vas con Linux en Wii?
Buenas,
hace un tiempo que ví este foro y me parecio muy interesante lo de meter el linux en la wii, sobretodo lo de las XWindows.
Finalmente lo he conseguido :), he estado como 1 mes para conseguir que funcionen (no tenía ni idea de las APIs de xorg), tenía un problema con el teclado y con la pantalla debido a que la gamecube no tenía soporte, la verdad es que va bastante suelto.....

Yo lo he conseguido hacer funcionar con:

- debian-etch-4.0+whiite-0.1
- SDL-1.2.8.tar.tar
- libsdl (de gamecube, modificado para que se trague eventos, básicamente modificando el gcevents.c....
- xorg-server-1.5.1 (usando kdrive, cambiando un par de returns a TRUE por FALSE del sdl.c (el kdrive entiende el FALSE como Success) )
- twm
- Dillo (Funcionando, pero no me mola porque no se traga ni hotmail, ni youtube ni nada que use páginas dinámicas..... )

Cuando tenga un momento subiré el libsdl modificado para Wii. Son unas pocas modificaciones.....Por cierto yo utilizo la salida por componentes y tuve que hacer un pequeño truco con fbset para que se viese bien la pantalla. Por otro lado yo por el momento no tengo problemas de refresco.

Un Saludo.
Enhorabuena [beer] . Sobre las SDL, te aconsejo que pruebes las 1.2.12 que sacó isobel con el Kobo Deluxe, ya que solucionaban bastantes problemas con eventos de teclado y ratón usb.
Pues la verdad es que con el SDL tuve algún problema al compilar y tuve que parchear (por ejemplo PAGE_SIZE compile error ) que por lo que veo lo solucionan con la 2.1.12. Para que los eventos del teclado y del raton hay que copiar un par de funciones del fichero ..\video\fbcon\SDL_fbevents.c en gcevents.c....

Ostras yo lo que no se es si se tragará el Opera Desktop para powerpc .... o quizás firefox....

Me planteé hacer un parche con las xorg standards, directamente haciendo una especie de timer en fbdevhw.c. que vaya actualizando periódicamente la pantalla, pero me pareció que ocuparía mucha cpu.....

En cuanto a la compilación del kdrive también es la monda ya que para la versión 1.5.X han cometido el error de que en las funciones del sdl.c:

static Bool sdlKeyboardInit(KdKeyboardInfo *ki)
static Bool sdlMouseInit (KdPointerInfo *pi)

Hay que cambiar el return de TRUE a FALSE(es decir que devuelva un 0 ).
Bueno, voy a detallar paso a paso como conseguir tener nuestro servidor de XWindows
funcionando:

Supongo que tenemos instalado debian con los paquetes automake 1.7, autoconf,etc...
y otros paquetes necesarios, sino ya se nos quejará en el paso 11.

0) Nos situamos en el directorio donde queremos hacer todo el trabajo...
1)Descargamos las SDL desde http://www.libsdl.org/release/SDL-1.2.8.tar.gz
2)tar xzvf SDL-1.2.8.tar.gz
3)Descargamos el parche de gamecube:
# cvs -d:pserver:anonymous@gc-linux.cvs.sourceforge.net:/cvsroot/gc-linux login
# cvs -z3 -d:pserver:anonymous@gc-linux.cvs.sourceforge.net:/cvsroot/gc-linux co -P libsdl
4)Entramos en .....\libsdl\src\video\gc
5)Hay que modificar estos cinco ficheros: sdl_gcevents.c , sdl_gcevents.h ,
sdl_gcvideo.c y sdl_gcvideo.h
6)Como no se subir ficheros los iré pegando uno a uno....
7)machacamos los ficheros originales con los del punto 5.
8)Volvemos al directorio de trabajo
9)cp -r libsdl/* SDL-1.2.8/
10)./autogen.sh
11)./configure \
--without-x \
--disable-video-x11 \
--disable-video-fbcon \
--disable-video-aalib \
--disable-video-opengl
12) make (es decir compilamos la sdl con gc-linux (libsdl))
13) Nos fallará lo del PAGE_SIZE en SDL_fbvideo.c , para ello abrimos el fichero y si quereis
justo después de la linea #include "SDL_fbriva.h" ponemos lo siguiente:

////Inicio/////////////////////////////////////////////////////
/*
* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
* page size. When using 64K pages however, whether we are really supporting
* 64K pages in HW or not is irrelevant to those definitions.
*/
#ifdef __ASSEMBLY__
# define stringify_in_c(...) __VA_ARGS__
# define ASM_CONST(x) x
#else
/* This version of stringify will deal with commas... */
# define __stringify_in_c(...) #__VA_ARGS__
# define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
# define __ASM_CONST(x) x##UL
# define ASM_CONST(x) __ASM_CONST(x)
#endif

#ifdef CONFIG_PPC_64K_PAGES
#define PAGE_SHIFT 16
#else
#define PAGE_SHIFT 12
#endif

#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)


////Final/////////////////////////////////////////////////////

14)Si finalmente ya hemos conseguido compilar, y no nos hemos cansado de descargar
paquetitos .deb podemos seguir.... creo que para el SDL no eran demasiados, no obstante
si os aburris probad a compilar el mesa3D y ya vereis.... casi me vuelvo loco...por suerte
no se necesita para nuestras XWindows....

15)make install (y se copiarán los ficheros en /usr/local.....)

16) Ahora vamos a por la segunda parte. Compilar el kdrive. Para esto nos vamos a descargar
todo el paquete de las XWindows de xorg.
17) http://xorg.freedesktop.org/releases/in ... 5.1.tar.gz

18)Lo descomprimimos en la carpeta de trabajo.. (tar xzvf xorg-server-1.5.1.tar.gz)

19)./autogen.sh --enable-composite --enable-kdrive --enable-xephyr --enable-xsdl --enable-xfbdev
--disable-kdrive-vesa --disable-xorg --disable-xprint

-->Creo que el xephyr se podria poner en disable.....pero por si acaso...

20) make (ojo si hacemos ./configure poned todos los parámetros anteriores)

21) En este punto fallará en algún punto, con un problema raro tipo:

VENDOR_RELEASE="(((1) * 10000000) + (() *100000) + (() * 1000) + 0)"

para arreglarlo hay que ir a la carpeta donde este el fichero abrir el Makefile y hacer que en
vez de () haya un 0, es decir:

VENDOR_RELEASE="(((1) * 10000000) + ((0) *100000) + ((0) * 1000) + 0)"

Creo que era en la linea donde se configuran los ACFLAGS....o algo así.

(Es posible que si os descargais la nueva versión 1.5.2 esto no pase, qui lo sa...)


22)Si quereis volved a intentar compilar a ver si todo va bien....ojo nuestro objetivo es que
en la carpeta ....\xorg-server-1.5.1\hw\kdrive\sdl se haya generado la aplicación Xsdl, que
mas da si hay carpetas que fallen, a mi me fallaba la vesa...porque no puse la opción
--disable-kdrive-vesa.


24) Bien, si finalmente ya hemos conseguido obtener la aplicación Xsdl podemos probar a lanzarla
y vereis como se levantan las XWindows pero sin el ratón y sin el teclado, ojo a mi me peto
la primera vez que lo lancé porque buscaba en la libSDL.so -> libSDL-1.2.so.0.7.1 y tuve
que hacer un link.(ln -s pp pp2 ...). Para probar:

whiite:/usr/local/bin# (Xsdl -screen 640x480x16 & (sleep 3 && xterm))

Nota:En este punto a lo mejor nuestro xserver se queja de que nos faltan las fuentes dpi...
yo las descargué de: http://xorg.freedesktop.org/releases/individual/font/

25)Ahora finalmente ya debería funcionar.... eso si sin teclado y sin mouse...para ello tendremos

que cambiar, los dos returns que comentaba :

/////////Inicio

static Bool sdlKeyboardInit(KdKeyboardInfo *ki)
{
ki->minScanCode = 8;
ki->maxScanCode = 255;
ki->keySyms.minKeyCode = 8;
ki->keySyms.maxKeyCode = 255;
ki->keySyms.mapWidth = 2;
memcpy(ki->keySyms.map, sdlKeymap, sizeof(sdlKeymap));

sdlKeyboard = ki;

return 0; ///Antes TRUE
}

static Bool sdlMouseInit (KdPointerInfo *pi)
{
sdlPointer = pi;
return 0; ///Antes TRUE;
}

//////////Final


26) Con este último cambio ya tendremos el teclado y el mouse funcionando, eso si el mapeo
del teclado fatal, para arreglarlo yo tuve que poner el minScanCode=0; ...... y todavía
hay alguna tecla suelta que no acaba de ir, pero por suerte no es problematica..... :)


27) Espero no haberme dejado nada :) , sino alguno que lo pruebe ya me dirá y lo completamos
un poco más. Perdonad si me he extendido mucho.



//////////////////////////////Edito////////////////////////////////////////////


//////////Inicio SDL_gcevents.c///////////////
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga

SDL port for the Nintendo GameCube
Copyright (C) 2004-2005 Albert Herranz

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

based on SDL_fbevents.c by

Sam Lantinga
slouken@libsdl.org
*/

#define DEBUG_KEYBOARD 1

/* Handle the event stream, converting console events into SDL events */

#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.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.h"
#include "SDL_mutex.h"
#include "SDL_sysevents.h"
#include "SDL_sysvideo.h"
#include "SDL_events_c.h"
#include "SDL_gcvideo.h"
#include "SDL_gcevents_c.h"

//emul fbbelo.c
#include <string.h>
/*
calibration default values
values are read from the following environment variables:

SDL_ELO_MIN_X
SDL_ELO_MAX_X
SDL_ELO_MIN_Y
SDL_ELO_MAX_Y
*/

static int ELO_MIN_X = 400;
static int ELO_MAX_X = 3670;
static int ELO_MIN_Y = 500;
static int ELO_MAX_Y = 3540;

#define ELO_SNAP_SIZE 6
#define ELO_TOUCH_BYTE 'T'
#define ELO_ID 'I'
#define ELO_MODE 'M'
#define ELO_PARAMETER 'P'
#define ELO_REPORT 'B'
#define ELO_ACK 'A'

#define ELO_INIT_CHECKSUM 0xAA

#define ELO_BTN_PRESS 0x01
#define ELO_STREAM 0x02
#define ELO_BTN_RELEASE 0x04

#define ELO_TOUCH_MODE 0x01
#define ELO_STREAM_MODE 0x02
#define ELO_UNTOUCH_MODE 0x04
#define ELO_RANGE_CHECK_MODE 0x40
#define ELO_TRIM_MODE 0x02
#define ELO_CALIB_MODE 0x04
#define ELO_SCALING_MODE 0x08
#define ELO_TRACKING_MODE 0x40

#define ELO_SERIAL_MASK 0xF8

#define ELO_SERIAL_IO '0'

#define ELO_MAX_TRIALS 3
#define ELO_MAX_WAIT 100000
#define ELO_UNTOUCH_DELAY 5
#define ELO_REPORT_DELAY 1

/* eloParsePacket
*/
int eloParsePacket(unsigned char* mousebuf, int* dx, int* dy, int* button_state) {
static int elo_button = 0;
static int last_x = 0;
static int last_y = 0;
int x,y;

/* Check if we have a touch packet */
if (mousebuf[1] != ELO_TOUCH_BYTE) {
return 0;
}

x = ((mousebuf[4] << 8) | mousebuf[3]);
y = ((mousebuf[6] << 8) | mousebuf[5]);

if((abs(x - last_x) > ELO_SNAP_SIZE) || (abs(y - last_y) > ELO_SNAP_SIZE)) {
*dx = ((mousebuf[4] << 8) | mousebuf[3]);
*dy = ((mousebuf[6] << 8) | mousebuf[5]);
}
else {
*dx = last_x;
*dy = last_y;
}

last_x = *dx;
last_y = *dy;

if ( (mousebuf[2] & 0x07) == ELO_BTN_PRESS ) {
elo_button = 1;
}
if ( (mousebuf[2] & 0x07) == ELO_BTN_RELEASE ) {
elo_button = 0;
}

*button_state = elo_button;
return 1;
}

/* Convert the raw coordinates from the ELO controller
to a screen position.
*/
void eloConvertXY(_THIS, int *dx, int *dy) {
int input_x = *dx;
int input_y = *dy;
int width = ELO_MAX_X - ELO_MIN_X;
int height = ELO_MAX_Y - ELO_MIN_Y;

*dx = (cache_vinfo.xres - (cache_vinfo.xres * (input_x - ELO_MIN_X)) / width);
*dy = (cache_vinfo.yres * (input_y - ELO_MIN_Y)) / height;
}


/* eloGetPacket
*/
int eloGetPacket(unsigned char* buffer, int* buffer_p, int* checksum, int fd) {
int num_bytes;
int ok;

if(fd == 0) {
num_bytes = ELO_PACKET_SIZE;
}
else {
num_bytes = read(fd,
(char *) (buffer + *buffer_p),
ELO_PACKET_SIZE - *buffer_p);
}

if (num_bytes < 0) {
#ifdef DEBUG_MOUSE
fprintf(stderr, "System error while reading from Elographics touchscreen.\n");
#endif
return 0;
}

while (num_bytes) {
if ((*buffer_p == 0) && (buffer[0] != ELO_START_BYTE)) {
memcpy(&buffer[0], &buffer[1], num_bytes-1);
}
else {
if (*buffer_p < ELO_PACKET_SIZE-1) {
*checksum = *checksum + buffer[*buffer_p];
*checksum = *checksum % 256;
}
(*buffer_p)++;
}
num_bytes--;
}

if (*buffer_p == ELO_PACKET_SIZE) {
ok = (*checksum == buffer[ELO_PACKET_SIZE-1]);
*checksum = ELO_INIT_CHECKSUM;
*buffer_p = 0;

if (!ok) {
return 0;
}

return 1;
}
else {
return 0;
}
}

/* eloSendPacket
*/

int eloSendPacket(unsigned char* packet, int fd)
{
int i, result;
int sum = ELO_INIT_CHECKSUM;

packet[0] = ELO_START_BYTE;
for (i = 0; i < ELO_PACKET_SIZE-1; i++) {
sum += packet[i];
sum &= 0xFF;
}
packet[ELO_PACKET_SIZE-1] = sum;

result = write(fd, packet, ELO_PACKET_SIZE);

if (result != ELO_PACKET_SIZE) {
#ifdef DEBUG_MOUSE
printf("System error while sending to Elographics touchscreen.\n");
#endif
return 0;
}
else {
return 1;
}
}


/* eloWaitForInput
*/
int eloWaitForInput(int fd, int timeout)
{
fd_set readfds;
struct timeval to;
int r;

FD_ZERO(&readfds);
FD_SET(fd, &readfds);
to.tv_sec = 0;
to.tv_usec = timeout;

r = select(FD_SETSIZE, &readfds, NULL, NULL, &to);
return r;
}

/* eloWaitReply
*/
int eloWaitReply(unsigned char type, unsigned char *reply, int fd) {
int ok;
int i, result;
int reply_p = 0;
int sum = ELO_INIT_CHECKSUM;

i = ELO_MAX_TRIALS;
do {
ok = 0;

result = eloWaitForInput(fd, ELO_MAX_WAIT);

if (result > 0) {
ok = eloGetPacket(reply, &reply_p, &sum, fd);

if (ok && reply[1] != type && type != ELO_PARAMETER) {
#ifdef DEBUG_MOUSE
fprintf(stderr, "Wrong reply received\n");
#endif
ok = 0;
}
}
else {
#ifdef DEBUG_MOUSE
fprintf(stderr, "No input!\n");
#endif
}

if (result == 0) {
i--;
}
} while(!ok && (i>0));

return ok;
}


/* eloWaitAck
*/

int eloWaitAck(int fd) {
unsigned char packet[ELO_PACKET_SIZE];
int i, nb_errors;

if (eloWaitReply(ELO_ACK, packet, fd)) {
for (i = 0, nb_errors = 0; i < 4; i++) {
if (packet[2 + i] != '0') {
nb_errors++;
}
}

if (nb_errors != 0) {
#ifdef DEBUG_MOUSE
fprintf(stderr, "Elographics acknowledge packet reports %d errors\n", nb_errors);
#endif
}
return 1;
}
else {
return 0;
}
}


/* eloSendQuery --
*/
int eloSendQuery(unsigned char *request, unsigned char* reply, int fd) {
int ok;

if (eloSendPacket(request, fd)) {
ok = eloWaitReply(toupper(request[1]), reply, fd);
if (ok) {
ok = eloWaitAck(fd);
}
return ok;
}
else {
return 0;
}
}


/* eloSendControl
*/
int eloSendControl(unsigned char* control, int fd) {
if (eloSendPacket(control, fd)) {
return eloWaitAck(fd);
}
else {
return 0;
}
}

/* eloInitController
*/
int eloInitController(int fd) {
unsigned char req[ELO_PACKET_SIZE];
unsigned char reply[ELO_PACKET_SIZE];
const char *buffer = NULL;
int result = 0;

struct termios mouse_termios;

/* try to read the calibration values */
buffer = getenv("SDL_ELO_MIN_X");
if(buffer) {
ELO_MIN_X = atoi(buffer);
}
buffer = getenv("SDL_ELO_MAX_X");
if(buffer) {
ELO_MAX_X = atoi(buffer);
}
buffer = getenv("SDL_ELO_MIN_Y");
if(buffer) {
ELO_MIN_Y = atoi(buffer);
}
buffer = getenv("SDL_ELO_MAX_Y");
if(buffer) {
ELO_MAX_Y = atoi(buffer);
}

#ifdef DEBUG_MOUSE
fprintf( stderr, "ELO calibration values:\nmin_x: %i\nmax_x: %i\nmin_y: %i\nmax_y: %i\n",
ELO_MIN_X,
ELO_MAX_X,
ELO_MIN_Y,
ELO_MAX_Y);
#endif

/* set comm params */
memset(&mouse_termios, 0, sizeof(mouse_termios));
mouse_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
mouse_termios.c_cc[VMIN] = 1;
result = tcsetattr(fd, TCSANOW, &mouse_termios);

if (result < 0) {
#ifdef DEBUG_MOUSE
fprintf( stderr, "Unable to configure Elographics touchscreen port\n");
#endif
return 0;
}

memset(req, 0, ELO_PACKET_SIZE);
req[1] = tolower(ELO_PARAMETER);
if (!eloSendQuery(req, reply, fd)) {
#ifdef DEBUG_MOUSE
fprintf( stderr, "Not at the specified rate or model 2310, will continue\n");
#endif
}

memset(req, 0, ELO_PACKET_SIZE);
req[1] = tolower(ELO_ID);
if (eloSendQuery(req, reply, fd)) {
#ifdef DEBUG_MOUSE
fprintf(stderr, "Ok, controller configured!\n");
#endif
}
else {
#ifdef DEBUG_MOUSE
fprintf( stderr, "Unable to ask Elographics touchscreen identification\n");
#endif
return 0;
}

memset(req, 0, ELO_PACKET_SIZE);
req[1] = ELO_MODE;
req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE;
req[4] = ELO_TRACKING_MODE;
if (!eloSendControl(req, fd)) {
#ifdef DEBUG_MOUSE
fprintf( stderr, "Unable to change Elographics touchscreen operating mode\n");
#endif
return 0;
}

memset(req, 0, ELO_PACKET_SIZE);
req[1] = ELO_REPORT;
req[2] = ELO_UNTOUCH_DELAY;
req[3] = ELO_REPORT_DELAY;
if (!eloSendControl(req, fd)) {
#ifdef DEBUG_MOUSE
fprintf( stderr, "Unable to change Elographics touchscreen reports timings\n");
#endif
return 0;
}

return 1;
}

int eloReadPosition(_THIS, int fd, int* x, int* y, int* button_state, int* realx, int* realy) {
unsigned char buffer[ELO_PACKET_SIZE];
int pointer = 0;
int checksum = ELO_INIT_CHECKSUM;

while(pointer < ELO_PACKET_SIZE) {
if(eloGetPacket(buffer, &pointer, &checksum, fd)) {
break;
}
}

if(!eloParsePacket(buffer, realx, realy, button_state)) {
return 0;
}

*x = *realx;
*y = *realy;
eloConvertXY(_this, x, y);
// eloConvertXY(_THIS, x, y);
return 1;
}


//fin emul fbelo

#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 FB_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 ) {
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 GC_InGraphicsMode(_THIS)
{
return in_graphics_mode;
}

int p=2;//1
/**
*
*/
int GC_EnterGraphicsMode(_THIS)
{
char *already_in_graphics_mode;

struct termios keyboard_termios;

/* do nothing if we are told so */
already_in_graphics_mode = getenv("SDL_HACK_GCAIGM");
if (already_in_graphics_mode) {
in_graphics_mode = 1;
return keyboard_fd;
}

if (!GC_InGraphicsMode(_this)) {
/* Switch to the correct virtual terminal */
fprintf(stderr,"current_vt=%d\n",current_vt);
if (current_vt > 0) {
struct vt_stat vtstate;
fprintf(stderr,"v_active1=%d\n",vtstate.v_active);
if (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) {
saved_vt = vtstate.v_active;
fprintf(stderr,"saved_vt=%d\n",saved_vt);
}
if (ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0) {
fprintf(stderr,"current_vt:%d: a 1\n",current_vt);
// current_vt=1;
ioctl(keyboard_fd, VT_WAITACTIVE, current_vt);
}
}

//JJB fbcon inicio
if (p==2) {
/* 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) {
GC_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 ) {
GC_CloseKeyboard(_this);
SDL_SetError("Unable to set keyboard in raw mode");
return(-1);
}
}
//JJB fbcon final


/* switch to graphics mode */
if (keyboard_fd > 0) {
int res1=ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS);
if (res1<0) {
if(p==2) {
fprintf(stderr,"Ojo OpenKeyboard Failed\n");
GC_CloseKeyboard(_this);///JJB fbcon
SDL_SetError("Unable to set keyboard in graphics mode");
return(-1);
}
}
}
in_graphics_mode = 1;
}
return (keyboard_fd);
}

/**
*
*/
void GC_LeaveGraphicsMode(_THIS)
{
char *already_in_graphics_mode;

/* do nothing if we are told so */
already_in_graphics_mode = getenv("SDL_HACK_GCAIGM");
if (already_in_graphics_mode) {
in_graphics_mode = 0;
return;
}

if (GC_InGraphicsMode(_this)) {
/* switch to text mode */
if (keyboard_fd > 0) {
ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
///JJB fbconini
if (p==2) {
ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode);
tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios);
saved_kbd_mode = -1;
}
///JJB fbconfin
}

/* Head back over to the original virtual terminal */
if (saved_vt > 0) {
ioctl(keyboard_fd, VT_ACTIVATE, saved_vt);
}

in_graphics_mode = 0;
}
}

/**
*
*/
void GC_CloseKeyboard(_THIS)
{
if (keyboard_fd >= 0) {
GC_LeaveGraphicsMode(_this);
if (keyboard_fd > 0) {
close(keyboard_fd);
}
}
keyboard_fd = -1;
}

/**
*
*/
int GC_OpenKeyboard(_THIS)
{
/* Open only if not already opened */
fprintf(stderr, "GC_OpenKeyboard\n");

if (keyboard_fd < 0) {
static const char *const tty0[] =
{ "/dev/tty0", "/dev/vc/0", NULL };
static const char *const 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, &current_vt);
close(tty0_fd);
if ((geteuid() == 0) && (current_vt > 0)) {
for (i = 0; vcs[i] && (keyboard_fd < 0); ++i) {
char vtpath[12];

sprintf(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
if (p==2) {
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 -con esto almenos podemos hacer ctrl-alt f1 y salir*/
FB_vgainitkeymaps(keyboard_fd);
}
}
return (keyboard_fd);
}

static enum {
MOUSE_NONE = -1,
MOUSE_MSC, /* Note: GPM uses the MSC protocol */
MOUSE_PS2,
MOUSE_IMPS2,
MOUSE_MS,
MOUSE_BM,
MOUSE_ELO,
NUM_MOUSE_DRVS
} mouse_drv = MOUSE_NONE;

///JJB fbcon inicio
///Aqui tenemos todos los tipos de ratones y varias utilities

void FB_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];

sprintf(path, "/proc/%s/status", entry->d_name);
status=fopen(path, "r");
if ( status ) {
name[0] = '\0';
fscanf(status, "Name: %s", name);
if ( 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 ) {
sprintf(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 ( strcmp(arg, "-R") == 0 ) {
available = 1;
}
arglen = 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 ( 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) || (ch == 4) ) {
imps2 = 1;
}
}
}
return imps2;
}

int FB_OpenMouse(_THIS)
{
int i;
const char *mousedev;
const char *mousedrv;

mousedrv = getenv("SDL_MOUSEDRV");
mousedev = getenv("SDL_MOUSEDEV");
mouse_fd = -1;

/* ELO TOUCHSCREEN SUPPORT */

if( (mousedrv != NULL) && (strcmp(mousedrv, "ELO") == 0) ) {
mouse_fd = open(mousedev, O_RDWR);
if ( mouse_fd >= 0 ) {
if(eloInitController(mouse_fd)) {
#ifdef DEBUG_MOUSE
fprintf(stderr, "Using ELO touchscreen\n");
#endif
mouse_drv = MOUSE_ELO;
}

}
else if ( mouse_fd < 0 ) {
mouse_drv = MOUSE_NONE;
}

return(mouse_fd);
}

/* STD MICE */

if ( mousedev == NULL ) {
/* FIXME someday... allow multiple mice in this driver */
static const char * const 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_MSC;
}
}
}
/* 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 {
#ifdef DEBUG_MOUSE
fprintf(stderr, "Using PS2 mouse\n");
#endif
mouse_drv = MOUSE_PS2;
}
}
}
/* 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 FB_vgamousecallback(int button, int relative, 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, relative, 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 MSC, 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];
static int relative = 1;

int i, nread;
int button = 0;
int dx = 0, dy = 0;
int packetsize = 0;
int realx, realy;

/* Figure out the mouse packet size */
switch (mouse_drv) {
case MOUSE_NONE:
/* Ack! */
read(mouse_fd, mousebuf, BUFSIZ);
return;
case MOUSE_MSC:
packetsize = 5;
break;
case MOUSE_IMPS2:
packetsize = 4;
break;
case MOUSE_PS2:
case MOUSE_MS:
case MOUSE_BM:
packetsize = 3;
break;
case MOUSE_ELO:
packetsize = ELO_PACKET_SIZE;
relative = 0;
break;
case NUM_MOUSE_DRVS:
/* Uh oh.. */
packetsize = 0;
break;
}

/* Special handling for the quite sensitive ELO controller */
if (mouse_drv == MOUSE_ELO) {

/* try to read the next packet */
if(eloReadPosition(_this, mouse_fd, &dx, &dy, &button, &realx, &realy)) {
button = (button & 0x01) << 2;
FB_vgamousecallback(button, relative, dx, dy);
}

return;
}

/* 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_MSC:
/* MSC 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 MOUSE_ELO:
if ( mousebuf[i] != ELO_START_BYTE ) {
i -= (packetsize-1);
continue;
}

if(!eloParsePacket(&(mousebuf[i]), &dx, &dy, &button)) {
i -= (packetsize-1);
continue;
}

button = (button & 0x01) << 2;

eloConvertXY(_this, &dx, &dy);
break;
*/

case MOUSE_ELO:
case NUM_MOUSE_DRVS:
/* Uh oh.. */
dx = 0;
dy = 0;
break;
}
FB_vgamousecallback(button, relative, dx, dy);
}
if ( i < nread ) {
memcpy(mousebuf, &mousebuf[i], (nread-i));
start = (nread-i);
} else {
start = 0;
}
return;
}

/* Handle switching to another VC, returns when our VC is back.
This isn't necessarily the best solution. For SDL 1.3 we need
a way of notifying the application when we lose access to the
video hardware and when we regain it.
*/
static void switch_vt(_THIS, unsigned short which)
{
struct vt_stat vtstate;
unsigned short current;
SDL_Surface *screen;
__u16 saved_pal[3*256];
Uint32 screen_arealen;
Uint8 *screen_contents;

/* Figure out whether or not we're switching to a new console */
if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) ||
(which == vtstate.v_active) ) {
return;
}
current = vtstate.v_active;

/* Save the contents of the screen, and go to text mode */
SDL_mutexP(hw_lock);
wait_idle(_this);
screen = SDL_VideoSurface;
screen_arealen = (screen->h*screen->pitch);
screen_contents = (Uint8 *)malloc(screen_arealen);
if ( screen_contents ) {
memcpy(screen_contents, screen->pixels, screen_arealen);
}
///FB_SavePaletteTo(_this, 256, saved_pal);
ioctl(keyboard_fd, KDSETMODE, KD_TEXT);

/* New console, switch to it */
if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) {
/* Wait for our console to be activated again */
ioctl(keyboard_fd, VT_WAITACTIVE, which);
while ( ioctl(keyboard_fd, VT_WAITACTIVE, current) < 0 ) {
if ( (errno != EINTR) && (errno != EAGAIN) ) {
/* Unknown VT error - cancel this */
break;
}
SDL_Delay(500);
}
}

/* Restore graphics mode and the contents of the screen */
ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS);
///FB_RestorePaletteFrom(_this, 256, saved_pal);
if ( screen_contents ) {
memcpy(screen->pixels, screen_contents, screen_arealen);
free(screen_contents);
}
SDL_mutexV(hw_lock);
}

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);
/* Handle Alt-FN for vt switch */
switch (keysym.sym) {
case SDLK_F1:
case SDLK_F2:
case SDLK_F3:
case SDLK_F4:
case SDLK_F5:
case SDLK_F6:
case SDLK_F7:
case SDLK_F8:
case SDLK_F9:
case SDLK_F10:
case SDLK_F11:
case SDLK_F12:
if ( SDL_GetModState() & KMOD_ALT ) {
if ( pressed ) {
switch_vt(_this, (keysym.sym-SDLK_F1)+1);
}
break;
}
/* Fall through to normal processing */
default:
posted += SDL_PrivateKeyboard(pressed, &keysym);
break;
}
}
}


///JJB fbcon fin

/**
*
*/
void GC_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 GC_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_TABLESIZE(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_TABLESIZE(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);
}

///////Final SDL_gcevents.c///////////////////

//////////Inicio SDL_gcevents_c.h///////////////
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga

SDL port for the Nintendo GameCube
Copyright (C) 2004-2005 Albert Herranz

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Sam Lantinga
slouken@libsdl.org
*/

#include "SDL_gcvideo.h"

//Inicio emulacion include SDL_fbkeys.h
/* 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

//Final SDL_fbkeys.h

//Inicio SDL_fbelo.h
#include <stdlib.h>

//#ifndef SDL_gcevents_c
//#define SDL_gcevents_c

/* ELO */
#define ELO_PACKET_SIZE 10
#define ELO_START_BYTE 'U'

/* eloConvertXY
Convert the raw coordinates from the ELO controller
to a screen position.
*/
void eloConvertXY(_THIS, int *dx, int *dy);

/* eloInitController(int fd)
Initialize the ELO serial touchscreen controller
*/
int eloInitController(int fd);

/* eloParsePacket
extract position and button state from a packet
*/
int eloParsePacket(unsigned char* mousebuf, int* dx, int* dy, int* button_state);

/* eloReadPosition
read a packet and get the cursor position
*/

int eloReadPosition(_THIS, int fd, int* x, int* y, int* button_state, int* realx, int* realy);
//#endif


//Final SDL_fbelo.h



/* Variables and functions exported by SDL_sysevents.c to other parts
of the native video subsystem (SDL_sysvideo.c)
*/
extern int GC_OpenKeyboard(_THIS);
extern void GC_CloseKeyboard(_THIS);

///JJB fbcon ini
extern int FB_OpenMouse(_THIS);
extern void FB_CloseMouse(_THIS);
///JJB fbcon fin

extern int GC_EnterGraphicsMode(_THIS);
extern int GC_InGraphicsMode(_THIS);
extern void GC_LeaveGraphicsMode(_THIS);

extern void GC_PumpEvents(_THIS);
extern void GC_InitOSKeymap(_THIS);

///////Final SDL_gcevents_c.h///////////////////

//////////Inicio SDL_gcvideo.c///////////////
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga

SDL port for the Nintendo GameCube
Copyright (C) 2004-2006 Albert Herranz

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

based on SDL_nullvideo.c by

Sam Lantinga
slouken@libsdl.org
*/

#define GC_DEBUG 1
//#undef GC_DEBUG

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/page.h> /* For definition of PAGE_SIZE */

#include "SDL.h"
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_sysvideo.h"
#include "SDL_pixels_c.h"
#include "SDL_events_c.h"

#include "SDL_gcvideo.h"
#include "SDL_gcyuv_c.h"
#include "SDL_gcevents_c.h"

#ifdef HAVE_OPENGL
#include "SDL_gcgl.h"
#endif /* HAVE_OPENGL */

/* Initialization/Query functions */


/*
* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
* page size. When using 64K pages however, whether we are really supporting
* 64K pages in HW or not is irrelevant to those definitions.
*/#ifdef __ASSEMBLY__
# define stringify_in_c(...) __VA_ARGS__
# define ASM_CONST(x) x
#else
/* This version of stringify will deal with commas... */
# define __stringify_in_c(...) #__VA_ARGS__
# define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
# define __ASM_CONST(x) x##UL
# define ASM_CONST(x) __ASM_CONST(x)
#endif

#ifdef CONFIG_PPC_64K_PAGES
#define PAGE_SHIFT 16
#else
#define PAGE_SHIFT 12
#endif

#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)




static int GC_VideoInit(_THIS, SDL_PixelFormat * vformat);
static SDL_Rect **GC_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags);
static SDL_Surface *GC_SetVideoMode(_THIS, SDL_Surface * current, int width,
int height, int bpp, Uint32 flags);
static int GC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors);
static void GC_VideoQuit(_THIS);

/* Hardware surface functions */
static int GC_AllocHWSurface(_THIS, SDL_Surface * surface);
static int GC_LockHWSurface(_THIS, SDL_Surface * surface);
static void GC_UnlockHWSurface(_THIS, SDL_Surface * surface);
static void GC_FreeHWSurface(_THIS, SDL_Surface * surface);
static int GC_FlipHWSurface(_THIS, SDL_Surface * surface);
static void FB_WaitIdle(_THIS);

/* etc. */
static void GC_InitRGB2YUVTables(void);
static void GC_UpdateRects(_THIS, int numrects, SDL_Rect * rects);
static void GC_UpdateRectRGB16(_THIS, SDL_Rect * rect, int pitch);
void GC_WaitForFlipCompletion(_THIS);

#define GC_BLACK 0x00800080


/*
*
* Bootstrap functions.
*/

/*
*
*/
static int GC_Available(void)
{
int console;
const char *SDL_fbdev;

/*
* XXX We could check that
* "/sys/devices/platform/gcnfb.0/graphics\:fb0/name"
* exists and contains gcnfb.
*/

SDL_fbdev = getenv("SDL_FBDEV");
if (SDL_fbdev == NULL) {
SDL_fbdev = "/dev/fb0";
}
console = open(SDL_fbdev, O_RDWR, 0);
if (console >= 0) {
close(console);
}
return (console >= 0);
}

/*
*
*/
static void GC_DeleteDevice(_THIS)
{
if (_this->hidden->buffer) {
free(_this->hidden->buffer);
_this->hidden->buffer = NULL;
}
free(_this->hidden);
#ifdef HAVE_OPENGL
if (_this->gl_data)
free(_this->gl_data);
#endif /* HAVE_OPENGL */
free(_this);
}

/*
*
*/
static SDL_VideoDevice *GC_CreateDevice(int devindex)
{
_THIS;

/* Initialize all variables that we clean on shutdown */
_this = (SDL_VideoDevice *) malloc(sizeof(SDL_VideoDevice));
if (_this) {
memset(_this, 0, (sizeof *_this));

#ifdef HAVE_OPENGL
_this->gl_data = (struct SDL_PrivateGLData *)
malloc((sizeof *_this->gl_data));
if (_this->gl_data == NULL) {
SDL_OutOfMemory();
free(_this);
return 0;
}
memset(_this->gl_data, 0, (sizeof *_this->gl_data));
#endif /* HAVE_OPENGL */

_this->hidden = (struct SDL_PrivateVideoData *)
malloc((sizeof *_this->hidden));
if (_this->hidden == NULL) {
SDL_OutOfMemory();
#ifdef HAVE_OPENGL
free(_this->gl_data);
#endif /* HAVE_OPENGL */
free(_this);
return (0);
}
}
memset(_this->hidden, 0, (sizeof *_this->hidden));

keyboard_fd = -1;
in_graphics_mode = 0;

/* Set the function pointers */
_this->VideoInit = GC_VideoInit;
_this->ListModes = GC_ListModes;
_this->SetVideoMode = GC_SetVideoMode;
_this->CreateYUVOverlay = GC_CreateYUVOverlay;
_this->SetColors = GC_SetColors;
_this->UpdateRects = GC_UpdateRects;
_this->VideoQuit = GC_VideoQuit;
_this->AllocHWSurface = GC_AllocHWSurface;
_this->CheckHWBlit = NULL;
_this->FillHWRect = NULL;
_this->SetHWColorKey = NULL;
_this->SetHWAlpha = NULL;
_this->LockHWSurface = GC_LockHWSurface;
_this->UnlockHWSurface = GC_UnlockHWSurface;
_this->FlipHWSurface = GC_FlipHWSurface;
_this->FreeHWSurface = GC_FreeHWSurface;
#ifdef HAVE_OPENGL
_this->GL_LoadLibrary = GC_GL_LoadLibrary;
_this->GL_GetProcAddress = GC_GL_GetProcAddress;
_this->GL_GetAttribute = GC_GL_GetAttribute;
_this->GL_MakeCurrent = GC_GL_MakeCurrent;
_this->GL_SwapBuffers = GC_GL_SwapBuffers;
#endif /* HAVE_OPENGL */
_this->SetCaption = NULL;
_this->SetIcon = NULL;
_this->IconifyWindow = NULL;
_this->GrabInput = NULL;
_this->GetWMInfo = NULL;
_this->InitOSKeymap = GC_InitOSKeymap;
_this->PumpEvents = GC_PumpEvents;

_this->free = GC_DeleteDevice;

return _this;
}

VideoBootStrap GC_bootstrap = {
"gcvideo", "GameCube Linux Video",
GC_Available, GC_CreateDevice
};


/*
*
* Video setup routines.
*/

/*
*
*/
int GC_VideoInit(_THIS, SDL_PixelFormat * vformat)
{
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
const char *fbdev;
int offset;

GC_InitRGB2YUVTables();

/* Initialize the library */
fbdev = getenv("SDL_FBDEV");
if (fbdev == NULL) {
fbdev = "/dev/fb0";
}
console_fd = open(fbdev, O_RDWR, 0);
if (console_fd < 0) {
SDL_SetError("Unable to open %s", fbdev);
return (-1);
}

/* Get the type of video hardware */
if (ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
SDL_SetError("Couldn't get console hardware info");
GC_VideoQuit(_this);
return (-1);
}
switch (finfo.type) {
case FB_TYPE_PACKED_PIXELS:
/* Supported, no worries.. */
break;
default:
SDL_SetError("Unsupported console hardware");
GC_VideoQuit(_this);
return (-1);
}
switch (finfo.visual) {
case FB_VISUAL_TRUECOLOR:
/* Supported, no worries.. */
break;
default:
SDL_SetError("Unsupported console hardware");
GC_VideoQuit(_this);
return (-1);
}

/* Memory map the device, compensating for buggy PPC mmap() */
offset = (((long)finfo.smem_start) -
(((long)finfo.smem_start) & ~(PAGE_SIZE - 1)));
mapped_memlen = finfo.smem_len + offset;
mapped_mem = mmap(NULL, mapped_memlen,
PROT_READ | PROT_WRITE, MAP_SHARED, console_fd, 0);
if (mapped_mem == (char *)-1) {
SDL_SetError("Unable to memory map the video hardware");
mapped_mem = NULL;
GC_VideoQuit(_this);
return (-1);
}

/* Determine the current screen depth */
if (ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
SDL_SetError("Couldn't get console pixel format");
GC_VideoQuit(_this);
return (-1);
}

/* XXX isobel, review */

/* 16 bits per pixel */
vformat->BitsPerPixel = 16;
vformat->BytesPerPixel = 2;
/* RGB565 */
vformat->Rmask = 0x0000f800;
vformat->Gmask = 0x000007e0;
vformat->Bmask = 0x0000001f;

saved_vinfo = vinfo;

vinfo.accel_flags = 0;
ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo);

/* Fill in our hardware acceleration capabilities */
_this->info.wm_available = 0;
_this->info.hw_available = 1;
_this->info.video_mem = finfo.smem_len / 1024;

/* let's say "enable" keyboard support */
if (GC_OpenKeyboard(_this) < 0) {
GC_VideoQuit(_this);
return (-1);
}
if ( FB_OpenMouse(_this) < 0 ) {
const char *sdl_nomouse;

sdl_nomouse = getenv("SDL_NOMOUSE");
if ( ! sdl_nomouse ) {
SDL_SetError("Unable to open mouse");
GC_VideoQuit(_this);
return(-1);
}
}

/* We're done! */
return (0);
}

/*
*
* Note: If we are terminated, this could be called in the middle of
* another SDL video routine -- notably UpdateRects.
*/
static void GC_VideoQuit(_THIS)
{
if (_this->hidden->buffer) {
free(_this->hidden->buffer);
_this->hidden->buffer = NULL;
}
if (_this->screen) {
Uint32 *rowp = (Uint32 *) (mapped_mem + page_offset);
int left =
(_this->screen->pitch * _this->screen->h) / sizeof(Uint32);
while (left--) {
*rowp++ = GC_BLACK;
}
if (_this->screen->pixels != NULL) {
/* already freed above */
_this->screen->pixels = NULL;
}
}
/* Close console and input file descriptors */
if (console_fd > 0) {
/* Unmap the video framebuffer and I/O registers */
if (mapped_mem) {
munmap(mapped_mem, mapped_memlen);
mapped_mem = NULL;
}

/* Restore the original video mode and palette */
if (GC_InGraphicsMode(_this)) {
//FB_RestorePalette(_this);
ioctl(console_fd, FBIOPUT_VSCREENINFO, &saved_vinfo);
}

/* We're all done with the framebuffer */
close(console_fd);
console_fd = -1;
}
GC_CloseKeyboard(_this);
}


/*
*
* 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
};

/*
*
*/
SDL_Rect **GC_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
{
switch (format->BitsPerPixel) {
case 32:
GC_DPRINTF("Hey! Hey! Someone asking for a 32bpp mode!\n");
return (SDL_Rect **) & vid_modes[0];
case 24:
GC_DPRINTF("Hey! Hey! Someone asking for a 24bpp mode!\n");
return (SDL_Rect **) & vid_modes[0];
case 16:
return (SDL_Rect **) & vid_modes[0];
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 (GC_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);

if (_this->hidden->buffer) {
free(_this->hidden->buffer);
_this->hidden->buffer = NULL;
}

_this->hidden->buffer = malloc(width * height * ((bpp + 7) / 8));
if (!_this->hidden->buffer) {
SDL_SetError("Couldn't allocate buffer for requested mode");
return (NULL);
}

/* Set up the new mode framebuffer */
current->flags = SDL_FULLSCREEN;
current->w = width;
current->h = height;
current->pitch = width * ((bpp + 7) / 8);
current->pixels = _this->hidden->buffer;

page_address[0] = mapped_mem;
page_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 void FB_WaitIdle(_THIS)
{
return;
}


/*
*
* Hardware surface hooks.
*/

/*
*
*/
static int GC_AllocHWSurface(_THIS, SDL_Surface * surface)
{
/* We don't actually allow hardware surfaces other than the main one */
return (-1);
}

/*
*
*/
static void GC_FreeHWSurface(_THIS, SDL_Surface * surface)
{
return;
}

/*
*
*/
static int GC_LockHWSurface(_THIS, SDL_Surface * surface)
{
return (0);
}

/*
*
*/
static void GC_UnlockHWSurface(_THIS, SDL_Surface * surface)
{
return;
}

/*
*
*/
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);
}

/*
*
*/
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.
*/
}
}


/*
*
* 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 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];

/*
*
*/
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);
}

/*
*
*/
static int GC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
{
int i;
__u16 r[256];
__u16 g[256];
__u16 b[256];
struct fb_cmap cmap;

/* Set up the colormap */
for (i = 0; i < ncolors; i++) {
r[i] = colors[i].r << 8;
g[i] = colors[i].g << 8;
b[i] = colors[i].b << 8;
}
cmap.start = firstcolor;
cmap.len = ncolors;
cmap.red = r;
cmap.green = g;
cmap.blue = b;
cmap.transp = NULL;

if ((ioctl(console_fd, FBIOPUTCMAP, &cmap) < 0) ||
!(_this->screen->flags & SDL_HWPALETTE)) {
colors = _this->screen->format->palette->colors;
ncolors = _this->screen->format->palette->ncolors;
cmap.start = 0;
cmap.len = ncolors;
memset(r, 0, sizeof(r));
memset(g, 0, sizeof(g));
memset(b, 0, sizeof(b));
if (ioctl(console_fd, FBIOGETCMAP, &cmap) == 0) {
for (i = ncolors - 1; i >= 0; --i) {
colors[i].r = (r[i] >> 8);
colors[i].g = (g[i] >> 8);
colors[i].b = (b[i] >> 8);
}
}
return (0);
}
return (1);
}


/*
*
* 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 = _this->hidden->buffer + (rect->y * pitch) + left * 2;
dst = page_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;
}
}

/*
*
*/
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++;
}
}
}

///////Final SDL_gcvideo.c///////////////////

//////////Inicio SDL_gcvideo.h///////////////
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga

SDL port for the Nintendo GameCube
Copyright (C) 2004-2005 Albert Herranz

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Sam Lantinga
slouken@libsdl.org
*/

#ifndef _SDL_gcvideo_h
#define _SDL_gcvideo_h

#include <sys/types.h>
#include <termios.h>
#include <linux/fb.h>

#ifdef GC_DEBUG
# define GC_DPRINTF(fmt, args...) \
fprintf(stderr,"DDD|%s: " fmt, __FUNCTION__ , ## args)
#else
# define GC_DPRINTF(fmt, args...)
#endif

#include "SDL_sysvideo.h"
#include "SDL_mutex.h"

#define FBIOFLIPHACK 0x4623 /* gc-linux */


/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *_this

extern void GC_WaitForFlipCompletion(_THIS);

/* Private display data */

struct SDL_PrivateVideoData {
int w, h;
void *buffer;

void (*UpdateRect) (_THIS, SDL_Rect * rect, int pitch);

int console_fd;
struct fb_var_screeninfo cache_vinfo;
struct fb_var_screeninfo saved_vinfo;

int current_vt;
int saved_vt;
int keyboard_fd;
int in_graphics_mode;

///JJB fbcon
int saved_kbd_mode;
struct termios saved_kbd_termios;
///JJB fbcon sino comentalo
int mouse_fd;

char *mapped_mem;
int mapped_memlen;

int flip_pending;
int back_page;
char *page_address[2];
int page_offset;

#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
int SDL_nummodes[NUM_MODELISTS];
SDL_Rect **SDL_modelist[NUM_MODELISTS];

void (*wait_idle)(_THIS);
SDL_mutex *hw_lock;//JJB fbcon
};

/* Old variable names */
#define console_fd (_this->hidden->console_fd)
#define cache_vinfo (_this->hidden->cache_vinfo)
#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 in_graphics_mode (_this->hidden->in_graphics_mode)
#define mouse_fd (_this->hidden->mouse_fd)
#define mapped_mem (_this->hidden->mapped_mem)
#define mapped_memlen (_this->hidden->mapped_memlen)
#define flip_pending (_this->hidden->flip_pending)
#define back_page (_this->hidden->back_page)
#define page_address (_this->hidden->page_address)
#define page_offset (_this->hidden->page_offset)
#define SDL_nummodes (_this->hidden->SDL_nummodes)
#define SDL_modelist (_this->hidden->SDL_modelist)
#define hw_lock (_this->hidden->hw_lock)

#define wait_idle (_this->hidden->wait_idle)
#define saved_kbd_mode (_this->hidden->saved_kbd_mode)
#define saved_kbd_termios (_this->hidden->saved_kbd_termios)

#endif /* _SDL_gcvideo_h */

///////Final SDL_gcvideo.h///////////////////
Gracias!!!. A mi me ha interesado desde hace mucho ponerlo, pero mi sd es de 256 mb y no me sirve.. Hay alguna posibilidad de hacerlo funcionar en esta sd asi sea con un usb??
jjb_wii creo que deberias llevarte un premio al poste mas largo xDD
almenos es el mas largo que he visto en eol o eso creo xD
Ya lo se. pero si alguien quiere de verdad poder tener la XWindows, esto es todo lo que necesita....
Yo lo he metido todo en una tarjeta de 1Gb. Tengo otra de 2 Gb que se supone que es la ostia
de rápida en la que instalaré el SDL y las XWindows intentando no meter mucha mierda.....

Nuvalo: No no he probado el mplayer, pero vamos yo no ganaría mucho porque por el momento no voy a ponerme un disco usb...por lo de la baja velocidad... De todas maneras seguramente lo pruebe tambien, para compararlo con el del linux de mi PC y de paso si te interesa...... yo había pensado instalarme el mame para jugar un poco...

En cuanto al kdrive una vez funciona no me está dando problemas..... En cuanto a lo que me comentabas de la shadow + la función rgb2yuv2. Si me dieses más información o las pruebas que hayas hecho te lo agradecería. No hay nada como tener
unas Xwindows auténticas funcionando :)

El opera no lo se, pero el firefox funciona, aunque tarda en cargar demasiado, ya que consume mucha ram. Estoy intentando poner mem2 y mem1 para tener mayor ram directa en vez de swap, posiblemente solucione o al menos mejore los tiempos de carga.



Tadabia no he conseguido hacer funcionar el linux, pero al que pueda, podeis probar a usar Fennec, el nuevo navegador "mobile" de mozilla.

Aquí l oteneis para descarga: http://ftp.mozilla.org/pub/mozilla.org/mobile/
Buenas, un par de apuntes:

Si puedes, actualiza a sdlib 1.2.12, te solucionará muchos problemas con teclado y ratón.


Ok.

Los de freedesktop ya no usan el cvs que has puesto, ahora todo va por git.


Ya lo estuve mirando, de momento voy descargandome los tars... (tengo que montarme un samba en la wii para parchear mejor, ahora voy por vi y voy muy lento....), en su momento estaba cansado de descargarme .debs y pase del git.....

Cuando pruebes el mplayer o alguna aplicación que necesite 50fps me cuentas


Ostras que miedo me das, pensaba que te referias a lo del refresco del fondo de pantalla..... espero que no sea por cpu...

Si estás pensando en sdlmame


No especialmente, pensaba utilizar las mismas que el debian de mi pc, creo que es la xmame0.106, pero no me mola lo que comentas, de que no puedan convivir varios SDLs.... Mi idea era no tener más aplicaciones con SDL, sino tirar de la X's...quizás
estoy pecando de inocente....no se...

de todas formas, este trabajo es un poco inútil

Porqué es inútil, molaria tener un driver de video funcionando para wii, que hay que hacer p'a que no se pierda este trabajo....
te preguntaba si podías probar alguna aplicación de ese estilo.


Ok, esto hay que probarlo, que versión de mplayer tienes?. Así provaré con la misma. Avísame si hay que parchear algo, porque
viendo lo del kdrive y compañía.
Nota: supongo que con el Dillo no puedo forzar esto, no ?.

Por lo que te he comentado. El problema principal para las X es trabajar con un framebuffer que solo soporta yuv2. Si isobel soluciona eso, se puede tirar con el driver de fbdev normal. No es que sea inútil del todo, se le puede sacar partido (mola tenerlo todo controlado desde cero, no tirar de trabajo ya hecho) pero da la impresión de estar reinventando la rueda.


Ok, por el momento aunque sea vamos parcheando.... no obstante lo bueno sería que isobel ya modificase el fbdev con soporte a yuv2, no?
Buenas,

ayer probé lo del mplayer. Hice varias pruebas.

A) Con el mplayer de los repositorios de debian (etch3 creo)

-- no funciona nada, ni con xv, ni x11, ni sdl .... yo flipo si el xclock funciona y cosas así porque las x11 o xv no van, por lo
que estuve viendo en el petazo ponía algo que me comentante ayer sobre la extensión xvideo, supongo que hay que
reprogramar algo de ese módulo. No me funcionó ni desde la consola, ni desde las X's.

B) Con el MPlayer 1.0pre7-3.3.6 de la dirección que me pasaste, te cuento:

-- Por lo que veo se basa solo en las librerias de sdl, por lo que no prové con otras configuraciones de video
-- Solo me funciona en desde la consola, el ejemplo de video que probé ocupaba 2,8Mb y era mpeg 1 creo...lo descargué de
http://gallery.mobile9.com/f/562560/. Más abajo tienes el report del mplayer, aunque no creo que sirva p'a nada.

-- Una cosa curiosa que ocurrió al probarlo desde el xterm en las X's fué que el mplayer no petó, me dijo que estava
cargandose en otro vt y no me apareció el video, te lo detallo:

cuando cargo el Xsdl desde la consola me dice:

------------------
DDD|GC_SetVideoMode: Setting 640x480 16bpp mode
current_vt=7
v_active1=4060
saved_vt= 1
current_vt:7: a 1

al lanzar mplayer desde el xterm me dice:

DDD|GC_SetVideoMode: Setting 640x480 16bpp(doublebuffer)mode
current_vt=8
v_active1=4060
saved_vt=7
current_vt:8: a 1
----------

La verdad es que no se que se puede sacar de mis pruebas :(



///////////Report///////////////////////////////
MPlayer 1.0pre7-3.3.6 (C) 2000-2005 MPlayer Team
CPU: PowerPC
Playing video1.mpeg.
MPEG-PS file format detected.
VIDEO: MPEG1 384x288 (aspect 1) 25.000 fps 648.0 kbps (81.0 kbyte/s)
==========================================================================
Opening audio decoder: [mp3lib] MPEG layer-2, layer-3
AUDIO: 44100 Hz, 2 ch, s16be, 112.0 kbit/7.94% (ratio: 14000->176400)
Selected audio codec: [mp3] afm:mp3lib (mp3lib MPEG layer-2, layer-3)
==========================================================================
SDL: Using driver: gcvideo
==========================================================================
Opening video decoder: [mpegpes] MPEG 1/2 Video passthrough
VDec: vo config request - 384 x 288 (preferred csp: Mpeg PES)
Could not find matching colorspace - retrying with -vf scale...
Opening video filter: [scale]
VDecoder init failed :(
Opening video decoder: [libmpeg2] MPEG 1/2 Video decoder libmpeg2-v0.4.0b
Selected video codec: [mpeg12] vfm:libmpeg2 (MPEG-1 or 2 (libmpeg2))
==========================================================================
Checking audio filter chain for 44100Hz/2ch/s16be -> 44100Hz/2ch/s16be...
AF_pre: 44100Hz/2ch/s16be
[AO SDL] Samplerate: 44100Hz Channels: Stereo Format s16be
AO: [sdl] 44100Hz 2ch s16be (2 bps)
Building audio filter chain for 44100Hz/2ch/s16be -> 44100Hz/2ch/s16be...
Starting playback...
VDec: vo config request - 384 x 288 (preferred csp: Planar YV12)
VDec: using Planar YV12 as output csp (no 0)
Movie-Aspect is undefined - no prescaling applied.
VO: [sdl] 384x288 => 384x288 Planar YV12
Una pregunta, estoy haciendo mis primeros programas en pascal, la pregunta es si compilo lso programas en freepascal en el ubuntu 8.04, podría ejecutarlos de alguna manera en este linux¿?
Nuvalo, conseguí hacer correr las X hace tiempo, pero ya no hay manera de que arranque, ni xdm ni nada... ¿A ti te ha pasado algo parecido? (en la wii).
Nuvalo, conseguí hacer correr las X hace tiempo, pero ya no hay manera de que arranque, ni xdm ni nada

Pues no, funcionan igual desde el primer día :) ¿que instalaste? Si me das el error te puedo ayudar, aunque lo más fácil sería reinstalar todo desde cero.
Muchas gracias nuvalo por el driver, tiene muy buena pinta.

A ver si tengo un rato, como molaría tener las XWindows "auténticas" con colores guapos.......
245 respuestas
1, 2, 3, 4, 5