[Suggestion]Future of PokittoLib - v2.0

Is there any reason why we don’t simply deprecate interrupt-based button handling? All games do polling in the end anyway (if( button pressed ) ...) and reading from GPIO takes up just as many cycles as reading a variable in RAM.


How about inverting the architecture: reduce the Core into a minimal HAL+Loader, with no public API (games wouldn’t even know it exists). Interface libraries (Mode*.h, Arduboy2.h, Gamebuino.h) would build on that to provide the wanted API without having to worry about simulator/hardware differences and we wouldn’t depend on defines so much. The core could be in C/C++98 and the libraries could provide C++11 if they want to, so mbed would still work to some degree. This would also make it simpler to port games from other systems (simple Arduboy games could just #include "Arduboy2.h" and work, provided the ino files are valid C++).

1 Like

You may be interested in this thread.
Particularly from about here onwards.

Essentially some people are of the opinion that it’s important for games with low (~10-15fps) framerates.

Personally I’m fine with either, but I err more on the side of polling.
I think most of my games (when I get round to actually making some) will be snapshotting the button state at the start of my update loop.


At the moment I’m just trying to divide everything up into logical units and trying to understand it all before I go trying to design anything too elaborate.
(The existing Core is a bit of a god object.)

I definitely think having screen modes as separate interfaces is a good idea and having some kind of adaptor for Arduboy2 and Gamebuino.

I’m half and half about the core being C++98/03.
The ideal would be to have a C++11 compiler that works on all platforms, and I’m pretty sure it’s possible to get Visual Studio and/or Code::Blocks doing that.
But I suspect some people would want to keep mbed online as an option.

The problem with using 98/03 for the core isn’t just that it’s 15-20 years out of date, but also that C++11 introduced so many new features and semantics that it would end up seriously limiting the flexibility of the design compared to what it could be with C++11 support. (I refer to my earlier list of C++11 improvements.)

I’m betting that’s not many of them.
Lack of function predeclaraion probably kills at least 55-75% of .inos.

If someone can get the Platformio compilation working, we have half the problems solved

You’d be willing to sacrifice the hardware debugging aspect due to the cost issues?

(Though I suspect we could get hardware debugging working on another system.)

No, we could abandon the mbed online compiler

You could still debug in any GCC offline compiler

I am in favour of abandoning mbed online (at least until their clock hits 2011).

I think most people here own a Github account anyway, so hosting code wouldn’t be an issue.

@dreamer was working on getting PlatformIO working a while back,
but it’s unclear if they managed it.

We have @FManga’s makefile as a base to work with,
we just need someone who can adapt it to work.

I’ve added a library to PlatformIO before, that much is easy, but setting up a compilation target will be more difficult.

A very minimalistic Core shouldn’t be hampered by C++98… but ditching mbed changes things completely.

Platformio works with makefiles? Or does “adapt it to work” actually mean rewrite it for some other build system? :stuck_out_tongue:

13 posts were merged into an existing topic: Using PlatformIO for compilation

The other day I sat down and thought about the buttons API and I’ve come up with a few ideas for improving it.

Firstly, I think it would be good to scrap all the aBtn()/aHeld()/aReleased() functions.
There’s a lot of them and I honestly think they muddy the waters and confuse the API rather than being useful.
(If they are still needed they could be included on a different class that acts as an adaptor.)

For the main API, I have two suggestions that differ mainly in wording.

Option 1:

class Buttons
{
public:
	// Manually called to update the button state.
	// Typically called once per frame/once per logic update.
	void update(void);
	
	// True if the button has just been pressed
	// (i.e. true for one update only)
	bool isPressed(Button button);
	
	// True if the button has just been released
	// (i.e. true for one update only)
	bool isReleased(Button button);
	
	// True if the button is currently pressed.
	// (i.e. true for multiple updates)
	bool isHeld(Button button);
	
	// True if the button is currently released.
	// (i.e. true for multiple updates)
	// Equivalent to !isHeld(button)
	bool isNotHeld(Button button);
};

Option2:

class Buttons
{
public:
	// Manually called to update the button state.
	// Typically called once per frame/once per logic update.
	void update(void);
	
	// True if the button is currently pressed.
	// (i.e. true for multiple updates)
	bool isPressed(Button button);
	
	// True if the button is currently released.
	// (i.e. true for multiple updates)
	// Equivalent to !isPressed(button)
	bool isReleased(Button button);
	
	// True if the button has just been pressed
	// (i.e. true for one update only)
	bool justPressed(Button button);
	
	// True if the button has just been released
	// (i.e. true for one update only)
	bool justReleased(Button button);
};

The timing aspect would still exist, but I think it should be an optional extra because most games can function on the minimal API.
I’m not sure if the timed API should be an adaptor class or a part of the main buttons class that can be enabled, but I’ll present it as an adaptor for now.

class ButtonTiming
{
public:
		
	// True if the button is has been held for the given number of updates.
	// Is true once and won't be true again until the button is released.
	bool isHeldOnce(Button button, uint16_t numberOfUpdates);
		
	// True if the button is has been held for the given number of updates.
	// Can be true multiple times until the button is released.
	bool isHeldRepeat(Button button, uint16_t numberOfUpdates);
	
	// Returns the number of updates that the button has been held for.
	uint16_t updatesHeld(Button button);
};

It may also be possible to develop an API that uses actual time instead of the number of updates.
I chose to use the terminology ‘number of updates’ rather than ‘number of frames’ because it’s entirely possible that update might be called more than once per frame.


As an extra thing, it might be a good idea to provide a pure virtual button class based on these interfaces with a concrete implementation handling the buttons.

Then if people want to attempt multiplayer games (e.g. through use of a bluetooth/wifi/serial hat) they could create an alternate implementation that would have the wired/wireless multiplayer link as its back-end.

This would allow the programmer to program their game objects to respond to a single interface but automatically allow them to respond to both real button presses and to input from a wired/wireless link.
Liskov substitution in action.

This might be better to have in a different library though, if the main library’s aim is to be kept small and simple.

1 Like

Here’s an untested draft of a simplified Buttons API:

Very much an early draft still, hence the lack of the timed functionality and currently no way to select the polling version rather than the interrupt version.

1 Like

@FManga :

Your checksum trick did not work in EmBitz:

c:/program files (x86)/embitz/1.11/share/em_armgcc/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld.exe:Pokitto/mbed-pokitto/targets/cmsis/TARGET_NXP/TARGET_LPC11U6X/TOOLCHAIN_GCC_ARM/TARGET_LPC11U68/LPC11U68.ld:238: syntax error

I had to revert that back to normal, as I do not have time to investigate

Yeah, I saw the PR. Looks like the embitz version of ld doesn’t like comments (// The reset handler).
Should I remove them and send another PR?
I don’t have embitz here, so I can’t test :stuck_out_tongue:

1 Like

Yes please !! (Do you ever sleep in Brazil?)

2 Likes

The PSP has a folder for saved data and a folder for games. Each game has its own folder inside of each. Applying that to this, maybe the saved data folder is public, but game folders are private? The author of the game can have it save to either the game folder or to the public savedata area.

I’ll make a note to look into it.

Having a separate shared folder and private folder per game sort of makes sense.

If we went with that though, I think it would make sense to store metadata about a game in the shared folder and make it so both the shared and private folders are only writable by the game that owns them, but the shared folder for each game is visible to all games.

That would mean the shared folder could function as a way of signalling the presence of a game so people can do cool tricks like adding special ‘DLC’ if you’ve played both games.
(Like how TF2 gives you cool hats if you preorder other games.)

I attempted to get the PokittoLib compiling in Code::Blocks today.

Via manual editing I managed to get within 50 errors of compiling.
Via @fmanga’s makefile I got “recipe for target all failed”.

It’s a start I guess.

The ARM hardware target you mean ?

Yep, trying to compile the actual ARM-targetting code through Code Blocks using the same compiler EmBitz uses.

Down to just one error: “unrecognized command lin option ‘-mwindows’”.

Never mind, solved that one.

1 Like