first commit
This commit is contained in:
commit
c591b2c272
50 changed files with 2650 additions and 0 deletions
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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue