Libraries, utilities, bootloaders...
Post a reply

Re: Display functions optimization

Thu Jan 15, 2015 7:47 am

Myndale wrote:82ns :D


Under 100 ns. Fantastic, I knew you could do it !

Image

Re: Display functions optimization

Thu Jan 15, 2015 8:11 am

Myndale wrote:82ns :D


Wow, that's awesome, there are so many possibilities...

I'm filled with emotion.gif
I'm filled with emotion.gif (499.9 KiB) Viewed 5819 times

Re: Display functions optimization

Thu Jan 15, 2015 9:46 am

Lol, thx guys :) I did have a quick play with pre-compiled sprites just to see what kind of results I'd get, first-pass got down to around 40ms unaligned for that particular sprite. Pity they're not much use in a generic library.

I do plan to revisit this thread once the basic tracker is up and running.

Re: Display functions optimization

Thu Jan 15, 2015 12:00 pm

Now aim for 20ns! You can do it!

Re: Display functions optimization

Thu Jan 15, 2015 7:48 pm

82ms.... Alright, let's put that in perspective.... MILLISECONDS.... with that sort of drawing time, you could mimic the four-shade effect of a Gameboy screen....

Re: Display functions optimization

Fri Jan 16, 2015 12:49 pm

I'm pretty sure that's NANOSECONDS (Say, for example, 80 ns would be 80/1,000,000,000 of a second, or 80 billionths of a second).
But still, great job guys. :mrgreen:

Re: Display functions optimization

Fri Jan 16, 2015 6:07 pm

I think he meant that 82ns (even if he mispelled is "ms") is pretty small compared to the milliseconds a frame lasts (50ms when the game runs at 20 frames per second). The high update rate of the screen would then allow 4 shades of gray (by alternating between black and white frames at high speed at different duty cycle to get different shades), just like the original Game Boy.

Re: Display functions optimization

Fri Jan 16, 2015 7:00 pm

I guess there will have to be some asm for shades to pop up?
Also a better understatement of the screen hardware itself?

Heck, this is beautiful, if 82 is possible in C/C++ then asm could make it 1 or less?
Nice thread here!

Re: Display functions optimization

Fri Jan 16, 2015 9:00 pm

Doesn't matter how fast you draw, it won't improve grey scale capability beyond what we've already achieved. When you send data to the LCD it doesn't change the pixels instantaneously, it instead stores the values in its internal DDRAM while a separate multiplex driver continually streams this memory to the actual display:

pcd8544.png
pcd8544.png (26.21 KiB) Viewed 5764 times


As far as I'm aware the only way to change the mux rate of the driver is to feed it an external clock, which in the case of Gamebuino isn't possible as that pin is tied high:

lcd.png
lcd.png (11.88 KiB) Viewed 5764 times

Re: Display functions optimization

Sun Jan 18, 2015 7:00 pm

With all these posts about drawBitmap optimization, I was thinking that as there is going to be big changes, we could re-think the way bitmaps are stored. I suggest the following changes, don't hesitate if you have any critics. If you agree that it would be a valuable update, I'll implement all that soon.

Now, bitmaps are stored in a mono dimensional array of byte in PROGMEM. Instead, we could use a Bitmap class that would store a pointer to the bitmaps data. We could use indexed color index to embed all the colors in one bitmap. We could also store several frames in one bitmaps (for animated bitmaps or tilemaps).
Here is a quick snippet to explain the idea :

Code:
class Bitmap{
public :
  uint8_t width;
  uint8_t height;
  uint8_t numColors; //number of indexed colors
  static uint8_t colorIndex[] = [WHITE, BLACK, GRAY, TRANSPARENT, INVERT];
                       //the colors are constants respectively equal to 0 1 2 3 4
                       //gray will be automatically filled by an alternating checkers pattern by gb.display.drawBitmap()
  uint8_t frames; //number of frames stored. Can be used for animated bitmaps or tilemaps
  uint8_t compression; //0 for raw bitmap, 1 for RLE, 2 for nokia swizzled...
  uint8_t location; //either 0 for PROGMEM or 1 for RAM (why not SD card support later on)
  const uint8_t *bitmap; //a pointer to the bitmap data array.
                        //Contains all the different colors, and one or several frames one after the other
                        //the duration of each frame is store right before the pixels data

  void loadPROGMEM(const uint8_t *bmp){
    location = 0; //bitmap located in progmem
    width = pgm_read_byte(bmp);
    height = pgm_read_byte(bmp + 1);
    colors = pgm_read_byte(bmp + 2);
    frames = pgm_read_byte(bmp + 3);
    compression = pgm_read_byte(bmp + 4);
    bitmap = bmp + 5;
  }

  void loadRAM(const uint8_t *bmp){
    location = 1; //bitmap located in RAM
    width = bmp[0];
    height = bmp[1];
    colors = bmp[2];
    frames = bmp[3];
    compression = bmp[4];
    bitmap = bmp + 5;
  }
};


The library function gb.display.drawBitmap() would then select the right algorithm to display the bitmap depending on the encoding, number of colors, etc.

It might also be interesting to add the continuous rotation (as in taxi fou) and scaling (as in the isle of maniax) of bitmaps to the library.
Instead of passing many arguments to gb.display.drawBitmap each times for the rotation, flipping, etc I could add the function gb.dislay.setBitmapRoation, gb.display.setBitmapScaling, etc. This will make the code more readable.

Another class that would be interesting to add to the library is an AnimatedBitmap class, for animated bitmaps to be played automatically and individually each time drawBitmap is called.

Code:
class AnimatedBitmap{
  Bitmap *bitmap;
  int8_t currentFrame; //-1 when not playing
  uint8_t looping; //0 no looping, 1 normal looping, 2 back and forth loopming, 3 stay on the last frame, etc.
}


I think it's better to separate the AnimatedBitmap class for the Bitmap class to limit the RAM footprint. For example, if you have 10 monsters, you will store only 1 Bitmap object (containing width, height and all), and 10 AnimatedBitmap objects (only containing the current state of the animation and a pointer to the Bitmap object).

These changes will break compatibility, but I will use preprocessor instructions to be able to compile games made using previous versions in "compatibility mode". This will be a setting available in libraries/Gamebuino/settings.c

That's some pretty big changes but I think it's worth it. What do you think ?
Post a reply