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