|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Amiga (native) specific support code; compiles with SAS/C 6.56,
5: * to get CyberGraphX support, add "DEFINE=_CYBERGFX" to the compiler
6: * flags in the smakefile. When running, hold down both Amiga keys
7: * to quit the emulation. The emulation also responds to ^C, which
8: * will abort it and to ^D which will reset it. Take care, the code
9: * appears to be very brittle and collapses easily if you switch
10: * screens. With CyberGraphX support enabled, the screen setup tries
11: * to be smart and falls back to standard screen update techniques
12: * if the screen to be opened does not belong to CyberGraphX. The
13: * 15/16/24 bit colour modes require that a graphics card like the
14: * CyberVision64 is installed that's not subject to byte ordering
15: * problems.
16: *
17: * (c) 1996 Olaf `Olsen' Barthel
18: */
19:
20: #include <intuition/intuitionbase.h>
21: #include <intuition/pointerclass.h>
22:
23: #include <graphics/gfxbase.h>
24: #include <graphics/displayinfo.h>
25:
26: #include <libraries/asl.h>
27:
28: #include <exec/memory.h>
29:
30: #include <dos/dos.h>
31: #include <dos/dosasl.h>
32:
33: #include <clib/intuition_protos.h>
34: #include <clib/graphics_protos.h>
35: #include <clib/exec_protos.h>
36: #include <clib/dos_protos.h>
37: #include <clib/asl_protos.h>
38:
39: #include <pragmas/intuition_pragmas.h>
40: #include <pragmas/graphics_pragmas.h>
41: #include <pragmas/exec_pragmas.h>
42: #include <pragmas/dos_pragmas.h>
43: #include <pragmas/asl_pragmas.h>
44:
45: #include <stdlib.h>
46: #include <string.h>
47: #include <stdio.h>
48:
49: #ifdef _CYBERGFX
50: #include <cybergraphics/cybergraphics.h>
51: #include <clib/cybergraphics_protos.h>
52: #include <pragmas/cybergraphics_pragmas.h>
53: #endif
54:
55: /****************************************************************************/
56:
57: #include "custom.h"
58: #include "options.h"
59: #include "keybuf.h"
60: #include "filesys.h"
61: #include "xwin.h"
62:
63: /****************************************************************************/
64:
65: extern struct ExecBase *SysBase;
66: extern struct DosLibrary *DOSBase;
67:
68: struct IntuitionBase *IntuitionBase;
69: struct GfxBase *GfxBase;
70: struct Library *AslBase;
71: struct Library *CyberGfxBase;
72:
73: /****************************************************************************/
74:
75: STATIC struct Screen *Screen;
76: STATIC struct Window *Window;
77: STATIC Object *Pointer;
78: STATIC ULONG WindowMask;
79:
80: STATIC struct RastPort *TempRPort,
81: *RenderPort;
82: STATIC struct BitMap *BitMap;
83: STATIC UBYTE *Line;
84:
85: STATIC LONG ScreenHeight,
86: ScreenWidth;
87:
88: /****************************************************************************/
89:
90: int buttonstate[3];
91: int lastmx, lastmy;
92: int newmousecounters;
93: long int xcolors[4096];
94: struct vidbuf_description gfxvidinfo;
95:
96: /****************************************************************************/
97:
98: void MC68000_reset(void);
99:
100: /****************************************************************************/
101:
102: STATIC VOID
103: AmigaCleanup(VOID)
104: {
105: if(BitMap)
106: {
107: WaitBlit();
108: FreeBitMap(BitMap);
109: BitMap = NULL;
110: }
111:
112: if(TempRPort)
113: {
114: FreeVec(TempRPort);
115: TempRPort = NULL;
116: }
117:
118: if(Line)
119: {
120: FreeVec(Line);
121: Line = NULL;
122: }
123:
124: if(Window)
125: {
126: CloseWindow(Window);
127: Window = NULL;
128: }
129:
130: if(Pointer)
131: {
132: DisposeObject(Pointer);
133: Pointer = NULL;
134: }
135:
136: if(Screen)
137: {
138: CloseScreen(Screen);
139: Screen = NULL;
140: }
141:
142: if(AslBase)
143: {
144: CloseLibrary(AslBase);
145: AslBase = NULL;
146: }
147:
148: if(GfxBase)
149: {
150: CloseLibrary(GfxBase);
151: GfxBase = NULL;
152: }
153:
154: if(IntuitionBase)
155: {
156: CloseLibrary(IntuitionBase);
157: IntuitionBase = NULL;
158: }
159:
160: if(CyberGfxBase)
161: {
162: CloseLibrary(CyberGfxBase);
163: CyberGfxBase = NULL;
164: }
165: }
166:
167: void
168: flush_line(int y)
169: {
170: if(!CyberGfxBase)
171: {
172: if(y >= 0 && y < ScreenHeight)
173: {
174: char *linebuf = y * gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
175:
176: CopyMem(linebuf,Line,ScreenWidth);
177: WritePixelLine8(RenderPort,0,y,ScreenWidth,Line,TempRPort);
178: }
179: }
180: }
181:
182: void
183: flush_block(int ystart,int ystop)
184: {
185: if(!CyberGfxBase)
186: {
187: if(ystart < 0)
188: ystart = 0;
189: else
190: {
191: if(ystart >= ScreenHeight)
192: ystart = ScreenHeight - 1;
193: }
194:
195: if(ystop < 0)
196: ystop = 0;
197: else
198: {
199: if(ystop >= ScreenHeight)
200: ystop = ScreenHeight - 1;
201: }
202:
203: if(ystart <= ystop)
204: {
205: char *mem;
206: int i;
207:
208: mem = ystart * gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
209:
210: for(i = ystart ; i <= ystop ; i++, mem += gfxvidinfo.rowbytes)
211: {
212: CopyMem(mem,Line,ScreenWidth);
213: WritePixelLine8(RenderPort,0,i,ScreenWidth,Line,TempRPort);
214: }
215: }
216: }
217: }
218:
219: void
220: flush_screen(int ystart,int ystop)
221: {
222: }
223:
224: static int
225: get_color(int r,int g,int b,long *cnp)
226: {
227: ULONG Red,Green,Blue;
228: LONG Pen;
229:
230: Red = 0x11111111 * r;
231: Green = 0x11111111 * g;
232: Blue = 0x11111111 * b;
233:
234: Pen = ObtainBestPen(Screen->ViewPort.ColorMap,Red,Green,Blue,
235: OBP_Precision,PRECISION_IMAGE,
236: TAG_DONE);
237:
238: if(Pen == -1)
239: return(0);
240: else
241: {
242: *cnp = Pen;
243:
244: return(1);
245: }
246: }
247:
248: int
249: graphics_init(void)
250: {
251: struct ScreenModeRequester *ScreenRequest;
252: ULONG DisplayID;
253: struct BitMap PointerBitMap;
254: UWORD PointerLine;
255: struct DimensionInfo Dims;
256: BOOL GotOne;
257: LONG Depth;
258: int vsize;
259:
260: atexit(AmigaCleanup);
261:
262: vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
263:
264: if(!(gfxvidinfo.bufmem = malloc(800 * vsize)))
265: {
266: fprintf(stderr,"Sorry guv'nor, not enough memory for the line buffer.\n");
267: return(0);
268: }
269:
270: memset(gfxvidinfo.bufmem,0,800 * vsize);
271:
272: gfxvidinfo.rowbytes = 800;
273: gfxvidinfo.pixbytes = 1;
274: gfxvidinfo.maxblocklines = 100;
275:
276: if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",39)))
277: {
278: fprintf(stderr,"Sorry guv'nor, unable to open intuition.library v39.\n");
279: return(0);
280: }
281:
282: if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39)))
283: {
284: fprintf(stderr,"Sorry guv'nor, unable to open graphics.library v39.\n");
285: return(0);
286: }
287:
288: DisplayID = INVALID_ID;
289: GotOne = FALSE;
290:
291: while((DisplayID = NextDisplayInfo(DisplayID)) != INVALID_ID)
292: {
293: if(GetDisplayInfoData(NULL,(APTR)&Dims,sizeof(Dims),DTAG_DIMS,DisplayID))
294: {
295: if(Dims.MaxDepth >= 8)
296: {
297: GotOne = TRUE;
298: break;
299: }
300: }
301: }
302:
303: if(!GotOne)
304: {
305: fprintf(stderr,"Sorry guv'nor, your Amiga needs an AA chip set or a graphics card.\n");
306: return(0);
307: }
308:
309: if(!(AslBase = OpenLibrary("asl.library",38)))
310: {
311: fprintf(stderr,"Sorry guv'nor, unable to open asl.library v38.\n");
312: return(0);
313: }
314:
315: if(!(ScreenRequest = AllocAslRequest(ASL_ScreenModeRequest,NULL)))
316: {
317: fprintf(stderr,"Sorry guv'nor, unable to allocate screen mode requester.\n");
318: return(0);
319: }
320:
321: if(AslRequestTags(ScreenRequest,
322: ASLSM_TitleText, "Select screen display mode",
323: ASLSM_MinDepth, 8,
324: TAG_DONE))
325: {
326: DisplayID = ScreenRequest->sm_DisplayID;
327:
328: GetDisplayInfoData(NULL,(APTR)&Dims,sizeof(Dims),DTAG_DIMS,DisplayID);
329:
330: Depth = Dims.MaxDepth;
331:
332: if(Depth > 8)
333: color_mode = 1;
334: }
335: else
336: DisplayID = INVALID_ID;
337:
338: FreeAslRequest(ScreenRequest);
339:
340: CloseLibrary(AslBase);
341: AslBase = NULL;
342:
343: if(DisplayID == INVALID_ID)
344: return(0);
345:
346: if(!(Screen = OpenScreenTags(NULL,
347: SA_DisplayID, DisplayID,
348: SA_Depth, Depth,
349: SA_Interleaved, TRUE,
350: SA_ShowTitle, FALSE,
351: SA_BackFill, LAYERS_NOBACKFILL,
352: SA_Quiet, TRUE,
353: SA_Behind, TRUE,
354: SA_SharePens, TRUE,
355: SA_Exclusive, TRUE,
356: SA_Draggable, FALSE,
357: TAG_DONE)))
358: {
359: fprintf(stderr,"Sorry guv'nor, unable to open the screen.\n");
360: return(0);
361: }
362:
363: ScreenWidth = Screen->Width;
364: ScreenHeight = Screen->Height;
365:
366: if(ScreenWidth > 800)
367: ScreenWidth = 800;
368:
369: if(ScreenHeight > 600)
370: ScreenHeight = 600;
371:
372: #ifdef _CYBERGFX
373: if(CyberGfxBase = OpenLibrary("cybergraphics.library",40))
374: {
375: if(!IsCyberModeID(DisplayID) || ScreenHeight < vsize)
376: {
377: CloseLibrary(CyberGfxBase);
378: CyberGfxBase = NULL;
379: }
380: }
381: #endif
382:
383: if(!(BitMap = AllocBitMap(Screen->Width,1,8,BMF_CLEAR|BMF_MINPLANES,Screen->RastPort.BitMap)))
384: {
385: fprintf(stderr,"Sorry guv'nor, unable to allocate BitMap.\n");
386: return(0);
387: }
388:
389: if(!(TempRPort = AllocVec(sizeof(struct RastPort),MEMF_ANY|MEMF_PUBLIC)))
390: {
391: fprintf(stderr,"Sorry guv'nor, unable to allocate RastPort.\n");
392: return(0);
393: }
394:
395: if(!(Line = AllocVec((Screen->Width + 15) & ~15,MEMF_ANY|MEMF_PUBLIC)))
396: {
397: fprintf(stderr,"Sorry guv'nor, unable to allocate raster buffer.\n");
398: return(0);
399: }
400:
401: CopyMem(&Screen->RastPort,TempRPort,sizeof(struct RastPort));
402: TempRPort->Layer = NULL;
403: TempRPort->BitMap = BitMap;
404:
405: PointerLine = 0x0000;
406:
407: InitBitMap(&PointerBitMap,2,16,1);
408: PointerBitMap.Planes[0] = (PLANEPTR)&PointerLine;
409: PointerBitMap.Planes[1] = (PLANEPTR)&PointerLine;
410:
411: if(!(Pointer = NewObject(NULL,POINTERCLASS,
412: POINTERA_BitMap, &PointerBitMap,
413: POINTERA_WordWidth, 1,
414: TAG_DONE)))
415: {
416: fprintf(stderr,"Sorry guv'nor, unable to allocate blank mouse pointer.\n");
417: return(0);
418: }
419:
420: if(!(Window = OpenWindowTags(NULL,
421: WA_Width, Screen->Width,
422: WA_Height, Screen->Height,
423: WA_CustomScreen, Screen,
424: WA_Backdrop, TRUE,
425: WA_Borderless, TRUE,
426: WA_BackFill, LAYERS_NOBACKFILL,
427: WA_RMBTrap, TRUE,
428: WA_IDCMP, IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
429: WA_Pointer, Pointer,
430: WA_ReportMouse, TRUE,
431: TAG_DONE)))
432: {
433: fprintf(stderr,"Sorry guv'nor, unable to open the window.\n");
434: return(0);
435: }
436:
437: RenderPort = &Screen->RastPort;
438:
439: WindowMask = 1UL << Window->UserPort->mp_SigBit;
440:
441: SetRast(RenderPort,0);
442:
443: switch(Depth)
444: {
445: case 8:
446:
447: alloc_colors256(get_color);
448: break;
449:
450: case 15:
451:
452: alloc_colors64k(5,5,5,10,5,0);
453: break;
454:
455: case 16:
456:
457: alloc_colors64k(5,6,5,11,5,0);
458: break;
459:
460: case 24:
461: case 32:
462:
463: alloc_colors64k(8,8,8,16,8,0);
464: break;
465: }
466:
467: ScreenToFront(Screen);
468: ActivateWindow(Window);
469:
470: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
471:
472: lastmx = lastmy = 0;
473: newmousecounters = 0;
474:
475: #ifdef _CYBERGFX
476: if(CyberGfxBase)
477: {
478: free(gfxvidinfo.bufmem);
479:
480: gfxvidinfo.bufmem = (char *)GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_DISPADR);
481: gfxvidinfo.rowbytes = GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_XMOD);
482: gfxvidinfo.pixbytes = GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_BPPIX);
483: }
484: #endif
485: return(1);
486: }
487:
488: void
489: graphics_leave(void)
490: {
491: AmigaCleanup();
492: }
493:
494: void
495: handle_events(void)
496: {
497: ULONG Mask;
498:
499: Mask = SetSignal(0,SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|WindowMask);
500:
501: if(Mask & SIGBREAKF_CTRL_C)
502: {
503: PrintFault(ERROR_BREAK,"uae");
504: exit(RETURN_WARN);
505: }
506:
507: if(Mask & SIGBREAKF_CTRL_D)
508: MC68000_reset();
509:
510: if(Mask & WindowMask)
511: {
512: struct IntuiMessage *IMsg;
513: ULONG MsgClass;
514: UWORD MsgCode;
515: WORD MsgX,MsgY;
516: WORD Button;
517: BOOL Quit;
518:
519: newmousecounters = 0;
520: Quit = FALSE;
521:
522: while(IMsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
523: {
524: MsgClass = IMsg->Class;
525: MsgCode = IMsg->Code;
526: MsgX = IMsg->MouseX;
527: MsgY = IMsg->MouseY;
528:
529: if((IMsg->Qualifier & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)) == (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
530: Quit = TRUE;
531:
532: ReplyMsg(IMsg);
533:
534: switch(MsgClass)
535: {
536: case IDCMP_RAWKEY:
537:
538: if(MsgCode & IECODE_UP_PREFIX)
539: record_key(((MsgCode & ~IECODE_UP_PREFIX) << 1) | 1);
540: else
541: record_key((MsgCode) << 1);
542:
543: break;
544:
545: case IDCMP_MOUSEBUTTONS:
546:
547: switch(MsgCode & ~IECODE_UP_PREFIX)
548: {
549: case IECODE_LBUTTON:
550:
551: Button = 0;
552: break;
553:
554: case IECODE_MBUTTON:
555:
556: Button = 1;
557: break;
558:
559: case IECODE_RBUTTON:
560:
561: Button = 2;
562: break;
563: }
564:
565: if(MsgCode & IECODE_UP_PREFIX)
566: buttonstate[Button] = 0;
567: else
568: buttonstate[Button] = 1;
569:
570: break;
571:
572: case IDCMP_MOUSEMOVE:
573:
574: lastmx = MsgX;
575: lastmy = MsgY;
576:
577: newmousecounters = 1;
578:
579: break;
580: }
581: }
582:
583: if(Quit)
584: exit(RETURN_OK);
585: }
586: }
587:
588: int
589: debuggable(void)
590: {
591: return 1;
592: }
593:
594: int
595: needmousehack(void)
596: {
597: return 1;
598: }
599:
600: void
601: LED(int on)
602: {
603: }
604:
605: /****************************************************************************/
606:
607: int quit_program;
608:
609: int
610: gui_init(void)
611: {
612: quit_program = 0;
613: }
614:
615: void
616: gui_exit(void)
617: {
618: }
619:
620: void
621: gui_led(int led, int on)
622: {
623: }
624:
625: void
626: gui_filename(int num, char *name)
627: {
628: }
629:
630: void
631: gui_handle_events(void)
632: {
633: }
634:
635: /****************************************************************************/
636:
637: int opterr = 1; /* error => print message */
638: int optind = 1; /* next argv[] index */
639: char *optarg = NULL; /* option parameter if any */
640:
641: static int
642: Err( name, mess, c ) /* returns '?' */
643: char *name; /* program name argv[0] */
644: char *mess; /* specific message */
645: int c; /* defective option letter */
646: {
647: if ( opterr )
648: (void) fprintf( stderr,
649: "%s: %s -- %c\n",
650: name, mess, c
651: );
652:
653: return '?'; /* erroneous-option marker */
654: }
655:
656: int
657: getopt( argc, argv, optstring ) /* returns letter, '?', EOF */
658: int argc; /* argument count from main */
659: char *argv[]; /* argument vector from main */
660: char *optstring; /* allowed args, e.g. "ab:c" */
661: {
662: static int sp = 1; /* position within argument */
663: register int osp; /* saved `sp' for param test */
664: register int c; /* option letter */
665: register char *cp; /* -> option in `optstring' */
666:
667: optarg = NULL;
668:
669: if ( sp == 1 ) /* fresh argument */
670: if ( optind >= argc /* no more arguments */
671: || argv[optind][0] != '-' /* no more options */
672: || argv[optind][1] == '\0' /* not option; stdin */
673: )
674: return EOF;
675: else if ( strcmp( argv[optind], "--" ) == 0 )
676: {
677: ++optind; /* skip over "--" */
678: return EOF; /* "--" marks end of options */
679: }
680:
681: c = argv[optind][sp]; /* option letter */
682: osp = sp++; /* get ready for next letter */
683:
684: if ( argv[optind][sp] == '\0' ) /* end of argument */
685: {
686: ++optind; /* get ready for next try */
687: sp = 1; /* beginning of next argument */
688: }
689:
690: if ( c == ':' /* optstring syntax conflict */
691: || (cp = strchr( optstring, c )) == NULL /* not found */
692: )
693: return Err( argv[0], "illegal option", c );
694:
695: if ( cp[1] == ':' ) /* option takes parameter */
696: {
697: if ( osp != 1 )
698: return Err( argv[0],
699: "option must not be clustered",
700: c
701: );
702:
703: if ( sp != 1 ) /* reset by end of argument */
704: return Err( argv[0],
705: "option must be followed by white space",
706: c
707: );
708:
709: if ( optind >= argc )
710: return Err( argv[0],
711: "option requires an argument",
712: c
713: );
714:
715: optarg = argv[optind]; /* make parameter available */
716: ++optind; /* skip over parameter */
717: }
718:
719: return c;
720: }
721:
722: /****************************************************************************/
723:
724: static void usage(void)
725: {
726: printf("UAE - The Un*x Amiga emulator\n");
727: printf("Summary of command-line options:\n");
728: printf(" -h : Print help\n");
729: printf(" -m VOLNAME:mount_point : mount file system at <mount point> as AmigaDOS\n"
730: " volume VOLNAME:\n");
731: printf(" -M VOLNAME:mount_point : like -m, but mount read-only\n");
732: printf(" -a : Don't mount the harddisk file automatically.\n"
733: " Useful only for testing.\n");
734: printf(" -S : Turn off sound support (if it is configured)\n");
735: printf(" -s : Emulate 1 MB slow memory at 0xC00000\n");
736: printf(" -F n : Emulate n MB fast memory at 0x200000\n");
737: printf(" -f n : Set the frame rate to 1/n\n");
738: printf(" -x : Use visible cross-hair cursor (X Windows version)\n");
739: printf(" -D : Start up the built-in debugger\n");
740: printf(" -[0123] file : Use file instead of df[0123].adf as disk image file\n");
741: printf(" -r file : Use file as ROM image instead of kick.rom\n");
742: printf(" -J : Fake joystick emulation with the numeric pad.\n");
743: printf(" -g : Turn on gfx-lib replacement.\n");
744: printf(" -d mode : Select resolution with the mode parameter.\n");
745: printf(" -H mode : Set the number of colors with the mode parameter.\n");
746: printf("\n");
747: printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n"
748: " 4 (800x600, correct aspect)\n"
749: "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
750: "UAE may choose to ignore the color mode/resolution setting.\n");
751: }
752:
753: void parse_cmdline(int argc, char **argv)
754: {
755: extern ULONG fastmem_size;
756:
757: int c;
758:
759: while(((c = getopt(argc, argv, "l:Df:gd:hxF:asSJm:M:0:1:2:3:r:H:")) != EOF)) switch(c) {
760: case 'h': usage(); exit(0);
761:
762: case '0': strncpy(df0, optarg, 255); df0[255] = 0; break;
763: case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
764: case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
765: case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
766: case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
767:
768: case 'm':
769: case 'M':
770: {
771: /* mount file system (repeatable)
772: * syntax: [-m | -M] VOLNAME:/mount_point
773: * example: -M CDROM:/cdrom -m UNIXFS:./disk
774: */
775: static int mount_seen = 0;
776: char buf[256];
777: char *s2;
778: int readonly = (c == 'M');
779:
780: if (mount_seen)
781: fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n");
782: mount_seen = 1;
783: strncpy(buf, optarg, 255); buf[255] = 0;
784: s2 = strchr(buf, ':');
785: if(s2) {
786: *s2++ = '\0';
787: add_filesys_unit(buf, s2, readonly);
788: } else {
789: fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
790: }
791: }
792: break;
793:
794: case 'S': produce_sound = 0; break;
795: case 'f': framerate = atoi(optarg); break;
796: case 'x': use_xhair = 1; break;
797: case 'D': use_debugger = 1; break;
798: case 'J': fake_joystick = 1; break;
799: case 'a': automount_uaedev = 0; break;
800: case 's': use_slow_mem = 1; break;
801: case 'g': use_gfxlib = 1; break;
802:
803: case 'F':
804: fastmem_size = atoi(optarg) * 0x100000;
805: if (fastmem_size != 0x100000 && fastmem_size != 0x200000
806: && fastmem_size != 0x400000 && fastmem_size != 0x800000)
807: {
808: fastmem_size = 0;
809: fprintf(stderr, "Unsupported fastmem size!\n");
810: }
811:
812: break;
813:
814: case 'd':
815: screen_res = atoi(optarg);
816: if (screen_res >= 0 && screen_res <= 4) {
817: } else {
818: fprintf(stderr, "Bad video mode selected. Using default.\n");
819: screen_res = 3;
820: }
821: dont_want_aspect = screen_res != 4;
822: use_lores = screen_res < 3;
823: break;
824:
825: case 'H':
826: color_mode = atoi(optarg);
827: if (color_mode < 0 || color_mode > 2) {
828: fprintf(stderr, "Bad color mode selected. Using default.\n");
829: color_mode = 0;
830: }
831: break;
832: }
833: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.