Ultracube: Supercube Revisited
David N. Benson
Auburn, IN
This program is an expansion of a popular Atari, 3-D drawing program which first appeared in COMPUTE!, April, 1981, #11. Here, a number of new commands are added to the original (you don't need to have the earlier version to use this one). Type it in and create some beautiful screen displays.
If there is one area in which Atari computers shine above all others it is in the field of graphics. Star Raiders is a good example of this. Another good example of this is Steve Steinberg's Supercube (COMPUTE!, April'81, #11). For the newer readers who missed it, Supercube enabled the user to make three-dimensional drawings with the joystick. The following program, Ultracube, also enables the user to make three-dimensional drawings, but many new commands have been added and some minor improvements have been made along the way.
When the "new and improved" version is run, a menu appears explaining the commands that are uses in the program. Skip this as the commands, will be explained later. After the menu, the computer asks for a dimension for the cube. The larger the number the larger the cube. For now use a number between four and twelve. The computer then asks for the color of the cube. This is two numbers: the first is the hue and the second is the luminance. A table of hue values can be found on page fifty of the Atari Basic Reference Manual.
You are now ready to draw. A cursor of the color you chose will appear on the upper left of the screen and can be moved by the joystick. If you push the joystick button a cube will appear. Notice that if you let go of the button the cursor does not return to the upper left of the screen, or draw an erasing line as it does in Steve's program. However, when the cursor moves into a cube the cursor changes to the background color and back to the cube color when it leaves the cube. So unless there is very little contrast between the color of the cube and the color of the background, the cursor should always be seen.
All of this is fine and good, but eventually you will want to change cube size, colors, correct a mistake or see your creation full screen. If you want to change the size of the cube, type "R" and input the new dimension. To change the color of the cube hit the C and input the new hue and luminance values. Hitting the B will have the same effect on the background. If you wish to clear the screen, hit the W and all graphics shall be banished from the screen. The size and color of the cube will remain the same. If you just want to erase a portion or a mistake in your creation, move the cursor to the undesired part and hit E. The computer will ask you for the size of the eraser. The eraser is a square the size of the number inputted, that, when moved by the joystick, will obliterate all trace of anything that had the misfortune of being in its path. The square is the color of the background; it will not be seen. When finished with the eraser, hit any key and you may begin drawing again. All of this should bring many hours of pleasure. When you eventually finish drawing, hit Q and your masterpiece shall be displayed full-screen.
The magic of the commands is the OPEN statement in line 50 which opens the keyboard for input. The first number is the device code and may be any number from one to five. The next number tells what kind of operation is to be performed; here, the four means input. The third number is required but means absolutely nothing here. The fourth character which must be enclosed in quotation marks tells what is being opened; K means keyboard.
Working hand-in-hand with the OPEN statement is the GET statement in line 74. Whenever a key is hit its ATASCII number is stored in the variable at right. The device code at left may also be any number from one to five but it must be the same number used in the OPEN statement. The next line 75 checks to see if the key pressed is one of the command letters, in which case the computer goes to subroutine 2000.
There are three memory locations used in this program: 77, 752, and 764. The number stored in location 77 increases by one every four seconds a key is not pressed. Pressing a key will reset the value to 0, but if the value reaches 128 the computer goes into the random color switching that we all know and love. Location 72 monitors the status of the cursor: POKEing a one will turn the cursor off and a zero back on again. Location 764 monitors whether a key has been pressed; 255 means that no key has been pressed and anything else means that a key has been pressed.
Here is the line-by-line explanation:
8 Sets graphics mode to zero; sets the colors of both the foreground and the background to blue and turns off the cursor.
10-28 Prints menu; anything underlined should be in inverse video.
30 Waits for user to hit a key to continue.
40 Clears character so that it will not appear later.
50 Goes into graphics mode 7; opens keyboard for input.
55 Turns off cursor.
60 Asks user for cube size.
70 Asks user for cube color.
72 Clears screen (to create this character hit ESC and hold CTRL and push CLEAR).
73-75 Checks if user entered a command.
73 Checks if a key has been pressed.
74 The ATASCII value is stored in R.
75 Checks to see if R is one of the command letters; if so, then it goes to subroutine 2000 which processes the command.
80 Checks to see if the joystick button has not been pressed – in which case it goes first to see whether the cursor is in a space occupied by a cube or the background, and then to move the cursor; and second, to a subroutine that checks if the joystick has been moved, and which way.
110 Clears the screen.
120 Resets location 77 to zero. If this location ever reaches 128, the Atari goes into the random color switching (see text).
130 If the joystick button has been pressed, control passes into the cube drawing sequence.
140 Goes to a subroutine that figures out if the joystick has been moved, and which way.
150 Updates x-y coordinates.
200-210 Makes sure that the new x-y coordinates are not out of range.
400 Starts entire procedure over again.
500-520 This subroutine plots the cursor and sets the color of the cursor.
500 The LOCATE statement stores the contents of plot position X,Y in L. This will be a number from 1 to 4 equal to the color register. If this number is 0 or a 4, the cursor is in the background as opposed to being in a cube; the color of the cursor will be the color of the cube.
510 If the cursor is not in the background, then it is in a cube; the color of the cursor will be set to the color of the background.
520 This line plots the cursor on the screen.
600-630 This subroutine is called whenever the color of the cube is changed.
600 If the luminance is below 4, then it is set to 10. This is done so that the front face of the cube is always the darkest.
610 This line calls the subroutine that updates the color of the screen.
700-830 This subroutine draws the cube.
700 The TRAP statement will send control to line 80 if the cube goes off the screen.
710-740 These lines draw the first face of the cube.
750-780 These lines draw the second face of the cube.
790-830 These lines draw the third face of the cube.
1000-1180 This subroutine checks which way the joystick has been moved. For more information on the numbers returned by the joystick, see pages 59-60 in the Basic Reference Manual.
2000-2060 These lines process any commands that have been entered by the user.
2000 This line clears the text window.
2010 This line checks to see if the R has been pressed – in which case, the computer asks for the new cube size. The TRAP 2000 sends control back to line 2000 to start the whole procedure over again if the user enters illegal input, and the TRAP 40000 resets the TRAP statement.
2020 If the B has been pressed, the computer asks for the new hue and luminance values for the background color.
2030 If the C has been pressed, the computer asks for the new color of the cube.
2040 If the Q has been pressed, the computer goes into graphics mode 7 + 16 + 32. The 7 is self-explanatory, the 16 means full-screen (no text window), and the 32 keeps the screen from going blank. The next instruction, GOSUB 4100, resets the colors to the ones the user chose instead of the default colors. Line 3000 is an endless loop that prevents the computer from going into graphics 0 and wiping out all graphics.
2050 If the W has been pressed, the computer reenters graphics 7, which clears the screen at the same time, surpresses the cursor, and resets the colors.
2060 This is the eraser routine. After the user inputs the size of the eraser, the computer goes to subroutine 4000 which plots the eraser on the screen.
3000 See line 2040 for explanation.
4000-4040 This subroutine plots the eraser on the screen, moves it, and looks for the user to hit a key to disengage it.
4000 This line plots the eraser on the screen and goes to subroutine 1000 to see if the joystick has moved.
4010-4020 See lines 200-210 for explanation.
4030 If a key has not been pressed, the procedure is done over again.
4040 If a key has been pressed, it is then cleared along with the text window.
4100-4140 This subroutine updates the colors of the cube and background.
The Bug That Got Away
The variable E is used to represent two different things in Ultracube: the luminance value of the background, and the size of the eraser. So, if the user uses the eraser and then changes the color of the cube, the color of the background will change. The solution to this problem is to change the variable E to ERASER in lines 2060 and 4000. The author apologizes for this inconvenience.
The Cube, The Whole Cube, And Nothing But The Cube
For the most part, whenever the joystick button is pressed, a cube will appear. However, there are exceptions, such as when part of the cube runs off the screen and leaves only two faces completed, and the third to the viewer's imagination. This is due to the TRAP 80 in line 700 which sends control to line 80 if an error occurs. If the TRAP 80 statement was not there and an error occurred, the program would come to a grinding halt and a beautiful ERROR 3 (value error) or ERROR 141 (cursor out of range) would appear at the bottom of the screen. To see a full cube everytime, make the following changes:
Change 700 TRAP 745 Add 745 TRAP 790 Change 810 TRAP 820:PLOT X + SQ + I, Y - I : DRAWTO X + SQ + I, Y + SQ - I + 1 : TRAP 40000
I hope that you have enjoyed this program as much as I have enjoyed improving it. However, there were some things that I would have liked to have added but couldn't, because of lack of expertise. An eraser that can be seen would be nice and so would a machine language subroutine to help speed up the joystick. Any help that anyone could give would be appreciated.
8 GRAPHICS 0 : SETCOLOT 2, 8, 0 : SETCOLOR 4, 8, 0 : POKE 752,1 10 POSITION 10, 0 : PRINT "I ULTRA CUBE MEN U I" :POSITION 5, 3 : PRINT "I JOYSTICK I" : POSITON 7, 4 :PRINT "JOYSTICK:" 12 POSITION 17, 4: PRINT "USE TO MOVE CURS OR" :POSITION 7, 5 : PRINT "BUTTON :USE TO DRAW CUBE" : POSITION 5, 8 14 PRINT "|KEYBOARD|": POSITION 7, 9 :<B>PRINT "|BACKGROUND COLOR| INPUT HUE" :POSITION 11, 10 : PRINT "AND LUMINANCE" 16 POSITION 25, 10 : PRINT "TO CHANGE COL-" :POSITION 11, 11: PRINT "OR OF BACKGROUND" : POSITION 7, 12: PRINT "<C> |CUBE COLO|" 18 POSIION 20, 12 : PRINT "|R| INPUT HUE AND LU-" : POSITION 11, 13 : PRINT "MANINCE TO CHANGE CUBE COLOR" : POSITION 7,14 20 PRINT "<E> |ERASE| INPUT SIZE OF ERASER" : POSITION 11,15 : PRINT "TO ERASE UNDES IRED PORTIONS" : POSITION 7,16 22 PRINT "<R> |REDEFINE| INPUT NEW DIMENSION" :POSITION 11, 17 : PRINT "TO CHANCE SIZE OF CUBE" : POSITION 7,18 24 PRINT "<Q> |QUIT| WHEN PRESSED CREATION" : POSITION 11, 19 : PRINT "WILL BE SEEN FULL SCREEN" : POSTION 7, 20 26 PRINT "<W> |WIPE OUT| USE TO ERASE EN-" : POSITION 11,21 : PRINT "TIRE SOREEN" : POSITION 8, 23 : PRINT "HIT ANY KEY"; 28 POSITION 20, 23 : PRINT "TO CONTINUE" : POKE 764, 255 30 IF PEEK(764) = 255 THEN 30 40 POKE 764,255 50 GRAPHICS 7 : OPEN #1,4,0, "K" 55 POKE 752,1 60 LET R = 82 : GOSUB 2000 70 LET R = 67 : GOSUB 2000 72 PRINT "{CLEAR}" 73 IF PEEK (764) = 255 THEN 80 74 GET #1,R 75 IF R = 82 0R R = 66 OR R = 67 OR R = 81 OR = 87 OR R = 69 THEN GOSUB 2000 80 IF STRIG(0)<>0 THEN GOSUB 500 : GOTO 140 110 PRINT "{CLEAR}" 120 POKE 77, 0 130 IF STRIG(0) = 0 THEN GOSUB 700 140 GOSUB 1000 150 X = X + XDIF : Y = YDIF 200 LET X = X + (X(0) - (X)159) 210 LET Y = Y + (Y(0) - (Y)95) 400 GOTO 73 500 LOCATE X,Y,L : LET LI = L : IF L = 0 OR L = 4 THEN LET L = 1 : GOTO 520 510 LET L=4 520 COLOR L : PLOT X, Y FOR I =1 TO 5 : NEXT I : COLOR L1 : PLT X, Y : RETURN 600 IF B<4 THEN B = 10 610 GOSUB 4100 620 IF X<10 THEN 120 630 RETURN 700 TRAP 745 710 COLOR 1 720 FOR I = 0 TO SQ 730 PLOT X, Y + I : DRAWTO X + SQ, Y + I 740 NEXT I 745 TRAP 790759 COLOR 2 760 FOR I=1 TO INT(3*SQ)/5 770 PLOT X+I,Y-I:DRAWTO X+I+SQ,Y-I 780 NEXT I 790 COLOR 3 800 FOR I=1 TO INT(3*SQ)/5 810 TRAP 820: PLOT X+SQ+I,Y-I: DRAWTO X+SQ+I, Y+SQ-I+1: TRAP 40000 820 NEXT I 830 RETURN 1000 LET WHAT=STICK(0): XDIF=0: YDIF=0 1100 IF WHAT=15 THEN RETURN 1110 IF WHAT=14 THEN YDIF=-1:RETURN 1120 IF WHAT=13 THEM YDIF=1:RETURN 1130 IF WHAT=11 THEN XDIF=-1:RETURN 1140 IF WHAT=10 THEN XDIF=-1:YDIF=-1:RETURN 1150 IF WHAT=9 THEN YDIF=1:XDIF=-1:RETURN 1168 IF WHAT=7 THEN XDIF=1:RETURN 1170 IF WHAT=6 THEN YDIF=-1:XDIF=1:RETURN 1180 IF WHAT=5 THEN XDIF=1:YDIF=1:RETURN 2000 PRINT "{CLEAR}" :PRINT 2010 IF R=82 THEN PRINT "ENTER NEW DIMENSION FOR CUBE":TRAP 2000: INPUT SQ:TRAP 40000:RETURN 2020 IF R=66 THEN PRINT "INPUT BACKGOUND COLOR, LUM.";: TRAP 2000 : INPUT D,E: TRAP 40000: SETCOLOR 4, D, E : RETURN 2030 IF R=67 THEN PRINT "INPUT NEW COLOR FOR CUBE ";: TRAP 2090= INPUT A, B : TRAP 400 : GOSUB 600: RETURN 2040 IF R=81 THEN GRAPHICS 7+16+32: GOSUB 4100: GOTO 3000 2050 IF R=87 THEN GRAPHICS 7:POKE 752,1: GOSUB 4100: RETURN 2060 IF R=69 THEN PRINT "INPUT SIZE OF ERASE",:TRAP 2000=INPUT ER:TRAP 40000:P0KE 764, 255 : GOSUB 4000:RETURN 3000 GOTO 3000 4000 COLOR 4:FOR P=0 TO ER-1:FOR P1=0 TO ER-1 :PLOT X+P, Y+P1 : NEXT P1 : NEXT P : GOSUB 1000 4010 LET X=X+XDIF:LET X=X+(X<0)-(X>159) 4020 LET Y=Y+YDIF: LET Y=Y+(Y<0)-(Y>80) 4030 IF PEEK(764)=255 THEN GOTO 4000 4040 POKE 764,255=PRINT "{CLEAR}":RETURN 4100 SETCOLOR 1, A, B 4110 SETCOLOR 2, A, B-2 4120 SETCOLOR 8, H, B-4 4130 SETCOLOR 4, D, E 4140 RETURN