Created
February 28, 2024 19:08
-
-
Save ambiguousname/1d55e77a1d3b742cfcbcdf0cce89d6b1 to your computer and use it in GitHub Desktop.
BouncyBall
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; | |
;; WASM-4: https://wasm4.org/docs | |
(import "env" "memory" (memory 1)) | |
;; ┌───────────────────────────────────────────────────────────────────────────┐ | |
;; │ │ | |
;; │ Drawing Functions │ | |
;; │ │ | |
;; └───────────────────────────────────────────────────────────────────────────┘ | |
(; Copies pixels to the framebuffer. ;) | |
(import "env" "blit" (func $blit (param i32 i32 i32 i32 i32 i32))) | |
(; Copies a subregion within a larger sprite atlas to the framebuffer. ;) | |
(import "env" "blitSub" (func $blitSub (param i32 i32 i32 i32 i32 i32 i32 i32 i32))) | |
(; Draws a line between two points. ;) | |
(import "env" "line" (func $line (param i32 i32 i32 i32))) | |
(; Draws a horizontal line. ;) | |
(import "env" "hline" (func $hline (param i32 i32 i32))) | |
(; Draws a vertical line. ;) | |
(import "env" "vline" (func $vline (param i32 i32 i32))) | |
(; Draws an oval (or circle). ;) | |
(import "env" "oval" (func $oval (param i32 i32 i32 i32))) | |
(; Draws a rectangle. ;) | |
(import "env" "rect" (func $rect (param i32 i32 i32 i32))) | |
(; Draws text using the built-in system font. ;) | |
(import "env" "text" (func $text (param i32 i32 i32))) | |
;; ┌───────────────────────────────────────────────────────────────────────────┐ | |
;; │ │ | |
;; │ Sound Functions │ | |
;; │ │ | |
;; └───────────────────────────────────────────────────────────────────────────┘ | |
(; Plays a sound tone. ;) | |
(import "env" "tone" (func $tone (param i32 i32 i32 i32))) | |
;; ┌───────────────────────────────────────────────────────────────────────────┐ | |
;; │ │ | |
;; │ Storage Functions │ | |
;; │ │ | |
;; └───────────────────────────────────────────────────────────────────────────┘ | |
(; Reads up to "size" bytes from persistent storage into the pointer "dest". ;) | |
(import "env" "diskr" (func $diskr (param i32 i32))) | |
(; Writes up to "size" bytes from the pointer "src" into persistent storage. ;) | |
(import "env" "diskw" (func $diskw (param i32 i32))) | |
(; Prints a message to the debug console. ;) | |
(import "env" "trace" (func $trace (param i32))) | |
(; Prints a message to the debug console. ;) | |
(import "env" "tracef" (func $tracef (param i32 i32))) | |
;; ┌───────────────────────────────────────────────────────────────────────────┐ | |
;; │ │ | |
;; │ Memory Addresses │ | |
;; │ │ | |
;; └───────────────────────────────────────────────────────────────────────────┘ | |
(global $PALETTE0 i32 (i32.const 0x04)) | |
(global $PALETTE1 i32 (i32.const 0x08)) | |
(global $PALETTE2 i32 (i32.const 0x0c)) | |
(global $PALETTE3 i32 (i32.const 0x10)) | |
(global $DRAW_COLORS i32 (i32.const 0x14)) | |
(global $GAMEPAD1 i32 (i32.const 0x16)) | |
(global $GAMEPAD2 i32 (i32.const 0x17)) | |
(global $GAMEPAD3 i32 (i32.const 0x18)) | |
(global $GAMEPAD4 i32 (i32.const 0x19)) | |
(global $MOUSE_X i32 (i32.const 0x1a)) | |
(global $MOUSE_Y i32 (i32.const 0x1c)) | |
(global $MOUSE_BUTTONS i32 (i32.const 0x1e)) | |
(global $SYSTEM_FLAGS i32 (i32.const 0x1f)) | |
(global $NETPLAY i32 (i32.const 0x20)) | |
(global $FRAMEBUFFER i32 (i32.const 0xa0)) | |
(global $BUTTON_1 i32 (i32.const 1)) | |
(global $BUTTON_2 i32 (i32.const 2)) | |
(global $BUTTON_LEFT i32 (i32.const 16)) | |
(global $BUTTON_RIGHT i32 (i32.const 32)) | |
(global $BUTTON_UP i32 (i32.const 64)) | |
(global $BUTTON_DOWN i32 (i32.const 128)) | |
(global $MOUSE_LEFT i32 (i32.const 1)) | |
(global $MOUSE_RIGHT i32 (i32.const 2)) | |
(global $MOUSE_MIDDLE i32 (i32.const 4)) | |
(global $SYSTEM_PRESERVE_FRAMEBUFFER i32 (i32.const 1)) | |
(global $SYSTEM_HIDE_GAMEPAD_OVERLAY i32 (i32.const 2)) | |
(global $BLIT_2BPP i32 (i32.const 1)) | |
(global $BLIT_1BPP i32 (i32.const 0)) | |
(global $BLIT_FLIP_X i32 (i32.const 2)) | |
(global $BLIT_FLIP_Y i32 (i32.const 4)) | |
(global $BLIT_ROTATE i32 (i32.const 8)) | |
(global $TONE_PULSE1 i32 (i32.const 0)) | |
(global $TONE_PULSE2 i32 (i32.const 1)) | |
(global $TONE_TRIANGLE i32 (i32.const 2)) | |
(global $TONE_NOISE i32 (i32.const 3)) | |
(global $TONE_MODE1 i32 (i32.const 0)) | |
(global $TONE_MODE2 i32 (i32.const 4)) | |
(global $TONE_MODE3 i32 (i32.const 8)) | |
(global $TONE_MODE4 i32 (i32.const 12)) | |
(global $TONE_PAN_LEFT i32 (i32.const 16)) | |
(global $TONE_PAN_RIGHT i32 (i32.const 32)) | |
;; smiley | |
(data (i32.const 0x19a0) "\c3\81\24\24\00\24\99\c3") | |
(data (i32.const 0x19a8) "Hello world!\00") | |
;; Global variables | |
(global $playerPos i32 (i32.const 0x3000)) | |
(global $playerVelocity i32 (i32.const 0x3008)) | |
(global $acceleration f32 (f32.const 0.5)) | |
(global $friction f32 (f32.const 0.95)) | |
;; Functions | |
(func (export "start") | |
(call $updatePos (i32.const 76) (i32.const 76)) | |
(i32.store (global.get $PALETTE0) (i32.const 0xffffff)) | |
(i32.store (global.get $PALETTE1) (i32.const 0x000000)) | |
(i32.store (global.get $PALETTE3) (i32.const 0xff0000)) | |
) | |
(func (export "update") | |
(local $gamepad i32) | |
;; *DRAW_COLORS = 2 | |
(i32.store16 (global.get $DRAW_COLORS) (i32.const 2)) | |
;; uint8_t gamepad = *GAMEPAD1; | |
(local.set $gamepad (i32.load8_u (global.get $GAMEPAD1))) | |
;; if (gamepad & BUTTON_1) { | |
;; *DRAW_COLORS = 4; | |
;; } | |
(if (i32.and (local.get $gamepad) (global.get $BUTTON_1)) | |
(then | |
(i32.store16 (global.get $DRAW_COLORS) (i32.const 4)) | |
)) | |
i32.const 0x19a8 | |
call $getPlayerX | |
i32.const -40 | |
i32.add | |
call $getPlayerY | |
i32.const -10 | |
i32.add | |
call $text | |
(call $getInput (local.get $gamepad)) | |
;; blit(smiley, 76, 76, 8, 8, BLIT_1BPP); | |
(call $blit (i32.const 0x19a0) (call $getPlayerX) (call $getPlayerY) (i32.const 8) (i32.const 8) (global.get $BLIT_1BPP)) | |
(call $cornerHandling) | |
) | |
(func $reverseDirection (param $velocityMem i32) | |
(call $tone (i32.const 262) (i32.const 50) (global.get $TONE_TRIANGLE)) | |
local.get $velocityMem | |
local.get $velocityMem | |
f32.load | |
f32.const -1 | |
f32.mul | |
f32.store | |
) | |
(func $cornerHandling | |
(if (i32.gt_s (call $getPlayerX) (i32.const 152)) | |
(then | |
call $getVelMemX | |
call $reverseDirection | |
call $getPlayerMemX | |
i32.const 152 | |
i32.store | |
)) | |
(if (i32.lt_s (call $getPlayerX) (i32.const 0)) | |
(then | |
call $getVelMemX | |
call $reverseDirection | |
call $getPlayerMemX | |
i32.const 0 | |
i32.store | |
)) | |
(if (i32.gt_s (call $getPlayerY) (i32.const 152)) | |
(then | |
call $getVelMemY | |
call $reverseDirection | |
call $getPlayerMemY | |
i32.const 152 | |
i32.store | |
)) | |
(if (i32.lt_s (call $getPlayerY) (i32.const 0)) | |
(then | |
call $getVelMemY | |
call $reverseDirection | |
call $getPlayerMemY | |
i32.const 0 | |
i32.store | |
)) | |
) | |
(func $updateVel (param $x f32) (param $y f32) | |
global.get $playerVelocity | |
local.get $x | |
f32.store | |
global.get $playerVelocity | |
i32.const 0x04 | |
i32.add | |
local.get $y | |
f32.store | |
) | |
(func $getVelMemX (result i32) | |
global.get $playerVelocity | |
return | |
) | |
(func $getVelMemY (result i32) | |
global.get $playerVelocity | |
i32.const 0x04 | |
i32.add | |
return | |
) | |
(func $getVelX (result f32) | |
call $getVelMemX | |
f32.load | |
return | |
) | |
(func $getVelY (result f32) | |
call $getVelMemY | |
f32.load | |
return | |
) | |
(func $getPlayerMemX (result i32) | |
global.get $playerPos | |
return | |
) | |
(func $getPlayerX (result i32) | |
call $getPlayerMemX | |
i32.load | |
return | |
) | |
(func $getPlayerMemY (result i32) | |
global.get $playerPos | |
i32.const 0x04 | |
i32.add | |
return | |
) | |
(func $getPlayerY (result i32) | |
call $getPlayerMemY | |
i32.load | |
return | |
) | |
(func $updatePos (param $x i32) (param $y i32) | |
global.get $playerPos | |
local.get $x | |
i32.store | |
global.get $playerPos | |
i32.const 0x04 | |
i32.add | |
local.get $y | |
i32.store | |
) | |
(func $getInput (param $input i32) | |
;; X param: | |
;; Right input: | |
(i32.shr_u (i32.and (local.get $input) (global.get $BUTTON_RIGHT)) (i32.const 5)) | |
;; Left input: | |
(i32.shr_u (i32.and (local.get $input) (global.get $BUTTON_LEFT)) (i32.const 4)) | |
;; Sub them together: | |
i32.sub | |
f32.convert_i32_s | |
global.get $acceleration | |
f32.mul | |
;; X-value: | |
call $getVelX | |
f32.add | |
global.get $friction | |
f32.mul | |
;; Y param: | |
;; Down: | |
(i32.shr_u (i32.and (local.get $input) (global.get $BUTTON_DOWN)) (i32.const 7)) | |
;; Up: | |
(i32.shr_u (i32.and (local.get $input) (global.get $BUTTON_UP)) (i32.const 6)) | |
i32.sub | |
f32.convert_i32_s | |
global.get $acceleration | |
f32.mul | |
call $getVelY | |
f32.add | |
global.get $friction | |
f32.mul | |
call $updateVel | |
(i32.add (i32.trunc_f32_s (call $getVelX)) (call $getPlayerX)) | |
(i32.add (i32.trunc_f32_s (call $getVelY)) (call $getPlayerY)) | |
call $updatePos | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment