Skip to content

Instantly share code, notes, and snippets.

@DanB91
Last active November 28, 2022 04:57
Show Gist options
  • Select an option

  • Save DanB91/4236e82025bb21f2a0d7d72482e391d8 to your computer and use it in GitHub Desktop.

Select an option

Save DanB91/4236e82025bb21f2a0d7d72482e391d8 to your computer and use it in GitHub Desktop.
Playdate Zig starting point
This is a small snippet of some code to get you started for developing for the Playdate on Zig. This code should be used as a starting point and may not compile without some massaging. This code has only been tested out on macOS and some modifications ar
const std = @import("std");
/////////////////
///This has only been tested on macOS, and you will need to modify when
///
///Depends on link_map.ld found in the Playdate SDK
///
///The following programs need to be in your $PATH
///- pdc
///- objcopy
///
///
//////////////
pub fn build(b: *std.build.Builder) !void {
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const lib = b.addSharedLibrary("pdex", "src/main.zig", .unversioned);
const output_path = try std.fs.path.join(b.allocator, &.{ b.install_path, "Source" });
lib.setOutputDir(output_path);
lib.setBuildMode(mode);
lib.install();
const game_elf = b.addExecutable("pdex.elf", "src/playdate_hardware_main.zig");
game_elf.step.dependOn(&lib.step);
game_elf.link_function_sections = true;
game_elf.stack_size = 61800;
game_elf.setLinkerScriptPath(.{ .path = "link_map.ld" });
game_elf.setOutputDir(b.install_path);
game_elf.setBuildMode(mode);
game_elf.setTarget(try std.zig.CrossTarget.parse(.{
.arch_os_abi = "thumb-freestanding-eabihf",
.cpu_features = "cortex_m7+fp_armv8d16sp",
}));
if (b.is_release) {
game_elf.omit_frame_pointer = true;
}
game_elf.install();
const pdc_step = b.addSystemCommand(&.{ "bash", "-c", "mv zig-out/Source/libpdex.dylib zig-out/Source/pdex.dylib && objcopy -O binary zig-out/pdex.elf zig-out/Source/pdex.bin && pdc --skip-unknown zig-out/Source zig-out/zig_game.pdx " });
pdc_step.step.dependOn(&game_elf.step);
b.getInstallStep().dependOn(&pdc_step.step);
const run_cmd = b.addSystemCommand(&.{ "open", "zig-out/zig_game.pdx" });
run_cmd.step.dependOn(&pdc_step.step);
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
pub export fn eventHandler(playdate: *pdapi.PlaydateAPI, event: pdapi.PDSystemEvent, arg: u32) c_int {
///game code starts here...
}
const std = @import("std");
pub const SCREEN_WIDTH = 400;
pub const SCREEN_HEIGHT = 240;
pub const Pixel = i32;
pub const PlaydateAPI = extern struct {
system: *const PlaydateSys,
file: *anyopaque,
graphics: *const PlaydateGraphics,
sprite: *anyopaque,
display: *const PlaydateDisplay,
sound: *anyopaque,
lua: *anyopaque,
json: *anyopaque,
scoreboards: *anyopaque,
};
pub const PDSystemEvent = enum(c_int) {
EventInit,
EventInitLua,
EventLock,
EventUnlock,
EventPause,
EventResume,
EventTerminate,
EventKeyPressed, // arg is keycode
EventKeyReleased,
EventLowPower,
};
pub const PDLanguage = enum(c_int) {
PDLanguageEnglish,
PDLanguageJapanese,
PDLanguageUnknown,
};
pub const PDPeripherals = enum(c_int) {
None = 0,
Accelerometer = (1 << 0),
// ...
AllPeripherals = 0xffff,
};
pub const PDStringEncoding = enum(c_int) {
ASCIIEncoding,
UTF8Encoding,
@"16BitLEEncoding",
};
pub const LCDBitmap = anyopaque;
pub const PDMenuItem = anyopaque;
pub const PDCallbackFunction = fn (userdata: ?*anyopaque) callconv(.C) c_int;
pub const PDMenuItemCallbackFunction = fn (userdata: ?*anyopaque) callconv(.C) void;
var pd: *PlaydateAPI = undefined;
var current_font: *LCDFont = undefined;
pub inline fn set_playdate_api(playdate: *PlaydateAPI) void {
pd = playdate;
}
////Buttons
pub const PDButtons = c_int;
pub const BUTTON_LEFT = (1 << 0);
pub const BUTTON_RIGHT = (1 << 1);
pub const BUTTON_UP = (1 << 2);
pub const BUTTON_DOWN = (1 << 3);
pub const BUTTON_B = (1 << 4);
pub const BUTTON_A = (1 << 5);
pub inline fn get_button_state(current: ?*PDButtons, pushed: ?*PDButtons, released: ?*PDButtons) void {
pd.system.getButtonState(current, pushed, released);
}
//Draw Color
pub inline fn solid_color_to_color(solid_color: LCDSolidColor) LCDColor {
return @intCast(usize, @enumToInt(solid_color));
}
pub inline fn pattern_to_color(pattern: LCDPatternSlice) LCDColor {
return @intCast(usize, @ptrToInt(pattern.ptr));
}
/////Draw context
pub inline fn push_drawing_context(target: ?*LCDBitmap) void {
pd.graphics.pushContext(target);
}
pub inline fn pop_drawing_context() void {
pd.graphics.popContext();
}
////Draw clipping
pub inline fn set_clip_rect(x: Pixel, y: Pixel, width: Pixel, height: Pixel) void {
pd.graphics.setClipRect(x, y, width, height);
}
pub inline fn clear_clip_rect() void {
pd.graphics.clearClipRect();
}
////Screen
pub inline fn clear_screen(color: LCDSolidColor) void {
pd.graphics.clear(@intCast(LCDColor, @enumToInt(color)));
}
pub inline fn set_screen_clip_rect(x: Pixel, y: Pixel, width: Pixel, height: Pixel) void {
pd.graphics.setScreenClipRect(x, y, width, height);
}
pub inline fn set_refresh_rate(comptime refresh_rate: f32) void {
pd.display.setRefreshRate(refresh_rate);
}
////Fonts and text
pub inline fn load_font(path: [*c]const u8) *LCDFont {
var err: [*c]const u8 = undefined;
const font_opt = pd.graphics.loadFont(path, &err);
if (font_opt) |font| {
return font;
}
@panic("Error loading font");
}
pub inline fn free_font(font: *LCDFont) void {
_ = font;
//TODO: there doesn't seem to be a free font function
//pd.graphics.freeFont(font);
}
pub inline fn set_font(font: *LCDFont) void {
current_font = font;
pd.graphics.setFont(font);
}
pub inline fn draw_text(text: []const u8, x: Pixel, y: Pixel) Pixel {
return pd.graphics.drawText(text.ptr, text.len, .UTF8Encoding, x, y);
}
pub inline fn draw_fmt(comptime fmt: []const u8, args: anytype, x: Pixel, y: Pixel) Pixel {
var buffer = [_]u8{0} ** 128;
const to_print = std.fmt.bufPrintZ(&buffer, fmt, args) catch @panic("draw_fmt failed");
return draw_text(to_print, x, y);
}
pub inline fn get_text_width(text: []const u8) Pixel {
return pd.graphics.getTextWidth(current_font, text.ptr, text.len, .UTF8Encoding, 0);
}
pub inline fn get_fmt_width(comptime fmt: []const u8, args: anytype) Pixel {
var buffer = [_]u8{0} ** 128;
const to_count = std.fmt.bufPrintZ(&buffer, fmt, args) catch @panic("draw_fmt failed");
return pd.graphics.getTextWidth(current_font, to_count.ptr, to_count.len, .UTF8Encoding, 0);
}
pub inline fn get_font_height() Pixel {
return pd.graphics.getFontHeight(current_font);
}
pub inline fn draw_fps(x: Pixel, y: Pixel) void {
pd.system.drawFPS(x, y);
}
////Bitmap
pub inline fn load_bitmap_table(path: [*c]const u8) *LCDBitmapTable {
var err: [*c]const u8 = undefined;
const bitmap_table_opt = pd.graphics.loadBitmapTable(path, &err);
if (bitmap_table_opt) |bitmap_table| {
return bitmap_table;
}
@panic("Error loading bitmap table");
}
pub inline fn free_bitmap_table(bitmap_table: *LCDBitmapTable) void {
pd.graphics.freeBitmapTable(bitmap_table);
}
pub inline fn load_bitmap(path: [*c]const u8) *LCDBitmap {
var err: [*c]const u8 = undefined;
const bitmap_opt = pd.graphics.loadBitmap(path, &err);
if (bitmap_opt) |bitmap| {
return bitmap;
}
@panic("Error loading bitmap");
}
pub inline fn free_bitmap(bitmap: *LCDBitmap) void {
pd.graphics.freeBitmap(bitmap);
}
//Shapes
pub inline fn draw_rect(x: Pixel, y: Pixel, width: Pixel, height: Pixel, color: LCDColor) void {
pd.graphics.drawRect(x, y, width, height, color);
}
pub inline fn fill_rect(x: Pixel, y: Pixel, width: Pixel, height: Pixel, color: LCDColor) void {
pd.graphics.fillRect(x, y, width, height, color);
}
pub const BitmapData = struct {
width: i32,
height: i32,
row_bytes: i32,
has_mask: bool,
data: []u8,
};
pub fn get_bitmap_data(bitmap: *LCDBitmap) BitmapData {
var ret: BitmapData = undefined;
var has_mask: c_int = 0;
var data: [*c]u8 = undefined;
pd.graphics.getBitmapData(bitmap, &ret.width, &ret.height, &ret.row_bytes, &has_mask, &data);
ret.has_mask = if (has_mask != 0) true else false;
ret.data = data[0..@intCast(usize, ret.row_bytes * ret.height)];
return ret;
}
pub inline fn get_table_bitmap(table: *LCDBitmapTable, index: i32) ?*LCDBitmap {
const table_bitmap = pd.graphics.getTableBitmap(table, @intCast(c_int, index));
return table_bitmap;
}
pub fn get_table_bitmap_size(table: *LCDBitmapTable) i32 {
var ret: i32 = 0;
while (get_table_bitmap(table, ret)) |_| {
ret += 1;
}
return ret;
}
pub inline fn tile_bitmap(bitmap: *LCDBitmap, x: Pixel, y: Pixel, width: Pixel, height: Pixel, flip: LCDBitmapFlip) void {
pd.graphics.tileBitmap(bitmap, x, y, width, height, flip);
}
pub inline fn draw_bitmap(bitmap: *LCDBitmap, x: Pixel, y: Pixel, flip: LCDBitmapFlip) void {
pd.graphics.drawBitmap(bitmap, x, y, flip);
}
pub inline fn draw_scaled_bitmap(bitmap: *LCDBitmap, x: Pixel, y: Pixel, xscale: f32, yscale: f32) void {
pd.graphics.drawScaledBitmap(bitmap, x, y, xscale, yscale);
}
//Crank
pub inline fn get_crank_change() f32 {
return pd.system.getCrankChange();
}
pub inline fn get_crank_angle() f32 {
return pd.system.getCrankAngle();
}
pub inline fn is_crank_docked() bool {
return pd.system.isCrankDocked() != 0;
}
pub inline fn set_crank_sounds_disabled(flag: bool) bool {
return pd.system.setCrankSoundsDisabled(if (flag) 1 else 0) != 0; // returns previous setting
}
//Menu items
pub inline fn add_menu_item(comptime title: [:0]const u8, callback: PDMenuItemCallbackFunction, userdata: ?*anyopaque) *PDMenuItem {
return pd.system.addMenuItem(title, callback, userdata).?;
}
pub const PlaydateSys = extern struct {
realloc: fn (ptr: ?*anyopaque, size: usize) callconv(.C) ?*anyopaque,
formatString: fn (ret: ?*[*c]u8, fmt: [*c]const u8, ...) callconv(.C) c_int,
logToConsole: fn (fmt: [*c]const u8, ...) callconv(.C) void,
@"error": fn (fmt: [*c]const u8, ...) callconv(.C) void,
getLanguage: fn () callconv(.C) PDLanguage,
getCurrentTimeMilliseconds: fn () callconv(.C) c_uint,
getSecondsSinceEpoch: fn (milliseconds: ?*c_uint) callconv(.C) c_uint,
drawFPS: fn (x: c_int, y: c_int) callconv(.C) void,
setUpdateCallback: fn (update: ?PDCallbackFunction, userdata: ?*anyopaque) callconv(.C) void,
getButtonState: fn (current: ?*PDButtons, pushed: ?*PDButtons, released: ?*PDButtons) callconv(.C) void,
setPeripheralsEnabled: fn (mask: PDPeripherals) callconv(.C) void,
getAccelerometer: fn (outx: ?*f32, outy: ?*f32, outz: ?*f32) callconv(.C) void,
getCrankChange: fn () callconv(.C) f32,
getCrankAngle: fn () callconv(.C) f32,
isCrankDocked: fn () callconv(.C) c_int,
setCrankSoundsDisabled: fn (flag: c_int) callconv(.C) c_int, // returns previous setting
getFlipped: fn () callconv(.C) c_int,
setAutoLockDisabled: fn (disable: c_int) callconv(.C) void,
setMenuImage: fn (bitmap: ?*LCDBitmap, xOffset: c_int) callconv(.C) void,
addMenuItem: fn (title: [*c]const u8, callback: ?PDMenuItemCallbackFunction, userdata: ?*anyopaque) callconv(.C) ?*PDMenuItem,
addCheckmarkMenuItem: fn (title: [*c]const u8, value: c_int, callback: ?PDMenuItemCallbackFunction, userdata: ?*anyopaque) callconv(.C) ?*PDMenuItem,
addOptionsMenuItem: fn (title: [*c]const u8, optionTitles: [*c][*c]const u8, optionsCount: c_int, f: ?PDMenuItemCallbackFunction, userdata: ?*anyopaque) callconv(.C) ?*PDMenuItem,
removeAllMenuItems: fn () callconv(.C) void,
removeMenuItem: fn (menuItem: ?*PDMenuItem) callconv(.C) void,
getMenuItemValue: fn (menuItem: ?*PDMenuItem) callconv(.C) c_int,
setMenuItemValue: fn (menuItem: ?*PDMenuItem, value: c_int) callconv(.C) void,
getMenuItemTitle: fn (menuItem: ?*PDMenuItem) callconv(.C) [*c]const u8,
setMenuItemTitle: fn (menuItem: ?*PDMenuItem, title: [*c]const u8) callconv(.C) void,
getMenuItemUserdata: fn (menuItem: ?*PDMenuItem) callconv(.C) ?*anyopaque,
setMenuItemUserdata: fn (menuItem: ?*PDMenuItem, ud: ?*anyopaque) callconv(.C) void,
getReduceFlashing: fn () callconv(.C) c_int,
// 1.1
getElapsedTime: fn () callconv(.C) f32,
resetElapsedTime: fn () callconv(.C) void,
// 1.4
getBatteryPercentage: fn () callconv(.C) f32,
getBatteryVoltage: fn () callconv(.C) f32,
};
pub const LCDVideoPlayer = anyopaque;
pub const PlaydateVideo = extern struct {
loadVideo: fn ([*c]const u8) callconv(.C) ?*LCDVideoPlayer,
freePlayer: fn (?*LCDVideoPlayer) callconv(.C) void,
setContext: fn (?*LCDVideoPlayer, ?*LCDBitmap) callconv(.C) c_int,
useScreenContext: fn (?*LCDVideoPlayer) callconv(.C) void,
renderFrame: fn (?*LCDVideoPlayer, c_int) callconv(.C) c_int,
getError: fn (?*LCDVideoPlayer) callconv(.C) [*c]const u8,
getInfo: fn (?*LCDVideoPlayer, [*c]c_int, [*c]c_int, [*c]f32, [*c]c_int, [*c]c_int) callconv(.C) void,
getContext: fn (?*LCDVideoPlayer) callconv(.C) ?*LCDBitmap,
};
const LCD_COLUMNS = 400;
const LCD_ROWS = 240;
const LCD_ROWSIZE = 52;
pub const LCDPattern = [16]u8;
pub const LCDPatternSlice = []u8;
pub const LCDColor = usize; //Pointer to LCDPattern or a LCDSolidColor value
pub const LCDSolidColor = enum(c_int) {
ColorBlack,
ColorWhite,
ColorClear,
ColorXOR,
};
pub const LCDBitmapDrawMode = enum(c_int) {
DrawModeCopy,
DrawModeWhiteTransparent,
DrawModeBlackTransparent,
DrawModeFillWhite,
DrawModeFillBlack,
DrawModeXOR,
DrawModeNXOR,
DrawModeInverted,
};
pub const LCDLineCapStyle = enum(c_int) {
LineCapStyleButt,
LineCapStyleSquare,
LineCapStyleRound,
};
pub const LCDFontLanguage = enum(c_int) {
LCDFontLanguageEnglish,
LCDFontLanguageJapanese,
LCDFontLanguageUnknown,
};
pub const LCDBitmapFlip = enum(c_int) {
BitmapUnflipped,
BitmapFlippedX,
BitmapFlippedY,
BitmapFlippedXY,
};
pub const LCDPolygonFillRule = enum(c_int) {
PolygonFillNonZero,
PolygonFillEvenOdd,
};
pub const LCDBitmapTable = anyopaque;
pub const LCDFont = anyopaque;
pub const LCDFontPage = anyopaque;
pub const LCDFontGlyph = anyopaque;
pub const LCDRect = extern struct {
left: c_int,
right: c_int,
top: c_int,
bottom: c_int,
};
pub const PlaydateGraphics = extern struct {
video: *const PlaydateVideo,
// Drawing Functions
clear: fn (color: LCDColor) callconv(.C) void,
setBackgroundColor: fn (color: LCDSolidColor) callconv(.C) void,
setStencil: fn (stencil: ?*LCDBitmap) callconv(.C) void, // deprecated in favor of setStencilImage, which adds a "tile" flag
setDrawMode: fn (mode: LCDBitmapDrawMode) callconv(.C) void,
setDrawOffset: fn (dx: c_int, dy: c_int) callconv(.C) void,
setClipRect: fn (x: c_int, y: c_int, width: c_int, height: c_int) callconv(.C) void,
clearClipRect: fn () callconv(.C) void,
setLineCapStyle: fn (endCapStyle: LCDLineCapStyle) callconv(.C) void,
setFont: fn (font: ?*LCDFont) callconv(.C) void,
setTextTracking: fn (tracking: c_int) callconv(.C) void,
pushContext: fn (target: ?*LCDBitmap) callconv(.C) void,
popContext: fn () callconv(.C) void,
drawBitmap: fn (bitmap: ?*LCDBitmap, x: c_int, y: c_int, flip: LCDBitmapFlip) callconv(.C) void,
tileBitmap: fn (bitmap: ?*LCDBitmap, x: c_int, y: c_int, width: c_int, height: c_int, flip: LCDBitmapFlip) callconv(.C) void,
drawLine: fn (x1: c_int, y1: c_int, x2: c_int, y2: c_int, width: c_int, color: LCDColor) callconv(.C) void,
fillTriangle: fn (x1: c_int, y1: c_int, x2: c_int, y2: c_int, x3: c_int, y3: c_int, color: LCDColor) callconv(.C) void,
drawRect: fn (x: c_int, y: c_int, width: c_int, height: c_int, color: LCDColor) callconv(.C) void,
fillRect: fn (x: c_int, y: c_int, width: c_int, height: c_int, color: LCDColor) callconv(.C) void,
drawEllipse: fn (x: c_int, y: c_int, width: c_int, height: c_int, lineWidth: c_int, startAngle: f32, endAngle: f32, color: LCDColor) callconv(.C) void,
fillEllipse: fn (x: c_int, y: c_int, width: c_int, height: c_int, startAngle: f32, endAngle: f32, color: LCDColor) callconv(.C) void,
drawScaledBitmap: fn (bitmap: ?*LCDBitmap, x: c_int, y: c_int, xscale: f32, yscale: f32) callconv(.C) void,
drawText: fn (text: ?*const anyopaque, len: usize, encoding: PDStringEncoding, x: c_int, y: c_int) callconv(.C) c_int,
// LCDBitmap
newBitmap: fn (width: c_int, height: c_int, color: LCDColor) callconv(.C) ?*LCDBitmap,
freeBitmap: fn (bitmap: ?*LCDBitmap) callconv(.C) void,
loadBitmap: fn (path: [*c]const u8, outerr: ?*[*c]const u8) callconv(.C) ?*LCDBitmap,
copyBitmap: fn (bitmap: ?*LCDBitmap) callconv(.C) ?*LCDBitmap,
loadIntoBitmap: fn (path: [*c]const u8, bitmap: ?*LCDBitmap, outerr: ?*[*c]const u8) callconv(.C) void,
getBitmapData: fn (bitmap: ?*LCDBitmap, width: ?*c_int, height: ?*c_int, rowbytes: ?*c_int, hasmask: ?*c_int, data: ?*[*c]u8) callconv(.C) void,
clearBitmap: fn (bitmap: ?*LCDBitmap, bgcolor: LCDColor) callconv(.C) void,
rotatedBitmap: fn (bitmap: ?*LCDBitmap, rotation: f32, xscale: f32, yscale: f32, allocedSize: ?*c_int) callconv(.C) ?*LCDBitmap,
// LCDBitmapTable
newBitmapTable: fn (count: c_int, width: c_int, height: c_int) callconv(.C) ?*LCDBitmapTable,
freeBitmapTable: fn (table: ?*LCDBitmapTable) callconv(.C) void,
loadBitmapTable: fn (path: [*c]const u8, outerr: ?*[*c]const u8) callconv(.C) ?*LCDBitmapTable,
loadIntoBitmapTable: fn (path: [*c]const u8, table: ?*LCDBitmapTable, outerr: ?*[*c]const u8) callconv(.C) void,
getTableBitmap: fn (table: ?*LCDBitmapTable, idx: c_int) callconv(.C) ?*LCDBitmap,
// LCDFont
loadFont: fn (path: [*c]const u8, outErr: ?*[*c]const u8) callconv(.C) ?*LCDFont,
getFontPage: fn (font: ?*LCDFont, c: u32) callconv(.C) ?*LCDFontPage,
getPageGlyph: fn (page: ?*LCDFontPage, c: u32, bitmap: ?**LCDBitmap, advance: ?*c_int) callconv(.C) ?*LCDFontGlyph,
getGlyphKerning: fn (glyph: ?*LCDFontGlyph, glyphcode: u32, nextcode: u32) callconv(.C) c_int,
getTextWidth: fn (font: ?*LCDFont, text: ?*const anyopaque, len: usize, encoding: PDStringEncoding, tracking: c_int) callconv(.C) c_int,
// raw framebuffer access
getFrame: fn () callconv(.C) [*c]u8, // row stride = LCD_ROWSIZE
getDisplayFrame: fn () callconv(.C) [*c]u8, // row stride = LCD_ROWSIZE
getDebugBitmap: ?fn () callconv(.C) ?*LCDBitmap, // valid in simulator only, function is null on device
copyFrameBufferBitmap: fn () callconv(.C) ?*LCDBitmap,
markUpdatedRows: fn (start: c_int, end: c_int) callconv(.C) void,
display: fn () callconv(.C) void,
// misc util.
setColorToPattern: fn (color: ?*LCDColor, bitmap: ?*LCDBitmap, x: c_int, y: c_int) callconv(.C) void,
checkMaskCollision: fn (bitmap1: ?*LCDBitmap, x1: c_int, y1: c_int, flip1: LCDBitmapFlip, bitmap2: ?*LCDBitmap, x2: c_int, y2: c_int, flip2: LCDBitmapFlip, rect: LCDRect) callconv(.C) c_int,
// 1.1
setScreenClipRect: fn (x: c_int, y: c_int, width: c_int, height: c_int) callconv(.C) void,
// 1.1.1
fillPolygon: fn (nPoints: c_int, coords: [*c]c_int, color: LCDColor, fillRule: LCDPolygonFillRule) callconv(.C) void,
getFontHeight: fn (font: ?*LCDFont) callconv(.C) u8,
// 1.7
getDisplayBufferBitmap: fn () callconv(.C) ?*LCDBitmap,
drawRotatedBitmap: fn (bitmap: ?*LCDBitmap, x: c_int, y: c_int, rotation: f32, centerx: f32, centery: f32, xscale: f32, yscale: f32) callconv(.C) void,
setTextLeading: fn (lineHeightAdustment: c_int) callconv(.C) void,
// 1.8
setBitmapMask: fn (bitmap: ?*LCDBitmap, mask: ?*LCDBitmap) callconv(.C) c_int,
getBitmapMask: fn (bitmap: ?*LCDBitmap) callconv(.C) ?*LCDBitmap,
// 1.10
setStencilImage: fn (stencil: ?*LCDBitmap, tile: c_int) callconv(.C) void,
};
const PlaydateDisplay = struct {
getWidth: fn () callconv(.C) c_int,
getHeight: fn () callconv(.C) c_int,
setRefreshRate: fn (rate: f32) callconv(.C) void,
setInverted: fn (flag: c_int) callconv(.C) void,
setScale: fn (s: c_uint) callconv(.C) void,
setMosaic: fn (x: c_uint, y: c_uint) callconv(.C) void,
setFlipped: fn (x: c_uint, y: c_uint) callconv(.C) void,
setOffset: fn (x: c_uint, y: c_uint) callconv(.C) void,
};
const game = @import("main.zig");
const pdapi = @import("playdate_api.zig");
pub const THIS_PLATFORM = toolbox.Platform.Playdate;
comptime {
asm (
\\.global _bss_start
\\.global _bss_end
\\.extern __bss_start__
\\.extern __bss_end__
\\.section .bss_start
\\_bss_start:
\\ .word __bss_start__
\\.section .bss_end
\\_bss_end:
\\ .word __bss_end__
\\
\\.section .text
\\.global eventHandler
\\.global _start
\\_start:
\\ b eventHandler //This is never exectued, but required for the linker to work correctly
);
}
export var PD_eventHandler: fn (playdate: *pdapi.PlaydateAPI, event: pdapi.PDSystemEvent, arg: u32) callconv(.C) c_int linksection(".capi_handler") = game.eventHandler;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment