move 1
authornotaz <notasas@gmail.com>
Sat, 7 Apr 2007 22:47:59 +0000 (22:47 +0000)
committernotaz <notasas@gmail.com>
Sat, 7 Apr 2007 22:47:59 +0000 (22:47 +0000)
git-svn-id: file:///home/notaz/opt/svn/fceu@96 be3aeb3a-fb24-0410-a615-afba39da0efa

20 files changed:
drivers/gp2x/dface.h [new file with mode: 0644]
drivers/gp2x/input.c [new file with mode: 0644]
drivers/gp2x/lnx-joystick.c [new file with mode: 0644]
drivers/gp2x/lnx-joystick.h [new file with mode: 0644]
drivers/gp2x/main.c [new file with mode: 0644]
drivers/gp2x/main.h [new file with mode: 0644]
drivers/gp2x/minimal.c [new file with mode: 0644]
drivers/gp2x/minimal.h [new file with mode: 0644]
drivers/gp2x/minimal_940t.h [new file with mode: 0644]
drivers/gp2x/sdl-sound.c [new file with mode: 0644]
drivers/gp2x/sdl-video.c [new file with mode: 0644]
drivers/gp2x/sdl-video.h [new file with mode: 0644]
drivers/gp2x/sdl.c [new file with mode: 0644]
drivers/gp2x/sdl.h [new file with mode: 0644]
drivers/gp2x/throttle.c [new file with mode: 0644]
drivers/gp2x/throttle.h [new file with mode: 0644]
drivers/gp2x/unix-basedir.h [new file with mode: 0644]
drivers/gp2x/unix-netplay.c [new file with mode: 0644]
drivers/gp2x/unix-netplay.h [new file with mode: 0644]
drivers/gp2x/usage.h [new file with mode: 0644]

diff --git a/drivers/gp2x/dface.h b/drivers/gp2x/dface.h
new file mode 100644 (file)
index 0000000..92df082
--- /dev/null
@@ -0,0 +1,32 @@
+extern CFGSTRUCT DriverConfig[];
+extern ARGPSTRUCT DriverArgs[];
+extern char *DriverUsage;
+
+void DoDriverArgs(void);
+void GetBaseDirectory(char *BaseDirectory);
+
+int InitSound(void);
+void WriteSound(int32 *Buffer, int Count, int NoWaiting);
+void KillSound(void);
+void SilenceSound(int s); /* DOS and SDL */
+
+
+int InitMouse(void);
+void KillMouse(void);
+void GetMouseData(uint32 *MouseData);
+
+int InitJoysticks(void);
+void KillJoysticks(void);
+uint32 *GetJSOr(void);
+
+int InitKeyboard(void);
+int UpdateKeyboard(void);
+char *GetKeyboard(void);
+void KillKeyboard(void);
+
+int InitVideo(void);
+void KillVideo(void);
+void BlitScreen(uint8 *XBuf);
+void LockConsole(void);
+void UnlockConsole(void);
+void ToggleFS();               /* SDL */
diff --git a/drivers/gp2x/input.c b/drivers/gp2x/input.c
new file mode 100644 (file)
index 0000000..8936ec0
--- /dev/null
@@ -0,0 +1,438 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Ben Parnell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define JOY_A   1
+#define JOY_B   2
+#define JOY_SELECT      4
+#define JOY_START       8
+#define JOY_UP  0x10
+#define JOY_DOWN        0x20
+#define JOY_LEFT        0x40
+#define JOY_RIGHT       0x80
+
+
+#include "minimal.h"
+extern int swapbuttons;
+extern int stretch_offset;
+extern int FSkip_setting;
+
+extern void SetVideoScaling(int pixels,int width,int height);
+INLINE long UpdateGamepadGP2X(void);
+
+
+
+/* UsrInputType[] is user-specified.  InputType[] is current
+       (game loading can override user settings)
+*/
+static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
+static int InputType[2];
+
+static int UsrInputTypeFC={SI_NONE};
+static int InputTypeFC;
+
+static uint32 JSreturn;
+int NoWaiting=0;
+
+static int powerpadsc[2][12];
+static int powerpadside=0;
+
+
+static uint32 MouseData[3];
+static uint8 fkbkeys[0x48];
+unsigned long lastpad=0;
+
+void FCEUD_UpdateInput(void)
+{
+  int t=0;
+  long lastpad2=lastpad;
+  long pad = UpdateGamepadGP2X();
+  t=1;
+  //  JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8);
+  if(gametype==GIT_FDS)
+  {
+    NoWaiting&=~1;
+       if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH)))
+       {
+      DriverInterface(DES_FDSSELECT,0);
+       }
+       else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L)))
+       {
+      DriverInterface(DES_FDSINSERT,0);
+       }
+       else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R)))
+       {
+      DriverInterface(DES_FDSEJECT,0);
+       }
+  }
+
+}
+
+
+//#ifdef GP2X
+
+extern void ResetNES(void);
+extern void CleanSurface(void);
+
+char soundvolmeter[21];
+int soundvolIndex=0;
+int L_count=0;
+int R_count=0;
+extern int CurrentState;
+int TurboFireOff=1;
+int TurboFireTop=0;  // 0 is none  // 1 is  A & X turbo  // 2 is Y & B turbo
+int TurboFireBottom=0;
+int turbo_toggle_A=0;
+int turbo_toggle_B=0;
+
+static void setsoundvol(int soundvolume)
+{
+    //FCEUI_SetSoundVolume(soundvol);
+    // draw on screen :D
+    gp2x_sound_volume(soundvolume, soundvolume);
+    int meterval=soundvolume/5;
+    for (soundvolIndex=0; soundvolIndex < 20; soundvolIndex++)
+    {
+       if (soundvolIndex < meterval)
+       {
+                 soundvolmeter[soundvolIndex]='*';
+       }
+       else
+       {
+                 soundvolmeter[soundvolIndex]='_';
+       }
+    }
+    soundvolmeter[20]=0;
+    FCEU_DispMessage("|%s|", soundvolmeter);
+}
+/**
+ * GP2x joystick reader
+ *
+ */
+INLINE long UpdateGamepadGP2X(void)
+{
+  uint32 JS=0;
+
+  unsigned long pad=gp2x_joystick_read();
+#define down(b) (pad & GP2X_##b)
+#define last_down(b) (lastpad & GP2X_##b)
+#define L_down (pad & GP2X_L)
+#define R_down (pad & GP2X_R)
+#define last_L_down (lastpad & GP2X_L)
+#define last_R_down (lastpad & GP2X_R)
+#define shift      ((pad     & GP2X_PUSH) || ((pad     & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
+#define last_shift ((lastpad & GP2X_PUSH) || ((lastpad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
+
+  if (L_down && R_down && !(pad & GP2X_PUSH) && !(last_R_down && last_L_down))
+  {
+     ResetNES();
+     puts("Reset");
+     goto no_pad;
+  }
+
+  if (down(VOL_UP) && !down(VOL_DOWN))
+  {
+    soundvol+=1;
+    if (soundvol >= 100) soundvol=100;
+    //FCEUI_SetSoundVolume(soundvol);
+    setsoundvol(soundvol);
+  }
+  else if (down(VOL_DOWN) && !down(VOL_UP))
+  {
+    soundvol-=1;
+    if (soundvol < 0) soundvol=0;
+    //FCEUI_SetSoundVolume(soundvol);
+    setsoundvol(soundvol);
+  }
+
+  if (shift)
+  {
+    // only if it's something else then last time, and not moving around the joystick
+    if (!(pad & (GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT)))
+    {
+      if (down(SELECT))
+      {
+        if (last_down(SELECT) && last_shift)
+       {
+          // still pressed down from stretching from last one
+          goto no_pad;
+       }
+        if (stretch_offset == 32)
+       {
+          stretch_offset=0;
+       }
+        else
+       {
+          stretch_offset=32;
+       }
+
+        if (stretch_offset == 32)
+       {
+          SetVideoScaling(320, 320, 240);
+          CleanSurface();
+       }
+        else
+       {
+         SetVideoScaling(320, 256, 240);
+       }
+
+        goto no_pad;
+      }
+      else if (L_down && R_down)
+      {
+        FCEUI_CloseGame();
+        puts("Quit");
+        goto no_pad;
+      }
+      else if (R_down && !(last_R_down && last_shift))
+      {
+       FCEUI_LoadState();
+       goto no_pad;
+      }
+      else if (L_down && !(last_L_down && last_shift))
+      {
+       FCEUI_SaveState();
+       goto no_pad;
+      }
+      else if (down(A) && !(last_down(A) && last_shift))
+      {
+       FSkip_setting--;
+       if (FSkip_setting < 0) {
+        FSkip_setting = -1;
+        FCEUI_DispMessage("Auto frameskip");
+       }
+       else
+        FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
+       goto no_pad;
+      }
+      else if (down(Y) && !(last_down(Y) && last_shift))
+      {
+       FSkip_setting++;
+       if (FSkip_setting > 8) FSkip_setting = 8;
+       FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
+       goto no_pad;
+      }
+    }
+  }
+
+  // r is toggle savestate
+  if (R_down)
+  {
+       if (last_R_down)
+       {
+         R_count++;
+      if ((R_count & 31)== 31)
+      {
+               CurrentState=(CurrentState+1) % 10;
+               FCEUI_DispMessage("Now Using Save State %d", CurrentState);
+         }
+       }
+  }
+  else
+  {
+    R_count=0;
+  }
+
+  // l is toggle turbo
+  if (L_down)
+  {
+       if (last_L_down)
+       {
+         L_count++;
+      if ((L_count & 31)== 31)
+      {
+       // 0 is none  // 1 is  Y & B turbo  // 2 is X & A turbo
+        if ((!TurboFireTop) && (!TurboFireBottom))
+        {
+               // was off
+               TurboFireTop=1;
+               TurboFireBottom=0;
+               if (swapbuttons)
+               {
+                 FCEUI_DispMessage("Turbo A and Y");
+               }
+               else
+               {
+                 FCEUI_DispMessage("Turbo Y and B");
+               }
+        }
+        else if (TurboFireTop)
+        {
+               TurboFireTop=0;
+               TurboFireBottom=1;
+               if (swapbuttons)
+               {
+                         FCEUI_DispMessage("Turbo X and B");
+               }
+               else
+               {
+                         FCEUI_DispMessage("Turbo A and X");
+               }
+        }
+        else
+        {
+               TurboFireTop=0;
+               TurboFireBottom=0;
+               FCEUI_DispMessage("Turbo Off");
+        }
+
+         }
+       }
+  }
+  else
+  {
+    L_count=0;
+  }
+
+  //unsigned long padTmp=0;
+  // shift the bits in
+  // up
+  //padTmp=(pad & GP2X_UP) ;  // 1 is 2^0,
+  JS |= ((pad & GP2X_UP) << (4-0));  // 0x10 is 2^4
+
+  //padTmp=(pad & GP2X_DOWN);  // 0x10 is 2^4,
+  JS |= ((pad & GP2X_DOWN) << (5-4));  // 0x20 is 2^5
+
+  //padTmp=(pad & GP2X_LEFT);  // 0x4 is 2^2,
+  JS |= ((pad & GP2X_LEFT) << (6-2));  // 0x40 is 2^6
+
+  //padTmp=(pad & GP2X_RIGHT);  // 0x40 is 2^6,
+  JS |= ((pad & GP2X_RIGHT) << (7-6));  // 0x80 is 2^7
+
+
+#define  A_down (pad & GP2X_A)
+#define  B_down (pad & GP2X_B)
+#define  X_down (pad & GP2X_X)
+#define  Y_down (pad & GP2X_Y)
+
+  // should be 2 cycles held, 1 cycle release
+  turbo_toggle_A=(turbo_toggle_A+1) % 3;
+  turbo_toggle_B=(turbo_toggle_B+1) % 3;
+
+   // 0 is none  // 1 is  Y & B turbo  // 2 is X & A turbo
+  // B or X are both considered A
+  //padTmp=B_down >> 13;  // 2^13,
+
+   if (!(TurboFireTop && (!turbo_toggle_A)))
+   {
+    JS |= ((B_down >> 13) << 0);  // 0x1 is 2^0
+   }
+   // A or Y are both considered B
+   //padTmp=A_down >> 12;  // 2^13,
+   if (!(TurboFireBottom && (!turbo_toggle_B)))
+   {
+    JS |= ((A_down >> 12) << 1);  // 0x2 is 2^1
+   }
+
+  if (swapbuttons)
+  {
+   //padTmp=X_down >> 14;  // 2^13,
+   if (!(TurboFireBottom && (!turbo_toggle_A)))
+   {
+//    JS |= ((X_down >> 14) << 0);  // 0x1 is 2^0
+    JS |= ((Y_down >> 15) << 0);  // 0x1 is 2^0
+   }
+
+   //padTmp=Y_down >> 15;  // 2^13,
+   if (!(TurboFireTop && (!turbo_toggle_B)))
+   {
+    JS |= ((X_down >> 14) << 1);  // 0x2 is 2^1
+   }
+  }
+  else
+  {
+   //padTmp=X_down >> 14;  // 2^13,
+   if (!(TurboFireBottom && (!turbo_toggle_A)))
+   {
+    JS |= ((X_down >> 14) << 0);  // 0x1 is 2^0
+   }
+
+   //padTmp=Y_down >> 15;  // 2^13,
+   if (!(TurboFireTop && (!turbo_toggle_B)))
+   {
+    JS |= ((Y_down >> 15) << 1);  // 0x2 is 2^1
+   }
+  }
+
+  // select
+  //padTmp=(pad & GP2X_SELECT) >> 9;  // 0x40 is 2^9,
+  JS |= (((pad & GP2X_SELECT) >> 9) << 2);  // 0x4 is 2^2
+
+  // start
+  //padTmp=(pad & GP2X_START) >> 8;  //   2^8,
+  JS |= (((pad & GP2X_START) >> 8) << 3);  // 0x8 is 2^3
+
+
+  JSreturn = JS;
+  lastpad=pad;
+
+  return pad;
+  //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
+no_pad:
+  JSreturn=0;
+  lastpad=pad;
+  return 0;
+}
+//#endif
+
+
+static void InitOtherInput(void)
+{
+
+   void *InputDPtr;
+
+   int t;
+   int x;
+   int attrib;
+
+   for(t=0,x=0;x<2;x++)
+   {
+    attrib=0;
+    InputDPtr=0;
+    switch(InputType[x])
+    {
+      //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
+     case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
+     case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
+     case SI_ZAPPER:InputDPtr=MouseData;
+                                t|=1;
+                                attrib=1;
+                                break;
+    }
+    FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
+   }
+
+   attrib=0;
+   InputDPtr=0;
+   switch(InputTypeFC)
+   {
+    case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
+    case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
+    case SIFC_FKB:InputDPtr=fkbkeys;break;
+   }
+
+   FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
+   FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
+
+   if(t && !(inited&16))
+   {
+    InitMouse();
+    inited|=16;
+   }
+}
diff --git a/drivers/gp2x/lnx-joystick.c b/drivers/gp2x/lnx-joystick.c
new file mode 100644 (file)
index 0000000..4c2ae6a
--- /dev/null
@@ -0,0 +1,201 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Ben Parnell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <linux/joystick.h>
+#include "main.h"
+#include "lnx-joystick.h"
+
+int joy[4]={0,0,0,0};
+int joyBMap[4][4];
+
+static int32 joybuttons[4]={0,0,0,0};
+static int32 joyx[4]={0,0,0,0};
+static int32 joyy[4]={0,0,0,0};
+
+static void ConfigJoystick(int z);
+static int fd[4];
+
+#define JOY_A   1
+#define JOY_B   2
+#define JOY_SELECT      4
+#define JOY_START       8
+#define JOY_UP  0x10
+#define JOY_DOWN        0x20
+#define JOY_LEFT        0x40
+#define JOY_RIGHT       0x80
+
+static void UpdateJoyData(int x)
+{
+       struct js_event e;
+
+       while(read(fd[x],&e,sizeof(struct js_event))==sizeof(struct js_event))
+       {
+        e.type&=~JS_EVENT_INIT;
+         if(e.type==JS_EVENT_BUTTON) 
+        {
+          if(e.value)
+           joybuttons[x]|=(1<<e.number);
+          else
+           joybuttons[x]&=~(1<<e.number);
+         }
+        else if(e.type==JS_EVENT_AXIS)
+        {
+         if(e.number==0)
+          joyx[x]=e.value;
+         else if(e.number==1)
+          joyy[x]=e.value;
+        }
+       }
+}
+
+uint32 GetJSOr(void)
+{
+       int x,y;
+       unsigned long ret;
+       ret=0;
+
+       for(x=0;x<4;x++)
+       {
+        int *joym=joyBMap[x];
+
+        if(!joy[x]) continue;
+        UpdateJoyData(x);
+        for(y=0;y<4;y++)
+         if(joybuttons[x]&joym[y]) ret|=(1<<y)<<(x<<3);
+        if(joyx[x]<=-16383) ret|=JOY_LEFT<<(x<<3);
+        else if(joyx[x]>=16383) ret|=JOY_RIGHT<<(x<<3);
+        if(joyy[x]<=-16383) ret|=JOY_UP<<(x<<3);
+        else if(joyy[x]>=16383) ret|=JOY_DOWN<<(x<<3);
+        }
+       return ret;
+}
+
+void KillJoysticks(void)
+{
+       int x;
+       for(x=0;x<4;x++)
+        if(joy[x]) 
+         close(fd[x]);
+}
+
+int InitJoysticks(void)
+{
+       char dbuf[64];
+       int version;
+       int z;
+
+       for(z=0;z<4;z++)
+       {
+        if(!joy[z]) continue;
+        sprintf(dbuf,"/dev/js%d",joy[z]-1);
+        if((fd[z]=open(dbuf,O_RDONLY|O_NONBLOCK))<0) 
+        {
+          printf("Could not open %s.\n",dbuf);
+          joy[z]=0;
+          continue;
+         }
+
+         if(ioctl(fd[z], JSIOCGVERSION, &version)==-1) 
+        {
+         printf("Error using ioctl JSIOCGVERSION on %s.\n",dbuf);
+         joy[z]=0;
+         close(fd[z]);
+         continue;
+        }
+
+         if(!(joyBMap[z][0]|joyBMap[z][1]|joyBMap[z][2]|joyBMap[z][3]))
+          ConfigJoystick(z);
+        }
+
+       return(joy[0]|joy[1]|joy[2]|joy[3]);
+}
+
+#define WNOINPUT(); for(;;){uint8 t; if(read(fileno(stdin),&t,1)==-1) \
+                          {break;}}
+
+static void BConfig(int z,int b)
+{
+  WNOINPUT();
+  for(;;)
+  {
+   uint8 t;
+   if(read(fileno(stdin),&t,1)==-1)
+   {
+    if(errno!=EAGAIN) break;
+   }
+   else
+    break;
+
+   {
+    struct js_event e;
+
+    while(read(fd[z],&e,sizeof(struct js_event))==sizeof(struct js_event))
+    {
+      if(e.type==JS_EVENT_BUTTON)
+      {
+       if(!e.value)
+       {
+       joyBMap[z][b]=1<<e.number;
+       goto endsa;
+       }
+      }
+    }
+   }
+
+  }
+  endsa:
+  WNOINPUT();
+}
+
+void ConfigJoystick(int z)
+{
+ int sa;
+ static char *genb="** Press button for ";
+
+ printf("\n\n Joystick button configuration:\n\n");
+ printf("   Push the button to map to the virtual joystick.\n");
+ printf("   If you do not wish to assign a button, press Enter to skip\n");
+ printf("   that button.\n\n");
+ printf("   Press enter to continue...\n");
+ getchar();
+ printf("****  Configuring joystick %d ****\n\n",z+1);
+
+ sa=fcntl(fileno(stdin),F_GETFL);
+ fcntl(fileno(stdin),F_SETFL,O_NONBLOCK);
+
+  printf("%s\"Select\".\n",genb);
+  BConfig(z,2);
+
+  printf("%s\"Start\".\n",genb);
+  BConfig(z,3);
+
+  printf("%s\"B\".\n",genb);
+  BConfig(z,1);
+
+  printf("%s\"A\".\n",genb);
+  BConfig(z,0);
+
+  fcntl(fileno(stdin),F_SETFL,sa);
+}
+
diff --git a/drivers/gp2x/lnx-joystick.h b/drivers/gp2x/lnx-joystick.h
new file mode 100644 (file)
index 0000000..a38ae77
--- /dev/null
@@ -0,0 +1,3 @@
+extern int joy[4];
+extern int joyBMap[4][4];
+
diff --git a/drivers/gp2x/main.c b/drivers/gp2x/main.c
new file mode 100644 (file)
index 0000000..d2be777
--- /dev/null
@@ -0,0 +1,385 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Ben Parnell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*  This file contains or coordinates all of the code necessary to compile
+    on a UNIX system that can use svgalib, such as FreeBSD and Linux.
+    This code is not guaranteed to compile on FreeBSD, though.
+*/
+
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "main.h"
+#include "throttle.h"
+
+#include "../common/config.h"
+#include "../common/args.h"
+#include "../common/unixdsp.h"
+#include "../common/cheat.h"
+
+#include "dface.h"
+
+static int ntsccol=0,ntschue=-1,ntsctint=-1;
+int soundvol=70;
+int inited=0;
+int swapbuttons=0;
+int showfps=0;
+
+int srendlinev[2]={0,0};
+//int srendlinev[2]={0,0};
+int erendlinev[2]={239,239};
+//int erendlinev[2]={231,239};
+int srendline,erendline;
+
+
+static char BaseDirectory[2048];
+
+int eoptions=0;
+
+static void DriverKill(void);
+static int DriverInitialize(void);
+
+static int gametype;
+#include "input.c"
+
+static void ParseGI(FCEUGI *gi)
+{
+ gametype=gi->type;
+
+ InputType[0]=UsrInputType[0];
+ InputType[1]=UsrInputType[1];
+ InputTypeFC=UsrInputTypeFC;
+
+ if(gi->input[0]>=0)
+  InputType[0]=gi->input[0];
+ if(gi->input[1]>=0)
+  InputType[1]=gi->input[1];
+ if(gi->inputfc>=0)
+  InputTypeFC=gi->inputfc;
+ FCEUI_GetCurrentVidSystem(&srendline,&erendline);
+}
+
+void FCEUD_PrintError(char *s)
+{
+ puts(s);
+}
+
+static char *cpalette=0;
+static void LoadCPalette(void)
+{
+ char tmpp[192];
+ FILE *fp;
+
+ if(!(fp=fopen(cpalette,"rb")))
+ {
+  printf(" Error loading custom palette from file: %s\n",cpalette);
+  return;
+ }
+ fread(tmpp,1,192,fp);
+ FCEUI_SetPaletteArray((uint8 *)tmpp);
+ fclose(fp);
+}
+
+static CFGSTRUCT fceuconfig[]={
+       AC(soundvol),
+       ACS(cpalette),
+       AC(ntsctint),
+       AC(ntschue),
+       AC(ntsccol),
+       AC(UsrInputTypeFC),
+       ACA(UsrInputType),
+       AC(powerpadside),
+       AC(powerpadsc),
+       AC(eoptions),
+       ACA(srendlinev),
+       ACA(erendlinev),
+       ADDCFGSTRUCT(DriverConfig),
+       ENDCFGSTRUCT
+};
+
+static void SaveConfig(void)
+{
+       char tdir[2048];
+       sprintf(tdir,"%s"PSS"fceu.cfg",BaseDirectory);
+        DriverInterface(DES_GETNTSCTINT,&ntsctint);
+        DriverInterface(DES_GETNTSCHUE,&ntschue);
+        SaveFCEUConfig(tdir,fceuconfig);
+}
+
+static void LoadConfig(void)
+{
+       char tdir[2048];
+        sprintf(tdir,"%s"PSS"fceu.cfg",BaseDirectory);
+        LoadFCEUConfig(tdir,fceuconfig);
+        if(ntsctint>=0) DriverInterface(DES_SETNTSCTINT,&ntsctint);
+        if(ntschue>=0) DriverInterface(DES_SETNTSCHUE,&ntschue);
+}
+
+static void CreateDirs(void)
+{
+ char *subs[5]={"fcs","snaps","gameinfo","sav","cheats"};
+ char tdir[2048];
+ int x;
+
+ mkdir(BaseDirectory,S_IRWXU);
+ for(x=0;x<5;x++)
+ {
+  sprintf(tdir,"%s"PSS"%s",BaseDirectory,subs[x]);
+  mkdir(tdir,S_IRWXU);
+ }
+}
+
+static void SetSignals(void (*t)(int))
+{
+  int sigs[11]={SIGINT,SIGTERM,SIGHUP,SIGPIPE,SIGSEGV,SIGFPE,SIGKILL,SIGALRM,SIGABRT,SIGUSR1,SIGUSR2};
+  int x;
+  for(x=0;x<11;x++)
+   signal(sigs[x],t);
+}
+
+static void CloseStuff(int signum)
+{
+       DriverKill();
+        printf("\nSignal %d has been caught and dealt with...\n",signum);
+        switch(signum)
+        {
+         case SIGINT:printf("How DARE you interrupt me!\n");break;
+         case SIGTERM:printf("MUST TERMINATE ALL HUMANS\n");break;
+         case SIGHUP:printf("Reach out and hang-up on someone.\n");break;
+         case SIGPIPE:printf("The pipe has broken!  Better watch out for floods...\n");break;
+         case SIGSEGV:printf("Iyeeeeeeeee!!!  A segmentation fault has occurred.  Have a fluffy day.\n");break;
+        /* So much SIGBUS evil. */
+        #ifdef SIGBUS
+        #if(SIGBUS!=SIGSEGV)
+         case SIGBUS:printf("I told you to be nice to the driver.\n");break;
+        #endif
+        #endif
+         case SIGFPE:printf("Those darn floating points.  Ne'er know when they'll bite!\n");break;
+         case SIGALRM:printf("Don't throw your clock at the meowing cats!\n");break;
+         case SIGABRT:printf("Abort, Retry, Ignore, Fail?\n");break;
+         case SIGUSR1:
+         case SIGUSR2:printf("Killing your processes is not nice.\n");break;
+        }
+        exit(1);
+}
+
+static void DoArgs(int argc, char *argv[])
+{
+        static char *cortab[5]={"none","gamepad","zapper","powerpad","arkanoid"};
+        static int cortabi[5]={SI_NONE,SI_GAMEPAD,
+                               SI_ZAPPER,SI_POWERPAD,SI_ARKANOID};
+       static char *fccortab[5]={"none","arkanoid","shadow","4player","fkb"};
+       static int fccortabi[5]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW,
+                                SIFC_4PLAYER,SIFC_FKB};
+
+       int x;
+       static char *inputa[2]={0,0};
+       static char *fcexp=0;
+       static int docheckie[4];
+
+        static ARGPSTRUCT FCEUArgs[]={
+         {"-soundvol",0,&soundvol,0},
+         {"-cpalette",0,&cpalette,0x4001},
+
+         {"-ntsccol",0,&ntsccol,0},
+         {"-pal",&docheckie[0],0,0},
+         {"-input1",0,&inputa[0],0x4001},{"-input2",0,&inputa[1],0x4001},
+         {"-fcexp",0,&fcexp,0x4001},
+
+         {"-gg",&docheckie[1],0,0},
+         {"-no8lim",0,&eoptions,0x8001},
+         {"-subase",0,&eoptions,0x8002},
+         {"-snapname",0,&eoptions,0x8000|EO_SNAPNAME},
+        {"-nofs",0,&eoptions,0x8000|EO_NOFOURSCORE},
+         {"-clipsides",0,&eoptions,0x8000|EO_CLIPSIDES},
+        {"-nothrottle",0,&eoptions,0x8000|EO_NOTHROTTLE},
+         {"-slstart",0,&srendlinev[0],0},{"-slend",0,&erendlinev[0],0},
+         {"-slstartp",0,&srendlinev[1],0},{"-slendp",0,&erendlinev[1],0},
+            {"-swapbuttons",&swapbuttons, 0, 0},
+            {"-showfps",&showfps, 0, 0},
+        {0,(void *)DriverArgs,0,0},
+        {0,0,0,0}
+        };
+
+        memset(docheckie,0,sizeof(docheckie));
+       ParseArguments(argc, argv, FCEUArgs);
+       if(cpalette)
+       {
+        if(cpalette[0]=='0')
+         if(cpalette[1]==0)
+         {
+          free(cpalette);
+          cpalette=0;
+         }
+       }
+       if(docheckie[0])
+        FCEUI_SetVidSystem(1);
+       if(docheckie[1])
+        FCEUI_SetGameGenie(1);
+        FCEUI_DisableSpriteLimitation(1);
+        FCEUI_SaveExtraDataUnderBase(eoptions&2);
+       FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
+
+       for(x=0;x<2;x++)
+       {
+         if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
+         if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
+       }
+
+       printf("main() setrendered lines: %d, %d, %d, %d\n",srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
+        printf("main() clip sides %d\n", eoptions&EO_CLIPSIDES);
+        srendlinev[0]=0;
+        FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
+        FCEUI_SetRenderedLines(0,erendlinev[0],srendlinev[1],erendlinev[1]);
+        FCEUI_SetSoundVolume(soundvol);
+       DriverInterface(DES_NTSCCOL,&ntsccol);
+       DoDriverArgs();
+
+       if(fcexp)
+       {
+        int y;
+         for(y=0;y<5;y++)
+         {
+          if(!strncmp(fccortab[y],fcexp,8))
+          {
+          UsrInputTypeFC=fccortabi[y];
+          break;
+          }
+         }
+        free(fcexp);
+       }
+       for(x=0;x<2;x++)
+       {
+        int y;
+
+         if(!inputa[x])
+         continue;
+
+        for(y=0;y<5;y++)
+        {
+         if(!strncmp(cortab[y],inputa[x],8))
+         {
+          UsrInputType[x]=cortabi[y];
+          if(y==3)
+          {
+           powerpadside&=~(1<<x);
+           powerpadside|=((((inputa[x][8])-'a')&1)^1)<<x;
+          }
+          free(inputa[x]);
+         }
+        }
+       }
+}
+
+#include "usage.h"
+
+int CLImain(int argc, char *argv[])
+{
+       FCEUGI *tmp;
+       int ret;
+
+       if(!(ret=FCEUI_Initialize()))
+         return(1);
+        GetBaseDirectory(BaseDirectory);
+       FCEUI_SetBaseDirectory(BaseDirectory);
+
+       CreateDirs();
+        if(argc<=1)
+        {
+         ShowUsage(argv[0]);
+         return 1;
+        }
+        LoadConfig();
+        DoArgs(argc-2,&argv[1]);
+       if(cpalette)
+        LoadCPalette();
+       if(InitSound())
+        inited|=1;
+
+        if(!(tmp=FCEUI_LoadGame(argv[argc-1])))
+        {
+         ret=0;
+         goto dk;
+        }
+       ParseGI(tmp);
+       //RefreshThrottleFPS();
+        if(!DriverInitialize())
+        {
+         ret=0;
+         goto dk;
+        }
+       InitOtherInput();
+       FCEUI_Emulate();
+
+       dk:
+       DriverKill();
+        return(ret?0:1);
+}
+
+static int DriverInitialize(void)
+{
+   SetSignals((void *)CloseStuff);
+
+   if(InitJoysticks())
+    inited|=2;
+   if(!InitVideo()) return 0;
+   inited|=4;
+   if(!InitKeyboard()) return 0;
+   inited|=8;
+   return 1;
+}
+
+static void DriverKill(void)
+{
+ SaveConfig();
+ SetSignals(SIG_IGN);
+
+ if(inited&2)
+  KillJoysticks();
+ if(inited&8)
+  KillKeyboard();
+ if(inited&4)
+  KillVideo();
+ if(inited&1)
+  KillSound();
+ if(inited&16)
+  KillMouse();
+ inited=0;
+}
+
+void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
+{
+ if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
+  SpeedThrottle();
+ BlitScreen(XBuf);
+ if(Count)
+  WriteSound(Buffer,Count,NoWaiting);
+ FCEUD_UpdateInput();
+}
+
diff --git a/drivers/gp2x/main.h b/drivers/gp2x/main.h
new file mode 100644 (file)
index 0000000..99dc5b5
--- /dev/null
@@ -0,0 +1,30 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Ben Parnell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "../../driver.h"
+
+extern int eoptions;
+#define EO_NO8LIM      1
+#define EO_SUBASE      2
+#define EO_CLIPSIDES   8
+#define EO_SNAPNAME    16
+#define EO_NOFOURSCORE 32
+#define EO_NOTHROTTLE  64
+extern int srendline,erendline,srendlinev[2],erendlinev[2];
+extern int NoWaiting;
diff --git a/drivers/gp2x/minimal.c b/drivers/gp2x/minimal.c
new file mode 100644 (file)
index 0000000..193fa9e
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+  GP2X minimal library v0.A by rlyeh, 2005. emulnation.info@rlyeh (swap it!)
+
+  + GP2X 920t/940t CPUs library with a FIFO message system.
+  + GP2X video library with double buffering.
+  + GP2X sound library with double buffering.
+  + GP2X blitter library.
+  + GP2X timer library.
+  + GP2X joystick library.
+
+  Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)
+
+
+  License
+  =======
+
+  Free for non-commercial projects (it would be nice receiving a mail from you).
+  Other cases, ask me first.
+
+  GamePark Holdings is not allowed to use this library and/or use parts from it.
+
+
+  Known projects using the library or parts from it
+  =================================================
+
+  REminiscence-0.1.8 (rlyeh)
+  Atari800 GP2X pre-release 3 (foft)
+  XUMP (kedo)
+  MAME2X (Franxis)
+  DrMD for GP2X (Reesy)
+
+
+  What's new
+  ==========
+
+  0.A: 940t disabled all time unless required
+       sound is paused by default now, use gp2x_sound_pause() to unlock it
+
+       fixed functions:
+        - gp2x_sound_play()                        ; increased the number of sampling buffers
+        - gp2x_timer_read()                        ; it should work again. broken at some point before
+        - gp2x_dualcore_launch_program_from_disk() ; it missed the code uploading call
+
+       added functions:
+        - gp2x_sound_pause()
+        - gp2x_timer_delay()
+        - gp2x_dualcore_pause()
+
+  0.9: initial FIFO message system for dual cpu cores.
+       initial 48 Mb support.
+       initial quadruple buffering in 8bbp mode.              
+
+       added functions:
+        - gp2x_dualcore_exec() ; initial FIFO message system for dual cpu cores. 
+        - gp2x_dualcore_sync() ; initial FIFO message system for dual cpu cores.
+
+       improved functions:
+        - gp2x_video_flip()    ; initial quadruple buffering in 8bbp mode.              
+
+  0.8: initial dual cores cpu support.
+       very basic blit functions by popular demand ;-)
+       vsync & hsync waiting code (thanks Reesy)
+
+       added functions:
+        - gp2x_launch_program()            ; initial dual cores cpu support.
+        - gp2x_launch_program_from_disk()  ; initial dual cores cpu support.
+        - gp2x_launch_subprogram()         ; initial dual cores cpu support.
+        - gp2x_blitter_rect15()            ; very basic blit function by popular demand ;-)
+        - gp2x_blitter_rect8()             ; very basic blit function by popular demand ;-)
+        - gp2x_video_hsync()               ; hsync waiting code (thanks Reesy)
+        - gp2x_video_vsync()               ; vsync waiting code (thanks Reesy)
+
+       fixed functions:
+        - gp2x_video_color8()              ; bugfixed a stupid typo (thanks Franxis for the bug report)
+
+  0.7: added functions:
+        - gp2x_sound_volume()
+
+       fixed functions:
+        - gp2x_deinit()           ; fixed menu launch code when exiting.
+
+       improved functions:
+        - gp2x_timer_read()       ; rewritten timer. it should be more accurate now.
+        - gp2x_init()             ; faster init code.
+
+  0.6: added functions:
+        - gp2x_timer_read()
+        - gp2x_sound_pause()
+
+       fixed functions:
+        - gp2x_video_setpalette() ; palette handling was incorrect. fixed.
+
+  0.5: improved functions:
+        - gp2x_init()             ; better and cleaner initalizing code.
+        - gp2x_init()             ; sound patched for real stereo output (by using NK's solution)
+
+  0.4: lots of cleanups.
+       sound is threaded and double buffered now.
+       8 bpp video support.
+
+       fixed functions:
+        - gp2x_deinit()           ; better and cleaner exiting code.
+
+  0.3: shorter library.
+
+       fixed functions:
+        - gp2x_joystick_read()    ; improved joystick diagonal detection.
+
+  0.2: better code layout.
+       public release.
+
+  0.1: beta release.
+*/
+
+#include "minimal.h"
+
+         unsigned char  *gp2x_screen8                 ,*gp2x_upperRAM;
+         unsigned long   gp2x_dev[8]={0,0,0,0,0,0,0,0}, gp2x_physvram[8], *gp2x_memregl,       gp2x_volume,                      gp2x_ticks_per_second;
+volatile unsigned long   gp2x_sound_pausei=1,           gp2x_ticks=0,      gp2x_sound=0,      *gp2x_dualcore_ram;
+         unsigned short *gp2x_memregs,                 *gp2x_screen15,    *gp2x_logvram15[4],  gp2x_sound_buffer[4+((44100/25)*2)*8]; //25 Hz gives our biggest supported sampling buffer
+volatile unsigned short  gp2x_palette[512];
+         pthread_t       gp2x_sound_thread=0;
+
+extern void gp2x_sound_frame(void *blah, void *buff, int samples);
+
+
+void gp2x_video_flip(void)
+{
+  unsigned long address=gp2x_physvram[gp2x_physvram[7]];
+
+  if(++gp2x_physvram[7]==4) gp2x_physvram[7]=0;
+  gp2x_screen15=gp2x_logvram15[gp2x_physvram[7]]; 
+  gp2x_screen8=(unsigned char *)gp2x_screen15; 
+  gp2x_memregs[0x290E>>1]=(unsigned short)(address & 0xFFFF);
+  gp2x_memregs[0x2910>>1]=(unsigned short)(address >> 16);
+  gp2x_memregs[0x2912>>1]=(unsigned short)(address & 0xFFFF);
+  gp2x_memregs[0x2914>>1]=(unsigned short)(address >> 16);
+}
+
+void gp2x_video_flip_single(void)
+{
+  unsigned long address=gp2x_physvram[0];
+
+  gp2x_screen15=gp2x_logvram15[0]; 
+  gp2x_screen8=(unsigned char *)gp2x_screen15; 
+  gp2x_memregs[0x290E>>1]=(unsigned short)(address & 0xFFFF);
+  gp2x_memregs[0x2910>>1]=(unsigned short)(address >> 16);
+  gp2x_memregs[0x2912>>1]=(unsigned short)(address & 0xFFFF);
+  gp2x_memregs[0x2914>>1]=(unsigned short)(address >> 16);
+}
+
+
+void gp2x_video_setgamma(unsigned short gamma) /*0..255*/
+{
+  int i=256*3; 
+  gp2x_memregs[0x295C>>1]=0;                                                     
+  while(i--) gp2x_memregs[0x295E>>1]=gamma; 
+}
+
+void gp2x_video_setpalette(void)
+{
+  unsigned short *g=(unsigned short *)gp2x_palette; int i=512;
+  gp2x_memregs[0x2958>>1]=0;                                                     
+  while(i--) gp2x_memregs[0x295A>>1]=*g++; 
+}
+
+void gp2x_blitter_rect15(gp2x_rect *r)
+{
+ int x, y; unsigned short *data=r->data15, *offset=&gp2x_screen15[r->x+r->y*320];
+
+ y=r->h; if(r->solid)
+         while(y--) { x=r->w; while(x--) *offset++=*data++; offset+=320-x; }
+         else
+         while(y--) { x=r->w; while(x--) { if(*data) *offset=*data; offset++, data++; }
+                      offset+=320-x; }
+}
+
+void gp2x_blitter_rect8(gp2x_rect *r)
+{
+ int x, y; unsigned char *data=r->data8,   *offset=&gp2x_screen8[r->x+r->y*320]; 
+
+ y=r->h; if(r->solid)
+         while(y--) { x=r->w; while(x--) *offset++=*data++; offset+=320-x; }
+         else
+         while(y--) { x=r->w; while(x--) { if(*data) *offset=*data; offset++, data++; }
+                      offset+=320-x; }
+}
+unsigned long gp2x_joystick_read(void)
+{
+  unsigned long value=(gp2x_memregs[0x1198>>1] & 0x00FF);
+
+  if(value==0xFD) value=0xFA;
+  if(value==0xF7) value=0xEB;
+  if(value==0xDF) value=0xAF;
+  if(value==0x7F) value=0xBE;
+  return ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16));
+}
+
+void gp2x_sound_volume(int l, int r)
+{
+ l=(((l*0x50)/100)<<8)|((r*0x50)/100);          //0x5A, 0x60
+ ioctl(gp2x_dev[4], SOUND_MIXER_WRITE_PCM, &l); //SOUND_MIXER_WRITE_VOLUME
+}
+
+void gp2x_timer_delay(unsigned long ticks)
+{
+ unsigned long target=gp2x_memregl[0x0A00>>2]+ticks*gp2x_ticks_per_second;
+ while(gp2x_memregl[0x0A00>>2]<target); 
+}
+
+unsigned long gp2x_timer_read(void)
+{
+ return gp2x_memregl[0x0A00>>2]/gp2x_ticks_per_second;
+} 
+
+unsigned long gp2x_timer_read_ms(void)
+{
+ return gp2x_memregl[0x0A00>>2];
+} 
+
+
+void gp2x_sound_pause(int yes) { gp2x_sound_pausei=yes; }
+
+
+static void *gp2x_sound_play(void *blah)
+{
+  int flip=0, flyp=gp2x_sound_buffer[1];
+  struct timespec ts; ts.tv_sec=0, ts.tv_nsec=gp2x_sound_buffer[2];
+
+  while(!gp2x_sound)  
+  { 
+    nanosleep(&ts, NULL);
+                        
+                        
+   if(!gp2x_sound_pausei) 
+   { 
+     // [1] is sound buffer size     at 22050, 16, stereo, it is 1468 (367*4)
+     // [0] number of bytes?,  at 22050,16,stereo, it is 367
+     // first half of buffer
+
+     // first one is 368
+
+     
+    gp2x_sound_frame(blah, (void *)(&gp2x_sound_buffer[4+flip]), gp2x_sound_buffer[0]);
+    // write out to second half of buffer
+    write(gp2x_dev[3],     (void *)(&gp2x_sound_buffer[4+flyp]), gp2x_sound_buffer[1]);
+
+    flip+=gp2x_sound_buffer[1];
+         if(flip==gp2x_sound_buffer[1]*8) flip=0;
+   flyp+=gp2x_sound_buffer[1]; 
+   if(flyp==gp2x_sound_buffer[1]*8) flyp=0;
+   }              
+  }
+  return NULL;
+}
+
+static void gp2x_initqueue(gp2x_queue *q, unsigned long queue_items, unsigned long *position920t, unsigned long *position940t)
+{
+  q->head  = q->tail  = q->items = 0;
+  q->max_items = queue_items;
+  if(position920t) q->place920t=position920t; else q->place920t=(unsigned long *)malloc(sizeof(unsigned long) * queue_items);
+  if(position940t) q->place940t=position940t;
+  memset(q->place920t, 0, sizeof(unsigned long) * queue_items);
+}
+
+static void gp2x_enqueue(gp2x_queue *q, unsigned long data)
+{      
+  while(q->items==q->max_items); /*waiting for tail to decrease...*/
+  q->place920t[q->head = (q->head < q->max_items ? q->head+1 : 0)] = data;
+  q->items++;
+}
+
+/* UNUSED
+ static unsigned long gp2x_dequeue(gp2x_queue *q)
+{
+  while(!q->items); //waiting for head to increase...
+  q->items--;
+  return q->place920t[q->tail = (q->tail < q->max_items ? q->tail+1 : 0)];
+} */
+
+
+
+       void gp2x_dualcore_pause(int yes) { if(yes) gp2x_memregs[0x0904>>1] &= 0xFFFE; else gp2x_memregs[0x0904>>1] |= 1; }
+static void gp2x_940t_reset(int yes)     { gp2x_memregs[0x3B48>>1] = ((yes&1) << 7) | (0x03); }
+static void gp2x_940t_pause(int yes)     { gp2x_dualcore_pause(yes); }
+
+static void gp2x_dualcore_registers(int save)
+{
+ static unsigned short regs[8];
+
+ if(save)
+ {
+  regs[0]=gp2x_memregs[0x0904>>1];  regs[1]=gp2x_memregs[0x0912>>1];
+  regs[2]=gp2x_memregs[0x091c>>1];  regs[3]=gp2x_memregs[0x3b40>>1];
+  regs[4]=gp2x_memregs[0x3b42>>1];  regs[5]=gp2x_memregs[0x3b48>>1];
+  regs[6]=gp2x_memregs[0x3b44>>1];  regs[7]=gp2x_memregs[0x3b46>>1];
+
+  gp2x_940t_reset(1);
+  gp2x_940t_pause(1);
+ }
+ else
+ {
+  gp2x_memregs[0x0904>>1]=regs[0];  gp2x_memregs[0x0912>>1]=regs[1];
+  gp2x_memregs[0x091c>>1]=regs[2];  gp2x_memregs[0x3b40>>1]=regs[3];
+  gp2x_memregs[0x3b42>>1]=regs[4];  gp2x_memregs[0x3b48>>1]=regs[5];
+  gp2x_memregs[0x3b44>>1]=regs[6];  gp2x_memregs[0x3b46>>1]=regs[7];
+ }
+}
+
+void gp2x_dualcore_sync(void)
+{
+  gp2x_queue *q=(gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR);
+  while(q->items);
+}
+
+void gp2x_dualcore_exec(unsigned long command) { gp2x_enqueue((gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR),command); }
+
+void gp2x_dualcore_launch_program(unsigned long *area, unsigned long size)
+{
+  unsigned long i=0, *arm940t_ram=(unsigned long *)gp2x_dualcore_ram;
+  
+  gp2x_940t_reset(1);
+
+  gp2x_memregs[0x3B40>>1] = 0;                               //disable interrupts
+  gp2x_memregs[0x3B42>>1] = 0;
+  gp2x_memregs[0x3B44>>1] = 0xffff;
+  gp2x_memregs[0x3B46>>1] = 0xffff;
+
+  gp2x_940t_pause(0);            
+                             
+  while(i < size) *arm940t_ram++=area[i++];
+
+  gp2x_initqueue((gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR), GP2X_QUEUE_MAX_ITEMS, (unsigned long *)gp2x_1stcore_data_ptr(GP2X_QUEUE_DATA_PTR), (unsigned long *)gp2x_2ndcore_data_ptr(GP2X_QUEUE_DATA_PTR));
+
+  gp2x_940t_reset(0);
+}
+
+void gp2x_dualcore_launch_program_from_disk(const char *file, unsigned long offset, unsigned long size)
+{
+ FILE *in; void *data;
+
+ if((in=fopen(file, "rb"))==NULL) return;
+ if((data=malloc(size))==NULL) { fclose(in); return; }
+ fseek(in, 0L, offset);
+ fread(data, 1, size, in);
+ gp2x_dualcore_launch_program((unsigned long *)data, size);
+ free(data);
+ fclose(in);
+}
+
+void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, int Hz)
+{
+  struct fb_fix_screeninfo fixed_info;
+  static int first=1;
+
+  // GP2X_DO_SOUND
+  int gp2x_do_sound=1;
+  int frag=0;
+  int channels=1;
+  int stereoLocal=0;
+
+  gp2x_ticks_per_second=7372800/ticks_per_second; 
+
+  if(!gp2x_dev[0])   gp2x_dev[0] = open("/dev/fb0",   O_RDWR);
+  if(!gp2x_dev[1])   gp2x_dev[1] = open("/dev/fb1",   O_RDWR);
+  if(!gp2x_dev[2])   gp2x_dev[2] = open("/dev/mem",   O_RDWR); 
+  
+  // don't run sound right now
+  if ( gp2x_do_sound)
+  {
+    if(!gp2x_dev[3])   gp2x_dev[3] = open("/dev/dsp",   O_WRONLY);
+    if(!gp2x_dev[4])   gp2x_dev[4] = open("/dev/mixer", O_RDWR);
+  }
+
+  gp2x_dualcore_ram=(unsigned long  *)mmap(0, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x03000000);
+/*gp2x_dualcore_ram=(unsigned long  *)mmap(0, 0x2000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x02000000);*/
+       gp2x_memregl=(unsigned long  *)mmap(0, 0x10000,   PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0xc0000000);
+        gp2x_memregs=(unsigned short *)gp2x_memregl;
+
+  if(first) { printf(MINILIB_VERSION "\n");
+              gp2x_dualcore_registers(1); 
+              gp2x_sound_volume(100,100);
+              gp2x_memregs[0x0F16>>1] = 0x830a; usleep(100000);
+              gp2x_memregs[0x0F58>>1] = 0x100c; usleep(100000); }
+
+  ioctl(gp2x_dev[gp2x_physvram[7]=0], FBIOGET_FSCREENINFO, &fixed_info); 
+   gp2x_screen15=gp2x_logvram15[2]=gp2x_logvram15[0]=(unsigned short *)mmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, gp2x_dev[0], 0);
+                                        gp2x_screen8=(unsigned char *)gp2x_screen15;
+                   gp2x_physvram[2]=gp2x_physvram[0]=fixed_info.smem_start;
+
+  ioctl(gp2x_dev[1], FBIOGET_FSCREENINFO, &fixed_info);
+                 gp2x_logvram15[3]=gp2x_logvram15[1]=(unsigned short *)mmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, gp2x_dev[1], 0);
+                   gp2x_physvram[3]=gp2x_physvram[1]=fixed_info.smem_start;
+
+  gp2x_memregs[0x28DA>>1]=(((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/
+  gp2x_memregs[0x290C>>1]=320*((bpp+1)/8);       /*line width in bytes*/
+
+  memset(gp2x_screen15, 0, 320*240*2); gp2x_video_flip();
+  memset(gp2x_screen15, 0, 320*240*2); gp2x_video_flip();
+
+  if(bpp==8)  gp2x_physvram[2]+=320*240,    gp2x_physvram[3]+=320*240,
+             gp2x_logvram15[2]+=320*240/2, gp2x_logvram15[3]+=320*240/2; 
+
+
+ if ( gp2x_do_sound)
+ {
+   
+    ioctl(gp2x_dev[3], SNDCTL_DSP_SPEED,  &rate);
+    ioctl(gp2x_dev[3], SNDCTL_DSP_SETFMT, &bits);
+
+    ioctl(gp2x_dev[3], SNDCTL_DSP_CHANNELS, &channels);
+    ioctl(gp2x_dev[3], SNDCTL_DSP_STEREO, &stereoLocal);
+
+    frag = 0x40000|13;
+    ioctl(gp2x_dev[3], SNDCTL_DSP_SETFRAGMENT, &frag);
+  
+
+    printf("minimal() do sound, rate %d, bits %d, stereo %d, frag %d\n", rate, bits, stereo, frag);
+
+    if(first) 
+    {   
+      first=0; 
+    }
+  }  
+
+}
+
+
+extern int fcloseall(void);
+void gp2x_deinit(void)
+{
+  while((gp2x_sound++)<1000000);                               //wait arm920t threads to finish
+
+  gp2x_dualcore_registers(0);
+
+  gp2x_memregs[0x28DA>>1]=0x4AB;                               //set video mode
+  gp2x_memregs[0x290C>>1]=640;   
+  { int i; for(i=0;i<8;i++) if(gp2x_dev[i]) close(gp2x_dev[i]); }    //close all devices
+
+  fcloseall();                                                   //close all files
+
+}
+
+void SetVideoScaling(int pixels,int width,int height)
+{
+        float x, y;
+        float xscale,yscale;
+
+        int bpp=(gp2x_memregs[0x28DA>>1]>>9)&0x3;  /* bytes per pixel */
+
+        if(gp2x_memregs[0x2800>>1]&0x100) /* TV-Out ON? */
+        {
+                xscale=489.0; /* X-Scale with TV-Out (PAL or NTSC) */
+                if (gp2x_memregs[0x2818>>1]  == 287) /* PAL? */
+                        yscale=(pixels*274.0)/320.0; /* Y-Scale with PAL */
+                else if (gp2x_memregs[0x2818>>1]  == 239) /* NTSC? */
+                        yscale=(pixels*331.0)/320.0; /* Y-Scale with NTSC */
+        }
+        else /* TV-Out OFF? */ 
+        {
+                xscale=1024.0; /* X-Scale for LCD */
+                yscale=pixels; /* Y-Scale for LCD */
+        }
+
+        x=(xscale*width)/320.0;
+        y=(yscale*bpp*height)/240.0;
+        gp2x_memregs[0x2906>>1]=(unsigned short)x; /* scale horizontal */
+        gp2x_memregl[0x2908>>2]=(unsigned  long)y; /* scale vertical */
+        gp2x_memregs[0x290C>>1]=pixels*bpp; /* Set Video Width */
+}
diff --git a/drivers/gp2x/minimal.h b/drivers/gp2x/minimal.h
new file mode 100644 (file)
index 0000000..53127b9
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+\r
+  GP2X minimal library v0.A by rlyeh, (c) 2005. emulnation.info@rlyeh (swap it!)\r
+\r
+  Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)\r
+\r
+  License\r
+  =======\r
+\r
+  Free for non-commercial projects (it would be nice receiving a mail from you).\r
+  Other cases, ask me first.\r
+\r
+  GamePark Holdings is not allowed to use this library and/or use parts from it.\r
+\r
+*/\r
+\r
+#include <fcntl.h>\r
+#include <linux/fb.h>\r
+#include <pthread.h>\r
+#include <signal.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <sys/mman.h>\r
+//#include <sys/ioctl.h>\r
+#include <sys/soundcard.h>\r
+#include <linux/soundcard.h>\r
+\r
+#include <sys/time.h>\r
+#include <unistd.h>\r
+#include <sys/ioctl.h>\r
+\r
+#ifndef __MINIMAL_H__\r
+#define __MINIMAL_H__\r
+\r
+#define MINILIB_VERSION  "GP2X minimal library v0.A by rlyeh, (c) 2005."\r
+\r
+typedef struct gp2x_queue { volatile unsigned long head, tail, items, max_items; unsigned long *place920t, *place940t; } gp2x_queue;\r
+typedef struct gp2x_rect  { int x,y,w,h,solid; unsigned short *data15; unsigned char *data8; } gp2x_rect;\r
+\r
+extern void gp2x_timer_delay(unsigned long ticks);\r
+extern void gp2x_sound_pause(int yes);\r
+extern void gp2x_dualcore_pause(int yes);\r
+extern void             gp2x_blitter_rect15(gp2x_rect *r);\r
+extern void             gp2x_blitter_rect8(gp2x_rect *r);\r
+\r
+\r
+\r
+//extern void             gp2x_sound_frame (void *blah, void *bufferg, int samples);\r
+\r
+enum  { GP2X_UP=0x1,       GP2X_LEFT=0x4,       GP2X_DOWN=0x10,  GP2X_RIGHT=0x40,\r
+        GP2X_START=1<<8,   GP2X_SELECT=1<<9,    GP2X_L=1<<10,    GP2X_R=1<<11,\r
+        GP2X_A=1<<12,      GP2X_B=1<<13,        GP2X_X=1<<14,    GP2X_Y=1<<15,\r
+        GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27                   };\r
+\r
+\r
+#define GP2X_QUEUE_MAX_ITEMS           16\r
+#define GP2X_QUEUE_ARRAY_PTR           ((0x1000-(sizeof(gp2x_queue)<<2)))\r
+#define GP2X_QUEUE_DATA_PTR            (GP2X_QUEUE_ARRAY_PTR-(GP2X_QUEUE_MAX_ITEMS<<2))\r
+\r
+#define gp2x_2ndcore_code(v)           (*(volatile unsigned long *)(v))\r
+#define gp2x_1stcore_code(v)           gp2x_dualcore_ram[(v)>>2]\r
+#define gp2x_2ndcore_data(v)           gp2x_2ndcore_code((v)+0x100000)\r
+#define gp2x_1stcore_data(v)           gp2x_1stcore_code((v)+0x100000)\r
+#define gp2x_dualcore_data(v)          gp2x_1stcore_data(v)\r
+\r
+#define gp2x_2ndcore_code_ptr(v)       ((volatile unsigned long *)(v))\r
+#define gp2x_1stcore_code_ptr(v)       (&gp2x_dualcore_ram[(v)>>2])\r
+#define gp2x_2ndcore_data_ptr(v)       gp2x_2ndcore_code_ptr((v)+0x100000)\r
+#define gp2x_1stcore_data_ptr(v)       gp2x_1stcore_code_ptr((v)+0x100000)\r
+                                            \r
+#define gp2x_video_wait_vsync()        while(gp2x_memregs[0x1182>>1]&(1<<4));\r
+#define gp2x_video_wait_hsync()        while(gp2x_memregs[0x1182>>1]&(1<<5));\r
+\r
+#define gp2x_video_color8(C,R,G,B)     do gp2x_palette[((C)<<1)+0]=((G)<<8)|(B),gp2x_palette[((C)<<1)+1]=(R); while(0)\r
+#define gp2x_video_color15(R,G,B,A)    ((((R)&0xF8)<<8)|(((G)&0xF8)<<3)|(((B)&0xF8)>>3)|((A)<<5))\r
+\r
+\r
+extern volatile unsigned short  gp2x_palette[512];\r
+extern          unsigned short *gp2x_screen15;\r
+extern          unsigned char  *gp2x_screen8;\r
+extern volatile unsigned long  *gp2x_dualcore_ram;\r
+\r
+extern void             gp2x_init(int tickspersecond, int bpp, int rate, int bits, int stereo, int hz);\r
+extern void             gp2x_deinit(void);\r
+\r
+extern void             gp2x_video_flip(void);\r
+extern void             gp2x_video_flip_single(void);\r
+extern void             gp2x_video_setpalette(void);\r
+\r
+extern unsigned long    gp2x_joystick_read(void);\r
+\r
+extern void             gp2x_sound_volume(int left, int right);\r
+\r
+extern unsigned long    gp2x_timer_read(void);\r
+extern unsigned long    gp2x_timer_read_ms(void);\r
+\r
+extern void             gp2x_dualcore_enable(int on);\r
+extern void             gp2x_dualcore_sync(void);\r
+extern void             gp2x_dualcore_exec(unsigned long command);\r
+extern void             gp2x_dualcore_launch_program(unsigned long *area, unsigned long size);\r
+extern void             gp2x_dualcore_launch_program_from_disk(const char *file, unsigned long offset, unsigned long size);\r
+\r
+#define gp2x_dualcore_declare_subprogram(name) extern void gp2x_dualcore_launch_## name ##_subprogram(void);\r
+#define gp2x_dualcore_launch_subprogram(name)  gp2x_dualcore_launch_## name ##_subprogram()\r
+\r
+#endif\r
+\r
diff --git a/drivers/gp2x/minimal_940t.h b/drivers/gp2x/minimal_940t.h
new file mode 100644 (file)
index 0000000..82cd1c0
--- /dev/null
@@ -0,0 +1,96 @@
+/*\r
+\r
+  GP2X minimal library v0.A by rlyeh, (c) 2005. emulnation.info@rlyeh (swap it!)\r
+\r
+  Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)\r
+\r
+  License\r
+  =======\r
+\r
+  Free for non-commercial projects (it would be nice receiving a mail from you).\r
+  Other cases, ask me first.\r
+\r
+  GamePark Holdings is not allowed to use this library and/or use parts from it.\r
+\r
+*/\r
+\r
+#include "minimal.h"\r
+\r
+#ifndef __MINIMAL_H_STUB_940T__\r
+#define __MINIMAL_H_STUB_940T__\r
+\r
+#undef    gp2x_dualcore_data\r
+#define   gp2x_dualcore_data(v)         gp2x_2ndcore_data(v)\r
+\r
+#define   main                          gp2x_2ndcore_run\r
+\r
+static void gp2x_2ndcore_start(void) __attribute__((naked));\r
+\r
+static void gp2x_2ndcore_start(void)\r
+{\r
+  unsigned long gp2x_dequeue(gp2x_queue *q)\r
+  {\r
+   unsigned long data;\r
+\r
+   while(!q->items); //waiting for head to increase...\r
+\r
+   data=q->place940t[q->tail = (q->tail < q->max_items ? q->tail+1 : 0)];\r
+   q->items--;\r
+\r
+   return data;\r
+  }\r
+\r
+#define gp2x_dualcore_name_subprogram(name) \\r
+/* 00000020 <_start>:                                                                             */ \\r
+/*    0:*/   asm volatile (".word 0xe59ff02c");  /*        ldr     pc, [pc, #44]  ; 34 <ioffset>  */ \\r
+/*    4:*/   asm volatile (".word 0xe59ff028");  /*        ldr     pc, [pc, #40]  ; 34 <ioffset>  */ \\r
+/*    8:*/   asm volatile (".word 0xe59ff024");  /*        ldr     pc, [pc, #36]  ; 34 <ioffset>  */ \\r
+/*    c:*/   asm volatile (".word 0xe59ff020");  /*        ldr     pc, [pc, #32]  ; 34 <ioffset>  */ \\r
+/*   10:*/   asm volatile (".word 0xe59ff01c");  /*        ldr     pc, [pc, #28]  ; 34 <ioffset>  */ \\r
+/*   14:*/   asm volatile (".word 0xe59ff018");  /*        ldr     pc, [pc, #24]  ; 34 <ioffset>  */ \\r
+/*   18:*/   asm volatile (".word 0xe59ff014");  /*        ldr     pc, [pc, #20]  ; 34 <ioffset>  */ \\r
+/*   1c:*/   asm volatile (".word 0xe59ff010");  /*        ldr     pc, [pc, #16]  ; 34 <ioffset>  */ \\r
+/* 00000020 <_init>:                                                                              */ \\r
+/*   20:*/   asm volatile (".word 0xe59fd010");  /*        ldr     sp, [pc, #16]   ; 38 <stack>         */ \\r
+/*   24:*/   asm volatile (".word 0xe59fc010");  /*        ldr     ip, [pc, #16]   ; 3c <deadbeef>      */ \\r
+/*   28:*/   asm volatile (".word 0xe59fb010");  /*        ldr     fp, [pc, #16]   ; 40 <leetface>      */ \\r
+/*   2c:*/   asm volatile (".word 0xe92d1800");  /*        stmdb   sp!, {fp, ip}                        */ \\r
+/*   30:*/   asm volatile (".word 0xea000004");  /*        b       48 <realinit>                        */ \\r
+/* 00000034 <ioffset>:                                                                                  */ \\r
+/*   34:*/   asm volatile (".word 0x00000020");  /*                                                     */ \\r
+/* 00000038 <stack>:                                                                                    */ \\r
+/*   38:*/   asm volatile (".word 0x000ffffc");  /*                                                     */ \\r
+/* 0000003c <deadbeef>:                                                                                 */ \\r
+/*   3c:*/   asm volatile (".word 0xdeadbeef");  /*                                                     */ \\r
+/* 00000040 <leetface>:                                                                                 */ \\r
+/*   40:*/   asm volatile (".word 0x1ee7face");  /*                                                     */ \\r
+/* 00000044 <area1>:                                                                                    */ \\r
+/*   44:*/   asm volatile (".word 0x00100019");  /*                                                     */ \\r
+/* 00000048 <realinit>:                                                                                 */ \\r
+/*  our main code starts here... */ \\r
+/*  48:*/   asm volatile (".word 0xe3a0003f"); /*        mov     r0, #63 ; 0x3f */ \\r
+/*  4c:*/   asm volatile (".word 0xee060f10"); /*        mcr     15, 0, r0, cr6, cr0, {0} */ \\r
+/*  50:*/   asm volatile (".word 0xee060f30"); /*        mcr     15, 0, r0, cr6, cr0, {1} */ \\r
+/*  54:*/   asm volatile (".word 0xe51f0018"); /*        ldr     r0, [pc, #-24]  ; 44 <area1> */ \\r
+/*  58:*/   asm volatile (".word 0xee060f11"); /*        mcr     15, 0, r0, cr6, cr1, {0} */ \\r
+/*  5c:*/   asm volatile (".word 0xee060f31"); /*        mcr     15, 0, r0, cr6, cr1, {1} */ \\r
+/*  60:*/   asm volatile (".word 0xe3a00001"); /*        mov     r0, #1  ; 0x1            */ \\r
+/*  64:*/   asm volatile (".word 0xee020f10"); /*        mcr     15, 0, r0, cr2, cr0, {0} */ \\r
+/*  68:*/   asm volatile (".word 0xee020f30"); /*        mcr     15, 0, r0, cr2, cr0, {1} */ \\r
+/*  6c:*/   asm volatile (".word 0xee030f10"); /*        mcr     15, 0, r0, cr3, cr0, {0} */ \\r
+/*  70:*/   asm volatile (".word 0xe3a0000f"); /*        mov     r0, #15 ; 0xf            */ \\r
+/*  74:*/   asm volatile (".word 0xee050f10"); /*        mcr     15, 0, r0, cr5, cr0, {0} */ \\r
+/*  78:*/   asm volatile (".word 0xee050f30"); /*        mcr     15, 0, r0, cr5, cr0, {1} */ \\r
+/*  7c:*/   asm volatile (".word 0xee110f10"); /*        mrc     15, 0, r0, cr1, cr0, {0} */ \\r
+/*  80:*/   asm volatile (".word 0xe3800001"); /*        orr     r0, r0, #1      ; 0x1    */ \\r
+/*  84:*/   asm volatile (".word 0xe3800004"); /*        orr     r0, r0, #4      ; 0x4    */ \\r
+/*  88:*/   asm volatile (".word 0xe3800a01"); /*        orr     r0, r0, #4096   ; 0x1000 */ \\r
+/*  8c:*/   asm volatile (".word 0xe3800103"); /*        orr     r0, r0, #-1073741824    ; 0xc0000000 */ \\r
+/*  90:*/   asm volatile (".word 0xee010f10"); /*        mcr     15, 0, r0, cr1, cr0, {0} */ \\r
+   while(1) gp2x_2ndcore_run(gp2x_dequeue((gp2x_queue *)gp2x_2ndcore_data_ptr(GP2X_QUEUE_ARRAY_PTR))); \\r
+} \\r
+void gp2x_dualcore_launch_##name##_subprogram(void) { gp2x_dualcore_launch_program((unsigned long *)&gp2x_2ndcore_start, ((int)&gp2x_dualcore_launch_##name##_subprogram)-((int)&gp2x_2ndcore_start)); }\r
+\r
+#endif\r
+\r
+\r
diff --git a/drivers/gp2x/sdl-sound.c b/drivers/gp2x/sdl-sound.c
new file mode 100644 (file)
index 0000000..6693222
--- /dev/null
@@ -0,0 +1,140 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+
+#include "sdl.h"
+#include "minimal.h"
+
+#define GP2X_SOUND 1
+
+extern void pthread_yield(void);
+extern void FCEUI_FrameSkip(int x);
+
+//extern int dosound;
+extern int soundvol;
+
+// always have this call
+INLINE void gp2x_sound_frame(void *blah, void *buff, int samples)
+ {
+}
+
+
+
+
+
+//static int sexy_in_function=0;
+#define NumSexyBufferBuffers 2
+struct timespec gp2x_sleep_ts;
+int firstentry=1;
+//int firstprint=1;
+struct timeval sleeptimer;
+
+
+
+pthread_t       gp2x_sexy_sound_thread=0;
+int**  SexyBufferBuffers=NULL;
+int    SexyBufferBufferCounts[NumSexyBufferBuffers];
+int  gp2x_sound_inited=0;
+int gp2x_in_sound_thread=0;
+extern unsigned long   gp2x_dev[8];
+
+pthread_cond_t gp2x_sound_cond=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t gp2x_sound_mutex = PTHREAD_MUTEX_INITIALIZER;
+int zzdebug01_entry=0;
+int zzdebug01_wait=0;
+int hasSound=0;
+extern unsigned long fps;
+extern unsigned long avg_fps;
+extern unsigned long ticks;
+
+int throttlecount=0;
+
+void WriteSound(int32 *Buffer, int Count)
+  {
+  write(gp2x_dev[3], Buffer, Count<<1);
+  pthread_yield();
+  SpeedThrottle();
+  }
+
+void* gp2x_write_sound(void* blah)
+  {
+  gp2x_in_sound_thread=1;
+  {
+    if (hasSound)
+  {
+      hasSound=0;
+  }
+    else
+  {
+  }
+
+ }
+  gp2x_in_sound_thread=0;
+  return NULL;
+}
+
+void SilenceSound(int n)
+{
+  soundvol=0;
+}
+
+int InitSound(FCEUGI *gi)
+{
+  Settings.sound=22050;
+  FCEUI_Sound(Settings.sound);
+  gp2x_sound_volume(soundvol, soundvol);
+  printf("InitSound() sound_rate: %d\n", Settings.sound);
+  if(firstentry)
+  {
+      firstentry=0;
+      gp2x_sound_inited=1;
+  }
+  return 1 ;
+}
+
+uint32 GetMaxSound(void)
+{
+ return(4096);
+}
+
+uint32 GetWriteSound(void)
+        {
+ return 1024;
+}
+
+int KillSound(void)
+{
+  FCEUI_Sound(0);
+  gp2x_sound_inited=0;
+
+  return 1;
+}
+
+
+
+
diff --git a/drivers/gp2x/sdl-video.c b/drivers/gp2x/sdl-video.c
new file mode 100644 (file)
index 0000000..9a4e787
--- /dev/null
@@ -0,0 +1,269 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "sdl.h"
+//#include "../common/vidblit.h"
+
+
+#include "minimal.h"
+
+extern int showfps;
+
+static char fps_str[32];
+static int framesEmulated, framesRendered;
+
+int stretch_offset=32;
+int paletterefresh;
+
+#define FPS_COLOR 61
+
+
+static unsigned char fontdata8x8[] =
+{
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x3C,0x42,0x99,0xBD,0xBD,0x99,0x42,0x3C,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C,
+       0xFE,0x82,0x8A,0xD2,0xA2,0x82,0xFE,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
+       0x80,0xC0,0xF0,0xFC,0xF0,0xC0,0x80,0x00,0x01,0x03,0x0F,0x3F,0x0F,0x03,0x01,0x00,
+       0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0x00,0xEE,0xEE,0xEE,0xCC,0x00,0xCC,0xCC,0x00,
+       0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
+       0x3C,0x66,0x7A,0x7A,0x7E,0x7E,0x3C,0x00,0x0E,0x3E,0x3A,0x22,0x26,0x6E,0xE4,0x40,
+       0x18,0x3C,0x7E,0x3C,0x3C,0x3C,0x3C,0x00,0x3C,0x3C,0x3C,0x3C,0x7E,0x3C,0x18,0x00,
+       0x08,0x7C,0x7E,0x7E,0x7C,0x08,0x00,0x00,0x10,0x3E,0x7E,0x7E,0x3E,0x10,0x00,0x00,
+       0x58,0x2A,0xDC,0xC8,0xDC,0x2A,0x58,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,
+       0x00,0x10,0x10,0x38,0x38,0x7C,0xFE,0x00,0xFE,0x7C,0x38,0x38,0x10,0x10,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x18,0x00,0x18,0x18,0x00,
+       0x6C,0x6C,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,
+       0x10,0x38,0x60,0x38,0x0C,0x78,0x10,0x00,0x40,0xA4,0x48,0x10,0x24,0x4A,0x04,0x00,
+       0x18,0x34,0x18,0x3A,0x6C,0x66,0x3A,0x00,0x18,0x18,0x20,0x00,0x00,0x00,0x00,0x00,
+       0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x00,
+       0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00,
+       0x38,0x4C,0xC6,0xC6,0xC6,0x64,0x38,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00,
+       0x7C,0xC6,0x0E,0x3C,0x78,0xE0,0xFE,0x00,0x7E,0x0C,0x18,0x3C,0x06,0xC6,0x7C,0x00,
+       0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x00,0xFC,0xC0,0xFC,0x06,0x06,0xC6,0x7C,0x00,
+       0x3C,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,0xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00,
+       0x78,0xC4,0xE4,0x78,0x86,0x86,0x7C,0x00,0x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
+       0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30,
+       0x1C,0x38,0x70,0xE0,0x70,0x38,0x1C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,
+       0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00,0x7C,0xC6,0xC6,0x1C,0x18,0x00,0x18,0x00,
+       0x3C,0x42,0x99,0xA1,0xA5,0x99,0x42,0x3C,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00,
+       0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
+       0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0x00,0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00,
+       0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00,0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00,
+       0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,
+       0x06,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0x00,
+       0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
+       0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
+       0xFC,0xC6,0xC6,0xC6,0xFC,0xC0,0xC0,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x7A,0x00,
+       0xFC,0xC6,0xC6,0xCE,0xF8,0xDC,0xCE,0x00,0x78,0xCC,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
+       0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
+       0xC6,0xC6,0xC6,0xEE,0x7C,0x38,0x10,0x00,0xC6,0xC6,0xD6,0xFE,0xFE,0xEE,0xC6,0x00,
+       0xC6,0xEE,0x3C,0x38,0x7C,0xEE,0xC6,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
+       0xFE,0x0E,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,
+       0x60,0x60,0x30,0x18,0x0C,0x06,0x06,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,
+       0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
+       0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3C,0x00,
+       0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00,
+       0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x3C,0x00,
+       0x1C,0x30,0x78,0x30,0x30,0x30,0x30,0x00,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x3C,
+       0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x00,
+       0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x38,0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00,
+       0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0xEC,0xFE,0xFE,0xFE,0xD6,0xC6,0x00,
+       0x00,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,
+       0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x06,
+       0x00,0x7E,0x70,0x60,0x60,0x60,0x60,0x00,0x00,0x3C,0x60,0x3C,0x06,0x66,0x3C,0x00,
+       0x30,0x78,0x30,0x30,0x30,0x30,0x1C,0x00,0x00,0x66,0x66,0x66,0x66,0x6E,0x3E,0x00,
+       0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x7C,0x6C,0x00,
+       0x00,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C,
+       0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x0E,0x18,0x0C,0x38,0x0C,0x18,0x0E,0x00,
+       0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x70,0x18,0x30,0x1C,0x30,0x18,0x70,0x00,
+       0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x10,0x28,0x10,0x54,0xAA,0x44,0x00,0x00,
+};
+
+static void gp2x_text(unsigned char *screen, int x, int y, char *text, int color, int flip)
+{
+       int i,l,slen;
+        slen=strlen(text);
+
+       screen=screen+x+y*320;
+
+       for (i=0;i<slen;i++)
+        {
+               for (l=0;l<8;l++)
+                {
+
+                       screen[l*320+0]=(fontdata8x8[((text[i])*8)+l]&0x80)?color:screen[l*320+0];
+                       screen[l*320+1]=(fontdata8x8[((text[i])*8)+l]&0x40)?color:screen[l*320+1];
+                       screen[l*320+2]=(fontdata8x8[((text[i])*8)+l]&0x20)?color:screen[l*320+2];
+                       screen[l*320+3]=(fontdata8x8[((text[i])*8)+l]&0x10)?color:screen[l*320+3];
+                       screen[l*320+4]=(fontdata8x8[((text[i])*8)+l]&0x08)?color:screen[l*320+4];
+                       screen[l*320+5]=(fontdata8x8[((text[i])*8)+l]&0x04)?color:screen[l*320+5];
+                       screen[l*320+6]=(fontdata8x8[((text[i])*8)+l]&0x02)?color:screen[l*320+6];
+                       screen[l*320+7]=(fontdata8x8[((text[i])*8)+l]&0x01)?color:screen[l*320+7];
+
+               }
+               screen+=8;
+       }
+}
+
+
+void CleanSurface(void)
+{
+       int c=4;
+       while (c--)
+       {
+               memset (gp2x_screen8, 0x80, 320*240);
+               gp2x_video_flip();
+       }
+}
+
+
+void KillVideo(void)
+{
+}
+
+
+int InitVideo(void)
+{
+       fps_str[0]=0;
+
+       CleanSurface();
+
+       puts("Initialized GP2X VIDEO via minimal");
+
+       srendline=0;
+       erendline=239;
+       return 1;
+}
+
+
+void ToggleFS(void)
+{
+}
+
+
+void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
+{
+       gp2x_video_color8(index, r, g, b);
+       gp2x_video_setpalette();
+
+       paletterefresh = 1;
+}
+
+
+void FCEUD_GetPalette(uint8 index, uint8 * r, uint8 * g, uint8 * b)
+{
+       *r = (uint8) gp2x_palette[(index << 1) + 1];
+       *g = (uint8) (gp2x_palette[(index << 1) + 0] >> 8);
+       *b = (uint8) gp2x_palette[(index << 1) + 0];
+}
+
+
+static INLINE void printFps(uint8 *screen)
+{
+       struct timeval tv_now;
+       static int prevsec, needfpsflip = 0;
+
+       gettimeofday(&tv_now, 0);
+       if (prevsec != tv_now.tv_sec)
+       {
+               sprintf(fps_str, "%i/%i", framesRendered, framesEmulated);
+               framesEmulated = framesRendered = 0;
+               needfpsflip = 4;
+               prevsec = tv_now.tv_sec;
+       }
+
+       if (stretch_offset > 0)
+       {
+               if (needfpsflip)
+               {
+                       int y, *destt = (int *) screen;
+                       for (y = 240; y; y--)
+                       {
+                               *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
+                               *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
+                               destt += 64;
+
+                               *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
+                               *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
+                       }
+                       if (showfps)
+                       {
+                               fps_str[2] = 0;
+                               gp2x_text(screen, 0,  0, fps_str,   FPS_COLOR, 0);
+                               gp2x_text(screen, 0, 10, fps_str+3, FPS_COLOR, 0);
+                       }
+                       needfpsflip--;
+               }
+       }
+       else
+       {
+               if (showfps)
+               {
+                       gp2x_text(screen, 0, 0, fps_str, FPS_COLOR, 0);
+               }
+       }
+}
+
+
+void BlitScreen(uint8 * XBuf)
+{
+       int x, y, yinc;
+
+       framesEmulated++;
+
+       if (!XBuf) return;
+
+       framesRendered++;
+
+#if 1 // 48->54
+       y=240;
+       yinc=272*(y-1);
+       while (y--)
+       {
+               int* dest=(int *) (gp2x_screen8+((y << 8) + (y << 6))+stretch_offset);
+
+               int* src=(int *) (XBuf+yinc);
+               x=64;
+               while (x--)
+               {
+                       dest[x]=src[x];
+               }
+               yinc-=272;
+       }
+
+       if (paletterefresh)
+       {
+               gp2x_video_setpalette();
+               paletterefresh = 0;
+       }
+#endif
+       printFps(gp2x_screen8);
+       gp2x_video_flip();
+}
+
+
diff --git a/drivers/gp2x/sdl-video.h b/drivers/gp2x/sdl-video.h
new file mode 100644 (file)
index 0000000..036c933
--- /dev/null
@@ -0,0 +1 @@
+uint32 PtoV(uint16 x, uint16 y);
diff --git a/drivers/gp2x/sdl.c b/drivers/gp2x/sdl.c
new file mode 100644 (file)
index 0000000..7826c8c
--- /dev/null
@@ -0,0 +1,253 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "sdl.h"
+#include "sdl-video.h"
+#ifdef NETWORK
+#include "unix-netplay.h"
+#endif
+#include "minimal.h"
+//extern int soundvol;
+int CLImain(int argc, char *argv[]);
+extern int gp2x_in_sound_thread;
+extern void pthread_yield(void);
+extern void SetVideoScaling(int, int, int);
+
+//#define SOUND_RATE 44100
+#define SOUND_RATE 22050
+
+DSETTINGS Settings;
+CFGSTRUCT DriverConfig[]={
+       AC(_xscale),
+       AC(_yscale),
+       AC(_xscalefs),
+       AC(_yscalefs),
+       AC(_efx),
+       AC(_efxfs),
+        AC(_sound),
+       #ifdef DSPSOUND
+        AC(_f8bit),
+       #else
+       AC(_ebufsize),
+       AC(_lbufsize),
+       #endif
+       AC(_fullscreen),
+        AC(_xres),
+       AC(_yres),
+        ACA(joyBMap),
+       ACA(joyAMap),
+        ACA(joy),
+        //ACS(_fshack),
+        ENDCFGSTRUCT
+};
+
+//-fshack x       Set the environment variable SDL_VIDEODRIVER to \"x\" when
+//                entering full screen mode and x is not \"0\".
+
+char *DriverUsage=
+"-xres   x       Set horizontal resolution to x for full screen mode.\n\
+-yres   x       Set vertical resolution to x for full screen mode.\n\
+-xscale(fs) x  Multiply width by x.\n\
+-yscale(fs) x  Multiply height by x.\n\
+-efx(fs) x     Enable scanlines effect if x is non zero.  yscale must be >=2\n\
+               and preferably a multiple of 2.\n\
+-fs     x      Select full screen mode if x is non zero.\n\
+-joyx   y       Use joystick y as virtual joystick x.\n\
+-sound x        Sound.\n\
+                 0 = Disabled.\n\
+                 Otherwise, x = playback rate.\n\
+"
+#ifdef DSPSOUND
+"-f8bit x        Force 8-bit sound.\n\
+                 0 = Disabled.\n\
+                 1 = Enabled.\n\
+"
+#else
+"-lbufsize x   Internal FCE Ultra sound buffer size. Size = 2^x samples.\n\
+-ebufsize x    External SDL sound buffer size. Size = 2^x samples.\n\
+"
+#endif
+"-connect s      Connect to server 's' for TCP/IP network play.\n\
+-server         Be a host/server for TCP/IP network play.\n\
+-netport x      Use TCP/IP port x for network play.";
+
+#ifdef NETWORK
+static int docheckie[2]={0,0};
+#endif
+ARGPSTRUCT DriverArgs[]={
+         {"-joy1",0,&joy[0],0},{"-joy2",0,&joy[1],0},
+         {"-joy3",0,&joy[2],0},{"-joy4",0,&joy[3],0},
+        {"-xscale",0,&_xscale,0},
+        {"-yscale",0,&_yscale,0},
+        {"-efx",0,&_efx,0},
+         {"-xscalefs",0,&_xscalefs,0},
+         {"-yscalefs",0,&_yscalefs,0},
+         {"-efxfs",0,&_efxfs,0},
+        {"-xres",0,&_xres,0},
+         {"-yres",0,&_yres,0},
+         {"-fs",0,&_fullscreen,0},
+         //{"-fshack",0,&_fshack,0x4001},
+         {"-sound",0,&_sound,0},
+        #ifdef DSPSOUND
+         {"-f8bit",0,&_f8bit,0},
+        #else
+        {"-lbufsize",0,&_lbufsize,0},
+        {"-ebufsize",0,&_ebufsize,0},
+        #endif
+        #ifdef NETWORK
+         {"-connect",&docheckie[0],&netplayhost,0x4001},
+         {"-server",&docheckie[1],0,0},
+         {"-netport",0,&Port,0},
+        #endif
+         {0,0,0,0}
+};
+
+
+
+
+
+void GetBaseDirectory(char *BaseDirectory)
+{
+ char *ol;
+
+ ol="/mnt/sd/roms/nes";
+ BaseDirectory[0]=0;
+ if(ol)
+ {
+  strncpy(BaseDirectory,ol,2047);
+  BaseDirectory[2047]=0;
+  strcat(BaseDirectory,"/fceultra");
+ }
+}
+
+static void SetDefaults(void)
+{
+ _xres=320;
+ _yres=240;
+ _fullscreen=0;
+ _sound=SOUND_RATE; // 48000 wrong
+ #ifdef DSPSOUND
+ _f8bit=0;
+ #else
+ _lbufsize=10;
+ _ebufsize=8;
+ #endif
+ _xscale=_yscale=_xscalefs=_yscalefs=1;
+ _efx=_efxfs=0;
+ //_fshack=_fshacksave=0;
+ memset(joy,0,sizeof(joy));
+}
+
+void DoDriverArgs(void)
+{
+        int x;
+
+       #ifdef BROKEN
+        if(_fshack)
+        {
+         if(_fshack[0]=='0')
+          if(_fshack[1]==0)
+          {
+           free(_fshack);
+           _fshack=0;
+          }
+        }
+       #endif
+
+       #ifdef NETWORK
+        if(docheckie[0])
+         netplay=2;
+        else if(docheckie[1])
+         netplay=1;
+
+        if(netplay)
+         FCEUI_SetNetworkPlay(netplay);
+       #endif
+
+        for(x=0;x<4;x++)
+         if(!joy[x])
+        {
+         memset(joyBMap[x],0,sizeof(joyBMap[0]));
+         memset(joyAMap[x],0,sizeof(joyAMap[0]));
+        }
+}
+int InitMouse(void)
+{
+ return(0);
+}
+void KillMouse(void){}
+void GetMouseData(uint32 *d)
+{
+}
+
+int InitKeyboard(void)
+{
+ return(1);
+}
+
+int UpdateKeyboard(void)
+{
+ return(1);
+}
+
+void KillKeyboard(void)
+{
+
+}
+
+char *GetKeyboard(void)
+{
+ return NULL;
+}
+
+#include "unix-basedir.h"
+extern int showfps;
+extern int swapbuttons;
+
+int main(int argc, char *argv[])
+{
+
+        puts("Starting GPFCE - Port version 0.2 05-29-2006");
+        puts("Based on FCE Ultra "VERSION_STRING"...");
+        puts("Ported by Zheng Zhu\n");
+
+         //  stereo
+        //gp2x_init (1000, 8, SOUND_RATE, 16, 1, 60);
+
+        // mono 44khz
+       //gp2x_init (1000, 8, SOUND_RATE<<1, 16, 0, 60);
+        // mono 22khz
+       gp2x_init (1000, 8, SOUND_RATE, 16, 0, 60);
+
+        SetDefaults();
+        int ret=CLImain(argc,argv);
+
+        // unscale the screen, in case this is bad.
+        SetVideoScaling(320, 320, 240);
+
+        gp2x_deinit();
+        // make sure sound thread has exited cleanly
+        while (gp2x_in_sound_thread) pthread_yield();
+        printf("Sound thread exited\n");
+        printf("Exiting main().  terminated");
+        if (showfps && swapbuttons)
+        {
+          execl("./selector","./selector","./gpfce_showfps_swapbuttons_config",NULL);
+        }
+        else if (showfps)
+        {
+          execl("./selector","./selector","./gpfce_showfps_config",NULL);
+        }
+        else if (swapbuttons)
+        {
+          execl("./selector","./selector","./gpfce_swapbuttons_config",NULL);
+        }
+        else
+        {
+          execl("./selector","./selector","./gpfce_config",NULL);
+        }
+        return(ret?0:-1);
+}
+
diff --git a/drivers/gp2x/sdl.h b/drivers/gp2x/sdl.h
new file mode 100644 (file)
index 0000000..7882e5b
--- /dev/null
@@ -0,0 +1,46 @@
+#include "../../driver.h"
+#include "../common/args.h"
+#include "../common/config.h"
+#include "main.h"
+
+typedef struct {
+        int xres;
+        int yres;
+       int xscale,yscale;
+       int xscalefs,yscalefs;
+       int efx,efxfs;
+        int fullscreen;
+       int sound;
+       #ifdef DSPSOUND
+       int f8bit;
+       #else
+       int lbufsize,ebufsize;
+       #endif
+       int joy[4];
+       int joyAMap[4][2];
+       int joyBMap[4][4];
+       char *fshack;
+       char *fshacksave;
+} DSETTINGS;
+
+extern DSETTINGS Settings;
+
+#define _xres Settings.xres
+#define _yres Settings.yres
+#define _fullscreen Settings.fullscreen
+#define _sound Settings.sound
+#define _f8bit Settings.f8bit
+#define _xscale Settings.xscale
+#define _yscale Settings.yscale
+#define _xscalefs Settings.xscalefs
+#define _yscalefs Settings.yscalefs
+#define _efx Settings.efx
+#define _efxfs Settings.efxfs
+#define _ebufsize Settings.ebufsize
+#define _lbufsize Settings.lbufsize
+#define _fshack Settings.fshack
+#define _fshacksave Settings.fshacksave
+
+#define joyAMap Settings.joyAMap
+#define joyBMap Settings.joyBMap
+#define joy    Settings.joy
diff --git a/drivers/gp2x/throttle.c b/drivers/gp2x/throttle.c
new file mode 100644 (file)
index 0000000..81cd916
--- /dev/null
@@ -0,0 +1,110 @@
+#include <sys/time.h>
+#include "main.h"
+#include "throttle.h"
+
+#if 0
+static uint64 tfreq;
+static uint64 desiredfps;
+
+void RefreshThrottleFPS(void)
+{
+ uint64 f=FCEUI_GetDesiredFPS();
+ // great, a bit faster than before
+ //f = (f*65) >> 6;
+ desiredfps=f>>8;
+ tfreq=1000000;
+ tfreq<<=16;    /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
+}
+
+static uint64 GetCurTime(void)
+{
+ uint64 ret;
+ struct timeval tv;
+
+ gettimeofday(&tv,0);
+ ret=(uint64)tv.tv_sec*1000000;
+ ret+=tv.tv_usec;
+ return(ret);
+}
+
+INLINE void SpeedThrottle(void)
+{
+ static uint64 ttime,ltime;
+
+ waiter:
+
+ ttime=GetCurTime();
+
+ if( (ttime-ltime) < (tfreq/desiredfps) )
+ {
+  goto waiter;
+ }
+ if( (ttime-ltime) >= (tfreq*4/desiredfps))
+  ltime=ttime;
+ else
+  ltime+=tfreq/desiredfps;
+}
+
+#else
+
+extern uint8 PAL;
+extern int FSkip, FSkip_setting;
+static int usec_aim = 0, usec_done = 0;
+static int skip_count = 0;
+
+INLINE void SpeedThrottle(void)
+{
+       static struct timeval tv_prev;
+       struct timeval tv_now;
+       int delta_nom = PAL ? 19997 : 16639; // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame
+
+
+       if (usec_done == 0) { // first time
+               usec_done = 1;
+               gettimeofday(&tv_prev, 0);
+               return;
+       }
+
+       gettimeofday(&tv_now, 0);
+
+       usec_aim += delta_nom;
+       if (tv_now.tv_sec != tv_prev.tv_sec)
+               usec_done += 1000000;
+       usec_done += tv_now.tv_usec - tv_prev.tv_usec;
+
+#ifdef FRAMESKIP
+       if (FSkip_setting >= 0)
+       {
+               if (skip_count >= FSkip_setting)
+                       skip_count = 0;
+               else {
+                       skip_count++;
+                       FSkip = 1;
+               }
+       }
+       else if (usec_done > usec_aim)
+       {
+               /* auto frameskip */
+               if (usec_done - usec_aim > 150000)
+                       usec_done = usec_aim = 0; // too much behind, try to recover..
+               FSkip = 1;
+               tv_prev = tv_now;
+               return;
+       }
+#endif
+
+       tv_prev = tv_now;
+       while (usec_done < usec_aim)
+       {
+               gettimeofday(&tv_now, 0);
+
+               if (tv_now.tv_sec != tv_prev.tv_sec)
+                       usec_done += 1000000;
+               usec_done += tv_now.tv_usec - tv_prev.tv_usec;
+               tv_prev = tv_now;
+       }
+       usec_done = usec_done - usec_aim + 1; // reset to prevent overflows
+       usec_aim = 0;
+}
+#endif
+
diff --git a/drivers/gp2x/throttle.h b/drivers/gp2x/throttle.h
new file mode 100644 (file)
index 0000000..0ea9365
--- /dev/null
@@ -0,0 +1,2 @@
+void RefreshThrottleFPS(void);
+INLINE void SpeedThrottle(void);
diff --git a/drivers/gp2x/unix-basedir.h b/drivers/gp2x/unix-basedir.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/drivers/gp2x/unix-netplay.c b/drivers/gp2x/unix-netplay.c
new file mode 100644 (file)
index 0000000..8e777db
--- /dev/null
@@ -0,0 +1,171 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Ben Parnell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <errno.h>
+
+#ifndef socklen_t
+#define socklen_t int
+#endif
+#ifdef NETWORK
+static int Socket=-1;
+#endif
+#include "main.h"
+#include "unix-netplay.h"
+
+char *netplayhost=0;
+int Port=0xFCE;
+int netplay=0;
+
+int FCEUD_NetworkConnect(void)
+{
+#ifdef NETWORK
+ struct sockaddr_in sockn;
+ int TSocket;
+
+ memset(&sockn,0,sizeof(sockn));
+ sockn.sin_family=AF_INET;
+ sockn.sin_port=htons(Port);
+
+ if((TSocket=socket(AF_INET, SOCK_STREAM, 0))<0)
+ {
+  puts("Error creating socket.");
+  return(0);
+ }
+
+ if(netplay==1)                /* Be a server. */
+ {
+  sockn.sin_addr.s_addr=INADDR_ANY;
+  if(bind(TSocket, (struct sockaddr *)&sockn, sizeof(sockn))<0)
+  {
+   close(TSocket);
+   puts("Error binding to socket."); 
+   return(0);
+  }
+  if(listen(TSocket, 1)<0)
+  {
+   puts("Error listening on socket.");
+   close(TSocket);
+   return(0);
+  }
+  {
+   socklen_t len=sizeof(sockn);
+     
+   printf("Accepting connection on port %d...\n",Port);
+   if((Socket=accept(TSocket,(struct sockaddr *)&sockn,&len))<0 )
+   {
+    puts("Error accepting a connection.");
+    close(TSocket);
+    return(0);
+   }
+   close(TSocket);
+  }
+
+ }
+ else /* Connect as a client if not a server. */
+ {
+  struct hostent *Host;
+
+  if((sockn.sin_addr.s_addr=inet_addr(netplayhost))==INADDR_NONE)
+  {
+   if(!(Host=gethostbyname(netplayhost)))
+   {
+    puts("Error getting network host entry.");
+    return(0);
+   }
+   memcpy(&sockn.sin_addr,Host->h_addr,Host->h_length);
+  }  
+  printf("Attempting to connect to %s...\n",netplayhost);
+  if( connect(TSocket, (struct sockaddr *)&sockn, sizeof(sockn)) <0 )
+  {
+   puts("Error connecting to remote host.");
+   close(TSocket);
+   return(0);
+  }
+  Socket=TSocket;
+ }
+#endif
+ return(1);  
+}
+
+/* 0 on failure, 1 on success, -1 if it would block and blocking is not
+   specified.
+*/
+
+int FCEUD_NetworkRecvData(uint8 *data, uint32 len, int block)
+{
+#ifdef NETWORK
+  if(block)
+  {
+   int t;
+   uint8 temp[32];
+   t=recv(Socket,temp,32,MSG_PEEK|MSG_DONTWAIT);
+   if(t==-1)
+   {
+    if(errno!=EAGAIN) return(0);
+   }
+   else if(t==32)
+    NoWaiting|=2;
+   else
+    NoWaiting&=~2;
+   return(recv(Socket,data,len,0)==len);
+  }
+  else
+  {
+   int t=recv(Socket,data,len,MSG_DONTWAIT);
+   if(t==-1)
+   {
+    if(errno==EAGAIN)   // Would block
+     return(-1);
+    return(0);
+   }
+   return(1);
+  }
+#else  
+  return 1;
+#endif
+}
+
+/* 0 on failure, 1 on success.  This function should always block. */
+
+int FCEUD_NetworkSendData(uint8 *Value, uint32 len)
+{
+#ifdef NETWORK
+ return(send(Socket,Value,len,0)==len);
+#else
+ return 0;
+#endif
+}
+
+void FCEUD_NetworkClose(void)
+{
+#ifdef NETWORK
+ if(Socket>0)
+  close(Socket);
+ Socket=-1;
+#endif
+}
+
diff --git a/drivers/gp2x/unix-netplay.h b/drivers/gp2x/unix-netplay.h
new file mode 100644 (file)
index 0000000..48769f6
--- /dev/null
@@ -0,0 +1,5 @@
+extern char *netplayhost;
+extern int Port;
+extern int FDnetplay;
+#define netplay FDnetplay
+
diff --git a/drivers/gp2x/usage.h b/drivers/gp2x/usage.h
new file mode 100644 (file)
index 0000000..425a907
--- /dev/null
@@ -0,0 +1,56 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Ben Parnell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+void ShowUsage(char *prog)
+{
+printf("\nUsage is as follows:\n%s <options> filename\n\n",prog);
+puts("Options:");
+puts(DriverUsage);
+puts("-cpalette x     Load a custom global palette from file x.\n\
+-ntsccol x      Emulate an NTSC's TV's colors.\n\
+                 0 = Disabled.\n\
+                 1 = Enabled.\n\
+-pal            Emulate a PAL NES.\n\
+-soundvol x    Sound volume. x is an integral percentage value.\n\
+-inputx str    Select device mapped to virtual input port x(1-2).\n\
+                str may be: none, gamepad, zapper, powerpada, powerpadb,\n\
+                            arkanoid\n\
+-fcexp str     Select Famicom expansion port device.\n\
+                str may be: none, shadow, arkanoid, 4player, fkb\n\
+-nofs x                Disables Four-Score emulation if x is 1.\n\
+-gg             Enable Game Genie emulation.\n\
+-no8lim x       Disables the 8 sprites per scanline limitation.\n\
+                 0 = Limitation enabled.\n\
+                 1 = Limitation disabled.\n\
+-subase x       Save extra game data files under the base directory if enabled.\n\
+                 0 = Disabled.\n\
+                1 = Enabled.\n\
+-snapname x    Selects what type of file name snapshots will have.\n\
+                0 = Numeric(0.png)\n\
+                1 = File base and numeric(mario-0.png)\n\
+-nothrottle x  Disable artificial speed throttling if x is non-zero.\n\
+-clipsides x   Clip leftmost and rightmost 8 columns of pixels of video output.\n\
+                 0 = No clipping.\n\
+                 1 = Clipping.\n\
+-slstart x     Set the first drawn emulated scanline.  Valid values for x are\n\
+               0 through 239.\n\
+-slend x       Set the last drawn emulated scanline.  Valid values for x are\n\
+               0 through 239.");
+}