|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * NeXT interface
5: * NeXTwin.m
6: *
7: * Copyright 1995, 1996 Bernd Schmidt
8: * Copyright 1996 Ed Hanway, Andre Beck
1.1.1.3 ! root 9: * Copyright 1996-97 Ian Stephenson
1.1 root 10: */
11:
12: #include "sysconfig.h"
13: #include "sysdeps.h"
14:
15: #import <appkit/appkit.h>
16:
17: #include "config.h"
18: #include "options.h"
1.1.1.3 ! root 19: #include "threaddep/penguin.h"
! 20: #include "uae.h"
1.1 root 21: #include "memory.h"
22: #include "custom.h"
1.1.1.3 ! root 23: #include "readcpu.h"
1.1 root 24: #include "newcpu.h"
25: #include "xwin.h"
26: #include "keyboard.h"
27: #include "keybuf.h"
1.1.1.3 ! root 28: #include "gui.h"
! 29: #include "debug.h"
1.1.1.2 root 30: // If you are compiling on NeXTStep 3.2, uncomment the following line:
31: //#define NX_EightBitRGBDepth 514
32:
33: int sigbrkhandler()
34: {
35: activate_debugger();
36: signal(SIGINT, sigbrkhandler);
37: }
1.1 root 38:
39: void setup_brkhandler(void)
40: {
1.1.1.2 root 41: signal(SIGINT, sigbrkhandler);
1.1 root 42: }
43:
44:
45: /* Keyboard and mouse */
46:
47: static BOOL keystate[256];
48: int commandKey = -1;
49:
50: int quit_program;
51:
52: static NXCursor *cursor;
53:
54: static View *screen;
55: static NXBitmapImageRep *bitmap;
56: static char * xlinebuffer;
57: static int bitOffset;
58: static int keycode2amiga(NXEvent * theEvent);
59:
60: @interface AmigaView:View
61: {
62: }
63: //From Menu...
64: - reset:sender;
65: - quit:sender;
66: - joystick:sender;
67:
68: //Floppy Stuff...
69: - eject:sender;
70: - insert:sender;
71:
72: //Misc...
73: - (BOOL)acceptsFirstResponder;
74: - resetCursorRects;
75:
76: //The ones which do the work...
77: - keyDown:(NXEvent *)theEvent;
78: - keyUp:(NXEvent *)theEvent;
79: - flagsChanged:(NXEvent *)theEvent;
80: - mouseDown:(NXEvent *)theEvent;
81: - mouseUp:(NXEvent *)theEvent;
82: - rightMouseDown:(NXEvent *)theEvent;
83: - rightMouseUp:(NXEvent *)theEvent;
84: @end
85:
86: @implementation AmigaView
87: -reset:sender
88: {
1.1.1.3 ! root 89: uae_reset();
! 90: //m68k_reset();
1.1 root 91: return self;
92: }
93: -quit:sender
94: {
1.1.1.3 ! root 95: uae_quit();
1.1 root 96: return self;
97: }
98: -joystick:sender
99: {
1.1.1.3 ! root 100: currprefs.fake_joystick=[sender state];
1.1 root 101: return self;
102: }
103: -eject:sender
104: {
105: disk_eject([sender tag]);
106: return self;
107: }
108: -insert:sender
109: {
110: disk_eject([sender tag]);
111: disk_insert([sender tag],[sender stringValue]);
112: return self;
113: }
114:
115: - (BOOL)acceptsFirstResponder
116: {
117: return YES;
118: }
119: - keyDown:(NXEvent *)theEvent
120: {
121: if(theEvent->data.key.repeat == 0)
122: {
123: int kc = keycode2amiga((NXEvent *)theEvent);
124: if (!keystate[kc])
125: {
126: keystate[kc] = TRUE;
127: record_key (kc << 1);
128: }
129: }
130: return self;
131: }
132: - keyUp:(NXEvent *)theEvent
133: {
134: int kc = keycode2amiga((NXEvent *)theEvent);
135: if (kc == -1) return;
136: keystate[kc] = FALSE;
137: record_key ((kc << 1) | 1);
138:
139: return self;
140: }
141: -flagsChanged:(NXEvent *)theEvent
142: {
143: if(theEvent->flags & NX_SHIFTMASK)
144: {//Shift is Down
145: if(!keystate[AK_LSH])
146: {
147: keystate[AK_LSH] = TRUE;
148: record_key ((AK_LSH << 1));
149: }
150: if(!keystate[AK_RSH])
151: {
152: keystate[AK_RSH] = TRUE;
153: record_key ((AK_RSH << 1));
154: }
155: }
156: else
157: {//Shift is Up
158: if(keystate[AK_LSH])
159: {
160: keystate[AK_LSH] = FALSE;
161: record_key ((AK_LSH << 1) | 1);
162: }
163: if(keystate[AK_RSH])
164: {
165: keystate[AK_RSH] = FALSE;
166: record_key ((AK_RSH << 1) | 1);
167: }
168: }
169:
170: if(theEvent->flags & NX_CONTROLMASK)
171: {
172: if(!keystate[AK_CTRL])
173: {
174: keystate[AK_CTRL] = TRUE;
175: record_key ((AK_CTRL << 1));
176: }
177: }
178: else
179: if(keystate[AK_CTRL])
180: {
181: keystate[AK_CTRL] = FALSE;
182: record_key ((AK_CTRL << 1) | 1);
183: }
184:
185: if(theEvent->flags & NX_ALTERNATEMASK)
186: {//Alt is Down
187: if(!keystate[AK_LALT])
188: {
189: keystate[AK_LALT] = TRUE;
190: record_key ((AK_LALT << 1));
191: }
192: if(!keystate[AK_RALT])
193: {
194: keystate[AK_RALT] = TRUE;
195: record_key ((AK_RALT << 1));
196: }
197: }
198: else
199: {//Alt is Up
200: if(keystate[AK_LALT])
201: {
202: keystate[AK_LALT] = FALSE;
203: record_key ((AK_LALT << 1) | 1);
204: }
205: if(keystate[AK_RALT])
206: {
207: keystate[AK_RALT] = FALSE;
208: record_key ((AK_RALT << 1) | 1);
209: }
210:
211: }
212: return self;
213: }
214: - mouseDown:(NXEvent *)theEvent
215: {
216: buttonstate[0] = 1;
217: return self;
218: }
219: - mouseUp:(NXEvent *)theEvent
220: {
221: buttonstate[0] = 0;
222: return self;
223: }
224: - rightMouseDown:(NXEvent *)theEvent
225: {
226: buttonstate[2] = 1;
227: return self;
228: }
229: - rightMouseUp:(NXEvent *)theEvent
230: {
231: buttonstate[2] = 0;
232: return self;
233: }
234:
235: - resetCursorRects
236: {
237: NXRect visible;
1.1.1.3 ! root 238:
1.1 root 239:
240:
241: if ([self getVisibleRect:&visible])
242: [self addCursorRect:&visible cursor:cursor];
243: return self;
244: }
245: @end
246: // End of AmigaView Object - common functions now!!!
247:
248:
249: void flush_block (int ystart, int ystop)
250: {
251: id tmpBitmap;
252: NXPoint where;
253:
254: //printf("Flush Block:%d->%d\n",ystart,ystop);
255: if(ystart >= ystop)
256: return;
257:
258: ystop++; //Make sure we get the last line!
259:
260: tmpBitmap=[[NXBitmapImageRep alloc]
261: initData:[bitmap data]+ystart*[bitmap bytesPerRow]
262: pixelsWide:(int)800
263: pixelsHigh:(int)(ystop-ystart)
264: bitsPerSample:[bitmap bitsPerSample]
265: samplesPerPixel:[bitmap samplesPerPixel]
266: hasAlpha:(BOOL)[bitmap hasAlpha]
267: isPlanar:(BOOL)NO
268: colorSpace:[bitmap colorSpace]
269: bytesPerRow:[bitmap bytesPerRow]
270: bitsPerPixel:[bitmap bitsPerPixel]
271: ];
272:
273: where.x=0;
274: where.y=283-ystop;
275: [screen lockFocus];
276: [tmpBitmap drawAt:&where];
277: [screen unlockFocus];
278: [screen display];
279: [tmpBitmap free];
280: }
281:
1.1.1.2 root 282: void flush_screen (int from, int to)
1.1 root 283: {
1.1.1.3 ! root 284: //printf("Flush Screen:%d->%d\n", from, to);
1.1 root 285: return;
286: //This simple version is no longer required...
287: [screen lockFocus];
288: [bitmap draw];
289: [screen unlockFocus];
290: [screen display];
291: }
292:
293: void flush_line(int y)
294: {
1.1.1.3 ! root 295: //printf("Flush Line:%d\n", y);
1.1 root 296: return;
297: }
298:
1.1.1.3 ! root 299: int graphics_setup(void)
! 300: {
! 301: return 1;
! 302: }
1.1 root 303:
1.1.1.2 root 304: int graphics_init(void)
1.1 root 305: {
1.1.1.3 ! root 306: int i;
! 307: NXRect rect;
1.1 root 308:
309: quit_program = NO;
1.1.1.3 ! root 310: currprefs.fake_joystick = NO;
! 311:
! 312: gfxvidinfo.can_double = 0;
! 313:
1.1 root 314: [Application new];
315: if (![NXApp loadNibSection:"Uae.nib" owner:NXApp withNames:NO])
316: {
317: puts("Can't find NIB file");
318: exit(-1);
319: }
320: [NXApp perform:@selector(stop:) with:nil afterDelay:0.0 cancelPrevious:NO];
321: [NXApp run];
322:
323: screen=[NXApp delegate];
1.1.1.2 root 324: [NXApp setDelegate:nil];
325:
1.1 root 326: [[screen window] addToEventMask:NX_RMOUSEDOWNMASK|NX_RMOUSEUPMASK];
327:
328: cursor=[[NXCursor alloc] initFromImage:[NXImage findImageNamed:"dummy"]];
329:
330: switch([Window defaultDepthLimit])
331: {
332: case NX_TwentyFourBitRGBDepth:
333: {
334: for(i = 0; i < 4096; i++)
335: {
336: xcolors[i]= NXSwapHostLongToBig(((i & 0x0f00) << (20))|
337: ((i & 0x00f0) << (16))|
338: ((i & 0x000f) << (12))|
339: 0xff);
340: }
341:
342: bitmap=[[NXBitmapImageRep alloc]
343: initData:(unsigned char *)NULL
344: pixelsWide:(int)800
345: pixelsHigh:(int)(313-29)
346: bitsPerSample:(int)8
347: samplesPerPixel:(int)4
348: hasAlpha:(BOOL)YES
349: isPlanar:(BOOL)NO
350: colorSpace:(NXColorSpace)NX_RGBColorSpace
351: bytesPerRow:(int)800*4
352: bitsPerPixel:(int)32
353: ];
354: gfxvidinfo.pixbytes=4;
355: break;
356: }
357: case NX_TwelveBitRGBDepth:
358: case NX_EightBitRGBDepth:
359: {
360: for(i = 0; i < 4096; i++)
361: {
362: xcolors[i] = NXSwapHostShortToBig((short)((i << 4) | 0xf));
363: }
364:
365: bitmap=[[NXBitmapImageRep alloc]
366: initData:(unsigned char *)NULL
367: pixelsWide:(int)800
368: pixelsHigh:(int)(313-29)
369: bitsPerSample:(int)4
370: samplesPerPixel:(int)4
371: hasAlpha:(BOOL)YES
372: isPlanar:(BOOL)NO
373: colorSpace:(NXColorSpace)NX_RGBColorSpace
374: bytesPerRow:(int)800*2
375: bitsPerPixel:(int)16
376: ];
377: gfxvidinfo.pixbytes=2;
378: break;
379: }
380: case NX_EightBitGrayDepth:
1.1.1.2 root 381: case NX_TwoBitGrayDepth:
382: default:
1.1 root 383: {
384: for(i = 0; i < 4096; i++)
385: {
386: xcolors[i]= ( ((i & 0x0f00) >> 5)+
387: ((i & 0x00f0) >>1 )+
388: ((i & 0x000f) <<2)) ;
389:
390: if(xcolors[i]>255)
391: xcolors[i]=255;
392: }
393:
394: bitmap=[[NXBitmapImageRep alloc]
395: initData:(unsigned char *)NULL
396: pixelsWide:(int)800
397: pixelsHigh:(int)(313-29)
398: bitsPerSample:(int)8
399: samplesPerPixel:(int)1
400: hasAlpha:(BOOL)NO
401: isPlanar:(BOOL)NO
402: colorSpace:(NXColorSpace)NX_OneIsWhiteColorSpace
403: bytesPerRow:(int)800
404: bitsPerPixel:(int)8
405: ];
406: gfxvidinfo.pixbytes=1;
407: break;
408: }
1.1.1.2 root 409: #if 0
410: //Sorry 2bit screeners (self included!)
411: //Bernd won't support special code just for us NeXTStation owners
412: //and I don't have time any more,
413: //So we have to use 8bit, and dither :-(
1.1.1.3 ! root 414: //On the bright side, it looks great (eventually!)
1.1 root 415: case NX_TwoBitGrayDepth:
416: {
417: for(i = 0; i < 4096; i++)
418: {
419: xcolors[i]= (((i & 0x0f00) >> (1+8))+
420: ((i & 0x00f0) >> (1+4))+
421: ((i & 0x000f) >> (2+0))) >> 2;
422:
423: if(xcolors[i]>3)
424: xcolors[i]=3;
425:
426: }
427:
428: bitmap=[[NXBitmapImageRep alloc]
429: initData:(unsigned char *)NULL
430: pixelsWide:(int)800
431: pixelsHigh:(int)(313-29)
432: bitsPerSample:(int)2
433: samplesPerPixel:(int)1
434: hasAlpha:(BOOL)NO
435: isPlanar:(BOOL)NO
436: colorSpace:(NXColorSpace)NX_OneIsWhiteColorSpace
437: bytesPerRow:(int)800/4
438: bitsPerPixel:(int)2
439: ];
440: gfxvidinfo.pixbytes=0; //bit of a hack!...
441: }
1.1.1.2 root 442: #endif
1.1 root 443: }
444: gfxvidinfo.bufmem=[bitmap data];
1.1.1.3 ! root 445: gfxvidinfo.linemem = NULL;
! 446: gfxvidinfo.rowbytes=[bitmap bytesPerRow];
! 447: gfxvidinfo.width = 800;
! 448: gfxvidinfo.height = (313-29); /* ??? */
! 449: gfxvidinfo.maxblocklines = (313-29); /* ??? */
! 450:
! 451: gfxvidinfo.can_double = FALSE;
! 452:
! 453: newmousecounters = 0;
1.1.1.2 root 454: return 1;
1.1 root 455: }
456:
457:
458:
459: void graphics_leave(void)
460: {
1.1.1.3 ! root 461: //[bitmap free];
! 462: //[NXApp free];
1.1 root 463: }
464:
465:
466: static int keycode2amiga(NXEvent * theEvent)
467: {
468:
469: if((theEvent->flags & NX_COMMANDMASK))
470: {
471: switch ((char)(theEvent->data.key.charCode))
472: {
473: case '1': commandKey = AK_F1; return AK_F1;
474: case '2': commandKey = AK_F2; return AK_F2;
475: case '3': commandKey = AK_F3; return AK_F3;
476: case '4': commandKey = AK_F4; return AK_F4;
477: case '5': commandKey = AK_F5; return AK_F5;
478: case '6': commandKey = AK_F6; return AK_F6;
479: case '7': commandKey = AK_F7; return AK_F7;
480: case '8': commandKey = AK_F8; return AK_F8;
481: case '9': commandKey = AK_F9; return AK_F9;
482: case '0': commandKey = AK_F10; return AK_F10;
483: default : return -1; //So not to generate stuck key.
484: }
485: }
486:
487: if ( theEvent->flags & NX_NUMERICPADMASK )
488: {
489:
490: switch ((char)(theEvent->data.key.charCode)) {
491: case '0': return AK_NP0;
1.1.1.3 ! root 492: case '1': return currprefs.fake_joystick?AK_LAMI:AK_NP1;
1.1 root 493: case '2': return AK_NP2;
1.1.1.3 ! root 494: case '3': return currprefs.fake_joystick?AK_RAMI:AK_NP3;
1.1 root 495: case '4': return AK_NP4;
496: case '5': return AK_NP5;
497: case '6': return AK_NP6;
498: case '7': return AK_NP7;
499: case '8': return AK_NP8;
500: case '9': return AK_NP9;
501: }
502: }
503:
504: switch ((char)(theEvent->data.key.charCode)) {
505: case 'a': case 'A': return AK_A;
506: case 'B': case 'b': return AK_B;
507: case 'C': case 'c': return AK_C;
508: case 'D': case 'd': return AK_D;
509: case 'E': case 'e': return AK_E;
510: case 'F': case 'f': return AK_F;
511: case 'G': case 'g': return AK_G;
512: case 'H': case 'h': return AK_H;
513: case 'I': case 'i': return AK_I;
514: case 'J': case 'j': return AK_J;
515: case 'K': case 'k': return AK_K;
516: case 'L': case 'l': return AK_L;
517: case 'M': case 'm': return AK_M;
518: case 'N': case 'n': return AK_N;
519: case 'O': case 'o': return AK_O;
520: case 'P': case 'p': return AK_P;
521: case 'Q': case 'q': return AK_Q;
522: case 'R': case 'r': return AK_R;
523: case 'S': case 's': return AK_S;
524: case 'T': case 't': return AK_T;
525: case 'U': case 'u': return AK_U;
526: case 'V': case 'v': return AK_V;
527: case 'W': case 'w': return AK_W;
528: case 'X': case 'x': return AK_X;
529: case 'Y': case 'y': return AK_Y;
530: case 'Z': case 'z': return AK_Z;
531:
532: case '0':case ')': return AK_0;
533: case '1':case '!': return AK_1;
534: case '2':case '@': return AK_2;
535: case '3':case '#': return AK_3;
536: case '4':case '$': return AK_4;
537: case '5':case '%': return AK_5;
538: case '6':case '^': return AK_6;
539: case '7':case '&': return AK_7;
540: case '8':case '*': return AK_8;
541: case '9':case '(': return AK_9;
1.1.1.3 ! root 542:
1.1 root 543:
544:
545: case ';': case ':': return AK_SEMICOLON;
546: case '-': case '_': return AK_MINUS;
547: case '/': case '?': return AK_SLASH;
548: case '.': case '>': return AK_PERIOD;
549: case ',': case '<': return AK_COMMA;
550: case '=': case '+': return AK_EQUAL;
551: case '[': case '{': return AK_LBRACKET;
552: case ']': case '}': return AK_RBRACKET;
1.1.1.3 ! root 553:
1.1 root 554:
555:
556: case 127: return AK_BS;
557: case 9: return AK_TAB;
558: case 13: return AK_RET;
559: case 32: return AK_SPC;
560: case 27: return AK_ESC;
561:
562: case -83: return AK_UP;
563: case -81: return AK_DN;
564: case -84: return AK_LF;
565: case -82: return AK_RT;
566:
567: case '\\': return AK_BACKSLASH;
568: }
569: return -1;
570: }
571:
572: void handle_events(void)
573: {
574: NXEvent dummy; // used for throwaway checks
1.1.1.3 ! root 575: NXPoint mouseLoc;
1.1 root 576:
577: //Update Mouse Position
1.1.1.3 ! root 578: [[screen window] getMouseLocation:&mouseLoc];
! 579: [screen convertPoint:&mouseLoc fromView:nil];
! 580:
1.1 root 581: lastmx=mouseLoc.x;
582: lastmy=(313-29)-mouseLoc.y;
583:
584: //COMMAND'd keypresses do not generate key ups!
585: //We therefore have to fake the key up...
586: if(commandKey != -1)
587: {
588: keystate[commandKey]=FALSE;
589: record_key ((commandKey << 1) | 1);
590: commandKey = -1;
591: }
592:
593: //Check for NeXT events, and run NXApp...
594: if([NXApp peekNextEvent: NX_ALLEVENTS into: &dummy])
595: {
596: [NXApp perform:@selector(stop:) with:nil afterDelay:0.0 cancelPrevious:NO];
597: [NXApp run];
598: }
599: }
600:
1.1.1.2 root 601: int debuggable(void)
1.1 root 602: {
603: return TRUE;
604: }
605:
1.1.1.2 root 606: int needmousehack(void)
1.1 root 607: {
608: return TRUE;
609: }
610:
611: void LED(int on)
612: {
613: }
614:
615:
616: //Keep X gui happy!
617:
1.1.1.3 ! root 618: void gui_changesettings(void)
1.1 root 619: {
620:
1.1.1.3 ! root 621: }
! 622: int gui_update(void)
1.1 root 623: {
1.1.1.3 ! root 624: return 0;
1.1 root 625: }
626:
1.1.1.3 ! root 627: int gui_init(void)
1.1 root 628: {
629: }
630:
1.1.1.3 ! root 631: void gui_exit(void)
1.1 root 632: {
633: }
634:
1.1.1.3 ! root 635: void gui_led(int led, int on)
1.1 root 636: {
637: }
638:
1.1.1.3 ! root 639: void gui_filename(int num, const char *name)
1.1 root 640: {
641: }
1.1.1.2 root 642:
1.1.1.3 ! root 643: void write_log (const char *buf)
! 644: {
! 645: fprintf (stderr, buf);
! 646: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.