This post describes two more routines from my Action! windowing library. These functions are for printing to a window and clearing a windows contents. The functions are part of the file LIBWIN.ACT. The entire library will be released at conclusion of the blog posts. The routines are:
- WPrint – Print to a window
- WClr – Clear a windows contents
This routine is used to print text at coordinates within a given window. It takes 4 parameters:
- Window handle (n)
- X position / column (x)
- Y position / row (y)
- String to print (s)
If no errors are encountered it returns 0 (good). If an error does occur, it returns the error code.
The print routine works as follows.
- First a default return code of error status NOT OPEN is set.
- Next the address of the window handle is computed. Then the status of the windows handle is checked.
- If the windows status is free, the routine exits with the default error code previously set.
- If the windows status is used, the passed string is copied to a temporary buffer. I check is made to ensure the length won’t exceed the windows right boundary. If it will, its truncated. Next the string is converted to internal character code from ATASCII because it will be copied directly to screen memory. Then if the inverse flag is set, the string is inversed.
- The screen position in memory is then computed. If the x parameter was specified as WPCENT, the text will be centered, otherwise it will be placed at the x position specified. The temporary string is then copied directly into screen memory.
- The return code is set to 0 (good) and the routine exits.
; -------------------------------------- ; Func..: BYTE WPrint(BYTE n,x,y ; CARD POINTER s) ; Desc..: Print text in window at pos ; Params: n = number of window handle ; x = column to print at ; y = row to print at ; s = Text string pointer ; Notes.: Max 38 for frame ; Return: 0 if success ; >100 on error ; -------------------------------------- BYTE FUNC WPrint(BYTE bN,x,y CHAR POINTER pS) BYTE bR CHAR ARRAY cL(38) CARD POINTER cS ; Set default return code bR=WERNOPN ; Find window handle record pWn=baW+(WRECSZ*bN) ; Only if handle in use if pWn.bS#WSFREE then ; Copy string to line buffer SCopy(cL,pS) ; Ensure text wont overrun ; Check len not > width-x-1 ; x is column offset ; width inc frames, remove 1 ; instead of 2 due to x as 1 based if cL(0) > pWn.bW-x-1 then cL(0)=pWn.bW-x-1 fi ; Convert from ATA to INT StrAI(cL) ; Make inverse if ON if pWn.bI=WINVON then ; Always inverse title text ; Skip first byte (str len) StrInv(cL+1,cL(0)) fi ; Find top left corner of window ; in screen memory (inside frame) cS=RSCRN+(pWn.bY*40)+pWn.bX ; Add 40 for each row (Y) cS==+(y*40) ; If not center, move to pos if x#WPCENT then ; Add x for column cS==+x ; Else move to centered position else ; Add width-length/2 for centered x. cS==+((pWn.bW-cL(0))/2) fi ; Move it to screen, skip len byte MoveBlock(cS,cL+1,cL(0)) ; Set valid return bR=0 fi RETURN(bR)
This routine is used to clear the inner contents of the given window. It takes only one parameter which is the window handle number to clear. It returns 0 (good) if no errors were encountered, otherwise it returns the error code. The routine works in the following way:
- First, a default error return code of NOT OPEN is set.
- Next, the address of the window handle is computed. The handle status is then checked.
- If the window status is free, the routine exits passing back the previously defined error code of NOT OPEN.
- If the window status is used, the top left position for the contents of the window (inside border) is computed. An empty string is created for the windows content width (not frame width). If the window has the inverse flag set, the empty string is inversed.
- Line by line the empty string is then copied directly into screen memory.
- Finally, the return code of 0 (good) is set and the routine exits with the return code.
; -------------------------------------- ; Func..: BYTE WClr(BYTE n) ; Desc..: Clears window contents ; Params: n = number of window handle ; Return: 0 if success ; >100 on error ; -------------------------------------- BYTE FUNC WClr(BYTE bN) BYTE bR,bL CHAR ARRAY cL(38) CARD POINTER cS ; Set default return code bR=WERNOPN ; Find window handle record pWn=baW+(WRECSZ*bN) ; Only if handle in use if pWn.bS=WSUSED then ; Find top left corner of window ; in screen memory (inside frame) cS=RSCRN+(pWn.bY*40)+pWn.bX+41 ; Make line empty SetBlock(cL,pWn.bW-2,0) ; If inverse flip line if pWn.bI=WINVON then StrInv(cL,pWn.bW-2) fi ; Clear window line by line for bL=1 to pWn.bH-2 DO ; Restore underlying scrn from win mem MoveBlock(cS,cL,pWn.bW-2) ; Inc scr by 40 to next line start cS==+40 OD ; Set return bR=0 fi RETURN(bR)
To demonstrate these functions, I’ve added on to the same demonstration program used in previous posts. A couple of minor changes were made to the window sizes to make them taller so they would overlap more, purely cosmetic.
The notable additions to the program are the WPrint() lines, the WClr() line, and the addition of another keystroke wait. This also demonstrates the usage of centering with WPrint(). The second “Hello” in window 3 is centered, as is “Inverse ATASCII Podcast” in window 2.
; Program: WINDOW.ACT ; Author.: Wade Ripkowski ; Date...: 2016.04 ; Desc...: Test Windowing Library ; License: Creative Commons ; Attribution-NonCommercial- ; NoDerivatives ; 4.0 International ; Include library INCLUDE "D3:DEFINES.ACT" INCLUDE "D3:DEFWIN.ACT" INCLUDE "D3:LIBSTR.ACT" INCLUDE "D3:LIBWIN.ACT" INCLUDE "D3:LIBMISC.ACT" ; Start MODULE PROC Main() ; Window handles BYTE bW1,bW2,bW3 ; Init Window System WInit() ; Open window 1 bW1=WOpen(10,5,20,7,WINVOFF) WTitle(bW1,"One") WPrint(bW1,1,1,"Row 1 Column 1") WPrint(bW1,1,5,"Unfinished Bitness") ; Open window 2 bW2=WOpen(5,15,30,6,WINVON) WTitle(bW2,"TWO") WPrint(bW2,2,2,"2,2") WPrint(bW2,WPCENT,4,"Inverse ATASCII Podcast") ; Open window 3 bW3=WOpen(15,8,10,10,WINVOFF) WTitle(bW3,"Three") WPrint(bW3,1,3,"Hello") WPrint(bW3,3,5,"Hello") WPrint(bW3,1,7,"Hello") ; Wait for a keystroke or console key WaitKC() ; Clear window 3 WClr(bW3) ; Wait for a keystroke or console key WaitKC() ; Close window 3 WClose(bW3) ; Close window 2 WClose(bW2) ; Close window 1 WClose(bW1) RETURN
Running the program produces the following screens. The first shows the windows opened, with content applied. It is waiting for a keystroke before proceeding:
This shows the windows after the contents of window 3 have been cleared. It is again waiting for a keystroke before continuing:
After the windows are closed, control is returned to the Action! cartridge:
The next post will include functions for positioning the virtual cursor, and for putting single characters to a window.