CodeWalrus

Development => Calculators => Calculator News, Coding, Help & Talk => Topic started by: p2 on August 24, 2016, 11:41:43 AM

Title: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 11:41:43 AM
Hey guys,
As some of you might already know, I haven't used axe for a couple of years and forgot almost everything about it  :'(
So now I'm trying to relearn axe and wanted ot ask you how I could improve the following code I wrote...
It's ment to be a player (just a square) kickign arount a Ball (a nice circle) with workign colission and gravty stuff...
I'm really sorry but I got no GIF to upload yet, hope you still understand what the code should do...  :(

[spoiler=Main Program].TRY07AXE
ClrDraw
[3C7EFFFFFFFF7E3C]->Pic01
[FF818181818181FF]->Pic02
.L1{0,2, 4, 6
.L1{X,Y,vX,vY
1000->{L1+0}^r
1000->{L1+2}^r
200->{L1+4}^r
100->{L1+6}^r
.Direction(X,Y)=T,U
1->T->U
.Pos Player *100 = V,W
5000->V
1000->W
.Gravitation=G
0->G
.N=NotCollide to prevent double collision
0->N
.C=Counter
0->C
Repeat getKey(15)
C++
ClrDraw
Pt-On({L1+0}^r/100,{L1+2}^r/100,Pic01)
Pt-On(V/100,W/100,Pic02)
DispGraph
{L1+0}^r+({L1+4}^r*T)->{L1+0}^r
{L1+2}^r+({L1+6}^r*T)->{L1+2}^r
prgmTRY07MOV
prgmTRY07COL
prgmTRY07GRV
End
[/spoiler]

[spoiler=Program for players Movement]..TRY07MOV
.DownArrowKey
If getKey(1) and (W<5600):W+100->W:End
.LeftArrowKey
If getKey(2) and (V>0):V-100->V:End
.RightArrowKey
If getKey(3) and (V<8600):V+100->V:End
.UpArrowKey
If getKey(4) and (W>0):W-100->W:End
[/spoiler]

[spoiler=Program for colission and stuff]..TRY07COL
.DOUBLECOLLIDE
N-1->N:If N=(0-1):0->N:End
.COLIDE
.Top Left
If (N=0) and (({L1+0}^r/100)>=((V/100)-7)) and (({L1+0}^r/100)<=((V/100)-6)) and (({L1+2}^r/100)>=((V/100)-7)) and (({L1+2}^r/100)<=((V/100)-6)):{L1+4}^r+80->{L1+4}^r:{L1+6}^r+80->{L1+6}^r:(0-1)->T->U:5->N:0->G:End
.Top Right
If (N=0) and (({L1+0}^r/100)>=((V/100)+7)) and (({L1+0}^r/100)<=((V/100)+7)) and (({L1+2}^r/100)>=((V/100)-7)) and (({L1+2}^r/100)<=((V/100)-6)):{L1+4}^r+80->{L1+4}^r:{L1+6}^r+80->{L1+6}^r:1->T:(0-1)->U:5->N:0->G:End
.Bottom Left
If (N=0) and (({L1+0}^r/100)>=((V/100)-7)) and (({L1+0}^r/100)<=((V/100)-6)) and (({L1+2}^r/100)>=((V/100)+6)) and (({L1+2}^r/100)<=((V/100)+7)):{L1+4}^r+100->{L1+4}^r:{L1+6}^r+100->{L1+6}^r:(0-1)->T:1->U:5->N:End
.Bottom Right
If (N=0) and (({L1+0}^r/100)>=((V/100)+6)) and (({L1+0}^r/100)<=((V/100)+7)) and (({L1+2}^r/100)>=((V/100)+6)) and (({L1+2}^r/100)<=((V/100)+7)):{L1+4}^r+100->{L1+4}^r:{L1+6}^r+100->{L1+6}^r:1->T->U:5->N:End
.Top
If (N=0) and (({L1+0}^r/100)>=((V/100)-5)) and (({L1+0}^r/100)<=((V/100)+5)) and (({L1+2}^r/100)>=((V/100)-8)) and (({L1+2}^r/100)<=((V/100)-6)):{L1+6}^r+100->{L1+6}^r:(0-1)->U:5->N:0->G:End
.Left
If (N=0) and (({L1+0}^r/100)>=((V/100)-8)) and (({L1+0}^r/100)<=((V/100)-7)) and (({L1+2}^r/100)>=((V/100)-5)) and (({L1+2}^r/100)<=((V/100)+5)):{L1+4}^r+80->{L1+4}^r:5->N:If ({L1+2}^r>5500):(0-1)->U:{L1+6}^r+80->{L1+6}^r:{L1+4}^r+20->{L1+4}^r:End:End
.Right
If (N=0) and (({L1+0}^r/100)>=((V/100)+7)) and (({L1+0}^r/100)<=((V/100)+8)) and (({L1+2}^r/100)>=((V/100)-5)) and (({L1+2}^r/100)<=((V/100)+5)):{L1+4}^r+80->{L1+4}^r:5->N:If ({L1+2}^r>5500):(0-1)->U:{L1+6}^r+80->{L1+6}^r:{L1+4}^r+20->{L1+4}^r:End:End
.Bottom
If (N=0) and (({L1+0}^r/100)>=((V/100)-5)) and (({L1+0}^r/100)<=((V/100)+5)) and (({L1+2}^r/100)>=((V/100)+7)) and (({L1+2}^r/100)<=((V/100)+8)):1->U:G/5+{L1+6}^r/2+50->{L1+6}^r:0->G:End
.BORDERS
.Left
If ({L1+0}^r<100) or ({L1+0}^r>(0-1000)):100->{L1+0}^r:1->T:End
.Right
If ({L1+0}^r>8600):8600->{L1+0}^r:(0-1)->T:End
.Top
If ({L1+2}^r)<100):100->{L1+2}^r:1->U:({L1+6}^r/2)->{L1+6}^r:End
.Bottom
If ({L1+2}^r)>5600):5600->{L1+2}^r:(0-1)->U:((G/10)+{L1+6}^r)->{L1+6}^r:0->G:End
[/spoiler]

[spoiler=Program fpr gravity]..TRY07GRV
.Friction
If {L1+4}^r>50:{L1+4}^r+99/100->{L1+4}^r:Else:If {L1+4}^r<20:If (C/4+4)=C:{L1+4}^r*99/100->{L1+4}^r:End:Else:If (C/2+2)=C:{L1+4}^r*99/100->{L1+4}^r:End:End:End
.Slow down and speed up
If U=1:{L1+6}^r*102->{L1+6}^r:Else:{L1+6}^r*97->{L1+6}^r:End:{L1+6}^r/100->{L1+6}^r
.Add Gravity
G+3->G:G/10+{L1+2}^r->{L1+2}^r
[/spoiler]

Aaand explanations:
You're a square kicking arount a circle....
{L1+0}^r = X-pos ball
{L1+2}^r = Y-pos ball
{L1+4}^r = X-speed ball
{L1+6}^r = Y-Speed ball
T = Direction X-Movement ball (1 or -1)
U = Direction Y-Movement ball (1 or -1)
V = X-Pos player
W = Y-Pos player
C = Counter (add 1 each loop in main program so I can use it for executing stuff every 2 or every 4 rounds)
N = No-collide (counter for how many "rounds" it's gonna ignore colission stuff. To prevent trigering the colusion twice at once)
G = Gravitation (always rising and reset/changed by colissions)

Important: All graphic-related stuff is multiplied with 100... So I't wirking with a 9600x6400 screen and a Speed of 100 means 1px movement per round.
That's where all the /100 is coming from :)
[spoiler=Where the strange numbers in Colission come from]


(http://img.omnimaga.org/COLLISION.png)These numbers seem a bit strange because it's actually the positions for the coliding object:
It's the top-left coordinates of an 8x8 image (the ball in this case) that collides with these zones (marked orange and green).
The darked boxes are the border of the player itself (just a square)

I used this for colission in order to bet the edges working well, too and also to prevent a colision from not being detected
(for example if the ball is faster than 1px/round and "jumps" inside the player)


I really hope you understand what I mean... :/


[/spoiler]


I plan on moving all teh vars inside L1, add a second player, add Goals and add the gravity for players, too (so you got a realistic jump isntead of just floating around).
Still It'll be a crappy game, but it's just for learning purposes not for being published or something ^^

Pls dont hate me for writing such crappy code - this is my first attempt after more than 4 years... :(

Edit: Fixed a typing mistake in Gravitation program... accidentally used '+' instead of '*' there...
Title: Re: Some super crappy Axe code...
Post by: c4ooo on August 24, 2016, 03:20:12 PM
Alot to of code to correct everything, but here are some tips:

Axe has left to right order of operations;
{L1+0}^r+({L1+4}^r*T)->{L1+0}^r
can be
{L1+4}^r*T+{L1+0}^r->{L1+0}^r


0->G
.N=NotCollide to prevent double collision
0->N
.C=Counter
0->C

The above can just be 0->G->N->C

G+3->G:G/10+{L1+2}^r->{L1+2}^r
Can be
G+3->G:/10+{L1+2}^r->{L1+2}^r
If there is no var/number before the "/10", then it just uses the last value. (in this case G+3)

If U=1:{L1+6}^r+102->{L1+6}^r:Else:{L1+6}^r+97->{L1+6}^r:End
Can be

If U=1:102:Else:97:End
+{L1+6}^r->{L1+6}^r


This block:

If getKey(1) and (W<5600):W+100->W:End
.LeftArrowKey
If getKey(2) and (V>0):V-100->V:End
.RightArrowKey
If getKey(3) and (V<8600):V+100->V:End
.UpArrowKey
If getKey(4) and (W>0):W-100->W:End

Can be:

If W<5600 and getKey(1):W+100->W:End
If V>0 and getKey(2):V-100->V:End
If V<8600 and getKey(3):V+100->V:End
If  W>0 and getKey(4):W-100->W:End

which can further be optimized to:

W<5600 and andgetKey(1)-(W>0 and getKey(4))*100+W->W
V<8600 and getKey(3)-(V>0 and getKey(2))*100+V->V



Please not that some of this stuff has the possibility of being wrong so dont change everything at once ;)
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 24, 2016, 03:30:02 PM
1) Indentation.
If you're developing on-calc, it's obviously harder to do. zStart has a small font editor but I'd also understand that you avoid zStart or that editor.
So, do it if you can, and obviously don't if you can't.

2) Custom variables.
Instead of having a comment saying "L1{X,Y,vX,vY" then using a lot of these "{L1+__}^r", you could use custom variables.
How? Well just try that:

L1+00->°PosX
L1+02->°PosY
L1+04->°VX
L1+06->°VY

Then do stuff with PosX, PosY and others as if they were variables. Like 0->PosX, PosX++, etc. It works.
Your names can contain 13 characters max. That's enough for most uses.

3) Names in general.
Pic01, what is that supposed to mean? Well, if it's a sprite, having "Pic" in the name is better than having "Str", but still. I guess it's the ball's sprite. And same, Pic02 must be the Player's sprite. Well, then, try that:

...
...
[3C7EFFFFFFFF7E3C]->°BallSprite
[FF818181818181FF]->°PlayerSprite
...
...
Pt-On({L1+0}^r/100,{L1+2}^r/100,°BallSprite)
Pt-On(V/100,W/100,°PlayerSprite)
...
...

Same, 13 characters max.

4) Subprograms.
I'd say they should only be used as a compilation of subfunctions you didn't want to put in the main file (to save space or have less lines or whatever), but having them in a loop the way you did is a bad idea. You seem to think this works the same way as in basic, which is "there is no custom subfunctions but there are subprograms that are not pasted everytime". Well it's exactly the contrary, there are subfunctions in Axe and subprograms are pasted everytime.
To use a subfunctions, do like that:

.TOASTER
...
...
Add(3,4)->A
...
...
Return

Lbl Add
r1+r2
Return


5) Optimization.
Well, I'm not talking about that one. Readability is better for beginners.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 04:28:16 PM
Quote from: c4ooo on August 24, 2016, 03:20:12 PM
G+3->G:G/10+{L1+2}^r->{L1+2}^r
Can be
G+3->G:/10+{L1+2}^r->{L1+2}^r
If there is no var/number before the "/10", then it just uses the last value. (in this case G+3)
Definitely gonna modify the whole code like this :D Thanks a lot!  :thumbsup:


Quote from: Hayleia on August 24, 2016, 03:30:02 PM
2) Custom variables.
Instead of having a comment saying "L1{X,Y,vX,vY" then using a lot of these "{L1+__}^r", you could use custom variables.
How? Well just try that:

L1+00->°PosX
L1+02->°PosY
L1+04->°VX
L1+06->°VY

Then do stuff with PosX, PosY and others as if they were variables. Like 0->PosX, PosX++, etc. It works.
Your names can contain 13 characters max. That's enough for most uses.

[3C7EFFFFFFFF7E3C]->°BallSprite
[FF818181818181FF]->°PlayerSprite
...
...
Pt-On({L1+0}^r/100,{L1+2}^r/100,°BallSprite)
Pt-On(V/100,W/100,°PlayerSprite)
...
...

Same, 13 characters max.
Okeyy these custom names are really cool :D I'll use them, too ^^ (Always got to add ° before the name, right? :)

But just in theory, let's say I wanted a second and a third ball added to the game...
Could I just do something like {100*Z+L1+2}^r and {100*Z+L1+4}^r and put it in a for(Z,0,2) or won't that work?
Because then it wouldn't always make sense for me to use custom variable names... ^^


Quote from: Hayleia on August 24, 2016, 03:30:02 PM
4) Subprograms.
I'd say they should only be used as a compilation of subfunctions you didn't want to put in the main file (to save space or have less lines or whatever), but having them in a loop the way you did is a bad idea. You seem to think this works the same way as in basic, which is "there is no custom subfunctions but there are subprograms that are not pasted everytime". Well it's exactly the contrary, there are subfunctions in Axe and subprograms are pasted everytime.
To use a subfunctions, do like that:

.TOASTER
...
...
Add(3,4)->A
...
...
Return

Lbl Add
r1+r2
Return

I guess this Add is an example for a subroutine... Do I have to give the variables as parameter or can it just access the vars, too?
That would be a problem since I'm gonna change a lot of stuff for example in the colission program (G, xPos, YPos, vX, vY, T, U)
Aaand do I need to add a "Return" too at the end of the subroutine as long as my subroutine shouldn't return a specific value but rather change a lot of vars...?


Quote from: Hayleia on August 24, 2016, 03:30:02 PM
5) Optimization.
Well, I'm not talking about that one. Readability is better for beginners.
Just show me some stuff and let's see how much I'll understand ;D Want to quickly learn everything again... >.>
*Thank you very much for your help!! :) :)
Title: Re: Some super crappy Axe code...
Post by: E37 on August 24, 2016, 04:55:22 PM
L1+2->oNAME
NAME = {L1+2}r
You don't need the angle. You can use NAME exactly as a letter var. It is two bytes. The angle is only needed in declaration.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 04:59:55 PM
So this is how it's done? :)
5->°SuperAwesome
3->A
A+SuperAwesome->A
Title: Re: Some super crappy Axe code...
Post by: E37 on August 24, 2016, 05:17:06 PM
SuperAwesome must be given a memory location at its declaration.
if you used your verson, 37->SuperAwesome would changes bytes 5 and 6 in ram.
if the variable was declared as L1->°SuperAwesome then 37-> SuperAwesome would set {L1}r to be 37.

What you are thinking of is a constant. Here is how to use them:
number->->°CONSTANT
creates a constant named CONSTANT and gives it the value number.
Disp °CONSTANT >dec
would display the value of the number. Note the angle sign!
Constants cannot be changed!
They do have the benefit of being the same size and speed of typing number in each time instead of constant. Axe simply replaces °CONSTANT with the number when it compiles.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 05:26:02 PM
wooow, wait a sec *-*
{L1+2}^r->°xBallA
{L1+102}^r->°xBallB
{L1+202}^r->°xBallC
for(Z,0,2):{100*Z+L1+2}^r->A:Text(10,10*Z,A>Dec):end

This would actually work? It would display all three values?
So I can then access the stuff both by using the fancy name xBallA AND by using the momory position {L1+2}^r  O.O
I love this language... >.>
Title: Re: Some super crappy Axe code...
Post by: E37 on August 24, 2016, 05:31:10 PM
Quote from: p2 on August 24, 2016, 05:26:02 PM
wooow, wait a sec *-*
{L1+2}^r->°xBallA
{L1+102}^r->°xBallB
{L1+202}^r->°xBallC
for(Z,0,2):{100*Z+L1+2}^r->A:Text(10,10*Z,A>Dec):end

This would actually work? It would display all three values?
So I can then access the stuff both by using the fancy name xBallA AND by using the momory position {L1+2}^r  O.O
I love this language... >.>
Woah, Woah, Woah! hang on a sec!
Custom variables need a MEMORY LOCATON not a number!
L1+102->°xBallB would be the correct way to declare it.
Disp xBallB={L1-102}r >Dec
should then always display true (1).
It needs a memory loction because, of course, you can't create memory. It needs a place to store its data.
edit: i'm not sure you can start a variable with a lowercase though...
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 24, 2016, 05:34:42 PM
Quote from: p2 on August 24, 2016, 04:28:16 PM
I guess this Add is an example for a subroutine... Do I have to give the variables as parameter or can it just access the vars, too?
That would be a problem since I'm gonna change a lot of stuff for example in the colission program (G, xPos, YPos, vX, vY, T, U)
Aaand do I need to add a "Return" too at the end of the subroutine as long as my subroutine shouldn't return a specific value but rather change a lot of vars...?
Yes it was a subroutine.
You never specify arguments in Axe. If there are any, they are r1,r2...r6.
So basically, Add(3,4,5) is the same as 3->r1:4->r2:5->r3:Add().
And the Return is the end of the subroutine. Even if it returns nothing, you must finish with a return.
And the same way G+3->G:/10 worked, the r1+r2:Return works.
Title: Re: Some super crappy Axe code...
Post by: E37 on August 24, 2016, 05:43:08 PM
As for modifying c4ooo code even further,
W<5600 and getKey(1)-(W>0 and getKey(4))*100+W->W
could be even further optimized to:
W<5600?getkey(1)-(W?getkey(4))*100+W->W //note that the question marks are there on purpose and that is a negative sign, not a minus.
Since Axe doesn't really do negative numbers, (that is up to you) W>0 could be changed to just number. since any nonzero number is greater than zero.
(there are negative commands but I don't really touch them since they aren't a lot of cases they are useful outside of physics engines and my physics engines are terrible)
The question mark means if the previous statement is true, continue. If it isn't skip the rest of the code and go the the next newline.

As for learning to program Axe I still find it helpful to program with a paper or electronic copy of the Axe command list nearby. http://axe.eeems.ca/Commands.html
Oh... by the way, your code isn't bad at all! It is heaps better than my first code! It took me weeks to grasp the concepts of how lists are structured.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 05:51:15 PM
Quote from: E37 on August 24, 2016, 05:31:10 PM
Woah, Woah, Woah! hang on a sec!
Custom variables need a MEMORY LOCATON not a number!
L1+102->°xBallB would be the correct way to declare it.
Disp xBallB={L1-102}r >Dec
should then always display true (1).
It needs a memory loction because, of course, you can't create memory. It needs a place to store its data.
edit: i'm not sure you can start a variable with a lowercase though...
uh sorry my fault ^^
ok then this should work now? :)
L1+2->°xBallA
L1+102->°xBallB
L1+202->°xBallC
for(Z,0,2):{100*Z+L1+2}^r->A:Text(10,10*Z,A>Dec):end

L1+2 would be a memory position while {L1+2} would be the content of the byte 2 adresses after that same one, right?
and the ^r in the declaration (first 3 lines) isn't needed because as  basic integer is's using 2 Bytes by default, right? :)
If this is both correct, I understood how to do it ^.^

Quote from: E37 on August 24, 2016, 05:31:10 PMedit: i'm not sure you can start a variable with a lowercase though...
Does someone here know this? ^^



Quote from: Hayleia on August 24, 2016, 05:34:42 PM
And the Return is the end of the subroutine. Even if it returns nothing, you must finish with a return.
And the same way G+3->G:/10 worked, the r1+r2:Return works.

So this Subfunction DoStuff would actually do 5->A->Z:
...
...
DoStuff( )->Z
...
...
Return

Lbl DoStuff
5->A:Return


But this one would not return anything so be an error?
...
...
DoStuff( )->Z
...
...
Return

Lbl DoStuff
5->A
Return


Is it a problem if a called Subfunction returns some value but It's not used afterwards...?
Or is it optional to use the returned value, no matter if there is one or not?
Like this:
...
...
DoStuff( )
...
...
Return

Lbl DoStuff
5->A:Return

Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 24, 2016, 06:08:02 PM
Quote from: p2 on August 24, 2016, 05:51:15 PM
So this Subfunction DoStuff would actually do 5->A->Z:
...
...
DoStuff( )->Z
...
...
Return

Lbl DoStuff
5->A:Return


But this one would not return anything so be an error?
...
...
DoStuff( )->Z
...
...
Return

Lbl DoStuff
5->A
Return

They are exactly the same. A new line or a ":" is the same thing.
You can even write something after the return if you want (and it can be useful in some cases). Like

...
...
Lbl Stuffs
r1*r2->r5
r3*r4->r6
Return r5+r6
...
...

Well yeah, not so useful here, but you see what I mean.

Quote from: p2 on August 24, 2016, 05:51:15 PM
Is it a problem if a called Subfunction returns some value but It's not used afterwards...?
Or is it optional to use the returned value, no matter if there is one or not?
There is something you didn't get about Axe. Every single thing "returns" something.
Example that seems unrelated but helps you understand Axe better.

A+3*3->B


A
+3
*3
->B

These codes do the same thing.
So as long as your subfunction (that we call "routine actually") has code, it will return something, even if you don't care and don't do anything with its return value.
And that's how you end up writing code that doesn't use any variable (https://www.omnimaga.org/hp-prime/hp-prime-nitacku-ized-(animation)/msg373280/#msg373280) (@matref involved too) :P
Title: Re: Some super crappy Axe code...
Post by: c4ooo on August 24, 2016, 06:08:16 PM
" As for modifying c4ooo code even further,
W<5600 and getKey(1)-(W>0 and getKey(4))*100+W->W
could be even further optimized to:
W<5600?getkey(1)-(W?getkey(4))*100+W->W //note that the question marks are there on purpose and that is a negative sign, not a minus."

Don't think that will work @E37  If W>5600, then everything past the "?" will simply be ignored, which we don't want. In the second case it might work, but it is unnecessary. Also you can't dojust do "W?"; that will only be true if W is non zero, and a negative number is non zero. However " W>0" won't work either because ">" is unsigned comparison. You would have to do "W>>0". (So -1>0 in axe would return true)
Title: Re: Some super crappy Axe code...
Post by: E37 on August 24, 2016, 06:10:32 PM
You got it!
Subroutines don't need to return anything.
They can just hold code. They will always return the result of the last line of code. Nobody said you had to do anything with it.
You nailed memory locations on the head.
Thanks c4ooo, my mind seemed to edit in an if at the beginning.
You don't need the greater than zero c4ooo it is unsigned.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 06:22:29 PM
This block:
If getKey(1) and (W<5600):W+100->W:End
.LeftArrowKey
If getKey(2) and (V>0):V-100->V:End
.RightArrowKey
If getKey(3) and (V<8600):V+100->V:End
.UpArrowKey
If getKey(4) and (W>0):W-100->W:End



Can be:
If W<5600 and getKey(1):W+100->W:End
If V>0 and getKey(2):V-100->V:End
If V<8600 and getKey(3):V+100->V:End
If  W>0 and getKey(4):W-100->W:End

Would this already speed it up, or did you just remove my stupid comments? ^^


which can further be optimized to:
W<5600 and andgetKey(1)-(W>0 and getKey(4))*100+W->W
V<8600 and getKey(3)-(V>0 and getKey(2))*100+V->V

I'm not sure, but if I pressed only the UP arrow key, then this first line should become the following:
0-(1)*100+W->W which would be the same as 65535*100+W->W which would result in ((2^16-1)*100)-99*(2^16) (no Axe) which is 65436 which iiiis 2^16-100 which equals (0-100) in Axe so it' the same as (0-100)+W->W which means this code is awesome ^.^ And I even under stood it *-*


could be even further optimized to:
W<5600?getKey(1)-(W?getkey(4))*100+W->W
V<8600?getKey(3)-(V?getKey(2))*100+V->V

Okey now I definitely need an explanation? ;D



Quote from: E37 on August 24, 2016, 05:43:08 PMAs for learning to program Axe I still find it helpful to program with a paper or electronic copy of the Axe command list nearby. http://axe.eeems.ca/Commands.html
Oh... by the way, your code isn't bad at all! It is heaps better than my first code! It took me weeks to grasp the concepts of how lists are structured.
I only learned this List stuff so fast because Sorunome took the time to explain it to me... twice ;D
I also asked others in the IRC, too, but didnt get it 100% back then (Thanks to all of them!) ^^

Also I got my Axe command list right next to me ;) But it's a pain to search stuff since it's such a long list xD


Sory for not replying to the last three posts yet, you're too fast for me xD
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 06:38:47 PM
Quote from: Hayleia on August 24, 2016, 06:08:02 PM
They are exactly the same. A new line or a ":" is the same thing.
You can even write something after the return if you want (and it can be useful in some cases). Like

...
...
Lbl Stuffs
r1*r2->r5
r3*r4->r6
Return r5+r6
...
...

Well yeah, not so useful here, but you see what I mean.
Quote from: E37 on August 24, 2016, 06:10:32 PM
You got it!
Subroutines don't need to return anything.
They can just hold code. They will always return the result of the last line of code. Nobody said you had to do anything with it.
You nailed memory locations on the head.
Thanks c4ooo, my mind seemed to edit in an if at the beginning.
You don't need the greater than zero c4ooo it is unsigned.


So this should return 5 and save it as X:
...
...
DoStuff( )->X
...
...
Return

Lbl DoStuff
6->C
5->A->B:Return




And this should return 5, too, but ignore it:
...
...
DoStuff( )
...
...
Return

Lbl DoStuff
6->C
5->A->B
Return




And this one will return 6 instead of 5 and ignore it, too:
...
...
DoStuff( )
...
...
Return

Lbl DoStuff
6->C
5->A->B
Return C




And it's impossible to get an error from the DoStuff()->X except in this example, in which it wouldn't try to save "Stupid" as X since it's waiting for a returned value from DoStuff() ;D
...
...
"Stupid"->Str01
DoStuff( )->X
...
...
Return

Lbl DoStuff
Return



You guys really are awesome teachers!! ;D  :thumbsup:


Sorry for the douplepost... It's just that I was too slow ^^
Title: Re: Some super crappy Axe code...
Post by: E37 on August 24, 2016, 06:41:22 PM
You can replace and with * and or with +
It never waist for a value, it just uses whatever is in hl when it returns. Hl is Axes answer.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 25, 2016, 09:24:12 AM
Quote from: E37 on August 24, 2016, 06:41:22 PM
You can replace and with * and or with +
It never waist for a value, it just uses whatever is in hl when it returns. Hl is Axes answer.
What do you men by HL? ^^ I never heard of it... ^^
Abd does replacing AND with * and replacing OR with + speed up the code? Or is it just to shorten it? :)

By the way... could anyone tell me if I understood it corectly now (my last 2 posts) :)
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 25, 2016, 10:26:03 AM
Quote from: p2 on August 25, 2016, 09:24:12 AM
What do you men by HL? ^^ I never heard of it... ^^
Abd does replacing AND with * and replacing OR with + speed up the code? Or is it just to shorten it? :)
HL is the z80's main 16-bit register. That's why Axe uses it for "everything".
When you write "3", it loads 3 in HL. When you write "+5", it adds 5 to HL. When you write "->A", it stores HL in the location that corresponds to A.
So "3+5->A" does what you expect, and

3
+5
->A

does the same thing but wastes two lines.

And about * and +, this doesn't make the code faster nor smaller. And it doesn't give the same result either actually :P
* and + work on 16 bits, "and" and "or" work on 8 only for example.

Quote from: p2 on August 24, 2016, 06:38:47 PM
So this should return 5 and save it as X:
And this should return 5, too, but ignore it:
And this one will return 6 instead of 5 and ignore it, too:
Yes for all of these ones. Except that "5->A->B:Return" is ugly, I only wrote that in my posts because I didn't want to open a code tag and write two lines :P
And

6->C
5->A->B
Return C

is unoptimized (well I know it's just an example but still, if that helps you do basic optimizations, that's good to know). You can just write that instead

5->A->B
6->C
Return

You saved 3 bytes just by inverting two lines. That's not really one of these unreadable optimizations :P

Quote from: p2 on August 24, 2016, 06:38:47 PM
And it's impossible to get an error from the DoStuff()->X except in this example, in which it wouldn't try to save "Stupid" as X since it's waiting for a returned value from DoStuff() ;D
Depends what you call an "error". Axe won't give you an error, it will always "return" the last value it "returned" in HL. Then maybe your program will do stupid stuff since it will receive a value it didn't expect, but technically you don't do "DoStuff()->X" if you don't know exactly what DoStuff returns and want it in X :P
Title: Re: Some super crappy Axe code...
Post by: p2 on August 25, 2016, 11:19:23 AM
Quote from: Hayleia on August 25, 2016, 10:26:03 AM
Quote from: p2 on August 25, 2016, 09:24:12 AM
What do you men by HL? ^^ I never heard of it... ^^
Abd does replacing AND with * and replacing OR with + speed up the code? Or is it just to shorten it? :)
HL is the z80's main 16-bit register. That's why Axe uses it for "everything".
When you write "3", it loads 3 in HL. When you write "+5", it adds 5 to HL. When you write "->A", it stores HL in the location that corresponds to A.
So "3+5->A" does what you expect, and

3
+5
->A

does the same thing but wastes two lines.
So HL is like what you call the Register in ASM? ^^ okey thx ^^ So This should do 5->A : A->B : B+1->C : C->D right? :)
:Whatever()->D
:Return
:Lbl Whatever
:5->A->B:+1->C:Return



Quote from: Hayleia on August 25, 2016, 10:26:03 AM
Quote from: p2 on August 24, 2016, 06:38:47 PM
And it's impossible to get an error from the DoStuff()->X except in this example, in which it wouldn't try to save "Stupid" as X since it's waiting for a returned value from DoStuff() ;D
Depends what you call an "error". Axe won't give you an error, it will always "return" the last value it "returned" in HL. Then maybe your program will do stupid stuff since it will receive a value it didn't expect, but technically you don't do "DoStuff()->X" if you don't know exactly what DoStuff returns and want it in X :P
Okeyy But then what would it do in my example code:
Quote from: p2 on August 24, 2016, 06:38:47 PM
...
...
"Stupid"->Str01
DoStuff( )->X
...
...
Return

Lbl DoStuff
Return
would it actually try to save "Stupid" as X since nothing else was saved as HL ???


And by the way... would it even be slower to write it like this...? Or would it result in the same but look stupid? ^^
Quote from: Hayleia on August 25, 2016, 10:26:03 AM
3
+5
->A

does the same thing but wastes two lines.
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 25, 2016, 03:30:34 PM
Quote from: p2 on August 25, 2016, 11:19:23 AM
So HL is like what you call the Register in ASM? ^^ okey thx ^^ So This should do 5->A : A->B : B+1->C : C->D right? :)
:Whatever()->D
:Return
:Lbl Whatever
:5->A->B:+1->C:Return

Yes, it's the same. With a useless call and without useless loads but the result from the point of view of your variables is the same.
But avoid putting the Return at the end of the line like this, it doesn't make more sense and is less readable since you can't visually align the Lbl with the Return.

Quote from: p2 on August 25, 2016, 11:19:23 AM
Okeyy But then what would it do in my example code:
Quote from: p2 on August 24, 2016, 06:38:47 PM

<snip>
would it actually try to save "Stupid" as X since nothing else was saved as HL ???
I don't remember if "Stupid"->Str01only declares the string and registers the pointer name or if it loads the pointer in HL too. So let's replace the Str01 in your code with A for example, to be sure it's loaded in HL (and in A).
In that case yes, it will also be loaded in X since that's still what's in HL after calling DoStuff (which didn't do stuff).

Quote from: p2 on August 25, 2016, 11:19:23 AM
And by the way... would it even be slower to write it like this...? Or would it result in the same but look stupid? ^^
Quote from: Hayleia on August 25, 2016, 10:26:03 AM
3
+5
->A

does the same thing but wastes two lines.
No, not slower or anything. Maybe slower to compile due to skipping more newlines, but you won't make the difference, and no one cares about compilation time anyway if execution is fast and readability saves more time.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 25, 2016, 08:51:30 PM
I modified the entire code as far as I understand it by now :)
I'm sure it's still far from being perfect, so please tell me if you notice anything that still can be modified :) Thank you!  :thumbsup:
.TRY07AXE
ClrDraw
[3C7EFFFFFFFF7E3C]->Pic01
[FF818181818181FF]->Pic02
L1->°BposX
L1+2->°BposY
1280->BposX->BposY
L1+4->°BmovX
L1+6->°BmovY
128->BmovY:*2->BmovX
L1+8->°BdirX
L1+10->°BdirY
1->BdirX->BdirY

.Pos Player *128 = V,W
6400->V
1280->W
.Gravitation=G
.N=NotCollide to prevent double collision
.C=Counter
0->G->N->C
while 1
C++
Pt-On(BposX/128,BposY/128,Pic01)
Pt-On(V/128,W/128,Pic02)
DispGraph:ClrDraw
BmovX*BdirX+BposX->BposX
BmovY*BdirY+BposY->BposY
Movement()
Collision()
Gravity()
EndIf getKey(15)
Return

Lbl Movement
.moveX
V<11008 and getKey(3)-(V>0 and getKey(2))*128+V->V
.moveY
W<7168 and getKey(1)-(W>0 and getKey(4))*128+W->W
Return


Lbl Collision
N>0?N--->N
.COLLIDE
.Top Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
BmovX+102->BmovX:BmovY+102->BmovY:(0-1)->BdirX->BdirY:5->N:0->G:End
.Top Right
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
BmovX+102->BmovX:BmovY+102->BmovY:1->BdirX:(0-1)->BdirY:5->N:0->G:End
.Bottom Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
BmovX+128->BmovX:BmovY+128->BmovY:(0-1)->BdirX:1->BdirY:5->N:End
.Bottom Right
If (N=0) and ((BposX/128)>=((V/128)+6)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
BmovX+128->BmovX:BmovY+128->BmovY:1->BdirX->BdirY:5->N:End
.Top
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((V/128)-8)) and ((BposY/128)<=((V/128)-6))
BmovY+128->BmovY:(0-1)->BdirY:5->N:0->G:End
.Left
If (N=0) and ((BposX/128)>=((V/128)-8)) and ((BposX/128)<=((V/128)-7)) and ((BposY/128)>=((V/128)-5)) and ((BposY/128)<=((V/128)+5))
BmovX+102->BmovX:5->N:If (BposY>5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
.Right
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+8)) and ((BposY/128)>=((V/128)-5)) and ((BposY/128)<=((V/128)+5))
BmovX+102->BmovX:5->N:If (BposY>5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
.Bottom
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((V/128)+7)) and ((BposY/128)<=((V/128)+8))
1->BdirY:G/5+BmovY/2+64->BmovY:0->G:End

.BORDERS
.Left
If (BposX<128) or (BposX>(0-1280)):128->BposX:1->BdirX:End
.Right
If (BposX>11008):11008->BposX:(0-1)->BdirX:End
.Top
If (BposY)<128):128->BposY:1->BdirY:(BmovY/2)->BmovY:End
.Bottom
If (BposY)>7168):7168->BposY:(G/10+BmovY)->BmovY:0->G:-1->BDirY:End
Return

Lbl Gravity
.Friction
If BmovX>50:BmovX*127/128->BmovX:Else:If BmovX<20:If (C/4+4)=C:BmovX*127/128->BmovX:End:Else:If (C/2+2)=C:BmovX*127/128->BmovX:End:End:End
.Slow down and speed up
If BdirY=1:102:Else:97:End:*BmovY/128->BmovY
.Add Gravity
G+3->G:/10+BposY->BposY
Return
Title: Re: Some super crappy Axe code...
Post by: c4ooo on August 25, 2016, 10:12:02 PM
Dont want to optimize the whole thing for you, but heres another tip:
(BposX<128) or (BposX>(0-1280)) can be optimized by simply switching some stuff around and removing unnecessary brackets.
BposX>-1280 or (BposX<128)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 25, 2016, 11:54:24 PM
Thx ^^ Gonna change that, too ;D

Finally got a GIF of my code. This is the unmodified old code:
Still buggy, I know... ^^
*pls remember its not ment to be perfect physics but perfect for a 1:1 soccer game I wanted to create for myself just for learning purposes ^^
(http://img.omnimaga.org/demo3.gif)
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 26, 2016, 07:13:45 AM
Quote from: p2 on August 25, 2016, 08:51:30 PM
I modified the entire code as far as I understand it by now :)
I'm sure it's still far from being perfect, so please tell me if you notice anything that still can be modified :) Thank you!  :thumbsup:
.TRY07AXE
ClrDraw
[3C7EFFFFFFFF7E3C]->Pic01
[FF818181818181FF]->Pic02
L1->°BposX
L1+2->°BposY
1280->BposX->BposY
L1+4->°BmovX
L1+6->°BmovY
128->BmovY:*2->BmovX
L1+8->°BdirX
L1+10->°BdirY
1->BdirX->BdirY

.Pos Player *128 = V,W
6400->V
1280->W
.Gravitation=G
.N=NotCollide to prevent double collision
.C=Counter
0->G->N->C
while 1
C++
Pt-On(BposX/128,BposY/128,Pic01)
Pt-On(V/128,W/128,Pic02)
DispGraph:ClrDraw
BmovX*BdirX+BposX->BposX
BmovY*BdirY+BposY->BposY
Movement()
Collision()
Gravity()
EndIf getKey(15)
Return

Lbl Movement
.moveX
V<11008 and getKey(3)-(V>0 and getKey(2))*128+V->V
.moveY
W<7168 and getKey(1)-(W>0 and getKey(4))*128+W->W
Return


Lbl Collision
N>0?N--->N
.COLLIDE
.Top Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
BmovX+102->BmovX:BmovY+102->BmovY:(0-1)->BdirX->BdirY:5->N:0->G:End
.Top Right
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
BmovX+102->BmovX:BmovY+102->BmovY:1->BdirX:(0-1)->BdirY:5->N:0->G:End
.Bottom Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
BmovX+128->BmovX:BmovY+128->BmovY:(0-1)->BdirX:1->BdirY:5->N:End
.Bottom Right
If (N=0) and ((BposX/128)>=((V/128)+6)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
BmovX+128->BmovX:BmovY+128->BmovY:1->BdirX->BdirY:5->N:End
.Top
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((V/128)-8)) and ((BposY/128)<=((V/128)-6))
BmovY+128->BmovY:(0-1)->BdirY:5->N:0->G:End
.Left
If (N=0) and ((BposX/128)>=((V/128)-8)) and ((BposX/128)<=((V/128)-7)) and ((BposY/128)>=((V/128)-5)) and ((BposY/128)<=((V/128)+5))
BmovX+102->BmovX:5->N:If (BposY>5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
.Right
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+8)) and ((BposY/128)>=((V/128)-5)) and ((BposY/128)<=((V/128)+5))
BmovX+102->BmovX:5->N:If (BposY>5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
.Bottom
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((V/128)+7)) and ((BposY/128)<=((V/128)+8))
1->BdirY:G/5+BmovY/2+64->BmovY:0->G:End

.BORDERS
.Left
If (BposX<128) or (BposX>(0-1280)):128->BposX:1->BdirX:End
.Right
If (BposX>11008):11008->BposX:(0-1)->BdirX:End
.Top
If (BposY)<128):128->BposY:1->BdirY:(BmovY/2)->BmovY:End
.Bottom
If (BposY)>7168):7168->BposY:(G/10+BmovY)->BmovY:0->G:-1->BDirY:End
Return

Lbl Gravity
.Friction
If BmovX>50:BmovX*127/128->BmovX:Else:If BmovX<20:If (C/4+4)=C:BmovX*127/128->BmovX:End:Else:If (C/2+2)=C:BmovX*127/128->BmovX:End:End:End
.Slow down and speed up
If BdirY=1:102:Else:97:End:*BmovY/128->BmovY
.Add Gravity
G+3->G:/10+BposY->BposY
Return

Well you still didn't replace Pic01 and Pic02 with custom names like °BallSprite for readability :P
And to answer your question on IRC, no, you can't do L1->°Wat:+2->°Lol, because they are preprocessor directives (which isn't an excuse actually, but it explains why A->B:+2->C works and not L1->°Wat:+2->°Lol).

Also, really, avoid putting End or Return at the end of a line. I mean, if you put everything on the line, it may be ok, like this
If A>B:A->C:Else:B->C:End
(even though one-liners are usually reserved to ternary operators, and even though that one line here could just be max(A,B)->C).
And putting it on several lines is ok too, which is why everyone does it, like this
If A>B
A->C
Else
B->C
End

because it allows indentation like that
If A>B
    A->C
Else
    B->C
End

But almost no one will agree with the following. Only people programming in Pico and Lisp. (https://en.wikipedia.org/wiki/Indent_style)
If A>B
A->C
Else
B->C:End

So in short version, always either put the whole If and it's Else/ElseIf and End on the same line, or put every Else/ElseIf and End on a new line (but the code between the Else/ElseIf/End can be on one line, no one cares as long as it doesn't kill indentation).

And obviously, this doesn't change anything from the compiler's point of view, but if you ask for help in a C forum and write code like this

    while(
1)
{
sleep(4);}

no one will read and no one will help. And you'll have problems reading too I'm sure. So really, keep the code a minimum readable (even if all lines in an Axe code are unreadable, the code as a whole can be "readable").
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on August 26, 2016, 03:58:24 PM
Wait, Axe now supports custom pointer names instead of just Pic1 and so on? O.O
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 26, 2016, 04:28:23 PM
Quote from: DJ Omnimaga on August 26, 2016, 03:58:24 PM
Wait, Axe now supports custom pointer names instead of just Pic1 and so on? O.O
Yes, custom pointers and variables.
Pointers start with a °, variables don't.
And it follows the rule that says that °<whatever> is the pointer to <whatever>. Like °A being the pointer to A (so {°A)^r is the same as A, but longer), or L1->°Toaster meaning that Toaster is a variable which value is stored in L1, etc.
If you're compiling as a program, you could even write [0000]->°Var and have a custom variable here. It will trigger writeback in shells that support it, but maybe you don't care or that's exactly what you want ;)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 26, 2016, 05:50:59 PM
Didnt know you could use the ° everywhere, thought it was just ment for var declaration but this as awesome :D
so It's like this? :)
{X} returns the value of memory position X (1 Byte)
{X}^r returns the value of the memory positions X and X+1 (2 Bytes)
°X returns the memory position of the pointer called X
And when using this stuff:
L1+123->°Var sets a new pointer named "Var" pointing at the memory position L1+123
Var->A gets the value of the memory position the pointer is pointing at and stores it as A
{{L1+123}}^r+Var->Var This would actually just double the value and store it again as {{L1+123}} is the memory position that "Var" is pointing at


Back to my crappy program:
I'm now using this source (I found a couple of mistakes when I copied the code by hand the first time):
*Also added the Source program and the compiled Axe Asm as files below*
.TRY08AXE
ClrDraw
[3C7EFFFFFFFF7E3C]->Pic01
[FF818181818181FF]->Pic02
L1->°BposX
L1+2->°BposY
1280->BposX->BposY
L1+4->°BmovX
L1+6->°BmovY
128->BmovY:*2->BmovX
L1+8->°BdirX
L1+10->°BdirY
1->BdirX->BdirY

.Pos Player *128 = V,W
6400->V
1280->W
.Gravitation=G
.N=NotCollide to prevent double collision
.C=Counter
0->G->N->C
while 1
C++
Pt-On(BposX/128,BposY/128,Pic01)
Pt-On(V/128,W/128,Pic02)
DispGraph:ClrDraw
BmovX*BdirX+BposX->BposX
BmovY*BdirY+BposY->BposY
Movement()
Collision()
Gravity()
EndIf getKey(15)
Return

Lbl Movement
.moveX
V<11008 and getKey(3)-(V>0 and getKey(2))*128+V->V
.moveY
W<7168 and getKey(1)-(W>0 and getKey(4))*128+W->W
Return


Lbl Collision
N>0?N--->N
.COLLIDE
.Top Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
BmovX+102->BmovX:BmovY+102->BmovY:(0-1)->BdirX->BdirY:5->N:0->G:End
.Top Right
If (N=0) and ((BposX/128)>=((V/128)+6)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
BmovX+102->BmovX:BmovY+102->BmovY:1->BdirX:(0-1)->BdirY:5->N:0->G:End
.Bottom Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
BmovX+128->BmovX:BmovY+128->BmovY:(0-1)->BdirX:1->BdirY:5->N:End
.Bottom Right
If (N=0) and ((BposX/128)>=((V/128)+6)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
BmovX+128->BmovX:BmovY+128->BmovY:1->BdirX->BdirY:5->N:End
.Top
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((W/128)-8)) and ((BposY/128)<=((W/128)-6))
BmovY+128->BmovY:(0-1)->BdirY:5->N:0->G:End
.Left
If (N=0) and ((BposX/128)>=((V/128)-8)) and ((BposX/128)<=((V/128)-7)) and ((BposY/128)>=((W/128)-5)) and ((BposY/128)<=((W/128)+5))
BmovX+102->BmovX:5->N:(0-1)->BdirX:If (BposY>=5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
.Right
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+8)) and ((BposY/128)>=((W/128)-5)) and ((BposY/128)<=((W/128)+5))
BmovX+102->BmovX:5->N:^->BdirX:If (BposY>=5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
.Bottom
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((W/128)+7)) and ((BposY/128)<=((W/128)+8))
1->BdirY:G/5+BmovY/2+64->BmovY:0->G:End

.BORDERS
.Left
If (BposX<128) or (BposX>(0-1280)):128->BposX:1->BdirX:End
.Right
If (BposX>11008):11008->BposX:(0-1)->BdirX:End
.Top
If (BposY)<128):128->BposY:1->BdirY:(BmovY/2)->BmovY:End
.Bottom
If (BposY)>7168):7168->BposY:(G/10+BmovY)->BmovY:0->G:-1->BDirY:End
Return

Lbl Gravity
.Friction
If BmovX>64:BmovX*127/128->BmovX:Else:If BmovX<26:If (C/4*4)=C:BmovX*127/128->BmovX:End:Else:If (C/2*2)=C:BmovX*127/128->BmovX:End:End:End
.Slow down and speed up
If BdirY=1:102:Else:97:End:*BmovY/128->BmovY
.Add Gravity
G+3->G:/10+BposY->BposY
Return

It seems to work fine for the X-axis but for some reason everything on the Y-axis is totally messed up... Can you maybe find the bug...? :(
Back in the old unmodified source there was no problem so it got to be because of some of the modifications...
See a picture of it:
(http://img.ourl.ca/try08.gif)



Edit: I got to admit I forgot to add the collision-below... but all edges as well as left, right and top are there :)

Edit 2: Having added teh colision for ball below player, too, it didnt change anything... Still cant find the bug :( Any of you guys found something?
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 28, 2016, 05:13:13 PM
Quote from: p2 on August 26, 2016, 05:50:59 PM
Didnt know you could use the ° everywhere, thought it was just ment for var declaration but this as awesome :D
so It's like this? :)
{X} returns the value of memory position X (1 Byte)
{X}^r returns the value of the memory positions X and X+1 (2 Bytes)
°X returns the memory position of the pointer called X
And when using this stuff:
L1+123->°Var sets a new pointer named "Var" pointing at the memory position L1+123
Var->A gets the value of the memory position the pointer is pointing at and stores it as A
Yes for all of that.
Quote from: p2 on August 26, 2016, 05:50:59 PM
{{L1+123}}^r+Var->Var This would actually just double the value and store it again as {{L1+123}} is the memory position that "Var" is pointing at
Well, no, why do you double the "{}"? Var is the same as {°Var}^r which is {L1+123}^r, not {{L1+123}}^r.

And for your problem, go back to the unmodified code (that you said worked) then do the modifications one by one until it stops working. You'll know what caused the problem ;)
Yes, that's annoying, that's debugging :P
But that's also why I didn't advise any optimization. Yes, an optimized code is better than a non-optimized code for the same result... but for the same result :P
Title: Re: Some super crappy Axe code...
Post by: p2 on August 28, 2016, 06:27:48 PM
Quote from: Hayleia on August 28, 2016, 05:13:13 PM
Quote from: p2 on August 26, 2016, 05:50:59 PM
{{L1+123}}^r+Var->Var This would actually just double the value and store it again as {{L1+123}} is the memory position that "Var" is pointing at
Well, no, why do you double the "{}"? Var is the same as {°Var}^r which is {L1+123}^r, not {{L1+123}}^r.
I'm sorry I thought for a moment it was {{ }} not { }...  9_9 But if it all would have been correct otherwise, I just understood another part about Axe  :love:

And about modifying code: You say you should either write super modified code from the beginning or stay with your crappy code? No modifications afterwards? ^^
Guess for you it's rater the 1st not the 2nd xD

As for the bug I'm guessing it's not in the .borders nor in the main loop.... since it was still functional after I modified these sections... which leaves the main collision codes for interactions with the player... At least all those concerning the Y-axis ^^ still gonna be enough work :P
Title: Re: Some super crappy Axe code...
Post by: E37 on August 28, 2016, 09:51:44 PM
Instead of doing:

L1->°BposX
L1+2->°BposY
L1+4->°BmovX
L1+6->°BmovY
L1+8->°BdirX
L1+10->°BdirY

You could do:

L1->°BposX+2->°BposY+2->°BmovX+2->°BmovY+2->°BdirX+2->°BdirY

Which in my opinion is more readable and prevents errors like defining two variables to the same spot.
It wouldn't  change the size or speed of the compiled program though.
Don't worry too much about how readable your code is if no one else is going to read though. (as long as you can!)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 28, 2016, 09:58:16 PM
It stopped being readable even to me a long time ago lol
I already started to only code when having my laptop by and then typing the exact same stuff I do on the calc on my laptop, too, so I end up with a text file of my code xD So I don't have to read the stuff on my calc anymore but instead read the source on my laptop screen ^^ Works great this way  :thumbsup:
Gonna add that, too (thx E37!), and do the debugging tomorrow I guess :)
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 29, 2016, 07:26:22 AM
Quote from: E37 on August 28, 2016, 09:51:44 PM
Instead of doing:

L1->°BposX
L1+2->°BposY
L1+4->°BmovX
L1+6->°BmovY
L1+8->°BdirX
L1+10->°BdirY

You could do:

L1->°BposX+2->°BposY+2->°BmovX+2->°BmovY+2->°BdirX+2->°BdirY

Which in my opinion is more readable and prevents errors like defining two variables to the same spot.
It wouldn't  change the size or speed of the compiled program though.
Don't worry too much about how readable your code is if no one else is going to read though. (as long as you can!)
I don't find it more readable (to each their own :P) but I agree that's a great way to avoid defining two variables to the same spot. I asked Runer if it would be possible to do this on several lines like L1-2:+2->°Meh:+2->°Toast etc, which seems impossible just like this (due to being preprocessor directives) but with a character that would say "ignore the following character", it could work, like L1-2':+2->°Meh':+2->°Toast etc, where the ' tells the parser to ignore the newline.
I don't remember his answer but at worst, that's just for a bit more readability so it doesn't matter that much.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 29, 2016, 08:16:41 AM
Quote from: Hayleia on August 29, 2016, 07:26:22 AM
Quote from: E37 on August 28, 2016, 09:51:44 PM
Instead of doing:

L1->°BposX
L1+2->°BposY
L1+4->°BmovX
L1+6->°BmovY
L1+8->°BdirX
L1+10->°BdirY

You could do:

L1->°BposX+2->°BposY+2->°BmovX+2->°BmovY+2->°BdirX+2->°BdirY

Which in my opinion is more readable and prevents errors like defining two variables to the same spot.
It wouldn't  change the size or speed of the compiled program though.
Don't worry too much about how readable your code is if no one else is going to read though. (as long as you can!)
I don't find it more readable (to each their own :P) but I agree that's a great way to avoid defining two variables to the same spot. I asked Runer if it would be possible to do this on several lines like L1-2:+2->°Meh:+2->°Toast etc, which seems impossible just like this (due to being preprocessor directives) but with a character that would say "ignore the following character", it could work, like L1-2':+2->°Meh':+2->°Toast etc, where the ' tells the parser to ignore the newline.
I don't remember his answer but at worst, that's just for a bit more readability so it doesn't matter that much.


Okey now I'm really confised because I remember someone having told me that this would NOT work:
L1->°BposX:+2->°BposY
since it'd have nothing to do with the HL register... ???
Then why would whis be so different?
it's just the "new line" symbol missing... O.o
L1->°BposX:+2->°BposY    //won't work
L1->°BposX+2->°BposY     //will work
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 29, 2016, 10:17:50 AM
Quote from: p2 on August 29, 2016, 08:16:41 AM
Quote from: Hayleia on August 29, 2016, 07:26:22 AM
I don't find it more readable (to each their own :P) but I agree that's a great way to avoid defining two variables to the same spot. I asked Runer if it would be possible to do this on several lines like L1-2:+2->°Meh:+2->°Toast etc, which seems impossible just like this (due to being preprocessor directives) but with a character that would say "ignore the following character", it could work, like L1-2':+2->°Meh':+2->°Toast etc, where the ' tells the parser to ignore the newline.
I don't remember his answer but at worst, that's just for a bit more readability so it doesn't matter that much.
Okey now I'm really confised because I remember someone having told me that this would NOT work:
L1->°BposX:+2->°BposY
since it'd have nothing to do with the HL register... ???
Then why would whis be so different?
it's just the "new line" symbol missing... O.o
L1->°BposX:+2->°BposY    //won't work
L1->°BposX+2->°BposY     //will work

Well yes, it won't work, I didn't say the contrary in my post (or at least if I did, I didn't mean it at all).
That's why I asked Runer for a workaround, to be able to insert newlines and tell the parser to ignore them.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 29, 2016, 10:24:04 AM
But isn't teh user forced to do L1+0->°BposX:°BposX+2->°BposY because °BposX is never moved to HL in the first place since it's something the compiler replaces with some other tuff without even touching HL...? Or did I misunderstand that...? :/
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 29, 2016, 11:30:36 AM
Quote from: p2 on August 29, 2016, 10:24:04 AM
But isn't teh user forced to do L1+0->°BposX:°BposX+2->°BposY because °BposX is never moved to HL in the first place since it's something the compiler replaces with some other tuff without even touching HL...? Or did I misunderstand that...? :/
Yes, he is forced to do that. And I still never said the contrary (or never meant to).
Title: Re: Some super crappy Axe code...
Post by: p2 on August 29, 2016, 11:35:28 AM
ooooh
so that means that 0->A+2->B is NOT the exact same as 0-A:+2->B  O.O
so if I undestood it corrctly it means that THIS one is gonna use the HL register:
0->A:+0->B:+2->C
while this one does NOT use it:
0->A->B+2->C

(I know that code makes no sence but I just wasnt sure if 0->A:->B woud be correct) xD
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 29, 2016, 11:49:54 AM
Quote from: p2 on August 29, 2016, 11:35:28 AM
ooooh
so that means that 0->A+2->B is NOT the exact same as 0-A:+2->B  O.O
so if I undestood it corrctly it means that THIS one is gonna use the HL register:
0->A:+0->B:+2->C
while this one does NOT use it:
0->A->B+2->C

(I know that code makes no sence but I just wasnt sure if 0->A:->B woud be correct) xD
No, I don't know what you think you understood today but really no, it was better yesterday :P
0->A+2->B is the exact same as 0->A:+2->B.
0->A:+0->B:+2->C uses the HL register and 0->A->B+2->C too, everything does anyway.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 29, 2016, 12:02:38 PM
okeeeey then I think I know now what it was that I misunderstood:

Quote from: Hayleia on August 26, 2016, 07:13:45 AM
And to answer your question on IRC, no, you can't do L1->°Wat:+2->°Lol, because they are preprocessor directives (which isn't an excuse actually, but it explains why A->B:+2->C works and not L1->°Wat:+2->°Lol).

After that I thought every time you decleared a new var with the ° you didnt use HL for some reason which appears to be wrong...

Or am I wrong again  ???

I am confused...  :P
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 29, 2016, 12:21:08 PM
Quote from: p2 on August 29, 2016, 12:02:38 PM
okeeeey then I think I know now what it was that I misunderstood:

Quote from: Hayleia on August 26, 2016, 07:13:45 AM
And to answer your question on IRC, no, you can't do L1->°Wat:+2->°Lol, because they are preprocessor directives (which isn't an excuse actually, but it explains why A->B:+2->C works and not L1->°Wat:+2->°Lol).

After that I thought every time you decleared a new var with the ° you didnt use HL for some reason which appears to be wrong...

Or am I wrong again  ???

I am confused...  :P
Well I really don't know what's happening, because it's true that there is no HL involved in a variable declaration with ° :P
Because this isn't even code actually, you're only telling the compiler "well, I'm too lazy to write L1+123 every time and wonder what it is so I'm going to write °Lolwat instead", but you never wrote any code. To convince you of this, just make a stupid program with only variable declarations in it, then make another stupid program with absolutely nothing. Notice that they're the same size once compiled (if their names are the same length).
Title: Re: Some super crappy Axe code...
Post by: E37 on August 29, 2016, 06:21:46 PM
Think of it this way:
When you declare a variable, that code is never included in the compiled code. That is just to tell the compiler to replace VarName with what ever it stands for.
When you store values into variables, like 5->A, that is in the compiled code and does affect HL. Since VarName is never run in the compiled code, it won't affect HL.
To prove that variable declarations don't affect HL try this:
:5
:->A
:Disp A>Dec
and it will display 5. Then try this:
:5
:L1_>°AAA
:->A
:Disp A>Dec
Will display 5.
There is a interesting way to get that value though:
:L1+234->°QQQ+27->°ASDF->X
X will then hold the same value as °ASDF
This can be useful if you chained the names like I mentioned above, as you then can :Fill(L1,X-L1,0) to zero all the variables
(which also points out one of the disadvantages of chaining variable declarations: you don't know where they end)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 29, 2016, 06:47:45 PM
allright then, stupid phase is over again I guess ^.^

As long as I only use integers, it should be 2 bytes by default,
8.8 is two bytes, too
X hex long tiles will be X bytes (16, 64, ...)
Aaaand strings are strange but they always were ^^

Actually I think it's super cool to use this method since you can easily access all your vars using some kind of counter now (the adress) which means if I do it correctly I can even work with it as if it was tables ^.^
(like {10*X+Y*2+L1} will be the 2-byte integer at pos X,Y inside this "Table")   :thumbsup:

But I guess I should stick to using thses declarations at the beginning of the program ^^
Quote from: E37 on August 29, 2016, 06:21:46 PM:L1+234->°QQQ+27->°ASDF->X
X will then hold the same value as °ASDF
cause this is just weird xD (It makes sense now but I'd never write it like that ^^)
Title: Re: Some super crappy Axe code...
Post by: E37 on August 29, 2016, 09:03:15 PM
8.8 variables? I don't think I have ever used them outside of experimentation...
yes, there is 8 bytes between each (8x8) sprite. That doesn't mean that you MUST access them in multiples of 8 though... try and find out!
(Or don't and wonder forever...)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 29, 2016, 09:06:12 PM
whatfor should I even want to have a 7byte hex var? xD
gonna try it but dont see wheee to use it ^^
Title: Re: Some super crappy Axe code...
Post by: E37 on August 29, 2016, 09:15:26 PM
Oh... and another thing... Endiness... I you have no clue what that is then consider yourself lucky...
Suffice it to say that {L1}r+256 is the same thing as {L1+1}+1
and {L1}+512 is the same as {L1+1}+2 and so on...
Don't ever use this trick if you want you code to be readable (and I am pretty sure Axe does it for you during compile anyway)

I meant above that you could:
:[0000000000000000]->pic1
:[FFFFFFFFFFFFFF]
:pt-on(0,,Pic1+5)
The only time you are going to have variables other that 1 or 2 bytes is 9-byte floating point (that is what the OS uses)
you can use float{var} to use it. (again, I've never used it for anything useful)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 30, 2016, 07:40:43 AM
Quote from: E37 on August 29, 2016, 09:15:26 PMOh... and another thing... Endiness... I you have no clue what that is then consider yourself lucky...
@E37: I must be super lucky as this makes almost no sense to me...  :thumbsup:

Quote from: E37 on August 29, 2016, 09:15:26 PMSuffice it to say that {L1}r+256 is the same thing as {L1+1}+1
and {L1}+512 is the same as {L1+1}+2 and so on...
Don't ever use this trick if you want you code to be readable (and I am pretty sure Axe does it for you during compile anyway)
{L1}r+256 == {L1+1}+1
Okeyy and you're sure you didn't mean this?:
{L1+256}^r == {L1+1}^r
It still wouldn't make that super much sense but at least it would look like valid Axe code to me then... ([axe] L₁: 768 bytes (saveSScreen) <----no 256)
what's the effect of adding a +... after the {...}^r and how comes {L1}r+256 (obviously 2 bytes) coule ever be the same as {L1+1}+1 since this got no ^r to mark it as two bytes ???








{L1}Adress of first byte (number 0) "in" L1 (I know L1 is just a fix position in memory but I'll stick to the "in L1")
{L1+5}Adress of Byte number 5 in L1
{L1}^r Adres of byte number 0 in L1 again but this tyme marked as 2Byte (no difference in storage since I could also rut a 50byte thing there and it'd just overwrite the following bytes but huge one in reading ince it returns 2 bytes not just 1)
{L1}+1Maybe Adress of Byte number 0 but marked as 2 bytes? (same as ^r)
{L1}+5Maybe Adress of Byte number 0 but marked as 6 bytes?
{L1}+256Maybe Adress of Byte number 0 but marked as 2 bytes? (max length for a single thing maybe 256byte so it takes like modulo(256) or something?)
At all the stuff marked in red I'm just guessing now, didn't even know until just now you could write stuff that way ^^
But I guess that's not what it means anyways? ^^



By the way, would this work? (using 8.8 for everything)

BdirY=1*0.05+0.97*BmovY->BmovY

isntead of:
If BdirY=1:1.02:Else:0.97:End:*BmovY->BmovY



And if I use this:
L1->°BposX
15.123->BposX
{L1}^r->A
{L1}->B
{L1+1}->C

then the results should be:
BposX = 15.123
A = 0000 1111 0111 1011 = 3963
B = 0000 1111 = 15
C = 0111 1011 = 123
But is there any way to create a new custom named var with only 1 byte?
i need B very often but always typing {L1} or {L1+4} or whatever is annoying...
Can I somehow modify L1->BPosXEinByte so it really only returns one byte ?
what I want is something like this:
L1->°BposX
???->°BPosXEinByte
15.123->BposX
12->BPosXEinByte
//now BposX should be "12.123"
18.3->BposX
//now BPosXEinByte should be "18"

Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 30, 2016, 11:19:56 AM
Quote from: p2 on August 30, 2016, 07:40:43 AM
{L1}r+256 == {L1+1}+1
Okeyy and you're sure you didn't mean this?:
{L1+256}^r == {L1+1}^r
It still wouldn't make that super much sense but at least it would look like valid Axe code to me then... ([axe] L₁: 768 bytes (saveSScreen) <----no 256)
what's the effect of adding a +... after the {...}^r and how comes {L1}r+256 (obviously 2 bytes) coule ever be the same as {L1+1}+1 since this got no ^r to mark it as two bytes ???
No, he meant that {L1}r+256->{L1}r is the same as {L1+1}+1->{L1+1}. But it doesn't matter, write readable code only for now :P

Quote from: p2 on August 30, 2016, 07:40:43 AM







{L1}Adress of first byte (number 0) "in" L1 (I know L1 is just a fix position in memory but I'll stick to the "in L1")
{L1+5}Adress of Byte number 5 in L1
{L1}^r Adres of byte number 0 in L1 again but this tyme marked as 2Byte (no difference in storage since I could also rut a 50byte thing there and it'd just overwrite the following bytes but huge one in reading ince it returns 2 bytes not just 1)
{L1}+1Maybe Adress of Byte number 0 but marked as 2 bytes? (same as ^r)
{L1}+5Maybe Adress of Byte number 0 but marked as 6 bytes?
{L1}+256Maybe Adress of Byte number 0 but marked as 2 bytes? (max length for a single thing maybe 256byte so it takes like modulo(256) or something?)
At all the stuff marked in red I'm just guessing now, didn't even know until just now you could write stuff that way ^^
But I guess that's not what it means anyways? ^^
Most of the stuff here is false.
{Whatever} is the value that is at the address Whatever. It's a value, not an address.
Well, obviously, it can also be an address for something else, but {L1} is not the address of the first byte in L1, it's the first byte in L1. The address of the first byte in L1 is... L1.
You should be able to correct the rest.

Quote from: p2 on August 30, 2016, 07:40:43 AM
By the way, would this work? (using 8.8 for everything)

BdirY=1*0.05+0.97*BmovY->BmovY

isntead of:
If BdirY=1:1.02:Else:0.97:End:*BmovY->BmovY
Well, I don't see why it wouldn't work, but we're not in Basic, so it's actually not more efficient (most likely takes more space and is slower).
Though I understand that the line with the If is ugly and too long, so you should use "COND?EXP1,EXP2" instead.
In your exact example, it would give
BdirY=1?1.02,0.97
*BmovY->BmovY

or even in one line (BdirY=1?1.02,0.97)*BmovY->BmovY
Title: Re: Some super crappy Axe code...
Post by: p2 on August 30, 2016, 12:08:42 PM
Quote from: Hayleia on August 30, 2016, 11:19:56 AM
Quote from: p2 on August 30, 2016, 07:40:43 AM
{L1}r+256 == {L1+1}+1
Okeyy and you're sure you didn't mean this?:
{L1+256}^r == {L1+1}^r
It still wouldn't make that super much sense but at least it would look like valid Axe code to me then... ([axe] L₁: 768 bytes (saveSScreen) <----no 256)
what's the effect of adding a +... after the {...}^r and how comes {L1}r+256 (obviously 2 bytes) coule ever be the same as {L1+1}+1 since this got no ^r to mark it as two bytes ???
No, he meant that {L1}r+256->{L1}r is the same as {L1+1}+1->{L1+1}. But it doesn't matter, write readable code only for now :P
okey ^^ +256 is too much (1 byte) so it's moved to the next one... just like when doing 0+10 results in a 0, too (but a 1 in the next place)

Command         {L1}    {L1+1}       
0 -> {L1}^r00
1 -> {L1}^r10
20 -> {L1}^r200
255 -> {L1}^r2550
256 -> {L1}^r01
257 -> {L1}^r11
276 -> {L1}^r201
511 -> {L1}^r2551
Command         {L1}    {L1+1}
0 -> {L1}042
1 -> {L1}142
20 -> {L1}2042
255 -> {L1}25542
256 -> {L1}042
257 -> {L1}142
276 -> {L1}2042
511 -> {L1}25542
Left side: using ^rOnly because I did 42->{L1+1} before that. This means the byte is not affected.




Quote from: Hayleia on August 30, 2016, 11:19:56 AM
Quote from: p2 on August 30, 2016, 07:40:43 AM







{L1}Adress of first byte (number 0) "in" L1 (I know L1 is just a fix position in memory but I'll stick to the "in L1")
{L1+5}Adress of Byte number 5 in L1
{L1}^r Adres of byte number 0 in L1 again but this tyme marked as 2Byte (no difference in storage since I could also rut a 50byte thing there and it'd just overwrite the following bytes but huge one in reading ince it returns 2 bytes not just 1)
{L1}+1Maybe Adress of Byte number 0 but marked as 2 bytes? (same as ^r)
{L1}+5Maybe Adress of Byte number 0 but marked as 6 bytes?
{L1}+256Maybe Adress of Byte number 0 but marked as 2 bytes? (max length for a single thing maybe 256byte so it takes like modulo(256) or something?)
At all the stuff marked in red I'm just guessing now, didn't even know until just now you could write stuff that way ^^
But I guess that's not what it means anyways? ^^
Most of the stuff here is false.
{Whatever} is the value that is at the address Whatever. It's a value, not an address.
Well, obviously, it can also be an address for something else, but {L1} is not the address of the first byte in L1, it's the first byte in L1. The address of the first byte in L1 is... L1.
You should be able to correct the rest.
Ok I guess I thought the right stuff but messed up when putting it into words:
L1 is an adress, like a single stupid number. So what L1 adresses is a single byte.
But after that byte comes a field of 768 bytes that are free to use, too.
So we do {L1+1} to adress the others. Doing this, L1+1 is the adress and {L1+1} is the value of that adress.
Aaand {L1} is not the first byte in RAM since $0000 - $8000 (hex adresses) is Flash memory so the RAM begins with $8001 aaaand L1 is somewhere within it xD (dont know the adress by heart sorry).


Quote from: p2 on August 30, 2016, 07:40:43 AM... first byte (number 0) "in" L1 (I know L1 is just a fix position in memory but I'll stick to the "in L1")
And with this I ment that since this field of 768 free-to-use bytes begins with the adress L1, it'd be easier to just speak of "adresses IN L1" (ignoring that L1 is just a single adress)



Quote from: Hayleia on August 30, 2016, 11:19:56 AM
Though I understand that the line with the If is ugly and too long, so you should use "COND?EXP1,EXP2" instead.
In your exact example, it would give
BdirY=1?1.02,0.97
*BmovY->BmovY

or even in one line (BdirY=1?1.02,0.97)*BmovY->BmovY
I never knew this was possible *-* Sooo much gonna use that *-* <3
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 30, 2016, 01:33:13 PM
I won't quote everything, I'll just say that I don't have anything to say, everything is right :D

Quote from: p2 on August 30, 2016, 12:08:42 PM
I never knew this was possible *-* Sooo much gonna use that *-* <3
Yeah, that's awesome. Check out the Commands.html file, you can also use "?" only (without ","), and you also have "??" as a negative option. That's great when you need a quick If or If/Else in a calculation but don't want to waste 3 lines or even 5 for that ;)
Title: Re: Some super crappy Axe code...
Post by: p2 on August 30, 2016, 01:45:27 PM
great :D Then it's time for some guessing again... >.>
Are those codes each the same as the line above? :)
if N= 0:5->X:End
  N??:*5->X

if N!=0:5->X:End
  N?:*5->X

if N=10: ->X:End
  (N=10?)*5->X

if N=2:5->X:Else:10->X:End
  N=2?5,10:->X

if N=2:5*A->X:Else:10*A->X:End
  (N=2?5,10)*A->X
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 30, 2016, 03:07:23 PM
No for the first one. Because "N??" is equivalent to "!If N", not to "If N=0". Because N=0 puts either 1 or 0 in HL (depending on if N=0 or not, obviously), while N puts N obviously.
Second reason, the code with the If only changes the value of X when N is 0, where the second one always does (and it's not even what you expected due to the previous sentence).

Same for the second one.

I think you made a mistake on the third one so I won't answer :P

Yes and no for the fourth one. I mean that yeah, from the user's point of view, yes. But the following are more equivalent:

If N=2:5->X:Else:10->X:End
  N=2?5->X,10->X


If N=2:5:Else:10:End:->X
  N=2?5,10:->X


Same as the fourth one for the last one.

(or at least, from what I can tell, maybe I made mistakes :P)

And as a general rule, putting either "?" or "??" on a line and doing nothing of it does nothing at all (I mean, stuff like "N??:*5->X", that's just "N*5->X").
Title: Re: Some super crappy Axe code...
Post by: E37 on August 30, 2016, 06:35:43 PM
A couple things:
First, you don't need the : in most cases. you can simply do X?*5->X since the ? ends the statement.
I'll try to go over all the ways to do and and or statements. Ill bring in to account the size, speed and problems with the statement.
With all of them I am going to take into account the worst case for them. (slowest and largest)
But first... a little math. Pause 1 takes up 3349 cycles. Pause 1800 is about a second in slow speed mode. 3349*1800=6028200 cycles a second. Just to give you an idea when I talk about speed.


1. " and " and " or "
Speed: 33 cycles - that's pretty quick.
Size: up to 7 bytes - not to bad.
Pitfalls: it only compares the lower byte of each argument. That means if number mod 256 is 0, it will treat it as 0. Only use if you are sure if this won't matter or if neither of the arguments can exceed 255.

2. "*" and "+"
Speed (for "*"): It can get up to 800 cycles - by far the slowest!
Speed (for "+"): It can get up to 32 cycles - not too bad.
Size: up to 5 bytes for "+" and 7 for "*" not bad.
Pitfalls: It has a chance that the math operations can wrap around and =0. It's not very likely though.

3. "?" and "??"
Speed: 18 cycles - that's screaming fast!
Size: always 5 bytes - that's really small!
Pitfalls: None really. Just watch the short circuiting as it can cause a headache if you forget it!
Note: since it is a short circuit operator, it has a chance to increase speed even more - even a large amount!

4. plot style tokens
Speed: 45 cycles - not the fastest.
Size: up to 10 bytes - pretty small!
Pitfalls: They can be hard to differentiate, "That's 'or' right... no, its 'and'!"
Notes: It functions the same way as " or " and " and" but doesn't have the >255 problem.

5. nested 'If" statements
Speed: who cares?
Size: does it matter?
Pitfalls/notes: ... just no. Don't do it. Any coder who tries to read your code where you made a separate 'If' for each and and calls the same routine for each 'or', will HATE you (and you probably won't be able to read it anyway) That kind of code is for assembly! NOT Axe!

That is all of the ways I can think of. Read over all of them and decide which is best for yourself.
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 31, 2016, 06:44:52 AM
Quote from: E37 on August 30, 2016, 06:35:43 PM
5. nested 'If" statements
Speed: who cares?
Size: does it matter?
Pitfalls/notes: ... just no. Don't do it. Any coder who tries to read your code where you made a separate 'If' for each and and calls the same routine for each 'or', will HATE you (and you probably won't be able to read it anyway) That kind of code is for assembly! NOT Axe!
(Note however that he only says this isn't good in the case where you're using them as "operators" for 'and'/'or' operations, but if you're doing "real code", using Ifs and stuff is perfectly ok).

(And lol, I actually used some of these "ugly" Ifs in Smash, and I agree it's stupid but I "had to" since my conditions were too long to be readable on one line only (and they were all "ands") :P).
Title: Re: Some super crappy Axe code...
Post by: p2 on August 31, 2016, 08:19:32 AM
Quote from: E37 on August 30, 2016, 06:35:43 PM
First, you don't need the : in most cases. you can simply do X?*5->X since the ? ends the statement.
Then it's like this:
A=B?5->A,10->A
now using HL for it, too:
A=B?5,10:->A
but how about multiple expressions? Will this be accepted? And fo I have to put an "End" then or is it just not possible uing the "?" stuff?
A=B?5->A:10->B,10->A:5->B
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 31, 2016, 09:11:35 AM
Quote from: p2 on August 31, 2016, 08:19:32 AM
Then it's like this:
A=B?5->A,10->A
now using HL for it, too:
A=B?5,10:->A
Yes, that works. If you want just one optimization here though, you may want to use "-" and "??" rather than "=" and "?", giving this:
A-B??5,10:->A
Notice though that this is only possible here since you don't care about the value of HL after the "?" or "??" (you immediately replace it with 5 or 10), but "A-B??" and "A=B?" don't "return" the same thing at all.

Quote from: p2 on August 31, 2016, 08:19:32 AM
but how about multiple expressions? Will this be accepted? And fo I have to put an "End" then or is it just not possible uing the "?" stuff?
A=B?5->A:10->B,10->A:5->B
No, that's not possible this way. There are stupid ways to make it possible sometimes, like putting a "useless" Select (such as "A=B?Select(5->A,10->B),Select(10->A,5->B)", which quickly becomes ugly as soon as you have more than 2 expressions on one side of the ","), or having luck (I think for example that 5->Br1->A does put 5 in B and r1 in A even without a newline, but that wouldn't work if you replaced r1 with C since it would read "BC" as one variable name), but otherwise this kind of stuff isn't supposed to be possible.
Title: Re: Some super crappy Axe code...
Post by: E37 on August 31, 2016, 02:52:15 PM
You think more than one line of conditionals is bad? For one of my games I wrote an entire subroutine on one line using ?? And ? !
You can chain statements though like:
A-B??1->A:7->B,0->A->B
That is perfectly legal to do.
Title: Re: Some super crappy Axe code...
Post by: Hayleia on August 31, 2016, 03:02:51 PM
The problem isn't that it's bad, it's less readable :P
I have this exactly in Smash:

{r1+°PX}^^r/64->X
{r1+°PY}^^r/64->Y
{r1+°Character}^^r->VCharacter
./collision
{{{r1+°State}^^r+°StateSprite+{r1+°Direction}}^^r+VCharacter->r4}*8->r2/4->r5
{r4+1}->r4
If Y>={r3+r6+2}^^r
If {r1+°OldPY}^^r/64<={r3+r6+2}^^r
If X+r5>={r3+r6+0}^^r
If W+{r3+r6+0}^^r>=(X-r5)
{r3+r6+2}^^r*64Select(,->{r1+°PY}^^r)->{r1+°OldPY}^^r
If r6
{r3+8}^^r*64->{r1+°GroundSpeedX}^^r
{r3+10}^^r*64->{r1+°GroundSpeedY}^^r
End
1->{r1+°OnTheGround}
End
End
End
End
If Y-r4>{r3+r6+2}^^r
If {r1+°OldPY}^^r/64-r4<{r3+r6+2}^^r
If X<={r3+r6+0}^^r
If X+r2>=({r3+r6+0}^^r-8)
If {r3-1} and °LeftLedge!=0
{VCharacter+°LedgeState}^^r+VCharacter
sub(ChangeState)
°DirRight->{r1+°Direction}
{r3+r6+0}^^r-({{{r1+°State}^^r+°StateSprite+{r1+°Direction}}^^r+VCharacter->r4}*8->r2/2)*64->{r1+°PX}^^r
{r3+r6+2}^^r+({r4+1}->r4)*64->{r1+°PY}^^r
1->{r1+°OnTheGround} ./sert à reinitialiser les jumps
End
End
End
End
End
If Y-r4>{r3+r6+2}^^r
If {r1+°OldPY}^^r/64-r4<{r3+r6+2}^^r
If X>=({r3+r6+0}^^r+W)
If X-r2<=({r3+r6+0}^^r+W+8)
If {r3-1} and °RightLedge!=0
{VCharacter+°LedgeState}^^r+VCharacter
sub(ChangeState)
°DirLeft->{r1+°Direction}
{r3+r6+0}^^r+({{{r1+°State}^^r+°StateSprite+{r1+°Direction}}^^r+VCharacter->r4}*8->r2/2)+W*64->{r1+°PX}^^r
{r3+r6+2}^^r+({r4+1}->r4)*64->{r1+°PY}^^r
1->{r1+°OnTheGround} ./sert à reinitialiser les jumps
End
End
End
End
End

And this allows me to read very quickly each component of the detection.

But otherwise, when I don't care about readability, I'm not afraid of long lines at all. I wrote that line in a TI-Concours line of code :P
   Pt-Change(Select(,+(*~1+Xp*(abs()>°MaxC*2-1)//256+{r3+4}^^r+RandPM128()min(max(,~°MaxV)^^r,°MaxV)^^r->r4->{r3+4}^^r)r4+{r3}^^r(??+1)->{r3}^^r)/256, and 0,°Hrt,{r3+2}^^rSelect(,+(*~1+Yp+(31*256)*(abs()>°MaxC*2-1)//256+{r3+6}^^r+RandPM128()min(max(,~°MaxV)^^r,°MaxV)^^r->r4->{r3+6}^^r)r4+{r3+2}^^r->{r3+2}^^r)/256+(*2)*2*2+A)
And yes it works, and you see it uses "?"-like statements :P
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on August 31, 2016, 05:29:32 PM
That last line reminds me Javascript O.O. Even Z80 ASM looks more readable lol. That said, CE Textlib could get really confusing too because it's all numbers XD
Title: Re: Some super crappy Axe code...
Post by: E37 on August 31, 2016, 05:48:43 PM

If {r3-1} and °RightLedge!=0

Wait... You can use "!" outside of If statements?
Title: Re: Some super crappy Axe code...
Post by: p2 on August 31, 2016, 08:41:56 PM
Quote from: Hayleia on August 31, 2016, 09:11:35 AM
Quote from: p2 on August 31, 2016, 08:19:32 AM
but how about multiple expressions? Will this be accepted? And fo I have to put an "End" then or is it just not possible uing the "?" stuff?
A=B?5->A:10->B,10->A:5->B
No, that's not possible this way. There are stupid ways to make it possible sometimes, like putting a "useless" Select (such as "A=B?Select(5->A,10->B),Select(10->A,5->B)", which quickly becomes ugly as soon as you have more than 2 expressions on one side of the ","), or having luck (I think for example that 5->Br1->A does put 5 in B and r1 in A even without a newline, but that wouldn't work if you replaced r1 with C since it would read "BC" as one variable name), but otherwise this kind of stuff isn't supposed to be possible.
So just use this for one single command each time to prevent it from getting really ugly? ^^

I'm gonna read through that piece of code of yours the next time, it's too much for this evening ^^ (I guess sunday since I'm gonna be away for a couple of days ^^)
Title: Re: Some super crappy Axe code...
Post by: Hayleia on September 01, 2016, 11:08:26 AM
Quote from: DJ Omnimaga on August 31, 2016, 05:29:32 PM
That last line reminds me Javascript O.O. Even Z80 ASM looks more readable lol. That said, CE Textlib could get really confusing too because it's all numbers XD
Well I obviously did it on purpose on that line :P
All other lines (not counting comments) are under 140 characters (counting indentation), and most "long" lines are If lines with several conditions, so they're obviously longer.

And I don't think it's weird that ASM would be more readable since I wrote most stuff in an "ASM order" but without an ASM syntax. For example:

...+RandPM128()min(max(,~°MaxV)^^r,°MaxV)^^r->r4

I wrote the "..." then the RandPM128() then the min(max(,... instead of putting everything in the first argument of the max, because that's the order the operations will be done in. That's the order an equivalent ASM code would have. But it's not written in ASM so it's normal to be like "why tf is the first argument of max before max instead of inside?" :P

Quote from: E37 on August 31, 2016, 05:48:43 PM

If {r3-1} and °RightLedge!=0

Wait... You can use "!" outside of If statements?
Erm, well that's "text code", so "!=" is the "not equal" sign. Same as "^^r" which is just the superscript r, not two hats and an r :P

Quote from: p2 on August 31, 2016, 08:41:56 PM
So just use this for one single command each time to prevent it from getting really ugly? ^^

I'm gonna read through that piece of code of yours the next time, it's too much for this evening ^^ (I guess sunday since I'm gonna be away for a couple of days ^^)
Depends what you find ugly and what you find bearable. If you prefer using a "useless" Select rather than wasting lines replacing your "?" with an If (and an End obviously), you can do it. If on the contrary you find it obfuscating, you can also not use it :P
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on September 03, 2016, 05:49:53 AM
To be honest, if my code was gonna become this hard to decipher while also using ASM order, then I would rather retry learning some ASM so I can use inline ASM in my games. But I try to keep my code as readable as possible when I can now.
Title: Re: Some super crappy Axe code...
Post by: Hayleia on September 03, 2016, 06:23:08 AM
Quote from: DJ Omnimaga on September 03, 2016, 05:49:53 AM
To be honest, if my code was gonna become this hard to decipher while also using ASM order, then I would rather retry learning some ASM so I can use inline ASM in my games. But I try to keep my code as readable as possible when I can now.
Same, and that's what I've been advising all the time in that thread rather than saying "ok, here's what your code should look like when you're a pro" and no one can read it again. I only made that one line completely unreadable because I was bored at the time, and it was in a game no one cared about (just a contest entry) :P
Title: Re: Some super crappy Axe code...
Post by: E37 on September 03, 2016, 03:59:55 PM
Have you ever tried to understand greylib? That's impossible to read!
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on September 03, 2016, 05:57:05 PM
Isn't greylib written in ASM?
Title: Re: Some super crappy Axe code...
Post by: E37 on September 03, 2016, 07:07:25 PM
GreyLib for Axe? it is in Axe.
(This thread should be renamed to like general Axe discussion...)
Title: Re: Some super crappy Axe code...
Post by: c4ooo on September 03, 2016, 07:11:45 PM
Greylib is in axe but uses inline asm. Anyways a longtime ago I just  took all the asm out of greylib and put it in my own graphics lib so I had a better understanding of what was going on :P
Title: Re: Some super crappy Axe code...
Post by: p2 on September 03, 2016, 07:15:22 PM
@E37:
I just returned from a lil vacation so I didnt have the time to read through all of your posts yet (sorry for that).
But actually it's somehow still about my little (once super crappy - now more like "rather crappy") axe code and I'm soon gonne upload a re-re-re-written version of it ;) ^^
But I admit it's also some kind of general axe discussion thread ;D
Title: Re: Some super crappy Axe code...
Post by: E37 on September 03, 2016, 07:20:28 PM
I was actually going to make a post on optimization in a bit.
You might want to hold off for a bit.
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on September 03, 2016, 07:33:30 PM
Quote from: E37 on September 03, 2016, 07:07:25 PM
GreyLib for Axe? it is in Axe.
(This thread should be renamed to like general Axe discussion...)
Aren't Axioms written in ASM as a mean to enhance the Axe language, though? I thought they were like Celtic, xLIB, Omnicalc and DCS Basic libs
Title: Re: Some super crappy Axe code...
Post by: E37 on September 03, 2016, 07:51:07 PM
GreyLib is a library. Axe has two types of includes Axioms (which are written in Asm) and Libraries which are written in Axe.
Libraries are meant for things Axe can already do like greyscale.
Axioms add completely new things like reading the VAT, running programs and more.
Libraries need to be compiled. Axioms already are.
Title: Re: Some super crappy Axe code...
Post by: c4ooo on September 03, 2016, 08:02:53 PM
Basicly in the end axioms add commands *as tockens*, while a library is just normal axe code that gets compiled by the axe parser. For example the memkit axiom renames the token Xmin (iirc) to Print( and gives it, as well as the token "dim(" functionality. Meanwhile greylib isn't an axiom and functions are called by typing out there full name. (Ex. GLOAD(), GUNLOAD()). Libraries are a lot more versatile then axioms, but when you don't need that versatility it is nice to add commands natively, as axioms do.
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on September 03, 2016, 09:07:57 PM
Weird, I was sure graylib was ASM, since it can generate perfect grayscale.
Title: Re: Some super crappy Axe code...
Post by: c4ooo on September 03, 2016, 10:59:52 PM
Quote from: DJ Omnimaga on September 03, 2016, 09:07:57 PM
Weird, I was sure graylib was ASM, since it can generate perfect grayscale.
It is asm. You can have inline ASM in axe.
Title: Re: Some super crappy Axe code...
Post by: E37 on September 10, 2016, 11:15:04 PM
INFORMATION OVERLOAD!
(I've been working on this for the past couple weeks)
Formatting!
[spoiler]
Ok, so here is the format that I will be using when I explain things:
But first... a little math. Pause 1 takes up 3349 cycles. Pause 1800 is about a second in slow speed mode. 3349*1800=6028200 cycles a second. Just to give you an idea when I talk about speed.
In Axe 'Ans' is the register 'HL'. I will refer to Axe's answer either as HL OR Ans (neither are actually of course typed in code)
I will start hex numbers with a $ following assembly tradition. (Yes I know in Axe it is that little 'E' but that can be easily confused) It will look like this: $E37 That is the hexadecimal number 'E37'
Also in assembly format binary numbers are started by a '%'. That would look %10101010 OK? (Yes Axe stars them with a pi sign)
[/spoiler]

'and' and 'or' statements!
[spoiler]
I'll try to go over all the ways to do and and or statements. Ill bring in to account the size, speed and problems with the statement.
With all of them I am going to take into account the worst case for them. (slowest and largest)

1. " and " and " or "
Speed: 33 cycles - that's pretty quick.
Size: up to 7 bytes - not to bad.
Pitfalls: it only compares the lower byte of each argument. That means if number mod 256 is 0, it will treat it as 0. Only use if you are sure if this won't matter or if neither of the arguments can exceed 255.

2. "*" and "+"
Speed (for "*"): It can get up to 800 cycles - by far the slowest!
Speed (for "+"): It can get up to 32 cycles - not too bad.
Size: up to 5 bytes for "+" and 7 for "*" not bad.
Pitfalls: It has a chance that the math operations can wrap around and =0. It's not very likely though.

3. "?" and "??"
Speed: 18 cycles - that's screaming fast!
Size: always 5 bytes - that's really small!
Pitfalls: None really. Just watch the short circuiting as it can cause a headache if you forget it!
Note: since it is a short circuit operator, it has a chance to increase speed even more - even a large amount!

4. plot style tokens
Speed: 45 cycles - not the fastest.
Size: up to 10 bytes - pretty small!
Pitfalls: They can be hard to differentiate, "That's 'or' right... no, its 'and'!"
Notes: It functions the same way as " or " and " and" but doesn't have the >255 problem.

5. nested 'If" statements
Speed: who cares?
Size: does it matter?
Pitfalls/notes: ... just no. Don't do it. Any coder who tries to read your code where you made a separate 'If' for each and and calls the same routine for each 'or', will HATE you (and you probably won't be able to read it anyway) That kind of code is for assembly! NOT Axe! As mentioned, this dosn't mean never use 'If' statements, just don't use them instead of an 'and' or 'or'.

That is all of the ways I can think of. Read over all of them and decide which is best for yourself.
[/spoiler]

Select(!
[spoiler]
This guy is kinda of tricky. It sound really complicated and large, but it is really very fast and small.
What do I mean? Lets talk size. It takes up 2 bytes! Thats awesome! Simply typing in any number is 3 bytes!
Speed? 22 clock cycles. Screamin' fast. (An 'If' statement takes 18 cycles)
It is really used if you want to evaluate an expression and don't want it to affect HL.
That will be REALLY useful when I get to optimization. Not that great otherwise.
[/spoiler]

Where is data anyway?!?
[spoiler]
Maybe you know, maybe you don't. Data is stored at the end of the program. So what? It is stored IN ORDER that is declared in the program. OK?
Will be helpful for optimization later.
Also, if you overflow a data buffer, it will affect the one after it!
[/spoiler]

Optimize!
[spoiler]
There is a lot of things for this. I'll go over some of the main points.

The most effective kind (besides organized code) is answer optimization.
Look at this code for example

:If COND
:Text COND>Char
:End

Anything you can do to optimize this? It may look fully optimized, but it isn't.

:If COND
:Text >Char
:End

Since the If statement already evaluated the condition and it is displayed right after, we don't need to re-evaluate it. COND is already stored in HL.

How about this:

:If A=5 or A=8 or A=37
:.Code
:End

What about that? It could be:

:!If A-5?-3?-29
:.Code
:End

What did I just do?
Think about it this way: plug a number in for A. Then run it through the first statement, and the the second. Remeber that the code after '?' is evaluated if the previous code is non-zero.
Lets use 37.
:37-5 that is 32. it is non-zero so we move on to the next one.
We use the previous answer for the next one so the equation is:32-3 That is 29. 29 is non-zero so we move on to the next one.
:29-29 that is zero so we return 0 and the If statement code executes.
If it wasn't 0 then it would return that number and nothing would happen.
If it was 0 on one of the middle steps, then the '?' would read 0 and return 0 to the If statement and the code would run.

Math operations:
Have a math operation that is the same but you use it a bunch?
How about this one, it gives the end of a file as a location:
:PTR+{PTR-2}r
And you look at that code and say: "Wait a sec E37, you can answer optimize that!" ... and you'd be right!
Does this look better?
:PTR+{-2}r
There! that saved... 0 bytes!?!
If you test that, it is the same size both ways!
WHY IS THAT! Surprise! Axe automatically optimizes it for you.
Proof?
[spoiler]
Compare the compiled size of :A+{A-2}r to that of :A+{B-2}r
They're different! The only way that could work is if Axe does that automatically!
Thanks Runer112!
[/spoiler]
(well.. at least it looks cleaner and your source is smaller)
Remember Data? (look back if you don't. I promise it is short!)
Here is where it comes in handy!
:"1224"[00]->str1   //string1
:"5678"[00]->str2   //string2
Imagine you want to chose want to choose string1 if X=0 and string2 if x=1
:If X=0      //yes I know you can optimize this
:Disp Str1
:ElseIf X=1
:Disp Str2
:End
Don't use an If statement!
try this instead:
:Disp X*5+Str1
Note that this fails if X is greater than one. But, it is a heck of a lot smaller and faster!

About those If statements then:
Compare :If A=1 and :!If A-1
They're the same size right?
NO!
If A=1 is 6 BYTES LARGER!

Lets try something else
How about :0->{A}
You can't optimize that!!! E37 you're crazy!
Really? Oh, but you can!
: xor 0->{A}
Wait... What?!? That's larger right?
*saves one byte
How?
It gets into how Axe stores constants.
All numbers in Axe take up 3 bytes. Yup. A program that has just :SOMENUMBER will be 3 bytes.
Note that 0 and 25565 take up the same amount of space in the program! Making the number less that 256 doesn't help.
xor has a special condition that if one of the arguments is 0 it only takes up 2 bytes. ;)
Don't start replacing all of your 0's with xor 0 !!!
That is only the 1 byte xor!
In my example, {A} can only take one byte.
If I had used {A}r instead, xor 0 wouldn't have worked.

Sometimes, a complete rewrite is necessary. I found that a complete rewrite (without the original code handy) can be very beneficial.

Some memory hacks:
If you desperately need 10 bytes of free ram, how about using a file. What? Each file takes up 10 bytes of space, and you can use them for yourself! (assuming you don't need to use the file) Were can you find their location? :Disp °Y1 >Hex will give you the location for the file!

[/spoiler]

Pathfinding!
[spoiler]
Subroutine: AStar
CALL   PushNode(OpenStack,StartingX,StartingY,0,0,0)   // this sets the starting node and sets it's distance to the goal to 0. (that value doesn't matter it can really be anything since the x and y cords. determine if the goal has been found) I set its parent's x and y to 0 so when I am calculating the path at the end, I know that it is the starting node.

While ("tmpOpen" is not empty){
    If (!PathFound){
    CALL    Calc1Node       //this doesn't really need to be a subroutine but it makes it easier to read
    }Else{
    Return    //Sucess! Each node points to the previous one in the path so all you need to do is return up the stack starting with the node on the goal
    }
}
Return          //Fail! no paths exist to the target!

Subroutine: Calc1Node
Find the node that is the closest to the target on the open stack and pop it off the stack. You should ignore the node if it is on an impassible tile or already exists - It is perfectly fine to only add a couple nodes. You will only add 8 nodes on the first tile as every other tile will be adjacent to the tile that called it.
Calculate the 8 nodes nearest to it and their distance from the target (I used sqrt(abs(Y-TargetX)2+abs(Y-TargetY)2)+ValueOfTile  ValueOfTile is how much movement is needed to cross this tile - higher numbers are harder to cross!)
Push each of the nodes onto the open stack. Make sure to have them include their parent node's location! However if the node is on the goal tile, push it to the closed stack and set PathFound to true.
Push the node that was evaluated (the one that was popped off when this was called) onto the closed stack
Return

PushNode
/*
Node Structure
Toal: 6 bytes
1b: NodeX
1b: NodeY
2b: Distance to goal
1b: parentX
1b: parentY
*/
Pushes the node to either the open or closed stack. I inserted memory on the end of the appv to do the least amout of shifting. I also refound the pointers for both stacks in case they moved.
Return

PopNode
//pops a 6 byte node off the open stack. See node structure...
I used deleteMem once the data was retrieved.
I also refound the pointers for both stacks in case they moved.
Return

Define: "tmpOpen"       //list of nodes left to be checked
Define: "tmpClosed"    //list of nodes that have already been checked

Note: this returns the path form finish to start. You will want to make the goal pathfind to the unit!

[/spoiler]

Map compression!
[spoiler]
Let's pretend you are making a game. Most games have multiple maps, it takes up a lot of space to have multiple arrays to hold all your maps.
Here is how to make all your maps (with in reason) take up the space of one!
First you need to know the number of tile types. If your game just has air, grass, and stone, then there is 2 (assuming that the first tile type is 0)
You need 2 maps. They must be the same size!
I want to edit the slot. I will set the slot on the compressed matrix equal to: (valueOfFirstMap) + (valueOfSecondMap*Prime)
What? Where did that prime come from? That is what lets me compress the map. The prime must be bigger that the amount of types.
In my example, I had 3 different types. I will pick 5 since it is the first prime greater than 3.
If you do mod (prime), then the remainder will have to be the first map's entry because the second entry will be some multiple of the prime and come out evenly. Divided by the prime will ignore the remainder (the first layer) and only give the second map.

Want more maps?
lets pretend that you have a total of 3 types of tiles for each layer
How to add / get from any of the layers (Let's pretend there are 3):
The first prime will be 5. that is the smallest prime that is greater than 3 (the supposed total number of tiles for the first layer)
If there are 3 types on the next, here is how to get the next prime. 3*5 +3 is 18. That is the highest number that the the first 2 layers combined can be right?
Well, for the third layer, we need a prime bigger than 18. let's use 19. You add the third layer to the total of the previous two.
To get layer 1 and 2 it is the same as above. To get the third, just divide by the second prime (19 in the example)


You can continue this pattern until it overflows. (if the max you can hold in one entry is 2^16, then the highest possible entry must be less than that)

It works well for multilayer maps, but it will work for any sets of data that are the same size.
[/spoiler]

Extras!
[spoiler]
Memory locations:
$86D7 and $86D8
That's the location of the graph screen pen's x and y coordinates respectively.
Right next to the 'appv' key is 'var'
What's that?
Try: float{GetCalc("varA")}->A
Now A holds the value of the OS letter variable 'A'. It still is in the range of 0-65535.
Or: A->float{Getcalc("varA")}
Will store the value of Axe's A to the OS's 'A'

Tired of making appv data files and then deleting them once the program exits?
Then this is the trick for you!
Replace "appv" with the "tmp" key that you kinda of ignored. (you know you did)
All 'temp' files are automatically deleted when you exit the program!

$844C->CurCol
$844B->CurRow
These are the locations of the column and row of the cursor in the homescreen. Output(5,6) is the same as 5->curCol:6->curRow

Although L2 in the Axe documentation is only stated as being 512 bytes it actually is over 800! That's enough to be an extra buffer with space left over for variables!

Crash!
Ever wanted to make you program crash? (but not the nasty kind that makes you pull the batteries)
Simply type :Goto (0)
It will do a nice crash-reset RAM that will only make you press the on key.
Nice if your program corrupts memory. (but you were going to fix that anyway right?)
[/spoiler]

Axioms?!?
[spoiler]
Ever wanted to make an axiom? (assembly knowledge required)
I decided to write a tutorial on how to create an axiom using Mimas.

Getting set up:
Download Axe. Open up the folders in it and find the files called TokenHook.inc and Axe.inc.
Download Mimas. Open it up and find the file asmTo8xv.exe.
Drag both files one at a time over asmTo8xv. They might need to be in the folder for it to work.
That should create the files TOKENHOO.8xv and AXE.8xv
Send TOKENHOO.8xv and AXE.8xv to your calc.
(If you don't already have Mimas and Axe this probably isn't for you)

Create a new program IN MIMAS. Whatever you name it, DON'T name it the same thing as what your axiom is going to be called.
Open the menu for that program and chose 'Libraries'. Add both TOKENHOO and AXE.
Now you are ready to start programming!
If you are unfamiliar with the Axiom format, Axe has a file on it in the 'Developers' folder.

Here is some example code, with descriptions:

DW AXM_HEADER
;This tells Axe that this is an axiom
;these name can be found by pressing 2nd + catalog and opening AXE
DW DispHLEnd
;sets the size
DB AXM_ALL
;It works for all compile types
DB $27,$00
;It will be the token fMin( found under math
DB AXM_INLINE
;It is inline
DB AXM_1ARG
;1 argument, A number in this case
RORG 0
;This is the start of the axiom's code!
BCALL DispHL
;The argument is already in HL. All we have to do is display it!
DispHLEnd:
;End of this command's code
DW $00
;The end of the axiom
DW hFmin
;which token to replace
DB 6
;the replacement is 6 characters long
DB "DispHL"
;thats all!

Now to compile!
Before compiling choose your axiom's name. It MUST be different from the code's name or it WON'T WORK!
Create a program in a include your axiom.
Compile once with Axe to convert the axiom to an appv.
Once you open you program (not the Mimas one!) the token replacements should show up. (if you made any)
If it just displays one empty line, your token repalcement was bad. Pull the batteries and try again.
You should have successfully created an axiom with Mimas!
[/spoiler]

Using Hex
[spoiler]
Here is some hex and examples to help optimize your code.
DispGraph: Asm(EF7150)
This is a much slower form of Axe's dispgraph. It will only be useful if you have never used dispgraph anywhere in the program.
It does give a very nice size reduction though.
If you know any assembly, it can be used to replace some Axe functions and you can gain in speed and size!
This goes especially well with the Mimas.
In libraries that require an axiom (like memkit), you can remove the axiom requirement and add inline hex instead.
I guess I should mention that there is nothing special about axioms. Anything that can be accomplished with axioms can be done with inline hex. (loops can get tricky though and you may need to some hacky things to add them - such as adding axe labels and passing the hex the address as an argument!)

Here are some cool things you can use...
:.some code
:Goto Gbd1HEX // this can also be a subroutine instead
:
:[] -> Gbd1HEX
:[*assembly code in hex here*]

This will result as the hex code being run as if you called it with Asm() !
[/spoiler]

"Hacking" Axe
[spoiler]
I have seen people asking for a function in Axe to return X number of times.
Runer said he wouldn't add something to do that.
Here is how to do it anyway! (there is a couple cases where things could go wrong - this "doesn't work" if it is called from inside a function that needs commas like Text(arg1,arg2,arg3) )
Asm(E1C9)
What? That's all? Yes. repeat the E1 for how many times you want to return. If you wanted to The above example would return from the subroutine and return from the one that called that.
If you return too many times (like returning twice while not in a subroutine) bad things will happen. I'm not entirely sure what, but it starts with a simple crash and can get worse from there.

How to make it work from inside a function with commas:
[spoiler]
For each comma before the function, add another E1. If the call is the 3rd argument, add two E1's.
[/spoiler]

How to return and jump to a label:
LLabel:Asm(D1E3C9)
Make sure the label is preceded by the little L for the address of the label. Again, you will need to add extra D1's to compensate for commas or to return multiple times.

[/spoiler]
Title: Re: Some super crappy Axe code...
Post by: p2 on September 13, 2016, 07:35:44 PM
I got a little understanding problem about the Axe modifications:
instead of asking stuff like this
If X=2: 4->Y: 6->Z: End
I could go and use the register HL for it:
If X=2: +2->Y: +2->Z: End
But wouldn't this actually make the code slower? This is what I think the processor does in those two cases:
Code (THE FIRST CODE) Select
load X
load "2"
*compare*
load "4"
store
load "6"
store

Code (THE SECOND CODE) Select
load X
load "2"
*compare*
load "2"
*addition*
store
load "2"
*addition*
store

Wouldnt the second code be slower due to higher number of loads and to multiplications...?

And is it the same when using that ?X+4 way of writing conditions? :)
Title: Re: Some super crappy Axe code...
Post by: E37 on September 13, 2016, 07:38:36 PM
If X=2: +2->Y: +2->Z: End
wouldn't work. The = statement returns 1 which would make Y=3.
Speed? Honestly, unless that is in the inner loop of the most time sensitive thing imaginable, It won't matter.
Without testing it, I think it would be larger.
Title: Re: Some super crappy Axe code...
Post by: p2 on September 13, 2016, 09:43:25 PM
Okes so now the updated (fixed) version: this code:
If X=2: 4->Y: 6->Z: End
should get the exact same results as this one:
If X=2: +3->Y: +2->Z: End
but the second one would even be a liiiitle bit slower and also bigger...? O.o

so modifying any code this is the rule I should follow?:
2->X: 4->Y // Don't change anything since it's just numbers
2->X: X+4->Y // Using a variable name twice here so modify to 2->X:+4->Y
SO this kind of "modification" only makes sense in very few situations since it's else just going to add even more stuff to process? :)
Title: Re: Some super crappy Axe code...
Post by: Hayleia on September 14, 2016, 07:58:10 AM
I think the "+constant->Whatever" is only worth it if the constant is either -2, -1, 0, 1 or 2. Because in these cases, you just have 1 or two "dec" or "inc" so you save space and time, but in all other cases you're actually doing an addition which is more costly than just a load.
So you can probably keep your +2->Z but the +3->Y isn't an awesome idea. I don't recall if -3 and 3 are to add to the list, but at least don't do this with +7 or whatever :P

And obviously, when you have "Whatever->Variable:Variable+Whatever->Whatever", as you said, you can get rid of one of your "Variable"s.
Title: Re: Some super crappy Axe code...
Post by: p2 on September 14, 2016, 08:29:19 AM
nice, thank you ^^ I think I now completely understood the use of the HL register  :thumbsup:
Next thing up for me to learn is ?X+2 and stuff...  :ninja:
Title: Re: Some super crappy Axe code...
Post by: ben_g on September 14, 2016, 11:39:35 PM
The ? is basically an inline if. If the expression before the ? returns true (iirc this equals to any nonzero number in axe), the code after the ? is executed.

Example:
If A=3
A++
End

Can also be written as

A=3?A++

You can also have a, to have an else condition.

The main advantage is that you can use it inline. For example to have a different sprite when a player is running or not: Pt-On(X,Y,Speed=0?°StandSPR,°RunSPR) This command functions similarly to this code:
If(Speed=0)
Pt-On(X,Y,°StandSPR)
Else
Pt-On(X,Y,°RunSPR)
End
However the first one only has one call to Pt-On. As for efficiency, I assume that performance-wise it's pretty much the same, but I think the first one compiles into slightly smaller code. I'm not sure of that though.
Title: Re: Some super crappy Axe code...
Post by: p2 on September 15, 2016, 08:39:18 AM
Quote from: ben_g on September 14, 2016, 11:39:35 PM
You can also have a, to have an else condition.
Had to read it 3 times before I understood that one xD


Quote from: ben_g on September 14, 2016, 11:39:35 PM
The main advantage is that you can use it inline. For example to have a different sprite when a player is running or not: Pt-On(X,Y,Speed=0?°StandSPR,°RunSPR) This command functions similarly to this code:
If(Speed=0)
Pt-On(X,Y,°StandSPR)
Else
Pt-On(X,Y,°RunSPR)
End
I never knew this was possible I always thought it was only useful for having to write less code... But the inline usage is really cool *-* (Gonna give it a try and create a few examples how I think it orks xD)
Title: Re: Some super crappy Axe code...
Post by: E37 on September 15, 2016, 02:31:10 PM
The most efficient size way to do it is
:A-3??A++
Or
:A+(=3)->A
Note that the comma in the ? Or ?? Statements adds 3 bytes.
Another way to do the sprites is to
:PtOn(X,Y,°StandSPR- °RunSPR*(A=3)+°RunSPR)
That code assumes that RunSPR was declared before StandSPR.
Switch stand and run if stand was declared first.
That would work for any amount of data between the sprites. If they are right next to each other when declared you can replace °StandSPR- °RunSPR with 8 (and change the order to  A=3*8+°RunSPR to remove the parenthesis around a=3 you can change run to stand again if stand is declared first)
Title: Re: Some super crappy Axe code...
Post by: E37 on September 18, 2016, 04:53:43 PM
https://www.omnimaga.org/axe-language/specific-tutorials-list-(axe)/
(-_(//));
Title: Re: Some super crappy Axe code...
Post by: p2 on September 19, 2016, 07:39:42 AM
I never knew there was such a list *-* thanks a lot ^.^
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on September 19, 2016, 04:30:47 PM
I think some of those are from the now defunct Omnimaga articles section, though, right? I know some of those had a backup copy on the forums but in the event where they don't, then you could check archive.org. Also Site du Zéro has an Axe tutorial but it's in French.
Title: Re: Some super crappy Axe code...
Post by: E37 on September 27, 2016, 04:14:41 PM
I have an update to my previous post. It will be here and added to the big list for completeness.

Using Hex
[spoiler]
Here is some hex and examples to help optimize your code.
DispGraph: Asm(EF7150)
This is a much slower form of Axe's dispgraph. It will only be useful if you have never used dispgraph anywhere in the program.
It does give a very nice size reduction though.
If you know any assembly, it can be used to replace some Axe functions and you can gain in speed and size!
This goes especially well with the Mimas.
In libraries that require an axiom (like memkit), you can remove the axiom requirement and add inline hex instead.
I guess I should mention that there is nothing special about axioms. Anything that can be accomplished with axioms can be done with inline hex. (loops can get tricky though and you may need to some hacky things to add them - such as adding axe labels and passing the hex the address as an argument!)

Here are some cool things you can use...
:.some code
:Goto Gbd1HEX // this can also be a subroutine instead
:
:[] -> Gbd1HEX
:[*assembly code in hex here*]

This will result as the hex code being run as if you called it with Asm() !
[/spoiler]

Updates to Extras:
[spoiler]
$844C->CurCol
$844B->CurRow
These are the locations of the column and row of the cursor in the homescreen. Output(5,6) is the same as 5->curCol:6->curRow
[/spoiler]
Title: Re: Some super crappy Axe code...
Post by: Dream of Omnimaga on October 06, 2016, 08:14:29 PM
On a side note, although they are old, the Omni tutorials are back. @Soru only needs to re-add thr Php script for thr ones that were using actual topic post content.
Title: Re: Some super crappy Axe code...
Post by: E37 on October 24, 2016, 09:23:22 PM
 >:D More things! (Updating my huge post as always) @p2

"Hacking" Axe
[spoiler]
I have seen people asking for a function in Axe to return X number of times.
Runer said he wouldn't add something to do that.
Here is how to do it anyway! (there is a couple cases where things could go wrong - this "doesn't work" if it is called from inside a function that needs commas like Text(arg1,arg2,arg3) )
Asm(E1C9)
What? That's all? Yes. repeat the E1 for how many times you want to return. If you wanted to The above example would return from the subroutine and return from the one that called that.
If you return too many times (like returning twice while not in a subroutine) bad things will happen. I'm not entirely sure what, but it starts with a simple crash and can get worse from there.

How to make it work from inside a function with commas:
[spoiler]
For each comma before the function, add another E1. If the call is the 3rd argument, add two E1's.
[/spoiler]

How to return and jump to a label:
LLabel:Asm(D1E3C9)
Make sure the label is preceded by the little L for the address of the label. Again, you will need to add extra D1's to compensate for commas or to return multiple times.

[/spoiler]

(I seriously need to find a better place to put this)
Title: Re: Some super crappy Axe code...
Post by: c4ooo on October 24, 2016, 10:02:41 PM
Hacky but very useful. Although, to be fair to runer112, if you need this in your code you should orgonize your code more with functions and stuff :P