mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 11:16:42 +01:00
add simple rust "script" to build platform binaries
This commit is contained in:
190
platform/src/loader.cwa
Normal file
190
platform/src/loader.cwa
Normal file
@@ -0,0 +1,190 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
global mut base_end: i32 = 0;
|
||||
|
||||
export fn load_uw8(module_size: i32) -> i32 {
|
||||
let lazy version = ?0 - 1;
|
||||
if version < 0 {
|
||||
return module_size;
|
||||
}
|
||||
|
||||
let module_end = 0x1e000 + module_size;
|
||||
if version & 1 {
|
||||
module_end = uncompress(1, 0x1e001);
|
||||
} else {
|
||||
copy(0x1e000, 0, module_size);
|
||||
}
|
||||
copy(0, 0x3c800, 8);
|
||||
|
||||
let base_start = 0x3c808;
|
||||
let dest = 8;
|
||||
let src = 0x1e001;
|
||||
|
||||
loop sections {
|
||||
if src < module_end & (base_start >= base_end | ?src <= ?base_start) {
|
||||
let lazy length2 = copy_section(dest, src);
|
||||
dest = dest + length2;
|
||||
if base_start < base_end & ?src == ?base_start {
|
||||
base_start = base_start + section_size(base_start);
|
||||
}
|
||||
src = src + length2;
|
||||
branch sections;
|
||||
}
|
||||
|
||||
if base_start < base_end {
|
||||
let lazy length3 = copy_section(dest, base_start);
|
||||
dest = dest + length3;
|
||||
base_start = base_start + length3;
|
||||
branch sections;
|
||||
}
|
||||
}
|
||||
|
||||
dest
|
||||
}
|
||||
|
||||
fn section_size(ptr: i32) -> i32 {
|
||||
let p = ptr + 1;
|
||||
let l = 0;
|
||||
let shift = 0;
|
||||
loop size {
|
||||
let lazy b = ?p;
|
||||
l = l | ((b & 127) << shift);
|
||||
shift = shift + 7;
|
||||
p = p + 1;
|
||||
branch_if b & 128: size;
|
||||
}
|
||||
p - ptr + l
|
||||
}
|
||||
|
||||
fn copy_section(dest: i32, src: i32) -> i32 {
|
||||
let lazy length = section_size(src);
|
||||
copy(dest, src, length);
|
||||
length
|
||||
}
|
||||
|
||||
fn copy(dest: i32, src: i32, len: i32) {
|
||||
if len > 0 {
|
||||
loop bytes {
|
||||
?(dest + (len := len - 1)) = ?(src + len);
|
||||
branch_if len: bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// upkr unpacker
|
||||
|
||||
global mut upkr_src_ptr: i32 = 0;
|
||||
global mut upkr_code: i64 = 0i64;
|
||||
global mut upkr_low: i64 = 0i64;
|
||||
global mut upkr_range: i64 = 0i64;
|
||||
|
||||
// uncompress upkr compressed data at `src` into the buffer at `dest`
|
||||
// returns the end of the uncompressed data
|
||||
export fn uncompress(src_ptr: i32, dest_ptr: i32) -> i32 {
|
||||
upkr_src_ptr = src_ptr;
|
||||
upkr_code = 0i64;
|
||||
upkr_low = 0i64;
|
||||
upkr_range = 1i64;
|
||||
|
||||
let offset: i32;
|
||||
|
||||
let byte: i32;
|
||||
|
||||
let i: i32;
|
||||
loop init_contexts {
|
||||
i!0x3c000 = 0x8000;
|
||||
branch_if (i := i + 4) < (256 + 1 + 128) * 4: init_contexts
|
||||
}
|
||||
|
||||
block finished {
|
||||
loop unpack_loop {
|
||||
if upkr_bit(0) {
|
||||
if upkr_bit(256) {
|
||||
offset = upkr_length(257) - 1;
|
||||
branch_if !offset: finished
|
||||
}
|
||||
let length = upkr_length(257 + 64);
|
||||
loop copy {
|
||||
dest_ptr?0 = (dest_ptr - offset)?0;
|
||||
dest_ptr = dest_ptr + 1;
|
||||
branch_if (length := length - 1): copy;
|
||||
}
|
||||
} else {
|
||||
// literal
|
||||
i = 0;
|
||||
byte = 1;
|
||||
loop literal {
|
||||
byte = (byte << 1) | upkr_bit(byte);
|
||||
branch_if (i := i + 1) < 8: literal;
|
||||
}
|
||||
dest_ptr?0 = byte;
|
||||
dest_ptr = dest_ptr + 1;
|
||||
}
|
||||
branch unpack_loop;
|
||||
}
|
||||
}
|
||||
|
||||
dest_ptr
|
||||
}
|
||||
|
||||
fn upkr_length(context_index: i32) -> i32 {
|
||||
let length: i32;
|
||||
let bit_pos: i32;
|
||||
loop bits {
|
||||
if upkr_bit(context_index) {
|
||||
length = length | (upkr_bit(context_index + 1) << bit_pos);
|
||||
context_index = context_index + 2;
|
||||
bit_pos = bit_pos + 1;
|
||||
branch bits;
|
||||
}
|
||||
}
|
||||
length | (1 << bit_pos)
|
||||
}
|
||||
|
||||
fn upkr_bit(context_index: i32) -> i32 {
|
||||
let prob = ((context_index * 4)!0x3c000) as i64;
|
||||
|
||||
loop refill {
|
||||
if upkr_low >> 32i64 == (upkr_low + upkr_range - 1i64) >> 32i64 {
|
||||
upkr_append_byte();
|
||||
branch refill;
|
||||
}
|
||||
}
|
||||
|
||||
if upkr_range < (1i64 << 24i64) {
|
||||
upkr_append_byte();
|
||||
upkr_append_byte();
|
||||
upkr_range = (1i64 << 40i64) - upkr_low;
|
||||
}
|
||||
|
||||
let range = upkr_range / 65536i64;
|
||||
let bit = (upkr_code - upkr_low) / range < prob;
|
||||
|
||||
if bit {
|
||||
upkr_range = range * prob;
|
||||
prob = prob + (((1i64 << 16i64) - prob) >> 4i64);
|
||||
} else {
|
||||
upkr_low = upkr_low + range * prob;
|
||||
upkr_range = range * (65536i64 - prob);
|
||||
prob = prob - (prob >> 4i64);
|
||||
}
|
||||
|
||||
(context_index * 4)!0x3c000 = prob as i32;
|
||||
|
||||
bit
|
||||
}
|
||||
|
||||
fn upkr_append_byte() {
|
||||
upkr_code = ((upkr_code & i64.extend_i32_u(-1)) << 8i64) | (?upkr_src_ptr) as i64;
|
||||
upkr_src_ptr = upkr_src_ptr + 1;
|
||||
upkr_low = (upkr_low & i64.extend_i32_u(-1)) << 8i64;
|
||||
upkr_range = upkr_range << 8i64;
|
||||
}
|
||||
|
||||
start fn unpack_base() {
|
||||
base_end = uncompress(0, 0x3c800);
|
||||
}
|
||||
|
||||
data 0 {
|
||||
file("../target/base.upk")
|
||||
}
|
||||
16
platform/src/main.rs
Normal file
16
platform/src/main.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use std::{fs::File, path::Path};
|
||||
use std::io::prelude::*;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
uw8_tool::BaseModule::create_binary(&Path::new("target/base.upk"))?;
|
||||
|
||||
let loader = curlywas::compile_file("src/loader.cwa")?;
|
||||
File::create("bin/loader.wasm")?.write_all(&loader)?;
|
||||
|
||||
let platform = curlywas::compile_file("src/platform.cwa")?;
|
||||
File::create("bin/platform.uw8")?.write_all(&platform)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
118
platform/src/platform.cwa
Normal file
118
platform/src/platform.cwa
Normal file
@@ -0,0 +1,118 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
global mut randomState: i64 = 37i64;
|
||||
|
||||
export fn random() -> i32 {
|
||||
(random64() >> 32i64) as i32
|
||||
}
|
||||
|
||||
export fn random64() -> i64 {
|
||||
let state: i64;
|
||||
randomState = (state := (
|
||||
state := randomState ^ (randomState #>> 12i64)
|
||||
) ^ (state << 25i64)
|
||||
) ^ (state #>> 27i64);
|
||||
randomState * 0x2545f4914f6cdd1di64
|
||||
}
|
||||
|
||||
export fn randomf() -> f32 {
|
||||
f32.reinterpret_i32(0x3f800000 | (random() #>> 9)) - 1 as f32
|
||||
}
|
||||
|
||||
export fn randomSeed(s: i32) {
|
||||
randomState = (s as i64 << 32i64) ^ ((63 - s) as i64);
|
||||
randomState = random64();
|
||||
randomState = random64();
|
||||
}
|
||||
|
||||
export fn fmod(a: f32, b: f32) -> f32 {
|
||||
a - floor(a / b) * b
|
||||
}
|
||||
|
||||
export fn cls(col: i32) {
|
||||
let i: i32;
|
||||
col = (col & 255) * 0x1010101;
|
||||
loop pixels {
|
||||
i!120 = col;
|
||||
branch_if (i := i + 4) < 320*240: pixels;
|
||||
}
|
||||
}
|
||||
|
||||
export fn setPixel(x: i32, y: i32, col: i32) {
|
||||
if x #< 320 & y #< 240 {
|
||||
(x + y * 320)?120 = col
|
||||
}
|
||||
}
|
||||
|
||||
export fn getPixel(x: i32, y: i32) -> i32 {
|
||||
if x #< 320 & y #< 240 {
|
||||
(x + y * 320)?120
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn clamp(v: i32, min: i32, max: i32) -> i32 {
|
||||
select(v < min, min, select(v > max, max, v))
|
||||
}
|
||||
|
||||
export fn hline(x1: i32, x2: i32, y: i32, col: i32) {
|
||||
x1 = clamp(x1, 0, 320);
|
||||
x2 = clamp(x2, 0, 320);
|
||||
if x1 < x2 & y #< 240 {
|
||||
let ptr = y * 320 + x1;
|
||||
let end = ptr + x2 - x1;
|
||||
loop pixels {
|
||||
ptr?120 = col;
|
||||
branch_if (ptr := ptr + 1) < end: pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export fn rectangle(x: f32, y: f32, w: f32, h: f32, col: i32) {
|
||||
if abs(w) == w & abs(h) == h {
|
||||
let x1 = nearest(x) as i32;
|
||||
let y1 = clamp(nearest(y) as i32, 0, 240);
|
||||
let x2 = nearest(x + w) as i32;
|
||||
let y2 = clamp(nearest(y + h) as i32, 0, 240);
|
||||
block done {
|
||||
loop lines {
|
||||
branch_if y1 >= y2: done;
|
||||
hline(x1, x2, y1, col);
|
||||
y1 = y1 + 1;
|
||||
branch lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export fn circle(cx: f32, cy: f32, radius: f32, col: i32) {
|
||||
let y = clamp(nearest(cy - radius) as i32, 0, 240);
|
||||
let maxY = clamp(nearest(cy + radius) as i32, 0, 240);
|
||||
|
||||
block done {
|
||||
loop lines {
|
||||
branch_if y >= maxY: done;
|
||||
|
||||
let lazy dy = y as f32 - cy + 0.5;
|
||||
let lazy q = radius * radius - dy * dy;
|
||||
if abs(q) == q {
|
||||
let lazy w = sqrt(q);
|
||||
hline(nearest(cx - w) as i32, nearest(cx + w) as i32, y, col);
|
||||
}
|
||||
|
||||
y = y + 1;
|
||||
branch lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start fn setup() {
|
||||
let i: i32;
|
||||
loop colors {
|
||||
(i*4)!(120+320*240) = i * 0x10101;
|
||||
branch_if (i := i + 1) < 256: colors
|
||||
}
|
||||
cls(0);
|
||||
randomSeed(random());
|
||||
}
|
||||
Reference in New Issue
Block a user