1 /*
2
3 unix.c
4
5 This file contains system specific information
6 (e.g. displaying routines, joystick access,
7 window controls etc ...)
8
9 */
10
11 #ifdef UNIX
12
13 #ifdef GLIDE
14 #ifdef FRAMEBUFFER
15 #error: Do not try to make GLIDE & FRAMEBUFFER !!!
16 #endif
17 #if !defined JOYSTICK && !defined BSD_JOYSTICK
18 #error: Do not try to make GLIDE w/o JOYSTICK/BSD_JOYSTICK !!!
19 #endif
20 #endif
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26
27 #include "globals.h"
28 #include "sys.h"
29 #include "gameboy.h"
30 #include "z80.h"
31 #include "arplay.h"
32 #include "settings.h"
33
34 /* unix signal processing */
35 #define __USE_POSIX
36 #include <signal.h>
37 #include <sys/time.h>
38 #include <sys/types.h>
39
40 #ifndef GLIDE
41 /* X specific */
42 #include <X11/Xlib.h>
43 #include <X11/Xutil.h>
44 #include <X11/keysym.h>
45
46 #ifdef MIT_SHM
47 #include <X11/extensions/XShm.h>
48 #include <sys/shm.h>
49 #include <sys/ipc.h>
50 #endif
51
52 #ifdef WITH_XVIDEO
53 #include <X11/extensions/Xvlib.h>
54 #endif
55
56 #endif
57
58 #ifdef JOYSTICK
59 /* linux joystick device */
60 #include <linux/joystick.h>
61 #include <fcntl.h>
62 #include <sys/ioctl.h>
63 #endif
64 #ifdef BSD_JOYSTICK
65 /* BSD joystick device */
66 #include <sys/joystick.h>
67 #include <fcntl.h>
68 #include <sys/ioctl.h>
69 #endif
70
71 #ifdef FRAMEBUFFER
72 /* framebuffer device */
73 #include <fcntl.h>
74 #include <linux/fb.h>
75 #include <sys/ioctl.h>
76 #include <sys/mman.h>
77 #include <termios.h>
78 #include <linux/vt.h>
79
80 char *fbdevname="/dev/fb0";
81 struct fb_fix_screeninfo fb_finfo;
82 struct fb_var_screeninfo fb_vinfo,fb_vinfo_orig;
83 struct termios termsave;
84 struct vt_mode vt_modesave;
85
86 int fbdev,tty,fbgb_linesize,ttystate;
87 int usingfb;
88 char *fbmem,*fbgb;
89 #endif
90
91 #ifdef GLIDE
92 #include <glide.h>
93 #include <sst1vid.h>
94 #include <termios.h>
95
96 struct termios termsave;
97 #endif
98
99 #ifdef DIALOGLINK
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <netdb.h>
103
104 char *sock_tcpsignature="cingb___init___socket";
105 int dialoglink,dlglink_status,sock_d,sock_nd,sock_desc;
106
107 int dlglink_init(void);
108 #endif
109
110 /* experimental ***************************************/
111 #ifdef SOUND
112 #include "sound.h"
113 #endif
114
115 #include "joypad.h"
116
117 #ifndef GLIDE
118 char *gbwintitle="cingb";
119
120 Display *display;
121 Visual *visual;
122 Window gbwin;
123 Colormap colormap;
124 int screen;
125 XColor *colors;
126 static XImage *gameboyscreen;
127 GC gbgc;
128 static size_t lcdbuffersize=0;
129
130 #ifdef MIT_SHM
131 /* XShm */
132 static Status use_xshm;
133 static XShmSegmentInfo shminfo;
134 #endif
135
136 #ifdef WITH_XVIDEO
137 static int use_xvideo=0;
138 static unsigned int xv_port=0, xv_format;
139 static XvImage *xv_gameboyscreen;
140 static int win_width=GB_LCDXSCREENSIZE;
141 static int win_height=GB_LCDYSCREENSIZE;
142 #endif
143 #endif
144
145 int joypaddev,usejoypad,usekeys,timerset,
146 resolution,doublesize,dsupdatenow,usingsound,bitmapbits;
147 volatile int refreshtimer;
148 struct itimerval itv;
149 int REDSHL,GREENSHL,BLUESHL;
150 int REDOFS,GREENOFS,BLUEOFS;
151
152 #ifdef JOYSTICK
153 struct JS_DATA_TYPE js;
154 #endif
155 #ifdef BSD_JOYSTICK
156 struct joystick js;
157 #endif
158
159 uchar GB_STD8BITPAL[]=
160 {
161 215,
162 172,
163 86,
164 0
165 };
166
167 unsigned long int GB_STDPAL[4];
168
169
timerhandler(int signr)170 void timerhandler(int signr)
171 {
172 #ifdef _LINUX
173 signal(SIGALRM, timerhandler);
174 #endif
175 refreshtimer++;
176 }
177
178 #ifdef FRAMEBUFFER
179
FB_ClearScreen(void)180 void FB_ClearScreen(void)
181 {
182 memset(fbmem,0,fb_vinfo.xres*fb_vinfo.yres*resolution/8);
183 }
184
tty_switchhandler(int signal)185 void tty_switchhandler(int signal)
186 {
187 switch (signal) {
188 case SIGUSR1:
189 ttystate=0;
190 ioctl(tty, VT_RELDISP, 1);
191 break;
192 case SIGUSR2:
193 ttystate=1;
194 ioctl(tty, VT_RELDISP, VT_ACKACQ);
195 FB_ClearScreen();
196 break;
197 }
198 }
199
InitFB(void)200 int InitFB(void)
201 {
202 struct termios term;
203 struct vt_mode vtm;
204 struct sigaction old,now;
205
206 fbdev=open(fbdevname,O_RDWR,0);
207 if (!fbdev) {
208 fprintf(stderr,"Could not open %s or an X connection.\n",fbdevname);
209 return 1;
210 }
211 if (ioctl(fbdev,FBIOGET_FSCREENINFO,&fb_finfo)<0) {
212 fprintf(stderr,"Error: FBIOGET_FSCREENINFO\n");
213 return 1;
214 }
215 if (ioctl(fbdev,FBIOGET_VSCREENINFO,&fb_vinfo)<0) {
216 fprintf(stderr,"Error: FBIOGET_VSCREENINFO\n");
217 return 1;
218 }
219 bitmapbits=resolution=fb_vinfo.bits_per_pixel;
220
221 if (resolution<16) {
222 fprintf(stderr,"Sorry: I don't support %d bits resolution, yet.\n",
223 resolution);
224 return 1;
225 }
226 memcpy(&fb_vinfo_orig,&fb_vinfo,sizeof(fb_vinfo_orig));
227
228 fbmem=mmap(NULL,fb_finfo.smem_len,PROT_WRITE,
229 MAP_SHARED,fbdev,0);
230
231 if (fbmem==MAP_FAILED) {
232 fprintf(stderr,"Error: mmap failed.\n");
233 return 1;
234 }
235
236 if (!smallview) {
237 fbgb=fbmem+(fb_vinfo.xres-GB_LCDXSCREENSIZE*2)*resolution/16+
238 (fb_vinfo.yres-GB_LCDYSCREENSIZE*2)/2*fb_finfo.line_length;
239 fbgb_linesize=GB_LCDXSCREENSIZE*2*resolution/8;
240 } else {
241 fbgb=fbmem+(fb_vinfo.xres-GB_LCDXSCREENSIZE)*resolution/16+
242 (fb_vinfo.yres-GB_LCDYSCREENSIZE)/2*fb_finfo.line_length;
243 fbgb_linesize=GB_LCDXSCREENSIZE*resolution/8;
244 }
245
246
247 if (fb_vinfo.xoffset!=0 || fb_vinfo.yoffset!=0) {
248 fb_vinfo.xoffset=0;
249 fb_vinfo.yoffset=0;
250 if (ioctl(fbdev,FBIOPAN_DISPLAY,&fb_vinfo)<0) {
251 fprintf(OUTSTREAM,"Error: FBIOPAN_DISPLAY\n");
252 return 1;
253 }
254 }
255
256 usingfb=1;
257 FB_ClearScreen();
258
259 logfile=fopen("cingb.log","w");
260 if (logfile==NULL) {
261 fprintf(stdout,"Could not open logfile (using stdout).\n");
262 logfile=stdout;
263 }
264
265 #ifdef DEBUG
266 printf("FB_TYPE : %d\n",fb_finfo.type);
267 printf("FB_VISUAL: %d\n",fb_finfo.visual);
268 printf("Resolution: %dx%dx%d\n",fb_vinfo.xres,fb_vinfo.yres,
269 fb_vinfo.bits_per_pixel);
270 printf("Pixel format: red : %d-%d\n",fb_vinfo.red.offset,
271 fb_vinfo.red.offset+fb_vinfo.red.length-1);
272 printf(" green: %d-%d\n",fb_vinfo.green.offset,
273 fb_vinfo.green.offset+fb_vinfo.green.length-1);
274 printf(" blue : %d-%d\n",fb_vinfo.blue.offset,
275 fb_vinfo.blue.offset+fb_vinfo.blue.length-1);
276 #endif
277 REDOFS =fb_vinfo.red.offset;
278 GREENOFS=fb_vinfo.green.offset;
279 BLUEOFS =fb_vinfo.blue.offset;
280
281 REDSHL =fb_vinfo.red.length-5;
282 GREENSHL=fb_vinfo.green.length-5;
283 BLUESHL =fb_vinfo.blue.length-5;
284
285 /* init terminal settings */
286 fprintf(OUTSTREAM,"Setting up terminal ... ");
287 tcgetattr(0,&termsave);
288 memcpy(&term,&termsave,sizeof(struct termios));
289 cfmakeraw(&term);
290 term.c_iflag|=BRKINT;
291 term.c_lflag|=ISIG;
292 tcsetattr(0,TCSANOW,&term);
293 out_ok;
294
295 /* tty init */
296 fprintf(OUTSTREAM,"Setting up tty device ... ");
297 if ((tty=open("/dev/tty",O_RDWR))<0) {
298 fprintf(OUTSTREAM,"Error opening tty device.\n");
299 return 1;
300 }
301 if (ioctl(tty,VT_GETMODE,&vt_modesave)<0) {
302 fprintf(OUTSTREAM,"Error writing to tty device.\n");
303 return 1;
304 }
305 memcpy(&vtm,&vt_modesave,sizeof(struct vt_mode));
306 now.sa_handler = tty_switchhandler;
307 now.sa_flags = 0;
308 now.sa_restorer = NULL;
309 sigemptyset(&now.sa_mask);
310 sigaction(SIGUSR1,&now,&old);
311 sigaction(SIGUSR2,&now,&old);
312
313 vtm.mode = VT_PROCESS;
314 vtm.waitv = 0;
315 vtm.relsig = SIGUSR1;
316 vtm.acqsig = SIGUSR2;
317
318 if (ioctl(tty,VT_SETMODE,&vtm)<0) {
319 fprintf(OUTSTREAM,"Error writing to tty device.\n");
320 return 1;
321 }
322 ttystate=1;
323 out_ok;
324
325 return 0;
326 }
327
DoneFB(void)328 void DoneFB(void)
329 {
330 /* clean up */
331
332 ioctl(tty,VT_SETMODE,&vt_modesave);
333 close(tty);
334
335 tcsetattr(0,TCSANOW,&termsave);
336 FB_ClearScreen();
337
338 if (ioctl(fbdev,FBIOPUT_VSCREENINFO,&fb_vinfo_orig)<0) {
339 fprintf(stderr,"Error: FBIOPUT_VSCREENINFO. (restoring state)\n");
340 }
341
342 if (munmap(fbmem,fb_finfo.smem_len)) {
343 fprintf(stderr,"Error: munmap failed.\n");
344 }
345 close(fbdev);
346 #ifdef VERBOSE
347 fprintf(OUTSTREAM,"Framebuffer device closed.\n");
348 #endif
349 fclose(logfile);
350 logfile=stdout;
351 }
352 #endif
353
allocate_lcdbuffer(void)354 void allocate_lcdbuffer(void) {
355 lcdbuffersize=doublesize ?
356 GB_XBUFFERSIZE*GB_LCDYSCREENSIZE*(bitmapbits/2) :
357 GB_XBUFFERSIZE*GB_LCDYSCREENSIZE*(bitmapbits/8);
358 fprintf(OUTSTREAM,"Allocating lcd buffer (%lu bytes%s)... ",
359 (size_t)lcdbuffersize, doublesize ? "; double-size" : "");
360 lcdbuffer=malloc(lcdbuffersize);
361 if (lcdbuffer==NULL) out_failed; else out_ok;
362 }
363
364 #ifdef GLIDE
365
366 /* **************************************** */
initGlide(void)367 int initGlide(void)
368 {
369 GrHwConfiguration hwconfig;
370 struct termios term;
371
372 /* init terminal settings */
373 fprintf(OUTSTREAM,"Setting up terminal ... ");
374 tcgetattr(0,&termsave);
375 memcpy(&term,&termsave,sizeof(struct termios));
376 cfmakeraw(&term);
377 term.c_iflag|=BRKINT;
378 term.c_lflag|=ISIG;
379 tcsetattr(0,TCSANOW,&term);
380 out_ok;
381
382 fprintf(OUTSTREAM,"Initializing glide ... ");
383 grGlideInit();
384 fprintf(OUTSTREAM,"ok\nSearching glide hardware ...\n");
385 if (grSstQueryHardware(&hwconfig)==FXTRUE) {
386 grSstSelect(0);
387 if (grSstWinOpen(0,GR_RESOLUTION_640x480,GR_REFRESH_NONE,
388 GR_COLORFORMAT_ARGB,GR_ORIGIN_UPPER_LEFT,2,1)!=FXTRUE) {
389 fprintf(OUTSTREAM,
390 "*** Error: Failed to set the standard 640x480 mode.\n");
391 return 1;
392 }
393 } else {
394 fprintf(OUTSTREAM,"*** Error: glide hardware not found.\n");
395 return 1;
396 }
397
398 grColorCombine( GR_COMBINE_FUNCTION_LOCAL,
399 GR_COMBINE_FACTOR_NONE,
400 GR_COMBINE_LOCAL_CONSTANT,
401 GR_COMBINE_OTHER_NONE,
402 FXFALSE );
403
404 grBufferClear(0,0,0);
405 grBufferSwap(0);
406 grBufferClear(0,0,0);
407 grDisableAllEffects();
408
409 /* fixed sst1 format (there aren't others defined) */
410
411 bitmapbits=resolution=16;
412 REDSHL=BLUESHL=0;
413 GREENSHL=1;
414 REDOFS=11;
415 GREENOFS=5;
416 BLUEOFS=0;
417
418 out_ok;
419
420 allocate_lcdbuffer();
421
422 return 0;
423 }
doneGlide(void)424 void doneGlide(void)
425 {
426 grGlideShutdown();
427 tcsetattr(0,TCSANOW,&termsave);
428 }
429
430 #else
InitXConnection(void)431 int InitXConnection(void)
432 {
433 XVisualInfo visualinfo;
434 XVisualInfo *retvinfo;
435 char *displayname=NULL;
436 int i,v;
437 #ifdef MIT_SHM
438 int major,minor;
439 Bool shared;
440 #endif
441 #ifdef WITH_XVIDEO
442 unsigned int xv_ver, xv_rel, xv_reqbase, xv_eventbase, xv_errbase,
443 adaptorcount;
444 XvAdaptorInfo *adaptorinfo = NULL;
445 #endif
446
447 display=XOpenDisplay(displayname);
448
449 if (display==NULL)
450 {
451 #if defined(FRAMEBUFFER) && !defined(DEBUG)
452 return InitFB();
453 #else
454 fprintf(stderr,"Cannot connect to X-Server.\n");
455 return 1;
456 #endif
457 }
458
459 #ifdef WITH_XVIDEO
460
461 if (check_xvideo) {
462 fprintf(OUTSTREAM, "Checking for XVideo extension ... ");
463 use_xvideo=(XvQueryExtension(display, &xv_ver, &xv_rel,
464 &xv_reqbase, &xv_eventbase, &xv_errbase)==Success);
465 if (!use_xvideo) out_failed;
466 else {
467 out_ok;
468 fprintf(OUTSTREAM, "Fetching XVideo adapters ... ");
469 if (XvQueryAdaptors(display,DefaultRootWindow(display),
470 &adaptorcount,&adaptorinfo)!=Success){
471
472 use_xvideo=0;
473 out_failed;
474 } else out_ok;
475 }
476 } else {
477 use_xvideo=0;
478 }
479
480 if (use_xvideo) {
481 int i;
482 int inuse=0;
483
484 xv_port=0;
485 fprintf(OUTSTREAM, "Opening XVideo port (adapters: %d) ... ",
486 adaptorcount);
487
488 for (i=0; i<adaptorcount && xv_port==0; i++) {
489 if ((adaptorinfo[i].type&XvInputMask) &&
490 (adaptorinfo[i].type&XvImageMask)) {
491
492 XvPortID id;
493
494 for (id=adaptorinfo[i].base_id;
495 id<adaptorinfo[i].base_id+
496 adaptorinfo[i].num_ports; id++)
497
498 if (XvGrabPort(display, id,
499 CurrentTime)==Success) {
500
501 xv_port = id;
502 break;
503 } inuse=1;
504 }
505 }
506
507 if (xv_port==0) {
508 if (inuse) fprintf(OUTSTREAM, "all ports in use ");
509 out_failed;
510 use_xvideo=0;
511 } else {
512 int i;
513 int formats=0;
514 XvImageFormatValues *fo;
515
516 fo = XvListImageFormats(display, xv_port, (int*)&formats);
517
518 xv_format=0;
519 for(i=0; i<formats; i++){
520 fprintf(OUTSTREAM, "Available XVideo image format: 0x%x (%4.4s) %s\n", fo[i].id,(char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar");
521 if (xv_format==0 &&
522 (fo[i].id==0x59565955|| fo[i].id==0x55595659)) {
523 xv_format = fo[i].id;
524 fprintf(OUTSTREAM, "y:%d, u:%d, v:%d (bits/pixel:%d)\n",
525 fo[i].y_sample_bits,
526 fo[i].u_sample_bits,
527 fo[i].v_sample_bits, fo[i].bits_per_pixel);
528 }
529 }
530 fprintf(OUTSTREAM, "Selecting XVideo output format ... ");
531 if (xv_format==0) {
532 XvUngrabPort(display, xv_port, CurrentTime);
533 use_xvideo=0;
534 out_failed;
535 } else out_ok;
536 }
537 }
538 #endif
539
540 #ifdef MIT_SHM
541 use_xshm=XShmQueryVersion (display, &major, &minor, &shared) && shared;
542 #endif
543
544
545 #ifdef FRAMEBUFFER
546 usingfb=0;
547 #endif
548
549 if (!smallview) doublesize=1;
550
551 screen=DefaultScreen(display);
552 visual=DefaultVisual(display, screen);
553 visualinfo.visualid=visual->visualid;
554 retvinfo=XGetVisualInfo(display, VisualIDMask, &visualinfo, &i);
555 if (retvinfo==NULL) {
556 fprintf(stderr, "Error getting VisualInfo for visual id %u.\n",
557 (unsigned int)visual->visualid);
558 exit(-1);
559 }
560 memcpy(&visualinfo, retvinfo, sizeof(XVisualInfo));
561 XFree(retvinfo);
562
563 bitmapbits=BitmapUnit(display);
564
565 if (use_xvideo) {
566 bitmapbits=32;
567 fprintf(OUTSTREAM,"Screen bitmap bits is %i, resolution is %i bits (YUV).\n", bitmapbits, resolution);
568 } else {
569 resolution = visualinfo.depth;
570 fprintf(OUTSTREAM,"Screen bitmap bits is %i, resolution is %i bits.\n", bitmapbits, resolution);
571 }
572
573 if (bitmapbits==8) {
574 /* create a palette with 6 shades for every color
575 this will be slower (multiplication) but it
576 looks far better than 4 shades. */
577
578 colormap=XCreateColormap(display, RootWindow(display,screen),
579 visual,AllocAll);
580 colors=(XColor *)calloc(256,sizeof(XColor));
581 for (i=0;i<256;i++)
582 {
583 colors[i].pixel=i;
584 colors[i].flags=DoRed|DoGreen|DoBlue;
585
586 if (i<216)
587 {
588 v=(i / 36) % 6;
589 colors[i].red=v*13107;
590 v=(i / 6) % 6;
591 colors[i].green=v*13107;
592 v=i % 6;
593 colors[i].blue=v*13107;
594 }
595 }
596 XStoreColors(display,colormap,colors,256);
597 } else {
598 REDOFS=BLUEOFS=GREENOFS=0;
599 REDSHL=BLUESHL=GREENSHL=0;
600 for (i=visualinfo.red_mask;!(i&1);i>>=1,REDOFS++);
601 for (;i&1;i>>=1,REDSHL++);
602 for (i=visualinfo.green_mask;!(i&1);i>>=1,GREENOFS++);
603 for (;i&1;i>>=1,GREENSHL++);
604 for (i=visualinfo.blue_mask;!(i&1);i>>=1,BLUEOFS++);
605 for (;i&1;i>>=1,BLUESHL++);
606 REDSHL-=5;GREENSHL-=5;BLUESHL-=5;
607 }
608 return 0;
609 }
610 #endif
611
612 /* signal hookfunc */
DoBreak(int signum)613 void DoBreak(int signum)
614 {
615 if (!ABORT_EMULATION) {
616 ABORT_EMULATION=1;
617 savestate();
618 tidyup();
619 exit(0);
620 }
621 }
622
623 #ifdef MIT_SHM
xerrorhandler(Display * display,XErrorEvent * event)624 int xerrorhandler (Display *display, XErrorEvent *event) {
625 use_xshm=0;
626 return 0;
627 }
628 #endif
629
630
631 #ifndef GLIDE
InitXRessources(void)632 int InitXRessources(void)
633 {
634 XSetWindowAttributes gbwinattr;
635 XTextProperty prop_gbwintitle;
636 XGCValues values;
637 #ifdef MIT_SHM
638 XErrorHandler old_handler;
639 #endif
640
641
642 fprintf(OUTSTREAM,"Window initialization ... ");
643
644 gbwinattr.event_mask=StructureNotifyMask|ExposureMask|KeyPressMask|
645 KeyReleaseMask;
646 gbwinattr.colormap=colormap;
647 gbwinattr.border_pixel=0;
648
649 gbwin=XCreateWindow(display,
650 RootWindow(display,screen),
651 100,50,
652 smallview ? GB_LCDXSCREENSIZE : GB_LCDXSCREENSIZE*2,
653 smallview ? GB_LCDYSCREENSIZE : GB_LCDYSCREENSIZE*2,
654 0,resolution,
655 InputOutput,
656 visual,
657 CWEventMask|
658 CWColormap|
659 CWBorderPixel,
660 &gbwinattr);
661
662 if (!gbwin) {
663 out_failed;
664 return 1;
665 } else out_ok;
666
667 values.background=0;
668 gbgc=XCreateGC(display,gbwin,GCBackground,&values);
669
670 XStringListToTextProperty(&gbwintitle,1,&prop_gbwintitle);
671 XSetWMName(display,gbwin,&prop_gbwintitle);
672 /*XSelectInput(display,gbwin,ExposureMask|KeyPressMask|KeyReleaseMask);*/
673 XMapRaised(display,gbwin);
674 XFlush(display);
675
676 dsupdatenow=0;
677
678
679 fprintf(OUTSTREAM,"Display initialized.\nCreating display image buffer ... ");
680
681 #ifdef MIT_SHM
682 tryagain:
683 if (use_xshm) {
684
685 #ifdef WITH_XVIDEO
686 if (use_xvideo) {
687 fprintf(OUTSTREAM,"(xv+shared) ");
688 xv_gameboyscreen=(XvImage *)XvShmCreateImage(display,
689 xv_port, xv_format, lcdbuffer,
690 GB_XBUFFERSIZE*2, GB_LCDYSCREENSIZE, &shminfo);
691 if (xv_gameboyscreen==NULL) {
692 fprintf(OUTSTREAM,"screen allocation failed for XVideo"
693 " trying X11\n Creating image buffer ... ");
694 use_xvideo=0;
695 goto tryagain;
696 }
697 }
698 else
699 #endif
700 {
701 fprintf(OUTSTREAM,"(shared) ");
702 gameboyscreen=XShmCreateImage(display,visual,resolution,
703 ZPixmap,NULL,&shminfo,
704 smallview ? GB_XBUFFERSIZE : GB_XBUFFERSIZE*2,
705 smallview ? GB_LCDYSCREENSIZE : GB_LCDYSCREENSIZE*2);
706 }
707
708 if (gameboyscreen==NULL) {
709 use_xshm=0;
710 out_failed;
711 fprintf(OUTSTREAM,"Trying normal mode ...\n");
712 goto tryagain;
713 }
714
715 shminfo.shmid=shmget(IPC_PRIVATE,gameboyscreen->bytes_per_line*
716 gameboyscreen->height,
717 IPC_CREAT|0777);
718
719 if (shminfo.shmid<0) {
720 out_failed;
721 fprintf(OUTSTREAM,"Trying normal mode ...\n");
722 XDestroyImage(gameboyscreen);
723 use_xshm=0;
724 goto tryagain;
725 }
726
727 lcdbuffer=shminfo.shmaddr=gameboyscreen->data=shmat(shminfo.shmid,0,0);
728
729 if (!lcdbuffer) {
730 out_failed;
731 fprintf(OUTSTREAM,"Trying normal mode ...\n");
732 XDestroyImage(gameboyscreen);
733 shmctl(shminfo.shmid,IPC_RMID,0);
734 use_xshm=0;
735 goto tryagain;
736 }
737
738 shminfo.readOnly=False;
739 old_handler=XSetErrorHandler(xerrorhandler);
740 XShmAttach(display,&shminfo);
741 XSync(display,False);
742 XShmPutImage(display,gbwin,gbgc,gameboyscreen,8,0,0,0,
743 1,1,0);
744 XSync(display,False);
745 XSetErrorHandler (old_handler);
746
747 if (!use_xshm) {
748 out_failed;
749 fprintf(OUTSTREAM,"Trying normal mode ...\n");
750 XDestroyImage(gameboyscreen);
751 shmdt(shminfo.shmaddr);
752 shmctl(shminfo.shmid,IPC_RMID,0);
753 goto tryagain;
754 } else fprintf(OUTSTREAM,"shared OK\n");
755 } else {
756
757 #endif
758
759 allocate_lcdbuffer();
760 gameboyscreen=NULL;
761
762 #ifdef WITH_XVIDEO
763 xv_gameboyscreen=NULL;
764 if (use_xvideo) {
765 fprintf(OUTSTREAM,"(xv) ");
766 xv_gameboyscreen=(XvImage *)XvCreateImage(display,
767 xv_port, xv_format, lcdbuffer,
768 GB_XBUFFERSIZE*2, GB_LCDYSCREENSIZE);
769
770 if (xv_gameboyscreen==NULL) {
771 fprintf(OUTSTREAM,"screen allocation failed for XVideo"
772 " trying X11\n Creating image buffer ... ");
773 use_xvideo=0;
774 free(lcdbuffer);
775 goto tryagain;
776 }
777
778 } else
779 #endif
780 {
781 fprintf(OUTSTREAM,"(x11) ");
782 gameboyscreen=XCreateImage(display,visual,resolution,ZPixmap,
783 0, lcdbuffer,
784 smallview ? GB_XBUFFERSIZE : GB_XBUFFERSIZE*2,
785 smallview ? GB_LCDYSCREENSIZE : GB_LCDYSCREENSIZE*2,
786 bitmapbits,0);
787 }
788
789 #ifdef MIT_SHM
790 }
791 #endif
792
793
794 fprintf(OUTSTREAM,"Preparing image ... ");
795 if (!use_xvideo) {
796 fprintf(OUTSTREAM,"X11 ... ");
797 if (gameboyscreen) out_ok; else {
798 out_failed;
799 return 1;
800 }
801 } else {
802 fprintf(OUTSTREAM,"XVideo (using %d bytes) ... ",
803 xv_gameboyscreen->data_size);
804 if (!xv_gameboyscreen) {
805 out_failed;
806 return 1;
807 }
808
809 if (xv_gameboyscreen->data_size>lcdbuffersize) {
810 out_failed;
811 return 1;
812 }
813
814 doublesize=0;
815 smallview=1;
816 out_ok;
817 }
818
819 #ifndef DEBUG
820 XAutoRepeatOff(display);
821 #endif
822 return 0;
823 }
824 #endif
825
initsys(void)826 int initsys(void)
827 {
828 int retval;
829 #ifdef JOYSTICK
830 int status;
831 struct JS_DATA_SAVE_TYPE_32 jsd;
832 #endif
833
834 doublesize=0;
835 #if defined(GLIDE) && !defined(DEBUG)
836 retval=initGlide();
837 #else
838 if ((retval=InitXConnection())!=0) return 1;
839 if (!retval
840 #ifdef FRAMEBUFFER
841 && !usingfb
842 #endif
843 ) retval=InitXRessources();
844 #endif
845
846 #ifdef MIT_SHM
847 if (use_xshm)
848 #endif
849 fprintf(OUTSTREAM,"Buffer allocation ... ");
850
851 if (lcdbuffer==NULL) {
852 out_failed;
853 retval=1;
854 } else out_ok;
855
856 /* B/W palette initialisation */
857 GB_STDPAL[0]=color_translate(0x7FFF);
858 GB_STDPAL[1]=color_translate(0x56B5);
859 GB_STDPAL[2]=color_translate(0x2D6B);
860 GB_STDPAL[3]=color_translate(0x0000);
861
862 usejoypad=0;
863 #if defined JOYSTICK || defined BSD_JOYSTICK
864 fprintf(OUTSTREAM,"Opening joypad device ... ");
865 joypaddev=open(joy_device,O_RDONLY);
866 if (joypaddev<0) {
867 out_failed;
868 } else {
869 out_ok;
870 #ifdef JOYSTICK
871 fprintf(OUTSTREAM,"Reading joystick info ... ");
872 status=ioctl(joypaddev,JS_GET_ALL,&jsd);
873 if (status<0) {
874 out_failed;
875 close(joypaddev);
876 } else {
877 out_ok;
878 usejoypad=1;
879 }
880 #endif
881 #ifdef BSD_JOYSTICK
882 usejoypad=1;
883 #endif
884 }
885 #endif
886
887 #ifdef GLIDE
888 if (!usejoypad) {
889 doneGlide();
890 return 1;
891 }
892 #endif
893
894 signal(SIGHUP,DoBreak);signal(SIGINT,DoBreak);
895 signal(SIGQUIT,DoBreak);signal(SIGTERM,DoBreak);
896 signal(SIGPIPE,DoBreak);
897
898 #ifdef __SVR4
899 sigset(SIGALRM,timerhandler);
900 #else
901 signal(SIGALRM,timerhandler);
902 #endif
903
904
905 itv.it_value.tv_usec=20000;
906 itv.it_value.tv_sec=0;
907 itv.it_interval.tv_usec=20000;
908 itv.it_interval.tv_sec=0;
909 timerset=setitimer(ITIMER_REAL,&itv,NULL);
910 refreshtimer=0;
911 if (timerset<0) {
912 fprintf(OUTSTREAM,"setitimer() failed./n");
913 fprintf(OUTSTREAM,"no real-time emulation will be available.\n");
914 }
915
916
917 #ifdef SOUND
918 if (producesound) {
919 fprintf(OUTSTREAM,"Initialize sound emulation ... \n");
920 usingsound=initsound();
921 fprintf(OUTSTREAM,"Sound %s\n",usingsound ? "OK" : "FAILED");
922 }
923 #endif
924
925 #ifdef DIALOGLINK
926 if (dialoglink)
927 dlglink_status=dlglink_init();
928 #endif
929
930 return retval;
931 }
932
933 #ifndef GLIDE
DoneXConnection(void)934 void DoneXConnection(void)
935 {
936 #ifndef DEBUG
937 XAutoRepeatOn(display);
938 #endif
939
940 #ifdef WITH_XVIDEO
941 fprintf(OUTSTREAM, "Freeing XVideo ressources ... ");
942 if (use_xvideo && xv_port) {
943 XvUngrabPort(display, xv_port, CurrentTime);
944 }
945 #endif
946
947 #ifdef VERBOSE
948 fprintf(OUTSTREAM,"Destroying window and freeing memory ... ");
949 #endif
950
951 #ifdef MIT_SHM
952 if (use_xshm) {
953 XShmDetach(display,&shminfo);
954 }
955 #endif
956
957 #ifdef WITH_XVIDEO
958 if (!use_xvideo)
959 #endif
960 XDestroyImage(gameboyscreen);
961
962 #ifdef MIT_SHM
963 if (use_xshm) {
964 shmdt(shminfo.shmaddr);
965 shmctl(shminfo.shmid,IPC_RMID,0);
966 }
967 #endif
968
969 XUnmapWindow(display,gbwin);
970 XDestroyWindow(display,gbwin);
971 XFreeGC(display,gbgc);
972 if (bitmapbits==8) {
973 XFreeColormap(display,colormap);
974 free(colors);
975 }
976 #ifdef VERBOSE
977 out_ok;
978 #endif
979
980 #ifdef VERBOSE
981 fprintf(OUTSTREAM,"Shutting down X-connection ... ");fflush(stdout);
982 #endif
983 XCloseDisplay(display);
984 #ifdef VERBOSE
985 out_ok;
986 #endif
987 }
988 #endif
989
donesys(void)990 void donesys(void)
991 {
992 #ifdef DIALOGLINK
993 switch (dlglink_status) {
994 case 1:
995 close(sock_nd);
996 close(sock_d);
997 break;
998 case 2:
999 close(sock_d);
1000 break;
1001 }
1002 #endif
1003
1004 #ifdef SOUND
1005 if (producesound) {
1006 fprintf(OUTSTREAM,"Closing sound.\n");
1007 donesound();
1008 }
1009 #endif
1010
1011
1012 #if defined JOYSTICK || defined BSD_JOYSTICK
1013 #ifdef VERBOSE
1014 fprintf(OUTSTREAM,"Closing joypad device ... ");
1015 #endif
1016 if (joypaddev>0) close(joypaddev);
1017 out_ok;
1018 #endif
1019
1020
1021 #ifdef GLIDE
1022 doneGlide();
1023 #else
1024 #ifdef FRAMEBUFFER
1025 if (!usingfb)
1026 #endif
1027 DoneXConnection();
1028 #ifdef FRAMEBUFFER
1029 else DoneFB();
1030 #endif
1031 #endif
1032 }
1033
color_translate(unsigned short int gbcol)1034 unsigned int color_translate(unsigned short int gbcol)
1035 {
1036 /* hope, it works now for every type of visual */
1037
1038 if (!use_xvideo) {
1039
1040 if (bitmapbits>8)
1041 return (((gbcol&0x1F)<<REDSHL)<<REDOFS)|
1042 ((((gbcol>>5)&0x1F)<<GREENSHL)<<GREENOFS)|
1043 ((((gbcol>>10)&0x1F)<<BLUESHL)<<BLUEOFS);
1044 else
1045 return ((gbcol&0x1F)/6)*36+(((gbcol>>5)&0x1F)/6)*6+
1046 ((gbcol>>10)&0x1F)/6;
1047 } else {
1048 int r;
1049 int g;
1050 int b;
1051
1052 int y, u, v;
1053
1054 r=(gbcol&0x1F)<<3;
1055 g=((gbcol>>5)&0x1F)<<3;
1056 b=((gbcol>>10)&0x1F)<<3;
1057
1058 y = (((66*r+129*g+25*b)>>8)+16)&0xff;
1059 u = (((-38*r-74*g+112*b)>>8)+128);
1060 v = (((112*r-94*g-18*b)>>8)+128);
1061
1062 /*fprintf(stderr, "r: %d, g: %d, b: %d\n", r, g, b);
1063 fprintf(stderr, "y: %d, u: %d, v: %d\n", y, u, v);*/
1064
1065 return (y<<24)|(y<<8)|u|(v<<16);
1066
1067 /* return (v<<24)|(y<<16)|(u<<8)|y; */
1068
1069 }
1070 }
1071
drawscreen(void)1072 void drawscreen(void)
1073 {
1074 #ifndef GLIDE
1075 #ifdef FRAMEBUFFER
1076 int y;
1077 char *lcdpos,*buffer;
1078 register int x,v;
1079 char *buffer2;
1080 #endif
1081
1082 if (doublesize
1083 #ifdef MIT_SHM
1084 && !use_xshm
1085 #endif
1086 ) {
1087 if (dsupdatenow++==0) return;
1088 if (dsupdatenow>2) dsupdatenow=0;
1089 }
1090
1091 if (smallview) {
1092 #ifdef FRAMEBUFFER
1093 if (usingfb) {
1094 if (ttystate) {
1095 for (y=0,buffer=fbgb,lcdpos=lcdbuffer+resolution;
1096 y<GB_LCDYSCREENSIZE;y++,buffer+=fb_finfo.line_length,
1097 lcdpos+=GB_XBUFFERSIZE*resolution/8) {
1098 memcpy(buffer,lcdpos,fbgb_linesize);
1099 }
1100 }
1101 } else
1102 #endif
1103
1104 #ifdef MIT_SHM
1105 if (use_xshm) {
1106 #ifdef WITH_XVIDEO
1107 if (use_xvideo)
1108 XvShmPutImage(display, xv_port, gbwin, gbgc,
1109 xv_gameboyscreen, 16, 0,
1110 GB_LCDXSCREENSIZE*2, GB_LCDYSCREENSIZE,
1111 0,0,
1112 win_width, win_height,
1113 False);
1114 else
1115 #endif
1116 XShmPutImage(display,gbwin,gbgc,gameboyscreen,8,0,0,0,
1117 GB_LCDXSCREENSIZE,GB_LCDYSCREENSIZE,0);
1118 } else
1119 #endif
1120
1121 #ifdef WITH_XVIDEO
1122 if (use_xvideo) {
1123 XvPutImage(display, xv_port, gbwin, gbgc,
1124 xv_gameboyscreen, 16, 0,
1125 GB_LCDXSCREENSIZE*2, GB_LCDYSCREENSIZE,
1126 0,0,
1127 win_width, win_height);
1128 } else
1129 #endif
1130 XPutImage(display,gbwin,gbgc,gameboyscreen,8,0,0,0,
1131 GB_LCDXSCREENSIZE,GB_LCDYSCREENSIZE);
1132 } else {
1133 #ifdef FRAMEBUFFER
1134 if (usingfb) {
1135 if (ttystate) {
1136 for (y=0,buffer=fbgb,buffer2=fbgb+fb_finfo.line_length,
1137 lcdpos=lcdbuffer+resolution;
1138 y<GB_LCDYSCREENSIZE;y++,buffer+=fb_finfo.line_length<<1,
1139 buffer2+=fb_finfo.line_length<<1,
1140 lcdpos+=GB_XBUFFERSIZE*resolution/8) {
1141 switch (resolution) {
1142 case 8:
1143 for (x=0;x<GB_LCDXSCREENSIZE;x++) {
1144 v=((unsigned char *)lcdpos)[x];v|=v<<8;
1145 ((unsigned short int *)buffer)[x]=v;
1146 ((unsigned short int *)buffer2)[x]=v;
1147 }
1148 break;
1149 case 16:
1150 for (x=0;x<GB_LCDXSCREENSIZE;x++) {
1151 v=((unsigned short int *)lcdpos)[x];v|=v<<16;
1152 ((unsigned int *)buffer)[x]=v;
1153 ((unsigned int *)buffer2)[x]=v;
1154 }
1155 break;
1156 case 32:
1157 for (x=0;x<(GB_LCDXSCREENSIZE<<1);x+=2) {
1158 v=((unsigned int *)lcdpos)[x>>1];
1159 ((unsigned int *)buffer)[x]=v;
1160 ((unsigned int *)buffer)[x+1]=v;
1161 ((unsigned int *)buffer2)[x]=v;
1162 ((unsigned int *)buffer2)[x+1]=v;
1163 }
1164 break;
1165 }
1166 }
1167 }
1168 } else
1169 #endif
1170
1171 #ifdef MIT_SHM
1172 if (use_xshm) {
1173 XShmPutImage(display,gbwin,gbgc,gameboyscreen,16,0,0,0,
1174 GB_LCDXSCREENSIZE*2,GB_LCDYSCREENSIZE*2,
1175 0);
1176 } else
1177 #endif
1178 XPutImage(display,gbwin,gbgc,gameboyscreen,16,0,0,0,
1179 GB_LCDXSCREENSIZE*2,GB_LCDYSCREENSIZE*2);
1180 }
1181
1182 #ifdef FRAMEBUFFER
1183 if (!usingfb)
1184 #endif
1185 /* XFlush(display);*/
1186 #else
1187 /* Glide version of drawscreen *********************************** */
1188
1189 GrLfbInfo_t info;
1190 unsigned short int *buffer,*buffer2,*lcdpos;
1191 register int x,y;
1192 register unsigned int v;
1193
1194 if (!grLfbLock(GR_LFB_WRITE_ONLY,GR_BUFFER_BACKBUFFER,
1195 GR_LFBWRITEMODE_565,GR_ORIGIN_UPPER_LEFT,
1196 FXFALSE,&info)) {
1197 grGlideShutdown();
1198 printf("Lock failed.\n");
1199 ABORT_EMULATION=1;
1200 return;
1201 }
1202 buffer=info.lfbPtr+((240-GB_LCDYSCREENSIZE)*info.strideInBytes)+
1203 320-(GB_LCDXSCREENSIZE>>1);
1204 buffer2=buffer+(info.strideInBytes>>1);
1205
1206 for (y=0,lcdpos=(unsigned short int *)(lcdbuffer+resolution);
1207 y<GB_LCDYSCREENSIZE;y++,
1208 buffer+=info.strideInBytes,buffer2+=info.strideInBytes,
1209 lcdpos+=GB_XBUFFERSIZE) {
1210 for (x=0;x<GB_LCDXSCREENSIZE;x++) {
1211 v=lcdpos[x];v|=v<<16;
1212 ((unsigned int *)buffer)[x]=v;
1213 ((unsigned int *)buffer2)[x]=v;
1214 }
1215 }
1216
1217 grLfbUnlock(GR_LFB_WRITE_ONLY,GR_BUFFER_BACKBUFFER);
1218 grBufferSwap(1);
1219 #endif
1220
1221 if (usingsound) return;
1222
1223 if (timerset>=0) {
1224 while (refreshtimer<1); /* sync loop */
1225 } else {
1226 while (refreshtimer<3); /* sync loop */
1227 }
1228 refreshtimer=0;
1229 }
1230
joypad(void)1231 void joypad(void)
1232 {
1233 #if defined JOYSTICK || defined BSD_JOYSTICK
1234 int status;
1235 #endif
1236 #if defined(FRAMEBUFFER) || defined (GLIDE)
1237 int retval;
1238 fd_set rfds;
1239 struct timeval tv;
1240 #endif
1241 #ifndef GLIDE
1242 XEvent E;
1243
1244 #ifdef FRAMEBUFFER
1245 if (!usingfb) {
1246 #endif
1247 while (XCheckWindowEvent(display,gbwin,KeyPressMask,&E)) {
1248 usekeys=1;
1249 switch(XLookupKeysym((XKeyEvent *)&E,0)) {
1250 case GBPAD_up:
1251 newjoypadstate&=0xBF;
1252 break;
1253 case GBPAD_down:
1254 newjoypadstate&=0x7F;
1255 break;
1256 case GBPAD_left:
1257 newjoypadstate&=0xDF;
1258 break;
1259 case GBPAD_right:
1260 newjoypadstate&=0xEF;
1261 break;
1262 case GBPAD_a:
1263 newjoypadstate&=0xFE;
1264 break;
1265 case GBPAD_b:
1266 newjoypadstate&=0xFD;
1267 break;
1268 case GBPAD_start:
1269 newjoypadstate&=0xF7;
1270 break;
1271 case GBPAD_select:
1272 newjoypadstate&=0xFB;
1273 break;
1274 case XK_Escape:
1275 case XK_q:
1276 usekeys=0;
1277 DoBreak(0);
1278 break;
1279 case XK_Return:
1280 ar_enabled=ar_enabled ? 0 : 1;
1281 break;
1282 #ifdef DEBUG
1283 case XK_b:
1284 breakpoint=-1;
1285 skipover=0;
1286 usekeys=0;
1287 break;
1288 case XK_t:
1289 db_trace=db_trace ? 0 : 1;
1290 usekeys=0;
1291 break;
1292 #endif
1293 }
1294 }
1295
1296 while (XCheckWindowEvent(display,gbwin,KeyReleaseMask,&E)) {
1297 switch(XLookupKeysym((XKeyEvent *)&E,0)) {
1298 case GBPAD_up:
1299 newjoypadstate|=0x40;
1300 break;
1301 case GBPAD_down:
1302 newjoypadstate|=0x80;
1303 break;
1304 case GBPAD_left:
1305 newjoypadstate|=0x20;
1306 break;
1307 case GBPAD_right:
1308 newjoypadstate|=0x10;
1309 break;
1310 case GBPAD_a:
1311 newjoypadstate|=0x01;
1312 break;
1313 case GBPAD_b:
1314 newjoypadstate|=0x02;
1315 break;
1316 case GBPAD_start:
1317 newjoypadstate|=0x08;
1318 break;
1319 case GBPAD_select:
1320 newjoypadstate|=0x04;
1321 break;
1322 }
1323 if (newjoypadstate==0xFF) usekeys=0;
1324 }
1325
1326 while (XCheckWindowEvent(display, gbwin, StructureNotifyMask, &E)) {
1327 if (E.type==ConfigureNotify) {
1328 win_width=E.xconfigure.width;
1329 win_height=E.xconfigure.height;
1330 }
1331 }
1332 #ifdef FRAMEBUFFER
1333 }
1334 #endif
1335 #endif
1336
1337 #if defined(FRAMEBUFFER) || defined(GLIDE)
1338 #ifdef FRAMEBUFFER
1339 if (usingfb) {
1340 #endif
1341 FD_ZERO(&rfds);
1342 FD_SET(0,&rfds);
1343 tv.tv_sec=0;tv.tv_usec=0;
1344 retval=select(1,&rfds,NULL,NULL,&tv);
1345
1346 if (retval) {
1347 read(0,&retval,1);
1348 /*
1349 printf("Pressed: %i\n",retval&0xFF);
1350 */
1351
1352 switch (retval&0xFF) {
1353 case 27:
1354 FD_ZERO(&rfds);
1355 FD_SET(0,&rfds);
1356 tv.tv_sec=0;tv.tv_usec=0;
1357 retval=select(1,&rfds,NULL,NULL,&tv);
1358 if (retval) {
1359 read(0,&retval,1);
1360 read(0,&retval,1);
1361 switch (retval&0xFF) {
1362 /* case 65:printf("up\n");break;
1363 case 66:printf("down\n");break;
1364 case 67:printf("right\n");break;
1365 case 68:printf("left\n");break;*/
1366 }
1367 } else DoBreak(0);
1368 break;
1369 case 113:
1370 DoBreak(0);
1371 break;
1372 case 13:
1373 ar_enabled=ar_enabled ? 0 : 1;
1374 break;
1375 }
1376 }
1377 #ifdef FRAMEBUFFER
1378 }
1379 #endif
1380 #endif
1381
1382
1383 #if defined JOYSTICK || defined BSD_JOYSTICK
1384 if (usejoypad && (!usekeys)) {
1385 #ifdef JOYSTICK
1386 status=read(joypaddev,&js,JS_RETURN);
1387 if (status==JS_RETURN) {
1388 newjoypadstate=
1389 (js.x<joy_left ? 0 : 0x20)|
1390 (js.x>joy_right ? 0 : 0x10)|
1391 (js.y<joy_top ? 0 : 0x40)|
1392 (js.y>joy_bottom ? 0 : 0x80)|
1393 (js.buttons & joy_buttonA ? 0 : 0x01)|
1394 (js.buttons & joy_buttonB ? 0 : 0x02)|
1395 (js.buttons & joy_buttonSTART ? 0 : 0x08)|
1396 (js.buttons & joy_buttonSELECT ? 0 : 0x04);
1397 }
1398 #else
1399 status=read(joypaddev,&js,sizeof(struct joystick));
1400 if (status==sizeof(struct joystick)) {
1401 int buttons;
1402
1403 buttons=(js.b1&0xFF)|((js.b2&0xFF)<<8);
1404
1405 newjoypadstate=
1406 (js.x<joy_left ? 0 : 0x20)|
1407 (js.x>joy_right ? 0 : 0x10)|
1408 (js.y<joy_top ? 0 : 0x40)|
1409 (js.y>joy_bottom ? 0 : 0x80)|
1410 (buttons & joy_buttonA ? 0 : 0x01)|
1411 (buttons & joy_buttonB ? 0 : 0x02)|
1412 (buttons & joy_buttonSTART ? 0 : 0x08)|
1413 (buttons & joy_buttonSELECT ? 0 : 0x04);
1414 }
1415 #endif
1416 }
1417 #endif
1418 }
1419
1420 #ifndef GLIDE
vramdump(tilescreen,dataofs)1421 void vramdump(tilescreen,dataofs)
1422 int tilescreen;
1423 int dataofs;
1424 {
1425 char *dumpwintitle="VRAM dump";
1426 Window dumpwin;
1427 XSetWindowAttributes gbwinattr;
1428 XTextProperty prop_wintitle;
1429 XEvent E;
1430 int x,y,xx,yy;
1431 GC gc;
1432 XGCValues gcval;
1433 uchar *tileofs,*tile,*tdofs;
1434 uchar scan1,scan2;
1435
1436 #ifdef FRAMEBUFFER
1437 if (usingfb) return;
1438 #endif
1439
1440 gbwinattr.event_mask=ExposureMask|KeyPressMask;
1441 gbwinattr.colormap=colormap;
1442 gbwinattr.border_pixel=0;
1443 dumpwin=XCreateWindow(display,
1444 RootWindow(display,screen),
1445 300,50,256,256,
1446 0,resolution,
1447 InputOutput,
1448 visual,
1449 CWEventMask|
1450 CWColormap|
1451 CWBorderPixel,
1452 &gbwinattr);
1453
1454 if (!dumpwin) return;
1455
1456 XStringListToTextProperty(&dumpwintitle,1,&prop_wintitle);
1457 XSetWMName(display,dumpwin,&prop_wintitle);
1458 XSelectInput(display,dumpwin,ExposureMask|KeyPressMask);
1459 XMapRaised(display,dumpwin);
1460 XWindowEvent(display,dumpwin,ExposureMask,&E);
1461
1462 gcval.background=0;
1463 gc=XCreateGC(display,dumpwin,GCBackground,&gcval);
1464
1465 tileofs=vram[0]+0x1800+(tilescreen ? 0x400 : 0);
1466 tdofs=vram[0]+(dataofs ? 0x0000 : 0x1000);
1467 for (y=0;y<32;y++)
1468 for (x=0;x<32;x++) {
1469 tile=tdofs+(dataofs ? (int)tileofs[y*32+x]*16 :
1470 (int)((signed char)tileofs[y*32+x])*16);
1471 for (yy=0;yy<8;yy++) {
1472 scan1=(tile+yy*2)[0];
1473 scan2=(tile+yy*2)[1];
1474 for (xx=0;xx<8;xx++) {
1475 gcval.foreground=GB_STDPAL[3-(
1476 (BGP>>
1477 ((3-(((scan1>>(7-xx))&1)|(((scan2>>(7-xx))&1)<<1)))*2))&3)
1478 ];
1479 XChangeGC(display,gc,GCForeground,&gcval);
1480 XDrawLine(display,dumpwin,gc,x*8+xx,y*8+yy,
1481 x*8+xx,y*8+yy);
1482 }
1483 }
1484 }
1485
1486 XFreeGC(display,gc);
1487 while (1) {
1488 XNextEvent(display,&E);
1489 if (E.type==KeyPress) break;
1490 }
1491 fprintf(OUTSTREAM,"exited.\n");
1492 XDestroyWindow(display,dumpwin);
1493 }
1494 #endif
1495
1496 #ifdef DIALOGLINK
1497
dlglink_getbyte(void)1498 int dlglink_getbyte(void)
1499 {
1500 int c=0;
1501 fd_set fds;
1502 struct timeval tv;
1503
1504 FD_ZERO(&fds);
1505 FD_SET(sock_desc,&fds);
1506 tv.tv_sec=0;tv.tv_usec=0;
1507
1508 c=select(16,&fds,NULL,NULL,&tv);
1509
1510 if (c<=0) return -1;
1511
1512 if (recv(sock_desc,&c,1,0)<=0) return -1;
1513
1514 return c;
1515 }
1516
dlglink_sndbyte(int c)1517 void dlglink_sndbyte(int c)
1518 {
1519 while (send(sock_desc,&c,1,0)<=0);
1520 }
1521
dlglink_getstr(char * buf,int size)1522 void dlglink_getstr(char *buf,int size)
1523 {
1524 int n,ch;
1525
1526 for (n=0;n<size;n++) {
1527 while ((ch=dlglink_getbyte())<0);
1528 buf[n]=ch;
1529 }
1530 }
1531
dlglink_sndstr(char * buf,int size)1532 void dlglink_sndstr(char *buf,int size)
1533 {
1534 int n;
1535
1536 for (n=0;n<size;n++) dlglink_sndbyte(buf[n]);
1537 }
1538
1539 #define TCPPORT 9121
dlglink_init(void)1540 int dlglink_init(void)
1541 {
1542 struct sockaddr_in sock_name;
1543 int n;
1544 socklen_t sock_len;
1545 struct hostent *sock_hp;
1546 char buffer[64];
1547
1548 if ((sock_d=socket(AF_INET,SOCK_STREAM,0))<0) {
1549 fprintf(OUTSTREAM,"Error: socket initialization failed.\n");
1550 fprintf(OUTSTREAM,"No dialog link supported.\n");
1551 exit(1);
1552 }
1553
1554 sock_len=sizeof(struct sockaddr_in);
1555
1556 if (strlen(servername)==0) {
1557 /* server side init */
1558
1559 memset(&sock_name,0,sizeof(struct sockaddr_in));
1560
1561 sock_name.sin_family=AF_INET;
1562 sock_name.sin_port=htons(TCPPORT);
1563 n=INADDR_ANY;
1564 memcpy(&sock_name.sin_addr,&n,sizeof(n));
1565
1566 if (bind(sock_d,(struct sockaddr *)&sock_name,sock_len)<0) {
1567 fprintf(OUTSTREAM,"Error: bind to port %i failed.\n",TCPPORT);
1568 close(sock_d);
1569 exit(1);
1570 }
1571
1572 if (listen(sock_d,1)<0) {
1573 fprintf(OUTSTREAM,"Error: listen on port %i failed.\n",TCPPORT);
1574 close(sock_d);
1575 exit(1);
1576 }
1577
1578 fprintf(OUTSTREAM,"Waiting for the other side ... ");
1579 if ((sock_nd=accept(sock_d,(struct sockaddr *)&sock_name,&sock_len))<0) {
1580 out_failed;
1581 close(sock_d);
1582 exit(1);
1583 } else out_ok;
1584
1585
1586 sock_desc=sock_nd;
1587
1588 dlglink_sndstr(sock_tcpsignature,strlen(sock_tcpsignature)+1);
1589 dlglink_getstr(buffer,strlen(sock_tcpsignature)+1);
1590
1591 if (strcmp(buffer,sock_tcpsignature)) {
1592 fprintf(OUTSTREAM,"Not a cingb-socket ?\nReceived: %s\n",buffer);
1593 close(sock_d);
1594 exit(1);
1595 }
1596
1597 fprintf(OUTSTREAM,"Connection established.\n");
1598
1599 return 1;
1600
1601 } else {
1602 /* client side init */
1603
1604 if ((sock_hp=gethostbyname(servername))==NULL) {
1605 fprintf(OUTSTREAM,"Error: unknown host %s.\n",servername);
1606 fprintf(OUTSTREAM,"Closing emulation.\n");
1607 close(sock_d);
1608 exit(1);
1609 }
1610
1611 memset(&sock_name,0,sizeof(struct sockaddr_in));
1612
1613 sock_name.sin_family=AF_INET;
1614 sock_name.sin_port=htons(TCPPORT);
1615 memcpy(&sock_name.sin_addr,sock_hp->h_addr_list[0],sock_hp->h_length);
1616
1617 fprintf(OUTSTREAM,"Trying to connect to server ... ");
1618 if (connect(sock_d,(struct sockaddr *)&sock_name,sock_len)<0) {
1619 out_failed;
1620 close(sock_d);
1621 exit(1);
1622 } else out_ok;
1623
1624 sock_desc=sock_d;
1625
1626 dlglink_getstr(buffer,strlen(sock_tcpsignature)+1);
1627
1628 if (strcmp(buffer,sock_tcpsignature)) {
1629 fprintf(OUTSTREAM,"Not a cingb-socket ?\nReceived: %s\n",buffer);
1630 close(sock_d);
1631 exit(1);
1632 }
1633 dlglink_sndstr(sock_tcpsignature,strlen(sock_tcpsignature)+1);
1634
1635 fprintf(OUTSTREAM,"Connection established.\n");
1636
1637 return 2;
1638 }
1639 }
1640 #endif /* DIALOGLINK */
1641
1642 #endif /* UNIX */
1643