|
|
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"
25:
26: void setup_brkhandler(void)
27: {
28: }
29:
30: // If you are compiling on NeXTStep 3.2, uncomment the following line:
31: // #define NX_EightBitRGBDepth 514
32:
33: struct vidbuf_description gfxvidinfo;
34:
35: /* Keyboard and mouse */
36:
37: static BOOL keystate[256];
38: int commandKey = -1;
39:
40: int quit_program;
41:
42: BOOL buttonstate[3];
43: int lastmx, lastmy;
44: BOOL newmousecounters;
45: long int xcolors[4096];
46:
47: static NXCursor *cursor;
48:
49: static View *screen;
50: static NXBitmapImageRep *bitmap;
51: static char * xlinebuffer;
52: static int bitOffset;
53: static int keycode2amiga(NXEvent * theEvent);
54:
55: @interface AmigaView:View
56: {
57: }
58: //From Menu...
59: - reset:sender;
60: - quit:sender;
61: - joystick:sender;
62:
63: //Floppy Stuff...
64: - eject:sender;
65: - insert:sender;
66:
67: //Misc...
68: - (BOOL)acceptsFirstResponder;
69: - resetCursorRects;
70:
71: //The ones which do the work...
72: - keyDown:(NXEvent *)theEvent;
73: - keyUp:(NXEvent *)theEvent;
74: - flagsChanged:(NXEvent *)theEvent;
75: - mouseDown:(NXEvent *)theEvent;
76: - mouseUp:(NXEvent *)theEvent;
77: - rightMouseDown:(NXEvent *)theEvent;
78: - rightMouseUp:(NXEvent *)theEvent;
79: @end
80:
81: @implementation AmigaView
82: -reset:sender
83: {
84: MC68000_reset();
85: return self;
86: }
87: -quit:sender
88: {
89: broken_in = TRUE;
90: specialflags |= SPCFLAG_BRK;
91: quit_program = 1;
92: return self;
93: }
94: -joystick:sender
95: {
96: fake_joystick=[sender state];
97: return self;
98: }
99: -eject:sender
100: {
101: disk_eject([sender tag]);
102: return self;
103: }
104: -insert:sender
105: {
106: disk_eject([sender tag]);
107: disk_insert([sender tag],[sender stringValue]);
108: return self;
109: }
110:
111: - (BOOL)acceptsFirstResponder
112: {
113: return YES;
114: }
115: - keyDown:(NXEvent *)theEvent
116: {
117: if(theEvent->data.key.repeat == 0)
118: {
119: int kc = keycode2amiga((NXEvent *)theEvent);
120: if (!keystate[kc])
121: {
122: keystate[kc] = TRUE;
123: record_key (kc << 1);
124: }
125: }
126: return self;
127: }
128: - keyUp:(NXEvent *)theEvent
129: {
130: int kc = keycode2amiga((NXEvent *)theEvent);
131: if (kc == -1) return;
132: keystate[kc] = FALSE;
133: record_key ((kc << 1) | 1);
134:
135: return self;
136: }
137: -flagsChanged:(NXEvent *)theEvent
138: {
139: if(theEvent->flags & NX_SHIFTMASK)
140: {//Shift is Down
141: if(!keystate[AK_LSH])
142: {
143: keystate[AK_LSH] = TRUE;
144: record_key ((AK_LSH << 1));
145: }
146: if(!keystate[AK_RSH])
147: {
148: keystate[AK_RSH] = TRUE;
149: record_key ((AK_RSH << 1));
150: }
151: }
152: else
153: {//Shift is Up
154: if(keystate[AK_LSH])
155: {
156: keystate[AK_LSH] = FALSE;
157: record_key ((AK_LSH << 1) | 1);
158: }
159: if(keystate[AK_RSH])
160: {
161: keystate[AK_RSH] = FALSE;
162: record_key ((AK_RSH << 1) | 1);
163: }
164: }
165:
166: if(theEvent->flags & NX_CONTROLMASK)
167: {
168: if(!keystate[AK_CTRL])
169: {
170: keystate[AK_CTRL] = TRUE;
171: record_key ((AK_CTRL << 1));
172: }
173: }
174: else
175: if(keystate[AK_CTRL])
176: {
177: keystate[AK_CTRL] = FALSE;
178: record_key ((AK_CTRL << 1) | 1);
179: }
180:
181: if(theEvent->flags & NX_ALTERNATEMASK)
182: {//Alt is Down
183: if(!keystate[AK_LALT])
184: {
185: keystate[AK_LALT] = TRUE;
186: record_key ((AK_LALT << 1));
187: }
188: if(!keystate[AK_RALT])
189: {
190: keystate[AK_RALT] = TRUE;
191: record_key ((AK_RALT << 1));
192: }
193: }
194: else
195: {//Alt is Up
196: if(keystate[AK_LALT])
197: {
198: keystate[AK_LALT] = FALSE;
199: record_key ((AK_LALT << 1) | 1);
200: }
201: if(keystate[AK_RALT])
202: {
203: keystate[AK_RALT] = FALSE;
204: record_key ((AK_RALT << 1) | 1);
205: }
206:
207: }
208: return self;
209: }
210: - mouseDown:(NXEvent *)theEvent
211: {
212: buttonstate[0] = 1;
213: return self;
214: }
215: - mouseUp:(NXEvent *)theEvent
216: {
217: buttonstate[0] = 0;
218: return self;
219: }
220: - rightMouseDown:(NXEvent *)theEvent
221: {
222: buttonstate[2] = 1;
223: return self;
224: }
225: - rightMouseUp:(NXEvent *)theEvent
226: {
227: buttonstate[2] = 0;
228: return self;
229: }
230:
231: - resetCursorRects
232: {
233: NXRect visible;
234:
235:
236:
237: if ([self getVisibleRect:&visible])
238: [self addCursorRect:&visible cursor:cursor];
239: return self;
240: }
241: @end
242: // End of AmigaView Object - common functions now!!!
243:
244:
245: void flush_block (int ystart, int ystop)
246: {
247: id tmpBitmap;
248: NXPoint where;
249:
250: //printf("Flush Block:%d->%d\n",ystart,ystop);
251: if(ystart >= ystop)
252: return;
253:
254: ystop++; //Make sure we get the last line!
255:
256: tmpBitmap=[[NXBitmapImageRep alloc]
257: initData:[bitmap data]+ystart*[bitmap bytesPerRow]
258: pixelsWide:(int)800
259: pixelsHigh:(int)(ystop-ystart)
260: bitsPerSample:[bitmap bitsPerSample]
261: samplesPerPixel:[bitmap samplesPerPixel]
262: hasAlpha:(BOOL)[bitmap hasAlpha]
263: isPlanar:(BOOL)NO
264: colorSpace:[bitmap colorSpace]
265: bytesPerRow:[bitmap bytesPerRow]
266: bitsPerPixel:[bitmap bitsPerPixel]
267: ];
268:
269: where.x=0;
270: where.y=283-ystop;
271: [screen lockFocus];
272: [tmpBitmap drawAt:&where];
273: [screen unlockFocus];
274: [screen display];
275: [tmpBitmap free];
276: }
277:
278: void flush_screen (void)
279: {
280: return;
281: //This simple version is no longer required...
282: [screen lockFocus];
283: [bitmap draw];
284: [screen unlockFocus];
285: [screen display];
286: }
287:
288: void flush_line(int y)
289: {
290:
291: return;
292: }
293:
294:
295: void graphics_init(void)
296: {
297: int i;
298: NXRect rect;
299:
300: quit_program = NO;
301: fake_joystick = NO;
302:
303: [Application new];
304: if (![NXApp loadNibSection:"Uae.nib" owner:NXApp withNames:NO])
305: {
306: puts("Can't find NIB file");
307: exit(-1);
308: }
309: [NXApp perform:@selector(stop:) with:nil afterDelay:0.0 cancelPrevious:NO];
310: [NXApp run];
311:
312: screen=[NXApp delegate];
313:
314: [[screen window] addToEventMask:NX_RMOUSEDOWNMASK|NX_RMOUSEUPMASK];
315:
316: cursor=[[NXCursor alloc] initFromImage:[NXImage findImageNamed:"dummy"]];
317:
318: switch([Window defaultDepthLimit])
319: {
320: case NX_TwentyFourBitRGBDepth:
321: {
322: for(i = 0; i < 4096; i++)
323: {
324: xcolors[i]= NXSwapHostLongToBig(((i & 0x0f00) << (20))|
325: ((i & 0x00f0) << (16))|
326: ((i & 0x000f) << (12))|
327: 0xff);
328: }
329:
330: bitmap=[[NXBitmapImageRep alloc]
331: initData:(unsigned char *)NULL
332: pixelsWide:(int)800
333: pixelsHigh:(int)(313-29)
334: bitsPerSample:(int)8
335: samplesPerPixel:(int)4
336: hasAlpha:(BOOL)YES
337: isPlanar:(BOOL)NO
338: colorSpace:(NXColorSpace)NX_RGBColorSpace
339: bytesPerRow:(int)800*4
340: bitsPerPixel:(int)32
341: ];
342: gfxvidinfo.pixbytes=4;
343: break;
344: }
345: case NX_TwelveBitRGBDepth:
346: case NX_EightBitRGBDepth:
347: {
348: for(i = 0; i < 4096; i++)
349: {
350: xcolors[i] = NXSwapHostShortToBig((short)((i << 4) | 0xf));
351: }
352:
353: bitmap=[[NXBitmapImageRep alloc]
354: initData:(unsigned char *)NULL
355: pixelsWide:(int)800
356: pixelsHigh:(int)(313-29)
357: bitsPerSample:(int)4
358: samplesPerPixel:(int)4
359: hasAlpha:(BOOL)YES
360: isPlanar:(BOOL)NO
361: colorSpace:(NXColorSpace)NX_RGBColorSpace
362: bytesPerRow:(int)800*2
363: bitsPerPixel:(int)16
364: ];
365: gfxvidinfo.pixbytes=2;
366: break;
367: }
368: case NX_EightBitGrayDepth:
369: {
370: for(i = 0; i < 4096; i++)
371: {
372: xcolors[i]= ( ((i & 0x0f00) >> 5)+
373: ((i & 0x00f0) >>1 )+
374: ((i & 0x000f) <<2)) ;
375:
376: if(xcolors[i]>255)
377: xcolors[i]=255;
378: }
379:
380: bitmap=[[NXBitmapImageRep alloc]
381: initData:(unsigned char *)NULL
382: pixelsWide:(int)800
383: pixelsHigh:(int)(313-29)
384: bitsPerSample:(int)8
385: samplesPerPixel:(int)1
386: hasAlpha:(BOOL)NO
387: isPlanar:(BOOL)NO
388: colorSpace:(NXColorSpace)NX_OneIsWhiteColorSpace
389: bytesPerRow:(int)800
390: bitsPerPixel:(int)8
391: ];
392: gfxvidinfo.pixbytes=1;
393: break;
394: }
395: case NX_TwoBitGrayDepth:
396: default:
397: {
398: for(i = 0; i < 4096; i++)
399: {
400: xcolors[i]= (((i & 0x0f00) >> (1+8))+
401: ((i & 0x00f0) >> (1+4))+
402: ((i & 0x000f) >> (2+0))) >> 2;
403:
404: if(xcolors[i]>3)
405: xcolors[i]=3;
406:
407: }
408:
409: bitmap=[[NXBitmapImageRep alloc]
410: initData:(unsigned char *)NULL
411: pixelsWide:(int)800
412: pixelsHigh:(int)(313-29)
413: bitsPerSample:(int)2
414: samplesPerPixel:(int)1
415: hasAlpha:(BOOL)NO
416: isPlanar:(BOOL)NO
417: colorSpace:(NXColorSpace)NX_OneIsWhiteColorSpace
418: bytesPerRow:(int)800/4
419: bitsPerPixel:(int)2
420: ];
421: gfxvidinfo.pixbytes=0; //bit of a hack!...
422: }
423: }
424: gfxvidinfo.rowbytes=[bitmap bytesPerRow];
425: gfxvidinfo.bufmem=[bitmap data];
426: gfxvidinfo.maxblocklines = 1000; /* whatever...??? */
427: gfxvidinfo.maxlinetoscr = 0;
428: gfxvidinfo.x_adjust = 0;
429: gfxvidinfo.maxline = 100000; /* ??? */
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: }
608:
609: void calc_adjustment(void)
610: {
611: gfxvidinfo.x_adjust = 0;
612: }
613:
614: void target_specific_usage(void)
615: {
616: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.