wasm4 icon indicating copy to clipboard operation
wasm4 copied to clipboard

sin/cos/atan2 etc.

Open binji opened this issue 2 years ago • 9 comments

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

binji avatar Dec 18 '21 08:12 binji

Math lib should be provided by language. AS already export all math operations like sin, cos etc, same as Rust.

eXponenta avatar Dec 18 '21 19:12 eXponenta

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.

binji avatar Dec 19 '21 03:12 binji

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.

eXponenta avatar Dec 19 '21 10:12 eXponenta

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 ;))))
  )

MaxGraey avatar Dec 19 '21 13:12 MaxGraey

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.

binji avatar Dec 19 '21 18:12 binji

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.

pfgithub avatar Dec 21 '21 04:12 pfgithub

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.

joshgoebel avatar Dec 22 '21 05:12 joshgoebel

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.

binji avatar Dec 28 '21 19:12 binji

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.

joshgoebel avatar Dec 28 '21 21:12 joshgoebel