home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d115 / marketroid.lha / Marketroid / src / text.c < prev   
C/C++ Source or Header  |  1987-11-22  |  5KB  |  227 lines

  1. /*  :ts=8 bk=0
  2.  *
  3.  * text.c:    Subtask to write text onto screen, and support routines.
  4.  *        A lot of this was stolen directly from another published
  5.  *        program I wrote.
  6.  *
  7.  * Leo L. Schwab            8710.6        (415) 456-3960
  8.  */
  9. #include <exec/types.h>
  10. #include <devices/timer.h>
  11. #include <graphics/gfx.h>
  12. #include <graphics/rastport.h>
  13. #include "marketroid.h"
  14.  
  15. #define docmd(p,r,c)    { PutMsg (p, c);  WaitPort (r);  GetMsg (r); }
  16.  
  17. #define TIMERSIG    (1L << tr -> tr_node.io_Message.mn_ReplyPort -> mp_SigBit)
  18. #define PRGSIG        (1L << prgport -> mp_SigBit)
  19. #define    TEXTPORT    "Text Port"
  20.  
  21. #define    CMD_SUICIDE    CMD_NONSTD
  22. #define    CMD_HELLO    (CMD_NONSTD+1)
  23.  
  24.  
  25. struct IOStdReq        *textcmd;
  26. struct MsgPort        *textport, *textreply;
  27. struct Task        *texttask;
  28.  
  29.  
  30. dotext (str, x, y)
  31. char *str;
  32. UWORD x, y;
  33. {
  34.     textcmd -> io_Command    = CMD_WRITE;
  35.     textcmd -> io_Data    = (APTR) str;
  36.     textcmd -> io_Offset    = ((long) x << 16) + y;
  37.     PutMsg (textport, textcmd);
  38. }
  39.  
  40. textdone ()
  41. {
  42.     return (GetMsg (textreply) != NULL);
  43. }
  44.  
  45. waittext ()
  46. {
  47.     WaitPort (textreply);
  48.     GetMsg (textreply);
  49. }
  50.  
  51. /*
  52.  * The text printing sub-task.  Designed to run at priority level 1.
  53.  */
  54. void
  55. texter ()
  56. {
  57.     register struct IOStdReq    *msg;
  58.     register long            sigmask;
  59.     register char            *str;
  60.     struct RastPort            rp;
  61.     struct timerequest        *tr = NULL;
  62.     struct IOStdReq            *replythis = NULL;
  63.     struct MsgPort            *timeport = NULL,
  64.                     *prgport = NULL;
  65.     long                x, y,
  66.                     delay = 100000;
  67.     char                stopped = 1,
  68.                     active = 0;
  69.  
  70.     geta4 ();
  71.  
  72.     /*
  73.      * Since this is an independent task, we'll have to do
  74.      * everything ourselves.....
  75.      */
  76.     if (!(timeport = CreatePort (NULL, NULL)))
  77.         goto bombout;
  78.  
  79.     if (!(prgport = CreatePort (TEXTPORT, 1L)))
  80.         goto bombout;
  81.  
  82.     if (!(tr = CreateExtIO (timeport, (long) sizeof (*tr))))
  83.         goto bombout;
  84.  
  85.     if (OpenDevice (TIMERNAME, UNIT_VBLANK, tr, 0L))
  86.         goto bombout;
  87.     tr -> tr_node.io_Command = TR_ADDREQUEST;
  88.  
  89.     /*
  90.      * Stand around twiddling our thumbs until the main program
  91.      * wants us to do something.
  92.      */
  93.     WaitPort (prgport);
  94.     msg = GetMsg (prgport);
  95.     if (msg -> io_Command != CMD_HELLO)
  96.         die ("texter(): Hello???\n");
  97.     rp = *((struct RastPort *) msg -> io_Data);
  98.     SetFont (&rp, msg -> io_Device);
  99.     ReplyMsg (msg);
  100.     sigmask = TIMERSIG | PRGSIG;
  101.  
  102.     while (1) {
  103.         Wait (sigmask);
  104.  
  105.         if (CheckIO (tr)) {
  106.             /*  Timer expired, write next chunk of text.  */
  107.             WaitIO (tr);
  108.             active = 0;
  109.             if (!stopped) {
  110.                 while (*str < ' ') {
  111.                     if (*str == '\033') {
  112.                         /*  Escape means Newline  */
  113.                         y += 8;
  114.                         Move (&rp, x, y);
  115.                     } else
  116.                         /*  Change color  */
  117.                         SetAPen (&rp, (long) *str);
  118.                     str++;
  119.                 }
  120.                 Text (&rp, str++, 1L);
  121.                 if (!*str) {
  122.                     stopped = 1;
  123.                     ReplyMsg (replythis);
  124.                 }
  125.             }
  126.         }
  127.  
  128.         while (msg = GetMsg (prgport))
  129.             /*  Command coming in from main program  */
  130.             switch (msg -> io_Command) {
  131.             case CMD_RESET:
  132.             case CMD_STOP:
  133.             /*  Main program asking us to stop  */
  134.                 stopped = 1;
  135.                 ReplyMsg (msg);
  136.                 break;
  137.             case CMD_START:
  138.                 stopped = 0;
  139.                 ReplyMsg (msg);
  140.                 break;
  141.             case CMD_UPDATE:
  142.                 delay = (ULONG) msg -> io_Device;
  143.                 ReplyMsg (msg);
  144.                 break;
  145.             case CMD_WRITE:
  146.                 str = (char *) msg -> io_Data;
  147.                 replythis = msg;
  148.                 x = msg->io_Offset >> 16;
  149.                 y = msg->io_Offset & 0xffff;
  150.                 Move (&rp, x, y);
  151.                 stopped = 0;
  152.                 break;
  153.             case CMD_SUICIDE:
  154.                 goto bombout;
  155.             default:
  156.                 ReplyMsg (msg);
  157.             }
  158.  
  159.         if (!stopped && !active) {
  160.             tr -> tr_time.tv_secs    = (ULONG) 0;
  161.             tr -> tr_time.tv_micro    = (ULONG) delay;
  162.             SendIO (tr);
  163.             active = 1;
  164.         }
  165.  
  166.     }
  167. bombout:
  168.     if (active) {    /*  Outstanding timer request  */
  169.         WaitPort (timeport);
  170.         GetMsg (timeport);
  171.     }
  172.     if (tr)
  173.         if (tr -> tr_node.io_Command == TR_ADDREQUEST)
  174.             /* Command got assigned, so its open */
  175.             CloseDevice (tr);
  176.         DeleteExtIO (tr, (long) sizeof (*tr));
  177.     if (prgport)
  178.         DeletePort (prgport);
  179.     if (timeport)
  180.         DeletePort (timeport);
  181.     if (msg)
  182.         /*  This must be the suicide message, so reply it  */
  183.         ReplyMsg (msg);
  184.  
  185.     /*  Wait for Godot  */
  186.     Wait (0L);
  187. }
  188.  
  189.  
  190. /*  Housekeeping  */
  191. opentext (rp, font)
  192. struct RastPort *rp;
  193. void *font;
  194. {
  195.     if (!(textreply = CreatePort (NULL, NULL)))
  196.         die ("Couldn't allocate textreply port.\n");
  197.  
  198.     if (!(textcmd = CreateStdIO (textreply)))
  199.         die ("Couldn't allocate textcmd.\n");
  200.  
  201.     if (!(texttask = CreateTask ("Text Task", 1L, texter, 4096L)))
  202.         die ("Text task failed to spawn\n");
  203.  
  204.     if (!(textport = FindPort (TEXTPORT)))
  205.         die ("Can't locate text task's command port.\n");
  206.  
  207.     textcmd -> io_Command    = CMD_HELLO;
  208.     textcmd -> io_Data    = (APTR) rp;
  209.     textcmd -> io_Device    = font;
  210.     docmd (textport, textreply, textcmd);
  211. }
  212.  
  213. closetext ()
  214. {
  215.     if (textreply)
  216.         while (GetMsg (textreply))
  217.             ;
  218.  
  219.     if (texttask) {
  220.         textcmd -> io_Command = CMD_SUICIDE;
  221.         docmd (textport, textreply, textcmd);
  222.         DeleteTask (texttask);
  223.     }
  224.     if (textcmd)    DeleteStdIO (textcmd);
  225.     if (textreply)    DeletePort (textreply);
  226. }
  227.