Viewports in IBM BASIC (COMPUTE! Magazine July 1985 by John Kearney) Lots of power is hidden within the depths of IBM BASIC. So many statements, commands and functions are tucked away that it's difficult to assimilate them all without studying the manual from cover to cover. One of these is the VIEW statement. It lets you segment or define an almost unlimited number of rectangular sections on the screen. Each viewport, as it is called, becomes a separate window with its own graphics and text, like a smaller screen pasted over the main screen. Viewports can exist independently of each other and can be of any size within the dimensions of the screen. Some can even be invisible. What makes viewports truly amazing is the way they handle graphics. To see for yourself the versatility of viewports, try running the programs below. By examining these programs and comparing them with the results, you'll see how easy it is to use the VIEW statement. With VIEW, you can locate a viewport anywhere on the screen, adjust the size of the viewport, fill the viewport with color, and assign a color to the surrounding border lines. The basic format of the VIEW statement is: VIEW [[SCREEN] [(x1,y1)-(x2,y2) [,[attribute] [,[boundary]]]] ] The first step before using VIEW is to declare the screen mode. VIEW works only in the graphics modes, SCREEN 1 or SCREEN 2. SCREEN 0 is a text mode and can't be used with VIEW. At first glance, you may think the SCREEN parameter in the VIEW statement lets you specify the screen mode, but it doesn't. Actually, this parameter determines how other graphics statements affect the viewports and main screen background. After declaring the screen mode with a separate SCREEN statement, you define the size of the viewport by specifying two sets of screen coordinates. The coordinates, naturally, correspond to the resolution available in the graphics mode you selected. For example, SCREEN 1 has 320 horizontal pixels by 200 vertical pixels, so the viewport must fit within this range: SCREEN 1 320 x 200 4-color mode SCREEN 2 640 x 200 2-color mode Remember that screen coordinates are numbered beginning with 0, so the actual range of coordinates in SCREEN 1 would be 0 to 319 horizontally and 0 to 199 vertically. The first set of coordinates (x1,y1) defines the position of the viewport's upper-left corner; x1 is the horizontal coordinate and y1 is the vertical coordinate. The second set of coordinates (x2,y2) defines the lower-right corner. If you want a very large viewport in SCREEN 1, you might specify: VIEW (4,1)-(300,100). If you want a very small viewport, you could specify: VIEW (4,1)-(10,12). If you actually enter these statements, you won't see anything happen. The viewport is there, but it's invisible. To make it appear, you have to set the viewport apart from the main screen background by filling it with color or surrounding it with a colored border. That's the purpose of the last two parameters of the VIEW statement. The attribute parameter lets you fill the viewport with the color assigned to that attribute number. The boundary parameter lets you draw a border around the viewport with the color assigned to the attribute number. Attribute numbers can range from 0 to 15, but of course this depends on the number of colors available in the screen mode you choose. For instance, SCREEN 1 is a four-color mode (see above), so it has four attributes numbered 0 to 3. SCREEN 2 is a two-color mode. The colors assigned to attributes are: 0 black 4 red 8 gray 12 light red 1 blue 5 magenta 9 light blue 13 light magenta 2 green 6 brown 10 light green 14 yellow 3 cyan 7 white 11 light cyan 15 bright white Keep in mind that you can assign any color to any attribute number with the PALETTE and PALETTE USING statements. For example: VIEW (4,1)-(300,100) Attribute parameter is omitted, so viewport defaults to same color as screen, rendering viewport invisible VIEW (4,1)-(300,100),4,14 Red viewport with yellow border VIEW (4,1)-(300,100),5,7 Magenta viewport with white border Once a viewport is defined and activated, the coordinates inside the viewport are no longer the same as the main screen coordinates. After you've created a viewport, you can print text or draw graphics inside it. Since the viewport is smaller than the main screen, however, a full-size graphics figure may not fit within its boundaries. You have to scale down the size of the figure to avoid what's called a clipping effect (the parts of the figure which don't fit are cut off, or clipped, within the viewport). Ordinarily, this scaling requires manual calculations. But another IBM BASIC statement -- WINDOW -- can help scale the graphics automatically. With WINDOW, each viewport acts as a microcosm of the main screen, so the computer automatically fits the graphics into the viewport. This scaling effect is demonstrated in the programs below. For example, Program 1 uses identical graphics subroutines for each viewport, even though the viewports are different sizes. For scaling purposes with viewports, you can simply insert this WINDOW statement prior to the VIEW statement: WINDOW SCREEN (x1,y1)-(x2,y2) where x1,y1 are the upper-left corner coordinates of the graphics mode (0,0), and x2,y2 are the lower-right corner coordinates (for instance, 319,199 in SCREEN 1). When you set up a viewport, the coordinates within its boundaries no longer correspond to the coordinates of the main screen. Instead, the coordinates for the upper-left corner or any viewport are (0,0), no matter where the viewport is located. There may be times when you don't want the automatic-scaling feature. You can defeat it simply by leaving out the WINDOW statement. You can also experiment with another variation of the VIEW statement by including the SCREEN parameter mentioned earlier. When SCREEN is included, all viewport coordinates coincide with the main screen coordinates. That is, the upper-left corner coordinates correspond to the main screen coordinates at that point, rather than 0,0. Points plotted outside the viewport boundaries won't appear on the screen. Like other screen statements, the CLS statement works in an interesting way with VIEW. When your program is executing, the viewport most recently defined is your current and only active viewport. All other viewports are inactive, as is the main screen. As a result, CLS clears only the area inside the active viewport. This may lead to some fascinating graphics effects. If your program no longer requires viewports, changing screen modes with the SCREEN statement removes them. Likewise, a VIEW statement without any parameters followed by CLS defines the entire screen as a viewport and clears it, accomplishing basically the same thing. Most of the BASIC graphics statements work with viewports, but there are a few exceptions. Some statements don't automatically scale themselves to fit within the viewport's boundaries. Those what work include GET, PAINT, PRESET, PUT, PSET, POINT, LINE, VIEW, and WINDOW. Statements that deserve more attention are CIRCLE (the size of the circle does not automatically scale or change shape if different viewports are the same width); and DRAW, LOCATE, and PRINT, which aren't restricted to the area of an active viewport. Some of these effects are demonstrated by Program 2. It starts by executing a subroutine that draws a series of concentric circles without any viewports. Next it defines five viewports with borders and clears them with CLS. At this point, only the final viewport is active and capable of accepting graphics commands. Then the program repeats the same subroutine that draws the circles, showing that only parts of the circles appear in the active viewport. Immediately afterward, the program executes a WINDOW statement and defines a very small invisible viewport at the center of the screen. Then it repeats the circles subroutine again, showing how the circles are scaled down to the size of the single invisible viewport. Program 1: Automatic Viewport Scaling 10 'Initialize 30 CLS:KEY OFF 40 SCREEN 1 50 COLOR 0,1 60 WINDOW SCREEN (0,0)-(319,199) 70 L$="BAR CHART VIEW COMPARISON" 80 GOSUB 340 90 LOCATE 22,3:PRINT "Using same input data and subroutine" 100 ' 110 VIEW (20,60)-(80,150),,3 120 GOSUB 230 130 VIEW (90,20)-(120,150),,3 140 RESTORE 380 150 GOSUB 230 160 VIEW (130,80)-(299,150),,3 170 RESTORE 380 180 GOSUB 230 190 GOTO 190 200 ' 210 'Graphics subroutine 220 ' 230 READ N 240 DX=1/N:DDX=.75*DX*319:Y=199 250 FOR I=0 TO N-1 260 X=DX*I*319 270 READ D:D=D/1.25 280 LINE (X,Y)-(X+DDX,Y-D),2,BF 290 NEXT I 300 RETURN 310 ' 320 'Center titles 330 ' 340 LOCATE 1,(40-LEN(L$))/2 350 PRINT L$ 360 RETURN 370 ' 380 DATA 24 390 DATA 3.9,5.3,7.2,9.6 400 DATA 12.9,17.0,33.2,31.4 410 DATA 39.8,50.2,62.9,76.0 420 DATA 92,0,105.7,102.8,101.7 430 DATA 122.7,134.3,183.2,211.0 440 DATA 212.7,217.3,223.2,231.0 Program 2: Viewport Variations 10 'Initiatlize 20 ' 30 CLS:SCREEN 1:KEY OFF 40 GOSUB 330 50 ' 60 'Viewport coordinates 70 ' 80 A1=8:A2=8:A3=52:A4=52 90 B1=64:B2=8:B3=112:B4=112 100 C1=8:C2=66:C3=52:C4=180 110 D1=124:D2=8:D3=150:D4=180 120 E1=64:E2=124:E3=112:E4=180 130 F1=140:F2=80:F3=180:F4=120 140 ' 150 'Define viewports 160 ' 170 VIEW (A1,A2)-(A3,A4),,2:CLS 180 VIEW (B1,B2)-(B3,B4),,1:CLS 190 VIEW (C1,C2)-(C3,C4),,2:CLS 200 VIEW (D1,D2)-(D3,D4),,1:CLS 210 VIEW (E1,E2)-(E3,E4),,2:CLS 220 ' 230 VIEW SCREEN (B1,B2)-(B3,B4) 240 GOSUB 330 250 ' 260 WINDOW SCREEN (0,0)-(319-199) 270 VIEW (F1,F2)-(F3,F4) 280 GOSUB 330 290 GOTO 290 300 ' 310 'Circle subroutine 320 ' 330 FOR X=1 TO 100 STEP 4 340 CIRCLE (160,100),X+60,3 350 NEXT X 360 RETURN