4 Commits

10 changed files with 71 additions and 27 deletions

Binary file not shown.

View File

@@ -62,7 +62,6 @@ export fn sndGes(t: i32) -> f32 {
let phase = channelState!GesChannelState.Phase;
let inline pulseWidth = channelReg?1;
let phaseShift = (pulseWidth - 128) * 255;
let invPhaseInc = 1 as f32 / phaseInc as f32;
i = 0;
@@ -131,7 +130,7 @@ export fn sndGes(t: i32) -> f32 {
let phaseInc = (freq * (65536.0 / 44100.0)) as i32;
let phase = channelState!GesChannelState.Phase;
if modSrc > ch {
if modSrc < ch {
phase = phase - (phaseInc << 6);
}

View File

@@ -372,16 +372,7 @@ export fn printChar(char: i32) {
global mut controlCodeLength = 0;
fn printSingleChar(char: i32) {
if char >= 4 & char <= 6 {
outputChannel = char - 4;
if !outputChannel {
textCursorX = 0;
textCursorY = 0;
}
return;
}
if outputChannel >= 2 {
if outputChannel >= 2 & (char < 4 | char > 6) {
logChar(char);
return;
}
@@ -399,6 +390,15 @@ fn printSingleChar(char: i32) {
return;
}
if char >= 4 & char <= 6 {
outputChannel = char - 4;
if !outputChannel {
textCursorX = 0;
textCursorY = 0;
}
return;
}
if char == 7 {
80?0 = 80?0 ^ 2;
return;

File diff suppressed because one or more lines are too long

View File

@@ -134,6 +134,10 @@ impl super::Runtime for MicroW8 {
let end_frame = platform_instance.get_typed_func::<(), (), _>(&mut store, "endFrame")?;
let update = instance.get_typed_func::<(), (), _>(&mut store, "upd").ok();
if let Some(start) = instance.get_typed_func::<(), (), _>(&mut store, "start").ok() {
start.call(&mut store, ())?;
}
let (sound_tx, stream) = if self.disable_audio {
(None, None)
} else {
@@ -419,6 +423,14 @@ fn init_sound(
mem[64..68].copy_from_slice(&current_time.to_le_bytes());
}
fn clamp_sample(s: f32) -> f32 {
if s.is_nan() {
0.0
} else {
s.max(-1.0).min(1.0)
}
}
if let Some(ref mut resampler) = resampler {
while !buffer.is_empty() {
let copy_size = resampler.output_buffers[0]
@@ -429,10 +441,12 @@ fn init_sound(
resampler.input_buffers[0].clear();
resampler.input_buffers[1].clear();
for _ in 0..resampler.resampler.input_frames_next() {
resampler.input_buffers[0]
.push(snd.call(&mut store, (sample_index,)).unwrap_or(0.0));
resampler.input_buffers[1]
.push(snd.call(&mut store, (sample_index + 1,)).unwrap_or(0.0));
resampler.input_buffers[0].push(clamp_sample(
snd.call(&mut store, (sample_index,)).unwrap_or(0.0),
));
resampler.input_buffers[1].push(clamp_sample(
snd.call(&mut store, (sample_index + 1,)).unwrap_or(0.0),
));
sample_index = sample_index.wrapping_add(2);
}
@@ -458,7 +472,7 @@ fn init_sound(
}
} else {
for v in buffer {
*v = snd.call(&mut store, (sample_index,)).unwrap_or(0.0);
*v = clamp_sample(snd.call(&mut store, (sample_index,)).unwrap_or(0.0));
sample_index = sample_index.wrapping_add(1);
}
}

View File

@@ -11,6 +11,7 @@ use warp::{http::Response, Filter};
pub struct RunWebServer {
cart: Arc<Mutex<Vec<u8>>>,
tx: broadcast::Sender<()>,
socket_addr: SocketAddr,
}
impl RunWebServer {
@@ -18,8 +19,13 @@ impl RunWebServer {
let cart = Arc::new(Mutex::new(Vec::new()));
let (tx, _) = broadcast::channel(1);
let socket_addr = "127.0.0.1:3030"
.parse::<SocketAddr>()
.expect("Failed to parse socket address");
let server_cart = cart.clone();
let server_tx = tx.clone();
let server_addr = socket_addr.clone();
thread::spawn(move || {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io()
@@ -47,24 +53,26 @@ impl RunWebServer {
warp::sse::reply(warp::sse::keep_alive().stream(event_stream(&server_tx)))
});
let socket_addr = "127.0.0.1:3030"
.parse::<SocketAddr>()
.expect("Failed to parse socket address");
let server_future = warp::serve(html.or(cart).or(events)).bind(socket_addr);
println!("Point browser at http://{}", socket_addr);
let _ignore_result = webbrowser::open(&format!("http://{}", socket_addr));
let server_future = warp::serve(html.or(cart).or(events)).bind(server_addr);
server_future.await
});
});
RunWebServer { cart, tx }
RunWebServer {
cart,
tx,
socket_addr,
}
}
}
impl super::Runtime for RunWebServer {
fn load(&mut self, module_data: &[u8]) -> Result<()> {
if let Ok(mut lock) = self.cart.lock() {
if lock.is_empty() && !module_data.is_empty() {
println!("Point browser at http://{}", self.socket_addr);
let _ignore_result = webbrowser::open(&format!("http://{}", self.socket_addr));
}
lock.clear();
lock.extend_from_slice(module_data);
}
@@ -86,4 +94,4 @@ impl Default for RunWebServer {
fn default() -> RunWebServer {
RunWebServer::new()
}
}
}

5
test/start_fn.cwa Normal file
View File

@@ -0,0 +1,5 @@
include "../examples/include/microw8-api.cwa"
export fn start() {
printChar('Test');
}

13
test/text_modes.cwa Normal file
View File

@@ -0,0 +1,13 @@
include "../examples/include/microw8-api.cwa"
export fn upd() {
printString(USER_MEM);
}
data USER_MEM {
i8(12, 31, 5, 6) "Text mode"
i8(5, 31, 4, 5) "Graphics mode"
i8(6) "Console output\nSecond line\n"
i8(4, 31, 4, 12) "Back to text mode"
i8(0)
}

1
todo.txt Normal file
View File

@@ -0,0 +1 @@
* add support for 16bit sound (not just float)

View File

@@ -263,6 +263,10 @@ export default function MicroW8(screen, config = {}) {
window.addEventListener('blur', () => updateVisibility(false), { signal: abortController.signal });
updateVisibility(document.hasFocus());
if (instance.exports.start) {
instance.exports.start();
}
function mainloop() {
if (!keepRunning) {
return;