Omnimaga
Calculator Community => TI Calculators => TI-BASIC => Topic started by: Builderboy on January 23, 2010, 01:31:57 am
-
So this is a small bit of code that takes advantage of Memory leaks in order to run 'Sub-Routines' that you can place within your programs! This can be advantageous for people who want to compile their games into a single program to clear up Program menus
Goto M //Start of Subroutine section. We want it to be at the top of the program, as all subroutines are accessed via lables
//This code is skipped due to the Goto M statement
Lbl A //Subroutine A
Disp "This is a fun sub"
Disp "Its over 9000"
End
Lbl M
Disp "Main program foo'!" //This is where normal program execution starts
For(F,-1,0) //The tricky bit. The first time the for loop loops, F=-1 and the if statement is true. Goto A
If F //Once the sub is executed, it reaches an End which it THINKS is the same end that ends the For loop
Goto A //since the loop is still looping, control jumps [i]back into the for loop[/i]
End //F is now 0 and the condition is false. Exit for loop :)
The code works by exploiting the fact that the TiOS cannot tell the difference between individual End's, and that jumping using Goto's does not clear Loop stacks. Whenever the OS encounters an End, it will automatically assume that the End is paired with the most recent loop, and act accordingly.
-
I believe I saw another thread about this somewhere here but I totally forgot the name, thanks for posting this tho ^^
-
I think it might have been in the long lost Portal 2 thread. But yeah, this has been really usefull in the past :)
-
Another method I use for the same thing is using While loops. It can get really complex, so it is important to write it out on paper or on the computer so you can keep an eye on how many Whiles to Ends there are, but the idea is fast.
The idea is to have your master loop, and have the rest of your loops inside that. You don't even have to make them all Whiles, you can use If as well.
:ClrDraw
:1→W:0→F
:" →Str1
:0→Xmin:0→Ymin
:94→Xmax
:62→Ymax
:AxesOff
:GridOff
:While W=1
:25→A
:Text(‾1,0,10,"SPRITE-2-HEX
:Text(25,25,"NEW SPRITE
:Text(31,25,"EDIT SPRITE
:Text(37,25,"ABOUT
:Text(43,25,"QUIT
:2→W
:While W=2
:Text(A,20,">
:getKey→K
:If max(K={25,34:Text(A,20,"
:A-6((K=25)(A>25)-(K=34)(A<43→A
:If max(K={21,105:Then
:If A=43:Then
:DelVar ADelVar WDelVar KClrDraw
:ClrHome
:Return:End
:If A=37:Then
:ClrDraw
:Text(‾1,0,10,"SRITE-2-HEX
:Text(13,0,"THIS PROGRAM CONVERTS
:Text(19,0,"8X8, 16X16, and 32X32
:Text(25,0,"SPRITES INTO HEXADECIMAL
:Text(31,0,"TO BE USED WITH THE
:Text(37,0,"HEX-2-SPRITE PROGRAM.
:Text(47,0,"SEND QUESTIONS TO:
:Text(53,0,"TIFREAK8XHOTMAIL.COM
:Pause
:ClrDraw
:1→W
:End
:If A=31:Then
:length(Str4
:Ans/(2+2(Ans>16)+4(Ans>64
:If min(Ans≠{8,16,32
:Then
:ClrDraw
:Text(0,0,"NO SPRITE IN MEMORY
:Pause
:ClrDraw
:1→W
:End
:If max(Ans={8,16,32:Then
:ClrDraw
:3→W:2→F
:End:End
:If A=25:Then
:ClrDraw
:Text(‾1,0,10,"SPRITE-2-HEX
:Text(15,1,"PLEASE SELECT SPRITE SIZE
:Text(30,25,"8X8
:Text(36,25,"16X16
:Text(42,25,"32X32
:Text(48,25,"BACK
:30→A
:4→W
:End:End
:While W=4
:Text(A,20,">
:getKey→K
:If max(K={25,34:Text(A,20,"
:A-6((K=25)(A>30)-(K=34)(A<48→A
:If max(K={21,105:Then
:If A=48:Then
:ClrDraw
:1→W:End
:If A=30:8→Z
:If A=36:16→Z
:If A=42:32→Z
:If A<48:3→W
:End:End
:While W=3
:ClrDraw
:If Z=8:Then
:Line(40,31,40,38
:Line(41,30,48,30
:Line(49,31,49,38
:Line(41,39,48,39
:End
:If Z=16:Then
:Line(36,27,36,42
:Line(37,26,52,26
:Line(53,27,53,42
:Line(37,43,52,43
:End
:If Z=32:Then
:Line(28,19,28,50
:Line(29,18,60,18
:Line(61,19,61,50
:Line(29,51,60,51
:End
:Horizontal(7
:Text(56,0,"EXPORT QUIT
:If F=2:Then
:length(Str4
:Ans/(2+2(Ans>16)+4(Ans>64→Z
:If Z=8:Then
:41→I:24→J:End
:If Z=16:Then
:37→I:20→J:End
:If Z=32:Then
:29→I:12→J:End
:I→C:J→U
:For(B,1,length(Str4
:inString("123456789ABCDEF",sub(Str4,B,1
:If 7<Ans
:Pxl-On(U,C
:If 3<8fPart(Ans/8
:Pxl-On(U,C+1
:If 1<4fPart(Ans/4
:Pxl-On(U,C+2
:If fPart(Ans/2
:Pxl-On(U,C+3
:C+4→C
:U+(C=I+Z→U
:If C=I+Z:I→C:End
:End
:45→M:35→N:6→W
:StorePic Pic4
:End
:While W=6
:Pt-Change(M,N
:getKey→K
:If max(K={24,25,26,34
:Then
:Pt-Off(M,N
:RecallPic Pic4
:M-(((K=24)((Z=8)(M>41)+(Z=16)(M>37)+(Z=32)(M>29))-((K=26)((Z=8)(M<48)+(Z=16)(M<52)+(Z=32)(M<60→M
:N-(((K=34)((Z=8)(N>31)+(Z=16)(N>27)+(Z=32)(N>19))-((K=25)((Z=8)(N<38)+(Z=16)(N<42)+(Z=32)(N<50→N
:End
:If K=21
:Then
:RecallPic Pic4
:Pt-On(M,N
:StorePic Pic4
:End
:If K=31:Then
:RecallPic Pic4
:Pt-Off(M,N
:StorePic Pic4
:End
:If K=15:Then
:DelVar W
:ClrDraw:ClrHome
:End
:If K=11:Then
:Pt-Off(M,N
:RecallPic Pic4
:If Z=8:Then
:41→S:48→T
:24→Q:31→R
:End
:If Z=16:Then
:37→S:52→T
:20→Q:35→R
:End
:If Z=32:Then
:29→S:60→T
:12→Q:43→R
:End
:For(A,Q,R
:For(B,S,T,4
:8pxl-Test(A,B)+4pxl-Test(A,B+1)+2pxl-Test(A,B+2)+pxl-Test(A,B+3)→C
:Pxl-On(A,B
:If C=0:Str1+"0"→Str1
:If C>0
:Str1+sub("123456789ABCDEF",C,1)→Str1
:End:End
:sub(Str1,2,length(Str1)-1)→Str4
:DelVar Str1
:ClrDraw
:Text(0,0,"YOUR SPRITE HAS BEEN
:Text(6,0,"CONVERTED, PASTE Str4
:Text(12,0,"INTO A PROGRAM TO USE
:Pause
:0→W
:End:End:End:End
Generated by SourceCoder (http://www.cemetech.net/projects/basicelite/sourcecoder.php), © 2005 Cemetech (http://www.cemetech.net)
That is an example of the set up. I managed to get everything in one program without using a single Lbl or Goto. And if you close off each While correctly, you get no memory leaks. :p
-
Yeah well, I think I'm going with Builderboy's method, I can actually understand it :p
-
I usually use Repeat loop to do these things XD
-
Yeah, note that this method is really only used when you have a large chunk of code that needs to be used in many different places over the span of your program, and trying to reorganize your entire engine around that limiting factor would be either a hassle or downright impossible. Obviously if you only ever call the routine once in your program it would be faster and easier to just recall the code to that spot :P
-
One issue to consider when using Goto is to never use them when the Lbl is completly at the bottom of a massive program. It takes a long while to load.
-
Right, thats why i suggest that you put the subroutines at the top, to preserve speed :)
-
ohhh this is much better than abusing recursion (eats up ram real fast that way) which is what piworld uses, i am definitely going to modify it to use this strategy instead
-
Yeah, i used recursion in one of my old games, and it ended up running really slow. x.x
-
I usually use Repeat loop to do these things XD
Problem with Repeat is that it always runs that loop at least once, before checking to see if it is true, while checks when it sees a while command. That is the difference.
And not trying to force this on anyone, just popping it out there that this works too :p
-
Well there are certain scenarios where Repeat is more usefull than while. The simplest example that comes to mind is this
While 1
Repeat Ans
GetKey->K
End
...
End
Repeat is actually better than while in this situation because we DO want it to enter the loop, regardless of what ans was in the first place. Using while, we would have to make sure that ans was not 0 before we enter.
-
Goto M //Start of Subroutine section. We want it to be at the top of the program, as all subroutines are accessed via lables
//This code is skipped due to the Goto M statement
Lbl A //Subroutine A
Disp "This is a fun sub"
Disp "Its over 9000"
End
Lbl M
Disp "Main program foo'!" //This is where normal program execution starts
For(F,-1,0 //The tricky bit. The first time the for loop loops, F=-1 and the if statement is true. Goto A
If F //Once the sub is executed, it reaches an End which it THINKS is the same end that ends the For loop
Goto A //since the loop is still looping, control jumps [i]back into the for loop[/i]
End //F is now 0 and the condition is false. Exit for loop :)
make sure the For( loop is closed tho because of the glitch with only one If statement, after the sub program is ran it returns to the For loop but the condition is false and if i remember correctly from the glitches thread a For( loop with a single If statement that is false can cause havoc, in that particular case it doesn't matter since you exit out after its done but if used in a big program it should be closed i would think :{o
-
The glitch will actually cause the entire game to run at like half the speed (or close) until you press ON in some cases. If that doesn't happen, there will still be a considerable slowdown during For loop, though
-
Thank you for posting that. I'm glad you are showing this, as it's very nice.
I think it might have been in the long lost Portal 2 thread. But yeah, this has been really usefull in the past :)
I found it there a long time ago (before I was a member here) and started using it often. If you look through the Escape code, you can find my first attempts of using this method. I will be using it in the battle code for Elmgon.
Thanks for posting this!
-
Mmmm yeah good catch. I fixed it. I actually never had the problem keep happening after the for loop had finished, but it is a strange error/glitch and definitely should be avoided.
-
At least I won't need to create hundreds of subprograms!
DJ, you said that the glitch causes the calc to run at half speed, but are you talking about the method in the 1st post or just about memory leakage?
-
At least I won't need to create hundreds of subprograms!
DJ, you said that the glitch causes the calc to run at half speed, but are you talking about the method in the 1st post or just about memory leakage?
He's talking about If s (No Then) in For( loops without closing brackets on the For loop.
http://tibasicdev.wikidot.com/for Check a little under optimization.
-
I wish XCOPY/Resource existed or that Flash Gordon was more reliable when I did Zelda, it would have maybe 45 subprograms at most instead of 200 x.x
-
Your Zelda had about 200 subprograms? O_o
-
Around that or maybe 210. That was because I had so extreme limited RAM that I had to split every small routine into their own program even if they were repeated only twice in the entire game. Same fashion as the TI-81 Illusiat
Zelda DLQ was just created 6 months too early
-
I wish XCOPY/Resource existed or that Flash Gordon was more reliable when I did Zelda, it would have maybe 45 subprograms at most instead of 200 x.x
How is it possible to follow the code? I couldn't handle that code without quitting for sure...
-
well each routines are pretty small. The problem is that there are so many that it can become hard to remember what they were.
Note that I was very lucky with Zelda DLQ. When I finished it I found no bug in it afterward, so no need to debug or anything.
-
Wait, you created a bug free program, ON THE FIRST TRY?!?!?!
-
Yea, basically the beta tester team I hired prior release wouldn't even have to report anything. Not that anyone got able to play the game, though, thanks stupid TI for releasing a TI-Connect build supporting a different 8xg format