home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff216.lzh / Wanderer / src / ami-curses.c < prev    next >
C/C++ Source or Header  |  1989-06-02  |  9KB  |  418 lines

  1. /*
  2.  * A simple curses emulation for the Amiga, specifically for WANDERER
  3.  *
  4.  * Alan Bland
  5.  */
  6. #ifdef AMIGA
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <curses.h>
  11.  
  12. #include <dos.h>
  13. #include <intuition/intuition.h>
  14. #include <exec/types.h>
  15. #include <exec/ports.h>
  16. #include <exec/io.h>
  17. #include <exec/memory.h>
  18.  
  19. #include <proto/exec.h>
  20. #include <proto/intuition.h>
  21.  
  22. /* generated by Power Windows 2.0 */
  23. #include "pw.palette.h"
  24. #include "pw.menus.h"
  25.  
  26. struct IntuitionBase *IntuitionBase;
  27. struct GfxBase *GfxBase;
  28. struct Screen *S;
  29. struct Window *W;
  30. struct RastPort *R;
  31. struct TextFont *map_font, *text_font;
  32. struct Library *DiskfontBase;
  33.  
  34. #define TOPEDGE 12    /* how much of screen bar to show */
  35. int WindowWidth = 640;
  36. int WindowHeight = 200 - TOPEDGE;
  37.  
  38. int MouseX, MouseY;
  39.  
  40. /* getmouse - get current row and column of mouse */
  41. getmouse(amr,amc)
  42. int *amr;
  43. int *amc;
  44. {
  45.     *amr = MouseY / 8;
  46.     *amc = MouseX / 8;
  47. }
  48.  
  49. /* Return when either a console key or mouse button is pressed. */
  50. mouseorkey()
  51. {
  52.     return nextevent(MOUSEBUTTONS | RAWKEY | MENUPICK, 1);
  53. }
  54.  
  55. flushinput()
  56. {
  57.     while (nextevent(RAWKEY, 0) >= 0) ;
  58. }
  59.  
  60. /* returns next character, with special WANDERER translations */
  61. getch()
  62. {
  63.     return nextevent(RAWKEY | MENUPICK, 1);
  64. }
  65.  
  66. /* returns next character with no special translations */
  67. /* used mainly for getstr() */
  68. getvanillach()
  69. {
  70.     return nextevent(VANILLAKEY, 1);
  71. }
  72.  
  73. cursor(state)
  74. int state;
  75. {
  76.     int x, y;
  77.     x = R->cp_x;
  78.     y = R->cp_y - R->Font->tf_Baseline;
  79.     SetDrMd(R, COMPLEMENT);
  80.     RectFill(R, x, y, x+8, y+R->Font->tf_YSize-1);
  81.     SetDrMd(R, JAM2);
  82. }
  83.  
  84. /* special keymap for wanderer raw mode - translates function keys and
  85.  * cursor keys to wanderer single-key commands */
  86. char mykeys[] = {
  87.     '`','1','2','3','4','5','6','7','8','9','0','-','=','\\',0,0,
  88.     'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'j',0,
  89.     'a','s','d','f','g','h','j','k','l',';','\'',0,0,'h','@','l',
  90.     0,'z','x','c','v','b','n','m',',','.','/',0,0,0,'k',0,
  91.     ' ','\b',0,'\n','\n','q',0,0,0,0,0,0,'k','j','l','h',
  92.     '~','#','@',0,0,'S','R',0,0,'!',0,0,0,0,0,'?',
  93.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  94.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  95. };
  96. char myshiftkeys[] = {
  97.     '~','!','@','#','$','%','^','&','*','(',')','_','+','|',0,0,
  98.     'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,0,0,
  99.     'A','S','D','F','G','H','J','K','L',':','"',0,0,0,0,0,
  100.     0,'Z','X','C','V','B','N','M','<','>','?',0,0,0,0,0,
  101.     ' ','\b',0,'\n','\n',0,0,0,0,0,0,0,'k','j','l','h',
  102.     '~','#','@',0,0,'S','R',0,0,'!',0,0,0,0,0,'?',
  103.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  104.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  105. };
  106.  
  107. nextevent(flags, wait)
  108. long flags;
  109. int wait;
  110. {
  111.     register int class, code;
  112.     register struct IntuiMessage *message;
  113.     int result, qual;
  114.  
  115.     /* show cursor if inputting a stream of text */
  116.     if (flags & VANILLAKEY) cursor(1);
  117.     ModifyIDCMP(W, CLOSEWINDOW | flags);
  118.     while (1)
  119.     {
  120.         if (wait)
  121.         {
  122.             /* get next event, waiting if none are available */
  123.             while ((message = (struct IntuiMessage *)GetMsg(W->UserPort)) == NULL)
  124.             {
  125.             Wait(1<<W->UserPort->mp_SigBit);
  126.             }
  127.         }
  128.         else
  129.         {
  130.             /* get next event, but return if none are available */
  131.             message = (struct IntuiMessage *)GetMsg(W->UserPort);
  132.             if (message == NULL)
  133.             {
  134.             result = -1;
  135.             break;
  136.             }
  137.         }
  138.         class = message->Class;
  139.         code = message->Code;
  140.         qual = message->Qualifier;
  141.         MouseX = message->MouseX;
  142.         MouseY = message->MouseY;
  143.         ReplyMsg((struct Message *)message);
  144.  
  145.         switch (class)
  146.         {
  147.         case CLOSEWINDOW:
  148.             /* ignore for now */
  149.             continue;
  150.         case VANILLAKEY:
  151.             result = code;
  152.             if (result == '\r') result = '\n';
  153.             break;
  154.         case RAWKEY:
  155.             if (code&0x80) continue;    /* ignore key releases */
  156.             /* only recognize wanderer keys */
  157.             /* can use cursor keys, hjkl, ibm keypad for moving */
  158.             if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  159.                 result = myshiftkeys[code];
  160.             else
  161.                 result = mykeys[code];
  162.             if (result == 0) continue;    /* ignore undef keys */
  163.             break;
  164.  
  165.         case MENUPICK:
  166.             if (code == MENUNULL) continue;
  167.             switch (MENUNUM(code)) {
  168.             case 0:
  169.                 switch (ITEMNUM(code)) {
  170.                 case 0:        result = 'W'; break;
  171.                 case 1:        result = 'S'; break;
  172.                 case 2:        result = 'R'; break;
  173.                 case 4:        result = 'c'; break;
  174.                 case 5:        result = 'q'; break;
  175.                 default:    continue;
  176.                 }
  177.                 break;
  178.             case 1:
  179.                 switch (ITEMNUM(code)) {
  180.                 case 0:        result = '~'; break;
  181.                 case 1:        result = '#'; break;
  182.                 case 2:        result = '@'; break;
  183.                 case 3:        result = '!'; break;
  184.                 case 4:        result = '?'; break;
  185.                 default:    continue;
  186.                 }
  187.                 break;
  188.             default:
  189.                 continue;
  190.             }
  191.             break;
  192.  
  193.         case MOUSEBUTTONS:
  194.             switch (code)
  195.             {
  196.             case SELECTDOWN:
  197.                 break;    /* left button pressed */
  198.             default:
  199.                 continue; /* ignore button releases */
  200.             }
  201.             result = MOUSE;
  202.             break;
  203.         default:
  204.             continue;
  205.         }
  206.         break;
  207.     }
  208.     /* turn off cursor if it was on */
  209.     if (flags & VANILLAKEY) cursor(0);
  210.     return result;
  211. }
  212.  
  213. struct TextAttr font =
  214. {
  215.     "topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT
  216. };
  217.  
  218. struct NewScreen ns =
  219. {
  220.     0,0,640,200,4,BLACK,WHITE,HIRES,CUSTOMSCREEN,&font,"Wanderer V2.2",NULL,NULL
  221. };
  222.  
  223. initscr()
  224. {
  225.     struct NewWindow nw;
  226.     struct TextAttr font_attr;
  227.  
  228.     if (S != NULL) return;
  229.  
  230.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
  231.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
  232.     if (IntuitionBase == NULL || GfxBase == NULL) exit(1);
  233.  
  234.     /* load the digitized sound effects (yeah, what's it doing here?) */
  235.     initSounds();
  236.  
  237.     /* load the map font */
  238.     DiskfontBase = (struct Library *) OpenLibrary("diskfont.library",0);
  239.     font_attr.ta_Name = "wanderer.font";
  240.     font_attr.ta_YSize = 8;
  241.     font_attr.ta_Style = 0;
  242.     font_attr.ta_Flags = 0;
  243.     map_font = (struct TextFont *) OpenDiskFont(&font_attr);
  244.  
  245.     if ((S = (struct Screen *) OpenScreen(&ns)) == NULL) exit(1);
  246.  
  247.     nw.LeftEdge = 0;
  248.     nw.TopEdge = TOPEDGE;
  249.     nw.Width = WindowWidth;
  250.     nw.Height = WindowHeight;
  251.     nw.DetailPen = BLACK;
  252.     nw.BlockPen = WHITE;
  253.     nw.Title = NULL;
  254.     nw.Flags = SMART_REFRESH | ACTIVATE | BACKDROP |
  255.            BORDERLESS | NOCAREREFRESH;
  256.     nw.IDCMPFlags = RAWKEY;
  257.     nw.Type = CUSTOMSCREEN;
  258.     nw.FirstGadget = NULL;
  259.     nw.CheckMark = NULL;
  260.     nw.Screen = S;
  261.     nw.BitMap = NULL;
  262.     if ((W = (struct Window *) OpenWindow(&nw)) == NULL) exit(1);
  263.     R = W->RPort;
  264.  
  265.     /* setup colors */
  266.     LoadRGB4(&S->ViewPort, Palette, PaletteColorCount);
  267.  
  268.     /* keep track of original font */
  269.     text_font = R->Font;
  270.  
  271.     SetAPen(R, TEXT_COLOR);
  272.     SetBPen(R, BACK_COLOR);
  273.     ShowTitle(S, FALSE);
  274.     SetMenuStrip(W, &MenuList1);
  275.     clear();
  276. }
  277.  
  278. move(r,c)
  279. int r,c;
  280. {
  281.     Move(R, c*8, r*8 + R->Font->tf_Baseline);
  282. }
  283.  
  284. eraseeol()
  285. {
  286.     int x, y;
  287.     x = R->cp_x;
  288.     y = R->cp_y  - R->Font->tf_Baseline;
  289.     SetAPen(R, BACK_COLOR);
  290.     RectFill(R, x, y, WindowWidth, y+R->Font->tf_YSize-1);
  291.     SetAPen(R, TEXT_COLOR);
  292. }
  293.  
  294. eraserow(r)
  295. {
  296.     move(r,0);
  297.     eraseeol();
  298. }
  299.  
  300. endwin()
  301. {
  302.     freeSounds(NULL);
  303.     if (map_font) CloseFont(map_font);
  304.     if (W) { ClearMenuStrip(W); CloseWindow(W); }
  305.     if (S) CloseScreen(S);
  306. }
  307.  
  308. set_map_font(flag)
  309. int flag;
  310. {
  311.     if (flag) SetFont(R, map_font);
  312.     else SetFont(R, text_font);
  313. }
  314.  
  315. clear()
  316. {
  317.     SetAPen(R, BACK_COLOR);
  318.     RectFill(R, 0, 0, WindowWidth, WindowHeight);
  319.     SetAPen(R, TEXT_COLOR);
  320.     move(0,0);
  321. }
  322.  
  323. /* get a line of input from the console, handling backspaces */
  324. /* menus are disable while inputting */
  325. getstr(s)
  326. char *s;
  327. {
  328.     char *origs = s;
  329.     int c;
  330.  
  331.     ClearMenuStrip(W);
  332.     SetAPen(R, INPUT_COLOR);
  333.     while ( (c=getvanillach()) != '\n' && c!='\r' && c!= EOF ) {
  334.         if ( c == '\b' ) {
  335.             if ( s > origs ) {
  336.                 addstr("\b \b");
  337.                 s--;
  338.             }
  339.         }
  340.         else if (c == 24) {
  341.             while (s > origs) {
  342.                 addstr("\b \b");
  343.                 s--;
  344.             }
  345.         } else if (isprint(c)) {
  346.             addch(c);
  347.             *s++ = c;
  348.         }
  349.         refresh();
  350.     }
  351.     *s = '\0';
  352.     SetAPen(R, TEXT_COLOR);
  353.     SetMenuStrip(W, &MenuList1);
  354. }
  355.  
  356. addstr(s)
  357. char *s;
  358. {
  359.     /* output is fastest if is many chars as possible can be */
  360.     /* displayed in a single Text() call, so we scan for special */
  361.     /* characters that need to be interpreted, and do the rest */
  362.     /* in as few Text() calls as possible */
  363.     register int i,a;
  364.     for (i=0,a=0; ; ++i) {
  365.         if (s[i] < ' ') {
  366.             /* special character found */
  367.             /* output everything up to this character */
  368.             if (i-a>0) Text(R, s+a, i-a);
  369.             /* interpret the special character */
  370.             if (s[i] == 0) break;
  371.             addch(s[i]);
  372.             /* continue after the special character */
  373.             a = i+1;
  374.         }
  375.     }
  376. }
  377.  
  378. addch(c)
  379. int c;
  380. {
  381.     char s;
  382.     switch (c) {
  383.     case '\n':
  384.         Move(R, 0, R->cp_y + 8);
  385.         break;
  386.     case '\r':
  387.         Move(R, 0, R->cp_y);
  388.         break;
  389.     case '\t':
  390.         Move(R, R->cp_x + 64 - (R->cp_x % 64), R->cp_y);
  391.         break;
  392.     case '\b':
  393.         Move(R, R->cp_x - 8, R->cp_y);
  394.         break;
  395.     case '\007':
  396.         DisplayBeep(S);
  397.         break;
  398.     default:
  399.         s = c;
  400.         Text(R, &s, 1);
  401.         break;
  402.     }
  403. }
  404.  
  405. struct IntuiText fataltext = { 1,0,COMPLEMENT,16,32,NULL,NULL,NULL };
  406. struct IntuiText canceltext = { 1,0,COMPLEMENT,2,2,NULL,"goodbye",NULL };
  407.  
  408. fatal(text)
  409. char *text;
  410. {
  411.     fataltext.IText = text;
  412.     AutoRequest(W, &fataltext, NULL, &canceltext, 0, 0, 320, 90);
  413.     endwin();
  414.     exit(1);
  415. }
  416.  
  417. #endif
  418.