home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / AmigaVGB / Unix.c < prev    next >
C/C++ Source or Header  |  1996-07-05  |  10KB  |  322 lines

  1. /** VGB: portable GameBoy emulator ***************************/
  2. /**                                                         **/
  3. /**                           Unix.c                        **/
  4. /**                                                         **/
  5. /** This file contains Unix/X-dependent subroutines and     **/
  6. /** drivers.                                                **/
  7. /**                                                         **/
  8. /** Copyright (C) Marat Fayzullin 1994,1995,1996            **/
  9. /**               Elan Feingold   1995                      **/
  10. /**     You are not allowed to distribute this software     **/
  11. /**     commercially. Please, notify me, if you make any    **/
  12. /**     changes to this file.                               **/
  13. /*************************************************************/
  14.  
  15. #define USE_XPAL  /* We are using XPal[] to determine colors */
  16.  
  17. /** Standard Unix/X #includes ********************************/
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <signal.h>
  22. #include <sys/time.h>
  23. #include <X11/Xlib.h>
  24. #include <X11/Xutil.h>
  25. #include <X11/keysym.h>
  26.  
  27. #include "GB.h"
  28.  
  29.  
  30. /** MIT Shared Memory Extension for X ************************/
  31. #ifdef MITSHM
  32. #include <sys/ipc.h>
  33. #include <sys/shm.h>
  34. #include <X11/extensions/XShm.h>
  35. XShmSegmentInfo SHMInfo;
  36. int UseSHM=1;
  37. #endif
  38.  
  39.  
  40. /** Various X-related variables ******************************/
  41. Display *Dsp;
  42. Window Wnd;
  43. Colormap DefaultCMap;
  44. XImage *Img;
  45. GC DefaultGC;
  46. unsigned long White,Black;
  47.  
  48.  
  49. /** Various variables and short functions ********************/
  50. #define WIDTH  176  /* Width (>=176, must be divisible by 8) */
  51. #define HEIGHT 144  /* Height (>=144)                        */
  52.  
  53. char *Title = "Virtual GameBoy Unix/X 0.7";
  54.  
  55. int  SaveCPU  = 1;
  56.  
  57. byte *XBuf,*ZBuf,XPal[12];
  58.  
  59. char *ColorNames[12] =
  60. {
  61.   "white","#989898","#585858","black",
  62.   "white","#989898","#585858","black",
  63.   "white","#989898","#585858","black"
  64. };
  65.  
  66. void OnBreak(int Arg) { CPURunning=0; }
  67.  
  68.  
  69. /** InitMachine **********************************************/
  70. /** Allocate resources needed by Unix/X-dependent code.     **/
  71. /*************************************************************/
  72. int InitMachine()
  73. {
  74.   Screen *Scr;
  75.   XEvent E;
  76.   XGCValues values;
  77.   XColor Color,C;
  78.   int J;
  79.  
  80.   if(Verbose)
  81.     printf("Initializing Unix/X drivers:\n  Opening display...");
  82.   Dsp=XOpenDisplay(NULL);
  83.   if(!Dsp) { if(Verbose) printf("FAILED\n");return(0); }
  84.  
  85.   Scr=DefaultScreenOfDisplay(Dsp);
  86.   White=WhitePixelOfScreen(Scr);
  87.   Black=BlackPixelOfScreen(Scr);
  88.   DefaultGC=DefaultGCOfScreen(Scr);
  89.   DefaultCMap=DefaultColormapOfScreen(Scr);
  90.  
  91.   if(Verbose) printf("OK\n  Opening window...");
  92.   Wnd=
  93.     XCreateSimpleWindow
  94.     (Dsp,RootWindowOfScreen(Scr),0,0,160,144,0,White,Black);
  95.   if(!Wnd) { if(Verbose) printf("FAILED\n");return(0); }
  96.  
  97.   {
  98.     XSizeHints Hints;
  99.     XWMHints WMHints;
  100.  
  101.     Hints.flags=PSize|PMinSize|PMaxSize;
  102.     Hints.min_width=Hints.max_width=Hints.base_width=160;
  103.     Hints.min_height=Hints.max_height=Hints.base_height=144;
  104.     WMHints.input=True;WMHints.flags=InputHint;
  105.     XSetWMHints(Dsp,Wnd,&WMHints);
  106.     XSetWMNormalHints(Dsp,Wnd,&Hints);
  107.     XStoreName(Dsp,Wnd,Title);
  108.   }
  109.  
  110.   XSelectInput
  111.   (Dsp,Wnd,FocusChangeMask|ExposureMask|KeyPressMask|KeyReleaseMask);
  112.   XMapRaised(Dsp,Wnd);
  113.   XClearWindow(Dsp,Wnd);
  114.   XAutoRepeatOff(Dsp);
  115.   XWindowEvent(Dsp,Wnd,ExposureMask,&E);
  116.  
  117.   if(Verbose) printf("OK\n  Allocating Z-buffer...");
  118.   if(!(ZBuf=malloc(2*WIDTH*HEIGHT/8))) return(0);
  119.  
  120. #ifdef MITSHM
  121.   if(UseSHM)
  122.   {
  123.     if(Verbose) printf("OK\n  Using shared memory:\n    Creating image...");
  124.     Img=
  125.       XShmCreateImage
  126.       (Dsp,DefaultVisualOfScreen(Scr),8,ZPixmap,NULL,&SHMInfo,WIDTH,HEIGHT);
  127.     if(!Img) { if(Verbose) printf("FAILED\n");return(0); }
  128.  
  129.     if(Verbose) printf("OK\n    Getting SHM info...");
  130.     SHMInfo.shmid=
  131.       shmget(IPC_PRIVATE,Img->bytes_per_line*Img->height,IPC_CREAT|0777);
  132.     if(SHMInfo.shmid<0) { if(Verbose) printf("FAILED\n");return(0); }
  133.  
  134.     if(Verbose) printf("OK\n    Allocating SHM...");
  135.     XBuf=(byte *)(Img->data=SHMInfo.shmaddr=shmat(SHMInfo.shmid,0,0));
  136.     if(!XBuf) { if(Verbose) printf("FAILED\n");return(0); }
  137.  
  138.     SHMInfo.readOnly=False;
  139.     if(Verbose) printf("OK\n    Attaching SHM...");
  140.     if(!XShmAttach(Dsp,&SHMInfo))
  141.     { if(Verbose) printf("FAILED\n");return(0); }
  142.   }
  143.   else
  144. #endif
  145.   {
  146.     if(Verbose) printf("OK\n  Allocating screen buffer...");
  147.     XBuf=(byte *)malloc(sizeof(byte)*HEIGHT*WIDTH);
  148.     if(!XBuf) { if(Verbose) printf("FAILED\n");return(0); }
  149.  
  150.     if(Verbose) printf("OK\n  Creating image...");
  151.     Img=
  152.       XCreateImage
  153.       (Dsp,DefaultVisualOfScreen(Scr),8,ZPixmap,0,XBuf,WIDTH,HEIGHT,8,0);
  154.     if(!Img) { if(Verbose) printf("FAILED\n");return(0); }
  155.   }
  156.  
  157.   if(Verbose) puts("OK");
  158.  
  159.   for(J=0;J<12;J++)
  160.     XPal[J]=XAllocNamedColor(Dsp,DefaultCMap,ColorNames[J],&Color,&C)?
  161.               Color.pixel : J&2? White:Black;
  162.  
  163.   signal(SIGHUP,OnBreak);signal(SIGINT,OnBreak);
  164.   signal(SIGQUIT,OnBreak);signal(SIGTERM,OnBreak);
  165.  
  166.   return(1);
  167. }
  168.  
  169.  
  170. /** TrashMachine *********************************************/  
  171. /** Deallocate all resources taken by InitMachine().        **/
  172. /*************************************************************/
  173. void TrashMachine()
  174. {
  175.   if(Verbose) printf("Shutting down...\n");
  176.  
  177.   if(Dsp&&Wnd)
  178.   {
  179. #ifdef MITSHM
  180.     if(UseSHM)
  181.     {
  182.       XShmDetach(Dsp,&SHMInfo);
  183.       if(SHMInfo.shmaddr) shmdt(SHMInfo.shmaddr);
  184.       if(SHMInfo.shmid>=0) shmctl(SHMInfo.shmid,IPC_RMID,0);
  185.     }
  186.     else
  187. #endif MITSHM
  188.     if(Img) XDestroyImage(Img);
  189.   }
  190.   if(ZBuf) free(ZBuf);
  191.   if(Dsp) { XAutoRepeatOn(Dsp);XCloseDisplay(Dsp); }
  192. }
  193.  
  194.  
  195. /** PutImage *************************************************/
  196. /** Put an image on the screen.                             **/
  197. /*************************************************************/
  198. void PutImage()
  199. {
  200. #ifdef MITSHM
  201.   if(UseSHM)
  202.     XShmPutImage(Dsp,Wnd,DefaultGC,Img,(WIDTH-160)/2,0,0,0,160,144,False);
  203.   else
  204. #endif
  205.   XPutImage(Dsp,Wnd,DefaultGC,Img,(WIDTH-160)/2,0,0,0,160,144);
  206.   XFlush(Dsp);
  207. }
  208.  
  209.  
  210. /** Joystick *************************************************/
  211. /** Return the current joystick state.                      **/
  212. /*************************************************************/
  213. byte Joystick(void)
  214. {
  215.   static byte JoyState = 0xFF;
  216.   XEvent E;
  217.   word J;
  218.  
  219.   if(XCheckWindowEvent(Dsp,Wnd,KeyPressMask|KeyReleaseMask,&E))
  220.   {
  221.     J=XLookupKeysym((XKeyEvent *)&E,0);
  222.     if(E.type==KeyPress)
  223.       switch(J)
  224.       {
  225.         case XK_F12:
  226.         case XK_Escape: CPURunning=0;break;
  227. #ifdef DEBUG
  228.         case XK_F1:     Trace=!Trace;break;
  229.         case XK_F2:     puts("\033[H\033[2J*** REGISTERS: ***");
  230.                         for(J=0xFF40;J<0xFF50;J++)
  231.                           printf("(%Xh) = %Xh\n",J,RAM[J]);
  232.                         printf("ISWITCH = %Xh\n",ISWITCH);
  233.                         break;
  234.         case XK_F3:     puts("\033[H\033[2J*** SPRITES: ***");
  235.                         for(J=0xFE9C;J<0xFE9C+4*40;J+=4)
  236.                           printf
  237.                           (
  238.                             "SPRITE %d: %d,%d   Pat %d   Attr %d\n",
  239.                             (J-0xFE9C)/4,RAM[J+1],RAM[J],RAM[J+2],RAM[J+3]
  240.                           );
  241.                         break;
  242. #endif
  243.         case XK_Return: JoyState&=0x7F;break;
  244.         case XK_Tab:    JoyState&=0xBF;break;
  245.         case XK_Down:   JoyState&=0xF7;break;
  246.         case XK_Up:     JoyState&=0xFB;break;
  247.         case XK_Left:   JoyState&=0xFD;break;
  248.         case XK_Right:  JoyState&=0xFE;break;
  249.         case XK_z: case XK_x: case XK_c: case XK_v:
  250.         case XK_b: case XK_n: case XK_m: 
  251.         case XK_Z: case XK_X: case XK_C: case XK_V:
  252.         case XK_B: case XK_N: case XK_M: 
  253.         case XK_Alt_L:  JoyState&=0xDF;break;
  254.         case XK_a: case XK_s: case XK_d: case XK_f:
  255.         case XK_g: case XK_h: case XK_j:
  256.         case XK_A: case XK_S: case XK_D: case XK_F:
  257.         case XK_G: case XK_H: case XK_J:
  258.         case XK_space:  JoyState&=0xEF;break;
  259.       }
  260.     else
  261.      switch(J)
  262.       {
  263.         case XK_Return: JoyState|=0x80;break;
  264.         case XK_Tab:    JoyState|=0x40;break;
  265.         case XK_Down:   JoyState|=0x08;break;
  266.         case XK_Up:     JoyState|=0x04;break;
  267.         case XK_Left:   JoyState|=0x02;break;
  268.         case XK_Right:  JoyState|=0x01;break;
  269.         case XK_z: case XK_x: case XK_c: case XK_v:
  270.         case XK_b: case XK_n: case XK_m: 
  271.         case XK_Z: case XK_X: case XK_C: case XK_V:
  272.         case XK_B: case XK_N: case XK_M: 
  273.         case XK_Alt_L:  JoyState|=0x20;break;
  274.         case XK_a: case XK_s: case XK_d: case XK_f:
  275.         case XK_g: case XK_h: case XK_j:
  276.         case XK_A: case XK_S: case XK_D: case XK_F:
  277.         case XK_G: case XK_H: case XK_J:
  278.         case XK_space:  JoyState|=0x10;break;
  279.       }
  280.   }
  281.  
  282.   for(J=0;XCheckWindowEvent(Dsp,Wnd,FocusChangeMask,&E);)
  283.     J=(E.type==FocusOut);
  284.   if(SaveCPU&&J)
  285.   {
  286.     XAutoRepeatOn(Dsp);
  287.     while(!XCheckWindowEvent(Dsp,Wnd,FocusChangeMask,&E)&&CPURunning)
  288.     {
  289.       if(XCheckWindowEvent(Dsp,Wnd,ExposureMask,&E)) PutImage();
  290.       XPeekEvent(Dsp,&E);
  291.     }
  292.     XAutoRepeatOff(Dsp);
  293.   }
  294.  
  295.   return(JoyState);
  296. }
  297.  
  298.  
  299. /*** SIOSend ****************************************************/
  300. /*** Send a byte onto the serial line.                        ***/
  301. /****************************************************************/
  302. byte SIOSend(register byte V) { return(0); }
  303.  
  304.  
  305. /*** SIOReceive *************************************************/
  306. /*** Receive a byte from the serial line. Returns 1 on        ***/
  307. /*** success, 0 otherwise.                                    ***/
  308. /****************************************************************/
  309. byte SIOReceive(register byte *V) { return(0); }
  310.  
  311.  
  312. /****************************************************************/
  313. /*** Write value into sound chip register (Reg #0 at FF10h).  ***/
  314. /****************************************************************/
  315. void Sound(byte R,byte V) { return; }
  316.  
  317.  
  318. /** Common.h ****************************************************/
  319. /** Parts of the drivers common for Unix/X and MSDOS.          **/
  320. /****************************************************************/
  321. #include "Common.h"
  322.