wasm4
wasm4 copied to clipboard
sin/cos/atan2 etc.
It would be nice to have these functions provided by the environment. As it is, I had to implement sin
from the musl sources:
see https://gist.github.com/binji/b97c8d29d7a7bfbfbaac8265d0a4d52a#file-maze-wasm4-wat-L136-L273
Math lib should be provided by language. AS already export all math operations like sin, cos etc, same as Rust.
Ok, but it doesn't work well for writing WebAssembly by hand. Any environment should be able to provide those functions too, and if you use them you can keep the Wasm file size smaller too.
Amm, not, not should.
WASM4 is console-like environment with WASM opcodes. ALU of this 'hardware' is limited, you should implement it yourself if you need more that mull/add etc,. How? Your problem. You can use a pre-builded wat blocks from Emcc or rust or AssemblyScript, it all has manually implemented math operations.
There are not sin/cos/atan/ operations in a lot of hardware, older CPU hadn't a float-point math at all.
This is one of limitations, same as 64kb of ram and flash, 4 colors on screen or limited audio synthetiser.
sin / cos and other functions could be implemented in very minimalistic way. Usually you're need only fixed point result which may use precalculated tables. Otherwise it could be some low precision routines like this:
;; |sin(x) - s(x)| < ~0.0007
(func $sin (param $x f32) (result f32)
(local $y f32)
;; y = floor(x * (1 / pi))
(local.set $y (f32.floor
(local.tee $x (f32.mul (local.get $x) (f32.const 0x1.45f306p-2 (; 1 / pi ;))))
))
;; y & 1 ? -z : z
(select
(f32.neg
;; z = x - y
;; z *= 1 - z
(local.tee $x (f32.mul
(local.tee $x (f32.mul
(local.tee $x (f32.sub (local.get $x) (local.get $y)))
(f32.sub (f32.const 1) (local.get $x))
))
;; z *= 3.6 * z + 3.1
(f32.add (f32.mul (local.get $x) (f32.const 3.6)) (f32.const 3.1))
))
)
(local.get $x)
;; i32(y) & 1
(i32.and (i32.trunc_sat_f32_s (local.get $y)) (i32.const 1))
)
)
(func $cos (param $x f32) (result f32)
(call $sin (f32.add (local.get $x) (f32.const 0x1.921fb6p+0 (; pi / 2 ;))))
)
I understand that wasm4 is meant to be minimal, and that there are many ways to work around the omission. But at least with most fantasy consoles the minimalism is meant to spark fun and creativity. I'm just saying that I don't think that omitting these functions helps much with that. Anyway, just a suggestion.
As far as I am aware, wasm4 is intended to be programmed with a programming language that provides these functions. A wasm4 built for hand-coding assembly would look very different.
If you want to hand-code assembly, I would probably recommend linking in some c code to provide common functions like these. If wasm4 ever wants to officially support hand-coded webassembly, it should probably provide common functions like these in its template.
If wasm4 ever wants to officially support hand-coded webassembly
I think we already do, but "supporting" doesn't necessarily imply providing a huge library of helper routines to make it easy... I think that is the job of the ecosystem. I don't see a need for the core library to provide different tools for WebAssembly target than it does for all the other targets. Sadly it's hard[er] to develop a unified ecosystem when you support a large variety of very different languages. TIC-80 suffers from this problem a little as well.
wasm4 already adds some functionality that is not strictly necessary, such as all the rendering functions. These could also be implemented in the language template, or an additional library. Mostly I'm hearing that trigonometric functions doesn't really fit in with the retro aesthetic, which makes sense to me.
wasm4 already adds some functionality that is not strictly necessary, such as all the rendering functions.
I'd imagine that's partly out of convenience for the WASM-4 team as well though... you write (and fix bugs) in a single place, instead of having 15 different languages libraries that ALL have a broken blit
function... what a quagmire that would be.