home *** CD-ROM | disk | FTP | other *** search
- /** VGB: portable GameBoy emulator ***************************/
- /** **/
- /** Unix.c **/
- /** **/
- /** This file contains Unix/X-dependent subroutines and **/
- /** drivers. **/
- /** **/
- /** Copyright (C) Marat Fayzullin 1994,1995,1996 **/
- /** Elan Feingold 1995 **/
- /** You are not allowed to distribute this software **/
- /** commercially. Please, notify me, if you make any **/
- /** changes to this file. **/
- /*************************************************************/
-
- #define USE_XPAL /* We are using XPal[] to determine colors */
-
- /** Standard Unix/X #includes ********************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <sys/time.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/keysym.h>
-
- #include "GB.h"
-
-
- /** MIT Shared Memory Extension for X ************************/
- #ifdef MITSHM
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <X11/extensions/XShm.h>
- XShmSegmentInfo SHMInfo;
- int UseSHM=1;
- #endif
-
-
- /** Various X-related variables ******************************/
- Display *Dsp;
- Window Wnd;
- Colormap DefaultCMap;
- XImage *Img;
- GC DefaultGC;
- unsigned long White,Black;
-
-
- /** Various variables and short functions ********************/
- #define WIDTH 176 /* Width (>=176, must be divisible by 8) */
- #define HEIGHT 144 /* Height (>=144) */
-
- char *Title = "Virtual GameBoy Unix/X 0.7";
-
- int SaveCPU = 1;
-
- byte *XBuf,*ZBuf,XPal[12];
-
- char *ColorNames[12] =
- {
- "white","#989898","#585858","black",
- "white","#989898","#585858","black",
- "white","#989898","#585858","black"
- };
-
- void OnBreak(int Arg) { CPURunning=0; }
-
-
- /** InitMachine **********************************************/
- /** Allocate resources needed by Unix/X-dependent code. **/
- /*************************************************************/
- int InitMachine()
- {
- Screen *Scr;
- XEvent E;
- XGCValues values;
- XColor Color,C;
- int J;
-
- if(Verbose)
- printf("Initializing Unix/X drivers:\n Opening display...");
- Dsp=XOpenDisplay(NULL);
- if(!Dsp) { if(Verbose) printf("FAILED\n");return(0); }
-
- Scr=DefaultScreenOfDisplay(Dsp);
- White=WhitePixelOfScreen(Scr);
- Black=BlackPixelOfScreen(Scr);
- DefaultGC=DefaultGCOfScreen(Scr);
- DefaultCMap=DefaultColormapOfScreen(Scr);
-
- if(Verbose) printf("OK\n Opening window...");
- Wnd=
- XCreateSimpleWindow
- (Dsp,RootWindowOfScreen(Scr),0,0,160,144,0,White,Black);
- if(!Wnd) { if(Verbose) printf("FAILED\n");return(0); }
-
- {
- XSizeHints Hints;
- XWMHints WMHints;
-
- Hints.flags=PSize|PMinSize|PMaxSize;
- Hints.min_width=Hints.max_width=Hints.base_width=160;
- Hints.min_height=Hints.max_height=Hints.base_height=144;
- WMHints.input=True;WMHints.flags=InputHint;
- XSetWMHints(Dsp,Wnd,&WMHints);
- XSetWMNormalHints(Dsp,Wnd,&Hints);
- XStoreName(Dsp,Wnd,Title);
- }
-
- XSelectInput
- (Dsp,Wnd,FocusChangeMask|ExposureMask|KeyPressMask|KeyReleaseMask);
- XMapRaised(Dsp,Wnd);
- XClearWindow(Dsp,Wnd);
- XAutoRepeatOff(Dsp);
- XWindowEvent(Dsp,Wnd,ExposureMask,&E);
-
- if(Verbose) printf("OK\n Allocating Z-buffer...");
- if(!(ZBuf=malloc(2*WIDTH*HEIGHT/8))) return(0);
-
- #ifdef MITSHM
- if(UseSHM)
- {
- if(Verbose) printf("OK\n Using shared memory:\n Creating image...");
- Img=
- XShmCreateImage
- (Dsp,DefaultVisualOfScreen(Scr),8,ZPixmap,NULL,&SHMInfo,WIDTH,HEIGHT);
- if(!Img) { if(Verbose) printf("FAILED\n");return(0); }
-
- if(Verbose) printf("OK\n Getting SHM info...");
- SHMInfo.shmid=
- shmget(IPC_PRIVATE,Img->bytes_per_line*Img->height,IPC_CREAT|0777);
- if(SHMInfo.shmid<0) { if(Verbose) printf("FAILED\n");return(0); }
-
- if(Verbose) printf("OK\n Allocating SHM...");
- XBuf=(byte *)(Img->data=SHMInfo.shmaddr=shmat(SHMInfo.shmid,0,0));
- if(!XBuf) { if(Verbose) printf("FAILED\n");return(0); }
-
- SHMInfo.readOnly=False;
- if(Verbose) printf("OK\n Attaching SHM...");
- if(!XShmAttach(Dsp,&SHMInfo))
- { if(Verbose) printf("FAILED\n");return(0); }
- }
- else
- #endif
- {
- if(Verbose) printf("OK\n Allocating screen buffer...");
- XBuf=(byte *)malloc(sizeof(byte)*HEIGHT*WIDTH);
- if(!XBuf) { if(Verbose) printf("FAILED\n");return(0); }
-
- if(Verbose) printf("OK\n Creating image...");
- Img=
- XCreateImage
- (Dsp,DefaultVisualOfScreen(Scr),8,ZPixmap,0,XBuf,WIDTH,HEIGHT,8,0);
- if(!Img) { if(Verbose) printf("FAILED\n");return(0); }
- }
-
- if(Verbose) puts("OK");
-
- for(J=0;J<12;J++)
- XPal[J]=XAllocNamedColor(Dsp,DefaultCMap,ColorNames[J],&Color,&C)?
- Color.pixel : J&2? White:Black;
-
- signal(SIGHUP,OnBreak);signal(SIGINT,OnBreak);
- signal(SIGQUIT,OnBreak);signal(SIGTERM,OnBreak);
-
- return(1);
- }
-
-
- /** TrashMachine *********************************************/
- /** Deallocate all resources taken by InitMachine(). **/
- /*************************************************************/
- void TrashMachine()
- {
- if(Verbose) printf("Shutting down...\n");
-
- if(Dsp&&Wnd)
- {
- #ifdef MITSHM
- if(UseSHM)
- {
- XShmDetach(Dsp,&SHMInfo);
- if(SHMInfo.shmaddr) shmdt(SHMInfo.shmaddr);
- if(SHMInfo.shmid>=0) shmctl(SHMInfo.shmid,IPC_RMID,0);
- }
- else
- #endif MITSHM
- if(Img) XDestroyImage(Img);
- }
- if(ZBuf) free(ZBuf);
- if(Dsp) { XAutoRepeatOn(Dsp);XCloseDisplay(Dsp); }
- }
-
-
- /** PutImage *************************************************/
- /** Put an image on the screen. **/
- /*************************************************************/
- void PutImage()
- {
- #ifdef MITSHM
- if(UseSHM)
- XShmPutImage(Dsp,Wnd,DefaultGC,Img,(WIDTH-160)/2,0,0,0,160,144,False);
- else
- #endif
- XPutImage(Dsp,Wnd,DefaultGC,Img,(WIDTH-160)/2,0,0,0,160,144);
- XFlush(Dsp);
- }
-
-
- /** Joystick *************************************************/
- /** Return the current joystick state. **/
- /*************************************************************/
- byte Joystick(void)
- {
- static byte JoyState = 0xFF;
- XEvent E;
- word J;
-
- if(XCheckWindowEvent(Dsp,Wnd,KeyPressMask|KeyReleaseMask,&E))
- {
- J=XLookupKeysym((XKeyEvent *)&E,0);
- if(E.type==KeyPress)
- switch(J)
- {
- case XK_F12:
- case XK_Escape: CPURunning=0;break;
- #ifdef DEBUG
- case XK_F1: Trace=!Trace;break;
- case XK_F2: puts("\033[H\033[2J*** REGISTERS: ***");
- for(J=0xFF40;J<0xFF50;J++)
- printf("(%Xh) = %Xh\n",J,RAM[J]);
- printf("ISWITCH = %Xh\n",ISWITCH);
- break;
- case XK_F3: puts("\033[H\033[2J*** SPRITES: ***");
- for(J=0xFE9C;J<0xFE9C+4*40;J+=4)
- printf
- (
- "SPRITE %d: %d,%d Pat %d Attr %d\n",
- (J-0xFE9C)/4,RAM[J+1],RAM[J],RAM[J+2],RAM[J+3]
- );
- break;
- #endif
- case XK_Return: JoyState&=0x7F;break;
- case XK_Tab: JoyState&=0xBF;break;
- case XK_Down: JoyState&=0xF7;break;
- case XK_Up: JoyState&=0xFB;break;
- case XK_Left: JoyState&=0xFD;break;
- case XK_Right: JoyState&=0xFE;break;
- case XK_z: case XK_x: case XK_c: case XK_v:
- case XK_b: case XK_n: case XK_m:
- case XK_Z: case XK_X: case XK_C: case XK_V:
- case XK_B: case XK_N: case XK_M:
- case XK_Alt_L: JoyState&=0xDF;break;
- case XK_a: case XK_s: case XK_d: case XK_f:
- case XK_g: case XK_h: case XK_j:
- case XK_A: case XK_S: case XK_D: case XK_F:
- case XK_G: case XK_H: case XK_J:
- case XK_space: JoyState&=0xEF;break;
- }
- else
- switch(J)
- {
- case XK_Return: JoyState|=0x80;break;
- case XK_Tab: JoyState|=0x40;break;
- case XK_Down: JoyState|=0x08;break;
- case XK_Up: JoyState|=0x04;break;
- case XK_Left: JoyState|=0x02;break;
- case XK_Right: JoyState|=0x01;break;
- case XK_z: case XK_x: case XK_c: case XK_v:
- case XK_b: case XK_n: case XK_m:
- case XK_Z: case XK_X: case XK_C: case XK_V:
- case XK_B: case XK_N: case XK_M:
- case XK_Alt_L: JoyState|=0x20;break;
- case XK_a: case XK_s: case XK_d: case XK_f:
- case XK_g: case XK_h: case XK_j:
- case XK_A: case XK_S: case XK_D: case XK_F:
- case XK_G: case XK_H: case XK_J:
- case XK_space: JoyState|=0x10;break;
- }
- }
-
- for(J=0;XCheckWindowEvent(Dsp,Wnd,FocusChangeMask,&E);)
- J=(E.type==FocusOut);
- if(SaveCPU&&J)
- {
- XAutoRepeatOn(Dsp);
- while(!XCheckWindowEvent(Dsp,Wnd,FocusChangeMask,&E)&&CPURunning)
- {
- if(XCheckWindowEvent(Dsp,Wnd,ExposureMask,&E)) PutImage();
- XPeekEvent(Dsp,&E);
- }
- XAutoRepeatOff(Dsp);
- }
-
- return(JoyState);
- }
-
-
- /*** SIOSend ****************************************************/
- /*** Send a byte onto the serial line. ***/
- /****************************************************************/
- byte SIOSend(register byte V) { return(0); }
-
-
- /*** SIOReceive *************************************************/
- /*** Receive a byte from the serial line. Returns 1 on ***/
- /*** success, 0 otherwise. ***/
- /****************************************************************/
- byte SIOReceive(register byte *V) { return(0); }
-
-
- /****************************************************************/
- /*** Write value into sound chip register (Reg #0 at FF10h). ***/
- /****************************************************************/
- void Sound(byte R,byte V) { return; }
-
-
- /** Common.h ****************************************************/
- /** Parts of the drivers common for Unix/X and MSDOS. **/
- /****************************************************************/
- #include "Common.h"
-