Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: Eeems on February 18, 2010, 11:12:16 pm

Title: Routines
Post by: Eeems on February 18, 2010, 11:12:16 pm
Share your cool little axe parser routines here! Or big too.
I currently don't have any, but I was wondering if anybody could come up with a good line drawing one (from point a to b).
I'll put up some that I come up with later too I guess.
Title: Re: Routines
Post by: DJ Omnimaga on February 19, 2010, 02:21:18 pm
would that be in Axe code or in z80 ASM (for helping Quigibo)?
Title: Re: Routines
Post by: Builderboy on February 19, 2010, 03:04:00 pm
Mmm i'm thinking it would be in Axe code, just to help out people in the future :)

I'll see if i can get a line drawing code whipped up, sounds like a good challenge ^^
Title: Re: Routines
Post by: Quigibo on February 19, 2010, 03:24:03 pm
Line drawing will obviously be built in later, so don't worry too much about that.
Title: Re: Routines
Post by: Builderboy on February 19, 2010, 03:29:35 pm
Haha alright then :P

Maybe I'll upload my very primitive and integer based Sin routine XD
Title: Re: Routines
Post by: Eeems on February 19, 2010, 04:06:58 pm
Axe Parser code :P

yeah, I know line will be included later, but now I can't stop trying to figure out how to do it with only pxl-on() x.x
Title: Re: Routines
Post by: Galandros on February 19, 2010, 04:11:23 pm
Axe Parser code :P

yeah, I know line will be included later, but now I can't stop trying to figure out how to do it with only pxl-on() x.x
Get the slope from the 2 points and pixel on points in line between the 2 points. Basically use y=mx+b equation.
This is how it can be done in assembly. There is a tutorial for this in Patagay assembly tutorial.
By using sine and cosine is also possible...
Title: Re: Routines
Post by: Eeems on February 19, 2010, 04:35:01 pm
hmm, but how would you do that with no decimal places?
Title: Re: Routines
Post by: Galandros on February 19, 2010, 04:45:03 pm
hmm, but how would you do that with no decimal places?
If you want 1 decimal place then use that number times 10 and the least significant digit is your decimal place.
Example of to show what the previous phrase means:
.1 turns 1
1.9 turns 19

Now imagine you want to multiply A and B where A is .1 (10) and B=1.9 (19).
You do (A*B)/100.
Note that these expressions are equivalent: .1*1.9 =  ((1/10) * (19/10)) / 100
Title: Re: Routines
Post by: Eeems on February 19, 2010, 04:51:16 pm
well that would work, but Axe doesn't support decimals, so that would be an issue...
Title: Re: Routines
Post by: DJ Omnimaga on February 19, 2010, 05:00:33 pm
Wasn't decimal support going to arrive in future versions of Axe? I remember Quigibo telling me on Yahoo that some variables would be reserved for integers while some others would be reserved for floating points...
Title: Re: Routines
Post by: Eeems on February 19, 2010, 05:23:17 pm
hmm, I don't know, but that would be nice, as of currently it doesn't allow for it.
Title: Re: Routines
Post by: Quigibo on February 20, 2010, 12:26:26 am
Check this out:

http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Its probably what I'll be using, it only requires addition and bit-shifting, no floats.
Title: Re: Routines
Post by: Eeems on February 20, 2010, 12:40:28 am
Sweet! I'll try and make a routine that can work for now until it's integrated.
Title: Re: Routines
Post by: Galandros on February 20, 2010, 03:31:44 am
Check this out:

http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Its probably what I'll be using, it only requires addition and bit-shifting, no floats.
There are already two excellent implementations in z80 of that algorithm by James Montelongo and quarnos.
To download the James Montelongo one see his ticalc profile. For quarnos see MaxCoderz forum.
Title: Re: Routines
Post by: calc84maniac on February 24, 2010, 12:06:39 pm
How to add/subtract two 32-bit numbers:
Code: [Select]
:'This will do AB+CD->AB
:((B+D->B)<D)+A+C->A
:'This will do AB-CD->AB
:A-C-((B-D->B)>=-D)->A
Note ">=" is greater than or equal token
Title: Re: Routines
Post by: Quigibo on February 24, 2010, 01:53:37 pm
Nice!  Although you don't need all those parenthesis since order of operations is still just left to right:
:B+D->B<D+A+C->A
:A-C-(B-D->B>=-D)->A
Won't make a difference in the compiled code, but saves some memory in the source.
Title: Re: Routines
Post by: DJ Omnimaga on February 24, 2010, 02:19:06 pm
I think I will probably start coding this by using the conventional BASIC operation syntax because I still can't memorize the weird Axe syntax so it's gonna take me a while to get used to when coding x.x
Title: Re: Routines
Post by: trevmeister66 on February 24, 2010, 02:35:48 pm
I think I will probably start coding this by using the conventional BASIC operation syntax because I still can't memorize the weird Axe syntax so it's gonna take me a while to get used to when coding x.x
You could always create your code the conventional BASIC way and then post it here and someone can convert it to "Axe friendly syntax" if you want.
Title: Re: Routines
Post by: DJ Omnimaga on February 24, 2010, 02:42:56 pm
I guess that could work too :P, altough if the code is massive some ppl might not want to XD

I want to port WoW to Axe Parser... j/k
Title: Re: Routines
Post by: calc84maniac on February 24, 2010, 03:02:23 pm
I optimized even more now :D
Code: [Select]
:'This does AB+CD->AB
:B>(+D->B)+A+C->A
Title: Re: Routines
Post by: ztrumpet on February 24, 2010, 04:54:55 pm
Nice job Calc84! :D
Title: Re: Routines
Post by: Eeems on February 24, 2010, 06:03:10 pm
Wow nice!
Title: Re: Routines
Post by: Quigibo on February 24, 2010, 06:11:52 pm
That's actually 1 byte less optimized. Try it.

That's because the parenthesis require a push and pop (2 bytes), and the "greater than" and "less than or equal to" operators take 2 more bytes than the other comparisons.  So you saved 3 bytes but then added 4.

You could have done this:
Code: [Select]
:B>=(+D->B-1)+A+C->ABut then its the same size as your first attempt.  Not sure if the speed is faster or slower though.
Title: Re: Routines
Post by: calc84maniac on February 24, 2010, 06:22:46 pm
That's actually 1 byte less optimized. Try it.

That's because the parenthesis require a push and pop (2 bytes), and the "greater than" and "less than or equal to" operators take 2 more bytes than the other comparisons.  So you saved 3 bytes but then added 4.

You could have done this:
Code: [Select]
:B>=(+D->B-1)+A+C->ABut then its the same size as your first attempt.  Not sure if the speed is faster or slower though.
Well, my logic was that it did one less variable access than before.
Title: Re: Routines
Post by: Builderboy on February 25, 2010, 10:15:08 pm
Here is my (most likely unoptimised) Sin approximation routine.  Since floating point numbers have not been implemented (yet?) I was forced to use a different approach.  Input is in 10x and output is in 10x.  For example to input 3.1 (PI :P) you would input 31.  And output is from -10 to 10.  It also *does* loop, so your input can go beyond 2PI (63).

Code: [Select]
Lbl S
->A
A^64/16->B
A^16->A
If B=1 Or (B=3
16-A->A
End
A-(A*A*A/600)->A
If B>1
-A->A
End
A
Return

The code is meant to be used like this

Code: [Select]
31sub(S)->C    //Will return 10x the sin of 3.1
Optimizations are welcome, i'm sure there are some ;D
Title: Re: Routines
Post by: rthprog on February 26, 2010, 11:54:44 am
I'm not familiar with Axe, so I'm just guessing when I make these modifications.

Code: [Select]
Lbl S
->Ans^16->A
A^4/16->B
A-2(A-8)(T=1 Or T=3
Ans-Ans^3/600-2(T>1->A
Return
Title: Re: Routines
Post by: Eeems on February 26, 2010, 01:01:08 pm
Unfortunatly Axe does not have Ans yet, and we don't know if it ever will. Also it would probably be slower to have it anyways.
Title: Re: Routines
Post by: Quigibo on February 26, 2010, 03:27:59 pm
Ans is always implied as the last computation every new line so its not really needed.  Storing it to a temporary variable is what "Ans" would do anyway, so just pick a variable and pretend that its "Ans".


I'm a little bit confused why you store to B and never use it and then reference T but don't declare it.  I'll assume thats a typo and are meant to both be the same variable.

Here are some optimizations:
Code: [Select]
Lbl S
->A^64/16->B
A^16->A
If B^2          ;Says "If B is odd"
16-A->A
End
A-(A*A*A/600)->A
If B/2^2        ;Checks 2nd bit
-A->A
End
A
Return
This should now work at ANY value of A, but I guess it is still just one term of the Maclaurin so estimates will be off...

EDIT: oops, fixed.
Title: Re: Routines
Post by: DJ Omnimaga on February 26, 2010, 04:51:36 pm
I wonder if he just posted a portion of his code, it could be why

Btw the other nigth I started messing around a bit with Axe the same way I started BASIC: by looking at code examples (in this case, Fall Down) and modifying parts of them, such as having the ball move 8x faster or the like. Maybe eventually I'll have some motivation and time to make an entire game to myself
Title: Re: Routines
Post by: Builderboy on February 26, 2010, 05:43:11 pm
Oops, I changed T to B accidentally, i fixed it, made them all B's :P

With only these two terms of the Maclaurin series (X and X^3/6) Sin can actually be approximated within 1/100 of the real Sin function (remember we only have to go up to PI/2 because i use symmetry) and so the way this could be improved in accuracy is by using 100x instead of 10x.  You would have to be tricky with the math though because 150x150x150 would not fit into the regular int
Title: Re: Routines
Post by: DJ Omnimaga on March 04, 2010, 11:48:42 pm
I made my first Axe Parser program tonight. I took the following program by Calc84maniac:

Code: [Select]
For(A,0,92,2
For(B,0,60,2
If Pxl-Test(B,A
Then
Pxl-On(B+1,A
Pxl-On(B,A+1
Pxl-On(B+1,A+1
Else
Pxl-Off(B+1,A
Pxl-Off(B,A+1
Pxl-Off(B+1,A+1
End
End
End

And with his help (such as telling me For doesn't support the last argument yet), I managed to turn this into an Axe Parser program, but a bit more complex. It is a program that pixelates the screen content in a style similar to old Super Nintendo games, such as when you are having a dream in Final Fantasy VI.

It is obviously slow, because it runs through multiple For( loops, but it is MUCH quicker than waht it would be in TI-BASIC. For every blur instances, it renders in about 0.75 seconds. Here's my code below:

Quote from: BASIC Code
:For(X,0,47
:For(Y,0,31
:2*X→A
:2*Y→B
:If pxl-Test(A,B
:Pxl-On(A+1,B
:Pxl-On(A,B+1
:Pxl-On(A+1,B+1
:Else
:Pxl-Off(A+1,B
:Pxl-Off(A,B+1
:Pxl-Off(A+1,B+1
:End
:End
:End
:DispGraph
:For(X,0,23
:For(Y,0,15
:4*X→A
:4*Y→B
:If pxl-Test(A,B
:For(C,0,3
:For(D,0,3
:Pxl-On(A+C,B+D
:End
:End
:Else
:For(C,0,3
:For(D,0,3
:Pxl-Off(A+C,B+D
:End
:End
:End
:End
:End
:DispGraph
:For(X,0,11
:For(Y,0,7
:8*X→A
:8*Y→B
:If pxl-Test(A,B
:For(C,0,7
:For(D,0,7
:Pxl-On(A+C,B+D
:End
:End
:Else
:For(C,0,7
:For(D,0,7
:Pxl-Off(A+C,B+D
:End
:End
:End
:End
:End
:DispGraph
Generated by SourceCoder (http://www.cemetech.net/projects/basicelite/sourcecoder.php), © 2005 Cemetech (http://www.cemetech.net)

With a screenshot attached below, showing it in action after recalling a pic in a BASIC program. NOTE: It runs at regular 83+ speed (6 MHz). If Axe was made so programs would run at the calc speed automatically, this would be twice as fast as it is now on SE models.
Title: Re: Routines
Post by: Geekboy1011 on March 04, 2010, 11:54:47 pm
thats awsome dj

i really need to try this soon X.x
Title: Re: Routines
Post by: Eeems on March 05, 2010, 12:06:18 am
Wow! Pretty intense!
The easiest way to "add the last argument to for loops" would be to just add a <var>+#-><var> to the end (<var> stands for the variable that the for loop increments and # is the amount extra that you want to increment it).
That could probably help to speed your program up a little tiny bit. Especially due to the fact that adding is faster then multiplication here.
Title: Re: Routines
Post by: DJ Omnimaga on March 05, 2010, 12:14:38 am
mhmm what would you mean? Do you mean something like For(X,0,47*2?
Title: Re: Routines
Post by: Builderboy on March 05, 2010, 12:29:57 am
Hey that looks awesome!  I don't know what You are talking about Eeems O.o what do you mean exactly?
Title: Re: Routines
Post by: Eeems on March 05, 2010, 12:36:10 am
What I mean is:
Code: [Select]
For(A,0,7
output(A,A,"HELLO
A+1->A
End
which is the equivalent of:
Code: [Select]
For(A,1,8,2)
output(A,A,"HELLO
End
in BASIC.
Title: Re: Routines
Post by: DJ Omnimaga on March 05, 2010, 12:38:25 am
oooh ok I see, I'll give this a try :)

thanks for the tips
Title: Re: Routines
Post by: Eeems on March 05, 2010, 12:40:51 am
Np! I actually use a form of this in the most recent version of alien. For drawing the background, every time a pixel is drawn it adds 3 to A otherwise it will increment normally. This keeps it from having multiple "stars" in a row.
Title: Re: Routines
Post by: trevmeister66 on March 05, 2010, 12:43:55 am
I have a question about a routine. I'm working on a project that has an array of numbers. Every time I go through the main loop, I move the numbers down one slot, and put in a new number in the 1st (or 0th) slot. While I do have this working fine, my problem comes when I try to increase the size of my array. I know that the arrays already have their max size, but I have it so it only does 'S' number of slots in the array, but when I increase 'S', it doesn't do what I want.

Well after rereading what i just said, I'm just going to post the code:
Code: [Select]
DiagnosticOff
ClrDraw
6üA // X Variable
6üB // Y Variable
5üS // Size of "snake"
1üC // X direction
0üD // Y direction
0üE
[0664646464]üStr1
[0664646464]üStr2
sub(ZZ

Repeat getKey(15) or pxl-Test(A,B)
Pxl-On(A,B)
Pxl-Off({Str1+S-1},{Str2+S-1})
DispGraph
If getKey(1)
0üC
1üD
End
If getKey(2)
ú1üC
0üD
End
If getKey(3)
1üC
0üD
End
If getKey(4)
0üC
ú1üD
End
****MY PROBLEM STARTS HERE****
If getKey(54)  // If 2nd was pushed
0ü{Str1+S      // Store 0 into
0ü{Str2+S      // The 'new' location
1+SüS            // Increase S (size)
End
****AND ENDS HERE****
A+CüA
B+DüB
For(X,1,S-1)
{Str1+S-X-1}ü{Str1+S-X
{Str2+S-X-1}ü{Str2+S-X
End
Aü{Str1+0
Bü{Str2+0
Pause 50
End
Return

****DRAWS BOX AROUND SCREEN****
Lbl ZZ
For(X,0,95
Pxl-On(X,0)
Pxl-On(X,63)
End
For(X,0,63
Pxl-On(0,X)
Pxl-On(95,X)
End
Return

When I remove the "If getKey(54)....End" part, it works normally.... any suggestions?

SPOILER: it's a snake game, or an attempt at one rather.

Also, sorry about my lack of using the correct program to retrieve the proper symbols.
Title: Re: Routines
Post by: Eeems on March 05, 2010, 01:03:28 am
Well, I didn't look too closely, but the problem might be trying to use str1/str2 for your array, I would try L1/L2 instead. They have a large amount of room and Str1/2 only have what you define at the start.
but from what you say I guess you already understand this. Could you create a simple test that just lists off all the numbers in eacharray and see if it's calling the correct area?
Title: Re: Routines
Post by: trevmeister66 on March 05, 2010, 01:05:55 am
Well, I didn't look too closely, but the problem might be trying to use str1/str2 for your array, I would try L1/L2 instead. They have a large amount of room and Str1/2 only have what you define at the start.
but from what you say I guess you already understand this. Could you create a simple test that just lists off all the numbers in eacharray and see if it's calling the correct area?
Hmm I might try your idea, although I believe it doesn't matter what you name your arrays/strings/pics because Axe just creates it into what it needs to be, regardless of what you name it. I'll just mess around with it some more.
Title: Re: Routines
Post by: Eeems on March 05, 2010, 01:07:50 am
Ah ok. Also I just thought, using L1/2 makes your program smaller because you don't have to store the in it, it's stored on the ram :D
well let us know your findings so we can help if we can.
Title: Re: Routines
Post by: DJ Omnimaga on March 05, 2010, 02:17:01 am
Np! I actually use a form of this in the most recent version of alien. For drawing the background, every time a pixel is drawn it adds 3 to A otherwise it will increment normally. This keeps it from having multiple "stars" in a row.
Btw tried your method and altough I got no speed gain in the part where the screen is pixelated to have 4x4 or 8x8 squares, for the 2x2 part it goes 1.5x faster than it did.

The only issue, though, with both methods, is that the produced ASM code is horribly bigger than  the original source. The source program "BLUR" is 298 bytes large while the ASM one called "LOL" is 779 bytes. I saved a few bytes with your method, though, because it was in the 800s before. I guess maybe that kind of ASM program is a bit memory hungry or I did it wrong x.x

I am still impressed by how fast it is, though.
Title: Re: Routines
Post by: Eeems on March 05, 2010, 09:17:13 am
Yay! Also I noticed for the others there is a way to speed them up a little, you just have to move the part where it stores to the first loops var outside the second loop to keep it from being set each time the second loop runs.

Yeah the compiled versions are usually around that large.
Title: Re: Routines
Post by: Quigibo on March 05, 2010, 11:14:54 am
@trevmeister66
Eeems was correct about the string sizes.  When you define data, like the data in your strings, that data is added to the end of the program, not to the RAM.  Your compiled code will look like this:

<Hex code for all of program>06646464640664646464

While you CAN use this area to modify data, it is limited by the room it has in the program.  A 1000 byte program can not use 2000 bytes of its own ram!  If you want to use the free ram, then at the start of your program, you have to copy your data to the RAM using a for loop or something.

@omnimaga
If you want to speed up the pixilation, you can draw 8x8 and 4x4 sprites instead of blocks of pixels using Pt-Off().  Its probobly even faster for the 2x2 case but I'm not quite sure about that.  Also, in the next version, you will be able to use 15MHz mode so yeah, that can be 3 times faster.
Title: Re: Routines
Post by: Galandros on March 05, 2010, 02:03:26 pm
Very cool effect DJ. ;) The current speed is good. And there is space for optimization. ;)
Good work to Quigibo, too, he did the language after all. :P
Title: Re: Routines
Post by: DJ Omnimaga on March 05, 2010, 02:27:37 pm
Thanks quigibo, I guess I need to learn about sprites now ^^

As for Eeems, unfortunately I don't understand what you mean. Could you show code as example?
Title: Re: Routines
Post by: trevmeister66 on March 05, 2010, 03:02:35 pm
@trevmeister66
Eeems was correct about the string sizes.  When you define data, like the data in your strings, that data is added to the end of the program, not to the RAM.  Your compiled code will look like this:

<Hex code for all of program>06646464640664646464

While you CAN use this area to modify data, it is limited by the room it has in the program.  A 1000 byte program can not use 2000 bytes of its own ram!  If you want to use the free ram, then at the start of your program, you have to copy your data to the RAM using a for loop or something.

Wow, that made everything clear. I get why it doesn't work. Thanks!

EDIT: Heh, your's and Eem's suggestions worked. Thanks guys!
Title: Re: Routines
Post by: ztrumpet on March 05, 2010, 03:45:07 pm
Looks nice DJ!

Eeems, the for loop code's really cool too.  I think I'll use that. :)
Title: Re: Routines
Post by: Eeems on March 05, 2010, 04:42:02 pm
thanks ztrumpet!
@trevmeister66: Yay! I'm glad it did :D
@DJ: instead of:
Code: [Select]
for(A,1,10)
for(B,1,10)
A*2->X
B*2->Y
-code-
End:End
you would do:
Code: [Select]
for(A,1,10)
A*2->X
for(B,1,10)
B*2->Y
-code-
End:End
Title: Re: Routines
Post by: DJ Omnimaga on March 05, 2010, 05:15:10 pm
oh ok, yeah you're right. Now I use your other method, though, of doing

for(B,1,9
for(A,1,9
-code-
A+1->A
End
B+1->B
End
Title: Re: Routines
Post by: Eeems on March 05, 2010, 06:02:33 pm
Yeah :)
how much faster is that btw?
Title: Re: Routines
Post by: DJ Omnimaga on March 05, 2010, 06:22:09 pm
i got a major speed gain in the 2x2 pixels part of my code, but no difference for the rest. I will probably try Quigibo 4x4 and 8x8 sprites method, though.
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 02:19:14 am
Ok now I tried with sprites. Here's the result:

2x2: way too slow. Stuck with pxl-on's
4x4: at least 2x faster than it was with pxl-ons
8x8: so incredibly fast it wouldn't let me see the 4x4 part. I had to put a For(Z,0,9000:End  before it so it goes at the same speed as the 4x4 rendering XD

Now that it is done, I think it might be good that I try again but this time instead of doubling every frame, I go like 2x2, 3x3, 4x4, 5x5, 6x6, 7x7 to end with 8x8

First, I need to re-backup Illusiat 2004-R files, though, in case that thing would get finished within the next 774 years

EDIT: The code

Quote from: BASIC Code
:[FFFFFFFFFFFFFFFF→Pic7
:[F0F0F0F000000000→Pic8
:For(A,0,94
:For(B,0,62
:If pxl-Test(A,B
:Pxl-On(A+1,B
:Pxl-On(A,B+1
:Pxl-On(A+1,B+1
:Else
:Pxl-Off(A+1,B
:Pxl-Off(A,B+1
:Pxl-Off(A+1,B+1
:End
:B+1→B
:End
:A+1→A
:End
:DispGraph
:For(A,0,92
:For(B,0,60
:If pxl-Test(A,B
:Pt-On(A,B,Pic8
:Else
:Pt-On(A,B,Pic8
:Pt-Change(A,B,Pic8
:End
:B+3→B
:End
:A+3→A
:End
:DispGraph
:For(A,0,9000
:End
:For(A,0,88
:For(B,0,56
:If pxl-Test(A,B
:Pt-On(A,B,Pic7
:Else
:Pt-On(A,B,Pic7
:Pt-Change(A,B,Pic7
:End
:B+7→B
:End
:A+7→A
:End
:DispGraph
Generated by SourceCoder (http://www.cemetech.net/projects/basicelite/sourcecoder.php), © 2005 Cemetech (http://www.cemetech.net)

EDIT: I attached a 2nd screenshot of a different pixelating routine, going through 2x, 3x,4x,5x,6x,7x and 8x. However for some reasons it seems a bit glitchy so I will have to look into that. Also the code is pretty large x.x, I'll prbly post later.
Title: Re: Routines
Post by: trevmeister66 on March 06, 2010, 10:15:05 am
Very nice DJ. One thing though: You don't have to do "For(X,0,####):End" to slow it down. All you have to do is "Pause ####" and it will pause for that many milliseconds. Other than that, great work.
Title: Re: Routines
Post by: ztrumpet on March 06, 2010, 10:38:52 am
For(Z,0,9000:End
But that's over 9000 iterations!
*ztrumpet hides

First, I need to re-backup Illusiat 2004-R files, though, in case that thing would get finished within the next 774 years
I can't wait for this to be done. Illusiat 2004-R will be awesome! ;D

Looks nice DJ.  Good luck with the odd numbers code. :)
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 12:59:20 pm
Woww strange, I totally missed the Pause command from the doc. I checked 3 times and never saw it x.x

I should have did a CTRL+F to search through the page for keyword "Pause"

Btw I kinda wish it was possible to do Pt-Change(A,B,8 instead of Pt-Change(A,B,Pic8 so I could just run a 3rd for( loop with C from 3 to 8 so my code is almost 5x smaller. I wonder if it would be much slower, though...
Title: Re: Routines
Post by: Quigibo on March 06, 2010, 01:57:59 pm
If your pics are in order, you can do "C*8+Pic0" and it will be the same as "PicC"
Title: Re: Routines
Post by: trevmeister66 on March 06, 2010, 02:11:56 pm
How would I get a random point on the screen? I get that "rand" returns a random 16-bit integer, but how would I get the results to be numbers that will fit within the screen limits? (96x65) or whatever.
Title: Re: Routines
Post by: Quigibo on March 06, 2010, 02:15:49 pm
:rand^96->X (returns 0-95)
:rand^64->Y (returns 0-63)

Modulus "^" is the remainder after a division.
Title: Re: Routines
Post by: trevmeister66 on March 06, 2010, 02:16:56 pm
Alright thanks. I thought I should use modulus, but I wasn't exactly sure (its been a few years since I've done any programming with modulus, BASIC or java or whatever).
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 02:34:36 pm
If your pics are in order, you can do "C*8+Pic0" and it will be the same as "PicC"
what would be the 8 for?
Title: Re: Routines
Post by: Quigibo on March 06, 2010, 03:37:50 pm
There are 8 bytes in every picture.  Lets say the first picture is stored at the end of your program at address 9000.  That means the second byte of the picture is at 9001, the third at 9002, etc. until the 8th byte is at 9007.  The first byte of the NEXT picture then starts at 9008.  You can try Disp Pic1>Dec if you want to see it visually, it will be over 9000!!!  You'll see each picture is 8 bytes apart, assuming that they were all created one after another.  If you have a string defined in between them or something, that would offset the data a little.

<Entire program><8 bytes of first pic><8 bytes of second pic>...
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 03:44:41 pm
aaah ok but why not having it so you just need to do C+Pic0 for example, and Axe, when compiling, adds the *8 for you?
Title: Re: Routines
Post by: Quigibo on March 06, 2010, 04:09:06 pm
Because there are conceivably situations where you may want to draw fractions of a sprite.  Consider this sprite, I'll draw it in ascii so you can see it.


........
........
........
........
...00...
..0000..
..0000..
...00...
........
........
........
........


Its not 8x8, but by drawing portions of this sprite with offsets from 0-3, you can have a bouncing ball animation without needing 4 separate sprites for each frame.  In fact, any scrolling, looping sprite like a barbershop spiral or checker pattern reversal can use this optimization.
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 04:13:16 pm
mhmm I still don,t understand x.x

Oh well, I guess what matter is that now I know how to choose which sprite to display dynamically, reducing code repetitiveness
Title: Re: Routines
Post by: trevmeister66 on March 06, 2010, 04:45:36 pm
I have another question: Is it possible to display the contents of a variable as a string? For example, I have 100 stored in L (for lives or something), and I want to display "LIVES: 100". Is it possible yet to do this with Axe? Because I tried using Output(X,Y,L) and it didn't work.
Title: Re: Routines
Post by: Quigibo on March 06, 2010, 05:37:58 pm
100 Lives?  That's a lot!

You're clearly thinking about how basic uses Output() which is not how Axe uses it.  In Axe, the last argument is the address of a string you want to display, not the value of the number.  If you want to instead display the number in base 10, you use >Dec at the end.

I think everyone would benefit by reading the documentation all the way through, maybe more than once, and then ask questions if you are unclear about a description.  A lot of these questions can be answered there.  But also, I think its the general unfamiliarity of pointers, arrays, and unsigned arithmetic that are throwing people off.  A new tutorial should address these issues.  Would anyone like to help me write one if you have a clear understanding already?  I think it would really clear up a lot of the confusion.
Title: Re: Routines
Post by: ztrumpet on March 06, 2010, 05:38:56 pm
Interesting.  I like that it will draw sprites like that.  Cool! ;D

I have another question: Is it possible to display the contents of a variable as a string? For example, I have 100 stored in L (for lives or something), and I want to display "LIVES: 100". Is it possible yet to do this with Axe? Because I tried using Output(X,Y,L) and it didn't work.
Use Output(X,Y,L>Dec)  //The >Dec is [Math] [2]

Good luck!

*Ztrumpet got ninja'ed!  O0
Title: Re: Routines
Post by: trevmeister66 on March 06, 2010, 05:43:08 pm
100 Lives?  That's a lot!

You're clearly thinking about how basic uses Output() which is not how Axe uses it.  In Axe, the last argument is the address of a string you want to display, not the value of the number.  If you want to instead display the number in base 10, you use >Dec at the end.

I think everyone would benefit by reading the documentation all the way through, maybe more than once, and then ask questions if you are unclear about a description.  A lot of these questions can be answered there.  But also, I think its the general unfamiliarity of pointers, arrays, and unsigned arithmetic that are throwing people off.  A new tutorial should address these issues.  Would anyone like to help me write one if you have a clear understanding already?  I think it would really clear up a lot of the confusion.
Heh heh.. :D my bad. Thanks!
Interesting.  I like that it will draw sprites like that.  Cool! ;D

I have another question: Is it possible to display the contents of a variable as a string? For example, I have 100 stored in L (for lives or something), and I want to display "LIVES: 100". Is it possible yet to do this with Axe? Because I tried using Output(X,Y,L) and it didn't work.
Use Output(X,Y,L>Dec)  //The >Dec is [Math] [2]

Good luck!
And thanks to you too!
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 05:59:54 pm
I like the doc so far, btw. I had trouble with some stuff, but I try to gradually improve so my code is still unoptimized I think. Eventually I will probably get better, though. But there are some asm-specifc stuff i might not understand such as this post (http://ourl.ca/4129/78016) x.x

Btw: It takes like 30 sprites on the screen moving around before I notice major slow downs. I tried Axe Parser demo program STARSHIP modified with 60 of them and got like 10 fps still XD. With 1, 2 or 3 rows of sprites it was fast like Galaxian in ASM

Nice job so far Quigibo
Title: Re: Routines
Post by: Quigibo on March 06, 2010, 06:13:41 pm
STARSHIP is hardly even playable with 60 sprites because its too fast with 16mhz mode XD

In regards to that other post, maybe this will help:

........ <- Normal sprite that will be drawn (lets call Pic1)
........
........
........
...00...
..0000..
..0000..
...00...
........
........
........
........


........
........ <- One byte after Pic1 (Pic1+1)
........
........
...00...
..0000..
..0000..
...00...
........
........
........
........


........
........
........ <- (Pic1+2)
........
...00...
..0000..
..0000..
...00...
........
........
........
........


........
........
........
........ <- (Pic1+3)
...00...
..0000..
..0000..
...00...
........
........
........
........


........
........
........
........
...00... <- (Pic1+4)
..0000..
..0000..
...00...
........
........
........
........


Notice how the sprite appears to animate a ball moving upwards. Reversing this would make it appear moving downwards.  Sorry for the really tall post.
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 06:27:40 pm
oooh thanks a lot. I am more a visual person so I tend to understand more with images like this. Thanks, and no problem with the large post :)

Btw is 15 Mhz mode gonna be implemented in next version? Will it be possible for 15 MHz programs to automatically run at 6 on 83+?
Title: Re: Routines
Post by: calc84maniac on March 06, 2010, 08:46:58 pm
I think in one of the topics he said there would be commands to switch to 15MHz and back (which will do nothing on the TI-83+) -- Full and Normal iirc
Title: Re: Routines
Post by: DJ Omnimaga on March 06, 2010, 08:59:58 pm
Aaaah ok. Well if these commands are ignored on the 83 I guess it's fine, since then the game would still run on them, just slower ^^

Btw Quigibo told me there would be another method for my pixelation animations, but apparently it's much more complicated to perform, for my current Axe skills. He is still trying to figure out how to do it, but it would involve manipulating the screen RAM directly.

For now I think I'll stick to my current methods tho XD
Title: Re: Routines
Post by: calc84maniac on March 06, 2010, 11:30:02 pm
Quigibo, I have a question. Currently, when you store to an address, the value of the expression becomes the address. Is this behavior ever planned to change, or can I safely use it for optimization?
Title: Re: Routines
Post by: Quigibo on March 07, 2010, 12:29:50 am
umm... do you mean the value of the address becomes the expression?  I think the other way around is the expected behavior, no?

I'm pretty confident this won't change.  I know that I might in the future add something to store 16 bit numbers into 2 consecutive bytes, but I think that will use a different syntax anyway.
Title: Re: Routines
Post by: calc84maniac on March 08, 2010, 09:02:21 pm
umm... do you mean the value of the address becomes the expression?  I think the other way around is the expected behavior, no?

I'm pretty confident this won't change.  I know that I might in the future add something to store 16 bit numbers into 2 consecutive bytes, but I think that will use a different syntax anyway.
I meant that if you do 1->{L6}, the result (to be used by further operations) will be L6.
Title: Re: Routines
Post by: Quigibo on March 08, 2010, 09:06:49 pm
That's what I thought.  So yes, you can use that optimization.  So you can do things like 2->{1->{L6}+1} but the code can get pretty crazy looking really fast.
Title: Re: Routines
Post by: calc84maniac on March 08, 2010, 09:10:56 pm
Also, I made an implementation of the Collatz Conjecture, inspired by a recent XKCD comic:
Code: [Select]
:9001->A
:Disp A>Dec,i
:Repeat A=1 or getKey
:If A^2
:A*3+1->A
:Else
:A/2->A
:End
:Disp A>Dec,i
:End
Title: Re: Routines
Post by: Quigibo on March 08, 2010, 09:13:29 pm
Another XKCD fan!  :)   I read it regularly as well.
Title: Re: Routines
Post by: calc84maniac on March 08, 2010, 09:25:36 pm
Another thing, Quigibo, I think you should note somewhere in your documentation that operations are evaluated left-to-right. Also, some of the example expressions in your optimization guide assume full order of operations.
Title: Re: Routines
Post by: DJ Omnimaga on March 08, 2010, 11:58:33 pm
I don't follow XKCD much because I tried in the past and english as a second language prevented to get most of the jokes :(

The only ones I get are some of the 4chan memes references :(
Title: Re: Routines
Post by: Galandros on March 14, 2010, 10:50:55 am
I don't follow XKCD much because I tried in the past and english as a second language prevented to get most of the jokes :(

The only ones I get are some of the 4chan memes references :(
I can get most jokes. I need to see again some to understand later (like the Rickroll one)

I don't follow xkcd closely but sometimes I see at random.

btw this is what calcmaniac referred http://xkcd.com/710/
Title: Re: Routines
Post by: Builderboy on March 16, 2010, 12:49:46 pm
Ok i have just finished my all new and super special awesome smoothscrolling tilemapper.  It supports scrolling anywhere from 1 to 8 pixels at a time, and could be expanded for vertical scrolling with not too much difficulty.  It uses the scrolling commands and then fills in the empty spaces made with new sprites.

(http://i199.photobucket.com/albums/aa72/builderboy2005/SCREENIE-2.gif)
Title: Re: Routines
Post by: trevmeister66 on March 16, 2010, 01:04:20 pm
Wow Builderboy, that is sweet, and really fast. Great work!
Title: Re: Routines
Post by: DJ Omnimaga on March 16, 2010, 02:36:29 pm
Lol nice and fast, and if you scroll way too far, then you no longer need a pixel artist to draw 8x8 monsters, or even some tiles in particular for a RPG/adventure game, as they'll be generated for you :P

Also I didn,t knew you could do

[FFFFFFFFFFFFFFFF
F0F0F0F0F0F0F0F0]->Str1

instead of
[FFFFFFFFFFFFFFFF->Str1
[F0F0F0F0F0F0F0F0

Is it the exact same thing?
Title: Re: Routines
Post by: ztrumpet on March 16, 2010, 05:55:27 pm
Yup, that's the same thing. :)

Looks nice Builderboy! ;D
Title: Re: Routines
Post by: DJ Omnimaga on March 16, 2010, 11:29:17 pm
Thanks, should make my source slightly smaller if I got many sprites
Title: Re: Routines
Post by: ztrumpet on March 17, 2010, 04:07:03 pm
Thanks, should make my source slightly smaller if I got many sprites
Yup. :D
Note: I wanted to point out that DJ's sentence is 100% correct, as the source is smaller.  However, the compiled program will still be the same size. :)
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 01:04:04 am
Super cool routine!
Okay, with the help of Will_W and Player_, I got this routine:
Program Write-Back
Call this first (I mean first, have it as the first line):
Asm(21788411DF83010900EDB0

then, this:
Asm(21DF83E7EFF1421A47131A4F13131321959DEDB0

Attached is the source code that makes it work.  Please note that you cannot corrupt the last 9 bytes of tempSwapArea (L4).

NOTE: This routine is buggy and obsolete.  Please look ahead for a more appropriate solution.

*EDIT*
Added a .gif of it in action
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 01:16:11 am
nice, but could you explain in more details how it works? Like, does it store to external vars and which ones? Does it use Self-modifying code? And if it's the later, where does it store the data in the program?
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 10:51:36 am
Well, the first routine gets the name of the program from OP1 and stores it to the last 9 bytes of tempSwapArea.  The last routine restores the name to OP1 and looks up the program, finds the length, and copies the program from 9D95 back into the original location (writeback).  That means you can modify any data that came from a [] statement and it will get saved back.  I'm not too sure though, because when I was playing around with it, I found that it crashed under certain conditions, such as If statements, While, Repeat, getkey().  I think Axe may use the last 9 bytes of tempSwapArea, which would explain it.  I'll look into it in a minute here and see if I can fix it.

*EDIT*
After comparing WikiTI's documentation of tempSwapArea to Axe's documentation of tempSwapArea, I found that tempSwapArea is 323 bytes long, but Axe only gives you 232.  I'll try revising my code to store to a different location and see if it works a bit better.
Title: Re: Routines
Post by: Eeems on March 19, 2010, 11:20:26 am
so pretty much program write back to preserve SMC? can't wait to try that! it will help immensely for saving things :)
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 11:23:16 am
That's exactly what it does, but I can't figure out why it crashes when you use certain tokens in your Axe program.  Anyone care to look at my source code and try to figure it out?
Title: Re: Routines
Post by: Eeems on March 19, 2010, 11:24:34 am
have you tried to debug with wabbitemu? that might help, but sure post it and I'll try to help.
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 11:27:05 am
I've been trying with Wabbit.  Look back a few posts to find the code.
Title: Re: Routines
Post by: Eeems on March 19, 2010, 11:28:44 am
ah ok. It would probably help if you knew what was being used by the routines created for the tokens.
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 11:38:51 am
Code: [Select]
Repeat getkey(15)
End
Dissassemles to:
Code: [Select]
Start:
 ld hl, $FD40
 call Label1
 jr Label2
Label1:
 ld a, h
 out ($01), a
 ld h, $00
 in a, ($01)
 and l
 ld l, h
 ret nz
 inc l
 ret
Label2:
 ld a, h
 or l
 jp nz, Label3
 jp Start
Label3:
 ret
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 12:10:36 pm
So I found out that nested conditionals are the deciding factor in whether or not it works.  However, I do not know why this is.  Help?
Title: Re: Routines
Post by: calc84maniac on March 19, 2010, 12:37:56 pm
Actually, looking at your hex codes, it seems like you are mixing up B and C when loading the size of the program. It is stored as little-endian. Also, since you are skipping the BB,6D bytes you may want to decrease BC twice to make sure there is not an overflow.
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 01:12:57 pm
Oh!  That is actually a really good point, let me try.
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 01:24:18 pm
Great, it worked!  Here are the new routines:
Program Write-back
This routine will allow you to save any changes you make during your program to data stored with the [] tokens.  Run this code in the very first line
Asm(217884118483010900EDB0

And run this to save your program:
Asm(218483E7EFF1421A4F131A4713131321959D0B0BEDB0

This routine uses the last nine bytes of L4 (tempSwapArea), so be careful not to modify them.

Attached is the code/hex.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 01:54:48 pm
Would there be a way to have it stored to a less volatile area of the memory, like L1 or L2, so we don't have problems archiving/unarchiving or the like after we exit the program (assuming that's what Axe doc means)?
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 02:15:27 pm
Sure!  Here you go:
L1: Asm(21788411E389010900EDB0) \ Asm(21E389E7EFF1421A4F131A4713131321959D0B0BEDB0)
L2: Asm(21788411448D010900EDB0) \ Asm(21448DE7EFF1421A4F131A4713131321959D0B0BEDB0)
L3: Asm(21788411699B010900EDB0) \ Asm(21699BE7EFF1421A4F131A4713131321959D0B0BEDB0)
L5: Asm(217884117F85010900EDB0) \ Asm(217F85E7EFF1421A4F131A4713131321959D0B0BEDB0)
L6: Asm(217884113796010900EDB0) \ Asm(213796E7EFF1421A4F131A4713131321959D0B0BEDB0)
This is untested, I just changed some hex values.  It should work, though.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 02:33:57 pm
aaah ok, thanks. Personally I would rather use L1 and L2 if possible, for more safety reasons ^^
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 03:12:08 pm
Fair enough, but I'm using L1 and L2 for Half-Life and wanted an alternative.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 03:17:41 pm
Aaah ok ^^

But seriously, thanks a lot for posting that stuff. Just making it clear, though, if for example you got your ASM code followed with [00->GDB1, when you run your program, [00->GDB1 becomes the equivalent of [01->GDB1, [02, [03 and so on, right? Just making sure so I won't start using writeback for the wrong stuff x.x Also could you show an example where you modify multiple lists elements at once? I would really like to know how it is done and what are the results depending of what the rest of your code does
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 04:14:49 pm
This is how it works.  The first routine copies the name of the currently running program to the end of tempSwapArea (unless you specify somewhere else).  Thats all it does.
The second routine is where the magic happens.  It copies the name from tempSwapArea into OP1 and looks it up using ChkFindSym.  Then, it copies the length of the program into bc.  Then, it puts 9D95 (the location of the currently executing program) into hl.  Then, it places the location of the data according to the VAT into de.  Then, it ldirs everything from 9D95 into the saved program.
What this means is that because Axe copies everything from [] tags to the end of the program, if you modify it while running at 9D95, the last routine applies the changes to the saved program.
This works because TIOS doesn't run compiled Axe programs from their real location in memory.  It copies them to 9D95 first.  So to use these routines, here is an example:
Code: [Select]
Asm(...) (First routine)
[00->GDB1
{GDB1}+1->{GDB1}
Asm(...) (Second routine)
So the output from Axe looks like this, more or less:

1) First routine
2) {GDB1}+1->{GDB1
3) Second routine
4) ret      ;Leave the program
5) 00      ;GDB1 Points here

When you run the program, this is copied to 9D95 and executed.  When it hits line 2, the code at 9D95 changes to this:

1) First routine
2) {GDB1}+1->{GDB1
3) Second routine
4) ret      ;Leave the program
5) 01      ;GDB1 Points here

When it his line 3, the second routine copies lines 1 to 5 into the original location.  The saved program becomes:

1) First routine
2) {GDB1}+1->{GDB1
3) Second routine
4) ret      ;Leave the program
5) 01      ;GDB1 Points here

Without the second routine, line 5 would remain at 00.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 04:33:51 pm
aaaah ok. This is some confusing stuff to understand, but I think I get what it does now. So now could I do
Code: [Select]
Asm(...) (First routine)
[0001050309050807->GDB1
{GDB1}+1->{GDB1}
{GDB1+1}+1->{GDB1+1}
{GDB1+2}+1->{GDB1+2}
{GDB1+3}+1->{GDB1+3}
{GDB1+4}+1->{GDB1+4}
{GDB1+5}+1->{GDB1+5}
{GDB1+6}+1->{GDB1+6}
{GDB1+7}+1->{GDB1+7}
Asm(...) (Second routine)

Then the code would change from like

1) First routine
2) {GDB1}+1->{GDB1
3) Second routine
4) ret      ;Leave the program
5) 0001050309050807     ;GDB1 Points here

to

1) First routine
2) {GDB1}+1->{GDB1
3) Second routine
4) ret      ;Leave the program
5) 010206040A060908     ;GDB1 Points here

?

Or would I need to do some modifications?
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 04:35:25 pm
At first glance, that looks correct.  Program write-back and SMC is kind of hard to explain to a non-assembly programmer, you are getting along with that description quite well! ;D
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 04:51:48 pm
yeah, I had an hard time understanding some Axe stuff due to that (like pointers). However, one awesome thing with axe is that it seems to act as some sort of bridge to learn some low level programming concepts easier, with a more familiar language.
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 04:58:02 pm
Yep!  And here is another routine for use in Axe that works quite well, and will work even better once getkey support for ON is added.
Toggle Screen On/Off
(Adapted from the WikiTI version)
Code: [Select]
Lbl TS
Asm(DB10CB6F20053E03D310B93E02D310)
Return
Note: This routine must be called as a subroutine, do not try to run it in-line if you don't want to exit your program prematruely and leave your user with a turned-off screen and no way to turn it on.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 05:01:59 pm
Does it acts like Auto Power Down?
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 05:09:19 pm
No, you call it, and if the screen is on, it turns it off.  If the screen is off, it turns it on.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 05:10:45 pm
aaah ok, I see.
Title: Re: Routines
Post by: Builderboy on March 19, 2010, 06:58:32 pm
Yay writeback!  Now i can add highscores to anything i want! ^^

So corect me if I'm wrong but running the asm code makes *all* data writeback?
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 07:44:07 pm
mhmm I hope not x.x, cuz what if I have like 200 sprites in my data?
Title: Re: Routines
Post by: Builderboy on March 19, 2010, 07:47:00 pm
Yeah, but from what it looks like there is no point where the data to be kept in the program is specified, so it seems to keep *all* the data D:

Then again, if you have 200 sprites in your program to begin with, enabling writeback won't mess with them unless you mess with them yourself, and it won't add to the size since they are already in the program normally.
Title: Re: Routines
Post by: Quigibo on March 19, 2010, 07:47:33 pm
Can I see the assembly for that write-back hex code?  And does it work when the program is archived?  And if so does it re-archive the program when it copies back?
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 07:51:43 pm
Yeah, but from what it looks like there is no point where the data to be kept in the program is specified, so it seems to keep *all* the data D:
yeah I asked him more info about that but he never awnsered my question. I guess it was poorly worded :(
Title: Re: Routines
Post by: SirCmpwn on March 19, 2010, 08:03:53 pm
mhmm I hope not x.x, cuz what if I have like 200 sprites in my data?

Hold your horses, Axe already puts the sprites there, and it doesn't take super long to copy.  Imagine Phoenix.  The time it takes Phoenix to exit is an outrageous example of an absurdly huge program writing back.  Descresion is not necissary.  Try it yourself - take your biggest Axe program and implement this.

Can I see the assembly for that write-back hex code?  And does it work when the program is archived?  And if so does it re-archive the program when it copies back?

The code is back a ways in terms of posts.  I'm going to modify it a little later on so that it works with archived programs.

yeah I asked him more info about that but he never awnsered my question. I guess it was poorly worded :(

Sorry, I have been offline.
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 08:39:27 pm
Well, my main worry about huge writeback is that is there a memory limit in how much stuff can be written back? Let's say, for example, I create a RPG with 9 KB of map data.
Title: Re: Routines
Post by: ztrumpet on March 19, 2010, 08:56:22 pm
That's pretty cool!  Great job SirCmpwn!  This opens a door in Axe programming. ;D
Title: Re: Routines
Post by: DJ Omnimaga on March 19, 2010, 09:08:14 pm
I would like to eventually see this implemented in Axe, though, in one of the builds, even if not now. It would be much easier to use and less risk of accidentally doing a typo when typing the hex code, not to mention the source would probably be smaller.
Title: Re: Routines
Post by: calc84maniac on March 19, 2010, 10:05:16 pm
Can I see the assembly for that write-back hex code?  And does it work when the program is archived?  And if so does it re-archive the program when it copies back?

The code is back a ways in terms of posts.  I'm going to modify it a little later on so that it works with archived programs.

Hold up, you can't even run no-stub ASM programs when they are archived, so this shouldn't be necessary.
Title: Re: Routines
Post by: ztrumpet on March 20, 2010, 02:33:19 pm
Can I see the assembly for that write-back hex code?  And does it work when the program is archived?  And if so does it re-archive the program when it copies back?

The code is back a ways in terms of posts.  I'm going to modify it a little later on so that it works with archived programs.

Hold up, you can't even run no-stub ASM programs when they are archived, so this shouldn't be necessary.
You can run Archived no-stub Asm programs with DoorsCS and CalcUtil. :)

I also would like to see this implemented into Axe itself. :D
Title: Re: Routines
Post by: Tribal on March 20, 2010, 03:04:56 pm
Can I see the assembly for that write-back hex code?  And does it work when the program is archived?  And if so does it re-archive the program when it copies back?

The code is back a ways in terms of posts.  I'm going to modify it a little later on so that it works with archived programs.

Hold up, you can't even run no-stub ASM programs when they are archived, so this shouldn't be necessary.
You can run Archived no-stub Asm programs with DoorsCS and CalcUtil. :)

I also would like to see this implemented into Axe itself. :D

I think when DoorsCS encountered a archived program it just copied it to ram and ran it, I came across this situation a few times when DCS didn't delete the copy.
Title: Re: Routines
Post by: SirCmpwn on March 20, 2010, 04:09:36 pm
Well, my main worry about huge writeback is that is there a memory limit in how much stuff can be written back? Let's say, for example, I create a RPG with 9 KB of map data.
You are thinking in a TI-Basic frame of mind.  Get out of it.  With pure assembly, there is direct access to the proccessor, and no interpreter in between.  A rough estimate to copy 9 KB is maybe about 6 seconds.  And, you can have a "saving..." screen, too.  I'll probably write some code later that will allow you to just store what you need into an AppVar or something.
Title: Re: Routines
Post by: ztrumpet on March 20, 2010, 09:18:53 pm
I'm sorry SirCmpwn, but this:
You are thinking in a TI-Basic frame of mind.  Get out of it.
caused me to rate your post down.  You can write in Ti Basic and think about Axe like Ti Basic and still have amazing programs.  There is a Basic frame of mind, but  no reason that you need to "get out of it".

Remember, fighting does not solve any problems. :)
Title: Re: Routines
Post by: SirCmpwn on March 20, 2010, 09:28:42 pm
I'm sorry SirCmpwn, but this:
You are thinking in a TI-Basic frame of mind.  Get out of it.
caused me to rate your post down.  You can write in Ti Basic and think about Axe like Ti Basic and still have amazing programs.  There is a Basic frame of mind, but  no reason that you need to "get out of it".

Remember, fighting does not solve any problems. :)

I would like to apologize for being offensive.  I did not mean any harm.  The reasoning behind my last post was because I felt that, in order to understand assembly code (which is the focus of the recent discussion), one had to have an assembly mentality.  In all honesty, copying 9KB from A to B is no sweat in assembly, where as in Basic it is an outrageous amount, and could be hard to grasp for a Basic programmer.  I know because I felt completely overwhelmed with assembly after using TI-Basic for so long, so I try to help out those who are used to using TI-Basic so that they don't feel the same way.  If I end up offending anyone in a post, I implore you to let me know like this so that I can fix it for the future.
Title: Re: Routines
Post by: DJ Omnimaga on March 21, 2010, 12:10:41 am
Well, my main worry about huge writeback is that is there a memory limit in how much stuff can be written back? Let's say, for example, I create a RPG with 9 KB of map data.
You are thinking in a TI-Basic frame of mind.  Get out of it.  With pure assembly, there is direct access to the proccessor, and no interpreter in between.  A rough estimate to copy 9 KB is maybe about 6 seconds.  And, you can have a "saving..." screen, too.  I'll probably write some code later that will allow you to just store what you need into an AppVar or something.
I was more worried about if there would be enough RAM areas left to put that 9 KB in for writeback purposes. For example, the pointers from L1 to L6 seemed to have limited RAM. This is why I asked. I was worried that if we tried to copy way too much data, that it could accidentally overwrite RAM areas that shouldn't be. I'm not sure if I understand the pointer concept in Axe, but what would happen if you loaded over 9000 bytes of hex data in L5?

Unfortunately, though, I rated down the post too, because one day you could be replying to a new member and scare him away, which is something we do not want. It also has risks of starting fights or feuds with certain people, especially if they are in a bad mood one day.

Also for my defense, it is not someone's fault if he doesn't understand something as easily as someone else. Understanding assembly is not for everyone. I myself tried for years and I barely even understand anything. This is something to understand, too.

Thanks for the apology, though.
Title: Re: Routines
Post by: Builderboy on March 21, 2010, 11:38:47 am
Let me see if i understand the concept behind the global data concept.  When the program is run, it is copied to RAM somewhere safe where the TiOS can run it.  After it is finished executing, it is NOT copied back, making the program effectively write protected :/. So all we need to do is write a little bit of code to find out where the program acualy located (the first hex code) and store it in a safe place (L4) until the end of the program where we use it.  Once we get to the end, we merely copy the program right back to where it started again, so that any changes we made are permanent.  We are not using any of the L1-L6 variables for anything more than a 4 byte address storage during the program execution, so there is no possibility that we could run out of memory due to large programs.

(did i get that correctly?)
Title: Re: Routines
Post by: calc84maniac on March 21, 2010, 12:24:18 pm
Let me see if i understand the concept behind the global data concept.  When the program is run, it is copied to RAM somewhere safe where the TiOS can run it.  After it is finished executing, it is NOT copied back, making the program effectively write protected :/. So all we need to do is write a little bit of code to find out where the program acualy located (the first hex code) and store it in a safe place (L4) until the end of the program where we use it.  Once we get to the end, we merely copy the program right back to where it started again, so that any changes we made are permanent.  We are not using any of the L1-L6 variables for anything more than a 4 byte address storage during the program execution, so there is no possibility that we could run out of memory due to large programs.

(did i get that correctly?)
Well actually, it is a 9-byte storage of the program name. But you've got the idea :)
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 12:37:37 pm
Let me see if i understand the concept behind the global data concept.  When the program is run, it is copied to RAM somewhere safe where the TiOS can run it.  After it is finished executing, it is NOT copied back, making the program effectively write protected :/. So all we need to do is write a little bit of code to find out where the program acualy located (the first hex code) and store it in a safe place (L4) until the end of the program where we use it.  Once we get to the end, we merely copy the program right back to where it started again, so that any changes we made are permanent.  We are not using any of the L1-L6 variables for anything more than a 4 byte address storage during the program execution, so there is no possibility that we could run out of memory due to large programs.

(did i get that correctly?)

Yeah, calc84 is right.  When you first run a program, TIOS stores the name of it to OP1 (a RAM area).  I read OP1 and store it to the end of L4.  That is what the first routine does.  Only 9 bytes.
Title: Re: Routines
Post by: DJ Omnimaga on March 21, 2010, 01:24:37 pm
For some reasons, I am even more confused after reading Builderboy post. I think I'll just give up on the whole Self-modifying code concept and wait until Quigibo implements an axe feature that allows us to do so in an easier to understand manner (if it's even possible for those used to using SMC the CelticIII/Y= way), or wait until external variable storage/reading (appvar maybe?) is supported
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 01:42:59 pm
If you don't want to read a huge post, the juicy stuff is in the last two paragraphs, down at the bottom.

Here, let me do my best to explain it.
The memory is a series of bytes.  A very long series of bytes.  Each byte is represented by an offset from the first byte, called an address.  Addresses are almost always written in hex.  For example, 0A00h is 10 bytes from the first byte.  0000h is the first byte.  Notice that numbers in hex are ended with an 'h'.  Now, Axe creates program LOL and outputs it to a spot in memory.  For the purposes of this example, we will say it's at B2C4h.  When you run a program, there is another address in memory called OP1 that TIOS copies the name of the program to.  So, when you run prgmLOL, OP1 looks like this:
ProtProgObj (this represents a protected program), L, O, L, 0, 0, 0, 0, 0
You may have noticed that you can only have up 8 character names in TIOS.  In reality, all names have 9 characters - the identifier (ProtProgObj in this case), and the name, buffered by zeros.  So, if a name is less than 8 characters (like LOL), zeros are added to make it equal 8.
Now, when you run the first routine, it looks at OP1, and copies it to 8384h (tempSwapArea, or L4, plus 223).  This means that it copies the name of the program to the end of L4.
Additionally, programs are not run from where they are saved.  If a program is saved to B2C4h, TIOS copies it to 9D95h to run it.  When the program ends, however, it is not copied back to B2C4h, essentially making it write protected.  This is important, because any changes we make will not be copied.
When you run the second routine, it copies the end of L4 back to OP1.  This is because, during the course of the program, it is possible for OP1 to change, so we back up the name first.  There is a routine provided by TIOS for looking up variables by name.  It requires the name to be in OP1, and when we call it, it will return B2C4h (remember, that's where the program is saved?).  We already know the program is running at 9D95h.  This is the most up-to-date version, the one with the modified data.  We need to keep that modified data, and the only way to do that is to copy it back to B2C4h.  So, when TIOS tells us the program is at B2C4h, we copy all the data from 9D95h to B2C4h.  This saves the modified data for the next time.

If you have any questions about this, please feel free to ask.  I want to make sure that you are comfortable with this, because it is the only way right now to save external data.

Also, if you are concerned about speed and the time it would take to copy it, think of it this way.  TIOS copies the program to 9D95h before running it.  We copy it from 9D95h when you call the second routine.  So, if you want to get a general idea of how long it might take, watch how long it takes to start, because that is exactly how long it will take to run the second routine.
Title: Re: Routines
Post by: DJ Omnimaga on March 21, 2010, 02:03:54 pm
OK so basically it's not the entire program content that is copied to OP1, just the name, right? No data from the program where your routine is ran is copied to OP1?

Also btw just so it is clear, since I thought people got the idea before: I am not concerned about the speed it takes to copy anything especially if it's just gonna be used for saving/loading.
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 02:20:28 pm
OK so basically it's not the entire program content that is copied to OP1, just the name, right? No data from the program where your routine is ran is copied to OP1?

Right.  Just 9 bytes.  Never enough to do damage.
Title: Re: Routines
Post by: DJ Omnimaga on March 21, 2010, 02:32:57 pm
That's good then. I misunderstood yesterday, I was convinced the entire program data stored at its end had to be copied during writeback.
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 03:38:36 pm
I made another routine, here is is:
Axe Programs in MirageOS
The attached program will help you get your Axe programs to show up in MirageOS.  Draw a 15x15 icon in the top-left hand corner of the graph screen and run the attached program.  Copy the resulting code into the first line of your program.  If you are also using my writeback routine, make sure this code comes before the first writeback routine.
Title: Re: Routines
Post by: DJ Omnimaga on March 21, 2010, 03:45:11 pm
:O

wow awesome! Thanks a lot for this ^^

Plus no more need for abusing the MirageOs 1.0/1.1 ungroup rename glitch to rename your program to something else than LOL.8xp now ^^, altough Quigibo is gonna add compiling under different name/shell in the future
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 03:48:05 pm
wow awesome! Thanks a lot for this ^^

Sure thing!
Title: Re: Routines
Post by: Builderboy on March 21, 2010, 03:51:46 pm
Nice! Thats very useful until Quigibo can get out the official version.  Will this interfere with any of the L1-L6 ram areas?
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 03:54:09 pm
Nice! Thats very useful until Quigibo can get out the official version.  Will this interfere with any of the L1-L6 ram areas?

No.  The outputted code is never run.  It's a header, what it looks like is this:
ret      ; Return to the TIOS, because it shouldn't run a mirage program
01       ; MirageOS ID
Icon
Description
0
The icon is taken from the graph screen, converted to hex and copied in.  The description is converted to hex (supported characters are A-Z, a-z, and [space]), and copied in.  MirageOS skips past all this to the first line of your code.  All this does is places some data into your program for MirageOS to read.
Title: Re: Routines
Post by: Builderboy on March 21, 2010, 04:12:05 pm
true, but does Mirage use any of the same safe areas that Axe uses?
Title: Re: Routines
Post by: calc84maniac on March 21, 2010, 04:37:18 pm
true, but does Mirage use any of the same safe areas that Axe uses?
I think StatVars holds Mirage's interrupt vector. To disable this, you might want to put Asm(ED56) after the header to make it use the TI-OS interrupt instead.
Title: Re: Routines
Post by: ztrumpet on March 21, 2010, 06:24:26 pm
Excellent routine SirCmpwn! ;D

true, but does Mirage use any of the same safe areas that Axe uses?
I think StatVars holds Mirage's interrupt vector. To disable this, you might want to put Asm(ED56) after the header to make it use the TI-OS interrupt instead.
Really, that's all?  Then why do Celtic III and xLib mess with Mirage so much?
Title: Re: Routines
Post by: _player1537 on March 21, 2010, 06:38:44 pm
I might be mistaken, but I believe that MOS uses one of the safe ram spots to hold the program lists, for speed.
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 06:55:21 pm
Really, that's all?  Then why do Celtic III and xLib mess with Mirage so much?
I don't know about Celtic, but xLib and MirageOS both use AppBackupScreen, which means they aren't happy together.

Excellent routine SirCmpwn! ;D

Why thank you!
Title: Re: Routines
Post by: SirCmpwn on March 21, 2010, 07:01:11 pm
Also, I just updated the conversion program.  If you want to use numbers, then follow these steps to enable them:
1) Open prgmAXEMIRAG for editing
2) Where it first stores to Str2 (lots of hex), add the following text to the beginning of the string:
30313233343536373839   (30-39)
3) In the next line, where it stores to Str3, add the following text to the beginning of the string:
0123456789

This will enable you to use numbers in the program description.  Follow this format to add any character you like - simply add the hex value to the beginning of Str2, and the actual value to the beginning of Str3.
Title: Re: Routines
Post by: calc84maniac on March 21, 2010, 07:35:02 pm
Oh yeah, messing with CmdShadow should mess up shells, but that is not one of the Axe data areas.
Title: Re: Routines
Post by: _player1537 on March 21, 2010, 10:46:59 pm
Ok, I made a couple of routines for anyone who wants them, the first one is like TI-Basic's input command, the second one displays a number without the spaces.
Input:
Code: [Select]
:.Input
:0→F→B
:Repeat F
:0→K
:Repeat K
:Output(0,{E844B},'?'►Frac
:getKey→K=9→F
:End
:K-1/10→A
:4-A→A
:If A=1
:K^10-4*3+A→A
:End
:If A=2
:K^10-6*3+A→A
:End
:If A=3
:K-1^10-7*3+A→A
:End
:If K=33
:0→A
:End
:If K≠9
:B*10+A→B→A
:sub(A)
:End
:End
:Return
This is the second part, it is used in the Input routine.
Code: [Select]
:Lbl A
:[000000→Pic99
:A→{Pic99}r
:If {Pic99}r>9
:1→{Pic99+2
:End
:If {Pic99}r>99
:2→{Pic99+2
:End
:If {Pic99}r>999
:3→{Pic99+2
:End
:If {Pic99}r>9999
:4→{Pic99+2
:End
:For(A,0,{Pic99+2
:Output(1+{Pic99+2}-A,{E844B},{Pic99}r^10+48►Frac
:{Pic99}r/10→{Pic99}r
:End
Title: Re: Routines
Post by: SirCmpwn on March 22, 2010, 09:23:55 am
Nice!
Title: Re: Routines
Post by: DJ Omnimaga on March 22, 2010, 02:14:07 pm
Interesting, altough I don't really understand what you mean by numbers without the spaces.
Title: Re: Routines
Post by: _player1537 on March 22, 2010, 04:35:47 pm
ok, say you have the number 12.  when you use 'Disp 12>Dec' it will ouput ('.'==' '(space))
...12
but with my routine (the second one) it will output
12
with out those spaces.
Title: Re: Routines
Post by: DJ Omnimaga on March 22, 2010, 11:05:46 pm
where does the "..." part of "...12" comes from? I'm even more confused now :/
Title: Re: Routines
Post by: Builderboy on March 22, 2010, 11:15:06 pm
Well try this code in Axe

Output(0,0,12>Dec

Even though you said to display it at 0,0, which is the top left hand corner, it still displays about 3 spaces to the right of that.  Why is this?  Because Axe displays every number with 5 digits #####.  The number you give it is pushed to the very right of these 5 digits ###12 and the whole 5 digits is displayed at your coordinates. Since there are some empty digits there will be some spaces before the numbers start.  His routine is an alternate way of displaying numbers that is more like the output form Basic that we are all familiar with.
Title: Re: Routines
Post by: DJ Omnimaga on March 23, 2010, 01:11:51 am
Ooooh I see now! Weird x.x, altough I can understand why it does that. But yea I guess it makes that routine more useful then.
Title: Re: Routines
Post by: Builderboy on March 23, 2010, 02:38:22 am
Yeah I belive that Axe does it that way because there is a built in BCALL to display text, and it helps having ti write nasty and memory consuming code for text manipulation :P
Title: Re: Routines
Post by: Quigibo on March 23, 2010, 11:54:51 am
Yeah, there is actually a bcall I can use in combination with some other code to display numbers left to right, but it would be slower and more memory.  You will be able to do it in the next version by using Text(X,Y,NUM>Dec) I think, but you have to make sure you specify the graph coordinates instead of the cursor coordinates.  But still, there are advantages to displaying numbers right aligned.  If you think about it, practically all scores in video games are displayed right aligned (but usually the spaces are extra zeros instead) and since Axe is mostly game oriented, it seems to fit well.
Title: Re: Routines
Post by: DJ Omnimaga on March 23, 2010, 01:29:35 pm
Yeah, this is an issue I have with TI-BASIC sometimes. I want my HPs to be right-aligned so it looks better, but doing so would require me to use a lot of boolean logic to check if HP is higher than 10, higher than 100, higher than 1000, etc
Title: Re: Routines
Post by: LordConiupiter on March 23, 2010, 03:14:05 pm
Ok, I made a couple of routines for anyone who wants them, the first one is like TI-Basic's input command, the second one displays a number without the spaces.
Input:
Code: [Select]
:.Input
:0→F→B
:Repeat F
:0→K
:Repeat K
:Output(0,{E844B},'?'►Frac
:getKey→K=9→F
:End
:K-1/10→A
:4-A→A
:If A=1
:K^10-4*3+A→A
:End
:If A=2
:K^10-6*3+A→A
:End
:If A=3
:K-1^10-7*3+A→A
:End
:If K=33
:0→A
:End
:If K≠9
:B*10+A→B→A
:sub(A)
:End
:End
:Return
This is the second part, it is used in the Input routine.
Code: [Select]
:Lbl A
:[000000→Pic99
:A→{Pic99}r
:If {Pic99}r>9
:1→{Pic99+2
:End
:If {Pic99}r>99
:2→{Pic99+2
:End
:If {Pic99}r>999
:3→{Pic99+2
:End
:If {Pic99}r>9999
:4→{Pic99+2
:End
:For(A,0,{Pic99+2
:Output(1+{Pic99+2}-A,{E844B},{Pic99}r^10+48►Frac
:{Pic99}r/10→{Pic99}r
:End


It's not working for me!
the r's are [2nd][Angle]->3:r ?
the E's are [2nd][EE] ?
further I just typed everything in my calc as you posted it, but at 26% I get a 'BAD SYMBOL' error...
can you please guess what could've gone be wrong?
Title: Re: Routines
Post by: Quigibo on March 23, 2010, 03:19:49 pm
Hmm... I don't see any syntax errors... Are you sure you copied it correctly?  And did you upgrade to the newest version?
Title: Re: Routines
Post by: LordConiupiter on March 23, 2010, 03:31:31 pm
yes, I downloaded it yesterday.
I typed the second code right after the first code.
when I delete that code and 'sub(A)', there are no errors, but then just only the enter key works to stop the prog...
Title: Re: Routines
Post by: _player1537 on March 23, 2010, 10:55:06 pm
I believe I had troubles with the "sub(A)" part as well, let me upload the actual program, see if it works
Title: Re: Routines
Post by: LordConiupiter on March 24, 2010, 11:26:45 am
thanks! this works! (not with 0.1.2, but with 0.1.3 its doing fine)
But there the maximum number is 65535 (serveral times pressed 9, or the [Y=] key :P)
I am writing something for a string input, but my calc crashed :(
I'll figure it out somehow ;D
Title: Re: Routines
Post by: SirCmpwn on March 24, 2010, 12:02:27 pm
But there the maximum number is 65535 (serveral times pressed 9, or the [Y=] key :P)
Axe has a maximum number, there is little we can do about it.
Title: Re: Routines
Post by: LordConiupiter on March 24, 2010, 12:15:59 pm
yes, of course we can use other bytes to extend it ourselves, if really needed...

I got an idea to use Then for: a kinda switch-case statement
like this:

Code: [Select]
:If VAR
:Then 1:
:CODE1
:End
:Then 2:
:CODE2
:End
:EndIf

something like that would be nice, I think.
Title: Re: Routines
Post by: Quigibo on March 24, 2010, 01:57:46 pm
The ideal input routine should store the input into a buffer in ram.  Then, the programmer has control of how to interpret the buffer; either as numerical, string, or something else.  And yes, you can store numbers larger than 16 bits using part of RAM to store the larger number (kind of like how the 16 bit number is really just two 8 bit numbers).  In fact, you can store as much precision as you want.  You can have a 100 trillion digit number if you need it.  It just complicates the math you have to do, but little subroutine can take care of that for you so you don't have to deal with it manually.
Title: Re: Routines
Post by: DJ Omnimaga on March 24, 2010, 02:52:12 pm
Can we actually display these larger numbers at all, though? If so, then how? (Not that I really need to in short term, but it might be useful to know)
Title: Re: Routines
Post by: SirCmpwn on March 24, 2010, 02:53:15 pm
With some thought, it is possible.  Unfortunately, I am low on thought right now.
Title: Re: Routines
Post by: LordConiupiter on March 24, 2010, 06:22:47 pm
I would just recommend to write one or two subroutines which convert real number to string and vice versa
Title: Re: Routines
Post by: _player1537 on March 24, 2010, 06:24:33 pm
I can get to work on this, along with the other input routine. These will most likely be needed eventually anyways
Title: Re: Routines
Post by: SirCmpwn on March 24, 2010, 06:29:24 pm
I can get to work on this, along with the other input routine. These will most likely be needed eventually anyways
Phew, now I don't have to do it ;)
I was planning on it later today.
Title: Re: Routines
Post by: _player1537 on March 26, 2010, 10:02:46 pm
I made a 16x16 sprite drawing routine, and a program to help make the sprites.  Here they are:
for the sprite making program, just use the arrow keys to move, and 2nd to toggle a pixel, then Clear to convert the sprite

Edit:The first sprite editor was not very optimized, this one is
Edit2:there were a few bugs that made it either quit or not draw the sprite correctly (order of operations messed it up), anyways heres the new "Dspaxe16" program
Title: Re: Routines
Post by: DJ Omnimaga on March 26, 2010, 10:22:36 pm
nice :D should be useful for some people :D
Title: Re: Routines
Post by: SirCmpwn on March 26, 2010, 10:53:05 pm
What's the size difference between unoptimized and optimized?
Title: Re: Routines
Post by: _player1537 on March 26, 2010, 10:57:51 pm
          Size
unoptimized:437
Optimized:427

the main optimization was speed, the first one had a bunch of "for(A,1+8*3)" etc in it, can't really test speed because two different calcs (83+ and 84+SE) but it should run faster.
Title: Re: Routines
Post by: SirCmpwn on March 26, 2010, 11:00:54 pm
Oh, I see.
Very nice routine, keep it up!
Also, when I made Pic2Hex, I had to reverse the bits, did you?
Title: Re: Routines
Post by: DJ Omnimaga on March 26, 2010, 11:01:48 pm
/me pokes sircmpwn for a Tilesheet2hex prog :D
Title: Re: Routines
Post by: SirCmpwn on March 26, 2010, 11:02:20 pm
/me is kinda busy with work stuff but promises to make one later
Title: Re: Routines
Post by: DJ Omnimaga on March 26, 2010, 11:08:13 pm
it's ok ^^
Title: Re: Routines
Post by: _player1537 on March 27, 2010, 10:34:34 am
there were a couple of bugs in the displaying program that I had to fix, I updated my earlier post to have them.  it still takes input through D but gets rid of the need for C, also now displaying the sprites in different spots works, before it only worked in the top left corner.
Title: Re: Routines
Post by: SirCmpwn on March 27, 2010, 11:52:45 am
By request, I have made a program that will convert a sprite sheet (a picture full of tiles) to hex so you can move your existing tile maps over to Axe.  If you have any questions, feel free to let me know.
Title: Re: Routines
Post by: Raylin on March 27, 2010, 12:44:10 pm
Very nice! :D

(First download, BTW.)

Now, work on the program writeback to custom AppVar! >:D
Title: Re: Routines
Post by: SirCmpwn on March 27, 2010, 12:52:16 pm
Grr, fine.  I'm starting on that now.
Title: Re: Routines
Post by: Raylin on March 27, 2010, 01:03:05 pm
Hooray! :D

Thank you, sir, for succumbing to my planyour kindness.
Title: Re: Routines
Post by: DJ Omnimaga on March 27, 2010, 01:29:21 pm
By request, I have made a program that will convert a sprite sheet (a picture full of tiles) to hex so you can move your existing tile maps over to Axe.  If you have any questions, feel free to let me know.
oh wow thank you! That goes on my calc as soon as I use it :)

For others: this program is meant to make it much easier to grab tiles hex data than with pic2hex. With pic2hex, your entire pic is converted into one straight string of hex code. For example if you have a pic where the top left 8x8 corner is turned black and the rest is plain white, with pic2hex, the first 8 rows of pixels, meaning 96x8, would look like this:

FF00000000000000FF00000000000000FF00000000000000FF00000000000000
FF00000000000000FF00000000000000FF00000000000000FF00000000000000

Good luck separating each tiles/sprites from each others.

Now with tile2hex, it will be like this:

FFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

All tiles separate! Easier to split the data!
Title: Re: Routines
Post by: SirCmpwn on March 27, 2010, 05:18:43 pm
Actually, it seperates the sprites so it is easier, like:
[FFFFFFFF->Pic1
[00000000

Plus, it only does the sprites you need, so if you have a small sprite sheet that doesn't take up the whole screen, you can just get the ones you need to save memory.
Title: Re: Routines
Post by: SirCmpwn on March 27, 2010, 07:39:47 pm
By demand request:
Save/Load AppVars
To save:
Asm(E7EFF1423803EFC64F2AEC86EF6A4EEB2323
Inputs:
Ans is the string representing the name of the AppVar (see below for more information).  It must be 8 characters or padded with zeros, and should have a [15 at the beginning.  A should be the length of the AppVar.
Outputs:
Ans is the pointer to the data.

To load:
Asm(E7EFF14230052100001803EB2323
Inputs:
Ans is the string to load
Outputs:
Ans is the pointer to the data.

Example:
This is a bit complex, so I thought I would offer an example implementation:

Saving:
:[15->Str1   ; AppVar Identifier
:"TESTSAVE   ; Name
:2->A   ; Length
:Str1:Asm(E7EFF1423803EFC64F2AEC86EF6A4EEB2323)->A   ; Create the variable
:5->{A}      ; Load the data into it
:6->{A+1}

The above code creates an AppVar called TESTSAVE and loads the data 5, 6 into it.
However, if you want to create an AppVar with a name less than 8 characters, you have to do this:
:[15->Str1   ; AppVar Identifier
:"TEST      ; Name
:[00000000   ; Add zeros to make 8 characters total
:2->A   ; Length
:Str1:Asm(E7EFF1423803EFC64F2AEC86EF6A4EEB2323)->A   ; Create the variable
:5->{A}      ; Load the data into it
:6->{A+1}

I added 4 bytes of zeros after the name, so that it would make the correct length.

Loading:
:[15->Str1   ; AppVar Identifier
:"TESTSAVE   ; Name
:Str1:Asm(E7EFF14230052100001803EB2323)->A
:{A}->B
:{A+1}->C

The above code loads the AppVar TESTSAVE into B and C.

This is a bit complex, let me know if you have questions!
Title: Re: Routines
Post by: _player1537 on March 27, 2010, 07:44:32 pm
if you wouldn't mind, could I see the source code I want to see how close I was to the routine.  I'm going to test it in a bit
Title: Re: Routines
Post by: SirCmpwn on March 27, 2010, 07:47:44 pm
Sure, its attached.
Title: Re: Routines
Post by: Raylin on March 27, 2010, 09:01:41 pm
This routine is full of EPIC and WIN.
Now, to see if hexadecimal can be stored in it...
Title: Re: Routines
Post by: DJ Omnimaga on March 28, 2010, 01:23:02 am
Mhmm I really have absolutely no clue what the code is doing x.x, I would like to specify which part I don't understand, but I just understand nothing, not even how the data looks like in the appvar x.x
Title: Re: Routines
Post by: mapar007 on March 28, 2010, 07:07:42 am
I think it does this:

(assuming you mean the ASM part)

Basically, it creates an appvar (removes it first if it existed) with the size specified in the first two bytes of savesscreen, and the name by the 9 bytes at HL. Then it returns a pointer (in HL) to the data start of the appvar. There you can start writing data.

The load routine works analogously.
I assume HL always points to ans in Axe, and (savesscreen); (savesscreen+1) contains the value of A? (sorry if I'm wrong, I didn't bother checking)




SirCmpwn's example does just that: it supplies the name of an appvar in ans, then length in A, next, it creates an appvar, storing the pointer to A. Then he writes to the location A is pointing to.
(I assume {A} is a pointer dereference operator)


EDIT: SirCmpwn, would you be so kind to remove the commented-out lines in your listing (code+hex) files next time? No offense intended, but it's a bit harder to read IMO.
Title: Re: Routines
Post by: SirCmpwn on March 28, 2010, 12:08:34 pm
Sorry about the comments.
Let me walk you guys through the code.  For future reference, you should know that A is at savesscreen and that Ans is in HL.
Code: [Select]
rst rmov9toop1 ; Moves the string at HL to OP1
bcall ChkFindSym ; Looks to see if it already exists
jr c, Continue ; If it doesn't exist, jump to Continue
bcall delvararc ; If it does, delete it
Continue:
ld hl, (savesscreen) ; Load A into HL for the size
bcall CreateAppVar ; Create the variable
ex de, hl ; Swap HL with DE (DE is a pointer to the data location)
inc hl ; The first two bytes of any variable are the length, so move past it
inc hl ; And return a pointer to the first data byte.
Here is the load routine:
Code: [Select]
Start:
rst rmov9toop1 ; Move the string in Ans (HL) to OP1
bcall ChkFindSym ; And look to see if it exists
jr nc, Continue ; If it exists, skip to Continue
ld hl, 0 ; If it doesn't exist, load 0 into Ans (HL)
jr End ; And skip to the end of the routine
Continue:
ex de, hl ; If it does, swap HL with DE (DE is pointer to data)
inc hl ; Move past the size bytes
inc hl ; And return a pointer in Ans
End:
Title: Re: Routines
Post by: DJ Omnimaga on March 28, 2010, 12:33:52 pm
@Sir I meant the entire code actually, including Axe. I now understand what {A} does, though, after a talk with Quigibo. {A} == LA(1), {A+1} == LA(2), etc, or something similar. I don't get the lenght thing, though.
Title: Re: Routines
Post by: calc84maniac on March 28, 2010, 03:07:36 pm
@Sir I meant the entire code actually, including Axe. I now understand what {A} does, though, after a talk with Quigibo. {A} == LA(1), {A+1} == LA(2), etc, or something similar. I don't get the lenght thing, though.
Length just means how big the appvar is. Make sure not to use data outside the appvar, or you might corrupt other things.
Title: Re: Routines
Post by: Raylin on March 28, 2010, 03:26:58 pm
This is also what makes the AppVar so sick. :D
You specify how many BYTES there are.
Each byte is a number up to 255 so...

WIN!

(This is in comparison to normal TI-BASIC lists.)
Title: Re: Routines
Post by: SirCmpwn on March 28, 2010, 03:28:32 pm
At least one person is grateful for the routine...
Title: Re: Routines
Post by: Raylin on March 28, 2010, 03:35:46 pm
Easy there, SirCmpwn.

You're cool.
And, you're very good at programming.
But, you're starting to sound like you have a condescending tone towards us.

Not cool.
Title: Re: Routines
Post by: SirCmpwn on March 28, 2010, 09:17:19 pm
Woah, I'm totally not trying to be condecending.  I apologize if I am, and I will definately try to be better about it.
I think Omnimaga is one of the best calculator based forums out there, and by no means do I look down on it.
Title: Re: Routines
Post by: DJ Omnimaga on March 28, 2010, 11:23:40 pm
@calc84 thanks for the clarification

@sircmpwn I was not being ungrateful toward the routine. I think it's even very good. I was just confused at how it worked.
Title: Re: Routines
Post by: LordConiupiter on March 29, 2010, 02:07:59 am
I have written an Input routine in Axe for inputting strings. It is attached to this post, and here is the code in plain text:

Code: [Select]
:.INPUT
:DiagnosticOff
:"'WRMHC ?θVQLGV .ZUPKFC∟ YTOJEBX→Str88
:"XSNIDAA[i]e[/i]
:"?→Str89
:0→Q→L→F+1→T
:Repeat Q
:Lbl GK
:0→K+9→T
:Repeat K
:Pause 100
:getKey→K
:T+1→T
:!If T^10-1
:Output(L,0,224+F►Frac
:End
:!If T^20-1
:Output(L,0," 
:1→T
:End
:End
:If K=15
:ClrHome
:0→L
:Goto GK
:End
:If K=54
:F+1→F
:F≠4*F→F
:Goto GK
:End
:ReturnIf K=9
:{Str88+K-10}→{Str89+L
:For(P,0,L
:Output(P,0,{Str89+P}►Frac
:End
:L+1→L
:End
Generated by SourceCoder (http://www.cemetech.net/projects/basicelite/sourcecoder.php), © 2005 Cemetech (http://www.cemetech.net)
Title: Re: Routines
Post by: DJ Omnimaga on March 29, 2010, 02:23:46 pm
Ooh nice, might be useful for highscore saving :D
Title: Re: Routines
Post by: LordConiupiter on April 05, 2010, 02:35:34 pm
yes, and for saving games with a non-standard name :P
I created a sprite editor in basic, with 8x8 and 16x16 size support, and a routine in Axe to draw 16x16 sprites.

A small explanation:
The draw routine draws a sprite from the data stored in Pic1 and the 24 bytes after its standard 8 bytes.
It just copies the sprite in couples of 2 bytes (r) to the plotSScreen (L6) in a For loop
after that it Draws the buffer to the screen with a simple DispGraph.
Title: Re: Routines
Post by: _player1537 on April 05, 2010, 02:38:12 pm
ooh, nice.  Looks a lot better than my sprite editor.  Does it use xlib+basic or pure basic?  I'm gonna have to check this out later :)

Edit:  Just noticed, where's the actual code?
Title: Re: Routines
Post by: DJ Omnimaga on April 05, 2010, 02:41:06 pm
wow looks nice :D

I will really need to update the site download section at one point with most program tools posted in this section. That stuff may be useful and might be hard to find since these topics grow larger and larger.
Title: Re: Routines
Post by: LordConiupiter on April 05, 2010, 03:01:57 pm
ooh, nice. Looks a lot better than my sprite editor.
and
wow looks nice :D
Thanks!


where's the actual code?

It's attached now, I forgot that. I'm sorry. :-[

I will really need to update the site download section at one point with most program tools posted in this section. That stuff may be useful and might be hard to find since these topics grow larger and larger.
yeah, that's a good idea. ^^
Title: Re: Routines
Post by: DJ Omnimaga on April 05, 2010, 03:04:30 pm
Oh I would also probably suggest uploading to ticalc.org eventually too, since some people there may find it useful. I would probably wait until Quigibo releases a build of Axe there, though, otherwise people on ticalc will have no clue what is Axe Parser (unless they frequent Omnimaga regulary)
Title: Re: Routines
Post by: LordConiupiter on April 05, 2010, 03:20:32 pm
yes, I can upload it already, because my editor is also usefull for creating icons for programs in DoorsCS form cemetech
Title: Re: Routines
Post by: DJ Omnimaga on April 05, 2010, 03:22:03 pm
Oh wait forgot about that one x.x

It uses the exact same format, right?
Title: Re: Routines
Post by: LordConiupiter on April 05, 2010, 03:23:55 pm
yes, right. 16x16 hex.
Title: Re: Routines
Post by: Silver Shadow on April 05, 2010, 04:51:31 pm
That sprite editor really rocks!!! I especially like the GUI... so much that I propose it should be included with the next Axe release!
Title: Re: Routines
Post by: LordConiupiter on April 06, 2010, 05:22:04 am
yes, I thought off creating an 16x16 sprite drawing routine in Axe, and then I thought that it would be usefull to have a tool to create sprites at that size...

Didn't dare to hope for so many enthousiastic reactions!
Title: Re: Routines
Post by: _player1537 on April 06, 2010, 07:25:38 am
how does it store the data, such as in mine it stores the date as 4 sprites which are called in order.  I noticed in yours that you used storing 2 bytes to L6.
Title: Re: Routines
Post by: LordConiupiter on April 06, 2010, 09:05:02 am
Well, I just use the r option built in in Axe, if that's what you mean.
The picture is the first 8 bytes of the data, and right behind/after it I store the left over 24 bytes.
Title: Re: Routines
Post by: DJ Omnimaga on April 06, 2010, 01:51:31 pm
Btw for 16x16 sprites do you still just display 8x8 sprites or did people figure out a way to display 16x16 ones faster?
Title: Re: Routines
Post by: Raylin on April 06, 2010, 01:58:52 pm
I'm still up for the Pt-On(X,Y,PIC,<dimension1>,<dimension2>).
Title: Re: Routines
Post by: Silver Shadow on April 06, 2010, 02:05:48 pm
Me too, especially for pics the size of the calc screen.
Title: Re: Routines
Post by: LordConiupiter on April 06, 2010, 02:29:15 pm
Btw for 16x16 sprites do you still just display 8x8 sprites or did people figure out a way to display 16x16 ones faster?
My routine doesn't display 4 8x8 sprites, but one 16x16 sprite:
The draw routine draws a sprite from the data stored in Pic1 and the 24 bytes after its standard 8 bytes.
It just copies the sprite in couples of 2 bytes (r) to the plotSScreen (L6) in a For loop
after that it Draws the buffer to the screen with a simple DispGraph.
The code is attached with that post: 'SPRT1X16 source Axe.8xp' (http://www.omnimaga.org/index.php?action=dlattach;topic=1532.0;attach=1013)
Title: Re: Routines
Post by: DJ Omnimaga on April 06, 2010, 02:34:02 pm
Btw for 16x16 sprites do you still just display 8x8 sprites or did people figure out a way to display 16x16 ones faster?
My routine doesn't display 4 8x8 sprites, but one 16x16 sprite:
The draw routine draws a sprite from the data stored in Pic1 and the 24 bytes after its standard 8 bytes.
It just copies the sprite in couples of 2 bytes (r) to the plotSScreen (L6) in a For loop
after that it Draws the buffer to the screen with a simple DispGraph.
The code is attached with that post: 'SPRT1X16 source Axe.8xp' (http://www.omnimaga.org/index.php?action=dlattach;topic=1532.0;attach=1013)
Cool thanks, and source code in text form

Quote
Quote from: BASIC Code
:.SPRT1X16
:DiagnosticOff
:ClrDraw
:[00002A5455AA4002→Pic1
:[481254AA5CBA48524182481247E241824C32342C03C00000
:64→X:16→Y
:For(A,0,15
:{2*A+Pic1}r→{A+Y*12+L6+X}r
:End
:DispGraph
Generated by SourceCoder (http://www.cemetech.net/projects/basicelite/sourcecoder.php), © 2005 Cemetech (http://www.cemetech.net)

Interesting I didn't knew we could do that x.x. I was sure it either required inline assembly or 4 pt-ons
Title: Re: Routines
Post by: LordConiupiter on April 06, 2010, 02:50:10 pm
and source code in text form
I'm sorry :-[
Interesting I didn't knew we could do that x.x. I was sure it either required inline assembly or 4 pt-ons
Well, apparently we can with the nice r option!
* LC really likes the nice r option *
Title: Re: Routines
Post by: DJ Omnimaga on April 06, 2010, 03:00:16 pm
and source code in text form
I'm sorry :-[
Interesting I didn't knew we could do that x.x. I was sure it either required inline assembly or 4 pt-ons
Well, apparently we can with the nice r option!
* LC really likes the nice r option *
oh no problem ^^ it's fine I just felt like posting it in text myself in case, but you don't really have too since people can open the file in SourceCoder ^^

I guess for the r function it's much more useful than I thought
Title: Re: Routines
Post by: LordConiupiter on April 06, 2010, 03:55:12 pm
yeah, sure it is!
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 06:43:46 pm
I just saw the small amount of text from DJ's post, I thought L6 corrupted when graph stuff was involved? Or did I read the Axe thing wrong?
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 06:45:52 pm
That is because L6 is the screen  (for all intents and purposes).  Writing random data to it will fill it with gibbersh.  However, writing meaningful data to it will fill it with meaningfullish.
Try this: write FF to L6.  You get a 8 pixel wide black bar.
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 06:55:05 pm
So basically when the readme.txt says L6 is corrupt it basically just means that it will overwrite screen data?
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 06:55:42 pm
Exactly.
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 07:01:28 pm
Ah ok. Interesting.
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:02:47 pm
Play around with L6 for a while.  You will have to be able to convert binary to hex, though.
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 07:04:57 pm
Ya, I don't really understand any hex currently. I need to look into that.
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:06:20 pm
Understanding the differences between decimal, hexidecimal, and binary is pretty important.  Wanna quick explination?
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 07:09:54 pm
Well I know decimal is base 10, binary is base 2, and hex is base 16. I know how to convert between binary and decimal back and forth, I just have never needed hex yet so haven't looked into it. If you wanna explain though you can. It'd be appreciated by more than me I'm sure.
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:12:47 pm
Reader's Digest:
Well, in base 10, you go from 0-9.  In hex, you go from 0-F.  (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F).  All data is stored as a single byte.  A byte is a pair of hex digits: 00 is 0, 0A is 10, FF is 256.  <- Recognize that number?  It's the maximum value of a byte.  A word is a pair of bytes, like BB6D.
Title: Re: Routines
Post by: Builderboy on April 06, 2010, 07:19:56 pm
Um, i think you meant FF = 255.  256 is 100 in Hex.  Remember, since F represents 15, than FF translates to this

FF = F in the 16s place + F in the 1s place = 15*16 + 15*1 = 255

Also, this is very important when learning about bases:  FF in hex == 255 in decimal.  They are the same number, the same amount.  Base does not change the number, or amount, that you have, only the method in which it is displayed or stored.
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:21:33 pm
Woops, thanks for the correction.
Yes, 255 is FF.
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 07:25:34 pm
So the first place is 1, then 16, 256, and so on? Correct?
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:27:01 pm
Please clarify what you mean by "place"
Title: Re: Routines
Post by: Builderboy on April 06, 2010, 07:31:17 pm
Like, in Base 10 we have the 1s place, the 10s place, the 100s place.

in 1234 the 3 is in the 10s place.  The 2 is in the 100s place.

With Other bases, its just the same, like in hex you have the 1s place, the 16s place, the 256s place, ect...
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 07:35:45 pm
Ya, sorry. I meant the exponent spot, I guess. I don't know the technical term, but what Builderboy said is what I meant.

Ex:
Decimal: 1000, 100, 10, 1
Binary: 32, 16, 8, 4, 2, 1
Octal: 4096, 512, 64, 8, 1 (I believe)
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:39:37 pm
Binary: 32, 16, 8, 4, 2, 1

I'm not entirely sure what your example is, but this cannot possibly be binary.  Binary is base 2, with ones and zeroes.  Not 3s, 2s, 6s, 8s, and 4s.
Title: Re: Routines
Post by: Builderboy on April 06, 2010, 07:42:36 pm
He's talking about the decimal places.  In binary, the 2nd decimal place has an exponent of 2, the 3rd with an exponent of 4, the 4th with 8 and so on.  Just like how in Base 10 the 2nd decimal place has an exponent of 10, the 3rd with 100 and so on...
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 07:43:15 pm
Oh, okay.  Oops again.
Title: Re: Routines
Post by: Juju on April 06, 2010, 07:59:23 pm
A table can be useful:
1b = 1d
10b = 2d
100b = 4d
1000b = 8d
10000b = 16d
etc.

So, if you want to convert, say, 11000, you may want to do 11000b = 10000b + 1000b = 16d + 8d = 24d
It's so simple.
Title: Re: Routines
Post by: calc84maniac on April 06, 2010, 08:04:13 pm
Also, it is easy to convert between hexadecimal and binary. Each hex digit corresponds to 4 binary digits.
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 08:14:30 pm
Sorry about the confussion, SirCmpwn. Thanks, guys.
Title: Re: Routines
Post by: DJ Omnimaga on April 06, 2010, 11:07:32 pm
My only issue with hex is when you have to convert 500 numbers to it, it takes so friggin long :/

I feel more enlightened about L6 now, though. However, question: does changing a byte in L6 automatically update the LCD or will you need to update the graph buffer? Also I assume updating the screen from L6 is considerably faster than pt-on/pxl-on, right?
Title: Re: Routines
Post by: calc84maniac on April 06, 2010, 11:12:33 pm
My only issue with hex is when you have to convert 500 numbers to it, it takes so friggin long :/

I feel more enlightened about L6 now, though. However, question: does changing a byte in L6 automatically update the LCD or will you need to update the graph buffer? Also I assume updating the screen from L6 is considerably faster than pt-on/pxl-on, right?
Well, L6 is the graph buffer. You will need to update the screen manually though. And speed-wise, in theory this would be faster, but since we are comparing Axe code with optimized Asm routines, it's hard to tell.
Title: Re: Routines
Post by: SirCmpwn on April 06, 2010, 11:16:08 pm
Well, I think there may be some confusion here.  The screen is 95x63 pixels in size.  That is a total of 5985 pixels.  The graph buffer is not 5989 bytes long.  It is 748 bytes long.  This works because it is monochrome (black and white).  A pixel is only ever on, or off.  Because of that, you can use binary.  There are 8 bits to a single byte, so if you wanted a dotted line, you could write 01010101b to the graph buffer.
Why this matters is that you can't just write a 1 to the graph buffer and expect a single pixel to change.  From what I know of Axe, it would be very hard indeed to manually change each pixel.
Title: Re: Routines
Post by: calc84maniac on April 06, 2010, 11:27:08 pm
Well, I think there may be some confusion here.  The screen is 95x63 pixels in size.  That is a total of 5985 pixels.  The graph buffer is not 5989 bytes long.  It is 748 bytes long.  This works because it is monochrome (black and white).  A pixel is only ever on, or off.  Because of that, you can use binary.  There are 8 bits to a single byte, so if you wanted a dotted line, you could write 01010101b to the graph buffer.
Why this matters is that you can't just write a 1 to the graph buffer and expect a single pixel to change.  From what I know of Axe, it would be very hard indeed to manually change each pixel.
It is 96x64 actually, and 768 bytes
Title: Re: Routines
Post by: Builderboy on April 06, 2010, 11:37:34 pm
96x64 but i know what you mean.  Yeah writing directly to the buffer is faster in some cases, like filling with paterns or doing other sort of drawing, but when doing pixel by pixel the math required to find the masks is a slower if you are filling large regions.

On a different note, in photo today i played around with greyscale.  The program below contains a sub that draws a colored pixel into the two buffers, dithering when necessary.  The colors range from 0 to 2 where 0 is white, 1 is grey, and 2 is black.  With that i wrote a small greyscale paint program to play around with :) The bitmasking required to write pixels was a bit weird, and im not sure if im finding the masks in the most efficient way possible, but it works

(http://i199.photobucket.com/albums/aa72/builderboy2005/SCREEN1-3.gif)

EDIT: oh and its [2nd] for black, [ALPHA] for grey, [CLEAR] for white, and + to exit.  Arrow keys to move of course :P
Title: Re: Routines
Post by: DJ Omnimaga on April 06, 2010, 11:42:50 pm
Well, I think there may be some confusion here.  The screen is 95x63 pixels in size.  That is a total of 5985 pixels.  The graph buffer is not 5989 bytes long.  It is 748 bytes long.  This works because it is monochrome (black and white).  A pixel is only ever on, or off.  Because of that, you can use binary.  There are 8 bits to a single byte, so if you wanted a dotted line, you could write 01010101b to the graph buffer.
Why this matters is that you can't just write a 1 to the graph buffer and expect a single pixel to change.  From what I know of Axe, it would be very hard indeed to manually change each pixel.
oh wait I forgot about each pixels being one bit, not one byte x.x, sorry for confusing both.

I guess for each string of 8 pixels, what pixel would change would depend of the hex value for that string of 8 pixel, right?

But yeah I remember a month or two ago Quigibo telling me updating the screen buffer directly was much faster than updating it with pxl-on commands. Example: my screen pixelating routine, which I think is on page 3 of this thread.

AND WOW BUILDERBOY! Nice :D
Title: Re: Routines
Post by: meishe91 on April 06, 2010, 11:46:24 pm
Very nice, Builderboy. Looks cool.
Title: Re: Routines
Post by: LordConiupiter on April 07, 2010, 01:57:52 am
yes, sure. Altough I don't get excactly what you mean, how u did it. But I'll discover that...
Title: Re: Routines
Post by: Builderboy on April 07, 2010, 10:15:38 am
Heh, yeah the pixel drawing routine is kinda convoluted because of the 8 pixels per byte thing, and the need to do bitmasking and stuff.  I'll get the code commented later today.
Title: Re: Routines
Post by: LordConiupiter on April 07, 2010, 04:08:00 pm
BTW: instead of Typing
Code: [Select]
0->X
0->K
etc...
you can just type
Code: [Select]
0->X->K->etc...
Title: Re: Routines
Post by: Builderboy on April 07, 2010, 08:17:24 pm
Yep, thats true, i didn't do any optimizing at all in this routine :P I'm really no good at it yet.
Title: Re: Routines
Post by: DJ Omnimaga on April 07, 2010, 08:19:16 pm
(I suggest providing both optimized and non optimized version when providing routines, btw, for now. It might actually help people even more about learning the syntax and stuff, to see more examples)
Title: Re: Routines
Post by: DJ Omnimaga on April 28, 2010, 11:45:10 pm
.NOM
StoreGDB
StorePic
ClrDraw
<draw shit in here>             <-example: Line(0,34,95,34)
Repeat Getkey(15)
DispGraphr
End

The screen content right before running this prog will be copied to the back buffer then displayed in grayscale as background behind some other stuff you can draw right before the repeat loop. It will exit when you press CLEAR.

Just some graphical fanciness :P
Title: Re: Routines
Post by: meishe91 on April 28, 2010, 11:58:58 pm
Why does it make the Asm(prgmNOM and the run indicator go into grey scale but no the line?

Cool piece of code by the way :)
Title: Re: Routines
Post by: _player1537 on April 29, 2010, 12:12:06 am
hmm, if I had to guess, it is because when you draw stuff it isn't actually sent to the screen.  IE it didn't have a normal DispGraph after you drew it.  that's just my guess though.

Edit:
hmm...I was able to get it to do text and the line and greyscale, but not at the same time...

anyways here was my code for the text:
ClrDraw
<output text here>
StoreGDB
StorePic
ClrDraw
repeat getkey(15)
DispGraph(r)
End

and one for the line:
ClrDraw
StoreGDB
<lines and whatnot here>
StorePic
ClrDraw
repeat getkey(15)
DispGraph(r)
End

Title: Re: Routines
Post by: meishe91 on April 29, 2010, 12:24:00 am
OH! Nevermind. I see why. It's because the line isn't already there when you store to the buffer and back-buffer. It's getting displayed after. (Had to look up a couple commands :P)

P.S. The smiley face that is used for examples in the Axe Parser Documentation looks funny when used with the grey scale command :P
Title: Re: Routines
Post by: DJ Omnimaga on April 29, 2010, 12:53:23 am
Why does it make the Asm(prgmNOM and the run indicator go into grey scale but no the line?

Cool piece of code by the way :)
everything that was in the screen right before running the prog turns into grayscale. What's drawn after the screen content is stored to back buffer remains black, though.

the grayscale command can be useful, for example, in a RPG where you see the map, and when entering the menu, the map becomes lighter and you see a monochrome menu on top of it.
Title: Re: Routines
Post by: DJ Omnimaga on May 24, 2010, 02:14:59 am
The following is pretty simple, but can be extremly useful for RPG magic animations or weather effects. It's a sandstorm effect program with grayscale. There are two versions, one that displays the sand in gray and the screen content in black in front and the other that displays the sand in black and the screen content behind in gray (altough hard to see in certain cases). Here's a screenshot attached to the post and the source code/zip file

Quote
:.SANDSTRM
:StoreGDB
:For(Z,0,50
:conj(Z,L3,768
:For(A,0,1
:DispGraphr
:End
:End
:DispGraph
Generated by SourceCoder, © 2005 Cemetech

Quote
:.SANDSTR2
:StoreGDB
:StorePic
:For(Z,0,50
:conj(Z,L6,768
:For(A,0,1
:DispGraphr
:End
:End
:RecallPic
:DispGraph
Generated by SourceCoder, © 2005 Cemetech

All it does, basically, is copying the RAM content starting at Z until 768 bytes further in either the screen buffer or the back-buffer, depending of the routine. Since doing such thing normally looks like garbage, making that garbage scroll will cause a sandstorm effect

The routines can be altered to make the scrolling start elsewhere (as long as it's within the RAM boundaries), move faster or slower and last longer.

A pretty cheap, but fast way to do such animation :P
Title: Re: Routines
Post by: meishe91 on May 24, 2010, 02:18:43 am
That's really cool. I personally like the gray "sand" with black background better, but that's just me. Great job :)
Title: Re: Routines
Post by: DJ Omnimaga on May 24, 2010, 02:22:42 am
Yeah same. It looks much better IMHO. The other one could probably work best in tilemaps that have lot of black areas.

And thanks, lol, altough it wasn't much work really except for one RAM clear cuz I used conj({Z},{L6},768 instead of conj(Z,L6,768 at first :P
Title: Re: Routines
Post by: ztrumpet on May 24, 2010, 07:48:24 am
That's really cool! I like the gray sand over the black background.  This makes me wish I was programming an Axe RPG. ;D
Title: Re: Routines
Post by: TIfanx1999 on May 24, 2010, 11:21:37 am
I'd have to agree with the others and say I like the gray over black one the best. Does the gray over black one animate faster, or is that just my imagination? O_o
Title: Re: Routines
Post by: DJ Omnimaga on May 24, 2010, 12:35:56 pm
thanks ^^

And no the two animates at the same speed
Title: Re: Routines
Post by: SirCmpwn on May 27, 2010, 10:20:06 am
So, I got a simple routine to measure a piece of small text.  It works like this:
The height is always 5 pixels.  Easy enough.
The width is harder.  However, I found a quick and easy method of doing this:
Code: (Axe Basic) [Select]
Fix 3
Text(X,Y,Str1
X→Z
While pxl-Test(Z,Y
Z+1→Z
End
Z-X→Z
Fix 2
Text(X,Y,Str1

This returns the width in Z, and draws the text in Str1 to the graph screen.
Title: Re: Routines
Post by: ztrumpet on May 27, 2010, 10:27:54 am
This returns the height in Z, and draws the text in Str1 to the graph screen.
Do you mean it returns the width? :)

It sounds like a great routine.  Nice job! :D
Title: Re: Routines
Post by: SirCmpwn on May 27, 2010, 10:30:47 am
*ahem* woops
Editing now...
Title: Re: Routines
Post by: Builderboy on May 27, 2010, 10:37:33 am
Thats a ice way to do it :) I myself use a lookup table in my Ti Basic Editor though, i need speed ^^ Since its inverted it works for space too right?
Title: Re: Routines
Post by: ztrumpet on May 27, 2010, 10:44:45 am
Since its inverted it works for space too right?
I'm pretty sure it does.  :)
Title: Re: Routines
Post by: SirCmpwn on May 27, 2010, 11:32:31 am
Yes, it will work for space.  I noticed that the top row of pixels is always black on the inverted font, so it is easy to measure it.
Title: Re: Routines
Post by: DJ Omnimaga on May 27, 2010, 02:20:10 pm
interesting
Title: Gravity
Post by: nemo on May 31, 2010, 01:36:26 pm
I figured i would put this under routines since it might be useful for other people if someone can help me.

how would i implement gravity in axe? it doesn't have to be realistic, i just want to manage getting a sprite to jump up and down.
i could easily implement this with some flag variables, but i'm really looking for a routine that only uses a few variables. Even just a starting point or hint would be helpful. So far, i can get a sprite to jump up, but it won't come back down.
Title: Re: Routines
Post by: Galandros on May 31, 2010, 02:39:16 pm
how would i implement gravity in axe? it doesn't have to be realistic, i just want to manage getting a sprite to jump up and down.
i could easily implement this with some flag variables, but i'm really looking for a routine that only uses a few variables. Even just a starting point or hint would be helpful. So far, i can get a sprite to jump up, but it won't come back down.
If you don't need realistic simulation simply reduce by some value (test for one that makes the desired effect) velocity in y coordinate each frame and that is it.
I think for gravity simulation you need at minimal 2 variables: Y position and velocity in Y coordinate.

Pseudo code:
Lbl A
// code
V-9->V
Y+V->Y
// code
Goto A
//Y has now the coordinate

Mind that V velocity will be negative, so when adding V to Y it will be actually subtracted.
Title: Re: Routines
Post by: Builderboy on May 31, 2010, 02:40:24 pm
This http://ourl.ca/4279 might be of some help to you :)
Title: Re: Routines
Post by: nemo on May 31, 2010, 04:14:29 pm
finally managed to get it to work. if anyone wants to look at the code here it is (let me know of any optimizations i could make):
Code: [Select]
.AA
ClrDraw
[3C7EE7C3C3E77E3C->Pic1
0->V+55->Y
Line(0,63,95,63
While getKey!=15
If getKey(4) and (V=0) and pxl-Test(5,Y+8
5->V
End
If V
V-1->V
Y-1->Y
End
If Y>99
0->V->Y
End
Pt-Change(5,Y,Pic1
DispGraph
Pt-Change(5,Y,Pic1
If (V=0) and (0=pxl-Test(5,Y+8
Y+1->Y
End
Pause 15
End

EDIT: now trying to modify it so you can't jump in the air.
EDIT: code edited to make that possible.
Title: Re: Routines
Post by: DJ Omnimaga on May 31, 2010, 11:55:50 pm
glad to see you got it working ^^

It is possible to make the jump gravity more smooth in the way that you'll gradually move up slower and slower then gradually start falling, but that's a step further. Builderboy has a tutorial explaining that in the Axe Parser sub-forum somewhere.

I need to start messing around with tilemaps and the like x.x
Title: Re: Routines
Post by: nemo on June 01, 2010, 03:24:15 pm
i actually managed to get that to work (finally got my head to wrap around bloating the y variable for precision). then i turned it into a simple game where you hop from platform to platform as the screen scrolls to the left and you try not to touch the ground.
Title: Re: Routines
Post by: DJ Omnimaga on June 01, 2010, 03:56:08 pm
aaah cool, kinda like that skate game someone posted a few days ago? I totally forgot where, though x.x

There is a similar game in the Axe video
at 2:43
Title: Re: Routines
Post by: nemo on June 01, 2010, 04:49:26 pm
if you're talking about the one with the ball, then no. it has a similar concept but mine has multiple platforms on the screen instead of a one broken line going across. nice video by the way (:
Title: Re: Routines
Post by: LordConiupiter on June 01, 2010, 04:50:44 pm
yeah, I also like the vid!
Title: Re: Routines
Post by: DJ Omnimaga on June 01, 2010, 05:10:00 pm
Thanks ^^

And nice Nemo ^^
Title: Re: Routines
Post by: ztrumpet on June 01, 2010, 07:54:00 pm
Nice nemo!  I can't wait to see it!
 * ZTrumpet also thanks DJ for the great video. :D
Title: Re: Routines
Post by: _player1537 on June 03, 2010, 04:53:52 pm
I made this for snake_x, but I figured others would want it, so here they are.  Its just a modified version of DJ's sandstorm program, except it starts at the top with the effect, and goes down to the bottom gradually.  Anyways here you go (if I'm breaking rules then delete this post)
Code: [Select]
0->Z
For(B,0,62
For(C,0,2
Z+1->Z
conj(Z,L6,B+1*12
Dispgraph(r)
Dispgraph(r)
End
End
Title: Re: Routines
Post by: DJ Omnimaga on June 03, 2010, 06:40:33 pm
ooh nice, that might look more realistic actually

And nah it's fine since it's just a small routine ^^
Title: Re: Routines
Post by: nemo on June 03, 2010, 09:44:33 pm
can anyone explain how this works?
Title: Re: Routines
Post by: DJ Omnimaga on June 03, 2010, 11:08:00 pm
The routine simply displays the calculator RAM content on the screen, starting at RAM address Z. Z starts at 0, and in the For( loops it increases by 1 every loop, so every loop you'll see the calculator RAM scrolling on the screen. It will look like garbage, but when scrolling, it's like a snowstorm.
Title: Re: Routines
Post by: calc84maniac on June 03, 2010, 11:40:51 pm
It's actually ROM content, in an area that is always part of the OS. So what you are seeing is random TI-OS code on the screen :)
Title: Re: Routines
Post by: DJ Omnimaga on June 03, 2010, 11:43:49 pm
Really? I always thought that stuff from 0 to 32767 was the RAM...
Title: Re: Routines
Post by: nemo on June 07, 2010, 10:16:15 pm
Code: [Select]
deltaList(32456^r,23845^r,23895^r)->GDB1
For(X,0,2
Disp {X+GDB1}^r>Dec,i
End
DOES NOT WORK.
Code: [Select]
deltaList(32456^r,23845^r,23895^r)->GDB1
For(X,0,2
Disp {X*2+GDB1}^r>Dec,i
End
DOES. it took me an hour to figure out what was wrong with my program because of this.
Title: Re: Routines
Post by: calc84maniac on June 07, 2010, 11:25:04 pm
Really? I always thought that stuff from 0 to 32767 was the RAM...
Nope, RAM is at 32768 to 65535.
Title: Re: Routines
Post by: DJ Omnimaga on June 08, 2010, 01:34:15 am
So the rest would be the archive, right?
Title: Re: Routines
Post by: Quigibo on June 08, 2010, 01:43:09 am
Not quite.  RAM (Random Access Memory) means you can read, write, and execute over it.  The rest is ROM (Read Only Memory) meaning that you can only read and execute over it.  So its only locked off from writing.  That's why you can read from it and see something, and obviously you can execute over it (its part of the OS after all).  Different combinations of these 3 factors exist, although I'm not sure about the variety for the calculator.
Title: Re: Routines
Post by: DJ Omnimaga on June 08, 2010, 01:45:44 am
Aaah ok thanks for the info.

So wow, until tonight, I did not even know what my game "Eat Nethams" was reading from x.x
Title: Re: Routines
Post by: meishe91 on June 08, 2010, 01:46:47 am
Quick Side Question: Is ROM the same thing as the Archive?
Title: Re: Routines
Post by: Quigibo on June 08, 2010, 02:00:12 am
I don't think so.  Archive is a type of ROM, but not vise versa.  The calculator is divided into "pages".  Have you ever wondered how the calculator can have hundreds of kilobytes of flash, but can only read values from 0-65535?  This is becasue you have to swap in pages which will temporarily replaces part of the rom with a page of flash in 16kb chunks (like for instance replacing over the location $4000 to $7FFF which is how applications run).  This is why its a little trickier to read from archive since you also have to keep track of page number and often you're replacing over parts of the ram or rom that are needed for other things.
Title: Re: Routines
Post by: meishe91 on June 08, 2010, 02:19:45 am
Ah ok. I kind of understand, I think.
Title: Re: Routines
Post by: SirCmpwn on June 08, 2010, 08:33:06 am
There are RAM pages, too.  It's all about managing your resources across several pages.  However, the only thing that ever really needs several pages of storage is an OS.  Massive RPGs don't usually even need that much on a calculator.
Title: Re: Routines
Post by: calcdude84se on June 08, 2010, 11:44:08 am
Unfortunately, not all calcs are equal when it comes to RAM. The 83+ has only 32KB, while the 83+SE and older 84+(SE) have 128KB. Regrettably, TI cut this down so that a newer 84+(SE) has only 48KB of RAM. But anyway, yes, paging makes things more difficult. Your running code is in the area $8000-$BFFF (more specifically from $9D95 to where the program ends), and the calculator's hardware is such that attempting to run code on page $80 ($40 for 83+), which is normally in the $C000-$FFFF area, causes a reset.
Btw, as for RPG's, I think I've seen ones over 16KB in size. I can't remember which ones, but, given that they require their components to be archived, yeah. What I don't know that I've seen are RPG's over one sector (64KB) in size.
Title: Re: Routines
Post by: DJ Omnimaga on June 08, 2010, 11:51:41 am
There are a lot of RPGs over 16 KB, especially in BASIC. In ASM we got Joltima, Desolate (well, not that much of an RPG but still seen as one by some people) and Dying Eyes. On the 83 we had Narkemen too. They're all around 18 KB in one file. In BASIC, we got FFTOM, ROL, Illusiat series, a lot of which are so large they won't fit in RAM (Illusiat 13 is 135 KB and uses most of the calc archive)
Title: Re: Routines
Post by: nemo on June 08, 2010, 08:56:59 pm
has anyone managed to create a substring routine? this has been bothering me

EDIT: made a crude one. only will work for same length substrings for now, because that's all i need for now.

L is the length of your substring. in this example, it would be 4.
Code: [Select]
"YOURTEXTHERE->Str1
" ->Str2          // one space
For(Z,0,2
conj(L*Z+Str1,Str2,L
det(16-L)
Disp Str2,i
End
Title: Re: Routines
Post by: Quigibo on June 08, 2010, 11:44:22 pm
det is not a command that contributes anything to executable code.  It only tells the parser to allocate extra space to the end of the program.  You want to use the Fill command to fill memory with zeros.

If you want a sub string of Str1 starting at A that is B bytes long, you can do this:
Code: [Select]
:"Hello World"->Str1
:
:conj(Str1+A,L1,B)           ;Copy the part of the string you want to L1
:0->{L1+B}                   ;Add a null character to signify the end of the substring
:Disp L1                     ;Display the substring
Title: Re: Routines
Post by: DJ Omnimaga on June 09, 2010, 12:20:27 am
For people who wants to get the current RAM:

Code: [Select]
{e9828}r-{e9824}r
Source of information: BrandonW, Calc84maniac and Iambian in the following IRC logs:

Quote
[00:09:04] <@OmnomIRC> <calc84maniac> you could manually do the Free Ram check in Axe by subtracting two values in memory
[00:09:29] <+Iambian> calc84maniac: The calc has those two values specified?
[00:09:36] <+BrandonW> Free RAM is actually quite easy to calculate, the subtraction of the values at two RAM pointers.
[00:09:44] <+BrandonW> ...and calc84maniac beat me to it.
[00:09:48] <@DJ_Omni> really?
[00:09:52] <@DJ_Omni> that would be nice to know
[00:09:55] <+Iambian> I knew it involved two pointers.
[00:09:57] <@OmnomIRC> <calc84maniac> what was it, (OPS) and (FPS)?
[00:10:10] <+BrandonW> Can't remember exactly.
[00:10:14] <+BrandonW> One moment.
[00:10:16] <+Iambian> Oh. I was thinking about the long way around it.
[00:10:16] <+SpyBot45> New post by Magic Banana in Hey Guys! http://ourl.ca/6026/94063
[00:10:41] <+Iambian> But I know it's the end of the floating point stack and the end of the operator stack.
[00:10:47] <@DJ_Omni> so we had magic mushrooms
[00:10:48] <+BrandonW> Yes, (OPS)-(FPS).
[00:10:52] <@DJ_Omni> now we have magic bananas!
[00:10:58] <@DJ_Omni> mhmm
[00:11:00] <@rcfreak0> oO
[00:11:03] <@CoolioJaz> @Iambian i think so, yeah....
[00:11:10] <@DJ_Omni> are those located at specific memory addresses?
[00:11:20] <+Iambian> They are, since they're labeled.
[00:11:21] <@DJ_Omni> If they are, then Axe should be able to easily access them
[00:11:21] <+BrandonW> Yes, (9828h)-(9824h).
[00:11:27] <@DJ_Omni> aah ok thanks
[00:11:31] <@OmnomIRC> <calc84maniac> so in Axe, that would be
[00:11:57] <@OmnomIRC> <calc84maniac> {e9828}r-{e9824}r
[00:12:15] <@OmnomIRC> <calc84maniac> where "e" is the exponential one
[00:12:34] <@OmnomIRC> <calc84maniac> I guess I should call it "ee"?
[00:12:49] <+Iambian> So that's how you're gonna check for free RAM without resorting to hex codes
[00:13:19] <+Iambian> Nifty workaround.
Title: Re: Routines
Post by: TIfanx1999 on June 09, 2010, 09:17:26 am
Oh wow, that's actually very useful! Thanks to Brandon W, Calcmaniac and to DJ Omnimaga for posting this.
Title: Re: Routines
Post by: Raylin on June 09, 2010, 11:00:09 am
^++

Agreed and seconded.
Title: Re: Routines
Post by: calcdude84se on June 09, 2010, 11:42:26 am
Nice to know. The less hex we have to use, the better.
Title: Re: Routines
Post by: ztrumpet on June 09, 2010, 06:03:14 pm
That's really nice to know!  Thanks DJ, Calc84, Iambian, and BrandonW! ;D
Title: Re: Routines
Post by: SirCmpwn on June 09, 2010, 07:46:04 pm
Very nice!  I will actually be using this, not for my contest entry, but for a different project.
Title: Re: Routines
Post by: DJ Omnimaga on June 09, 2010, 11:22:44 pm
I think Builderboy might find this useful for his BASIC editor for when he wants to make sure there's enough RAM to add stuff to programs.
Title: Re: Routines
Post by: cooliojazz on June 10, 2010, 03:52:16 pm
That doesn't seem to work... it gives numbers that are anywhere for 50 to 1000 btes less than the actual...
Title: Re: Routines
Post by: calc84maniac on June 10, 2010, 03:54:30 pm
That doesn't seem to work... it gives numbers that are anywhere for 50 to 1000 btes less than the actual...
Well, while the program is running there is less RAM available. So it will be different from the memory menu, I think.
Title: Re: Routines
Post by: calcdude84se on June 10, 2010, 03:54:32 pm
When your programs running no-shell, a copy of it is created in RAM, for which reason there is less space.
Edit: Ninja'd again!
Title: Re: Routines
Post by: cooliojazz on June 10, 2010, 03:55:44 pm
O... so to get the actual value I would have to subtract the size of the program?
Title: Re: Routines
Post by: calcdude84se on June 10, 2010, 03:57:17 pm
no. that is the actual value: you can only create a variable up to that size.
If you mean the RAM available when nothing is running, then it is yes, actually.
Title: Re: Routines
Post by: calc84maniac on June 10, 2010, 03:57:38 pm
It is the "actual value" for all practical purposes, unless you want to display exactly what is on the memory menu.
Title: Re: Routines
Post by: cooliojazz on June 10, 2010, 03:58:45 pm
Yeah, I want the value when nothing is running. Thanks! (And this time, Calc84Maniac is ninja'd...)
Title: Re: Routines
Post by: calc84maniac on June 16, 2010, 10:10:13 pm
Bresenham circle algorithm is in your Axe. Draws perfect circles. :)
Code: [Select]
:.INPUTS: X,Y=CENTER, R=RADIUS
:Lbl C
:-(R→M)→E
:0->N
:While M≥N
:Pxl-On(X+M,Y+N
:Pxl-On(X+M,Y-N
:Pxl-On(X-M,Y+N
:Pxl-On(X-M,Y-N
:Pxl-On(X+N,Y+M
:Pxl-On(X+N,Y-M
:Pxl-On(X-N,Y+M
:Pxl-On(X-N,Y-M
:If N+1→N*2-1+E→E≥≥0
:-(M-1→M)*2+E→E
:End
:End
:Return
Title: Re: Routines
Post by: SirCmpwn on June 17, 2010, 12:28:05 am
Woah.  Nice.
Title: Re: Routines
Post by: DJ Omnimaga on June 17, 2010, 03:13:04 am
Mhmm could you post a SourceCoder version of this program? I copied it in SC and saved, but had to edit the syntax a bit and couldn't figure out what is it it seems, because when I ran the program I got a RAM clear
Title: Re: Routines
Post by: calc84maniac on June 17, 2010, 03:15:03 am
Did you initialize X,Y,R and call the routine? Also, apparently R value of 0 crashes... I found this out the hard way.
Title: Re: Routines
Post by: DJ Omnimaga on June 17, 2010, 03:17:34 am
oh I did not realize we had to enter inputs. I did not know Axe supported variables other than Ans now.
Title: Re: Routines
Post by: calc84maniac on June 17, 2010, 03:18:20 am
I meant Axe variables.

Edit:
Yeah, the above code wasn't a full program, just a callable routine.
Title: Re: Routines
Post by: DJ Omnimaga on June 17, 2010, 03:25:11 am
oh ok thanks

Wow that's sure fast circle stuff... /me stabs TI with their slow circle display routines (even the fast one)

Nice job
Title: Re: Routines
Post by: meishe91 on June 17, 2010, 03:29:08 am
That is really cool.
Title: Re: Routines
Post by: Quigibo on June 22, 2010, 03:23:00 am
8.8 Fixed Point Multiplication:

Inputs:
Argument 1 = First 8.8 number
Argument 2 = Second 8.8 number
Output:
Result of the multiplication

Code: [Select]
:Lbl ML
:r1/32768 xor (r2/32768)→r3
:abs(r1)→r1
:abs(r2)→r2
:r1/256*(r2^256)+(r2/256*(r1^256))+(r2^256*(r1^256)/256)+(r1/256*(r2/256)*256)→r1
:If r1/32768 xor r3
:‾r1
:Return
:End
:r1
:Return

Ever wanted to graph a complete Mandelbrot Set on your calculator in less than a minute?  Now, you can!  8)
Don't bother zooming in though.  8 bit decimal resolution is not too great.  The screenshot is 25 iterations by the way.
Title: Re: Routines
Post by: souvik1997 on June 22, 2010, 07:43:05 am
That is really fast.
Title: Re: Routines
Post by: calcdude84se on June 22, 2010, 10:18:21 am
Nice, that's pretty fast.
*calcdude goes off to write a 16.16 multiplication routine.
If I succeed, I'll post it here.
Edit: Nevermind, this seems rather difficult to do in pure Axe, if not impossible, since Axe can't return 4 bytes, nor can it multiply two words efficiently to give a four-byte result. Maybe in a later version...
Title: Re: Routines
Post by: calc84maniac on June 22, 2010, 11:11:31 am
/32768 is probably more optimized as /256*2/256 :)

Edit:
It might be better to do
r1□r2->r3
and
If r1□r3<<0

Edit2:
Whoops, didn't notice that /32768 was on the auto-ops list. Ignore my original comment.
Title: Re: Routines
Post by: DJ Omnimaga on June 22, 2010, 12:59:45 pm
mhmm interesting. I don't know much about that stuff, though x.x, I wonder how slow is a TI-BASIC one? XD
Title: Re: Routines
Post by: SirCmpwn on June 22, 2010, 01:29:30 pm
I don't know about a TI Basic version, DJ.
Quigibo, that is sweet!  Can you make the sin, cos, and tan routine work with this?  Cause you would make me a very happy person if you could.  (Remember my perspective 3D demo?)
Title: Re: Routines
Post by: ztrumpet on June 23, 2010, 11:33:16 am
Awesome!  Nice job on this. ;D
Title: Re: Routines
Post by: DJ Omnimaga on June 27, 2010, 02:08:17 pm
Since not everyone absolutely wants to install Celtic III to turn their program into appvar or vice-versa, it would be nice if somebody wrote a small routine (ASM or hybrid) to do so or at least a small tutorial on how to do it in CalcSys (preferably the small routine, so people don't need to install CalcSys either, which can take a lot of memory for when you are developping stuff on a regular 83+). It would be handy until Quigibo adds support for storing data inside programs, as for now Axe only stores to Appvars
Title: Re: Routines
Post by: Deep Toaster on June 27, 2010, 07:54:09 pm
I still haven't figured out what the plot style tokens do. What does the bitwise AND, OR, and XOR mean? Are they different from the logic tokens?
Title: Re: Routines
Post by: calc84maniac on June 27, 2010, 07:57:25 pm
I still haven't figured out what the plot style tokens do. What does the bitwise AND, OR, and XOR mean? Are they different from the logic tokens?
At this point, the compiler does not make a huge distinction between them (the logic tokens do an 8-bit bitwise operation instead of 16-bit to reduce code size). Basically, each bit in the binary values are ANDed, ORed, or XORed together. It's like doing the operation on two 16-element lists in TI-Basic.
Title: Re: Routines
Post by: Deep Toaster on June 27, 2010, 08:16:01 pm
Oh, thanks. So right now, the plot style tokens work basically the same way, except it uses 16-bit?
Title: Re: Routines
Post by: DJ Omnimaga on June 27, 2010, 11:08:40 pm
I still haven't figured out what the plot style tokens do. What does the bitwise AND, OR, and XOR mean? Are they different from the logic tokens?
plot style tokens? What are those?
Title: Re: Routines
Post by: Runer112 on June 28, 2010, 01:01:05 am
I still haven't figured out what the plot style tokens do. What does the bitwise AND, OR, and XOR mean? Are they different from the logic tokens?
plot style tokens? What are those?

EXP1·EXP2
EXP1+EXP2
EXP1☐EXP2   Returns respectively the bitwise "and", "or", and "xor" of the two expressions. These are the plot style tokens.
Title: Re: Routines
Post by: DJ Omnimaga on June 28, 2010, 03:38:17 am
oh, that x.x I remember now.
Title: Re: Routines
Post by: Galandros on June 28, 2010, 04:12:57 am
Incredible.
The fractal is completely recognizable.
Title: Re: Routines
Post by: Quigibo on July 01, 2010, 10:33:55 pm
Automated Sound Loader/Player:

Code: [Select]
:.Setup Code
:DiagnosticOff
:0→L
:fnInt(I,6)


:.QuitCode
:LnReg
:Return


:.To Play Music that is pointed to
:Ptr→L


:.To Stop All Music
:0→L


:.To see if any music is currently playing
:If L


:.Music Loader/Player
:Lbl I
:!If L
:1→C
:Return
:End
:ReturnIf C-1→C
:If {L+1}
:Freq({L},2000)
:{L+2→L-1}→C
:Else
:0→L
:End
:Return


:.Music Data should be in this form
:Data(note1,time1,note2,time2,...,lastenote,0)→GDB1


Typical note times in this case are maybe 10 or 20, these aren't the same times as the pause command or anything.  The routines uses L for the loader and C for the counter, you can change these letters to anything you desire.  This can be used for sound effects too, especially with low frequencies (high wave values) and short wait times.
Title: Re: Routines
Post by: Deep Toaster on July 01, 2010, 10:43:03 pm
Ooh, thanks. Didn't really understand music in Axe until now.
Title: Re: Routines
Post by: Michael.3545 on July 01, 2010, 11:43:16 pm
DJ, I can answer the question about the BASIC Mandelbrot set.  I made this program a while ago.  It is cool, because it can estimate (very accurately  :D) how long it will take.  25 iterations takes about 22 minutes to graph.  Big speed difference.

Title: Re: Routines
Post by: DJ Omnimaga on July 02, 2010, 02:39:06 am
@Quigibo nice! It should make it easier to make sound programs that uses interrupts.

@Michael I see. Huge speed difference indeed in BASIC XD
Title: Re: Routines
Post by: DJ Omnimaga on July 13, 2010, 06:36:19 pm
Quote
StoreGDB
StorePic
For(Z,0,63)
Copy(Z*12+L3,L6+756-(Z*12),12)
End
DispGraph

This inverts the screen content, like they wanted to do in this topic: http://ourl.ca/6348 . However, it poses no compatibility issues between each calc hardwares. Screenshot below (added Repeat getkey(15):End inside the code).
Title: Re: Routines
Post by: TC01 on July 13, 2010, 07:23:23 pm
Quote
StoreGDB
StorePic
For(Z,0,63)
Copy(Z*12+L3,L6+756-(Z*12),12)
End
DispGraph

This inverts the screen content, like they wanted to do in this topic: http://ourl.ca/6348 . However, it poses no compatibility issues between each calc hardwares. Screenshot below (added Repeat getkey(15):End inside the code).

When I try compiling just that in WabbitEmu (due to my calc's link port being broken), I get an Err:Out of Mem at 53%, pointing to that last DispGraph command.

What's strange about this is that the only thing I have on WabbitEmu is Axe and prgmLCDFLIP (what I called it).
Title: Re: Routines
Post by: DJ Omnimaga on July 13, 2010, 07:27:22 pm
o.O? Really?

Are you sure you are typing the program right?

Btw if by suspicious you mean that I am trying to crash people calcs, I do not understand why you think I would do this, considering I have been doing calc stuff for 9 years, got 7 programs featured on ticalc.org and am not the person to make junk programs.

If it still fails after double-checking, could you add the following after the DispGraph?

Repeat Getkey(15)
End

EDIT: Btw don't use SourceCoder to copy this. I did not copy the code with it, but by hand
Title: Re: Routines
Post by: Quigibo on July 13, 2010, 08:47:51 pm
Its a bug that doesn't allow you to have the last line of code be a command which can possibly use the r modifier, you have to add an extra [Enter] at the end.  I've already fixed it, but it won't be updated until 0.4.0

Nice job DJ!  I think I can optimize it a little though:
Code: [Select]
StoreGDB
For(Z,0,31)
Exch(Z*12+L6,L6+756-(Z*12),12)
End
DispGraph

That way it doesn't need the back buffer.
Title: Re: Routines
Post by: DJ Omnimaga on July 13, 2010, 08:51:48 pm
Strange, it worked fine for me. I noticed the compile screen shifted down 8 pixels (see screenshot above), tho

I guess that could explain why it didn't work x.x

And thanks for the optimization, I didn't thought about that one.
Title: Re: Routines
Post by: TC01 on July 13, 2010, 08:53:28 pm
o.O? Really?

Are you sure you are typing the program right?

Btw if by suspicious you mean that I am trying to crash people calcs, I do not understand why you think I would do this, considering I have been doing calc stuff for 9 years, got 7 programs featured on ticalc.org and am not the person to make junk programs.

If it still fails after double-checking, could you add the following after the DispGraph?

Repeat Getkey(15)
End

EDIT: Btw don't use SourceCoder to copy this. I did not copy the code with it, but by hand

Poorly-chosen word- I meant "why I think it's probably related to Axe and not the program/WabbitEmu's memory". Changed it to "strange". I didn't mean to imply anything, sorry.

It compiles if I add the extra Enter at the end, thanks Quigibo.
Title: Re: Routines
Post by: DJ Omnimaga on July 13, 2010, 08:55:08 pm
Aaah ok  x.x

As for the bug, it's funny because it reminds me so much the first time I tried learning ASM and compiling Hello World. Silly No End Directive Before EOF errors due to that TASM bug x.x
Title: Re: Routines
Post by: nemo on July 17, 2010, 10:12:07 pm
let's rotate some sprites, shall we?

Code: [Select]
[AAAAAAAAAAAAAAFF->Pic1    .your sprite!
Pt-On(0,0,Pic1
For(Y,0,7
For(X,0,7
If pxl-Test(X,Y
Pxl-On(Y+9,7-X
End:End:End
DispGraph
currently trying to figure out how to not use any graphics commands and rotate the sprite's data... i'm having very minimal luck with this, though.



and some cool trickery with flipping:
Code: [Select]
[0102040810204080->Pic1 . your sprite data.
Pt-On(0,0,Pic1
For(A,0,3
Exch(Pic1+A,Pic1+8-A,1
End
Pt-On(9,0,Pic1
DispGraph

EDIT:
this is a triumph, i'm making a note here: huge success.

i can rotate sprites 90 degrees... by just rotating their data (: of course my routine requires 8 bytes of memory to store the rotated sprite. Observe  ;)
Code: [Select]
.YYYEAHHH
[4875038562839462->Pic1 . This data doesn't matter, cause this routine will rotate any sprite (:
ClrDraw
For(A,0,7
{Pic1+A}->T
For(B,0,1
If B
T^16->D
Else
T/16->D
End
If D>7
e^(A)->C+{4*B->E+L1}->{E+L1}
End
If D>3 and (D<8) or (D>11)
C+{E+L1+1}->{E+L1+1}
End
If D!=1 and (D!=4) and (D!=5) and (D!=8) and (D!=9) and (D!=12) and (D!=13) and (D!=0)
C+{E+L1+2}->{E+L1+2}
End
If D^2
C+{E+L1+3}->{E+L1+3}
End
End
End

memory efficient? No. it's 750 bytes or so, i believe. i'm sure there is a vast field of optimizations to make. for instance, that long conditional that draws the 3rd and 7th row of the translated sprite. and since you save to a byte L1+(num), you can probably substitute that for A with some tricky logic... i'm lazy to optimize this right now, though.

edit: optimized a bit. it's now 520 ish bytes.
Title: Re: Routines
Post by: DJ Omnimaga on July 18, 2010, 12:28:53 am
Still nice, though.

Runer112 also had a routine to rotate/flip sprites in his sprite editor, but for some reasons, he hasn't been posting on the forums in almost 2 weeks :(
Title: Re: Routines
Post by: nemo on July 19, 2010, 09:49:41 pm
RLE map decompression where the first half-byte is frequency and the second half-byte is the tile number 1-F. this is a quick example:
Code: (Map Data) [Select]
.Uncompressed (24 bytes. each pair is a byte.)
[010101010101
[010303000001
[010200000201
[010101010101
.Compressed (8 bytes. each pair is a byte.)
[7123202112201271->GDB1
Code: (Decompression Routine) [Select]
Zeroes(8)
[FFFFFFFFFFFFFFFF->Pic1    .Your tiles
[0102030405060708
[0123456789ABCDEF
0->X->Y
For(A,0,7                  .7 is the number of bytes your compressed map is, minus one.
For(W,1,{GDB1+A}->Z/16     .GDB1 is where the map is housed
Pt-On(8*X,8*Y,Z^16-1*8+Pic1
Z^16->{6*Y+X+L1}           .L1 will house the uncompressed map. 6 is used as the width of the map.
!If X+1->X^6               . again, 6 is the width of the uncompressed map.
0->X:Y+1->Y
End
End
End

i'll post RLE compression once i get it working, but it's a routine i doubt anyone would need in axe.
Title: Re: Routines
Post by: DJ Omnimaga on July 19, 2010, 09:51:59 pm
mhmm interesting. I would like to see it in action in a program. I wonder how fast is it? It would be useful for extremly large maps with large areas filled with the same tile over and over
Title: Re: Routines
Post by: nemo on July 19, 2010, 09:54:08 pm
i sent you my axe parser contest entry awhile ago, didn't i? it uses a similar algorithm, modified because of the tile size. i'd say the maps loaded pretty fast. my newly improved contest entry has the slightest pause between levels.
Title: Re: Routines
Post by: DJ Omnimaga on July 19, 2010, 11:13:31 pm
Oh wait! I remember now. There have been just so many people joining in the past few months and active users that I have an hard time remembering who's working on what Axe project anymore, now XD
Title: Re: Routines
Post by: nemo on July 19, 2010, 11:18:38 pm
lol i see. and yeah, if you're wondering if you could use it to scroll on the fly, i highly doubt it. it'd be better to decompress the whole map into a free RAM area, then scroll off the RAM area.
Title: Re: Routines
Post by: DJ Omnimaga on July 19, 2010, 11:21:52 pm
Yeah I guessed that scrolling may be a bit overkill. I heard half-byte compression with scrolling required a 15 MHz calc to get a speed similar to my ball game. Often, decompressing the entire map will be necessary, but then, what if the maps are like 16 KB each? x.x
Title: Re: Routines
Post by: nemo on July 19, 2010, 11:27:31 pm
RLE compression is not for you  ::)
Title: Re: Routines
Post by: DJ Omnimaga on July 20, 2010, 12:18:10 am
Could you explain what did I said wrong and why would RLE compression would not be for me? I am not sure what you imply by that.
Title: Re: Routines
Post by: nemo on July 20, 2010, 12:47:10 am
i mean, if you need a 16KB tilemap to be decompressed on a calculator there are a few issues. 1) it would take awhile to decompress, leaving your user waiting. not good. 2) i doubt there's enough room for an uncompressed version of the map on a calculator. so you'd need to decompress the map on the fly while executing the game. this would be very difficult with RLE. making RLE not a realistic compression choice, aka "not for you". "you" being whoever wants to decompress 16KB maps with RLE on a calculator.
Title: Re: Routines
Post by: DJ Omnimaga on July 20, 2010, 12:50:51 am
Well maybe 16 KB was a bit overkill as an example. Let's say 5-6 KB. The game would most likely require the entire remainder of the calc RAM for the uncompressing.

If it's slow, I think it may be best to keep RLE for stuff that requires no constant refreshing of the map during gameplay.
Title: Re: Routines
Post by: Builderboy on July 20, 2010, 01:31:24 am
The problem for using RLE for large maps is that it is not random access.  Meaning that if you want to access the 213th tile, you have to computer all 212 tiles before it, which makes it not the best for large maps unless you decompress the entire thing when you load the game.
Title: Re: Routines
Post by: DJ Omnimaga on July 20, 2010, 01:40:53 am
Yeah, I guess RLE is out of the question, then x.x, especially when collision detection needs to be added.
Title: Re: Routines
Post by: Builderboy on July 20, 2010, 01:53:51 am
Yeah, i use it for PortalX and i use almost all of L4 to store the tilemap when its decompressed, so i couldnt even do something like scrolling using RLE because there isnt anywhere to put the tilemap data x.x
Title: Re: Routines
Post by: Quigibo on July 20, 2010, 06:09:18 am
There actually is a way to decompress RLE on the fly for gigantic maps.  It's not as efficient as the original RLE, but it allows random access (well random-er at least) to the data in the structure.  Its a little complicated, but here is what I am thinking:

First of all, for this to be worth it, each row has to save more than 2 bytes on average, or 4 tiles if you're using this as an alternative to half byte encoding.  The way this works, is you only compress each row or column with RLE instead of the entire data.  You then keep a list of pointers that each point to the individual rows of the data.  The rows themselves are small compared to the whole thing so they can be decompressed on the fly.

Here are some phony numbers:
Maps size: 100x100
Tiles: 10,000
Half Byte compression size: 5,000 bytes
Each row given RLE compression: 3,000 bytes
List of pointers: 200 bytes
Combined total size: 3,200 bytes

Average bytes in a row: 30
Average worst case number of operations to get to intended data: 30
^ This is definitely fast enough for on the fly decompression.

This is valid syntax when defined in this order:

[RLE row 1]->Str0
[RLE row 2]->Str1
[RLE row 3]->Str2
...
[RLE row 100]->Str99
{Str0r,Str1r,...,Str99r}->GDB1


Unfortunately, that list already uses 100 out of the 150 names you're allowed so it might be better to keep track of the cumulative size and use Str0+Offset so that you're only using one name.
Title: Re: Routines
Post by: DJ Omnimaga on July 20, 2010, 02:19:49 pm
Mhmm sounds interesting, it would be nice if someone made an example routine using this method
Title: Re: Routines
Post by: nemo on July 26, 2010, 04:28:04 pm
RLE compression. compresses as the first half-byte is the frequency, and the second is the tile number. this routine exports the data as a hex string in Str1.

Code: (map data) [Select]
.Uncompressed (24 bytes. each pair is a byte.)
[010101010101
[010303000001
[010200000201
[010101010101
.Compressed (8 bytes. each pair is a byte.)
[7123202112201271->GDB1

Code: (Routine) [Select]
.ROUTINE
[010101010101->GDB1
[010303000001
[010200000201
[010101010101
"0123456789ABCDEF"->Str1
"Str1"->Str2
GetCalc(Str2,16)->M    .16 is the size because our compressed map is 8 bytes, which is 16 half-bytes.
0->C->D
For(G,0,23)    .23 is the size of the map minus one.
If {GDB1+G}->A={GDB1+G+1} and (C!=14)  . "!=" is the does not equal sign
C+1->C
Else
{Str1+C+1}->{M+D}
{Str1+A}->{M+D+1}
D+2->D
0->C
End
End
Title: Re: Routines
Post by: calcdude84se on July 26, 2010, 04:47:55 pm
Nice. However, I think I should tell you that RLE is typically done slightly differently, with a reserved number to indicate runs. For example:
Code: [Select]
.Uncompressed (each tile is a half-byte)
[567222220874999F
[033AAAAAAAAAAAAA
[AAA23279BBBBB8FF
.24 bytes
.Compressed
[567F520874999F1F
[033F0A23279F5B8F
[2F
.17 bytes
Where normal data is just inserted, and a run (more than three here) is indicated by 'F' followed by the run length (one nibble, 0 is length 16) followed by the tile number. An 'F' tile is always recorded in run format because it would otherwise be treated as the start of a run.
I'll try to get some code up in a bit.
Title: Re: Routines
Post by: Builderboy on July 26, 2010, 04:54:11 pm
Interesting CalcDude, i've never encountered RLE implemented in that way.  I use it in the same way as Nemo did when i wrote Portal and PortalX, i shall have to do some tests to see if your method offers more compression.  Its too bad that it would take 3 bytes to represent a single F though, whereas Nemo's method it only takes 1.  It would seem that they are both suited for slightly different kinds of data?  Nemo's method where there are longer runs and less random data, and Calcdudes method where there is runs and random data mixed together.
Title: Re: Routines
Post by: calcdude84se on July 26, 2010, 04:57:23 pm
Mine takes three nibbles, while his takes one byte, or two nibbles. It's only 50% larger ;D Not to mention I'm assuming the 'F' tile won't be used as often.
/me goes off to code this
Title: Re: Routines
Post by: Builderboy on July 26, 2010, 05:00:46 pm
Ah yes thats right, good catch.  Its also good to note that in both methods, tiles can only go up to 4bit, so Nemo's representation of his original data in 8bit adds on twice the amount of data then can be compressed.  There is only 12 bytes of information being compressed.
Title: Re: Routines
Post by: nemo on July 26, 2010, 05:09:50 pm
builderboy, i could make the routine compress half-byte tilemaps, but it would be more complicated, so i just stuck with one tile as being equal to one byte, though my compression is preferably used in maps that have 15 or less tiles, and have long runs of the same data. if you need more than 15 tiles and have very, very long runs of the same data,  you could use a method where one byte holds frequency, and the next holds the tile number.
so [43050320] would represent tile 5 67 times, then tile 32 3 times. but that can be very memory inefficient unless you have many runs of data, specifically runs of data that last more than 4 tiles.
Title: Re: Routines
Post by: Builderboy on July 26, 2010, 05:12:41 pm
Ah gotcha, yeah that makes sense.  Yeah i was just commenting on uncompressed vs compressed sizes :)
Title: Re: Routines
Post by: nemo on July 27, 2010, 03:17:51 pm
calcdude, wouldn't RLE under your example only allow tiles 0-E, since F is reserved for indicating a run? and sometimes you could end up with an odd number of nibbles. regardless, i like that type of RLE and i'll probably post some de/compression routines about it.

edit: and my routines will have the uncompressed map data as each tile being one byte.

edit2: compression is working.

Code: [Select]
.ROUTINE
0->C->D
"0123456789ABCDE0->Str1    .Make sure you have 0 at the end, not F.
For(Y,0,S                  .Replace S with the height of your uncompressed map minus 1
For(X,0,T                  .Replace T with the width of your uncompressed map minus 1
If {T+1*Y+X+GDB1}->A={T+1*Y+X+GDB1+1} and (C!=14)
C+1->C
Else
If C>3
70->{L1+D}
{Str1+C+1}->{L1+D+1}
{Str1+A}->{L1+D+2}
D+3->D
Else
For(Z,0,C
{Str1+A}->{L1+D}
D+1->D
End:End:0->C:End:End:End
GetCalc("Str4",D^2+D)->I
For(Z,0,D-1
{L1+Z}->{I+Z}
End
If D^2
70->{I+Z+1}
End

that was much more difficult to write... i wonder how decompression will be.
Title: Re: Routines
Post by: calcdude84se on July 27, 2010, 04:34:18 pm
As I said, you always have to use the 'F' tile in run form, no matter what. But it is possible. As for an odd number of nibbles, you could always just add an extra 'F'. Now to write this, since I have the time. We're doing this by row, right?
* calcdude goes and codes
Title: Re: Routines
Post by: nemo on July 27, 2010, 04:52:33 pm
yes, mine works by row. i think decompression will be harder, though. because if you run into an F, all your arithmetic has to change to compensate for reading the bytes differently. i think it'd be easiest to make the sequence for starting a run be a full byte, like FF, unless you've found an easy way to decompress already.
Title: Re: Routines
Post by: calcdude84se on July 27, 2010, 04:56:49 pm
Hm... I'll write it both ways. One that always uses one 'F', or one that uses one or two to get it to a full byte. But I'll start with my way ;)
Title: Re: Routines
Post by: Builderboy on July 27, 2010, 04:58:22 pm
Maybe it would make it easier to write a quick subroutine that extracts each nibble from the data and returns them one at a time?  That way you dont even have to think about the half byte compression going on?
Title: Re: Routines
Post by: nemo on July 27, 2010, 04:58:39 pm
i'm going to try to write decompression your way, and we can compare afterwards. and i'm going to edit my RLE compression routine so that if you have an odd number of nibbles, it tacks on an 'F' at the end of the hex string.

great success?

Code: [Select]
.BB
[F71011011100F810]->GDB1
Zeroes(8)->Pic1
[FFFFFFFFFFFFFFFF]
0->X->Y
For(Z,0,15
  If sub(GN,Z)->N=15
    For(U,1,sub(GN,Z+1)
      Pt-On(X*8,Y*8,sub(GN,Z+2)*8+Pic1
      !If X+1->X^6
        0->X:Y+1->Y
      End
    End
    Z+2->Z
  Else
    Pt-On(X*8,Y*8,N*8+Pic1
    !If X+1->X^6
      0->X:Y+1->Y
    End
  End
End
DispGraph
Lbl GN
{r1/2+GDB1}->T
If r1^2
  T^16
Else
  T/16
End

as you can tell, i used builderboy's idea of having a subroutine to get a specific nibble.

edit: edited some whitespace in for readability
Title: Re: Routines
Post by: Runer112 on August 23, 2010, 07:53:23 pm
This thread shouldn't be floating down this far! And since I just answered a question in the main thread about how to retrieve data from OS matrices, I may as well post these two routines here:

Code: [Select]
.Returns an element of OS matrix (pointer to matrix, 0-based column, 0-based row)
Lbl M
  float{r₃*{r₁-2}+r₂*9+r₁}
Return

Code: [Select]
.Returns an element of OS matrix (pointer to matrix, 1-based column, 1-based row)
Lbl M
  float{r₃-1*{r₁-2}+(r₂-1)*9+r₁}
Return

Code: [Select]
.Returns an element of OS list (pointer to list, 0-based entry)
Lbl L
  float{r₂*9+r₁}
Return

Code: [Select]
.Returns an element of OS list (pointer to list, 1-based entry)
Lbl L
  float{r₂-1*9+r₁}
Return
Title: Re: Routines
Post by: DJ Omnimaga on August 23, 2010, 09:08:34 pm
darn, I am really out of the loop on new functions, I really need to re-read the command index when I get some time x.x (I last did on 0.2.6)
Title: Re: Routines
Post by: _player1537 on August 26, 2010, 10:09:01 pm
darn, I am really out of the loop on new functions, I really need to re-read the command index when I get some time x.x (I last did on 0.2.6)

Lol, I know the feeling :P
Title: Re: Routines
Post by: DJ Omnimaga on August 26, 2010, 11:07:09 pm
That said, it is very possible to do cool stuff with the old functions already. A lot of the new stuff that got added is much more low level or technical, like fixed points, which I never got able to understand, even with the tutorials. I still recommend using the latest Axe, though, for optimization and safety.

Title: Re: Routines
Post by: Quigibo on September 04, 2010, 02:27:28 pm
By the way, I think I forgot to mention during the last update the additional uses for the inData() command because its more powerful than it looks.

First thing, yes, it can be used to find the position of a character in a string:
Code: [Select]
inData('I',"IGNITION")->L
To find the second, third, etc. instance of 'I', you could loop through this.
Code: [Select]
inData('I',"IGNITION"+L)->L
This moves the pointer to the spot directly after the last character found so it starts looking at the 'G' until it gets to the end.

Another use for this is to see if a number is part of a specific group.  The only problem with this is that 0 is always found at the end since its the terminating character.  So you should check for 0 before using the inData() command usually.  Another thing to mention is that inData() only works with bytes so make sure you guarantee that your input is restricted to numbers between 0 to 255 or -128 to 127.

Code: [Select]
.Inefficient
If (A=3 or (A=5) or (A=20) or (A=28) or (A=61))
.Some code
End

.Efficient
If A
  If inData(A,Data(3,5,20,28,61,0))
  .Some code
  End
End
This is probably unnoticeable slower, but its much smaller and the routine is a subroutine so using it more than once in your program will definitely be a large size optimization.
Title: Re: Routines
Post by: LordConiupiter on September 04, 2010, 02:36:50 pm
wow! nice hint! I myself wouldn't have thought of it. I'm really gonna use this.
Title: Re: Routines
Post by: coolsnake on September 04, 2010, 04:14:19 pm
Ow just the thing I needed, thank you :D
Title: Re: Routines
Post by: Builderboy on September 04, 2010, 04:24:42 pm
Wow, looks like the inData is a really powerful command!  Im going to have to use this now in all of my programs :D
Title: Re: Routines
Post by: DJ Omnimaga on September 04, 2010, 07:49:37 pm
Nice, that could become useful eventually :)
Title: Re: Routines
Post by: Deep Toaster on September 07, 2010, 07:57:31 pm
Wow, inData( is pretty useful...
Title: Re: Routines
Post by: ztrumpet on September 29, 2010, 04:08:42 pm
I've seen some people wanting to use Text input routines, so here's the one I use in Axe Snake, SpiderAx, and Jump.  Press Second when done typing, del to backspace, and Clear to quit.
At the end of the routine, the string is null terminated and begins at L1.  It also Displays it again because I wanted to show how to display it and waits for you to press second again. :)

If you use this routine, you may credit me, but it is not necessary. ;D
Title: Re: Routines
Post by: ACagliano on September 29, 2010, 06:02:06 pm
Is there a length limit on the input?
Title: Re: Routines
Post by: ztrumpet on September 29, 2010, 06:50:21 pm
Yes.  There's a comment in the source just before the line that would need to be changed. :)
Title: Re: Routines
Post by: DJ Omnimaga on September 29, 2010, 11:40:08 pm
Wow nice! Thanks a lot for this. :)
Title: Re: Routines
Post by: shmibs on September 30, 2010, 01:40:03 am
/\Very! thanks
since i havent seen one put out for display yet, here is a smoothscrolling tilemapper(works for left/right and up/down)
this is also partially for my own benefit because i have a lot riding on this routine and if there's anywhere it can be optimized it would be nice to know =D
Code: [Select]
:0->A->BClrDraw
:For(L,0,11:For(M,0,7
:Pt-on(L*8,M*8,{M*[MapWidth]+8+[MapData]}*8+[TileData]
:End:End
:StorePic
:Repeat getkey(15)
:If getkey(3) xor getkey(2)
::If getkey(3)
:Horizontal -
:For(L,0,8
:Pt-Off(95-(A^8),L*8-(B^8),{B/8+L*[MapWidth]+12+(A/8)+[MapData]}*8+[TileData]
:End:A+1->AElse
:Horizontal +
:For(L,0,8
:Pt-Off(1-(A^8),L*8-(B^8),{B/8+L*[MapWidth]+(A/8)+[MapData]}*8+[TileData]
:End:A-1->AEnd
:End
:If getkey(1) xor getkey(4)
:If getkey(1)
:Vertical -
:For(L,0,12
:Pt-Off(L*8-(A^8-(A^8),63-(B^8),{B/8+8*[MapWidth]+L+(A/8)+[MapData]}*8+[TileData]
:End:B+1->BElse
:Vertical+
:For(L,0,12
:Pt-Off(L*8-(A^8),1-(B^8),{B/8*[MapWidth]+L+(A/8)+[MapData]}*8+[TileData]
:End:B-1->BEnd
:End
:Dispgraph
:End
this can be easily converted to do gray as well, although you shouldn't use vertical scrolling and the axe grayscale routines together as the result will look gross. also, make sure that A and B remain greater than 0, or you'll end up with errors
Title: Re: Routines
Post by: DJ Omnimaga on September 30, 2010, 01:46:06 am
Nice! I assume I can try this right away with no other code?

EDIT: You should maybe post a 8xp or SourceCoder-compatible code, because I do not feel like typing everything out x.x
Title: Re: Routines
Post by: shmibs on September 30, 2010, 09:55:11 pm
well, you do need a tileset(8*8 monochrome) and map data(anything larger than 13*9) as well, but all the code is there, yes.
if you really want one i can post an .8xp tomorrow-ish. i have work to do right now, though.
Title: Re: Routines
Post by: DJ Omnimaga on September 30, 2010, 10:11:06 pm
Ah ok, I guess I could quickly do a map or something when I have some time.
Title: Re: Routines
Post by: Runer112 on October 01, 2010, 08:57:59 am
I just helped someone out with a specific case of writing a value to an OS list, so I figured I'd post this generic routine for others to use while I'm at it.

A note about list names: for L1 through L6, you can just define the name with something like:
Code: [Select]
"L₁"→Str1But for custom lists, you must do the following:
Code: [Select]
[015D]→Str1
"NAME"
[00]

And now the actual routine:

Code: [Select]
.Write a series of 2-byte values to an OS list (Pointer to name, number of elements, pointer to list of 2-byte values)
Lbl OSL
  GetCalc(r₁,r₂*9)→r₄
  r₂→{r₄-2}ʳ
  For(r₅,0,r₂-1)
    {r₅*2+r₃}ʳ→float{r₅*9+r₄}
  End
Return
Title: Re: Routines
Post by: DJ Omnimaga on October 01, 2010, 09:44:00 am
Mhmm, wait, so 015D would be the L character, right?
Title: Re: Routines
Post by: Runer112 on October 01, 2010, 09:53:36 am
Yes, and it doesn't appear to work correctly when trying to store it into a string. Perhaps this is something Quigibo should look into fixing?
Title: Re: Routines
Post by: DJ Omnimaga on October 01, 2010, 04:57:59 pm
Aw I see :(. Are you sure it would be an Axe bug? Might be something he should check, indeed.
Title: Re: Routines
Post by: ztrumpet on October 01, 2010, 05:04:32 pm
That's a nice routine Runer. :)  Thanks! ;D
Title: Re: Routines
Post by: aeTIos on October 02, 2010, 08:11:04 am
number input routine:
Code: [Select]
..INNUMBER
"Your text here->Str9
.(following is not necessary)
.sub(IN)
.return

Lbl IN
DiagnosticOff
ClrHome
Str9->A
"+-*/^C -369)TV .258(CPS0147,SALO>LL[X2][X-1]MA->Str4
Text(2,0,A)
0->K
While K=0
getKey->K
End
Text(8,6,{Str4+K-10}>Char)
0->L
While L=0
getKey->L
End
Text(12,6,{Str4+L-10}>Char
0->M
While M=0
getKey->M
End
Text(16,6,{Str4+M-10}>Char
{Str4+K-10}->X
{Str4+L-10}->Y
{Str4+M-10}->Z
Pause 2000
ClrHome
0->K

Please notify me if the code is too long and feel free to optimize them.

NOTE and EDIT: in code you see [X2] and [X-1]
you should type X2 and X-1
in code you cant type that...
Title: Re: Routines
Post by: Deep Toaster on October 02, 2010, 12:19:41 pm
Nice. Some opts:

Use Repeat K instead of While K.

Save a byte by changing "+-*/^C -369)TV .258(CPS0147,SALO>LL[X2][X-1]MA->Str4 to []->Str4:"+-*/^C -369)TV .258(CPS0147,SALO>LL[X2][X-1]MA".

Also, try not to leave closing parentheses/quotes off.
Title: Re: Routines
Post by: ztrumpet on October 02, 2010, 09:56:22 pm
Use Repeat K instead of While K.
To clarify, "Use Repeat K instead of While K=0." :)
Title: Re: Routines
Post by: Deep Toaster on October 02, 2010, 10:55:40 pm
Right. I've gotta start proofing my posts...
Title: Re: Routines
Post by: DJ Omnimaga on October 03, 2010, 04:32:42 am
Nice routine :D
Title: Re: Routines
Post by: Runer112 on October 04, 2010, 09:42:03 pm
Here's a very compact 125-byte library for hex display. It contains the following subroutines:

To include it in your program, send prgmHEXLIB to your calculator and put prgmHEXLIB among the other subroutines in your program. Just make that sure wherever you put it, it won't be accidentally reached and executed unless you call it.

I challenge anyone to find a single optimization in this code or produce a smaller library of their own ;) (/me waits for Quigibo to make it way more compact than anyone thought possible)


EDIT: Changed name from prgmHEXSRC to prgmHEXLIB and reuploaded. This name just seems more appropriate for a library that you don't compile as a standalone program.
Title: Re: Routines
Post by: DJ Omnimaga on October 04, 2010, 09:58:19 pm
Nice! :D
Title: Re: Routines
Post by: Deep Toaster on October 04, 2010, 10:50:45 pm
Awesome! And great job on the optimizations :)

I challenge anyone to find a single optimization in this code or produce a smaller library of their own ;) (/me waits for Quigibo to make it way more compact than anyone thought possible)

Easy. Just take out the comments ;)

J/k.
Title: Re: Routines
Post by: aeTIos on October 06, 2010, 02:59:18 pm
Nice routine :D
thanks, it was my first
Title: Re: Routines
Post by: aeTIos on October 06, 2010, 03:34:31 pm
number input routine:(EDITED)
Code: [Select]
..INNUMBER
"Your text here->Str9
.(following is not necessary)
.sub(IN)
.return

Lbl IN
DiagnosticOff
ClrHome
Str9->A
"+-*/^C -369)TV .258(CPS0147,SALO>LL[X2][X-1]MA->Str4
Text(2,0,A)
0->K
repeat getKey->K
End
Text(8,6,{Str4+K-10}>Char)
0->L
While L=0
getKey->L
End
Text(12,6,{Str4+L-10}>Char
0->M
While M=0
getKey->M
End
Text(16,6,{Str4+M-10}>Char
{Str4+K-10}->X
{Str4+L-10}->Y
{Str4+M-10}->Z
X-48*10+Y-48*10+Z-48->X
Pause 2000
ClrHome
0->K

WOW v2.1 :)

Title: Re: Routines
Post by: DJ Omnimaga on October 06, 2010, 04:03:50 pm
As a side note, when it has been below the time limit you should probably use the EDIT button to not double-post, else you can lose the game. :P
Title: Re: Routines
Post by: Runer112 on October 18, 2010, 09:31:56 am
Well I wanted to post the source for a routine I had just made, but the option to attach files seems to have vanished... ???
Title: Re: Routines
Post by: JosJuice on October 18, 2010, 11:11:37 am
Well I wanted to post the source for a routine I had just made, but the option to attach files seems to have vanished... ???
It's because of the server move, I think.
Title: Re: Routines
Post by: DJ Omnimaga on October 18, 2010, 02:00:49 pm
Yeah I disabled them because anything uploaded as of today will be lost after the move (and may cause errors). The backup was made last night and will not be in sync with the database backup.

You can use Mediafire.com for the time being. Or you can just post in a CODE tag.
Title: Re: Routines
Post by: Runer112 on October 20, 2010, 02:38:42 am
Cool, I now have access to the forums again.

Anyways, the routines I had were a pair of deadly accurate sine and cosine routines. And by deadly accurate I mean percent errors in the hundredths or thousandths of a percent. Whereas the built-in routines accept integer inputs and give signed 8-bit integer outputs, these routines accept 8.8 fixed point inputs and give signed 8.8 fixed point outputs. That means it accepts inputs with 256 times the precision, and gives outputs with 256 times the precision as well!


The first file (TRIGLIB.8xp) is the library you probably want to use in most situations, as it's slower than the second library but over 300 bytes smaller. This is because, whereas the first library uses a 128-byte LUT for one quarter of the period and makes use of the symmetry of the sine wave to do extra calculations for values anywhere in the period, the second uses a 512-byte LUT for the full period.


EDIT: Oh right, I forgot to say: use sub(SIN,value) and sub(COS,value) to use them. And to properly insert a library like this into your program, put a line saying prgmTRIGLIB in the subroutine section of your code.
Title: Re: Routines
Post by: DJ Omnimaga on October 20, 2010, 02:41:22 am
YAY! Welcome back from the other side of the universe, Runer112. ;D

Those routines seems pretty nice. Are they much slower than the regular Axe sin routine or is it almost the same?
Title: Re: Routines
Post by: Runer112 on October 20, 2010, 03:23:38 am
Well obviously they're not going to be as fast as the built-in sine and cosine routines, as not only are those written in pure, optimized assembly, but they don't have to be nearly as accurate. Timing the routines at 6MHz gave these results:


19% speed may sound a bit slow, but that's still almost 3,000 calculations per second. So these routines are about 4 (speed-optimized routine) or 5 (size optimized routine) times slower than the built-in routines. My routines are also 12 (size-optimized routine) or 22 (speed-optimized routine) times the size of the built-in routines (378 or 695 vs. 31 bytes). But you get 256 times the accuracy, so depending upon what you need, it could be worth it.
Title: Re: Routines
Post by: DJ Omnimaga on October 20, 2010, 04:37:28 am
Ah ok. Seems kinda good I guess for Axe. One question, though: I never learned Sin/Cos much in hi school and never got into 3D stuff, but with your routine, what kind of game could be possible that wouldn't be with the built-in routine?
Title: Re: Routines
Post by: ASHBAD_ALVIN on October 20, 2010, 08:08:11 am
making accurate polygons :D

Title: Re: Routines
Post by: Runer112 on October 20, 2010, 08:12:52 am
Ah ok. Seems kinda good I guess for Axe. One question, though: I never learned Sin/Cos much in hi school and never got into 3D stuff, but with your routine, what kind of game could be possible that wouldn't be with the built-in routine?

Raycaster :P
Title: Re: Routines
Post by: Builderboy on October 20, 2010, 11:20:02 am
Although if you wanted to get the highest speed you would prerender a sin table into somewhere in memory to get high accuracy and high speed ^^
Title: Re: Routines
Post by: Runer112 on October 20, 2010, 11:23:50 am
Although if you wanted to get the highest speed you would prerender a sin table into somewhere in memory to get high accuracy and high speed ^^

Well that's the point of the library called "TRIGLIB - Fast 512-byte LUT.8xp" :P
Title: Re: Routines
Post by: Builderboy on October 20, 2010, 11:28:03 am
Oh whoops i misread your post :O It already is a LUT! *party*

EDIT: Wow that is really clever with the blending!
Title: Re: Routines
Post by: Runer112 on October 20, 2010, 01:24:36 pm
Now go make a raycaster in Axe ;)
Title: Re: Routines
Post by: DJ Omnimaga on October 20, 2010, 01:41:07 pm
Ah I see. So I take it that the regular routines cannot achieve 3D and raycasting, or is it just too innacurate to achieve decent ones?
Title: Re: Routines
Post by: Builderboy on October 20, 2010, 01:42:36 pm
I actually don't think that the built in ones are so bad that it wont work, it just might be a little more distorted.  But given that the screen is so small i dont know how noticeable it is
Title: Re: Routines
Post by: DJ Omnimaga on October 20, 2010, 01:47:39 pm
Yeah that's what I was wondering, personally.
Title: Re: Routines
Post by: calc84maniac on October 27, 2010, 04:21:53 pm
Here is an Asm routine that will return the state of the ON button, just like getKey() does for other keys -- 1 if pressed, 0 if not pressed.

Asm(DB041F1F1F1FED6223)

Edit:
Here is the assembly code, in case anyone (hint hint Quigibo) might want it :P
Code: [Select]
in a,(4)
rra
rra
rra
rra
sbc hl,hl
inc hl
Title: Re: Routines
Post by: DJ Omnimaga on October 27, 2010, 10:55:21 pm
Nice, since that button works differently than others, this might be useful. Will this work regardless of if interrupts are disabled or something, though?
Title: Re: Routines
Post by: ztrumpet on October 28, 2010, 05:59:12 pm
Nice, since that button works differently than others, this might be useful. Will this work regardless of if interrupts are disabled or something, though?
It must be in LnReg mode, I believe. :)
Title: Re: Routines
Post by: DJ Omnimaga on October 28, 2010, 06:01:53 pm
You mean LnReg might have to be called before using Calc84maniac's routine?
Title: Re: Routines
Post by: ztrumpet on October 28, 2010, 06:05:32 pm
I think so.  I may be wrong, though. :-\
Title: Re: Routines
Post by: calcdude84se on October 29, 2010, 11:27:19 pm
You don't need to be in any specific interrupt mode, actually. ;D
You can be in any mode, interrupts enabled or disabled, and it will work.
What the code does is read a bit the corresponds to whether the [ON] key is being pressed. Interrupts are not involved ;)
Title: Re: Routines
Post by: DJ Omnimaga on October 29, 2010, 11:58:14 pm
Ah ok thanks for the confirmation :)
Title: Re: Routines
Post by: Builderboy on November 02, 2010, 08:31:34 pm
I was fiddling around in axe today and i randomly made a random realistic map generator.  It generates a map as seen from space in greyscale and depending on how much terrain you want it to have.  It can also be easily modified to generate terrain from basic shapes already drawn on the screen.

Title: Re: Routines
Post by: DJ Omnimaga on November 02, 2010, 08:51:20 pm
wow that's great! That makes me wonder if there could be a random dungeon generator or something in the future...
Title: Re: Routines
Post by: Deep Toaster on November 03, 2010, 06:40:16 pm
Looks great! Really nice code too :D
Title: Re: Routines
Post by: MRide on November 03, 2010, 06:42:50 pm
So, the number is how much land you want? Looks cool!
Title: Re: Routines
Post by: Deep Toaster on November 03, 2010, 06:45:31 pm
Yeah, and if I'm not mistaken, it's out of 16.
Title: Re: Routines
Post by: MRide on November 03, 2010, 06:48:21 pm
'K Thanks.  That looks like it might be useful, for stuff like dungeons, like DJ said.
Also, Deep, your dragon pic needs updating.
Title: Re: Routines
Post by: Deep Toaster on November 03, 2010, 06:50:58 pm
Yeah, and I really like the way you did the grayscale, Builderboy.

[/offtopic]Right, I just uploaded that pic today, though :P[/offtopic]
Title: Re: Routines
Post by: DJ Omnimaga on November 04, 2010, 03:51:35 am
Well, dungeon generation would require a lot of changes, though, so rooms won't look weird.
Title: Re: Routines
Post by: Michael_Lee on November 08, 2010, 10:48:51 pm
This is a variant of Bresenham's line algorithm that radiates lines outwards (which you could use for raycasting (*cough*) and can draw points at intervals.
Arrows to move, clear to quit, plus and minus to increase/decrease interval.
I purposely added a pause so you can see how it radiates outwards.
(It needs optimization, though, and I'd really appreciate it if anybody could find a way to increase its speed)

Code: [Select]
.LINE
ClrDraw
50->A->B
2->L

Repeat getKey(15)
  If getKey
    getKey(3)-getKey(2)+A->A
    getKey(1)-getKey(4)+B->B
    getKey(10)-getKey(11)+L->L
    L=0+L->L
    sub(LIN,30,30,A,B,L)    //r1 and r2 are the x and y coordinates of the starting point - it radiates out to (r3,r4).  r5 is the interval between points and 1 is minimum.
  End
  DispGraph
End
Return

Lbl LIN
  If abs(r4-r2)>abs(r3-r1)
    Exch(°r1,°r2,2)
    Exch(°r3,°r2,2)
  End
  r1>r3->K
  abs(r3-r1)->S/2->V
  abs(r4-r2)->T
  r2->Y<r4*2-1->W
  For(Z,0,abs(r3-r1)/r5)
    Z*r5->X
    If K
      -X->X
    End
    If U
      Pxl-On(Y,X+r1)
    Else
      Pxl-On(X+r1,Y)
    End
    R5->I
    While I
      I-1->I
      If V-T->V>99
        Y+W->Y
        V+S->V
      End
    End
    DispGraph  //DispGraph and Pause are added to show how the line radiates outwards
    Pause 50
  End
Return
Title: Re: Routines
Post by: ztrumpet on November 08, 2010, 10:51:54 pm
Looks great Michael!  Nice job. :)
Title: Re: Routines
Post by: DJ Omnimaga on November 08, 2010, 11:19:23 pm
Hmm interesting stuff
Title: Re: Routines
Post by: Runer112 on November 14, 2010, 09:50:35 pm
This is hardly a routine, as it's only a one-liner, but it can be quite useful to know if you use any Shade() commands in your program to change the contrast. No more exiting your program with a contrast value you hope was close to the original value! The following line of code will set the screen's contrast to the value the user/OS previously had it set at:

Code: [Select]
Shade({ᴇ8447}ʳ+24)
Note: The contrast value is actually only one byte, not two as the ʳ would suggest. The ʳ is just included as an optimization.
Title: Re: Routines
Post by: DJ Omnimaga on November 15, 2010, 02:07:26 am
Ooooh I never thought about doing that before! I tried figuring out from WikiTI how to change the contrast directly by setting a different value to the memory address, but it did not update the LCD contrast itself, just its value in the memory. Should be useful for game fade-in/out effects. :)
Title: Re: Routines
Post by: squidgetx on November 15, 2010, 02:31:43 pm
Speaking of fade in/out effects, here's a variant that doesn't mess with the contrast (the ones that do always look weird to me, I don't know why :P)

Code: [Select]
RecallPic
DrawInv ʳ
For(E,0,15
DispGraphʳ
End
Clrdraw
DrawInv
For(E,0,10)
DispGraph
End
Title: Re: Routines
Post by: Deep Toaster on November 15, 2010, 06:31:23 pm
Speaking of fade in/out effects, here's a variant that doesn't mess with the contrast (the ones that do always look weird to me, I don't know why :P)

Code: [Select]
RecallPic
ClrDrawʳ
DrawInv ʳ
For(E,0,15
DispGraphʳ
End
Clrdraw
DrawInv
For(E,0,10)
DispGraph
End

Nice, and an added benefit is that interrupts get disabled temporarily with Shade(.
Title: Re: Routines
Post by: Kiligolo on November 22, 2010, 05:29:41 am
Hello, I have a problem:
In the input routine (http://ourl.ca/4129/80803), I have ERR:BAD SYMBOL on :
Code: (Axe) [Select]
Output(1+{Pic99+2}-A,{E844B},{Pic99}r^10+48?Frac(http://i62.servimg.com/u/f62/15/22/38/00/ti_pro10.jpg)
Thanks for your help. :)
Title: Re: Routines
Post by: Runer112 on November 22, 2010, 01:40:11 pm
That looks fine to me. Make sure the program is in RAM, try to compile it again, and press PRGM when you get the error. Where does the cursor scroll to?
Title: Re: Routines
Post by: Kiligolo on November 22, 2010, 02:15:20 pm
To O (the output( 's beginning)

I it help you. I put the whole code:
Code: [Select]
Lbl A
[000000000000000→Pic99
A→{Pic99}r
If {Pic99}r>9
1→{Pic99+2
End
If {Pic99}r>99
2→{Pic99+2
End
If {Pic99}r>999
3→{Pic99+2
End
If {Pic99}r>9999
4→{Pic99+2
End
For(A,0,{Pic99+2
Output(1+{Pic99+2}-A,{ᴱ844B},{Pic99}r^10+48►Frac
{Pic99}r/10→{Pic99}r
End
ᴱ is on the bouton , (EE)
Title: Re: Routines
Post by: DJ Omnimaga on November 22, 2010, 02:20:37 pm
Output(1+{Pic99+2}-A,{E844B},{Pic99}r^10+48►Frac) with the closed parenthesis doesn't work either?
Title: Re: Routines
Post by: Runer112 on November 22, 2010, 02:27:31 pm
This is an excellent example of why it is best NOT to omit closing parentheses and brackets. I wasn't kidding when I made this post (http://ourl.ca/4050/142761) :P. The error is occuring because you didn't add a closing bracket on {Pic99+2 in the line immediately before it.
Title: Re: Routines
Post by: Kiligolo on November 22, 2010, 02:35:23 pm
I'm going to try it...

It works! Thanks you for your help. :D
Title: Re: Routines
Post by: DJ Omnimaga on November 22, 2010, 02:36:58 pm
Yeah we often think parhentesizes can be omitted because it works somewhere, but it's not intended to be like that. I personally close them whenever possible. In the end it saves me much trouble.

Glad it works now!
Title: Re: Routines
Post by: Kiligolo on November 22, 2010, 02:40:20 pm
But when the program is compiled, it's the same size even if we remove parhentesizes?
Title: Re: Routines
Post by: kindermoumoute on November 22, 2010, 02:54:12 pm
But when the program is compiled, it's the same size even if we remove parhentesizes?

Sure, I think.
Only interpreted langage have difference size with less parenthesized.
Title: Re: Routines
Post by: DJ Omnimaga on November 22, 2010, 03:23:11 pm
It should be. Parenthesizes should only be closed if you're in extreme need of every byte of RAM available.
Title: Re: Routines
Post by: squidgetx on November 22, 2010, 05:49:13 pm
I believe you mean,
It should be. Parenthesizes should only be left open if you're in extreme need of every byte of RAM available.
Title: Re: Routines
Post by: DJ Omnimaga on November 23, 2010, 12:06:34 am
Er yea X.x

I got it the other way around. My bad x.x
Title: Re: Routines
Post by: nemo on November 27, 2010, 09:59:16 pm
flexible-ish dropdown menu.
inputs - sub(MEN,Ypos*256+Xpos,numItems,"String1","String2","String3","String4") // String2-4 are optional. 0 < numItems < 5
String format:
cannot be more than 10 characters (bummer).
must be formatted like so: "4File". the 4 is the length of the string.
if you have a string greater than 9 in length, check this (http://tibasicdev.wikidot.com/83lgfont) table to find out what you should put before the string. for example, ":Horizontal" will work.
outputs - integer 0-(numItems-1) indicating which option was selected

Code: [Select]
Lbl MEN
r1^256->X
r1/256->Y
0->Z
For(U,1,r2
Text(X+2,U-1*7+Y+1,{U*2+°r2}^r->V+1
!If Z:V->Z:End
If {V}>{Z}
V->Z:End
End
{Z}-48->{Z}
ZAsm(EFB44C6F2600)->V  //finds the length of a string in pixels. thank you calc84maniac!
{Z}+48->{Z}
RectI(X,Y,V+3,r2*7+2
RectI(X+1,Y+1,V+1,r2*7
0->Z
Repeat getKey(9) or getKey(54)
getKey->K
=1-(K=4)+Z->Z
!If +1:r2-1->Z
End
Z^r2->Z
End
Z*7+Y*256+X+V+3->r1:Z
Return

just so you know, this routine *can* fail. Quit and Save have different pixel-lengths on calculator but they'd both be represented as 4Quit and 4Save in my routine.since Save is larger than Quit, make sure you put 4Save as an argument before 4Quit in the parameter list.

also, if you want to use more than 4 options you can group them into categories and call the routine more than once. the next logical placement for a menu after selection is stored into r1 for convenience.
Title: Re: Routines
Post by: Darl181 on November 28, 2010, 08:13:41 pm
A while back, I wrote a sort of character explorer" for selecting a number and it displays the ►Char thing.  now, I've optimized it a bit and added the ►Tok tokens.
[←]/[→] : +/- 1
[↑]/[↓] : +/- 20
Title: Re: Routines
Post by: Runer112 on November 28, 2010, 11:07:09 pm
Creating Ans as a string:
Code: [Select]
Data(4,ᵀAns,0,0)→Str0AN
DelVar Str0AN
GetCalc(Str0AN,size_goes_here)
Title: Re: Routines
Post by: Darl181 on November 29, 2010, 12:02:44 am
Code: (Creating Ans as a string) [Select]
Data(4,ᵀAns,0,0)→Str0AN
DelVar Str0AN
GetCalc(Str0AN,size_goes_here)
What does that do? Does it store the token/character to Ans?
Title: Re: Routines
Post by: calc84maniac on November 29, 2010, 12:07:20 am
It creates a string which is the Ans variable. You have to call Delvar manually, because for some reason Getcalc() wasn't deleting it if Ans wasn't already a string.
Title: Re: Routines
Post by: Darl181 on November 29, 2010, 12:08:49 am
What does it store in the Ans string, though?  The token or the character?
Title: Re: Routines
Post by: calc84maniac on November 29, 2010, 12:10:24 am
It doesn't store anything, it just creates the string.
Title: Re: Routines
Post by: Darl181 on November 29, 2010, 12:24:15 am
Oh, so one could choose what to store in Ans...I guess I'll put that in ;)

How do I get the size required by getcalc( ?
Looking at some of the two-byte tokens...huge...
Title: Re: Routines
Post by: Deep Toaster on November 29, 2010, 12:31:13 am
Well, it's a string of tokens, so you'll just have to manually count tokens :-\
Title: Re: Routines
Post by: Darl181 on November 29, 2010, 12:34:42 am
/me is confused
How do I get the length of it?  No idea of how to go about it.../me hopes he won't have to use ASM
Title: Re: Routines
Post by: Deep Toaster on November 29, 2010, 12:36:54 am
/me is confused
How do I get the length of it?  No idea of how to go about it.../me hopes he won't have to use ASM

I don't really understand what you mean...

You don't need the length of the token. All tokens stored in Ans are either one byte or two bytes, which you can check with http://tibasicdev.wikidot.com/tokens (http://tibasicdev.wikidot.com/tokens).
Title: Re: Routines
Post by: Darl181 on November 29, 2010, 12:38:32 am
Oh I see what you mean now :P
I'll need to find the first two-byte token, then...or does anybody know?
Title: Re: Routines
Post by: SirCmpwn on December 13, 2010, 08:56:51 pm
So I made a simple menu routine that will display a TIOS-style menu for your program, and return the selected index in I.  MENU.8xp contains the actual routine, and MENUTST.8xp provides a sample implementation.
Enjoy!
Title: Re: Routines
Post by: Builderboy on December 13, 2010, 09:01:31 pm
Lolls for a second i was thinking to myself, 'what is he waiting for just go to the program already!  Or compile it if you have to!' not realizing that it was already in the program XD great job :D
Title: Re: Routines
Post by: AngelFish on December 13, 2010, 09:02:51 pm
Can you customize the display if you wanted to make a GUI or something?
Title: Re: Routines
Post by: lookitsan00b on December 13, 2010, 09:25:26 pm
Can you customize the display if you wanted to make a GUI or something?

more importantly, can it scroll down? :P
Title: Re: Routines
Post by: SirCmpwn on December 13, 2010, 09:58:57 pm
It can't scroll down :( but I'm working on scrolling and having multiple headers.
Can you customize the display if you wanted to make a GUI or something?
It's a pretty simple routine, you could probably modify the source.
Title: Re: Routines
Post by: AngelFish on December 13, 2010, 10:09:21 pm
Yay, bugs (or user idiocy) :P

(http://img.removedfromgame.com/imgs/Menutest.gif)

The part where it returns Err: Syntax is followed by a RAM clear, although Wabbit doesn't record it.
Title: Re: Routines
Post by: SirCmpwn on December 13, 2010, 10:10:18 pm
Don't use 2.53 MP, you silly Qwerty!
And is that the demo, or your own implementation?
Title: Re: Routines
Post by: AngelFish on December 13, 2010, 10:11:21 pm
That's Menu.8xp, unmodified. The Demo won't compile for me.
Title: Re: Routines
Post by: SirCmpwn on December 13, 2010, 10:12:12 pm
Ah, weird that the demo won't compile.
Menu.8xp will crash, I guarantee it.  It isn't designed to work on its own.  What errors does the demo give you?
Title: Re: Routines
Post by: AngelFish on December 13, 2010, 10:15:33 pm
Silly Qwerty  ;)

You have to have BOTH programs to compile...
Title: Re: Routines
Post by: SirCmpwn on December 13, 2010, 10:15:51 pm
lol XD
Title: Re: Routines
Post by: DJ Omnimaga on December 14, 2010, 03:55:38 pm
It can't scroll down :( but I'm working on scrolling and having multiple headers.
Can you customize the display if you wanted to make a GUI or something?
It's a pretty simple routine, you could probably modify the source.
Scrolling down and having multiple tabs would be really awesome. The lack of this in TI-BASIC was an annoying limitation in that language. D:

Nice job by the way! At one point I should try to convert ROL4 (defunct) menu routine to Axe.
Title: Re: Routines
Post by: ztrumpet on December 14, 2010, 04:02:23 pm
That looks neat!  Nice routine Sir! ;D
Title: Re: Routines
Post by: Runer112 on December 14, 2010, 05:50:10 pm
I believe I posted some normal sorting routines a while ago, but there are probably many more times when a linked sort is in order. So here are two linked sorting libraries. LSORTBLB sorts a list of bytes whereas LSORTWLB sorts a list of words, and both are linked to a list of words (which will typically be pointers). These routines allow you to sort objects based on certain attributes.

The general syntax for a sort call:
Code: [Select]
sub(___, Pointer to list of values to sort, Pointer to list of words to rearrange based on sort, Number of bytes to sort)Note: If you are sorting bytes, the last argument will be the number of values to sort. If you are sorting words, the last argument will be the number of values times 2.

Routines in LSORTBLB:

Routines in LSORTWLB:



As an example, say your program was managing 256 objects, and each object has 4 bytes of data: [x position, y position, x velocity, y velocity]. You have a list of pointers to the objects located at P. Let's say you want to sort the objects in this list by descending x velocity.
Code: [Select]
.Move attributes to be sorted by to a sequential section of memory
For(A,0,255)
{{A*2+P}+2}→{A+L₁}
End
.Sort
sub(SBD,L₁,P,256)
Title: Re: Routines
Post by: DJ Omnimaga on December 15, 2010, 12:47:04 am
Oh a sorting routine? Nice! This might be handy eventually if I was to work on an item menu like Illusiat 13 :D
Title: Re: Routines
Post by: ztrumpet on December 15, 2010, 04:45:07 pm
Wow, that looks nice!  Great job. :)
Title: Re: Routines
Post by: Ashbad on December 15, 2010, 05:18:06 pm
Draw an elliptical shape like an oval/circle

Code: [Select]
For(A,0,255
sin(A)//W->S
cos(A)//H->C
pxl-on(X+S,Y-C
End

W = Width inverse, the smaller the value, the wider the circle.  16 draws with outward radius of ~10 pixels
H = Height inverse, the smaller the value, the taller the circle.  16 draws with outward radius of ~10 pixels
A = used in for statement as the intermediate "angle"
S = intermediate sine value
C = intermediate cosine value
X = Elliptical center X
Y = Elliptical center Y
Title: Re: Routines
Post by: nemo on December 15, 2010, 05:25:31 pm
Code: [Select]
For(A,0,255
pxl-on(sin(A)//W+X,Y-(cos(A)//H)
End
yay optimization
Title: Re: Routines
Post by: Ashbad on December 15, 2010, 05:27:12 pm
yay ;)

funny thing is, until I wrote the routine and looked up what a sine and cosine is, I had NO IDEA what they did O.O

I mean, I used before in Alg honors last year, but it was the last chapter for honors only, which was a crash course of trig basics :P

..and we just used the sin/cos functions like once and were never told what they did :P
Title: Re: Routines
Post by: Runer112 on December 15, 2010, 07:04:38 pm
Code: [Select]
For(A,0,255
pxl-on(sin(A)//W+X,Y-(cos(A)//H)
End
yay optimization

Code: [Select]
256→A
While
Pxl-On(sin(A)//W+X,sin(A+64)//H+Y)
A-1→A
End

Good fight ;)

And just a note: Unless you absolutely want width and height to be inverted, multiplying instead of signed dividing is probably better. The multiplication routine is smaller and faster than the signed division routine.
Title: Re: Routines
Post by: Deep Toaster on December 15, 2010, 07:09:05 pm
Code: [Select]
257
While -1→A
Pxl-On(sin(A)//W+X,sin(A+64)//H+Y)
A
End

Even better ;)
Title: Re: Routines
Post by: Runer112 on December 15, 2010, 07:16:02 pm
Ah how did I not see that!
Title: Re: Routines
Post by: Deep Toaster on December 15, 2010, 07:18:16 pm
Code: [Select]
257
While -1→A
Pxl-On(sin()//W+X,sin(A+64)//H+Y)
A
End

I should stop.
Title: Re: Routines
Post by: DJ Omnimaga on December 16, 2010, 04:29:06 am
Nice routine guys!
Title: Re: Routines
Post by: Runer112 on December 19, 2010, 10:43:15 pm
FinaleTI was wondering how he could do some basic operations on 3-byte numbers, namely addition, subtraction, and decimal display. It took me a while to get it all working, but I wrote an Axe library to do all of the above. And while I was at it, because it would only require minor modifications to this code, I wrote a similar library to perform those three operations on 4-byte numbers. No longer shall Axe be limited to 2 bytes! (At least regarding addition, subtraction, and decimal display)

Anyways, the two libraries are very similar. They accept inputs in the form of pointers to the 3- or 4-byte numbers you want to operate on and have the same three functions:


To include the library in your program, have the library you want present on your calculator and insert a line reading ":prgmLIB3BYTE" or ":prgmLIB4BYTE" in the subroutine section of your code. The syntax for the commands is also included as comments under each function in the library source files, so you can look there if you need a refresher.


NOTE: The decimal display routine uses OP4-OP5 for scratch memory and OP6 to store the resulting string, so if you're wondering why any data you store there is mysteriously being corrupted, that's why.


EDIT: I just realized there was a slight flaw with my code. But I fixed it and reuploaded the two libraries before anyone could download them (I think). That's why the "by Runer112" is on the end of the filenames, I wasn't sure what else to add.
Title: Re: Routines
Post by: DJ Omnimaga on December 19, 2010, 10:50:45 pm
Hmm question, you say pointer to first argument, but I assume this grabs 3 numbers starting there, right? Just wondering. Also does the routine allows you to display such number without adding/substracting? I am curious since this might be useful for games where money or scores can go above 65536, for example.
Title: Re: Routines
Post by: Runer112 on December 19, 2010, 10:56:20 pm
Yes and yes. The arguments should be pointers to where you store the values, not the actual values, because the actual values wouldn't fit in Axe's 2-byte value system. For instance, if you had a 4-byte number spanning variables A-B in memory and a 4-byte number spanning variables C-D, you could add the two values and store the result in A-B like so:
Code: [Select]
sub(ADD,°C,°A,)(Note the trick employed here. You can do this if you are adding two values and storing the result back into one of the values. Enter the pointer to the value that should serve as both an argument and the answer as the second argument and then leave the third argument blank.)

The display routines can display any number that you can fit in the 3 or 4 bytes of data: 0-16777215 for the 3-byte library and 0-4294967295 for the 4-byte library.



EDIT: Here's a little program I whipped up using the 4-byte library, showing its capabilities. It pases 65536 with ease, but unfortunately it can only go up to about 4 billion. ;) You might recognize the pattern...
(Note that the actual routines run a lot faster than this, I manually set it to iterate only twice per second)

You can look at the source for an example of how to use the commands.
Title: Re: Routines
Post by: Michael_Lee on December 20, 2010, 12:31:14 am
Very cool looking!
A pseudo-random question (out of curiosity only): Is it possible to modify the code so that when you call the subroutine(s), you can define how long you want your data to be?
Title: Re: Routines
Post by: Runer112 on December 20, 2010, 12:53:09 am
That would definitely be possible for the addition and subtraction routines, but I don't know how that would work with the decimal display routine. It works by having all the multiples of 10 that can fit in the data size you're using hardcoded into the routine. I could hardcode the multiples of 10 up to a very high amount and just hope the user doesn't exceed it, although that would probably be a bit wasteful, as I doubt most people would require most of the excess data.

But it's possible. Want me to try it?


Note: That question was pretty much rhetorical, because now I want to try this anyway. ;)
Title: Re: Routines
Post by: DJ Omnimaga on December 20, 2010, 12:56:45 am
Cool Runer112, thanks for explaining. :)
Title: Re: Routines
Post by: Michael_Lee on December 20, 2010, 12:59:22 am
A rhetorical response to a rhetorial question... I would like to announce 'FTW', but I can't come up with a way to word it...
Hmm...

It would be even cooler if you could mix and match the sizes, especially for addition and subtraction, allowing me to do things like add a 3 byte number to a 5 byte number...  And for completeness, something that could take an X byte number and truncate/pad it to a Y byte size number...

I'm not really sure how decimals would work with all that, though.
Title: Re: Routines
Post by: ztrumpet on December 20, 2010, 12:23:42 pm
Wow.  This is great.  Thanks Runer! ;D
Title: Re: Routines
Post by: squidgetx on February 02, 2011, 04:15:55 pm
Woo, necro. I thought I'd share my own custom input routine, coming in at ~360 bytes.(For some reason I've never liked input...). Anyway, it's very flexible and allows the use of ALPHA to toggle between caps, lowercase, and number input. Writes ASCII to the desired location in memory. Press Enter to "finish"
Code: [Select]
.A0

0->A->K->P->{pointer}^^r

Fill(pointer,max amount of characters+1)
DeltaList(47,39,31,46,38,30,22,14,45,37,29,21,13,44,36,28,20,12,43,35,27,19,11,42,34,26,18,0)->GDB0A
GDB0A->G
64->L
DeltaList(33,34,26,18,35,27,19,36,28,20,0)->GDB0N
[]->Str00
"ABC"[00]
"abc"[00]
"123"[00]

While K-9
getKey->K
!If -48
A+1->A
!If -3
->A
End
!If A
GDB0A->G
64->L
End
!If -1
GDB0A->G
96->L
End
!If -1
GDB0N->G
47->L
End
End

Text(0,58,A*4+Str00
If K
If inString(,G)
+L->{P+pointer}
If P-(max amount of characters-1)
P+1->P
0->{P+pointer+1}
End
End
End
Text(x position,y position,pointer

End
edit: here's a basic screenie
Title: Re: Routines
Post by: ztrumpet on February 02, 2011, 04:56:16 pm
Nice.  Looks great. :D
Title: Re: Routines
Post by: DJ Omnimaga on February 02, 2011, 06:50:53 pm
I don't understand what's the text at the bottom for ???
Title: Re: Routines
Post by: squidgetx on February 02, 2011, 07:30:42 pm
It shows whether the current input mode is in caps (ABC), lowercase (abc), or numerical (123) :)
Title: Re: Routines
Post by: DJ Omnimaga on February 03, 2011, 12:56:51 am
Oh ok, you should probably add text saying Mode: or something, so it is a bit more clear. :P
Title: Re: Routines
Post by: squidgetx on February 07, 2011, 07:24:24 am
While messing around with my memory mapper I came across a way to basically use file objects in archive as pointers. This means that you can draw sprites from archive :o Unfortunately, it only works with nostub executables :(
Code: [Select]
Asm(DB0665)^256->theta //run this line at the beginning of the program and make sure that you don't touch theta ever)
...stuff
GetCalc("prgmBLA",Y1)
{degreeY1+2}Asm(7DD306)
.Now whenever you want to reference Y1...
Pt-On(X,Y,{degreeY1}r
.If you have more than one file object make sure that the last 7DD306 matches the one you are using.
...at the end of the program
thetaAsm(7DD306)
Title: Re: Routines
Post by: calc84maniac on February 07, 2011, 11:46:44 am
I think you might run into problems if the sprite data spans two pages.
Title: Re: Routines
Post by: squidgetx on February 07, 2011, 06:01:23 pm
Hm. Yeah, that's true. I guess it's not really very useful then lol XD
Title: Re: Routines
Post by: Michael_Lee on February 12, 2011, 02:09:28 am
Should this be stickied now that there's more room?
Title: Re: Routines
Post by: DJ Omnimaga on February 12, 2011, 07:40:10 pm
You should probably sticky all the important threads I guess, now that it won't clutter the progress threads list anymore. Someone already did with this one, though.
Title: Re: Routines
Post by: aeTIos on March 03, 2011, 09:43:39 am
Xeda made this routine for running Basic progs:
Okay, so earlier I was asked by aeTIos for a hex code to run BASIC programs in Axe and I have heard that this was requested by others, so here goes my rendition... I am sorry in advance if my Axeing is horrible, this is only my second routine:
Code: [Select]
"prgmHELLO"→Str1                     ;Name of the var
Str1                                 ;To get the pointer to the string in HL (Ans)
Asm(E7FDCB08CEEF9B4AFDCB088E         ;

As a word of warning, do not use "Stop" in your BASIC programs... This seems to cause a crash :(
You can use "Return" and all the other commands, though, to my knowledge.

I hope this helps!
++ Xeda, well done!
And the Axe is okay :D
Title: Re: Routines
Post by: Michael_Lee on March 18, 2011, 01:25:07 am
Drawing Bezier Curves

I found a webpage on Bezier curves, and translated it to Axe.
It basically takes two points, a vector from those two points (represented by the grey line), and draws a curve.

[2ND] to flip between changing the two adjustable grey lines, and [CLEAR] to quit.

Source and gif attached.
Title: Re: Routines
Post by: Builderboy on March 18, 2011, 01:27:58 am
That is really cool!  If you drag the lines too far does the curve become dotted?  Or are you using some awesomly clever algorithm to make sure the curve is always continuous?
Title: Re: Routines
Post by: Michael_Lee on March 18, 2011, 01:38:03 am
The curve is comprised of 8 dots connected to each other by lines.  They should always be continuous, although they might become a bit angular.
I would have done more points, but it seems two byte vars were too small for more dots.

I'm not exactly certain what happens if you drag the lines too far, except that they wrap to the other side and then warp oddly.
Title: Re: Routines
Post by: Builderboy on March 18, 2011, 01:44:38 am
Ahh thats a very simple solution that I hadent thought of! Very nice implementation :) I love these curves, they are so useful!
Title: Re: Routines
Post by: ztrumpet on March 20, 2011, 08:24:27 pm
Oooh, very shiny.  Nice job, Michael! :D
Title: Re: Routines
Post by: Darl181 on March 21, 2011, 07:03:18 pm
So we know how to make fire from Builderboy's tutorial.
Code: [Select]
.Axe
ClrDraw
[FEFDFBF7EFDFBD7F]->Str1  //Each Byte here has 7 bits set and 1 bit not set (like FE is 11111110 in binary)
                      //This is so that we can erase a random pixel, since Axe has no built in way to do that
Line(0,63,95,63       //the pixels to catch fire, explained a little later

Repeat getKey(15)    //until we press clear

For(F,L6+12,L6+767       //loop through all of the screen pixels except the last 12
{F} and {rand^8+Str1}->{F-12}   //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *above* it
End                     //this makes it so that as the byte rises, each frame a pixel is erased from it

DispGraph

End

Today, after some experimenting, I figured out how to make water.

Code: [Select]
.Axe
ClrDraw
[FEFDFBF7EFDFBD7F]->Str1  //Each Byte here has 7 bits set and 1 bit not set (like FE is 11111110 in binary)
                      //This is so that we can erase a random pixel, since Axe has no built in way to do that
Line(0,0,95,63       //the pixels to catch fire, explained a little later

Repeat getKey(15)    //until we press clear

For(F,L6+12,L6+767      
L6+755→F
While F-L6     //loop through all of the screen pixels except the first 12
F-1→F
{F} and {rand^8+Str1}->{F+12}   //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *below* it
End                     //this makes it so that as the byte drops, each frame a pixel is erased from it

DispGraph

End

voilà, it's water.
Title: Re: Routines
Post by: Deep Toaster on March 21, 2011, 07:14:48 pm
Nice, that looks good as a sort of sprinkler effect :) For water that doesn't evaporate, there's this (http://ourl.ca/4279/169816;topicseen#msg115692).
Title: Re: Routines
Post by: Darl181 on March 21, 2011, 07:29:07 pm
I was able to use it for a menu (http://ourl.ca/8025/187726), and I figured I might as well post it  ;)

Quote from the next post
That looks pretty nice.  It's too bad the water coming from the character looks a little funny when he moves down.  Other than that, wonderful job! ;D
It works the same as the fire, so the fire looks odd when moving up.

The post after that
For a moment there I thought you magically saw a quote from the future O.O
You have a lot to learn...
jk :P
such as this?
Maybe...
ok I'll stop now :P
Title: Re: Routines
Post by: ztrumpet on March 21, 2011, 07:29:08 pm
That looks pretty nice.  It's too bad the water coming from the character looks a little funny when he moves down.  Other than that, wonderful job! ;D
Title: Re: Routines
Post by: Deep Toaster on March 21, 2011, 07:35:02 pm
Quote from the next post
That looks pretty nice.  It's too bad the water coming from the character looks a little funny when he moves down.  Other than that, wonderful job! ;D
It works the same as the fire, so the fire looks odd when moving up.

For a moment there I thought you magically saw a quote from the future O.O
Title: Re: Routines
Post by: ztrumpet on March 21, 2011, 07:37:40 pm
Quote from the next post
That looks pretty nice.  It's too bad the water coming from the character looks a little funny when he moves down.  Other than that, wonderful job! ;D
It works the same as the fire, so the fire looks odd when moving up.

For a moment there I thought you magically saw a quote from the future O.O
It's only one second; he could do it, if he really believed.
Title: Re: Routines
Post by: Happybobjr on March 21, 2011, 07:43:26 pm
Quote from the next post
That looks pretty nice.  It's too bad the water coming from the character looks a little funny when he moves down.  Other than that, wonderful job! ;D
It works the same as the fire, so the fire looks odd when moving up.

For a moment there I thought you magically saw a quote from the future O.O
such as this?
Title: Re: Routines
Post by: DJ Omnimaga on March 25, 2011, 03:26:31 am
Lol XD

Anyway nice routines guys above, I love the water effect and I think the bezier curves could be useful for a drawing program.
Title: Re: Routines
Post by: ZippyDee on March 25, 2011, 03:47:39 am
I agree, that bezier curve routine is awesome. It could be pretty great for a lot of things actually. For example: using that routine to draw the curves connecting  control points in a uniform b-spline could allow you to draw smooth curved lines between a set of points. If anyone could write a fast enough routine to do that, drawing arbitrary curves (for any reason) could end up being much smoother. Dealing with control points in beziers is not as straightforward as spline control points.

In fact, using a uniform b-spline with quadratic bezier curves could likely be faster and easier to implement into a uniform b-spline algorithm. (unless I'm just remembering wrong and uniform b-splines already use quadratic instead of cubic...)
Title: Re: Routines
Post by: ZippyDee on March 30, 2011, 04:15:11 pm
Here's a quick atan routine that I threw together last night. It's not the most accurate, but it's accurate enough for most things you'd need it for. Like Runer112's Sin and Cos routines, this uses 8.8 fixed point input and returns an 8.8 fixed point angle. Use it with sub(ATN,slope).

And I'm sure it can be optimized, so feel free to do so.

EDIT: added atan2 that accepts deltaY and deltaX inputs as one byte integers -127 to 127 and outputs an 8.8 fixed point. Use it with sub(AT2,dY,dX).
Title: Re: Routines
Post by: Darl181 on May 06, 2011, 11:50:28 pm
I'm trying to update the ASCII program from before.

The option I plan on including is storing any one of the following:
Number, Hex number, Charactor, Token
to the TIOS var Ans.

How would I do this?  I've been able to create Ans as a string (http://ourl.ca/4129/146998), but the IRC convo about how to do it got kind of confusing so I'm making a post instead.

TIA
Title: Re: Routines
Post by: Deep Toaster on May 07, 2011, 12:08:23 am
Well, you'll have to convert it all yourself. For the numbers just do some math tricks to get each digit (using division and modulus; we can help you if you need help figuring out code to do this), and for tokens it's even easier (just store the value right there, since TI-BASIC strings are read as tokens anyway), but characters may become impossible. The reason is that a lot of characters are accessible only in ASM (or Axe) and don't have token equivalents.
Title: Re: Routines
Post by: Darl181 on May 07, 2011, 12:12:09 am
Well, you'll have to convert it all yourself. For the numbers just do some math tricks to get each digit (using division and modulus; we can help you if you need help figuring out code to do this)
this would be just for the hex number, or for the decimal number as well?
Quote
and for tokens it's even easier (just store the value right there, since TI-BASIC strings are read as tokens anyway), but characters may become impossible. The reason is that a lot of characters are accessible only in ASM (or Axe) and don't have token equivalents.
ok...guess I'll take that out :P
Title: Re: Routines
Post by: Runer112 on May 26, 2011, 12:38:01 am
A lovely animated vertical screen flipping routine! It requires a buffer to store the image to be flipped, and by default uses L3. You could change this to use any 768-byte section of RAM by replacing the StorePic and instead copying your original buffer image (probably in L6) somewhere else.

The code is both pasted below and attached as VFLIPLIB.8xp. The easiest way to include this code in your program would be to just include prgmVFLIPLIB in the subroutine section of your program and call sub(VF) to use it.

Code: [Select]
StorePic
0+128
While 1
 -128-2→θ
 cos()+129/2/2→Y
 +(≥32)-(=0)*256→Z
 ClrDraw
 64
 While 1
  -1→I
  If Z/256≠((31+(Y<32)-Y)→H*8+Z→Z/256)
   Copy(I*12+L₃,Z/256*12+L₆,12)
  End
 End!If I
 DispGraph
End!If θ+128
Title: Re: Routines
Post by: Darl181 on May 26, 2011, 12:28:02 pm
Awesome ;D
Is there a way to have it invert half-way through?  Put a DrawInvr just before the second While 1 or something?
Title: Re: Routines
Post by: Runer112 on May 26, 2011, 01:10:48 pm
This should work:

Code: [Select]
StorePic
0+128
While 1
 -128-2→θ
 !If +64
  DrawInv ʳ
 End
 cos(θ)+129/2/2→Y
 +(≥32)-(=0)*256→Z
 ClrDraw
 64
 While 1
  -1→I
  If Z/256≠((31+(Y<32)-Y)→H*8+Z→Z/256)
   Copy(I*12+L₃,Z/256*12+L₆,12)
  End
 End!If I
 DispGraph
End!If θ+128
Title: Re: Routines
Post by: ztrumpet on May 26, 2011, 04:56:24 pm
Nice!  That's awesome, Runer.  Excellent job there. ;D
Title: Re: Routines
Post by: Ashbad on May 26, 2011, 05:04:04 pm
that's pretty awesome.  What's even more awesome is how optimized that is O.O

Runer++
Title: Re: Routines
Post by: DrDnar on June 12, 2011, 02:27:32 am
I do not know if this has been posted before, so here are two different snippets to get the current hardware version. The first checks the hardware ports, and returns 0 for the TI-83+, 1 for the TI-84+SE, 2 for the TI-83+SE, and 3 for the TI-84+SE. So, doing AND 1 returns true for a TI-84+ or TI-84+SE.
Code: [Select]
Asm(210000 DB02 47 E680 280D 2C DB21 E603 2806 2C CB68 2801 2C)->V   . V=HW version. 23 bytes
Spoiler For Assembly Code:
Code: [Select]
ld hl, 0
in a, (2)
ld b, a
and 80h
jr z, done
inc l
in a, (21h)
and 3
jr z, done
inc l
bit 5, b
jr z, done
inc l
done: ; nothing more here!

This second one uses the rarely-used GetSysInfo bcall. It probably returns 0 for the TI-83+, 1 for the TI-83+SE, 2 for the TI-84+, and 3 for the TI-84+SE, but I cannot verify that.
Code: [Select]
Asm(EF6F4C 2E00 78 FE0D 380A 217884 EFDD50 3A7A84 6F 2600)->V   . V=HW revision. 22 bytes
Spoiler For Assembly Code:
Code: [Select]
BCALL getBaseVer ; You can probably get away with not checking the OS version, as most units in use these days will have 1.13+
ld l, 0
ld a, b
cp 0Dh
jr c, done
ld hl, OP1
BCALL GetSysInfo
ld a, (OP1+2)
ld l, a
done:
ld h, 0 ; done!


And while I'm at it, here's how to read and write to any port. $ = the small capital E used for hex notation in Axe. This first one takes the port to write to in the high byte, and the value to write in the low byte.
Code: [Select]
variable Asm(4C 45 ED41)   . Write the value (variable And $FF) to port (variable/256)$1060Asm(4C45ED14) will vertically rotate the screen by half. ($10 is the LCD command port, and $60 is a command that rotates the screen. It's useful for instant scrolling.)

This reads from the specified port.
Code: [Select]
variable1 Asm(4D ED68 2600)->variable2   . Read from port variable1 and store to variable26Asm(4DED682600)->P will probably make P a number less than 8 if the program is running from the OS, and greater than or equal to 8 if the program is running from a shell. (The code for running nostub programs happens to be on page 7 on 2.43. That can change, of course.)

This writes a value to one particular port.
Code: [Select]
value Asm(7D D3nn)   . Writes value to port nn.$60Asm(7DD310) will vertically rotate the screen by half.

This reads a value from one particular port.
Code: [Select]
Asm(DBnn 6F 2600)->variable   . Write the value in port nn to variable.Asm(DB06F62600)->P will probably make P a number less than 8 if the program is running from the OS, and greater than or equal to 8 if the program is running from a shell.

You can also inline these. For example,
Code: [Select]
If randAsm(4DED682600)>42
 some code
End
will execute some code if the value in a random port is greater than 42. May cause a hang on TI-84+s if it reads from the wrong USB port :p.
Title: Re: Routines
Post by: Deep Toaster on June 12, 2011, 10:00:56 am
Nice routines, DrDnar. I can see the first few being useful for people who want to do crystal timers in Axe :D
Title: Re: Routines
Post by: ztrumpet on June 12, 2011, 01:58:33 pm
Nice routines, DrDnar. I can see the first few being useful for people who want to do crystal timers in Axe :D
That would be epic. :D
By the way, it there something like the crystal timers on the 83+?

Thanks, DrDnar.  Great routines. ;D
Title: Re: Routines
Post by: Runer112 on June 12, 2011, 02:05:41 pm
Massive hardware version check optimization? 6 bytes, about one quarter the size of your code. ;)

Asm(EFBA8026006F)
Title: Re: Routines
Post by: BrownyTCat on June 12, 2011, 02:06:46 pm
Massive hardware version check optimization? 6 bytes, about one quarter the size of your code. ;)

Asm(EFBA8026006F)
I don't even know how it works, and it's still amazing.
Title: Re: Routines
Post by: Deep Toaster on June 12, 2011, 02:10:28 pm
lol undocumented bcalls ftw :D
Title: Re: Routines
Post by: DrDnar on June 13, 2011, 04:35:48 pm
It's not that much shorter if you add in an OS version check. I doubt the getHardwareVersion call exists on pre-1.13.
Title: Re: Routines
Post by: Runer112 on June 13, 2011, 06:54:51 pm
It's a B_CALL to the boot code, so it should exist on every OS with boot code. In other words, every OS. ;)
Title: Re: Routines
Post by: aeTIos on June 15, 2011, 09:54:02 am
Request: OS version check (Would be cool for my very old fake RAM clear program xD)
EDIT: Was this program, sucks abit: (http://www.omnimaga.org/index.php?action=dlattach;topic=4676.0;attach=3900;image)
Also the text is indeed a bit off. O.o (
Quote from: DJ long time ago
Nice, although I think the text is a bit off, though, and there are two black squares at the end of the screenshot. It might be nice if it could be implemented as fake reset in a game :P
)
Title: Re: Routines
Post by: DrDnar on June 16, 2011, 03:44:40 am
OS version check? Really? Molest me not with this pocket calculator---er . . . well anyway, EF6F4C6768 will return the major version number in the high byte and the minor version number in the low byte. So divide by 256 to get the high byte and do "and 255" to get the low byte. In theory, "or 0" should also work, assuming that doing an 8-bit logical operation implicitly strips the high octet.
Title: Re: Routines
Post by: aeTIos on June 16, 2011, 03:50:17 am
erm, cant you just do (ASM code)->A then do A->{L1}r ?
Title: Re: Routines
Post by: DrDnar on June 16, 2011, 03:51:42 am
Sure. You could then read the major version in {L1+1} and the minor version number in {L1}. In fact, Asm(EF6F4C6768)->{L1}r will work.
Title: Re: Routines
Post by: aeTIos on June 16, 2011, 03:52:06 am
Aha. Thats way easier xD
Title: Re: Routines
Post by: Fast Crash on June 18, 2011, 07:38:50 am
He is a routine that Mighty Moose and me made, it allows you to copy data from flash to ram (it uses flashtoram):

Code: [Select]
Getcalc(<your var in flash>,Yx)
{°Yx}r->H
{°Yx+2}->A
<Number of bytes to copy>->B
<Your pointer in RAM>->D
Asm(2AC489ED5BBC893AB689ED4BB889EF1750)
Title: Re: Routines
Post by: Munchor on June 18, 2011, 07:44:18 am
He is a routine that Mighty Moose and me made, it allows you to copy data from flash to ram (it uses flashtoram):

Code: [Select]
Getcalc(<your var in flash>,Yx)
{°Yx}r->H
{°Yx+2}->A
<Number of bytes to copy>->B
<Your pointer in RAM>->D
Asm(2AC489ED5BBC893AB689ED4BB889EF1750)

Nice, I don't really understand how it works, but nice :D
Title: Re: Routines
Post by: Ashbad on June 18, 2011, 07:51:58 am
Well, iirc, you can just do this, since it is valid to use Page-pointer varsity in a Copy instruction:

Code: [Select]
Getcalc(YourVar,Yx)
Copy(Yx,RAMptr,amount)

I thnk I used that for TaNF, it's very useful if you want to keep tons of data in Archive but be able to access little parts quickly when needed.
Title: Re: Routines
Post by: Deep Toaster on June 19, 2011, 12:39:15 pm
Well, iirc, you can just do this, since it is valid to use Page-pointer varsity in a Copy instruction:

Code: [Select]
Getcalc(YourVar,Yx)
Copy(Yx,RAMptr,amount)

I thnk I used that for TaNF, it's very useful if you want to keep tons of data in Archive but be able to access little parts quickly when needed.

Does it work when there's a page break?
Title: Re: Routines
Post by: Munchor on June 19, 2011, 12:45:20 pm
Well, iirc, you can just do this, since it is valid to use Page-pointer varsity in a Copy instruction:

Code: [Select]
Getcalc(YourVar,Yx)
Copy(Yx,RAMptr,amount)

I thnk I used that for TaNF, it's very useful if you want to keep tons of data in Archive but be able to access little parts quickly when needed.

Does it work when there's a page break?

I don't really understand this, but does Frash/Mighty's work when there's a page break? I really don't understand these routines :P
Title: Re: Routines
Post by: Runer112 on June 19, 2011, 01:52:20 pm
For copying data from archive to RAM, you want to use Axe's built-in Copy() command. It's smaller, easier to use, and handles page boundaries better. They both handle boundary crossing during copying correctly, but only Axe's built-in command handles boundary crossing before copying correctly. Like:

Copy(Y₁+16384,L₁,256)
Title: Re: Routines
Post by: ztrumpet on June 20, 2011, 09:48:03 pm
Here's a routine I made to clear a 6*6 square on both buffers.  I believe it's fairly optimized and much more elegant than the equivalent Pt-On(r1,r2,[FCFCFCFCFCFC0000]) / Pt-Change(r1,r2,[FCFCFCFCFCFC0000]).  With slight modification this could even be used for other sprite sizes like 5*5 and 12*12.

Here it is:
Code: [Select]
:Lbl CLR
:.Clear a 6*6 spot on both buffers
:.r1 is the X coordinate and r2 is the Y coordinate
:r1^8
:Asm(450421FF07B7CB1CCB1D10FA)→r3
:...
:  ld b, l
:  ld hl, 0000011111111111b
:  or a
:loop:
:  rr h
:  rr l
:  djnz loop
:...
:r1/8+(r2*12)→r5
:For(r4,0,5)
:{r4*12+r5→r6+L6}rr∙r3→{r6+L6}rr
:{r6+L3}rr∙r3→{r6+L3}rr
:End
:Return

What not to do with my routine:
It doesn't clip, so don't pass it any arguments that will make it go off the bottom of the screen.  This includes even the very bottom corner, as it'll still overwrite one byte. :-\  However, it's quicker not to clip so that's why I wrote it this way.

Enjoy! ;D

P.S.  Thanks to Eeems and Runer for helping with small clarifications throughout my coding. :)
Title: Re: Routines
Post by: Quigibo on June 20, 2011, 10:03:30 pm
You can always use a single Pt-Mask() to write a white square to both buffers.  Not sure if yours is faster than that or not, but its possible due to the lack of clipping and argument checking.
Title: Re: Routines
Post by: Runer112 on June 20, 2011, 11:45:12 pm
I think this is about as fast as it gets for drawing a white square to both buffers. It is not clipped. The code given is for drawing a 6x6 square, but it can be modified to draw a rectangle of any width from 1-9 and any height.

I haven't actually tested this, but hopefully it works. If it does work, it will be very fast. It is faster than drawing a single unaligned sprite to only one buffer.


Code: (79 bytes, 1164 cycles) [Select]
Lbl CLR
.Clear a 6*6 spot on both buffers
.r₁ is the X coordinate and r₂ is the Y coordinate
Asm(447D85856F29293AA5834FCB39CB39CB390911409319E5E607874F)
([03FF81FFC0FFE07FF03FF81FFC0FFE07])
Asm(095E2356E10606C57EA377237EA277013105097EA377237EA27701D9FA09C110E6)
Return


Code: (Source code) [Select]
  ld b,h
  ld a,l
  add a,l
  add a,l
  ld l,a
  add hl,hl
  add hl,hl
  ld a,(axv_r1)
  ld c,a
  srl c
  srl c
  srl c
  add hl,bc
  ld de,plotSScreen
  add hl,de
  push hl
  and %00000111
  add a,a
  ld c,a
  ld hl,$0000        ;Replace with mask LUT
  add hl,bc
  ld e,(hl)
  inc hl
  ld d,(hl)
  pop hl
  ld b,6
DrawLoop:
  push bc
  ld a,(hl)
  and e
  ld (hl),a
  inc hl
  ld a,(hl)
  and d
  ld (hl),a
  ld bc,appBackUpScreen-plotSScreen-1
  add hl,bc
  ld a,(hl)
  and e
  ld (hl),a
  inc hl
  ld a,(hl)
  and d
  ld (hl),a
  ld bc,plotSScreen-appBackUpScreen-1+12
  add hl,bc
  pop bc
  djnz DrawLoop
Title: Re: Routines
Post by: ztrumpet on June 21, 2011, 12:26:33 pm
Runer, your routine doesn't appear to work for me.  Maybe I typed it in wrong, but I checked it after typing it in and don't appear to have. :-\
Title: Re: Routines
Post by: Runer112 on June 21, 2011, 05:23:37 pm
I found an error and fixed it, try it again? Hopefully it was the last error.
Title: Re: Routines
Post by: ztrumpet on June 21, 2011, 05:45:39 pm
Yay, that worked!  Thanks, Runer. ;D
Title: Re: Routines
Post by: Deep Toaster on July 01, 2011, 12:35:15 pm
Simple stuff that you probably know already, but I'll post it here anyway.

To round a fixed-point number down (floor function), it's pretty simple. Just mask the first eight bits (· being the 16-bit AND operator):
EFF00
To round up (ceiling function), add 255:
A+255·EFF00
These obviously don't work (and don't need to work) on integers, but if you want integer division to round up instead of down, you can do:
A-1/B+1
Title: Re: Routines
Post by: Runer112 on July 28, 2011, 10:31:39 pm
Someone asked for subtring and instring functions like those in TI-BASIC. So I made an Axe library with those two routines! Here's a quick summary of each one:






The Axe library is attached below. To use it in your program, simply send this to your calculator and include "prgmSTRLIB" in your program. I tested it a bit and think it works perfectly, but if not, please inform me! :)
Title: Re: Routines
Post by: Michael_Lee on August 03, 2011, 01:54:30 am
Polygons:

I made a subroutine that can draw a shaded polygon with an arbitrarily high amount of vertexes.

It can also handle convex and almost handle concave polygons.

You have to designate a segment of memory that contains a list of vertex.  The 0th byte is the X-coordinate of the first vertex, the 1st byte is the Y-coordinate of the first vertex, the 2nd byte is the X-coordinate of the second vertex, etc...  The last pair of vertexes has to be identical to the first pair, to 'close the loop'.

Also, the first (and therefore last) point in the list has to be the left-most or right-most point of the polygon, otherwise it'll look weird.

I made a demo -- source attached, and comments and pic below.
[2ND] to place a vertex, [ALPHA] to display the polygon, and [DEL] to clear the screen.  [CLEAR] exits.

It should be compatible with Axe 0.5.x and 1.0.x

Code: [Select]
.POLYGON

Fix 5

10->A        .The X coordinate of the vertex selector
10->B        .The Y coordinate of the vertex selector

0->T         .Total amount of vertexes
20->M        .Maximum amount of vertexes (not necessary -- only for sanity checks)

L4->V        .Pointer to the list of Vertexes
L1->C        .Pointer to some free ram (for Calculations)

ClrDraw
ClrDraw^^r

RectI(A-1,B-1,3,3)^^r


Repeat getKey(15)
    RectI(A-1,B-1,3,3)^^r
    getKey(3)-getKey(2)+A->A
    getKey(1)-getKey(4)+B->B
    RectI(A-1,B-1,3,3)^^r
       
    Rect(80,9,40,40)
    RectI(80,9,40,40)

    Text(80,10,A>Dec)
    Text(80,18,B>Dec)
    Text(80,30,T>Dec)
       
    If getKey(54)          .Adds a vertex
        If T<M
            A->{T*2+V}     .The last element in the list must equal the first one.
            B->{T*2+1+V}
            T+1->T
            Pxl-On(A,B)
        End
        For(Z,0,20)        .Delay for usability
            DispGraph^^r
        End
    End

    If getKey(48)          .Draws the polygon
        {V}->{T*2+V}
        {V+1}->{T*2+V+1}
        sub(POL,T,V,C)
        0->T
        For(Z,0,20)
            DispGraph^^r
        End
    End

    If getKey(56)           .Clears the screen
        ClrDraw
        ClrDraw^^r
        RectI(A-1,B-1,3,3)^^r
        0->T
    End

    DispGraph^^r
End

Return


Lbl POL
    .Parameters
    .  r1: The total amount of vertexes
    .  r2: A list of vertexes (pairs of X and Y coordinates, each one byte)
    .  r3: A pointer to some free ram (Amount needed == approx. (max polygon width) * 2)
    .
    .Destroyed
    .  W, X, Y, Z, r3, r4, r5, r6
    .
    r3->W
    For(r4,0,r1-1)
        r4*2+r2->r5
        r4+1*2+r2->r6

        {r5}-{r6}->X
        {r5+1}-{r6+1}->Y
       
        If X>=>=0
            For(Z,0,X)
                {r5}-Z->{r3}
                ~Y*Z//X+{r5+1}->{r3+1}
                r3+2->r3
                M+2->M
            End
        Else
            For(Z,0,abs(X))
                {r5}+Z->{r3}
                Y*Z//X+{r5+1}->{r3+1}
                r3+2->r3
                M+2->M
            End
        End
    End

    For(Z,1,r3-W/2-1)
        Line({Z*2+W},{Z*2+W+1},{Z*2+W},{Z*~2+r3+1})^^r
    End
Return
Title: Re: Routines
Post by: ztrumpet on August 03, 2011, 09:18:55 am
Nice.  :D  Great job, Michael. :)
Title: Re: Routines
Post by: Happybobjr on September 01, 2011, 10:59:31 pm
Could someone make a routine to rotate the screen (or a 64x64 region) 64 (90) degrees?
Title: Re: Routines
Post by: WaeV on September 21, 2011, 02:15:09 am
This is an example of some functional code that we wrote in one of my programming classes.  The objective was to write a function that creates iterators.  Each time you call the iterator, it returns one more than the previous call.  Each time you call the iterator generator, it returns a new iterator.  We do this with lambda syntax and closures.  We wrote this in Scheme, but I was surprised and impressed to see it correctly execute in Axe.

The Axe code:
(I used liberal amounts of spaces to get it to line up the way I did)
Code: [Select]
.ITERATE

Iter()→L

Disp (L)()►Dec,i
Disp (L)()►Dec,i
Disp (L)()►Dec,i

Iter()→M

Disp (M)()►Dec,i
Disp (M)()►Dec,i
Disp (L)()►Dec,i

Lbl Iter
Return
λ(
  λ(
    λ(
      r₁+1→r₁
    )
  )(0)
)()

Output:
Code: [Select]
asm(prgmITERATE
    1
    2
    3
    1
    2
    4

An interesting side-effect of this is that the current iteration value is not stored in any variables - it's captured in the closure.  Not that it's efficient to do this on a calculator with limited memory, but it's interesting to say the least.
Title: Re: Routines
Post by: ztrumpet on September 21, 2011, 03:26:58 pm
This is an untested routine for displaying text with newlines in Axe.
Quote
:Lbl TXT
:.sub(TXT,Initial X,Initial Y,String)
:r1->r4
:For(I,0,length(r3))
:If {I+r3}->{L1}r-255
:Text(r1,r2,L1)
:r4+4->r4
:Else
:r2+7->r2
:r1->r4
:End
:End
:Return

Here is a sample usage:
Quote
:"TEXT[FF]NEWLINE[FF]ANOTHER LINE"->Str1
:sub(TXT,X,Y,Str1)
Title: Re: Routines
Post by: Darl181 on October 08, 2011, 01:19:49 am
How feasible would it be to make a line clipping routine?  I'm seeing more and more games that could use it, and iirc Quigibo doesn't plan on building it in :(
Title: Re: Routines
Post by: Deep Toaster on October 08, 2011, 01:24:48 pm
They're actually pretty simple. (Let's see if I can find my routine...)

The idea behind it is to shorten the X- and Y-lengths of the line so it's completely within the screen, but keeping them proportional (so the slope Y/X stays the same). For example, if the line runs from (X1,Y1) to (X2,Y2) and X2 is the only out-of-bounds point (say 99), you assign 95 to X2 (within the screen bounds), then move Y2 so the slope stays the same.

Take 95–X1 (which is the horizontal length of the clipped line), divide it by the original horizontal length (in our case, 99–X1), and multiply it by the current vertical length (Y2–Y1), to find the vertical length of the clipped line. Add that to Y1 and you get the new value for Y2. Now that both the points are completely within the screen, you can use Line() to draw the new line.
Title: Re: Routines
Post by: Darl181 on October 10, 2011, 02:51:05 pm
I'll try to work something out of that, thanks ;D
Title: Re: Routines
Post by: Darl181 on October 11, 2011, 09:10:46 pm
Ok, I'm confused.  Using the ideas from Deep's post I threw something together:
(S,T)="(X1,Y1)"
(X,Y) are manipulated
(N,O)="(X2,Y2)"
Spoiler For Code:
Quote from: Axe
.ATEST1
40→X→Y
48→S
32→T
Repeat getKey(15)
If getKey(54)
ClrHome
Disp "N",N>Dec,"  O",O>Dec,i,"X",X>Dec,"  Y",Y>Dec
While getKey(54)
Pause 10
End
End
X+getKey(3)-(getKey(2))→X
X→N
Y+getKey(1)-(getKey(4))→Y
Y→O
If N>>95
95→N
(95-S)//(X-S)*(O-T)→O
O+T→O
End
If O>>63
63→O
63-T//(Y-T)*(N-S)→N
N+48→N
End
If N<<0
-1→N
~S//(X-S)*(O-T)+T→O
End
If O<<0
-1→O
~T//(Y-T)*(N-S)+S→N
End
Line(S,T,N,O)
DispGraphClrDraw
Pause 20
End

Generated by the BBify'r (http://clrhome.tk/resources/bbify/ (http://clrhome.tk/resources/bbify/))
But for some reason, once the manipulable point goes off-screen, the program does something wrong and will only draw horizontal or vertical lines.  I'm suspecting it's rounding down to zero where the division happens, but idk.

After screwing around with it for a bit, I got this:
Spoiler For Code:
Quote from: Axe
.ATEST2
40→X→Y
48→S
32→T
Repeat getKey(15)
If getKey(54)
ClrHome
Disp "N",N>Dec,"  O",O>Dec,i,"X",X>Dec,"  Y",Y>Dec
While getKey(54)
Pause 10
End
End
X+getKey(3)-(getKey(2))→X
X→N
Y+getKey(1)-(getKey(4))→Y
Y→O
If N>>95
95→N
(95-S)//(N-S)*(O-T)→O
O+T→O
End
If O>>63
63→O
63-T//(O-T)*(N-S)→N
N+48→N
End
If N<<0
-1→N
~S//(N-S)*(O-T)+T→O
End
If O<<0
-1→O
~T//(O-T)*(N-S)+S→N
End
Line(S,T,N,O)
DispGraphClrDraw
Pause 20
End

Generated by the BBify'r (http://clrhome.tk/resources/bbify/ (http://clrhome.tk/resources/bbify/))
...and it somewhat* works, I have no idea why but it does. :P

So um yeah, I guess have a really unoptimized line routine (with other stuff thrown in)! ;)

*watching the screenie, you can tell the endpoint of the line is fixed on the edge, so the slope doesn't change accordingly...?

EDIT: btw it runs a bit slower than it should b/c there's a Pause 20 in there.  It can run faster than in the screenshot.
Title: Re: Routines
Post by: turiqwalrus on October 12, 2011, 10:23:05 am
nice ;)
once that's optimized, I'll switch from 0.5.3 :P
(and once I finally read the newest commands list x.x)
Title: Re: Routines
Post by: Darl181 on October 13, 2011, 12:12:09 am
Another one :P

How feasible would it be to make xoring lines/circles?  I just got a freaking huge optimization in Essence :D but it requires that whatever draws to the buffer inverts its pixels :|
(the explosions are lines+a circle and the blitz gun is made of lines as well)
Title: Re: Routines
Post by: aeTIos on October 14, 2011, 06:43:24 am
Who would like a search routine?
Title: Re: Routines
Post by: MGOS on October 25, 2011, 01:23:50 am
Does someone know a short and fast routine for a broke / dotted line?
Title: Re: Routines
Post by: Michael_Lee on October 25, 2011, 01:46:02 am
I don't know if you could call it either short or fast, but I did once make a variant on a line-drawing algorithm that can also do dotted lines at arbitrary intervals:
http://ourl.ca/4129/138496 (http://ourl.ca/4129/138496)

I deliberately added a 'Pause' in there, and constructed in such a way so that it would always radiate outwards (I was making a raycaster thing at the time), so it could definitely be optimized.
Title: Re: Routines
Post by: MGOS on October 25, 2011, 07:17:19 am
Thanks, that's good enough for my purposes.

I found a pixel-wise xor (or / and) function for sprites, to invert a sprite if it is on dark background.

Code: [Select]
pt-Get(X,Y)->W
For(I,0,7)
{W+I} xor ({sprite+I})->{W+I}
End
Pt-Off(X,Y,W)
Title: Re: Routines
Post by: Keoni29 on November 24, 2011, 03:29:54 pm
Thanks, that's good enough for my purposes.

I found a pixel-wise xor (or / and) function for sprites, to invert a sprite if it is on dark background.

Code: [Select]
pt-Get(X,Y)->W
For(I,0,7)
{W+I} xor ({sprite+I})->{W+I}
End
Pt-Off(X,Y,W)

That might come in handy for monochrome games :D
Title: Re: Routines
Post by: MGOS on November 25, 2011, 10:02:52 am
That might come in handy for monochrome games :D
Yeah, I needed it for a cursor in my program, which got undesiredly invisible if you moved to a black area.
Title: Re: Routines
Post by: calc84maniac on November 25, 2011, 10:48:05 am
Thanks, that's good enough for my purposes.

I found a pixel-wise xor (or / and) function for sprites, to invert a sprite if it is on dark background.

Code: [Select]
pt-Get(X,Y)->W
For(I,0,7)
{W+I} xor ({sprite+I})->{W+I}
End
Pt-Off(X,Y,W)

Is something wrong with Pt-Change(X,Y,sprite)?
Title: Re: Routines
Post by: aeTIos on November 25, 2011, 11:14:00 am
^That.
Title: Re: Routines
Post by: MGOS on November 25, 2011, 12:07:32 pm
Is something wrong with Pt-Change(X,Y,sprite)?
Yeah, else I wouldn't have posted this. The Pt-Change function inverts also white pixels, which isn't desired.
My routine only inverts if the background-pixel AND the sprite-pixel are black.
Title: Re: Routines
Post by: aeTIos on November 25, 2011, 01:26:58 pm
Aha.
Title: Re: Routines
Post by: Builderboy on November 25, 2011, 03:20:41 pm
Is something wrong with Pt-Change(X,Y,sprite)?
Yeah, else I wouldn't have posted this. The Pt-Change function inverts also white pixels, which isn't desired.
My routine only inverts if the background-pixel AND the sprite-pixel are black.

Actually looking at your code, it looks like your routine and Pt-Change() will do exactly the same things.  All Pt-Change is, is an XOR sprite display, which is exactly what you wrote
Title: Re: Routines
Post by: MGOS on November 25, 2011, 03:40:21 pm
Is something wrong with Pt-Change(X,Y,sprite)?
Yeah, else I wouldn't have posted this. The Pt-Change function inverts also white pixels, which isn't desired.
My routine only inverts if the background-pixel AND the sprite-pixel are black.

Actually looking at your code, it looks like your routine and Pt-Change() will do exactly the same things.  All Pt-Change is, is an XOR sprite display, which is exactly what you wrote

Ok, I tried it out and it's actually the same. But the routine stays usefull for ANDing sprites and maybe XORing with different buffers
Title: Re: Routines
Post by: jacobly on December 11, 2011, 02:31:21 am
Due to multiple requests, I wrote an axe clock library, LIBCLOCK. See CLOCKTST for example code.

Axe Code Function on calculators with a clock (function on calculators without a clock).

Main functions:
ClkOf() Turns the clock off (does nothing).
ClkOn() Turns the clock on (does nothing).
IsClk() Returns 1 if the clock is on, 0 if off (returns 0).
°A:GetDT() Gets the current date and time. Sets 6 consecutive variables, or 6 consecutive words, starting at the passed in address.  In this example, A = year, B = month, C = day, D = hour, E = minute, F = second (returns midnight of January 1, 1997). Do not pass in °r₁.
SetDT(year,month,day,hour,minute,second) Sets the current date and time (does nothing relatively slowly).
DOfWk(year,month,day) Returns the day of the week of the specified date, 1 = Sunday, ..., 7 = Saturday.

Low level functions:
°A:GetRT() Gets the current raw time. Sets 2 consecutive variables, or 2 consecutive words, starting at the passed in address.  In this example, AB = seconds since January 1, 1997 (AB = 0).
°A:SetRT() Sets the current raw time.  Uses 2 consecutive variables, or 2 consecutive words, starting at the passed in address (does nothing).

Bonus functions:
Mul21(r₁,r₂,r₃) Multiplies r₁r₂ by r₃ and stores the result in r₁r₂.
Div21(r₁,r₂,r₃) Divides r₁r₂ by r₃ and stores the result in r₁r₂, and the remainder in r₄. Edit: I think r₃ must be < 256.
Title: Re: Routines
Post by: Quigibo on December 13, 2011, 03:17:28 am
I made this fun little program and I wanted to share it because its awesome.  See if you can guess what shape it draws. ;D  
(Requires 1.1.0)

:.COOL
:.Allocate a 96x64 bitmap
:[6040]→Str1
:Buff(768)
:
:.Draw a single pixel on the screen
:ClrDraw
:Pxl-On(0,0)
:
:.Loop a few times
:1→C
:For(6)
:  .Turn the buffer into a bitmap
:  Copy(L6,Str1+2,768)
:
:  .Draw some bitmaps
:  Bitmap(C,0,Str1)
:  Bitmap(0,C,Str1)
:  
:  .Display and iterate
:  DispGraph
:  C*2→C
:End
:Pause 5000
Title: Re: Routines
Post by: jacobly on December 13, 2011, 03:46:34 am
Spoiler For guess:
Sierpinski-ish?
################################################################
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ## 
#   #   #   #   #   #   #   #   #   #   #   #   #   #   #   #   
####    ####    ####    ####    ####    ####    ####    ####   
# #     # #     # #     # #     # #     # #     # #     # #     
##      ##      ##      ##      ##      ##      ##      ##     
#       #       #       #       #       #       #       #       
########        ########        ########        ########       
# # # #         # # # #         # # # #         # # # #         
##  ##          ##  ##          ##  ##          ##  ##         
#   #           #   #           #   #           #   #           
####            ####            ####            ####           
# #             # #             # #             # #             
##              ##              ##              ##             
#               #               #               #               
################                ################               
# # # # # # # #                 # # # # # # # #                 
##  ##  ##  ##                  ##  ##  ##  ##                 
#   #   #   #                   #   #   #   #                   
####    ####                    ####    ####                   
# #     # #                     # #     # #                     
##      ##                      ##      ##                     
#       #                       #       #                       
########                        ########                       
# # # #                         # # # #                         
##  ##                          ##  ##                         
#   #                           #   #                           
####                            ####                           
# #                             # #                             
##                              ##                             
#                               #                               
################################
# # # # # # # # # # # # # # # #
##  ##  ##  ##  ##  ##  ##  ## 
#   #   #   #   #   #   #   #   
####    ####    ####    ####   
# #     # #     # #     # #     
##      ##      ##      ##     
#       #       #       #       
########        ########       
# # # #         # # # #         
##  ##          ##  ##         
#   #           #   #           
####            ####           
# #             # #             
##              ##             
#               #               
################
# # # # # # # #
##  ##  ##  ## 
#   #   #   #   
####    ####   
# #     # #     
##      ##     
#       #       
########       
# # # #         
##  ##         
#   #           
####           
# #             
##             
#               
I feel like a computer now... :P
Title: Re: Routines
Post by: parserp on December 23, 2011, 03:12:23 pm
I've seen some people wanting to use Text input routines, so here's the one I use in Axe Snake, SpiderAx, and Jump.  Press Second when done typing, del to backspace, and Clear to quit.
At the end of the routine, the string is null terminated and begins at L1.  It also Displays it again because I wanted to show how to display it and waits for you to press second again. :)

If you use this routine, you may credit me, but it is not necessary. ;D
so... I have been trying to use this, but would it be possible to store it in a string rather than a list?
I've tried L1->Str0, but it doesn't work when trying to do stuff like this: GatCalc("appvStr0",Y0)

...but, is that even possible?
Title: Re: Routines
Post by: epic7 on December 23, 2011, 03:16:10 pm
Maybe use Copy(?
Title: Re: Routines
Post by: parserp on December 23, 2011, 03:26:16 pm
Maybe use Copy(?
hmmm, doesn't seem to work D:
Title: Re: Routines
Post by: jacobly on December 23, 2011, 09:44:02 pm
L₁→Str0 and GetCalc("Str0",Y₀) refer to two completely different Str0's. Assuming you want to get L₁ into Str0, as in if you were to type Str0 on the home screen, it would display the string at L₁, then:
Copy(L₁,GetCalc("Str0",length(L₁)→L),L)
Title: Re: Routines
Post by: Builderboy on December 23, 2011, 10:26:14 pm
Yeah it all depends on what you mean.  You say you want it to store into a string rather than a list, but it doesn't store the text to a list in the first place, it stores it directly to memory, at the location L1.  When you say string, we are not sure if you mean an Axe data string (Str0 GDB0 Pic0) or an OS string
Title: Re: Routines
Post by: ztrumpet on December 23, 2011, 10:35:45 pm
Do you mean into an OS string?  If so, you will want to combine a couple of routines here.  If you just want to store it to the Axe variable, Str0, that's different.  For it, do Buff(17)->Str0 at the beginning of the program and then replace L1 in my routine with Str0.
Title: Re: Routines
Post by: parserp on December 23, 2011, 11:41:24 pm
Do you mean into an OS string?  If so, you will want to combine a couple of routines here.  If you just want to store it to the Axe variable, Str0, that's different.  For it, do Buff(17)->Str0 at the beginning of the program and then replace L1 in my routine with Str0.
ah, ok. I'm trying to get it as an axe variable, and I need it to create an appvar with the selected name in the program.
However, I'm not understanding exactly what I need to do in order to do that. D:
Title: Re: Routines
Post by: jacobly on December 23, 2011, 11:45:18 pm
Is this what you want?
Code: [Select]
"appv"Buff(8)→Str0
Copy(L₁,Str0+1,8)
GetCalc(Str0,Y₀)
Title: Re: Routines
Post by: parserp on December 23, 2011, 11:49:53 pm
Is this what you want?
Code: [Select]
"appv"Buff(8)→Str0
Copy(L₁,Str0+1,8)
GetCalc(Str0,Y₀)
Ahh, yes!!! it works! thanks! :D
Title: Re: Routines
Post by: Keoni29 on January 31, 2012, 07:16:13 am
http://ourl.ca/15074
A routine which draws a sprite scaled.
Title: Re: Routines
Post by: Xeda112358 on January 31, 2012, 08:56:42 am
To make Serpinski's triangle, I am not sure if this is proper Axe code, but it is essentially how I do it in other languages where I have such fun screen access (and it does not use another buffer):
Code: [Select]
0→A
ClrDraw
Repeat getKey(15
If A≤95
A++
Pxl-On(A,0            ;Axe use (X,Y), right?
End
DispGraph
L6+767→C-12→D
For(756)
{C--} xor {D--}→{C}
End
End
That isn't nearly as fast as it could be, but I'm not too good with Axe XD

EDIT: THe screenie isn't the above Axe program (it is in another language)
EDIT2: calc84maniac gave some optimisation tricks (using For(756) and {C--} for example)
Title: Re: Routines
Post by: Deep Toaster on January 31, 2012, 09:37:52 am
http://ourl.ca/15074
A routine which draws a sprite scaled.
I think this got lost in the threads of time, but meishe91, DJ_O, and Quigibo came up with some really neat scalers (for partial sizes, even) on this page: http://ourl.ca/60160
Title: Re: Routines
Post by: Keoni29 on January 31, 2012, 02:34:18 pm
http://ourl.ca/15074
A routine which draws a sprite scaled.
I think this got lost in the threads of time, but meishe91, DJ_O, and Quigibo came up with some really neat scalers (for partial sizes, even) on this page: http://ourl.ca/60160
Cool! I haven't seen that one before. I wrote my routine at school today, because I was bored :)
Title: Re: Routines
Post by: Hayleia on February 10, 2013, 02:19:35 am
Due to multiple requests, I wrote an axe clock library, LIBCLOCK. See CLOCKTST for example code.

Axe Code Function on calculators with a clock (function on calculators without a clock).

Main functions:
ClkOf() Turns the clock off (does nothing).
ClkOn() Turns the clock on (does nothing).
IsClk() Returns 1 if the clock is on, 0 if off (returns 0).
°A:GetDT() Gets the current date and time. Sets 6 consecutive variables, or 6 consecutive words, starting at the passed in address.  In this example, A = year, B = month, C = day, D = hour, E = minute, F = second (returns midnight of January 1, 1997). Do not pass in °r₁.
SetDT(year,month,day,hour,minute,second) Sets the current date and time (does nothing relatively slowly).
DOfWk(year,month,day) Returns the day of the week of the specified date, 1 = Sunday, ..., 7 = Saturday.

Low level functions:
°A:GetRT() Gets the current raw time. Sets 2 consecutive variables, or 2 consecutive words, starting at the passed in address.  In this example, AB = seconds since January 1, 1997 (AB = 0).
°A:SetRT() Sets the current raw time.  Uses 2 consecutive variables, or 2 consecutive words, starting at the passed in address (does nothing).

Bonus functions:
Mul21(r₁,r₂,r₃) Multiplies r₁r₂ by r₃ and stores the result in r₁r₂.
Div21(r₁,r₂,r₃) Divides r₁r₂ by r₃ and stores the result in r₁r₂, and the remainder in r₄. Edit: I think r₃ must be < 256.
Reading the clock works great :)
But why does setting it does nothing (as mentionned in your post) ?
Title: Re: Routines
Post by: Matrefeytontias on July 04, 2013, 06:04:00 am
Mega bump,

I wrote this for TheMachine02's GLib, and thought it could be useful to others (even if I doubt so :P). So here's a clipped triangle filler that takes arguments between -512 and 511 (might be a bit inaccurate though, and is surely unoptimized) :

Triangle(x1,y1,x2,y2,x3,y3)

E90D3→°DX1+2→°DX2+2→°SX1+2→°SX2

Lbl Triangle
If r2>>r4
Exch(°r1,°r3,4)
End
If r4>>r6
Exch(°r3,°r5,4)
End
If r2>>r4
Exch(°r1,°r3,4)
End

If r4-r2→X
r3-r1*64//X
Else
r3-r1*64
End
→DX1
If r6-r2→X
r5-r1*64//X
Else
r5-r1*64
End
→DX2

r1*64→SX1→SX2
r2→Y

For(2)
While 1
If Y<64
!If SX1·SX2ee0
min(max(SX1,0)r/64,95)→Z
min(max(SX2,0)r/64,95)→Θ
.Remember that HLine(Y,X1,X) is broken in 1.2.1, so remember to update it with the next versions of Axe
Line(Z,Y,Θ,Y)
End
End
DX1+SX1→SX1
DX2+SX2→SX2
Y++
EndIf Y+1>>r4
If r6-r4→X
r5-r3*64//X
Else
r5-r3*64
End
→DX1
r6→r4
End

And yeah. This routine uses 10.6 fixed point numbers.
Title: Re: Routines
Post by: TheMachine02 on July 04, 2013, 12:20:06 pm
there is just a little problem in your routine  :P , wich is, in other part very good
You don't do a perfect clipping due to one line :

Code: [Select]
If Y<64

who let enter in the drawing part even if y<0 ...
you can do this instead :

Code: [Select]
!If Y.π1111111111000000

if y<0 or Y>64 it will not draw anything  ;D(http://www.omnimaga.org/Themes/default/images/gpbp_arrow_up.gif)
Title: Re: Routines
Post by: Matrefeytontias on July 04, 2013, 12:26:23 pm
You're wrong : I test if the unsigned value of Y is lesser than 64. If Y is lesser than 0, the 15th bit will be set, making it at least 32768. So it's okay. I would have been wrong if I had used :

If Y<<64
Title: Re: Routines
Post by: TheMachine02 on July 04, 2013, 12:30:29 pm
Oh yes effectively.   I take Y<64 for Y<<64    ;D
I don't know if   !If Y.π1111111111000000  is more faster  ,thought
Title: Re: Routines
Post by: Matrefeytontias on July 04, 2013, 12:31:16 pm
I don't know ... I guess we'll have to test it ;D (I won't do it though :P)
Title: Re: Routines
Post by: Streetwalrus on August 09, 2013, 05:32:08 pm
Asm(DB02CB7FC8)
This opcode is a conditional Return. If run on an 83+BE it will return else it will continue along. More efficient than Return!If Full:Normal. ;)
Title: Re: Routines
Post by: nikitouzz on May 08, 2014, 04:49:25 pm
Runer112 : "Decimal display: Disp Pointer to number to display sub(DEC) - Note that this does not return a string of a fixed length padded on the left with spaces like the usual Disp ►Dec. The string returned has any leading zeros clipped and consists only of the number itself."

When i try to use the fonctions dec.... text(32,71,°Osub(DEC^^r)) the programm don't function and the calto crash.... but on another programme, it work...

Then i want replace all the E8499 and Eblabla by L2 and L2+100 i've make this :

L2→r1
L2+100→r2
and i replace all the E... by r1 or r2 but... the calculator crash...


Code: [Select]
:Lbl DEC
:L2→r1
:L2+100→r2
:  conj(,R1,3)
:  0→{R2}r
:  Fill(1+R2,8)
:  R2→{10+R1}r
:  0+R1→r1
:  4+R1→r2
:  0+R1→r3
:  ([806967])
:  sub(DE0)
:  ([C0BDF0])
:  sub(DE0)
:  ([6079FE])
:  sub(DE0)
:  ([F0D8FF])
 :  sub(DE0)
:  ([18FCFF])
:  sub(DE0)
:  ([9CFFFF])
:  sub(DE0)
:  ([F6FFFF])
:  sub(DE0)
:  ([FFFFFF])
:  sub(DE0)
:  R2
:  Return
:  Lbl DE0
:  conj(,4+R1,3)
:  '0'-1→{8+R1}r
:  Lbl DE1
:  {8+R1}r+1→{8+R1}r
:  If {2+R1}≥{sub(ADD)}
:       Goto DE1
:  End
:  sub(SUB)
:  Return!If {4+R1}+1/256+{8+R1}r-'0'+{R2}r
:     {8+R1}r→{{10+R1}r}+1→{10+R1}r
:Return








PS : i don't use L2 in my programme
Title: Re: Routines
Post by: c4ooo on March 11, 2015, 04:41:47 pm
I made a Flood Fill algorithm here: https://www.omnimaga.org/axe-language/my-axe-flood-fill-algorithm/msg399980/#msg399980 .