Omnimaga
Calculator Community => TI Calculators => Axe => Topic started by: Matrefeytontias on June 21, 2013, 09:22:36 am
-
Hallaw,
When you have to draw a great part of the screen pixel by pixel (like for a game of life), the program usually become reaaally slow, since Axe is not good at pixel drawing. So I've thought of a method to greatly speed up this kind of tasks.
So, how does it work ? You know that the TI-z80-s screen (excepted the 84+ C) takes 1 byte to code 8 pixels, so that 1 bit = 1 pixel. The technique consists in calculating each pixel as we would do normally, and then turn on or off the corresponding bit of a variable instead of turning it on on the screen (which is absolutely slower). Then, when the 8 bits of the variable have been modified the way you wanted, you can directly store the variable in the corresponding byte of the buffer, thus turning on/off 8 pixels at a time. Of course, this'll only work if the width of area you want to paint is a multiple of 8.
So let's do it !
Let's say that our function is named BuildByte, since that's what it does.
First, we need a counter. This counter must send a signal every 8 times we call it.
:.Only once
:0→C
:
:Lbl BuildByte
:If C++^8
:.The counter doesn't send the signal
:Else
:.It does
:End
:...
Then, we need the variable which will contain the pixels data :
:.It must be initialized to 0 at the beginning of the program
:0→B
Say that the function BuildByte takes three arguments, the X-coordinate of the byte where the pixel must be drawn (not the pixel, so it must be a number between 0 and 11), the Y-coordinate of the pixel (between 0 and 63), then 0 if the current pixel must be white, or 1 if it must be black. We need to put this 0 or 1 to the corresponding bit of B. Then if C is a multiple of 8, then it means that the 8 bits of B have been set, and we store B in the corresponding byte of L6.
But how do we do set the corresponding bit precisely, and not any other bit ? It's actually pretty simple : we always set the first bit, and then if C modulo 8 is not 0, we shift B left once. Why that ? After 7 shifts, the first pixel/bit you passed to the function will become the last bit → the first pixel of the byte when it's on-screen.
:Lbl BuildByte
:.r1 is the X coordinate
:;r2 is the Y coordinate
:.r3 is the value of the pixel
:
:r3 or B→B
:If C++^8
:B*2→B
:Else
:B→{r2*12+r1+L6}
:0→B
:End
:Return
Remember that this will be efficient only if a relatively high number of calculations are needed for each pixel. For example, this plasma program I wrote a while ago uses this method (attached screenshot runs at 6 MHz).
Hoping that this'll help you :)
-
I read this diagonally but the screenie looks pretty fast. :D
-
Wow that is great! I think I thought about doing that in the past once, but I didn't realize it was actually faster. Thanks for the tutorial. :)
-
Out of curiosity, could you post the source of that plasma program? I'd be interested to look at it, I like Axe programs that do manual graphics rendering. :)
I'm certainly not asking because I want to try to optimize it to hell >.>
-
Out of curiosity, could you post the source of that plasma program? I'd be interested to look at it, I like Axe programs that do manual graphics rendering. :)
You only want the source so you can make a version that is twice faster? :trollface:
I'm certainly not asking because I want to try to optimize it to hell >.>
[/quote]
-
Xeda asked for the source so I posted it on pastebin, but for some reason I can't reach it :/ you'd better look at the "Axe plasma" thread.
-
I still have it open here (http://pastebin.com/EibJgE4K). If that isn't working:
:.PLASMA
:.by KKI+MAT
:.Full
:.Precalculs
:det(256)→C
:For(A,0,255)
: 127+cos(A*256/32)→{A+C}
:End
:0→Θ
:Repeat getKey(15)
: L6-1→P+12→Q
: Θ+1^32→Θ
: {Θ*2+24+C}/40→D
: {Θ+C}/32→E
: .Lignes
: 0→Y
: Lbl YH
: .Precalculs
: {Y+E+C}→M
: .Colonnes
: 0→X
: Lbl XW
: .Couleur
: M+{X+D+C}
: +{X+Y+D+E/2+Θ+C}→Z
: .Init/Decale
: !If X^4
: P+++12→Q
: 0→{P}:0→{Q}
:Else
: {P}*4→{P}
: {Q}*4→{Q}
:End
:If Z≤192
: {P}+3→{P}
:{Q}+3→{Q}
:ElseIf Z≤384
: {P}++
:{Q}+2→{Q}
:ElseIf Z≤576
: {P}++
:End
:If X++-48
: Goto XW
:End
:If Y++-32
: P+12→P+12→Q
:Goto YH
:End
:DispGraph
:.Output(0,0,A►Dec,{A+S}►Dec
:End