diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-06-19 04:45:52 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-06-19 04:45:52 -0300 |
commit | 3b2d3075929a6dcfd03fb1123ede810d54e9bb00 (patch) | |
tree | c7346d71f9662798690508cf2f876e4de6f69788 | |
parent | 8ec72b300bd4d3123a052a58ca8b707febfbe8e5 (diff) |
reicast-git-r1200.a9fc0f5-2: enable joystick support
-rw-r--r-- | pcr/reicast-git/PKGBUILD | 19 | ||||
-rw-r--r-- | pcr/reicast-git/enable_joystick_support.patch | 1999 |
2 files changed, 2013 insertions, 5 deletions
diff --git a/pcr/reicast-git/PKGBUILD b/pcr/reicast-git/PKGBUILD index aae8b1862..ab671fc2f 100644 --- a/pcr/reicast-git/PKGBUILD +++ b/pcr/reicast-git/PKGBUILD @@ -4,7 +4,7 @@ pkgname=reicast-git pkgver=r1200.a9fc0f5 -pkgrel=1 +pkgrel=2 pkgdesc="A multiplatform Sega Dreamcast emulator" arch=('i686' 'x86_64') url="http://reicast.com/" @@ -13,16 +13,25 @@ conflicts=('reicast') provides=('reicast') makedepends=('git') makedepends_x86_64=('gcc-multilib') -depends_x86_64=('lib32-libgl' 'lib32-alsa-lib') -depends_i686=('libgl' 'alsa-lib') -source=(reicast::"git+https://github.com/reicast/reicast-emulator.git") -md5sums=('SKIP') +depends_x86_64=('lib32-libgl' 'lib32-alsa-plugins') +depends_i686=('libgl' 'alsa-plugins') +optdepends=('xboxdrv: Userspace gamepad driver for Xbox and Xbox360 gamepads' + 'antimicro: Graphical program used to map keyboard keys and mouse controls to gamepad buttons') +source=(reicast::"git+https://github.com/reicast/reicast-emulator.git" + 'enable_joystick_support.patch') +sha256sums=('SKIP' + 'e0f53e5834acb5978c2b9f55cbfb8586f9482ea0bab1eec4398d87608a9b264e') pkgver() { cd reicast printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" } +prepare () { + cd reicast + patch -Np1 -i "$srcdir"/enable_joystick_support.patch +} + build () { make -C reicast/shell/lin86 } diff --git a/pcr/reicast-git/enable_joystick_support.patch b/pcr/reicast-git/enable_joystick_support.patch new file mode 100644 index 000000000..bab81e3f1 --- /dev/null +++ b/pcr/reicast-git/enable_joystick_support.patch @@ -0,0 +1,1999 @@ +diff -Nur reicast-emulator.orig/core/linux-dist/main.cpp reicast-emulator/core/linux-dist/main.cpp +--- reicast-emulator.orig/core/linux-dist/main.cpp 2015-06-18 01:18:38.310320960 -0300 ++++ reicast-emulator/core/linux-dist/main.cpp 2015-06-18 01:30:26.611571730 -0300 +@@ -1,900 +1,1095 @@ +-#include "types.h" +-#include "cfg/cfg.h" +- +-#if HOST_OS==OS_LINUX +-#include <poll.h> +-#include <termios.h> +-//#include <curses.h> +-#include <fcntl.h> +-#include <semaphore.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <sys/param.h> +-#include <sys/mman.h> +-#include <sys/time.h> +-#include "hw/sh4/dyna/blockmanager.h" +-#include <unistd.h> +- +- +- +- +-#if defined(SUPPORT_X11) +- #include <X11/Xlib.h> +- #include <X11/Xatom.h> +- #include <X11/Xutil.h> +- +- #if !defined(GLES) +- #include <GL/gl.h> +- #include <GL/glx.h> +- #endif +- +- #include <map> +- map<int, int> x11_keymap; +-#endif +- +-#if !defined(ANDROID) && HOST_OS != OS_DARWIN +- #include <linux/joystick.h> +- #include <sys/stat.h> +- #include <sys/types.h> +-#endif +- +-#ifdef TARGET_PANDORA +-#include <signal.h> +-#include <execinfo.h> +-#include <sys/soundcard.h> +- +-#define WINDOW_WIDTH 800 +-#else +-#define WINDOW_WIDTH 640 +-#endif +-#define WINDOW_HEIGHT 480 +- +-void* x11_win=0,* x11_disp=0; +-void* libPvr_GetRenderTarget() +-{ +- return x11_win; +-} +- +-void* libPvr_GetRenderSurface() +-{ +- return x11_disp; +-} +- +-int msgboxf(const wchar* text,unsigned int type,...) +-{ +- va_list args; +- +- wchar temp[2048]; +- va_start(args, type); +- vsprintf(temp, text, args); +- va_end(args); +- +- //printf(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL); +- puts(temp); +- return MBX_OK; +-} +- +- +- +-u16 kcode[4]; +-u32 vks[4]; +-s8 joyx[4],joyy[4]; +-u8 rt[4],lt[4]; +- +-enum DCPad { +- Btn_C = 1, +- Btn_B = 1<<1, +- Btn_A = 1<<2, +- Btn_Start = 1<<3, +- DPad_Up = 1<<4, +- DPad_Down = 1<<5, +- DPad_Left = 1<<6, +- DPad_Right = 1<<7, +- Btn_Z = 1<<8, +- Btn_Y = 1<<9, +- Btn_X = 1<<10, +- Btn_D = 1<<11, +- DPad2_Up = 1<<12, +- DPad2_Down = 1<<13, +- DPad2_Left = 1<<14, +- DPad2_Right = 1<<15, +- +- Axis_LT= 0x10000, +- Axis_RT= 0x10001, +- Axis_X= 0x20000, +- Axis_Y= 0x20001, +-}; +- +- +-void emit_WriteCodeCache(); +- +-static int JoyFD = -1; // Joystick file descriptor +-static int kbfd = -1; +-#ifdef TARGET_PANDORA +-static int audio_fd = -1; +-#endif +- +- +-#define MAP_SIZE 32 +- +-const u32 JMapBtn_USB[MAP_SIZE] = +- { Btn_Y,Btn_B,Btn_A,Btn_X,0,0,0,0,0,Btn_Start }; +- +-const u32 JMapAxis_USB[MAP_SIZE] = +- { Axis_X,Axis_Y,0,0,0,0,0,0,0,0 }; +- +-const u32 JMapBtn_360[MAP_SIZE] = +- { Btn_A,Btn_B,Btn_X,Btn_Y,0,0,0,Btn_Start,0,0 }; +- +-const u32 JMapAxis_360[MAP_SIZE] = +- { Axis_X,Axis_Y,Axis_LT,0,0,Axis_RT,DPad_Left,DPad_Up,0,0 }; +- +-const u32* JMapBtn=JMapBtn_USB; +-const u32* JMapAxis=JMapAxis_USB; +- +- +-void SetupInput() +-{ +- for (int port=0;port<4;port++) +- { +- kcode[port]=0xFFFF; +- rt[port]=0; +- lt[port]=0; +- } +- +-#if HOST_OS != OS_DARWIN +- if (true) { +- #ifdef TARGET_PANDORA +- const char* device = "/dev/input/event4"; +- #else +- const char* device = "/dev/event2"; +- #endif +- char name[256]= "Unknown"; +- +- if ((kbfd = open(device, O_RDONLY)) > 0) { +- fcntl(kbfd,F_SETFL,O_NONBLOCK); +- if(ioctl(kbfd, EVIOCGNAME(sizeof(name)), name) < 0) { +- perror("evdev ioctl"); +- } +- +- printf("The device on %s says its name is %s\n",device, name); +- +- } +- else +- perror("evdev open"); +- } +-#endif +- // Open joystick device +- JoyFD = open("/dev/input/js0",O_RDONLY); +-#if HOST_OS != OS_DARWIN +- if(JoyFD>=0) +- { +- int AxisCount,ButtonCount; +- char Name[128]; +- +- AxisCount = 0; +- ButtonCount = 0; +- Name[0] = '\0'; +- +- fcntl(JoyFD,F_SETFL,O_NONBLOCK); +- ioctl(JoyFD,JSIOCGAXES,&AxisCount); +- ioctl(JoyFD,JSIOCGBUTTONS,&ButtonCount); +- ioctl(JoyFD,JSIOCGNAME(sizeof(Name)),&Name); +- +- printf("SDK: Found '%s' joystick with %d axis and %d buttons\n",Name,AxisCount,ButtonCount); +- +- if (strcmp(Name,"Microsoft X-Box 360 pad")==0) +- { +- JMapBtn=JMapBtn_360; +- JMapAxis=JMapAxis_360; +- printf("Using Xbox 360 map\n"); +- } +- } +-#endif +-} +- +-bool HandleKb(u32 port) { +-#if HOST_OS != OS_DARWIN +- if (kbfd < 0) +- return false; +- +- input_event ie; +- +- #if defined(TARGET_GCW0) +- +- #define KEY_A 0x1D +- #define KEY_B 0x38 +- #define KEY_X 0x2A +- #define KEY_Y 0x39 +- #define KEY_L 0xF +- #define KEY_R 0xE +- #define KEY_SELECT 0x1 +- #define KEY_START 0x1C +- #define KEY_LEFT 0x69 +- #define KEY_RIGHT 0x6A +- #define KEY_UP 0x67 +- #define KEY_DOWN 0x6C +- #define KEY_LOCK 0x77 // Note that KEY_LOCK is a switch and remains pressed until it's switched back +- +- static int keys[13]; +- while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) { +- //printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); +- if (ie.type=EV_KEY) +- switch (ie.code) { +- case KEY_SELECT: keys[9]=ie.value; break; +- case KEY_UP: keys[1]=ie.value; break; +- case KEY_DOWN: keys[2]=ie.value; break; +- case KEY_LEFT: keys[3]=ie.value; break; +- case KEY_RIGHT: keys[4]=ie.value; break; +- case KEY_Y:keys[5]=ie.value; break; +- case KEY_B:keys[6]=ie.value; break; +- case KEY_A: keys[7]=ie.value; break; +- case KEY_X: keys[8]=ie.value; break; +- case KEY_START: keys[12]=ie.value; break; +- } +- } +- if (keys[6]) { kcode[port] &= ~Btn_A; } +- if (keys[7]) { kcode[port] &= ~Btn_B; } +- if (keys[5]) { kcode[port] &= ~Btn_Y; } +- if (keys[8]) { kcode[port] &= ~Btn_X; } +- if (keys[1]) { kcode[port] &= ~DPad_Up; } +- if (keys[2]) { kcode[port] &= ~DPad_Down; } +- if (keys[3]) { kcode[port] &= ~DPad_Left; } +- if (keys[4]) { kcode[port] &= ~DPad_Right; } +- if (keys[12]){ kcode[port] &= ~Btn_Start; } +- if (keys[9]){ die("death by escape key"); } +- if (keys[10]) rt[port]=255; +- if (keys[11]) lt[port]=255; +- +- return true; +- +- #elif defined(TARGET_PANDORA) +- static int keys[13]; +- while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) { +- if (ie.type=EV_KEY) +- //printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); +- switch (ie.code) { +- case KEY_SPACE: keys[0]=ie.value; break; +- case KEY_UP: keys[1]=ie.value; break; +- case KEY_DOWN: keys[2]=ie.value; break; +- case KEY_LEFT: keys[3]=ie.value; break; +- case KEY_RIGHT: keys[4]=ie.value; break; +- case KEY_PAGEUP:keys[5]=ie.value; break; +- case KEY_PAGEDOWN:keys[6]=ie.value; break; +- case KEY_END: keys[7]=ie.value; break; +- case KEY_HOME: keys[8]=ie.value; break; +- case KEY_MENU: keys[9]=ie.value; break; +- case KEY_RIGHTSHIFT: keys[10]=ie.value; break; +- case KEY_RIGHTCTRL: keys[11]=ie.value; break; +- case KEY_LEFTALT: keys[12]=ie.value; break; +- } +- } +- +- if (keys[0]) { kcode[port] &= ~Btn_C; } +- if (keys[6]) { kcode[port] &= ~Btn_A; } +- if (keys[7]) { kcode[port] &= ~Btn_B; } +- if (keys[5]) { kcode[port] &= ~Btn_Y; } +- if (keys[8]) { kcode[port] &= ~Btn_X; } +- if (keys[1]) { kcode[port] &= ~DPad_Up; } +- if (keys[2]) { kcode[port] &= ~DPad_Down; } +- if (keys[3]) { kcode[port] &= ~DPad_Left; } +- if (keys[4]) { kcode[port] &= ~DPad_Right; } +- if (keys[12]){ kcode[port] &= ~Btn_Start; } +- if (keys[9]){ die("death by escape key"); } +- if (keys[10]) rt[port]=255; +- if (keys[11]) lt[port]=255; +- +- return true; +- #else +- while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) { +- printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); +- } +- #endif +-#endif +-return true; +-} +- +-bool HandleJoystick(u32 port) +-{ +- +- // Joystick must be connected +- if(JoyFD<0) return false; +- +-#if HOST_OS != OS_DARWIN +- struct js_event JE; +- while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE)) +- if (JE.number<MAP_SIZE) +- { +- switch(JE.type & ~JS_EVENT_INIT) +- { +- case JS_EVENT_AXIS: +- { +- u32 mt=JMapAxis[JE.number]>>16; +- u32 mo=JMapAxis[JE.number]&0xFFFF; +- +- //printf("AXIS %d,%d\n",JE.number,JE.value); +- s8 v=(s8)(JE.value/256); //-127 ... + 127 range +- +- if (mt==0) +- { +- kcode[port]|=mo; +- kcode[port]|=mo*2; +- if (v<-64) +- { +- kcode[port]&=~mo; +- } +- else if (v>64) +- { +- kcode[port]&=~(mo*2); +- } +- +- // printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2)); +- } +- else if (mt==1) +- { +- if (v>=0) v++; //up to 255 +- +- // printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127); +- +- if (mo==0) +- lt[port]=v+127; +- else if (mo==1) +- rt[port]=v+127; +- } +- else if (mt==2) +- { +- // printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v); +- if (mo==0) +- joyx[port]=v; +- else if (mo==1) +- joyy[port]=v; +- } +- } +- break; +- +- case JS_EVENT_BUTTON: +- { +- u32 mt=JMapBtn[JE.number]>>16; +- u32 mo=JMapBtn[JE.number]&0xFFFF; +- +- // printf("BUTTON %d,%d\n",JE.number,JE.value); +- +- if (mt==0) +- { +- // printf("Mapped to %d\n",mo); +- if (JE.value) +- kcode[port]&=~mo; +- else +- kcode[port]|=mo; +- } +- else if (mt==1) +- { +- // printf("Mapped to %d %d\n",mo,JE.value?255:0); +- if (mo==0) +- lt[port]=JE.value?255:0; +- else if (mo==1) +- rt[port]=JE.value?255:0; +- } +- +- } +- break; +- } +- } +-#endif +- return true; +- +-} +- +-extern bool KillTex; +- +-#ifdef TARGET_PANDORA +-static Cursor CreateNullCursor(Display *display, Window root) +-{ +- Pixmap cursormask; +- XGCValues xgc; +- GC gc; +- XColor dummycolour; +- Cursor cursor; +- +- cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); +- xgc.function = GXclear; +- gc = XCreateGC(display, cursormask, GCFunction, &xgc); +- XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); +- dummycolour.pixel = 0; +- dummycolour.red = 0; +- dummycolour.flags = 04; +- cursor = XCreatePixmapCursor(display, cursormask, cursormask, +- &dummycolour,&dummycolour, 0,0); +- XFreePixmap(display,cursormask); +- XFreeGC(display,gc); +- return cursor; +-} +-#endif +- +-int x11_dc_buttons = 0xFFFF; +- +-void UpdateInputState(u32 port) +-{ +- static char key = 0; +- +- kcode[port]= x11_dc_buttons; +- rt[port]=0; +- lt[port]=0; +- +-#if defined(TARGET_GCW0) || defined(TARGET_PANDORA) +- HandleJoystick(port); +- HandleKb(port); +-return; +-#endif +- for(;;) +- { +- key = 0; +- read(STDIN_FILENO, &key, 1); +- +- if (0 == key || EOF == key) break; +- if ('k' == key) KillTex=true; +- +-#ifdef TARGET_PANDORA +- if (' ' == key) { kcode[port] &= ~Btn_C; } +- if ('6' == key) { kcode[port] &= ~Btn_A; } +- if ('O' == key) { kcode[port] &= ~Btn_B; } +- if ('5' == key) { kcode[port] &= ~Btn_Y; } +- if ('H' == key) { kcode[port] &= ~Btn_X; } +- if ('A' == key) { kcode[port] &= ~DPad_Up; } +- if ('B' == key) { kcode[port] &= ~DPad_Down; } +- if ('D' == key) { kcode[port] &= ~DPad_Left; } +- if ('C' == key) { kcode[port] &= ~DPad_Right; } +-#else +- if ('b' == key) { kcode[port] &= ~Btn_C; } +- if ('v' == key) { kcode[port] &= ~Btn_A; } +- if ('c' == key) { kcode[port] &= ~Btn_B; } +- if ('x' == key) { kcode[port] &= ~Btn_Y; } +- if ('z' == key) { kcode[port] &= ~Btn_X; } +- if ('i' == key) { kcode[port] &= ~DPad_Up; } +- if ('k' == key) { kcode[port] &= ~DPad_Down; } +- if ('j' == key) { kcode[port] &= ~DPad_Left; } +- if ('l' == key) { kcode[port] &= ~DPad_Right; } +-#endif +- if (0x0A== key) { kcode[port] &= ~Btn_Start; } +-#ifdef TARGET_PANDORA +- if ('q' == key){ die("death by escape key"); } +-#endif +- //if (0x1b == key){ die("death by escape key"); } //this actually quits when i press left for some reason +- +- if ('a' == key) rt[port]=255; +- if ('s' == key) lt[port]=255; +-#if !defined(HOST_NO_REC) +- if ('b' == key) emit_WriteCodeCache(); +- if ('n' == key) bm_Reset(); +- if ('m' == key) bm_Sort(); +- if (',' == key) { emit_WriteCodeCache(); bm_Sort(); } +-#endif +- } +-} +- +-void os_DoEvents() +-{ +- #if defined(SUPPORT_X11) +- if (x11_win) { +- //Handle X11 +- XEvent e; +- if(XCheckWindowEvent((Display*)x11_disp, (Window)x11_win, KeyPressMask | KeyReleaseMask, &e)) +- { +- switch(e.type) +- { +- +- case KeyPress: +- case KeyRelease: +- { +- int dc_key = x11_keymap[e.xkey.keycode]; +- +- if (e.type == KeyPress) +- x11_dc_buttons &= ~dc_key; +- else +- x11_dc_buttons |= dc_key; +- +- //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons ); +- } +- break; +- +- +- { +- printf("KEYRELEASE\n"); +- } +- break; +- +- } +- } +- } +- #endif +-} +- +-void os_SetWindowText(const char * text) +-{ +- if (0==x11_win || 0==x11_disp || 1) +- printf("%s\n",text); +-#if defined(SUPPORT_X11) +- else if (x11_win) { +- XChangeProperty((Display*)x11_disp, (Window)x11_win, +- XInternAtom((Display*)x11_disp, "WM_NAME", False), //WM_NAME, +- XInternAtom((Display*)x11_disp, "UTF8_STRING", False), //UTF8_STRING, +- 8, PropModeReplace, (const unsigned char *)text, strlen(text)); +- } +-#endif +-} +- +- +-void* x11_glc; +- +-int ndcid=0; +-void os_CreateWindow() +-{ +-#if defined(SUPPORT_X11) +- if (cfgLoadInt("pvr","nox11",0)==0) +- { +- XInitThreads(); +- // X11 variables +- Window x11Window = 0; +- Display* x11Display = 0; +- long x11Screen = 0; +- XVisualInfo* x11Visual = 0; +- Colormap x11Colormap = 0; +- +- /* +- Step 0 - Create a NativeWindowType that we can use it for OpenGL ES output +- */ +- Window sRootWindow; +- XSetWindowAttributes sWA; +- unsigned int ui32Mask; +- int i32Depth; +- +- // Initializes the display and screen +- x11Display = XOpenDisplay( 0 ); +- if (!x11Display && !(x11Display = XOpenDisplay( ":0" ))) +- { +- printf("Error: Unable to open X display\n"); +- return; +- } +- x11Screen = XDefaultScreen( x11Display ); +- +- // Gets the window parameters +- sRootWindow = RootWindow(x11Display, x11Screen); +- +- int depth = CopyFromParent; +- +- #if !defined(GLES) +- // Get a matching FB config +- static int visual_attribs[] = +- { +- GLX_X_RENDERABLE , True, +- GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, +- GLX_RENDER_TYPE , GLX_RGBA_BIT, +- GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, +- GLX_RED_SIZE , 8, +- GLX_GREEN_SIZE , 8, +- GLX_BLUE_SIZE , 8, +- GLX_ALPHA_SIZE , 8, +- GLX_DEPTH_SIZE , 24, +- GLX_STENCIL_SIZE , 8, +- GLX_DOUBLEBUFFER , True, +- //GLX_SAMPLE_BUFFERS , 1, +- //GLX_SAMPLES , 4, +- None +- }; +- +- int glx_major, glx_minor; +- +- // FBConfigs were added in GLX version 1.3. +- if ( !glXQueryVersion( x11Display, &glx_major, &glx_minor ) || +- ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) +- { +- printf("Invalid GLX version"); +- exit(1); +- } +- +- int fbcount; +- GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); +- if (!fbc) +- { +- printf( "Failed to retrieve a framebuffer config\n" ); +- exit(1); +- } +- printf( "Found %d matching FB configs.\n", fbcount ); +- +- GLXFBConfig bestFbc = fbc[ 0 ]; +- XFree( fbc ); +- +- // Get a visual +- XVisualInfo *vi = glXGetVisualFromFBConfig( x11Display, bestFbc ); +- printf( "Chosen visual ID = 0x%x\n", vi->visualid ); +- +- +- depth = vi->depth; +- x11Visual = vi; +- +- x11Colormap = XCreateColormap(x11Display, RootWindow(x11Display, x11Screen), vi->visual, AllocNone); +- #else +- i32Depth = DefaultDepth(x11Display, x11Screen); +- x11Visual = new XVisualInfo; +- XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, x11Visual); +- if (!x11Visual) +- { +- printf("Error: Unable to acquire visual\n"); +- return; +- } +- x11Colormap = XCreateColormap( x11Display, sRootWindow, x11Visual->visual, AllocNone ); +- #endif +- +- sWA.colormap = x11Colormap; +- +- // Add to these for handling other events +- sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; +- ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; +- +- #ifdef TARGET_PANDORA +- int width=800; +- int height=480; +- #else +- int width=cfgLoadInt("x11","width", WINDOW_WIDTH); +- int height=cfgLoadInt("x11","height", WINDOW_HEIGHT); +- #endif +- +- if (width==-1) +- { +- width=XDisplayWidth(x11Display,x11Screen); +- height=XDisplayHeight(x11Display,x11Screen); +- } +- +- // Creates the X11 window +- x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height, +- 0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA); +- #ifdef TARGET_PANDORA +- // fullscreen +- Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); +- Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); +- XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); +- +- XMapRaised(x11Display, x11Window); +- #else +- XMapWindow(x11Display, x11Window); +- +- #if !defined(GLES) +- +- #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +- #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +- typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); +- +- glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; +- glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) +- glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); +- +- verify( glXCreateContextAttribsARB != 0 ); +- +- int context_attribs[] = { +- GLX_CONTEXT_MAJOR_VERSION_ARB, 3, +- GLX_CONTEXT_MINOR_VERSION_ARB, 1, +- GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, +- GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, +- None +- }; +- +- x11_glc = glXCreateContextAttribsARB( x11Display, bestFbc, 0, True, context_attribs); +- XSync( x11Display, False ); +- +- if (!x11_glc) { +- die("Failed to create GL3.1 context\n"); +- } +- #endif +- #endif +- XFlush(x11Display); +- +- +- +- //(EGLNativeDisplayType)x11Display; +- x11_disp=(void*)x11Display; +- x11_win=(void*)x11Window; +- } +- else +- printf("Not creating X11 window ..\n"); +-#endif +-} +- +-termios tios, orig_tios; +- +-int setup_curses() +-{ +- //initscr(); +- //cbreak(); +- //noecho(); +- +- +- /* Get current terminal settings */ +- if (tcgetattr(STDIN_FILENO, &orig_tios)) { +- printf("Error getting current terminal settings\n"); +- return -1; +- } +- +- memcpy(&tios, &orig_tios, sizeof(struct termios)); +- tios.c_lflag &= ~ICANON; //(ECHO|ICANON);&= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL); +- +- tios.c_cc[VTIME] = 0; +- tios.c_cc[VMIN] = 0; +- +- if (tcsetattr(STDIN_FILENO, TCSANOW, &tios)) { +- printf("Error applying terminal settings\n"); +- return -2; +- } +- +- if (tcgetattr(STDIN_FILENO, &tios)) { +- tcsetattr(0, TCSANOW, &orig_tios); +- printf("Error while asserting terminal settings\n"); +- return -3; +- } +- +- if ((tios.c_lflag & ICANON) || !(tios.c_lflag & ECHO)) { +- tcsetattr(STDIN_FILENO, TCSANOW, &orig_tios); +- printf("Could not apply all terminal settings\n"); +- return -4; +- } +- +- fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); +- return 1; +-} +- +-void common_linux_setup(); +-int dc_init(int argc,wchar* argv[]); +-void dc_run(); +- +-#ifdef TARGET_PANDORA +-void gl_term(); +- +-void clean_exit(int sig_num) { +- void *array[10]; +- size_t size; +- +- // close files +- if (JoyFD>=0) close(JoyFD); +- if (kbfd>=0) close(kbfd); +- if(audio_fd>=0) close(audio_fd); +- +- // Close EGL context ??? +- if (sig_num!=0) +- gl_term(); +- +- // close XWindow +- if (x11_win) { +- XDestroyWindow(x11_disp, x11_win); +- x11_win = 0; +- } +- if (x11_disp) { +- XCloseDisplay(x11_disp); +- x11_disp = 0; +- } +- +- // finish cleaning +- if (sig_num!=0) { +- write(2, "\nSignal received\n", sizeof("\nSignal received\n")); +- +- size = backtrace(array, 10); +- backtrace_symbols_fd(array, size, STDERR_FILENO); +- exit(1); +- } +-} +- +-void init_sound() +-{ +- if((audio_fd=open("/dev/dsp",O_WRONLY))<0) { +- printf("Couldn't open /dev/dsp.\n"); +- } +- else +- { +- printf("sound enabled, dsp openned for write\n"); +- int tmp=44100; +- int err_ret; +- err_ret=ioctl(audio_fd,SNDCTL_DSP_SPEED,&tmp); +- printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp); +- int channels=2; +- err_ret=ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels); +- printf("set dsp to stereo (%i => %i)\n", channels, err_ret); +- int format=AFMT_S16_LE; +- err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); +- printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed" ,AFMT_S16_LE, format, err_ret); +- } +-} +-#endif +- +-int main(int argc, wchar* argv[]) +-{ +- //if (argc==2) +- //ndcid=atoi(argv[1]); +- +- if (setup_curses() < 0) die("failed to setup curses!\n"); +-#ifdef TARGET_PANDORA +- signal(SIGSEGV, clean_exit); +- signal(SIGKILL, clean_exit); +- +- init_sound(); +-#else +- void os_InitAudio(); +- os_InitAudio(); +-#endif +- +-#if defined(USES_HOMEDIR) && HOST_OS != OS_DARWIN +- string home = (string)getenv("HOME"); +- if(home.c_str()) +- { +- home += "/.reicast"; +- mkdir(home.c_str(), 0755); // create the directory if missing +- SetHomeDir(home); +- } +- else +- SetHomeDir("."); +-#else +- SetHomeDir("."); +-#endif +- +- #if defined(SUPPORT_X11) +- x11_keymap[113] = DPad_Left; +- x11_keymap[114] = DPad_Right; +- +- x11_keymap[111] = DPad_Up; +- x11_keymap[116] = DPad_Down; +- +- x11_keymap[52] = Btn_Y; +- x11_keymap[53] = Btn_X; +- x11_keymap[54] = Btn_B; +- x11_keymap[55] = Btn_A; +- +- /* +- //TODO: Fix sliders +- x11_keymap[38] = DPad_Down; +- x11_keymap[39] = DPad_Down; +- */ +- +- x11_keymap[36] = Btn_Start; +- #endif +- +- printf("Home dir is: %s\n",GetPath("/").c_str()); +- +- common_linux_setup(); +- +- SetupInput(); +- +- settings.profile.run_counts=0; +- +- dc_init(argc,argv); +- +- dc_run(); +- +-#ifdef TARGET_PANDORA +- clean_exit(0); +-#endif +- +- return 0; +-} +- +-u32 alsa_Push(void* frame, u32 samples, bool wait); +-u32 os_Push(void* frame, u32 samples, bool wait) +-{ +- #ifndef TARGET_PANDORA +- int audio_fd = -1; +- #endif +- +- if (audio_fd > 0) { +- write(audio_fd, frame, samples*4); +- } else { +- return alsa_Push(frame, samples, wait); +- } +- +- return 1; +-} +-#endif +- +-int get_mic_data(u8* buffer) { return 0; } +-int push_vmu_screen(u8* buffer) { return 0; } +- +- +-void os_DebugBreak() +-{ +- raise(SIGTRAP); +-} ++#include "types.h"
++#include "cfg/cfg.h"
++
++#if HOST_OS==OS_LINUX
++#include <poll.h>
++#include <termios.h>
++//#include <curses.h>
++#include <fcntl.h>
++#include <semaphore.h>
++#include <stdarg.h>
++#include <signal.h>
++#include <sys/param.h>
++#include <sys/mman.h>
++#include <sys/time.h>
++#include "hw/sh4/dyna/blockmanager.h"
++#include <unistd.h>
++
++
++
++
++#if defined(SUPPORT_X11)
++ #include <X11/Xlib.h>
++ #include <X11/Xatom.h>
++ #include <X11/Xutil.h>
++ #include <X11/XKBlib.h>
++
++ #if !defined(GLES)
++ #include <GL/gl.h>
++ #include <GL/glx.h>
++ #endif
++
++ #include <map>
++ map<int, int> x11_keymap;
++#endif
++
++#if !defined(ANDROID) && HOST_OS != OS_DARWIN
++ #include <linux/joystick.h>
++ #include <sys/stat.h>
++ #include <sys/types.h>
++#endif
++
++#ifdef TARGET_PANDORA
++#include <signal.h>
++#include <execinfo.h>
++#include <sys/soundcard.h>
++
++#define WINDOW_WIDTH 800
++#else
++#define WINDOW_WIDTH 640
++#endif
++#define WINDOW_HEIGHT 480
++
++/*****************************************************************/
++/****************** Configure Controls ***************************/
++/*****************************************************************/
++
++// Use XEV in terminal window to find keycodes to configure buttons.
++#define XANA_UP (25)
++#define XANA_DOWN (39)
++#define XANA_LEFT (38)
++#define XANA_RIGHT (40)
++#define XANA_LT (79)
++#define XANA_RT (81)
++#define XDPAD_UP (31)
++#define XDPAD_DOWN (45)
++#define XDPAD_LEFT (44)
++#define XDPAD_RIGHT (46)
++#define XBTN_Y (80)
++#define XBTN_X (83)
++#define XBTN_B (85)
++#define XBTN_A (84)
++#define XBTN_START (36)
++
++/*******************************************************************/
++
++u8 temp_joyx = 0;
++u8 temp_joyy = 0;
++u8 temp_lt = 0;
++u8 temp_rt = 0;
++
++void* x11_win=0,* x11_disp=0;
++void* libPvr_GetRenderTarget()
++{
++ return x11_win;
++}
++
++void* libPvr_GetRenderSurface()
++{
++ return x11_disp;
++}
++
++int msgboxf(const wchar* text,unsigned int type,...)
++{
++ va_list args;
++
++ wchar temp[2048];
++ va_start(args, type);
++ vsprintf(temp, text, args);
++ va_end(args);
++
++ //printf(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
++ puts(temp);
++ return MBX_OK;
++}
++
++
++
++u16 kcode[4];
++u32 vks[4];
++s8 joyx[4],joyy[4];
++u8 rt[4],lt[4];
++
++enum DCPad {
++ Btn_C = 1,
++ Btn_B = 1<<1,
++ Btn_A = 1<<2,
++ Btn_Start = 1<<3,
++ DPad_Up = 1<<4,
++ DPad_Down = 1<<5,
++ DPad_Left = 1<<6,
++ DPad_Right = 1<<7,
++ Btn_Z = 1<<8,
++ Btn_Y = 1<<9,
++ Btn_X = 1<<10,
++ Btn_D = 1<<11,
++ DPad2_Up = 1<<12,
++ DPad2_Down = 1<<13,
++ DPad2_Left = 1<<14,
++ DPad2_Right = 1<<15,
++
++ Axis_LT= 0x10000,
++ Axis_RT= 0x10001,
++ Axis_X= 0x20000,
++ Axis_Y= 0x20001,
++};
++
++
++void emit_WriteCodeCache();
++
++static int JoyFD = -1; // Joystick file descriptor
++static int kbfd = -1;
++#ifdef TARGET_PANDORA
++static int audio_fd = -1;
++#endif
++
++
++#define MAP_SIZE 32
++
++const u32 JMapBtn_USB[MAP_SIZE] =
++ { Btn_Y,Btn_B,Btn_A,Btn_X,0,0,0,0,0,Btn_Start };
++
++const u32 JMapAxis_USB[MAP_SIZE] =
++ { Axis_X,Axis_Y,0,0,0,0,0,0,0,0 };
++
++const u32 JMapBtn_360[MAP_SIZE] =
++ { Btn_A,Btn_B,Btn_X,Btn_Y,0,0,0,Btn_Start,0,0 };
++
++const u32 JMapAxis_360[MAP_SIZE] =
++ //{ Axis_X,Axis_Y,Axis_LT,0,0,Axis_RT,DPad_Left,DPad_Up,0,0 };
++ { Axis_X,Axis_Y,0,0,Axis_RT,Axis_LT,DPad_Left,DPad_Up,0,0 };
++const u32* JMapBtn=JMapBtn_USB;
++const u32* JMapAxis=JMapAxis_USB;
++
++
++void SetupInput()
++{
++ for (int port=0;port<4;port++)
++ {
++ kcode[port]=0xFFFF;
++ rt[port]=0;
++ lt[port]=0;
++ }
++
++#if HOST_OS != OS_DARWIN
++ if (true) {
++ #ifdef TARGET_PANDORA
++ const char* device = "/dev/input/event4";
++ #else
++ const char* device = "/dev/event2";
++ #endif
++ char name[256]= "Unknown";
++
++ if ((kbfd = open(device, O_RDONLY)) > 0) {
++ fcntl(kbfd,F_SETFL,O_NONBLOCK);
++ if(ioctl(kbfd, EVIOCGNAME(sizeof(name)), name) < 0) {
++ perror("evdev ioctl");
++ }
++
++ printf("The device on %s says its name is %s\n",device, name);
++
++ }
++ else
++ perror("evdev open");
++ }
++#endif
++ // Open joystick device
++ JoyFD = open("/dev/input/js0",O_RDONLY);
++#if HOST_OS != OS_DARWIN
++ if(JoyFD>=0)
++ {
++ int AxisCount,ButtonCount;
++ char Name[128];
++
++ AxisCount = 0;
++ ButtonCount = 0;
++ Name[0] = '\0';
++
++ fcntl(JoyFD,F_SETFL,O_NONBLOCK);
++ ioctl(JoyFD,JSIOCGAXES,&AxisCount);
++ ioctl(JoyFD,JSIOCGBUTTONS,&ButtonCount);
++ ioctl(JoyFD,JSIOCGNAME(sizeof(Name)),&Name);
++
++ printf("SDK: Found '%s' joystick with %d axis and %d buttons\n",Name,AxisCount,ButtonCount);
++
++ if (strcmp(Name,"Microsoft X-Box 360 pad")==0 || strcmp(Name,"Xbox Gamepad (userspace driver)")==0)
++ {
++ JMapBtn=JMapBtn_360;
++ JMapAxis=JMapAxis_360;
++ printf("Using Xbox 360 map\n");
++ }
++ }
++#endif
++}
++
++bool HandleKb(u32 port) {
++#if HOST_OS != OS_DARWIN
++ if (kbfd < 0)
++ return false;
++
++ input_event ie;
++
++ #if defined(TARGET_GCW0)
++
++ #define KEY_A 0x1D
++ #define KEY_B 0x38
++ #define KEY_X 0x2A
++ #define KEY_Y 0x39
++ #define KEY_L 0xF
++ #define KEY_R 0xE
++ #define KEY_SELECT 0x1
++ #define KEY_START 0x1C
++ #define KEY_LEFT 0x69
++ #define KEY_RIGHT 0x6A
++ #define KEY_UP 0x67
++ #define KEY_DOWN 0x6C
++ #define KEY_LOCK 0x77 // Note that KEY_LOCK is a switch and remains pressed until it's switched back
++
++ static int keys[13];
++ while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) {
++ //printf("type %i key %i state %i\n", ie.type, ie.code, ie.value);
++ if (ie.type=EV_KEY)
++ switch (ie.code) {
++ case KEY_SELECT: keys[9]=ie.value; break;
++ case KEY_UP: keys[1]=ie.value; break;
++ case KEY_DOWN: keys[2]=ie.value; break;
++ case KEY_LEFT: keys[3]=ie.value; break;
++ case KEY_RIGHT: keys[4]=ie.value; break;
++ case KEY_Y:keys[5]=ie.value; break;
++ case KEY_B:keys[6]=ie.value; break;
++ case KEY_A: keys[7]=ie.value; break;
++ case KEY_X: keys[8]=ie.value; break;
++ case KEY_START: keys[12]=ie.value; break;
++ }
++ }
++ if (keys[6]) { kcode[port] &= ~Btn_A; }
++ if (keys[7]) { kcode[port] &= ~Btn_B; }
++ if (keys[5]) { kcode[port] &= ~Btn_Y; }
++ if (keys[8]) { kcode[port] &= ~Btn_X; }
++ if (keys[1]) { kcode[port] &= ~DPad_Up; }
++ if (keys[2]) { kcode[port] &= ~DPad_Down; }
++ if (keys[3]) { kcode[port] &= ~DPad_Left; }
++ if (keys[4]) { kcode[port] &= ~DPad_Right; }
++ if (keys[12]){ kcode[port] &= ~Btn_Start; }
++ if (keys[9]){ die("death by escape key"); }
++ if (keys[10]) rt[port]=255;
++ if (keys[11]) lt[port]=255;
++
++ return true;
++
++ #elif defined(TARGET_PANDORA)
++ static int keys[13];
++ while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) {
++ if (ie.type=EV_KEY)
++ //printf("type %i key %i state %i\n", ie.type, ie.code, ie.value);
++ switch (ie.code) {
++ case KEY_SPACE: keys[0]=ie.value; break;
++ case KEY_UP: keys[1]=ie.value; break;
++ case KEY_DOWN: keys[2]=ie.value; break;
++ case KEY_LEFT: keys[3]=ie.value; break;
++ case KEY_RIGHT: keys[4]=ie.value; break;
++ case KEY_PAGEUP:keys[5]=ie.value; break;
++ case KEY_PAGEDOWN:keys[6]=ie.value; break;
++ case KEY_END: keys[7]=ie.value; break;
++ case KEY_HOME: keys[8]=ie.value; break;
++ case KEY_MENU: keys[9]=ie.value; break;
++ case KEY_RIGHTSHIFT: keys[10]=ie.value; break;
++ case KEY_RIGHTCTRL: keys[11]=ie.value; break;
++ case KEY_LEFTALT: keys[12]=ie.value; break;
++ }
++ }
++
++ if (keys[0]) { kcode[port] &= ~Btn_C; }
++ if (keys[6]) { kcode[port] &= ~Btn_A; }
++ if (keys[7]) { kcode[port] &= ~Btn_B; }
++ if (keys[5]) { kcode[port] &= ~Btn_Y; }
++ if (keys[8]) { kcode[port] &= ~Btn_X; }
++ if (keys[1]) { kcode[port] &= ~DPad_Up; }
++ if (keys[2]) { kcode[port] &= ~DPad_Down; }
++ if (keys[3]) { kcode[port] &= ~DPad_Left; }
++ if (keys[4]) { kcode[port] &= ~DPad_Right; }
++ if (keys[12]){ kcode[port] &= ~Btn_Start; }
++ if (keys[9]){ die("death by escape key"); }
++ if (keys[10]) rt[port]=255;
++ if (keys[11]) lt[port]=255;
++
++ return true;
++ #else
++ while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) {
++ printf("type %i key %i state %i\n", ie.type, ie.code, ie.value);
++ }
++ #endif
++#endif
++return true;
++}
++
++bool HandleJoystick(u32 port)
++{
++
++ // Joystick must be connected
++ if(JoyFD<0) return false;
++
++#if HOST_OS != OS_DARWIN
++ struct js_event JE;
++ while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE))
++ if (JE.number<MAP_SIZE)
++ {
++ switch(JE.type & ~JS_EVENT_INIT)
++ {
++ case JS_EVENT_AXIS:
++ {
++ u32 mt=JMapAxis[JE.number]>>16;
++ u32 mo=JMapAxis[JE.number]&0xFFFF;
++
++ //printf("AXIS %d,%d\n",JE.number,JE.value);
++ s8 v=(s8)(JE.value/256); //-127 ... + 127 range
++
++ if (mt==0)
++ {
++ kcode[port]|=mo;
++ kcode[port]|=mo*2;
++ if (v<-64)
++ {
++ kcode[port]&=~mo;
++ }
++ else if (v>64)
++ {
++ kcode[port]&=~(mo*2);
++ }
++
++ // printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
++ }
++ else if (mt==1)
++ {
++ if (v>=0) v++; //up to 255
++
++ // printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
++
++ if (mo==0)
++ lt[port]=v+127;
++ else if (mo==1)
++ rt[port]=v+127;
++ }
++ else if (mt==2)
++ {
++ // printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
++ if (mo==0)
++ joyx[port]=v;
++ else if (mo==1)
++ joyy[port]=v;
++ }
++ }
++ break;
++
++ case JS_EVENT_BUTTON:
++ {
++ u32 mt=JMapBtn[JE.number]>>16;
++ u32 mo=JMapBtn[JE.number]&0xFFFF;
++
++ // printf("BUTTON %d,%d\n",JE.number,JE.value);
++
++ if (mt==0)
++ {
++ // printf("Mapped to %d\n",mo);
++ if (JE.value)
++ kcode[port]&=~mo;
++ else
++ kcode[port]|=mo;
++ }
++ else if (mt==1)
++ {
++ // printf("Mapped to %d %d\n",mo,JE.value?255:0);
++ if (mo==0)
++ lt[port]=JE.value?255:0;
++ else if (mo==1)
++ rt[port]=JE.value?255:0;
++ }
++
++ }
++ break;
++ }
++ }
++#endif
++ return true;
++
++}
++
++extern bool KillTex;
++
++#ifdef TARGET_PANDORA
++static Cursor CreateNullCursor(Display *display, Window root)
++{
++ Pixmap cursormask;
++ XGCValues xgc;
++ GC gc;
++ XColor dummycolour;
++ Cursor cursor;
++
++ cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
++ xgc.function = GXclear;
++ gc = XCreateGC(display, cursormask, GCFunction, &xgc);
++ XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
++ dummycolour.pixel = 0;
++ dummycolour.red = 0;
++ dummycolour.flags = 04;
++ cursor = XCreatePixmapCursor(display, cursormask, cursormask,
++ &dummycolour,&dummycolour, 0,0);
++ XFreePixmap(display,cursormask);
++ XFreeGC(display,gc);
++ return cursor;
++}
++#endif
++
++int x11_dc_buttons = 0xFFFF;
++
++void UpdateInputState(u32 port)
++{
++ static char key = 0;
++
++ if (cfgLoadInt("config","usejoypad",0)==1)
++ {
++ HandleJoystick(port);
++ return;
++ }
++ else
++ {
++ kcode[port]= x11_dc_buttons;
++ joyx[0] = temp_joyx;
++ joyy[0] = temp_joyy;
++ lt[0] = temp_lt;
++ rt[0] = temp_rt;
++ return;
++ }
++
++#if defined(TARGET_GCW0) || defined(TARGET_PANDORA)
++ HandleJoystick(port);
++ HandleKb(port);
++return;
++#endif
++ for(;;)
++ {
++ key = 0;
++ read(STDIN_FILENO, &key, 1);
++
++ if (0 == key || EOF == key) break;
++ if ('k' == key) KillTex=true;
++
++#ifdef TARGET_PANDORA
++ if (' ' == key) { kcode[port] &= ~Btn_C; }
++ if ('6' == key) { kcode[port] &= ~Btn_A; }
++ if ('O' == key) { kcode[port] &= ~Btn_B; }
++ if ('5' == key) { kcode[port] &= ~Btn_Y; }
++ if ('H' == key) { kcode[port] &= ~Btn_X; }
++ if ('A' == key) { kcode[port] &= ~DPad_Up; }
++ if ('B' == key) { kcode[port] &= ~DPad_Down; }
++ if ('D' == key) { kcode[port] &= ~DPad_Left; }
++ if ('C' == key) { kcode[port] &= ~DPad_Right; }
++#else
++ if ('b' == key) { kcode[port] &= ~Btn_C; }
++ if ('v' == key) { kcode[port] &= ~Btn_A; }
++ if ('c' == key) { kcode[port] &= ~Btn_B; }
++ if ('x' == key) { kcode[port] &= ~Btn_Y; }
++ if ('z' == key) { kcode[port] &= ~Btn_X; }
++ if ('i' == key) { kcode[port] &= ~DPad_Up; }
++ if ('k' == key) { kcode[port] &= ~DPad_Down; }
++ if ('j' == key) { kcode[port] &= ~DPad_Left; }
++ if ('l' == key) { kcode[port] &= ~DPad_Right; }
++#endif
++ if (0x0A== key) { kcode[port] &= ~Btn_Start; }
++#ifdef TARGET_PANDORA
++ if ('q' == key){ die("death by escape key"); }
++#endif
++ //if (0x1b == key){ die("death by escape key"); } //this actually quits when i press left for some reason
++
++ if ('a' == key) rt[port]=255;
++ if ('s' == key) lt[port]=255;
++#if !defined(HOST_NO_REC)
++ if ('b' == key) emit_WriteCodeCache();
++ if ('n' == key) bm_Reset();
++ if ('m' == key) bm_Sort();
++ if (',' == key) { emit_WriteCodeCache(); bm_Sort(); }
++#endif
++ }
++}
++
++void os_DoEvents()
++{
++ #if defined(SUPPORT_X11)
++
++ static bool ana_up = false;
++ static bool ana_down = false;
++ static bool ana_left = false;
++ static bool ana_right = false;
++
++ if (x11_win) {
++ //Handle X11
++ XEvent e;
++ if(XCheckWindowEvent((Display*)x11_disp, (Window)x11_win, KeyPressMask | KeyReleaseMask, &e))
++ {
++ switch(e.type)
++ {
++
++ case KeyPress:
++ case KeyRelease:
++ {
++
++ //Detect up press
++ if(e.xkey.keycode == XANA_UP)
++ {
++ if(e.type == KeyPress)
++ {
++ ana_up = true;
++ }
++ else if(e.type == KeyRelease)
++ {
++ ana_up = false;
++ }
++ else
++ {
++ }
++ }
++
++ //Detect down Press
++ if(e.xkey.keycode == XANA_DOWN)
++ {
++ if(e.type == KeyPress)
++ {
++ ana_down = true;
++ }
++ else if(e.type == KeyRelease)
++ {
++ ana_down = false;
++ }
++ else
++ {
++ }
++ }
++
++ //Detect left press
++ if(e.xkey.keycode == XANA_LEFT)
++ {
++ if(e.type == KeyPress)
++ {
++ ana_left = true;
++ }
++ else if(e.type == KeyRelease)
++ {
++ ana_left = false;
++ }
++ else
++ {
++ }
++ }
++
++ //Detect right Press
++ if(e.xkey.keycode == XANA_RIGHT)
++ {
++ if(e.type == KeyPress)
++ {
++ ana_right = true;
++ }
++ else if(e.type == KeyRelease)
++ {
++ ana_right = false;
++ }
++ else
++ {
++ }
++ }
++
++ //detect LT press
++ if (e.xkey.keycode == XANA_LT)
++ {
++ if (e.type == KeyPress)
++ {
++ temp_lt = 255;
++ }
++ else if (e.type == KeyRelease)
++ {
++ temp_lt = 0;
++ }
++ else
++ {
++ }
++ }
++
++ //detect RT press
++ if (e.xkey.keycode == XANA_RT)
++ {
++ if (e.type == KeyPress)
++ {
++ temp_rt = 255;
++ }
++ else if (e.type == KeyRelease)
++ {
++ temp_rt = 0;
++ }
++ else
++ {
++ }
++ }
++
++ int dc_key = x11_keymap[e.xkey.keycode];
++
++ if (e.type == KeyPress)
++ x11_dc_buttons &= ~dc_key;
++ else
++ x11_dc_buttons |= dc_key;
++
++ //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons );
++ }
++ break;
++
++ default:
++ {
++ printf("KEYRELEASE\n");
++ }
++ break;
++
++ }
++ }
++
++ /* Check analogue control states (up/down) */
++ if((ana_up == true) && (ana_down == false))
++ {
++ temp_joyy = -127;
++ }
++ else if((ana_up == false) && (ana_down == true))
++ {
++ temp_joyy = 127;
++ }
++ else
++ {
++ /* Either both pressed simultaniously or neither pressed */
++ temp_joyy = 0;
++ }
++
++ /* Check analogue control states (left/right) */
++ if((ana_left == true) && (ana_right == false))
++ {
++ temp_joyx = -127;
++ }
++ else if((ana_left == false) && (ana_right == true))
++ {
++ temp_joyx = 127;
++ }
++ else
++ {
++ /* Either both pressed simultaniously or neither pressed */
++ temp_joyx = 0;
++ }
++ }
++ #endif
++}
++
++void os_SetWindowText(const char * text)
++{
++ if (0==x11_win || 0==x11_disp || 1)
++ printf("%s\n",text);
++#if defined(SUPPORT_X11)
++ else if (x11_win) {
++ XChangeProperty((Display*)x11_disp, (Window)x11_win,
++ XInternAtom((Display*)x11_disp, "WM_NAME", False), //WM_NAME,
++ XInternAtom((Display*)x11_disp, "UTF8_STRING", False), //UTF8_STRING,
++ 8, PropModeReplace, (const unsigned char *)text, strlen(text));
++ }
++#endif
++}
++
++
++void* x11_glc;
++
++int ndcid=0;
++void os_CreateWindow()
++{
++#if defined(SUPPORT_X11)
++
++ Bool ar_set, ar_supp = false;
++
++ if (cfgLoadInt("pvr","nox11",0)==0)
++ {
++ XInitThreads();
++ // X11 variables
++ Window x11Window = 0;
++ Display* x11Display = 0;
++ long x11Screen = 0;
++ XVisualInfo* x11Visual = 0;
++ Colormap x11Colormap = 0;
++
++ /*
++ Step 0 - Create a NativeWindowType that we can use it for OpenGL ES output
++ */
++ Window sRootWindow;
++ XSetWindowAttributes sWA;
++ unsigned int ui32Mask;
++ int i32Depth;
++
++ // Initializes the display and screen
++ x11Display = XOpenDisplay( 0 );
++ if (!x11Display && !(x11Display = XOpenDisplay( ":0" )))
++ {
++ printf("Error: Unable to open X display\n");
++ return;
++ }
++ x11Screen = XDefaultScreen( x11Display );
++
++ // Gets the window parameters
++ sRootWindow = RootWindow(x11Display, x11Screen);
++
++ int depth = CopyFromParent;
++
++ #if !defined(GLES)
++ // Get a matching FB config
++ static int visual_attribs[] =
++ {
++ GLX_X_RENDERABLE , True,
++ GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
++ GLX_RENDER_TYPE , GLX_RGBA_BIT,
++ GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
++ GLX_RED_SIZE , 8,
++ GLX_GREEN_SIZE , 8,
++ GLX_BLUE_SIZE , 8,
++ GLX_ALPHA_SIZE , 8,
++ GLX_DEPTH_SIZE , 24,
++ GLX_STENCIL_SIZE , 8,
++ GLX_DOUBLEBUFFER , True,
++ //GLX_SAMPLE_BUFFERS , 1,
++ //GLX_SAMPLES , 4,
++ None
++ };
++
++ int glx_major, glx_minor;
++
++ // FBConfigs were added in GLX version 1.3.
++ if ( !glXQueryVersion( x11Display, &glx_major, &glx_minor ) ||
++ ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
++ {
++ printf("Invalid GLX version");
++ exit(1);
++ }
++
++ int fbcount;
++ GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount);
++ if (!fbc)
++ {
++ printf( "Failed to retrieve a framebuffer config\n" );
++ exit(1);
++ }
++ printf( "Found %d matching FB configs.\n", fbcount );
++
++ GLXFBConfig bestFbc = fbc[ 0 ];
++ XFree( fbc );
++
++ // Get a visual
++ XVisualInfo *vi = glXGetVisualFromFBConfig( x11Display, bestFbc );
++ printf( "Chosen visual ID = 0x%x\n", vi->visualid );
++
++
++ depth = vi->depth;
++ x11Visual = vi;
++
++ x11Colormap = XCreateColormap(x11Display, RootWindow(x11Display, x11Screen), vi->visual, AllocNone);
++ #else
++ i32Depth = DefaultDepth(x11Display, x11Screen);
++ x11Visual = new XVisualInfo;
++ XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, x11Visual);
++ if (!x11Visual)
++ {
++ printf("Error: Unable to acquire visual\n");
++ return;
++ }
++ x11Colormap = XCreateColormap( x11Display, sRootWindow, x11Visual->visual, AllocNone );
++ #endif
++
++ sWA.colormap = x11Colormap;
++
++ // Add to these for handling other events
++ sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
++ ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
++
++ #ifdef TARGET_PANDORA
++ int width=800;
++ int height=480;
++ #else
++ int width=cfgLoadInt("x11","width", WINDOW_WIDTH);
++ int height=cfgLoadInt("x11","height", WINDOW_HEIGHT);
++ #endif
++
++ //if (width==-1)
++ if (cfgLoadInt("x11","fullscreen",0)==1)
++ {
++ width=XDisplayWidth(x11Display,x11Screen);
++ height=XDisplayHeight(x11Display,x11Screen);
++ }
++
++ // Creates the X11 window
++ x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height,
++ 0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA);
++ #ifdef TARGET_PANDORA
++ // fullscreen
++ Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
++ Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False);
++ XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1);
++
++ XMapRaised(x11Display, x11Window);
++ #else
++
++ if (cfgLoadInt("x11","fullscreen",0)==1)
++ {
++ // fullscreen
++ Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
++ Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False);
++ XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1);
++ }
++
++ XMapWindow(x11Display, x11Window);
++
++ //This 1 second delay is important. Without it the GLX code can execute before the window
++ //resize completes causing a black border at the top of the screen....
++ sleep(1);
++
++ #if !defined(GLES)
++
++ #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
++ #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
++ typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
++
++ glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
++ glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
++ glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
++
++ verify( glXCreateContextAttribsARB != 0 );
++
++ int context_attribs[] = {
++ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
++ GLX_CONTEXT_MINOR_VERSION_ARB, 1,
++ GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
++ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
++ None
++ };
++
++ x11_glc = glXCreateContextAttribsARB( x11Display, bestFbc, 0, True, context_attribs);
++ XSync( x11Display, False );
++
++ if (!x11_glc) {
++ die("Failed to create GL3.1 context\n");
++ }
++ #endif
++ #endif
++ XFlush(x11Display);
++
++
++
++ //(EGLNativeDisplayType)x11Display;
++ x11_disp=(void*)x11Display;
++ x11_win=(void*)x11Window;
++
++ ar_set = XkbSetDetectableAutoRepeat(x11Display, True, &ar_supp);
++ printf("XkbSetDetectableAutoRepeat returns %u, supported = %u\n",ar_set, ar_supp);
++
++
++ }
++ else
++ printf("Not creating X11 window ..\n");
++#endif
++}
++
++termios tios, orig_tios;
++
++int setup_curses()
++{
++ //initscr();
++ //cbreak();
++ //noecho();
++
++
++ /* Get current terminal settings */
++ if (tcgetattr(STDIN_FILENO, &orig_tios)) {
++ printf("Error getting current terminal settings\n");
++ return -1;
++ }
++
++ memcpy(&tios, &orig_tios, sizeof(struct termios));
++ tios.c_lflag &= ~ICANON; //(ECHO|ICANON);&= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
++
++ tios.c_cc[VTIME] = 0;
++ tios.c_cc[VMIN] = 0;
++
++ if (tcsetattr(STDIN_FILENO, TCSANOW, &tios)) {
++ printf("Error applying terminal settings\n");
++ return -2;
++ }
++
++ if (tcgetattr(STDIN_FILENO, &tios)) {
++ tcsetattr(0, TCSANOW, &orig_tios);
++ printf("Error while asserting terminal settings\n");
++ return -3;
++ }
++
++ if ((tios.c_lflag & ICANON) || !(tios.c_lflag & ECHO)) {
++ tcsetattr(STDIN_FILENO, TCSANOW, &orig_tios);
++ printf("Could not apply all terminal settings\n");
++ return -4;
++ }
++
++ fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
++ return 1;
++}
++
++void common_linux_setup();
++int dc_init(int argc,wchar* argv[]);
++void dc_run();
++
++#ifdef TARGET_PANDORA
++void gl_term();
++
++void clean_exit(int sig_num) {
++ void *array[10];
++ size_t size;
++
++ // close files
++ if (JoyFD>=0) close(JoyFD);
++ if (kbfd>=0) close(kbfd);
++ if(audio_fd>=0) close(audio_fd);
++
++ // Close EGL context ???
++ if (sig_num!=0)
++ gl_term();
++
++ // close XWindow
++ if (x11_win) {
++ XDestroyWindow(x11_disp, x11_win);
++ x11_win = 0;
++ }
++ if (x11_disp) {
++ XCloseDisplay(x11_disp);
++ x11_disp = 0;
++ }
++
++ // finish cleaning
++ if (sig_num!=0) {
++ write(2, "\nSignal received\n", sizeof("\nSignal received\n"));
++
++ size = backtrace(array, 10);
++ backtrace_symbols_fd(array, size, STDERR_FILENO);
++ exit(1);
++ }
++}
++
++void init_sound()
++{
++ if((audio_fd=open("/dev/dsp",O_WRONLY))<0) {
++ printf("Couldn't open /dev/dsp.\n");
++ }
++ else
++ {
++ printf("sound enabled, dsp openned for write\n");
++ int tmp=44100;
++ int err_ret;
++ err_ret=ioctl(audio_fd,SNDCTL_DSP_SPEED,&tmp);
++ printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp);
++ int channels=2;
++ err_ret=ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels);
++ printf("set dsp to stereo (%i => %i)\n", channels, err_ret);
++ int format=AFMT_S16_LE;
++ err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
++ printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed" ,AFMT_S16_LE, format, err_ret);
++ }
++}
++#endif
++
++int main(int argc, wchar* argv[])
++{
++ //if (argc==2)
++ //ndcid=atoi(argv[1]);
++
++ if (setup_curses() < 0) die("failed to setup curses!\n");
++#ifdef TARGET_PANDORA
++ signal(SIGSEGV, clean_exit);
++ signal(SIGKILL, clean_exit);
++
++ init_sound();
++#else
++ void os_InitAudio();
++ os_InitAudio();
++#endif
++
++#if defined(USES_HOMEDIR) && HOST_OS != OS_DARWIN
++ string home = (string)getenv("HOME");
++ if(home.c_str())
++ {
++ home += "/.reicast";
++ mkdir(home.c_str(), 0755); // create the directory if missing
++ SetHomeDir(home);
++ }
++ else
++ SetHomeDir(".");
++#else
++ SetHomeDir(".");
++#endif
++
++ #if defined(SUPPORT_X11)
++ x11_keymap[XDPAD_LEFT] = DPad_Left;
++ x11_keymap[XDPAD_RIGHT] = DPad_Right;
++
++ x11_keymap[XDPAD_UP] = DPad_Up;
++ x11_keymap[XDPAD_DOWN] = DPad_Down;
++
++ x11_keymap[XBTN_Y] = Btn_Y;
++ x11_keymap[XBTN_X] = Btn_X;
++ x11_keymap[XBTN_B] = Btn_B;
++ x11_keymap[XBTN_A] = Btn_A;
++
++ /*
++ //TODO: Fix sliders
++ x11_keymap[38] = DPad_Down;
++ x11_keymap[39] = DPad_Down;
++ */
++
++ x11_keymap[XBTN_START] = Btn_Start;
++ #endif
++
++ printf("Home dir is: %s\n",GetPath("/").c_str());
++
++ common_linux_setup();
++
++ SetupInput();
++
++ settings.profile.run_counts=0;
++
++ dc_init(argc,argv);
++
++ dc_run();
++
++#ifdef TARGET_PANDORA
++ clean_exit(0);
++#endif
++
++ return 0;
++}
++
++u32 alsa_Push(void* frame, u32 samples, bool wait);
++u32 os_Push(void* frame, u32 samples, bool wait)
++{
++ #ifndef TARGET_PANDORA
++ int audio_fd = -1;
++ #endif
++
++ if (audio_fd > 0) {
++ write(audio_fd, frame, samples*4);
++ } else {
++ return alsa_Push(frame, samples, wait);
++ }
++
++ return 1;
++}
++#endif
++
++int get_mic_data(u8* buffer) { return 0; }
++int push_vmu_screen(u8* buffer) { return 0; }
++
++
++void os_DebugBreak()
++{
++ raise(SIGTRAP);
++}
|