[CPP] API and Extensions

Playdate CPP Extensions library

As promised a few months ago while resurrecting the old PlaydateCPP project, I'm happy to introduce the Playdate CPP Extensions library.

View the PlaydateCPP Extensions library on GitHub here

The goal of this project is to take the initial PlaydateCPP project a step further by:

  • replicating the C API in C++ so that you can work with honest-to-goodness RAII-compliant, C++ objects and patterns.
  • providing a codebase of classes to streamline the development of games and Lua extensions.

This is all standing on the shoulders of the boilerplate PlaydateCPP project that enables this goofy dream to begin with so please start over there:

There's a README.md that goes over the basics of building it into your project, TL;DR it's all CMake, so if you're building with PlaydateCPP already, building the extensions lib is just one more submodule and one more line of code in your CMakeLIsts.txt file.

CPPong

There's a version of Pong in the repo to help demonstrate how one can reasonably create a full game using the extensions.

Obviously a game as simple as Pong cannot cover everything you can imagine, but it does touch on more than one might immediately expect, highlighting the basics of how to handle user control, graphics, and sound. Expect the range of examples to expand in the future to cover more of the codebase.

Contribute!

I'm heavily invested in this library so it's going to get updates and bug fixes regularly, take a dependency with confidence. That said, if left to my own devices, the updates are going to generally follow my own needs, so this project will need contributors.

If there's something that you've developed that you think others would find useful, or if there's a bug that needs to be fixed, please DM me and/or file a PR. Read more here.

What happens if/when Panic releases a C++ API?

There have been rumblings for some time that Panic has interest in doing this.

The guidance will always be to use their version of any object which overlaps with functionality from this library, and whatever is in this library will be deprecated. Anything that doesn't overlap will live on, and will be refactored to use Panic's APIs under the hood if necessary.
2 Likes

i already used playdate-cpp as a module in a fork of the arduboy collection to make it compile again see GitHub - joyrider3774/playdate-arduboy at SDK_2.XX_SUPPORT . Also before this was working again and when i ported my older games to playdate i converted c++ (classes mostly) to C using struct constructs and function pointers, but now that playdate cpp is there and working for rev b units for my next port i'm not going todo this anymore and i'm actually using c++ code i initally had along with playdate-cpp. It saves me a lot of time and tedious editing code from converting c++ code to c and makes the projects remain more readable / editable as well

So for me as a user of library / repo it works great, but i can not contribute any code related to the project iself as well i just have no clue about this all to get this working and c++ specifics but i am a happy enduser of your project

1 Like

v0.2.0 Release Notes

Tons of major updates in this version! It's normally going to be my goal to have smaller, more frequent releases, but this one was pretty unavoidable since the additions here are fairly foundational. Let's get into the details:

UI Tools Updates

Components

Components are UI objects that A: don't draw themselves, and B: have a child hierarchy from which larger widgets and functionality can be composed. Use them with Sprites to manage when they're re-drawn based on system updates. Sprites are still great, and I'd really like to find ways to bring the features of Components and Sprites closer together in future, so keep an eye out for that.

Key New Components

  • Viewport -- puts a visible window over another "content" component, and allows scrolling the content on either axis. This is the basis for many new components such as...
  • ComponentFocusView -- Add child Components to the focus container, and then use the API to automatically bring child components into the visible window of the Viewport
  • GridView -- Sets up a grid of components, allows for scrolling and selecting. Not quite as feature-complete as the class in the Lua API yet, but that's the goal.

Graphics

v.0.1.0 deliberately over-looked this part of the C API, but over the last two months of development on various components have made it clear a C++ API would be preferable. This allows us to add new features not in the C API such as drawing rectangles with rounded corners, or drawing a polygon out of line segments.

Templated Rectangle and Point objects

in v0.1.0, everything would be done with PDRects and the pdcpp::RectHelpers class to do common actions like find overlaps, or getting the position of various corners, centers, etc. By moving all of these tools into the Rectangle<T> and Point<T> classes, the number #includes and over-all lines of code needed are fewer, the code is more semantic with C++, and ultimately things are a lot clearer.

User Input Tools Updates

Three additions here:

CrankManager

Does what it says on the tin. Put one in your application, add some listeners, or set the callback, and call checkStateAndNotify in the update loop. Any time the user moves the crank, the listeners will be notified. There's also now another way:

InputContext and InputContextManager

We often need to change what happens when users press buttons or turn the crank based on something they've done in the application. Using the "listener" model means you have to dynamically add and remove listeners or replace callbacks to change these contexts, and things can get messy.

Now you can break your input management logic into various InputContexts, and push/pop them of a stack using an InputContextManager. This also will allow you to react to when the context changes and how. Use them for menus, modal text boxes, etc.

KeyRepeatTimer

Basically just trying to replicate what the Lua API is doing here in a C++ style way.

Audio/Synthesis updates

There were some holes in coverage of the C API here, and then a few things that weren't supported natively that now are:

Custom Generators for SynthesizerVoices

The C API supported it, the C++ API did not. Now we do.

Modulation Mixing

Audio-rate signals can be mixed using Channels and 0-delay DelayTaps, but, as far as I could tell, there wasn't any way to natively mix modulation-rate signals. The C++ API now supports this using ModulationChannel objects, so you can use both an Envelope and an LFO to modulate that synth voice parameter by first adding both to a ModulationChannel, and then using the channel itself as a signal for modulation.

Bug Fixes

  • Font::drawWrappedText actually works
  • mkdir and rename were missing from the File API, and now work.
  • calling std::move on a Sprite could cause the pointer the C API had registered as the userdata pointer for a C++ object to go out of sync with the this pointer of the actual object, resulting in odd crashes. This is fixed.

Deprecations

RectHelpers is now deprecated in favor of Rectangle, and will be removed in future versions.

3 Likes

v0.3.0 Release Notes

New Features:

UI Elements:

  • Adding a TextKeyboard like the one the Lua API has
  • Adding a FileList component to help with file management

UI Features:

  • GridView now has independently sizeable columns and rows!
  • Fonts can now draw wrapped within bounds and with left/center/right justification
  • You can now get access to the underlying bitmap data of an Image
  • Sliders now have different draw styles.
  • Sliders now cache their images to improve drawing performance when the slider isn't being moved.

General:

  • Moving around FileStat functions to the FileHelper to assist with the FileList component
  • SystemMenu items now take callback functions as parameters instead of forcing the user to use inheritance. Write less code!

Bug Fixes:

  • Fixing some off-by-ones which would result in missing words in wrapped font drawing
  • Taking on updates from the boilerplate repo involving linkages in CMake
  • Certain methods in Point<T> now return the right types if the point isn't a float type.
  • Component LookAndFeel settings now cascade to component children as intended, including ComponentFocusView members.
  • Fixing memcpy compilation issues for hardware in File
  • Rectangle objects now will not invert themselves if an operation is taken that sets the height or width to 0: No more startup crashes using ScopedGraphics!
  • Not really a "bug fix": removing some workarounds to bugs that were in the Playdate C API surrounding note on/off timing.
1 Like

v0.3.1 Release

Bug fixes:

  • Support for 2.4.0! The addition of userdata for custom sound sources was a breaking change for this library, but it's also a feature that has had a comment in the code for a while saying "TODO: ask panic to add userdata" so I'm truly thrilled by this change.
  • drawing wrapped fonts now honors user's \n characters.
  • drawing wrapped fonts with center justification had an issue where calculation and word wrapping included extra whitespace, leading to awkward, incorrect offsets.

General changes:

  • getBitmapData is now const. The data pointers aren't though so... be careful I guess?
  • LookAndFeel::getDefaultFont is now const as it always should have been.

May I offer you a nice feature in this trying time?

Yes, this is not how versioning is supposed to work. I'm going to hide behind the idea that you could probably call each of these call bug fixes, (if you screwed up your eyes in the right way,) to evade criticism for being too lazy to go cherry pick the actual bug-fixes out of the v0.4.0 dev branch.

  • Refactored the graduated crank-calculation code out of the keyboard so it could be used elsewhere
  • adding withWidth/Height methods to Rectangle because they should have been there already
  • Slider has a new drawing type with Numeric if you just want to see the number of the slider
1 Like