Skip to content

Commit e00af9d

Browse files
committed
Mandelrust
1 parent 6e861ef commit e00af9d

File tree

4 files changed

+242
-13
lines changed

4 files changed

+242
-13
lines changed

.cargo/config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[target.thumbv7em-none-eabihf]
2-
runner = 'npx --yes -- [email protected].15 install-nwa'
2+
runner = 'npx --yes -- [email protected].16 install-nwa'
33
rustflags = ["-C", "link-arg=--relocatable", "-C", "link-arg=-no-gc-sections"]
44

55
[build]

src/eadk.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#[repr(C)]
2+
#[derive(Clone,Copy)]
23
pub struct Color {
34
pub rgb565: u16
45
}
@@ -95,6 +96,76 @@ extern "C" {
9596
fn eadk_random() -> u32;
9697
}
9798

99+
pub mod keyboard {
100+
pub struct Scan {
101+
value: u64
102+
}
103+
104+
impl Scan {
105+
pub fn scan() -> Scan {
106+
unsafe {
107+
Scan { value: eadk_keyboard_scan() }
108+
}
109+
}
110+
111+
pub fn is_key_down(&self, key: Key) -> bool {
112+
(self.value & (1 << key as u8)) != 0
113+
}
114+
}
115+
116+
pub enum Key {
117+
Left = 0,
118+
Up = 1,
119+
Down = 2,
120+
Right = 3,
121+
Ok = 4,
122+
Back = 5,
123+
Home = 6,
124+
Shift = 12,
125+
Alpha = 13,
126+
Xnt = 14,
127+
Bar = 15,
128+
Toolbox = 16,
129+
Backspace = 17,
130+
Exp = 18,
131+
Ln = 19,
132+
Log = 20,
133+
Imaginary = 21,
134+
Comma = 22,
135+
Power = 23,
136+
Sine = 24,
137+
Cosine = 25,
138+
Tangent = 26,
139+
Pi = 27,
140+
Sqrt = 28,
141+
Square = 29,
142+
Seven = 30,
143+
Eight = 31,
144+
Nine = 32,
145+
LeftParenthesis = 33,
146+
RightParenthesis = 34,
147+
Four = 36,
148+
Five = 37,
149+
Six = 38,
150+
Multiplication = 39,
151+
Division = 40,
152+
One = 42,
153+
Two = 43,
154+
Three = 44,
155+
Plus = 45,
156+
Minus = 46,
157+
Zero = 48,
158+
Dot = 49,
159+
EE = 50,
160+
Ans = 51,
161+
Exe = 52,
162+
}
163+
164+
extern "C" {
165+
fn eadk_keyboard_scan() -> u64;
166+
}
167+
}
168+
98169
use core::panic::PanicInfo;
99170

100171
#[panic_handler]

src/icon.png

6.28 KB
Loading

src/main.rs

Lines changed: 170 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,191 @@
22
#![no_main]
33

44
pub mod eadk;
5+
use eadk::*;
6+
7+
use core::ops::Range;
8+
9+
#[allow(non_upper_case_globals)]
510

611
#[used]
712
#[link_section = ".rodata.eadk_app_name"]
8-
pub static EADK_APP_NAME: [u8; 10] = *b"HelloRust\0";
13+
pub static EADK_APP_NAME: [u8; 11] = *b"Mandelrust\0";
914

1015
#[used]
1116
#[link_section = ".rodata.eadk_api_level"]
1217
pub static EADK_APP_API_LEVEL: u32 = 0;
1318

1419
#[used]
1520
#[link_section = ".rodata.eadk_app_icon"]
16-
pub static EADK_APP_ICON: [u8; 4250] = *include_bytes!("../target/icon.nwi");
21+
pub static EADK_APP_ICON: [u8; 2648] = *include_bytes!("../target/icon.nwi");
22+
23+
const WIDTH: usize = 320;
24+
const HEIGHT: usize = 240;
25+
26+
fn color_range(n : u8) -> Color {
27+
let n = n as u16;
28+
let r = (n/2)<<11;
29+
let g = (0xb7*n/0xff)<<5;
30+
let b = (0x34*n/0xff)>>1;
31+
Color { rgb565: r | g | b }
32+
}
33+
34+
const BHEIGHT : usize = 256;
1735

18-
fn random_u16() -> u16 {
19-
return eadk::random() as u16;
36+
struct Buffer {
37+
// 5 values of 6 bits per word
38+
buffer : [[u8; BHEIGHT]; WIDTH],
39+
dx : usize,
40+
dy : usize,
2041
}
2142

22-
fn random_coordinate() -> u16 {
23-
return (eadk::random() % 0xFF) as u16;
43+
impl Buffer {
44+
fn new() -> Buffer {
45+
Buffer { buffer: [[0; BHEIGHT]; WIDTH], dx: 0, dy: 0 }
46+
}
47+
48+
fn pos(&self, x: usize, y: usize) -> (usize, usize) {
49+
((x + self.dx)%WIDTH, (y + self.dy)%BHEIGHT)
50+
}
51+
52+
fn set(&mut self, x: usize, y:usize, v:u8) {
53+
let (xa, ya) = self.pos(x,y);
54+
self.buffer[xa][ya] = v;
55+
}
56+
57+
fn get(&self, x: usize, y: usize) -> u8 {
58+
let (xa, ya) = self.pos(x,y);
59+
self.buffer[xa][ya]
60+
}
61+
62+
fn scroll_x(&mut self, delta_x: isize) {
63+
self.dx = (((self.dx as isize) + delta_x + WIDTH as isize) as usize) % WIDTH;
64+
}
65+
66+
fn scroll_y(&mut self, delta_y: isize) {
67+
self.dy = (((self.dy as isize) + delta_y + BHEIGHT as isize) as usize) % BHEIGHT;
68+
}
69+
}
70+
71+
struct Zone {
72+
x_range: Range<usize>,
73+
y_range: Range<usize>,
74+
}
75+
76+
impl Zone {
77+
fn screen() -> Zone {
78+
Zone { x_range: 0..WIDTH, y_range: 0..HEIGHT }
79+
}
80+
}
81+
82+
fn mandel(buf: &mut Buffer, zone: Zone, x_center: f32, y_center: f32, width:f32, n:u8, coarse: bool) {
83+
let scale : f32 = width / WIDTH as f32;
84+
85+
for xi in zone.x_range {
86+
if coarse && xi%3 != 1 { continue }
87+
let cr : f32 = ((xi as i16 - (WIDTH/2) as i16) as f32)*scale+x_center;
88+
for yi in zone.y_range.clone() {
89+
if coarse && yi%3 != 1 { continue }
90+
let ci : f32 = ((yi as i16 - (HEIGHT/2) as i16) as f32)*scale+y_center;
91+
let mut zr : f32 = 0.;
92+
let mut zi : f32 = 0.;
93+
let mut v = 63;
94+
for n in 0..n {
95+
let ozr = zr;
96+
zr = zr*zr - zi*zi + cr;
97+
zi = 2.*ozr*zi + ci;
98+
if zr*zr + zi*zi > 4. {
99+
v = n;
100+
break;
101+
}
102+
}
103+
if coarse {
104+
for x in xi-1..=xi+1 {
105+
for y in yi-1..=yi+1 {
106+
buf.set(x, y, v);
107+
}
108+
}
109+
} else {
110+
buf.set(xi, yi, v);
111+
}
112+
}
113+
}
114+
}
115+
116+
fn blit(buf: &Buffer) {
117+
display::wait_for_vblank();
118+
const SIDE: usize = 16;
119+
let mut array = [Color { rgb565: 0 }; SIDE*SIDE];
120+
for x in 0..WIDTH/SIDE {
121+
for y in 0..HEIGHT/SIDE {
122+
for xi in 0..SIDE {
123+
for yi in 0..SIDE {
124+
array[yi*SIDE+xi] = color_range(buf.get(x*SIDE+xi,y*SIDE+yi));
125+
}
126+
}
127+
let r = Rect { x: (SIDE*x) as u16, y: (SIDE*y) as u16, width: SIDE
128+
as u16, height: SIDE as u16};
129+
display::push_rect(r, &array);
130+
}
131+
}
24132
}
25133

26134
#[no_mangle]
27-
pub fn main() {
28-
for _ in 0..100 {
29-
let c = eadk::Color { rgb565: random_u16() };
30-
let r = eadk::Rect { x: random_coordinate(), y: random_coordinate(), width: random_coordinate(), height: random_coordinate() };
31-
eadk::display::push_rect_uniform(r, c);
135+
fn main() {
136+
let mut buffer = Buffer::new();
137+
let mut x : f32 = -0.5;
138+
let mut y : f32 = 0.0;
139+
let mut n : u8 = 64;
140+
let mut size : f32 = 3.5;
141+
let mut was_coarse : bool = false;
142+
let delta_pixel : isize = 2;
143+
mandel(&mut buffer, Zone::screen(), x, y, size, n, false);
144+
blit(&buffer);
145+
loop {
146+
let scan = keyboard::Scan::scan();
147+
let mut zone = Zone::screen();
148+
use keyboard::Key::*;
149+
let factor = if scan.is_key_down(Shift) { 5 } else { 1 };
150+
let delta_pixel = factor * delta_pixel;
151+
let delta_size = delta_pixel as f32 * size / WIDTH as f32;
152+
let mut coarse = false;
153+
if scan.is_key_down(Plus) || scan.is_key_down(Ok) {
154+
size /= 1.5;
155+
coarse = true;
156+
was_coarse = true;
157+
} else if scan.is_key_down(Minus) || scan.is_key_down(Back) {
158+
size *= 1.5;
159+
coarse = true;
160+
was_coarse = true;
161+
} else if scan.is_key_down(Multiplication) {
162+
n = (n + 4).clamp(1,63);
163+
} else if scan.is_key_down(Division) {
164+
n = (n - 4).clamp(1,100);
165+
} else if scan.is_key_down(Left) {
166+
x -= delta_size;
167+
buffer.scroll_x(-delta_pixel);
168+
zone.x_range = 0..(delta_pixel as usize);
169+
} else if scan.is_key_down(Right) {
170+
x += delta_size;
171+
buffer.scroll_x(delta_pixel);
172+
zone.x_range= (WIDTH - delta_pixel as usize)..WIDTH;
173+
} else if scan.is_key_down(Up) {
174+
y -= delta_size;
175+
buffer.scroll_y(-delta_pixel);
176+
zone.y_range = 0..(delta_pixel as usize);
177+
} else if scan.is_key_down(Down) {
178+
y += delta_size;
179+
buffer.scroll_y(delta_pixel);
180+
zone.y_range = (HEIGHT - delta_pixel as usize)..HEIGHT;
181+
} else if scan.is_key_down(Zero) {
182+
x = -0.5; y = 0.0; size = 3.5; n = 40;
183+
} else if was_coarse {
184+
was_coarse = false;
185+
} else {
186+
continue;
187+
}
188+
size = size.min(3.5);
189+
mandel(&mut buffer,zone,x,y,size,n,coarse);
190+
blit(&buffer);
32191
}
33-
loop {}
34192
}

0 commit comments

Comments
 (0)