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 -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include "hw/sh4/dyna/blockmanager.h" -#include - - - - -#if defined(SUPPORT_X11) - #include - #include - #include - - #if !defined(GLES) - #include - #include - #endif - - #include - map x11_keymap; -#endif - -#if !defined(ANDROID) && HOST_OS != OS_DARWIN - #include - #include - #include -#endif - -#ifdef TARGET_PANDORA -#include -#include -#include - -#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>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 +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include "hw/sh4/dyna/blockmanager.h" +#include + + + + +#if defined(SUPPORT_X11) + #include + #include + #include + #include + + #if !defined(GLES) + #include + #include + #endif + + #include + map x11_keymap; +#endif + +#if !defined(ANDROID) && HOST_OS != OS_DARWIN + #include + #include + #include +#endif + +#ifdef TARGET_PANDORA +#include +#include +#include + +#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>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); +}