home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / UAE061.LZH / uae-0.6.1 / NeXTwin.m < prev    next >
Encoding:
Text File  |  1996-08-28  |  12.3 KB  |  613 lines

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