home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / graphics / a090_1 / c / edraw < prev    next >
Text File  |  1992-04-18  |  4KB  |  153 lines

  1. /**** edraw.c ****/
  2. /* By Paul Field
  3.  * See !ReadMe file for distribution/modification restrictions
  4.  */
  5.  
  6. #include "edraw.h"
  7.  
  8. #include <assert.h>
  9. #include "alarm.h"
  10. #include "bbc.h"
  11.  
  12. struct edraw_splitinfostr
  13.  { int height;
  14.    int y;
  15.    int lx, by, rx, ty;
  16.    BOOL realtimedout;
  17.    euclid_drawinfo infocopy;
  18.  };
  19.  
  20. os_error nomem = {0, "Not enough memory to draw picture"};
  21.  
  22.  
  23. #pragma no_check_stack
  24.  
  25. void edraw_initialise(edraw_info *info)
  26.  { info->timedout  = FALSE;
  27.    info->splitinfo = NULL;
  28.  }
  29.  
  30. os_error *edraw_draw(edraw_info *info)
  31.  { os_error *e;
  32.    euclid_drawstyle style;
  33.    unsigned int timeout;
  34.  
  35.    assert(!(info->style & edrawstyle_continuetimedout));
  36.    assert(!(info->style & (edrawstyle_timeout * 0xff)));
  37.  
  38.    timeout = (info->timeout < 254 ? info->timeout : 254);
  39.    style   = (info->timedout ? edrawstyle_continuetimedout : info->style);
  40.    style |= edrawstyle_timeout * timeout;
  41.    e = euclid_draw(style, info->structure, info->xoffset, info->yoffset,
  42.                    info->camera, info->vduvars,
  43.                    &info->timedout, &info->infoblock);
  44.    if (!timeout || e)
  45.     { info->timedout = FALSE;
  46.     }
  47.    return(e);
  48.  }
  49.  
  50. void edraw_stop(edraw_info *info)
  51.  { assert(info->timeout);
  52.    info->timedout = FALSE;
  53.    free(info->splitinfo);
  54.    info->splitinfo = NULL;
  55.  }
  56.  
  57.  
  58. static void edraw_getgwindow(int *coords)
  59.  { /* Assumes coords points to 'array' : lx, by, rx, ty */
  60.    static int vduvars[] =
  61.     { bbc_GWLCol, bbc_GWBRow, bbc_GWRCol, bbc_GWTRow, bbc_OrgX, bbc_OrgY,
  62.       bbc_XEigFactor, bbc_YEigFactor, -1
  63.     };
  64.    int varvals[8];
  65.    int dx, dy;
  66.  
  67.    bbc_vduvars(vduvars, varvals);
  68.    dx  = 1<<varvals[6];  /*XEigFactor*/
  69.    dy  = 1<<varvals[7];  /*YEigFactor*/
  70.    *coords++ = varvals[0]*dx - varvals[4];
  71.    *coords++ = varvals[1]*dy - varvals[5];
  72.    *coords++ = varvals[2]*dx - varvals[4];
  73.    *coords   = varvals[3]*dy - varvals[5];
  74.  }
  75.  
  76.  
  77. os_error *edraw_split(edraw_info *info)
  78.  { os_error *e = NULL;
  79.    int starttime, timeleft;
  80.    int timeout;
  81.    edraw_splitinfo *split;
  82.  
  83.    /* Outside of this routine : */
  84.    /* 'split->realtimedout' indicates whether euclid has timed out */
  85.    /* 'info->timedout' indicates whether euclid or split has timed out */
  86.  
  87.    assert(info->splitinfo || !info->timedout);
  88.    assert(!info->splitinfo || info->timedout);
  89.  
  90.    if (!info->splitinfo)
  91.     { if ((split = malloc(sizeof(edraw_splitinfo))) == NULL)
  92.        { return(&nomem);
  93.        }
  94.       edraw_getgwindow(&split->lx);
  95.       split->y = split->ty;
  96.       split->height = split->ty - split->by;
  97.       split->realtimedout = FALSE;
  98.     }
  99.    else
  100.     { split = info->splitinfo;
  101.     }
  102.    starttime = alarm_timenow();
  103.    timeout   = info->timeout;
  104.    timeleft  = timeout;
  105.    info->timedout = split->realtimedout;
  106.    do
  107.     { if (split->y - split->height < split->by)
  108.        { split->height = split->y - split->by;
  109.        }
  110.       info->timeout = timeleft;
  111.       bbc_gwindow(split->lx,split->y - split->height,split->rx,split->y);
  112.       if ((e = edraw_draw(info)) != NULL)
  113.        { /* Euclid cannot draw the picture so we'll try drawing smaller strips */
  114.          if (split->height > 1)
  115.           { split->height /= 2;
  116.             e = NULL;
  117.           }
  118.        }
  119.       else
  120.        { if (!info->timedout)
  121.           { split->y -= split->height+1;
  122.           }
  123.        }
  124.       if (timeout)
  125.        { timeleft = timeout - alarm_timedifference(starttime, alarm_timenow());
  126.        }
  127.     }
  128.    while(split->y >= split->by && !e && (timeleft > 0 || !timeout));
  129.  
  130.    split->realtimedout = info->timedout;
  131.    info->timedout = (split->y >= split->by) && !e;
  132.    if (info->timedout)
  133.     { info->splitinfo = split;
  134.       if (timeout)
  135.        { if (split->realtimedout)
  136.           { info->infoblock->nexty += split->y - split->height-1;
  137.           }
  138.          else
  139.           { info->infoblock = &split->infocopy;
  140.             info->infoblock->nexty = split->y - split->by;
  141.             info->infoblock->nextx = 0;
  142.           }
  143.        }
  144.     }
  145.    else
  146.     { free(split);
  147.       info->splitinfo = NULL;
  148.     }
  149.    info->timeout = timeout;
  150.  
  151.    return(e);
  152.  }
  153.