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