Open joshgoebel opened 2 years ago
Oh yeah, forgot the memory related functions. In that case I'll just finish off the Rust bindings using
opt-level = 0
. The size penalty isn't just a one time cost, but it's also not too bad as far as I can tell. Every bit of code does end up larger than it would when compiled withopt-level = "s"
, but wasm-opt can shrink the build a decent amount.Relying on this to access 0x00000 is probably not right, since that's still undefined behaviour, but I imagine it's highly unlikely to ever change. Plus, it really does seem to be the only remaining option, since even
opt-level = 1
can optimise away null pointers dereferences, and that seems to be far too deeply in ingrained in Rust to change.
@soxfox42 I have found how to deal with this issue. Since Rust 1.66 we have stable std::hint::black_box
which is used to prevent optimization of certain code block (mostly used for benchmarking). This code works for me even with opt-level = "z"
:
#[export_name = "TIC"]
pub fn tic() {
unsafe {
let nullptr = std::hint::black_box(0 as *mut u8);
// Same as `tic80::poke4(0, 12)`
*nullptr = 12;
};
}
Although it is stated in Rust doc that this function should not be relied upon to control critical program behavior, I think it is still better than having no optimizations at all. I would make a PR but I do not know if this kind of hack is acceptable.
Which parts of the API are we talking about using this hack, exactly?
I think I found another way a while ago and never got around to updating the docs. I believe std::ptr::write_volatile
(which is basically designed for MMIO), while still technically undefined for address 0, is actually able to successfully write there even with optimisations on. It's been a while since I tested that though, so I might do some tests and open a PR to mention it in the Rust README.
Which parts of the API are we talking about using this hack, exactly?
@joshgoebel
This is just for directly writing to memory from the Rust code, like *((char *) 0) = 42
in C. It doesn't affect the API.
Any chance we can get AssemblyScript bindings, or at least have it added to the list in the first post?
https://www.assemblyscript.org/ https://github.com/aduros/wasm4/tree/main/cli/assets/templates/assemblyscript
Done. These bindings are all community provided... if you want to contribute...
I've recently made one game with Odin lang and TIC-80 for game jam and have made some kind of bindings for that purpose. It's not very clean and does not cover 100% of TIC-80 API and have some extra methods that I've found convenient but if I'll have enough time I can try to make a fully covered bindings and project template from that.
That language really deserves some attention in gamedev space in my opinion.
Creating a master topic to link to from our wiki/documentation for those wishing to contribute language templates/libraries.
We should be able to support all the same languages as the WASM-4 project. The list:
Essentially any language that compiles to WASM and allows you to configure the memory layout is a potential.
What is needed? Port over the build/template scripts from the WASM-4 project templates and update for TIC-80. These templates are typically well thought out and well maintained so they are a great starting point.
templates
wasm4.h
library headertic80.h
library headerWhat is the core API?
Reference:
The ZIG API definition is pretty easy to read:
It follows VERY closely to the native C API which you can find in:
core.c
,io.c
, anddraw.c
It's often quite a bit lower level than the API docs on the wiki, so don't rely on those TOO much.