orion1052003 Posted October 21, 2011 Share Posted October 21, 2011 (edited) Since I am both not understanding and misunderstanding Subprograms, I thought I would run some tests to find out what passing a variable is and how it works. (In the program I've been writing the variables never pass, and I'm not even sure when they need to be passed or left alone) Probably another 10 tests to do after this, but here's something. In some of the looped RUNS of the subprogram testing program I only wrote down the first results, because the other results were expected, and I took screenshots of all 10 runs. Just lazy to write all that down. These tests may seem silly, or not even make sense, but it is just an attempt to understand. RUN 1 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 70 DISPLAY AT(6,12):"CALLING SUBPROGRAM..." 80 CALL TEST 85 GOTO 85 90 SUB TEST 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 SUBPROGRAM= X=0 Y= 0 Z=0 X+Y=0 RUN 2 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 70 DISPLAY AT(6,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 85 GOTO 85 90 SUB TEST(X,Y) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 SUBPROGRAM= X=3 Y= 2 Z=5 X+Y=5 RUN 3 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 70 DISPLAY AT(6,12):"CALLING SUBPROGRAM..." 80 CALL TEST(A,B) 85 GOTO 85 90 SUB TEST(A,B) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 SUBPROGRAM= X=0 Y= 0 Z=0 X+Y=0 RUN 4 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 70 DISPLAY AT(6,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 85 GOTO 85 90 SUB TEST(A,B) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RUN 5 & 6 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 25 FOR I=1 TO 3 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 70 DISPLAY AT(6,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 83 X=4 :: Y=6 84 DISPLAY AT(23,1):"PRESS A LETTER" 85 ACCEPT AT(24,1):L$ 86 NEXT I 90 SUB TEST(X,Y) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND 5 RESULTS- MAIN= X=3 Y=2 SUBPROGRAM= X=3 Y= 2 Z=5 X+Y=5 6 RESULTS- MAIN= X=4 Y=6 SUBPROGRAM= X=4 Y= 6 Z=10 X+Y=10 RUN 7 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 25 FOR I=1 TO 3 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 65 DISPLAY AT(5,12):"X+Y= ";Z 70 DISPLAY AT(9,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 83 X=4 :: Y=6 84 DISPLAY AT(23,1):"PRESS A LETTER" 85 ACCEPT AT(24,1):L$ 86 NEXT I 90 SUB TEST(X,Y) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 X+Y=0 SUBPROGRAM= X=3 Y= 2 Z=5 X+Y=5 RUN 8 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 :: Z=0 25 FOR I=1 TO 3 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 65 DISPLAY AT(5,12):"X+Y= ";Z 70 DISPLAY AT(9,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 83 X=4 :: Y=6 84 DISPLAY AT(23,1):"PRESS A LETTER" 85 ACCEPT AT(24,1):L$ 86 NEXT I 90 SUB TEST(X,Y) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 X+Y=0 SUBPROGRAM= X=3 Y= 2 Z=5 X+Y=5 RUN 9 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 :: Z=0 25 FOR I=1 TO 3 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 63 Z=X+Y 65 DISPLAY AT(5,12):"X+Y= ";Z 70 DISPLAY AT(9,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 83 X=4 :: Y=6 84 DISPLAY AT(23,1):"PRESS A LETTER" 85 ACCEPT AT(24,1):L$ 86 NEXT I 90 SUB TEST(X,Y) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 X+Y=5 SUBPROGRAM= X=3 Y= 2 Z=5 X+Y=5 RUN 10 10 !SUBTEST 20 X=3 :: Y=2 :: A=4 :: B=5 :: Z=0 25 FOR I=1 TO 3 30 CALL SCREEN(4) :: CALL CLEAR 40 DISPLAY AT(2,:"MAIN PROGRAM" 50 DISPLAY AT(3,:"------------" 60 DISPLAY AT(4,12):"X= ";X;"Y= ";Y 63 Z=X+Y+1 65 DISPLAY AT(5,12):"X+Y= ";Z 70 DISPLAY AT(9,12):"CALLING SUBPROGRAM..." 80 CALL TEST(X,Y) 83 X=4 :: Y=6 84 DISPLAY AT(23,1):"PRESS A LETTER" 85 ACCEPT AT(24,1):L$ 86 NEXT I 90 SUB TEST(X,Y) 100 Z=X+Y 110 DISPLAY AT(15,:"SUBPROGRAM" 120 DISPLAY AT(16,:"----------" 130 DISPLAY AT(17,12):"X= ";X;"Y= ";Y 140 DISPLAY AT(19,12):"Z= ";Z 150 DISPLAY AT(21,12):"X+Y= ";Z 160 SUBEND RESULTS- MAIN= X=3 Y=2 X+Y=6 SUBPROGRAM= X=3 Y= 2 Z=5 X+Y=5 Edited October 21, 2011 by orion1052003 Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted October 21, 2011 Share Posted October 21, 2011 Nice. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 21, 2011 Share Posted October 21, 2011 Since I am both not understanding and misunderstanding Subprograms, I thought I would run some tests to find out what passing a variable is and how it works. (In the program I've been writing the variables never pass, and I'm not even sure when they need to be passed or left alone) Probably another 10 tests to do after this, but here's something. In some of the looped RUNS of the subprogram testing program I only wrote down the first results, because the other results were expected, and I took screenshots of all 10 runs. Just lazy to write all that down. These tests may seem silly, or not even make sense, but it is just an attempt to understand. That is certainly a good way to learn. The major detail to remember with subprograms in TI Extended Basic is that variables are local, i.e., the names of variables have meaning only within program units. Naming a variable "X" in a subprogram does not give it access to a variable named "X" in the main program and, of course, vice versa. The only way to do that is to pass the variables by name in a parameter list, as you discovered in your tests. They do not need to have the same name. In fact, that is part of the confusion. You can use the same names; but, that can visually imply they are the same and lead to confusion. I did not peruse your tests enough to see whether you already did this; but, a good way to demonstrate this is to change the order of variables with the same name in your parameter lists as follows: 100 CALL CLEAR 110 X=10::Y=20 120 PRINT "BEFORE SUB CALL--" 130 PRINT " X,Y: ";X,Y 140 CALL JUNK(X,Y) 150 PRINT "AFTER SUB CALL--" 160 PRINT " X,Y: ";X,Y 170 SUB JUNK(Y,X) 180 X=3::Y=300 190 SUBEND You will find after the call to JUNK that X = 300 and Y = 3 because what matters is the order in the parameter list, not the names of the variables. X is first in CALL JUNK(X,Y); but, the first variable in SUB JUNK(Y,X) is JUNK's Y (not the same variable as the main program's Y), i.e., JUNK's Y references the main program's X. This is hard to swallow because the same variable names are in use. It may be a little easier to take if you change the subprogram's variable names to A and B: 100 CALL CLEAR 110 X=10::Y=20 120 PRINT "BEFORE SUB CALL--" 130 PRINT " X,Y: ";X,Y 140 CALL JUNK(X,Y) 150 PRINT "AFTER SUB CALL--" 160 PRINT " X,Y: ";X,Y 170 SUB JUNK(B,A) 180 A=3::B=300 190 SUBEND You will get exactly the same output. What you are telling SUB JUNK(B,A) in CALL JUNK(X,Y) is to do to X what it does to B and to do to Y what it does to A simply by the order of the variables in the parameter list. ...lee Quote Link to comment Share on other sites More sharing options...
unhuman Posted October 21, 2011 Share Posted October 21, 2011 I never use sub programs.. Someone sometimes said they were slower and I believed them. Quote Link to comment Share on other sites More sharing options...
orion1052003 Posted October 24, 2011 Author Share Posted October 24, 2011 This is a Joystick tester program and a test to see if SUBPROGRAMS will work with it. The CALL COINC works, but the "meteor" will appear over and over in the loop. Which seems to mean you can't use subprograms to call adversaries for the game player. It is at magnification one, so the meteor resembles a small piece of hair. 100 !TEST PROGRAM-USE CALL LOCATE WITH JOYST 110 P1=15 :: P2=10 120 CALL CLEAR :: CALL SCREEN(6) 130 A$=RPT$("F",16) :: CALL CHAR(96,A$) 140 CALL SPRITE(#1,96,2,89,121)!JOYST DOT 143 S$=RPT$("F",16) :: CALL CHAR(104,S$) 145 CALL SPRITE(#2,104,16,57,223)!STATIONARY DOT 150 DR=100 :: DC=100 160 CALL HCHAR(1,16,104)!UP 170 CALL HCHAR(24,16,112)!DOWN 180 CALL HCHAR(12,3,120)!LEFT 190 CALL HCHAR(12,30,128)!RIGHT 192 M$="00000000000F10204980A0829041221C0000000000C020A02020204080000000"!METEOR 193 CALL CHAR(128,M$) :: MDR=193 :: MDC=1 195 CALL SPRITE(#3,128,16,MDR,MDC)!METEOR 1,169,20,-20 200 CALL JOYST(1,X,Y) 210 CALL COLOR(10,P1,P1,11,P1,P1,12,P1,P1,13,P1,P1) 220 R=R-Y/4 :: C=C+X/4 230 DR=DR-Y*4 :: DC=DC+X*4 260 CALL LOCATE(#1,DR,DC) 270 CALL KEY(1,K,S) 280 DISPLAY AT(16,1):"SAME KEY=0 NEW KEY=1 NO KEY PRESS=-1" 290 DISPLAY AT(18,5):"KEY= ";K;"STATUS= ";S 300 DISPLAY AT(20,1):"X= ";X;"Y= ";Y 310 DISPLAY AT(21,1):"R= ";R;"C= ";C 320 DISPLAY AT(22,1):"DR= ";DR;"DC= ";DC 330 IF Y=4 AND X=0 THEN CALL COLOR(10,P2,P2) 340 IF Y=0 AND X=4 THEN CALL COLOR(13,P2,P2) 350 IF Y=-4 AND X=0 THEN CALL COLOR(11,P2,P2) 360 IF Y=0 AND X=-4 THEN CALL COLOR(12,P2,P2) 365 CALL COINC(#1,#2,10,C) :: IF C THEN CALL SOUND(300,-2,10) 368 DISPLAY AT(14,12):"C= ";C 369 CALL METEOR(MDR,MDC) 370 GOTO 200 1071 SUB METEOR(DR,DC) 1072 DR=1 :: DC=169 1075 CALL COINC(#1,#3,10,CO) :: IF CO THEN CALL SOUND(300,-2,10) :: CALL DELSPRITE(#3) 1078 !HOWLONGSHOULDMETEORLAST? 1079 SUBEND Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 24, 2011 Share Posted October 24, 2011 Subprograms should work just fine to do your bidding. I am not sure what you are trying to do with the subprogram. First, statement 193 does not reflect the comment, i.e., no motion. Statement 1072 sets the meteor sprite's coordinates, but does nothing with them. Since sprite #3 (meteor) has no motion and is sitting at row 193 and column 1 (essentially off-screen at the bottom left), the IF in statement 1075 will never be TRUE unless sprite #1 is moved to that location. ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 24, 2011 Share Posted October 24, 2011 I never use sub programs.. Someone sometimes said they were slower and I believed them. That may be true, but your code can be MUCH clearer and easier to read with them. Mark Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 24, 2011 Share Posted October 24, 2011 Here's a nice sprite designer program that I wrote back in about 2006 I think. It uses sub-programs heavily, as a result I think the code itself is quite easy to read. 40 DATA 120,124,128,132,136,140 50 CALL CLEAR :: CALL MAGNIFY(4):: CALL SCREEN(2):: FOR I=1 TO 14 :: CALL COLOR(I,15,1):: NEXT I :: CALL COLOR(4,5,1) 60 CALL CHAR(92,"F8F0F0F89C0E0703000000000000000000000000000000000000000000000000") 70 A$="AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55" 80 CALL CHAR(88,"08080006C6191B061D336142444A3400003C6282848A54E05CFC60DED8561400") 90 RESTORE 40 :: FOR I=1 TO 6 :: READ A :: CALL CHAR(A,A$):: NEXT I 100 CALL CHARPAT(ASC(":"),A$):: CALL CHAR(ASC("@"),A$) 110 CALL SPRITE(#2,120,15,16,156):: CALL SPRITE(#3,124,15,16,204) 120 CALL SPRITE(#4,128,15,60,156):: CALL SPRITE(#5,132,15,60,204):: CALL SPRITE(#6,136,15,104,156):: CALL SPRITE(#7,140,15,104,204) 130 CALL CHAR(60,"0000001818000000"):: CALL CHAR(62,"FEFEFEFEFEFEFE00") 140 CX=1 :: CY=2 :: OPTION BASE 1 :: DIM C$(16,4),C(16,4):: SZ=1 150 CALL INIT(C$(,),C(,)) 160 CALL HELP 170 CALL SPRITE(#1,92,4,(CY*-4,(CX*+14) 180 CALL KEY(0,K,S):: IF K=-1 THEN 180 190 IF K=101 THEN CY=CY-1 :: IF CY<2 THEN CY=17 ELSE GOTO 170 200 IF K=120 THEN CY=CY+1 :: IF CY>17 THEN CY=2 ELSE GOTO 170 210 IF K=115 THEN CX=CX-1 :: IF CX<1 THEN CX=16 ELSE GOTO 170 220 IF K=100 THEN CX=CX+1 :: IF CX>16 THEN CX=1 ELSE GOTO 170 230 IF K=48 THEN CALL POINT(CY-1,CX,C$(,),C(,)) 240 IF K=73 THEN CALL INVERT(C$(,),C(,)) 250 IF K=68 THEN CALL DOWN(C$(,),C(,)) 260 IF K=85 THEN CALL UP(C$(,),C(,)) 270 IF K=76 THEN CALL LEFT(C$(,),C(,)) 280 IF K=50 THEN SZ=SZ XOR 1 :: CALL MAGNIFY(3+SZ) 290 IF K=82 THEN CALL RIGHT(C$(,),C(,)) 300 IF K=72 THEN CALL HFLIP(C$(,),C(,)) 310 IF K=86 THEN CALL VFLIP(C$(,),C(,)) 320 IF K=78 THEN CALL SCRATCH(C$(,),C(,)) 330 IF K=65 THEN CALL ASSIGN(C$(,),C(,)) 340 IF K=71 THEN CALL LOADGRID(C$(,),C(,)) 350 IF K=70 THEN CALL FILEMENU(C$(,),C(,)) 360 IF K=74 THEN CALL LFSPRITE(C$(,),C(,)) 370 IF K=87 THEN CALL ANIMATE(C$(,),C(,)) 380 GOTO 170 390 ! ############# 400 SUB INIT(C$(,),C(,)) 410 CALL BUSY :: DISPLAY AT(1,1):"Sprite designer v1.2 M.Wills" 420 CALL NEW(C$(,),C(,)):: CALL DONE 430 SUBEND 440 ! ############# 450 SUB NEW(C$(,),C(,)):: CALL BUSY 460 FOR Y=1 TO 16 :: FOR X=1 TO 4 :: C$(Y,X)="<<<<" :: C(Y,X)=0 :: NEXT X :: NEXT Y 470 CALL DRAWGRID(C$(,),C(,)):: CALL DONE 480 SUBEND 490 ! ############# 500 SUB DRAWGRID(C$(,),C(,)):: CALL BUSY 510 FOR Y=1 TO 16 :: XX=1 :: FOR X=1 TO 4 :: DISPLAY AT(Y+1,XX)SIZE(4):C$(Y,X):: XX=XX+4 :: NEXT X :: NEXT Y :: CALL DONE 520 SUBEND 530 ! ############# 540 SUB POINT(Y,X,C$(,),C(,)) 550 S=INT((X-1)/4)+1 :: P=3-(X-1)AND 3 :: C(Y,S)=C(Y,S)XOR 2^P 560 CALL GETNYBBLE(C(Y,S),N$):: DISPLAY AT(Y+1,((S-1)*4)+1)SIZE(4):N$:: C$(Y,S)=N$ 570 SUBEND 580 ! ############# 590 SUB GETNYBBLE(V,N$) 600 IF V=0 THEN GOSUB 620 ELSE ON V GOSUB 630,640,650,660,670,680,690,700,710,720,730,740,750,760,770 610 SUBEXIT 620 N$="<<<<" :: RETURN 630 N$="<<<>" :: RETURN 640 N$="<<><" :: RETURN 650 N$="<<>>" :: RETURN 660 N$="<><<" :: RETURN 670 N$="<><>" :: RETURN 680 N$="<>><" :: RETURN 690 N$="<>>>" :: RETURN 700 N$="><<<" :: RETURN 710 N$="><<>" :: RETURN 720 N$="><><" :: RETURN 730 N$="><>>" :: RETURN 740 N$=">><<" :: RETURN 750 N$=">><>" :: RETURN 760 N$=">>><" :: RETURN 770 N$=">>>>" :: RETURN 780 SUBEND 790 ! ################ 800 SUB INVERT(C$(,),C(,)):: CALL BUSY 810 FOR Y=1 TO 16 :: FOR X=1 TO 4 :: C(Y,X)=15-C(Y,X):: CALL GETNYBBLE(C(Y,X),N$):: C$(Y,X)=N$ :: NEXT X :: NEXT Y :: CALL DRAWGRID(C$(,),C(,)):: CALL DONE 820 SUBEND 830 ! ############## 840 SUB DOWN(C$(,),C(,)) 850 DIM T$(1,4),T(1,4) 860 CALL BUSY :: FOR X=1 TO 4 :: T$(1,X)=C$(16,X):: T(1,X)=C(16,X):: NEXT X 870 FOR Y=16 TO 2 STEP -1 :: FOR X=1 TO 4 :: C$(Y,X)=C$(Y-1,X):: C(Y,X)=C(Y-1,X):: NEXT X :: NEXT Y 880 FOR X=1 TO 4 :: C$(1,X)=T$(1,X):: C(1,X)=T(1,X):: NEXT X :: CALL DRAWGRID(C$(,),C(,)):: CALL DONE 890 SUBEND 900 ! ############# 910 SUB UP(C$(,),C(,)) 920 DIM T$(1,4),T(1,4) 930 CALL BUSY :: FOR X=1 TO 4 :: T$(1,X)=C$(1,X):: T(1,X)=C(1,X):: NEXT X 940 FOR Y=2 TO 16 :: FOR X=1 TO 4 :: C$(Y-1,X)=C$(Y,X):: C(Y-1,X)=C(Y,X):: NEXT X :: NEXT Y 950 FOR X=1 TO 4 :: C$(16,X)=T$(1,X):: C(16,X)=T(1,X):: NEXT X :: CALL DRAWGRID(C$(,),C(,)):: CALL DONE 960 SUBEND 970 ! ############## 980 SUB LEFT(C$(,),C(,)) 990 CALL BUSY 1000 FOR Y=1 TO 16 :: T4=C(Y,4)*2 :: IF T4>15 THEN C4=1 ELSE C4=0 1010 T3=C(Y,3)*2 :: IF T3>15 THEN C3=1 ELSE C3=0 1020 T2=C(Y,2)*2 :: IF T2>15 THEN C2=1 ELSE C2=0 1030 T1=C(Y,1)*2 :: IF T1>15 THEN C1=1 ELSE C1=0 1040 T4=T4 AND 15 :: T3=T3 AND 15 :: T2=T2 AND 15 :: T1=T1 AND 15 1050 C(Y,1)=T1 OR C2 :: C(Y,2)=T2 OR C3 :: C(Y,3)=T3 OR C4 :: C(Y,4)=T4 OR C1 1060 CALL GETNYBBLE(C(Y,1),N$):: C$(Y,1)=N$ :: CALL GETNYBBLE(C(Y,2),N$):: C$(Y,2)=N$ :: CALL GETNYBBLE(C(Y,3),N$):: C$(Y,3)=N$ 1070 CALL GETNYBBLE(C(Y,4),N$):: C$(Y,4)=N$ :: NEXT Y 1080 CALL DRAWGRID(C$(,),C(,)):: CALL DONE 1090 SUBEND 1100 ! ############ 1110 SUB RIGHT(C$(,),C(,)):: CALL BUSY 1120 FOR Y=1 TO 16 :: C1=(C(Y,1)AND 1)*8 :: C2=(C(Y,2)AND 1)*8 :: C3=(C(Y,3)AND 1)*8 :: C4=(C(Y,4)AND 1)*8 1130 T1=INT(C(Y,1)/2):: T2=INT(C(Y,2)/2):: T3=INT(C(Y,3)/2):: T4=INT(C(Y,4)/2) 1140 C(Y,1)=T1 OR C4 :: C(Y,2)=T2 OR C1 :: C(Y,3)=T3 OR C2 :: C(Y,4)=T4 OR C3 1150 CALL GETNYBBLE(C(Y,1),N$):: C$(Y,1)=N$ :: CALL GETNYBBLE(C(Y,2),N$):: C$(Y,2)=N$ :: CALL GETNYBBLE(C(Y,3),N$):: C$(Y,3)=N$ 1160 CALL GETNYBBLE(C(Y,4),N$):: C$(Y,4)=N$ :: NEXT Y 1170 CALL DRAWGRID(C$(,),C(,)):: CALL DONE 1180 SUBEND 1190 ! ############## 1200 SUB HFLIP(C$(,),C(,)):: CALL BUSY 1210 DIM T$(16,4),T(16,4):: FOR Y=1 TO 16 :: XX=4 :: FOR X=1 TO 4 1220 IF C(Y,X)=0 THEN T(Y,XX)=0 ELSE ON C(Y,X)GOSUB 1260,1270,1280,1290,1300,1310,1320,1330,1340,1350,1360,1370,1380,1390,1400 1230 XX=XX-1 :: NEXT X :: NEXT Y 1240 FOR Y=1 TO 16 :: FOR X=1 TO 4 :: C(Y,X)=T(Y,X):: CALL GETNYBBLE(C(Y,X),N$):: C$(Y,X)=N$ :: NEXT X :: NEXT Y :: CALL DRAWGRID(C$(,),C(,)) 1250 SUBEXIT 1260 T(Y,XX)=8 :: RETURN 1270 T(Y,XX)=4 :: RETURN 1280 T(Y,XX)=12 :: RETURN 1290 T(Y,XX)=2 :: RETURN 1300 T(Y,XX)=10 :: RETURN 1310 T(Y,XX)=6 :: RETURN 1320 T(Y,XX)=14 :: RETURN 1330 T(Y,XX)=1 :: RETURN 1340 T(Y,XX)=9 :: RETURN 1350 T(Y,XX)=5 :: RETURN 1360 T(Y,XX)=13 :: RETURN 1370 T(Y,XX)=3 :: RETURN 1380 T(Y,XX)=11 :: RETURN 1390 T(Y,XX)=7 :: RETURN 1400 T(Y,XX)=15 :: RETURN 1410 CALL DONE :: SUBEND 1420 ! ############## 1430 SUB VFLIP(C$(,),C(,)):: CALL BUSY :: DIM T(16,4) 1440 YY=16 :: FOR Y=1 TO 16 :: FOR X=1 TO 4 :: T(YY,X)=C(Y,X):: NEXT X :: YY=YY-1 :: NEXT Y 1450 FOR Y=1 TO 16 :: FOR X=1 TO 4 :: CALL GETNYBBLE(T(Y,X),N$):: C$(Y,X)=N$ :: C(Y,X)=T(Y,X):: NEXT X :: NEXT Y :: CALL DRAWGRID(C$(,),C(,)) 1460 SUBEND 1470 SUB BUSY :: CALL PATTERN(#1,88):: SUBEND 1480 SUB DONE :: CALL PATTERN(#1,140):: SUBEND 1490 SUB HELP 1500 DISPLAY AT(18,1):"arrows@move 0@plot N@new D@scroll down U@scroll up R@right L@left H@flip l/r V@flip u/d G@load grid" 1510 DISPLAY AT(22,1):"F@file A@assign W@animate 2@small J@put sprite on grid" 1520 SUBEND 1530 ! ########## 1540 SUB SCRATCH(C$(,),C(,)):: CALL HCHAR(18,1,32,6*32) 1550 DISPLAY AT(20,1):"Erase grid? y/n" :: ACCEPT AT(20,16)SIZE(1)VALIDATE("YNyn"):A$ 1560 IF A$="y" OR A$="Y" THEN CALL NEW(C$(,),C(,)) 1570 CALL HELP 1580 SUBEND 1590 ! ######## 1600 SUB ASSIGN(C$(,),C(,)) 1610 CALL HCHAR(18,1,32,6*32) 1620 DISPLAY AT(19,1):"Assign design to 1-6:" :: ACCEPT AT(19,22)SIZE(1)VALIDATE("123456"):V$ :: IF V$="" THEN CALL HELP :: SUBEXIT 1630 H$="0123456789ABCDEF" :: CALL BUSY 1640 A$="" :: FOR Y=1 TO 16 :: FOR X=1 TO 2 :: A$=A$&SEG$(H$,C(Y,X)+1,1):: NEXT X :: NEXT Y 1650 FOR Y=1 TO 16 :: FOR X=3 TO 4 :: A$=A$&SEG$(H$,C(Y,X)+1,1):: NEXT X :: NEXT Y 1660 V=116+(VAL(V$)*4) 1670 CALL CHAR(V,A$):: CALL HELP :: CALL DONE 1680 SUBEND 1690 ! ########## 1700 SUB LOADGRID(C$(,),C(,)):: CALL HCHAR(18,1,32,6*32) 1710 H$="0123456789ABCDEF" :: FOR I=1 TO 4 1720 DISPLAY AT(18,1):"Enter data for character";I 1730 ACCEPT AT(19,1)SIZE(16)VALIDATE("0123456789ABCDEF"):A$ :: CALL BUSY 1740 IF I=1 THEN Y=1 ELSE IF I=2 THEN Y=9 ELSE IF I=3 THEN Y=1 ELSE Y=9 1750 IF I<3 THEN S=1 ELSE S=3 1760 FOR M=1 TO LEN(A$) 1770 V=POS(H$,SEG$(A$,M,1),1)-1 1780 C(Y,S)=V :: CALL GETNYBBLE(C(Y,S),N$):: C$(Y,S)=N$ :: IF M/2<>INT(M/2)THEN S=S+1 ELSE S=S-1 1790 IF M/2=INT(M/2)THEN Y=Y+1 1800 NEXT M :: CALL DRAWGRID(C$(,),C(,)):: NEXT I 1810 CALL HELP :: CALL DONE 1820 SUBEND 1830 ! ########### 1840 SUB SAVEDATA 1850 CALL HCHAR(18,1,32,6*32) 1860 DISPLAY AT(18,1):"Enter device and file name, eg DSK1.SPRITES etc Press enter to abort" 1870 ACCEPT AT(21,1)SIZE(15)VALIDATE("_-#@.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):FN$ 1880 IF FN$="" THEN CALL HELP :: SUBEXIT 1890 CALL BUSY :: OPEN #1:FN$,DISPLAY ,VARIABLE 80,OUTPUT 1900 RESTORE 40 1910 FOR I=1 TO 6 :: B$=" DATA " :: READ V :: FOR II=V TO V+3 :: CALL CHARPAT(II,T$):: CALL SPLIT(T$,B$):: NEXT II 1920 PRINT #1:SEG$(B$,1,LEN(B$)-1):: NEXT I 1930 CLOSE #1 :: CALL HELP :: CALL DONE 1940 SUBEND 1950 ! ############## 1960 SUB SPLIT(A$,B$) 1970 FOR I=1 TO 16 STEP 4 :: B$=B$&">"&SEG$(A$,I,4)&"," :: NEXT I 1980 SUBEND 1990 ! ########## 2000 SUB FILEMENU(C$(,),C(,)) 2010 CALL HCHAR(18,1,32,6*32):: DISPLAY AT(19,1):"S=SAVE L=LOAD Press enter to abort" 2020 ACCEPT AT(21,1)SIZE(1)VALIDATE("sSlL"):A$ 2030 IF A$="" THEN CALL HELP :: SUBEXIT 2040 IF A$="s" OR A$="S" THEN CALL SAVEDATA 2050 IF A$="l" OR A$="L" THEN CALL LOADDATA(C$(,),C(,)) 2060 CALL HELP 2070 SUBEND 2080 ! ########## 2090 SUB LOADDATA(C$(,),C(,)) 2100 CALL HCHAR(18,1,32,6*32):: DISPLAY AT(20,1):"Enter device and filename Eg DSK1.SPRITES Press Enter to abort" 2110 ACCEPT AT(23,1)SIZE(15)VALIDATE("_-#@.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):FN$ 2120 IF FN$="" THEN CALL HELP :: SUBEXIT 2130 CALL BUSY :: OPEN #1:FN$,INPUT ,DISPLAY ,VARIABLE 80 2140 IF EOF(1)<>0 THEN 2170 2150 RESTORE :: FOR I=1 TO 6 :: LINPUT #1:A$ :: LINPUT #1:B$ :: A$=A$&B$ 2160 A$=SEG$(A$,8,LEN(A$)):: B$="" :: XX=1 :: FOR X=1 TO 16 :: B$=B$&SEG$(A$,XX,4):: XX=XX+6 :: NEXT X :: READ V :: CALL CHAR(V,B$):: NEXT I 2170 CLOSE #1 2180 CALL DONE :: SUBEND 2190 ! ############ 2200 SUB LFSPRITE(C$(,),C(,)) 2210 CALL HCHAR(18,1,32,6*32):: DISPLAY AT(19,1):"Load grid from which sprite?" :: ACCEPT AT(20,1)SIZE(1)VALIDATE("123456"):S$ :: CALL HELP 2220 IF S$="" THEN SUBEXIT ELSE S=VAL(S$) 2230 CALL BUSY :: SP=116+(S*4) 2240 CALL CHARPAT(SP,P1$):: CALL CHARPAT(SP+1,P2$):: CALL CHARPAT(SP+2,P3$):: CALL CHARPAT(SP+3,P4$):: H$="0123456789ABCDEF" 2250 P$=P1$&P2$&P3$&P4$ 2260 Y=1 :: FOR I=1 TO 31 STEP 2 2270 V$=SEG$(P$,I,1):: V1=POS(H$,V$,1)-1 :: V$=SEG$(P$,I+1,1):: V2=POS(H$,V$,1)-1 2280 CALL GETNYBBLE(V1,N$):: C$(Y,1)=N$ :: CALL GETNYBBLE(V2,N$):: C$(Y,2)=N$ :: C(Y,1)=V1 :: C(Y,2)=V2 :: Y=Y+1 :: NEXT I 2290 Y=1 :: FOR I=33 TO 63 STEP 2 2300 V$=SEG$(P$,I,1):: V1=POS(H$,V$,1)-1 :: V$=SEG$(P$,I+1,1):: V2=POS(H$,V$,1)-1 2310 CALL GETNYBBLE(V1,N$):: C$(Y,3)=N$ :: CALL GETNYBBLE(V2,N$):: C$(Y,4)=N$ :: C(Y,3)=V1 :: C(Y,4)=V2 :: Y=Y+1 :: NEXT I 2320 CALL DRAWGRID(C$(,),C(,)):: CALL DONE 2330 SUBEND 2340 ! ################# 2350 SUB ANIMATE(C$(,),C(,)):: CALL COLOR(#1,1) 2360 FOR I=2 TO 17 :: CALL HCHAR(I,3,32,16):: NEXT I 2370 DISPLAY AT(3,1):"Frame order@" :: DISPLAY AT(4,2):"1234565432" 2380 ACCEPT AT(4,2)VALIDATE(DIGIT)SIZE(-10)$ 2390 CALL DRAWGRID(C$(,),C(,)):: CALL DONE :: SUBEND Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted October 24, 2011 Share Posted October 24, 2011 Subprograms are useful for breaking down your program's functions... a good one is to have a subprogram to play all the sound effects, which uses an ON GOTO so all you need to do is pass a single value to indicate which sound you want to play. What annoyed me about this is that they explicitly BLOCK the use of recursive subprograms... the one kind of programming challenge that they could actually be USEFUL for, and it's denied. (For good reasons, I'll admit, but still...) Adamantyr Quote Link to comment Share on other sites More sharing options...
orion1052003 Posted October 25, 2011 Author Share Posted October 25, 2011 Lee, thanks for pointing that out. I think I forgot to add some statements. I made a program called JOYPROG. First, I was just trying to make a test that would show the joystick values. It ended being 4 dots for the directions, one of which will light up when you move in that direction. Also, it shows some values on screen of variables like X,Y,R, and C. Then, it became a test to try CALL LOCATE with JOYST. Then I figured to test COINC. I put a stationary dot on screen, you can move your dot, touch the stationary one, and it beeps a coincidence. I wanted to try subprograms on a game, and I couldn't get em to work. I thought, why not try these subprograms one at a time in this test program? Changed the name to JOYSUB. In line 193 I set the Meteor coordinates for off screen. In 195 I create the Sprite, off screen and stationary. In the comment I remind myself of where it should start on screen and how fast it should go in the subprogram. I think I should have put 1074 CALL LOCATE(#3,DR,DC) :: CALL MOTION(#3,20,-20) The meteor probably appears to move because it is repeatedly called inside the loop. But since it is stuck at the spot like you said, Sprite #1 has to be moved there by the joystick and it registers a coincidence. I just added line 1074. Now it moves across screen, but gets cut off and starts again. Probably this happens each time as the sub is called. I guess CALL LOCATE and some statements have to be dome outside of subprograms, due to the looping effect? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 26, 2011 Share Posted October 26, 2011 (edited) I think I should have put 1074 CALL LOCATE(#3,DR,DC) :: CALL MOTION(#3,20,-20) The meteor probably appears to move because it is repeatedly called inside the loop. But since it is stuck at the spot like you said, Sprite #1 has to be moved there by the joystick and it registers a coincidence. I just added line 1074. Now it moves across screen, but gets cut off and starts again. Probably this happens each time as the sub is called. I guess CALL LOCATE and some statements have to be dome outside of subprograms, due to the looping effect? You could put some more conditional statements in the subprogram to react to where the meteor is on the screen, especially if you only want it to make one pass of the screen. not relocate the meteor if it is in motion create a variable in the subprogram to keep track of whether the meteor is moving or crashed (deleted or hidden). Variables local to subprograms and not part of the parameter list retain their values from one call to the next. Unless you're just doing it here to get a handle on how to pass variables to and from subprograms, you really don't need the parameters in the METEOR subprogram because they are changed only in the subprogram and you don't do anything with the changed values when you return to the main program. Also, rather than deleting the meteor sprite, you could park it off-screen until you want it to do something. I may be just stating the obvious here. I'll stop rambling now. ...lee Edited October 26, 2011 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
orion1052003 Posted October 29, 2011 Author Share Posted October 29, 2011 Can you do a CALL SOUND and a CALL COINC at the same time? Or does it actually do one and then the other next? I ask because I hear that CALL SOUND is the only command or SUB that can run while another statement is running. While maybe DATA does that too. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted October 29, 2011 Share Posted October 29, 2011 The 99/4A does not have any co-processors, in the sense that they don't execute some sort of code. You only have the 9900 CPU to work with, which means nothing really happens "at the same time". The sound chip in the 99/4A, once set to a tone, will continue playing that tone until it is told to be quite, change its tone, etc. The BASIC/XB SOUND subroutine has the option to wait until the sound is finished before executing the next instruction, or by using a negative duration the SOUND subroutine will start the sound playing, then move on to the next instruction. BASIC then has to go back and check if the sound is done and turn off the sound chip (BASIC checks if it should shut off the sound every 1/60th of a second via the system ISR (interrupt service routine)). In this sense, the sound is playing truly in parallel with the 9900 CPU, but unless told to shut off, the sound chip would continue to play the same tone indefinitely. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 30, 2011 Share Posted October 30, 2011 Can you do a CALL SOUND and a CALL COINC at the same time? Or does it actually do one and then the other next? I ask because I hear that CALL SOUND is the only command or SUB that can run while another statement is running. While maybe DATA does that too. The statements do not actually execute at the same time; but, once CALL SOUND is executed, the computer does not wait for the sound to complete before continuing with the remaining computer statements unless it encounters another CALL SOUND statement with a positive duration. Then, of course, it waits for the previous sound to complete. The CPU (TMS9900) can only do one thing at a time; but, once the sound data is passed to the sound processor, the CPU can do other things and thus appear to be doing two things at once. DATA is not really an executable statement. It is declaring a storage location to be referenced later by a READ statement. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 30, 2011 Share Posted October 30, 2011 The BASIC/XB SOUND subroutine has the option to wait until the sound is finished before executing the next instruction, or by using a negative duration the SOUND subroutine will start the sound playing, then move on to the next instruction. I think the way you stated this is misleading. The SOUND routine does not have "the option to wait ...". Rather, the SOUND routine's option is to cancel a previously initiated sound "by using a negative duration". If there is no previously initiated sound still playing, the SOUND routine starts playing the sound and "move on to the next instruction" regardless of the duration value. ...lee Quote Link to comment Share on other sites More sharing options...
+RXB Posted October 30, 2011 Share Posted October 30, 2011 (edited) Lee he The BASIC/XB SOUND subroutine has the option to wait until the sound is finished before executing the next instruction, or by using a negative duration the SOUND subroutine will start the sound playing, then move on to the next instruction. I think the way you stated this is misleading. The SOUND routine does not have "the option to wait ...". Rather, the SOUND routine's option is to cancel a previously initiated sound "by using a negative duration". If there is no previously initiated sound still playing, the SOUND routine starts playing the sound and "move on to the next instruction" regardless of the duration value. ...lee Lee well this is the source code so see for yourself what happens in XB. VRMSND EQU >0379 <0135> AA0B D7,80,CC SOUND DCEQ VRMSND,@>83CC Insure previous sound started <0136> AA10 6A,0B BS SOUND <0137> AA12 31,00,09 MOVE 9,G@SNDREG,V@VRMSND It waits till the previous sound list is done this is the XB source code for CALL SOUND, I did not modify it in RXB. Edited October 30, 2011 by RXB Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 30, 2011 Share Posted October 30, 2011 It waits till the previous sound list is done this is the XB source code for CALL SOUND, I did not modify it in RXB. I believe that's what I said, Rich. What I was trying to clarify (perhaps not well) is that Matthew's explanation seemed to imply that the programmer can decide to make the currently executing SOUND call wait for its own sound list to complete before going on to the next instruction, when, in fact, that is not so. It never waits on anything except a previous sound list to complete (unless, of course, the current SOUND call includes a negative duration---then it just cuts off the previous sound and goes on). Thanks for the code. ...lee Quote Link to comment Share on other sites More sharing options...
matthew180 Posted October 31, 2011 Share Posted October 31, 2011 Yeah, thanks for the clarification. I didn't review the SOUND subprogram before posting, and it has been a while since I used it. A quick test shows that SOUND starts playing a tone and goes on with the program. Any subsequent SOUND commands will wait on the previous sound to finish (which does block execution of the program), unless the duration is negative - in which case the new sound interrupts any previously playing sound (as Lee stated.) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.