|
|
1.1 ! root 1: #include <jerq.h> ! 2: #include "layer.h" ! 3: ! 4: /* ! 5: * Magic ! 6: * ! 7: * Intersect a rectangle to a layer, doing all subdivision into rectangles. ! 8: * layerop() clips rectangle to outer edge of layer, then calls mRlayerop ! 9: * which recursively chains along the layer list, doing op's (specified ! 10: * by a pointer to a function) whenever there is an intersection. Differs ! 11: * from rob's by taking a direction of evaluation, so that the subrectangles ! 12: * produced are properly sorted for bitblt from a layer to itself. ! 13: * ! 14: */ ! 15: ! 16: /* For the portion outside the current layer, we use recursion */ ! 17: #define out(or,co) mRlayerop(l, fn, Rpt(or,co), fp, o->back) ! 18: ! 19: /* For the portion inside, we perform the function */ ! 20: #define in(r) (*fn)(l, r, (l?l->obs:0), fp, o) ! 21: ! 22: #define C_DONE 0 ! 23: #define C_UP 1 ! 24: #define C_LEFT 2 ! 25: #define C_MID 3 ! 26: #define C_RIGHT 4 ! 27: #define C_DOWN 5 ! 28: ! 29: int blitdir = 0; /* direction from source to destination */ ! 30: ! 31: /* ! 32: * directions: 0 = up and left, ! 33: * 1 = up and right, ! 34: * 2 = down and left, ! 35: * 3 = down and right ! 36: */ ! 37: ! 38: static short nextcase[4][6] = { ! 39: C_UP, C_LEFT, C_MID, C_RIGHT, C_DOWN, C_DONE, ! 40: C_UP, C_RIGHT, C_MID, C_LEFT, C_DOWN, C_DONE, ! 41: C_DOWN, C_LEFT, C_MID, C_RIGHT, C_UP, C_DONE, ! 42: C_DOWN, C_RIGHT, C_MID, C_LEFT, C_UP, C_DONE, ! 43: }; ! 44: ! 45: mRlayerop(l, fn, r, fp, o) ! 46: register Layer *l; ! 47: void (*fn)(); ! 48: Rectangle r; /* Screen coords */ ! 49: int *fp; ! 50: register Layer *o; ! 51: { ! 52: Rectangle clipr; ! 53: register Rectangle *rp= &r, *cp= &clipr, *bp; ! 54: register short *next; ! 55: ! 56: *cp = *rp; ! 57: Top: ! 58: bp= &o->rect; ! 59: if((o==l) || (o==0)) /* We have a piece that wasn't obscured */ ! 60: (*fn)(l, r, l, fp, o); ! 61: else if (rectclip(cp, *bp)==0) { /* note side-effect to clipr */ ! 62: o=o->back; /* efficiency hack */ ! 63: goto Top; ! 64: } else { ! 65: /* They must overlap */ ! 66: for (next=&nextcase[blitdir][0]; *next != C_DONE; ) ! 67: switch(*next++) { ! 68: case C_UP: ! 69: if (rp->origin.y<bp->origin.y) ! 70: out(rp->origin, ! 71: Pt(rp->corner.x, bp->origin.y)); ! 72: break; ! 73: case C_DOWN: ! 74: if (rp->corner.y>bp->corner.y) ! 75: out(Pt(rp->origin.x, bp->corner.y), ! 76: rp->corner); ! 77: break; ! 78: case C_LEFT: ! 79: if (rp->origin.x<bp->origin.x) ! 80: out(Pt(rp->origin.x, cp->origin.y), ! 81: Pt(bp->origin.x, cp->corner.y)); ! 82: break; ! 83: case C_RIGHT: ! 84: if (rp->corner.x>bp->corner.x) ! 85: out(Pt(bp->corner.x, cp->origin.y), ! 86: Pt(rp->corner.x, cp->corner.y)); ! 87: break; ! 88: case C_MID: ! 89: in(*cp); ! 90: break; ! 91: } ! 92: } ! 93: } ! 94: ! 95: /* ! 96: * Clip to outer rectangle of layer, then call layerop ! 97: */ ! 98: /*VARARGS3*/ ! 99: layerop(l, fn, r, f) ! 100: register Layer *l; ! 101: void (*fn)(); ! 102: Rectangle r; /* Screen coords */ ! 103: int f; ! 104: { ! 105: if(l && (rectclip(&r, l->rect)==0)) ! 106: return; ! 107: if (l && (l->someobs == l->nonevis)) ! 108: (*fn)(l, r, l->nonevis?l->obs:(Bitmap *)l, &f, ! 109: (l->nonevis?lfront:l)); ! 110: else ! 111: mRlayerop(l, fn, r, &f, lfront); ! 112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.