Struct spectrusty_formats::ay::AyString
source · pub struct AyString(_);
Expand description
The type of a parsed AY file’s strings.
Implementations§
source§impl AyString
impl AyString
sourcepub fn as_slice(&self) -> &[u8] ⓘ
pub fn as_slice(&self) -> &[u8] ⓘ
Returns a reference to the string as an array of bytes.
Examples found in repository?
src/ay.rs (line 149)
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl Deref for AyBlob {
type Target = [u8];
fn deref(&self) -> &[u8] {
self.as_slice()
}
}
impl AyBlob {
fn new(slice: &[u8]) -> Self {
AyBlob(NonNull::from(slice))
}
/// Returns a reference to data.
pub fn as_slice(&self) -> &[u8] {
unsafe { self.0.as_ref() } // creating of this type is private so it will be only made pinned
}
}
impl AyString {
fn new(slice: &[u8]) -> Self {
AyString(NonNull::from(slice))
}
/// Returns a reference to the string as an array of bytes.
pub fn as_slice(&self) -> &[u8] {
unsafe { self.0.as_ref() } // creating of this type is private so it will be only made pinned
}
/// Returns a string reference if the underlying bytes can form a proper UTF-8 string.
pub fn to_str(&self) -> Result<&str, core::str::Utf8Error> {
core::str::from_utf8(self.as_slice())
}
/// Returns a reference to a `str` if the underlying bytes can form a proper UTF-8 string.
/// Otherwise, returns a [String], including invalid characters.
pub fn to_str_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.as_slice())
}
sourcepub fn to_str(&self) -> Result<&str, Utf8Error>
pub fn to_str(&self) -> Result<&str, Utf8Error>
Returns a string reference if the underlying bytes can form a proper UTF-8 string.
sourcepub fn to_str_lossy(&self) -> Cow<'_, str>
pub fn to_str_lossy(&self) -> Cow<'_, str>
Returns a reference to a str
if the underlying bytes can form a proper UTF-8 string.
Otherwise, returns a String, including invalid characters.
Examples found in repository?
src/ay.rs (line 125)
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "AyString: {:?}", self.to_str_lossy())
}
}
impl fmt::Display for AyString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_str_lossy())
}
}
impl fmt::Debug for AyFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "AyFile {{ raw: ({:?}), meta: {:?}, songs: {:?} }}", self.raw.len(), self.meta, self.songs)
}
}
impl AsRef<[u8]> for AyBlob {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl AsRef<[u8]> for AyString {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl Deref for AyBlob {
type Target = [u8];
fn deref(&self) -> &[u8] {
self.as_slice()
}
}
impl AyBlob {
fn new(slice: &[u8]) -> Self {
AyBlob(NonNull::from(slice))
}
/// Returns a reference to data.
pub fn as_slice(&self) -> &[u8] {
unsafe { self.0.as_ref() } // creating of this type is private so it will be only made pinned
}
}
impl AyString {
fn new(slice: &[u8]) -> Self {
AyString(NonNull::from(slice))
}
/// Returns a reference to the string as an array of bytes.
pub fn as_slice(&self) -> &[u8] {
unsafe { self.0.as_ref() } // creating of this type is private so it will be only made pinned
}
/// Returns a string reference if the underlying bytes can form a proper UTF-8 string.
pub fn to_str(&self) -> Result<&str, core::str::Utf8Error> {
core::str::from_utf8(self.as_slice())
}
/// Returns a reference to a `str` if the underlying bytes can form a proper UTF-8 string.
/// Otherwise, returns a [String], including invalid characters.
pub fn to_str_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.as_slice())
}
}
static PLAYER_ONE: &[u8] = &[
/* 0000:*/ 0xF3, /* di */
/* 0001:*/ 0xCD,0x00,0x00, /* call 0000H -> init */
/* 0004:*/ 0xED,0x5E, /* im 2 :loop1 */
/* 0006:*/ 0xFB, /* ei */
/* 0007:*/ 0x76, /* halt */
/* 0008:*/ 0x18,0xFA, /* jr 0004H -> loop1 */
];
static PLAYER_TWO: &[u8] = &[
/* 0000:*/ 0xF3, /* di */
/* 0001:*/ 0xCD,0x00,0x00, /* call 0000H -> init */
/* 0004:*/ 0xED,0x56, /* im 1 :loop1 */
/* 0006:*/ 0xFB, /* ei */
/* 0007:*/ 0x76, /* halt */
/* 0008:*/ 0xCD,0x00,0x00, /* call 0000H -> interrupt */
/* 000B:*/ 0x18,0xF7, /* jr 0004H -> loop1 */
];
const PLAYER_INIT_OFFSET: usize = 2;
const PLAYER_TWO_INTERRUPT_OFFSET: usize = 9;
impl AyFile {
/// Initializes `memory` and the `cpu` registers, creates a player routine, and loads song data into `memory`.
/// Provide `song_index` of the desired song from this file to be played.
///
/// # Panics
/// * If `song_index` is larger or equal to the number of contained songs.
/// You may get the number of songs by invoking `.songs.len()` method.
/// * If a special player is required. See [AyMeta].
/// * If the capacity of provided memory is less than 64kb.
pub fn initialize_player<C, M>(&self, cpu: &mut C, memory: &mut M, song_index: usize)
where C: Cpu, M: ZxMemory
{
if self.meta.special_player {
panic!("can't initialize file with a special player");
}
let song = &self.songs[song_index];
debug!("loading song: ({}) {}", song_index, song.name.to_str_lossy());
let rawmem = memory.mem_mut();
for p in rawmem[0x0000..0x0100].iter_mut() { *p = 0xC9 };
for p in rawmem[0x0100..0x4000].iter_mut() { *p = 0xFF };
for p in rawmem[0x4000..].iter_mut() { *p = 0x00 };
rawmem[0x0038] = 0xFB;
debug!("INIT: ${:x}", song.init);
let init = if song.init == 0 {
debug!("INIT using: ${:x}", song.blocks[0].address);
song.blocks[0].address
}
else {
song.init
}.to_le_bytes();
debug!("INTERRUPT: ${:x}", song.interrupt);
let player = if song.interrupt == 0 {
debug!("PLAYER ONE");
PLAYER_ONE
}
else {
debug!("PLAYER TWO");
PLAYER_TWO
};
rawmem[0x0000..player.len()].copy_from_slice(player);
if song.interrupt != 0 {
let intr = song.interrupt.to_le_bytes();
rawmem[PLAYER_TWO_INTERRUPT_OFFSET..PLAYER_TWO_INTERRUPT_OFFSET+intr.len()].copy_from_slice(&intr);
}
rawmem[PLAYER_INIT_OFFSET..PLAYER_INIT_OFFSET+init.len()].copy_from_slice(&init);
for block in song.blocks.iter() {
debug!("Block: ${:x} <- {:?}", block.address, block.data);
let address = block.address as usize;
let mut data = block.data.as_slice();
if address + data.len() > (u16::max_value() as usize) + 1 {
debug!("Block too large: ${:x}", address + data.len());
data = &data[..u16::max_value() as usize - address];
}
rawmem[address..address+data.len()].copy_from_slice(data);
}
debug!("STACK: ${:x}", song.stack);
// debug_memory(0x0000, &rawmem[0x0000..player.len()]);
cpu.reset();
cpu.set_i(self.meta.player_version);
cpu.set_reg(Reg8::H, None, song.hi_reg);
cpu.set_reg(Reg8::L, None, song.lo_reg);
cpu.set_reg(Reg8::D, None, song.hi_reg);
cpu.set_reg(Reg8::E, None, song.lo_reg);
cpu.set_reg(Reg8::B, None, song.hi_reg);
cpu.set_reg(Reg8::C, None, song.lo_reg);
cpu.exx();
cpu.set_acc(song.hi_reg);
cpu.set_flags(CpuFlags::from_bits_truncate(song.lo_reg));
cpu.ex_af_af();
cpu.set_reg(Reg8::H, None, song.hi_reg);
cpu.set_reg(Reg8::L, None, song.lo_reg);
cpu.set_reg(Reg8::D, None, song.hi_reg);
cpu.set_reg(Reg8::E, None, song.lo_reg);
cpu.set_reg(Reg8::B, None, song.hi_reg);
cpu.set_reg(Reg8::C, None, song.lo_reg);
cpu.set_reg(Reg8::H, Some(Prefix::Yfd), song.hi_reg);
cpu.set_reg(Reg8::L, Some(Prefix::Yfd), song.lo_reg);
cpu.set_reg(Reg8::H, Some(Prefix::Xdd), song.hi_reg);
cpu.set_reg(Reg8::L, Some(Prefix::Xdd), song.lo_reg);
cpu.set_acc(song.hi_reg);
cpu.set_flags(CpuFlags::from_bits_truncate(song.lo_reg));
cpu.disable_interrupts();
cpu.set_sp(song.stack);
cpu.set_im(InterruptMode::Mode0);
cpu.set_pc(0x0000);
}
Trait Implementations§
Auto Trait Implementations§
impl RefUnwindSafe for AyString
impl !Send for AyString
impl !Sync for AyString
impl Unpin for AyString
impl UnwindSafe for AyString
Blanket Implementations§
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
Causes
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
Causes
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
Formats each item in a sequence. Read more
source§impl<S, T> IntoSample<S> for Twhere
S: FromSample<T>,
impl<S, T> IntoSample<S> for Twhere
S: FromSample<T>,
source§fn into_sample(self) -> S
fn into_sample(self) -> S
Convert to
S
a sample type from self
.§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Pipes by value. This is generally the method you want to use. Read more
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
Borrows
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
Mutably borrows
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
Borrows
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Immutable access to the
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
Mutable access to the
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
Immutable access to the
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
Mutable access to the
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
Immutable access to the
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Mutable access to the
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
Calls
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
Calls
.tap_mut()
only in debug builds, and is erased in release
builds. Read more§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Calls
.tap_borrow()
only in debug builds, and is erased in release
builds. Read more§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
Calls
.tap_borrow_mut()
only in debug builds, and is erased in release
builds. Read more§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
Calls
.tap_ref()
only in debug builds, and is erased in release
builds. Read more§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
Calls
.tap_ref_mut()
only in debug builds, and is erased in release
builds. Read more