Skip to content

Commit

Permalink
[ch08] The WAT Module > The $main function
Browse files Browse the repository at this point in the history
  • Loading branch information
zaki-yama committed Jul 20, 2021
1 parent f6ecf36 commit d6cc073
Show file tree
Hide file tree
Showing 8 changed files with 806 additions and 2 deletions.
122 changes: 122 additions & 0 deletions the-art-of-webassembly/ch08/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
### https://raw.github.com/github/gitignore/3bb7b4b767f3f8df07e362dfa03c8bd425f16d32/Node.gitignore

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test
.env.production

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*


14 changes: 14 additions & 0 deletions the-art-of-webassembly/ch08/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [Setting a Pixel Color](#setting-a-pixel-color)
- [Drawing the Object](#drawing-the-object)
- [Setting and Getting Object Attributes](#setting-and-getting-object-attributes)
- [The $main Function](#the-main-function)

<!-- /TOC -->

Expand Down Expand Up @@ -75,3 +76,16 @@
- attribute の get と set でアドレスの計算は共通化できる (DRY) けど、しばしばパフォーマンス低下につながることがあるのでやらない
- また、この後の Chapter でさらに DRY をやめることになる
- 他のアセンブリ言語においては、マクロは DRY 原則とパフォーマンスを両立させるためのすばらしい方法だが、wat2wasm は現在マクロをサポートしていない

### The $main Function

- 毎フレーム JS から呼ばれる処理
- オブジェクトを velocity に基づいて動かし、衝突判定し、色を塗る
- Defining Local Variables
- The $move_loop
- フレームごとにオブジェクトを移動させる処理
- Beginning of the Outer Loop, The Inner Loop
- 衝突判定の 2 重ループ
- 2 つのオブジェクトの x 座標の差 < オブジェクトのサイズ && 2 つのオブジェクトの y 座標の差 < オブジェクト なら衝突していることになる
- Redrawing the Objects
- 再計算された座標と衝突フラグを元に再描画
2 changes: 1 addition & 1 deletion the-art-of-webassembly/ch08/collide.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
mem_i32[obj_start_32 + i] = temp;

// random value less than canvas_size
temp = Math.floo(Math.random() * cnvs_size);
temp = Math.floor(Math.random() * cnvs_size);
// set object y attribute to random value
mem_i32[obj_start_32 + i + 1] = temp;

Expand Down
Binary file modified the-art-of-webassembly/ch08/collide.wasm
Binary file not shown.
187 changes: 186 additions & 1 deletion the-art-of-webassembly/ch08/collide.wat
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@

;; get the attribute of an object in linear memory using the object number,
;; the attributes offset
(func $set_obj_attr
(func $get_obj_attr
(param $obj_number i32)
(param $attr_offset i32)
(result i32)
Expand All @@ -188,4 +188,189 @@
i32.load ;; load the pointer above
;; returns the attribute
)

;; move and detect collisions between all of the objects in our app
(func $main (export "main")
(local $i i32) ;; outer loop index
(local $j i32) ;; inner loop index
(local $outer_ptr i32) ;; pointer to outer loop object
(local $inner_ptr i32) ;; pointer to inner loop object

(local $x1 i32) ;; outer loop object x coordinate
(local $x2 i32) ;; inner loop object x coordinate
(local $y1 i32) ;; outer loop object y coordinate
(local $y2 i32) ;; inner loop object y coordinate

(local $xdist i32) ;; distance between objects on x axis
(local $ydist i32) ;; distance between objects on y axis

(local $i_hit i32) ;; i object hit boolean flag
(local $xv i32) ;; x velocity
(local $yv i32) ;; y velocity

(call $clear_canvas)

(loop $move_loop
;; get x attribute
(call $get_obj_attr (local.get $i) (global.get $x_offset))
local.set $x1

;; get y attribute
(call $get_obj_attr (local.get $i) (global.get $y_offset))
local.set $y1

;; get x velocity attribute
(call $get_obj_attr (local.get $i) (global.get $xv_offset))
local.set $xv

;; get y velocity attribute
(call $get_obj_attr (local.get $i) (global.get $yv_offset))
local.set $yv

;; add velocity to x and force it to stay in the canvas bounds
(i32.add (local.get $xv) (local.get $x1))
i32.const 0x1ff ;; 511 decimal
i32.and ;; clear high-order 23 bits
local.set $x1

;; add velocity to y and force it to stay in the canvas bounds
(i32.add (local.get $yv) (local.get $y1))
i32.const 0x1ff ;; 511 decimal
i32.and ;; clear high-order 23 bits
local.set $y1

;; set the x attribute in linear memory
(call $set_obj_attr
(local.get $i)
(global.get $x_offset)
(local.get $x1)
)

;; set the y attribute in linear memory
(call $set_obj_attr
(local.get $i)
(global.get $y_offset)
(local.get $y1)
)

local.get $i
i32.const 1
i32.add
local.tee $i ;; increment $i

global.get $obj_cnt
i32.lt_u ;; $i < $obj_cnt

if ;; if $i < $obj_cnt branch back to top of $move_loop
br $move_loop
end
)

i32.const 0
local.set $i

(loop $outer_loop (block $outer_break
i32.const 0
local.tee $j ;; setting j to 0

;; $i_hit is a boolean value. 0 for false, 1 for true
local.set $i_hit ;; setting i_hit to 0

;; get x attribute for object $i
(call $get_obj_attr (local.get $i) (global.get $x_offset))
local.set $x1

;; get y attribute for object $i
(call $get_obj_attr (local.get $i) (global.get $y_offset))
local.set $y1

(loop $inner_loop (block $inner_break
local.get $i
local.get $j
i32.eq
if ;; if $i == $j increment $j
local.get $j
i32.const 1
i32.add
local.set $j
end

local.get $j
global.get $obj_cnt
i32.ge_u
if ;; if $j >= $obj_count break from inner loop
br $inner_break
end

;; get x attribute
(call $get_obj_attr (local.get $j) (global.get $x_offset))
local.set $x2

;; distance between $x1 and $x2
(i32.sub (local.get $x1) (local.get $x2))

call $abs ;; distance is not negative so get the absolute value
local.tee $xdist

global.get $obj_size
i32.ge_u

if ;; if $xdist >= $obj_sizse object does not collide
local.get $j
i32.const 1
i32.add
local.set $j

br $inner_loop ;; increment $j and jump to beginning of inner loop
end

;; get y attribute
(call $get_obj_attr (local.get $j) (global.get $y_offset))
local.set $y2

(i32.sub (local.get $y1) (local.get $y2))
call $abs
local.tee $ydist

global.get $obj_size
i32.ge_u

if
local.get $j
i32.const 1
i32.add
local.set $j

br $inner_loop
end

i32.const 1
local.set $i_hit
;; exit the loop if there is a collision
)) ;; end of inner loop

local.get $i_hit
i32.const 0
i32.eq
if ;; if $i_hit == 0 (no hit)
(call $draw_obj
(local.get $x1) (local.get $y1) (global.get $no_hit_color))
else ;; if $i_hit == 1 (hit)
(call $draw_obj
(local.get $x1) (local.get $y1) (global.get $hit_color))
end

local.get $i
i32.const 1
i32.add
local.tee $i ;; increment $i

global.get $obj_cnt
i32.lt_u
if ;; if $i < $obj_cnt jump to top of the outer loop
br $outer_loop
end
)) ;; end of outer loop
) ;; end of function

)
Loading

0 comments on commit d6cc073

Please sign in to comment.