Omnimaga
Calculator Community => TI Calculators => Axe => Topic started by: Spenceboy98 on April 03, 2012, 11:29:46 pm
-
I don't know how to optimize Axe code, so I am asking for help.
What original code does:
(http://img.removedfromgame.com/imgs/AxeTest.gif)
Code:
:.AXETEST
:identity(3FFC3FFC30CF30CF300C300C0C300C303FFC3FFC330C330C3FFC3FFCF00FF00F)
:0→X
:56→Y
:[7E4B42247E527EC3]→Pic1
:Repeat getKey(15)
:StorePic
:Pt-On(X,Y,Pic1)
:DispGraph
:Pt-Change(X,Y,Pic1
:RecallPic
:If getKey(2)
:Lbl PIP
:[7ED242247E4A7EC3]→Pic2
:X-1→X
:Goto LEFT
:End
:If getKey(3)
:Lbl PI
:X+2→X
:End
:If getKey(4)
:Lbl IP
:[7E7E42247EC37EC3]→Pic3
:Y-1→Y
:Goto UP
:End
:If getKey(1)
:Lbl PIPI
:[7E665A247EC37EC3]→Pic4
:Y+1→Y
:Goto DOWN
:End
:End
:Lbl LEFT
:Repeat getKey(15)
:StorePic
:Pt-On(X,Y,Pic2)
:DispGraph
:Pt-Change(X,Y,Pic2
:RecallPic
:If getKey(2)
:X-2→X
:End
:If getKey(3)
:Goto PI
:End
:If getKey(4)
:Goto IP
:End
:If getKey(1)
:Goto PIPI
:End
:End
:Lbl UP
:Repeat getKey(15)
:StorePic
:Pt-On(X,Y,Pic3)
:DispGraph
:Pt-Change(X,Y,Pic3)
:RecallPic
:If getKey(4)
:Y-1→Y
:End
:If getKey(2)
:Goto PIP
:End
:If getKey(3)
:Goto PI
:End
:If getKey(1)
:Goto PIPI
:End
:End
:Lbl DOWN
:Repeat getKey(15)
:StorePic
:Pt-On(X,Y,Pic4
:DispGraph
:Pt-Change(X,Y,Pic4
:RecallPic
:If getKey(1)
:Y+1→Y
:End
:If getKey(2)
:Goto PIP
:End
:If getKey(3)
:Goto PI
:End
:If getKey(4)
:Goto IP
:End
:End
:
Is there any way to optimize it?
-
Here's a simple, fairly optimized way to do what you are trying to achieve. I have detailed most of the optimizations in comments in the code, but I did not comment about the biggest optimization. This optimization is to draw sprites from a variable pointer, instead of requiring four different copies of the whole loop just for facing in different directions. For instance, here's the line I used to initialize the player sprite to the right-facing sprite:
:2*8+Pic1→S
If you're familiar with how this works, then go ahead and skip to looking at the code to see the final product with the rest of my suggested simple optimizations. If you're not familiar with how this works, I'll give a quick explanation. Because of how Axe includes data like sprites, the order in which you list data (like sprites) is exactly the order it will assume in the compiled program. Since each sprite is 8 bytes, that means that each successive sprite is found in memory 8 bytes after the previous sprite. Pic1 points to the start of the block of 4 sprites, so it points to the first one, the down-facing sprite. 2*8+Pic1 would point to the data 16 bytes after the down-facing sprite, which we know is the right-facing sprite because it's 2 sprites (remember, a sprite is 8 bytes) after the down-facing sprite. This offset from Pic1 logic is used to draw the proper sprite for facing in all 4 directions.
So here's my suggested fairly optimized and hopefully easy-to-understand solution:
:.AXETEST
:identity(3FFC3FFC30CF30CF300C300C0C300C303FFC3FFC330C330C3FFC3FFCF00FF00F)
:
:[]→Pic1
:[7E665A247EC37EC3] .DOWN
:[7ED242247E4A7EC3] .LEFT
:[7E4B42247E527EC3] .RIGHT
:[7E7E42247EC37EC3] .UP
:
:.START FACING RIGHT AT (0,56):
:2*8+Pic1→S
:0→X
:56→Y
:.THIS DOESN'T NEED TO BE INSIDE THE LOOP:
:StorePic
:
:While 1
: Pt-On(X,Y,S)
: DispGraph
: .ERASING WITH Pt-Change() UNNECESSARY BECAUSE:
: RecallPic
: If getKey(1)
: Y+2→Y
: 0*8+Pic1→S
: End
: If getKey(2)
: X-2→X
: 1*8+Pic1→S
: End
: If getKey(3)
: X+2→X
: 2*8+Pic1→S
: End
: If getKey(4)
: Y-2→Y
: 3*8+Pic1→S
: End
:.OPTIMIZED POST-CHECK LOOP:
:End!If getKey(15)
Now, if you want really optimized code... That can be arranged. :hyper: I'll leave figuring out how it works as an exercise.
:.AXETEST
:identity(3FFC3FFC30CF30CF300C300C0C300C303FFC3FFC330C330C3FFC3FFCF00FF00F)
:
:[]→Pic1
:[7ED242247E4A7EC3] .LEFT
:[7E7E42247EC37EC3] .UP
:[7E4B42247E527EC3] .RIGHT
:[7E665A247EC37EC3] .DOWN
:
:56→Y
: and 0→X
:→S
:
:While 1
: ClrDraw
: Pt-On(X,Y,S*8+16+Pic1)
: DispGraph
: If getKey(1)-getKey(4)
: →S
: *2+Y→Y
: End
: If getKey(3)-getKey(2)
: -1→S+1
: *2+X→X
: End
:EndIf getKey(15)
-
EDIT:ninjasked
it's just moving up/down/left/right and remembering the direction the character is facing? i'd structure it differently, with something like this:
ClrDraw
DiagnosticsOff
.A=x_pos, B=y_pos, C=direction_faced
0->A->B->C
[sprite data, one after another, ordered up, down, left, right stored here]->Pic1
Repeat getkey(15)
if getkey(4)-getkey(1)
.go up
if getkey(4)
-1->C
B--
end
.go down
if getkey(1)
->C
B++
end
end
if getkey(2)-getkey(3)
.go left
if getkey(2)
+1->C
A--
end
.go right
if getkey(3)
+2->C
A++
end
end
ClrDraw
Pt-On(A,B,C*8+Pic1
DispGraph
end
-
Thank you!
-
All this does is display the sprite, but I still need it optimized:
(http://img.removedfromgame.com/imgs/karrace.gif)
Code:
:.KARRACE
:identity(318C4BD24FF24E724FF2366C0FF0166818181BD87BDE981997E99FF99FF967E6)
:.KAR
:[314B4F4E4F360F16]→Pic1
:[8CD2F272F26CF068]→Pic2
:[181B7B98979F9F67]→Pic3
:[18D8DE19E9F9F9E6]→Pic4
:.DRAW
:Repeat getKey(15)
:Pt-On(0,0,Pic1
:Pt-On(0,8,Pic3
:Pt-On(8,0,Pic2
:Pt-On(8,8,Pic4
:DispGraph
:End
I know there is a way to optimize it, but I don't know how.
-
Code:
:.KARRACE
:identity(318C4BD24FF24E724FF2366C0FF0166818181BD87BDE981997E99FF99FF967E6)
:.KAR
:[314B4F4E4F360F16]→Pic1
:[8CD2F272F26CF068]→Pic2
:[181B7B98979F9F67]→Pic3
:[18D8DE19E9F9F9E6]→Pic4
:.DRAW
:Repeat getKey(15)
:Pt-On(0,,Pic1
:Pt-On(0,8,Pic3
:Pt-On(8,0,Pic2
:Pt-On(8,,Pic4
:DispGraph
:End
that's all i see
Edit: It will be best to stick with Pt-On IMO, as you already have the command in the previous and assumed related code
-
Code:
:.KARRACE
:identity(318C4BD24FF24E724FF2366C0FF0166818181BD87BDE981997E99FF99FF967E6)
:.KAR
:[314B4F4E4F360F16]→Pic1
:[8CD2F272F26CF068]→Pic2
:[181B7B98979F9F67]→Pic3
:[18D8DE19E9F9F9E6]→Pic4
:.DRAW
:Repeat getKey(15)
:Pt-On(0,,Pic1
:Pt-On(0,8,Pic3
:Pt-On(8,0,Pic2
:Pt-On(8,,Pic4
:DispGraph
:End
that's all i see
Edit: It will be best to stick with Pt-On IMO, as you already have the command in the previous and assumed related code
Even this is unnecessary due to the new peephole optimizer :P Although I believe (I need Runer to confirm) that a While 1 : EndIf getKey(15) might be better than Repeat getKey(15) : End
-
What is this "peephole optimizer" of which you speak? How do I use it?
-
What is this "peephole optimizer" of which you speak? How do I use it?
It's built into Axe, so you really don't have to do anything to use it, just compile like normal. However, you can choose not to use it by pressing [zoom] at the compile menu instead of [Enter] or [2nd]
-
Even this is unnecessary due to the new peephole optimizer :P
It would make sense to think this, but this is actually not true. A peephole optimization to do this was added in Axe 1.0.5, but it was disabled in the next version (Axe 1.1.0) and has been ever since. Don't ask me why because I don't know; a quick test with Axe 1.0.5 appears to suggest that the optimization works fine. Perhaps I'll ask Quigibo in a more appropriate thread why this optimization (called o_PushPop5 in Commands.inc) is disabled.
Although I believe (I need Runer to confirm) that a While 1 : EndIf getKey(15) might be better than Repeat getKey(15) : End
This is true. :)
-
Even this is unnecessary due to the new peephole optimizer :P
It would make sense to think this, but this is actually not true. A peephole optimization to do this was added in Axe 1.0.5, but it was disabled in the next version (Axe 1.1.0) and has been ever since. Don't ask me why because I don't know; a quick test with Axe 1.0.5 appears to suggest that the optimization works fine. Perhaps I'll ask Quigibo in a more appropriate thread why this optimization (called o_PushPop5 in Commands.inc) is disabled.
Although I believe (I need Runer to confirm) that a While 1 : EndIf getKey(15) might be better than Repeat getKey(15) : End
This is true. :)
Wow, really? That is weird (The first part). By habit i automatically will type "0,," instead of "0,0" but thanks O.o.
Also thanks for the second part too. In terms of what they accomplish they are exactly the same, no? (Well I guess using Repeat checks the condition at the beginning, where the EndIf version checks at the end?)
-
I was looking through the code of Eat Nethams(it seemed easy) to try to understand it. I'm having trouble figuring out how it is displaying so many lobsters at once. Can someone explain this to me?
-
I was looking through the code of Eat Nethams(it seemed easy) to try to understand it. I'm having trouble figuring out how it is displaying so many lobsters at once. Can someone explain this to me?
*BUMP*
Can no one help me with this^^^^?
-
I was looking through the code of Eat Nethams(it seemed easy) to try to understand it. I'm having trouble figuring out how it is displaying so many lobsters at once. Can someone explain this to me?
*BUMP*
Can no one help me with this^^^^?
They're all sprites, and you can draw as many sprites as you want. I don't quite understand what you mean ???
-
But it only has one instance of saying Pt-On. How is it displaying so many without anymore?
-
It doesn't clear the screen every frame, so all the lobsters that were drawn in previous frames are still there. (The entire screen is shifted down each frame, so it looks like the lobsters get shifted down.)