Code Monkey home page Code Monkey logo

yocto-8's Introduction

yocto-8

A (WIP) open-source PICO-8 cartridge runner for the Raspberry Pi Pico.

PICO-8 is a fantasy game console from Lexaloffle which allows you to create, edit, share and play small games in a virtual console.
yocto-8 is a PICO-8 implementation that aims to run unmodified games.

That's the plan anyway -- see the current progress.

The main implementation goals are:

  • To reach good PICO-8 compatibility
  • To be as fast as possible, and to minimize the RAM footprint as much as reasonably possible
  • To be generally portable to platforms with a high quality C++20 toolchain

The current plan is not to be a PICO-8 devkit, that is, it will not provide any editor tools.

yocto = pico².

Progress and plans

With some modifications, some demos and games run. We're far from good compatibility, especially on real hardware.

It is possible to build and run yocto-8 on the desktop which is currently the preferred way for implementing new API features due to facilitated debugging and allowing a faster development cycle in general. The main target remains the embedded implementation.

This is currently in an early stage: there is no user-friendly way to get this working yet and most cartridges will not work.

A significant problem is the reliance on a hack that enables mapping of SPI RAM.
At the moment, this hack is very slow and may compromise the usage of the RP2040 for a real handheld project. Many games and demos rely on using way more memory than the RP2040 SRAM could provide no matter how many optimizations are done.
There is a lot of room for optimization for the RAM hack routine. It is currently not known what real world performance can be theoretically reached.

There are (uncertain) plans to design a real handheld. The main two contenders are the RP2040 and the ESP32-S3 (which supports QSPI RAM), but there are drawbacks to both of these.

Limitations

  • This does currently only aim to be a pico-8-compatible game runner, not an editor.
  • There is currently no plan to support games that require the mouse or extra keyboard keys to function.
  • No emulation of "CPU cycles" as calculated by pico-8 is planned for now: Game performance will be limited by how fast the RP2040 can run it. This is usually slower than official pico-8 anyways, but may be faster at some operations, namely draw calls.
  • Yocto-8 uses an external SPI RAM chip to provide more Lua memory when the malloc pool limit is reached (pico-8 allows allocating up to 2MB of Lua memory). As this requires expensive emulation on the RP2040, games that heavily allocate may run significantly slower.

Supported platforms


yocto-8 running Celeste Classic on the PicoSystem.

  • Y8_ARCH=desktop: Desktop (both with a SFML frontend and headless)
  • Y8_ARCH=pico: Raspberry Pi Pico based platforms
    • Y8_PLATFORM=asupico: My setup (Pico+SSD1351 display+8MB PSRAM+push buttons)
    • Y8_PLATFORM=picosystem: Pimoroni PicoSystem

Pros and cons against a SBC-based solution

Pros:

  • ~Instant bootup
  • Some extra appeal: hackable firmware and allowing to support a niche specific-purpose device
  • Usually lower cost
  • It should be possible to drive power draw quite a bit lower

Cons:

  • SBCs-based solutions are more general purpose (e.g. cheap emulation handhelds)
  • SBCs are more versatile (WiFi & Bluetooth, etc)
  • Will probably never be fully compatible with all PICO-8 games
  • No editor tools, etc.
  • More standard hardware

yocto-8's People

Contributors

asumagic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

yocto-8's Issues

RP2040 SPI RAM performance is very poor for most workloads

There are several reasons for this:

  • The page cache is 1-way and keeps no statistics. We could keep statistics about what pages get swapped in/out the most and use n-way caching that could make use of this.
  • The page cache size and mapping could be chosen in a much smarter way. Need to think about how region flushes etc. interacts with this.
  • We could transmit cached pages to RAM in the background using DMA. NOTE: It seems like the CSn behavior is pretty crappy with SPI and I haven't managed to get it to behave properly. Moving to QSPI PIO would allow solving this issue at the same time if we're careful to design it to be DMA-friendly.
  • We use SPI, not QSPI. This would require PIO, need to investigate available resources for this.
  • It is not entirely certain why but page rx doesn't work beyond 25MHz even though we use the supposedly 125MHz compatible command. Using a PCB might make this more bearable.
  • The page size is 1KiB. This reduces the amount of hard faults we encounter but it also means we transfer much more data than good caching would need. However reducing the transfer size causes issues (probably on page tx, as page rx seems fine). It's possible that raising CE soon enough would prevent this from happening. As it is not currently tied to SPI, it is possible that it is just raised too late.

CI/CD pipeline

Automatic builds for all supported platforms & testing on the desktop platform would be a plus, especially as we gain testing support.

Unit tests, integration tests and fuzzing

This would be a huge nice to have by now because:

  • We are reaching the point where accurate emulation matters. Automatically testing edge cases especially for some API drawing functions may be useful, e.g. to optimize code more aggressively while reducing the testing workload.
  • Test-driven development would make sense in some cases while implementing the API. String rendering, RNG, and some other things could benefit from this approach, in particular.
  • We could probably do some nice testing against PICO-8 by injecting a printh of the PICO-8 memory somewhere in update functions. This would allow detecting subtle bugs and differences in the implementation especially if performed automatically.
  • Fuzzing the API to detect differences in parameter count handling or argument type handling may unravel some inaccuracies in the interface implementation.

This raises a few issues:

  • CMake does not support cross-compilation for different architectures within the same build directory. Making two build directories is possible, but this would likely need some tinkering with VSC so that the CMake integration isn't dogcrap to use. If external development is ever opened up this has to be tackled. Ideally only one command should be run to compile for both arches and execute tests, at least as an option. Emulating ARMv6-M with qemu or something is an option but would be complicated to set up, would make instrumentation difficult, and is of limited use since recent bugs that were difficult to debug happened both on the Pico and on the desktop builds.
  • How to even execute tests? We could use CTest from CMake, but how about running the tests themselves? Integration tests might be easier to implement in pure Python, unit tests might be a lot easier to make using Catch or a similar library.

USB interface ideas

Ideally when these ideas mature out a little this issue could be split up into several with a "USB support" tag.

USB mass storage

This would allow for copying games to the flash and to update the firmware. This should preferably allow to reserve some amount of storage for the firmware, should be bricking-resilient to an extent, and not wipe out games and config on flashing.
Maybe this could both take .p8 and .p8.png but perform some sort of preprocessing and compression on the fly which would allow storing probably more than twice as many cartridges.
Also maybe something that would make loading cartridges from BBS easier?

Usage as a desktop PICO-8 monitor/gamepad?

It would be really nice if you could just plug in yocto-8 hardware, open up PICO-8 and have seamless integration: the PICO-8 display would be mirrored on the device and you could use it as a gamepad as well.
This may be a bit complicated to implement, and how would one even do that on Windows without a custom driver?
We don't really want to use an existing display interface since a pico-8 framebuffer is paletted and would be much lighter to send over without compression.

Pluggable mouse and keyboard

This would really be an extra, but if it's possible without too much development workload, why not? AFAIK tinyUSB should have plenty of examples for something like that, and it seems like that in the next minor pico SDK support for this should be better.

External USB storage

I don't think this would be very useful since a few MB of Flash should already hold plenty of cartridges, and this would require at least having a FAT32 driver.

Reducing Lua RAM usage

There is a number of things that could be done to reduce RAM usage, at varying levels of complexity:

  • Pre-compiling the core functions that are declared as Lua.
  • Allowing some strings to live in Flash rather than having to let Lua allocate them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.