DEFT AGS by Ken Schunk Copyright 1985 by TCE I. Introduction: The DEFT AGS package is a collection of routines that allow the easy creation of complex graphics programs. It's features include the ability to restrict the drawing to a section of the screen, the ability tosave part of a screen for later recall, and the easy creation of menubars and menus. II. Background: The DEFT AGS routines are set up to use the CoCo's PMODE 4 screen, along with the artificed colors. The screen resolution is 256 horizontal by 192 vertical. When using the artifice colors, the x coordinate is divided internally by two, giving an effective resolution of 128. The top left coordinate of the screen is 0,0 and the bottom right coordinate is 255,191. III. Use: The DEFT AGS disk contains a number of files. First on the list is the file DEFTAGS/LIB. This is the library that contains all of the routines in the package. The next file is DEFTAGS/EXT. This file contains all of the information needed by the Pascal compiler to use the graphics routines in the program. Also included are a number of fonts, including the system font DEFTAGS/FNT. You will also find the file PASBOOT/OBJ on the disk. This MUST be used in place of the normal PASBOOT. It puts the stack at $C000, making room for the buffers and graphics screen. If it is not used, the graphics screen will overwrite the stack with unpleasant results. To use the DEFT AGS functions in your program, the following line must be placed at the start of the program: %CDEFTAGS/EXT:DRIVENUMBER This will cause the compiler to read in the defintions for the library from the file DEFTAGS/EXT at the start of compiliation. The DRIVENUMBER must be replaced by the number of the drive that the DEFTAGS/EXT file is on. When linking the resultant object file, the file DEFTAGS/LIB is linked into your program. This file should be specified as the last object file to link, with the main file being the first linked. IV. Commands: The following is an alphabetical list of the commands added by the DEFT AGS package.The description for each command is laid out as follows: Name Calling format Parameter description Description Side effects Module in library that command resides in. The Commands 1. AboutDEFTAGS A. AboutDEFTAGS(Device_Number); B. Device_Number: Device number to use for input. See list in appendix B. C. This procedure will request an area on the screen, and place in that area information about the DEFT AGS package, including the revision number and copyright information. It will then wait for an input from the device number passed to it. The screen is restored upon exit. D. Changes Viewport, PenColor, XCursor and YCursor. Requires enough buffer space to save area. If the buffer is not large enough, the routine returns with no action. E. Menus 2. Background A. Background; B. None C. This procedure sets the viewport to the entire screen and fills the screen with a checked pattern with a black border. On a color monitor the pattern will appear as blue and red lines. D. Changes Viewport, PenColor, XCursor and YCursor. E. Menus 3. Box A. Box(Left,Right,Top,Bottom); B. Left : Integer value for the left side of the box. Right : Integer value for the right side of the box Top : Integer value for the top of the box Bottom: Integer value for the bottom of the box C. This procedure draws a black box on the screen and fills the inside of the box with white. The box is drawn with a with thicker bottom and right sides, which gives a shadowed effect. D. Changes Viewport, PenColor, XCursor and YCursor. E. Menus 4. CharMode A. I:=CharMode; B. None C. This function returns an integer representing the current character print attributes. The low byte of the returned integer can be interpreted as follows: Bit number 76543210 :::::::: Unused ---------+++++::+--- Inverse flag. 1=Inverse :: 0=Normal Dim flag 1=Dim -----+: 0=Normal +---- Bold flag. 1=Bold 0=Normal D. None E. Charactr 5. CharType A. CharType(Attributes); B. Attributes : An integer value whose low byte contains the desired character attributes. See the description in the CharMode command for the meaning of this byte. C. This procedure is used to set the current character print attributes. D. None E. Charactr 6. CharWidth A. I:=CharWidth(Character); B. Character : Char type variable or constant C. This function returns the width in screen dots of the character passed to it. Since the character set can be proportionally spaced, each character could occupy a different amount of space on the screen. This function returns the actual amount of room a character will use. D. None E. Charactr 7. Circle A. Circle(X,Y,Radius); B. X : Integer value for X location of center of circle Y : Integer value for Y location of center of circle Radius : Integer value for radius of circle. C. This procedure will draw a circle on the screen using the current pencolor. If the circle is larger than the current viewport, the circle will be clipped at the viewport edge. D. Changes XCursor and YCursor. E. Circle 8. Fill A. Fill(X,Y,StopColor); B. X : X coordinate for the start of filling Y : Y coordinate for the start of filling StopColor: The boundary color to stop filling at C. This procedure fills the screen with the current pattern starting at X,Y and stopping at a boundary of StopColor. This procedure ignores the viewport boundaries, and will fill the entire screen if a boundary of StopColor is not present. The routine is neither smart nor fast, and repeated calls to the fill routine may be necessary to completely fill complex shapes. The routine cannot fill on a colored background using a border color of White1 or Black1 since the colored background would be seen as a series of White1 and Black1 stripes. D. None E. Paint 9. FillScreen A. FillScreen(Color); B. Color : Screencolor type variable or constant for color to fill the screen. C. This procedure fills the current viewport with the color specified. Only the current viewport will be affected. If the viewport left and right sides are set to full screen (0 and 255), the screen fill will be faster. D. Changes pencolor to the Color used to fill the screen E. Menus 10.FillBkgd A. FillBkgd; B. None C. This procedure will quickly fill the entire screen with a background checked pattern. Used by the procedure Background. This procedure ignores the viewport boundaries. D. None E. LowLevel 11.GetKeyPress A. I:=GetKeyPress; B. None C. This function returns the ASCII code for the key pressed on the keyboard. The routine supports autorepeat, so if a key is held down it will continue to return codes. If there is no key pressed, the routine will return the ASCII code of 0. D. None E. LowLevel 12.GetPosition A. Value:=GetPosition(Device_Number,XValue,YValue,Button); B. Device_Number: Device number to use for input. See appendix B for list. XValue,YValue: Returned x and y position value. When using the keyboard for input, the passed value will be modified and returned. Example: If the x and y values are passed as one, and the up arrow is pressed, the x value will return unchanged and the y value will be one less, or 0. Button: Boolean value, true if button pressed, false if not. C. This function returns the current position of the device passed to it. Pressing the break key will change the device to the keyboard and get all further input from there. Pressing the device's button for devices 1 thru 4, or ENTER for device 0 will return a value of True for button. The joystick ports will return a number between 0 and 255 (steps of 4) for the x position and 0 thru 191 ( steps of 3 ) for the y position. All devices return x values of 0..255 and y values of 0..191. D. Reads keyboard each time called. E. Menus 13.GrafInit A. GrafInit; B. None C. This machine language procedure performs the following actions: 1. Sets viewport to full screen. 2. Clears the screen to black. 3. Sets the pencolor to White1. 4. Sets the X and Y cursor locations to 0. 5. Sets the character mode to black normal letters on a white background. 6. Sets the graphics mode and displays the screen. D. Resets the graphics system. Does not initialize the screen save buffer. E. LowLevel 14.GrafMode A. GrafMode; B. None C. This procedure sets the VDG display mode to 6GR with a screen at $C000, and does no other initialization. D. None E. LowLevel 15.InitGraf A. InitGraf(Char_Set_Name); B. Char_Set_Name: Name of the character set to read in from disk. If the name has a length of zero (''), then no character set will be read in. C. This procedure initializes the entire graphics system with the exception of the screen save buffer. It will attempt to read in a character set from disk using the Char_Set_Name passed to it as a file name. If this has a length of zero , then no character set will be read in. If the font cannot be found on the disk, then it will attempt to load the font DEFTAGS from drive 0. D. See the GrafInit command. E. Initlize 16.InitBuffer A. InitBuffer; B. None C. Initializes the screen save buffer. This command sets up all of the pointers for the buffer, and MUST be called before any calls to ScrnSave or ScrnRestore. D. Resets all of the buffer information. E. Buffers 17.KeyIn A. KeyIn(Input_String,X,Y,Max_Length,Prompt_String); B. Input_String: Returned string value from procedure. X: X location to print prompt. Y: Y location to print prompt. Max_Length: The maximum length permitted for the inputted string. Prompt_String: Prompt string to be printed before input. C. This procedure allows the inputting of a string from the keyboard, with the echoing of the string to the HiRes display as it is typed. The back arrow key is functional for input editing. The X and Y values determine where the prompt is printed. The input is echoed directly after the prompt. No more then Max_Length characters will be accepted form the keyboard. D. Alters PenColor, XCursor and YCursor. E. Menus 18.Line A. Line(X1,Y1,X2,Y2); B. X1: Starting X coordinate for line. Y1: Starting Y coordinate for line. X2: Ending X coordinate for line. Y2: Ending Y coordinate for line. C. This procedure draws a line between two points using the current pencolor. The line will be clipped at the current viewport boundary. D. The XCursor and YCursor values will be set to the endpoint coordinates. E. LowLevel 19.LineTo A. LineTo(X2,Y2); B. X2: Ending X coordinate for the line. Y2: Ending Y coordinate for line. C. This procedure draws a line from the current position to the new coordinates passed to it. D. The XCursor and YCursor values will be set to the endpoint coordinates. E. LowLevel 20.Menu A. Menu(Menu_Entries,States,Menu_Title,Left,Top,Device_Number); B. Menu_Entries: Array[0..15] of strings. These are the menu entries for the menu. List is terminated by a zero length ('') string. States: Array[0..15] of integer. These are the current state for each menu entry. The state value has the same format as the attributes in CharMode, with on addition. If bit 7 is set, the entry will be printed with a check mark preceeding it. If the state for an entry is dimmed, then that entry will be disabled on the menu and will not be able to be selected. Menu_Title: Optional title for menu. If no title is desired, us a zero length string. Left: Coordinate for left side of menu. If the menu will not fit on the screen with the given left coordinate, the menu will be shifted left enough to allow it to fit. Top: Coordinate for the top of the menu. If the menu will not fit on the screen with the given top coordinate, the menu will be shifted up to allow the menu to fit on the screen. Device_Number: Device number to use for input. See list in appendix B. C. This function creates a menu at the specified location and returns an integer value indicating which item on the menu was chosen. The first entry in the menu_entries array has a number of zero, and the entries are number sequentially up from there. If the break key is pressed, the function will switch to the keyboard for input. D. Changes Viewport, PenColor,XCursor and YCursor. Uses save buffer. If there is not enough buffer space to save area needed then the function exits with no action, returning a value of -2. E. Menus 21.MenuBar A. MenuBar(Menu_Entries,States,Device_Number); B. Menu_Entries: Array[0..15] of strings. These are the menu entries for the menu. List is terminated by a zero length ('') string. States: Array[0..15] of integer. These are the current state for each menu entry. The state value has the same format as the attributes in CharMode. If the state for an entry is dimmed, then that entry will be disabled on the menu and will not be able to be selected. Device_Number: Device number to use for input. See list in appendix B. C. This function creates a menu bar on the top of the screen and returns an integer value representing the function chosen from the menu. The old screen information is not preserved. If the break key is pressed, the function will get it's input from the keyboard D. Changes Viewport, Pencolor, XCursor and Ycursor. Overwrites the contents of the top 11 rows of the screen. E. Menus 22.Outline A. Outline(Left,Right,Top,Bottom); B. Left : Integer value for the left side of the outline. Right : Integer value for the right side of the outline. Top : Integer value for the top of the outline. Bottom: Integer value for the bottom of the outline. C. This procedure draws a black box on the screen and fills the inside of the box with white. The box is drawn with thicker bottom and right sides which gives a shadowed effect. After the box is drawn, a smaller box is drawn at the top for a title box. D. Changes Viewport, PenColor, XCursor and YCursor. E. Menus 23.Paint A. Paint(X,Y,PaintColor,StopColor); B. X : X coordinate for the start of painting. Y : Y coordinate for the start of painting. PaintColor: The color to paint with. Cannot be Reverse. StopColor: The boundary color to stop filling at. C. This procedure paints the screen with PaintColor starting at X,Y and stopping at a boundary of StopColor. This procedure ignores the viewport boundaries, and will fill the entire screen if a boundary of StopColor is not present. The routine is neither smart nor fast, and repeated calls to the fill routine may be necessary to completely fill complex shapes. The routine cannot fill on a colored background using a border color of White1 or Black1 since the colored background would be seen as a series of White1 and Black1 stripes. D. Resets the pattern set by SetPattern. E. Paint 24.PenColor A. PenColor(Color); B. Color: Variable or constant of the type screencolor, as defined by: Type ScreenColor = (None,Reverse,Black,White,Blue,Red,Black1,White1); The type declaration for ScreenColor is in the interface section of the DEFT AGS package. A brief description of the colors follows: None - This causes all draws to be invisible. Used for moves between line segments. Reverse- This causes all drawing to be done by X-OR'ing the lines on the screen. Can be used to draw lines against complex backgrounds, reverse part of the screen, or for rubber band type lines for positioning. Black - Draws with a 2 dot wide black color. White - Draws with a 2 dot wide white color. Blue - Draws with a blue color, which is 2 PMODE 4 dots wide. Red - Draws with a red color. Black1 - Draws with a one dot wide black color. This color may show up as shades of grey or blue and red if drawn near vertical. White1 - Draws with a 1 dot wide color of white. C. This procedure sets the color to be used by the drawing commands. D. None E. LowLevel 25.Point A. Point(X,Y); B. X: X coordinate to plot point. Y: Y coordinate to plot point. C. This procedure plots a point on the screen. If the desired position is outside the current viewport, then the point will not be plotted. D. Sets XCursor and YCursor to X and Y. E. LowLevel 26.Print A. Print(X,Y,Print_String); B. X: X coordinate to start printing. Y: Y coordinate to start printing. Print_String: String to print on the screen. C. This procedure will print a string on the screen at the location specified. If the location is outside of the current viewport, then it will be mapped into the current viewport at the closest point. D. Sets XCursor and YCursor to the end of the string. E. Strings 27.ROMCall A. I:=ROMCall(A_Accumulator,Address); B. A_Accumulator: Integer value whose low byte is loaded into the A accumulator when the ROM routine is called. Address: Address of ROM routine to call. C. This function will call a routine in the RS Basic ROMs, passing to it the value in the A accumulator. The function sets up a 50 byte stack in the lower 32K of memory for use by the Basic ROMs, turns on the ROMs and JSRs to the subroutine. Upon return, the ROMs are turned off, the stack is restored to its original location, and the returned value in the A accumulator is placed on the stack. D. None E. LowLevel 28.ROMICall A. I:=ROMICall(A_Accumulator,Address); B. A_Accumulator: Integer value whose low byte is loaded into the A accumulator when the ROM routine is called. Address: Address containing address of ROM routine to call. C. This function will indirectly call a routine in the RS Basic ROMs, passing to it the value in the A accumulator. The function sets up a 50 byte stack in the lower 32K of memory for use by the Basic ROMs, turns on the ROMs and indirectly JSRs to the subroutine. Upon return, the ROMs are turned off, the stack is restored to its original location, and the returned value in the A accumulator is placed on the stack. D. None E. LowLevel 29.ScreenBit A. Set:=ScreenBit(X,Y); B. X: X coordinate to interogate on screen. Y: Y coordinate to interogate on screen. C. This function returns a boolean value indicating whether a dot is set on the screen. It does not return any kind of color information about the dot, only whether it is on or off. White1 is on and Black1 is off. Colors will give varying results, depending on the color and the x coordinate. D. None E. LowLevel 30.ScreenFill A. ScreenFill; B. None C. Fills the current viewport with the current Pencolor. If the viewport has X values of 0 and 255, the fill will be much faster. D. None E. LowLevel 31.ScrnRestore A. ScrnRestore; B. None C. This procedure restores the last area saved in the buffer. If no areas are in the buffer then the routine returns with no action. D. None E. Buffers 32.ScrnSave A. Ok:=ScrnSave(Left,Right,Top,Bottom); B. Left: Left edge of area to be saved. Right: Right edge of area to be saved. Top: Top edge of area to be saved. Bottom: Bottom edge of area to be saved. C. This function will save an area of the screen for later recall. The area is saved in the buffer above the graphics screen memory. Up to 10 areas or about 7K of data may be saved. If there is not enough buffer space left to save the area or illegal values are passed (left > right or top > bottom), the routine will return a value of false. If all goes well with the save the value of true is returned. D. None E. Buffers 33.SetChrUp A. SetChrUp(Char_Addr,Max_Chr); B. Char_Addr: Address for start of character font table. Max_Char : Maximum defined character code. C. This procedure sets up the character generator to use a font in memory. The Max_Char is the maximum defined character. If the character value is higher than this, it will first be reduced to the range of 0..127. If it is still higher a CHR(0) will be printed instead. See appendix A for information on the layout of the font files. D. None E. LowLevel 34.SetPattern A. SetPattern(P0,P1,P2,P3,P4,P5,P6,P7); B. P0..P7: Integers whose low byte contain the pattern to set. Example: Bit Number 76543210 P0 11111111 $FF P1 10000001 $7E P2 10111101 $42 P3 10111101 $42 P4 10111101 $42 P5 10111101 $42 P6 10000001 $7E P7 11111111 $FF This would set up a pattern of a black box on a white background. For each bit that is set, the corresponding dot on the screen is turned on. For each bit that is clear, the dot on the screen is off. C. This procedure sets up the pattern to use for subsequent fills. D. None E. Paint 35.Stick A. I:=Stick(Joystick_Number); B. Joystick_Number: Number of the joystick to read. C. This routine will return the value of the requested joystick. D. None E. LowLevel 36.StringWidth A. I:=StringWidth(Str); B. Str: String to find width of. C. This function will return the length of the passed string in screen dots. Since the character set is proportionally spaced, the length of a string on the screen is dependent on the character set in use. D. None E. Strings 37.SwapByte A. Swapbyte; B. None C. This procedure swaps the color masks used to create red and blue. Since which pattern will create red is not predictable, some of the time the patterns for red and blue would be reversed. This procedure allows the patterns to be swapped to correct this. D. None E. LowLevel 38.TextMode A. TextMode; B. None C. This procedure sets the VDG to normal text mode with the screen at $400 D. None E. LowLevel 39.ViewPort A. ViewPort(Left,Right,Top,Bottom); B. Left: Left side of active screen area desired. Right: Right side of active screen area desired. Top: Top edge of active screen area desired. Bottom: Bottom edge of active screen area desired. C. This procedure will set the active screen area. All lines drawn will be clipped at the viewport boundary, and the Screenfill command will only fill the area inside of the viewport. The text generating commands will map the character generated to within the viewport. The following procedures and functions do not heed the viewport, or they reset it: Menu MenuBar Box OutLine Paint Fill BackGround FillBkgd InitGraf GrafInit D. None E. LowLevel 40.WaitKey A. WaitKey(Device_Number,X,Y); B. Device_Number: input device to use. See list in appendix B. X,Y: x and y coordinates to print message at. C. This procedure will print the message 'Press device to continue' on the screen at location x,y and then wait for the button or key to be pressed. D. Changes X and Y cursor location. E. Menus 41.WChar A. WChar(Ch); B. Ch: Char type variable or constant to print to screen. C. This procedure will write a character on the screen, with the top left edge at the current cursor position. The cursor is moved to the right by the width of the character after printing. If the character will not fit on the current line it will be moved down by 8 dots and placed on the left side of the viewport. If the character would be past the end of the viewport, it is moved up to the bottom of the viewport. D. Changes the XCursor and possibly YCursor values to the end location of the character. E. Charactr 42.WString A. WString(Str); B. Str: String to be printed on the screen. C. This procedure will print a string on the Hi-Res screen, with the top of the left character at the current cursor position. The string will wrap around at the right edge if it is too long to fit in the current viewport D. Changes XCursor and YCursor to point at end of the string. E. Strings 43.XCursor A. I:=XCursor; B. None C. This function returns an integer value for the current X coordinate of the cursor. D. None E. LowLevel 44.YCursor A. I:=YCursor; B. None C. This function returns an integer value for the current X coordinate of the cursor. D. None E. LowLevel Appendix A - Character font file layout The character generator used in the DEFT AGS package is capable of using user defined character sets. The character set must be in a disk file formatted as follows: Record CharWidth: Char; (* 1 byte 0..8 value for character width*) CharMasks: Array[0..7] of Char (*8 1 byte values 0..255 for each mask *) End; The mask defines how to print each character on the screen. The mask for a letter A that is 6 dots wide would look like: bit 76543210 CharMasks[0] 100011XX =$8F Note X= Don't care CharMasks[1] 011101XX =$88 CharMasks[2] 011101XX =$88 CharMasks[3] 000001XX =$08 CharMasks[4] 011101XX =$88 CharMasks[5] 011101XX =$88 CharMasks[6] 011101XX =$88 CharMasks[7] 111111XX =$FF Note that the 6 dot width of the letter includes on row of dots on the right edge used for inter-letter spacing. If this is not present, the characters will run together when printing on the screen. Certain characters have special uses in the DEFT AGS package, and any re-defined character sets should not alter these in order to insure compatibility with the package. The special use characters are: Chr(0) - This character is defined to print a special shape, such as a hourglass or apple. It can be used for single character entries on a menubar. Chr(1) - This character is a checkmark, and is used by the Menu routine. Chr(32)- The space character. This character is used by the KeyIn function to overwrite other characters. For best results, it should be at least half as wide as the widest character in the file. Chr(127)-This character is used as the cursor character by the KeyIn function. The default system font file is called DEFTAGS/FNT. It is a proportionally spaced font, with each letter being 1-8 dots wide including a one dot inter-letter space to the right of the character. Appendix B - Device Numbers. The DEFT AGS system is able to use various input devices. The current defined device numbers and the associated device are listed below: Device Number Device -------------------------------------------------------------- 0 Keyboard. Arrow keys and Enter key are used. 1 HiRes Input Pack. Addressed at $FF90. 2 Digitizer pad. 3 Right joystick. 4 Left joystick. 5 Tandy HiRes Mouse (Version 1.6 only) Appendix C - Memory usage. The DEFT AGS system changes the way that DEFT Pascal uses memory. Normally the PASBOOT routines set the stack to the very top of memory. Since some protected memory was needed for the screen, character font and screen buffers, the PASBOOT file was modified so that the stack will start at $C000 on a 64K machine. The DEFT AGS package is not usable on a 32K or smaller machine. The memory map for the DEFT AGS system is as follows: $FDFF :-------------------------------------------: : Screen save buffer area. : $E100 :-------------------------------------------: : Character set masks. : $D800 :-------------------------------------------: : Graphics screen memory : $C000 :-------------------------------------------: : Stack and Heap area : Appendix D - Module interdependence. The DEFT AGS library is composed of eight modules, each containing one or more object routines. Some of the more complex routines use the other modules as building blocks, and as a result will result in the module being linked in even though none of the routines in that module were explicitly called by your program. The following chart is a list of all module inter-relations. Module Modules referenced -------------- ---------------------------- Menus Strings,Charactr,LowLevel,Buffers Strings Charactr,LowLevel Buffers LowLevel Charactr LowLevel Paint LowLevel Initlize LowLevel Circle LowLevel LowLevel None Appendix E - Public symbols. The following is a list of all public symbols in the DEFT AGS package, along with a description of each. All of the routines listed in the commands section are public, and they are not repeated here. Name Use --------- ------------------------------------ BIT1 1 bit screen masks BIT2VAL Mask used in draw routines CHRTBL 2 byte pointer to start of character font table CMODE 1 byte character print attributes COLRMSK Masks used for color generation CURSORX Current X cursor coordinate CURSORY Current Y cursor coordinate FTAB 2 bit paint masks GRASTRT 2 byte pointer to start of screen memory MAXCHR 1 byte, holds the # of the maximum character PMASK 8 byte current fill pattern XCLIP Routine that clips a signed integer in the D register to 0..255 XMAX 1 byte, holds maximum x coordinate in viewport XMIN 1 byte, holds minimum x coordinate in viewport YCLIP Routine that clips a signed integer in the D register to 0..191 YMAX 1 byte, holds maximum y coordinate in viewport YMIN 1 byte, holds minimum y coordinate in viewport These symbols are defined as PUBLIC in the DEFT AGS library. Use of these names in your program for other things will result in a linker error detecting the duplicate symbol. Appendix F - Clipping and DEFT AGS The DEFT AGS package uses the CoCo's PMODE 3 and 4 screens, giving a screen resolution of 0..255 for X and 0..191 for Y. If values outside of this range are passed to the package, they will be clipped to that range. All values passed are 16 bit signed integers, ranging in value from -32768 to 32767. If a value is less than zero, it will be changed to zero before use. If a X value is greater than 255, it will be changed to 255 before use. If a Y value is greater than 191, it will be changed to 191 before use. These changes are made independently of each other. The angle of any lines may be changed if clipping is needed. Example: If you ask for a line from 0,0 to 260,260, the result would be a line from 0,0 to 255,191. If you call the routines from an assembly language program, be sure to push correct 16 bit values for the parameters. If you use 8 bit values in your routine, be sure to push a zero high order byte when calling. The graphics routines look at all 16 bits when clipping.