home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- *
- * text.c: Subtask to write text onto screen, and support routines.
- * A lot of this was stolen directly from another published
- * program I wrote.
- *
- * Leo L. Schwab 8710.6 (415) 456-3960
- */
- #include <exec/types.h>
- #include <devices/timer.h>
- #include <graphics/gfx.h>
- #include <graphics/rastport.h>
- #include "marketroid.h"
-
- #define docmd(p,r,c) { PutMsg (p, c); WaitPort (r); GetMsg (r); }
-
- #define TIMERSIG (1L << tr -> tr_node.io_Message.mn_ReplyPort -> mp_SigBit)
- #define PRGSIG (1L << prgport -> mp_SigBit)
- #define TEXTPORT "Text Port"
-
- #define CMD_SUICIDE CMD_NONSTD
- #define CMD_HELLO (CMD_NONSTD+1)
-
-
- struct IOStdReq *textcmd;
- struct MsgPort *textport, *textreply;
- struct Task *texttask;
-
-
- dotext (str, x, y)
- char *str;
- UWORD x, y;
- {
- textcmd -> io_Command = CMD_WRITE;
- textcmd -> io_Data = (APTR) str;
- textcmd -> io_Offset = ((long) x << 16) + y;
- PutMsg (textport, textcmd);
- }
-
- textdone ()
- {
- return (GetMsg (textreply) != NULL);
- }
-
- waittext ()
- {
- WaitPort (textreply);
- GetMsg (textreply);
- }
-
- /*
- * The text printing sub-task. Designed to run at priority level 1.
- */
- void
- texter ()
- {
- register struct IOStdReq *msg;
- register long sigmask;
- register char *str;
- struct RastPort rp;
- struct timerequest *tr = NULL;
- struct IOStdReq *replythis = NULL;
- struct MsgPort *timeport = NULL,
- *prgport = NULL;
- long x, y,
- delay = 100000;
- char stopped = 1,
- active = 0;
-
- geta4 ();
-
- /*
- * Since this is an independent task, we'll have to do
- * everything ourselves.....
- */
- if (!(timeport = CreatePort (NULL, NULL)))
- goto bombout;
-
- if (!(prgport = CreatePort (TEXTPORT, 1L)))
- goto bombout;
-
- if (!(tr = CreateExtIO (timeport, (long) sizeof (*tr))))
- goto bombout;
-
- if (OpenDevice (TIMERNAME, UNIT_VBLANK, tr, 0L))
- goto bombout;
- tr -> tr_node.io_Command = TR_ADDREQUEST;
-
- /*
- * Stand around twiddling our thumbs until the main program
- * wants us to do something.
- */
- WaitPort (prgport);
- msg = GetMsg (prgport);
- if (msg -> io_Command != CMD_HELLO)
- die ("texter(): Hello???\n");
- rp = *((struct RastPort *) msg -> io_Data);
- SetFont (&rp, msg -> io_Device);
- ReplyMsg (msg);
- sigmask = TIMERSIG | PRGSIG;
-
- while (1) {
- Wait (sigmask);
-
- if (CheckIO (tr)) {
- /* Timer expired, write next chunk of text. */
- WaitIO (tr);
- active = 0;
- if (!stopped) {
- while (*str < ' ') {
- if (*str == '\033') {
- /* Escape means Newline */
- y += 8;
- Move (&rp, x, y);
- } else
- /* Change color */
- SetAPen (&rp, (long) *str);
- str++;
- }
- Text (&rp, str++, 1L);
- if (!*str) {
- stopped = 1;
- ReplyMsg (replythis);
- }
- }
- }
-
- while (msg = GetMsg (prgport))
- /* Command coming in from main program */
- switch (msg -> io_Command) {
- case CMD_RESET:
- case CMD_STOP:
- /* Main program asking us to stop */
- stopped = 1;
- ReplyMsg (msg);
- break;
- case CMD_START:
- stopped = 0;
- ReplyMsg (msg);
- break;
- case CMD_UPDATE:
- delay = (ULONG) msg -> io_Device;
- ReplyMsg (msg);
- break;
- case CMD_WRITE:
- str = (char *) msg -> io_Data;
- replythis = msg;
- x = msg->io_Offset >> 16;
- y = msg->io_Offset & 0xffff;
- Move (&rp, x, y);
- stopped = 0;
- break;
- case CMD_SUICIDE:
- goto bombout;
- default:
- ReplyMsg (msg);
- }
-
- if (!stopped && !active) {
- tr -> tr_time.tv_secs = (ULONG) 0;
- tr -> tr_time.tv_micro = (ULONG) delay;
- SendIO (tr);
- active = 1;
- }
-
- }
- bombout:
- if (active) { /* Outstanding timer request */
- WaitPort (timeport);
- GetMsg (timeport);
- }
- if (tr)
- if (tr -> tr_node.io_Command == TR_ADDREQUEST)
- /* Command got assigned, so its open */
- CloseDevice (tr);
- DeleteExtIO (tr, (long) sizeof (*tr));
- if (prgport)
- DeletePort (prgport);
- if (timeport)
- DeletePort (timeport);
- if (msg)
- /* This must be the suicide message, so reply it */
- ReplyMsg (msg);
-
- /* Wait for Godot */
- Wait (0L);
- }
-
-
- /* Housekeeping */
- opentext (rp, font)
- struct RastPort *rp;
- void *font;
- {
- if (!(textreply = CreatePort (NULL, NULL)))
- die ("Couldn't allocate textreply port.\n");
-
- if (!(textcmd = CreateStdIO (textreply)))
- die ("Couldn't allocate textcmd.\n");
-
- if (!(texttask = CreateTask ("Text Task", 1L, texter, 4096L)))
- die ("Text task failed to spawn\n");
-
- if (!(textport = FindPort (TEXTPORT)))
- die ("Can't locate text task's command port.\n");
-
- textcmd -> io_Command = CMD_HELLO;
- textcmd -> io_Data = (APTR) rp;
- textcmd -> io_Device = font;
- docmd (textport, textreply, textcmd);
- }
-
- closetext ()
- {
- if (textreply)
- while (GetMsg (textreply))
- ;
-
- if (texttask) {
- textcmd -> io_Command = CMD_SUICIDE;
- docmd (textport, textreply, textcmd);
- DeleteTask (texttask);
- }
- if (textcmd) DeleteStdIO (textcmd);
- if (textreply) DeletePort (textreply);
- }
-