Initial commit
This commit is contained in:
406
src/touch.rs
Normal file
406
src/touch.rs
Normal file
@@ -0,0 +1,406 @@
|
||||
use crate::{display::ColorScheme, state::{CommanderDamage, Game, MainScreenItem, Screen, SettingScreenEntry, SettingScreenItem, SystemState}};
|
||||
|
||||
const CMDDMGLIST: [MainScreenItem;6] = [
|
||||
MainScreenItem::Dmg1,
|
||||
MainScreenItem::Dmg2,
|
||||
MainScreenItem::Dmg3,
|
||||
MainScreenItem::Dmg4,
|
||||
MainScreenItem::Dmg5,
|
||||
MainScreenItem::Dmg6,
|
||||
];
|
||||
|
||||
pub fn get_touch_action(x: f32, y: f32, gesture: u8, ctx: &mut SystemState) -> () {
|
||||
let x = x - 120.;
|
||||
let y = -(y - 120.);
|
||||
let touch_rad = (x*x)+(y*y);
|
||||
let angle;
|
||||
|
||||
let next_state;
|
||||
|
||||
if (gesture == 0x3) | (gesture == 0x4) {
|
||||
ctx.screen = match &ctx.screen {
|
||||
Screen::Main(_) => Screen::Settings(SettingScreenItem { entry: SettingScreenEntry::NewGame, inner: false , prev: None}),
|
||||
Screen::Settings(_) => Screen::Main(MainScreenItem::Life),
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
match &ctx.screen {
|
||||
Screen::Main(selected) => {
|
||||
|
||||
let mut bottom_selectable_list: [Option<MainScreenItem>;5] = [const {None};5];
|
||||
let mut pos = 0;
|
||||
if ctx.settings.show_cmd_tax {
|
||||
bottom_selectable_list[pos] = Some(crate::state::MainScreenItem::Tax);
|
||||
pos += 1;
|
||||
}
|
||||
if ctx.settings.show_energy {
|
||||
bottom_selectable_list[pos] = Some(crate::state::MainScreenItem::Energy);
|
||||
pos+=1;
|
||||
};
|
||||
if ctx.settings.show_experience {
|
||||
bottom_selectable_list[pos] = Some(crate::state::MainScreenItem::Experience);
|
||||
pos+=1;
|
||||
};
|
||||
if ctx.settings.show_tickets {
|
||||
bottom_selectable_list[pos] = Some(crate::state::MainScreenItem::Tickets);
|
||||
pos+=1;
|
||||
};
|
||||
if ctx.settings.show_infect {
|
||||
bottom_selectable_list[pos] = Some(crate::state::MainScreenItem::Poison);
|
||||
};
|
||||
|
||||
let bottom_count = bottom_selectable_list.iter().fold(0, |acc, x| acc+x.is_some() as u8);
|
||||
|
||||
if touch_rad > (70.*70.) {
|
||||
angle = atan2_norm(y, x)*90.;
|
||||
//ctx.game.life = angle as i32; //debug
|
||||
let top;
|
||||
let check_angles = if y >= 0. {
|
||||
if ctx.settings.opponenets == 0 {
|
||||
return;
|
||||
}
|
||||
top = true;
|
||||
ctx.positions.get_top_list(ctx.settings.opponenets)
|
||||
} else {
|
||||
if bottom_count == 0 {
|
||||
return;
|
||||
}
|
||||
top = false;
|
||||
ctx.positions.get_bottom_list(bottom_count)
|
||||
};
|
||||
|
||||
let touch_item = match check_angles.iter().position(|x| (x.angle.to_degrees()-angle).abs()<15.) {
|
||||
Some(loc) => loc,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let sel_match = if top {
|
||||
Some(CMDDMGLIST.into_iter().nth(touch_item).unwrap_or(MainScreenItem::Dmg1))
|
||||
} else {
|
||||
bottom_selectable_list[touch_item]
|
||||
};
|
||||
|
||||
if let Some(selected_item) = sel_match {
|
||||
if selected_item == *selected {
|
||||
next_state = Screen::Main(MainScreenItem::Life);
|
||||
} else {
|
||||
next_state = Screen::Main(selected_item);
|
||||
}
|
||||
} else {
|
||||
next_state = Screen::Main(MainScreenItem::Life);
|
||||
}
|
||||
|
||||
} else {
|
||||
match selected {
|
||||
crate::state::MainScreenItem::Life => {
|
||||
let d = touch_inc_dec(y, gesture);
|
||||
ctx.game.life = ctx.game.life.saturating_add(d as i32);
|
||||
},
|
||||
|
||||
crate::state::MainScreenItem::Dmg1 => {
|
||||
cmd_dmg_w_swap(ctx, x, y, gesture, 0);
|
||||
},
|
||||
crate::state::MainScreenItem::Dmg2 => {
|
||||
cmd_dmg_w_swap(ctx, x, y, gesture, 1);
|
||||
},
|
||||
crate::state::MainScreenItem::Dmg3 => {
|
||||
cmd_dmg_w_swap(ctx, x, y, gesture, 2);
|
||||
},
|
||||
crate::state::MainScreenItem::Dmg4 => {
|
||||
cmd_dmg_w_swap(ctx, x, y, gesture, 3);
|
||||
},
|
||||
crate::state::MainScreenItem::Dmg5 => {
|
||||
cmd_dmg_w_swap(ctx, x, y, gesture, 4);
|
||||
},
|
||||
crate::state::MainScreenItem::Dmg6 => {
|
||||
cmd_dmg_w_swap(ctx, x, y, gesture, 5);
|
||||
},
|
||||
|
||||
crate::state::MainScreenItem::Tax => {
|
||||
cmd_tax_w_swap(ctx, x, y, gesture);
|
||||
},
|
||||
crate::state::MainScreenItem::Energy => {
|
||||
let d = touch_inc_dec(y, gesture);
|
||||
ctx.game.energy = ctx.game.energy.saturating_add_signed(d.into());
|
||||
},
|
||||
crate::state::MainScreenItem::Experience => {
|
||||
let d = touch_inc_dec(y, gesture);
|
||||
ctx.game.experience = ctx.game.experience.saturating_add_signed(d.into());
|
||||
},
|
||||
crate::state::MainScreenItem::Tickets => {
|
||||
let d = touch_inc_dec(y, gesture);
|
||||
ctx.game.tickets = ctx.game.tickets.saturating_add_signed(d.into());
|
||||
},
|
||||
crate::state::MainScreenItem::Poison => {
|
||||
let d = touch_inc_dec(y, gesture);
|
||||
ctx.game.infect = ctx.game.infect.saturating_add_signed(d.into());
|
||||
},
|
||||
};
|
||||
next_state = ctx.screen;
|
||||
};
|
||||
},
|
||||
Screen::Settings(selected) => {
|
||||
if !selected.inner {
|
||||
if gesture == 0x01_u8 {
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry.prev(), inner: false, prev: selected.prev });
|
||||
} else if gesture == 0x02_u8 {
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry.next(), inner: false, prev: selected.prev });
|
||||
} else {
|
||||
if y > 55. {
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry.prev(), inner: false, prev: selected.prev});
|
||||
} else if y < -55. {
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry.next(), inner: false, prev: selected.prev });
|
||||
} else {
|
||||
let prev = match selected.entry {
|
||||
SettingScreenEntry::NewGame => None,
|
||||
SettingScreenEntry::Opponents => Some(ctx.settings.opponenets as u32),
|
||||
SettingScreenEntry::StartingLife => Some(ctx.settings.starting_life as u32),
|
||||
SettingScreenEntry::Colors => Some(Into::<u8>::into(ctx.settings.color_scheme) as u32),
|
||||
SettingScreenEntry::Brightness => Some(ctx.settings.brightness.into()),
|
||||
SettingScreenEntry::ShowTax => Some(ctx.settings.show_cmd_tax as u32),
|
||||
SettingScreenEntry::ShowEnergy => Some(ctx.settings.show_energy as u32),
|
||||
SettingScreenEntry::ShowExperience => Some(ctx.settings.show_experience as u32),
|
||||
SettingScreenEntry::ShowTickets => Some(ctx.settings.show_tickets as u32),
|
||||
SettingScreenEntry::ShowPoison => Some(ctx.settings.show_infect as u32),
|
||||
};
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry, inner: true, prev: prev});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if x < -75. {
|
||||
match selected.entry {
|
||||
SettingScreenEntry::NewGame => {
|
||||
ctx.game = Game {
|
||||
life: ctx.settings.starting_life,
|
||||
cmd_dmg: [CommanderDamage{main: 0, partner: 0, is_partner: false};6],
|
||||
cmd_tax: CommanderDamage { main: 0, partner: 0, is_partner: false },
|
||||
infect: 0,
|
||||
energy: 0,
|
||||
experience: 0,
|
||||
tickets: 0,
|
||||
monarch: false,
|
||||
};
|
||||
next_state = Screen::Main(MainScreenItem::Life);
|
||||
},
|
||||
_ => {
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry, inner: false, prev: None })
|
||||
}
|
||||
}
|
||||
} else if x > 75. {
|
||||
match selected.entry {
|
||||
SettingScreenEntry::NewGame => {},
|
||||
SettingScreenEntry::Opponents => {
|
||||
ctx.settings.opponenets = selected.prev.unwrap_or(0) as u8;
|
||||
},
|
||||
SettingScreenEntry::StartingLife => {
|
||||
ctx.settings.starting_life = selected.prev.unwrap_or(0) as i32;
|
||||
},
|
||||
SettingScreenEntry::Colors => {
|
||||
ctx.settings.color_scheme =Into::<ColorScheme>::into(selected.prev.unwrap_or(0) as u8);
|
||||
},
|
||||
SettingScreenEntry::Brightness => {
|
||||
ctx.settings.brightness = selected.prev.unwrap_or(0).into();
|
||||
},
|
||||
SettingScreenEntry::ShowTax => {
|
||||
ctx.settings.show_cmd_tax = selected.prev.unwrap_or_default() != 0;
|
||||
},
|
||||
SettingScreenEntry::ShowEnergy => {
|
||||
ctx.settings.show_energy = selected.prev.unwrap_or_default() != 0;
|
||||
},
|
||||
SettingScreenEntry::ShowExperience => {
|
||||
ctx.settings.show_experience = selected.prev.unwrap_or_default() != 0;
|
||||
},
|
||||
SettingScreenEntry::ShowTickets => {
|
||||
ctx.settings.show_tickets = selected.prev.unwrap_or_default() != 0;
|
||||
},
|
||||
SettingScreenEntry::ShowPoison => {
|
||||
ctx.settings.show_infect = selected.prev.unwrap_or_default() != 0;
|
||||
},
|
||||
}
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry, inner: false, prev: None })
|
||||
} else {
|
||||
match selected.entry {
|
||||
SettingScreenEntry::NewGame => {
|
||||
|
||||
},
|
||||
SettingScreenEntry::Opponents => {
|
||||
ctx.settings.opponenets = ctx.settings.opponenets.saturating_add_signed(touch_inc_dec(y, gesture));
|
||||
},
|
||||
SettingScreenEntry::StartingLife => {
|
||||
ctx.settings.starting_life = ctx.settings.starting_life.saturating_add(touch_inc_dec(y, gesture) as i32);
|
||||
},
|
||||
SettingScreenEntry::Colors => {
|
||||
if y > 40. {
|
||||
ctx.settings.color_scheme = ctx.settings.color_scheme.dec();
|
||||
} else if y < -40. {
|
||||
ctx.settings.color_scheme = ctx.settings.color_scheme.inc();
|
||||
}
|
||||
},
|
||||
SettingScreenEntry::Brightness => {
|
||||
let tmp = touch_inc_dec(y, gesture);
|
||||
if tmp > 0 {
|
||||
ctx.settings.brightness = ctx.settings.brightness.inc();
|
||||
} else {
|
||||
ctx.settings.brightness = ctx.settings.brightness.dec();
|
||||
}
|
||||
},
|
||||
SettingScreenEntry::ShowTax => {
|
||||
let det = select_button(x, y, gesture);
|
||||
if let Some(i) = det {
|
||||
ctx.settings.show_cmd_tax = i;
|
||||
}
|
||||
},
|
||||
SettingScreenEntry::ShowEnergy => {
|
||||
let det = select_button(x, y, gesture);
|
||||
if let Some(i) = det {
|
||||
ctx.settings.show_energy = i;
|
||||
}
|
||||
},
|
||||
SettingScreenEntry::ShowExperience => {
|
||||
let det = select_button(x, y, gesture);
|
||||
if let Some(i) = det {
|
||||
ctx.settings.show_experience = i;
|
||||
}
|
||||
},
|
||||
SettingScreenEntry::ShowTickets => {
|
||||
let det = select_button(x, y, gesture);
|
||||
if let Some(i) = det {
|
||||
ctx.settings.show_tickets = i;
|
||||
}
|
||||
},
|
||||
SettingScreenEntry::ShowPoison => {
|
||||
let det = select_button(x, y, gesture);
|
||||
if let Some(i) = det {
|
||||
ctx.settings.show_infect = i;
|
||||
}
|
||||
},
|
||||
}
|
||||
next_state = Screen::Settings(SettingScreenItem { entry: selected.entry, inner: selected.inner, prev: selected.prev })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.screen = next_state;
|
||||
}
|
||||
|
||||
/// Approximates `atan2(y,x)` normalized to the `[0, 4)` range with a maximum
|
||||
/// error of `0.1620` degrees.
|
||||
fn atan2_norm(lhs: f32, rhs: f32) -> f32 {
|
||||
const SIGN_MASK: u32 = 0x8000_0000;
|
||||
const B: f32 = 0.596_227;
|
||||
|
||||
let y = lhs;
|
||||
let x = rhs;
|
||||
|
||||
// Extract sign bits from floating point values
|
||||
let ux_s = SIGN_MASK & x.to_bits();
|
||||
let uy_s = SIGN_MASK & y.to_bits();
|
||||
|
||||
// Determine quadrant offset
|
||||
let q = ((!ux_s & uy_s) >> 29 | ux_s >> 30) as f32;
|
||||
|
||||
// Calculate arctangent in the first quadrant
|
||||
let bxy_a = (B * x * y).abs();
|
||||
let n = bxy_a + y * y;
|
||||
let atan_1q = n / (x * x + bxy_a + n);
|
||||
|
||||
// Translate it to the proper quadrant
|
||||
let uatan_2q = (ux_s ^ uy_s) | atan_1q.to_bits();
|
||||
q + f32::from_bits(uatan_2q)
|
||||
}
|
||||
|
||||
fn touch_inc_dec(y: f32, gesture: u8) -> i8 {
|
||||
if gesture == 0x05 {
|
||||
if y >= 0. {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
} else if gesture == 0x02 {
|
||||
5
|
||||
} else if gesture == 0x01 {
|
||||
-5
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn touch_left_right(x: f32, y: f32, gesture: u8) -> (i8, bool) {
|
||||
if x <= 0. {
|
||||
(touch_inc_dec(y, gesture), true)
|
||||
} else {
|
||||
(touch_inc_dec(y, gesture), false)
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_dmg_calc(ctx: &mut SystemState, x: f32, y: f32, gesture: u8, pos: usize) {
|
||||
if ctx.game.cmd_dmg[pos].is_partner {
|
||||
let (d, left) = touch_left_right(x, y, gesture);
|
||||
if left {
|
||||
ctx.game.cmd_dmg[pos].main = ctx.game.cmd_dmg[pos].main.saturating_add_signed(d);
|
||||
} else {
|
||||
ctx.game.cmd_dmg[pos].partner = ctx.game.cmd_dmg[pos].partner.saturating_add_signed(d);
|
||||
}
|
||||
} else {
|
||||
let d = touch_inc_dec(y, gesture);
|
||||
ctx.game.cmd_dmg[pos].main = ctx.game.cmd_dmg[pos].main.saturating_add_signed(d);
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_tax_calc(ctx: &mut SystemState, x: f32, y: f32, gesture: u8) {
|
||||
if ctx.game.cmd_tax.is_partner {
|
||||
let (mut d, left) = touch_left_right(x, y, gesture);
|
||||
|
||||
if d >= 0 {
|
||||
d = 2;
|
||||
} else {
|
||||
d =-2;
|
||||
}
|
||||
|
||||
if left {
|
||||
ctx.game.cmd_tax.main = ctx.game.cmd_tax.main.saturating_add_signed(d);
|
||||
} else {
|
||||
ctx.game.cmd_tax.partner = ctx.game.cmd_tax.partner.saturating_add_signed(d);
|
||||
}
|
||||
} else {
|
||||
let mut d = touch_inc_dec(y, gesture);
|
||||
|
||||
if d >= 0 {
|
||||
d = 2;
|
||||
} else {
|
||||
d =-2;
|
||||
}
|
||||
|
||||
ctx.game.cmd_tax.main = ctx.game.cmd_tax.main.saturating_add_signed(d);
|
||||
}
|
||||
}
|
||||
|
||||
/// true is left selection false is right selection
|
||||
fn select_button(x: f32, y: f32, _gesture: u8) -> Option<bool> {
|
||||
if (y<60.) & (y>-60.) {
|
||||
if x<=0. {
|
||||
Some(true)
|
||||
} else {
|
||||
Some(false)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_dmg_w_swap(ctx: &mut SystemState, x: f32, y: f32, gesture: u8, pos: usize) {
|
||||
if (x>-20.) & (x<20.) & (y< -30.)&(y>-50.) {
|
||||
ctx.game.cmd_dmg[pos].is_partner = !ctx.game.cmd_dmg[pos].is_partner;
|
||||
} else {
|
||||
cmd_dmg_calc(ctx, x, y, gesture, pos);
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_tax_w_swap(ctx: &mut SystemState, x: f32, y: f32, gesture: u8) {
|
||||
if (x>-20.) & (x<20.) & (y< -30.)&(y>-50.) {
|
||||
ctx.game.cmd_tax.is_partner = !ctx.game.cmd_tax.is_partner;
|
||||
} else {
|
||||
cmd_tax_calc(ctx, x, y, gesture);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user