|
|
|
@ -1,13 +1,13 @@
|
|
|
|
// TODO:
|
|
|
|
// TODO:
|
|
|
|
|
|
|
|
// * Fix randomly audio not working
|
|
|
|
|
|
|
|
// * Lock down system scheduling/run_if conditions
|
|
|
|
// * Fix tiling repeating
|
|
|
|
// * Fix tiling repeating
|
|
|
|
// * Negative coordinates should not mirror
|
|
|
|
// * Negative coordinates should not mirror
|
|
|
|
// * Fix randomly audio not working
|
|
|
|
|
|
|
|
// * Make click and drag feel better
|
|
|
|
|
|
|
|
// * Show shadow of piece (same tile, just with alpha transparency)
|
|
|
|
|
|
|
|
// * UI widget explaining rules/hotkeys
|
|
|
|
// * UI widget explaining rules/hotkeys
|
|
|
|
// * UI minimize widgets
|
|
|
|
// * Show shadow of piece (same tile, just with alpha transparency)
|
|
|
|
// * Start with an interesting pattern
|
|
|
|
// * Start with an interesting pattern
|
|
|
|
// * Lock down system scheduling/run_if conditions
|
|
|
|
// * UI minimize widgets
|
|
|
|
|
|
|
|
// * Make click and drag feel better
|
|
|
|
#![allow(clippy::complexity)]
|
|
|
|
#![allow(clippy::complexity)]
|
|
|
|
// Only because of FromTemplat macros unfortunately...
|
|
|
|
// Only because of FromTemplat macros unfortunately...
|
|
|
|
#![allow(dead_code)]
|
|
|
|
#![allow(dead_code)]
|
|
|
|
@ -588,24 +588,39 @@ impl Coordinates {
|
|
|
|
|
|
|
|
|
|
|
|
/// For the purposes of creating assests, what does the given coordinate translate to CellPitch wise
|
|
|
|
/// For the purposes of creating assests, what does the given coordinate translate to CellPitch wise
|
|
|
|
fn to_cell_pitch(&self) -> CellPitch {
|
|
|
|
fn to_cell_pitch(&self) -> CellPitch {
|
|
|
|
let note = match self.x {
|
|
|
|
let Coordinates { x, y } = self.normalized();
|
|
|
|
-6 => Note::A,
|
|
|
|
let note = match x {
|
|
|
|
-5 => Note::ASharp,
|
|
|
|
0 => Note::A,
|
|
|
|
-4 => Note::B,
|
|
|
|
1 => Note::ASharp,
|
|
|
|
-3 => Note::C,
|
|
|
|
2 => Note::B,
|
|
|
|
-2 => Note::CSharp,
|
|
|
|
3 => Note::C,
|
|
|
|
-1 => Note::D,
|
|
|
|
4 => Note::CSharp,
|
|
|
|
0 => Note::DSharp,
|
|
|
|
5 => Note::D,
|
|
|
|
1 => Note::E,
|
|
|
|
6 => Note::DSharp,
|
|
|
|
2 => Note::F,
|
|
|
|
7 => Note::E,
|
|
|
|
3 => Note::FSharp,
|
|
|
|
8 => Note::F,
|
|
|
|
4 => Note::G,
|
|
|
|
9 => Note::FSharp,
|
|
|
|
5 => Note::GSharp,
|
|
|
|
10 => Note::G,
|
|
|
|
|
|
|
|
11 => Note::GSharp,
|
|
|
|
_ => panic!("This shouldn't happen!"),
|
|
|
|
_ => panic!("This shouldn't happen!"),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let octave = self.y;
|
|
|
|
let octave = y;
|
|
|
|
CellPitch { note, octave }
|
|
|
|
CellPitch { note, octave }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Turn an arbitrary coordinate to a "normalized" coordinate centered on 0,0
|
|
|
|
|
|
|
|
fn normalized(&self) -> Self {
|
|
|
|
|
|
|
|
println!("normalizing {:?}", (self.x, self.y));
|
|
|
|
|
|
|
|
let x = self.x.rem_euclid(12);
|
|
|
|
|
|
|
|
let y = self.y.rem_euclid(11);
|
|
|
|
|
|
|
|
println!("normalized {:?}", (x,y));
|
|
|
|
|
|
|
|
debug_assert!(x >= 0);
|
|
|
|
|
|
|
|
debug_assert!(x <= 12);
|
|
|
|
|
|
|
|
debug_assert!(y >= 0);
|
|
|
|
|
|
|
|
debug_assert!(y <= 11);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Coordinates { x, y }
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// When the cursor moves, update the Coordinates
|
|
|
|
/// When the cursor moves, update the Coordinates
|
|
|
|
@ -966,7 +981,7 @@ impl CellPitch {
|
|
|
|
]
|
|
|
|
]
|
|
|
|
.into_iter()
|
|
|
|
.into_iter()
|
|
|
|
.flat_map(|note| {
|
|
|
|
.flat_map(|note| {
|
|
|
|
(-5..6).map(move |octave| CellPitch {
|
|
|
|
(0..11).map(move |octave| CellPitch {
|
|
|
|
note: note.clone(),
|
|
|
|
note: note.clone(),
|
|
|
|
octave,
|
|
|
|
octave,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
@ -1037,6 +1052,7 @@ fn load_materials(
|
|
|
|
};
|
|
|
|
};
|
|
|
|
cell_assets.materials.insert(cell_pitch, handle);
|
|
|
|
cell_assets.materials.insert(cell_pitch, handle);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// 12 notes * 11 octaves = 132 materials
|
|
|
|
debug_assert_eq!(cell_assets.materials.iter().len(), 132);
|
|
|
|
debug_assert_eq!(cell_assets.materials.iter().len(), 132);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -1154,24 +1170,64 @@ impl PitchMap {
|
|
|
|
|
|
|
|
|
|
|
|
/// Given the currently selected notes and octave range selected in the PitchMap convert the given coordinates to a CellPitch
|
|
|
|
/// Given the currently selected notes and octave range selected in the PitchMap convert the given coordinates to a CellPitch
|
|
|
|
fn coordinates_cell_pitch(&self, c: &Coordinates) -> CellPitch {
|
|
|
|
fn coordinates_cell_pitch(&self, c: &Coordinates) -> CellPitch {
|
|
|
|
|
|
|
|
let Coordinates { x, y } = c.normalized();
|
|
|
|
let note: Note = {
|
|
|
|
let note: Note = {
|
|
|
|
let num_notes: usize = self.notes.len();
|
|
|
|
let num_notes = self.notes.len();
|
|
|
|
let x_coord: usize = c.x.strict_abs() as usize; // TODO: shift first or something
|
|
|
|
self.notes.get((x % num_notes as isize) as usize).unwrap().clone()
|
|
|
|
self.notes.get(x_coord % num_notes).unwrap().clone()
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let octave: isize = {
|
|
|
|
let octave: isize = {
|
|
|
|
let num_octaves: usize = self.octaves_up + self.octaves_down + 1;
|
|
|
|
let num_octaves = self.octaves_up + self.octaves_down + 1;
|
|
|
|
let y_coord: usize = c.y.strict_abs() as usize; // TODO: shift first or something
|
|
|
|
println!("num_octaves: {:?}", num_octaves);
|
|
|
|
debug!("num_octaves: {:?}", num_octaves);
|
|
|
|
(y % num_octaves as isize) as isize
|
|
|
|
debug!("y_coord: {:?}", y_coord);
|
|
|
|
|
|
|
|
(y_coord % num_octaves) as isize - 5
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let cp = CellPitch { note, octave };
|
|
|
|
let cp = CellPitch { note, octave };
|
|
|
|
debug!("Cell Pitch: {:?}", cp);
|
|
|
|
println!("Cell Pitch: {:?}", cp);
|
|
|
|
cp
|
|
|
|
cp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
|
|
fn test_cell_pitch() {
|
|
|
|
|
|
|
|
let pm = PitchMap {
|
|
|
|
|
|
|
|
notes: vec![Note::A, Note::B, Note::C],
|
|
|
|
|
|
|
|
octaves_up: 1,
|
|
|
|
|
|
|
|
octaves_down: 1,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let xs = [-6, -3, 0, 3, 6];
|
|
|
|
|
|
|
|
let ys = [-5, -2, 0, 3, 6];
|
|
|
|
|
|
|
|
xs.iter().for_each(|x| {
|
|
|
|
|
|
|
|
ys.iter().for_each(|y| {
|
|
|
|
|
|
|
|
let CellPitch { note, octave } = pm.coordinates_cell_pitch(&Coordinates { x: *x, y: *y });
|
|
|
|
|
|
|
|
debug_assert_eq!(note, Note::A);
|
|
|
|
|
|
|
|
debug_assert_eq!(octave, 0);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let xs = [-5, -2, 1, 4, 7];
|
|
|
|
|
|
|
|
let ys = [-4, -1, 1, 4, 7];
|
|
|
|
|
|
|
|
xs.iter().for_each(|x| {
|
|
|
|
|
|
|
|
ys.iter().for_each(|y| {
|
|
|
|
|
|
|
|
let CellPitch { note, octave } = pm.coordinates_cell_pitch(&Coordinates { x: *x, y: *y });
|
|
|
|
|
|
|
|
debug_assert_eq!(note, Note::B);
|
|
|
|
|
|
|
|
debug_assert_eq!(octave, 1);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let xs = [-4, -1, 2, 5, 8];
|
|
|
|
|
|
|
|
let ys = [-3, 0, 2, 5, 8];
|
|
|
|
|
|
|
|
xs.iter().for_each(|x| {
|
|
|
|
|
|
|
|
ys.iter().for_each(|y| {
|
|
|
|
|
|
|
|
let CellPitch { note, octave } = pm.coordinates_cell_pitch(&Coordinates { x: *x, y: *y });
|
|
|
|
|
|
|
|
debug_assert_eq!(note, Note::C);
|
|
|
|
|
|
|
|
debug_assert_eq!(octave, 2);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// When the pitch map changes, update all cells to use the correct pitch (note + octave)
|
|
|
|
/// When the pitch map changes, update all cells to use the correct pitch (note + octave)
|
|
|
|
fn reassign_cell_pitch(mut query: Query<(&mut CellPitch, &Coordinates)>, pitch_map: Res<PitchMap>) {
|
|
|
|
fn reassign_cell_pitch(mut query: Query<(&mut CellPitch, &Coordinates)>, pitch_map: Res<PitchMap>) {
|
|
|
|
debug!("query size: {:?}", query.iter().len());
|
|
|
|
debug!("query size: {:?}", query.iter().len());
|
|
|
|
|