home *** CD-ROM | disk | FTP | other *** search
- { ===================================================================== }
- { WINDO - Windowing routines for Turbo PASCAL }
- { }
- { Author: Michael Burton }
- { 15540 Boot Hill Rd. }
- { Hayden Lake, ID 83835 }
- { (208) 772-9347 (after 1800 PST) }
- { Revision: 2.1 }
- { Date: 04 March 1986 }
- { }
- { Execute the WINTUTOR program for an explanation of use. }
- { }
- { This is a 'Shareware' program. If you find it to be of significant }
- { use to you, a $10 donation to the above address would be greatly }
- { appreciated. This would also place you on our mailing list to keep }
- { you informed of upgrades to Windo and of new programs. }
- { }
- { Modifications: }
- { DATE Rev Description }
- { 04 Mar 86 2.1 Make the heap available check properly }
- { ===================================================================== }
- type
- windimtype = record
- colb,rowb,cole,rowe,attrib,bordr,lastx,lasty : byte;
- end;
- charptr = ^char;
- winstr = string[80];
- brdtype = record
- ul,ur,ll,lr,hz,vtl,vtr: char;
- end;
-
- const maxwin = 30; { Total number of windows on screen at any time }
- noneb = 0; { No border }
- singleb = 1; { Single border }
- doubleb = 2; { Double border }
- mixedb = 3; { Mixed border }
- solidb = 4; { Solid border }
- dimondb = 5; { Diamond border }
- circleb = 6; { Circles border }
- lhatchb = 7; { light hatch border }
- mhatchb = 8; { medium hatch border }
- dhatchb = 9; { dense hatch border }
- brd: array[1..9] of brdtype = (
- (ul:'┌';ur:'┐';ll:'└';lr:'┘';hz:'─';vtl:'│';vtr:'│'), { single }
- (ul:'╔';ur:'╗';ll:'╚';lr:'╝';hz:'═';vtl:'║';vtr:'║'), { double }
- (ul:'╒';ur:'╕';ll:'╘';lr:'╛';hz:'═';vtl:'│';vtr:'│'), { mixed }
- (ul:'█';ur:'█';ll:'█';lr:'█';hz:'█';vtl:'▌';vtr:'▐'), { solid }
- (ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '), { diamond}
- (ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '), { circle }
- (ul:'░';ur:'░';ll:'░';lr:'░';hz:'░';vtl:'░';vtr:'░'), { lhatch }
- (ul:'▒';ur:'▒';ll:'▒';lr:'▒';hz:'▒';vtl:'▒';vtr:'▒'), { mhatch }
- (ul:'▓';ur:'▓';ll:'▓';lr:'▓';hz:'▓';vtl:'▓';vtr:'▓')); { dhatch }
-
- var
- wndo : Array [0..maxwin] of windimtype; { window attributes }
- wndoptr : Array [1..maxwin] of charptr; { pointer to window on heap }
- tmpptr : charptr; { temporary pointer }
- l_i : byte; { level index }
- wndostr : winstr; { string for building wndos }
-
- { ===================================================================== }
- { GETDISP - Get an array of characters from the CRT display and store }
- { them in tostrng. }
- { The row and column inputs are relative to zero and are }
- { also relative to the entire screen, not any open window. }
- { }
- { Inputs: }
- { colb : byte; Starting column (0 - 79) }
- { rowb : byte; Starting row (0 - 24) }
- { len : byte; length of array }
- { tostrng : charptr; Pointer to character storage }
- { ===================================================================== }
- Procedure GetDisp(colb,rowb,len : byte; tostrng : charptr);
- Begin
- Inline(
- $1E/ { PUSH DS }
- $8A/$86/rowb/ { MOV AL,rowb[BP] }
- $B3/$50/ { MOV BL,80 }
- $F6/$E3/ { MUL BL }
- $2B/$DB/ { SUB BX,BX }
- $8A/$9E/colb/ { MOV BL,colb[BP] }
- $03/$C3/ { ADD AX,BX }
- $03/$C0/ { ADD AX,AX }
- $8B/$F8/ { MOV DI,AX }
- $C4/$B6/tostrng/ { LES SI,tostrng[BP] }
- $8A/$8E/len/ { MOV CL,len[BP] }
- $03/$C9/ { ADD CX,CX }
- $2B/$C0/ { ADD AX,AX }
- $8E/$D8/ { MOV DS,AX }
- $A0/$49/$04/ { MOV AL,DS:[0449H] }
- $22/$C9/ { AND CL,CL }
- $74/$32/ { JZ DONE }
- $2C/$07/ { SUB AL,7 }
- $74/$20/ { JZ MONO }
- $BA/$00/$B8/ { MOV DX,0B800H }
- $8E/$DA/ { MOV DS,DX }
- $BA/$DA/$03/ { MOV DX,03DAH }
- $EC/ { TESTLOW: IN AL,DX }
- $A8/$01/ { TEST AL,1 }
- $75/$FB/ { JNZ TESTLOW }
- $FA/ { CLI }
- $EC/ { TESTHI: IN AL,DX }
- $A8/$01/ { TEST AL,1 }
- $74/$FB/ { JZ TESTHI }
- $8A/$1D/ { MOV BL,DS:[DI] }
- $26/$88/$1C/ { MOV ES:[SI],BL }
- $47/ { INC DI }
- $46/ { INC SI }
- $E2/$EC/ { LOOP GETCHAR }
- $2A/$C0/ { SUB AL,AL }
- $74/$0E/ { JZ DONE }
- $BA/$00/$B0/ { MONO: MOV DX,0B000H }
- $8E/$DA/ { MOV DS,DX }
- $8A/$1D/ { MONO1: MOV BL,DS:[DI] }
- $26/$88/$1C/ { MOV ES:[SI],BL }
- $47/ { INC DI }
- $46/ { INC SI }
- $E2/$F7/ { LOOP MONO1 }
- $1F); { DONE: POP DS }
- End;
-
- { ===================================================================== }
- { DISPALL - Display an array of characters and attributes on the CRT. }
- { The array is usually one that has been created using the }
- { GetDisp procedure. }
- { The row and column inputs are relative to zero and are }
- { also relative to the entire screen, not any open window. }
- { }
- { Inputs: }
- { colb : byte; Starting column (0 - 79) }
- { rowb : byte; Starting row (0 - 24) }
- { len : byte; length of array (not including attributes)}
- { fromstrng : charptr; Pointer to array to display }
- { ===================================================================== }
- Procedure DispAll(colb,rowb,len : byte; fromstrng : charptr);
- Begin
- Inline(
- $1E/ { PUSH DS }
- $8A/$86/rowb/ { MOV AL,rowb[BP] }
- $B3/$50/ { MOV BL,80 }
- $F6/$E3/ { MUL BL }
- $2B/$DB/ { SUB BX,BX }
- $8A/$9E/colb/ { MOV BL,colb[BP] }
- $03/$C3/ { ADD AX,BX }
- $03/$C0/ { ADD AX,AX }
- $8B/$F8/ { MOV DI,AX }
- $C4/$B6/fromstrng/ { LES SI,fromstrng[BP] }
- $8A/$8E/len/ { MOV CL,len[BP] }
- $03/$C9/ { ADD CX,CX }
- $2B/$C0/ { ADD AX,AX }
- $8E/$D8/ { MOV DS,AX }
- $A0/$49/$04/ { MOV AL,DS:[0449H] }
- $22/$C9/ { AND CL,CL }
- $74/$32/ { JZ DONE }
- $2C/$07/ { SUB AL,7 }
- $74/$20/ { JZ MONO }
- $BA/$00/$B8/ { MOV DX,0B800H }
- $8E/$DA/ { MOV DS,DX }
- $BA/$DA/$03/ { MOV DX,03DAH }
- $26/$8A/$1C/ { GETCHAR: MOV BL,ES:[SI] }
- $EC/ { TESTLOW: IN AL,DX }
- $A8/$01/ { TEST AL,1 }
- $75/$FB/ { JNZ TESTLOW }
- $FA/ { CLI }
- $EC/ { TESTHI: IN AL,DX }
- $A8/$01/ { TEST AL,1 }
- $74/$FB/ { JZ TESTHI }
- $88/$1D/ { MOV DS:[DI],BL }
- $47/ { INC DI }
- $46/ { INC SI }
- $E2/$EC/ { LOOP GETCHAR }
- $2A/$C0/ { SUB AL,AL }
- $74/$0E/ { JZ DONE }
- $BA/$00/$B0/ { MONO: MOV DX,0B000H }
- $8E/$DA/ { MOV DS,DX }
- $26/$8A/$1C/ { MONO1: MOV BL,ES:[SI] }
- $88/$1D/ { MOV DS:[DI],BL }
- $47/ { INC DI }
- $46/ { INC SI }
- $E2/$F7/ { LOOP MONO1 }
- $1F); { DONE: POP DS }
- End;
-
- { ===================================================================== }
- { DISPLINE - Display a string of characters on the CRT (with the same }
- { attributes) }
- { The row and column inputs are relative to zero and are }
- { also relative to the entire screen, not any open window. }
- { }
- { Inputs: }
- { colb : byte; Starting column (0 - 79) }
- { rowb : byte; Starting row (0 - 24) }
- { attrib : byte; Line attributes }
- { fromstrng : string[80]; String to display }
- { ===================================================================== }
- Procedure DispLine(colb,rowb,attrib : byte; VAR fromstrng : winstr);
- Begin
- Inline(
- $1E/ { PUSH DS }
- $8A/$86/rowb/ { MOV AL,rowb[BP] }
- $B3/$50/ { MOV BL,80 }
- $F6/$E3/ { MUL BL }
- $2B/$DB/ { SUB BX,BX }
- $8A/$9E/colb/ { MOV BL,colb[BP] }
- $03/$C3/ { ADD AX,BX }
- $03/$C0/ { ADD AX,AX }
- $8B/$F8/ { MOV DI,AX }
- $8A/$BE/attrib/ { MOV BH,attrib[BP] }
- $C4/$B6/fromstrng/ { LES SI,fromstrng[BP] }
- $2B/$C9/ { SUB CX,CX }
- $26/$8A/$0C/ { MOV CL,ES:[SI] }
- $2B/$C0/ { ADD AX,AX }
- $8E/$D8/ { MOV DS,AX }
- $A0/$49/$04/ { MOV AL,DS:[0449H] }
- $22/$C9/ { AND CL,CL }
- $74/$34/ { JZ DONE }
- $2C/$07/ { SUB AL,7 }
- $74/$21/ { JZ MONO }
- $BA/$00/$B8/ { MOV DX,0B800H }
- $8E/$DA/ { MOV DS,DX }
- $BA/$DA/$03/ { MOV DX,03DAH }
- $46/ { GETCHAR: INC SI }
- $26/$8A/$1C/ { MOV BL,ES:[SI] }
- $EC/ { TESTLOW: IN AL,DX }
- $A8/$01/ { TEST AL,1 }
- $75/$FB/ { JNZ TESTLOW }
- $FA/ { CLI }
- $EC/ { TESTHI: IN AL,DX }
- $A8/$01/ { TEST AL,1 }
- $74/$FB/ { JZ TESTHI }
- $89/$1D/ { MOV DS:[DI],BX }
- $47/ { INC DI }
- $47/ { INC DI }
- $E2/$EB/ { LOOP GETCHAR }
- $2A/$C0/ { SUB AL,AL }
- $74/$0F/ { JZ DONE }
- $BA/$00/$B0/ { MONO: MOV DX,0B000H }
- $8E/$DA/ { MOV DS,DX }
- $46/ { MONO1: INC SI }
- $26/$8A/$1C/ { MOV BL,ES:[SI] }
- $89/$1D/ { MOV DS:[DI],BX }
- $47/ { INC DI }
- $47/ { INC DI }
- $E2/$F6/ { LOOP MONO1 }
- $1F); { DONE: POP DS }
- End;
-
- { ======================================================================== }
- { NAME: Normalize VERSION: 1.0 DATE: 23 January 1986 }
- { AUTHOR: Michael Burton }
- { DESCRIPTION: Normalize coordinates }
- { INPUTS: s,e : byte; start and end coordinates }
- { OUTPUTS: s,e : byte; coordinates with s < e }
- { }
- { ======================================================================== }
- Procedure Normalize(VAR s,e: byte);
- Var temp: byte;
- Begin
- If s > e Then
- Begin
- temp := s;
- s := e;
- e := temp;
- End;
- End;
-
- { ======================================================================== }
- { NAME: Bleep VERSION: 1.0 DATE: 14 January 1986 }
- { AUTHOR: Michael Burton }
- { DESCRIPTION: Produce a bleeping sound times number of times }
- { INPUTS: times : byte; The number of bleeps required }
- { }
- { ======================================================================== }
- Procedure Bleep(times : byte);
- Var i : byte;
- Begin
- For i := 1 To times Do
- Begin
- Nosound;
- Sound(880);
- Delay(60);
- Sound(440);
- Delay(60);
- Nosound;
- End;
- End;
-
- { ======================================================================== }
- { NAME: Set_Cursor VERSION: 1.0 DATE: 27 January 1986 }
- { AUTHOR: }
- { DESCRIPTION: Set the cursor size }
- { INPUTS: The number of cursor lines to display (0 -7, 0-14) }
- { }
- { ======================================================================== }
- Procedure Set_Cursor (n: byte);
- Type
- regrec = Record
- ax,bx,cx,dx,bp,si,di,ds,es,flags: integer
- End;
- Var regpak: regrec;
- Begin
- regpak.ax:= $100;
- If Not n In [1..8] Then regpak.cx:= $0800
- Else regpak.cx:= ((8-n) shl 8) or 7;
- Intr($10,regpak)
- End;
-
- { ===================================================================== }
- { INITWINDO - Initialize the window variables }
- { }
- { Use this routine before using MAKEWINDO, REMOVEWINDO or TITLEWINDO }
- { }
- { Inputs: }
- { txtcolor : byte; Starting text color }
- { bkgndclr : byte; Starting background color }
- { ===================================================================== }
- Procedure InitWindo(txtcolor,bkgndclr : byte);
- Begin
- brd[5].ul := chr(08); { Set up circle border constants }
- brd[5].ur := chr(08);
- brd[5].ll := chr(08);
- brd[5].lr := chr(08);
- brd[5].hz := chr(08);
- brd[5].vtl := chr(08);
- brd[5].vtr := chr(08);
- brd[6].ul := chr(10); { Set up diamond border constants }
- brd[6].ur := chr(10);
- brd[6].ll := chr(10);
- brd[6].lr := chr(10);
- brd[6].hz := chr(10);
- brd[6].vtl := chr(10);
- brd[6].vtr := chr(10);
- textcolor(txtcolor);
- textbackground(bkgndclr);
- wndo[0].rowb := 0; { Initialize non-window zero }
- wndo[0].rowe := 24;
- wndo[0].colb := 0;
- wndo[0].cole := 79;
- wndo[0].attrib := (bkgndclr * 16) + txtcolor;
- wndo[0].bordr := noneb;
- wndo[0].lastx := Wherex;
- wndo[0].lasty := Wherey;
- l_i := 0;
- End;
-
- { ===================================================================== }
- { MAKEWINDO - Create a window }
- { }
- { Inputs: }
- { colb : byte; Start column (1 - 80) }
- { rowb : byte; Start row (1 - 25) }
- { cole : byte; End column (1 - 80) }
- { rowe : byte; End row (1 - 25) }
- { tcolor : byte; Text color (0 - 15) }
- { tback : byte; Text background (0 - 7, > 7 for blinking) }
- { bordr : boolean; Border indicator (0 - 9) }
- { ===================================================================== }
- Procedure MakeWindo(colb,rowb,cole,rowe,tcolor,tback:byte;bordr:byte);
- Var i : byte;
- wsize : integer;
- pseg : integer;
- pofs : integer;
- mema : real;
- Begin
- rowb := rowb - 1; { Set coordinates relative to zero }
- rowe := rowe - 1;
- colb := colb - 1;
- cole := cole - 1;
- Normalize(rowb,rowe);
- Normalize(colb,cole);
- wsize := 2 * ((cole - colb + 1) * (rowe - rowb + 1)); { Total size of area }
- { needed to store display }
- If l_i + 1 > maxwin Then
- Begin
- Writeln('Too many Windows!');
- Bleep(4);
- End
- Else
- Begin
- If memavail < 0 then mema := 65536.0 + memavail
- else mema := memavail;
- If (wsize DIV 16 + 1) > mema Then
- Begin
- Writeln('Not enough Heap space!');
- Bleep(4);
- End
- Else
- Begin
- wndo[l_i].lastx := Wherex; { Store old cursor coordinates }
- wndo[l_i].lasty := Wherey;
- l_i := l_i + 1; { Go to next window level }
- Textcolor(tcolor);
- Textbackground(tback);
- wndo[l_i].rowb := rowb; { Store all variables for this window }
- wndo[l_i].rowe := rowe;
- wndo[l_i].colb := colb;
- wndo[l_i].cole := cole;
- wndo[l_i].attrib := (tback * 16) + tcolor;
- wndo[l_i].bordr := bordr;
- GetMem(wndoptr[l_i],wsize); { Get enough heap to store old display }
- tmpptr := wndoptr[l_i];
- For i := rowb To rowe Do { Store old display one row at a time }
- Begin
- GetDisp(colb,i,(cole-colb+1),tmpptr);
- pseg := Seg(tmpptr^);
- pofs := Ofs(tmpptr^);
- pofs := pofs + 2 * (cole - colb + 1);
- tmpptr := Ptr(pseg,pofs);
- End;
- wndostr[0] := chr(cole - colb + 1); { Set up String length }
- If bordr = noneb Then
- Begin
- FillChar(wndostr[1],cole-colb+1,' '); { Do no border }
- For i := rowb To rowe Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
- Window(colb+1,rowb+1,cole+1,rowe+1); { Create actual Turbo window }
- End
- Else
- Begin
- wndostr[1] := brd[bordr].ul; { Do border top line }
- wndostr[cole-colb+1] := brd[bordr].ur;
- FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
- DispLine(colb,rowb,wndo[l_i].attrib,wndostr);
- wndostr[1] := brd[bordr].vtl; { Do border middle lines }
- wndostr[cole-colb+1] := brd[bordr].vtr;
- FillChar(wndostr[2],cole-colb-1,' ');
- For i := rowb+1 To rowe-1 Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
- wndostr[1] := brd[bordr].ll; { Do border bottom line }
- wndostr[cole-colb+1] := brd[bordr].lr;
- FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
- DispLine(colb,rowe,wndo[l_i].attrib,wndostr);
- Window(colb+2,rowb+2,cole,rowe); { Create actual Turbo window }
- End;
- Gotoxy(1,1);
- End;
- End;
- End;
-
- { ===================================================================== }
- { REMOVEWINDO - Remove the last window created from the screen. To }
- { get back to the original screen, there must be as many }
- { Removewindos as there are Makewindos. }
- { }
- { Inputs: }
- { None }
- { ===================================================================== }
- Procedure RemoveWindo;
- Var i : byte;
- wsize: integer;
- pseg : integer;
- pofs : integer;
- Begin
- If l_i = 0 Then
- Begin
- Writeln('No Window To Remove!');
- Bleep(4);
- End
- Else
- Begin
- wsize := wndo[l_i].cole - wndo[l_i].colb + 1;
- tmpptr := wndoptr[l_i];
- For i := wndo[l_i].rowb To wndo[l_i].rowe Do { Put back old display }
- Begin
- DispAll(wndo[l_i].colb,i,wsize,tmpptr);
- pseg := Seg(tmpptr^);
- pofs := Ofs(tmpptr^);
- pofs := pofs + 2 * wsize;
- tmpptr := Ptr(pseg,pofs);
- End;
- wsize := 2 * ((wndo[l_i].cole - wndo[l_i].colb + 1) * (wndo[l_i].rowe - wndo[l_i].rowb + 1));
- FreeMem(wndoptr[l_i],wsize); { Release heap space }
- l_i := l_i - 1; { Go to next lower level }
- Textcolor(wndo[l_i].attrib AND $0F); { Set up all for this level }
- Textbackground(wndo[l_i].attrib DIV 16);
- If wndo[l_i].bordr = noneb Then
- Window(wndo[l_i].colb+1,wndo[l_i].rowb+1,wndo[l_i].cole+1,wndo[l_i].rowe+1)
- Else
- Window(wndo[l_i].colb+2,wndo[l_i].rowb+2,wndo[l_i].cole,wndo[l_i].rowe);
- Gotoxy(wndo[l_i].lastx,wndo[l_i].lasty);
- End;
- End;
-
- { ===================================================================== }
- { TITLEWINDO - Place a centered title in the top border of a window. }
- { }
- { Inputs: }
- { title : string[80]; The title of the window }
- { ===================================================================== }
- Procedure TitleWindo (title: winstr);
- Var i : byte;
- Begin
- i := (((wndo[l_i].cole-wndo[l_i].colb) - length(title)) DIV 2 + 1) + wndo[l_i].colb;
- DispLine(i,wndo[l_i].rowb,wndo[l_i].attrib,title);
- End;