|
|
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 - metrics - 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 */
}