hello_world/
hello-world.rs1#![no_std]
4extern crate alloc;
5use core::ffi::*;
6use core::ptr::null_mut;
7use alloc::boxed::Box;
8
9#[macro_use]
10extern crate playdate_sys as pd;
11use pd::ffi::*;
12
13
14const INITIAL_X: u32 = LCD_COLUMNS / 2;
15const INITIAL_Y: u32 = (pd::ffi::LCD_ROWS - TEXT_HEIGHT) / 2;
16const TEXT_HEIGHT: u32 = 16;
17const TEXT: &str = "Hello, Rust World";
18
19
20struct Point<T> {
22 x: T,
23 y: T,
24}
25
26impl<T> Point<T> {
27 const fn new(x: T, y: T) -> Point<T> { Point { x, y } }
28}
29
30
31struct State {
33 location: Point<i32>,
34 velocity: Point<i32>,
35}
36
37impl State {
38 const fn new() -> Self {
39 Self { location: Point::new(INITIAL_X as _, INITIAL_Y as _),
40 velocity: Point::new(1, 2) }
41 }
42
43
44 fn update(&mut self) -> Option<()> {
46 unsafe {
47 let graphics = (*pd::API).graphics;
48 (*graphics).clear?(LCDSolidColor::kColorWhite as LCDColor);
49
50 let c_text = CString::new(TEXT).ok()?;
51 let text_width = (*graphics).getTextWidth?(
52 null_mut(),
53 c_text.as_ptr() as *const _,
54 TEXT.len(),
55 PDStringEncoding::kUTF8Encoding,
56 0,
57 );
58 (*graphics).drawText?(
59 c_text.as_ptr() as *const _,
60 TEXT.len(),
61 PDStringEncoding::kUTF8Encoding,
62 self.location.x,
63 self.location.y,
64 );
65
66 self.location.x += self.velocity.x;
67 self.location.y += self.velocity.y;
68
69 if self.location.x < 0 || self.location.x > LCD_COLUMNS as i32 - text_width {
70 self.velocity.x = -self.velocity.x;
71 }
72
73 if self.location.y < 0 || self.location.y > LCD_ROWS as i32 - TEXT_HEIGHT as i32 {
74 self.velocity.y = -self.velocity.y;
75 }
76
77 (*(*pd::API).system).drawFPS?(0, 0);
78 Some(())
79 }
80 }
81
82
83 fn event(&mut self, event: PDSystemEvent) -> Option<()> {
85 match event {
86 PDSystemEvent::kEventInit => unsafe {
88 (*(*pd::API).display).setRefreshRate?(20.0);
89 },
90 _ => {},
91 }
92 Some(())
93 }
94}
95
96
97#[no_mangle]
98pub extern "C" fn eventHandlerShim(api: *const PlaydateAPI, event: PDSystemEvent, _arg: u32) -> c_int {
100 static mut STATE: Option<Box<State>> = None;
101
102 match event {
103 PDSystemEvent::kEventInit => unsafe {
104 pd::API = api;
106
107 if STATE.is_none() {
109 STATE = Some(Box::new(State::new()));
110 }
111 let state = STATE.as_mut().unwrap().as_mut() as *mut State;
112
113 let f = (*(*api).system).setUpdateCallback.expect("setUpdateCallback");
115 f(Some(on_update), state.cast());
117 },
118 _ => {},
119 }
120
121 if let Some(state) = unsafe { STATE.as_mut() } {
122 state.event(event).and(Some(0)).unwrap_or(1)
123 } else {
124 1
125 }
126}
127
128
129unsafe extern "C" fn on_update(state: *mut c_void) -> i32 {
131 let ptr: *mut State = state.cast();
132 let state = ptr.as_mut().expect("missed state");
133 state.update().and(Some(1)).unwrap_or_default()
134}
135
136
137ll_symbols!();