@@ 1,80 1,123 @@
#![no_std]
pub mod pokedex {
- use minicbor::{Encode, Decode, bytes::ByteArray};
-
+ use minicbor::{bytes::ByteArray, Decode, Encode};
+
#[derive(Encode, Decode, Debug)]
pub struct Pokemon {
- #[n(0)] pub species_id: u8,
- #[n(1)] pub nickname: Option<[u8; 12]>,
-
- #[n(2)] pub level: u8,
- #[n(3)] pub xp: u16,
- #[n(5)] pub current_hp: u16,
-
- #[n(6)] pub hp: StatData,
- #[n(7)] pub attack: StatData,
- #[n(8)] pub defense: StatData,
- #[n(9)] pub special_attack: StatData,
- #[n(10)] pub special_defense: StatData,
- #[n(11)] pub speed: StatData,
-
- #[n(12)] pub moves: [Option<u16>; 4],
+ #[n(0)]
+ pub species_id: u8,
+ #[n(1)]
+ pub nickname: Option<[u8; 12]>,
+
+ #[n(2)]
+ pub level: u8,
+ #[n(3)]
+ pub xp: u16,
+ #[n(5)]
+ pub current_hp: u16,
+
+ #[n(6)]
+ pub hp: StatData,
+ #[n(7)]
+ pub attack: StatData,
+ #[n(8)]
+ pub defense: StatData,
+ #[n(9)]
+ pub special_attack: StatData,
+ #[n(10)]
+ pub special_defense: StatData,
+ #[n(11)]
+ pub speed: StatData,
+
+ #[n(12)]
+ pub moves: [Option<u16>; 4],
}
#[derive(Encode, Decode, Debug, Clone, Copy)]
pub struct StatData {
- #[n(0)] pub value: u16,
- #[n(2)] pub effort_value: u16,
- #[n(3)] pub individual_value: u8,
+ #[n(0)]
+ pub value: u16,
+ #[n(2)]
+ pub effort_value: u16,
+ #[n(3)]
+ pub individual_value: u8,
}
#[derive(Encode, Decode, Debug)]
pub struct PokemonSpecies {
- #[n(0)] pub id: u8,
- #[n(1)] pub name: [u8; 12],
- #[n(2)] pub type_primary: Type,
- #[n(3)] pub type_secondary: Option<Type>,
- #[n(14)] pub growth_rate: GrowthRate,
-
- #[n(4)] pub capture_rate: u8,
- #[n(5)] pub base_experience: u8,
-
- #[n(7)] pub hp: SpeciesStatData,
- #[n(8)] pub attack: SpeciesStatData,
- #[n(9)] pub defense: SpeciesStatData,
- #[n(10)] pub special_attack: SpeciesStatData,
- #[n(11)] pub special_defense: SpeciesStatData,
- #[n(12)] pub speed: SpeciesStatData,
-
- #[n(13)] pub sprite: ByteArray<578>,
+ #[n(0)]
+ pub id: u8,
+ #[n(1)]
+ pub name: [u8; 12],
+ #[n(2)]
+ pub type_primary: Type,
+ #[n(3)]
+ pub type_secondary: Option<Type>,
+ #[n(14)]
+ pub growth_rate: GrowthRate,
+
+ #[n(4)]
+ pub capture_rate: u8,
+ #[n(5)]
+ pub base_experience: u8,
+
+ #[n(7)]
+ pub hp: SpeciesStatData,
+ #[n(8)]
+ pub attack: SpeciesStatData,
+ #[n(9)]
+ pub defense: SpeciesStatData,
+ #[n(10)]
+ pub special_attack: SpeciesStatData,
+ #[n(11)]
+ pub special_defense: SpeciesStatData,
+ #[n(12)]
+ pub speed: SpeciesStatData,
+
+ #[n(13)]
+ pub sprite: ByteArray<578>,
}
#[derive(Encode, Decode, Debug)]
#[cbor(index_only)]
pub enum Stats {
- #[n(0)] Hp,
- #[n(1)] Attack,
- #[n(2)] Defense,
- #[n(3)] SpecialAttack,
- #[n(4)] SpecialDefense,
- #[n(5)] Speed,
+ #[n(0)]
+ Hp,
+ #[n(1)]
+ Attack,
+ #[n(2)]
+ Defense,
+ #[n(3)]
+ SpecialAttack,
+ #[n(4)]
+ SpecialDefense,
+ #[n(5)]
+ Speed,
}
#[derive(Encode, Decode, Debug, Clone, Copy)]
pub struct SpeciesStatData {
- #[n(0)] pub base_value: u16,
- #[n(1)] pub effort_value_yield: u8,
+ #[n(0)]
+ pub base_value: u16,
+ #[n(1)]
+ pub effort_value_yield: u8,
}
#[derive(Encode, Decode, Debug, Clone, Copy)]
pub enum GrowthRate {
- #[n(0)] ERRATIC,
- #[n(1)] FAST,
- #[n(2)] MEDIUM_FAST,
- #[n(3)] MEDIUM_SLOW,
- #[n(4)] SLOW,
- #[n(5)] FLUCTUATING
+ #[n(0)]
+ ERRATIC,
+ #[n(1)]
+ FAST,
+ #[n(2)]
+ MEDIUM_FAST,
+ #[n(3)]
+ MEDIUM_SLOW,
+ #[n(4)]
+ SLOW,
+ #[n(5)]
+ FLUCTUATING,
}
impl GrowthRate {
@@ 95,24 138,42 @@ pub mod pokedex {
#[derive(Encode, Decode, Debug, Clone, Copy)]
#[cbor(index_only)]
pub enum Type {
- #[n(0)] Normal,
- #[n(1)] Fighting,
- #[n(2)] Flying,
- #[n(3)] Poison,
- #[n(4)] Ground,
- #[n(5)] Rock,
- #[n(6)] Bug,
- #[n(7)] Ghost,
- #[n(8)] Steel,
- #[n(9)] Fire,
- #[n(10)] Water,
- #[n(11)] Grass,
- #[n(12)] Electric,
- #[n(13)] Psychic,
- #[n(14)] Ice,
- #[n(15)] Dragon,
- #[n(16)] Dark,
- #[n(17)] Fairy,
+ #[n(0)]
+ Normal,
+ #[n(1)]
+ Fighting,
+ #[n(2)]
+ Flying,
+ #[n(3)]
+ Poison,
+ #[n(4)]
+ Ground,
+ #[n(5)]
+ Rock,
+ #[n(6)]
+ Bug,
+ #[n(7)]
+ Ghost,
+ #[n(8)]
+ Steel,
+ #[n(9)]
+ Fire,
+ #[n(10)]
+ Water,
+ #[n(11)]
+ Grass,
+ #[n(12)]
+ Electric,
+ #[n(13)]
+ Psychic,
+ #[n(14)]
+ Ice,
+ #[n(15)]
+ Dragon,
+ #[n(16)]
+ Dark,
+ #[n(17)]
+ Fairy,
}
impl Type {
@@ 135,116 196,170 @@ pub mod pokedex {
Type::Ice => "ICE",
Type::Dragon => "DRAGON",
Type::Dark => "DARK",
- Type::Fairy => "FAIRY"
+ Type::Fairy => "FAIRY",
}
}
}
#[derive(Encode, Decode, Debug)]
pub struct MoveListChunk {
- #[n(0)] pub is_final_chunk: bool,
- #[n(1)] pub moves: [Option<LearnableMove>; 16],
+ #[n(0)]
+ pub is_final_chunk: bool,
+ #[n(1)]
+ pub moves: [Option<LearnableMove>; 16],
}
#[derive(Encode, Decode, Debug, Copy, Clone)]
pub struct LearnableMove {
- #[n(0)] pub id: u16,
- #[n(1)] pub condition: LearnCondition,
+ #[n(0)]
+ pub id: u16,
+ #[n(1)]
+ pub condition: LearnCondition,
}
#[derive(Encode, Decode, Debug, Copy, Clone)]
pub enum LearnCondition {
- #[n(0)] LevelUp(#[n(0)] u8),
- #[n(1)] Machine,
+ #[n(0)]
+ LevelUp(#[n(0)] u8),
+ #[n(1)]
+ Machine,
}
#[derive(Encode, Decode, Debug)]
pub struct Move {
- #[n(0)] pub id: u16,
- #[n(1)] pub name: [u8; 12],
-
- #[n(2)] pub type_: Type,
- #[n(3)] pub damage_class: DamageClass,
- #[n(4)] pub target: Target,
-
- #[n(5)] pub accuracy: u8,
- #[n(6)] pub power: u8,
- #[n(7)] pub pp: u8,
- #[n(8)] pub priority: u8,
-
- #[n(9)] pub parameters: Parameters,
- #[n(10)] pub stat_changes: [Option<StatChange>; 2]
+ #[n(0)]
+ pub id: u16,
+ #[n(1)]
+ pub name: [u8; 12],
+
+ #[n(2)]
+ pub type_: Type,
+ #[n(3)]
+ pub damage_class: DamageClass,
+ #[n(4)]
+ pub target: Target,
+
+ #[n(5)]
+ pub accuracy: u8,
+ #[n(6)]
+ pub power: u8,
+ #[n(7)]
+ pub pp: u8,
+ #[n(8)]
+ pub priority: u8,
+
+ #[n(9)]
+ pub parameters: Parameters,
+ #[n(10)]
+ pub stat_changes: [Option<StatChange>; 2],
}
#[derive(Encode, Decode, Debug)]
#[cbor(map)]
pub struct Parameters {
- #[n(0)] pub ailment: Option<AilmentParameter>,
- #[n(1)] pub crit_rate: u8,
- #[n(2)] pub drain: u8,
- #[n(3)] pub flinch_chance: u8,
- #[n(4)] pub healing: u8,
- #[n(5)] pub stat_chance: u8,
- #[n(6)] pub turn_range: Option<ParameterRange>,
- #[n(7)] pub hit_range: Option<ParameterRange>,
+ #[n(0)]
+ pub ailment: Option<AilmentParameter>,
+ #[n(1)]
+ pub crit_rate: u8,
+ #[n(2)]
+ pub drain: u8,
+ #[n(3)]
+ pub flinch_chance: u8,
+ #[n(4)]
+ pub healing: u8,
+ #[n(5)]
+ pub stat_chance: u8,
+ #[n(6)]
+ pub turn_range: Option<ParameterRange>,
+ #[n(7)]
+ pub hit_range: Option<ParameterRange>,
}
#[derive(Encode, Decode, Debug)]
pub struct AilmentParameter {
- #[n(0)] pub ailment: AilmentType,
- #[n(1)] pub chance: u8,
+ #[n(0)]
+ pub ailment: AilmentType,
+ #[n(1)]
+ pub chance: u8,
}
#[derive(Encode, Decode, Debug)]
#[cbor(index_only)]
pub enum AilmentType {
- #[n(0)] Burn,
- #[n(1)] Confusion,
- #[n(2)] Disable,
- #[n(3)] Freeze,
- #[n(4)] LeechSeed,
- #[n(5)] Paralysis,
- #[n(6)] Poison,
- #[n(7)] Sleep,
- #[n(8)] Trap,
+ #[n(0)]
+ Burn,
+ #[n(1)]
+ Confusion,
+ #[n(2)]
+ Disable,
+ #[n(3)]
+ Freeze,
+ #[n(4)]
+ LeechSeed,
+ #[n(5)]
+ Paralysis,
+ #[n(6)]
+ Poison,
+ #[n(7)]
+ Sleep,
+ #[n(8)]
+ Trap,
}
#[derive(Encode, Decode, Debug)]
pub struct ParameterRange {
- #[n(0)] pub min: u8,
- #[n(1)] pub max: u8,
+ #[n(0)]
+ pub min: u8,
+ #[n(1)]
+ pub max: u8,
}
#[derive(Encode, Decode, Debug)]
#[cbor(index_only)]
pub enum DamageClass {
- #[n(0)] Physical,
- #[n(1)] Special,
- #[n(2)] Status,
+ #[n(0)]
+ Physical,
+ #[n(1)]
+ Special,
+ #[n(2)]
+ Status,
}
#[derive(Encode, Decode, Debug)]
#[cbor(index_only)]
pub enum Target {
- #[n(0)] AllOpponents,
- #[n(1)] AllOtherPokemon,
- #[n(2)] EntireField,
- #[n(3)] RandomOpponent,
- #[n(4)] SelectedPokemon,
- #[n(5)] SpecificMove,
- #[n(6)] User,
- #[n(7)] UserField,
+ #[n(0)]
+ AllOpponents,
+ #[n(1)]
+ AllOtherPokemon,
+ #[n(2)]
+ EntireField,
+ #[n(3)]
+ RandomOpponent,
+ #[n(4)]
+ SelectedPokemon,
+ #[n(5)]
+ SpecificMove,
+ #[n(6)]
+ User,
+ #[n(7)]
+ UserField,
}
#[derive(Encode, Decode, Debug)]
pub struct StatChange {
- #[n(0)] pub amount: u8,
- #[n(1)] pub stat: Stats,
+ #[n(0)]
+ pub amount: u8,
+ #[n(1)]
+ pub stat: Stats,
}
}
pub mod generation {
- use crate::pokedex::{Pokemon, PokemonSpecies, StatData, SpeciesStatData, StatChange, LearnableMove, LearnCondition};
+ use crate::pokedex::{
+ LearnCondition, LearnableMove, Pokemon, PokemonSpecies, SpeciesStatData, StatChange,
+ StatData,
+ };
trait Random {
fn random(&self) -> u8;
@@ 254,7 369,12 @@ pub mod generation {
}
}
- pub fn generate_pokemon(species: PokemonSpecies, move_list: &mut dyn Iterator<Item = &LearnableMove>, level: u8, rng: &dyn Random) -> Pokemon {
+ pub fn generate_pokemon(
+ species: PokemonSpecies,
+ move_list: &mut dyn Iterator<Item = &LearnableMove>,
+ level: u8,
+ rng: &dyn Random,
+ ) -> Pokemon {
let mut moves = [None; 4];
let mut i = 0;
for m in move_list {
@@ 271,9 391,9 @@ pub mod generation {
let hp = StatData {
value: calculate_hp_stat(species.hp.base_value, 0, hp_iv, level),
effort_value: 0,
- individual_value: hp_iv
+ individual_value: hp_iv,
};
- return Pokemon{
+ return Pokemon {
species_id: species.id,
nickname: None,
level,
@@ 285,20 405,24 @@ pub mod generation {
special_attack: new_stat(species.special_attack, level, rng),
special_defense: new_stat(species.special_defense, level, rng),
speed: new_stat(species.speed, level, rng),
- moves
- }
+ moves,
+ };
}
fn new_stat(stat: SpeciesStatData, level: u8, rng: &dyn Random) -> StatData {
let iv = rng.generate_iv();
- return StatData { value: calculate_stat(stat.base_value, 0, iv, level), effort_value: 0, individual_value: iv }
+ return StatData {
+ value: calculate_stat(stat.base_value, 0, iv, level),
+ effort_value: 0,
+ individual_value: iv,
+ };
}
fn calculate_stat(base: u16, ev: u16, iv: u8, level: u8) -> u16 {
- return (((2 * base) + (iv as u16) + ev) * (level as u16) / 100) + 5
+ return (((2 * base) + (iv as u16) + ev) * (level as u16) / 100) + 5;
}
fn calculate_hp_stat(base: u16, ev: u16, iv: u8, level: u8) -> u16 {
- return (((2 * base) + (iv as u16) + ev) * (level as u16) / 100) + (level as u16) + 10
+ return (((2 * base) + (iv as u16) + ev) * (level as u16) / 100) + (level as u16) + 10;
}
}
@@ 4,11 4,11 @@
extern crate nb;
use bitbang_hal;
-use embedded_graphics::{egrectangle, egtext, egline};
use embedded_graphics::fonts::Text;
use embedded_graphics::image::Image;
use embedded_graphics::primitives::Rectangle;
use embedded_graphics::style::{PrimitiveStyleBuilder, TextStyleBuilder};
+use embedded_graphics::{egline, egrectangle, egtext};
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*};
use embedded_picofont::FontPico;
use esp8266_hal::ehal::digital::v2::InputPin;
@@ 187,7 187,13 @@ fn main() -> ! {
if !has_drawn {
has_drawn = true;
- egrectangle!(top_left = (0, 0), bottom_right = (128, 64), style = black_solid).draw(&mut display).ok();
+ egrectangle!(
+ top_left = (0, 0),
+ bottom_right = (128, 64),
+ style = black_solid
+ )
+ .draw(&mut display)
+ .ok();
let res = read_pokemon(pokemon_id, &mut storage);
if res.is_err() {
@@ 205,29 211,116 @@ fn main() -> ! {
}
pokemon = res.unwrap();
- egrectangle!(top_left = (0, 0), bottom_right = (128, 6), style = white_solid).draw(&mut display).ok();
- egtext!(text = core::str::from_utf8(&pokemon.name).unwrap(), top_left = (1, 1), style = black_text).draw(&mut display).ok();
- egline!(start = (57, 7), end = (57, 64), style = white_solid).draw(&mut display).ok();
-
- egtext!(text = pokemon.type_primary.name(), top_left = (58, 10), style = white_text).draw(&mut display).ok();
- pokemon.type_secondary.and_then(|t| egtext!(text = t.name(), top_left = (58, 16), style = white_text).draw(&mut display).ok());
-
- egtext!(text = "HP", top_left = (58, 28), style = white_text).draw(&mut display).ok();
- egtext!(text = "ATK", top_left = (58, 36), style = white_text).draw(&mut display).ok();
- egtext!(text = "DEF", top_left = (58, 44), style = white_text).draw(&mut display).ok();
- egtext!(text = "SPD", top_left = (93, 28), style = white_text).draw(&mut display).ok();
- egtext!(text = "SATK", top_left = (93, 36), style = white_text).draw(&mut display).ok();
- egtext!(text = "SDEF", top_left = (93, 44), style = white_text).draw(&mut display).ok();
-
- egtext!(text = core::str::from_utf8(&num_to_str(pokemon.hp.base_value.into())).unwrap(), top_left = (75, 28), style = white_text).draw(&mut display).ok();
- egtext!(text = core::str::from_utf8(&num_to_str(pokemon.attack.base_value.into())).unwrap(), top_left = (75, 36), style = white_text).draw(&mut display).ok();
- egtext!(text = core::str::from_utf8(&num_to_str(pokemon.defense.base_value.into())).unwrap(), top_left = (75, 44), style = white_text).draw(&mut display).ok();
- egtext!(text = core::str::from_utf8(&num_to_str(pokemon.speed.base_value.into())).unwrap(), top_left = (113, 28), style = white_text).draw(&mut display).ok();
- egtext!(text = core::str::from_utf8(&num_to_str(pokemon.special_attack.base_value.into())).unwrap(), top_left = (113, 36), style = white_text).draw(&mut display).ok();
- egtext!(text = core::str::from_utf8(&num_to_str(pokemon.special_defense.base_value.into())).unwrap(), top_left = (113, 44), style = white_text).draw(&mut display).ok();
-
- egrectangle!(top_left = (56, 57), bottom_right = (128, 64), style = white_solid).draw(&mut display).ok();
- egtext!(text = "A:MOVES B:BACK", top_left = (58, 58), style = black_text).draw(&mut display).ok();
+ egrectangle!(
+ top_left = (0, 0),
+ bottom_right = (128, 6),
+ style = white_solid
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text = core::str::from_utf8(&pokemon.name).unwrap(),
+ top_left = (1, 1),
+ style = black_text
+ )
+ .draw(&mut display)
+ .ok();
+ egline!(start = (57, 7), end = (57, 64), style = white_solid)
+ .draw(&mut display)
+ .ok();
+
+ egtext!(
+ text = pokemon.type_primary.name(),
+ top_left = (58, 10),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+ pokemon.type_secondary.and_then(|t| {
+ egtext!(text = t.name(), top_left = (58, 16), style = white_text)
+ .draw(&mut display)
+ .ok()
+ });
+
+ egtext!(text = "HP", top_left = (58, 28), style = white_text)
+ .draw(&mut display)
+ .ok();
+ egtext!(text = "ATK", top_left = (58, 36), style = white_text)
+ .draw(&mut display)
+ .ok();
+ egtext!(text = "DEF", top_left = (58, 44), style = white_text)
+ .draw(&mut display)
+ .ok();
+ egtext!(text = "SPD", top_left = (93, 28), style = white_text)
+ .draw(&mut display)
+ .ok();
+ egtext!(text = "SATK", top_left = (93, 36), style = white_text)
+ .draw(&mut display)
+ .ok();
+ egtext!(text = "SDEF", top_left = (93, 44), style = white_text)
+ .draw(&mut display)
+ .ok();
+
+ egtext!(
+ text = core::str::from_utf8(&num_to_str(pokemon.hp.base_value.into())).unwrap(),
+ top_left = (75, 28),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text = core::str::from_utf8(&num_to_str(pokemon.attack.base_value.into())).unwrap(),
+ top_left = (75, 36),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text =
+ core::str::from_utf8(&num_to_str(pokemon.defense.base_value.into())).unwrap(),
+ top_left = (75, 44),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text = core::str::from_utf8(&num_to_str(pokemon.speed.base_value.into())).unwrap(),
+ top_left = (113, 28),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text = core::str::from_utf8(&num_to_str(pokemon.special_attack.base_value.into()))
+ .unwrap(),
+ top_left = (113, 36),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text = core::str::from_utf8(&num_to_str(pokemon.special_defense.base_value.into()))
+ .unwrap(),
+ top_left = (113, 44),
+ style = white_text
+ )
+ .draw(&mut display)
+ .ok();
+
+ egrectangle!(
+ top_left = (56, 57),
+ bottom_right = (128, 64),
+ style = white_solid
+ )
+ .draw(&mut display)
+ .ok();
+ egtext!(
+ text = "A:MOVES B:BACK",
+ top_left = (58, 58),
+ style = black_text
+ )
+ .draw(&mut display)
+ .ok();
let image = Bmp::from_slice(pokemon.sprite.as_ref()).unwrap();
let mut real_image = Image::new(&image, Point::zero());
@@ 268,7 361,7 @@ fn num_to_str(mut num: u32) -> [u8; 3] {
num %= base;
base /= 10;
}
- return buf
+ return buf;
}
const DATA_OFFSET: u32 = 0x200000;