Subscribe Now
Trending News

Blog Post

Write Playdate Games in Zig
News

Write Playdate Games in Zig 

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, };

Read More

Related posts

© Copyright 2022, All Rights Reserved