$include (..\lib\compStch.ext) /* *============================================================================ * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE * * Permission to use for any purpose, modify, copy, and make enhancements * and derivative works of the software is granted if attribution is given to * R.M. Gillmore, dba the ACME Software Deli, as the author * * While the ACME Software Deli does not work for money, there is nonetheless * a significant amount of work involved. The ACME Software Deli maintains the * rights to all code written, though it may be used and distributed as long as * the following conditions are maintained. * * 1. The copyright statement at the top of each code block is maintained in * your distribution. * 2. You do not identify yourself as the ACME Software Deli * 3. Any changes made to the software are sent to the ACME Software Deli *============================================================================ */ vDrawBoxModule: do; $if not noID declare IDString (*) byte data ( '@(#)vDrawBox.p86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 ); $endif $set( vDrawBoxImplementation ) $include (..\lib\videoIO.ext) $include (..\lib\sysCalls.ext) $if LOGGING $ include (..\lib\logger.ext) $endif /* * ----------------------------------------------------------------------------- * the drawBox() function creates a box of extended ASCII characters. The * line type is either SINGLE_LINE or DOUBLE_LINE, and may differ for the * horizontal and vertical lines. * * The upper left and lower right corners are specified using a pointer to the * coordinate type * ----------------------------------------------------------------------------- */ drawBox: procedure ( verticalLineType, horizontalLineType, upperLeft, lowerRight, clearWindow ) public; declare verticalLineType lineType, horizontalLineType lineType, upperLeft pointer, upperLeftCoordinate based upperLeft coordinate_t, lowerRight pointer, lowerRightCoordinate based lowerRight coordinate_t, clearWindow boolean; declare leftSide literally 'upperLeftCoordinate.x', rightSide literally 'lowerRightCoordinate.x', upperLine literally 'upperLeftCoordinate.y', lowerLine literally 'lowerRightCoordinate.y', lineIndex byte; declare currentLocation word, ( currentX, currentY ) byte at ( @currentLocation ); declare upperLeftCharacter byte, upperRightCharacter byte, lowerLeftCharacter byte, lowerRightCharacter byte, horizontalCharacter byte, verticalCharacter byte; declare tokenStructureType literally 'structure ( upperLeftCorner byte, upperRightCorner byte, lowerLeftCorner byte, lowerRightCorner byte, leftIntersection byte, rightIntersection byte, topIntersection byte, bottomIntersection byte, horizontalChar byte, verticalChar byte )'; /* tokenStructureType */ declare tokens tokenStructureType; cornerDefinitions: procedure; declare horizontalDefinitions ( NUMBER_LINE_TYPES ) lineType data( LINE_SINGLE_HORIZONTAL, LINE_DOUBLE_HORIZONTAL, ' ' ), verticalDefinitions ( NUMBER_LINE_TYPES ) lineType data( LINE_SINGLE_VERTICAL, LINE_DOUBLE_VERTICAL, ' ' ); tokens.horizontalChar = horizontalDefinitions( horizontalLineType ); tokens.verticalChar = verticalDefinitions( verticalLineType ); if ( ( verticalLineType <> DOUBLE_LINE ) and ( verticalLineType <> SINGLE_LINE ) ) then do; tokens.upperLeftCorner = ' '; tokens.upperRightCorner = ' '; tokens.lowerLeftCorner = ' '; tokens.lowerRightCorner = ' '; end; else do; /* * traditional double/single line combination possible, so * determine the corner type */ if ( verticalLineType = horizontalLineType ) then do; if ( verticalLineType = DOUBLE_LINE ) then do; tokens.upperLeftCorner = UPPER_LEFT_DOUBLE_DOUBLE; tokens.upperRightCorner = UPPER_RIGHT_DOUBLE_DOUBLE; tokens.lowerLeftCorner = LOWER_LEFT_DOUBLE_DOUBLE; tokens.lowerRightCorner = LOWER_RIGHT_DOUBLE_DOUBLE; end; else do; tokens.upperLeftCorner = UPPER_LEFT_SINGLE_SINGLE; tokens.upperRightCorner = UPPER_RIGHT_SINGLE_SINGLE; tokens.lowerLeftCorner = LOWER_LEFT_SINGLE_SINGLE; tokens.lowerRightCorner = LOWER_RIGHT_SINGLE_SINGLE; end; end; else do; if ( verticalLineType = DOUBLE_LINE ) then do; tokens.upperLeftCorner = UPPER_LEFT_SINGLE_DOUBLE; tokens.upperRightCorner = UPPER_RIGHT_SINGLE_DOUBLE; tokens.lowerLeftCorner = LOWER_LEFT_SINGLE_DOUBLE; tokens.lowerRightCorner = LOWER_RIGHT_SINGLE_DOUBLE; end; else do; tokens.upperLeftCorner = UPPER_LEFT_DOUBLE_SINGLE; tokens.upperRightCorner = UPPER_RIGHT_DOUBLE_SINGLE; tokens.lowerLeftCorner = LOWER_LEFT_DOUBLE_SINGLE; tokens.lowerRightCorner = LOWER_RIGHT_DOUBLE_SINGLE; end; end; end; end cornerDefinitions; drawBoxStarts: /* * push ( currentLocation ) */ currentLocation = curpos; /* * discover corner types */ call cornerDefinitions; if ( clearWindow ) then do; /* * clear the window which the box will enclose */ declare attribute byte; attribute = getAttributeAtLocation ( leftSide, upperLine ); call clrWindow( leftSide, upperLine, rightSide, lowerLine, attribute ); end; $if LOGGING call addToLog( DEBUG, __FILE__, __LINE__, @( 'upperLeft ( %bd, %bd ) ; lowerRight ( %bd, %bd )', 0 ), upperLeftCoordinate.x, upperLeftCoordinate.y, lowerRightCoordinate.x, lowerRightCoordinate.y ); call addToLog( DEBUG, __FILE__, __LINE__, @( 'horizontal: %bx, vertical: %bx', 0 ), tokens.horizontalChar, tokens.verticalChar ); $endif /* * We've done everything else, draw the box */ call writeAt( tokens.upperLeftCorner, leftSide, upperLine ); call writeManyAt( tokens.horizontalChar, leftSide + 1, upperLine, ( rightSide - leftSide - 1 ) ); call writeAt( tokens.upperRightCorner, rightSide, upperLine ); do lineIndex = ( upperLine + 1 ) to ( lowerLine - 1 ); call writeAt( tokens.verticalChar, leftSide, lineIndex ); call writeAt( tokens.verticalChar, rightSide, lineIndex ); end; call writeAt( tokens.lowerLeftCorner, leftSide, lowerLine ); call writeManyAt( tokens.horizontalChar, leftSide + 1, lowerLine, ( rightSide - leftSide - 1 ) ); call writeAt( tokens.lowerRightCorner, rightSide, lowerLine ); /* * pop (cursor location) */ call gotoxy( currentX, currentY ); end drawBox; end vDrawBoxModule;