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