|
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: 10471 (0x28e7) Types: TextFile Notes: UNIX file Names: »gtext2.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─⟦this⟧ »hr/src/smgr/gtext2.c«
#include "graph.h" #define SCROLL_BUF MAX_LRBUF SM_REGION s[SCROLL_BUF]; SM_REGION cheater[MAX_LRBUF]; RECT cl_area_rect; extern POINT gkToLogical(), gkToGlobal(); extern RECT R_inset(); extern RECT R_Intersection(); /****************************************************************************** Define the text cursor: SM_DefChar() Draw the text cursor: SM_DrawCurs() Text scroll the clipping region:SM_Scroll() *****************************************************************************/ void SM_DefCurs() { register int i; if ( (i = msgBytL0 + msgBytL1) < 0 ) return; if ( (unsigned) msgData2 > DIS_WIDTH ) return; gkCursor.x = msgData2; gkCursor.y = i; gkCascnt = msgBytL0; } void SM_DrawCurs() { register BLTSTRUCT blt; POINT pt; if ( msgData1 ) /* request to turn cursor on */ if ( gkFlags & WT_CURSOR_ON ) { #ifdef DEBUG peteprint("double on\n"); #endif return; } else gkFlags |= WT_CURSOR_ON; else if ( gkFlags & WT_CURSOR_ON ) gkFlags &= ~WT_CURSOR_ON; else { #ifdef DEBUG peteprint("double off\n"); #endif return; } blt.src = &gkBitMap; blt.dst = &gkBitMap; if ( msgData1 ) /* on */ { blt.dr.origin.x = gkDp.x; blt.dr.origin.y = gkDp.y - gkCascnt; gk.wn_Curpos = gkToLogical(gkDp); #ifdef DEBUG peteprint("cursor on \n"); #endif } else /* off */ { pt = gkToGlobal(gk.wn_Curpos); blt.dr.origin.x = pt.x; blt.dr.origin.y = pt.y - gkCascnt; #ifdef DEBUG peteprint("cursor off \n"); #endif } blt.dr.corner.x = blt.dr.origin.x + gkCursor.x; blt.dr.corner.y = blt.dr.origin.y + gkCursor.y; blt.sp = blt.dr.origin; blt.op = L_NDST; blt.pat = texture[0]; lbitblt(&blt, 1, 1); } void SM_Scroll() { extern int ALL_ON[]; BLTSTRUCT blt; GETPTR f; register int dy; register int i; int j; /* if the layer is fully visible, lblt can do it, otherwise */ /* we must rely on the update method */ #ifdef DEBUG peteprint("scroll\n"); #endif f.gfid = gkFont.fi_Id; f.gch = ' '; if ( FM_getch(&f) == -1 ) { msgCmd = WM_ACK; sendmsg(&msg); return; } dy = msgData2 * f.gleading; if ( msgData2 == 0 ) { #ifdef DEBUG peteprint("msgData2 == 0 in scroll\n"); #endif dy = f.gleading; } if ( dy <= 0 ) { msgCmd = WM_ACK; sendmsg(&msg); return; } if ( dy >= gkCrect.corner.y - gkCrect.origin.y ) { SM_ClrClip(); gk.wn_Flags &= ~WT_CURSOR_ON; msgCmd = WM_ACK; sendmsg(&msg); return; } /* turn the cursor off */ if ( gkFlags & WT_CURSOR_ON ) { i = msgData1; msgData1 = 0; SM_DrawCurs(); gkFlags |= WT_CURSOR_WON; msgData1 = i; } cl_area_rect = gkCrect; if ( msgData1 ) /* down */ cl_area_rect.corner.y = gkCrect.origin.y + dy; else /* up */ cl_area_rect.origin.y = gkCrect.corner.y - dy; blt.src = blt.dst = &gkBitMap; blt.op = L_SRC; blt.pat = ALL_ON; blt.sp.x = gkCrect.origin.x; blt.dr = gkCrect; /* all we really want here are the x's */ if ( gkFullyVis ) { if ( msgData1 ) { /* Scroll Down */ blt.sp.y = gkCrect.origin.y; blt.dr.origin.y = gkCrect.origin.y + dy; blt.dr.corner.y = gkCrect.corner.y; bitblt(&blt, 0, 1); blt.dr.corner.y = blt.dr.origin.y; blt.dr.origin.y -= dy; /* gk.wn_Curpos.y += dy; */ } else { /* Scroll Up */ blt.sp.y = gkCrect.origin.y + dy; blt.dr.origin.y = gkCrect.origin.y; blt.dr.corner.y = gkCrect.corner.y - dy; bitblt(&blt, 0, 1); blt.dr.origin.y = blt.dr.corner.y; blt.dr.corner.y += dy; /* gk.wn_Curpos.y -= dy; */ } blt.op = L_TRUE; blt.pat = texture[ msgBytL0 ? gkBpat : gkFpat ]; bitblt(&blt, 0, 1); msgCmd = WM_ACK; sendmsg(&msg); if ( gkFlags & WT_CURSOR_WON ) { msgData1 = 1; SM_DrawCurs(); gkFlags &= ~WT_CURSOR_WON; } return; } /* window not fully visible... harder case to handle */ /* save off real layer region list */ /* for ( i = 0; i < MAX_LRBUF; i++ ) cheater[i] = gkLayer->reg[i]; */ fcpy(cheater, gkLayer->reg, sizeof(SM_REGION)*MAX_LRBUF/2); mk_sc_list(msgData1, dy); /* install our new cheat version */ /* for ( i = 0; i < SCROLL_BUF; i++ ) gkLayer->reg[i] = s[i]; */ fcpy(gkLayer->reg, s, sizeof(SM_REGION)*SCROLL_BUF/2); /* set the right destination rectangle and source point */ if ( msgData1 ) /* down */ { blt.sp.y = gkCrect.origin.y; blt.dr.origin.y = gkCrect.origin.y + dy; blt.dr.corner.y = gkCrect.corner.y; gk.wn_Curpos.y += dy; } else /* up */ { blt.sp.y = gkCrect.origin.y + dy; blt.dr.origin.y = gkCrect.origin.y; blt.dr.corner.y = gkCrect.corner.y - dy; gk.wn_Curpos.y -= dy; } /* perform the visible portion of the scroll */ lblt(&blt, 1, 1); /* now erase the sections which did not get stuff in'em*/ /* replace the real layer definition */ /* for ( i = 0; i < MAX_LRBUF; i++ ) gkLayer->reg[i] = cheater[i]; */ fcpy(gkLayer->reg, cheater, sizeof(SM_REGION)*MAX_LRBUF/2); mk_sc_vlist(msgData1, dy); /* now eliminate all non-visible regions */ for ( i = 0; i < MAX_LRBUF && gkLayer->reg[i].flag != L_EMPTY; i++) if ( gkLayer->reg[i].flag == L_OBSCURED ) { for ( j = i; gkLayer->reg[j+1].flag != L_EMPTY; j++) gkLayer->reg[j] = gkLayer->reg[j+1]; gkLayer->reg[j].flag = L_EMPTY; i--; } gkLayer->reg[i].flag = L_EMPTY; blt.pat = texture[0]; blt.op = L_TRUE; blt.dr = gkCrect; blt.sp = gkCrect.origin; lblt(&blt, 1, 1); /* having blanked out the areas, we now remove all bitmap regions */ /* that intersect the clear_area_rect */ for ( i = 0; i < SCROLL_BUF && gkLayer->reg[i].flag != L_EMPTY; i++ ) if ( R_intersect(cl_area_rect, gkLayer->reg[i].bm.rect) ) { for ( j = i; gkLayer->reg[j+1].flag != L_EMPTY; j++ ) gkLayer->reg[j] = gkLayer->reg[j+1]; gkLayer->reg[j].flag = L_EMPTY; i--; } gkLayer->reg[i].flag = L_EMPTY; /* If there is anything left, redraw the ascii map */ if ( gkLayer->reg[0].flag != L_EMPTY ) redraw_map(gkWid); /* replace the real layer definition */ /* for ( i = 0; i < MAX_LRBUF; i++ ) gkLayer->reg[i] = cheater[i]; */ fcpy(gkLayer->reg, cheater, sizeof(SM_REGION)*MAX_LRBUF/2); msgCmd = WM_ACK; sendmsg(&msg); if ( gkFlags & WT_CURSOR_WON ) { msgData1 = 1; SM_DrawCurs(); gkFlags &= ~WT_CURSOR_WON; } } mk_sc_list(dir, yoff) int dir; int yoff; { register int i,j,k; #ifdef DEBUG peteprint("mk_sc_list\n"); #endif for ( i = 0; i < SCROLL_BUF; i++) s[i].flag = L_EMPTY; /* make a list of all rectangle , either in topright to bottomleft * order for scrolling up or bottomright to topleft order for * scrolling down . The list, produced in the global array of * structures 's', is terminated by the element containing the * flag value L_EMPTY (0). */ if ( dir == 0 ) /* up ? */ { for ( i = 0; i < MAX_LRBUF && gkLayer->reg[i].flag != L_EMPTY; i++ ) if ( gkLayer->reg[i].flag == L_VISIBLE ) for ( j = 0 ; j < SCROLL_BUF; j++ ) if ( s[j].flag == L_EMPTY ) { s[j] = gkLayer->reg[i]; s[j].bm.rect.corner.y -= yoff; break; } else if ( RTL(gkLayer->reg[i].bm.rect.origin, s[j].bm.rect.origin) ) { /* shift all current above 'j' up one */ for (k = SCROLL_BUF - 1; k > j; k-- ) s[k] = s[k - 1]; s[j] = gkLayer->reg[i]; s[j].bm.rect.corner.y -= yoff; break; } } else /* downward scrolling */ { for ( i = 0; i < MAX_LRBUF && gkLayer->reg[i].flag != L_EMPTY; i++ ) if ( gkLayer->reg[i].flag == L_VISIBLE ) for ( j = 0 ; j < SCROLL_BUF; j++ ) if ( s[j].flag == L_EMPTY ) { s[j] = gkLayer->reg[i]; s[j].bm.rect.origin.y += yoff; break; } else if ( RBR(gkLayer->reg[i].bm.rect.origin, s[j].bm.rect.origin) ) { /* shift all current above 'j' up one */ for (k = SCROLL_BUF - 1; k > j; k-- ) s[k] = s[k - 1]; s[j] = gkLayer->reg[i]; s[j].bm.rect.origin.y += yoff; break; } } /* now clip all rectangle of all bitmaps to the current clipping * rectangle . This also computes the final base address for * all visible regions. */ for ( i = 0; i < SCROLL_BUF && s[i].flag != L_EMPTY; i++ ) { s[i].bm.rect = R_Intersection(s[i].bm.rect, gkCrect); /* If the rectangle is now null, eliminate it * else recompute the base address for it */ if ( R_null(s[i].bm.rect)) { for ( j = i; j < (SCROLL_BUF - 1); j++ ) s[j] = s[j+1]; s[SCROLL_BUF-1].flag = L_EMPTY; i--; /* back 'i' up by one */ } else s[i].bm.base = screen_addr(s[i].bm.rect.origin); } } mk_sc_vlist(dir, yoff) int dir; int yoff; { register RECT r; register int i; /* note that the fake list is now in gkLayer->reg[*] */ /* This routine computes, only for the visible regions, * the correct area to be cleared out which is also the * area to run the ascii map through */ if ( dir == 0 ) /* scrolling up */ { /* for each element of the fake list, get only the */ /* lower yoff lines of the region */ for ( i = 0; i < MAX_LRBUF && gkLayer->reg[i].flag != L_EMPTY; i++ ) { if ( gkLayer->reg[i].flag == L_VISIBLE ) { r = gkLayer->reg[i].bm.rect; if ( R_intersect(r, cl_area_rect) ) r = R_Intersection(r, cl_area_rect); else if ( ( r.corner.y - yoff) > r.origin.y ) r.origin.y = r.corner.y - yoff; gkLayer->reg[i].bm.base = screen_addr(r.origin); gkLayer->reg[i].bm.rect = r; } } gkLayer->reg[i].flag = L_EMPTY; } else { /* for each element of the fake list, get only the */ /* top yoff lines of the region */ for ( i = 0; i < MAX_LRBUF && gkLayer->reg[i].flag != L_EMPTY; i++ ) { if ( gkLayer->reg[i].flag == L_VISIBLE ) { r = gkLayer->reg[i].bm.rect; if ( R_intersect(r, cl_area_rect) ) r = R_Intersection(r, cl_area_rect); else if ( ( r.origin.y + yoff) < r.corner.y ) r.corner.y = r.origin.y + yoff; gkLayer->reg[i].bm.rect = r; gkLayer->reg[i].bm.base = screen_addr(r.origin); } } gkLayer->reg[i].flag = L_EMPTY; } } bool RTL(p1, p2) /* is r1 top left of r2 */ POINT p1, p2; { if ( p1.y < p2.y ) return(1); if ( (p1.y == p2.y) && (p1.x < p2.x) ) return(1); return(0); } bool RBR(p1, p2) /* is r1 below right of r2 */ POINT p1, p2; { if ( p1.y > p2.y) return(1); if ( (p1.y == p2.y) && (p1.x > p2.x) ) return(1); return(0); }