[Back to TEXTWNDW SWAG index] [Back to Main SWAG index] [Original]
{
Ok, here comes my window routines. They should be quite fast, and hopefully
not too hard to understand. No range-checking on the screen coordinates is
done (I don't think it's necessary).
The ColorAttr variable is the color-attribute :-). It's used as in the
videomemory. If you want to call the procedure with a separate foreground
and background color (why?), drop me a note and I'll fix it if you can't
do it yourself.
It'll run on a 8086, and I don't want copies optimized with 286 code!
(if this message gets chopped for you -- too bad. Get it from a friend or
tell someone to upload it to a BBS in the US if you want it. Use good
mailing software!)
--------------------------------------------------->8-------------------------
{ Window routines by Jens Larsson (Fido address, 2:201/2120.3), Sweden, PD. }
{ Feel free to use it in your own programs. But do credit me, will you? :-) }
{ Put it in SWAG if you like... }
{$M 1024,0,0}
Uses Crt;
{ The following variable should be assigned at startup to the correct segment }
{ address (b800h or b000h). I've posted a source for doing this before, thus }
{ it's not included here. }
Const TextVidSeg : Word = $b800;
Var ScrBuf, Pdwns : Word;
Function AllocMemory(Paragraphs : Word) : Word; Assembler;
Asm
mov ax,4800h
mov bx,Paragraphs { Number of 16-byte chunks }
int 21h
jnc @Done { Ok? }
mov ax,4c00h
int 21h { If not, halt program! }
@Done:
End;
Procedure PullDown(x1, y1, x2, y2 : Word;
FrameType,
ColorAttr : Byte;
PDName : String); Assembler;
Var DeltaX, DeltaY, AddDI : Word;
Asm
jmp @CodeBegin { Jump to the actual code }
{ Ok Pascal-lovers... I'm sorry, but I declared the data like below... }
{ Somehow it seemed easier to me (I guess I've used assembler too much) }
@Frame:
{ This is all the ASCII codes for all the possible types of frames }
db 020h,020h,020h,020h,020h,020h { ' ' }
db 0dah,0c4h,0bfh,0b3h,0c0h,0d9h { 'ÚÄ¿³ÀÙ' }
db 0c9h,0cdh,0bbh,0bah,0c8h,0bch { 'ÉÍ»ºÈ¼' }
db 0d6h,0c4h,0b7h,0bah,0d3h,0bdh { 'ÖÄ·ºÓ½' }
db 0d5h,0cdh,0b8h,0b3h,0d4h,0beh { 'Õ͸³Ô¾' }
@FrameOfs:
{ And this is the offsets to the above structures }
db 000h,006h,00ch,012h,018h
@CodeBegin:
cmp Pdwns,16 { Max pulldowns = 16 (16 * 4096 = 65536) }
jz @Done
cld
{ Calculate start offset }
mov di,y1
dec di
mov ax,di
mov cl,5
shl di,cl
mov cl,7
shl ax,cl
add di,ax
mov ax,x1
dec ax
add ax,ax
add di,ax
mov dx,di
add dx,4 { This is the offset for the PutName part later }
mov ax,x2
sub ax,x1
dec ax
mov DeltaX,ax
add ax,2
mov bx,80
sub bx,ax
sub bx,2
add bx,bx
mov AddDI,bx
mov ax,y2
sub ax,y1
dec ax
mov DeltaY,ax
push ds
push di
mov si,di
mov di,Pdwns
mov cl,12
shl di,cl { Calculate offset in save segment }
mov es,ScrBuf { Save segment -> ES }
mov ds,TextVidSeg
mov es:[di],si { Store offset to screen }
mov bx,DeltaX
add bx,4
mov es:[di+2],bx { Store DeltaX }
mov cx,DeltaY
add cx,3
mov es:[di+4],cx { Store DeltaY }
mov ax,AddDI
mov es:[di+6],ax { Store AddDI }
add di,8
@SaveScreen:
push cx
mov cx,bx
rep movsw { Save line }
add si,ax
pop cx
dec cx
jnz @SaveScreen
pop di
pop ds
mov es,TextVidSeg
xor bh,bh
mov bl,FrameType
lea si,@FrameOfs
add si,bx
mov bl,cs:[si] { Get offset within frame data }
lea si,@Frame
add si,bx { SI points to frame }
mov ah,ColorAttr
mov al,cs:[si]
stosw { Print upper-left corner }
mov al,cs:[si+1]
mov cx,DeltaX
rep stosw { Print horisontal line }
mov al,cs:[si+2]
stosw { Print upper-right corner }
add di,AddDI
add di,4
push ds
xchg dx,di { Save DI }
mov bx,si { Save SI }
lds si,PDName
mov cl,[si] { Get length of string }
xor ch,ch
mov ah,ColorAttr
inc si
@PutName:
lodsb { Get next char }
stosw { Print next name-char }
dec cx
jnz @PutName
mov di,dx
mov si,bx
pop ds
mov cx,DeltaY
@PutWindow:
push cx
mov al,cs:[si+3] { Get horisontal-line char }
stosw { Print... }
mov al,20h
mov cx,DeltaX
rep stosw { Print some spaces }
mov al,cs:[si+3]
stosw
mov al,08h { Shadow attribute (Bkgr = 0 Frgr = 8) }
inc di
stosb { Print first shaded char... }
inc di
stosb { ... and second }
add di,AddDI
pop cx
dec cx
jnz @PutWindow
mov al,cs:[si+4]
stosw { Print lower-left corner }
mov al,cs:[si+1]
mov cx,DeltaX
rep stosw
mov al,cs:[si+5]
stosw { Print lower-right corner }
mov al,08h
inc di
stosb
inc di
stosb
add di,AddDI
add di,5
mov cx,DeltaX
add cx,2
@PutLastShadowLine:
stosb
inc di
dec cx
jnz @PutLastShadowLine
inc Pdwns
@Done:
End;
Procedure RestoreScreen; Assembler;
Asm
cmp Pdwns,0 { If no pulldowns then exit }
jz @Done
cld
dec Pdwns
mov si,Pdwns
mov es,TextVidSeg
push ds
mov ds,ScrBuf
mov cl,12
shl si,cl
mov di,[si] { Load offset to screen }
mov bx,[si+2] { Load DeltaX }
mov cx,[si+4] { ... DeltaY }
mov dx,[si+6] { ... AddDI }
add si,8
@PutText:
push cx
mov cx,bx
rep movsw { Restore line }
add di,dx
pop cx
dec cx
jnz @PutText
pop ds
@Done:
End;
{ Short example program }
Begin
ScrBuf := AllocMemory(4096);
TextBackground(4);
ClrScr;
PullDown(10,5,70,20,1,$1f,' Window #1 ');
ReadKey;
PullDown(5,10,60,22,2,$4e,' Window #2 ');
ReadKey;
RestoreScreen;
ReadKey;
RestoreScreen;
End.
[Back to TEXTWNDW SWAG index] [Back to Main SWAG index] [Original]