add palette support (default is still greyscale for now)

This commit is contained in:
2021-11-13 22:29:20 +01:00
parent 944856b267
commit 294b9f5634
6 changed files with 49 additions and 17 deletions

View File

@@ -26,15 +26,15 @@ export fn randomSeed(s: i32) {
}
export fn fmod(a: f32, b: f32) -> f32 {
let lazy t = a / b;
(t - floor(t)) * b
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 + 1) < 320*256: pixels;
i!120 = col;
branch_if (i := i + 4) < 320*256: pixels;
}
}
@@ -106,3 +106,11 @@ export fn circle(cx: f32, cy: f32, radius: f32, col: i32) {
}
}
}
start fn setup() {
let i: i32;
loop colors {
(i*4)!(120+320*256) = i * 0x10101;
branch_if (i := i + 1) < 256: colors
}
}

View File

@@ -4,13 +4,14 @@
## Versions
* [v0.1pre1](v0.1pre1)
* [v0.1pre2](v0.1pre2)
## Spec
MicroW8 loads WebAssembly modules with a maximum size of 256kb. You module needs to export
a function `fn tic(time: i32)` which will be called once per frame.
After calling `tic` MicroW8 will display the 320x256 8bpp framebuffer located
at offset 120 in memory.
at offset 120 in memory with the 32bpp palette located at 82040.
The memory has to be imported as `"env" "memory"` and has a maximum size of 256kb (4 pages).
@@ -26,6 +27,18 @@ Other imports provided by the platform, also all in module `env`:
* `fn sin(f32) -> f32`
* `fn tan(f32) -> f32`
* `fn pow(f32) -> f32`
* `fn fmod(f32, f32) -> f32`
* `fn random() -> i32`
* `fn randomf() -> f32`
* `fn randomSeed(i32)`
* `fn cls(color: i32)`
* `fn setPixel(x: i32, y: i32, color: i32)`
* `fn getPixel(x: i32, y: i32) -> i32`
* `fn hline(left: i32, right: i32, y: i32, color: i32)`
* `fn rectangle(x1: f32, y1: f32, x2: f32, y2: f32, color: i32)`
* `fn circle(cx: f32, cy: f32, radius: f32, color: i32)`
## `.uw8` format
@@ -70,5 +83,6 @@ possible but no examples are provided, yet.
## Examples
* [Technotunnel](v0.1pre1#AQrDAQHAAQIBfwp9A0AgAUEAsiABQcACb7JDmhkgQ5MiBCAEIASUIAFBwAJtQYABa7IiBSAFlJKRIgaVIgcgByAAskHQD7KVIgIQAEPNzEw/lCIDlCAHIAeUIAOUIAOUQQGykiADIAOUk5GSIgiUIAOTQQqylCACkiIJqCAFIAaVIAiUQQqylCACkiIKqHMgCEEyspQgBpUiCyACkkEUspSocUEFcbJBArIgC5OUQRaylJeoOgB4IAFBAWoiAUGAgAVIDQALCw==) (199 bytes): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final
* [XorScroll](v0.1pre1#AQovAS0BAX8DQCABIAFBwAJvIABBCm1qIAFBwAJtczoAeCABQQFqIgFBgIAFSA0ACws=) (50 bytes): A simple scrolling XOR pattern. Fun fact: This is the pre-loaded effect when entering a bytebattle.
* [Technotunnel](v0.1pre2#AQrDAQHAAQIBfwp9A0AgAUEAsiABQcACb7JDmhkgQ5MiBCAEIASUIAFBwAJtQYABa7IiBSAFlJKRIgaVIgcgByAAskHQD7KVIgIQAEPNzEw/lCIDlCAHIAeUIAOUIAOUQQGykiADIAOUk5GSIgiUIAOTQQqylCACkiIJqCAFIAaVIAiUQQqylCACkiIKqHMgCEEyspQgBpUiCyACkkEUspSocUEFcbJBArIgC5OUQRaylJeoOgB4IAFBAWoiAUGAgAVIDQALCw==) (199 bytes): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final
* [XorScroll](v0.1pre2#AQovAS0BAX8DQCABIAFBwAJvIABBCm1qIAFBwAJtczoAeCABQQFqIgFBgIAFSA0ACws=) (50 bytes): A simple scrolling XOR pattern. Fun fact: This is the pre-loaded effect when entering a bytebattle.
* [CircleWorm](v0.1pre2#AQp7AXkCAX8CfUEgEA0DQCABskEEspUiAkECspUgALJBiCeylSIDQQWylJIQAEEBspJBoAGylCACQQOylSADQQSylJIQAEEBspJBgAGylCADQRGylCACQQKylJIQAEECspJBELKUIAFBAmxBP2oQEiABQQFqIgFBP0gNAAsL) (126 bytes): Just a test for the circle fill function.

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@
<section>
<h1 class="text-center heading-text">A WebAssembly based sizecoding platform</h1>
</section>
<a href="v0.1pre1">
<a href="v0.1pre2">
<div class="demonstration-gif" style="width:640px;height:512px;background-color:black"></div>
</a>
</div>

View File

@@ -61,7 +61,8 @@ fn main() -> Result<()> {
let mut loader = Loader::new(&engine)?;
let platform_module = wasmtime::Module::new(&engine, include_bytes!("../platform/platform.wasm"))?;
let platform_module =
wasmtime::Module::new(&engine, include_bytes!("../platform/platform.wasm"))?;
let module = wasmtime::Module::new(&engine, loader.load(&uw8_module)?)?;
@@ -98,7 +99,13 @@ fn main() -> Result<()> {
let platform_instance = linker.instantiate(&mut store, &platform_module)?;
for export in platform_instance.exports(&mut store) {
linker.define("env", export.name(), export.into_func().expect("platform surely only exports functions"))?;
linker.define(
"env",
export.name(),
export
.into_func()
.expect("platform surely only exports functions"),
)?;
}
let instance = linker.instantiate(&mut store, &module)?;
@@ -114,9 +121,13 @@ fn main() -> Result<()> {
tic.call(&mut store, start_time.elapsed().as_millis() as i32)?;
let framebuffer = &memory.data(&store)[120..];
let palette = &framebuffer[320 * 256..];
for i in 0..320 * 256 {
let c = framebuffer[i];
buffer[i] = (c as u32) * 0x01010101;
let offset = framebuffer[i] as usize * 4;
buffer[i] = 0xff000000
| ((palette[offset + 2] as u32) << 16)
| ((palette[offset + 1] as u32) << 8)
| palette[offset] as u32;
}
window.update_with_buffer(&buffer, 320, 256)?;

View File

@@ -105,7 +105,7 @@ async function runModule(data) {
let instance = new WebAssembly.Instance(await WebAssembly.compile(data), importObject);
let buffer = imageData.data;
let buffer = new Uint32Array(imageData.data.buffer);
let startTime = Date.now();
@@ -121,11 +121,9 @@ async function runModule(data) {
instance.exports.tic(Date.now() - startTime);
let framebuffer = new Uint8Array(importObject.env.memory.buffer.slice(120, 120 + 320 * 256));
let palette = new Uint32Array(importObject.env.memory.buffer.slice(82040, 82040 + 1024));
for (let i = 0; i < 320 * 256; ++i) {
buffer[i * 4] = framebuffer[i];
buffer[i * 4 + 1] = framebuffer[i];
buffer[i * 4 + 2] = framebuffer[i];
buffer[i * 4 + 3] = 255;
buffer[i] = palette[framebuffer[i]] | 0xff000000;
}
framebufferCanvasCtx.putImageData(imageData, 0, 0);
canvasCtx.imageSmoothingEnabled = false;