/* * raster: routines to do operations on raster screens */ #include #include #include "raster.h" static struct { int b_wd; int b_ht; int plane_ct; int fg_col; int bg_col; char op_tab[4]; int s_xmin; int s_ymin; char *s_form; int s_nxwd; int s_nxln; int s_nxpl; int d_xmin; int d_ymin; char *d_form; int d_nxwd; int d_nxln; int d_nxpl; char *p_addr; int p_nxln; int p_nxpl; int p_mask; char reserved[24]; } magic; int bltmode[] = { 4, 3, 6, 0, 15, 10 }; #define NPAGES 3 static char map1space[YMAX * 80 + 512]; static char map2space[YMAX * 80]; static char map3space[YMAX * 80]; char *display, *mapptr; Bitmap Dblock = { 0L, 80, { {0,0}, {640,400} } }; dispinit() { display = (char*)Physbase(); Dblock.blk_address = display; mapptr = (char *)((long)map1space | 511L) + 1; } bitblt(src, srcpos, dst, dstcorner, mode) Bitmap *src; Rectangle *srcpos; Bitmap *dst; Point *dstcorner; { register rez = Getrez(); if (mode < 0 || mode > 5) return; /* gotoxy(1,1); printf("bitblt(\nsrc->blk_address = %0lx\n",src->blk_address); printf("src->rect.origin.x,y %d,%d\n",src->rect.origin.x,src->rect.origin.y); printf("srcpos->origin.x,y %d,%d\n",srcpos->origin.x,srcpos->origin.y); printf("srcpos->corner.x,y %d,%d\n",srcpos->corner.x,srcpos->corner.y); printf("dst->blk_address = %0lx\n",dst->blk_address); printf("dst->rect.origin.x,y %d,%d\n",dst->rect.origin.x,dst->rect.origin.y); printf("dstcorner->x,y %d,%d\n",dstcorner->x,dstcorner->y); Crawcin(); */ magic.op_tab[0] = bltmode[mode]; magic.bg_col = magic.fg_col = 0; magic.plane_ct = 1; magic.b_wd = srcpos->corner.x - srcpos->origin.x; magic.b_ht = srcpos->corner.y - srcpos->origin.y; magic.s_nxpl = magic.d_nxpl = 2; magic.s_nxwd = magic.d_nxwd = 1 << ((2-rez)+1); magic.d_form = dst->blk_address; magic.d_xmin = dst->rect.origin.x + dstcorner->x; magic.d_ymin = dst->rect.origin.y + dstcorner->y; magic.d_nxln = dst->blk_width; magic.s_form = src->blk_address; magic.s_xmin = src->rect.origin.x + srcpos->origin.x; magic.s_ymin = src->rect.origin.y + srcpos->origin.y; magic.s_nxln = src->blk_width; _blit(&magic); } texture(b, ox, oy, cx, cy, pattern, plast, mode) Bitmap *b; char *pattern; { Setscreen(b->blk_address,-1L,-1); jtexture(b->rect.origin.x + ox, b->rect.origin.y + oy, b->rect.origin.x + cx, b->rect.origin.y + cy, pattern, plast, mode); Setscreen(display,-1L,-1); } rectf(src, srcpos, mode) Bitmap *src; Rectangle *srcpos; { bitblt(src, srcpos, src, &srcpos->origin, mode + F_ERASE); } jrectf(srcpos, mode) Rectangle *srcpos; { bitblt(&Dblock, srcpos, &Dblock, &srcpos->origin, mode + F_ERASE); } static int currx = 0, curry = 0, maxy = 0, pages = 1; Bitmap * balloc(rect) Rectangle *rect; { Bitmap *tmp, *malloc(); int width, bwidth, size, height; width = rect->corner.x - rect->origin.x; height = rect->corner.y - rect->origin.y; bwidth = (width + 7)/8; size = bwidth * height; if (tmp = malloc(sizeof(Bitmap))) { if (bwidth + currx > 80) { currx = 0; curry = maxy; } if (height + curry > YMAX) { if (++pages > NPAGES) { fprintf(stderr,"not enough bitmap space for block in balloc\n"); exit(-42); } mapptr = (char *)((long)mapptr + (80L * YMAX)); currx = 0; curry = 0; maxy = 0; } tmp->rect.origin.x = currx * 8; tmp->rect.origin.y = curry; tmp->rect.corner.x = width + currx * 8; tmp->rect.corner.y = height + curry; currx += bwidth; if (height + curry > maxy) maxy = curry + height; tmp->blk_width = 80 /* in the real world we could have this be bwidth */; tmp->blk_address = mapptr; } else { fprintf(stderr,"malloc failed in balloc\n"); exit(-42); } return tmp; } bfree(p) Bitmap *p; { free(p); } jsegment(x1, y1, x2, y2, mode) { dline(x1, y1, x2, y2, mode); } segment(b, x1, y1, x2, y2, mode) Bitmap *b; { Setscreen(b->blk_address,-1L,-1); dline(b->rect.origin.x + x1, b->rect.origin.y + y1, b->rect.origin.x + x2, b->rect.origin.y + y2, mode); Setscreen(display,-1L,-1); } jpolygon(pts, size, colour) Point pts[]; register size; { register point; for (point=0; pointrect.origin.x, centery = cy + b->rect.origin.y; Point *orig,*corn; register int lx, rx, ty, by; register int rootrad; rad_sqr = (float)radius * (float)radius; rootrad = (float)radius / sqrt(2.0); Setscreen(b->blk_address,-1L,-1); orig = &b->rect.origin; corn = &b->rect.corner; if (centery >= orig->y && centery <= corn->y) { lx = (centerx - radius); rx = (centerx + radius); if (lx >= orig->x && lx <= corn->x) dline(lx, centery, lx, centery, colour); if (rx <= corn->x && rx >= orig->x) dline(rx, centery, rx, centery, colour); } if (centerx >= orig->x && centerx <= corn->x) { ty = (centery - radius); by = (centery + radius); if (ty >= orig->y && ty <= corn->y) dline(centerx, ty, centerx, ty, colour); if (by <= corn->y && by >= orig->y) dline(centerx, by, centerx, by, colour); } for (y_offset = 1; y_offset <= rootrad; y_offset++) { x_offset = sqrt(rad_sqr - (y_offset * y_offset)); lx = (centerx - x_offset); rx = (centerx + x_offset); if ((ty = centery - y_offset) >= orig->y && ty <= corn->y) { if (lx >= orig->x && lx <= corn->x) dline(lx, ty, lx, ty, colour); if (rx <= corn->x && rx >= orig->x) dline(rx, ty, rx, ty, colour); } if ((by = centery + y_offset) <= corn->y && by >= orig->y) { if (lx >= orig->x && lx <= corn->x) dline(lx, by, lx, by, colour); if (rx <= corn->x && rx >= orig->x) dline(rx, by, rx, by, colour); } if (y_offset != x_offset) { lx = (centerx - y_offset); rx = (centerx + y_offset); if ((ty = centery - x_offset) >= orig->y && ty <= corn->y) { if (lx >= orig->x && lx <= corn->x) dline(lx, ty, lx, ty, colour); if (rx <= corn->x && rx >= orig->x) dline(rx, ty, rx, ty, colour); } if ((by = centery + x_offset) <= corn->y && by >= orig->y) { if (lx >= orig->x && lx <= corn->x) dline(lx, by, lx, by, colour); if (rx <= corn->x && rx >= orig->x) dline(rx, by, rx, by, colour); } } } Setscreen(display,-1L,-1); #else #define SIDES 36 #define pi 3.1415926 #define two_pi 6.2831852 static Point pts[SIDES]; float ang, inc, correction; float cos(), sin(); register point; register int centerx = cx + b->rect.origin.x, centery = cy + b->rect.origin.y; correction = pi/2; inc = two_pi/SIDES; ang = correction; for (point=0; pointblk_address,-1L,-1); jpolygon(pts, SIDES, colour); Setscreen(display,-1L,-1); #endif } jcircle(centerx, centery, radius, colour) { #define SIDES 36 #define pi 3.1415926 #define two_pi 6.2831852 static Point pts[SIDES]; float ang, inc, correction; float cos(), sin(); register point; correction = pi/(float)2; inc = two_pi/(float)SIDES; ang = correction; for (point=0; pointrect.origin.x, centery = cy + b->rect.origin.y; Point *orig,*corn; register int lx, rx, ty, by; rad_sqr = (float)radius * (float)radius; orig = &b->rect.origin; corn = &b->rect.corner; Setscreen(b->blk_address,-1L,-1); if (centery >= orig->y && centery <= corn->y) { if ((lx = (centerx - radius)) < orig->x) lx = orig->x; if (lx <= corn->x) { if ((rx = (centerx + radius)) > corn->x) rx = corn->x; if (rx >= orig->x) dline(lx, centery, rx, centery, colour); } } for (y_offset = 1; y_offset <= radius; y_offset++) { x_offset = sqrt(rad_sqr - (y_offset * y_offset)); if ((lx = (centerx - x_offset)) < orig->x) lx = orig->x; if (lx > corn->x) continue; if ((rx = (centerx + x_offset)) > corn->x) rx = corn->x; if (rx < orig->x) continue; if ((ty = centery - y_offset) >= orig->y && ty <= corn->y) dline(lx, ty, rx, ty, colour); if ((by = centery + y_offset) <= corn->y && by >= orig->y) dline(lx, by, rx, by, colour); } Setscreen(display,-1L,-1); } jdisc(centerx, centery, radius, colour) { int x_offset, y_offset; float sqrt(), rad_sqr; rad_sqr = (float)radius * (float)radius; dline(centerx - radius, centery, centerx + radius, centery, colour); for (y_offset = 1; y_offset < radius; y_offset++) { x_offset = sqrt(rad_sqr - (y_offset * y_offset)); dline(centerx - x_offset,centery + y_offset, centerx + x_offset,centery + y_offset,colour); dline(centerx - x_offset,centery - y_offset, centerx + x_offset,centery - y_offset,colour); } }