Author Topic: [TUTO] How to make "beautiful greyscale" in Axe using interrupts  (Read 11293 times)

0 Members and 3 Guests are viewing this topic.

Offline Hayleia

  • Programming Absol
  • Coder Of Tomorrow
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3367
  • Rating: +393/-7
    • View Profile
(please tell me where I made typos, I am sure I made some :P)

With my recent work on TinyCraft, people have been asking me how I make my grayscale so beautiful. So here is a tutorial!
(what do you mean by "you stole thepenguin's sentence" ? :P)

So one day, I read thepenguin's tutorial to see if I could get something to work in Axe on a 83+BE without Full speed and I understood that I had to refresh the screen 50-60 times per second.

Now, How would you do this in Axe ? With a loop that runs exactly at 50 Hz ? Not really, for two reasons:
- maybe your calc will have beautiful grey at 50 Hz but others may hae it beautiful at 52 Hz
- maybe the loop will run at 50 Hz on your calc but will run at 48 Hz on others

So you need interrupts. If you don't know how interrupts work, check out Hot Dog's tutorial.
Problem: the slowest interrupts still runs at a higher frequency than 100 Hz, there is no interrupt at 50 Hz. But who told you that the screen was actually refreshed every time the interrupt runs ? ;)

The speeds for the interrupts are as follow (according to Hot Dog):

Speed // 83+ // 84+
0 // 560 Hz // 512 Hz
2 // 248 Hz // 228 Hz
4 // 170 Hz // 146 Hz
6 // 118 Hz // 108 Hz

So:
-with speed 0, we would need to refresh the screen only 1 time every ten runs, because 50<560/10<60
-with speed 6, we would need to refresh the screen only 1 time every 2 runs, because 50<118/2<60
-etc

Let's make a try with speed 0 for example. Then, it will be easy to get it to work with arbitrary speeds ;)
So for educationnal reasons, we are going to make a stupid and unoptimized program that will include beautiful grey. Note that I don't code so bad in real life :P
Let's draw for example two rectangles, one black, the other one grey.

.AA
ClrDrawrr
Rect(0,0,8,8,L3)
Rect(0,8,8,8,L6)

Now we need to set up the interrupt. We use speed 0 so we need to refresh the screen 1 time every 10 runs. We need a counter that will tell the calculator if it should refresh or not. So the routine used as an interrupt should look like this.

Lbl DG
T+1?T
If T=10
 0?T
 DispGraphr
End
Return

Another solution would be this one

Lbl DG
T+1?T
!If T^10
 DispGraphr
End
Return

And now, the only thing we need is to set this interrupt on to refresh the screen automatically ;)

.AA
FnOff
ClrDrawrr
Rect(0,0,8,8,L3)
Rect(0,8,8,8,L6)
0?T
fnInt(DG,0)
Repeat getKey(0)
End
LnReg
Return

Lbl DG
T+1?T
!If T^10
 DispGraphr
End
Return

If you want a little more optimised version of this, here it is

.AA
FnOff
ClrDrawrr
Rect(0,,8,,L3)
Rect(0?T,8,,,L6)
fnInt(DG,0)
While 1
EndIf getKey(0)
LnReg
Return

Lbl DG
!If T++^10
 DispGraphr
End
Return

If you want a faster-than-light or a smaller-than-0-bytes version of this, ask Runer112.

Now, the only thing that is missing in that tutorial is "how to make a calibration screen ?", but I am sure you can do this without my help. You just need to make a menu that will select between 4 values and each value gives an interupt speed and a timer-max.

Notes:
I made an example with 3 levels of grey but it works with 4 levels too ;)
See TinyCraft for example.

Disadvantages of this method:
-First of all, the screen is automatically refreshed. This means two bad things: this will make you forget your good habit to make "DispGraph"s inside your loops, and sometimes, you only want to refresh after it cleared all and redraw all, but now you can't choose anymore where the refreshing will happen
-For some reason, using the Text() command on a regular 83+ (not SE) kills the interrupt (but everything else in the program runs fine). To avoid problems, you can use Jacobly's TEXT Axiom or simply avoid the Text() command when the interrupt is running (disable it before using Text() then put it back for example, or prerender all the text in your menus instead of putting the Text() commands in the loop).
« Last Edit: March 22, 2013, 05:42:05 pm by Hayleia »
I own: 83+ ; 84+SE ; 76.fr ; CX CAS ; Prizm ; 84+CSE
Sorry if I answer with something that seems unrelated, English is not my primary language and I might not have understood well. Sorry if I make English mistakes too.

click here to know where you got your last +1s

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #1 on: October 03, 2012, 02:05:48 pm »
So I guess the question we all have to ask is, how well does it work?

The best way to simulate a real calculator would be to go into wabbitemu and set the grayscale on steady freq at ~63Hz with 4 shades. (From my experience, 63 is average with the upperbound at 66 and lower at 59).

For comparison, here's chess at 63Hz with 4 shades:

Where 173 is the correct setting.

If you can match that with axe, I'll be impressed :D

zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline Hayleia

  • Programming Absol
  • Coder Of Tomorrow
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3367
  • Rating: +393/-7
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #2 on: October 03, 2012, 03:50:20 pm »
If you can match that with axe, I'll be impressed :D
I get exactly this on both my 83+BE (with interrupt 4) and my 84+SE (with interrupt 0), with just the little "scrolling glitch line", as you say :D
However, the grey is not that perfect on my sister's calc, whatever the interrupt I choose :-\

edit: here is what I get with Wabbitemu set at 68 Hz and 5 shades with this program ;)
.AA
FnOff
ClrDrawrr
Fill(L3+252,252,255)
Fill(L6+252+252,252,255)
fnInt(DG,0)
Pause 200
While 1
EndIf getKey(0)
LnReg
Return

Lbl DG
!If T++^10
 DispGraphr
End
Return
« Last Edit: October 03, 2012, 04:02:00 pm by Hayleia »
I own: 83+ ; 84+SE ; 76.fr ; CX CAS ; Prizm ; 84+CSE
Sorry if I answer with something that seems unrelated, English is not my primary language and I might not have understood well. Sorry if I make English mistakes too.

click here to know where you got your last +1s

Offline Sorunome

  • Fox Fox Fox Fox Fox Fox Fox!
  • Support Staff
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 7920
  • Rating: +374/-13
  • Derpy Hooves
    • View Profile
    • My website! (You might lose the game)
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #3 on: October 03, 2012, 07:40:15 pm »
wow, nice tutorial!
Quote
If you want a faster-than-light or a smaller-than-0-bytes version of this, ask Runer112.
I LOL'd at that one XD

THE GAME
Also, check out my website
If OmnomIRC is screwed up, blame me!
Click here to give me an internet!

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #4 on: October 03, 2012, 10:24:56 pm »
here is what I get with Wabbitemu set at 68 Hz and 5 shades with this program ;)

That counts, I'm impressed.
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #5 on: October 04, 2012, 02:34:29 pm »
here is what I get with Wabbitemu set at 68 Hz and 5 shades with this program ;)

That counts, I'm impressed.


I have to comment though, I don't think it works that well on the majority of calculators. Basically this method is the same as your method thepenguin77, except it uses the 560/512Hz first hardware timer interrupt instead of a 10922Hz crystal timer interrupt. Tuning this is about 20x rougher, so it's really just luck if one tuning setting looks close to perfect.


For instance, this is about what pure dark gray looks like at the best tuning setting on the luckier of my two calculators:


Change the tuning setting by just one in either direction and I get something that looks approximately like this:
« Last Edit: October 04, 2012, 02:40:22 pm by Runer112 »

Offline Sorunome

  • Fox Fox Fox Fox Fox Fox Fox!
  • Support Staff
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 7920
  • Rating: +374/-13
  • Derpy Hooves
    • View Profile
    • My website! (You might lose the game)
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #6 on: October 04, 2012, 05:32:16 pm »
I guess i have a unlucky calc then, coz greyscale never really worked out for me D:

THE GAME
Also, check out my website
If OmnomIRC is screwed up, blame me!
Click here to give me an internet!

Offline Hayleia

  • Programming Absol
  • Coder Of Tomorrow
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3367
  • Rating: +393/-7
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #7 on: October 05, 2012, 01:16:29 am »
I have to comment though, I don't think it works that well on the majority of calculators. Basically this method is the same as your method thepenguin77, except it uses the 560/512Hz first hardware timer interrupt instead of a 10922Hz crystal timer interrupt. Tuning this is about 20x rougher, so it's really just luck if one tuning setting looks close to perfect.
Yes, of course my method doesn't give perfect greyscale. I only get this on my two calcs but my sister's calc doesn't have this beautiful glitch line (it has several of them if you see what I mean :P)
The real advantage of my method though is that the grey is constant (I mean that if you go from a loop to another, there is no "no grey" time) and that you can get acceptable grey even in 6 MHz :)
I own: 83+ ; 84+SE ; 76.fr ; CX CAS ; Prizm ; 84+CSE
Sorry if I answer with something that seems unrelated, English is not my primary language and I might not have understood well. Sorry if I make English mistakes too.

click here to know where you got your last +1s

Offline Streetwalrus

  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3821
  • Rating: +80/-8
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #8 on: March 19, 2013, 06:53:09 am »
Necropost. :P

Quote
!If T++^10
Why don't you just do DS(T,10) ?

Anyway this method is awesome, but smooth scrolling a tilemap with 4 level gray looks crappy. I'll stick with three.

Offline Hayleia

  • Programming Absol
  • Coder Of Tomorrow
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3367
  • Rating: +393/-7
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #9 on: March 19, 2013, 11:55:40 am »
Necropost. :P

Quote
!If T++^10
Why don't you just do DS(T,10) ?
Because a tutorial is meant to be easy to understand, and once you understood the concepts, you can optimize yourself ;)

Anyway this method is awesome, but smooth scrolling a tilemap with 4 level gray looks crappy. I'll stick with three.
Thanks :)
But I don't think a smooth scrolling tilemapper looks that crappy with 4 levels, I do this in TinyCraft and I am not so disturbed. Or maybe this is because I am the coder and I am now used to seeing my greyscale tilemapper :P
I own: 83+ ; 84+SE ; 76.fr ; CX CAS ; Prizm ; 84+CSE
Sorry if I answer with something that seems unrelated, English is not my primary language and I might not have understood well. Sorry if I make English mistakes too.

click here to know where you got your last +1s

Offline Streetwalrus

  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3821
  • Rating: +80/-8
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #10 on: March 21, 2013, 05:27:01 am »
Or maybe I'm just scrolling too fast. :P Syncing scrolling to LCD updates with While and Stop actually makes it looks a lot better. But also incredibly slow. :S
« Last Edit: March 21, 2013, 05:27:22 am by Streetwalker »

Offline ralphdspam

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 841
  • Rating: +38/-1
  • My name is actually Matt.
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #11 on: March 21, 2013, 10:41:04 am »
Does Axe still draw the screen twice on the grayscale routine?  If so, that might give you sub-optimal results.
ld a, 0
ld a, a

Offline leafy

  • CoT Emeritus
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1554
  • Rating: +475/-97
  • Seizon senryakuuuu!
    • View Profile
    • keff.me
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #12 on: March 21, 2013, 10:46:27 am »
No, Axe only draws once each frame, but four frames for each full "greyscale loop." Of course, that hardly matters in an interrupt.
In-progress: Graviter (...)

Offline Streetwalrus

  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3821
  • Rating: +80/-8
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #13 on: March 21, 2013, 03:12:43 pm »
So it updates the whole screen four times each time I call dispgraphrr ? Anyways I tried to calibrate it and now it looks a lot less blurry when scrolling and less flickery when standing still. ;)

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: [TUTO] How to make "beautiful greyscale" in Axe using interrupts
« Reply #14 on: March 21, 2013, 04:20:44 pm »
How would you go about allowing moving objects on the screen with the interrupt running?  Would you have to somehow sync the refresh rate with the amount of frames? (Sorry if I worded that incorrectly)