|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 16793 (0x4199) Types: TextFile Notes: UNIX file Names: »layer.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─ ⟦this⟧ »hr/src/smgr/layer.c«
#include <stdio.h> #include "smgr.h" extern int memfail(); extern char *malloc(); extern BITMAP display; extern UPDATE update[]; extern RECT R_addp(), R_subp(); extern int *screen_addr(); extern int ALL_ON[]; #define FILL_CLR (0) #define FILL_BCK (1) #define FILL_HLF (2) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* */ /* lblt - layer blt call */ /* */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ lblt(blt, clip, mouse) BLTSTRUCT *blt; int clip, /* 1 == clipping, 0 == not */ mouse; /* 1 == think about it , 0 == concern not thyself */ { BLTSTRUCT b; register int i; register LAYER *lp; #ifdef DEBUG peteprint("LBLT: entry : blt structure : \n"); peteprint("\tsrc bitmap = 0x%lx, (%d, %d) (%d, %d), %d\n", blt->src->base, blt->src->rect.origin.x, blt->src->rect.origin.y, blt->src->rect.corner.x, blt->src->rect.corner.y, blt->src->width); peteprint("\tdst bitmap = 0x%lx, (%d, %d) (%d, %d), %d\n", blt->dst->base, blt->dst->rect.origin.x, blt->dst->rect.origin.y, blt->dst->rect.corner.x, blt->dst->rect.corner.y, blt->dst->width); peteprint("\tdr = (%d, %d) (%d, %d), sp = (%d, %d)\n", blt->dr.origin.x, blt->dr.origin.y, blt->dr.corner.x, blt->dr.corner.y, blt->sp.x, blt->sp.y); #endif b = *blt; lp = (LAYER *)blt->dst; for ( i = 0; i < MAX_LRBUF; i++ ) if ( lp->reg[i].flag == L_VISIBLE ) { b.dst = &(lp->reg[i].bm); bitblt(&b, clip, mouse); } else if ( lp->reg[i].flag == L_EMPTY ) return; } lbitblt(blt, clip, mouse) register BLTSTRUCT *blt; int clip, mouse; { lblt(blt, clip, mouse); } /* \f */ LAYER * newlayer(r) register RECT r; { register LAYER *newlp; #ifdef TRACE peteprint("newlayer\n"); #endif newlp = (LAYER *)malloc(sizeof(LAYER)) ; if (newlp == (LAYER *)NULL ) { peteprint("NEWLAYER STRUCTURE ALLOCATE FAILURE\n"); memfail(); } newlp->rect = r; /* link newlp into the layer list */ if ( DM_frontmost != (LAYER *)NULL ) DM_frontmost->front = newlp; newlp->back = DM_frontmost; newlp->front = (LAYER *)NULL; DM_frontmost = newlp; if ( DM_rearmost == (LAYER *)NULL ) DM_rearmost = newlp; make_vis_list(); rectf(r, FILL_CLR); return newlp; } /* \f */ int dellayer(lp) register LAYER *lp; { register int i; int j,k; register LAYER *rlp; SM_REGION reg; #ifdef TRACE peteprint("dellayer 0x%lx\n", lp); #endif /* make background those parts of the layer visible */ for ( i = 0; i < MAX_LRBUF; i++ ) if ( lp->reg[i].flag == L_VISIBLE ) background(lp->reg[i].bm.rect); /* unhook lp from the list of layers */ if ( lp == DM_frontmost ) DM_frontmost = lp->back; else lp->front->back = lp->back; if ( lp == DM_rearmost ) DM_rearmost = lp->front; else lp->back->front = lp->front; /* make the update list */ for ( i = 0; i < MAX_UPBUF; i ++ ) { update[i].wmgr = -1; update[i].wid = -1; } j = 0; for ( rlp = DM_rearmost; rlp; rlp = rlp->front ) for ( i = 0; i < MAX_LRBUF; i++ ) { reg = rlp->reg[i]; if ( (reg.cov_by == lp) && (reg.flag == L_OBSCURED) ) { update[j].r = reg.bm.rect; k = update[j].wid = lp2id(rlp); update[j].wmgr = wtbl[k]->wn_Wmgr; j++; } } make_vis_list(); /* the actual perform_update in back in Delete..so the old layer */ /* does not get outlined */ #ifdef DEBUG peteprint("dellayer: upfront and background complete\n"); peteprint("\tfr = 0x%lx, re = 0x%lx, lp = 0x%lx\n",DM_frontmost,DM_rearmost,lp); #endif } /* \f */ upfront(lp) register LAYER *lp; { register int i,j; #ifdef TRACE peteprint("upfront 0x%lx, fr = 0x%lx, re = 0x%lx\n", lp,DM_frontmost,DM_rearmost); #endif if ( lp == DM_frontmost ) return; lp->front->back = lp->back; if ( lp->back != (LAYER *)NULL ) lp->back->front = lp->front; else DM_rearmost = DM_rearmost->front; lp->front = NULL; if ( DM_frontmost ) DM_frontmost->front = lp; lp->back = DM_frontmost; DM_frontmost = lp; for ( i = 0; i < MAX_UPBUF; i++ ) { update[i].wmgr = -1; update[i].wid = -1; } j = 0; for ( i = 0 ; i < MAX_LRBUF; i++ ) if ( lp->reg[i].flag == L_OBSCURED ) { update[j].wmgr = wtbl[lp2id(lp)]->wn_Wmgr; update[j].r = lp->reg[i].bm.rect; update[j].wid = lp2id(lp); j++; } make_vis_list(); perform_update(); #ifdef DEBUG peteprint("upfront return: fr = 0x%lx, rear = 0x%lx\n", DM_frontmost, DM_rearmost); #endif } pushback(lp) register LAYER *lp; { register int i,j; register LAYER *tlp; #ifdef TRACE peteprint("pushback : entry\n"); #endif if ( DM_rearmost == lp ) return; if ( DM_frontmost == lp ) { DM_frontmost = lp->back; DM_frontmost->front = (LAYER *)NULL; } else lp->front->back = lp->back; lp->back->front = lp->front; for ( i = 0; i < MAX_UPBUF; i++ ) update[i].wmgr = update[i].wid = -1; j = 0; for ( tlp = DM_rearmost; tlp ; tlp = tlp->front ) for ( i = 0; i < MAX_LRBUF; i++ ) if ((tlp->reg[i].cov_by == lp)&&(tlp->reg[i].flag == L_OBSCURED) ) { update[j].wmgr = wtbl[lp2id(tlp)]->wn_Wmgr; update[j].r = tlp->reg[i].bm.rect; update[j].wid = lp2id(tlp); j++; } DM_rearmost->back = lp; lp->front = DM_rearmost; lp->back = (LAYER *)NULL; DM_rearmost = lp; make_vis_list(); perform_update(); #ifdef DEBUG peteprint("\tpushback returns\n"); #endif } /* \f */ static rectf(r, op) register RECT r; register int op; { BITMAP s; register BLTSTRUCT blt; #ifdef TRACE peteprint("Rectf: entry\n"); #endif if ( op == FILL_CLR ) blt.pat = texture[0]; else if ( op == FILL_BCK ) blt.pat = texture[10]; else if ( op == FILL_HLF ) blt.pat = texture[3]; s.rect = r; s.width = 16 * words_between(r.origin.x, r.corner.x); s.base = screen_addr(r.origin.x, r.origin.y); blt.src = &s; blt.sp = s.rect.origin; blt.dst = &display; blt.dr = s.rect; blt.op = L_TRUE; bitblt(&blt); } background(r) register RECT r; { rectf(r, FILL_BCK); } int *screen_addr(x,y) register int x,y; { register long addr; addr = ((long)y) << 7; /* (long)y*128 */ addr += ( x >> 4 ) << 1; /* addr += (x / 16) * 2 */ if (addr & 0xffff0000L ) { addr &= 0x0000ffffL; addr |= (long)SEG1; } else addr |= (long)SEG0; return ((int *)addr); } memfail() { for(;;); } words_between(left,right) register int left,right; { if (right <= left) return 0; left &= 0xfff0; if ((right & 0x000f) != 0) right = (right & 0xfff0) + 0x0010; return ((right - left) >> 4); } int *bmialloc(r) register RECT r; { return((int*)malloc(words_between(r.origin.x,r.corner.x) *(r.corner.y-r.origin.y) << 1)); } perform_update() { register int i,j, k; /* now for every window to be updated, if the cursor is */ /* on, turn the cursor off and set the flag WT_CURSOR_WON */ /* in the flag field */ /* save off current window id so we can restore it to gk */ j = gkWid; for ( i = 0; i < MAX_UPBUF && update[i].wmgr != -1 ; i++ ) if ( wtbl[update[i].wid]->wn_Flags & WT_CURSOR_ON ) { gk = *wtbl[update[i].wid]; msgData1 = 0; SM_DrawCurs(); gkFlags |= WT_CURSOR_WON; *wtbl[update[i].wid] = gk; } if ( legalwindow(j) && wtbl[j] != (WSTRUCT *)NULL) gk = *wtbl[j]; /* first clear out all the regions to be updated */ for ( i = 0; i < MAX_UPBUF && update[i].wmgr != -1 ; i++ ) rectf(update[i].r, FILL_CLR); /* and then generate the update events to the managers */ for ( i = 0; i < MAX_WINDOWS; i++ ) for ( j = 0; j < MAX_UPBUF; j++ ) if ( update[j].wid == i ) { msgSender = wtbl[i]->wn_Wmgr; msgWid = i; if (not ( wtbl[i]->wn_Type & WT_SMARTUPDATE )) { msgCmd = WM_UPDATE; /* * eliminate all other update events * for this window */ for ( k = j+1; k < MAX_UPBUF; k++ ) if ( update[k].wid == i ) update[k].wid = -1; outline(i); if ( wtbl[i]->wn_Wmgr == 3 ) /* text window */ redraw_map(i); else sendmsg(&msg); } else { msgCmd = WM_RGNUPDATE; update[i].r=R_subp(update[i].r,wtbl[i]->wn_Layer->rect.origin); update[i].r=R_addp(update[i].r,wtbl[i]->wn_Lorigin); msgPtr = &update[i].r; sendmsg( &msg ); } } j = gkWid; for ( i = 0; i < MAX_WINDOWS; i++ ) if ( wtbl[i] && wtbl[i]->wn_Flags & WT_CURSOR_WON ) { gk = *wtbl[i]; msgData1 = 1; SM_DrawCurs(); gkFlags &= ~WT_CURSOR_WON; *wtbl[i] = gk; } if ( legalwindow(j) && wtbl[j] != ( WSTRUCT *)NULL ) gk = *wtbl[j]; } make_vis_list() { register LAYER *back, *front; register int i; GETPTR f; #ifdef TRACE peteprint("Make_Vis_List\n"); #endif /* mark all buffers in all layers as not used */ for ( back = DM_rearmost; back; back = back->front ) for ( i = 0; i < MAX_LRBUF; i++ ) back->reg[i].flag = L_EMPTY; for ( back = DM_rearmost; back; back = back->front ) { back->reg[0].bm.rect = back->rect; back->reg[0].bm.width = 1024; back->reg[0].bm.base = screen_addr(back->rect.origin.x, back->rect.origin.y); back->reg[0].flag = L_VISIBLE; for ( front = back->front; front; front = front->front ) if ( R_intersect(front->rect, back->rect) ) for ( i = 0; i < MAX_LRBUF; i++ ) if ( back->reg[i].flag ) while ( R_intersect(front->rect, back->reg[i].bm.rect)) if ( split(back, i, front) == 0 ) break; } for ( i = 0; i < MAX_WINDOWS; i++ ) if ( wtbl[i] != (WSTRUCT *)NULL) { wtbl[i]->wn_Flags &= ~WT_FULLY_VIS; if ( R_equal(wtbl[i]->wn_Layer->rect, wtbl[i]->wn_Layer->reg[0].bm.rect) ) if ( wtbl[i]->wn_Layer->reg[0].flag == L_VISIBLE ) wtbl[i]->wn_Flags |= WT_FULLY_VIS; if ( i == gkWid ) gk = *(wtbl[i]); } } split(lp, i, front) register LAYER *lp;/* the layer containing the vis region to be broken up */ int i; /* the index number of the layers vis region to break */ LAYER *front; { int j; /* the available region index for this layer */ RECT frect; RECT old, new; register LAYER *tlp; #ifdef TRACE peteprint("split : entry\n"); #endif frect = front->rect; old = lp->reg[i].bm.rect; #ifdef DEBUG peteprint("lp = %d, i=%d, old, frect : \n", lp2id(lp), i); DB_prect(old); DB_prect(frect); #endif if ( R_subset( old, frect ) ) { /* since it is a subset of some other a higher window */ /* it must be obscured... scan up the layer list and */ /* find out who is the topmost obscuring */ lp->reg[i].flag = L_OBSCURED; for ( tlp = lp->front; tlp; tlp = tlp->front ) if ( R_intersect(old, tlp->rect) ) lp->reg[i].cov_by = tlp; return(0); } for (j = 0; j < MAX_LRBUF - 1; j++ ) if ( lp->reg[j].flag == L_EMPTY ) break; if ( j == (MAX_LRBUF - 1) ) { peteprint("EXCEEDED RBUF FOR LAYER %d\n", lp2id(lp)); return (0); } new = old; if ( old.origin.x < frect.origin.x ) new.origin.x = old.corner.x = frect.origin.x; else if ( old.origin.y < frect.origin.y ) new.origin.y = old.corner.y = frect.origin.y; else if ( old.corner.x > frect.corner.x ) new.corner.x = old.origin.x = frect.corner.x; else if ( old.corner.y > frect.corner.y ) new.corner.y = old.origin.y = frect.corner.y; else peteprint("WHAT THE HELL ARE YOU DOING HERE????????\n"); lp->reg[i].bm.rect = old; lp->reg[i].bm.base = screen_addr(old.origin.x, old.origin.y); lp->reg[i].bm.width = 1024; /* assume visibility */ lp->reg[i].flag = L_VISIBLE; /* and now scan for the highest layer which obscures it */ for ( tlp = lp->front; tlp; tlp = tlp->front ) if ( R_intersect(old, tlp->rect) ) { lp->reg[i].flag = L_OBSCURED; lp->reg[i].cov_by = tlp; } lp->reg[j].bm.rect = new; lp->reg[j].bm.base = screen_addr(new.origin.x, new.origin.y); lp->reg[j].bm.width = 1024; /* first assume visibility */ lp->reg[j].flag = L_VISIBLE; /* now scan for the highest layer which covers it */ for ( tlp = lp->front; tlp; tlp = tlp->front ) if ( R_intersect(new, tlp->rect) ) { lp->reg[j].flag = L_OBSCURED; lp->reg[j].cov_by = tlp; } #ifdef DEBUG DB_prect(lp->reg[i].bm.rect); DB_prect(lp->reg[j].bm.rect); #endif return (1); } int who_top_at(p) register POINT p; { register LAYER *lp; for ( lp = DM_frontmost; lp; lp = lp->back ) if ( R_point_in(lp->rect, p)) return(lp2id(lp)); return(NO_WINDOW); } int new_dimensions(r) RECT r; { register LAYER *lp; RECT clip_rect_off; POINT dp_off; register int i,j; int k; SM_REGION reg; WSTRUCT *wp; if ( r.corner.x > XMAX ) return; if ( r.corner.y > YMAX ) return; /* would this new location obscure any non-obscurable window ? */ /* COMMENTED OUT BECAUSE NO WINDOW SHOULD CURRENTLY BE UN_OBSCURABLE */ /* AND SM_SETSIZE DEPENDS ON THIS NOT FAILING */ /* for ( i = 0; i < MAX_WINDOWS; i++ ) if ( i != msgWid ) if ( wp = wtbl[i] ) if ( wp->wn_Type & WT_NOOBS ) if ( R_intersect( r, wp->wn_Layer->rect ) ) return; */ /* make update list */ /* clear update table */ for ( i = 0; i < MAX_UPBUF; i++ ) { update[i].wmgr = -1; update[i].wid = -1; } /* initialize update table index */ j = 0; for ( lp = DM_rearmost; lp; lp = lp->front ) for ( i = 0; i < MAX_LRBUF; i++ ) { reg = lp->reg[i]; if ((reg.cov_by==gkLayer)&&(reg.flag==L_OBSCURED)) { update[j].r = reg.bm.rect; k = update[j].wid = lp2id(lp); update[j].wmgr = wtbl[k]->wn_Wmgr; j++; } } /* save off the offset from the layer origin to the clipping rect */ clip_rect_off.origin.x = gkCrect.origin.x - gkLayer->rect.origin.x; clip_rect_off.origin.y = gkCrect.origin.y - gkLayer->rect.origin.y; clip_rect_off.corner.x = gkCrect.corner.x - gkLayer->rect.corner.x; clip_rect_off.corner.y = gkCrect.corner.y - gkLayer->rect.corner.y; /* same for drawing point */ dp_off.x = gkDp.x - gkLayer->rect.origin.x; dp_off.y = gkDp.y - gkLayer->rect.origin.y; for ( i = 0; i < MAX_LRBUF; i++ ) if ( gkLayer->reg[i].flag == L_VISIBLE ) background(gkLayer->reg[i].bm.rect); gkLayer->rect = r; gkLayer->base = screen_addr(r.origin.x, r.origin.y); /* restore new clipping rectangle and drawing point */ gkCrect.origin.x = gkLayer->rect.origin.x + clip_rect_off.origin.x; gkCrect.origin.y = gkLayer->rect.origin.y + clip_rect_off.origin.y; gkCrect.corner.x = gkLayer->rect.corner.x + clip_rect_off.corner.x; gkCrect.corner.y = gkLayer->rect.corner.y + clip_rect_off.corner.y; gkDp.x = gkLayer->rect.origin.x + dp_off.x; gkDp.y = gkLayer->rect.origin.y + dp_off.y; gkPsize.x = gkLayer->rect.corner.x - gkLayer->rect.origin.x; gkPsize.y = gkLayer->rect.corner.y - gkLayer->rect.origin.y; /* PTB NEW */ *wtbl[gkWid] = gk; make_vis_list(); /* add to the update list all areas of the translated layer */ /* which are now visible */ for ( i = 0; (i < MAX_LRBUF) && (gkLayer->reg[i].flag != L_EMPTY); i++ ) { reg = gkLayer->reg[i]; if ( reg.flag == L_VISIBLE ) { update[j].r = reg.bm.rect; update[j].wid = gkWid; update[j].wmgr = gkWmgr; j++; } } perform_update(); #ifdef DEBUG peteprint("new_dimension: made it back from perform_update\n"); #endif } int lp2id(lp) register LAYER *lp; { register int i; for (i=0; i<MAX_WINDOWS; i++) if ( wtbl[i] ) if ( wtbl[i]->wn_Layer == lp ) return(i); return -1; } outline(i) register int i; { register BLTSTRUCT blt; RECT r; r = wtbl[i]->wn_Layer->rect; blt.src = blt.dst = wtbl[i]->wn_Layer; blt.pat = texture[0]; blt.op = L_FALSE; /* top line */ blt.dr = r; blt.dr.corner.y = blt.dr.origin.y + 1; blt.dr.corner.x -= 5; blt.sp = blt.dr.origin; lblt(&blt, 1, 1); /* left wall */ blt.dr = r; blt.dr.corner.x = blt.dr.origin.x + 1; blt.dr.corner.y -=5; blt.sp = blt.dr.origin; lblt(&blt, 1, 1); /* right wall */ blt.dr = r; blt.dr.origin.x = blt.dr.corner.x - 5; blt.dr.corner.x -= 4; blt.dr.corner.y -= 4; blt.sp = blt.dr.origin; lblt(&blt, 1, 1); for ( i = 0; i < 4; i++) { blt.dr.origin.x++; blt.dr.corner.x++; blt.dr.origin.y++; blt.dr.corner.y++; blt.sp = blt.dr.origin; lblt(&blt, 1, 1); } /* bottom wall */ blt.dr = r; blt.dr.origin.y = blt.dr.corner.y - 5; blt.dr.corner.y -=4; blt.dr.corner.x -=4; blt.sp = blt.dr.origin; lblt(&blt, 1, 1); for ( i = 0 ; i < 4; i++ ) { blt.dr.origin.x++; blt.dr.corner.x++; blt.dr.origin.y++; blt.dr.corner.y++; blt.sp = blt.dr.origin; lblt(&blt, 1, 1); } /* done */ }