Personal commit
This commit is contained in:
		
							parent
							
								
									5dc481e671
								
							
						
					
					
						commit
						257ee10a85
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
.zig-cache/
 | 
			
		||||
zig-out/
 | 
			
		||||
*.fap
 | 
			
		||||
							
								
								
									
										37
									
								
								build.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								build.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const Target = std.Target;
 | 
			
		||||
const Build = std.Build;
 | 
			
		||||
 | 
			
		||||
pub fn build(b: *Build) void {
 | 
			
		||||
    // Module
 | 
			
		||||
    const flipperzero = b.addModule("flipperzero", .{
 | 
			
		||||
        .root_source_file = b.path("lib/flipperzero/flipperzero.zig"),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Configuration
 | 
			
		||||
    const optimize = b.standardOptimizeOption(.{});
 | 
			
		||||
    const target_query = .{ .cpu_arch = .thumb, .cpu_model = .{ .explicit = &Target.arm.cpu.cortex_m4 }, .os_tag = .freestanding, .abi = .none };
 | 
			
		||||
 | 
			
		||||
    // Relocatable elf
 | 
			
		||||
    const elf = b.addObject(.{
 | 
			
		||||
        .name = "zlipper.fap",
 | 
			
		||||
        .root_source_file = b.path("src/start.zig"),
 | 
			
		||||
        .target = b.resolveTargetQuery(target_query),
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
        .strip = true,
 | 
			
		||||
        .pic = true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    elf.root_module.addImport("flipperzero", flipperzero);
 | 
			
		||||
    elf.setLinkerScript(b.path("linker.ld"));
 | 
			
		||||
    elf.setVerboseLink(true);
 | 
			
		||||
 | 
			
		||||
    elf.build_id = .none;
 | 
			
		||||
    elf.bundle_compiler_rt = false;
 | 
			
		||||
    elf.link_gc_sections = true;
 | 
			
		||||
    elf.linkage = .static;
 | 
			
		||||
 | 
			
		||||
    b.default_step.dependOn(&elf.step);
 | 
			
		||||
    const install_artifact = b.addInstallArtifact(elf, .{ .dest_dir = .{ .override = .{ .bin = {} } } });
 | 
			
		||||
    b.getInstallStep().dependOn(&install_artifact.step);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								lib/flipperzero/atomic.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								lib/flipperzero/atomic.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
const flipperzero = @import("flipperzero.zig");
 | 
			
		||||
const c = flipperzero.c;
 | 
			
		||||
 | 
			
		||||
pub fn FuriMessageQueue(comptime T: type) type {
 | 
			
		||||
    return extern struct {
 | 
			
		||||
        const Self = @This();
 | 
			
		||||
 | 
			
		||||
        pub fn create(msg_count: u32) *Self {
 | 
			
		||||
            return @ptrCast(c.furi_message_queue_alloc(msg_count, @sizeOf(T)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn destroy(self: *Self) void {
 | 
			
		||||
            c.furi_message_queue_free(self);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn get(self: *Self, msg_ptr: *T, timeout: u32) void {
 | 
			
		||||
            _ = c.furi_message_queue_get(self, msg_ptr, timeout);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn put(self: *Self, msg_ptr: *const T, timeout: u32) void {
 | 
			
		||||
            _ = c.furi_message_queue_put(self, msg_ptr, timeout);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										154
									
								
								lib/flipperzero/c.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								lib/flipperzero/c.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,154 @@
 | 
			
		||||
// C
 | 
			
		||||
pub extern fn aligned_malloc(len: usize, alignment: usize) ?*anyopaque;
 | 
			
		||||
pub extern fn aligned_free(ptr: *anyopaque) void;
 | 
			
		||||
pub extern fn malloc(size: usize) ?*anyopaque;
 | 
			
		||||
pub extern fn memset(dest: *anyopaque, c: i32, count: usize) *anyopaque;
 | 
			
		||||
pub extern fn free(memblock: *anyopaque) void;
 | 
			
		||||
pub extern fn snprintf(buffer: [*:0]u8, count: usize, format: [*:0]const u8, ...) i32;
 | 
			
		||||
 | 
			
		||||
// Canvas
 | 
			
		||||
pub extern fn canvas_clear(canvas: *anyopaque) void;
 | 
			
		||||
pub extern fn canvas_draw_str(canvas: *anyopaque, x: u8, y: u8, str: [*:0]const u8) void;
 | 
			
		||||
pub extern fn canvas_set_font(canvas: *anyopaque, font: Font) void;
 | 
			
		||||
 | 
			
		||||
// Furi
 | 
			
		||||
pub const FuriMutexType = enum(u8) {
 | 
			
		||||
    FuriMutexTypeNormal,
 | 
			
		||||
    FuriMutexTypeRecursive,
 | 
			
		||||
};
 | 
			
		||||
pub const FuriWait = enum(u32) {
 | 
			
		||||
    FuriWaitForever = 0xFFFFFFFF,
 | 
			
		||||
};
 | 
			
		||||
pub const FuriStatus = enum(i32) { FuriStatusOk = 0, FuriStatusError = -1, FuriStatusErrorTimeout = -2, FuriStatusErrorResource = -3, FuriStatusErrorParameter = -4, FuriStatusErrorNoMemory = -5, FuriStatusErrorISR = -6, FuriStatusReserved = 0x7FFFFFFF };
 | 
			
		||||
 | 
			
		||||
pub extern fn furi_delay_us(microseconds: u32) void;
 | 
			
		||||
pub extern fn furi_message_queue_alloc(msg_count: u32, msg_size: u32) *anyopaque;
 | 
			
		||||
pub extern fn furi_message_queue_free(instance: *anyopaque) void;
 | 
			
		||||
pub extern fn furi_message_queue_get(instance: *anyopaque, msg_ptr: *anyopaque, timeout: u32) FuriStatus;
 | 
			
		||||
pub extern fn furi_message_queue_put(instance: *anyopaque, msg_ptr: *const anyopaque, timeout: u32) FuriStatus;
 | 
			
		||||
pub extern fn furi_mutex_alloc(type: FuriMutexType) *anyopaque;
 | 
			
		||||
pub extern fn furi_mutex_free(instance: *anyopaque) void;
 | 
			
		||||
pub extern fn furi_record_close(name: [*:0]const u8) void;
 | 
			
		||||
pub extern fn furi_record_open(name: [*:0]const u8) *anyopaque;
 | 
			
		||||
 | 
			
		||||
// GUI
 | 
			
		||||
pub const RECORD_GUI = "gui";
 | 
			
		||||
pub const Font = enum(u8) {
 | 
			
		||||
    FontPrimary,
 | 
			
		||||
    FontSecondary,
 | 
			
		||||
    FontKeyboard,
 | 
			
		||||
    FontBigNumbers,
 | 
			
		||||
    FontTotalNumber,
 | 
			
		||||
};
 | 
			
		||||
pub const GuiLayer = enum(u8) {
 | 
			
		||||
    GuiLayerDesktop,
 | 
			
		||||
    GuiLayerWindow,
 | 
			
		||||
    GuiLayerStatusBarTop, // Custom on RogueMaster
 | 
			
		||||
    GuiLayerStatusBarLeft,
 | 
			
		||||
    GuiLayerStatusBarLeftSlim, // Custom on RogueMaster
 | 
			
		||||
    GuiLayerStatusBarRight,
 | 
			
		||||
    GuiLayerStatusBarRightSlim, // Custom on RogueMaster
 | 
			
		||||
    GuiLayerFullscreen,
 | 
			
		||||
    GuiLayerMAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub extern fn gui_add_view_port(gui: *anyopaque, view_port: *anyopaque, layer: GuiLayer) void;
 | 
			
		||||
pub extern fn gui_remove_view_port(gui: *anyopaque, view_port: *anyopaque) void;
 | 
			
		||||
 | 
			
		||||
// Input
 | 
			
		||||
pub const InputEvent = extern struct {
 | 
			
		||||
    sequence: u32 align(4),
 | 
			
		||||
    key: InputKey align(1),
 | 
			
		||||
    type: InputType align(1),
 | 
			
		||||
};
 | 
			
		||||
pub const InputKey = enum(u8) {
 | 
			
		||||
    InputKeyUp,
 | 
			
		||||
    InputKeyDown,
 | 
			
		||||
    InputKeyRight,
 | 
			
		||||
    InputKeyLeft,
 | 
			
		||||
    InputKeyOk,
 | 
			
		||||
    InputKeyBack,
 | 
			
		||||
    InputKeyMAX,
 | 
			
		||||
};
 | 
			
		||||
pub const InputType = enum(u8) {
 | 
			
		||||
    InputTypePress,
 | 
			
		||||
    InputTypeRelease,
 | 
			
		||||
    InputTypeShort,
 | 
			
		||||
    InputTypeLong,
 | 
			
		||||
    InputTypeRepeat,
 | 
			
		||||
    InputTypeMAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub extern fn input_get_key_name(key: InputKey) [*:0]const u8;
 | 
			
		||||
pub extern fn input_get_type_name(type: InputType) [*:0]const u8;
 | 
			
		||||
 | 
			
		||||
// SceneManager
 | 
			
		||||
pub extern fn scene_manager_alloc() *anyopaque;
 | 
			
		||||
pub extern fn scene_manager_free(scene_manager: *anyopaque) void;
 | 
			
		||||
pub extern fn scene_manager_get_scene_state(scene_manager: *anyopaque, scene_id: u32) u32;
 | 
			
		||||
pub extern fn scene_manager_handle_back_event(scene_manager: *anyopaque) bool;
 | 
			
		||||
pub extern fn scene_manager_handle_custom_event(scene_manager: *anyopaque, custom_event: u32) bool;
 | 
			
		||||
pub extern fn scene_manager_handle_tick_event(scene_manager: *anyopaque) void;
 | 
			
		||||
pub extern fn scene_manager_has_previous_scene(scene_manager: *const anyopaque, scene_id: u32) bool;
 | 
			
		||||
pub extern fn scene_manager_next_scene(scene_manager: *anyopaque, next_scene_id: u32) bool;
 | 
			
		||||
pub extern fn scene_manager_previous_scene(scene_manager: *anyopaque) bool;
 | 
			
		||||
pub extern fn scene_manager_search_and_switch_to_another_scene(scene_manager: *anyopaque, scene_id: u32) bool;
 | 
			
		||||
pub extern fn scene_manager_search_and_switch_to_previous_scene(scene_manager: *anyopaque, scene_id: u32) bool;
 | 
			
		||||
pub extern fn scene_manager_search_and_switch_to_previous_scene_one_of(scene_manager: *anyopaque, scene_ids: *const u32, scene_ids_size: usize) bool;
 | 
			
		||||
pub extern fn scene_manager_set_scene_state(scene_manager: *anyopaque, scene_id: u32, state: u32) void;
 | 
			
		||||
pub extern fn scene_manager_stop(scene_manager: *anyopaque) void;
 | 
			
		||||
 | 
			
		||||
// Storage
 | 
			
		||||
pub const RECORD_STORAGE = "storage";
 | 
			
		||||
 | 
			
		||||
// View
 | 
			
		||||
pub const ViewModelType = enum(u8) {
 | 
			
		||||
    ViewModelTypeNone,
 | 
			
		||||
    ViewModelTypeLockFree,
 | 
			
		||||
    ViewModelTypeLocking,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub extern fn view_alloc() *anyopaque;
 | 
			
		||||
pub extern fn view_allocate_model(view: *anyopaque, type: ViewModelType, size: usize) void;
 | 
			
		||||
pub extern fn view_commit_model(view: *anyopaque, update: bool) void;
 | 
			
		||||
pub extern fn view_free(view: *anyopaque) void;
 | 
			
		||||
pub extern fn view_free_model(view: *anyopaque) void;
 | 
			
		||||
pub extern fn view_get_model(view: *anyopaque) *anyopaque;
 | 
			
		||||
 | 
			
		||||
// Viewdispatcher
 | 
			
		||||
pub const ViewDispatcherType = enum(u8) {
 | 
			
		||||
    ViewDispatcherTypeDesktop,
 | 
			
		||||
    ViewDispatcherTypeWindow,
 | 
			
		||||
    ViewDispatcherTypeFullscreen,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub extern fn view_dispatcher_add_view(view_dispatcher: *anyopaque, view_id: u32, view: *anyopaque) void;
 | 
			
		||||
pub extern fn view_dispatcher_alloc() *anyopaque;
 | 
			
		||||
pub extern fn view_dispatcher_attach_to_gui(view_dispatcher: *anyopaque, gui: *anyopaque, type: ViewDispatcherType) void;
 | 
			
		||||
pub extern fn view_dispatcher_enable_queue(view_dispatcher: *anyopaque) void;
 | 
			
		||||
pub extern fn view_dispatcher_free(view_dispatcher: *anyopaque) void;
 | 
			
		||||
pub extern fn view_dispatcher_get_event_loop(view_dispatcher: *anyopaque) *anyopaque;
 | 
			
		||||
pub extern fn view_dispatcher_remove_view(view_dispatcher: *anyopaque, view_id: u32) void;
 | 
			
		||||
pub extern fn view_dispatcher_run(view_dispatcher: *anyopaque) void;
 | 
			
		||||
pub extern fn view_dispatcher_send_custom_event(view_dispatcher: *anyopaque, event: u32) void;
 | 
			
		||||
pub extern fn view_dispatcher_send_to_back(view_dispatcher: *anyopaque) void;
 | 
			
		||||
pub extern fn view_dispatcher_send_to_front(view_dispatcher: *anyopaque) void;
 | 
			
		||||
pub const ViewDispatcherCustomEventCallback = *const fn (?*anyopaque, event: u32) callconv(.C) void;
 | 
			
		||||
pub extern fn view_dispatcher_set_custom_event_callback(view_dispatcher: *anyopaque, callback: ViewDispatcherCustomEventCallback) void;
 | 
			
		||||
pub extern fn view_dispatcher_set_event_callback_context(view_dispatcher: *anyopaque, context: ?*anyopaque) void;
 | 
			
		||||
pub const ViewDispatcherNavigationEventCallback = *const fn (?*anyopaque) callconv(.C) void;
 | 
			
		||||
pub extern fn view_dispatcher_set_navigation_event_callback(view_dispatcher: *anyopaque, callback: ViewDispatcherNavigationEventCallback) void;
 | 
			
		||||
pub const ViewDispatcherTickEventCallback = *const fn (*anyopaque) callconv(.C) void;
 | 
			
		||||
pub extern fn view_dispatcher_set_tick_event_callback(view_dispatcher: *anyopaque, callback: ViewDispatcherTickEventCallback, tick_period: u32) void;
 | 
			
		||||
pub extern fn view_dispatcher_stop(view_dispatcher: *anyopaque) void;
 | 
			
		||||
pub extern fn view_dispatcher_switch_to_view(view_dispatcher: *anyopaque, view_id: u32) void;
 | 
			
		||||
 | 
			
		||||
// Viewport
 | 
			
		||||
pub extern fn view_port_alloc() *anyopaque;
 | 
			
		||||
pub const ViewPortDrawCallback = *const fn (*anyopaque, ?*anyopaque) callconv(.C) void;
 | 
			
		||||
pub extern fn view_port_draw_callback_set(view_port: *anyopaque, draw_callback: ViewPortDrawCallback, context: ?*anyopaque) void;
 | 
			
		||||
pub extern fn view_port_enabled_set(view_port: *anyopaque, enabled: bool) void;
 | 
			
		||||
pub extern fn view_port_free(view_port: *anyopaque) void;
 | 
			
		||||
pub const ViewPortInputCallback = *const fn (*InputEvent, ?*anyopaque) callconv(.C) void;
 | 
			
		||||
pub extern fn view_port_input_callback_set(view_port: *anyopaque, input_callback: ViewPortInputCallback, context: ?*anyopaque) void;
 | 
			
		||||
pub extern fn view_port_update(view_port: *anyopaque) void;
 | 
			
		||||
							
								
								
									
										7
									
								
								lib/flipperzero/flipperzero.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								lib/flipperzero/flipperzero.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
pub const atomic = @import("atomic.zig");
 | 
			
		||||
pub const c = @import("c.zig");
 | 
			
		||||
pub const gui = @import("gui.zig");
 | 
			
		||||
pub const heap = @import("heap.zig");
 | 
			
		||||
pub const manifest = @import("manifest.zig");
 | 
			
		||||
pub const storage = @import("storage.zig");
 | 
			
		||||
pub const thread = @import("thread.zig");
 | 
			
		||||
							
								
								
									
										227
									
								
								lib/flipperzero/gui.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								lib/flipperzero/gui.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,227 @@
 | 
			
		||||
const flipperzero = @import("flipperzero.zig");
 | 
			
		||||
const c = flipperzero.c;
 | 
			
		||||
 | 
			
		||||
pub const Canvas = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn clear(self: *Self) void {
 | 
			
		||||
        c.canvas_clear(@ptrCast(self));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn drawStr(self: *Self, x: u8, y: u8, str: [*:0]const u8) void {
 | 
			
		||||
        c.canvas_draw_str(@ptrCast(self), x, y, str);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setFont(self: *Self, font: c.Font) void {
 | 
			
		||||
        c.canvas_set_font(@ptrCast(self), font);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const Gui = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn open() *Self {
 | 
			
		||||
        return @ptrCast(c.furi_record_open(c.RECORD_GUI));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn close(self: *Self) void {
 | 
			
		||||
        _ = self;
 | 
			
		||||
        c.furi_record_close(c.RECORD_GUI);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn addViewPort(self: *Self, view_port: *ViewPort, layer: c.GuiLayer) void {
 | 
			
		||||
        c.gui_add_view_port(self, view_port, layer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn removeViewPort(self: *Self, view_port: *ViewPort) void {
 | 
			
		||||
        c.gui_remove_view_port(self, view_port);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const SceneManager = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn create() *Self {
 | 
			
		||||
        return @ptrCast(c.scene_manager_alloc());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn destroy(self: *Self) void {
 | 
			
		||||
        c.scene_manager_free(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn getSceneState(self: *Self, scene_id: u32) u32 {
 | 
			
		||||
        return c.scene_manager_get_scene_state(self, scene_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn handleBackEvent(self: *Self) bool {
 | 
			
		||||
        return c.scene_manager_handle_back_event(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn handleCustomEvent(self: *Self, custom_event: u32) bool {
 | 
			
		||||
        return c.scene_manager_handle_custom_event(self, custom_event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn handleTickEvent(self: *Self) void {
 | 
			
		||||
        c.scene_manager_handle_tick_event(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn hasPreviousScene(self: *Self, scene_id: u32) bool {
 | 
			
		||||
        return c.scene_manager_has_previous_scene(self, scene_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn nextScene(self: *Self, next_scene_id: u32) void {
 | 
			
		||||
        c.scene_manager_next_scene(self, next_scene_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn previousScene(self: *Self) bool {
 | 
			
		||||
        return c.scene_manager_previous_scene(self);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    pub fn searchAndSwitchToAnotherScene(self: *Self, scene_id: u32) bool {
 | 
			
		||||
        return c.scene_manager_search_and_switch_to_another_scene(self, scene_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn searchAndSwitchToPreviousScene(self: *Self, scene_id: u32) bool {
 | 
			
		||||
        return c.scene_manager_search_and_switch_to_previous_scene(self, scene_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn searchAndSwitchToPreviousSceneOneOf(self: *Self, scene_ids: *const u32, scene_ids_size: usize) bool {
 | 
			
		||||
        return c.scene_manager_search_and_switch_to_previous_scene_one_of(self, scene_ids, scene_ids_size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setSceneState(self: *Self, scene_id: u32, state: u32) void {
 | 
			
		||||
        c.scene_manager_set_scene_state(self, scene_id, state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn stop(self: *Self) void {
 | 
			
		||||
        c.scene_manager_stop(self);
 | 
			
		||||
    }
 | 
			
		||||
}; 
 | 
			
		||||
 | 
			
		||||
pub const View = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn create() *Self {
 | 
			
		||||
        return @ptrCast(c.view_alloc());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn allocateModel(self: *Self, type_: c.ViewModelType, size: usize) void {
 | 
			
		||||
        c.view_allocate_model(self, type_, size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn commitModel(self: *Self, update: bool) void {
 | 
			
		||||
        c.view_commit_model(self, update);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn destroy(self: *Self) void {
 | 
			
		||||
        c.view_free(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn freeModel(self: *Self) void {
 | 
			
		||||
        c.view_free_model(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn getModel(self: *Self) *anyopaque {
 | 
			
		||||
        return c.view_get_model(self);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const ViewDispatcher = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn create() *Self {
 | 
			
		||||
        return @ptrCast(c.view_dispatcher_alloc());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn addView(self: *Self, view_id: u32, view: *View) void {
 | 
			
		||||
        c.view_dispatcher_add_view(self, view_id, view);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn attachToGui(self: *Self, gui: *Gui, type_: c.ViewDispatcherType) void {
 | 
			
		||||
        c.view_dispatcher_attach_to_gui(self, gui, type_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn enableQueue(self: *Self) void {
 | 
			
		||||
        c.view_dispatcher_enable_queue(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn destroy(self: *Self) void {
 | 
			
		||||
        c.view_dispatcher_free(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn getEventLoop(self: *Self) *anyopaque {
 | 
			
		||||
        return c.view_dispatcher_get_event_loop(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn removeView(self: *Self, view_id: u32) void {
 | 
			
		||||
        c.view_dispatcher_remove_view(self, view_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn run(self: *Self) void {
 | 
			
		||||
        c.view_dispatcher_run(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sendCustomEvent(self: *Self, event: u32) void {
 | 
			
		||||
        c.view_dispatcher_send_custom_event(self, event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sendToBack(self: *Self) void {
 | 
			
		||||
        c.view_dispatcher_send_to_back(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sendToFront(self: *Self) void {
 | 
			
		||||
        c.view_dispatcher_send_to_front(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setCustomEventCallback(self: *Self, callback: c.ViewDispatcherCustomEventCallback) void {
 | 
			
		||||
        c.view_dispatcher_set_custom_event_callback(self, callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setEventCallbackContext(self: *Self, context: ?*anyopaque) void {
 | 
			
		||||
        c.view_dispatcher_set_event_callback_context(self, context orelse null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setNavigationEventCallback(self: *Self, callback: c.ViewDispatcherNavigationEventCallback) void {
 | 
			
		||||
        c.view_dispatcher_set_navigation_event_callback(self, callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setTickEventCallback(self: *Self, callback: c.ViewDispatcherTickEventCallback, tick_period: u32) void {
 | 
			
		||||
        c.view_dispatcher_set_tick_event_callback(self, callback, tick_period);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn stop(self: *Self) void {
 | 
			
		||||
        c.view_dispatcher_stop(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn switchToView(self: *Self, view_id: u32) void {
 | 
			
		||||
        c.view_dispatcher_switch_to_view(self, view_id);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const ViewPort = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn create() *Self {
 | 
			
		||||
        return @ptrCast(c.view_port_alloc());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn destroy(self: *Self) void {
 | 
			
		||||
        c.view_port_free(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update(self: *Self) void {
 | 
			
		||||
        c.view_port_update(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setDrawCallback(self: *Self, callback: c.ViewPortDrawCallback, context: ?*anyopaque) void {
 | 
			
		||||
        c.view_port_draw_callback_set(self, callback, context orelse null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setInputCallback(self: *Self, callback: c.ViewPortInputCallback, context: ?*anyopaque) void {
 | 
			
		||||
        c.view_port_input_callback_set(self, callback, context orelse null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setEnabled(self: *Self, enabled: bool) void {
 | 
			
		||||
        c.view_port_enabled_set(self, enabled);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										48
									
								
								lib/flipperzero/heap.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/flipperzero/heap.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const Allocator = std.mem.Allocator;
 | 
			
		||||
const flipperzero = @import("flipperzero.zig");
 | 
			
		||||
const c = flipperzero.c;
 | 
			
		||||
 | 
			
		||||
pub const FuriAllocator = struct {
 | 
			
		||||
    fn alloc(
 | 
			
		||||
        _: *anyopaque,
 | 
			
		||||
        len: usize,
 | 
			
		||||
        log2_align: u8,
 | 
			
		||||
        return_address: usize,
 | 
			
		||||
    ) ?[*]u8 {
 | 
			
		||||
        _ = return_address;
 | 
			
		||||
        const alignment = @as(usize, 1) << @intCast(log2_align);
 | 
			
		||||
        return @ptrCast(c.aligned_malloc(len, alignment));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn resize(
 | 
			
		||||
        _: *anyopaque,
 | 
			
		||||
        buf: []u8,
 | 
			
		||||
        log2_buf_align: u8,
 | 
			
		||||
        new_len: usize,
 | 
			
		||||
        return_address: usize,
 | 
			
		||||
    ) bool {
 | 
			
		||||
        _ = return_address;
 | 
			
		||||
        _ = log2_buf_align;
 | 
			
		||||
        return new_len <= buf.len;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn free(
 | 
			
		||||
        _: *anyopaque,
 | 
			
		||||
        buf: []u8,
 | 
			
		||||
        log2_buf_align: u8,
 | 
			
		||||
        return_address: usize,
 | 
			
		||||
    ) void {
 | 
			
		||||
        _ = return_address;
 | 
			
		||||
        _ = log2_buf_align;
 | 
			
		||||
        c.aligned_free(buf.ptr);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const furi_allocator_vtable = Allocator.VTable{
 | 
			
		||||
    .alloc = FuriAllocator.alloc,
 | 
			
		||||
    .resize = FuriAllocator.resize,
 | 
			
		||||
    .free = FuriAllocator.free,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const furi_allocator = Allocator{ .ptr = undefined, .vtable = &furi_allocator_vtable };
 | 
			
		||||
							
								
								
									
										39
									
								
								lib/flipperzero/manifest.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lib/flipperzero/manifest.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const mem = std.mem;
 | 
			
		||||
 | 
			
		||||
const MANIFEST_MAGIC: u32 = 0x52474448;
 | 
			
		||||
const API_VERSION: u32 = 0x00480001; // API_VERSION 72.1
 | 
			
		||||
 | 
			
		||||
const FlipperManifestBase = extern struct {
 | 
			
		||||
    manifest_magic: u32 align(1),
 | 
			
		||||
    manifest_version: u32 align(1),
 | 
			
		||||
    api_version: u32 align(1),
 | 
			
		||||
    hardware_target_id: u16 align(1),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const FlipperApplicationManifestV1 = extern struct {
 | 
			
		||||
    base: FlipperManifestBase,
 | 
			
		||||
    stack_size: u16 align(1),
 | 
			
		||||
    app_version: u32 align(1),
 | 
			
		||||
    name: [32]u8 align(1),
 | 
			
		||||
    has_icon: u8 align(1),
 | 
			
		||||
    icon: [32]u8 align(1),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const FlipperApplicationManifest = FlipperApplicationManifestV1;
 | 
			
		||||
 | 
			
		||||
pub fn createApplicationManifest(stack_size: u16, app_version: u32, comptime name: [*:0]const u8, has_icon: u8, icon: ?[32]u8) FlipperApplicationManifest {
 | 
			
		||||
    return FlipperApplicationManifest{
 | 
			
		||||
        .base = FlipperManifestBase{
 | 
			
		||||
            .manifest_magic = MANIFEST_MAGIC,
 | 
			
		||||
            .manifest_version = 1,
 | 
			
		||||
            .api_version = API_VERSION,
 | 
			
		||||
            .hardware_target_id = 7,
 | 
			
		||||
        },
 | 
			
		||||
        .stack_size = stack_size,
 | 
			
		||||
        .app_version = app_version,
 | 
			
		||||
        .name = (mem.span(name) ++ mem.zeroes([32 - mem.len(name)]u8)).*,
 | 
			
		||||
        .has_icon = has_icon,
 | 
			
		||||
        .icon = icon orelse mem.zeroes([32]u8),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								lib/flipperzero/storage.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lib/flipperzero/storage.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
const flipperzero = @import("flipperzero.zig");
 | 
			
		||||
const c = flipperzero.c;
 | 
			
		||||
 | 
			
		||||
pub const Storage = extern struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn open() *Self {
 | 
			
		||||
        return @ptrCast(c.furi_record_open(c.RECORD_STORAGE));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn close(self: *Self) void {
 | 
			
		||||
        _ = self;
 | 
			
		||||
        c.furi_record_close(c.RECORD_STORAGE);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										35
									
								
								lib/flipperzero/thread.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								lib/flipperzero/thread.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
const flipperzero = @import("flipperzero.zig");
 | 
			
		||||
const c = flipperzero.c;
 | 
			
		||||
 | 
			
		||||
pub const FuriMutex = struct {
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn create(type_: c.FuriMutexType) *Self {
 | 
			
		||||
        return @ptrCast(c.furi_mutex_alloc(type_));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn destroy(self: *Self) void {
 | 
			
		||||
        c.furi_mutex_free(self);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// pub const FuriThread = struct {
 | 
			
		||||
//     data: *anyopaque,
 | 
			
		||||
 | 
			
		||||
//     const Self = @This();
 | 
			
		||||
 | 
			
		||||
//     pub fn create() Self {
 | 
			
		||||
//         return Self{
 | 
			
		||||
//             .data = c.furi_thread_alloc()
 | 
			
		||||
//         };
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn join(self: Self) void {
 | 
			
		||||
//         c.furi_thread_join(self.data);
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn destroy(self: Self) void {
 | 
			
		||||
//         self.join();
 | 
			
		||||
//         c.furi_thread_free(self.data);
 | 
			
		||||
//     }
 | 
			
		||||
// };
 | 
			
		||||
							
								
								
									
										51
									
								
								linker.ld
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								linker.ld
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
ENTRY(_start);
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
    .text 0x00000000 : ALIGN(4)
 | 
			
		||||
    {
 | 
			
		||||
        KEEP(*(.init));
 | 
			
		||||
        *(.text .text.*);
 | 
			
		||||
        KEEP(*(.fini));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .rodata :
 | 
			
		||||
    {
 | 
			
		||||
        *(.rodata .rodata.*);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .bss :
 | 
			
		||||
    {
 | 
			
		||||
        *(.bss .bss.*);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .data :
 | 
			
		||||
    {
 | 
			
		||||
        *(.data .data.*);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	.ARM.attributes :
 | 
			
		||||
	{
 | 
			
		||||
		*(.ARM.attributes .ARM.attributes.*);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    .fapmeta (INFO) :
 | 
			
		||||
    {
 | 
			
		||||
        KEEP(*(.fapmeta));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /DISCARD/ :
 | 
			
		||||
    {
 | 
			
		||||
        *(.text.strlen);
 | 
			
		||||
 | 
			
		||||
        /* LLVM bitcode should never be in the binary */
 | 
			
		||||
        *(.llvmbc .llvmcmd);
 | 
			
		||||
 | 
			
		||||
        /* Unwinding is not supported */
 | 
			
		||||
        *(.ARM.exidx .ARM.exidx.*);
 | 
			
		||||
        
 | 
			
		||||
        *(.comment .comment.*);
 | 
			
		||||
        *(.note .note.*);
 | 
			
		||||
        *(.debug*);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										263
									
								
								src/app.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								src/app.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,263 @@
 | 
			
		||||
// Imports
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const fz = @import("flipperzero");
 | 
			
		||||
 | 
			
		||||
// const Zlipper = struct {
 | 
			
		||||
//     allocator: std.mem.Allocator,
 | 
			
		||||
//     mutex: *anyopaque,
 | 
			
		||||
//     gui: *anyopaque,
 | 
			
		||||
//     view_port: *anyopaque,
 | 
			
		||||
//     input_queue: *anyopaque,
 | 
			
		||||
//     input_event: ?*c.InputEvent,
 | 
			
		||||
//     running: bool,
 | 
			
		||||
//     acc: u32,
 | 
			
		||||
 | 
			
		||||
//     const Self = @This();
 | 
			
		||||
 | 
			
		||||
//     pub fn init(allocator: std.mem.Allocator) *Self {
 | 
			
		||||
//         const self = allocator.create(Self) catch unreachable;
 | 
			
		||||
//         self.* = Self{
 | 
			
		||||
//             .allocator = allocator,
 | 
			
		||||
//             .mutex = c.furi_mutex_alloc(c.FuriMutexType.FuriMutexTypeNormal),
 | 
			
		||||
//             .gui = c.furi_record_open(c.RECORD_GUI),
 | 
			
		||||
//             .view_port = c.view_port_alloc(),
 | 
			
		||||
//             .input_queue = c.furi_message_queue_alloc(8, @sizeOf(c.InputEvent)),
 | 
			
		||||
//             .input_event = null,
 | 
			
		||||
//             .running = true,
 | 
			
		||||
//             .acc = 0,
 | 
			
		||||
//         };
 | 
			
		||||
 | 
			
		||||
//         c.view_port_draw_callback_set(self.view_port, Self.draw_callback, @ptrCast(self));
 | 
			
		||||
//         c.view_port_input_callback_set(self.view_port, Self.input_callback, @ptrCast(self));
 | 
			
		||||
//         c.gui_add_view_port(self.gui, self.view_port, c.GuiLayer.GuiLayerFullscreen);
 | 
			
		||||
 | 
			
		||||
//         return self;
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn deinit(self: *Self) void {
 | 
			
		||||
//         c.view_port_enabled_set(self.view_port, false);
 | 
			
		||||
//         c.gui_remove_view_port(self.gui, self.view_port);
 | 
			
		||||
//         c.view_port_free(self.view_port);
 | 
			
		||||
//         c.furi_message_queue_free(self.input_queue);
 | 
			
		||||
//         c.furi_mutex_free(self.mutex);
 | 
			
		||||
//         c.furi_record_close(c.RECORD_GUI);
 | 
			
		||||
//         self.allocator.destroy(self);
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn update(self: *Self) void {
 | 
			
		||||
//         var event: c.InputEvent = undefined;
 | 
			
		||||
//         _ = c.furi_message_queue_get(self.input_queue, @ptrCast(&event), @intFromEnum(c.FuriWait.FuriWaitForever));
 | 
			
		||||
 | 
			
		||||
//         self.input_event = &event;
 | 
			
		||||
 | 
			
		||||
//         if (event.type == c.InputType.InputTypeShort and event.key == c.InputKey.InputKeyBack) {
 | 
			
		||||
//             self.running = !self.running;
 | 
			
		||||
//         }
 | 
			
		||||
 | 
			
		||||
//         c.view_port_update(self.view_port);
 | 
			
		||||
//         self.acc += 1;
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     fn draw_callback(canvas: *anyopaque, context: ?*anyopaque) callconv(.C) void {
 | 
			
		||||
//         const self: *Self = @alignCast(@ptrCast(context.?));
 | 
			
		||||
 | 
			
		||||
//         var c_buf = std.mem.zeroes([32:0]u8);
 | 
			
		||||
//         _ = c.snprintf(&c_buf, 32, "snprintf: %d", self.acc);
 | 
			
		||||
 | 
			
		||||
//         var zig_buf = std.mem.zeroes([32:0]u8);
 | 
			
		||||
//         _ = std.fmt.bufPrint(&zig_buf, "bufPrint: {}", .{self.acc}) catch return;
 | 
			
		||||
 | 
			
		||||
//         const alloc_buf = std.fmt.allocPrintZ(self.allocator, "allocPrint: {}", .{self.acc}) catch return;
 | 
			
		||||
//         defer self.allocator.free(alloc_buf);
 | 
			
		||||
 | 
			
		||||
//         c.canvas_clear(canvas);
 | 
			
		||||
//         c.canvas_set_font(canvas, c.Font.FontPrimary);
 | 
			
		||||
//         c.canvas_draw_str(canvas, 0, 10, &c_buf);
 | 
			
		||||
//         c.canvas_draw_str(canvas, 0, 20, &zig_buf);
 | 
			
		||||
//         c.canvas_draw_str(canvas, 0, 30, alloc_buf);
 | 
			
		||||
 | 
			
		||||
//         if (self.input_event) |input_event| {
 | 
			
		||||
//             const type_buf = std.fmt.allocPrintZ(self.allocator, "InputType: {s}", .{c.input_get_type_name(input_event.type)}) catch return;
 | 
			
		||||
//             defer self.allocator.free(type_buf);
 | 
			
		||||
//             c.canvas_draw_str(canvas, 0, 40, type_buf);
 | 
			
		||||
 | 
			
		||||
//             const key_buf = std.fmt.allocPrintZ(self.allocator, "InputKey: {s}", .{c.input_get_key_name(input_event.key)}) catch return;
 | 
			
		||||
//             defer self.allocator.free(key_buf);
 | 
			
		||||
//             c.canvas_draw_str(canvas, 0, 50, key_buf);
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     fn input_callback(input_event: *c.InputEvent, context: ?*anyopaque) callconv(.C) void {
 | 
			
		||||
//         const self: *Self = @alignCast(@ptrCast(context.?));
 | 
			
		||||
 | 
			
		||||
//         _ = c.furi_message_queue_put(self.input_queue, input_event, @intFromEnum(c.FuriWait.FuriWaitForever));
 | 
			
		||||
//     }
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
const Zlipper = struct {
 | 
			
		||||
    allocator: std.mem.Allocator,
 | 
			
		||||
    mutex: *fz.thread.FuriMutex,
 | 
			
		||||
    gui: *fz.gui.Gui,
 | 
			
		||||
    view_port: *fz.gui.ViewPort,
 | 
			
		||||
    input_queue: *fz.atomic.FuriMessageQueue(fz.c.InputEvent),
 | 
			
		||||
    input_event: ?*const fz.c.InputEvent,
 | 
			
		||||
    running: bool,
 | 
			
		||||
    acc: u32,
 | 
			
		||||
 | 
			
		||||
    const Self = @This();
 | 
			
		||||
 | 
			
		||||
    pub fn init(allocator: std.mem.Allocator) *Self {
 | 
			
		||||
        const self = allocator.create(Self) catch unreachable;
 | 
			
		||||
        self.* = Self{
 | 
			
		||||
            .allocator = allocator,
 | 
			
		||||
            .mutex = fz.thread.FuriMutex.create(fz.c.FuriMutexType.FuriMutexTypeNormal),
 | 
			
		||||
            .gui = fz.gui.Gui.open(),
 | 
			
		||||
            .view_port = fz.gui.ViewPort.create(),
 | 
			
		||||
            .input_queue = fz.atomic.FuriMessageQueue(fz.c.InputEvent).create(8),
 | 
			
		||||
            .input_event = null,
 | 
			
		||||
            .running = true,
 | 
			
		||||
            .acc = 0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        self.view_port.setDrawCallback(Self.draw_callback, @ptrCast(self));
 | 
			
		||||
        self.view_port.setInputCallback(Self.input_callback, @ptrCast(self));
 | 
			
		||||
        self.gui.addViewPort(self.view_port, fz.c.GuiLayer.GuiLayerFullscreen);
 | 
			
		||||
 | 
			
		||||
        return self;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn deinit(self: *Self) void {
 | 
			
		||||
        self.view_port.setEnabled(false);
 | 
			
		||||
        self.gui.removeViewPort(self.view_port);
 | 
			
		||||
        self.view_port.destroy();
 | 
			
		||||
        self.input_queue.destroy();
 | 
			
		||||
        self.mutex.destroy();
 | 
			
		||||
        self.gui.close();
 | 
			
		||||
        self.allocator.destroy(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update(self: *Self) void {
 | 
			
		||||
        var event: fz.c.InputEvent = undefined;
 | 
			
		||||
        self.input_queue.get(&event, @intFromEnum(fz.c.FuriWait.FuriWaitForever));
 | 
			
		||||
 | 
			
		||||
        self.input_event = &event;
 | 
			
		||||
 | 
			
		||||
        if (event.type == fz.c.InputType.InputTypeShort and event.key == fz.c.InputKey.InputKeyBack) {
 | 
			
		||||
            self.running = !self.running;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.view_port.update();
 | 
			
		||||
        self.acc += 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn draw_callback(canvas_: *anyopaque, context: ?*anyopaque) callconv(.C) void {
 | 
			
		||||
        const self: *Self = @alignCast(@ptrCast(context.?));
 | 
			
		||||
        const canvas: *fz.gui.Canvas = @ptrCast(canvas_);
 | 
			
		||||
 | 
			
		||||
        var c_buf = std.mem.zeroes([32:0]u8);
 | 
			
		||||
        _ = fz.c.snprintf(&c_buf, 32, "snprintf: %d", self.acc);
 | 
			
		||||
 | 
			
		||||
        var zig_buf = std.mem.zeroes([32:0]u8);
 | 
			
		||||
        _ = std.fmt.bufPrint(&zig_buf, "bufPrint: {}", .{self.acc}) catch return;
 | 
			
		||||
 | 
			
		||||
        const alloc_buf = std.fmt.allocPrintZ(self.allocator, "allocPrint: {}", .{self.acc}) catch return;
 | 
			
		||||
        defer self.allocator.free(alloc_buf);
 | 
			
		||||
 | 
			
		||||
        canvas.clear();
 | 
			
		||||
        canvas.setFont(fz.c.Font.FontPrimary);
 | 
			
		||||
        canvas.drawStr(0, 10, &c_buf);
 | 
			
		||||
        canvas.drawStr(0, 20, &zig_buf);
 | 
			
		||||
        canvas.drawStr(0, 30, alloc_buf);
 | 
			
		||||
 | 
			
		||||
        if (self.input_event) |input_event| {
 | 
			
		||||
            const type_buf = std.fmt.allocPrintZ(self.allocator, "InputType: {s}", .{fz.c.input_get_type_name(input_event.type)}) catch return;
 | 
			
		||||
            defer self.allocator.free(type_buf);
 | 
			
		||||
            canvas.drawStr(0, 40, type_buf);
 | 
			
		||||
 | 
			
		||||
            const key_buf = std.fmt.allocPrintZ(self.allocator, "InputKey: {s}", .{fz.c.input_get_key_name(input_event.key)}) catch return;
 | 
			
		||||
            defer self.allocator.free(key_buf);
 | 
			
		||||
            canvas.drawStr(0, 50, key_buf);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn input_callback(input_event: *fz.c.InputEvent, context: ?*anyopaque) callconv(.C) void {
 | 
			
		||||
        const self: *Self = @alignCast(@ptrCast(context.?));
 | 
			
		||||
        self.input_queue.put(input_event, @intFromEnum(fz.c.FuriWait.FuriWaitForever));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// const ZlipperView = enum(u8) {
 | 
			
		||||
//     MainMenu,
 | 
			
		||||
//     FileBrowser,
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
// const Zlipper = struct {
 | 
			
		||||
//     allocator: std.mem.Allocator,
 | 
			
		||||
//     gui: *fz.gui.Gui,
 | 
			
		||||
//     storage: *fz.storage.Storage,
 | 
			
		||||
//     scene_manager: *fz.gui.SceneManager,
 | 
			
		||||
//     view_dispatcher: *fz.gui.ViewDispatcher,
 | 
			
		||||
//     // file_browser_output: *fz.string.
 | 
			
		||||
//     running: bool,
 | 
			
		||||
 | 
			
		||||
//     const Self = @This();
 | 
			
		||||
 | 
			
		||||
//     pub fn init(allocator: std.mem.Allocator) *Self {
 | 
			
		||||
//         const self = allocator.create(Self) catch unreachable;
 | 
			
		||||
//         self.* = Self {
 | 
			
		||||
//             .allocator = allocator,
 | 
			
		||||
//             .gui = fz.gui.Gui.open(),
 | 
			
		||||
//             .storage = fz.storage.Storage.open(),
 | 
			
		||||
//             .scene_manager = fz.gui.SceneManager.create(),
 | 
			
		||||
//             .view_dispatcher = fz.gui.ViewDispatcher.create(),
 | 
			
		||||
//             .running = true,
 | 
			
		||||
//         };
 | 
			
		||||
 | 
			
		||||
//         self.view_dispatcher.enableQueue();
 | 
			
		||||
//         self.view_dispatcher.setEventCallbackContext(@ptrCast(self));
 | 
			
		||||
//         self.view_dispatcher.setCustomEventCallback(Self.customEventCallback);
 | 
			
		||||
//         self.view_dispatcher.setNavigationEventCallback(Self.navigationEventCallback);
 | 
			
		||||
//         self.view_dispatcher.attachToGui(self.gui, fz.c.ViewDispatcherType.ViewDispatcherTypeFullscreen);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//         return self;
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn customEventCallback(context: ?*anyopaque, event: u32) callconv(.C) void {
 | 
			
		||||
//         const self: *Self = @alignCast(@ptrCast(context));
 | 
			
		||||
//         _ = self;
 | 
			
		||||
//         _ = event;
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn navigationEventCallback(context: ?*anyopaque) callconv(.C) void {
 | 
			
		||||
//         const self: *Self = @alignCast(@ptrCast(context));
 | 
			
		||||
//         _ = self;
 | 
			
		||||
//     } 
 | 
			
		||||
 | 
			
		||||
//     pub fn update(self: *Self) void {
 | 
			
		||||
//         self.running = false;
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     pub fn deinit(self: *Self) void {
 | 
			
		||||
//         self.view_dispatcher.removeView(ZlipperView.MainMenu);
 | 
			
		||||
//         self.view_dispatcher.destroy();
 | 
			
		||||
//         self.scene_manager.destroy();
 | 
			
		||||
//         self.storage.close();
 | 
			
		||||
//         self.gui.close();
 | 
			
		||||
//         self.allocator.destroy(self);
 | 
			
		||||
//     }
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
// Application
 | 
			
		||||
pub fn main(args: *u8) i32 {
 | 
			
		||||
    _ = args;
 | 
			
		||||
 | 
			
		||||
    var zlipper = Zlipper.init(fz.heap.furi_allocator);
 | 
			
		||||
    defer zlipper.deinit();
 | 
			
		||||
 | 
			
		||||
    while (zlipper.running) {
 | 
			
		||||
        zlipper.update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/start.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/start.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
// Imports
 | 
			
		||||
const flipperzero = @import("flipperzero");
 | 
			
		||||
const app = @import("app.zig");
 | 
			
		||||
const manifest = flipperzero.manifest;
 | 
			
		||||
 | 
			
		||||
// Manifest
 | 
			
		||||
export const FAP_MANIFEST linksection(".fapmeta") = manifest.createApplicationManifest(2048, 1, "Zlipper", 0, null);
 | 
			
		||||
 | 
			
		||||
// Entry function
 | 
			
		||||
export fn _start(args: *u8) i32 {
 | 
			
		||||
    return app.main(args);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user