Skip to content

Instantly share code, notes, and snippets.


James jaames

View GitHub Profile
jaames / crc32.lua
Last active Sep 17, 2022
crc32 function for playdate lua. only works on strings.
View crc32.lua
local CRC32_LUT = nil
local function crc32_init()
if not CRC32_LUT then
CRC32_LUT = table.create(255, 0)
local rem
for i = 0, 255 do
rem = i
for j = 1, 8 do
if (rem & 1 == 1) then
jaames / playdate-prism-highlight.js
Created Aug 5, 2022
Prism.js syntax highlighting settings for Playdate-flavour Lua
View playdate-prism-highlight.js
Prism.languages.lua = {
'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,
// \z may be used to skip the following space
'string': {
pattern: /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,
greedy: true
'number': /\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,
'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,
'function': /(?!\d)\w+(?=\s*(?:[({]))/,
jaames / PdvParser.ts
Last active Jul 6, 2022
Basic Playdate .PDV video format parser in Typescript (doesn't handle frame type 3 yet)
View PdvParser.ts
import { unzlibSync } from 'fflate';
function assert(condition: boolean, errMsg: string = 'Assert failed'): asserts condition {
if (!condition) {
throw new Error(errMsg);
function readChars(data: DataView, ptr: number, size?: number) {
jaames /
Created May 23, 2022
Playdate Season 1 game bundle IDs. Enjoy :)
jaames /
Last active Aug 30, 2022
James' Playdate performance tips

General tips

  • For repeated expensive drawing options, such as drawing a rotated sprite or a large amount of text, it's a good idea to cache the result to an image once and draw that repeatedly instead.
  • Audio formats in order of decode speed, fastest to slowest: 16-bit pcm wav, 8-bit pcm wav, adpcm, mp3.
  • The Playdate's audio sample rate is 44100, but if you're experiencing lag when playing audio at that rate, you can try halving the rate to 22050.

C tips

  • The Playdate has a weak CPU but a comparatively generous amount of memory. Favour memory-based optimisation techniques, such as lookup tables.
  • Where possible, move branch statements outside of loops, even if it means duplicating the code for the loop. (probably applies to Lua too?)
  • If you need to parse a binary file, use playdate->file->seek to jump to the parts you need and playdate->file->read to only read the data you want. Try to avoid memcpy-ing the whole file to memory in one go.
  • If you're blitting to the frame buffer and need to ap
jaames / playdate-curve.lua
Last active Jun 10, 2022
Simple bezier curve drawing functions for the Playdate Lua SDK
View playdate-curve.lua
-- bezier curve drawing functions for playdate lua
-- these are based on de Casteljau's algorithm
-- this site has a nice interactive demo to compare both types of curve:
-- draws a curve starting at x1,y1, ending at x3,y3, with x2,y2 being a control point that "pulls" the curve towards it
-- steps is the number of line segments to use, lower is better for performance, higher makes your curve look smoother
-- the playdate is kinda slow, so it's recommended to find a relatively low step number that looks passable enough!
function drawQuadraticBezier(x1, y1, x2, y2, x3, y3, steps)
steps = steps or 8
local d = 1 / steps
jaames / playdate_adpcm.c
Last active Apr 2, 2022
Example for decoding and playing an ADPCM audio buffer on the Playdate in C, only supports mono IMA-ADPCM with no blocks!
View playdate_adpcm.c
// adpcm.h
#define CLAMP(n, l, h) \
if (n < l) n = l; \
if (n > h) n = h;
#define min(a,b) (((a) < (b)) ? (a) : (b))
static const int8_t indexTable[8] =
{ -1, -1, -1, -1, 2, 4, 6, 8 };
jaames / pd_bitmap_notes.c
Created Mar 8, 2022
playdate->graphics->getBitmapData pixel format notes
View pd_bitmap_notes.c
int width = 0;
int height = 0;
int stride = 0;
int hasMask = 0;
u8* bitmapBuffer;
pd->graphics->getBitmapData(bitmap, &width, &height, &stride, &hasMask, &bitmapBuffer);
// bitmap data is comprised of two maps for each channel, one after the other
int mapSize = height * stride;
jaames / astro.config.mjs
Created Jan 3, 2022
Injecting global SCSS variables in Astro (, using additionalData and a path alias
View astro.config.mjs
import { fileURLToPath } from 'url';
import path, { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export default {
// all the usual config goes here...
jaames / main.c
Last active Mar 16, 2022
Playdate C memory management functions (and extras!) as macros
View main.c
// usage example in your C entry file...
#include "pd_api.h"
#include "platform.h"
PlaydateAPI *pd = NULL;
int eventHandler(PlaydateAPI *playdate, PDSystemEvent event, uint32_t arg)
if (event == kEventInitLua) {