Author Topic: z80 8-level greyscale shenanigans  (Read 4453 times)

0 Members and 1 Guest are viewing this topic.

Offline miotatsu

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 332
  • Rating: +11/-1
    • View Profile
z80 8-level greyscale shenanigans
« on: November 30, 2010, 01:29:48 am »
I am wondering if there are any tutorials on 8-level greyscale/if someone could explain to me basically how its done.
I would like to write my own greyscale routine but I was sad to see there was not much info about it online... :<

Offline FloppusMaximus

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 290
  • Rating: +57/-5
    • View Profile
Re: z80 8-level greyscale shenanigans
« Reply #1 on: November 30, 2010, 09:16:38 pm »
Are you asking about 8-level grayscale specifically, or grayscale in general?  Using 8 levels isn't intrinsically any different from 4 levels; it's just that with smaller differences between the levels, any flickering becomes more noticeable.

In general, to display grayscale, you turn pixels on and off very rapidly, and rely on the eye to "average" things out.  A pixel that's turned on continuously looks darker than one that's only turned on 67% of the time, which looks darker than one that's turned on 33% of the time.

The most common way of doing this is to have two (or more) separate screen buffers with different "weights".  So for 4 levels you'd have two buffers, where buffer B is displayed twice as often as buffer A (which is to say, buffer B is displayed 67% of the time, and buffer A 33% of the time.)  For 8 levels, you'd add a third buffer, C, that's displayed twice as often as buffer B (so, buffer C is displayed 57% of the time, B 29% of the time, and A 14% of the time.)

It tends to look better if adjacent pixels don't change at the same time; to avoid that, you can stagger the updates, so instead of displaying one entire buffer at once, 57% of the pixels are being displayed from buffer C, 29% from buffer B, and 14% from buffer A; and you're rotating these sets with each update.

For minimal flickering, you want to synchronize your updates with the LCD driver's refresh rate.  This is rather difficult to do.  Some clever folks (not me) have mostly solved this problem for the 83+ SE and 84+, using the programmable timers.  On the 83+ BE, I don't think it's really possible without carefully tuning your entire program.

I could go on, but which of these subjects in particular are you curious about?

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: z80 8-level greyscale shenanigans
« Reply #2 on: December 01, 2010, 04:47:00 am »
With 4 level grayscale, scanlines are generated (some sort of interlacing) to make your eyes notice the flicker effect less. In 8 level grayscale it's used as well, as shown in Calc84maniac's Chips Challenge clone and in 3 level, it's just a checkered pattern that rapidly alternates.

I think he got 4 level grayscale tutorials, but he wants to know how 8 level works. I'M not sure, though.

Offline miotatsu

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 332
  • Rating: +11/-1
    • View Profile
Re: z80 8-level greyscale shenanigans
« Reply #3 on: December 01, 2010, 05:28:12 pm »
oh I see, that answered a lot of my questions. I would like to know more about staggering the updates then, like if adjacent pixels should not be updated at the same time, how would you go about updating some from each buffer in such a way that adjacent ones do not end up getting updated? also I will probably need help with timing stuff when I get that far.

ASHBAD_ALVIN

  • Guest
Re: z80 8-level greyscale shenanigans
« Reply #4 on: December 01, 2010, 05:31:47 pm »
what you can do and go about and AND the scanline to the buffers.

i.e. AND A,%11011011 is part of the scanline for darkgrey in 4 level grayscale.

Offline miotatsu

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 332
  • Rating: +11/-1
    • View Profile
Re: z80 8-level greyscale shenanigans
« Reply #5 on: December 02, 2010, 05:48:21 pm »
eh I am still very confused, I will probably take a look at some code and see if I can understand it better that way

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: z80 8-level greyscale shenanigans
« Reply #6 on: December 03, 2010, 12:53:37 am »
You could ask Calc84maniac for Chips Challenge 83+ source.

Offline FloppusMaximus

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 290
  • Rating: +57/-5
    • View Profile
Re: z80 8-level greyscale shenanigans
« Reply #7 on: December 04, 2010, 06:21:31 pm »
oh I see, that answered a lot of my questions. I would like to know more about staggering the updates then, like if adjacent pixels should not be updated at the same time, how would you go about updating some from each buffer in such a way that adjacent ones do not end up getting updated? also I will probably need help with timing stuff when I get that far.
First of all, to do this you're going to need to write your own routine to copy the screen buffer(s) to the display.  (To get good performance, the routine will need to be seriously optimized, which is a huge topic unto itself.)  Normally, a routine like that would just read the bytes from one buffer, in order, and write them to the LCD driver.  Instead, what you want to do is alternate between the buffers somehow.  You can do this on a byte-by-byte basis (say, read one byte from buffer A, one from C, one from B, two from C, one from B, and one from C, and repeat.)  Or you can do it on a bit-by-bit basis, so each 8x7-pixel block contains pixels from all 3 buffers, arranged like this:
Code: [Select]
ACBCCBCA
CBCCBCAC
BCCBCACB
CCBCACBC
CBCACBCC
BCACBCCB
CACBCCBC
(note that this is just one possible arrangement - you can design your own.)  If you rotate this pattern by one bit (or one row) each time the screen updates, you'll see that in 7 updates, each pixel is set to its 'A' value once, its 'B' value twice, and its 'C' value four times.

So, for instance, for the first line above, if your 3 buffers contain the byte values xA, xB, and xC, the value you want to display is (xA AND 81h) + (xB AND 24h) + (xC AND 5Ah).  I'm not sure what the fastest way would be to compute this; it might help if you used the buffers to store bitwise differences (XORs) between the bit planes, instead of the "actual" xA, xB, and xC values.

You'd probably find this easier if you tried writing a 4-level version first.

You could ask Calc84maniac for Chips Challenge 83+ source.
Seconding this.

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: z80 8-level greyscale shenanigans
« Reply #8 on: December 06, 2010, 04:06:20 pm »
Or you could ask thepenguin77.

Here's the source. You would be most interested in the grayCopy: section at the bottom.

Edit:
   Here's a sample pic so that you can see it in action in a debugger.
« Last Edit: December 06, 2010, 04:09:08 pm by thepenguin77 »
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 DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: z80 8-level greyscale shenanigans
« Reply #9 on: December 06, 2010, 04:33:16 pm »
Oh right I forgot you made the 16 level grayscale routines. I didn't knew you made 8 level ones too, though. ;D