home *** CD-ROM | disk | FTP | other *** search
- /**** edraw.c ****/
- /* By Paul Field
- * See !ReadMe file for distribution/modification restrictions
- */
-
- #include "edraw.h"
-
- #include <assert.h>
- #include "alarm.h"
- #include "bbc.h"
-
- struct edraw_splitinfostr
- { int height;
- int y;
- int lx, by, rx, ty;
- BOOL realtimedout;
- euclid_drawinfo infocopy;
- };
-
- os_error nomem = {0, "Not enough memory to draw picture"};
-
-
- #pragma no_check_stack
-
- void edraw_initialise(edraw_info *info)
- { info->timedout = FALSE;
- info->splitinfo = NULL;
- }
-
- os_error *edraw_draw(edraw_info *info)
- { os_error *e;
- euclid_drawstyle style;
- unsigned int timeout;
-
- assert(!(info->style & edrawstyle_continuetimedout));
- assert(!(info->style & (edrawstyle_timeout * 0xff)));
-
- timeout = (info->timeout < 254 ? info->timeout : 254);
- style = (info->timedout ? edrawstyle_continuetimedout : info->style);
- style |= edrawstyle_timeout * timeout;
- e = euclid_draw(style, info->structure, info->xoffset, info->yoffset,
- info->camera, info->vduvars,
- &info->timedout, &info->infoblock);
- if (!timeout || e)
- { info->timedout = FALSE;
- }
- return(e);
- }
-
- void edraw_stop(edraw_info *info)
- { assert(info->timeout);
- info->timedout = FALSE;
- free(info->splitinfo);
- info->splitinfo = NULL;
- }
-
-
- static void edraw_getgwindow(int *coords)
- { /* Assumes coords points to 'array' : lx, by, rx, ty */
- static int vduvars[] =
- { bbc_GWLCol, bbc_GWBRow, bbc_GWRCol, bbc_GWTRow, bbc_OrgX, bbc_OrgY,
- bbc_XEigFactor, bbc_YEigFactor, -1
- };
- int varvals[8];
- int dx, dy;
-
- bbc_vduvars(vduvars, varvals);
- dx = 1<<varvals[6]; /*XEigFactor*/
- dy = 1<<varvals[7]; /*YEigFactor*/
- *coords++ = varvals[0]*dx - varvals[4];
- *coords++ = varvals[1]*dy - varvals[5];
- *coords++ = varvals[2]*dx - varvals[4];
- *coords = varvals[3]*dy - varvals[5];
- }
-
-
- os_error *edraw_split(edraw_info *info)
- { os_error *e = NULL;
- int starttime, timeleft;
- int timeout;
- edraw_splitinfo *split;
-
- /* Outside of this routine : */
- /* 'split->realtimedout' indicates whether euclid has timed out */
- /* 'info->timedout' indicates whether euclid or split has timed out */
-
- assert(info->splitinfo || !info->timedout);
- assert(!info->splitinfo || info->timedout);
-
- if (!info->splitinfo)
- { if ((split = malloc(sizeof(edraw_splitinfo))) == NULL)
- { return(&nomem);
- }
- edraw_getgwindow(&split->lx);
- split->y = split->ty;
- split->height = split->ty - split->by;
- split->realtimedout = FALSE;
- }
- else
- { split = info->splitinfo;
- }
- starttime = alarm_timenow();
- timeout = info->timeout;
- timeleft = timeout;
- info->timedout = split->realtimedout;
- do
- { if (split->y - split->height < split->by)
- { split->height = split->y - split->by;
- }
- info->timeout = timeleft;
- bbc_gwindow(split->lx,split->y - split->height,split->rx,split->y);
- if ((e = edraw_draw(info)) != NULL)
- { /* Euclid cannot draw the picture so we'll try drawing smaller strips */
- if (split->height > 1)
- { split->height /= 2;
- e = NULL;
- }
- }
- else
- { if (!info->timedout)
- { split->y -= split->height+1;
- }
- }
- if (timeout)
- { timeleft = timeout - alarm_timedifference(starttime, alarm_timenow());
- }
- }
- while(split->y >= split->by && !e && (timeleft > 0 || !timeout));
-
- split->realtimedout = info->timedout;
- info->timedout = (split->y >= split->by) && !e;
- if (info->timedout)
- { info->splitinfo = split;
- if (timeout)
- { if (split->realtimedout)
- { info->infoblock->nexty += split->y - split->height-1;
- }
- else
- { info->infoblock = &split->infocopy;
- info->infoblock->nexty = split->y - split->by;
- info->infoblock->nextx = 0;
- }
- }
- }
- else
- { free(split);
- info->splitinfo = NULL;
- }
- info->timeout = timeout;
-
- return(e);
- }
-