#include #include #include "system.h" #ifndef Plan9 #include "stdio.h" #include "njerq.h" #include "object.h" char *beg_mem; Bitmap * balloc(Rectangle r, int i) { register Bitmap *b; int j = i+1; b = (Bitmap *) vm_alloc(sizeof(Bitmap)); if(b == (Bitmap *)NULL){ fprintf(stderr,"failed to allocate bitmap\n"); pserror("big problems", "balloc"); } b->r = r; b->width = ((r.max.x + 31) >> 5) - (r.min.x >> 5); b->base = (Word *) vm_alloc(j*b->width*(r.max.y-r.min.y)*4); if(b->base == (Word *)NULL){ fprintf(stderr,"failed to allocate bitmap base %d\n", b->width*(r.max.y-r.min.y)*4); pserror("big problems", "balloc"); } rectf(b, b->r, Zero); return(b); } static int fcount; static int nomore=0; Bitmap * cachealloc(Rectangle r) { register Bitmap *b; fcount++; if(nomore) return(0); b = (Bitmap *) malloc(sizeof(Bitmap)); if((char *)b >=beg_mem){ fprintf(stderr,"ran out of cache memory %d fonts\n",fcount); nomore = 1; return(0); } b->r = r; b->width = ((r.max.x + 31) >> 5) - (r.min.x >> 5); b->base = (Word *) malloc(b->width*(r.max.y-r.min.y)*4); if((char *)b->base >= beg_mem){ fprintf(stderr,"ran out of cache memory %d\n",b->width*(r.max.y-r.min.y)*4); nomore = 1; return(0); } rectf(b, b->r, Zero); return(b); } #define addr(b,p) b->base + (b->width*(p.y-b->r.min.y) + (((p.x>>5)<<5)/32) - (b->r.min.x>>5)) #ifdef AHMDAL #define DOIT(src,roff,xmask,shift) ((*src<>shift)&xmask)) #endif #ifdef SUN #define DOIT(src,roff,xmask,shift) ((*src<>shift)&xmask)) #endif #ifdef I386 /* deal with inability to shift by 32 */ #define DOIT(src,roff,xmask,shift) (shift==32?((*src>>roff)&xmask):(roff==32?(*(src+1)<>roff)&xmask)|(*(src+1)<>roff)&xmask)|(*(src+1)<r.min.x) < 0) { p.x -= i; r.min.x -= i; } if ((i = p.y - b->r.min.y) < 0) { p.y -= i; r.min.y -= i; } if ((i = b->r.max.x - dp.x) < 0) r.max.x += i; if ((i = b->r.max.y - dp.y) < 0) r.max.y += i; /* recompute loop numbers */ w = r.max.x - r.min.x; h = r.max.y - r.min.y; nw = ((p.x+w-1)>>5) - (p.x>>5) - 1; lmask = Lmask[p.x & 0x1f]; rmask = Rmask[(p.x+w) & 0x1f]; sw = sm->width; dw = dm->width; if (sm == dm) { /* may have to change loop order */ if (r.min.y < p.y) { r.min.y += h-1; p.y += h-1; sw = -sw; dw = -dw; } if (r.min.x < p.x) { left = 1; r.min.x += w-1; p.x += w-1; } } roff = (r.min.x&0x1f) - (p.x&0x1f); if (roff < 0) { roff += 32; r.min.x -= 32; } shift = 32-roff; #ifndef VAX xmask = Lmask[shift]; #else xmask = mask[roff]; #endif if (sm != dm && f == (S|D)) { if (nw < 0) { lmask &= rmask; source = addr(sm,r.min); dest = addr(dm,p); for (i = 0; i < h; i++) { m = DOIT(source,roff,xmask,shift); *dest |= lmask&m; dest += dw; source += sw; } } else { lsource = addr(sm,r.min); ldest = addr(dm,p); for (i = 0; i < h; i++, lsource += sw, ldest += dw) { source = lsource; dest = ldest; m = DOIT(source,roff,xmask,shift); source++; *dest |= lmask&m; dest++; for (j = 0; j < nw; j++) { m = DOIT(source,roff,xmask,shift); source++; *dest++ |= m; } m = DOIT(source,roff,xmask,shift); *dest |= rmask&m; } } return; } if (nw < 0) { lmask &= rmask; rmask = ~lmask; source = addr(sm,r.min); dest = addr(dm,p); for (i = 0; i < h; i++) { m = DOIT(source,roff,xmask,shift); switch(f) { case (S|D): *dest |= lmask&m; break; case DandnotS: *dest &= ~(lmask&m); break; case S: *dest = lmask&m | rmask&*dest; } dest += dw; source += sw; } } else if (left == 0) { lsource = addr(sm,r.min); ldest = addr(dm,p); for (i = 0; i < h; i++, lsource += sw, ldest += dw) { source = lsource; dest = ldest; m = DOIT(source,roff,xmask,shift); source++; switch(f) { case (S|D): *dest |= lmask&m; break; case DandnotS: *dest &= ~(lmask&m); break; case S: *dest = lmask&m | (~lmask)&*dest; } dest++; for (j = 0; j < nw; j++) { m = DOIT(source,roff,xmask,shift); source++; switch(f) { case (S|D): *dest++ |= m; break; case DandnotS: *dest++ &= ~m; break; case S: *dest++ = m; } } m = DOIT(source,roff,xmask,shift); switch(f) { case (S|D): *dest |= rmask&m; break; case DandnotS: *dest &= ~(rmask&m); break; case S: *dest = rmask&m | (~rmask)&*dest; } } } else { lsource = addr(sm,r.min); ldest = addr(dm,p); for (i = 0; i < h; i++, lsource += sw, ldest += dw) { source = lsource; dest = ldest; m = DOIT(source,roff,xmask,shift); source--; switch(f) { case (S|D): *dest |= rmask&m; break; case DandnotS: *dest &= ~(rmask&m); break; case S: *dest = rmask&m | (~rmask)&*dest; } for (j = 0; j < nw; j++) { m = DOIT(source,roff,xmask,shift); source--; switch(f) { case (S|D): *--dest |= m; break; case DandnotS: *--dest &= ~m; break; case S: *--dest = m; } } m = DOIT(source,roff,xmask,shift); dest--; switch(f) { case (S|D): *dest |= lmask&m; break; case DandnotS: *dest &= ~(lmask&m); break; case S: *dest = lmask&m | (~lmask)&*dest; } } } } Texture zeros; Texture ones = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, }; Texture grey[] = { 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xFFFFFFFF , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x55555555 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0xAAAAAAAA , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 , }; void /*general modified to only do STORE or CLEAR*/ texture(Bitmap *b, Rectangle r, Texture t, Fcode f) { register i,j; register long lmask,rmask; register long *dest,*tp; int w,h; long *ldest; lmask = Lmask[r.min.x & 0x1f]; rmask = Rmask[r.max.x & 0x1f]; i = r.max.x-r.min.x; w = ((r.max.x-1)>>5) - (r.min.x>>5) - 1; h = r.max.y - r.min.y; if(i <= 0 || h <= 0 ){ if(mdebug)fprintf(stderr,"bad texture (%d %d) (%d %d)\n", r.min.x,r.min.y,r.max.x,r.max.y); return; } if(f == (S|D))f = S; tp = &t[r.min.y & 0x1f]; if (w < 0) { lmask &= rmask; rmask = ~lmask; dest = addr(b,r.min); for (i = 0; i < h; i++) { if(f == S)*dest = lmask&*tp++ | rmask&*dest; else *dest &= ~(lmask&*tp++); dest += b->width; if (tp == &t[32]) tp = t; } } else { ldest = addr(b,r.min); for (i = 0; i < h; i++, ldest += b->width) { dest = ldest; if(f == S)*dest = lmask&*tp | (~lmask)&*dest; else *dest &= ~(lmask&*tp); dest++; for (j = 0; j < w; j++) if(f == S)*dest++ = *tp; else *dest++ &= ~*tp; if(f == S)*dest = rmask&*tp | (~rmask)&*dest; else *dest &= ~(rmask&*tp); if (++tp == &t[32]) tp = t; } } } Rectangle Rect(int x, int y, int u, int v) { Rectangle r; r.min.x = x; r.min.y = y; r.max.x = u; r.max.y = v; return(r); } Point Pt(int x, int y) { Point p; p.x = x; p.y = y; return(p); } #ifdef VAX long bit[] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, }; #endif #ifdef AHMDAL long bit[] = { 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; #endif #ifdef SUN long bit[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, }; #endif long * faddr(register Bitmap *b, Point p) { return(b->base + (b->width*(p.y-b->r.min.y) + (((p.x>>5)<<5)/32) - (b->r.min.x>>5))); } void point(Bitmap *b, Point p, int i, Fcode f) { switch (f) { case S: case D: *faddr(b,p) |= bit[p.x&31]; break; case Zero: /*XOR*/ *faddr(b,p) ^= bit[p.x&31]; break; case DandnotS: *faddr(b,p) &= ~bit[p.x&31]; break; } } #endif