first commit
This commit is contained in:
commit
c591b2c272
50 changed files with 2650 additions and 0 deletions
19
.cargo/config.toml
Normal file
19
.cargo/config.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[build]
|
||||||
|
target = "arduboy.json"
|
||||||
|
target-dir = "./target"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = "fat"
|
||||||
|
opt-level = "z"
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = "fat"
|
||||||
|
opt-level = "z"
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
build-std = ["core", "compiler_builtins"]
|
||||||
|
build-std-features = ["compiler-builtins-mem"]
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/target
|
||||||
|
/.vscode
|
||||||
|
|
||||||
|
/Wrapper-Project/.pio
|
||||||
|
/Wrapper-Project/lib/*.a
|
95
Cargo.lock
generated
Normal file
95
Cargo.lock
generated
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arduboy-rust"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e80037f297e2a5db1e58804b7a3b1b10f448b104623422db1c94b185b45b1ea5"
|
||||||
|
dependencies = [
|
||||||
|
"panic-halt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "demo2"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "demo3"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "demo4"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "demo5"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "demo6"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "eeprom-demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "game"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "panic-halt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pong"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustacean"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "snake"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tone"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduboy-rust",
|
||||||
|
]
|
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"Examples/Arduboy-Tutorials/eeprom",
|
||||||
|
"Examples/Arduboy-Tutorials/tone",
|
||||||
|
"Examples/Arduboy-Tutorials/demo2",
|
||||||
|
"Examples/Arduboy-Tutorials/demo3",
|
||||||
|
"Examples/Arduboy-Tutorials/demo4",
|
||||||
|
"Examples/Arduboy-Tutorials/demo5",
|
||||||
|
"Examples/Arduboy-Tutorials/demo6",
|
||||||
|
"Examples/pong",
|
||||||
|
"Examples/rustacean",
|
||||||
|
"Examples/snake",
|
||||||
|
"Project/game",
|
||||||
|
]
|
||||||
|
resolver = "2"
|
11
Examples/Arduboy-Tutorials/demo2/Cargo.toml
Normal file
11
Examples/Arduboy-Tutorials/demo2/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "demo2"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ZennDev <zenndev@protonmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
18
Examples/Arduboy-Tutorials/demo2/src/lib.rs
Normal file
18
Examples/Arduboy-Tutorials/demo2/src/lib.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#![no_std]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
//The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
arduboy.begin();
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("Holmes is cool!\0");
|
||||||
|
arduboy.display();
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
// put your main code here, to run repeatedly:
|
||||||
|
}
|
11
Examples/Arduboy-Tutorials/demo3/Cargo.toml
Normal file
11
Examples/Arduboy-Tutorials/demo3/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "demo3"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ZennDev <zenndev@protonmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
38
Examples/Arduboy-Tutorials/demo3/src/lib.rs
Normal file
38
Examples/Arduboy-Tutorials/demo3/src/lib.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#![no_std]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
//Initialize our counter variable
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
static mut counter: c_int = 0;
|
||||||
|
//The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
//Start the Arduboy properly and display the Arduboy logo
|
||||||
|
arduboy.begin();
|
||||||
|
//Get rid of the Arduboy logo and clear the screen
|
||||||
|
arduboy.clear();
|
||||||
|
//Assign our counter variable to be equal to 0
|
||||||
|
counter = 0;
|
||||||
|
//Set framerate to 30
|
||||||
|
arduboy.set_frame_rate(30);
|
||||||
|
}
|
||||||
|
//The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
//Skip cycles not in the framerate
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Clear whatever is printed on the screen
|
||||||
|
arduboy.clear();
|
||||||
|
//Move the cursor to the position 30, 30 of the screen
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
//Increase counter's value by 1
|
||||||
|
counter += 1;
|
||||||
|
//Print out the value of counter
|
||||||
|
arduboy.print(counter);
|
||||||
|
//Refresh the screen to show whatever's printed to it
|
||||||
|
arduboy.display();
|
||||||
|
}
|
11
Examples/Arduboy-Tutorials/demo4/Cargo.toml
Normal file
11
Examples/Arduboy-Tutorials/demo4/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "demo4"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ZennDev <zenndev@protonmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
54
Examples/Arduboy-Tutorials/demo4/src/lib.rs
Normal file
54
Examples/Arduboy-Tutorials/demo4/src/lib.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
//Initialize our counter variable
|
||||||
|
|
||||||
|
static mut counter: c_int = 0;
|
||||||
|
//The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
//Start the Arduboy properly and display the Arduboy logo
|
||||||
|
arduboy.begin();
|
||||||
|
//Get rid of the Arduboy logo and clear the screen
|
||||||
|
arduboy.clear();
|
||||||
|
//Assign our counter variable to be equal to 0
|
||||||
|
counter = 0;
|
||||||
|
//Set framerate to 10
|
||||||
|
arduboy.set_frame_rate(10);
|
||||||
|
}
|
||||||
|
//The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
//Skip cycles not in the framerate
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Clear whatever is printed on the screen
|
||||||
|
arduboy.clear();
|
||||||
|
//Check if the UP_BUTTON is being pressed
|
||||||
|
if UP.pressed() {
|
||||||
|
//Increase counter by 1
|
||||||
|
counter = counter + 1;
|
||||||
|
}
|
||||||
|
//Check if the DOWN_BUTTON is being pressed
|
||||||
|
if DOWN.pressed() {
|
||||||
|
//Decrease counter
|
||||||
|
counter = counter - 1;
|
||||||
|
}
|
||||||
|
//Check if counter is equal to 36
|
||||||
|
if counter == 36 {
|
||||||
|
//Move the cursor to the position 30, 30 of the screen
|
||||||
|
arduboy.set_cursor(30, 30);
|
||||||
|
//Printing the yay (important always put the \0 at the end for &str)
|
||||||
|
arduboy.print("Yay!\0");
|
||||||
|
}
|
||||||
|
//Move the cursor back to the top-left of the screen
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
//Print out the value of counter
|
||||||
|
arduboy.print(counter);
|
||||||
|
//Refresh the screen to show whatever's printed to it
|
||||||
|
arduboy.display();
|
||||||
|
}
|
10
Examples/Arduboy-Tutorials/demo5/Cargo.toml
Normal file
10
Examples/Arduboy-Tutorials/demo5/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "demo5"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
95
Examples/Arduboy-Tutorials/demo5/src/lib.rs
Normal file
95
Examples/Arduboy-Tutorials/demo5/src/lib.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
//Initialize variables used in this game
|
||||||
|
static mut playerwin: c_int = 0;
|
||||||
|
static mut attempts: c_int = 0;
|
||||||
|
static mut guessednumber: c_int = 0;
|
||||||
|
static mut randomnumber: c_int = 0;
|
||||||
|
static mut lastguess: c_int = 0;
|
||||||
|
|
||||||
|
//The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
arduboy.begin();
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.init_random_seed();
|
||||||
|
randomnumber = random_between(1, 101) as i16;
|
||||||
|
}
|
||||||
|
//The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
// put your main code here, to run repeatedly:
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.poll_buttons();
|
||||||
|
if playerwin == 0 {
|
||||||
|
//Ask the player for a number and play the game
|
||||||
|
if attempts == 7 {
|
||||||
|
//Game Over screen
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.print("You lost!\0");
|
||||||
|
arduboy.print("\n\0");
|
||||||
|
arduboy.print("Correct Number: \0");
|
||||||
|
arduboy.print(randomnumber);
|
||||||
|
if A.just_pressed() {
|
||||||
|
randomnumber = random_between(1, 101) as i16;
|
||||||
|
attempts = 0;
|
||||||
|
playerwin = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Player has more attempts
|
||||||
|
if UP.just_pressed() {
|
||||||
|
guessednumber += 1;
|
||||||
|
}
|
||||||
|
if DOWN.just_pressed() {
|
||||||
|
guessednumber -= 1;
|
||||||
|
}
|
||||||
|
if A.just_pressed() {
|
||||||
|
if guessednumber == randomnumber {
|
||||||
|
playerwin += 1;
|
||||||
|
} else {
|
||||||
|
attempts += 1;
|
||||||
|
lastguess = guessednumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.print("Attempt: \0");
|
||||||
|
arduboy.print(attempts);
|
||||||
|
arduboy.print("\n\0");
|
||||||
|
arduboy.print("Number to guess: \0");
|
||||||
|
arduboy.print(guessednumber);
|
||||||
|
arduboy.print("\n\0");
|
||||||
|
if attempts == 0 {
|
||||||
|
arduboy.print("Good luck!\0");
|
||||||
|
} else {
|
||||||
|
arduboy.print(lastguess);
|
||||||
|
if lastguess > randomnumber {
|
||||||
|
arduboy.print(" is too high!\0");
|
||||||
|
}
|
||||||
|
if lastguess < randomnumber {
|
||||||
|
arduboy.print(" is too low!\0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Tell the player that they won!
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.print("You won!\0");
|
||||||
|
arduboy.print("\n\0");
|
||||||
|
arduboy.print("Correct Number: \0");
|
||||||
|
arduboy.print(randomnumber);
|
||||||
|
|
||||||
|
if A.just_pressed() {
|
||||||
|
randomnumber = random_between(1, 101) as c_int;
|
||||||
|
attempts = 0;
|
||||||
|
playerwin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arduboy.display();
|
||||||
|
}
|
10
Examples/Arduboy-Tutorials/demo6/Cargo.toml
Normal file
10
Examples/Arduboy-Tutorials/demo6/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "demo6"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
76
Examples/Arduboy-Tutorials/demo6/src/lib.rs
Normal file
76
Examples/Arduboy-Tutorials/demo6/src/lib.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
#[link_section = ".progmem.data"]
|
||||||
|
static background_sprite: [u8; 10] = [8, 8, 0x81, 0x00, 0x12, 0x40, 0x04, 0x11, 0x00, 0x04];
|
||||||
|
#[link_section = ".progmem.data"]
|
||||||
|
static player_sprite1: [u8; 34] = [
|
||||||
|
16, 16, 0xfe, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0x01, 0xc1, 0x01, 0x3d, 0x25, 0x25, 0x3d,
|
||||||
|
0x01, 0xfe, 0x7f, 0x80, 0x9c, 0xbc, 0xb0, 0xb0, 0xb2, 0xb2, 0xb3, 0xb0, 0xb0, 0xb0, 0xbc, 0x9c,
|
||||||
|
0x80, 0x7f,
|
||||||
|
];
|
||||||
|
#[link_section = ".progmem.data"]
|
||||||
|
static player_sprite2: [u8; 34] = [
|
||||||
|
16, 16, 0xfc, 0x02, 0x19, 0x25, 0x25, 0x19, 0x01, 0x01, 0x01, 0x01, 0x19, 0x25, 0x25, 0x19,
|
||||||
|
0x02, 0xfc, 0x3f, 0x40, 0x80, 0x98, 0x8c, 0x86, 0x82, 0x82, 0x82, 0x82, 0x86, 0x8c, 0x98, 0x80,
|
||||||
|
0x40, 0x3f,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Put your variables here
|
||||||
|
static mut playerx: c_int = 5;
|
||||||
|
static mut playery: c_int = 10;
|
||||||
|
static mut playermode: bool = false;
|
||||||
|
// The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
arduboy.begin();
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.set_frame_rate(60);
|
||||||
|
}
|
||||||
|
// The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// put your main code here, to run repeatedly:
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.poll_buttons();
|
||||||
|
|
||||||
|
if arduboy.pressed(LEFT) {
|
||||||
|
playerx -= 1;
|
||||||
|
}
|
||||||
|
if arduboy.pressed(RIGHT) {
|
||||||
|
playerx += 1;
|
||||||
|
}
|
||||||
|
if arduboy.pressed(UP) {
|
||||||
|
playery -= 1;
|
||||||
|
}
|
||||||
|
if arduboy.pressed(DOWN) {
|
||||||
|
playery += 1;
|
||||||
|
}
|
||||||
|
if arduboy.just_pressed(A) {
|
||||||
|
playermode = !playermode
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in (0..WIDTH).step_by(8) {
|
||||||
|
for j in (0..HEIGHT).step_by(8) {
|
||||||
|
sprites::draw_override(i.into(), j.into(), get_sprite_addr!(background_sprite), 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if playermode {
|
||||||
|
sprites::draw_override(playerx, playery, get_sprite_addr!(player_sprite1), 0);
|
||||||
|
} else {
|
||||||
|
sprites::draw_override(playerx, playery, get_sprite_addr!(player_sprite2), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.display();
|
||||||
|
}
|
12
Examples/Arduboy-Tutorials/eeprom/Cargo.toml
Normal file
12
Examples/Arduboy-Tutorials/eeprom/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "eeprom-demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ZennDev <zenndev@protonmail.com>"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
59
Examples/Arduboy-Tutorials/eeprom/src/lib.rs
Normal file
59
Examples/Arduboy-Tutorials/eeprom/src/lib.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
// #[link_section = ".progmem.data"]
|
||||||
|
|
||||||
|
// Setup eeprom memory
|
||||||
|
static mut eeprom: EEPROM = EEPROM::new(10);
|
||||||
|
|
||||||
|
static mut count: u8 = 0;
|
||||||
|
static mut MEM: u8 = 0;
|
||||||
|
|
||||||
|
// The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
arduboy.begin();
|
||||||
|
eeprom.init();
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.set_frame_rate(30);
|
||||||
|
}
|
||||||
|
// The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
// put your main code here, to run repeatedly:
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.poll_buttons();
|
||||||
|
if arduboy.just_pressed(UP) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
if arduboy.just_pressed(DOWN) {
|
||||||
|
count -= 1;
|
||||||
|
}
|
||||||
|
if arduboy.just_pressed(A) {
|
||||||
|
unsafe { eeprom.put(count) }
|
||||||
|
}
|
||||||
|
if arduboy.just_pressed(B) {
|
||||||
|
eeprom.get(&mut MEM)
|
||||||
|
}
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.print(count as u16);
|
||||||
|
|
||||||
|
arduboy.set_cursor(0, 30);
|
||||||
|
arduboy.print("Memory:\0");
|
||||||
|
arduboy.print(MEM as u16);
|
||||||
|
arduboy.set_cursor(0, 40);
|
||||||
|
arduboy.print("eeprom:\0");
|
||||||
|
|
||||||
|
arduboy.print(eeprom.read() as u16);
|
||||||
|
|
||||||
|
arduboy.display();
|
||||||
|
}
|
12
Examples/Arduboy-Tutorials/tone/Cargo.toml
Normal file
12
Examples/Arduboy-Tutorials/tone/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "tone"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ZennDev <zenndev@protonmail.com>"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
490
Examples/Arduboy-Tutorials/tone/src/lib.rs
Normal file
490
Examples/Arduboy-Tutorials/tone/src/lib.rs
Normal file
|
@ -0,0 +1,490 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
use arduboy_rust::arduboy_tone_pitch::*;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
#[link_section = ".progmem.data"]
|
||||||
|
static allNotes: [u16; 241] = [
|
||||||
|
NOTE_C0H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B0,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C1H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B1,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C2H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B2,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C3H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B3,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C4H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B4,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C5H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B5,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C6H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B6,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C7H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B7,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C8H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B8,
|
||||||
|
NDUR,
|
||||||
|
NOTE_C9H,
|
||||||
|
NDUR,
|
||||||
|
NOTE_CS9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_D9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_DS9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_E9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_F9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_FS9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_G9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_GS9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_A9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_AS9,
|
||||||
|
NDUR,
|
||||||
|
NOTE_B9,
|
||||||
|
NDUR,
|
||||||
|
TONES_REPEAT,
|
||||||
|
];
|
||||||
|
#[link_section = ".progmem.data"]
|
||||||
|
static sound1: [u16; 73] = [
|
||||||
|
NOTE_C1, 500, NOTE_C1H, 500, NOTE_G1, 500, NOTE_G1H, 500, NOTE_C2, 500, NOTE_C2H, 500, NOTE_G2,
|
||||||
|
500, NOTE_G2H, 500, NOTE_C3, 500, NOTE_C3H, 500, NOTE_G3, 500, NOTE_G3H, 500, NOTE_C4, 500,
|
||||||
|
NOTE_C4H, 500, NOTE_G4, 500, NOTE_G4H, 500, NOTE_C5, 500, NOTE_C5H, 500, NOTE_G5, 500,
|
||||||
|
NOTE_G5H, 500, NOTE_C6, 500, NOTE_C6H, 500, NOTE_G6, 500, NOTE_G6H, 500, NOTE_C7, 500,
|
||||||
|
NOTE_C7H, 500, NOTE_G7, 500, NOTE_G7H, 500, NOTE_C8, 500, NOTE_C8H, 500, NOTE_G8, 500,
|
||||||
|
NOTE_G8H, 500, NOTE_C9, 500, NOTE_C9H, 500, NOTE_G9, 500, NOTE_G9H, 500, TONES_END,
|
||||||
|
];
|
||||||
|
|
||||||
|
static mut circle_pos: i16 = 7;
|
||||||
|
const BUTTON_DELAY: u32 = 200;
|
||||||
|
|
||||||
|
// The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
arduboy.begin();
|
||||||
|
}
|
||||||
|
// The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
let mut in_ram: [u16; 43] = [
|
||||||
|
NOTE_E4,
|
||||||
|
400,
|
||||||
|
NOTE_D4,
|
||||||
|
200,
|
||||||
|
NOTE_C4,
|
||||||
|
400,
|
||||||
|
NOTE_REST,
|
||||||
|
200,
|
||||||
|
NOTE_D4,
|
||||||
|
200,
|
||||||
|
NOTE_C4,
|
||||||
|
300,
|
||||||
|
NOTE_REST,
|
||||||
|
100,
|
||||||
|
NOTE_C4,
|
||||||
|
300,
|
||||||
|
NOTE_REST,
|
||||||
|
100,
|
||||||
|
NOTE_E4,
|
||||||
|
300,
|
||||||
|
NOTE_REST,
|
||||||
|
100,
|
||||||
|
NOTE_G4,
|
||||||
|
300,
|
||||||
|
NOTE_REST,
|
||||||
|
100,
|
||||||
|
NOTE_F4,
|
||||||
|
300,
|
||||||
|
NOTE_REST,
|
||||||
|
100,
|
||||||
|
NOTE_A4,
|
||||||
|
300,
|
||||||
|
NOTE_REST,
|
||||||
|
100,
|
||||||
|
NOTE_D5H,
|
||||||
|
200,
|
||||||
|
NOTE_REST,
|
||||||
|
200,
|
||||||
|
NOTE_D5H,
|
||||||
|
200,
|
||||||
|
NOTE_REST,
|
||||||
|
1500,
|
||||||
|
TONES_REPEAT,
|
||||||
|
];
|
||||||
|
// put your main code here, to run repeatedly:
|
||||||
|
let mut new_notes: bool;
|
||||||
|
display_audio();
|
||||||
|
loop {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(UP) {
|
||||||
|
arduboy.audio_on();
|
||||||
|
display_audio();
|
||||||
|
}
|
||||||
|
if arduboy.pressed(DOWN) {
|
||||||
|
arduboy.audio_off();
|
||||||
|
display_audio();
|
||||||
|
}
|
||||||
|
if arduboy.pressed(B) {
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.tone(1000, 0);
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("tone(1000)\n\nB: no_tone()\n delay(1000)\n break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B_BUTTON) {
|
||||||
|
sound.no_tone();
|
||||||
|
delay(1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.tone(500, 4000);
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("tone(500, 4000)\n\nB: break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B_BUTTON) {
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.tone2(NOTE_C4, 500, NOTE_C5H, 5000);
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("tone(C4,500,C5H,5000)\n\nB: no_tone(), break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B_BUTTON) {
|
||||||
|
sound.no_tone();
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.tone3(NOTE_C7H, 500, NOTE_REST, 1000, NOTE_C6, 5000);
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("tone(C7H,500,\n REST,1000,\n C6,6000)\n\nB: no_tone(), break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B_BUTTON) {
|
||||||
|
sound.no_tone();
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.tones(get_tones_addr!(allNotes));
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("tones(allNotes)\n\nA: no_tone(), again\nUP: again\nB: break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(A_BUTTON) {
|
||||||
|
sound.no_tone();
|
||||||
|
sound.tones(get_tones_addr!(allNotes));
|
||||||
|
}
|
||||||
|
if arduboy.pressed(UP_BUTTON) {
|
||||||
|
sound.tones(get_tones_addr!(allNotes));
|
||||||
|
}
|
||||||
|
if arduboy.pressed(B_BUTTON) {
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_notes = false;
|
||||||
|
sound.tones_in_ram(get_tones_addr!(in_ram) as *mut u32);
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("tonesInRAM(inRAM)\n\nA: change notes\nB: break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(A_BUTTON) {
|
||||||
|
new_notes = !new_notes;
|
||||||
|
if new_notes {
|
||||||
|
in_ram[34] = in_ram[38];
|
||||||
|
in_ram[38] = NOTE_C5H;
|
||||||
|
} else {
|
||||||
|
in_ram[34] = in_ram[38];
|
||||||
|
in_ram[38] = NOTE_D5H;
|
||||||
|
}
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
}
|
||||||
|
if arduboy.pressed(B) {
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.tones(get_tones_addr!(sound1));
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("volume_mode(IN_TONES)\ntones(sound1)\n\nB: break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B) {
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.volume_mode(VOLUME_ALWAYS_NORMAL);
|
||||||
|
sound.tones(get_tones_addr!(sound1));
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("volume_mode(NORMAL)\ntones(sound1)\n\nB: no_tone(), break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B) {
|
||||||
|
sound.no_tone();
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.volume_mode(VOLUME_ALWAYS_HIGH);
|
||||||
|
sound.tones(get_tones_addr!(sound1));
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("volume_mode(HIGH)\ntones(sound1)\n\nB: break\0");
|
||||||
|
while sound.playing() {
|
||||||
|
move_circle();
|
||||||
|
if arduboy.pressed(B) {
|
||||||
|
delay(BUTTON_DELAY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sound.volume_mode(VOLUME_IN_TONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_circle() {
|
||||||
|
unsafe {
|
||||||
|
arduboy.fill_circle(circle_pos, 54, 7, Color::Black);
|
||||||
|
circle_pos += 8;
|
||||||
|
if circle_pos > 119 {
|
||||||
|
circle_pos = 7;
|
||||||
|
}
|
||||||
|
arduboy.fill_circle(circle_pos, 54, 7, Color::White);
|
||||||
|
}
|
||||||
|
arduboy.display();
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_audio() {
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.print("Audio enabled: \0");
|
||||||
|
if arduboy.audio_enabled() {
|
||||||
|
arduboy.print("YES\0");
|
||||||
|
} else {
|
||||||
|
arduboy.print("NO\0")
|
||||||
|
}
|
||||||
|
|
||||||
|
arduboy.print("\n\nUP: enable\nDOWN: disable\nB: break\0");
|
||||||
|
arduboy.invert(!arduboy.audio_enabled());
|
||||||
|
}
|
12
Examples/pong/Cargo.toml
Normal file
12
Examples/pong/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "pong"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Brian Bowman <seeker14491@gmail.com>"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
230
Examples/pong/src/lib.rs
Normal file
230
Examples/pong/src/lib.rs
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
enum GameState {
|
||||||
|
Title,
|
||||||
|
Gameplay,
|
||||||
|
Win,
|
||||||
|
Lose,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Ball {
|
||||||
|
x: i16,
|
||||||
|
y: i16,
|
||||||
|
size: u8,
|
||||||
|
right: bool,
|
||||||
|
down: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ball {
|
||||||
|
unsafe fn draw(&self) {
|
||||||
|
arduboy.fill_rect(self.x.into(), self.y.into(), self.size, self.size, Color::White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Paddle {
|
||||||
|
x: i16,
|
||||||
|
y: i16,
|
||||||
|
width: u8,
|
||||||
|
height: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Paddle {
|
||||||
|
unsafe fn draw(&self) {
|
||||||
|
arduboy.fill_rect(self.x.into(), self.y.into(), self.width, self.height, Color::White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut G: Globals = Globals {
|
||||||
|
game_state: GameState::Title,
|
||||||
|
player_score: 0,
|
||||||
|
ai_score: 0,
|
||||||
|
ball: Ball {
|
||||||
|
x: 62,
|
||||||
|
y: 1,
|
||||||
|
size: 4,
|
||||||
|
right: true,
|
||||||
|
down: true,
|
||||||
|
},
|
||||||
|
player: Paddle {
|
||||||
|
x: 0,
|
||||||
|
y: 50,
|
||||||
|
width: 2,
|
||||||
|
height: 12,
|
||||||
|
},
|
||||||
|
ai: Paddle {
|
||||||
|
x: (WIDTH - 4) as i16,
|
||||||
|
y: 50,
|
||||||
|
width: 2,
|
||||||
|
height: 12,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Globals {
|
||||||
|
game_state: GameState,
|
||||||
|
player_score: u8,
|
||||||
|
ai_score: u8,
|
||||||
|
ball: Ball,
|
||||||
|
player: Paddle,
|
||||||
|
ai: Paddle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
arduboy.begin();
|
||||||
|
arduboy.init_random_seed();
|
||||||
|
arduboy.set_frame_rate(60);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arduboy.poll_buttons();
|
||||||
|
|
||||||
|
arduboy.clear();
|
||||||
|
match G.game_state {
|
||||||
|
GameState::Title => {
|
||||||
|
arduboy.set_cursor(52, 10);
|
||||||
|
arduboy.print(&b"PONG\0"[..]);
|
||||||
|
arduboy.set_cursor(16, 22);
|
||||||
|
arduboy.print(&b"Press A to start\0"[..]);
|
||||||
|
if A.just_pressed() {
|
||||||
|
G.game_state = GameState::Gameplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameState::Gameplay => {
|
||||||
|
gameplay();
|
||||||
|
if A.just_pressed() {
|
||||||
|
reset_game();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameState::Win => {
|
||||||
|
arduboy.set_cursor(40, 10);
|
||||||
|
arduboy.print(&b"You Win!\0"[..]);
|
||||||
|
if A.just_pressed() {
|
||||||
|
reset_game();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameState::Lose => {
|
||||||
|
arduboy.set_cursor(37, 10);
|
||||||
|
arduboy.print(&b"Game Over\0"[..]);
|
||||||
|
if A.just_pressed() {
|
||||||
|
reset_game();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arduboy.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn reset_game() {
|
||||||
|
G.game_state = GameState::Title;
|
||||||
|
G.ball.x = (WIDTH / 2) as i16;
|
||||||
|
G.player_score = 0;
|
||||||
|
G.ai_score = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn gameplay() {
|
||||||
|
//
|
||||||
|
// Player movement
|
||||||
|
//
|
||||||
|
|
||||||
|
if UP.pressed() && G.player.y > 0 {
|
||||||
|
G.player.y -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if DOWN.pressed() && G.player.y + (G.player.height as i16) < (HEIGHT - 1) as i16 {
|
||||||
|
G.player.y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// AI movement
|
||||||
|
//
|
||||||
|
|
||||||
|
if G.ball.x > 115 || random_between(0, 20) == 0 {
|
||||||
|
if G.ball.y < G.ai.y {
|
||||||
|
G.ai.y -= 1;
|
||||||
|
} else if G.ball.y + (G.ball.size as i16) > G.ai.y + G.ai.height as i16 {
|
||||||
|
G.ai.y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ball movement
|
||||||
|
//
|
||||||
|
|
||||||
|
if G.ball.y == 1 {
|
||||||
|
G.ball.down = true;
|
||||||
|
} else if G.ball.y + G.ball.size as i16 == (HEIGHT - 1) as i16 {
|
||||||
|
G.ball.down = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if G.ball.x == G.player.x + G.player.width as i16
|
||||||
|
&& G.ball.y + G.ball.size as i16 > G.player.y
|
||||||
|
&& G.ball.y < G.player.y + G.player.height as i16
|
||||||
|
{
|
||||||
|
G.ball.right = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if G.ball.x + G.ball.size as i16 == G.ai.x
|
||||||
|
&& G.ball.y + G.ball.size as i16 > G.ai.y
|
||||||
|
&& G.ball.y < G.ai.y + G.ai.height as i16
|
||||||
|
{
|
||||||
|
G.ball.right = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if G.ball.right {
|
||||||
|
G.ball.x += 1;
|
||||||
|
} else {
|
||||||
|
G.ball.x -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if G.ball.down {
|
||||||
|
G.ball.y += 1;
|
||||||
|
} else {
|
||||||
|
G.ball.y -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// Scoring
|
||||||
|
if G.ball.x + G.ball.size as i16 == -10 {
|
||||||
|
G.ai_score += 1;
|
||||||
|
G.ball.x = (WIDTH / 2) as i16;
|
||||||
|
G.ball.right = true;
|
||||||
|
} else if G.ball.x == (WIDTH + 10) as i16 {
|
||||||
|
G.player_score += 1;
|
||||||
|
G.ball.x = (WIDTH / 2) as i16;
|
||||||
|
G.ball.right = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if G.player_score == 5 {
|
||||||
|
G.game_state = GameState::Win;
|
||||||
|
} else if G.ai_score == 5 {
|
||||||
|
G.game_state = GameState::Lose;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Drawing
|
||||||
|
//
|
||||||
|
|
||||||
|
arduboy.set_cursor(20, 2);
|
||||||
|
arduboy.print(G.player_score as u16);
|
||||||
|
|
||||||
|
arduboy.set_cursor(101, 2);
|
||||||
|
arduboy.print(G.ai_score as u16);
|
||||||
|
|
||||||
|
arduboy.draw_fast_hline(0, 0, WIDTH, Color::White);
|
||||||
|
arduboy.draw_fast_hline(0, (HEIGHT - 1) as i16, WIDTH, Color::White);
|
||||||
|
|
||||||
|
G.player.draw();
|
||||||
|
G.ai.draw();
|
||||||
|
G.ball.draw();
|
||||||
|
}
|
10
Examples/rustacean/Cargo.toml
Normal file
10
Examples/rustacean/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "rustacean"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
74
Examples/rustacean/src/lib.rs
Normal file
74
Examples/rustacean/src/lib.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#![no_std]
|
||||||
|
#![feature(c_size_t)]
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
const BOTTOM: u8 = 64;
|
||||||
|
const RIGHT_END: u8 = 128;
|
||||||
|
|
||||||
|
const CHAR_WIDTH: u8 = 6;
|
||||||
|
const CHAR_HEIGHT: u8 = 8;
|
||||||
|
|
||||||
|
const MSG: &str = " I'm now a \0";
|
||||||
|
const MSG2: &str = "Rustacean <3\0";
|
||||||
|
|
||||||
|
struct Environment {
|
||||||
|
x: u8,
|
||||||
|
y: u8,
|
||||||
|
msg_len: u8,
|
||||||
|
}
|
||||||
|
impl Environment {
|
||||||
|
unsafe fn setup(&mut self) {
|
||||||
|
arduboy.begin();
|
||||||
|
arduboy.set_frame_rate(60);
|
||||||
|
let msg_len = MSG.len();
|
||||||
|
debug_assert!(msg_len <= (core::u8::MAX as c_size_t));
|
||||||
|
self.msg_len = msg_len as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn loop_(&mut self) {
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if UP.pressed() && self.y > 0 {
|
||||||
|
self.y -= 1;
|
||||||
|
}
|
||||||
|
if RIGHT.pressed() && self.x < RIGHT_END - CHAR_WIDTH * self.msg_len {
|
||||||
|
self.x += 1;
|
||||||
|
}
|
||||||
|
if LEFT.pressed() && self.x > 0 {
|
||||||
|
self.x -= 1;
|
||||||
|
}
|
||||||
|
if DOWN.pressed() && self.y < BOTTOM - CHAR_HEIGHT * 2 {
|
||||||
|
self.y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (A | B).pressed() {
|
||||||
|
sound.tone(0xff, 0x3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
arduboy.clear();
|
||||||
|
arduboy.set_cursor(self.x.into(), self.y.into());
|
||||||
|
arduboy.print(MSG);
|
||||||
|
arduboy.set_cursor(self.x.into(), (self.y + 9).into());
|
||||||
|
arduboy.print(MSG2);
|
||||||
|
arduboy.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut E: Environment = Environment {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
msg_len: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
E.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
E.loop_();
|
||||||
|
}
|
12
Examples/snake/Cargo.toml
Normal file
12
Examples/snake/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "snake"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ZennDev <zenndev@protonmail.com>"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
274
Examples/snake/src/lib.rs
Normal file
274
Examples/snake/src/lib.rs
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
#![no_std]
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
static mut MEM: u8 = 0;
|
||||||
|
static SCORE: EEPROM = EEPROM::new(100);
|
||||||
|
|
||||||
|
const WORLD_WIDTH: u8 = 32;
|
||||||
|
const WORLD_HEIGHT: u8 = 16;
|
||||||
|
const SCALE_FACTOR: u8 = 4;
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum State {
|
||||||
|
Title,
|
||||||
|
Game,
|
||||||
|
Win,
|
||||||
|
GameOver,
|
||||||
|
Reset,
|
||||||
|
Pause,
|
||||||
|
}
|
||||||
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
enum Direction {
|
||||||
|
Up,
|
||||||
|
Left,
|
||||||
|
Down,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
struct Snake {
|
||||||
|
game_state: State,
|
||||||
|
points: u8,
|
||||||
|
len: u8,
|
||||||
|
pos: [(u8, u8); 255 as usize],
|
||||||
|
next_food: (u8, u8),
|
||||||
|
delta_time: u8,
|
||||||
|
direction: Direction,
|
||||||
|
last_direction: Direction,
|
||||||
|
}
|
||||||
|
impl Snake {
|
||||||
|
fn movement(&mut self) {
|
||||||
|
for i in 0..(self.len - 1) as usize {
|
||||||
|
self.pos[i] = self.pos[i + 1];
|
||||||
|
}
|
||||||
|
let (x, y) = self.pos[(self.len - 1) as usize];
|
||||||
|
match self.direction {
|
||||||
|
Direction::Up => {
|
||||||
|
self.pos[(self.len - 1) as usize] = (x, y - 1);
|
||||||
|
}
|
||||||
|
Direction::Left => {
|
||||||
|
self.pos[(self.len - 1) as usize] = (x - 1, y);
|
||||||
|
}
|
||||||
|
Direction::Down => {
|
||||||
|
self.pos[(self.len - 1) as usize] = (x, y + 1);
|
||||||
|
}
|
||||||
|
Direction::Right => {
|
||||||
|
self.pos[(self.len - 1) as usize] = (x + 1, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.last_direction = self.direction;
|
||||||
|
}
|
||||||
|
unsafe fn get_new_dir(&mut self) {
|
||||||
|
if UP.just_pressed() && self.last_direction != Direction::Down {
|
||||||
|
self.direction = Direction::Up
|
||||||
|
}
|
||||||
|
if LEFT.just_pressed() && self.last_direction != Direction::Right {
|
||||||
|
self.direction = Direction::Left
|
||||||
|
}
|
||||||
|
if DOWN.just_pressed() && self.last_direction != Direction::Up {
|
||||||
|
self.direction = Direction::Down
|
||||||
|
}
|
||||||
|
if RIGHT.just_pressed() && self.last_direction != Direction::Left {
|
||||||
|
self.direction = Direction::Right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn new_food(&mut self) {
|
||||||
|
self.next_food.0 = 0;
|
||||||
|
self.next_food.1 = 0;
|
||||||
|
while self.next_food.0 == 0 && self.next_food.1 == 0 {
|
||||||
|
self.next_food.0 = random_between(2, (WORLD_WIDTH - 2).into()) as u8;
|
||||||
|
self.next_food.1 = random_between(2, (WORLD_HEIGHT - 2).into()) as u8;
|
||||||
|
for i in 0..(self.len) as usize {
|
||||||
|
if self.pos[i] == self.next_food {
|
||||||
|
self.next_food.0 = 0;
|
||||||
|
self.next_food.1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe fn render(&self) {
|
||||||
|
arduboy.draw_circle(
|
||||||
|
((self.next_food.0 * SCALE_FACTOR) + SCALE_FACTOR / 4)
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
((self.next_food.1 * SCALE_FACTOR) + SCALE_FACTOR / 4)
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
SCALE_FACTOR / 4,
|
||||||
|
Color::White,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.pos.iter().enumerate().for_each(|(i, p)| {
|
||||||
|
if i == (self.len) as usize {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if *p == (0, 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arduboy.fill_rect(
|
||||||
|
(p.0 as u8 * SCALE_FACTOR).try_into().unwrap(),
|
||||||
|
(p.1 as u8 * SCALE_FACTOR).try_into().unwrap(),
|
||||||
|
SCALE_FACTOR / 2,
|
||||||
|
SCALE_FACTOR / 2,
|
||||||
|
Color::White,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
unsafe fn init(&mut self) {
|
||||||
|
self.points = 0;
|
||||||
|
self.len = 3;
|
||||||
|
self.direction = Direction::Right;
|
||||||
|
self.last_direction = Direction::Left;
|
||||||
|
self.pos = [(0, 0); 255 as usize];
|
||||||
|
self.pos[0] = (3, 4);
|
||||||
|
self.pos[1] = (4, 4);
|
||||||
|
self.pos[2] = (5, 4);
|
||||||
|
}
|
||||||
|
unsafe fn boarder(&self) {
|
||||||
|
for x in 0..WORLD_WIDTH as usize {
|
||||||
|
for y in 0..WORLD_HEIGHT as usize {
|
||||||
|
if x == 0
|
||||||
|
|| y == 0
|
||||||
|
|| x == (WORLD_WIDTH - 1) as usize
|
||||||
|
|| y == (WORLD_HEIGHT - 1) as usize
|
||||||
|
{
|
||||||
|
let scale: u8 = 2;
|
||||||
|
if self.delta_time % 20 == 0 {
|
||||||
|
//scale = 1;
|
||||||
|
};
|
||||||
|
arduboy.fill_rect(
|
||||||
|
(x as u8 * SCALE_FACTOR + scale / 2).try_into().unwrap(),
|
||||||
|
(y as u8 * SCALE_FACTOR + scale / 2).try_into().unwrap(),
|
||||||
|
SCALE_FACTOR / scale,
|
||||||
|
SCALE_FACTOR / scale,
|
||||||
|
Color::White,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn collision_check(&mut self) {
|
||||||
|
let (x, y) = self.pos[(self.len - 1) as usize];
|
||||||
|
if x == 0 || x == 31 || y == 0 || y == 15 {
|
||||||
|
self.game_state = State::GameOver;
|
||||||
|
}
|
||||||
|
self.pos.iter().enumerate().for_each(|(i, p)| {
|
||||||
|
if p == &(x, y) && i != (self.len - 1) as usize {
|
||||||
|
self.game_state = State::GameOver;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if self.pos[(self.len - 1) as usize] == self.next_food {
|
||||||
|
self.points += 1;
|
||||||
|
self.new_food();
|
||||||
|
self.pos[self.len as usize] = self.pos[(self.len - 1) as usize];
|
||||||
|
self.len += 1;
|
||||||
|
sound.tone(0xff, 0x3f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
static mut snake: Snake = Snake {
|
||||||
|
game_state: State::Reset,
|
||||||
|
len: 3,
|
||||||
|
points: 0,
|
||||||
|
pos: [(0, 0); 255 as usize],
|
||||||
|
next_food: (0, 0),
|
||||||
|
delta_time: 0,
|
||||||
|
direction: Direction::Right,
|
||||||
|
last_direction: Direction::Left,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
arduboy.begin();
|
||||||
|
SCORE.init();
|
||||||
|
arduboy.init_random_seed();
|
||||||
|
arduboy.set_frame_rate(60);
|
||||||
|
arduboy.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
if !arduboy.next_frame() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arduboy.poll_buttons();
|
||||||
|
arduboy.clear();
|
||||||
|
match snake.game_state {
|
||||||
|
State::Reset => {
|
||||||
|
snake.init();
|
||||||
|
snake.new_food();
|
||||||
|
snake.game_state = State::Title;
|
||||||
|
}
|
||||||
|
State::Title => {
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.set_text_size(2);
|
||||||
|
arduboy.print(&b"RustySnake\n\0"[..]);
|
||||||
|
arduboy.set_text_size(1);
|
||||||
|
arduboy.print(&b"\nControls: \nB for Pause\nA&B for reset\n\0"[..]);
|
||||||
|
arduboy.print(&b"\nZennDev 2023\n\0"[..]);
|
||||||
|
if A.just_pressed() {
|
||||||
|
snake.game_state = State::Game;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Game => {
|
||||||
|
snake.get_new_dir();
|
||||||
|
if snake.delta_time % 10 == 0 {
|
||||||
|
snake.movement();
|
||||||
|
snake.collision_check();
|
||||||
|
};
|
||||||
|
snake.render();
|
||||||
|
snake.boarder();
|
||||||
|
if B.just_pressed() {
|
||||||
|
sound.tone(800, 100);
|
||||||
|
snake.game_state = State::Pause;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Win => (),
|
||||||
|
State::Pause => {
|
||||||
|
let msg = &b"[ Break ]\0"[..];
|
||||||
|
let l = msg.len() as u8 * FONT_SIZE / 2;
|
||||||
|
arduboy.set_cursor(
|
||||||
|
((WIDTH / 2) as u16 - l as u16).try_into().unwrap(),
|
||||||
|
((HEIGHT / 2) as u16).try_into().unwrap(),
|
||||||
|
);
|
||||||
|
snake.render();
|
||||||
|
snake.boarder();
|
||||||
|
arduboy.print(msg);
|
||||||
|
if B.just_pressed() {
|
||||||
|
snake.game_state = State::Game;
|
||||||
|
sound.tone(800, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::GameOver => {
|
||||||
|
SCORE.get(&mut MEM);
|
||||||
|
if MEM == 255 {
|
||||||
|
MEM = 0;
|
||||||
|
}
|
||||||
|
if snake.points > MEM {
|
||||||
|
SCORE.put(snake.points);
|
||||||
|
}
|
||||||
|
|
||||||
|
arduboy.set_cursor(0, 0);
|
||||||
|
arduboy.print(&b"Game Over!\0"[..]);
|
||||||
|
arduboy.print(&b"\n\n\0"[..]);
|
||||||
|
arduboy.print(&b"Score: \0"[..]);
|
||||||
|
arduboy.print(snake.points as u16);
|
||||||
|
arduboy.print(&b"\nHigh Score: \0"[..]);
|
||||||
|
arduboy.print(MEM as u16);
|
||||||
|
arduboy.print(&b"\n\n\0"[..]);
|
||||||
|
arduboy.print(&b"Press A to Play Again\0"[..]);
|
||||||
|
|
||||||
|
if A.just_pressed() {
|
||||||
|
snake.game_state = State::Reset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (A | B).pressed() {
|
||||||
|
snake.game_state = State::Reset;
|
||||||
|
}
|
||||||
|
arduboy.display();
|
||||||
|
if snake.delta_time == 60 {
|
||||||
|
snake.delta_time = 1
|
||||||
|
} else {
|
||||||
|
snake.delta_time += 1;
|
||||||
|
}
|
||||||
|
}
|
199
LICENSE-APACHE
Normal file
199
LICENSE-APACHE
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
19
LICENSE-MIT
Normal file
19
LICENSE-MIT
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
10
Project/game/Cargo.toml
Normal file
10
Project/game/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "game"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arduboy-rust = "1.0.0"
|
20
Project/game/src/lib.rs
Normal file
20
Project/game/src/lib.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
//Include the Arduboy Library
|
||||||
|
//Initialize the arduboy object
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use arduboy_rust::prelude::*;
|
||||||
|
|
||||||
|
//#[link_section = ".progmem.data"]
|
||||||
|
|
||||||
|
// The setup() function runs once when you turn your Arduboy on
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
}
|
||||||
|
// The loop() function repeats forever after setup() is done
|
||||||
|
#[no_mangle]
|
||||||
|
#[export_name = "loop"]
|
||||||
|
pub unsafe extern "C" fn loop_() {
|
||||||
|
// put your main code here, to run repeatedly:
|
||||||
|
}
|
199
README.md
Normal file
199
README.md
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
# Rust for Arduboy
|
||||||
|
|
||||||
|
Running Rust on the [Arduboy](https://arduboy.com/) miniature game system.
|
||||||
|
|
||||||
|
The most important first.
|
||||||
|
I didn't create this project from scratch, @Seeker14491 the legend has already done a lot in his old project [ArduboyRust](https://github.com/Seeker14491/ArduboyRust)
|
||||||
|
|
||||||
|
I just updated and completed the project.
|
||||||
|
|
||||||
|
### What do i mean by completed?
|
||||||
|
|
||||||
|
I provided all the important functions from the [Arduboy2](https://github.com/MLXXXp/Arduboy2) library in a safe Rust API.
|
||||||
|
|
||||||
|
Most of the Arduboy2 funktions can be called the same way like in C.
|
||||||
|
|
||||||
|
# How to use this Project
|
||||||
|
|
||||||
|
First clone the repo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/ZennDev1337/Rust-for-Arduboy
|
||||||
|
```
|
||||||
|
|
||||||
|
Install [PlatformIO Core](https://docs.platformio.org/en/latest/core/installation/methods/pypi.html) on your system.
|
||||||
|
I recommend the pip install if you don't want to configure a new path variable for pio.
|
||||||
|
Otherwise you will know how to do that.
|
||||||
|
|
||||||
|
The rust-analyzer will complain about a missing test crate to fix this
|
||||||
|
add the following rule to the lsp settings :
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"rust-analyzer.checkOnSave.allTargets": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If your using Visual Studio Code: Create a folder named `.vscode` and a file named `settings.json` inside. Past the setting above in the new file. (I have excluded my `.vscode` folder because I have many different settings there that you don't need)
|
||||||
|
|
||||||
|
Your game is located in the Project/game folder. This is also the folder you are working in
|
||||||
|
|
||||||
|
Inside the game folder you will find a lib.rs file which contains the setup and loop function as you know it from a normal Arduboy C project.
|
||||||
|
|
||||||
|
You can use the following command to open the Rust doc of the arduboy_rust crate
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo doc -p arduboy_rust --open
|
||||||
|
```
|
||||||
|
|
||||||
|
Most of the time you will use the prelude.
|
||||||
|
There is listed witch funktionality you will have.
|
||||||
|
|
||||||
|
And last but not least there are multiple examples inside of the Examples folder which shows you how to use the functions.
|
||||||
|
I will from time to time also upload my projects to the Example folder so you have as much ressurces as possible.
|
||||||
|
|
||||||
|
## Usage of the run tool
|
||||||
|
|
||||||
|
**Both run scripts** (only works if you use the given folder structure)
|
||||||
|
|
||||||
|
requirements:
|
||||||
|
|
||||||
|
- [PlatformIO Core](https://docs.platformio.org/en/latest/core/installation/methods/pypi.html) must be installed
|
||||||
|
- The Arduboy must be plugged in
|
||||||
|
- You are in the root directory of this project
|
||||||
|
|
||||||
|
All builded `.hex` files are saved inside of `Wrapper-Project/.pio/build/<GAMENAME>.hex` after you uploaded them to the Arduboy.
|
||||||
|
|
||||||
|
To upload your own game to the Arduboy use:
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
.\run.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
## Play the examples
|
||||||
|
|
||||||
|
### Snake
|
||||||
|
|
||||||
|
To upload snake to the Arduboy use:
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run snake
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
.\run.bat snake
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pong
|
||||||
|
|
||||||
|
To upload pong to the Arduboy use:
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run pong
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
.\run.bat pong
|
||||||
|
```
|
||||||
|
|
||||||
|
### I'm now a Rustacean <3
|
||||||
|
|
||||||
|
To upload rustacean to the Arduboy use:
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run rustacean
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
.\run.bat rustacean
|
||||||
|
```
|
||||||
|
|
||||||
|
### The demo games / tutorials from the official Arduboy forum [Rewritten in Rust]
|
||||||
|
|
||||||
|
- [Make Your Own Arduboy Game: Part 1 - Setting Up Your Computer](https://community.arduboy.com/t/make-your-own-arduboy-game-part-1-setting-up-your-computer/7924/1)
|
||||||
|
- [demo2] [Make Your Own Arduboy Game: Part 2 - Printing Text](https://community.arduboy.com/t/make-your-own-arduboy-game-part-2-printing-text/7925)
|
||||||
|
- [demo3] [Make Your Own Arduboy Game: Part 3 - Storing Data & Loops](https://community.arduboy.com/t/make-your-own-arduboy-game-part-3-storing-data-loops/7926)
|
||||||
|
- [demo4] [Make Your Own Arduboy Game: Part 4 - Questions & Button Input](https://community.arduboy.com/t/make-your-own-arduboy-game-part-4-questions-button-input/7927)
|
||||||
|
- [demo5] [Make Your Own Arduboy Game: Part 5 - Your First Game!](https://community.arduboy.com/t/make-your-own-arduboy-game-part-5-your-first-game/7928)
|
||||||
|
- [demo6] [Make Your Own Arduboy Game: Part 6 - Graphics!](https://community.arduboy.com/t/make-your-own-arduboy-game-part-6-graphics/7929)
|
||||||
|
Link for the [arduboy-tile-converter](https://github.com/Team-ARG-Museum/arduboy-tile-converter)
|
||||||
|
- not done [demo7] [Make Your Own Arduboy Game: Part 7 - Make Pong From Scratch!](https://community.arduboy.com/t/make-your-own-arduboy-game-part-7-make-pong-from-scratch/7930)
|
||||||
|
- not done [demo8] [Make Your Own Arduboy Game: Part 8 - Starting DinoSmasher](https://community.arduboy.com/t/make-your-own-arduboy-game-part-8-starting-dinosmasher/7932)
|
||||||
|
- [eeprom] [Help, I’m struggling with EEPROM!](https://community.arduboy.com/t/help-im-struggling-with-eeprom/7178)
|
||||||
|
- [tone] [ArduboyTonesTest](https://github.com/MLXXXp/ArduboyTones/blob/master/examples/ArduboyTonesTest/ArduboyTonesTest.ino)
|
||||||
|
|
||||||
|
To upload a demo to the Arduboy use:
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run demo2
|
||||||
|
./run demo3
|
||||||
|
./run demo4
|
||||||
|
./run demo5
|
||||||
|
./run demo6
|
||||||
|
./run eeprom
|
||||||
|
./run tone
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
.\run.bat demo2
|
||||||
|
.\run.bat demo3
|
||||||
|
.\run.bat demo4
|
||||||
|
.\run.bat demo5
|
||||||
|
.\run.bat demo6
|
||||||
|
.\run.bat eeprom
|
||||||
|
.\run.bat tone
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating and building an Arduboy crate [Outdated]
|
||||||
|
|
||||||
|
You can find instructions on how all build steps work in detail here [ArduboyRust creating and building an arduboy crate](https://github.com/Seeker14491/ArduboyRust#creating-and-building-an-arduboy-crate)
|
||||||
|
|
||||||
|
## Linking the static library to the Arduino C++ project [Outdated]
|
||||||
|
|
||||||
|
Instructions on how to link all the static libraries in the Arduino C++ project can be found here [ArduboyRust linking the static library to the arduino c++ project](https://github.com/Seeker14491/ArduboyRust#linking-the-static-library-to-the-arduino-c-project)
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Thanks to @Seeker14491 who wrote [ArduboyRust](https://github.com/Seeker14491/ArduboyRust), the starting point for me to create my own project based on this project. (you are a hero <3)
|
||||||
|
|
||||||
|
Thanks to @simon-i1-h who wrote [arduboy-hello-rs](https://github.com/simon-i1-h/arduboy-hello-rs), the proof of concept that inspired me to try Rust on the Arduboy.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
You can license it under either one of those licenses:
|
||||||
|
|
||||||
|
- Apache License, Version 2.0
|
||||||
|
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
- MIT license
|
||||||
|
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
Whichever you may prefer.
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||||
|
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
39
Wrapper-Project/include/README
Normal file
39
Wrapper-Project/include/README
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the usual convention is to give header files names that end with `.h'.
|
||||||
|
It is most portable to use only letters, digits, dashes, and underscores in
|
||||||
|
header file names, and at most one dot.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
Wrapper-Project/lib/README
Normal file
46
Wrapper-Project/lib/README
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
This directory is intended for project specific (private) libraries.
|
||||||
|
PlatformIO will compile them to static libraries and link into executable file.
|
||||||
|
|
||||||
|
The source code of each library should be placed in a an own separate directory
|
||||||
|
("lib/your_library_name/[here are source files]").
|
||||||
|
|
||||||
|
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||||
|
|
||||||
|
|--lib
|
||||||
|
| |
|
||||||
|
| |--Bar
|
||||||
|
| | |--docs
|
||||||
|
| | |--examples
|
||||||
|
| | |--src
|
||||||
|
| | |- Bar.c
|
||||||
|
| | |- Bar.h
|
||||||
|
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||||
|
| |
|
||||||
|
| |--Foo
|
||||||
|
| | |- Foo.c
|
||||||
|
| | |- Foo.h
|
||||||
|
| |
|
||||||
|
| |- README --> THIS FILE
|
||||||
|
|
|
||||||
|
|- platformio.ini
|
||||||
|
|--src
|
||||||
|
|- main.c
|
||||||
|
|
||||||
|
and a contents of `src/main.c`:
|
||||||
|
```
|
||||||
|
#include <Foo.h>
|
||||||
|
#include <Bar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
PlatformIO Library Dependency Finder will find automatically dependent
|
||||||
|
libraries scanning project source files.
|
||||||
|
|
||||||
|
More information about PlatformIO Library Dependency Finder
|
||||||
|
- https://docs.platformio.org/page/librarymanager/ldf.html
|
21
Wrapper-Project/platformio.ini
Normal file
21
Wrapper-Project/platformio.ini
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
;PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:arduboy]
|
||||||
|
platform = atmelavr
|
||||||
|
board = arduboy
|
||||||
|
framework = arduino
|
||||||
|
|
||||||
|
build_flags =
|
||||||
|
-L lib -l libgame
|
||||||
|
|
||||||
|
lib_deps =
|
||||||
|
mlxxxp/Arduboy2@^6.0.0
|
||||||
|
ArduboyTones@^1.0.3
|
123
Wrapper-Project/src/library/arduboy/arduboy.cpp
Normal file
123
Wrapper-Project/src/library/arduboy/arduboy.cpp
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
#include "arduboy.h"
|
||||||
|
extern Arduboy2 arduboy;
|
||||||
|
|
||||||
|
void arduboy_begin(void)
|
||||||
|
{
|
||||||
|
arduboy.begin();
|
||||||
|
}
|
||||||
|
void arduboy_clear(void)
|
||||||
|
{
|
||||||
|
arduboy.clear();
|
||||||
|
}
|
||||||
|
void arduboy_display(void)
|
||||||
|
{
|
||||||
|
arduboy.display();
|
||||||
|
}
|
||||||
|
void arduboy_display_and_clear_buffer(void)
|
||||||
|
{
|
||||||
|
arduboy.display(CLEAR_BUFFER);
|
||||||
|
}
|
||||||
|
void arduboy_draw_fast_hline(int16_t x, int16_t y, uint8_t w, uint8_t color)
|
||||||
|
{
|
||||||
|
arduboy.drawFastHLine(x, y, w, color);
|
||||||
|
}
|
||||||
|
void arduboy_draw_fast_vline(int16_t x, int16_t y, uint8_t h, uint8_t color)
|
||||||
|
{
|
||||||
|
arduboy.drawFastVLine(x, y, h, color);
|
||||||
|
}
|
||||||
|
void arduboy_draw_pixel(int16_t x, int16_t y, uint8_t color)
|
||||||
|
{
|
||||||
|
arduboy.drawPixel(x, y, color);
|
||||||
|
}
|
||||||
|
void arduboy_draw_circle(int16_t x, int16_t y, uint8_t r, uint8_t color)
|
||||||
|
{
|
||||||
|
arduboy.drawCircle(x, y, r, color);
|
||||||
|
}
|
||||||
|
void arduboy_fill_circle(int16_t x, int16_t y, uint8_t r, uint8_t color)
|
||||||
|
{
|
||||||
|
arduboy.fillCircle(x, y, r, color);
|
||||||
|
}
|
||||||
|
void arduboy_fill_rect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color)
|
||||||
|
{
|
||||||
|
arduboy.fillRect(x, y, w, h, color);
|
||||||
|
}
|
||||||
|
unsigned long arduboy_generate_random_seed()
|
||||||
|
{
|
||||||
|
return arduboy.generateRandomSeed();
|
||||||
|
}
|
||||||
|
uint8_t arduboy_get_pixel(uint8_t x, uint8_t y)
|
||||||
|
{
|
||||||
|
return arduboy.getPixel(x, y);
|
||||||
|
}
|
||||||
|
void arduboy_init_random_seed(void)
|
||||||
|
{
|
||||||
|
arduboy.initRandomSeed();
|
||||||
|
}
|
||||||
|
bool arduboy_just_pressed(uint8_t button)
|
||||||
|
{
|
||||||
|
return arduboy.justPressed(button);
|
||||||
|
}
|
||||||
|
bool arduboy_just_released(uint8_t button)
|
||||||
|
{
|
||||||
|
return arduboy.justReleased(button);
|
||||||
|
}
|
||||||
|
bool arduboy_next_frame(void)
|
||||||
|
{
|
||||||
|
return arduboy.nextFrame();
|
||||||
|
}
|
||||||
|
void arduboy_poll_buttons()
|
||||||
|
{
|
||||||
|
arduboy.pollButtons();
|
||||||
|
}
|
||||||
|
bool arduboy_pressed(uint8_t buttons)
|
||||||
|
{
|
||||||
|
return arduboy.pressed(buttons);
|
||||||
|
}
|
||||||
|
void arduboy_print_chars(const char *cstr)
|
||||||
|
{
|
||||||
|
arduboy.print(cstr);
|
||||||
|
}
|
||||||
|
size_t arduboy_print_char(char c)
|
||||||
|
{
|
||||||
|
return arduboy.print(c);
|
||||||
|
}
|
||||||
|
size_t arduboy_print_int(int n, int base)
|
||||||
|
{
|
||||||
|
return arduboy.print(n, base);
|
||||||
|
}
|
||||||
|
size_t arduboy_print_long(long n, int base)
|
||||||
|
{
|
||||||
|
return arduboy.print(n, base);
|
||||||
|
}
|
||||||
|
size_t arduboy_print_unsigned_char(unsigned char n, int base)
|
||||||
|
{
|
||||||
|
return arduboy.print(n, base);
|
||||||
|
}
|
||||||
|
size_t arduboy_print_unsigned_int(unsigned int n, int base)
|
||||||
|
{
|
||||||
|
return arduboy.print(n, base);
|
||||||
|
}
|
||||||
|
size_t arduboy_print_unsigned_long(unsigned long n, int base)
|
||||||
|
{
|
||||||
|
return arduboy.print(n, base);
|
||||||
|
}
|
||||||
|
void arduboy_set_cursor(int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
arduboy.setCursor(x, y);
|
||||||
|
}
|
||||||
|
void arduboy_set_frame_rate(uint8_t rate)
|
||||||
|
{
|
||||||
|
arduboy.setFrameRate(rate);
|
||||||
|
}
|
||||||
|
bool arduboy_not_pressed(uint8_t button)
|
||||||
|
{
|
||||||
|
arduboy.notPressed(button);
|
||||||
|
}
|
||||||
|
void arduboy_set_text_size(uint8_t s)
|
||||||
|
{
|
||||||
|
arduboy.setTextSize(s);
|
||||||
|
}
|
||||||
|
void arduboy_invert(bool inverse)
|
||||||
|
{
|
||||||
|
arduboy.invert(inverse);
|
||||||
|
}
|
36
Wrapper-Project/src/library/arduboy/arduboy.h
Normal file
36
Wrapper-Project/src/library/arduboy/arduboy.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
#include <Arduboy2.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void arduboy_begin(void);
|
||||||
|
void arduboy_clear(void);
|
||||||
|
void arduboy_display(void);
|
||||||
|
void arduboy_display_and_clear_buffer(void);
|
||||||
|
void arduboy_draw_fast_hline(int16_t x, int16_t y, uint8_t w, uint8_t color);
|
||||||
|
void arduboy_draw_fast_vline(int16_t x, int16_t y, uint8_t h, uint8_t color);
|
||||||
|
void arduboy_draw_pixel(int16_t x, int16_t y, uint8_t color);
|
||||||
|
void arduboy_draw_circle(int16_t x, int16_t y, uint8_t r, uint8_t color);
|
||||||
|
void arduboy_fill_circle(int16_t x, int16_t y, uint8_t r, uint8_t color);
|
||||||
|
void arduboy_fill_rect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color);
|
||||||
|
unsigned long arduboy_generate_random_seed();
|
||||||
|
uint8_t arduboy_get_pixel(uint8_t x, uint8_t y);
|
||||||
|
void arduboy_init_random_seed(void);
|
||||||
|
bool arduboy_just_pressed(uint8_t button);
|
||||||
|
bool arduboy_just_released(uint8_t button);
|
||||||
|
bool arduboy_next_frame(void);
|
||||||
|
void arduboy_poll_buttons();
|
||||||
|
bool arduboy_pressed(uint8_t buttons);
|
||||||
|
void arduboy_print_chars(const char *cstr);
|
||||||
|
size_t arduboy_print_char(char c);
|
||||||
|
size_t arduboy_print_int(int n, int base);
|
||||||
|
size_t arduboy_print_long(long n, int base);
|
||||||
|
size_t arduboy_print_unsigned_char(unsigned char n, int base);
|
||||||
|
size_t arduboy_print_unsigned_int(unsigned int n, int base);
|
||||||
|
size_t arduboy_print_unsigned_long(unsigned long n, int base);
|
||||||
|
void arduboy_set_cursor(int16_t x, int16_t y);
|
||||||
|
void arduboy_set_frame_rate(uint8_t rate);
|
||||||
|
bool arduboy_not_pressed(uint8_t button);
|
||||||
|
void arduboy_set_text_size(uint8_t s);
|
||||||
|
void arduboy_invert(bool inverse);
|
||||||
|
}
|
46
Wrapper-Project/src/library/arduboy/arduboy_tones.cpp
Normal file
46
Wrapper-Project/src/library/arduboy/arduboy_tones.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include "arduboy_tones.h"
|
||||||
|
|
||||||
|
void arduboy_audio_on()
|
||||||
|
{
|
||||||
|
arduboy.audio.on();
|
||||||
|
}
|
||||||
|
void arduboy_audio_off()
|
||||||
|
{
|
||||||
|
arduboy.audio.off();
|
||||||
|
}
|
||||||
|
bool arduboy_audio_enabled()
|
||||||
|
{
|
||||||
|
return arduboy.audio.enabled();
|
||||||
|
}
|
||||||
|
void sound_tone(unsigned int frequency, unsigned long duration)
|
||||||
|
{
|
||||||
|
sound.tone(frequency, duration);
|
||||||
|
}
|
||||||
|
void sound_tone2(unsigned int frequency1, unsigned long duration1, unsigned int frequency2, unsigned long duration2)
|
||||||
|
{
|
||||||
|
sound.tone(frequency1, duration1, frequency2, duration2);
|
||||||
|
}
|
||||||
|
void sound_tone3(unsigned int frequency1, unsigned long duration1, unsigned int frequency2, unsigned long duration2, unsigned int frequency3, unsigned long duration3)
|
||||||
|
{
|
||||||
|
sound.tone(frequency1, duration1, frequency2, duration2, frequency3, duration3);
|
||||||
|
}
|
||||||
|
void sound_tones(const uint16_t *tones)
|
||||||
|
{
|
||||||
|
sound.tones(tones);
|
||||||
|
}
|
||||||
|
void sound_no_tone()
|
||||||
|
{
|
||||||
|
sound.noTone();
|
||||||
|
}
|
||||||
|
bool sound_playing()
|
||||||
|
{
|
||||||
|
sound.playing();
|
||||||
|
}
|
||||||
|
void sound_tones_in_ram(uint16_t *tones)
|
||||||
|
{
|
||||||
|
sound.tonesInRAM(tones);
|
||||||
|
}
|
||||||
|
void sound_volume_mode(uint8_t mode)
|
||||||
|
{
|
||||||
|
sound.volumeMode(mode);
|
||||||
|
}
|
21
Wrapper-Project/src/library/arduboy/arduboy_tones.h
Normal file
21
Wrapper-Project/src/library/arduboy/arduboy_tones.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduboyTones.h>
|
||||||
|
#include <Arduboy2.h>
|
||||||
|
extern ArduboyTones sound;
|
||||||
|
extern Arduboy2 arduboy;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void arduboy_audio_on();
|
||||||
|
void arduboy_audio_off();
|
||||||
|
bool arduboy_audio_enabled();
|
||||||
|
void sound_tone(unsigned int frequency, unsigned long duration);
|
||||||
|
void sound_tone2(unsigned int frequency1, unsigned long duration1, unsigned int frequency2, unsigned long duration2);
|
||||||
|
void sound_tone3(unsigned int frequency1, unsigned long duration1, unsigned int frequency2, unsigned long duration2, unsigned int frequency3, unsigned long duration3);
|
||||||
|
void sound_tones(const uint16_t *tones);
|
||||||
|
void sound_no_tone();
|
||||||
|
bool sound_playing();
|
||||||
|
void sound_tones_in_ram(uint16_t *tones);
|
||||||
|
void sound_volume_mode(uint8_t mode);
|
||||||
|
}
|
6
Wrapper-Project/src/library/arduboy/sprites.cpp
Normal file
6
Wrapper-Project/src/library/arduboy/sprites.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "sprites.h"
|
||||||
|
|
||||||
|
void arduino_draw_override(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame)
|
||||||
|
{
|
||||||
|
Sprites::drawOverwrite(x, y, bitmap, frame);
|
||||||
|
}
|
7
Wrapper-Project/src/library/arduboy/sprites.h
Normal file
7
Wrapper-Project/src/library/arduboy/sprites.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
#include <Sprites.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void arduino_draw_override(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t frame);
|
||||||
|
}
|
14
Wrapper-Project/src/library/arduino/arduino.cpp
Normal file
14
Wrapper-Project/src/library/arduino/arduino.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "arduino.h"
|
||||||
|
|
||||||
|
long arduino_random_between(long min, long max)
|
||||||
|
{
|
||||||
|
return random(min, max);
|
||||||
|
}
|
||||||
|
long arduino_random_less_than(long max)
|
||||||
|
{
|
||||||
|
return random(max);
|
||||||
|
}
|
||||||
|
void arduino_delay(unsigned long ms)
|
||||||
|
{
|
||||||
|
delay(ms);
|
||||||
|
}
|
9
Wrapper-Project/src/library/arduino/arduino.h
Normal file
9
Wrapper-Project/src/library/arduino/arduino.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
#include <Arduboy2.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
long arduino_random_between(long min, long max);
|
||||||
|
long arduino_random_less_than(long max);
|
||||||
|
void arduino_delay(unsigned long ms);
|
||||||
|
}
|
26
Wrapper-Project/src/library/arduino/eeprom.cpp
Normal file
26
Wrapper-Project/src/library/arduino/eeprom.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "eeprom.h"
|
||||||
|
|
||||||
|
int eeprom;
|
||||||
|
|
||||||
|
uint8_t arduboy_eeprom_read(int idx)
|
||||||
|
{
|
||||||
|
eeprom = EEPROM.read(idx);
|
||||||
|
return eeprom;
|
||||||
|
}
|
||||||
|
void arduboy_eeprom_update(int idx, uint8_t val)
|
||||||
|
{
|
||||||
|
EEPROM.update(idx, val);
|
||||||
|
}
|
||||||
|
void arduboy_eeprom_write(int idx, uint8_t val)
|
||||||
|
{
|
||||||
|
EEPROM.write(idx, val);
|
||||||
|
}
|
||||||
|
uint8_t arduboy_eeprom_get(int idx)
|
||||||
|
{
|
||||||
|
EEPROM.get(idx, eeprom);
|
||||||
|
return eeprom;
|
||||||
|
}
|
||||||
|
void arduboy_eeprom_put(int idx, uint8_t val)
|
||||||
|
{
|
||||||
|
EEPROM.put(idx, val);
|
||||||
|
}
|
12
Wrapper-Project/src/library/arduino/eeprom.h
Normal file
12
Wrapper-Project/src/library/arduino/eeprom.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
uint8_t arduboy_eeprom_read(int idx);
|
||||||
|
void arduboy_eeprom_update(int idx, uint8_t val);
|
||||||
|
void arduboy_eeprom_write(int idx, uint8_t val);
|
||||||
|
uint8_t arduboy_eeprom_get(int idx);
|
||||||
|
void arduboy_eeprom_put(int idx, uint8_t val);
|
||||||
|
}
|
4
Wrapper-Project/src/main.cpp
Normal file
4
Wrapper-Project/src/main.cpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
Arduboy2 arduboy;
|
||||||
|
ArduboyTones sound(arduboy.audio.enabled);
|
9
Wrapper-Project/src/main.h
Normal file
9
Wrapper-Project/src/main.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduboy2.h>
|
||||||
|
#include <ArduboyTones.h>
|
||||||
|
#include "./library/arduboy/arduboy.h"
|
||||||
|
#include "./library/arduboy/sprites.h"
|
||||||
|
#include "./library/arduboy/arduboy_tones.h"
|
||||||
|
#include "./library/arduino/arduino.h"
|
||||||
|
#include "./library/arduino/eeprom.h"
|
11
Wrapper-Project/test/README
Normal file
11
Wrapper-Project/test/README
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
This directory is intended for PIO Unit Testing and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/page/plus/unit-testing.html
|
27
arduboy.json
Normal file
27
arduboy.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"arch": "avr",
|
||||||
|
"atomic-cas": false,
|
||||||
|
"cpu": "atmega32u4",
|
||||||
|
"data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
|
||||||
|
"eh-frame-header": false,
|
||||||
|
"exe-suffix": ".elf",
|
||||||
|
"executables": true,
|
||||||
|
"late-link-args": {
|
||||||
|
"gcc": [
|
||||||
|
"-lgcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"linker": "avr-gcc",
|
||||||
|
"linker-is-gnu": true,
|
||||||
|
"llvm-target": "avr-unknown-unknown",
|
||||||
|
"max-atomic-width": 8,
|
||||||
|
"no-default-libraries": false,
|
||||||
|
"pre-link-args": {
|
||||||
|
"gcc": [
|
||||||
|
"-mmcu=atmega32u4",
|
||||||
|
"-Wl,--as-needed"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"target-c-int-width": "16",
|
||||||
|
"target-pointer-width": "16"
|
||||||
|
}
|
41
run
Executable file
41
run
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
option=$1
|
||||||
|
|
||||||
|
if [ -z "$option" ]
|
||||||
|
then
|
||||||
|
cargo build -p game --release && cp ./target/arduboy/release/libgame.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/game.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "snake" ]
|
||||||
|
then
|
||||||
|
cargo build -p snake --release && cp ./target/arduboy/release/libsnake.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/snake.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "pong" ]
|
||||||
|
then
|
||||||
|
cargo build -p pong --release && cp ./target/arduboy/release/libpong.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/pong.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "rustacean" ]
|
||||||
|
then
|
||||||
|
cargo build -p rustacean --release && cp ./target/arduboy/release/librustacean.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/rustacean.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "tone" ]
|
||||||
|
then
|
||||||
|
cargo build -p tone --release && cp ./target/arduboy/release/libtone.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/tone.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "eeprom" ]
|
||||||
|
then
|
||||||
|
cargo build -p eeprom-demo --release && cp ./target/arduboy/release/libeeprom_demo.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/eeprom.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "demo2" ]
|
||||||
|
then
|
||||||
|
cargo build -p demo2 --release && cp ./target/arduboy/release/libdemo2.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo2.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "demo3" ]
|
||||||
|
then
|
||||||
|
cargo build -p demo3 --release && cp ./target/arduboy/release/libdemo3.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo3.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "demo4" ]
|
||||||
|
then
|
||||||
|
cargo build -p demo4 --release && cp ./target/arduboy/release/libdemo4.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo4.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "demo5" ]
|
||||||
|
then
|
||||||
|
cargo build -p demo5 --release && cp ./target/arduboy/release/libdemo5.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo5.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
elif [ "$option" = "demo6" ]
|
||||||
|
then
|
||||||
|
cargo build -p demo6 --release && cp ./target/arduboy/release/libdemo6.a ./Wrapper-Project/lib/libgame.a && cd Wrapper-Project/ && pio run -t upload && cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo6.hex && pio run -t clean && rm lib/libgame.a && cd ..
|
||||||
|
else
|
||||||
|
echo Usage: for uploading your game \|./run.sh
|
||||||
|
echo Usage: for uploading an example game \| ./run.sh \<Example Game\>
|
||||||
|
fi
|
43
run.bat
Normal file
43
run.bat
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
set option=%1
|
||||||
|
|
||||||
|
if [%option%]==[] (
|
||||||
|
powershell -Command "cargo build -p game --release; cp ./target/arduboy/release/libgame.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/game.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
)
|
||||||
|
|
||||||
|
if %option%==snake (
|
||||||
|
powershell -Command "cargo build -p snake --release; cp ./target/arduboy/release/libsnake.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/snake.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==pong (
|
||||||
|
powershell -Command "cargo build -p pong --release; cp ./target/arduboy/release/libpong.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/pong.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==rustacean (
|
||||||
|
powershell -Command "cargo build -p rustacean --release; cp ./target/arduboy/release/librustacean.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/rustacean.hex; pio run -t upload; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==tone (
|
||||||
|
powershell -Command "cargo build -p tone --release; cp ./target/arduboy/release/libtone.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/tone.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==eeprom (
|
||||||
|
powershell -Command "cargo build -p eeprom-demo --release; cp ./target/arduboy/release/libeeprom_demo.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/eeprom.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==demo2 (
|
||||||
|
powershell -Command "cargo build -p demo2 --release; cp ./target/arduboy/release/libdemo2.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo2.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==demo3 (
|
||||||
|
powershell -Command "cargo build -p demo3 --release; cp ./target/arduboy/release/libdemo3.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo3.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==demo4 (
|
||||||
|
powershell -Command "cargo build -p demo4 --release; cp ./target/arduboy/release/libdemo4.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo4.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==demo5 (
|
||||||
|
powershell -Command "cargo build -p demo5 --release; cp ./target/arduboy/release/libdemo5.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo5.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
) else if %option%==demo6 (
|
||||||
|
powershell -Command "cargo build -p demo6 --release; cp ./target/arduboy/release/libdemo6.a ./Wrapper-Project/lib/libgame.a; cd Wrapper-Project/; pio run -t upload; cp ./.pio/build/arduboy/firmware.hex ./.pio/build/demo6.hex; pio run -t clean; rm lib/libgame.a; cd .."
|
||||||
|
goto :eof
|
||||||
|
)
|
||||||
|
|
||||||
|
@echo Usage: .\run.bat // for uploading your game
|
||||||
|
@echo Usage: .\run.bat ^<Example Game^> // for uploading an example game
|
4
rust-toolchain.toml
Normal file
4
rust-toolchain.toml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[toolchain]
|
||||||
|
# We need to pin to this old Rust version due to an LLVM bug: https://github.com/rust-lang/rust/issues/82104
|
||||||
|
channel = "nightly"
|
||||||
|
components = ["rust-src"]
|
5
rustfmt.toml
Normal file
5
rustfmt.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
format_code_in_doc_comments = true
|
||||||
|
imports_granularity = "Module"
|
||||||
|
newline_style = "Unix"
|
||||||
|
use_field_init_shorthand = true
|
||||||
|
use_try_shorthand = true
|
Loading…
Add table
Add a link
Reference in a new issue