So nice to gain AGAIN 1 kb with this update !
Awesome! Amazing work as always!
Just tested this out in Ardu Valley, great stuff!
The procgen i use uses the drawPixel function heavily, so improvements here have smoothed out some parts of the game, which is awesome.
Knew someone would benefit from that. How do you use it exactly? The bad part about the function is it has to calculate the address for every single pixel every time… if you were able to inline the code manualy yourself in a routine that could calculate the address less often (say you were writing a bunch of horizontal pixels in a row, etc) you could get a LOT more speed.
I might have to look into that.
Basically i have a seed value, and i run a horizontal pass over the value, setting a bit on if the bit is 1, and leaving it if 0.
Then, the next row uses the bits of the previous value to determine its bit pattern, and does the same thing.
The process repeats to a set height or when the bit pattern is all 0’s
So yeah, it would be a massively fast operation if bits were horizontal major in the sBuffer, but as it stands they are not.
And yeah, there is for sure some room for improving it, but at the moment i am saving that to fix gameplay stuff.
Yeah you might find it’s more than fast enough without optimization - depending on what exactly you’re doing and how large the area of effect.
Arduboy2 library version 4.0.1 has been released and is available through the Arduino Library Manager.
Thanks go to @Pharap for determining the problem and assisting with the fix.
Arduboy2 library version 4.1.0 has been released and is available through the Arduino Library Manager.
It adds functions for getting the values currently set that control text rendering:
getTextSize(), getTextColor(), getTextBackground() and getTextWrap()
(getCursorX() and getCursorY() were already there previously.)
Nice work on the update, @MLXXXp.
Can I make another request? Where possible, can you make the methods static where possible in the same way that the Sprites library does?
I have been building a sideways scrolling car game where the cars are objects that detected collisions between themselves and render themselves. The rendering I can perform using the static methods of the Sprite class but I have had to incorporate a reference to an Arduboy2 instance to do the collision detection.
In C++, static methods can be invoked directly from an instance of the object so this will (should?) have no impact on people’s existing code but will make it simpler to consume the static methods from classes.
@filmote, Can you give more details or provide an example for how making library functions static would help you?
No problem @MLXXXp - I am only using a handful of methods but others may user more.
In my game, I have a class that represents a car and in the main .ino file I have a collection of cars. Each car instance is responsible for keeping track of its own x and y positions and to move itself based on an algorithm. It does this by holding a reference to the same collection of cars and iterating through them testing for collisions. Finally, it renders itself for display.
In my example, the car only requires the Rect structure and the ‘collide’ function.I have two options: create an instance of Arduboy2 in each car or pass a reference to an existing Arduboy2 library as I construct the cars.
The methods in the Sprite library are predominantly static so I can simply Sprites::drawOverwrite() (or whatever) without having to isntantiate one.
Why can’t you create the usual global instance of the Arduboy2 or Arduboy2Base class at the start of the sketch, like every other sketch does:
#include <Arduboy2.h> Arduboy2 arduboy;
and then call the collide() function of that global instance:
from the functions in your car class?
I am not 100% sure what you mean. Do you mean create a single .ino file with the classes defined within it and then define a ‘global’ variable they can all see? I used to program in a language called RPG III where every single variable was global and there was no such thing as a local … but that was in a language released in 1978.
I am not a gun C++ programmer - and I have a lot to learn - but I have created my classes as separate .h and .cpp files for many reasons not least of all that they are easier to maintain in the IDE in separate tabs. I have a base class which my car, player and obstacles all extend and they are getting quite lengthy and maintainability is becoming an issue. I guess I could do this in a single .ino file but it doesn’t seem right to me.
You can have ‘global’ variables and separate class files but to do this I would need to create a header file specifically for storing this ‘global’ variable so that it can then be visible to my base and sub-classes. Again, this doesn’t seem right to me.
As mentioned earlier, static methods can be invoked directly from an instance of the object so this will not cause any compatibility issues. I am not sure what others think of this suggestion - am I asking for something that has not value to others or is it a relatively simple change that may have benefits?
Then create a global instance of the Arduboy2 (or Arduboy2Base) class in the main .ino file, as normal:
#include <Arduboy2.h> Arduboy2 arduboy;
In any other file (probably a .cpp) needing access to the arduboy instance, put:
#include <Arduboy2.h> extern Arduboy2 arduboy;
I guess I could do that. Long live the global variable !
If all the classes have a common base class you could have a static Arduboy2 arduboy; member in the base that is accessible to all the inherited classes. Then you only need to initialize that one static member.
Yes, that could work. However, you would have to do all Arduboy2 library access from functions within this single class hierarchy, since you shouldn’t create more than one instance of the Arduoby2 class in a sketch so as not to waste memory.
I suppose you could make the arduboy instance public, which means calls to Arduboy2 functions outside of the class hierarchy, could be done like:
16 posts were merged into an existing topic: Arduboy2 library paintScreen() optimisation
Arduboy2 library version 5.0.0 has been released and is available through the Arduino Library Manager.
As usual, one main goal was to make more code space available to sketches.
- Classes BeepPin1 and BeepPin2 added. These can be used to play simple tones on the speaker. They are very code efficient.
- New example sketch BeepDemo demonstrates the use of the BeepPin classes.
- Class SpritesB added as an alternative to Sprites. This class has the same functions as Sprites but will produce less code in many cases (at the expense of slower execution speed). Thanks, @dxb (Delio Brignoli)
- The ability to eliminate the USB code that is normally included in the Arduino environment. This will free up a significant amount of code space but will require the user to do a manual reset in order to upload a new sketch. Thanks, @Dreamer3 (Josh Goebel) for the concept.
- The ability to set a flag in system EEPROM that will bypass the boot logo sequence and go straight to the sketch. New functions writeShowBootLogoFlag() and readShowBootLogoFlag() allow setting and reading this the flag.
- Example sketch SetNameAndID has been renamed to SetSystemEEPROM. The ability to set the “show boot logo” flag has been added to it. It can now also be used to erase the entire system EEPROM or user EEPROM areas.
- A new 2 parameter version of setRGBled() allows setting an individual RGB LED, given the color and brightness.
- New function freeRGBled(). Using setRGBled() will take over the RGB LED pins so that digitalWriteRGB() will no longer work. Calling freeRGBled() will restore the pins for use by digitalWriteRGB().
- New example sketch RGBled demonstrates the use of the RGB LED in both digital and analog modes.
- New function setFrameDuration() can set the frame rate as the time per frame (in milliseconds), as an alternative to using setFrameRate() to set the frame rate in frames per second.
- The loop at the end of the begin() function that waits for all buttons to be released has been replaced by function waitNoButtons(). This is to make it easier to add the functionality back in if boot() is used instead of begin().
Fixed a problem in the Sprites drawPlusMask() function that sometimes caused bitmaps to be drawn improperly. Thanks, @Dreamer3 (Josh Goebel)
The speed that the boot logo scrolls down has been increased, so that the actual sketch code begins faster.
The ArduBreakout example sketch has been modified to use the BeepPin1 class instead of Arduino tone().
Functions that have been refactored to optimize for size and usually speed:
- paintScreen(), which is used by display(), has been re-written in assembler. Thanks, @Mr.Blinky and @veritazz (Michael Gollnick)
- setRGBled() directly controls the hardware, instead of using the Arduino analogWrite() function.
- bootLogoShell() and bootLogoText()
- drawCompressed(). Thanks, @Pharap and @Mr.Blinky
- buttonsState(). Thanks, @Mr.Blinky
- begin() (by using display() instead of blank() to clear the display).
Minor clarifications and corrections to previous README.md and Doxygen documentation, plus:
- Thanks, @eried (Erwin Ried) for correcting a typo in the everyXFrames() example code.
- Added info on sketch EEPROM use to README.md
- Changed characters used for Sprites examples to make them more readable.
Some of the code savings available by using this release:
Just recompiling an existing sketch using this new release will reduce code size. Based on testing, typical savings will be about 150 bytes, compared to version 4.1.0, but it could be more or less depending on library functions that the sketch uses.
If a sketch uses more than one of the Sprites class functions, switching to SpritesB will save about 360 bytes, as long as the slower rendering speed of SpritesB is acceptable.
Sketches that currently use the setRGBled() function will see a significant reduction in code size, on the order of hundreds of bytes.
Removing the USB code will save about 2700 bytes or more but you should carefully consider if you need to do this, due to the inconvenience and possible frustration it can cause users because of the requirement to manually reset the Arduboy in order to upload a new sketch. Also, it’s recommended that some of the code freed up be used to add a menu item or prompt that allows the user to perform a reset using the DOWN button (by calling the new exitToBootloader() function).
Arduboy2 library update?
Guinea Pigs Wanted!